Project
Loading...
Searching...
No Matches
TreeStreamRedirector.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12// For the functionality of TreeStreamRedirector see the testTreeStream.cxx
13
15#include <TFile.h>
16#include <TLeaf.h>
17#include <cstring>
18
19using namespace o2::utils;
20
21//_________________________________________________
22TreeStreamRedirector::TreeStreamRedirector(const char* fname, const char* option)
23{
24 // Constructor
25
26 TString name(fname);
27 if (!name.IsNull()) {
28 mOwnDirectory = std::unique_ptr<TDirectory>(TFile::Open(fname, option));
29 mDirectory = mOwnDirectory.get();
30 } else {
31 mDirectory = gDirectory;
32 }
33}
34
35//_________________________________________________
37{
38 // Destructor
39 Close(); // write the tree to the selected file
40}
41
42//_________________________________________________
44{
45 // set the external file
46 SetDirectory(sfile);
47}
48
49//_________________________________________________
51{
52 // Set the external directory
53 // In case other directory already attached old file is closed before
54 // Redirector will be the owner of file ?
55
56 if (mOwnDirectory) {
57 mDirectory->Close();
58 mOwnDirectory.reset();
59 }
60 mDirectory = sfile;
61}
62
63//_____________________________________________________
65{
66 // return reference to the data layout with given identifier
67 // if not existing - creates new
68
69 for (auto& layout : mDataLayouts) {
70 if (layout->getID() == id) {
71 return *layout.get();
72 }
73 }
74
75 TDirectory* backup = gDirectory;
76 mDirectory->cd();
77 mDataLayouts.emplace_back(std::unique_ptr<TreeStream>(new TreeStream(Form("Tree%d", id))));
78 auto layout = mDataLayouts.back().get();
79 layout->setID(id);
80 if (backup) {
81 backup->cd();
82 }
83 return *layout;
84}
85
86//_________________________________________________
88{
89 // return reference to the data layout with given identifier
90 // if not existing - creates new
91
92 for (auto& layout : mDataLayouts) {
93 if (!std::strcmp(layout->getName(), name)) {
94 return *layout.get();
95 }
96 }
97
98 // create new
99 TDirectory* backup = gDirectory;
100 mDirectory->cd();
101 mDataLayouts.emplace_back(std::unique_ptr<TreeStream>(new TreeStream(name)));
102 auto layout = mDataLayouts.back().get();
103 layout->setID(-1);
104 if (backup) {
105 backup->cd();
106 }
107 return *layout;
108}
109
110//_________________________________________________
112{
113 // flush and close
114 if (!mDirectory) {
115 return;
116 }
117 TDirectory* backup = gDirectory;
118 mDirectory->cd();
119 for (auto& layout : mDataLayouts) {
120 layout->getTree().Write(layout->getName(), TObject::kOverwrite);
121 }
122 mDataLayouts.clear();
123 if (backup) {
124 backup->cd();
125 }
126
127 if (mOwnDirectory) {
128 mDirectory->Close();
129 } else {
130 mDirectory = nullptr;
131 }
132}
133
134//_________________________________________________
136{
137 // On the fly BUG FIX for name and titles of branches and Leave:
138 // renaming Leaves and changing title of branches to be the same as Branch name
139 // Explanation of FIX:
140 // In the friend tree Join logic it is assumed leaf names are used to find appropraiat primary/secondary keys
141 // For the standard queries however the branch names are used to identify data
142 // Hovewer in the Branch constructor it is not checked
143 // As a consequence - in case the name of the leave and and the name of branch is not the same + freind trees are
144 // sparse
145 // wrong joins ( unrelated pair of information) are used
146 // FIX:
147 // To be able to use friend trees with proper indexing (in case of sarse trees) branches and leaves has to be named
148 // consistently
149 // In this routine bnrach name is taken as a reference and branch title and leave name titles are renamed
150 // After the fix unit test code with pairs of sprse friend trees worked properly
151 // Side effects of fix:
152 //
153 if (!tree) {
154 return;
155 }
156 TObjArray* brArray = tree->GetListOfBranches();
157 TObjArray* lArray = tree->GetListOfLeaves();
158 for (int i = 0; i < brArray->GetLast(); i++) {
159 TBranch* br = (TBranch*)brArray->At(i);
160 TString brTitle(br->GetTitle());
161 if (!brTitle.Contains(br->GetName())) {
162 int pos = brTitle.First("/");
163 TString leafName;
164 if (pos < brTitle.Length()) {
165 brTitle[pos] = 0;
166 leafName = TString::Format("%s", brTitle.Data()).Data();
167 TLeaf* leaf = (TLeaf*)lArray->FindObject(leafName);
168 if (leaf) {
169 leaf->SetName(br->GetName());
170 leaf->SetTitle(br->GetName());
171 br->SetTitle(TString::Format("%s/%s", br->GetName(), &(brTitle.Data()[pos + 1])).Data());
172 }
173 }
174 }
175 }
176}
int32_t i
uint16_t pos
Definition RawData.h:3
static void FixLeafNameBug(TTree *tree)
virtual TreeStream & operator<<(Int_t id)
TreeStreamRedirector(const char *fname="", const char *option="recreate")
GLuint const GLchar * name
Definition glcorearb.h:781
GLuint id
Definition glcorearb.h:650
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))