source: tags/Mars-V0.9/mtools/MTFillMatrix.cc

Last change on this file was 2744, checked in by tbretz, 21 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, 12/2003 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2003
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MTFillMatrix
28//
29// Use this tool to fill eg trainings and test-matrices, while the matrix
30// to be filled can be a real matrix (MHMatrix) or a file (MWriteRootFile)
31// or both.
32//
33// First create a reference histogram (MH3). For more details see
34// MFEventSelector2 which is used to select events according to the
35// reference histogram.
36//
37// If no reference histogram is available the number of events are
38// randomly choosen from the sample with a probability which fits
39// the total destination number of events.
40//
41// Here is an example of how to choose 1000 events somehow distributed in
42// size from a file.
43// -----------------------------------------------------------------------
44//
45// MH3 ref("MHillas.fSize"); // choose a predefined size distribution
46// // Now setup the distribution
47//
48// MHMatrix matrix1; // create matrix to fill
49// matrix.AddColumn("MHillas.fWidth"); // setup columns of your matrix
50//
51// MReadMarsFile read("myfile.root"); // Setup your 'reader'
52// read.DisableAutoScheme(); // make sure everything is read
53//
54// MTFillMatrix fill(&ref); // setup MTFillMatrix
55// fill.SetNumDestEvents1(1000); // setup number of events to select
56// fill.SetDestMatrix1(&matrix1); // setup destination matrix
57// if (!fill.Process()) // check if everything worked
58// return;
59// fill.WriteMatrix1("myoutput.root"); // write matrix to file
60//
61//
62// To get two matrices instead of one (splitted randomly) you can add
63// the following before calling Process():
64// ------------------------------------------------------------------------
65//
66// MHMatrix matrix2;
67// fill.SetNumDestEvents2(500); // setup number of events to select
68// fill.SetDestMatrix2(&matrix2); // setup destination matrix
69// [...]
70// fill.WriteMatrix2("myoutput2.root");
71//
72//
73// To write both matrices into a single file use:
74// ----------------------------------------------
75//
76// fill.WriteMatrices("myfile.root");
77//
78/////////////////////////////////////////////////////////////////////////////
79#include "MTFillMatrix.h"
80
81#include <TFile.h>
82
83#include "MHMatrix.h"
84
85#include "MLog.h"
86#include "MLogManip.h"
87
88#include "MParList.h"
89#include "MTaskList.h"
90#include "MEvtLoop.h"
91
92#include "MRead.h"
93#include "MFillH.h"
94#include "MContinue.h"
95#include "MFilterList.h"
96#include "MFEventSelector.h"
97#include "MFEventSelector2.h"
98
99ClassImp(MTFillMatrix);
100
101using namespace std;
102
103// --------------------------------------------------------------------------
104//
105// Print Size and contained columns.
106// Check whether the number of generated events is compatible with
107// the number of requested events.
108//
109Bool_t MTFillMatrix::CheckResult(MHMatrix *m, Int_t num) const
110{
111 if (!m)
112 return kTRUE;
113
114 m->Print("SizeCols");
115
116 const Int_t generated = m->GetM().GetNrows();
117 if (TMath::Abs(generated-num) <= TMath::Sqrt(9.0*num))
118 return kTRUE;
119
120 *fLog << warn << "WARNING - No. of generated events (";
121 *fLog << generated << ") incompatible with requested events (";
122 *fLog << num << ") for " << m->GetDescriptor() << endl;
123
124 return kFALSE;
125}
126
127// --------------------------------------------------------------------------
128//
129// Write the given MHMatrix with its name as default name to a
130// file fname.
131//
132Bool_t MTFillMatrix::WriteMatrix(MHMatrix *m, const TString &fname, Int_t i) const
133{
134 if (!m)
135 {
136 *fLog << "ERROR - Unable to write matrix #" << i << " (=NULL)... ignored." << endl;
137 return kFALSE;
138 }
139 if (fname.IsNull())
140 {
141 *fLog << "ERROR - Unable to write matrix, file name empty." << endl;
142 return kFALSE;
143 }
144
145 TFile file(fname, "RECREATE", m->GetTitle());
146 m->Write();
147 return kTRUE;
148}
149
150// --------------------------------------------------------------------------
151//
152// Constructor. Takes an MH3 as argument. This MH3 is the reference
153// distribution to fill the matrix. More information can be found
154// at MFEventSelector2 which is used to select the events.
155//
156// If no MH3 *ref is given the events are randomly selected from the
157// total sample - this may result in samples which don't have exactly
158// the predefined size, but it is much faster.
159//
160MTFillMatrix::MTFillMatrix(const MH3 *ref)
161: fReference(0), fReader(0), fDestMatrix1(0), fDestMatrix2(0),
162 fNumDestEvents1(0), fNumDestEvents2(0), fWriteFile1(0), fWriteFile2(0)
163{
164 fName = "MFillMatrix";
165 fTitle = "Tool to fill MHMatrix from file";
166
167 if (ref)
168 fReference = (MH3*)ref->Clone();
169}
170
171MTFillMatrix::~MTFillMatrix()
172{
173 if (fReference)
174 delete fReference;
175}
176
177// --------------------------------------------------------------------------
178//
179// Fill the matrix (FIXME: Flow diagram missing)
180//
181Bool_t MTFillMatrix::Process()
182{
183 if (!fReader)
184 {
185 *fLog << err << "ERROR - No task to read data was given... abort." << endl;
186 return kFALSE;
187 }
188
189 *fLog << inf;
190 fLog->Separator(GetDescriptor());
191 *fLog << "Fill " << fDestMatrix1->GetDescriptor() << " with " << fNumDestEvents1 << endl;
192 *fLog << "Fill " << fDestMatrix2->GetDescriptor() << " with " << fNumDestEvents2 << endl;
193 *fLog << "Distribution choosen ";
194 if (fReference && fReference->GetHist().GetEntries()>0)
195 *fLog << "from " << fReference->GetDescriptor();
196 else
197 *fLog << "randomly";
198 *fLog << endl;
199
200 //
201 // Create parameter list and task list, add tasklist to parlist
202 //
203 MParList plist;
204 MTaskList tlist;
205 plist.AddToList(&tlist);
206
207 //
208 // A selector to select a given number of events from a sample
209 //
210 // FIXME: Merge MFEventSelector and MFEventSelector2
211 MFilter *selector=0;
212 if (fReference)
213 {
214 // Case of a reference/nominal distribution
215 // The events must be read before selection
216 MFEventSelector2 *sel = new MFEventSelector2(*fReference);
217 sel->SetNumMax(fNumDestEvents1+fNumDestEvents2);
218 sel->SetInverted();
219
220 selector = sel;
221 }
222 else
223 {
224 // Case of a random distribution
225 // The events can be selected before reading
226 MFEventSelector *sel = new MFEventSelector;
227 sel->SetNumSelectEvts(fNumDestEvents1+fNumDestEvents2);
228 fReader->SetSelector(sel);
229
230 selector = sel;
231 }
232
233 //
234 // Continue for all events which are not (SetInverted())
235 // selected by the 'selector'
236 //
237 MContinue cont(selector);
238
239 //
240 // Create a filter doing a random split
241 //
242 const Double_t prob = (Double_t)fNumDestEvents1/(fNumDestEvents1+fNumDestEvents2);
243 MFEventSelector split;
244 split.SetSelectionRatio(prob);
245
246 //
247 // Create the logical inverted filter for 'split'
248 //
249 MFilterList invsplit;
250 invsplit.AddToList(&split);
251 invsplit.SetInverted();
252
253 //
254 // The two tasks filling the two matrices
255 //
256 MFillH fill1(fDestMatrix1);
257 MFillH fill2(fDestMatrix2);
258 fill1.SetFilter(&split);
259 fill2.SetFilter(&invsplit);
260
261 // entries in MTaskList
262 tlist.AddToList(fReader); // Read events
263 if (fReference)
264 tlist.AddToList(&cont); // select a sample of events
265 tlist.AddToList(&invsplit); // process invsplit (which implicitly processes split)
266 if (fDestMatrix1 && fNumDestEvents1>0)
267 tlist.AddToList(&fill1); // fill matrix 1
268 if (fDestMatrix2 && fNumDestEvents2>0)
269 tlist.AddToList(&fill2); // fill matrix 2
270 if (fWriteFile1)
271 {
272 fWriteFile1->SetFilter(&split);
273 tlist.AddToList(fWriteFile1);
274 }
275 if (fWriteFile2)
276 {
277 fWriteFile2->SetFilter(&invsplit);
278 tlist.AddToList(fWriteFile2);
279 }
280
281 //
282 // Execute the eventloop
283 //
284 MEvtLoop evtloop(fName);
285 evtloop.SetParList(&plist);
286 evtloop.SetDisplay(fDisplay);
287 evtloop.SetLogStream(fLog);
288
289 const Bool_t rc = evtloop.Eventloop();
290
291 // Print execution statistics of the tasklist
292 if (rc)
293 tlist.PrintStatistics();
294
295 delete selector;
296
297 if (!rc)
298 {
299 *fLog << err << GetDescriptor() << ": Failed." << endl;
300 return kFALSE;
301 }
302
303 // Check the result of filling...
304 CheckResult(fDestMatrix1, fNumDestEvents1);
305 CheckResult(fDestMatrix2, fNumDestEvents2);
306
307 *fLog << inf << GetDescriptor() << ": Done." << endl;
308 return kTRUE;
309}
310
311// --------------------------------------------------------------------------
312//
313// Write both matrices to a file. Return kFALSE if writing one of them
314// failed or both have the same name.
315//
316Bool_t MTFillMatrix::WriteMatrices(const TString &fname) const
317{
318 if (fDestMatrix1 && fDestMatrix2 &&
319 (TString)fDestMatrix1->GetName()==(TString)fDestMatrix2->GetName())
320 {
321 *fLog << "ERROR - Cannot write matrices (both have the same name)... ignored." << endl;
322 return kFALSE;
323 }
324
325 return WriteMatrix1(fname) && WriteMatrix2(fname);
326}
Note: See TracBrowser for help on using the repository browser.