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