- solution 2: You create a different Tree with this data.
For example you have the "event dependent" Tree and the RUN Tree.
This solution may be interesting in case you are processing a
large number of runs in the same session.
- solution 3: For things such as the RUN parameters, it is
better to save the corresponding RUN object with its own key in
the data base. We give an example (recommended way) in the
ATLFast example
(see http://root.cern.ch/root/Atlfast.html).
In this example, the control object (a singleton of class ATLFast)
has data members with the RUN parameters. One of the data members
is the pointer to the Event Tree.
At the end of the job, the ATLFast object is written to the file
via a statement like gAtlfast->Write(). This function invokes
the function ATLFast::Streamer. In Streamer, we close the Event Tree
When reading the ATLFast object in the next session, the Streamer
function takes care of reading the Event Tree header.
This solution has the GREAT advantage of saving the program
parameters on the file. In the above example, it is essential
for the application to know the parameters with which the data
have been generated in a previous session.
Rene Brun
Steffen A. Bass wrote:
>
> Hi!
> I am running into problems when trying to store two different objects into
> a single tree, one of which should be stored only once, whereas the other
> should be stored multiple times (e.g. like Event objects in the
> MainEvent.cxx example):
>
> first the prelimaries:
>
> Int_t split = 1; // by default, split Event in sub branches
>
> TOscarEvent *event=0; // Event class
> TOscarFileHeader *fheader; // File header class, to be stored only once
> TParticle particle; // aka Track in Event example
>
> TFile *hfile = new TFile("Event.root","RECREATE","TTree ROOT file");
>
> TTree *tree = new TTree("T","ROOT tree");
>
> // now create (super)branch for file header
> TBranch *FileHeaderBranch =
> tree->Branch("fHeaderBranch","TOscarFileHeader", &fheader, bufsize,split);
>
> // ... construct fheader object
> fheader = new TOscarFileHeader();
> // ... fill fheader object
>
> nb += tree->Fill(); //fill the tree
> delete fheader;
>
> // now create (super)branch for events
> TBranch *EventBranch =
> tree->Branch("EventBranch", "TOscarEvent",&event, bufsize,split);
>
> // now in loop over events...
> event = new TOscarEvent();
> // ... construct and fill event object
> nb += tree->Fill(); //fill the tree
> delete event;
>
> // and at the end
> hfile->Write();
>
> OK, now comes the problem:
> Invoking tree->Fill() of course loops over all branches, i.e. the
> fheader object gets written to file as often as the event object
> instead of once (deleting it only causes the empty object to be written
> to file). I then tried to replace the tree->Fill() statements by
> nb += FileHeaderBranch->Fill();
> and
> nb += EventBranch->Fill();
> respectively, hoping that now only the branches of the indicated
> (super)branch are filled and that I could thus write fheader only once to
> the tree file.
> The code compiled without error messages and generated the the outputfile;
> however, it contained no readable data.
> I'd be grateful for any advice you could give,
> thanks a lot,
> Steffen
>
> --------------------------------------------------------------------------
> Steffen A. Bass phone : [01] 919 660 2570
> Duke University, Dept. of Physics fax : [01] 919 660 2464
> Box 90305, Durham N.C. 27708-0305, USA e-mail: bass@phy.duke.edu
> --------------------------------------------------------------------------