From 275f3f2c3caa17e2df82fcecbc543b6dca087e3b Mon Sep 17 00:00:00 2001 From: Rene Brun <Rene.Brun@cern.ch> Date: Thu, 30 Jan 2003 06:40:33 +0000 Subject: [PATCH] From Philippe: This patch adds systematic test for the ability of TTree::Draw to draw TBits objects. It also fixes all the bug discovered during the tests. It also adds a test for split level 2. git-svn-id: http://root.cern.ch/svn/root/trunk@6011 27541ba8-7e3a-0410-8455-c3a389f83636 --- test/Event.cxx | 55 +++++++++++++++++++-- test/Event.h | 5 ++ test/dt_DrawTest.C | 84 ++++++++++++++++++++------------ test/dt_MakeRef.C | 37 +++++++++++++- test/dt_Makefile | 10 +++- test/dt_RunDrawTest.C | 13 +++-- test/dt_RunDrawTest.sh | 69 ++++++++++++++------------ treeplayer/inc/TTreeFormula.h | 4 +- treeplayer/src/TSelectorDraw.cxx | 10 +++- treeplayer/src/TTreeFormula.cxx | 35 ++++++++++--- 10 files changed, 235 insertions(+), 87 deletions(-) diff --git a/test/Event.cxx b/test/Event.cxx index 1a2dde7a217..d76e45bae0b 100644 --- a/test/Event.cxx +++ b/test/Event.cxx @@ -1,4 +1,4 @@ -// @(#)root/test:$Name: $:$Id: Event.cxx,v 1.18 2002/08/07 13:55:45 brun Exp $ +// @(#)root/test:$Name: $:$Id: Event.cxx,v 1.19 2002/08/20 15:21:42 brun Exp $ // Author: Rene Brun 19/08/96 //////////////////////////////////////////////////////////////////////// @@ -156,7 +156,11 @@ void Event::Build(Int_t ev, Int_t arg5, Float_t ptmin) { } } - // Create and Fill the Track objects + fTriggerBits.SetBitNumber((UInt_t)(64*gRandom->Rndm(1))); + fTriggerBits.SetBitNumber((UInt_t)(64*gRandom->Rndm(1))); + fTriggerBits.SetBitNumber((UInt_t)(64*gRandom->Rndm(1))); + + // Create and Fill the Track objects for (Int_t t = 0; t < ntrack; t++) AddTrack(random,ptmin); //Restore Object count @@ -234,7 +238,47 @@ void Event::SetRandomVertex() { } //______________________________________________________________________________ -Track::Track(Float_t random) : TObject() +Track::Track(const Track &orig) : TObject(orig) +{ + // Copy a track object + + fPx = orig.fPx; + fPy = orig.fPy; + fPz = orig.fPx; + fRandom = orig.fRandom; + fMass2 = orig.fMass2; + fBx = orig.fBx; + fBy = orig.fBy; + fMeanCharge = orig.fMeanCharge; + fXfirst = orig.fXfirst; + fXlast = orig.fXlast; + fYfirst = orig.fYfirst; + fYlast = orig.fYlast; + fZfirst = orig.fZfirst; + fZlast = orig.fZlast; + fCharge = orig.fCharge; + + fVertex[0] = orig.fVertex[0]; + fVertex[1] = orig.fVertex[1]; + fVertex[2] = orig.fVertex[2]; + fNpoint = orig.fNpoint; + fNsp = orig.fNsp; + if (fNsp) { + fPointValue = new Float_t[fNsp]; + for(int i=0; i<fNsp; i++) { + fPointValue[i] = orig.fPointValue[i]; + } + } else { + fPointValue = 0; + } + fValid = orig.fValid; + + fTriggerBits = orig.fTriggerBits; + +} + +//______________________________________________________________________________ +Track::Track(Float_t random) : TObject(),fTriggerBits(64) { // Create a track object. // Note that in this example, data members do not have any physical meaning. @@ -264,6 +308,11 @@ Track::Track(Float_t random) : TObject() fZfirst = 50 + 5*a; fZlast = 200 + 10*b; fCharge = Float_t(Int_t(3*gRandom->Rndm(1)) - 1); + + fTriggerBits.SetBitNumber((UInt_t)(64*gRandom->Rndm(1))); + fTriggerBits.SetBitNumber((UInt_t)(64*gRandom->Rndm(1))); + fTriggerBits.SetBitNumber((UInt_t)(64*gRandom->Rndm(1))); + fVertex[0] = gRandom->Gaus(0,0.1); fVertex[1] = gRandom->Gaus(0,0.2); fVertex[2] = gRandom->Gaus(0,10); diff --git a/test/Event.h b/test/Event.h index 0b763fccefb..af894543d3a 100644 --- a/test/Event.h +++ b/test/Event.h @@ -42,9 +42,11 @@ private: Short_t fValid; //Validity criterion Int_t fNsp; //Number of points for this track with a special value Float_t* fPointValue; //[fNsp] a special quantity for some point. + TBits fTriggerBits; //Bits triggered by this track. public: Track() { fPointValue = 0; } + Track(const Track& orig); Track(Float_t random); virtual ~Track() {Clear();} void Clear(Option_t *option="") { delete [] fPointValue; fPointValue=0; } @@ -66,6 +68,7 @@ public: Float_t GetCharge() const { return fCharge; } Float_t GetVertex(Int_t i=0) {return (i<3)?fVertex[i]:0;} Int_t GetNpoint() const { return fNpoint; } + TBits& GetTriggerBits() { return fTriggerBits; } Short_t GetValid() const { return fValid; } virtual void SetValid(Int_t valid=1) { fValid = valid; } Int_t GetN() const { return fNsp; } @@ -113,6 +116,7 @@ private: TRef fLastTrack; //reference pointer to last track TRef fWebHistogram; //EXEC:GetWebHistogram reference to an histogram in a TWebFile TH1F *fH; //-> + TBits fTriggerBits; //Bits triggered by this event. static TClonesArray *fgTracks; static TH1F *fgHist; @@ -152,6 +156,7 @@ public: TH1 *GetWebHistogram() const {return (TH1*)fWebHistogram.GetObject();} Int_t GetMeasure(UChar_t which) { return (which<10)?fMeasures[which]:0; } Float_t GetMatrix(UChar_t x, UChar_t y) { return (x<4&&y<4)?fMatrix[x][y]:0; } + TBits& GetTriggerBits() { return fTriggerBits; } ClassDef(Event,1) //Event structure }; diff --git a/test/dt_DrawTest.C b/test/dt_DrawTest.C index 9adc93994df..3625cc5c6f0 100644 --- a/test/dt_DrawTest.C +++ b/test/dt_DrawTest.C @@ -7,27 +7,31 @@ int gHasLibrary = kFALSE; int gBranchStyle = 1; TList gSkipped; -void DrawSkippable(TTree* tree, const char* what, const char* where, Bool_t skip) { +void DrawSkippable(TTree* tree, const char* what, const char* where, Bool_t draw) { //cerr << "Doing " << what << " which is " << skip << endl; - if (skip) gSkipped.Add(new TNamed(where,where)); - else { + if (draw) { TString cut = what; cut.Append(">>"); cut.Append(where); tree->Draw(cut.Data(),"","goff"); + + } else { + gSkipped.Add(new TNamed(where,where)); } + }; void DrawSkippable(TTree* tree, const char* what, const char* cond, - const char* where, Bool_t skip) { - //cerr << "Doing " << what << " which is " << skip << endl; - if (skip) gSkipped.Add(new TNamed(where,where)); - else { - TString cut = what; - cut.Append(">>"); - cut.Append(where); - tree->Draw(cut.Data(),cond,"goff"); - } + const char* where, Bool_t draw) { + //cerr << "Doing " << what << " which is " << skip << endl; + if (draw) { + TString cut = what; + cut.Append(">>"); + cut.Append(where); + tree->Draw(cut.Data(),cond,"goff"); + } else { + gSkipped.Add(new TNamed(where,where)); + } }; // Rootmarks for fcdflnx1 is 153.4 @@ -50,7 +54,7 @@ void DrawMarks() { //_______________________________________________________________ -TDirectory* GenerateDrawHist(TTree *tree,int level = 1, int quietLevel = 0) +TDirectory* GenerateDrawHist(TTree *tree,int level = 2, int quietLevel = 0) { // Test selections via TreeFormula // tree is a TTree when called by stress9 @@ -66,7 +70,7 @@ TDirectory* GenerateDrawHist(TTree *tree,int level = 1, int quietLevel = 0) gBenchmark->Start("DrawTest"); // Each tree->Draw generates an histogram - DrawSkippable(tree,"GetNtrack()","hGetNtrack",!(level>0 && gHasLibrary)); + DrawSkippable(tree,"GetNtrack()","hGetNtrack",(level>0 && gHasLibrary)); //gBenchmark->Show("DrawTest"); gBenchmark->Start("DrawTest"); @@ -77,12 +81,12 @@ TDirectory* GenerateDrawHist(TTree *tree,int level = 1, int quietLevel = 0) tree->Draw("fH.GetMean()>>hHmean","","goff"); if (level>0) tree->Draw("fH.fXaxis.fXmax>>hHAxisMax","","goff"); if (level>0) tree->Draw("fH.fXaxis.GetXmax()>>hHAxisGetMax","","goff"); - DrawSkippable(tree,"fH.GetXaxis().GetXmax()","hHGetAxisGetMax",!(level>0)); - DrawSkippable(tree,"fH.GetXaxis().fXmax","hHGetAxisMax",!(level>0)); + DrawSkippable(tree,"fH.GetXaxis().GetXmax()","hHGetAxisGetMax",(level>0)); + DrawSkippable(tree,"fH.GetXaxis().fXmax","hHGetAxisMax",(level>0)); DrawSkippable(tree,"GetHistogram().GetXaxis().GetXmax()","hGetHGetAxisMax", - !(level>0&&gHasLibrary)); + (level>0&&gHasLibrary)); DrawSkippable(tree,"event.GetHistogram().GetXaxis().GetXmax()", - "hGetRefHGetAxisMax",!(level>0&&gHasLibrary)); + "hGetRefHGetAxisMax",(level>0&&gHasLibrary)); tree->Draw("fTracks.fPx>>hPx","fEvtHdr.fEvtNum%10 == 0","goff"); tree->Draw("fTracks.fPy>>hPy","fEvtHdr.fEvtNum%10 == 0","goff"); @@ -100,7 +104,7 @@ TDirectory* GenerateDrawHist(TTree *tree,int level = 1, int quietLevel = 0) tree->Draw("fCharge>>hCharge","fPx < 0","goff"); tree->Draw("fNpoint>>hNpoint","fPx < 0","goff"); tree->Draw("fValid>>hValid", "fPx < 0","goff"); - DrawSkippable(tree,"fPointValue","hPointValue", gBranchStyle==0); + DrawSkippable(tree,"fPointValue","hPointValue", gBranchStyle!=0); tree->Draw("fMatrix>>hFullMatrix","","goff"); tree->Draw("fMatrix[][0]>>hColMatrix","","goff"); @@ -124,28 +128,44 @@ TDirectory* GenerateDrawHist(TTree *tree,int level = 1, int quietLevel = 0) // Test variable indexing DrawSkippable(tree,"fClosestDistance[fNvertex/2]","hClosestDistanceIndex", - !(level>0)); - DrawSkippable(tree,"fPx:fPy[fNpoint/6]","fPy[fNpoint/6]>0","hPxInd",!(level>0)); + (level>0)); + DrawSkippable(tree,"fPx:fPy[fNpoint/6]","fPy[fNpoint/6]>0","hPxInd",(level>0)); // Test of simple function calls - DrawSkippable(tree,"sqrt(fNtrack)","hSqrtNtrack",!(level>0)); + DrawSkippable(tree,"sqrt(fNtrack)","hSqrtNtrack",(level>0)); // Test string operations - DrawSkippable(tree,"fEvtHdr.fEvtNum","fType==\"type1\" ","hString",!(level>0)); - DrawSkippable(tree,"fEvtHdr.fEvtNum","strstr(fType,\"1\") ","+hString",!(level>0)); + DrawSkippable(tree,"fEvtHdr.fEvtNum","fType==\"type1\" ","hString",(level>0)); + DrawSkippable(tree,"fEvtHdr.fEvtNum","strstr(fType,\"1\") ","+hString",(level>0)); // Test binary operators - DrawSkippable(tree,"fValid<<4","hShiftValid",!(level>0)); - DrawSkippable(tree,"((fValid<<4)>>2)","+hShiftValid",!(level>0)); + DrawSkippable(tree,"fValid<<4","hShiftValid",(level>0)); + DrawSkippable(tree,"((fValid<<4)>>2)","+hShiftValid",(level>0)); DrawSkippable(tree,"fValid&0x1","(fNvertex>10) && (fNseg<=6000)" - ,"hAndValid",!(level>0)); + ,"hAndValid",(level>0)); // Test weight - DrawSkippable(tree,"fPx","(fBx>.25) || (fBy<=-.25)","hPxBx",!(level>0)); - DrawSkippable(tree,"fPx","fBx*fBx*(fBx>.25) + fBy*fBy*(fBy<=-.25)", - "hPxBxWeight",!(level>0)); - - if (quietLevel<2) gBenchmark->Show("DrawTest"); + DrawSkippable(tree,"fPx","(fBx>.15) || (fBy<=-.15)","hPxBx",(level>0)); + DrawSkippable(tree,"fPx","fBx*fBx*(fBx>.15) + fBy*fBy*(fBy<=-.15)", + "hPxBxWeight",(level>0)); + + DrawSkippable(tree,"event.fTriggerBits", + "hTriggerBits",level>1 && gBranchStyle!=0); + DrawSkippable(tree,"event.fTriggerBits.fNbits", + "event.fTriggerBits.TestBitNumber(10)", + "hFiltTriggerBits",level>1 && gBranchStyle!=0); + + DrawSkippable(tree,"event.GetTriggerBits()", + "hTriggerBitsFunc",level>1 && gBranchStyle!=0 && gHasLibrary ); + + DrawSkippable(tree,"fTracks.fTriggerBits", + "hTrackTrigger", level>1 && gBranchStyle!=0); + DrawSkippable(tree,"fPx", + "fTracks.fTriggerBits.TestBitNumber(5)", + "hFiltTrackTrigger", level>1 && gBranchStyle!=0); + + + if (quietLevel<2) gBenchmark->Show("DrawTest"); else gBenchmark->Stop("DrawTest"); gBenchmark->Start("DrawTest"); diff --git a/test/dt_MakeRef.C b/test/dt_MakeRef.C index faf044a2123..c389b0bd6df 100644 --- a/test/dt_MakeRef.C +++ b/test/dt_MakeRef.C @@ -101,6 +101,13 @@ void MakeHisto(TTree *tree, TDirectory* To) { TH1F *refPxBx = RefClone(where,"hPxBx"); TH1F *refPxBxWeight = RefClone(where,"hPxBxWeight"); + TH1F *refTriggerBits = RefClone(where,"hTriggerBits"); + TH1F *refTriggerBitsFunc = RefClone(where,"hTriggerBitsFunc"); + TH1F *refFiltTriggerBits = RefClone(where,"hFiltTriggerBits"); + + TH1F *refTrackTrigger = RefClone(where,"hTrackTrigger"); + TH1F *refFiltTrackTrigger = RefClone(where,"hFiltTrackTrigger"); + // Loop with user code on all events and fill the ref histograms // The code below should produce identical results to the tree->Draw above @@ -151,6 +158,20 @@ void MakeHisto(TTree *tree, TDirectory* To) { } refCellMatrix->Fill(event->GetMatrix(2,2)); + TBits bits = event->GetTriggerBits(); + Int_t nbits = bits.GetNbits(); + Int_t ncx = refTriggerBits->GetXaxis()->GetNbins(); + Int_t nextbit = -1; + while(1) { + nextbit = bits->FirstSetBit(nextbit+1); + if (nextbit >= nbits) break; + if (nextbit > ncx) refTriggerBits->Fill(ncx+1); + else refTriggerBits->Fill(nextbit); + if (nextbit > ncx) refTriggerBitsFunc->Fill(ncx+1); + else refTriggerBitsFunc->Fill(nextbit); + } + if (bits.TestBitNumber(10)) refFiltTriggerBits->Fill(nbits); + ntracks = event->GetNtrack(); if ( 5 < ntracks ) { t = (Track*)tracks->UncheckedAt(5); @@ -200,8 +221,8 @@ void MakeHisto(TTree *tree, TDirectory* To) { float Bx,By; Bx = t->GetBx(); By = t->GetBy(); - if ((Bx>.25) || (By<=-.25)) refPxBx->Fill(t->GetPx()); - double weight = Bx*Bx*(Bx>.25) + By*By*(By<=-.25); + if ((Bx>.15) || (By<=-.15)) refPxBx->Fill(t->GetPx()); + double weight = Bx*Bx*(Bx>.15) + By*By*(By<=-.15); if (weight) refPxBxWeight->Fill(t->GetPx(),weight); if (i<4) { @@ -215,6 +236,18 @@ void MakeHisto(TTree *tree, TDirectory* To) { for(i1=0; i1<t->GetN(); i1++) { refPointValue->Fill( t->GetPointValue(i1) ); } + TBits bits = t->GetTriggerBits(); + Int_t nbits = bits.GetNbits(); + Int_t ncx = refTrackTrigger->GetXaxis()->GetNbins(); + Int_t nextbit = -1; + while(1) { + nextbit = bits->FirstSetBit(nextbit+1); + if (nextbit >= nbits) break; + if (nextbit > ncx) refTrackTrigger->Fill(ncx+1); + else refTrackTrigger->Fill(nextbit); + } + if (bits.TestBitNumber(5)) refFiltTrackTrigger->Fill(t->GetPx()); + } } diff --git a/test/dt_Makefile b/test/dt_Makefile index 6efa81da9c4..90962e01aa4 100644 --- a/test/dt_Makefile +++ b/test/dt_Makefile @@ -8,7 +8,8 @@ action=1 include ./Makefile -DATAFILES = Event.new.split0.root Event.new.split1.root Event.new.split9.root \ +DATAFILES = Event.new.split0.root Event.new.split1.root \ + Event.new.split2.root Event.new.split9.root \ Event.old.streamed.root Event.old.split.root REFFILE=dt_reference.root @@ -27,6 +28,11 @@ Event.new.split1.root : Event$(ExeSuf) libEvent.$(DllSuf) mv Event.root Event.new.split1.root && \ echo "$@ made" +Event.new.split2.root : Event$(ExeSuf) libEvent.$(DllSuf) + @./Event $(size) $(comp) 2 $(action) $(tracks) $(OUTPUT) && \ + mv Event.root Event.new.split2.root && \ + echo "$@ made" + Event.new.split9.root : Event$(ExeSuf) libEvent.$(DllSuf) @./Event $(size) $(comp) 9 $(action) $(tracks) $(OUTPUT) && \ mv Event.root Event.new.split9.root && \ @@ -52,7 +58,7 @@ Streamer="Event::Streamer not available," dt_RunDrawTest_C.$(DllSuf) : dt_RunDrawTest.C dt_DrawTest.C - @root -l -b -q 'gSystem->Exit(!gSystem->CompileMacro("dt_RunDrawTest.C","kf"));' | $(OUTPUT) && \ + @root -l -b -q dt_build.C $(OUTPUT) && \ echo "$@ made" #Windows does not like piping diff --git a/test/dt_RunDrawTest.C b/test/dt_RunDrawTest.C index 03ee0d33139..16bef0dddf7 100644 --- a/test/dt_RunDrawTest.C +++ b/test/dt_RunDrawTest.C @@ -21,7 +21,8 @@ Int_t HistCompare(TH1 *ref, TH1 *comp) // Compare histograms h1 and h2 // Check number of entries, mean and rms // if means differ by more than 1/1000 of the range return -1 -// if rms differs in percent by more than 1/1000 return -2 +// if means differ by more than 1/100 of the original mean return -2 +// if rms differs in percent by more than 1/1000 return -3 // Otherwise return difference of number of entries Int_t n1 = (Int_t)ref->GetEntries(); @@ -38,9 +39,10 @@ Int_t HistCompare(TH1 *ref, TH1 *comp) } Float_t xrange = ref->GetXaxis()->GetXmax() - ref->GetXaxis()->GetXmin(); - if (xrange==0) fprintf(stderr,"no range for %s\n",ref->GetName()); - if (TMath::Abs((mean1-mean2)/xrange) > 0.001*xrange) return -1; - if (rms1 && TMath::Abs((rms1-rms2)/rms1) > 0.001) return -2; + if (xrange==0) { fprintf(stderr,"no range for %s\n",ref->GetName()); return -4; } + if (xrange>0.0001 && TMath::Abs((mean1-mean2)/xrange) > 0.001) return -1; + if (mean2> 0.0001 && TMath::Abs((mean1-mean2)/mean2) > 0.01) return -2; + if (rms1 > 0.0001 && TMath::Abs((rms1-rms2)/rms1) > 0.0001) return -3; return n1*factor-n2; } @@ -53,6 +55,7 @@ Int_t Compare(TDirectory* from) { Int_t comp; Int_t fail = 0; TKey* key; + while ((key=(TKey*)next())) { if (strcmp(key->GetClassName(),"TH1F") && strcmp(key->GetClassName(),"TH2F") ) @@ -169,7 +172,7 @@ bool dt_RunDrawTest(const char* from, Int_t mode = 0, Int_t verboseLevel = 0) { // cerr << "Branch style is " << gBranchStyle << endl; if (gQuietLevel<2) cout << "Generating histograms from TTree::Draw" << endl; - TDirectory* where = GenerateDrawHist(tree,1,gQuietLevel); + TDirectory* where = GenerateDrawHist(tree,2,gQuietLevel); if (gQuietLevel<2) cout << "Comparing histograms" << endl; if (Compare(where)>0) { diff --git a/test/dt_RunDrawTest.sh b/test/dt_RunDrawTest.sh index 7ac0ee598ed..f4ad43d9032 100755 --- a/test/dt_RunDrawTest.sh +++ b/test/dt_RunDrawTest.sh @@ -1,48 +1,55 @@ -#!/bin/sh +#!/bin/sh # Previous step is to do something like # root -l -q 'MakeRef.C("Event.old.split.root");' ClassWarning='Warning in <TClass::TClass>: no dictionary for class' RootPrompt='root \[0\]' +EmptyLine='^$' Streamer="Event::Streamer not available," # launch replace # root.exe -l -b 'dt_RunDrawTest.C+("Event.new.split9.root",0)' launch () { - echo test $1 level $2 +# echo test $1 level $2 # (echo 'gROOT->ProcessLine(".L dt_RunDrawTest.C+");gSystem->Exit(!dt_RunDrawTest("'$1'",'$2'));' | root.exe -l -b 2>&1; return $?;) | grep -v "$3"; # (root.exe -l -b -q 'gROOT->ProcessLine(".L dt_RunDrawTest.C+");gSystem->Exit(!dt_RunDrawTest("'$1'",'$2'));' 2>&1; return $?;) | grep -v "$3"; (root.exe -l -b -q 'dt_wrap.C("'$1'",'$2')' 2>&1; return $?;) | grep -v "$3"; } -launch "Event.old.split.root" 0 "$ClassWarning\|$RootPrompt" && \ -launch "Event.old.split.root" 1 "$RootPrompt" && \ -launch "Event.old.split.root" 2 "$ClassWarning\|$RootPrompt" && \ -launch "Event.old.split.root" 3 "$RootPrompt" && \ -launch "Event.old.split.root" 4 "$RootPrompt" - -launch "Event.old.streamed.root" 0 "$Streamer\|$ClassWarning\|$RootPrompt" && \ -launch "Event.old.streamed.root" 1 "$RootPrompt" && \ -launch "Event.old.streamed.root" 2 "$ClassWarning\|$RootPrompt" && \ -launch "Event.old.streamed.root" 3 "$RootPrompt" && \ -launch "Event.old.streamed.root" 4 "$RootPrompt" - -launch "Event.new.split9.root" 0 "$ClassWarning\|$RootPrompt" && \ -launch "Event.new.split9.root" 1 "$RootPrompt" && \ -launch "Event.new.split9.root" 2 "$ClassWarning\|$RootPrompt" && \ -launch "Event.new.split9.root" 3 "$RootPrompt" && \ -launch "Event.new.split9.root" 4 "$RootPrompt" - -launch "Event.new.split1.root" 0 "$ClassWarning\|$RootPrompt" && \ -launch "Event.new.split1.root" 1 "$RootPrompt" && \ -launch "Event.new.split1.root" 2 "$ClassWarning\|$RootPrompt" && \ -launch "Event.new.split1.root" 3 "$RootPrompt" && \ -launch "Event.new.split1.root" 4 "$RootPrompt" - -launch "Event.new.split0.root" 0 "$Streamer\|$ClassWarning\|$RootPrompt" && \ -launch "Event.new.split0.root" 1 "$RootPrompt" && \ -launch "Event.new.split0.root" 2 "$ClassWarning\|$RootPrompt" && \ -launch "Event.new.split0.root" 3 "$RootPrompt" && \ -launch "Event.new.split0.root" 4 "$RootPrompt" +launch "Event.old.split.root" 0 "$ClassWarning\|$RootPrompt\|$EmptyLine" && \ +launch "Event.old.split.root" 1 "$RootPrompt\|$EmptyLine" && \ +launch "Event.old.split.root" 2 "$ClassWarning\|$RootPrompt\|$EmptyLine" && \ +launch "Event.old.split.root" 3 "$RootPrompt\|$EmptyLine" && \ +launch "Event.old.split.root" 4 "$RootPrompt\|$EmptyLine" + +launch "Event.old.streamed.root" 0 "$Streamer\|$ClassWarning\|$RootPrompt\|$EmptyLine" && \ +launch "Event.old.streamed.root" 1 "$RootPrompt\|$EmptyLine" && \ +launch "Event.old.streamed.root" 2 "$ClassWarning\|$RootPrompt\|$EmptyLine" && \ +launch "Event.old.streamed.root" 3 "$RootPrompt\|$EmptyLine" && \ +launch "Event.old.streamed.root" 4 "$RootPrompt\|$EmptyLine" + +launch "Event.new.split9.root" 0 "$ClassWarning\|$RootPrompt\|$EmptyLine" && \ +launch "Event.new.split9.root" 1 "$RootPrompt\|$EmptyLine" && \ +launch "Event.new.split9.root" 2 "$ClassWarning\|$RootPrompt\|$EmptyLine" && \ +launch "Event.new.split9.root" 3 "$RootPrompt\|$EmptyLine" && \ +launch "Event.new.split9.root" 4 "$RootPrompt\|$EmptyLine" + +launch "Event.new.split2.root" 0 "$ClassWarning\|$RootPrompt\|$EmptyLine" && \ +launch "Event.new.split2.root" 1 "$RootPrompt\|$EmptyLine" && \ +launch "Event.new.split2.root" 2 "$ClassWarning\|$RootPrompt\|$EmptyLine" && \ +launch "Event.new.split2.root" 3 "$RootPrompt\|$EmptyLine" && \ +launch "Event.new.split2.root" 4 "$RootPrompt\|$EmptyLine" + +launch "Event.new.split1.root" 0 "$ClassWarning\|$RootPrompt\|$EmptyLine" && \ +launch "Event.new.split1.root" 1 "$RootPrompt\|$EmptyLine" && \ +launch "Event.new.split1.root" 2 "$ClassWarning\|$RootPrompt\|$EmptyLine" && \ +launch "Event.new.split1.root" 3 "$RootPrompt\|$EmptyLine" && \ +launch "Event.new.split1.root" 4 "$RootPrompt\|$EmptyLine" + +launch "Event.new.split0.root" 0 "$Streamer\|$ClassWarning\|$RootPrompt\|$EmptyLine" && \ +launch "Event.new.split0.root" 1 "$RootPrompt\|$EmptyLine" && \ +launch "Event.new.split0.root" 2 "$ClassWarning\|$RootPrompt\|$EmptyLine" && \ +launch "Event.new.split0.root" 3 "$RootPrompt\|$EmptyLine" && \ +launch "Event.new.split0.root" 4 "$RootPrompt\|$EmptyLine" diff --git a/treeplayer/inc/TTreeFormula.h b/treeplayer/inc/TTreeFormula.h index df5d6011883..801e19dec72 100644 --- a/treeplayer/inc/TTreeFormula.h +++ b/treeplayer/inc/TTreeFormula.h @@ -1,4 +1,4 @@ -// @(#)root/treeplayer:$Name: $:$Id: TTreeFormula.h,v 1.25 2002/08/01 21:33:48 brun Exp $ +// @(#)root/treeplayer:$Name: $:$Id: TTreeFormula.h,v 1.26 2003/01/24 07:04:29 brun Exp $ // Author: Rene Brun 19/01/96 /************************************************************************* @@ -110,7 +110,7 @@ public: TTreeFormula(const char *name,const char *formula, TTree *tree); virtual ~TTreeFormula(); virtual Int_t DefinedVariable(TString &variable); - virtual TClass* EvalClass(); + virtual TClass* EvalClass() const; virtual Double_t EvalInstance(Int_t i=0); virtual void* EvalObject(Int_t i=0); // EvalInstance should be const. See comment on GetNdata() diff --git a/treeplayer/src/TSelectorDraw.cxx b/treeplayer/src/TSelectorDraw.cxx index 234e25335aa..7fb65cea2e9 100644 --- a/treeplayer/src/TSelectorDraw.cxx +++ b/treeplayer/src/TSelectorDraw.cxx @@ -1,4 +1,4 @@ -// @(#)root/treeplayer:$Name: $:$Id: TSelectorDraw.cxx,v 1.5 2003/01/17 17:48:09 brun Exp $ +// @(#)root/treeplayer:$Name: $:$Id: TSelectorDraw.cxx,v 1.6 2003/01/24 07:04:29 brun Exp $ // Author: Rene Brun 08/01/2003 /************************************************************************* @@ -926,7 +926,7 @@ void TSelectorDraw::ProcessFillObject(Int_t /*entry*/) TClass *cl = fVar1->EvalClass(); if (cl==TBits::Class()) { - void *obj = fVar1->EvalObject(); + void *obj = fVar1->EvalObject(i); TBits *bits = (TBits*)obj; Int_t nbits = bits->GetNbits(); @@ -940,6 +940,12 @@ void TSelectorDraw::ProcessFillObject(Int_t /*entry*/) fNfill++; } + } else { + + Warning("ProcessFillObject", + "Not implemented for %s", + cl?cl->GetName():"unknown class"); + } } } diff --git a/treeplayer/src/TTreeFormula.cxx b/treeplayer/src/TTreeFormula.cxx index 8c3b97511ca..eca2cd1f008 100644 --- a/treeplayer/src/TTreeFormula.cxx +++ b/treeplayer/src/TTreeFormula.cxx @@ -1,4 +1,4 @@ -// @(#)root/treeplayer:$Name: $:$Id: TTreeFormula.cxx,v 1.107 2003/01/17 17:48:09 brun Exp $ +// @(#)root/treeplayer:$Name: $:$Id: TTreeFormula.cxx,v 1.108 2003/01/24 07:04:29 brun Exp $ // Author: Rene Brun 19/01/96 /************************************************************************* @@ -1973,7 +1973,7 @@ Int_t TTreeFormula::DefinedVariable(TString &name) strcat(right,&cname[i]); } - if (!final && branch) { // NOTE: should we add && !leaf ??? + if (!final && branch && !leaf) { // NOTE: should we add && !leaf ??? leaf = (TLeaf*)branch->GetListOfLeaves()->UncheckedAt(0); if (!leaf) return -1; final = leaf->IsOnTerminalBranch(); @@ -2114,8 +2114,8 @@ Int_t TTreeFormula::DefinedVariable(TString &name) } break; } - // If we have a got a class object, we need to verify whether it is on a split TClonesArray - // sub branch. + // If we got a class object, we need to verify whether it is on a + // split TClonesArray sub branch. if (cl && BranchEl->GetBranchCount()) { if (BranchEl->GetType()==31) { // This is inside a TClonesArray. @@ -2144,6 +2144,20 @@ Int_t TTreeFormula::DefinedVariable(TString &name) maininfo->fNext = previnfo; } + } else if (BranchEl->GetType()==3) { + + TFormLeafInfo* clonesinfo = new TFormLeafInfoClones(cl, 0, &gFakeClonesElem, kTRUE); + // The dimension needs to be handled! + numberOfVarDim += RegisterDimensions(code,clonesinfo); + + maininfo = clonesinfo; + previnfo = maininfo; + + } else if (strlen(right)==0 && cl && element && !element->IsaPointer() && final) { + + maininfo = new TFormLeafInfoDirect(BranchEl); + previnfo = maininfo; + } } if (cl) { @@ -3021,7 +3035,7 @@ Int_t TTreeFormula::GetRealInstance(Int_t instance, Int_t codeindex) { } //______________________________________________________________________________ -TClass* TTreeFormula::EvalClass() +TClass* TTreeFormula::EvalClass() const { //*-*-*-*-*-*-*-*-*-*-*Evaluate the class of this treeformula*-*-*-*-*-*-*-*-*-* //*-* ====================================== @@ -3037,8 +3051,11 @@ TClass* TTreeFormula::EvalClass() if (leaf->IsA()==TLeafObject::Class()) { return ((TLeafObject*)leaf)->GetClass(); } else if ( leaf->IsA()==TLeafElement::Class()) { - TBranchElement * br = (TBranchElement*)((TLeafElement*)leaf)->GetBranch(); - return gROOT->GetClass( br->GetTypeName() ); + TBranchElement * branch = (TBranchElement*)((TLeafElement*)leaf)->GetBranch(); + TStreamerInfo * info = branch->GetInfo(); + Int_t id = branch->GetID(); + TStreamerElement* elem = (TStreamerElement*)info->GetElements()->At(id); + return gROOT->GetClass( elem->GetTypeName() ); } else { return 0; } @@ -3086,7 +3103,7 @@ void* TTreeFormula::EvalObject(int instance) switch(fLookupType[0]) { case kDirect: { if (real_instance) { - Warning("EvalObject","Not yet implement for kDirect and arrays.\nPlease contact the developers (%s)\n",GetName()); + Warning("EvalObject","Not yet implement for kDirect and arrays (for %s).\nPlease contact the developers \n",GetName()); } return leaf->GetValuePointer(); } @@ -3494,6 +3511,8 @@ Bool_t TTreeFormula::IsInteger(Int_t code) const return kFALSE; } } + + if (EvalClass()==TBits::Class()) return kTRUE; TLeaf *leaf = (TLeaf*)fLeaves.At(code); if (!leaf) return kFALSE; -- GitLab