source: trunk/MagicSoft/Mars/mhist/MHMatrix.cc@ 1343

Last change on this file since 1343 was 1336, checked in by tbretz, 23 years ago
*** empty log message ***
File size: 9.7 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz 2002 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2002
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MHMatrix
28//
29// This is a histogram container which holds a matrix with one column per
30// data variable. The data variable can be a complex rule (MDataChain).
31// Each event for wich Fill is called (by MFillH) is added as a new
32// row to the matrix.
33//
34// For example:
35// MHMatrix m;
36// m.AddColumn("MHillas.fSize");
37// m.AddColumn("MMcEvt.fImpact/100");
38// m.AddColumn("HillasSource.fDist*MGeomCam.fConvMm2Deg");
39// MFillH fillm(&m);
40// taskliost.AddToList(&fillm);
41// [...]
42// m.Print();
43//
44/////////////////////////////////////////////////////////////////////////////
45#include "MHMatrix.h"
46
47#include <TList.h>
48#include <TArrayD.h>
49#include <TArrayI.h>
50
51#include "MLog.h"
52#include "MLogManip.h"
53
54#include "MParList.h"
55
56#include "MDataChain.h"
57
58ClassImp(MHMatrix);
59
60// --------------------------------------------------------------------------
61//
62// Default Constructor
63//
64MHMatrix::MHMatrix(const char *name, const char *title)
65 : fNumRow(0)
66{
67 fName = name ? name : "MHMatrix";
68 fTitle = title ? title : "Multidimensional Matrix";
69
70 fData = new TList;
71 fData->SetOwner();
72
73 fRules = new TList;
74 fRules->SetOwner();
75}
76
77// --------------------------------------------------------------------------
78//
79// Destructor
80//
81MHMatrix::~MHMatrix()
82{
83 delete fData;
84 delete fRules;
85}
86
87// --------------------------------------------------------------------------
88//
89// Add a new column to the matrix. This can only be done before the first
90// event (row) was filled into the matrix. For the syntax of the rule
91// see MDataChain.
92//
93void MHMatrix::AddColumn(const char *rule)
94{
95 if (fM.IsValid())
96 {
97 *fLog << warn << "Warning - matrix is already in use. Can't add a new column... skipped." << endl;
98 return;
99 }
100
101 MDataChain &chain = *new MDataChain(rule);
102 if (!chain.IsValid())
103 {
104 *fLog << err << "Error - Rule cannot be translated... ignored." << endl;
105 delete &chain;
106 return;
107 }
108
109 fData->Add(&chain);
110
111 TNamed *name = new TNamed(rule, "");
112 fRules->Add(name);
113}
114
115void MHMatrix::AddColumns(const MHMatrix *matrix)
116{
117 TIter Next(matrix->fRules);
118 TObject *rule=NULL;
119 while ((rule=Next()))
120 AddColumn(rule->GetName());
121}
122
123// --------------------------------------------------------------------------
124//
125// Checks whether at least one column is available and PreProcesses all
126// data chains.
127//
128Bool_t MHMatrix::SetupFill(const MParList *plist)
129{
130 if (fData->GetSize()==0)
131 {
132 *fLog << err << "Error - No Column specified... aborting." << endl;
133 return kFALSE;
134 }
135
136 TIter Next(fData);
137 MData *data = NULL;
138 while ((data=(MData*)Next()))
139 if (!data->PreProcess(plist))
140 return kFALSE;
141
142 return kTRUE;
143}
144
145// --------------------------------------------------------------------------
146//
147// If the matrix has not enough rows double the number of available rows.
148//
149void MHMatrix::AddRow()
150{
151 fNumRow++;
152
153 if (fM.GetNrows() > fNumRow)
154 return;
155
156 if (!fM.IsValid())
157 {
158 fM.ResizeTo(1, fData->GetSize());
159 return;
160 }
161
162 TMatrix m(fM);
163
164 fM.ResizeTo(fM.GetNrows()*2, fData->GetSize());
165
166 for (int x=0; x<m.GetNcols(); x++)
167 for (int y=0; y<m.GetNrows(); y++)
168 fM(y, x) = m(y, x);
169}
170
171// --------------------------------------------------------------------------
172//
173// Add the values correspoding to the columns to the new row
174//
175Bool_t MHMatrix::Fill(const MParContainer *par)
176{
177 AddRow();
178
179 int col=0;
180 TIter Next(fData);
181 MData *data = NULL;
182 while ((data=(MData*)Next()))
183 fM(fNumRow-1, col++) = data->GetValue();
184
185 return kTRUE;
186}
187
188// --------------------------------------------------------------------------
189//
190// Resize the matrix to a number of rows which corresponds to the number of
191// rows which have really been filled with values.
192//
193Bool_t MHMatrix::Finalize()
194{
195 TMatrix m(fM);
196
197 fM.ResizeTo(fNumRow, fData->GetSize());
198
199 for (int x=0; x<fM.GetNcols(); x++)
200 for (int y=0; y<fM.GetNrows(); y++)
201 fM(y, x) = m(y, x);
202
203 return kTRUE;
204}
205/*
206// --------------------------------------------------------------------------
207//
208// Draw clone of histogram. So that the object can be deleted
209// and the histogram is still visible in the canvas.
210// The cloned object are deleted together with the canvas if the canvas is
211// destroyed. If you want to handle destroying the canvas you can get a
212// pointer to it from this function
213//
214TObject *MHMatrix::DrawClone(Option_t *opt) const
215{
216 TCanvas &c = *MH::MakeDefCanvas(fHist);
217
218 //
219 // This is necessary to get the expected bahviour of DrawClone
220 //
221 gROOT->SetSelectedPad(NULL);
222
223 fHist->DrawCopy(opt);
224
225 TString str(opt);
226 if (str.Contains("PROFX", TString::kIgnoreCase) && fDimension==2)
227 {
228 TProfile *p = ((TH2*)fHist)->ProfileX();
229 p->Draw("same");
230 p->SetBit(kCanDelete);
231 }
232 if (str.Contains("PROFY", TString::kIgnoreCase) && fDimension==2)
233 {
234 TProfile *p = ((TH2*)fHist)->ProfileY();
235 p->Draw("same");
236 p->SetBit(kCanDelete);
237 }
238
239 c.Modified();
240 c.Update();
241
242 return &c;
243}
244
245// --------------------------------------------------------------------------
246//
247// Creates a new canvas and draws the histogram into it.
248// Be careful: The histogram belongs to this object and won't get deleted
249// together with the canvas.
250//
251void MHMatrix::Draw(Option_t *opt)
252{
253 if (!gPad)
254 MH::MakeDefCanvas(fHist);
255
256 fHist->Draw(opt);
257
258 TString str(opt);
259 if (str.Contains("PROFX", TString::kIgnoreCase) && fDimension==2)
260 {
261 TProfile *p = ((TH2*)fHist)->ProfileX();
262 p->Draw("same");
263 p->SetBit(kCanDelete);
264 }
265 if (str.Contains("PROFY", TString::kIgnoreCase) && fDimension==2)
266 {
267 TProfile *p = ((TH2*)fHist)->ProfileY();
268 p->Draw("same");
269 p->SetBit(kCanDelete);
270 }
271
272 gPad->Modified();
273 gPad->Update();
274}
275*/
276
277// --------------------------------------------------------------------------
278//
279// Prints the meaning of the columns and the contents of the matrix.
280// Becareful, this can take a long time for matrices with many rows.
281//
282void MHMatrix::Print(Option_t *) const
283{
284 int n=0;
285
286 TIter Next(fData->GetSize() ? fData : fRules);
287 MData *data = NULL;
288 while ((data=(MData*)Next()))
289 {
290 *fLog << all << " Column " << setw(3) << n++ << ": " << flush;
291 data->Print();
292 *fLog << endl;
293 }
294
295 fM.Print();
296}
297
298const TMatrix *MHMatrix::InvertPosDef()
299{
300 /*
301 ----------------------------------
302 Substract Mean of Rows from Rows
303 ----------------------------------
304
305 const Int_t rows = fM.GetNrows();
306 const Int_t cols = fM.GetNcols();
307
308 for (int i=0; i<rows; i++)
309 {
310 Double_t mean = 0;
311 for (int j=0; j<cols; j++)
312 mean += fM(i, j);
313 mean /= cols;
314
315 for (int j=0; j<cols; j++)
316 fM(i, j) -= mean;
317 }
318 */
319 /*
320 ----------------------------------
321 Substract Mean of Cols from Cols
322 ----------------------------------
323
324 const Int_t rows = fM.GetNrows();
325 const Int_t cols = fM.GetNcols();
326
327 for (int i=0; i<cols; i++)
328 {
329 Double_t mean = 0;
330 for (int j=0; j<rows; j++)
331 mean += fM(j, i);
332 mean /= rows;
333
334 for (int j=0; j<rows; j++)
335 fM(j, i) -= mean;
336 }
337 */
338
339 TMatrix *m2 = new TMatrix(fM, TMatrix::kTransposeMult, fM);
340
341 Double_t det;
342 m2->Invert(&det);
343 if (det==0)
344 {
345 *fLog << err << "ERROR - MHMatrix::InvertPosDef failed (Matrix is sigular)." << endl;
346 delete m2;
347 return NULL;
348 }
349
350 // m2->Print();
351
352 return m2;
353}
354
355Double_t MHMatrix::CalcDist(const TMatrix &m, const TVector &evt, Int_t num) const
356{
357 const Int_t rows = fM.GetNrows();
358 const Int_t cols = fM.GetNcols();
359
360 TArrayD dists(rows);
361
362 //
363 // Calculate: v^T * M * v
364 //
365 for (int i=0; i<rows; i++)
366 {
367 TVector col(cols);
368 col = TMatrixRow(fM, i);
369
370 TVector d = evt;
371 d -= col;
372
373 TVector d2 = d;
374 d2 *= m;
375
376 dists[i] = fabs(d2*d);
377 }
378
379 TArrayI idx(rows);
380 TMath::Sort(dists.GetSize(), dists.GetArray(), idx.GetArray(), kFALSE);
381
382 const Int_t n = num<rows ? num : rows;
383
384 Double_t res = 0;
385 for (int i=0; i<n; i++)
386 res += dists[idx[i]];
387
388 return res/n;
389}
390
391Double_t MHMatrix::CalcDist(const TVector &evt, Int_t num)
392{
393 if (!fM2.IsValid())
394 {
395 const TMatrix &m = *InvertPosDef();
396 fM2.ResizeTo(m);
397 fM2 = m;
398 delete &m;
399 }
400
401 return CalcDist(fM2, evt, num);
402}
403
404void MHMatrix::Reassign()
405{
406 TMatrix m = fM;
407 fM.ResizeTo(1,1);
408 fM.ResizeTo(m);
409 fM = m;
410
411 TIter Next(fRules);
412 TObject *obj = NULL;
413 while ((obj=Next()))
414 fData->Add(new MDataChain(obj->GetName()));
415}
Note: See TracBrowser for help on using the repository browser.