GRSISort "v4.0.0.5"
An extension of the ROOT analysis Framework
Loading...
Searching...
No Matches
TGRSIHelper.cxx
Go to the documentation of this file.
1#include "TGRSIHelper.h"
2#include "RVersion.h" // IWYU pragma: keep
3#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 14, 0)
4
5#include "TGRSIOptions.h"
6#include "GValue.h"
7#include "TBufferFile.h"
8
10 : fPpg(static_cast<TPPG*>(input->FindObject("TPPG"))), fRunInfo(static_cast<TRunInfo*>(input->FindObject("TRunInfo"))), fUserSettings(static_cast<TUserSettings*>(input->FindObject("UserSettings")))
11{
12 // get the analysis options from the input list and assign them to our local analysis options
13 // (this might not be needed anymore since the workers aren't started as separate processes but threads)
14 *(TGRSIOptions::AnalysisOptions()) = *static_cast<TAnalysisOptions*>(input->FindObject("TAnalysisOptions"));
15 // check that we have a parser library
16 if(TGRSIOptions::Get()->ParserLibrary().empty()) {
17 std::ostringstream str;
18 str << DRED << "No parser library set!" << RESET_COLOR << std::endl;
19 throw std::runtime_error(str.str());
20 }
21 // loop over all cal-files, val-files, and cut-files we might have (these are full paths!)
22 for(int i = 0; input->FindObject(Form("calFile%d", i)) != nullptr; ++i) {
23 const char* fileName = static_cast<TNamed*>(input->FindObject(Form("calFile%d", i)))->GetTitle();
24 if(fileName[0] == 0) {
25 std::cout << "Error, empty file name!" << std::endl;
26 break;
27 }
28 TChannel::ReadCalFile(fileName);
29 }
30 for(int i = 0; input->FindObject(Form("valFile%d", i)) != nullptr; ++i) {
31 const char* fileName = static_cast<TNamed*>(input->FindObject(Form("valFile%d", i)))->GetTitle();
32 if(fileName[0] == 0) {
33 std::cout << "Error, empty file name!" << std::endl;
34 break;
35 }
36 GValue::ReadValFile(fileName);
37 }
38 for(int i = 0; input->FindObject(Form("cutFile%d", i)) != nullptr; ++i) {
39 std::cout << "trying to open " << Form("cutFile%d", i) << std::flush << " = " << input->FindObject(Form("cutFile%d", i)) << std::flush << " with title " << static_cast<TNamed*>(input->FindObject(Form("cutFile%d", i)))->GetTitle() << std::endl;
40 const char* fileName = static_cast<TNamed*>(input->FindObject(Form("cutFile%d", i)))->GetTitle();
41 if(fileName[0] == 0) {
42 std::cout << "Error, empty file name!" << std::endl;
43 break;
44 }
45 // if we have a relative path and a working directory, combine them
46 auto* file = new TFile(fileName);
47 if(file != nullptr && file->IsOpen()) {
48 TIter iter(file->GetListOfKeys());
49 TKey* key = nullptr;
50 while((key = static_cast<TKey*>(iter.Next())) != nullptr) {
51 if(strcmp(key->GetClassName(), "TCutG") != 0) {
52 continue;
53 }
54 auto* tmpCut = static_cast<TCutG*>(key->ReadObj());
55 if(tmpCut != nullptr) {
56 fCuts[tmpCut->GetName()] = tmpCut;
57 }
58 }
59 } else {
60 std::cout << "Error, failed to open file " << fileName << "!" << std::endl;
61 break;
62 }
63 }
64 for(auto& cut : fCuts) {
65 std::cout << cut.first << " = " << cut.second << std::endl;
66 if(cut.second != nullptr) { cut.second->Print(); }
67 }
68
69 if(GValue::Size() == 0) {
70 std::cout << "No g-values!" << std::endl;
71 } else {
72 std::cout << GValue::Size() << " g-values" << std::endl;
73 }
74}
75
77{
78 const auto nSlots = ROOT::IsImplicitMTEnabled() ? TGRSIOptions::Get()->GetMaxWorkers() : 1;
79 TH1::AddDirectory(false); // turns off warnings about multiple histograms with the same name because ROOT doesn't manage them anymore
80 for(auto i : ROOT::TSeqU(nSlots)) {
81 fLists.emplace_back(std::make_shared<std::map<std::string, TList>>());
82 fH1.emplace_back(TGRSIMap<std::string, TH1*>());
83 fH2.emplace_back(TGRSIMap<std::string, TH2*>());
84 fH3.emplace_back(TGRSIMap<std::string, TH3*>());
85 fSym.emplace_back(TGRSIMap<std::string, GHSym*>());
90 for(auto& it : fH1[i]) {
91 // if the key/name of the histogram does not contain a forward slash we put it in the root-directory
92 if(it.first.find_last_of('/') == std::string::npos) {
93 (*fLists[i])[""].Add(it.second);
94 } else {
95 // extract the path from the key/name
96 auto lastSlash = it.first.find_last_of('/');
97 (*fLists[i])[it.first.substr(0, lastSlash)].Add(it.second);
98 }
99 }
100 for(auto& it : fH2[i]) {
101 // if the key/name of the histogram does not contain a forward slash we put it in the root-directory
102 if(it.first.find_last_of('/') == std::string::npos) {
103 (*fLists[i])[""].Add(it.second);
104 } else {
105 // extract the path from the key/name
106 auto lastSlash = it.first.find_last_of('/');
107 (*fLists[i])[it.first.substr(0, lastSlash)].Add(it.second);
108 }
109 }
110 for(auto& it : fH3[i]) {
111 // if the key/name of the histogram does not contain a forward slash we put it in the root-directory
112 if(it.first.find_last_of('/') == std::string::npos) {
113 (*fLists[i])[""].Add(it.second);
114 } else {
115 // extract the path from the key/name
116 auto lastSlash = it.first.find_last_of('/');
117 (*fLists[i])[it.first.substr(0, lastSlash)].Add(it.second);
118 }
119 }
120 for(auto& it : fSym[i]) {
121 // if the key/name of the histogram does not contain a forward slash we put it in the root-directory
122 if(it.first.find_last_of('/') == std::string::npos) {
123 (*fLists[i])[""].Add(it.second);
124 } else {
125 // extract the path from the key/name
126 auto lastSlash = it.first.find_last_of('/');
127 (*fLists[i])[it.first.substr(0, lastSlash)].Add(it.second);
128 }
129 }
130 for(auto& it : fCube[i]) {
131 // if the key/name of the histogram does not contain a forward slash we put it in the root-directory
132 if(it.first.find_last_of('/') == std::string::npos) {
133 (*fLists[i])[""].Add(it.second);
134 } else {
135 // extract the path from the key/name
136 auto lastSlash = it.first.find_last_of('/');
137 (*fLists[i])[it.first.substr(0, lastSlash)].Add(it.second);
138 }
139 }
140 for(auto& it : fTree[i]) {
141 // trees can only be written into the root-directory due to the way they get merge in Finalize (for now?)
142 (*fLists[i])[""].Add(it.second);
143 }
144 for(auto& it : fObject[i]) {
145 // if the key/name of the histogram does not contain a forward slash we put it in the root-directory
146 if(it.first.find_last_of('/') == std::string::npos) {
147 (*fLists[i])[""].Add(it.second);
148 } else {
149 // extract the path from the key/name
150 auto lastSlash = it.first.find_last_of('/');
151 (*fLists[i])[it.first.substr(0, lastSlash)].Add(it.second);
152 }
153 }
154 CheckSizes(i, "use");
155 }
156 TH1::AddDirectory(true); // restores old behaviour
157}
158
160{
161 /// This function merges all maps of lists into the map of the first slot (slot 0)
162 CheckSizes(0, "write");
163 // get all objects from the first slot
164 auto& res = fLists[0];
165 // map to keep track of trees we found
166 std::map<TTree*, TList*> treeList;
167 // loop over all other slots
168 for(auto slot : ROOT::TSeqU(1, fLists.size())) {
169 CheckSizes(slot, "write");
170 // loop over each TList in the map we merge into
171 for(const auto& list : *res) {
172 // loop over each object in the list
173 for(const auto&& obj : list.second) {
174 // check if object exists in the slot's list
175 if((*fLists[slot]).at(list.first).FindObject(obj->GetName()) != nullptr) {
176 // check object type and merge correspondingly
177 if(obj->InheritsFrom(TH1::Class())) {
178 // histograms can just be added together
179 static_cast<TH1*>(obj)->Add(static_cast<TH1*>((*fLists[slot]).at(list.first).FindObject(obj->GetName())));
180 } else if(obj->InheritsFrom(TTree::Class())) {
181 // trees are added to the list and merged later
182 auto* tree = static_cast<TTree*>(obj);
183 // std::cout<<slot<<" copied "<<tree->CopyEntries(static_cast<TTree*>((*fLists[slot]).at(list.first).FindObject(obj->GetName())))<<" bytes to tree "<<tree->GetName()<<std::endl;
184 treeList.emplace(tree, new TList); // emplace does not overwrite existing elements!
185 treeList.at(tree)->Add((*fLists[slot]).at(list.first).FindObject(obj->GetName()));
186 std::cout << slot << ": adding " << treeList.at(tree)->GetSize() << ". " << tree->GetName() << " tree with " << static_cast<TTree*>((*fLists[slot]).at(list.first).FindObject(obj->GetName()))->GetEntries() << " entries" << std::endl;
187 } else {
188 std::cerr << "Object '" << obj->GetName() << "' is not a histogram (" << obj->ClassName() << "), don't know what to do with it!" << std::endl;
189 }
190 } else {
191 // only warn about not finding the object in other lists for histograms and trees
192 if(obj->InheritsFrom(TH1::Class()) || obj->InheritsFrom(TTree::Class())) {
193 std::cerr << "Failed to find object '" << obj->GetName() << "' in " << slot << ". list" << std::endl;
194 }
195 }
196 }
197 }
198 }
199 // merge the trees in the list (if there are any)
200 for(auto& tree : treeList) {
201 tree.second->Add(tree.first);
202 Long64_t entries = 0;
203 int i = 0;
204 for(const auto&& obj : *tree.second) {
205 std::cout << ++i << ". " << tree.first->GetName() << " tree: " << static_cast<TTree*>(obj)->GetEntries() << " entries" << std::endl;
206 entries += static_cast<TTree*>(obj)->GetEntries();
207 }
208 std::cout << "total of " << entries << " entries" << std::endl;
209 auto* newTree = TTree::MergeTrees(tree.second);
210 std::cout << "Got new tree with " << newTree->GetEntries() << " => " << entries - newTree->GetEntries() << " less than total" << std::endl;
211 (*res).at("").Remove(tree.first);
212 (*res).at("").Add(newTree);
213 // std::cout<<"Adding "<<tree.second->GetSize()<<" "<<tree.first->GetName()<<" trees to "<<tree.first->GetEntries()<<" entries"<<std::endl;
214 // tree.first->Merge(tree.second);
215 // std::cout<<"Got "<<tree.first->GetEntries()<<" entries"<<std::endl;
216 }
217 EndOfSort(res);
218}
219
220void TGRSIHelper::CheckSizes(unsigned int slot, const char* usage)
221{
222 /// check size of each object in the output list
223 // loop over each TList in the map
224 for(auto& list : *fLists[slot]) {
225 // loop over each object in the list
226 for(const auto&& obj : list.second) {
227 TBufferFile buf(TBuffer::kWrite, 10000);
228 obj->IsA()->WriteBuffer(buf, obj);
229 if(buf.Length() > fSizeLimit) {
230 std::ostringstream str;
231 str << DRED << slot << ". slot: " << obj->ClassName() << " '" << obj->GetName() << "' too large to " << usage << ": " << buf.Length() << " bytes = " << buf.Length() / 1024. / 1024. / 1024. << " GB, removing it!" << RESET_COLOR << std::endl;
232 std::cout << str.str();
233 // we only remove it from the output list, not deleting the object itself
234 // this way the filling of that histogram will still work, it just won't get written to file
235 // we remove it from all lists though, not just the first one
236 list.second.Remove(obj);
237 }
238 }
239 }
240}
241#endif
#define DRED
Definition Globals.h:18
#define RESET_COLOR
Definition Globals.h:5
static int ReadValFile(const char *filename="", Option_t *opt="replace")
Definition GValue.cxx:194
static int Size()
Definition GValue.h:63
static Int_t ReadCalFile(std::ifstream &infile)
std::vector< TGRSIMap< std::string, TTree * > > fTree
Definition TGRSIHelper.h:49
std::map< std::string, TCutG * > fCuts
Definition TGRSIHelper.h:51
std::vector< TGRSIMap< std::string, GCube * > > fCube
Definition TGRSIHelper.h:48
std::vector< TGRSIMap< std::string, GHSym * > > fSym
Definition TGRSIHelper.h:47
std::vector< TGRSIMap< std::string, TH2 * > > fH2
Definition TGRSIHelper.h:45
void CheckSizes(unsigned int slot, const char *usage)
std::vector< TGRSIMap< std::string, TObject * > > fObject
Definition TGRSIHelper.h:50
std::vector< TGRSIMap< std::string, TH1 * > > fH1
Definition TGRSIHelper.h:44
virtual void CreateHistograms(unsigned int)
Virtual helper function that the user uses to create their histograms.
Definition TGRSIHelper.h:72
virtual void EndOfSort(std::shared_ptr< std::map< std::string, TList > > &)
This method gets called at the end of Finalize()
Definition TGRSIHelper.h:96
std::vector< std::shared_ptr< std::map< std::string, TList > > > fLists
Definition TGRSIHelper.h:43
TGRSIHelper(TList *input)
static constexpr int fSizeLimit
! 1 GiB size limit for objects in ROOT
Definition TGRSIHelper.h:58
virtual void Setup()
std::vector< TGRSIMap< std::string, TH3 * > > fH3
Definition TGRSIHelper.h:46
static TGRSIOptions * Get(int argc=0, char **argv=nullptr)
Do not use!
static TAnalysisOptions * AnalysisOptions()
int GetMaxWorkers() const
Definition TPPG.h:130