GRSISort
Created by P.C. Bender
Developement Team: P.C. Bender, R. Dunlop, V. Bildstein
An extension of the ROOT analysis Framework
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 <signal.h>
27 
30 TStopwatch* gStopwatch;
32 
33 bool startedProof = false;
34 bool controlC = false;
35 
36 void Analyze(const char* tree_type)
37 {
38  std::vector<std::string> tree_list;
39 
40  // Loop over all of the file names, find all the files with the tree type in them and are "openable"
41  for(const auto& i : gGRSIOpt->RootInputFiles()) {
42  TFile* in_file = TFile::Open(i.c_str());
43  if((in_file != nullptr) && in_file->IsOpen()) {
44  if(in_file->FindObjectAny(tree_type) != nullptr) {
45  tree_list.push_back(i);
46 
48 
49  // try and add PPG from this file to global PPG
50  if(in_file->Get("TPPG") != nullptr) {
51  std::cout<<in_file->GetName()<<": adding ppg"<<std::endl;
52  gPpg->Add(static_cast<TPPG*>(in_file->Get("TPPG")));
53  }
54  }
55  in_file->Close(); // Close the files when you are done with them
56  }
57  }
58 
59  if(tree_list.empty()) {
60  return;
61  }
62 
63  TRunInfo::Get()->Print();
64  gGRSIProof->AddInput(TRunInfo::Get());
65 
66  //add the global PPG to the input list
67  gGRSIProof->AddInput(gPpg);
68 
69  auto* proof_chain = new TChain(tree_type);
70  // loop over the list of files that belong to this tree type and add them to the chain
71  for(auto& i : tree_list) {
72  proof_chain->Add(i.c_str()); // First add the file to the chain.
73  }
74  // Start getting ready to run proof
75  gGRSIProof->ClearCache();
76  if(!(gGRSIOpt->SelectorOnly())) {
77  proof_chain->SetProof();
78  }
79 
80  for(const auto& macro_it : gGRSIOpt->MacroInputFiles()) {
81  std::cout<<"Currently Running: "<<(Form("%s", macro_it.c_str()))<<std::endl;
82  try {
83  if(gGRSIOpt->NumberOfEvents() == 0) {
84  proof_chain->Process(Form("%s+", macro_it.c_str()));
85  } else {
86  proof_chain->Process(Form("%s+", macro_it.c_str()), "", gGRSIOpt->NumberOfEvents());
87  }
88  } catch(TGRSIMapException<std::string>& e) {
89  std::cout<<DRED<<"Exception when processing chain: "<<e.detail()<<RESET_COLOR<<std::endl;
90  throw e;
91  }
92  std::cout<<"Done with "<<(Form("%s", macro_it.c_str()))<<std::endl;
93  }
94 
95  // Delete the proof chain now that we are done with it.
96  if(proof_chain != nullptr) {
97  delete proof_chain;
98  proof_chain = nullptr;
99  }
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  TRunInfo* runInfo = TRunInfo::Get();
113  Int_t runNumber = runInfo->RunNumber();
114  Int_t subRunNumber = runInfo->SubRunNumber();
115 
116  std::string firstMacro;
117  if(!gGRSIOpt->MacroInputFiles().empty()) firstMacro = gGRSIOpt->MacroInputFiles().at(0);
118  firstMacro = basename(firstMacro.c_str()); // remove path
119  firstMacro = firstMacro.substr(0, firstMacro.find_last_of('.')); // remove extension
120 
121  if(runNumber != 0 && subRunNumber != -1) {
122  // both run and subrun number set => single file processed
123  pl->Save("*", Form("%s%05d_%03d.log", firstMacro.c_str(), runNumber, subRunNumber));
124  std::cout<<"Wrote logs to '"<<Form("%s%05d_%03d.log", firstMacro.c_str(), runNumber, subRunNumber)<<"'"<<std::endl;
125  } else if(runNumber != 0) {
126  // multiple subruns of a single run
127  pl->Save("*", Form("%s%05d_%03d-%03d.log", firstMacro.c_str(), runNumber, runInfo->FirstSubRunNumber(), runInfo->LastSubRunNumber()));
128  std::cout<<"Wrote logs to '"<<Form("%s%05d_%03d-%03d.log", firstMacro.c_str(), runNumber, runInfo->FirstSubRunNumber(), runInfo->LastSubRunNumber())<<"'"<<std::endl;
129  } else {
130  // multiple runs
131  pl->Save("*", Form("%s%05d-%05d.log", firstMacro.c_str(), runInfo->FirstRunNumber(), runInfo->LastRunNumber()));
132  std::cout<<"Wrote logs to '"<<Form("%s%05d-%05d.log", firstMacro.c_str(), runInfo->FirstRunNumber(), runInfo->LastRunNumber())<<"'"<<std::endl;
133  }
134  } else {
135  std::cout<<"Failed to get logs!"<<std::endl;
136  }
137 
138  std::cout<<"stopping all workers ..."<<std::endl;
139  gGRSIProof->StopProcess(true);
140  }
141 
142  // print time it took to run grsiproof
143  double realTime = gStopwatch->RealTime();
144  int hour = static_cast<int>(realTime / 3600);
145  realTime -= hour * 3600;
146  int min = static_cast<int>(realTime / 60);
147  realTime -= min * 60;
148  std::cout<<DMAGENTA<<std::endl
149  <<"Done after "<<hour<<":"<<std::setfill('0')<<std::setw(2)<<min<<":"
150  <<std::setprecision(3)<<std::fixed<<realTime<<" h:m:s"
151  <<RESET_COLOR<<std::endl;
152 }
153 
154 void HandleSignal(int)
155 {
156  // sigaction requires a function that takes an integer as argument
157  // since we don't care what the signal was, we just call AtExitHandler
158  AtExitHandler();
159 }
160 
161 static void CatchSignals()
162 {
163  struct sigaction action;
164  action.sa_handler = HandleSignal;
165  action.sa_flags = 0;
166  sigemptyset(&action.sa_mask);
167  sigaction(SIGINT, &action, NULL);
168  sigaction(SIGTERM, &action, NULL);
169 }
170 
172 {
173  std::string grsi_path = getenv("GRSISYS"); // Finds the GRSISYS path to be used by other parts of the grsisort code
174  if(grsi_path.length() > 0) {
175  grsi_path += "/";
176  }
177  // Read in grsirc in the GRSISYS directory to set user defined options on grsisort startup
178  grsi_path += ".grsirc";
179  gEnv->ReadFile(grsi_path.c_str(), kEnvChange);
180 }
181 
182 int main(int argc, char** argv)
183 {
184  gStopwatch = new TStopwatch;
185  try {
186  SetGRSIEnv();
188  if(gGRSIOpt->ShouldExit()) {
189  return 0;
190  }
191  } catch(ParseError& e) {
192  return 1;
193  }
194  gPpg = new TPPG;
195 
196  std::atexit(AtExitHandler);
197  CatchSignals();
198 
199  // Add the path were we store headers for GRSIProof macros to see
200  const char* pPath = getenv("GRSISYS");
201  gInterpreter->AddIncludePath(Form("%s/include", pPath));
202  // if we have a data parser/detector library, add it's include path as well
203  std::string library = gGRSIOpt->ParserLibrary();
204  if(!library.empty()) {
205  size_t tmpPos = library.rfind("/lib/lib");
206  if(tmpPos != std::string::npos) {
207  gInterpreter->AddIncludePath(Form("%s/include", library.substr(0,tmpPos).c_str()));
208  } else {
209  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;
210  }
211  // no need to load the parser library, that is already taken care of by TGRSIProof class
212  } else {
213  std::cout<<"Warning, no dataparser/detector library provided, won't be able to add include path!"<<std::endl;
214  }
215  // The first thing we want to do is see if we can compile the macros that are passed to us
216  if(gGRSIOpt->MacroInputFiles().empty()) {
217  std::cout<<DRED<<"Can't PROOF if there is no MACRO"<<RESET_COLOR<<std::endl;
218  return 1;
219  }
220  std::cout<<DCYAN<<"************************* MACRO COMPILATION ****************************"<<RESET_COLOR
221  <<std::endl;
222  for(const auto& i : gGRSIOpt->MacroInputFiles()) {
223  Int_t error_code = 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
224  if(error_code == 0) {
225  std::cout<<DRED<<i<<" failed to compile properly.. ABORT!"<<RESET_COLOR<<std::endl;
226  return 1;
227  }
228  }
229  std::cout<<DCYAN<<"************************* END COMPILATION ******************************"<<RESET_COLOR
230  <<std::endl;
231 
232  if(!gGRSIOpt->InputFiles().empty()) {
233  std::cout<<DRED<<"Can't Proof a Midas file..."<<RESET_COLOR<<std::endl;
234  }
235 
236  // The first thing we do is get the PROOF Lite instance to run
237  if(gGRSIOpt->GetMaxWorkers() >= 0) {
238  std::cout<<"Opening proof with '"<<Form("workers=%d", gGRSIOpt->GetMaxWorkers())<<"'"<<std::endl;
239  gGRSIProof = TGRSIProof::Open(Form("workers=%d", gGRSIOpt->GetMaxWorkers()));
240  } else if(gGRSIOpt->SelectorOnly()) {
241  std::cout<<"Opening proof with one worker (selector-only)"<<std::endl;
242  gGRSIProof = TGRSIProof::Open("workers=1");
243  } else {
245  }
246 
247  if(gGRSIProof == nullptr) {
248  std::cout<<"Couldn't connect to proof on first attempt, trying again"<<std::endl;
249  if(gGRSIOpt->GetMaxWorkers() >= 0) {
250  std::cout<<"Opening proof with '"<<Form("workers=%d", gGRSIOpt->GetMaxWorkers())<<"'"<<std::endl;
251  gGRSIProof = TGRSIProof::Open(Form("workers=%d", gGRSIOpt->GetMaxWorkers()));
252  } else if(gGRSIOpt->SelectorOnly()) {
253  std::cout<<"Opening proof with one worker (selector-only)"<<std::endl;
254  gGRSIProof = TGRSIProof::Open("workers=1");
255  } else {
257  }
258  }
259 
260  if(gGRSIProof == nullptr) {
261  std::cout<<"Still can't connect to proof, try running it again?"<<std::endl;
262  return 0;
263  }
264 
265  startedProof = true;
266 
267  gGRSIProof->SetBit(TProof::kUsingSessionGui);
268  gGRSIProof->AddEnvVar("GRSISYS", pPath);
269  gInterpreter->AddIncludePath(Form("%s/include", pPath));
270  gGRSIProof->AddIncludePath(Form("%s/include", pPath));
271  gGRSIProof->AddDynamicPath(Form("%s/lib", pPath));
272 
273  gGRSIProof->AddInput(gGRSIOpt->AnalysisOptions());
274  gGRSIProof->AddInput(new TNamed("pwd", getenv("PWD")));
275  int i = 0;
276  for(const auto& valFile : gGRSIOpt->ValInputFiles()) {
277  gGRSIProof->AddInput(new TNamed(Form("valFile%d", i++), valFile.c_str()));
278  }
279  i = 0;
280  for(const auto& calFile : gGRSIOpt->CalInputFiles()) {
281  gGRSIProof->AddInput(new TNamed(Form("calFile%d", i++), calFile.c_str()));
282  }
283  i = 0;
284  for(const auto& cutFile : gGRSIOpt->InputCutFiles()) {
285  gGRSIProof->AddInput(new TNamed(Form("cutFile%d", i++), cutFile.c_str()));
286  }
287  gGRSIProof->AddInput(new TNamed("ParserLibrary", library.c_str()));
288 
289  Analyze("FragmentTree");
290  Analyze("AnalysisTree");
291  Analyze("Lst2RootTree");
292 
293  AtExitHandler();
294 
295  return 0;
296 }
const std::vector< std::string > & ValInputFiles()
Definition: TGRSIOptions.h:45
void AtExitHandler()
Definition: grsiproof.cxx:102
const std::vector< std::string > & MacroInputFiles()
Definition: TGRSIOptions.h:50
TStopwatch * gStopwatch
Definition: grsiproof.cxx:30
#define DRED
Definition: Globals.h:17
const std::vector< std::string > & InputFiles()
Definition: TGRSIOptions.h:42
#define RESET_COLOR
Definition: Globals.h:4
TPPG * gPpg
Definition: grsiproof.cxx:31
static TGRSIOptions * Get(int argc=0, char **argv=nullptr)
Do not use!
static TRunInfo * AddCurrent()
Definition: TSingleton.h:137
int GetMaxWorkers() const
Definition: TGRSIOptions.h:131
bool startedProof
Definition: grsiproof.cxx:33
size_t NumberOfEvents() const
Definition: TGRSIOptions.h:112
#define DCYAN
Definition: Globals.h:20
bool SelectorOnly() const
Definition: TGRSIOptions.h:132
static TRunInfo * Get(bool verbose=false)
Definition: TSingleton.h:34
void SetGRSIEnv()
Definition: grsiproof.cxx:171
static int LastRunNumber()
Definition: TRunInfo.h:125
static int FirstSubRunNumber()
Definition: TRunInfo.h:123
bool controlC
Definition: grsiproof.cxx:34
const std::vector< std::string > & CalInputFiles()
Definition: TGRSIOptions.h:44
const std::vector< std::string > & RootInputFiles()
Definition: TGRSIOptions.h:43
static int RunNumber()
Definition: TRunInfo.h:119
static TAnalysisOptions * AnalysisOptions()
Definition: TGRSIOptions.h:68
static void CatchSignals()
Definition: grsiproof.cxx:161
void Print(Option_t *opt="") const override
Definition: TRunInfo.cxx:83
static int SubRunNumber()
Definition: TRunInfo.h:120
TGRSIOptions * gGRSIOpt
Definition: grsiproof.cxx:29
void ParserLibrary(std::string &library)
Definition: TGRSIOptions.h:137
TGRSIProof * gGRSIProof
Definition: grsiproof.cxx:28
static TGRSIProof * Open(const char *worker="")
Definition: TGRSIProof.h:48
void Add(const TPPG *ppg)
Definition: TPPG.cxx:676
#define DMAGENTA
Definition: Globals.h:19
void HandleSignal(int)
Definition: grsiproof.cxx:154
static int FirstRunNumber()
Definition: TRunInfo.h:122
static int LastSubRunNumber()
Definition: TRunInfo.h:126
int main(int argc, char **argv)
Definition: grsiproof.cxx:182
void Analyze(const char *tree_type)
Definition: grsiproof.cxx:36
Definition: TPPG.h:122
bool ShouldExit()
Definition: TGRSIOptions.h:41
const std::vector< std::string > & InputCutFiles()
Definition: TGRSIOptions.h:48