// $Id$ //----------------------------------------------------------------------- // The GSI Online Offline Object Oriented (Go4) Project // Experiment Data Processing at EE department, GSI //----------------------------------------------------------------------- // Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH // Planckstr. 1, 64291 Darmstadt, Germany // Contact: http://go4.gsi.de //----------------------------------------------------------------------- // This software can be used under the license agreements as stated // in Go4License.txt file which is part of the distribution. //----------------------------------------------------------------------- #include "TGo4HistogramEntry.h" #include "TH1.h" #include "TH2.h" #include "TH3.h" #include "TDataMember.h" #include "TDataType.h" #include "TROOT.h" #include "TGo4Log.h" #include "TGo4Condition.h" #include "TGo4DynamicListException.h" const char *TGo4HistogramEntry::fgcNOCONDITION = "No Condition"; const char *TGo4HistogramEntry::fgcNODATA = "No Data"; const char *TGo4HistogramEntry::fgcNOEVENT = "No Event"; TGo4HistogramEntry::TGo4HistogramEntry() : TGo4DynamicEntry(), fxHistogram(nullptr), fxCondition(nullptr), fbNeedInitialisation(kTRUE) { } TGo4HistogramEntry::TGo4HistogramEntry(const char *name) : TGo4DynamicEntry(name), fxHistogram(nullptr), fxCondition(nullptr), fbNeedInitialisation(kTRUE) { fxHistogramName = fgcNOCONDITION; for (UInt_t t = 0; t < __MAXHISDIM__; ++t) { SetHisEventName(t, fgcNOEVENT); SetHisVarName(t, fgcNODATA); } fxConditionName = fgcNOCONDITION; for (Int_t t = 0; t < __MAXCONDIM__; ++t) { SetConEventName(t, fgcNOEVENT); SetConVarName(t, fgcNODATA); } Reset(); } TGo4HistogramEntry::~TGo4HistogramEntry() { } void TGo4HistogramEntry::SetHisVarName(Int_t ix, const char *name) { if ((ix >= 0) && (ix < __MAXHISDIM__)) fxHisVarName[ix] = name; } const char *TGo4HistogramEntry::GetHistVarName(Int_t ix) const { return ((ix >= 0) && (ix < __MAXHISDIM__)) ? fxHisVarName[ix].Data() : nullptr; } void TGo4HistogramEntry::SetHisEventName(Int_t ix, const char *name) { if ((ix >= 0) && (ix < __MAXHISDIM__)) fxHisEventName[ix] = name; } const char *TGo4HistogramEntry::GetHistEventName(Int_t ix) const { return ((ix >= 0) && (ix < __MAXHISDIM__)) ? fxHisEventName[ix].Data() : nullptr; } void TGo4HistogramEntry::SetConVarName(Int_t ix, const char *name) { GO4TRACE((12,"TGo4DynamicEntry::SetConVarName(UInt_t, char*)",__LINE__, __FILE__)); if ((ix >= 0) && (ix < __MAXCONDIM__)) fxConVarName[ix] = name; } const char *TGo4HistogramEntry::GetConVarName(Int_t ix) const { return ((ix >= 0) && (ix < __MAXCONDIM__)) ? fxConVarName[ix].Data() : nullptr; } void TGo4HistogramEntry::SetConEventName(Int_t ix, const char *name) { GO4TRACE((12,"TGo4DynamicEntry::SetConEventName(UInt_t, char*)",__LINE__, __FILE__)); if ((ix >= 0) && (ix < __MAXCONDIM__)) fxConEventName[ix] = name; } const char *TGo4HistogramEntry::GetConEventName(Int_t ix) const { return ((ix >= 0) && (ix < __MAXCONDIM__)) ? fxConEventName[ix].Data() : nullptr; } void TGo4HistogramEntry::Reset() { fxHistogram = nullptr; for (Int_t t = 0; t < __MAXHISDIM__; ++t) { fxHisEvents[t] = nullptr; fxHistType[t] = 0; fxHistPtr[t] = nullptr; } fxCondition = nullptr; for (Int_t t = 0; t < __MAXCONDIM__; ++t) { fxConEvents[t] = nullptr; fxCondType[t] = 0; fxCondPtr[t] = nullptr; } fbNeedInitialisation = kTRUE; } void TGo4HistogramEntry::InitHistPointer(Int_t ix, TObject *event, TDataMember *member, Long_t offset) { if ((ix<0) || (ix>=__MAXHISDIM__)) return; fxHistPtr[ix] = nullptr; fxHisEvents[ix] = event; if (!event || !member || !member->IsBasic()) return; fxHistPtr[ix] = (char *) event + offset; fxHistType[ix] = member->GetDataType()->GetType(); } void TGo4HistogramEntry::InitCondPointer(Int_t ix, TObject *event, TDataMember *member, Long_t offset) { if ((ix<0) || (ix>=__MAXCONDIM__)) return; fxCondPtr[ix] = nullptr; fxConEvents[ix] = event; if (!event || !member || !member->IsBasic()) return; fxCondPtr[ix] = (char *) event + offset; fxCondType[ix] = member->GetDataType()->GetType(); } Double_t TGo4HistogramEntry::GetPtrValue(Int_t type, void *ptr) { if (!ptr) return 0.; switch (type) { case kUInt_t: return *((UInt_t *)ptr); case kInt_t: return *((Int_t *)ptr); case kULong_t: return *((ULong_t *)ptr); case kLong_t: return *((Long_t *)ptr); case kULong64_t: return *((ULong64_t *)ptr); case kLong64_t: return *((Long64_t *)ptr); case kUShort_t: return *((UShort_t *)ptr); case kShort_t: return *((Short_t *)ptr); case kUChar_t: return *((UChar_t *)ptr); case kChar_t: return *((Char_t *)ptr); case kBool_t: return *((Bool_t *)ptr); case kFloat_t: return *((Float_t *)ptr); case kDouble_t: return *((Double_t *)ptr); case kDouble32_t: return *((Double32_t *)ptr); } return 0.; } Bool_t TGo4HistogramEntry::TestConditionNew() { if (!fxCondition) return kTRUE; Bool_t rev = kTRUE; Double_t dat[__MAXCONDIM__]; UInt_t dimension; // find out how many dimensions are set for condition: // maximum condition dimension defined by first index // with all data pointers set to zero. for (dimension = 0; dimension < __MAXCONDIM__; ++dimension) if (!fxCondPtr[dimension]) break; // fill pointers to test variables: for (UInt_t j = 0; j < dimension; ++j) dat[j] = GetPtrValue(fxCondType[j], fxCondPtr[j]); switch(dimension) { // case 0: // rev = fxCondition->GetLast(); // no own variables: last result // break; case 1: rev = fxCondition->Test(dat[0]); break; case 2: rev = fxCondition->Test(dat[0], dat[1]); break; default: rev = kTRUE; break; } return rev; } void TGo4HistogramEntry::ProcessNew(Bool_t *evvalid) { if (!fxHistogram) return; if (!TestConditionNew()) return; Double_t dat[3]; Int_t dimension = fxHistogram->GetDimension(); for (Int_t j = 0; j < dimension; ++j) dat[j] = GetPtrValue(fxHistType[j], fxHistPtr[j]); switch (dimension) { case 1: if(evvalid[0]) fxHistogram->Fill(dat[0]); break; case 2: if(evvalid[0] && evvalid[1]) { TH2 *his2 = dynamic_cast(fxHistogram); if(his2) his2->Fill(dat[0],dat[1]); } break; case 3: if(evvalid[0] && evvalid[1] && evvalid[2]) { TH3 *his3 = dynamic_cast(fxHistogram); if (his3) his3->Fill(dat[0], dat[1], dat[2]); } break; default: throw TGo4DynamicListException(this, TString::Format("Dynamic Histogram Entry %s Process error: Wrong histogram dimension %d !!!", GetName(), dimension).Data()); } // switch(dimension) } void TGo4HistogramEntry::RecursiveRemove(TObject *obj) { if (!obj) return; if(fxHistogram == obj) Reset(); if(fxCondition == obj) Reset(); for (Int_t n = 0; n < __MAXCONDIM__; n++) if (fxConEvents[n] == obj) Reset(); for (Int_t n = 0; n < __MAXHISDIM__; n++) if (fxHisEvents[n] == obj) Reset(); } void TGo4HistogramEntry::Print(Option_t *) const { // this trick is needed since root defines Print as const function... TROOT::IndentLevel(); std::cout <<"-Dynamic Histogram Entry " << GetName()<<" :"<