LCOV - code coverage report
Current view: top level - STEER/STEERBase - TTreeStream.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 25 394 6.3 %
Date: 2016-06-14 17:26:59 Functions: 9 37 24.3 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
       3             :  *                                                                        *
       4             :  * Author: The ALICE Off-line Project.                                    *
       5             :  * Contributors are mentioned in the code where appropriate.              *
       6             :  *                                                                        *
       7             :  * Permission to use, copy, modify and distribute this software and its   *
       8             :  * documentation strictly for non-commercial purposes is hereby granted   *
       9             :  * without fee, provided that the above copyright notice appears in all   *
      10             :  * copies and that both the copyright notice and this permission notice   *
      11             :  * appear in the supporting documentation. The authors make no claims     *
      12             :  * about the suitability of this software for any purpose. It is          *
      13             :  * provided "as is" without express or implied warranty.                  *
      14             :  **************************************************************************/
      15             : 
      16             : /* $Id$ */
      17             : 
      18             : //
      19             : //  marian.ivanov@cern.ch
      20             : //
      21             : //  ------------------------------------------------------------------------------------------------
      22             : //  TTreeStream
      23             : //  Standard stream (cout) like input for the tree
      24             : //  Run and see TTreeStreamer::Test() - to see TTreeStreamer functionality
      25             : //  ------------------------------------------------------------------------------------------------  
      26             : //
      27             : //  -------------------------------------------------------------------------------------------------
      28             : //  TTreeSRedirector
      29             : //  Redirect file to  different TTreeStreams  
      30             : //  Run and see   TTreeSRedirector::Test() as an example of TTreeSRedirectorer functionality 
      31             : // 
      32             : 
      33             : #include <TClass.h>
      34             : #include <TFile.h>
      35             : #include <TDirectory.h>
      36             : #include <TObjArray.h>
      37             : #include <TTree.h>
      38             : #include "TTreeStream.h"
      39             : // includes for test procedures
      40             : #include "TVectorD.h"
      41             : #include "TRandom.h"
      42             : 
      43         176 : ClassImp(TTreeDataElement)
      44         176 : ClassImp(TTreeStream)
      45         176 : ClassImp(TTreeSRedirector)
      46             : 
      47             : 
      48             : 
      49             : void TTreeStream::Test()
      50             : {
      51             :   //
      52             :   // 
      53           0 :   TFile *ftest = new TFile("teststreamer.root","recreate");
      54           0 :   if (!ftest) ftest = new TFile("teststreamer.root","new");
      55             :   //
      56             :   //create to streems Tree1 and Tree2
      57           0 :   TTreeStream stream1("Tree1");
      58           0 :   TTreeStream stream2("Tree2");
      59             :   //
      60           0 :   Char_t ch='s';
      61           0 :   Float_t f=3.;
      62           0 :   Float_t f2=1;
      63           0 :   TObject *po  = new TObject;
      64           0 :   TObject *po2 = new TObject;
      65           0 :   for (Int_t i=0;i<100000;i++) {
      66           0 :     f=i*100;
      67           0 :     po->SetUniqueID(i);
      68           0 :     po2->SetUniqueID(i*100);
      69           0 :     ch=i%120;
      70             :     //
      71             :     //    Stream the data
      72             :     //    The data layout of stream is defined during first invocation of streamer.
      73             :     //    Endl is the trigger which define the end of structure.
      74             :     // 
      75             :     //    The name of branch can be specified using strings with = at the the end
      76             :     //    if string is not specified automatic convention is u (sed B0, B1, ...Bn)
      77           0 :     stream1<<"i="<<i<<"ch="<<ch<<"f="<<f<<"po="<<po<<"\n";
      78           0 :     f  = 1./(100.1+i);
      79           0 :     f2 = -f;     
      80             :     //3.) just another example - we can fill the same tree with different objects
      81             :     //
      82           0 :     stream2<<f<<po<<"\n";
      83           0 :     stream2<<f2<<po2<<"\n";
      84             :   }
      85             :   //
      86             :   //4.) Close the streeamers (Write the streamed tree's to the file) and close the corresponding file.
      87             :   //
      88           0 :   stream1.Close();
      89           0 :   stream2.Close();
      90           0 :   ftest->Close();
      91           0 :   delete ftest;
      92             :   //
      93             :   //5.) and now see results  in file tteststreamer.root
      94           0 : }
      95             : 
      96             : void TTreeSRedirector::Test2()
      97             : {
      98             :   //
      99             :   //Example test function to show functionality of TTreeSRedirector
     100             :   //
     101             :   //
     102             :   //1.)create the  redirector associated with file (testredirector.root)
     103             :   //
     104             :   //
     105           0 :   TFile* file = new TFile("test.root","recreate");
     106           0 :   TTreeSRedirector *pmistream= new TTreeSRedirector();
     107             :   TTreeSRedirector &mistream = *pmistream;
     108           0 :   Char_t ch='s';
     109           0 :   Float_t f=3.;
     110           0 :   Float_t f2=1;
     111           0 :   TObject *po  = new TObject;
     112           0 :   TObject *po2 = new TObject;
     113           0 :   for (Int_t i=0;i<100000;i++) {
     114           0 :     f=i*100;
     115           0 :     po->SetUniqueID(i);
     116           0 :     po2->SetUniqueID(i*100);
     117           0 :     ch=i%120;
     118             :     //
     119             :     //2.) create the tree with identifier specified by first argument
     120             :     //                                layout specified by sequence of arguments
     121             :     //                                Tree identifier has to be specified as first argument !!! 
     122             :     //    if the tree and layout was already defined the consistency if layout is checked
     123             :     //                                if the data are consisten fill given tree 
     124             :     //    the name of branch can be specified using strings with = at the the end
     125             :     //    if string is not specified use automatic convention  B0, B1, ...Bn
     126           0 :     mistream<<"TreeIdentifier"<<"i="<<i<<"ch="<<ch<<"f="<<f<<"po="<<po<<"\n";
     127           0 :     f  = 1./(100.1+i);
     128           0 :     f2 = -f; 
     129             :     
     130             :     //3.) just another example - we can fill the same tree with different objects
     131             :     //
     132           0 :     mistream<<"TreeK"<<f<<po<<"\n";
     133           0 :     mistream<<"TreeK"<<f2<<po2<<"\n";
     134             :   }
     135             :   //
     136             :   //4.) write the streamed tree's to the file and close the corresponding file in destructor
     137             :   //
     138           0 :   delete pmistream;
     139           0 :   delete file;
     140             :   //
     141             :   //5.) and now see results in file testredirector.root 
     142           0 : }
     143             : 
     144             : void TTreeSRedirector::Test()
     145             : {
     146             :   //
     147             :   //Example test function to show functionality of TTreeSRedirector
     148             :   //
     149             :   //
     150             :   //1.)create the  redirector associated with file (testredirector.root)
     151             :   //
     152             :   //
     153           0 :   TTreeSRedirector *pmistream= new TTreeSRedirector("testredirector.root");
     154             :   TTreeSRedirector &mistream = *pmistream;
     155           0 :   Char_t ch='s';
     156           0 :   Float_t f=3.;
     157           0 :   Float_t f2=1;
     158           0 :   TObject *po  = new TObject;
     159           0 :   TObject *po2 = new TObject;
     160           0 :   for (Int_t i=0;i<100000;i++) {
     161           0 :     f=i*100;
     162           0 :     po->SetUniqueID(i);
     163           0 :     po2->SetUniqueID(i*100);
     164           0 :     ch=i%120;
     165             :     //
     166             :     //2.) create the tree with identifier specified by first argument
     167             :     //                                layout specified by sequence of arguments
     168             :     //                                Tree identifier has to be specified as first argument !!! 
     169             :     //    if the tree and layout was already defined the consistency if layout is checked
     170             :     //                                if the data are consisten fill given tree 
     171             :     //    the name of branch can be specified using strings with = at the the end
     172             :     //    if string is not specified use automatic convention  B0, B1, ...Bn
     173           0 :     mistream<<"TreeIdentifier"<<"i="<<i<<"ch="<<ch<<"f="<<f<<"po="<<po<<"\n";
     174           0 :     f  = 1./(100.1+i);
     175           0 :     f2 = -f; 
     176             :     
     177             :     //3.) just another example - we can fill the same tree with different objects
     178             :     //
     179           0 :     mistream<<"TreeK"<<f<<po<<"\n";
     180           0 :     mistream<<"TreeK"<<f2<<po2<<"\n";
     181             :   }
     182             :   //
     183             :   //4.) write the streamed tree's to the file and close the corresponding file in destructor
     184             :   //
     185           0 :   delete pmistream;
     186             :   //
     187             :   //5.) and now see results in file testredirector.root 
     188           0 : }
     189             : 
     190             : void TTreeSRedirector::UnitTest(Int_t testEntries){
     191             :   //
     192             :   //
     193             :   //
     194           0 :   UnitTestSparse(0.5,testEntries);
     195           0 :   UnitTestSparse(0.1,testEntries);
     196           0 :   UnitTestSparse(0.01,testEntries);
     197           0 : }
     198             : 
     199             : void TTreeSRedirector::UnitTestSparse(Double_t scale, Int_t testEntries){
     200             :   //
     201             :   // Unit test for the TTreeSRedirector
     202             :   // 1.) Test TTreeRedirector 
     203             :   //      a.) Fill tree with random vectors
     204             :   //      b.) Fill downscaled version of vectors
     205             :   //      c.) The same skipping first entry
     206             :   // 2.) Check results wtitten to terminale
     207             :   //     a.) Disk consumption 
     208             :   //             skip data should be scale time smaller than full
     209             :   //             zerro replaced  ata should be compresed time smaller than full
     210             :   //     b.) Test invariants
     211             :   // Input parameter scale => downscaling of sprse element 
     212             :   //            
     213           0 :   if (scale<=0) scale=1;
     214           0 :   if (scale>1) scale=1;
     215           0 :   TTreeSRedirector *pcstream = new TTreeSRedirector("testpcstreamSparse.root","recreate");
     216           0 :   for (Int_t ientry=0; ientry<testEntries; ientry++){
     217           0 :     TVectorD vecRandom(200);
     218           0 :     TVectorD vecZerro(200);   // zerro vector
     219           0 :     for (Int_t j=0; j<200; j++) vecRandom[j]=j+ientry+0.1*gRandom->Rndm();
     220           0 :     Bool_t isSelected= (gRandom->Rndm()<scale);
     221             :     TVectorD *pvecFull   = &vecRandom;
     222           0 :     TVectorD *pvecSparse = isSelected ? &vecRandom:0;
     223             :     TVectorD *pvecSparse0 = isSelected ? &vecRandom:0;
     224           0 :     TVectorD *pvecSparse1 = isSelected ? &vecRandom:&vecZerro;
     225             : 
     226           0 :     if (ientry==0) {
     227             :       pvecSparse0=0;
     228             :       pvecSparse=&vecRandom;
     229           0 :     }
     230           0 :     (*pcstream)<<"Full"<<                  // stored all vectors
     231           0 :       "ientry="<<ientry<<
     232           0 :       "vec.="<<pvecFull<<                  
     233             :       "\n";
     234           0 :     (*pcstream)<<"SparseSkip"<<                // fraction of vectors stored
     235           0 :       "ientry="<<ientry<<
     236           0 :       "vec.="<<pvecSparse<<                
     237             :       "\n";
     238           0 :     (*pcstream)<<"SparseSkip0"<<               // fraction with -pointer
     239           0 :       "ientry="<<ientry<<
     240           0 :       "vec.="<<pvecSparse0<<
     241             :       "\n";
     242           0 :     (*pcstream)<<"SparseZerro"<<               // all vectors filled, franction filled with 0
     243           0 :       "ientry="<<ientry<<
     244           0 :       "vec.="<<pvecSparse1<<
     245             :       "\n";
     246           0 :   }
     247           0 :   delete pcstream;
     248             :   //
     249             :   // 2.) check results
     250             :   //
     251             : 
     252           0 :   TFile* f = TFile::Open("testpcstreamSparse.root");
     253           0 :   if (!f){
     254           0 :     printf("FAILED: file: %p, TTreeSRedirector::IsDisabled()=%i\n",f,TTreeSRedirector::IsDisabled()?1:0);
     255           0 :     return;
     256             :   }
     257           0 :   TTree * treeFull = (TTree*)f->Get("Full");
     258           0 :   TTree * treeSparseSkip = (TTree*)f->Get("SparseSkip");
     259           0 :   TTree * treeSparseSkip0 = (TTree*)f->Get("SparseSkip0");
     260           0 :   TTree * treeSparseZerro = (TTree*)f->Get("SparseZerro");
     261             :   //    a.) data volume
     262             :   //
     263           0 :   Double_t ratio=(1./scale)*treeSparseSkip->GetZipBytes()/Double_t(treeFull->GetZipBytes());
     264           0 :   Double_t ratio0=(1./scale)*treeSparseSkip0->GetZipBytes()/Double_t(treeFull->GetZipBytes());
     265           0 :   Double_t ratio1=(1./scale)*treeSparseZerro->GetZipBytes()/Double_t(treeFull->GetZipBytes());
     266           0 :   printf("#UnitTest:\tTTreeSRedirector::TestSparse(%f)\tRatioSkip\t%f\n",scale,ratio);
     267           0 :   printf("#UnitTest:\tTTreeSRedirector::TestSparse(%f)\tRatioSkip0\t%f\n",scale,ratio0);
     268           0 :   printf("#UnitTest:\tTTreeSRedirector::TestSparse(%f)\tRatioZerro\t%f\n",scale,ratio1);
     269             :   //    b.) Integrity 
     270           0 :   Int_t outlyersSparseSkip=treeSparseSkip->Draw("1","(vec.fElements-ientry-Iteration$-0.5)>0.5","goff");
     271           0 :   Int_t outlyersSparseSkip0=treeSparseSkip0->Draw("1","(vec.fElements-ientry-Iteration$-0.5)>0.5","goff");
     272           0 :   printf("#UnitTest:\tTTreeSRedirector::TestSparse(%f)\tOutlyersSkip\t%d\n",scale,outlyersSparseSkip!=0);
     273           0 :   printf("#UnitTest:\tTTreeSRedirector::TestSparse(%f)\tOutlyersSkip0\t%d\n",scale,outlyersSparseSkip0!=0);
     274             :   //    c.) Number of entries
     275             :   //
     276           0 :   Int_t entries=treeFull->GetEntries();
     277           0 :   Int_t entries0=treeSparseSkip0->GetEntries();
     278           0 :   Bool_t  isOKStat =(entries==entries0);
     279           0 :   printf("#UnitTest:\tTTreeSRedirector::TestSparse(%f)\tEntries\t%d\n",scale,isOKStat);
     280             :   //
     281             :   //   d.)Reading test
     282           0 :   TVectorD *pvecRead   = 0;
     283           0 :   treeSparseSkip0->SetBranchAddress("vec.",&pvecRead);
     284             :   Bool_t readOK=kTRUE;
     285           0 :   for (Int_t ientry=0; ientry<testEntries; ientry++){
     286           0 :     if (!pvecRead) continue;
     287           0 :     if (pvecRead->GetNrows()==0) continue;
     288           0 :     if (TMath::Abs((*pvecRead)[0]-ientry)>0.5) readOK=kFALSE;
     289             :   }
     290           0 :   printf("#UnitTest:\tTTreeSRedirector::TestSparse(%f)\tReadOK\t%d\n",scale,readOK);
     291             :   //
     292             :   //   e.)Global test
     293           0 :   Bool_t isOK=(outlyersSparseSkip0==0)&&isOKStat&&readOK;
     294           0 :   printf("#UnitTest:\tTTreeSRedirector::TestSparse(%f)\tisOk\t%d\n",scale,isOK);  
     295             : 
     296           0 : }
     297             : 
     298             : Bool_t TTreeSRedirector::fgDisabled=kFALSE;
     299           2 : TTreeSRedirector::TTreeSRedirector(const char *fname,const char * option) :
     300           2 :   fDirectory(NULL),
     301           2 :   fDirectoryOwner(kTRUE),
     302           2 :   fDataLayouts(NULL)
     303          10 : {
     304             :   //
     305             :   // Constructor
     306             :   //
     307           2 :   if (fgDisabled) {fDirectory=gDirectory;fDirectoryOwner=kFALSE;return;}
     308             : 
     309           2 :   TString name(fname);
     310           4 :   if (!name.IsNull()){
     311           6 :     fDirectory = new TFile(fname,option);
     312           2 :   }
     313             :   else
     314             :   {
     315           0 :     fDirectory = gDirectory;
     316           0 :     fDirectoryOwner = kFALSE;
     317             :   }
     318           6 : }
     319             : 
     320             : TTreeSRedirector::~TTreeSRedirector()
     321          12 : {
     322             :   //
     323             :   // Destructor
     324             :   //
     325           2 :   Close();       //write the tree to the selected file
     326           2 :   if (fDirectoryOwner)
     327             :   {
     328           2 :     fDirectory->Close();
     329           4 :     delete fDirectory;
     330             :   }
     331           6 : }
     332             : void TTreeSRedirector::StoreObject(TObject* object){
     333             :   //
     334             :   //
     335             :   //
     336           0 :   if (fgDisabled) return;
     337           0 :   TDirectory * backup = gDirectory;
     338           0 :   fDirectory->cd();
     339           0 :   object->Write();
     340           0 :   if (backup) backup->cd();
     341           0 : }
     342             : 
     343             : void  TTreeSRedirector::SetDirectory(TDirectory *sfile){
     344             :   //
     345             :   // Set the external file 
     346             :   // In case other file already attached old file is closed before
     347             :   // Redirector will be the owner of file ?
     348           0 :   if (fDirectory && fDirectoryOwner) {
     349           0 :     fDirectory->Close();
     350           0 :     delete fDirectory;
     351             :   }
     352           0 :   fDirectory=sfile;
     353           0 : }
     354             : 
     355             : TTreeStream  & TTreeSRedirector::operator<<(Int_t id)
     356             : {
     357             :   //
     358             :   // return reference to the data layout with given identifier
     359             :   // if not existing - creates new
     360           0 :   if (!fDataLayouts) fDataLayouts = new TObjArray(fgDisabled?1:10000);
     361             :   TTreeStream *clayout=0;
     362           0 :   Int_t entries = fDataLayouts->GetEntriesFast();
     363           0 :   for (Int_t i=0;i<entries;i++){
     364           0 :     TTreeStream * layout = (TTreeStream*)fDataLayouts->At(i);
     365           0 :     if (!layout) continue;
     366           0 :     if (fgDisabled?kTRUE:layout->fId==id) {
     367             :       clayout = layout;
     368           0 :       break;
     369             :     }
     370           0 :   }
     371           0 :   if (!clayout){
     372           0 :     TDirectory * backup = gDirectory;
     373           0 :     fDirectory->cd();
     374           0 :     char chname[100];
     375           0 :     snprintf(chname,100,"Tree%d",id);
     376           0 :     clayout = new TTreeStream(chname);
     377           0 :     clayout->fId=id;
     378           0 :     fDataLayouts->AddAt(clayout,entries);
     379           0 :     if (backup) backup->cd();
     380           0 :   }
     381           0 :   return *clayout;
     382           0 : }
     383             : 
     384             : void TTreeSRedirector::SetExternalTree(const char* name, TTree* externalTree)
     385             : {
     386           0 :   TTreeStream *clayout=(TTreeStream*)fDataLayouts->FindObject(name);
     387             : 
     388           0 :   if (!clayout){
     389           0 :     TDirectory * backup = gDirectory;
     390           0 :     fDirectory->cd();
     391           0 :     clayout = new TTreeStream(name,externalTree);
     392           0 :     clayout->fId=-1;
     393           0 :     clayout->SetName(name);
     394           0 :     Int_t entries = fDataLayouts->GetEntriesFast();
     395           0 :     fDataLayouts->AddAt(clayout,entries);
     396           0 :     if (backup) backup->cd();
     397           0 :   }
     398             :   //else
     399             :   //  AliError(Form("identifier %s already associated",name));
     400           0 : }
     401             : 
     402             : 
     403             : TTreeStream  & TTreeSRedirector::operator<<(const char* name)
     404             : {
     405             :   //
     406             :   // return reference to the data layout with given identifier
     407             :   // if not existing - creates new
     408           0 :   if (!fDataLayouts) fDataLayouts = new TObjArray(10000);
     409           0 :   TTreeStream *clayout=(TTreeStream*)fDataLayouts->FindObject(name);
     410           0 :   Int_t entries = fDataLayouts->GetEntriesFast();
     411             : 
     412           0 :   if (!clayout){
     413           0 :     TDirectory * backup = gDirectory;
     414           0 :     fDirectory->cd();
     415           0 :     clayout = new TTreeStream(name);
     416           0 :     clayout->fId=-1;
     417           0 :     clayout->SetName(name);
     418           0 :     fDataLayouts->AddAt(clayout,entries);    
     419           0 :     if (backup) backup->cd();
     420           0 :   }
     421           0 :   return *clayout;
     422           0 : }
     423             : 
     424             : 
     425             : 
     426             : 
     427             : void TTreeSRedirector::Close(){
     428             :   //
     429             :   //
     430           4 :   TDirectory * backup = gDirectory;
     431           2 :   fDirectory->cd();
     432           2 :   if (fDataLayouts){
     433           0 :     Int_t entries = fDataLayouts->GetEntriesFast();
     434           0 :     for (Int_t i=0;i<entries;i++){
     435           0 :       TTreeStream * layout = (TTreeStream*)fDataLayouts->At(i);
     436           0 :       if (layout && !fgDisabled){
     437           0 :         if (layout->fTree) layout->fTree->Write(layout->GetName());
     438             :       }
     439             :     }
     440           0 :     delete fDataLayouts;
     441           0 :     fDataLayouts=0;
     442           0 :   }
     443           4 :   if (backup) backup->cd();
     444           2 : }
     445             : 
     446             : //-------------------------------------------------------------
     447             : TTreeDataElement:: TTreeDataElement(Char_t type) :
     448           0 :   TNamed(),
     449           0 :   fType(type),
     450           0 :   fDType(0),
     451           0 :   fClass(0),
     452           0 :   fPointer(0)
     453           0 : {
     454             :   //
     455             :   //
     456             :   //
     457           0 : }
     458             : 
     459             : TTreeDataElement:: TTreeDataElement(TDataType* type) :
     460           0 :   TNamed(),
     461           0 :   fType(0),
     462           0 :   fDType(type),
     463           0 :   fClass(0),
     464           0 :   fPointer(0)
     465           0 : {
     466             :   //
     467             :   //
     468             :   //
     469           0 : }
     470             : 
     471             : TTreeDataElement:: TTreeDataElement(TClass* cl) :
     472           0 :   TNamed(),
     473           0 :   fType(0),
     474           0 :   fDType(0),
     475           0 :   fClass(cl),
     476           0 :   fPointer(0)
     477           0 : {
     478             :   //
     479             :   //
     480             :   //
     481           0 : }
     482             : 
     483             : //-------------------------------------------------------------------
     484             : TTreeStream::TTreeStream(const char *treename, TTree* externalTree):
     485           0 :   TNamed(treename,treename),
     486           0 :   fElements(0),
     487           0 :   fBranches(0),
     488           0 :   fTree(externalTree),
     489           0 :   fCurrentIndex(0),
     490           0 :   fId(0),
     491           0 :   fNextName(),
     492           0 :   fNextNameCounter(),
     493           0 :   fStatus(0)
     494           0 : {
     495             :   //
     496             :   // Standard ctor
     497             :   //
     498           0 :   if (!fTree) fTree = new TTree(treename, treename);
     499           0 : }
     500             : 
     501             : TTreeStream::~TTreeStream()
     502           0 : {
     503             :   //
     504             :   // Class dtor
     505             :   //
     506           0 :   fElements->Delete();
     507           0 :   fBranches->Clear();
     508           0 :   delete fElements;
     509           0 :   delete fBranches;
     510           0 : }
     511             : 
     512             : void TTreeStream::Close()
     513             : {
     514             :   //
     515             :   // Flush data to disk and close
     516             :   //
     517           0 :   if (TTreeSRedirector::IsDisabled()) return;
     518           0 :   fTree->Write();
     519           0 : }
     520             : 
     521             : Int_t TTreeStream::CheckIn(Char_t type, void *pointer)
     522             : {
     523             :   //
     524             :   // Insert object of given type
     525             :   //
     526           0 :   if (TTreeSRedirector::IsDisabled()) return 0;
     527           0 :   if (!fElements) fElements = new TObjArray(10000);
     528           0 :   if (fElements->GetSize()<=fCurrentIndex) fElements->Expand(fCurrentIndex*2);
     529           0 :   TTreeDataElement* element = (TTreeDataElement*)fElements->At(fCurrentIndex);
     530           0 :   if (!element) {
     531           0 :     element = new TTreeDataElement(type);
     532             :     //
     533           0 :     char name[1000];
     534           0 :     if (fNextName.Length()>0){
     535           0 :       if (fNextNameCounter==0){
     536           0 :         snprintf(name,1000,"%s",(const char*)fNextName);
     537           0 :       }
     538           0 :       if (fNextNameCounter>0){
     539           0 :         snprintf(name,1000,"%s%d",(const char*)fNextName,fNextNameCounter);
     540           0 :       }      
     541             :     }
     542             :     else{
     543           0 :       snprintf(name,1000,"B%d.",fCurrentIndex);
     544             :     }
     545           0 :     element->SetName(name);
     546             :     //
     547           0 :     element->SetPointer(pointer);
     548           0 :     fElements->AddAt(element,fCurrentIndex);
     549           0 :     fCurrentIndex++;
     550             :     return 0; //new element added
     551           0 :   }
     552           0 :   if (element->GetType()!=type){
     553           0 :     fStatus++;
     554           0 :     return 1; //mismatched data element
     555             :   }
     556           0 :   element->SetPointer(pointer);
     557           0 :   fCurrentIndex++;
     558           0 :   return 0;
     559           0 : }
     560             : 
     561             : Int_t TTreeStream::CheckIn(TObject *pObject){
     562             :   //
     563             :   // Insert TObject
     564             :   //
     565           0 :   if (TTreeSRedirector::IsDisabled()) return 0;
     566             :   TClass *pClass = 0;
     567           0 :   if (pObject) pClass=pObject->IsA();
     568           0 :   if (!fElements) fElements = new TObjArray(1000);
     569           0 :   TTreeDataElement* element = (TTreeDataElement*)fElements->At(fCurrentIndex);
     570           0 :   if (!element) {
     571           0 :     element = new TTreeDataElement(pClass);
     572             :     //
     573           0 :     char name[1000];
     574           0 :     if (fNextName.Length()>0){
     575           0 :       if (fNextNameCounter==0){
     576           0 :         snprintf(name,1000,"%s",(const char*)fNextName);
     577           0 :       }
     578           0 :       if (fNextNameCounter>0){
     579           0 :         snprintf(name,1000,"%s%d",(const char*)fNextName,fNextNameCounter);
     580           0 :       }      
     581             :     }
     582             :     else{
     583           0 :       snprintf(name,1000,"B%d",fCurrentIndex);
     584             :     }
     585           0 :     element->SetName(name);
     586             :     
     587           0 :     element->SetPointer(pObject);
     588           0 :     fElements->AddAt(element,fCurrentIndex);
     589           0 :     fCurrentIndex++;
     590             :     return 0; //new element added
     591           0 :   }
     592           0 :   if (element->fClass==0) {
     593           0 :     element->fClass=pClass;
     594           0 :   }else{
     595           0 :     if (element->fClass!=pClass && pClass!=0){
     596           0 :       fStatus++;
     597           0 :       return 1; //mismatched data element
     598             :     }
     599             :   }
     600           0 :   element->SetPointer(pObject);
     601           0 :   fCurrentIndex++;
     602           0 :   return 0;  
     603           0 : }
     604             : 
     605             : void TTreeStream::BuildTree(){
     606             :   //
     607             :   // Build the Tree
     608             :   //
     609             :   //if (fTree && fTree->GetEntries()>0) return;
     610           0 :   if (TTreeSRedirector::IsDisabled()) return;
     611             :   Int_t entriesFilled=0;
     612           0 :   if (!fTree)  {
     613           0 :     fTree = new TTree(GetName(),GetName());
     614           0 :   }else{
     615           0 :     entriesFilled=fTree->GetEntries();
     616             :   }
     617           0 :   Int_t entries = fElements->GetEntriesFast();  
     618           0 :   if (!fBranches) fBranches = new TObjArray(entries);
     619             :   
     620           0 :   for (Int_t i=0;i<entries;i++){
     621             :     //
     622           0 :     TTreeDataElement* element = (TTreeDataElement*)fElements->At(i);
     623           0 :     if (fBranches->At(i)) continue;
     624           0 :     char bname1[1000];
     625           0 :     if (element->GetName()[0]==0){
     626           0 :       snprintf(bname1,1000,"B%d",i);
     627           0 :     }
     628             :     else{
     629           0 :       snprintf(bname1,1000,"%s",element->GetName());
     630             :     }
     631           0 :     if (element->fClass){
     632           0 :       if (element->fClass->GetBaseClass("TClonesArray")){
     633           0 :         TBranch * br = fTree->Branch(bname1,element->fClass->GetName(),&(element->fPointer));
     634           0 :         if (entriesFilled!=0) {
     635           0 :           br->SetAddress(0);
     636           0 :           for (Int_t ientry=0; ientry<entriesFilled;ientry++) br->Fill();
     637           0 :           br->SetAddress(&(element->fPointer));
     638           0 :         }
     639           0 :         fBranches->AddAt(br,i);
     640           0 :       }else
     641             :         {
     642           0 :           TBranch * br = fTree->Branch(bname1,element->fClass->GetName(),&(element->fPointer));
     643           0 :           if (entriesFilled!=0) {
     644           0 :             br->SetAddress(0);
     645           0 :             for (Int_t ientry=0; ientry<entriesFilled;ientry++) br->Fill();
     646           0 :             br->SetAddress(&(element->fPointer));
     647           0 :           }
     648           0 :           fBranches->AddAt(br,i);
     649             :         }
     650             :     }
     651           0 :     if (element->GetType()>0){
     652           0 :       char bname2[1000];
     653           0 :       snprintf(bname2,1000,"B%d/%c",i,element->GetType());
     654           0 :       TBranch * br = fTree->Branch(bname1,element->fPointer,bname2);
     655           0 :       if (entriesFilled!=0) {
     656           0 :         br->SetAddress(0);
     657           0 :         for (Int_t ientry=0; ientry<entriesFilled;ientry++) br->Fill();
     658           0 :         br->SetAddress(element->fPointer);
     659           0 :       }
     660             : 
     661           0 :       fBranches->AddAt(br,i);
     662           0 :     }
     663           0 :   }
     664           0 : }
     665             : 
     666             : void TTreeStream::Fill(){
     667             :   //
     668             :   // Fill the tree
     669             :   //
     670           0 :   if (TTreeSRedirector::IsDisabled()) return;
     671           0 :   if (fTree) { 
     672           0 :     Int_t entries=fElements->GetEntriesFast();
     673           0 :     if (entries>fTree->GetNbranches()) BuildTree();
     674           0 :     for (Int_t i=0;i<entries;i++){    
     675           0 :       TTreeDataElement* el  = (TTreeDataElement*)fElements->At(i);
     676           0 :       if (!el) continue;
     677           0 :       if (!el->GetType()) continue;
     678           0 :       TBranch      * br  = (TBranch*)fBranches->At(i);
     679           0 :       if (br &&el){
     680           0 :         if (el->GetType())  br->SetAddress(el->fPointer);
     681             :       }
     682           0 :     }
     683           0 :     if (fStatus==0) fTree->Fill(); //fill only in case of non conflicts
     684           0 :     fStatus=0;
     685           0 :   }
     686           0 : }
     687             : 
     688             : TTreeStream & TTreeStream::Endl()
     689             : {
     690             :   //
     691             :   // Perform pseudo endl operation
     692             :   //
     693           0 :   if (TTreeSRedirector::IsDisabled()) return *this;
     694           0 :   if (fTree->GetNbranches()==0) BuildTree();
     695           0 :   Fill();
     696           0 :   fStatus =0;
     697           0 :   fCurrentIndex=0;
     698           0 :   return *this;
     699           0 : }
     700             : 
     701             : 
     702             : TTreeStream  &TTreeStream::operator<<(const Char_t *name)
     703             : {
     704             :   //
     705             :   // Endl 
     706             :   //
     707           0 :   if (name[0]=='\n'){
     708           0 :     return Endl();
     709             :   }
     710             :   //
     711             :   //if tree was already defined ignore
     712           0 :   if (fTree->GetEntries()>0) return *this;
     713             :   //check branch name if tree was not 
     714             :   //
     715             :   Int_t last=0;
     716           0 :   for (last=0;;last++){
     717           0 :     if (name[last]==0) break;    
     718             :   }
     719             :   
     720           0 :   if (last>0&&name[last-1]=='='){
     721           0 :     fNextName = name;
     722           0 :     fNextName[last-1]=0;
     723           0 :     fNextNameCounter=0;
     724           0 :   }
     725             :   return *this;
     726           0 : }
     727             : 

Generated by: LCOV version 1.11