New classes to facilitate features extraction (M.Ivanov)
authorhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 1 Dec 2004 08:29:13 +0000 (08:29 +0000)
committerhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 1 Dec 2004 08:29:13 +0000 (08:29 +0000)
STEER/STEERLinkDef.h
STEER/TTreeStream.cxx [new file with mode: 0644]
STEER/TTreeStream.h [new file with mode: 0644]
STEER/libSTEER.pkg

index 4f9472481a4e9eee18cdd31345d70da6e23c56d6..232742f88564fa190157eefc414956116cb1f6d8 100644 (file)
@@ -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 (file)
index 0000000..aad0231
--- /dev/null
@@ -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="<<i<<"ch="<<ch<<"f="<<f<<"po="<<po<<"\n";
+    f  = 1./(100.1+i);
+    f2 = -f;     
+    //3.) just another example - we can fill the same tree with different objects
+    //
+    stream2<<f<<po<<"\n";
+    stream2<<f2<<po2<<"\n";
+  }
+  //
+  //4.) Close the streeamers (Write the streamed tree's to the file) and close the corresponding file.
+  //
+  stream1.Close();
+  stream2.Close();
+  ftest->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="<<i<<"ch="<<ch<<"f="<<f<<"po="<<po<<"\n";
+    f  = 1./(100.1+i);
+    f2 = -f; 
+    
+    //3.) just another example - we can fill the same tree with different objects
+    //
+    mistream<<"TreeK"<<f<<po<<"\n";
+    mistream<<"TreeK"<<f2<<po2<<"\n";
+  }
+  //
+  //4.) write the streamed tree's to the file and close the corresponding file in destructor
+  //
+  delete pmistream;
+  //
+  //5.) and now see results in file testredirector.root 
+}
+
+
+
+
+
+
+TTreeSRedirector::TTreeSRedirector(const char *fname){
+  //
+  //
+  fFile = new TFile(fname,"recreate");
+  if (!fFile){
+    fFile = new TFile(fname,"new");
+  }
+  fDataLayouts =0;
+  
+}
+
+TTreeSRedirector::~TTreeSRedirector(){
+  //
+  //
+  Close();       //write the tree to the selected file
+  fFile->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;i<entries;i++){
+    TTreeStream * layout = (TTreeStream*)fDataLayouts->At(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;i<entries;i++){
+    TTreeStream * layout = (TTreeStream*)fDataLayouts->At(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;i<entries;i++){
+     TTreeStream * layout = (TTreeStream*)fDataLayouts->At(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;i<entries;i++){
+    //
+    TTreeDataElement* element = (TTreeDataElement*)fElements->At(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;i<entries;i++){    
+      TTreeDataElement* el  = (TTreeDataElement*)fElements->At(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 (file)
index 0000000..3250f35
--- /dev/null
@@ -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
index e33566e8f409ad9b11b2251c21b244b9a166891e..80247ae9aef1f8d12d25dbf883b4c1ff85f23ed8 100644 (file)
@@ -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)