GRSISort "v4.0.0.5"
An extension of the ROOT analysis Framework
Loading...
Searching...
No Matches
grsiproof.cxx
Go to the documentation of this file.
1#include "TEnv.h"
2#include "TFile.h"
3#include "TTree.h"
4#include "TChain.h"
5#include "TProofLite.h"
6#include "TProofLog.h"
7#include "TSystemDirectory.h"
8#include "TList.h"
9#include "TChainElement.h"
10#include "TROOT.h"
11#include "TInterpreter.h"
12
13#include "TGRSIProof.h"
14#include "TGRSIOptions.h"
15#include "TChannel.h"
16#include "TRunInfo.h"
17#include "TObjectWrapper.h"
18#include "TStopwatch.h"
19#include "TGRSIMap.h"
20#include "TPPG.h"
21#include "TCutG.h"
22
23#include <iostream>
24#include <vector>
25#include <string>
26#include <csignal>
27#include <libgen.h>
28
31TStopwatch* gStopwatch;
33
34bool startedProof = false;
35bool controlC = false;
36
37void Analyze(const char* treeType)
38{
39 std::vector<std::string> treeList;
40 TChannel* channel = nullptr;
41
42 // Loop over all of the file names, find all the files with the tree type in them and are "openable"
43 for(const auto& i : gGRSIOpt->RootInputFiles()) {
44 TFile* inputFile = TFile::Open(i.c_str());
45 if((inputFile != nullptr) && inputFile->IsOpen()) {
46 if(inputFile->FindObjectAny(treeType) != nullptr) {
47 treeList.push_back(i);
48
50
51 // try and add PPG from this file to global PPG
52 if(inputFile->Get("TPPG") != nullptr) {
53 std::cout << inputFile->GetName() << ": adding ppg" << std::endl;
54 gPpg->Add(static_cast<TPPG*>(inputFile->Get("TPPG")));
55 }
56 }
57 if(channel == nullptr || inputFile->FindObjectAny("Channel") != nullptr) {
58 channel = static_cast<TChannel*>(inputFile->Get("Channel"));
59 }
60 inputFile->Close(); // Close the files when you are done with them
61 }
62 }
63
64 // add the channel map to the input list
65 gGRSIProof->AddInput(channel);
66
67 if(treeList.empty()) {
68 return;
69 }
70
72 gGRSIProof->AddInput(TRunInfo::Get());
73
74 // add the global PPG to the input list
75 gGRSIProof->AddInput(gPpg);
76
77 auto* proofChain = new TChain(treeType);
78 // loop over the list of files that belong to this tree type and add them to the chain
79 for(auto& i : treeList) {
80 proofChain->Add(i.c_str()); // First add the file to the chain.
81 }
82 // Start getting ready to run proof
83 gGRSIProof->ClearCache();
84 if(!(gGRSIOpt->SelectorOnly())) {
85 proofChain->SetProof();
86 }
87
88 for(const auto& macroIt : gGRSIOpt->MacroInputFiles()) {
89 std::cout << "Currently Running: " << (Form("%s", macroIt.c_str())) << std::endl;
90 try {
91 if(gGRSIOpt->NumberOfEvents() == 0) {
92 proofChain->Process(Form("%s+", macroIt.c_str()));
93 } else {
94 proofChain->Process(Form("%s+", macroIt.c_str()), "", gGRSIOpt->NumberOfEvents());
95 }
97 std::cout << DRED << "Exception when processing chain: " << e.detail() << RESET_COLOR << std::endl;
98 throw e;
99 }
100 std::cout << "Done with " << (Form("%s", macroIt.c_str())) << std::endl;
101 }
102
103 // Delete the proof chain now that we are done with it.
104 delete proofChain;
105}
106
108{
109 // this function is called on normal exits (via std::atexit) or
110 // if the programm is killed with ctrl-c (via sigaction and HandleSignal)
111 if(controlC) { return; }
112 controlC = true;
113 if(startedProof) {
114 std::cout << "getting session logs ..." << std::endl;
115 TProofLog* pl = TProof::Mgr("proof://__lite__")->GetSessionLogs();
116 if(pl != nullptr) {
117 Int_t runNumber = TRunInfo::RunNumber();
118 Int_t subRunNumber = TRunInfo::SubRunNumber();
119
120 std::string firstMacro;
121 if(!gGRSIOpt->MacroInputFiles().empty()) { firstMacro = gGRSIOpt->MacroInputFiles().at(0); }
122 firstMacro = basename(const_cast<char*>(firstMacro.c_str())); // remove path
123 firstMacro = firstMacro.substr(0, firstMacro.find_last_of('.')); // remove extension
124
125 if(runNumber != 0 && subRunNumber != -1) {
126 // both run and subrun number set => single file processed
127 pl->Save("*", Form("%s%05d_%03d.log", firstMacro.c_str(), runNumber, subRunNumber));
128 std::cout << "Wrote logs to '" << Form("%s%05d_%03d.log", firstMacro.c_str(), runNumber, subRunNumber) << "'" << std::endl;
129 } else if(runNumber != 0) {
130 // multiple subruns of a single run
131 pl->Save("*", Form("%s%05d_%03d-%03d.log", firstMacro.c_str(), runNumber, TRunInfo::FirstSubRunNumber(), TRunInfo::LastSubRunNumber()));
132 std::cout << "Wrote logs to '" << Form("%s%05d_%03d-%03d.log", firstMacro.c_str(), runNumber, TRunInfo::FirstSubRunNumber(), TRunInfo::LastSubRunNumber()) << "'" << std::endl;
133 } else {
134 // multiple runs
135 pl->Save("*", Form("%s%05d-%05d.log", firstMacro.c_str(), TRunInfo::FirstRunNumber(), TRunInfo::LastRunNumber()));
136 std::cout << "Wrote logs to '" << Form("%s%05d-%05d.log", firstMacro.c_str(), TRunInfo::FirstRunNumber(), TRunInfo::LastRunNumber()) << "'" << std::endl;
137 }
138 } else {
139 std::cout << "Failed to get logs!" << std::endl;
140 }
141
142 std::cout << "stopping all workers ..." << std::endl;
143 gGRSIProof->StopProcess(true);
144 }
145
146 // print time it took to run grsiproof
147 double realTime = gStopwatch->RealTime();
148 int hour = static_cast<int>(realTime / 3600);
149 realTime -= hour * 3600;
150 int min = static_cast<int>(realTime / 60);
151 realTime -= min * 60;
152 std::cout << DMAGENTA << std::endl
153 << "Done after " << hour << ":" << std::setfill('0') << std::setw(2) << min << ":"
154 << std::setprecision(3) << std::fixed << realTime << " h:m:s"
155 << RESET_COLOR << std::endl;
156}
157
159{
160 // sigaction requires a function that takes an integer as argument
161 // since we don't care what the signal was, we just call AtExitHandler
163}
164
165static void CatchSignals()
166{
167 struct sigaction action{};
168 action.sa_handler = HandleSignal;
169 action.sa_flags = 0;
170 sigemptyset(&action.sa_mask);
171 sigaction(SIGINT, &action, nullptr);
172 sigaction(SIGTERM, &action, nullptr);
173}
174
176{
177 std::string grsiPath = getenv("GRSISYS"); // Finds the GRSISYS path to be used by other parts of the grsisort code
178 if(grsiPath.length() > 0) {
179 grsiPath += "/";
180 }
181 // Read in grsirc in the GRSISYS directory to set user defined options on grsisort startup
182 grsiPath += ".grsirc";
183 gEnv->ReadFile(grsiPath.c_str(), kEnvChange);
184}
185
186int main(int argc, char** argv)
187{
188 gStopwatch = new TStopwatch;
189 try {
190 SetGRSIEnv();
191 gGRSIOpt = TGRSIOptions::Get(argc, argv);
192 if(gGRSIOpt->ShouldExit()) {
193 return 0;
194 }
195 } catch(ParseError& e) {
196 return 1;
197 }
198 gPpg = new TPPG;
199
200 std::atexit(AtExitHandler);
201 CatchSignals();
202
203 // Add the path were we store headers for GRSIProof macros to see
204 const char* pPath = getenv("GRSISYS");
205 gInterpreter->AddIncludePath(Form("%s/include", pPath));
206 // if we have a data parser/detector library, add it's include path as well
207 std::string library = gGRSIOpt->ParserLibrary();
208 if(!library.empty()) {
209 size_t tmpPos = library.rfind("/lib/lib");
210 if(tmpPos != std::string::npos) {
211 gInterpreter->AddIncludePath(Form("%s/include", library.substr(0, tmpPos).c_str()));
212 } else {
213 std::cout << "Warning, expected dataparser/detector library location to be of form <path>/lib/lib<name>.so, but it is " << library << ". Won't be able to add include path!" << std::endl;
214 }
215 // no need to load the parser library, that is already taken care of by TGRSIProof class
216 } else {
217 std::cout << "Warning, no dataparser/detector library provided, won't be able to add include path!" << std::endl;
218 }
219 // The first thing we want to do is see if we can compile the macros that are passed to us
220 if(gGRSIOpt->MacroInputFiles().empty()) {
221 std::cout << DRED << "Can't PROOF if there is no MACRO" << RESET_COLOR << std::endl;
222 return 1;
223 }
224 std::cout << DCYAN << "************************* MACRO COMPILATION ****************************" << RESET_COLOR
225 << std::endl;
226 for(const auto& i : gGRSIOpt->MacroInputFiles()) {
227 Int_t errorCode = gSystem->CompileMacro(i.c_str(), "kgOs"); // k - keep shared library after session ends, g - add debuging symbols, O - optimize the code, s - silent, v - verbose output
228 if(errorCode == 0) {
229 std::cout << DRED << i << " failed to compile properly.. ABORT!" << RESET_COLOR << std::endl;
230 return 1;
231 }
232 }
233 std::cout << DCYAN << "************************* END COMPILATION ******************************" << RESET_COLOR
234 << std::endl;
235
236 if(!gGRSIOpt->InputFiles().empty()) {
237 std::cout << DRED << "Can't Proof a Midas file..." << RESET_COLOR << std::endl;
238 }
239
240 // The first thing we do is get the PROOF Lite instance to run
241 if(gGRSIOpt->GetMaxWorkers() >= 0) {
242 std::cout << "Opening proof with '" << Form("workers=%d", gGRSIOpt->GetMaxWorkers()) << "'" << std::endl;
243 gGRSIProof = TGRSIProof::Open(Form("workers=%d", gGRSIOpt->GetMaxWorkers()));
244 } else if(gGRSIOpt->SelectorOnly()) {
245 std::cout << "Opening proof with one worker (selector-only)" << std::endl;
246 gGRSIProof = TGRSIProof::Open("workers=1");
247 } else {
249 }
250
251 if(gGRSIProof == nullptr) {
252 std::cout << "Couldn't connect to proof on first attempt, trying again" << std::endl;
253 if(gGRSIOpt->GetMaxWorkers() >= 0) {
254 std::cout << "Opening proof with '" << Form("workers=%d", gGRSIOpt->GetMaxWorkers()) << "'" << std::endl;
255 gGRSIProof = TGRSIProof::Open(Form("workers=%d", gGRSIOpt->GetMaxWorkers()));
256 } else if(gGRSIOpt->SelectorOnly()) {
257 std::cout << "Opening proof with one worker (selector-only)" << std::endl;
258 gGRSIProof = TGRSIProof::Open("workers=1");
259 } else {
261 }
262 }
263
264 if(gGRSIProof == nullptr) {
265 std::cout << "Still can't connect to proof, try running it again?" << std::endl;
266 return 0;
267 }
268
269 startedProof = true;
270
271 // set some proof parameters
272 // average rate, can also be set via Proof.RateEstimation in gEnv ("current" or "average)
273 if(gGRSIOpt->AverageRateEstimation()) { gGRSIProof->SetParameter("PROOF_RateEstimation", "average"); }
274
275 // Parallel unzip, can also be set via ProofPlayer.UseParallelUnzip
276 if(gGRSIOpt->ParallelUnzip()) {
277 gGRSIProof->SetParameter("PROOF_UseParallelUnzip", 1);
278 } else {
279 gGRSIProof->SetParameter("PROOF_UseParallelUnzip", 0);
280 }
281
282 // Tree cache
283 if(gGRSIOpt->CacheSize() >= 0) {
284 if(gGRSIOpt->CacheSize() == 0) {
285 gGRSIProof->SetParameter("PROOF_UseTreeCache", 0);
286 } else {
287 gGRSIProof->SetParameter("PROOF_UseTreeCache", 1);
288 gGRSIProof->SetParameter("PROOF_CacheSize", gGRSIOpt->CacheSize());
289 }
290 } else {
291 // Use defaults
292 gGRSIProof->DeleteParameters("PROOF_UseTreeCache");
293 gGRSIProof->DeleteParameters("PROOF_CacheSize");
294 }
295
296 // Enable submergers, if required
297 if(gGRSIOpt->Submergers() >= 0) {
298 gGRSIProof->SetParameter("PROOF_UseMergers", gGRSIOpt->Submergers());
299 } else {
300 gGRSIProof->DeleteParameters("PROOF_UseMergers");
301 }
302
303 // enable perfomance output
304 if(gGRSIOpt->ProofStats()) {
305 gGRSIProof->SetParameter("PROOF_StatsHist", "");
306 gGRSIProof->SetParameter("PROOF_StatsTrace", "");
307 gGRSIProof->SetParameter("PROOF_RateTrace", "");
308 gGRSIProof->SetParameter("PROOF_SlaveStatsTrace", "");
309 }
310
311 gGRSIProof->SetBit(TProof::kUsingSessionGui);
312 TGRSIProof::AddEnvVar("GRSISYS", pPath);
313 gInterpreter->AddIncludePath(Form("%s/include", pPath));
314 gGRSIProof->AddIncludePath(Form("%s/include", pPath));
315 gGRSIProof->AddDynamicPath(Form("%s/lib", pPath));
316
318 gGRSIProof->AddInput(new TNamed("pwd", getenv("PWD")));
319 int index = 0;
320 for(const auto& valFile : gGRSIOpt->ValInputFiles()) {
321 gGRSIProof->AddInput(new TNamed(Form("valFile%d", index++), valFile.c_str()));
322 }
323 index = 0;
324 for(const auto& calFile : gGRSIOpt->CalInputFiles()) {
325 gGRSIProof->AddInput(new TNamed(Form("calFile%d", index++), calFile.c_str()));
326 }
327 index = 0;
328 for(const auto& cutFile : gGRSIOpt->InputCutFiles()) {
329 gGRSIProof->AddInput(new TNamed(Form("cutFile%d", index++), cutFile.c_str()));
330 }
331 gGRSIProof->AddInput(new TNamed("ParserLibrary", library.c_str()));
332
333 if(gGRSIOpt->TreeName().empty()) {
334 Analyze("FragmentTree");
335 Analyze("AnalysisTree");
336 Analyze("Lst2RootTree");
337 } else {
338 std::cout << "Running selector on tree '" << gGRSIOpt->TreeName() << "'" << std::endl;
339 Analyze(gGRSIOpt->TreeName().c_str());
340 }
341
343
344 return 0;
345}
#define DRED
Definition Globals.h:18
#define DCYAN
Definition Globals.h:21
#define RESET_COLOR
Definition Globals.h:5
#define DMAGENTA
Definition Globals.h:20
std::string detail() const noexcept
Definition TGRSIMap.h:112
const std::vector< std::string > & RootInputFiles() const
bool AverageRateEstimation() const
int Submergers() const
bool SelectorOnly() const
static TGRSIOptions * Get(int argc=0, char **argv=nullptr)
Do not use!
const std::vector< std::string > & InputFiles() const
size_t NumberOfEvents() const
bool ProofStats() const
const std::vector< std::string > & InputCutFiles() const
static TAnalysisOptions * AnalysisOptions()
std::string TreeName() const
const std::vector< std::string > & ValInputFiles() const
int CacheSize() const
bool ParallelUnzip() const
bool ShouldExit() const
const std::vector< std::string > & CalInputFiles() const
void ParserLibrary(std::string &library)
const std::vector< std::string > & MacroInputFiles() const
int GetMaxWorkers() const
static TGRSIProof * Open(const char *worker="")
Definition TGRSIProof.h:53
Definition TPPG.h:132
void Add(const TPPG *ppg)
Definition TPPG.cxx:680
static int LastRunNumber()
Definition TRunInfo.h:207
static int SubRunNumber()
Definition TRunInfo.h:202
static int LastSubRunNumber()
Definition TRunInfo.h:208
static int RunNumber()
Definition TRunInfo.h:201
static int FirstSubRunNumber()
Definition TRunInfo.h:205
void Print(Option_t *opt="") const override
Definition TRunInfo.cxx:72
static int FirstRunNumber()
Definition TRunInfo.h:204
static TRunInfo * AddCurrent()
Definition TSingleton.h:141
static TRunInfo * Get(bool verbose=false)
Definition TSingleton.h:33
TPPG * gPpg
Definition grsiproof.cxx:32
TStopwatch * gStopwatch
Definition grsiproof.cxx:31
int main(int argc, char **argv)
static void CatchSignals()
bool startedProof
Definition grsiproof.cxx:34
void Analyze(const char *treeType)
Definition grsiproof.cxx:37
TGRSIOptions * gGRSIOpt
Definition grsiproof.cxx:30
void SetGRSIEnv()
void AtExitHandler()
void HandleSignal(int)
TGRSIProof * gGRSIProof
Definition grsiproof.cxx:29
bool controlC
Definition grsiproof.cxx:35