Hall A ROOT/C++ Analyzer (podd)
Loading...
Searching...
No Matches
THaAnalysisObject.cxx
Go to the documentation of this file.
1//*-- Author : Ole Hansen 15-Jun-01
2
4//
5// THaAnalysisObject
6//
7// Abstract base class for a detector or subdetector.
8//
9// Derived classes must define all internal variables, a constructor
10// that registers any internal variables of interest in the global
11// physics variable list, and a Decode() method that fills the variables
12// based on the information in the THaEvData structure.
13//
15
16#include "THaAnalysisObject.h"
17#include "THaVarList.h"
18#include "THaGlobals.h"
19#include "TClass.h"
20#include "TDatime.h"
21#include "TROOT.h"
22#include "TMath.h"
23#include "TError.h"
24#include "TVector3.h"
25#include "TSystem.h"
26#include "TString.h"
27
28#include <cstring>
29#include <iostream>
30#include <sstream>
31#include <cstdio>
32#include <string>
33#include <exception>
34#include <cassert>
35#include <iomanip>
36#include <type_traits>
37#include <limits>
38
39using namespace std;
40using namespace Podd;
41
43
44//_____________________________________________________________________________
46 const char* description ) :
47 TNamed(name,description), fPrefix(nullptr), fStatus(kNotinit),
48 fDebug(0), fIsInit(false), fIsSetup(false), fProperties(0),
49 fOKOut(false), fInitDate(19950101,0), fNEventsWithWarnings(0),
50 fExtra(nullptr)
51{
52 // Constructor
53
54 if( !fgModules ) fgModules = new TList;
55 fgModules->Add( this );
56}
57
58//_____________________________________________________________________________
60 : fPrefix(nullptr), fStatus(kNotinit), fDebug(0), fIsInit(false),
61 fIsSetup(false), fProperties(), fOKOut(false), fNEventsWithWarnings(0),
62 fExtra(nullptr)
63{
64 // only for ROOT I/O
65}
66
67//_____________________________________________________________________________
69{
70 // Destructor
71
73
74 delete fExtra; fExtra = nullptr;
75
76 if (fgModules) {
77 fgModules->Remove( this );
78 if( fgModules->GetSize() == 0 ) {
79 delete fgModules;
80 fgModules = nullptr;
81 }
82 }
83 delete [] fPrefix; fPrefix = nullptr;
84}
85
86//_____________________________________________________________________________
88{
89 // Method called right before the start of the event loop
90 // for 'run'. Begin() is similar to Init(), but since there is a default
91 // Init() implementing standard database and global variable setup,
92 // Begin() can be used to implement start-of-run setup tasks for each
93 // module cleanly without interfering with the standard Init() procedure.
94 //
95 // The default Begin() method clears the history of warning messages
96 // and warning message event counter
97
98 fMessages.clear();
100
101 return 0;
102}
103
104//_____________________________________________________________________________
106{
107 // Method called right after the end of the event loop for 'run'.
108 // May be used by modules to clean up, compute averages, write summaries, etc.
109 //
110 // The default End() method prints warning message summary
111
112 if( !fMessages.empty() ) {
113 ULong64_t ntot = 0;
114 for(const auto& fMessage : fMessages) {
115 ntot += fMessage.second;
116 }
117 ostringstream msg;
118 msg << endl
119 << " Encountered " << fNEventsWithWarnings << " events with "
120 << "warnings, " << ntot << " total warnings"
121 << endl
122 << R"/( Call Print("WARN") for channel list. )/"
123 << "Re-run with fDebug>0 for per-event details.";
124 Warning( Here("End"), "%s", msg.str().c_str() );
125 }
126 return 0;
127}
128
129//_____________________________________________________________________________
131{
132 // Wrapper for calling this object's virtual DefineVariables method.
133 // It takes care of setting/unsetting the guard variable fIsSetup which
134 // prevents multiple attempts to define variables.
135
136 if( mode == kDefine && fIsSetup )
137 // Exit if already set up.
138 // Multiple attempts to remove variables are OK: If this detector's
139 // variables have already been removed, nothing will be done.
140 // This test can be present in DefineVariables as well, but does not
141 // have to be. However, unlike in analyzer versions before 1.7,
142 // DefineVariables methods should NOT set or clear fIsSetup themselves.
143 return kOK;
144
146 if( ret )
147 // If setting or removing failed, allow retry. Currently, this would only
148 // happen if no global variable list was defined.
149 // Inability to define individual variables simply triggers warnings.
150 // TODO: Have this behave differently? Failing variable definitions can
151 // TODO: be hard to spot and so may waste quite a bit of time ...
152 // Inability to find variables for removal will not even be reported since
153 // it has no practical effect.
154 return ret;
155
156 fIsSetup = (mode == kDefine);
157
158 return ret;
159}
160
161//_____________________________________________________________________________
163{
164 // Default method for defining global variables. Currently does nothing.
165 // If there should be any common variables for all analysis objects,
166 // define them here.
167
168 return kOK;
169}
170
171//_____________________________________________________________________________
173 const char* def_prefix,
174 const char* comment_subst ) const
175{
176 return DefineVarsFromList(list, kVarDef, mode, def_prefix, comment_subst);
177}
178
179//_____________________________________________________________________________
181 const char* def_prefix,
182 const char* comment_subst ) const
183{
184 return DefineVarsFromList(list, kRVarDef, mode, def_prefix, comment_subst);
185}
186
187//_____________________________________________________________________________
189 EMode mode, const char* def_prefix,
190 const char* comment_subst ) const
191{
192 // Add/delete variables defined in 'list' to/from the list of global
193 // variables, using prefix of the current apparatus.
194 // Internal function that can be called during initialization.
195
197 here.Append("::DefineVarsFromList");
198 return DefineVarsFromList(list, type, mode, def_prefix, this,
199 fPrefix, here.Data(), comment_subst);
200}
201
202//_____________________________________________________________________________
204 EType type, EMode mode,
205 const char* def_prefix,
206 const TObject* obj,
207 const char* prefix,
208 const char* here,
209 const char* comment_subst )
210{
211 // Actual implementation of the variable definition utility function.
212 // Static function that can be used by classes other than THaAnalysisObjects
213
214 if( !gHaVars ) {
215 TString action;
216 if( mode == kDefine )
217 action = "defined";
218 else if( mode == kDelete )
219 action = "deleted (this is safe when exiting)";
220 ::Warning( ::Here(here,prefix), "No global variable list found. "
221 "No variables %s.", action.Data() );
222 return (mode==kDefine ? kInitError : kOK);
223 }
224
225 if( mode == kDefine ) {
226 if( type == kVarDef )
227 gHaVars->DefineVariables( static_cast<const VarDef*>(list),
228 prefix, ::Here(here,prefix) );
229 else if( type == kRVarDef )
230 gHaVars->DefineVariables(static_cast<const RVarDef*>(list), obj,
231 prefix, ::Here(here, prefix), def_prefix,
232 comment_subst);
233 }
234 else if( mode == kDelete ) {
235 if( type == kVarDef ) {
236 const auto *item = static_cast<const VarDef*>(list);
237 while( item && item->name ) {
238 TString name(prefix);
239 name.Append( item->name );
241 ++item;
242 }
243 } else if( type == kRVarDef ) {
244 const auto *item = static_cast<const RVarDef*>(list);
245 while( item && item->name ) {
246 TString name(prefix);
247 name.Append( item->name );
249 ++item;
250 }
251 }
252 }
253
254 return kOK;
255}
256
257//_____________________________________________________________________________
259 const char* classname,
260 bool do_error )
261{
262 // Locate the object 'name' in the global list of Analysis Modules
263 // and check if it inherits from 'classname' (if given), and whether
264 // it is properly initialized.
265 // Return pointer to valid object, else return nullptr.
266 // If do_error == true (default), also print error message and set fStatus
267 // to kInitError.
268 // If do_error == false, don't print error messages and not test if object is
269 // initialized.
270 //
271 // This function is intended to be called from physics module initialization
272 // routines.
273
274 static const char* const here = "FindModule";
275 static const char* const anaobj = "THaAnalysisObject";
276
277 if( !name || !*name ) {
278 if( do_error )
279 Error( Here(here), "No module name given." );
281 return nullptr;
282 }
283
284 // Find the module in the list, comparing 'name' to the module's fPrefix
285 TIter next(fgModules);
286 TObject* obj = nullptr;
287 while( (obj = next()) ) {
288#ifdef NDEBUG
289 auto* module = static_cast<THaAnalysisObject*>(obj);
290#else
291 auto* module = dynamic_cast<THaAnalysisObject*>(obj);
292 assert(module);
293#endif
294 TString prefix = module->GetPrefixName();
295 if( prefix.IsNull() ) {
296 module->MakePrefix();
297 prefix = module->GetPrefixName();
298 if( prefix.IsNull() )
299 continue;
300 }
301 if( prefix == name )
302 break;
303 }
304 if( !obj ) {
305 if( do_error )
306 Error( Here(here), "Module %s does not exist.", name );
308 return nullptr;
309 }
310
311 // Type check (similar to dynamic_cast, except resolving the class name as
312 // a string at run time
313 if( !obj->IsA()->InheritsFrom( anaobj )) {
314 if( do_error )
315 Error( Here(here), "Module %s (%s) is not a %s.",
316 obj->GetName(), obj->GetTitle(), anaobj );
318 return nullptr;
319 }
320 if( classname && *classname && strcmp(classname,anaobj) != 0 &&
321 !obj->IsA()->InheritsFrom( classname )) {
322 if( do_error )
323 Error( Here(here), "Module %s (%s) is not a %s.",
324 obj->GetName(), obj->GetTitle(), classname );
326 return nullptr;
327 }
328 auto* aobj = static_cast<THaAnalysisObject*>( obj );
329 if( do_error ) {
330 if( !aobj->IsOK() ) {
331 Error( Here(here), "Module %s (%s) not initialized.",
332 obj->GetName(), obj->GetTitle() );
334 return nullptr;
335 }
336 }
337 return aobj;
338}
339
340//_____________________________________________________________________________
342{
343 return GetPrefix();
344}
345
346//_____________________________________________________________________________
348{
349 const char* classname = "UnknownClass";
350 if( TROOT::Initialized() )
351 classname = ClassName();
352 return classname;
353}
354
355//_____________________________________________________________________________
356void THaAnalysisObject::DoError( int level, const char* here,
357 const char* fmt, va_list va) const
358{
359 // Interface to ErrorHandler. Inserts this object's name after the class name.
360 // If 'here' = ("prefix")::method -> print <Class("prefix")::method>
361 // If 'here' = method -> print <Class::method>
362
363 TString location(here);
364 if( !location.BeginsWith("(\"") )
365 location.Prepend("::");
366
367 location.Prepend(GetClassName());
368
369 ::ErrorHandler(level, location.Data(), fmt, va);
370}
371
372//_____________________________________________________________________________
373const char* THaAnalysisObject::Here( const char* here ) const
374{
375 // Return a string consisting of ("fPrefix")::here
376 // Used for generating diagnostic messages.
377 // The return value points to an internal static buffer that
378 // one should not try to delete ;)
379
380 return ::Here( here, fPrefix );
381}
382
383//_____________________________________________________________________________
384const char* THaAnalysisObject::ClassNameHere( const char* here ) const
385{
386 // Return a string consisting of Class("fPrefix")::here
387
388 TString method(here);
389 if( method.Index("::") == kNPOS ) {
390 method.Prepend("::");
391 method.Prepend(GetClassName());
392 }
393 return ::Here( method.Data(), fPrefix );
394}
395
396//_____________________________________________________________________________
398{
399 // Initialize this object for current time. See Init(date) below.
400
401 return Init( TDatime() );
402}
403
404//_____________________________________________________________________________
405class database_error : public std::runtime_error {
406public:
407 explicit database_error( Int_t st, const char* fnam )
408 : std::runtime_error("Error reading database"),
409 status(st), filename(fnam) {}
411 const char* filename;
412};
413
414//_____________________________________________________________________________
416{
417 // Common Init function for THaAnalysisObjects.
418 //
419 // Check if this object or any base classes have defined a custom
420 // ReadDatabase() method. If so, open the database file called
421 // "db_<fPrefix>dat" and, if successful, call ReadDatabase().
422 //
423 // This implementation will change once the real database is available.
424
425 static const char* const here = "Init";
426
427 if( IsZombie() )
428 return fStatus = kNotinit;
429
430 // Generate the name prefix for global variables. Do this here, not in
431 // the constructor, so we can use a virtual function - detectors and
432 // especially subdetectors may have their own idea what prefix they like.
433 MakePrefix();
434
435 // Skip reinitialization if there is no (relevant) date change.
436 if( DBDatesDiffer(date, fInitDate) ) {
437 try {
438 // Open the run database and call the reader. If database cannot be opened,
439 // fail only if this object needs the run database
440 // Call this object's actual database reader
441 Int_t status = ReadRunDatabase(date);
442 if( status && (status != kFileError || (fProperties & kNeedsRunDB) != 0) ) {
443 throw database_error(status, "run.");
444 }
445
446 // Read the database for this object.
447 // Don't bother if this object has not implemented its own database reader.
448 if( IsA()->GetMethodAllAny("ReadDatabase") !=
449 gROOT->GetClass("THaAnalysisObject")->GetMethodAllAny("ReadDatabase") ) {
450
451 // Call this object's actual database reader
452 if( (status = ReadDatabase(date)) )
453 throw database_error(status, GetDBFileName());
454
455 } else if( fDebug > 2 ) {
456 Info(Here(here), "No ReadDatabase function defined. "
457 "Database not read.");
458 }
459 }
460
461 catch( const database_error& e ) {
462 if( e.status == kFileError )
463 Error(Here(here), "Cannot open database file db_%sdat", e.filename);
464 else
465 Error(Here(here), "Error while reading file db_%sdat", e.filename);
466 return fStatus = static_cast<EStatus>(e.status);
467 }
468 catch( const std::bad_alloc& ) {
469 Error(Here(here), "Out of memory in ReadDatabase.");
470 return fStatus = kInitError;
471 }
472 catch( const std::exception& e ) {
473 Error(Here(here), "Exception \"%s\" caught in ReadDatabase. "
474 "Module not initialized. Check database or call expert.",
475 e.what());
476 return fStatus = kInitError;
477 }
478 } else if( fDebug > 1 ) {
479 Info(Here(here), "Not re-reading database for same date.");
480 }
481
482 // Save the last successful initialization date. This is used to prevent
483 // unnecessary reinitialization.
484 fInitDate = date;
485
486 // Define this object's variables.
488
489 // Clear() the object. The "I" option indicates that the call comes from
490 // Init(), which can be used to perform or skip certain steps, as needed.
491 Clear("I");
492
493 return fStatus;
494}
495
496//_____________________________________________________________________________
498{
499 // This method is called from THaAnalyzer::DoInit,
500 // after THaOutput is initialized.
501 // The TTree to work with can be retrieved like:
502 // TTree *tree = output->GetTree()
503 //
504 // tree is the TTree to append the branches to
505 //
506 // construct all branches here. Set kOKOut=true if
507 // all is okay, and return 0
508 //
509 // anything else will trigger error messages.
510 fOKOut = true;
511 return kOK;
512}
513
514//_____________________________________________________________________________
515void THaAnalysisObject::MakePrefix( const char* basename )
516{
517 // Set up name prefix for global variables.
518 // Internal function called by constructors of derived classes.
519 // If basename != nullptr,
520 // fPrefix = basename + "." + GetName() + ".",
521 // else
522 // fPrefix = GetName() + "."
523
524 delete [] fPrefix;
525 if( basename && *basename ) {
526 fPrefix = new char[ strlen(basename) + strlen(GetName()) + 3 ];
527 strcpy( fPrefix, basename );
528 strcat( fPrefix, "." );
529 } else {
530 fPrefix = new char[ strlen(GetName()) + 2 ];
531 *fPrefix = 0;
532 }
533 strcat( fPrefix, GetName() );
534 strcat( fPrefix, "." );
535}
536
537//_____________________________________________________________________________
539{
540 // Make default prefix: GetName() + "."
541
542 MakePrefix(nullptr);
543}
544
545//_____________________________________________________________________________
547{
548 // Default database reader. Currently does nothing.
549
550 return kOK;
551}
552
553//_____________________________________________________________________________
555{
556 // Default run database reader. Reads one key, <prefix>.config, into
557 // fConfig. If not found, fConfig is empty. If fConfig was explicitly
558 // set with SetConfig(), the run database is not parsed and fConfig is
559 // not touched.
560
561 if( !fPrefix ) return kInitError;
562
563 if( (fProperties & kConfigOverride) == 0) {
564 FILE* file = OpenRunDBFile( date );
565 if( !file ) return kFileError;
566
567 TString name(fPrefix); name.Append("config");
568 Int_t ret = Podd::LoadDBvalue(file, date, name, fConfig );
569 fclose(file);
570
571 if( ret == -1 ) return kFileError;
572 if( ret < 0 ) return kInitError;
573 if( ret == 1 ) fConfig = "";
574 }
575 return kOK;
576}
577
578//_____________________________________________________________________________
580{
581 // Remove global variables of this object.
582 // Should be called form the destructor of every class that defines any
583 // global variables via the standard DefineVariables mechanism.
584
585 if( fIsSetup )
587 return kOK;
588}
589
590//_____________________________________________________________________________
591void THaAnalysisObject::SetName( const char* name )
592{
593 // Set/change the name of the object.
594
595 if( !name || !*name ) {
596 Warning( Here("SetName()"),
597 "Cannot set an empty object name. Name not set.");
598 return;
599 }
601 MakePrefix();
602}
603
604//_____________________________________________________________________________
605void THaAnalysisObject::SetNameTitle( const char* name, const char* title )
606{
607 // Set name and title of the object.
608
609 SetName( name );
610 SetTitle( title );
611}
612
613//_____________________________________________________________________________
614void THaAnalysisObject::SetConfig( const char* label )
615{
616 // Set the "configuration" to select in the database.
617 // In text-based database files, this will make the database reader
618 // seek to a section header [ config=label ] if the module supports it.
619
620 fConfig = label;
621 if( fConfig.IsNull() )
622 fProperties &= ~kConfigOverride;
623 else
625}
626
627//_____________________________________________________________________________
629{
630 // Set debug level
631
632 fDebug = level;
633}
634
635//---------- Geometry functions -----------------------------------------------
636//_____________________________________________________________________________
638 const TVector3& yax,
639 const TVector3& org,
640 const TVector3& ray_start,
641 const TVector3& ray_vect,
642 Double_t& length,
643 TVector3& intersect )
644{
645 // Find intersection point of plane (given by 'xax', 'yax', 'org') with
646 // ray (given by 'ray_start', 'ray_vect').
647 // Returns true if intersection found, else false (ray parallel to plane).
648 // Output is in 'length' and 'intersect', where
649 // intersect = ray_start + length*ray_vect
650 // 'length' and 'intersect' must be provided by the caller.
651
652 // Calculate explicitly for speed.
653
654 Double_t nom[9], den[9];
655 nom[0] = den[0] = xax.X();
656 nom[3] = den[3] = xax.Y();
657 nom[6] = den[6] = xax.Z();
658 nom[1] = den[1] = yax.X();
659 nom[4] = den[4] = yax.Y();
660 nom[7] = den[7] = yax.Z();
661 den[2] = -ray_vect.X();
662 den[5] = -ray_vect.Y();
663 den[8] = -ray_vect.Z();
664
665 Double_t det1 = den[0]*(den[4]*den[8]-den[7]*den[5])
666 -den[3]*(den[1]*den[8]-den[7]*den[2])
667 +den[6]*(den[1]*den[5]-den[4]*den[2]);
668 if( fabs(det1) < 1e-5 )
669 return false;
670
671 nom[2] = ray_start.X()-org.X();
672 nom[5] = ray_start.Y()-org.Y();
673 nom[8] = ray_start.Z()-org.Z();
674 Double_t det2 = nom[0]*(nom[4]*nom[8]-nom[7]*nom[5])
675 -nom[3]*(nom[1]*nom[8]-nom[7]*nom[2])
676 +nom[6]*(nom[1]*nom[5]-nom[4]*nom[2]);
677
678 length = det2/det1;
679 intersect = ray_start + length*ray_vect;
680 return true;
681}
682
683//_____________________________________________________________________________
685 Double_t& th_sph, Double_t& ph_sph )
686{
687 // Convert geographical to spherical angles. Units are rad.
688 // th_geo and ph_geo can be anything.
689 // th_sph is in [0,pi], ph_sph in [-pi,pi].
690
691 static const Double_t twopi = 2.0*TMath::Pi();
692 Double_t ct = cos(th_geo), cp = cos(ph_geo);
693 Double_t tmp = ct*cp;
694 th_sph = acos( tmp );
695 tmp = sqrt(1.0 - tmp*tmp);
696 ph_sph = (fabs(tmp) < 1e-6 ) ? 0.0 : acos( sqrt(1.0-ct*ct)*cp/tmp );
697 if( th_geo/twopi-floor(th_geo/twopi) > 0.5 ) ph_sph = TMath::Pi() - ph_sph;
698 if( ph_geo/twopi-floor(ph_geo/twopi) > 0.5 ) ph_sph = -ph_sph;
699}
700
701//_____________________________________________________________________________
703 Double_t& th_geo, Double_t& ph_geo )
704{
705 // Convert spherical to geographical angles. Units are rad.
706 // th_sph and ph_sph can be anything, although th_sph outside
707 // [0,pi] is not really meaningful.
708 // th_geo is in [-pi,pi] and ph_sph in [-pi/2,pi/2]
709
710 static const Double_t twopi = 2.0*TMath::Pi();
711 Double_t ct = cos(th_sph), st = sin(th_sph), cp = cos(ph_sph);
712 if( fabs(ct) > 1e-6 ) {
713 th_geo = atan( st/ct*cp );
714 if( cp>0.0 && th_geo<0.0 ) th_geo += TMath::Pi();
715 else if( cp<0.0 && th_geo>0.0 ) th_geo -= TMath::Pi();
716 } else {
717 th_geo = TMath::Pi()/2.0;
718 if( cp<0.0 ) th_geo = -th_geo;
719 }
720 ph_geo = acos( sqrt( st*st*cp*cp + ct*ct ));
721 if( ph_sph/twopi - floor(ph_sph/twopi) > 0.5 ) ph_geo = -ph_geo;
722}
723
724//_____________________________________________________________________________
726{
727 // Default method for opening database file
728
729 return OpenDBFile(GetDBFileName(), date, ClassNameHere("OpenDBFile()"),
730 "r", fDebug);
731}
732
733//_____________________________________________________________________________
735{
736 // Default method for opening run database file
737
738 return OpenDBFile("run", date, ClassNameHere("OpenDBFile()"),
739 "r", fDebug);
740}
741
742//_____________________________________________________________________________
744 const DBRequest* req, Int_t search ) const {
745 // Member function version of LoadDB, uses current object's fPrefix and
746 // class name
747
749 here.Append("::LoadDB");
750 return LoadDB(f, date, req, GetPrefix(), search, here.Data());
751}
752
753#ifdef WITH_DEBUG
754//_____________________________________________________________________________
755void THaAnalysisObject::DebugPrint( const DBRequest* list ) const
756{
757 // Print values of database parameters given in 'list'
758
759 if( !list )
760 return;
761 cout << GetPrefixName() << " database parameters: " << endl;
762 size_t maxw = 1;
763 ios_base::fmtflags fmt = cout.flags();
764 for( const auto *it = list; it->name; ++it )
765 maxw = TMath::Max(maxw,strlen(it->name));
766 for( const auto *it = list; it->name; ++it ) {
767 cout << " " << std::left << setw(static_cast<int>(maxw)) << it->name;
768 size_t maxc = it->nelem;
769 if( maxc == 0 ) maxc = 1;
770 if( it->type == kDoubleV )
771 maxc = ((vector<Double_t>*)it->var)->size();
772 else if( it->type == kFloatV )
773 maxc = ((vector<Float_t>*)it->var)->size();
774 else if( it->type == kIntV )
775 maxc = ((vector<Int_t>*)it->var)->size();
776 for( size_t i=0; i<maxc; ++i ) {
777 cout << " ";
778 switch( it->type ) {
779 case kDouble:
780 cout << ((Double_t*)it->var)[i];
781 break;
782 case kFloat:
783 cout << ((Float_t*)it->var)[i];
784 break;
785 case kInt:
786 cout << ((Int_t*)it->var)[i];
787 break;
788 case kIntV:
789 cout << ((vector<Int_t>*)it->var)->at(i);
790 break;
791 case kFloatV:
792 cout << ((vector<Float_t>*)it->var)->at(i);
793 break;
794 case kDoubleV:
795 cout << ((vector<Double_t>*)it->var)->at(i);
796 break;
797 default:
798 break;
799 }
800 }
801 cout << endl;
802 }
803 cout.flags(fmt); // Restore previous cout formatting
804}
805
806//_____________________________________________________________________________
807template <typename T>
808void THaAnalysisObject::WriteValue( T val, int p, int w )
809{
810 // Helper function for printing debug information
811 ios_base::fmtflags fmt = cout.flags();
812 streamsize prec = cout.precision();
813 if( std::is_floating_point<T>::value && val < kBig )
814 cout << fixed << setprecision(p) << setw(w) << val;
815 else if( std::is_integral<T>::value && val != THaVar::kInvalidInt &&
816 val != numeric_limits<T>::max() && val < 10 * static_cast<T>(w) &&
817 (std::is_unsigned<T>::value || -val < 10 * static_cast<T>(w)) )
818 cout << setw(w) << val;
819 else
820 cout << " --- ";
821 cout.flags(fmt);
822 cout.precision(prec);
823}
824
825// Explicit instantiations
826template void THaAnalysisObject::WriteValue<Double_t>( Double_t val, int p=0, int w=5 );
827template void THaAnalysisObject::WriteValue<Float_t>( Float_t val, int p=0, int w=5 );
828template void THaAnalysisObject::WriteValue<Int_t>( Int_t val, int p=0, int w=5 );
829template void THaAnalysisObject::WriteValue<UInt_t>( UInt_t val, int p=0, int w=5 );
830
831#endif
832
833//_____________________________________________________________________________
835{
836 cout << "AOBJ: " << IsA()->GetName()
837 << "\t" << GetName()
838 << "\t\"";
839 if( fPrefix )
840 cout << fPrefix;
841 cout << "\"\t" << GetTitle()
842 << endl;
843
844 // Print warning details
845 if( opt && strstr(opt,"WARN") != nullptr && !fMessages.empty() ) {
846 string name = GetPrefix();
847 string::size_type len = name.length();
848 if( len>0 && name[len-1] == '.' )
849 name.erase(len-1);
850 cout << "Module \"" << name << "\" encountered warnings:" << endl;
851 for( const auto& fMessage : fMessages ) {
852 cout << " " << fMessage.first << ": " << fMessage.second << " times" << endl;
853 }
854 }
855}
856
857//_____________________________________________________________________________
859{
860 // Print all defined analysis objects (useful for debugging)
861
862 TIter next(fgModules);
863 while( TObject* obj = next() ) {
864 obj->Print(opt);
865 }
866}
867
868//_____________________________________________________________________________
870{
871 // Get current prefix without the trailing ".", which turns out to be
872 // frequently needed task
873
874 TString prefix(GetPrefix());
875 if( prefix.EndsWith(".") )
876 prefix.Chop();
877 return prefix;
878}
879
880//_____________________________________________________________________________
int Int_t
unsigned int UInt_t
#define f(i)
#define e(i)
bool Bool_t
const Ssiz_t kNPOS
float Float_t
double Double_t
const char Option_t
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t org
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
R__EXTERN class THaVarList * gHaVars
Definition THaGlobals.h:11
static const char *const here
Definition THaVar.cxx:64
#define gROOT
Bool_t InheritsFrom(const char *cl) const override
virtual Int_t GetSize() const
virtual void SetDebug(Int_t level)
static void GeoToSph(Double_t th_geo, Double_t ph_geo, Double_t &th_sph, Double_t &ph_sph)
virtual Int_t ReadRunDatabase(const TDatime &date)
virtual void SetNameTitle(const char *name, const char *title)
virtual Int_t Begin(THaRunBase *r=nullptr)
static void SphToGeo(Double_t th_sph, Double_t ph_sph, Double_t &th_geo, Double_t &ph_geo)
static Int_t LoadDB(FILE *file, const TDatime &date, const DBRequest *request, const char *prefix, Int_t search=0, const char *here="THaAnalysisObject::LoadDB")
static Int_t DefineVarsFromList(const void *list, EType type, EMode mode, const char *def_prefix, const TObject *obj, const char *prefix, const char *here, const char *comment_subst="")
virtual Int_t InitOutput(THaOutput *)
virtual Int_t End(THaRunBase *r=nullptr)
virtual const char * Here(const char *) const
const char * GetPrefix() const
THaAnalysisObject * FindModule(const char *name, const char *classname, bool do_error=true)
virtual Int_t ReadDatabase(const TDatime &date)
std::map< std::string, UInt_t > fMessages
virtual const char * ClassNameHere(const char *) const
virtual void MakePrefix()
TString GetPrefixName() const
static Bool_t IntersectPlaneWithRay(const TVector3 &xax, const TVector3 &yax, const TVector3 &org, const TVector3 &ray_start, const TVector3 &ray_vect, Double_t &length, TVector3 &intersect)
void SetConfig(const char *label)
virtual FILE * OpenRunDBFile(const TDatime &date)
const char * GetClassName() const
virtual Int_t DefineVariables(EMode mode=kDefine)
virtual void DoError(int level, const char *location, const char *fmt, va_list va) const
static TList * fgModules
virtual FILE * OpenFile(const TDatime &date)
static void PrintObjects(Option_t *opt="")
virtual void Clear(Option_t *="")
virtual const char * GetDBFileName() const
Int_t DefineVariablesWrapper(EMode mode=kDefine)
virtual void SetName(const char *name)
virtual void Print(Option_t *opt="") const
virtual Int_t RemoveName(const char *name)
virtual Int_t DefineVariables(const VarDef *list, const char *prefix="", const char *caller="")
static const Long64_t kInvalidInt
Definition THaVar.h:23
void Add(TObject *obj) override
TObject * Remove(const TObjLinkPtr_t &lnk)
virtual void SetTitle(const char *title="")
const char * GetName() const override
const char * GetTitle() const override
virtual void SetName(const char *name)
TClass * IsA() const override
virtual const char * GetName() const
virtual const char * ClassName() const
virtual void Warning(const char *method, const char *msgfmt,...) const
R__ALWAYS_INLINE Bool_t IsZombie() const
virtual void Error(const char *method, const char *msgfmt,...) const
virtual const char * GetTitle() const
virtual TClass * IsA() const
virtual void Info(const char *method, const char *msgfmt,...) const
static Bool_t Initialized()
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
const char * Data() const
TString & Chop()
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Bool_t IsNull() const
TString & Prepend(char c, Ssiz_t rep=1)
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Double_t Z() const
Double_t Y() const
Double_t X() const
database_error(Int_t st, const char *fnam)
unsigned long long ULong64_t
RVec< PromoteType< T > > cos(const RVec< T > &v)
RVec< PromoteType< T > > floor(const RVec< T > &v)
RVec< PromoteType< T > > acos(const RVec< T > &v)
RVec< PromoteType< T > > atan(const RVec< T > &v)
RVec< PromoteType< T > > sin(const RVec< T > &v)
double T(double x)
Expr< UnaryOp< Sqrt< T >, Expr< A, T, D, D2, R >, T >, T, D, D2, R > sqrt(const Expr< A, T, D, D2, R > &rhs)
Expr< UnaryOp< Fabs< T >, Expr< A, T, D, D2, R >, T >, T, D, D2, R > fabs(const Expr< A, T, D, D2, R > &rhs)
constexpr Double_t Pi()
Double_t Max(Double_t a, Double_t b)
STL namespace.
ClassImp(TPyArg)