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

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