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

Last change on this file since 2711 was 2711, checked in by tbretz, 21 years ago
*** empty log message ***
File size: 8.5 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 if (fname.IsNull())
137 {
138 *fLog << "ERROR - Unable to write matrix, file name empty." << endl;
139 return kFALSE;
140 }
141
142 TFile file(fname, "RECREATE", m->GetTitle());
143 m->Write();
144 return kTRUE;
145}
146
147// --------------------------------------------------------------------------
148//
149// Constructor. Takes an MH3 as argument. This MH3 is the reference
150// distribution to fill the matrix. More information can be found
151// at MFEventSelector2 which is used to select the events.
152//
153// FIXME: Make a copy of ref.
154//
155MTFillMatrix::MTFillMatrix(const MH3 &ref)
156: fReference(ref), fReader(0), fDestMatrix1(0),
157fDestMatrix2(0), fNumDestEvents1(0), fNumDestEvents2(0),
158fWriteFile1(0), fWriteFile2(0)
159{
160 fName = "MFillMatrix";
161 fTitle = "Tool to fill MHMatrix from file";
162}
163
164// --------------------------------------------------------------------------
165//
166// Fill the matrix (FIXME: Flow diagram missing)
167//
168Bool_t MTFillMatrix::Process()
169{
170 if (!fReader)
171 {
172 *fLog << err << "ERROR - No task to read data was given... abort." << endl;
173 return kFALSE;
174 }
175
176 *fLog << inf;
177 fLog->Separator(GetDescriptor());
178 *fLog << "Fill " << fDestMatrix1->GetDescriptor() << " with " << fNumDestEvents1 << endl;
179 *fLog << "Fill " << fDestMatrix2->GetDescriptor() << " with " << fNumDestEvents2 << endl;
180 *fLog << "Distribution choosen ";
181 if (fReference.GetHist().GetEntries()>0)
182 *fLog << "from " << fReference.GetDescriptor();
183 else
184 *fLog << "randomly";
185 *fLog << endl;
186
187 //
188 // Create parameter list and task list, add tasklist to parlist
189 //
190 MParList plist;
191 MTaskList tlist;
192 plist.AddToList(&tlist);
193
194 //
195 // A selector to select a given number of events from a sample
196 //
197 MFEventSelector2 selector(fReference);
198 selector.SetNumMax(fNumDestEvents1+fNumDestEvents2);
199 selector.SetInverted();
200
201 //
202 // Continue for all events which are not (SetInverted())
203 // selected by the 'selector'
204 //
205 MContinue cont(&selector);
206
207 //
208 // Create a filter doing a random split
209 //
210 const Double_t prob = (Double_t)fNumDestEvents1/(fNumDestEvents1+fNumDestEvents2);
211 MFRandomSplit split(prob);
212
213 //
214 // Create the logical inverted filter for 'split'
215 //
216 MFilterList invsplit;
217 invsplit.AddToList(&split);
218 invsplit.SetInverted();
219
220 //
221 // The two tasks filling the two matrices
222 //
223 MFillH fill1(fDestMatrix1);
224 MFillH fill2(fDestMatrix2);
225 fill1.SetFilter(&split);
226 fill2.SetFilter(&invsplit);
227
228 // entries in MTaskList
229 tlist.AddToList(fReader); // Read events
230 tlist.AddToList(&cont); // select a sample of events
231 tlist.AddToList(&invsplit); // process invsplit (which implicitly processes split)
232 if (fDestMatrix1 && fNumDestEvents1>0)
233 tlist.AddToList(&fill1); // fill matrix 1
234 if (fDestMatrix2 && fNumDestEvents2>0)
235 tlist.AddToList(&fill2); // fill matrix 2
236 if (fWriteFile1)
237 {
238 fWriteFile1->SetFilter(&split);
239 tlist.AddToList(fWriteFile1);
240 }
241 if (fWriteFile2)
242 {
243 fWriteFile2->SetFilter(&invsplit);
244 tlist.AddToList(fWriteFile2);
245 }
246
247 //
248 // Execute the eventloop
249 //
250 MEvtLoop evtloop(fName);
251 evtloop.SetParList(&plist);
252 evtloop.SetDisplay(fDisplay);
253 evtloop.SetLogStream(fLog);
254 if (!evtloop.Eventloop())
255 {
256 *fLog << err << GetDescriptor() << ": Failed." << endl;
257 return kFALSE;
258 }
259
260 // Print execution statistics of the tasklist
261 tlist.PrintStatistics();
262
263 // Check the result of filling...
264 CheckResult(fDestMatrix1, fNumDestEvents1);
265 CheckResult(fDestMatrix2, fNumDestEvents2);
266
267 *fLog << inf << GetDescriptor() << ": Done." << endl;
268 return kTRUE;
269}
270
271// --------------------------------------------------------------------------
272//
273// Write both matrices to a file. Return kFALSE if writing one of them
274// failed or both have the same name.
275//
276Bool_t MTFillMatrix::WriteMatrices(const TString &fname) const
277{
278 if (fDestMatrix1 && fDestMatrix2 &&
279 (TString)fDestMatrix1->GetName()==(TString)fDestMatrix2->GetName())
280 {
281 *fLog << "ERROR - Cannot write matrices (both have the same name)... ignored." << endl;
282 return kFALSE;
283 }
284
285 return WriteMatrix1(fname) && WriteMatrix2(fname);
286}
Note: See TracBrowser for help on using the repository browser.