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