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