source: trunk/MagicSoft/Mars/mtools/MTFillMatrix.cc@ 2702

Last change on this file since 2702 was 2695, checked in by tbretz, 21 years ago
*** empty log message ***
File size: 8.3 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//
38// Here is an example of how to choose 1000 events somehow distributed in
39// size from a file.
40// -----------------------------------------------------------------------
41//
42// MH3 ref("MHillas.fSize"); // choose a predefined size distribution
43// // Now setup the distribution
44//
45// MHMatrix matrix1; // create matrix to fill
46// matrix.AddColumn("MHillas.fWidth"); // setup columns of your matrix
47//
48// MReadMarsFile read("myfile.root"); // Setup your 'reader'
49// read.DisableAutoScheme(); // make sure everything is read
50//
51// MTFillMatrix fill(ref); // setup MTFillMatrix
52// fill.SetNumDestEvents1(1000); // setup number of events to select
53// fill.SetDestMatrix1(&matrix1); // setup destination matrix
54// if (!fill.Process()) // check if everything worked
55// return;
56// fill.WriteMatrix1("myoutput.root"); // write matrix to file
57//
58//
59// To get two matrices instead of one (splitted randomly) you can add
60// the following before calling Process():
61// ------------------------------------------------------------------------
62//
63// MHMatrix matrix2;
64// fill.SetNumDestEvents2(500); // setup number of events to select
65// fill.SetDestMatrix2(&matrix2); // setup destination matrix
66// [...]
67// fill.WriteMatrix2("myoutput2.root");
68//
69//
70// To write both matrices into a single file use:
71// ----------------------------------------------
72//
73// fill.WriteMatrices("myfile.root");
74//
75/////////////////////////////////////////////////////////////////////////////
76#include "MTFillMatrix.h"
77
78#include <TFile.h>
79
80#include "MHMatrix.h"
81
82#include "MLog.h"
83#include "MLogManip.h"
84
85#include "MParList.h"
86#include "MTaskList.h"
87#include "MEvtLoop.h"
88
89#include "MRead.h"
90#include "MFillH.h"
91#include "MContinue.h"
92#include "MFilterList.h"
93#include "MFRandomSplit.h"
94#include "MFEventSelector2.h"
95
96ClassImp(MTFillMatrix);
97
98using namespace std;
99
100// --------------------------------------------------------------------------
101//
102// Print Size and contained columns.
103// Check whether the number of generated events is compatible with
104// the number of requested events.
105//
106Bool_t MTFillMatrix::CheckResult(MHMatrix *m, Int_t num) const
107{
108 if (!m)
109 return kTRUE;
110
111 m->Print("SizeCols");
112
113 const Int_t generated = m->GetM().GetNrows();
114 if (TMath::Abs(generated-num) <= TMath::Sqrt(9.0*num))
115 return kTRUE;
116
117 *fLog << warn << "WARNING - No. of generated events (";
118 *fLog << generated << ") incompatible with requested events (";
119 *fLog << num << ") for " << m->GetDescriptor() << endl;
120
121 return kFALSE;
122}
123
124// --------------------------------------------------------------------------
125//
126// Write the given MHMatrix with its name as default name to a
127// file fname.
128//
129Bool_t MTFillMatrix::WriteMatrix(MHMatrix *m, const TString &fname, Int_t i) const
130{
131 if (!m)
132 {
133 *fLog << "ERROR - Unable to write matrix #" << i << " (=NULL)... ignored." << endl;
134 return kFALSE;
135 }
136
137 TFile file(fname, "RECREATE", m->GetTitle());
138 m->Write();
139 return kTRUE;
140}
141
142// --------------------------------------------------------------------------
143//
144// Constructor. Takes an MH3 as argument. This MH3 is the reference
145// distribution to fill the matrix. More information can be found
146// at MFEventSelector2 which is used to select the events.
147//
148// FIXME: Make a copy of ref.
149//
150MTFillMatrix::MTFillMatrix(const MH3 &ref)
151: fReference(ref), fReader(0), fDestMatrix1(0),
152fDestMatrix2(0), fNumDestEvents1(0), fNumDestEvents2(0),
153fWriteFile1(0), fWriteFile2(0)
154{
155 fName = "MFillMatrix";
156 fTitle = "Tool to fill MHMatrix from file";
157}
158
159// --------------------------------------------------------------------------
160//
161// Fill the matrix (FIXME: Flow diagram missing)
162//
163Bool_t MTFillMatrix::Process()
164{
165 if (!fReader)
166 {
167 *fLog << err << "ERROR - No task to read data was given... abort." << endl;
168 return kFALSE;
169 }
170
171 *fLog << inf;
172 fLog->Separator(GetDescriptor());
173 *fLog << "Fill " << fDestMatrix1->GetDescriptor() << " with " << fNumDestEvents1 << endl;
174 *fLog << "Fill " << fDestMatrix2->GetDescriptor() << " with " << fNumDestEvents2 << endl;
175 *fLog << "Distribution choosen ";
176 if (fReference.GetHist().GetEntries()>0)
177 *fLog << "from " << fReference.GetDescriptor();
178 else
179 *fLog << "randomly";
180 *fLog << endl;
181
182 //
183 // Create parameter list and task list, add tasklist to parlist
184 //
185 MParList plist;
186 MTaskList tlist;
187 plist.AddToList(&tlist);
188
189 //
190 // A selector to select a given number of events from a sample
191 //
192 MFEventSelector2 selector(fReference);
193 selector.SetNumMax(fNumDestEvents1+fNumDestEvents2);
194 selector.SetInverted();
195
196 //
197 // Continue for all events which are not (SetInverted())
198 // selected by the 'selector'
199 //
200 MContinue cont(&selector);
201
202 //
203 // Create a filter doing a random split
204 //
205 const Double_t prob = (Double_t)fNumDestEvents1/(fNumDestEvents1+fNumDestEvents2);
206 MFRandomSplit split(prob);
207
208 //
209 // Create the logical inverted filter for 'split'
210 //
211 MFilterList invsplit;
212 invsplit.AddToList(&split);
213 invsplit.SetInverted();
214
215 //
216 // The two tasks filling the two matrices
217 //
218 MFillH fill1(fDestMatrix1);
219 MFillH fill2(fDestMatrix2);
220 fill1.SetFilter(&split);
221 fill2.SetFilter(&invsplit);
222
223 // entries in MTaskList
224 tlist.AddToList(fReader); // Read events
225 tlist.AddToList(&cont); // select a sample of events
226 tlist.AddToList(&invsplit); // process invsplit (which implicitly processes split)
227 if (fDestMatrix1 && fNumDestEvents1>0)
228 tlist.AddToList(&fill1); // fill matrix 1
229 if (fDestMatrix2 && fNumDestEvents2>0)
230 tlist.AddToList(&fill2); // fill matrix 2
231 if (fWriteFile1)
232 {
233 fWriteFile1->SetFilter(&split);
234 tlist.AddToList(fWriteFile1);
235 }
236 if (fWriteFile2)
237 {
238 fWriteFile2->SetFilter(&invsplit);
239 tlist.AddToList(fWriteFile2);
240 }
241
242 //
243 // Execute the eventloop
244 //
245 MEvtLoop evtloop(fName);
246 evtloop.SetParList(&plist);
247 if (!evtloop.Eventloop())
248 {
249 *fLog << err << GetDescriptor() << ": Failed." << endl;
250 return kFALSE;
251 }
252
253 // Print execution statistics of the tasklist
254 tlist.PrintStatistics();
255
256 // Check the result of filling...
257 CheckResult(fDestMatrix1, fNumDestEvents1);
258 CheckResult(fDestMatrix2, fNumDestEvents2);
259
260 *fLog << inf << GetDescriptor() << ": Done." << endl;
261 return kTRUE;
262}
263
264// --------------------------------------------------------------------------
265//
266// Write both matrices to a file. Return kFALSE if writing one of them
267// failed or both have the same name.
268//
269Bool_t MTFillMatrix::WriteMatrices(const TString &fname) const
270{
271 if (fDestMatrix1 && fDestMatrix2 &&
272 (TString)fDestMatrix1->GetName()==(TString)fDestMatrix2->GetName())
273 {
274 *fLog << "ERROR - Cannot write matrices (both have the same name)... ignored." << endl;
275 return kFALSE;
276 }
277
278 return WriteMatrix1(fname) && WriteMatrix2(fname);
279}
Note: See TracBrowser for help on using the repository browser.