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 }
67
68 if(GValue::Size() == 0) {
69 std::cout << "No g-values!" << std::endl;
70 } else {
71 std::cout << GValue::Size() << " g-values" << std::endl;
72 }
73}
74
76{
77 const auto nSlots = ROOT::IsImplicitMTEnabled() ? TGRSIOptions::Get()->GetMaxWorkers() : 1;
78 TH1::AddDirectory(false); // turns off warnings about multiple histograms with the same name because ROOT doesn't manage them anymore
79 for(auto i : ROOT::TSeqU(nSlots)) {
80 fLists.emplace_back(std::make_shared<std::map<std::string, TList>>());
81 fH1.emplace_back(TGRSIMap<std::string, TH1*>());
82 fH2.emplace_back(TGRSIMap<std::string, TH2*>());
83 fH3.emplace_back(TGRSIMap<std::string, TH3*>());
84 fSym.emplace_back(TGRSIMap<std::string, GHSym*>());
89 for(auto& it : fH1[i]) {
90 // if the key/name of the histogram does not contain a forward slash we put it in the root-directory
91 if(it.first.find_last_of('/') == std::string::npos) {
92 (*fLists[i])[""].Add(it.second);
93 } else {
94 // extract the path from the key/name
95 auto lastSlash = it.first.find_last_of('/');
96 (*fLists[i])[it.first.substr(0, lastSlash)].Add(it.second);
97 }
98 }
99 for(auto& it : fH2[i]) {
100 // if the key/name of the histogram does not contain a forward slash we put it in the root-directory
101 if(it.first.find_last_of('/') == std::string::npos) {
102 (*fLists[i])[""].Add(it.second);
103 } else {
104 // extract the path from the key/name
105 auto lastSlash = it.first.find_last_of('/');
106 (*fLists[i])[it.first.substr(0, lastSlash)].Add(it.second);
107 }
108 }
109 for(auto& it : fH3[i]) {
110 // if the key/name of the histogram does not contain a forward slash we put it in the root-directory
111 if(it.first.find_last_of('/') == std::string::npos) {
112 (*fLists[i])[""].Add(it.second);
113 } else {
114 // extract the path from the key/name
115 auto lastSlash = it.first.find_last_of('/');
116 (*fLists[i])[it.first.substr(0, lastSlash)].Add(it.second);
117 }
118 }
119 for(auto& it : fSym[i]) {
120 // if the key/name of the histogram does not contain a forward slash we put it in the root-directory
121 if(it.first.find_last_of('/') == std::string::npos) {
122 (*fLists[i])[""].Add(it.second);
123 } else {
124 // extract the path from the key/name
125 auto lastSlash = it.first.find_last_of('/');
126 (*fLists[i])[it.first.substr(0, lastSlash)].Add(it.second);
127 }
128 }
129 for(auto& it : fCube[i]) {
130 // if the key/name of the histogram does not contain a forward slash we put it in the root-directory
131 if(it.first.find_last_of('/') == std::string::npos) {
132 (*fLists[i])[""].Add(it.second);
133 } else {
134 // extract the path from the key/name
135 auto lastSlash = it.first.find_last_of('/');
136 (*fLists[i])[it.first.substr(0, lastSlash)].Add(it.second);
137 }
138 }
139 for(auto& it : fTree[i]) {
140 // trees can only be written into the root-directory due to the way they get merge in Finalize (for now?)
141 (*fLists[i])[""].Add(it.second);
142 }
143 for(auto& it : fObject[i]) {
144 // if the key/name of the histogram does not contain a forward slash we put it in the root-directory
145 if(it.first.find_last_of('/') == std::string::npos) {
146 (*fLists[i])[""].Add(it.second);
147 } else {
148 // extract the path from the key/name
149 auto lastSlash = it.first.find_last_of('/');
150 (*fLists[i])[it.first.substr(0, lastSlash)].Add(it.second);
151 }
152 }
153 CheckSizes(i, "use");
154 }
155 TH1::AddDirectory(true); // restores old behaviour
156}
157
159{
160 /// This function merges all maps of lists into the map of the first slot (slot 0)
161 CheckSizes(0, "write");
162 // get all objects from the first slot
163 auto& res = fLists[0];
164 // map to keep track of trees we found
165 std::map<TTree*, TList*> treeList;
166 // loop over all other slots
167 for(auto slot : ROOT::TSeqU(1, fLists.size())) {
168 CheckSizes(slot, "write");
169 // loop over each TList in the map we merge into
170 for(const auto& list : *res) {
171 // loop over each object in the list
172 for(const auto&& obj : list.second) {
173 // check if object exists in the slot's list
174 if((*fLists[slot]).at(list.first).FindObject(obj->GetName()) != nullptr) {
175 // check object type and merge correspondingly
176 if(obj->InheritsFrom(TH1::Class())) {
177 // histograms can just be added together
178 static_cast<TH1*>(obj)->Add(static_cast<TH1*>((*fLists[slot]).at(list.first).FindObject(obj->GetName())));
179 } else if(obj->InheritsFrom(TTree::Class())) {
180 // trees are added to the list and merged later
181 auto* tree = static_cast<TTree*>(obj);
182 // std::cout<<slot<<" copied "<<tree->CopyEntries(static_cast<TTree*>((*fLists[slot]).at(list.first).FindObject(obj->GetName())))<<" bytes to tree "<<tree->GetName()<<std::endl;
183 treeList.emplace(tree, new TList); // emplace does not overwrite existing elements!
184 treeList.at(tree)->Add((*fLists[slot]).at(list.first).FindObject(obj->GetName()));
185 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;
186 } else {
187 std::cerr << "Object '" << obj->GetName() << "' is not a histogram (" << obj->ClassName() << "), don't know what to do with it!" << std::endl;
188 }
189 } else {
190 // only warn about not finding the object in other lists for histograms and trees
191 if(obj->InheritsFrom(TH1::Class()) || obj->InheritsFrom(TTree::Class())) {
192 std::cerr << "Failed to find object '" << obj->GetName() << "' in " << slot << ". list" << std::endl;
193 }
194 }
195 }
196 }
197 }
198 // merge the trees in the list (if there are any)
199 for(auto& tree : treeList) {
200 tree.second->Add(tree.first);
201 Long64_t entries = 0;
202 int i = 0;
203 for(const auto&& obj : *tree.second) {
204 std::cout << ++i << ". " << tree.first->GetName() << " tree: " << static_cast<TTree*>(obj)->GetEntries() << " entries" << std::endl;
205 entries += static_cast<TTree*>(obj)->GetEntries();
206 }
207 std::cout << "total of " << entries << " entries" << std::endl;
208 auto* newTree = TTree::MergeTrees(tree.second);
209 std::cout << "Got new tree with " << newTree->GetEntries() << " => " << entries - newTree->GetEntries() << " less than total" << std::endl;
210 (*res).at("").Remove(tree.first);
211 (*res).at("").Add(newTree);
212 // std::cout<<"Adding "<<tree.second->GetSize()<<" "<<tree.first->GetName()<<" trees to "<<tree.first->GetEntries()<<" entries"<<std::endl;
213 // tree.first->Merge(tree.second);
214 // std::cout<<"Got "<<tree.first->GetEntries()<<" entries"<<std::endl;
215 }
216 EndOfSort(res);
217}
218
219void TGRSIHelper::CheckSizes(unsigned int slot, const char* usage)
220{
221 /// check size of each object in the output list
222 // loop over each TList in the map
223 for(auto& list : *fLists[slot]) {
224 // loop over each object in the list
225 for(const auto&& obj : list.second) {
226 TBufferFile buf(TBuffer::kWrite, 10000);
227 obj->IsA()->WriteBuffer(buf, obj);
228 if(buf.Length() > fSizeLimit) {
229 std::ostringstream str;
230 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;
231 std::cout << str.str();
232 // we only remove it from the output list, not deleting the object itself
233 // this way the filling of that histogram will still work, it just won't get written to file
234 // we remove it from all lists though, not just the first one
235 list.second.Remove(obj);
236 }
237 }
238 }
239}
240#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