Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

TGo4DynamicList.cxx

Go to the documentation of this file.
00001 //-------------------------------------------------------------
00002 //        Go4 Release Package v3.04-01 (build 30401)
00003 //                      28-November-2008
00004 //---------------------------------------------------------------
00005 //   The GSI Online Offline Object Oriented (Go4) Project
00006 //   Experiment Data Processing at EE department, GSI
00007 //---------------------------------------------------------------
00008 //
00009 //Copyright (C) 2000- Gesellschaft f. Schwerionenforschung, GSI
00010 //                    Planckstr. 1, 64291 Darmstadt, Germany
00011 //Contact:            http://go4.gsi.de
00012 //----------------------------------------------------------------
00013 //This software can be used under the license agreements as stated
00014 //in Go4License.txt file which is part of the distribution.
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(); // will disable the error causing entry, continue other entries
00105            errorentry = (TGo4DynamicEntry*) entry;
00106          }
00107       } // while
00108       //if(processtrees) TGo4Analysis::Instance()->ResetBackStores(kTRUE); // clear backstore reset bits
00109       // note: the above call is redundant in current usage, becaus in processtrees case the
00110       // backstore is immediately reset again for the next time
00111       // (buffer reset interval equals treedraw interval)
00112    }
00113    catch(std::exception& ex) { // treat standard library exceptions
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 // here we might parse the memname for dots to figure out aggregated classes
00126 
00128 // check for array member index:
00129 Long_t indexoffset=0;
00130 Text_t ixtext[256];
00131 const char* ixbegin = strstr(memname,"[");
00132 if(ixbegin)
00133 {
00134 //   cout <<"-------------FindDataMember of Entry " << GetName() << endl;
00135 //   cout <<"Found index in member" << memname << endl;
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); // to be used downstream
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      // if not found directly, check for baseclass members:
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                   // we have a baseclass
00162                   TClass* bclass=baseclass->GetClassPointer();
00163                   // search for member in all superclasses recursively:
00164                   eventmember=FindDataMember(bclass,memname,totaloffset);
00165                   if(eventmember)
00166                     {
00167                        // we found member in any of the baseclasses
00168                        *totaloffset+=baseclass->GetDelta();
00169                           // inc total offset to this by baseclass offset
00170                           // member offset is relative to TClass (i.e. baseclass here)
00171                        //cout <<"iiiiiiiiiInitPointers baseclass member: " << eventmember << endl;
00172                        //cout <<"iiiiiiiiiInitPointers baseclass delta: " << baseclass->GetDelta() << endl;
00173                        break;
00174                     } else{ }
00175               } // if(baseclass)
00176         } // while
00177     } // if (eventmember)
00178 
00179 // finally, we check for eventmember type to add
00180 //correct offset in case of array:
00181 if(eventmember)
00182    {
00183    const char* tname = eventmember->GetFullTypeName();
00184    // check if given index is inside allocated size:
00185    Int_t maxindex=eventmember->GetMaxIndex(0);
00186    if(maxindex<0) maxindex=1; // for non-array members maxindex is -1
00187    if(indexoffset<maxindex)
00188       {
00189          Int_t datasize = eventmember->GetDataType()->Size();
00190          *totaloffset += indexoffset*datasize;
00191          //cout <<"totaloffset:"<< *totaloffset<<endl;
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    // for now, we only handle 1d arrays
00200    // root allows to check higher dimensions, maybe later...?
00201    //for(Int_t ii=0; ii<4; ++ii)
00202    //{
00203    //   Int_t maxindex=eventmember->GetMaxIndex(ii);
00204    //   cout <<"Found maxindex "<<maxindex<<" for dimension "<<ii << endl;
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    //if(!histo) cout <<"ProcessTEntry do did not find histo "<<hname << endl;
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 //        cout <<"gDirectory is "<<gDirectory->GetName() << endl;
00307 //        cout <<"gROOT is "<<gROOT->GetName() << endl;
00308        histo = dynamic_cast<TH1*>(gROOT->FindObject(hname));
00309        if(histo==0)
00310          {
00311 //            cout <<"not found by FindObject, try FindObjectAny..." << endl;
00312             histo = dynamic_cast<TH1*>(gROOT->FindObjectAny(hname));
00313          }
00314        // note JA: FindObject fails with histogram created in hsimple.C on Cintserver when gDirectory was different from gRoot
00315        // in this case, histogram is only available in TRoot::fList via scan over root folders
00316        // note2: second fix is in TGo4Analysis::Process() which explicitely resets gDirectory to gROOT
00317        // before entering the MainCycle(); so FindObjectAny should be never necessary now
00318        if(histo!=0) {
00319           //cout <<"ProcessTEntry did FIND NEW histo "<<hname << endl;
00320           TGo4Analysis::Instance()->AddHistogram(histo); // we put the new histogram into our histo folder!
00321           histo->SetBit(TGo4Status::kGo4CanDelete);
00322           tentry->fbNewHistogram=kFALSE;
00323        }
00324        else{
00325            // never come here!
00326            //cout <<"ProcessTEntry do did neither find NEW histo "<<hname << endl;
00327 
00328        }
00329 
00330    }
00331 
00332    return true;
00333 }
00334 
00335 //----------------------------END OF GO4 SOURCE FILE ---------------------

Generated on Fri Nov 28 12:59:04 2008 for Go4-v3.04-1 by  doxygen 1.4.2