source: trunk/MagicSoft/Mars/mhist/MFillH.cc@ 1788

Last change on this file since 1788 was 1715, checked in by tbretz, 22 years ago
*** empty log message ***
File size: 15.9 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 07/2001 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2002
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26// //
27// MFillH //
28// //
29// This is a common interface (task) to fill mars histograms. Every mars //
30// histogram which is derived from MH can be filled with this task. //
31// //
32// There are two options to use: //
33// //
34// 1) You specifiy the parameter container with which data the //
35// histogram container should be filled, and the histogram container //
36// which has to be filled. This can be done by either specifing the //
37// name of the objects in the parameter list or by specifiing a pointer //
38// to the object. (s. Constructor) // //
39// //
40// 2) You specify the name and/or type of the histogram to become filled. //
41// Any other action imust be taken by the histogram class. //
42// //
43// PreProcess: In the preprocessing of this task we setup all pointers //
44// to instances which are needed and call FillSetup of the //
45// histogram class with the parameter list as an argument. //
46// //
47// Process: The process function calls the Fill member function of the //
48// histogram class instance (inheriting from MH) with either //
49// a NULL pointer or a pointer to the corresponding container //
50// as an argument. //
51// //
52// WARNING: //
53// Because MFillH is a generalized task to fill histograms it doesn't //
54// know about which branches from a file are necessary to fill the //
55// histograms. If you are reading data from a file which is directly //
56// filled into a histogram via MFillH, please call either //
57// MReadTree::DisableAutoScheme() or enable the necessary branches by //
58// yourself, using MReadTree::EnableBranch() //
59// //
60// Checkout the Warning in MTaskList. //
61// //
62// Input Containers: //
63// A parameter container //
64// //
65// Output Containers: //
66// A histogram container //
67// //
68//////////////////////////////////////////////////////////////////////////////
69#include "MFillH.h"
70
71#include <fstream.h>
72
73#include <TClass.h>
74
75#include "MDataChain.h"
76
77#include "MLog.h"
78#include "MLogManip.h"
79
80#include "MH.h"
81#include "MHArray.h"
82
83#include "MParList.h"
84
85ClassImp(MFillH);
86
87// --------------------------------------------------------------------------
88//
89// Initializes name and title of the object. It is called by all
90// constructors.
91//
92void MFillH::Init(const char *name, const char *title)
93{
94 fName = name ? name : "MFillH";
95 fTitle = title ? title : "Task to fill Mars histograms";
96
97 fH = NULL;
98 fParContainer = NULL;
99
100 fIndex = NULL;
101}
102
103// --------------------------------------------------------------------------
104//
105// Default Constructor. This is to support some root-stuff.
106// Never try to use it yourself!
107//
108MFillH::MFillH()
109{
110 Init(NULL, NULL);
111}
112
113// --------------------------------------------------------------------------
114//
115// Constructor.
116//
117// 1) - par is the name of the parameter container which should be filled into
118// the histogram
119// - hist is the name of the histogram container (which must have been
120// derived from MH)
121//
122// In this case MH::Fill is called with a pointer to the corresponding
123// histogram instance.
124//
125// 2) - hist is the name and/or type of the histogram.
126// 1) The name and type is identical, eg: "MHHillas"
127// 2) They are not identical, eg: "MyHistogram [MHHillas]"
128// This searches for a class instance of MHHillas with the name
129// "MyHistogram". If it doesn't exist one is created.
130//
131// In this case PreProcess calls MH::SetupFill with a pointer to the
132// parameter list and MH::Fill is called with a NULL-pointer.
133//
134MFillH::MFillH(const char *hist, const char *par, const char *name, const char *title)
135{
136 Init(name, title);
137
138 fHName = hist;
139 fParContainerName = par;
140
141 if (title)
142 return;
143
144 fTitle = "Fill " + fHName;
145 if (!par)
146 return;
147
148 fTitle += " from " + fParContainerName;
149}
150
151// --------------------------------------------------------------------------
152//
153// Constructor.
154//
155// 1) - par is a pointer to the instance of your parameter container from which
156// the data should be used to fill the histogram.
157// - hist is the name of the histogram container (which must have been
158// derived from MH)
159//
160// In this case MH::Fill is called with a pointer to the corresponding
161// histogram instance.
162//
163// 2) - hist is the name and/or type of the histogram.
164// 1) The name and type is identical, eg: "MHHillas"
165// 2) They are not identical, eg: "MyHistogram [MHHillas]"
166// This searches for a class instance of MHHillas with the name
167// "MyHistogram". If it doesn't exist one is created. Everything
168// which is between the first '[' and the last ']' in the string
169// is used as the histogram type.
170//
171// In this case PreProcess calls MH::SetupFill with a pointer to the
172// parameter list and MH::Fill is called with a NULL-pointer.
173//
174//
175MFillH::MFillH(const char *hist, MParContainer *par, const char *name, const char *title)
176{
177 Init(name, title);
178
179 fHName = hist;
180 fParContainer = par;
181 fParContainerName = par->GetName();
182
183 if (!title)
184 fTitle = "Fill " + fHName + " from " + par->GetDescriptor();
185}
186
187// --------------------------------------------------------------------------
188//
189// Constructor.
190//
191// - par is a pointer to the instance of your parameter container from which
192// the data should be used to fill the histogram.
193// - hist is a pointer to the instance of your histogram container (which must
194// have been derived from MH) into which the data should flow
195//
196MFillH::MFillH(MH *hist, const char *par, const char *name, const char *title)
197{
198 Init(name, title);
199
200 fH = hist;
201 fHName = hist->GetName();
202 fParContainerName = par;
203
204 AddToBranchList(fH->GetDataMember());
205
206 if (title)
207 return;
208
209 fTitle = (TString)"Fill " + hist->GetDescriptor();
210 if (!par)
211 return;
212
213 fTitle += " from " + fParContainerName;
214}
215
216// --------------------------------------------------------------------------
217//
218// Constructor.
219//
220// - par is a pointer to the instance of your parameter container from which
221// the data should be used to fill the histogram.
222// - hist is the name of the histogram container (which must have been
223// derived from MH)
224//
225MFillH::MFillH(MH *hist, MParContainer *par, const char *name, const char *title)
226{
227 Init(name, title);
228
229 fH = hist;
230 fHName = hist->GetName();
231 fParContainer = par;
232 fParContainerName = par->GetName();
233
234 AddToBranchList(fH->GetDataMember());
235
236 if (!title)
237 fTitle = (TString)"Fill " + hist->GetDescriptor() + " from " + par->GetDescriptor();
238}
239
240// --------------------------------------------------------------------------
241//
242// Destructor. Delete fData if existing and kCanDelete is set.
243//
244MFillH::~MFillH()
245{
246 if (fIndex)
247 if (fIndex->TestBit(kCanDelete))
248 delete fIndex;
249}
250
251// --------------------------------------------------------------------------
252//
253// If the histogram to be filles is a MHArray you can specify a 'rule'
254// This rule is used to create an MDataChain. The return value of the chain
255// is casted to int. Each int acts as a key. For each (new) key a new
256// histogram is created in the array. (eg for the rule
257// "MRawEvtHeader::fRunNumber" you would get one histogram per run-number)
258//
259void MFillH::SetRuleForIdx(const TString rule)
260{
261 fIndex = new MDataChain(rule);
262 fIndex->SetBit(kCanDelete);
263}
264
265// --------------------------------------------------------------------------
266//
267// If the histogram to be filles is a MHArray you can specify a MData-object
268// The return value of the object is casted to int. Each int acts as a key.
269// For each (new) key a new histogram is created in the array. (eg for
270// MDataMember("MRawEvtHeader::fRunNumber") you would get one histogram per
271// run-number)
272//
273void MFillH::SetRuleForIdx(MData *data)
274{
275 fIndex = data;
276}
277
278// --------------------------------------------------------------------------
279//
280// Extracts the name of the histogram from the MFillH argument
281//
282TString MFillH::ExtractName(const char *name) const
283{
284 TString type = name;
285
286 const Ssiz_t first = type.First('[');
287 const Ssiz_t last = type.First(']');
288
289 if (!first || !last || first>=last)
290 return type;
291
292 return type.Remove(first).Strip(TString::kBoth);
293}
294
295// --------------------------------------------------------------------------
296//
297// Extracts the class-name of the histogram from the MFillH argument
298//
299TString MFillH::ExtractClass(const char *name) const
300{
301 TString type = name;
302
303 const Ssiz_t first = type.First('[');
304 const Ssiz_t last = type.First(']');
305
306 if (!first || !last || first>=last)
307 return type;
308
309 const Ssiz_t length = last-first-1;
310
311 TString strip = fHName(first+1, length);
312 return strip.Strip(TString::kBoth);
313}
314
315// --------------------------------------------------------------------------
316//
317// Checks the parameter list for the existance of the parameter container. If
318// the name of it was given in the constructor. It checks also for the
319// existance of the histogram container in the parameter list if a name was
320// given. If it is not available it tried to create a histogram container
321// with the same type as the given object name.
322//
323Bool_t MFillH::PreProcess(MParList *pList)
324{
325 if (fIndex)
326 {
327 if (!fIndex->PreProcess(pList))
328 {
329 *fLog << all << "PreProcessing of Index rule failed... aborting." << endl;
330 return kFALSE;
331 }
332
333 if (!fIndex->IsValid())
334 {
335 *fLog << all << "Given Index rule invalid... aborting." << endl;
336 return kFALSE;
337 }
338 }
339
340 //
341 // Try to get the histogram container with name fHName from list
342 // or create one with this name
343 //
344 if (!fH)
345 {
346 const TString cls = ExtractClass(fHName);
347 const TString name = ExtractName(fHName);
348
349 TObject *obj=NULL;
350 if (cls==name)
351 obj = pList->FindObject(fHName);
352
353 if (!obj)
354 {
355 if (cls==name)
356 *fLog << inf << "Object '" << fHName << "' not found in parlist... creating." << endl;
357 obj = pList->FindCreateObj(cls, name);
358 }
359
360 if (!obj)
361 return kFALSE;
362
363 //
364 // We were successfull getting it. Check whether it really inherits
365 // from MH, FindCreateObj does only check for inheritance from
366 // 'type'.
367 //
368 TClass *tcls = fIndex ? MHArray::Class() : MH::Class();
369 if (!obj->InheritsFrom(tcls))
370 {
371 *fLog << err << dbginf << obj->GetName() << " doesn't inherit ";
372 *fLog << "from " << tcls->GetName() << " - cannot be used for MFillH...";
373 *fLog << "aborting." << endl;
374 return kFALSE;
375 }
376
377 fH = (MH*)obj;
378 }
379
380 //
381 // Now we have the histogram container available. Try to Setup Fill.
382 //
383 if (!fH->SetupFill(pList))
384 {
385 *fLog << err << dbginf << "Error: calling SetupFill for ";
386 *fLog << fH->GetDescriptor() << "... aborting." << endl;
387 return kFALSE;
388 }
389
390 //
391 // If also a parameter container is already set we are done.
392 //
393 if (fParContainer)
394 return kTRUE;
395
396 //
397 // If a name is given try to find the input container in the
398 // list. If it could not be found we cannot proceed.
399 //
400 if (fParContainerName.IsNull())
401 {
402 fParContainer = NULL;
403 return kTRUE;
404 }
405
406 fParContainer = (MParContainer*)pList->FindObject(fParContainerName);
407
408 if (fParContainer)
409 return kTRUE;
410
411 *fLog << err << dbginf << "'" << fParContainerName << "' [MParContainer] not found... aborting." << endl;
412 return kFALSE;
413}
414
415// --------------------------------------------------------------------------
416//
417// Fills the data from the parameter conatiner into the histogram container
418//
419Bool_t MFillH::Process()
420{
421 if (fIndex)
422 ((MHArray*)fH)->SetIndexByKey(fIndex->GetValue());
423 /*
424 const Int_t key = (Int_t)fIndex->GetValue();
425 const Int_t idx = fMapIdx->Add(key);
426 ((MHArray*)fH)->SetIndex(idx);
427 */
428
429 return fH->Fill(fParContainer);
430}
431
432// --------------------------------------------------------------------------
433//
434// Set the ReadyToSave flag of the histogram container, because now all data
435// has been filled into the histogram.
436//
437Bool_t MFillH::PostProcess()
438{
439 //
440 // Now all data is in the histogram. Maybe some final action is
441 // necessary.
442 //
443 if (!fH->Finalize())
444 {
445 *fLog << err << dbginf << "Error: calling Finalize for ";
446 *fLog << fH->GetDescriptor() << "... aborting." << endl;
447 return kFALSE;
448 }
449
450 fH->SetReadyToSave();
451 return kTRUE;
452}
453
454// --------------------------------------------------------------------------
455//
456// Implementation of SavePrimitive. Used to write the call to a constructor
457// to a macro. In the original root implementation it is used to write
458// gui elements to a macro-file.
459//
460void MFillH::StreamPrimitive(ofstream &out) const
461{
462 if (fH)
463 fH->SavePrimitive(out);
464
465 if (fParContainer)
466 fParContainer->SavePrimitive(out);
467
468 out << " MFillH " << GetUniqueName() << "(";
469
470 if (fH)
471 out << "&" << fH->GetUniqueName();
472 else
473 out << "\"" << fHName << "\"";
474
475 if (fParContainer)
476 out << ", &" << fParContainer->GetUniqueName();
477 else
478 if (!fParContainerName.IsNull())
479 out << ", \"" << fParContainerName << "\"";
480
481 out << ");" << endl;
482
483 if (!fIndex)
484 return;
485
486 out << " " << GetUniqueName() << ".SetRuleForIdx(\"";
487 out << fIndex->GetRule() << "\");" << endl;
488}
Note: See TracBrowser for help on using the repository browser.