From cd246117683a9647a750128a6546c18d6c985559 Mon Sep 17 00:00:00 2001 From: hristov Date: Wed, 1 Dec 2004 08:29:13 +0000 Subject: [PATCH] New classes to facilitate features extraction (M.Ivanov) --- STEER/STEERLinkDef.h | 4 + STEER/TTreeStream.cxx | 427 ++++++++++++++++++++++++++++++++++++++++++ STEER/TTreeStream.h | 93 +++++++++ STEER/libSTEER.pkg | 2 +- 4 files changed, 525 insertions(+), 1 deletion(-) create mode 100644 STEER/TTreeStream.cxx create mode 100644 STEER/TTreeStream.h diff --git a/STEER/STEERLinkDef.h b/STEER/STEERLinkDef.h index 4f9472481a4..232742f8856 100644 --- a/STEER/STEERLinkDef.h +++ b/STEER/STEERLinkDef.h @@ -74,4 +74,8 @@ #pragma link C++ class AliVertexGenFile+; #pragma link C++ class AliVertexer+; #pragma link C++ class AliDetectorEventHeader+; + +#pragma link C++ class TTreeDataElement+; +#pragma link C++ class TTreeStream+; +#pragma link C++ class TTreeSRedirector+; #endif diff --git a/STEER/TTreeStream.cxx b/STEER/TTreeStream.cxx new file mode 100644 index 00000000000..aad02310901 --- /dev/null +++ b/STEER/TTreeStream.cxx @@ -0,0 +1,427 @@ +#include "TObjArray.h" +#include "TFile.h" +#include "TTree.h" +#include "TBrowser.h" +#include "TTreeStream.h" + + +ClassImp(TTreeDataElement) +ClassImp(TTreeStream) +ClassImp(TTreeSRedirector) + +/* + marian.ivanov@cern.ch + // + ------------------------------------------------------------------------------------------------ + TTreeStream + Standard stream (cout) like input for the tree + Run and see TTreeStreamer::Test() - to see TTreeStreamer functionality + ------------------------------------------------------------------------------------------------ + // + ------------------------------------------------------------------------------------------------- + TTreeSRedirector + Redirect file to different TTreeStreams + Run and see TTreeSRedirector::Test() as an example of TTreeSRedirectorer functionality + // +*/ + + +void TTreeStream::Test() +{ + // + // + TFile *ftest = new TFile("teststreamer.root","recreate"); + if (!ftest) ftest = new TFile("teststreamer.root","new"); + // + //create to streems Tree1 and Tree2 + TTreeStream stream1("Tree1"); + TTreeStream stream2("Tree2"); + // + Char_t ch='s'; + Float_t f=3.; + Float_t f2=1; + TObject *po = new TObject; + TObject *po2 = new TObject; + for (Int_t i=0;i<100000;i++) { + f=i*100; + po->SetUniqueID(i); + po2->SetUniqueID(i*100); + ch=i%120; + // + // Stream the data + // The data layout of stream is defined during first invocation of streamer. + // Endl is the trigger which define the end of structure. + // + // The name of branch can be specified using strings with = at the the end + // if string is not specified automatic convention is u (sed B0, B1, ...Bn) + stream1<<"i="<Close(); + delete ftest; + // + //5.) and now see results in file tteststreamer.root +} + + + +void TTreeSRedirector::Test() +{ + // + //Example test function to show functionality of TTreeSRedirector + // + // + //1.)create the redirector associated with file (testredirector.root) + // + // + TTreeSRedirector *pmistream= new TTreeSRedirector("testredirector.root"); + TTreeSRedirector &mistream = *pmistream; + Char_t ch='s'; + Float_t f=3.; + Float_t f2=1; + TObject *po = new TObject; + TObject *po2 = new TObject; + for (Int_t i=0;i<100000;i++) { + f=i*100; + po->SetUniqueID(i); + po2->SetUniqueID(i*100); + ch=i%120; + // + //2.) create the tree with identifier specified by first argument + // layout specified by sequence of arguments + // Tree identifier has to be specified as first argument !!! + // if the tree and layout was already defined the consistency if layout is checked + // if the data are consisten fill given tree + // the name of branch can be specified using strings with = at the the end + // if string is not specified use automatic convention B0, B1, ...Bn + mistream<<"TreeIdentifier"<<"i="<Close(); + delete fFile; +} + +TTreeStream & TTreeSRedirector::operator<<(Int_t id) +{ + // + // return reference to the data layout with given identifier + // if not existing - creates new + if (!fDataLayouts) fDataLayouts = new TObjArray(10000); + TTreeStream *clayout=0; + Int_t entries = fDataLayouts->GetEntriesFast(); + for (Int_t i=0;iAt(i); + if (!layout) continue; + if (layout->fId==id) { + clayout = layout; + break; + } + } + if (!clayout){ + char chname[100]; + sprintf(chname,"Tree%d",id); + clayout = new TTreeStream(chname); + clayout->fId=id; + fDataLayouts->AddAt(clayout,entries); + } + return *clayout; +} + + +TTreeStream & TTreeSRedirector::operator<<(const char* name) +{ + // + // return reference to the data layout with given identifier + // if not existing - creates new + if (!fDataLayouts) fDataLayouts = new TObjArray(10000); + TTreeStream *clayout=0; + Int_t hash = TMath::Hash(name); + Int_t entries = fDataLayouts->GetEntriesFast(); + for (Int_t i=0;iAt(i); + if (!layout) continue; + if (layout->fHash==hash) { + clayout = layout; + break; + } + } + if (!clayout){ + clayout = new TTreeStream(name); + clayout->fId=-1; + clayout->SetName(name); + clayout->fHash = hash; + fDataLayouts->AddAt(clayout,entries); + } + return *clayout; +} + + + + +void TTreeSRedirector::Close(){ + // + // + Int_t entries = fDataLayouts->GetEntriesFast(); + for (Int_t i=0;iAt(i); + if (layout){ + if (layout->fTree) layout->fTree->Write(); + } + } +} + + + +//------------------------------------------------------------- +TTreeDataElement:: TTreeDataElement(Char_t type){ + // + // + fType = type; + fDType = 0; + fClass = 0; + fPointer= 0; +} +TTreeDataElement:: TTreeDataElement(TDataType* type){ + // + // + fType = 0; + fDType = type; + fClass = 0; + fPointer= 0; +} +TTreeDataElement:: TTreeDataElement(TClass* cl){ + // + // + fType = 0; + fDType = 0; + fClass = cl; + fPointer= 0; +} + +//------------------------------------------------------------------- +TTreeStream::TTreeStream(const char *treename):TNamed(treename,treename){ + fElements =0; + fTree =0; + fCurrentIndex =0; + fNextName=""; + fNextNameCounter=0; + fTree = new TTree(treename, treename); +} + +TTreeStream::~TTreeStream() +{ + fElements->Delete(); + fBranches->Clear(); + delete fElements; + delete fBranches; +} + +void TTreeStream::Close() +{ + // + fTree->Write(); +} + +Int_t TTreeStream::CheckIn(Char_t type, void *pointer) +{ + if (!fElements) fElements = new TObjArray(1000); + TTreeDataElement* element = (TTreeDataElement*)fElements->At(fCurrentIndex); + if (!element) { + element = new TTreeDataElement(type); + // + char name[1000]; + if (fNextName.Length()>0){ + if (fNextNameCounter==0){ + sprintf(name,"%s",(const char*)fNextName); + } + if (fNextNameCounter>0){ + sprintf(name,"%s%d",(const char*)fNextName,fNextNameCounter); + } + } + else{ + sprintf(name,"B%d.",fCurrentIndex); + } + element->SetName(name); + // + element->SetPointer(pointer); + fElements->AddAt(element,fCurrentIndex); + fCurrentIndex++; + return 0; //new element added + } + if (element->GetType()!=type){ + fStatus++; + return 1; //mismatched data element + } + element->SetPointer(pointer); + fCurrentIndex++; + return 0; +} + +Int_t TTreeStream::CheckIn(TObject *o){ + // + // + if (!o) return 0; + if (!fElements) fElements = new TObjArray(1000); + TTreeDataElement* element = (TTreeDataElement*)fElements->At(fCurrentIndex); + if (!element) { + element = new TTreeDataElement(o->IsA()); + // + char name[1000]; + if (fNextName.Length()>0){ + if (fNextNameCounter==0){ + sprintf(name,"%s",(const char*)fNextName); + } + if (fNextNameCounter>0){ + sprintf(name,"%s%d",(const char*)fNextName,fNextNameCounter); + } + } + else{ + sprintf(name,"B%d",fCurrentIndex); + } + element->SetName(name); + + element->SetPointer(o); + fElements->AddAt(element,fCurrentIndex); + fCurrentIndex++; + return 0; //new element added + } + if (element->fClass!=o->IsA()){ + fStatus++; + return 1; //mismatched data element + } + element->SetPointer(o); + fCurrentIndex++; + return 0; +} + +void TTreeStream::BuildTree(){ + // + // + if (fTree->GetEntries()>0) return; + fTree = new TTree(GetName(),GetName()); + Int_t entries = fElements->GetEntriesFast(); + fBranches = new TObjArray(entries); + + for (Int_t i=0;iAt(i); + char bname1[1000]; + if (element->GetName()[0]==0){ + sprintf(bname1,"B%d",i); + } + else{ + sprintf(bname1,element->GetName()); + } + if (element->fClass){ + TBranch * br = fTree->Branch(bname1,element->fClass->GetName(),&(element->fPointer)); + fBranches->AddAt(br,i); + } + if (element->GetType()>0){ + char bname2[1000]; + sprintf(bname2,"B%d/%c",i,element->GetType()); + TBranch * br = fTree->Branch(bname1,element->fPointer,bname2); + fBranches->AddAt(br,i); + } + } +} + +void TTreeStream::Fill(){ + // + // + if (fTree) { + Int_t entries=fElements->GetEntriesFast(); + if (entries>fTree->GetNbranches()) BuildTree(); + for (Int_t i=0;iAt(i); + if (!el) continue; + if (!el->GetType()) continue; + TBranch * br = (TBranch*)fBranches->At(i); + if (br &&el){ + if (el->GetType()) br->SetAddress(el->fPointer); + } + } + if (fStatus==0) fTree->Fill(); //fill only in case of non conflicts + fStatus=0; + } +} + +TTreeStream & TTreeStream::Endl(){ + if (fTree->GetNbranches()==0) BuildTree(); + Fill(); + fStatus =0; + fCurrentIndex=0; + return *this; +} + + +TTreeStream &TTreeStream::operator<<(Char_t *name) +{ + // + // + // + //Endl + if (name[0]=='\n'){ + return Endl(); + } + // + //if tree was already defined ignore + if (fTree->GetEntries()>0) return *this; + //check branch name if tree was not + // + Int_t last=0; + for (last=0;;last++){ + if (name[last]==0) break; + } + + if (last>0&&name[last-1]=='='){ + fNextName = name; + fNextName[last-1]=0; + fNextNameCounter=0; + } + return *this; +} + diff --git a/STEER/TTreeStream.h b/STEER/TTreeStream.h new file mode 100644 index 00000000000..3250f35a3aa --- /dev/null +++ b/STEER/TTreeStream.h @@ -0,0 +1,93 @@ +#ifndef TTREESTREAM_H +#define TTREESTREAM_H +/////////////////////////////////////////////////////////////////////////////// +// // +// TTreeSRedirector // + +#include "TObject.h" +#include "TString.h" +class TFile; +class TObjArray; +class TTree; +class TDataType; + +class TTreeDataElement: public TNamed { + friend class TTreeStream; + public: + TTreeDataElement(Char_t type); + TTreeDataElement(TDataType* type); + TTreeDataElement(TClass* cl); + void SetPointer(void* pointer) {fPointer=pointer;} + Char_t GetType() const {return fType;} + protected: + TString fName; // name of the data element + Char_t fType; // type of data element + TDataType *fDType; //data type pointer + TClass *fClass; //data type pointer + void * fPointer; // pointer to element + ClassDef(TTreeDataElement,1) +}; + +class TTreeStream: public TNamed { + friend class TTreeSRedirector; +public: + TTreeStream(const char *treename); + ~TTreeStream(); + void Close(); + static void Test(); + Int_t CheckIn(Char_t type, void *pointer); + //Int_t CheckIn(const char *type, void *pointer); + Int_t CheckIn(TObject *o); + void BuildTree(); + void Fill(); + TTreeStream& Endl(); + // + TTreeStream &operator<<(Bool_t &b){CheckIn('B',&b);return *this;} + TTreeStream &operator<<(Char_t &c){CheckIn('B',&c);return *this;} + TTreeStream &operator<<(UChar_t &c){CheckIn('b',&c);return *this;} + TTreeStream &operator<<(Short_t &h){CheckIn('S',&h);return *this;} + TTreeStream &operator<<(UShort_t &h){CheckIn('s',&h);return *this;} + TTreeStream &operator<<(Int_t &i){CheckIn('I',&i);return *this;} + TTreeStream &operator<<(UInt_t &i){CheckIn('i',&i);return *this;} + TTreeStream &operator<<(Long_t &l){CheckIn('L',&l);return *this;} + TTreeStream &operator<<(ULong_t &l){CheckIn('l',&l);return *this;} + TTreeStream &operator<<(Long64_t &l){CheckIn('L',&l);return *this;} + TTreeStream &operator<<(ULong64_t &l){CheckIn('l',&l);return *this;} + TTreeStream &operator<<(Float_t &f){CheckIn('F',&f);return *this;} + TTreeStream &operator<<(Double_t &d){CheckIn('D',&d);return *this;} + TTreeStream &operator<<(TObject*o){CheckIn(o);return *this;} + TTreeStream &operator<<(Char_t *name); + protected: + // + TObjArray *fElements; //array of elements + TObjArray *fBranches; //pointers to branches + TTree *fTree; //data storage + Int_t fCurrentIndex; //index of current element + Int_t fId; //identifier of layout + Int_t fHash; //hash value of string + TString fNextName; //name for next entry + Int_t fNextNameCounter; //next name counter + Int_t fStatus; //status of the layout + ClassDef(TTreeStream,1) +}; + + + +class TTreeSRedirector: public TObject { +public: + TTreeSRedirector(const char *fname); + ~TTreeSRedirector(); + void Close(); + static void Test(); + virtual TTreeStream &operator<<(Int_t id); + virtual TTreeStream &operator<<(const char *name); + private: + TFile* fFile; //file + TObjArray *fDataLayouts; //array of data layouts + ClassDef(TTreeSRedirector,1) +}; + + + + +#endif diff --git a/STEER/libSTEER.pkg b/STEER/libSTEER.pkg index e33566e8f40..80247ae9aef 100644 --- a/STEER/libSTEER.pkg +++ b/STEER/libSTEER.pkg @@ -19,7 +19,7 @@ AliMemoryWatcher.cxx \ AliVertexer.cxx \ AliMC.cxx AliSimulation.cxx AliReconstruction.cxx AliVertexGenFile.cxx \ AliReconstructor.cxx \ -AliDetectorEventHeader.cxx +AliDetectorEventHeader.cxx TTreeStream.cxx HDRS:= $(SRCS:.cxx=.h) -- 2.39.3