00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "TGo4DynamicList.h"
00017
00018 #include "Riostream.h"
00019 #include <stdexcept>
00020 #include <stdlib.h>
00021 #include "TFolder.h"
00022 #include "TDataMember.h"
00023 #include "TDataType.h"
00024 #include "TBaseClass.h"
00025 #include "TClass.h"
00026 #include "TH1.h"
00027 #include "TList.h"
00028 #include "TROOT.h"
00029 #include "snprintf.h"
00030
00031 #include "TGo4Log.h"
00032 #include "TGo4DynamicListException.h"
00033 #include "TGo4HistogramEntry.h"
00034 #include "TGo4TreeHistogramEntry.h"
00035 #include "TGo4EventElement.h"
00036 #include "TGo4Status.h"
00037 #include "TGo4AnalysisImp.h"
00038
00039 void TGo4DynamicList::ResetEntries(TFolder* folder)
00040 {
00041 if (folder==0) return;
00042
00043 TIter iter(folder->GetListOfFolders());
00044 TObject* obj;
00045 while((obj = iter()) !=0) {
00046 TGo4DynamicEntry* entry = dynamic_cast<TGo4DynamicEntry*> (obj);
00047 if (entry!=0) entry->Reset();
00048 }
00049 }
00050
00051 void TGo4DynamicList::PrintEntries(TFolder* folder)
00052 {
00053 if (folder==0) return;
00054
00055 TIter iter(folder->GetListOfFolders());
00056 TObject* obj;
00057 while((obj = iter()) !=0) {
00058 TGo4DynamicEntry* entry = dynamic_cast<TGo4DynamicEntry*> (obj);
00059 if (entry!=0) entry->Print("*");
00060 }
00061 }
00062
00063 void TGo4DynamicList::CleanupPointerInEntries(TFolder* folder, TObject* objtoremove)
00064 {
00065 if (folder==0) return;
00066
00067 TIter iter(folder->GetListOfFolders());
00068 TObject* obj;
00069 while((obj = iter()) !=0) {
00070 TGo4DynamicEntry* entry = dynamic_cast<TGo4DynamicEntry*> (obj);
00071 if (entry!=0) entry->RecursiveRemove(objtoremove);
00072 }
00073 }
00074
00075
00076 void TGo4DynamicList::ProcessEntries(TFolder* folder, Bool_t processtrees, Int_t interval)
00077 {
00078 if (folder==0) return;
00079
00080 TGo4DynamicEntry* errorentry = 0;
00081 TIter iter(folder->GetListOfFolders());
00082 TObject* obj;
00083
00084 try {
00085 while((obj = iter()) !=0) {
00086 TGo4DynamicEntry* entry = dynamic_cast<TGo4DynamicEntry*> (obj);
00087 if (entry==0) continue;
00088
00089 try {
00090 if (!entry->IsEnabledProcessing()) continue;
00091
00092 if (!ProcessHEntry(dynamic_cast<TGo4HistogramEntry*> (entry))) {
00093 errorentry = entry;
00094 break;
00095 }
00096
00097 if (!ProcessTEntry(dynamic_cast<TGo4TreeHistogramEntry*> (entry), processtrees, interval)) {
00098 errorentry = entry;
00099 break;
00100
00101 }
00102 }
00103 catch(TGo4DynamicListException& ex) {
00104 ex.Handle();
00105 errorentry = (TGo4DynamicEntry*) entry;
00106 }
00107 }
00108
00109
00110
00111
00112 }
00113 catch(std::exception& ex) {
00114 throw TGo4DynamicListException(errorentry,
00115 "!!!STD exception %s was raised processing dynamic entry!!!",
00116 ex.what());
00117 }
00118 }
00119
00120 TDataMember* FindDataMember(TClass* eventclass,
00121 const char* memname,
00122 Long_t* totaloffset)
00123 {
00124 if(!eventclass) return 0;
00125
00126
00128
00129 Long_t indexoffset=0;
00130 Text_t ixtext[256];
00131 const char* ixbegin = strstr(memname,"[");
00132 if(ixbegin)
00133 {
00134
00135
00136 ixbegin++;
00137 const char* ixend=strstr(ixbegin,"]");
00138 if(ixend)
00139 {
00140 Int_t ixlen=ixend-ixbegin;
00141 snprintf(ixtext,ixlen+1,"%s",ixbegin);
00142 indexoffset=atoi(ixtext);
00143 if(indexoffset<0) indexoffset=0;
00144 }
00145 else {}
00146 }
00147 else {}
00149
00150 TDataMember* eventmember= eventclass->GetDataMember(memname);
00151 if(eventmember) {
00152 *totaloffset+=eventmember->GetOffset();
00153 } else {
00154
00155 TIter baseiter(eventclass->GetListOfBases());
00156 TObject* ob=0;
00157 while((ob=baseiter()) !=0) {
00158 TBaseClass* baseclass=dynamic_cast<TBaseClass*>(ob);
00159 if(baseclass!=0)
00160 {
00161
00162 TClass* bclass=baseclass->GetClassPointer();
00163
00164 eventmember=FindDataMember(bclass,memname,totaloffset);
00165 if(eventmember)
00166 {
00167
00168 *totaloffset+=baseclass->GetDelta();
00169
00170
00171
00172
00173 break;
00174 } else{ }
00175 }
00176 }
00177 }
00178
00179
00180
00181 if(eventmember)
00182 {
00183 const char* tname = eventmember->GetFullTypeName();
00184
00185 Int_t maxindex=eventmember->GetMaxIndex(0);
00186 if(maxindex<0) maxindex=1;
00187 if(indexoffset<maxindex)
00188 {
00189 Int_t datasize = eventmember->GetDataType()->Size();
00190 *totaloffset += indexoffset*datasize;
00191
00192 }
00193 else
00194 {
00195 throw TGo4DynamicListException(0,
00196 "Index %d for array member:%s out of range %s[%d]",
00197 indexoffset, memname, tname, maxindex);
00198 }
00199
00200
00201
00202
00203
00204
00205
00206 }
00207
00208 return eventmember;
00209 }
00210
00211 bool TGo4DynamicList::ProcessHEntry(TGo4HistogramEntry* hentry)
00212 {
00213 if (hentry==0) return true;
00214
00215 if (hentry->NeedInitialisation()) {
00216 TGo4Analysis* ana= TGo4Analysis::Instance();
00217
00218 hentry->fxCondition = ana->GetAnalysisCondition(hentry->GetConditionName());
00219
00220 for(Int_t n=0; n<__MAXCONDIM__; n++) {
00221 TGo4EventElement* event = 0;
00222 TDataMember* eventmember = 0;
00223 Long_t offset=0;
00224
00225 const char* evname = hentry->GetConEventName(n);
00226 const char* memname = hentry->GetConVarName(n);
00227
00228 if (!TString(evname).Contains(TGo4HistogramEntry::Get_fgcNOEVENT()))
00229 event = ana->GetEventStructure(evname);
00230
00231 if(event!=0)
00232 if(!TString(memname).Contains(TGo4HistogramEntry::Get_fgcNODATA()))
00233 eventmember = FindDataMember(event->IsA(), memname, &offset);
00234
00235 hentry->InitCondPointer(n, event, eventmember, offset);
00236 }
00237
00238 hentry->fxHistogram = ana->GetHistogram(hentry->GetHistogramName());
00239
00240 for(Int_t n=0; n<__MAXHISDIM__; n++) {
00241 TGo4EventElement* event = 0;
00242 TDataMember* eventmember = 0;
00243 Long_t offset=0;
00244
00245 const char* evname = hentry->GetHistEventName(n);
00246 const char* memname = hentry->GetHistVarName(n);
00247
00248 if (!TString(evname).Contains(TGo4HistogramEntry::Get_fgcNOEVENT()))
00249 event = ana->GetEventStructure(evname);
00250
00251 if(event!=0)
00252 if(!TString(memname).Contains(TGo4HistogramEntry::Get_fgcNODATA()))
00253 eventmember = FindDataMember(event->IsA(), memname, &offset);
00254
00255 hentry->InitHistPointer(n, event, eventmember, offset);
00256 }
00257
00258 hentry->SetNeedInitialisation(kFALSE);
00259 }
00260
00261 Bool_t evvalid[__MAXHISDIM__];
00262 for (Int_t n=0;n<__MAXHISDIM__;n++) {
00263 evvalid[n] = kFALSE;
00264 TGo4EventElement* event = (TGo4EventElement*) hentry->fxHisEvents[n];
00265 if (event!=0)
00266 evvalid[n] = event->IsValid();
00267 }
00268
00269 hentry->ProcessNew(evvalid);
00270
00271 return true;
00272 }
00273
00274 bool TGo4DynamicList::ProcessTEntry(TGo4TreeHistogramEntry* tentry, Bool_t processtrees, Int_t interval)
00275 {
00276 if (tentry==0) return true;
00277
00278 tentry->SetDynListInterval(interval);
00279
00280 if(!processtrees) return true;
00281
00282 const char* hname = tentry->GetHistogramName();
00283
00284 TTree* tree = TGo4Analysis::Instance()->GetTree(tentry->GetTreeName());
00285 if (tree==0) {
00286 throw TGo4DynamicListException(tentry,
00287 "Tree Histogram Entry: !!! Could not find Tree %s ",tentry->GetTreeName());
00288 return kFALSE;
00289 }
00290
00291 TH1* histo = TGo4Analysis::Instance()->GetHistogram(hname);
00292
00293 if (!tentry->fbNewHistogram && (histo==0)) {
00294 throw TGo4DynamicListException(tentry,
00295 "Tree Histogram Entry: !!! Could not find Histogram %s ",hname);
00296 return kFALSE;
00297 }
00298
00299 if (histo!=0)
00300 tentry->fbNewHistogram = kFALSE;
00301
00302 tentry->ProcessTreeNew(tree, TGo4Analysis::Instance()->GetDynListInterval());
00303
00304 if (tentry->fbNewHistogram) {
00306
00307
00308 histo = dynamic_cast<TH1*>(gROOT->FindObject(hname));
00309 if(histo==0)
00310 {
00311
00312 histo = dynamic_cast<TH1*>(gROOT->FindObjectAny(hname));
00313 }
00314
00315
00316
00317
00318 if(histo!=0) {
00319
00320 TGo4Analysis::Instance()->AddHistogram(histo);
00321 histo->SetBit(TGo4Status::kGo4CanDelete);
00322 tentry->fbNewHistogram=kFALSE;
00323 }
00324 else{
00325
00326
00327
00328 }
00329
00330 }
00331
00332 return true;
00333 }
00334
00335