Int_t value; tree->Branch(branchname, &value);
MyClass object; TBranch *branch = tree->Branch(branchname, &object, bufsize, splitlevel)
Example:
branch->SetAddress(0); Event* event = branch->GetObject(); ... Do some work.If addr is not zero, but the pointer addr points at is zero, then we allocate a branch object and set the passed pointer to point at the allocated object. The caller owns the allocated object and is responsible for deleting it when it is no longer needed.
Example:
Event* event = 0; branch->SetAddress(&event); ... Do some work. delete event; event = 0;If addr is not zero and the pointer addr points at is also not zero, then the caller has allocated a branch object and is asking us to use it. The caller owns it and must delete it when it is no longer needed.
Example:
Event* event = new Event(); branch->SetAddress(&event); ... Do some work. delete event; event = 0;These rules affect users of TTree::Branch(), TTree::SetBranchAddress(), and TChain::SetBranchAddress() as well because those routines call this one.
An example of a tree with branches with objects allocated and owned by us:
TFile* f1 = new TFile("myfile_original.root"); TTree* t1 = (TTree*) f->Get("MyTree"); TFile* f2 = new TFile("myfile_copy.root", "recreate"); TTree* t2 = t1->Clone(0); for (Int_t i = 0; i < 10; ++i) { t1->GetEntry(i); t2->Fill(); } t2->Write() delete f2; f2 = 0; delete f1; f1 = 0;An example of a branch with an object allocated by us, but owned by the caller:
TFile* f = new TFile("myfile.root", "recreate"); TTree* t = new TTree("t", "A test tree.") Event* event = 0; TBranchElement* br = t->Branch("event.", &event); for (Int_t i = 0; i < 10; ++i) { ... Fill event with meaningful data in some way. t->Fill(); } t->Write(); delete event; event = 0; delete f; f = 0;Notice that the only difference between this example and the following example is that the event pointer is zero when the branch is created.
An example of a branch with an object allocated and owned by the caller:
TFile* f = new TFile("myfile.root", "recreate"); TTree* t = new TTree("t", "A test tree.") Event* event = new Event(); TBranchElement* br = t->Branch("event.", &event); for (Int_t i = 0; i < 10; ++i) { ... Fill event with meaningful data in some way. t->Fill(); } t->Write(); delete event; event = 0; delete f; f = 0;
TBranch *branch = tree->Branch( branchname, STLcollection, buffsize, splitlevel )where STLcollection is the address of a pointer to std::vector, std::list, std::deque, std::set or std::multiset containing pointers to objects.
The ROOT test example in ROOTSYS/test/bench.cxx shows many examples of collections and storage in a TTree when using split mode or not. This program illustrates the important gain in space and time when using this new facility.
The size of this unzipping cache is 20% the size of the TTreeCache and can be modified with TTreeCache::SetUnzipBufferSize(Long64_t bufferSize). Theoretically, we only need one buffer in advance but in practice we might fall short if the unzipping cache is too small (synchronization costs).
This experimental feature is disabled by default, to activate it use the static function
TTreeCache::SetParallelUnzip(TTreeCacheUnzip::EParUnzipMode option = TTreeCacheUnzip::kEnable).The possible values to pass are:
void TBranch::DeleteBaskets(Option_t* option)new function which loops on all branch baskets. If the file where branch buffers reside is writable, free the disk space associated to the baskets of the branch, then call Reset(). If the option contains "all", delete also the baskets for the subbranches. The branch is reset.
This omission meant that slow CloneTree was (fataly) missing in some cases the copy of the TStreamerInfo for class that are part part of the TTree but had only a base and no member or in some cases where it had only object data members.