Presentation is loading. Please wait.

Presentation is loading. Please wait.

ROOT courses1 The ROOT System A Data Access & Analysis Framework 4-5-6 February 2003 Ren é Brun/EP Input/Output.

Similar presentations


Presentation on theme: "ROOT courses1 The ROOT System A Data Access & Analysis Framework 4-5-6 February 2003 Ren é Brun/EP Input/Output."— Presentation transcript:

1 ROOT courses1 The ROOT System A Data Access & Analysis Framework 4-5-6 February 2003 Ren é Brun/EP http://root.cern.ch Input/Output

2 R.Brun LCG ROOT corses2

3 R.Brun LCG ROOT corses3 ROOT + RDBMS Model histograms Calibrations Geometries Run/File Catalog Trees Event Store ROOT files Oracle MySQL

4 R.Brun LCG ROOT corses4 Ideal Persistency transient persistent Automatic converters obj1;1, obj1;2,obj1;3 obj2;1, obj2;2 Automatic schema evolution Efficient storage compression Granularity matching access patterns Remote access LAN WAN Machine independent format No constraints on object model

5 R.Brun LCG ROOT corses5 Evolution of ROOT I/O Hand-written Streamers Streamers generated via rootcint Support for Class Versions Support for ByteCount Persistent class Dictionary written to files rootcint modified to generate automatic Streamers Support for Automatic Schema Evolution Can generate code for “DataObjects” classes in a file Support for STL and more complex C++ cases Can read files without the classes Persistent Reference pointers Support for foreign classes 3.00 3.01 1995 2003 3.02 New 3.04

6 R.Brun LCG ROOT corses6 Object Persistency (in a nutshell) Two I/O modes supported (Keys and Trees). Key access: simple object streaming mode. A ROOT file is like a Unix directory tree Very convenient for objects like histograms, geometries, mag.field, calibrations Trees A generalization of ntuples to objects Designed for storing events split and no split modes query processor Chains: Collections of files containing Trees ROOT files are self-describing Interfaces with RDBMS also available Access to remote files (RFIO, DCACHE, GRID)

7 R.Brun LCG ROOT corses7 ROOT I/O : An Example TFile f(“example.root”,”new”); TH1F h(“h”,”My histogram”,100,-3,3); h.FillRandom(“gaus”,5000); h.Write(); TFile f(“example.root”); TH1F *h = (TH1F*)f.Get(“h”): h->Draw(); f.Map(); Program Writing Program Reading 20010831/171903 At:64 N=90 TFile 20010831/171941 At:154 N=453 TH1F CX = 2.09 20010831/171946 At:607 N=2364 StreamerInfo CX = 3.25 20010831/171946 At:2971 N=96 KeysList 20010831/171946 At:3067 N=56 FreeSegments 20010831/171946 At:3123 N=1 END demoh.C demohr.C

8 R.Brun LCG ROOT corses8 All what you need to known to navigate in a ROOT file

9 R.Brun LCG ROOT corses9 ROOT files can be structured like a Unix file system

10 R.Brun LCG ROOT corses10 A Root file pippa.root with two levels of directories Objects in directory /pippa/DM/CJ eg: /pippa/DM/CJ/h15

11 R.Brun LCG ROOT corses11 Browsing the file root [0] TFile f("demo1.root") root [1] TBrowser b root [2] f.ls(); root [3] f.Map(); root [4] hit2.Dump(); theEntryPoint ->874a01c position theEntryPoint.theVector ->874a01c theEntryPoint.theVector.theX 1 theEntryPoint.theVector.theY 2 theEntryPoint.theVector.theZ 3 theExitPoint ->874a030 theExitPoint.theVector ->874a030 theExitPoint.theVector.theX 10 theExitPoint.theVector.theY 20 theExitPoint.theVector.theZ 30 thePabs 41 momentum theTof 1.67e-08 Time Of Flight theEnergyLoss 0.00578 Energy loss theParticleType 12 theDetUnitId 67 theTrackId 1234 fUniqueID 0 object unique identifier fBits 50331648 bit field status word TFile* demo1.root KEY: PSimHit hit1;1 KEY: PSimHit hit2;1 20011008/091050 At:64 N=86 TFile 20011008/091050 At:150 N=128 KeysList Address = 278 Nbytes = -27 =====G A P=========== 20011008/091050 At:305 N=140 PSimHit 20011008/091050 At:445 N=140 PSimHit 20011008/091050 At:585 N=952 StreamerInfo CX = 2.66 20011008/091050 At:1537 N=64 FreeSegments 20011008/091050 At:1601 N=1 END The description of all classes in a file is written in one single record when the file is closed StreamerInfo

12 R.Brun LCG ROOT corses12 Example with CMS classes In the following slides we will use the CMS simulation classes PSimHit, etc. Classes suggested by Vincenzo as exercise. Goal: No changes in the class model. Example1: How to generate the dictionary Example2: How to write PSimHit objects to a ROOT file (and read) Example3: How to write PSimHit objects to a Tree (and read) ftp://root.cern.ch/root/courses.tar.gz

13 R.Brun LCG ROOT corses13 PSimHit.h #include "LocalPoint.h" #include "LocalVector.h" #include "TObject.h" class DetUnit; class PSimHit : public TObject { public: PSimHit() : theDetUnitId(-1) {} PSimHit( const Local3DPoint& entry, const Local3DPoint& exit, float pabs, float tof, float eloss, int particleType, int detId, unsigned int trackId) : theEntryPoint( entry), theExitPoint(exit),..... float pabs() const {return thePabs;} float tof() const {return theTof;} float energyLoss() const {return theEnergyLoss;} int particleType() const {return theParticleType;} int detUnitId() const {return theDetUnitId;} unsigned int trackId() const {return theTrackId;} private: // properties Local3DPoint theEntryPoint; // position Local3DPoint theExitPoint; float thePabs; // momentum float theTof; // Time Of Flight float theEnergyLoss; // Energy loss int theParticleType; // association int theDetUnitId; unsigned int theTrackId; ClassDef(PSimHit,1) }; #include "LocalTag.h" #include "Point2DBase.h" #include "Point3DBase.h" typedef Point2DBase Local2DPoint; typedef Point3DBase Local3DPoint; // Local points are two-dimensional by default typedef Local3DPoint LocalPoint ;

14 R.Brun LCG ROOT corses14 Point3DBase.h #include "PV3DBase.h" #include "Point2DBase.h" #include "Vector3DBase.h" template class Point3DBase : public PV3DBase { public: typedef PV3DBase BaseClass; typedef Vector3DBase VectorType; typedef Basic3DVector BasicVectorType; Point3DBase() {} Point3DBase(const T& x, const T& y, const T& z) : BaseClass(x, y, z) {} ……. };

15 R.Brun LCG ROOT corses15 Point3DBase.h #include "Basic3DVector.h" #include template class PV3DBase { public: typedef Basic3DVector BasicVectorType; PV3DBase() : theVector() {} PV3DBase(const T & x, const T & y, const T & z) : theVector(x, y, z) {} PV3DBase( const Basic3DVector & v) : theVector(v) {} T x() const { return basicVector().x();} T y() const { return basicVector().y();} T mag2() const { return basicVector().mag2();} T r() const { return basicVector().r();} …….. protected: BasicVectorType& basicVector() { return theVector;} private: BasicVectorType theVector; };

16 R.Brun LCG ROOT corses16 Basic3DVector.h #include "Basic2DVector.h" #include template class Basic3DVector { public: // default constructor Basic3DVector() : theX(0), theY(0), theZ(0){} Basic3DVector( const T& x, const T& y, const T& z) : theX(x), theY(y), theZ(z) {} T x() const { return theX;} T y() const { return theY;} T z() const { return theZ;} …... private: T theX; T theY; T theZ; };

17 R.Brun LCG ROOT corses17 Running rootcint on PSimHit.h Building the shared lib rootcint -f Dict.cxx -c PSimHit.h LinkDef.h g++ -fPIC -I$ROOTSYS/include -c Dict.cxx g++ -fPIC -I$ROOTSYS/include -c PSimHit.cxx g++ -shared -g PSimHit.o Dict.o -o libHit.so #pragma link off all globals; #pragma link off all classes; #pragma link off all functions; #pragma link C++ class LocalTag+; #pragma link C++ class PointTag+; #pragma link C++ class VectorTag+; #pragma link C++ class Basic2DVector +; #pragma link C++ class Basic3DVector +; #pragma link C++ class PV2DBase +; #pragma link C++ class PV3DBase +; #pragma link C++ class Vector2DBase +; #pragma link C++ class Vector3DBase +; #pragma link C++ class Point2DBase +; #pragma link C++ class Point3DBase +; #pragma link C++ class PSimHit+; LinkDef.h Classes used by PSimHit use C++ templates heavily All Template instances must be declared

18 R.Brun LCG ROOT corses18 Writing CMS PSimHit objects void demo1() { //create a new ROOT file TFile f("demo1.root","recreate"); //Create a PSimHit with the default constructor PSimHit h1; //Write it to the file with the key name hit1 h1.Write("hit1"); //Create a normal PSimHit with the entry and exit point Local3DPoint pentry(1,2,3); Local3DPoint pexit(10,20,30); float pabs = 41; float tof = 1.67e-8; float eloss = 5.78e-3; int pType = 12; int detId = 67; int trackId = 1234; PSimHit h2(pentry,pexit,pabs,tof,eloss,pType,detId,trackId); //Write it to the file with the key name hit2 h2.Write("hit2"); } Demo1.C

19 R.Brun LCG ROOT corses19 Reading CMS PSimHit objects void demo2() { //connect the ROOT file demo1.root in readonly mode TFile *f = new TFile("demo1.root"); //Read hit2 PSimHit *hit = (PSimHit*)f->Get("hit2"); //print some hit members cout entryPoint().x() exitPoint().y() <<" pabs= "<<hit.pabs()<<endl; delete hit; //Open the ROOT browser and inspect the file new TBrowser; //click on "ROOT files", then "demo1.root", with the //right button, select menu items "Inspect", "DrawClass" //on hit2 } Demo2.C

20 R.Brun LCG ROOT corses20 Root objects or any User Object can be stored in ROOT folders and browsed

21 R.Brun LCG ROOT corses21 LAN/WAN files Files and Directories a directory holds a list of named objects a file may have a hierarchy of directories (a la Unix) ROOT files are machine independent built-in compression Support for local, LAN and WAN files TFile f1("myfile.root") TFile f2("http://pcbrun.cern.ch/Renefile.root") TFile f3("root://cdfsga.fnal.gov/bigfile.root") TFile f4("rfio://alice/run678.root") Local file Remote file access via a Web server Remote file access via the ROOT daemon Access to a file on a mass store hpps, castor, via RFIO

22 ROOT courses22 Streaming Objects

23 R.Brun LCG ROOT corses23 ROOT I/O -- Sequential/Flat Object in memory Streamer TFile Object in memory ObjectGram TBuffer Transient Object is serialized by the Streamer No need for transient/persistent classes TWebFile web server TNetFile rootd TRFIOFile RFIO daemon TMapFile shared memory sockets http

24 R.Brun LCG ROOT corses24 The CINT RTTI The Run Time Type Information provided by CINT (rootcint) is the brain of Root. rootcint can be used to parse user classes and considerably extend the power of Root. RTTI is used by the I/O services By definition the interpreter is based on it. The GUI object context sensitive menus also. Also Browsers, Inspectors and html generator also Root utilities to draw class diagrams rootcint can be used to parse user classes such that user class functions can be called interactively and code for I/O generated automatically.

25 R.Brun LCG ROOT corses25 Rootcint Preprocessor UserClass1.h rootcint UserCint.C C++ code to create the RTTI Interface for CINT interpreter Streamers

26 R.Brun LCG ROOT corses26 Any User class library with the RTTI info can be plugged into a ROOT executable and its functions called interactively idem for I/O

27 R.Brun LCG ROOT corses27 Old Streamers in 0.90 (1996) Evolution illustrated with the ROOT class TAxis class TAxis : public TNamed, public TAttAxis { private: Int_t fNbins; Float_t fXmin; Float_t fXmax; TArrayF fXbins; void TAxis::Streamer(TBuffer &b) { if (b.IsReading()) { Version_t v = b.ReadVersion(); TNamed::Streamer(b); TAttAxis::Streamer(b); b >> fNbins; b >> fXmin; b >> fXmax; fXbins.Streamer(b); } else { b.WriteVersion(TAxis::IsA()); TNamed::Streamer(b); TAttAxis::Streamer(b); b << fNbins; b << fXmin; b << fXmax; fXbins.Streamer(b); } rootcint TBuffer b; object.Streamer(b); TAxis.h Dict.cxx

28 R.Brun LCG ROOT corses28 Old Streamers in 2.25 (1999) class TAxis : public TNamed, public TAttAxis { private: Int_t fNbins; Float_t fXmin; Float_t fXmax; TArrayF fXbins; Int_t fFirst; Int_t fLast; TString fTimeFormat; Bool_t fTimeDisplay; void TAxis::Streamer(TBuffer &b) { UInt_t R__s, R__c; if (b.IsReading()) { Version_t v = b.ReadVersion(&R__s, &R__c); TNamed::Streamer(b); TAttAxis::Streamer(b); b >> fNbins; b >> fXmin; b >> fXmax; fXbins.Streamer(b); if (v > 2) { b >> fFirst; b >> fLast; } if (v > 3) { b >> fTimeDisplay; fTimeFormat.Streamer(b); } else { SetTimeFormat(); } b.CheckByteCount(R__s, R__c, TAxis::IsA()); } else { R__c = b.WriteVersion(TAxis::IsA(), kTRUE); TNamed::Streamer(b); TAttAxis::Streamer(b); b << fNbins; b << fXmin; b << fXmax; fXbins.Streamer(b); b << fFirst; b << fLast; b << fTimeDisplay; fTimeFormat.Streamer(b); b.SetByteCount(R__c, kTRUE); } rootcint

29 R.Brun LCG ROOT corses29 Problems with Old Streamers Experience in several large experiments has shown that a system based only on automatic code generation with no support for schema evolution is not a long term solution. A huge maintenance problem. In a system with several hundred (thousand) classes and as many users, it is difficult to maintain coherent shared libs to support all possible combinations when accessing collections of old data sets. A few attempts (eg in STAR) to support automatic schema evolution seen as a progress, but not sufficient. We have seen a rapidly growing request for reading data sets without having the original classes. Backward compatibility (reading an old data set with new classes) is a must. Forward compatibility (reading a new data set with old classes) also a must.

30 R.Brun LCG ROOT corses30 The ROOT solution Minimize reliance on generated code. Exploit the powerful CINT Object Dictionary Make the process as automatic as possible and as simple as possible. Be as efficient as with the generated code. Self-describing data sets. Come with a solution that does not prevent the move to another language in the future. Back compatibility with the original system. Like upgrading the engine in a running car Implementing all these features was a non trivial exercise and a lot of work Thanks to our huge users base for providing many use cases and testing

31 R.Brun LCG ROOT corses31 New Streamers in 3.00 class TAxis : public TNamed, public TAttAxis { private: Int_t fNbins; Double_t fXmin; Double_t fXmax; TArrayD fXbins; Char_t *fXlabels; //! Int_t fFirst; Int_t fLast; TString fTimeFormat; Bool_t fTimeDisplay; TObject *fParent; //! void TAxis::Streamer(TBuffer &b) { // Stream an object of class TAxis. if (b.IsReading()) TAxis::Class()->ReadBuffer(b, this); else TAxis::Class()->WriteBuffer(b,this); } rootcint

32 R.Brun LCG ROOT corses32 Support for more complex C++ enum {kSize=10}; char fType[20]; //array of 20 chars Int_t fNtrack; //number of tracks Int_t fNvertex; //number of vertices Int_t fX[kSize]; //an array where dimension is an enum UInt_t fFlag; //bit pattern event flag Float_t fMatrix[4][4]; //a two-dim array Float_t *fDistance; //[fNvertex] array of floats of length fNvertex Double_t fTemperature; //event temperature TString *fTstringp; //[fNvertex] array of TString TString fNames[12]; //array of TString TAxis fXaxis; //example of class derived from TObject TAxis fYaxis[3]; //array of objects TAxis *fVaxis[3]; //pointer to an array of TAxis TAxis *fPaxis; //[fNvertex] array of TAxis of length fNvertex TAxis **fQaxis; //[fNvertex] array of pointers to TAxis objects TDatime fDatime; //date and time EventHeader fEvtHdr; //example of class not derived from TObject TObjArray fObjArray; //An object array of TObject* TClonesArray *fTracks; //-> array of tracks TH1F *fH; //-> pointer to an histogram TArrayF fArrayF; //an array of floats TArrayI *fArrayI; //a pointer to an array of integers ………………..(see next)

33 R.Brun LCG ROOT corses33 Support for STL vector fVectorint; //STL vector on ints vector fVectorshort; //STL vector of shorts vector fVectorD[4]; //array of STL vectors of doubles vector fVectorTLine; //|| STL vector of TLine objects vector *fVectorTobject; //|| pointer to an STL vector vector *fVectorTnamed[6]; //|| array of pointers to STL vectors deque fDeque; //STL deque list fVectorTobjectp; //STL list of pointers to objects list *fListString; //STL list of strings list fListStringp; //STL list of pointers to strings map fMapTNamedp; //STL map map fMapList; //STL map map *fMapTAxisp; //pointer to STL map set fSetTAxis; //STL set set *fSetTAxisp; //pointer to STL set multimap fMultiMapTNamedp; //STL multimap multiset *fMultiSetTAxisp; //pointer to STL multiset string fString; //C++ standard string string *fStringp; //pointer to standard C++ string UShortVector fUshort; //class with an STL vector as base class

34 R.Brun LCG ROOT corses34 Complex STL use not supported vector > fVectAxis; //!STL vector of vectors of TAxis* map > fMapString; //!STL map of string/vector deque > fDequePair; //!STL deque of pair Use a custom Streamer for these complex cases

35 R.Brun LCG ROOT corses35 The ROOT Collection Classes All ROOT collections support Polymorphism -TCollection (abstract base class) -TSeqCollection, TList, THashList -TMap, TExMap -TObjArray TClonesArray is a specialized collection for arrays of objects of the same class. It minimizes the overhead due to new/delete. Much more efficient than STL for I/O (see next slides) TRefArray is an optimized collection for persistent reference pointers. See example Event Tbuffer b; collection.Streamer(b); New in 3.02

36 R.Brun LCG ROOT corses36 The Test suite “bench” ( example on fcdfsgi2 with KAI compiler) Test performance of STL vector of objects, vectors of pointers and same with a TClonesArray of TObjHit deriving from THit Better compression with TClonesArray Better write with TClonesArray Much better read with TClonesArray

37 R.Brun LCG ROOT corses37 Self-Describing file Root > TFile f(“demo1.root”); Root > f.ShowStreamerInfo(); StreamerInfo for class: PSimHit, version=1 BASE TObject offset= 0 type=66 Basic ROOT object Local3DPoint theEntryPoint offset= 0 type=62 position Local3DPoint theExitPoint offset= 0 type=62 float thePabs offset= 0 type= 5 momentum float theTof offset= 0 type= 5 Time Of Flight float theEnergyLoss offset= 0 type= 5 Energy loss int theParticleType offset= 0 type= 3 int theDetUnitId offset= 0 type= 3 unsigned int theTrackId offset= 0 type=13 StreamerInfo for class: Point3DBase, version=1 BASE PV3DBase offset= 0 type= 0 StreamerInfo for class: PV3DBase, version=1 Basic3DVector theVector offset= 0 type=62 StreamerInfo for class: Basic3DVector, version=1 float theX offset= 0 type= 5 float theY offset= 0 type= 5 float theZ offset= 0 type= 5

38 R.Brun LCG ROOT corses38 Self-describing files Dictionary for persistent classes written to the file when closing the file. ROOT files can be read by foreign readers (eg JavaRoot (Tony Johnson) Support for Backward and Forward compatibility Files created in 2003 must be readable in 2015 Classes (data objects) for all objects in a file can be regenerated via TFile::MakeProject Root >TFile f(“demo.root”); Root > f.MakeProject(“dir”,”*”,”new++”);

39 R.Brun LCG ROOT corses39 Showing classes in a file TFile::ShowStreamerInfo Root > f.ShowStreamerInfo()

40 R.Brun LCG ROOT corses40 ROOT conventions/extentions class TGeoNode : public TNamed, public TGeoAtt { protected: TGeoVolume *fVolume; // volume associated with this TGeoVolume *fMother; // mother volume Int_t fNumber; // copy number Int_t fNovlp ; // number of overlaps Int_t *fOverlaps; //[fNovlp] list of indices for overlapping class TGeoManager : public TNamed { private : Double_t fStep; //! step to be done from current point Double_t fSafety; //! safety radius from current point Double_t fPhimin; // lowest range for phi cut Double_t fPhimax; // highest range for phi cut TGeoNodeCache *fCache; //! cache for physical nodes TVirtualGeoPainter *fPainter; //! current painter TList *fMatrices; //-> list of local transformations TObjArray *fNodes; //-> current branch of nodes TGeoVolume *fMasterVolume; // master volume TGeoVolume *fCurrentVolume; //! current volume TGeoNode *fCurrentNode; //! current node

41 R.Brun LCG ROOT corses41 Automatic Schema Evolution

42 R.Brun LCG ROOT corses42 Auto Schema Evolution (2)

43 R.Brun LCG ROOT corses43 Normal Streaming mode References using C++ pointers A TBuffer b; A.Streamer(b) Only one copy of each object in the graph saved to buffer

44 R.Brun LCG ROOT corses44 Normal Streaming mode References using C++ pointers TBuffer b1; A.Streamer(b1) TBuffer b2; B.Streamer(b2) B A Objects in red are in b1 and b2 C++ pointer

45 R.Brun LCG ROOT corses45 Normal Streaming mode References using TRef pointers TBuffer b1; A.Streamer(b1) TBuffer b2; B.Streamer(b2) B Objects in blue are only in b1 C++ pointer TRef A Bz z Set pointer to z with: TRef Bz = z; Get pointer to z with: z = Bz.GetObject()

46 R.Brun LCG ROOT corses46 TRef example: Event.h class Event : public TObject { private: char fType[20]; //event type char *fEventName; //run+event number in character format int fNtrack; //Number of tracks int fNseg; //Number of track segments int fNvertex; int fMeasures[10]; float fMatrix[4][4]; float *fClosestDistance; //[fNvertex] EventHeader fEvtHdr; TClonesArray *fTracks; //->array with all tracks TRefArray *fHighPt; //array of High Pt tracks only TRefArray *fMuons; //array of Muon tracks only TRef fLastTrack; //reference pointer to last track TRef fWebHistogram; //EXEC:GetWebHistogram TH1F *fH; //-> public:... TH1F *GetHistogram() const {return fH;} TH1F *GetWebHistogram(Bool_t reload=kFALSE) const { return (TH1F*)fWebHistogram.GetObject(reload);}

47 R.Brun LCG ROOT corses47 TRef, TRefArray Designed as light weight entities Assume large number of TRefs per event Very fast dereferencing (direct access tables) Cannot (not designed for) find an object in a file TLongRef, TUUID classes proposed for references with load on demand

48 R.Brun LCG ROOT corses48 TRef/TRefArray goals TRef is perfect for referencing objects like hits, clusters, tracks that may be > 10000. You would not like to have the size of a TRef bigger than the size of its referenced object ! A TRef occupies in average 2.5 bytes in the file There is no point in providing load on demand for one single hit, cluster or track.

49 R.Brun LCG ROOT corses49 Setting a TRef pointer Assuming obj = pointer to a TObject* TRef ref = obj; TRef is itself a TObject If the obj::kIsReferenced bit is not yet set, the obj::fUniqueID is set to the CurrentNumber+1 and obj::kIsReferenced is set to 1. Its fUniqueID is set to obj::fUniqueID CurrentNumber is managed by TProcessID fObjs[CurrentNumber] is set to obj in fPID Class TRef : public TObject { TProcessID *fPID; //!pointer to process id Class TObject { unsigned int fBits; unsigned int fUniqueID;

50 R.Brun LCG ROOT corses50 Writing Referenced objects A referenced object is written by obj->Streamer This Streamer at some point calls its TObject::Streamer In TObject::Streamer, if the kIsReferenced bit is set in fBits, the following additional info is also written: pid (4 bytes) = TProcessID of current process Average overhead in memory = 0 bytes Average overhead on disk (no comp) = 2 bytes Average overhead on disk (comp) = 2.4 bytes (0.4) A Referenced object may be written multiple times in the same file as the TRef or in other files

51 R.Brun LCG ROOT corses51 Writing TRefs to a buffer A TRef is written by TRef::Streamer Writes uid(4 bytes) + pid(4 bytes) uid = object unique identifier uid = ref::fUniqueID = obj::fUniqueID = current object nr pid = Process identifier Each process has a unique pid (TProcessID) A file contains the pids of all processes that have written objects to it. TRef memory size = 16 bytes TRef size on disk (no comp) = 8 bytes TRef size on disk (comp) = 2.4 bytes

52 R.Brun LCG ROOT corses52 Reading Referenced objects A referenced object is read by obj->Streamer This Streamer at some point calls its TObject::Streamer In TObject::Streamer, if the kIsReferenced bit is set in fBits, the following additional info is also read: pid (4 bytes) = TProcessID of current process In TProcessID::fObjs fObjs[fUniqueID] = obj When obj is deleted, fObjs[fUniqueID] = 0;

53 R.Brun LCG ROOT corses53 Reading TRefs from a buffer A TRef object is read by TRef::Streamer The pair uid,pid is read the fUniqueID of TRef is set to uid The transient pointer fPID is set to the TProcessID corresponding to pid The bit 1 of fBits is set

54 R.Brun LCG ROOT corses54 A TRef use case obj1r1 r2 obj1 r1r2 f1.root f2.root f3.root Myclass *obj1; TRef r1 = obj1; TFile f1(“f1.root”,”new”); obj1->Write(“obj1”); TFile f2(“f2.root”,”new”); r1.Write(“r1”); TFile f2(“f2.root”); TRef *r1; r1 = (TRef*)f2.Get(“r1”); TFile f3(“f3.root”,”new”); TRef r2 = *r1; r2.Write(“r2”) TFile f3(“f3.root”); TRef *r2; r2 = (TRef*)f3.Get(“r2”); r2->GetObject(); = 0 TFile f1(“f1.root”); Myclass *obj1; obj1 = (Myclass*)f1.Get(“obj1”); r2->GetObject(); --> obj1 Session 1 Session 2 Session 3

55 R.Brun LCG ROOT corses55 Using a TRef To get a pointer to the referenced object, do: Myclass *obj = (Myclass*)ref.GetObject() GetObject fBits[1] =0Returns obj = fUniqueID + gSystem =1 NO Set fBits[1]=0 return obj YESexecid = fBits[8/8] execid = 0 YES return null NO Execute TExec with execid Obj = 0 YES fPID = 0 or fPID>GetObjectWithUniqueID() = 0

56 R.Brun LCG ROOT corses56 TRef & Action on Demand When the keyword “EXEC:” is found in the comments of the data member as in: TRef fWebHistogram; //EXEC:GetWebHistogram The information in the comment field is kept in the dictionary. Execid is saved in TStreamerElement When the TRef object is read, the execid is stored in the fBits on one byte (from TStreamerElement). When TRef::GetObject is called, TObjArray *lexecs = gROOT->GetListOfExecs(); TExec *exec = (TExec*)lexecs[execid]; exec->Exec(); fWebHistogram.GetObject() executes the action GetWebHistogram Action on Demand is Persistent

57 R.Brun LCG ROOT corses57 What a TExec can do TExec is a CORE ROOT class that can be used to execute: a call to a compiled or interpreted function example: Exec:LoadHits() an interpreted script example: Exec:GetWebHistogram If GetWebHistogram is not a function (compiled or interpreted), then TExec::Exec will try to execute the script GetWebHistogram.C void GetWebHistogram(){ // example of script called from an Action on Demand when a TRef object // is dereferenced. See Event.h, member fWebHistogram TFile *f= TFile::Open("http://root.cern.ch/files/pippa.root"); TH1 *h6 = (TH1*)f->Get("h6"); h6->SetDirectory(0); delete f; Tref::SetObject(h6); }

58 R.Brun LCG ROOT corses58 A Working Example { gSystem.Load("libEvent"); TFile f("Event.root"); Event *event=0; T.SetBranchAddress("event",&event); T.GetEntry(45); event->GetWebHistogram()->Draw(); } void GetWebHistogram(){ // example of script called from an Action on Demand when a TRef object // is dereferenced. See Event.h, member fWebHistogram TFile *f= TFile::Open("http://root.cern.ch/files/pippa.root"); TH1 *h6 = (TH1*)f->Get("h6"); h6->SetDirectory(0); delete f; TRef::SetObject(h6); } Action.C GetWebHistogram.C Root >.x Action.C

59 R.Brun LCG ROOT corses59 TLongRef, TUUID File 1 container X File 2 container Y Object A has a TLongRef Object B has a TUUID Map of TUUIDs gROOT->GetUUIIDs()

60 R.Brun LCG ROOT corses60 Object Identification Pointer to object in memory File Identification and directory Access method in file (Tree, etc) ID

61 R.Brun LCG ROOT corses61 TLongRef A TLongRef points to an object inheriting from TUUID or having a TUUID. TLongRef attributes are identical to TUUID. In addition it includes a pointer to the object. When a TLongRef is written, its TUUID components are written. When a TLongRef is dereferenced, its pointer is computed (if not already there) by searching in the map of TUUIDs.

62 R.Brun LCG ROOT corses62 Object referenced by a TLongRef class MyClass { TUUID fUUID; etc… } root [0] TUUID u root [1] u.AsString() (const char* 0x40476a80)"c62ad97a-78c9-11d6-9e58-4ed58a89beef" TUUID unique in time (nanoseconds) and space Up to 128 bits ROOT objects like TFile and TDirectory have a TUUID

63 R.Brun LCG ROOT corses63 TLongRef class TLongRef { TUUID fUUID; TString fWhere; TString fHow; etc… } Additional info to be discussed FileID subdirectory branch in Tree, etc A copy of the TUUID in the ref object


Download ppt "ROOT courses1 The ROOT System A Data Access & Analysis Framework 4-5-6 February 2003 Ren é Brun/EP Input/Output."

Similar presentations


Ads by Google