KaliVeda  1.13/01
Heavy-Ion Analysis Toolkit
KVPROOFSelector.cpp
Go to the documentation of this file.
1 #include "KVPROOFSelector.h"
2 #include <KVClassFactory.h>
3 #include <TDirectory.h>
4 #include <TProfile.h>
5 #include <TProfile2D.h>
6 #include <TTree.h>
7 #include "TProof.h"
8 #include <iostream>
9 #include "KVBase.h"
10 #include "TROOT.h"
11 
13 
14 
15 
16 
17 
22 void KVPROOFSelector::Begin(TTree* /*tree*/)
23 {
24  // Need to parse options here for use in Terminate
25  // Also, on PROOF, any KVDataAnalyser instance has to be passed to the workers
26  // via the TSelector input list.
27 
28  ParseOptions();
29 
30  if (IsOptGiven("CombinedOutputFile")) {
31  fCombinedOutputFile = GetOpt("CombinedOutputFile");
32  }
33  else if (gProof) {
34  // when running with PROOF, if the user calls SetCombinedOutputFile()
35  // in InitAnalysis(), it will only be executed on the workers (in SlaveBegin()).
36  // therefore we call InitAnalysis() here, but deactivate CreateTreeFile(),
37  // AddTree() and AddHisto() in order to avoid interference with workers
38  fDisableCreateTreeFile = kTRUE;
39  InitAnalysis(); //user initialisations for analysis
40  fDisableCreateTreeFile = kFALSE;
41  }
42 }
43 
44 
45 
59 
61 {
62  // The SlaveBegin() function is called after the Begin() function.
63  // When running with PROOF SlaveBegin() is called on each slave server.
64  // The tree argument is deprecated (on PROOF 0 is passed).
65  //
66  // ParseOptions : Manage options passed as arguments
67  //
68  // Called user method InitAnalysis where users can create trees or histos
69  // using the appropiate methods :
70  // CreateTrees and CreateMethods
71  //
72  // Test the presence or not of such histo or tree
73  // to manage it properly
74 
75  ParseOptions();
76 
77  if (IsOptGiven("CombinedOutputFile")) {
78  fCombinedOutputFile = GetOpt("CombinedOutputFile");
79  Info("SlaveBegin", "Output file name = %s", fCombinedOutputFile.Data());
80  }
81 
82  fEventsRead = 0;
83 
84  InitAnalysis(); //user initialisations for analysis
85 
86  if (ltree->GetEntries() > 0)
87  for (Int_t ii = 0; ii < ltree->GetEntries(); ii += 1) {
88  TTree* tt = (TTree*)ltree->At(ii);
89  tt->SetDirectory(writeFile);
90  tt->AutoSave();
91  }
92 }
93 
94 
95 
100 
102 {
103  // For PROOF:
104  // This method must be called before creating any user TTree in InitAnalysis().
105  // If no filename is given, default name="TreeFileFrom[name of selector class].root"
106 
107  if (fDisableCreateTreeFile) return kTRUE;
108 
109  if (!strcmp(filename, ""))
110  tree_file_name.Form("TreeFileFrom%s.root", ClassName());
111  else
112  tree_file_name = filename;
113 
116 
117  TDirectory* savedir = gDirectory;
118  writeFile = mergeFile->OpenFile("RECREATE");
120  savedir->cd();
121 
122  // Cannot continue
123  if (!writeFile) {
124  Info("CreateTreeFile", "could not create '%s': instance is invalid!", filename);
125  return kFALSE;
126  }
127  return kTRUE;
128 
129 }
130 
131 
132 
140 
142 {
143  // Processing will abort cleanly if static flag fCleanAbort has been set
144  // by some external controlling process.
145  //
146  // Use fStatus to set the return value of TTree::Process().
147  //
148  // The return value is currently not used.
149 
150  fEventsRead = entry;
152  Info("Process", " +++ %lld events processed +++ ", fEventsRead);
153  ProcInfo_t pid;
154  if (gSystem->GetProcInfo(&pid) == 0) {
155  std::cout << " ------------- Process infos -------------" << std::endl;
156  printf(" CpuSys = %f s. CpuUser = %f s. ResMem = %f MB VirtMem = %f MB\n",
157  pid.fCpuSys, pid.fCpuUser, pid.fMemResident / 1024., pid.fMemVirtual / 1024.);
158  }
159  }
160 
161  Bool_t ok_anal = kTRUE;
162  ok_anal = Analysis(); //user analysis
163 
164  return ok_anal;
165 }
166 
167 
168 
176 
178 {
179  // The SlaveTerminate() function is called after all entries or objects
180  // have been processed. When running with PROOF SlaveTerminate() is called
181  // on each slave server.
182  // if tree have been defined in the CreateTrees method
183  // manage the merge of them in ProofLite session
184  //
185 
186  if (ltree->GetEntries() > 0) {
187 
188  if (writeFile) {
189  TDirectory* savedir = gDirectory;
190  TTree* tt = 0;
191  for (Int_t ii = 0; ii < ltree->GetEntries(); ii += 1) {
192  tt = (TTree*)ltree->At(ii);
193  writeFile->cd();
194  tt->Write();
195  }
196  mergeFile->Print();
198 
199  for (Int_t ii = 0; ii < ltree->GetEntries(); ii += 1) {
200  tt = (TTree*)ltree->At(ii);
201  tt->SetDirectory(0);
202  }
203 
204  gDirectory = savedir;
205  writeFile->Close();
206  }
207 
208  }
209 
210 }
211 
212 
213 
222 
224 {
225  // The Terminate() function is the last function to be called during
226  // a query. It always runs on the client, it can be used to present
227  // the results graphically or save the results to file.
228  //
229  // This method call the user defined EndAnalysis
230  // where user can do what she wants
231  //
232 
233  TDatime now;
234  Info("Terminate", "Analysis ends at %s", now.AsString());
235 
236  if (fCombinedOutputFile != "") {
237  Info("Terminate", "combine = %s", fCombinedOutputFile.Data());
238  // combine histograms and trees from analysis into one file
239  TString file1, file2;
240  file1.Form("HistoFileFrom%s.root", ClassName());
241  file2.Form("TreeFileFrom%s.root", ClassName());
242  if (GetOutputList()->FindObject("ThereAreHistos")) {
243  if (GetOutputList()->FindObject(file2)) {
244  Info("Terminate", "both");
245  SaveHistos();
247  }
248  else {
249  // no trees - just rename histo file
250  Info("Terminate", "histo");
252  }
253  }
254  else if (GetOutputList()->FindObject(file2)) {
255  // no histos - just rename tree file
256  Info("Terminate", "tree");
258  }
259  else Info("Terminate", "none");
260  }
261 
262  EndAnalysis(); //user end of analysis routine
263 }
264 
265 
266 
267 
270 
272 {
273 
274  //return the list of created trees
275  return lhisto;
276 
277 }
278 
279 
280 
281 
283 
284 TH1* KVPROOFSelector::GetHisto(const Char_t* histo_name) const
285 {
286 
287  return lhisto->get_object<TH1>(histo_name);
288 
289 }
290 
291 
292 
293 
297 
299 {
300  // Declare a histogram to be used in analysis.
301  // This method must be called when using PROOF.
302 
303  if (fDisableCreateTreeFile) return;
304 
305  lhisto->Add(histo);
306  fOutput->Add(histo);
307  if (!fOutput->FindObject("ThereAreHistos")) fOutput->Add(new TNamed("ThereAreHistos", "...so save them!"));
308 }
309 
310 
311 
315 
317 {
318  // Declare a TTree to be used in analysis.
319  // This method must be called when using PROOF.
320 
321  if (fDisableCreateTreeFile) return;
322 
323  ltree->Add(tree);
324 }
325 
326 
327 
328 
334 
335 void KVPROOFSelector::FillHisto(const Char_t* histo_name, Double_t one, Double_t two, Double_t three, Double_t four)
336 {
337 
338  //Find in the list, if there is an histogram named "sname"
339  //If not print an error message
340  //If yes redirect to the right method according to its closest mother class
341  //to fill it
342  TH1* h1 = 0;
343  if ((h1 = GetHisto(histo_name))) {
344  if (h1->InheritsFrom("TH3"))
345  FillTH3((TH3*)h1, one, two, three, four);
346  else if (h1->InheritsFrom("TProfile2D"))
347  FillTProfile2D((TProfile2D*)h1, one, two, three, four);
348  else if (h1->InheritsFrom("TH2"))
349  FillTH2((TH2*)h1, one, two, three);
350  else if (h1->InheritsFrom("TProfile"))
351  FillTProfile((TProfile*)h1, one, two, three);
352  else if (h1->InheritsFrom("TH1"))
353  FillTH1(h1, one, two);
354  else
355  Warning("FillHisto", "%s -> Classe non prevue ...", lhisto->FindObject(histo_name)->ClassName());
356  }
357  else {
358  Warning("FillHisto", "%s introuvable", histo_name);
359  }
360 
361 }
362 
363 
364 
365 
367 
369 {
370 
371  h1->Fill(one, two);
372 
373 }
374 
375 
376 
377 
379 
381 {
382 
383  h1->Fill(one, two, three);
384 
385 }
386 
387 
388 
389 
391 
393 {
394 
395  h2->Fill(one, two, three);
396 
397 }
398 
399 
400 
401 
403 
405 {
406 
407  h2->Fill(one, two, three, four);
408 }
409 
410 
411 
412 
414 
416 {
417 
418  h3->Fill(one, two, three, four);
419 }
420 
421 
422 
423 
438 
439 void KVPROOFSelector::SaveHistos(const Char_t* filename, Option_t* option, Bool_t onlyfilled)
440 {
441  // Write in file all histograms declared with AddHisto(TH1*)
442  // This method works with PROOF.
443  //
444  // If no filename is specified, set default name : HistoFileFrom[KVEvenSelector::GetName()].root
445  //
446  // If a filename is specified, search in gROOT->GetListOfFiles() if
447  // this file has been already opened
448  // - if yes write in it
449  // - if not, create it with the corresponding option, write in it
450  // and close it just after
451  //
452  // onlyfilled flag allow to write all (onlyfilled=kFALSE, default)
453  // or only histograms (onlyfilled=kTRUE) those have been filled
454 
455  TString histo_file_name = "";
456  if (!strcmp(filename, ""))
457  histo_file_name.Form("HistoFileFrom%s.root", GetName());
458  else
459  histo_file_name = filename;
460 
461  Bool_t justopened = kFALSE;
462 
463  TFile* file = 0;
464  TDirectory* pwd = gDirectory;
465  //if filename correspond to an already opened file, write in it
466  //if not open/create it, depending on the option ("recreate" by default)
467  //and write in it
468  if (!(file = (TFile*)gROOT->GetListOfFiles()->FindObject(histo_file_name.Data()))) {
469  file = new TFile(histo_file_name.Data(), option);
470  justopened = kTRUE;
471  }
472  file->cd();
473  TIter next(GetOutputList());
474  TObject* obj = 0;
475  while ((obj = next())) {
476  if (obj->InheritsFrom("TH1")) {
477  if (onlyfilled) {
478  if (((TH1*)obj)->GetEntries() > 0) {
479  obj->Write();
480  }
481  }
482  else {
483  obj->Write();
484  }
485  }
486  }
487  if (justopened)
488  file->Close();
489  pwd->cd();
490 
491 }
492 
493 
494 
495 
498 
500 {
501  //return the list of created trees
502  return ltree;
503 
504 }
505 
506 
507 
508 
511 
512 TTree* KVPROOFSelector::GetTree(const Char_t* tree_name) const
513 {
514  //return the tree named tree_name
515  return ltree->get_object<TTree>(tree_name);
516 
517 }
518 
519 
520 
521 
528 
529 void KVPROOFSelector::FillTree(const Char_t* tree_name)
530 {
531  //Filltree method, the tree named tree_name
532  //has to be declared with AddTTree(TTree*) method
533  //
534  //if no sname="", all trees in the list is filled
535  //
536  if (!strcmp(tree_name, "")) {
537  ltree->Execute("Fill", "");
538  }
539  else {
540  TTree* tt = 0;
541  if ((tt = GetTree(tree_name))) {
542  tt->Fill();
543  }
544  else {
545  Warning("FillTree", "%s introuvable", tree_name);
546  }
547  }
548 
549 }
550 
551 
552 
555 
556 void KVPROOFSelector::SetOpt(const Char_t* option, const Char_t* value)
557 {
558  //Set a value for an option
559  KVString tmp(value);
560  fOptionList.SetValue(option, tmp);
561 }
562 
563 
564 
565 
568 
570 {
571  // Returns kTRUE if the option 'opt' has been set
572 
573  return fOptionList.HasParameter(opt);
574 }
575 
576 
577 
578 
582 
584 {
585  // Returns the value of the option
586  // Only use after checking existence of option with IsOptGiven(const Char_t* opt)
587 
588  return fOptionList.GetTStringValue(opt);
589 }
590 
591 
592 
593 
596 
598 {
599  // Removes the option 'opt' from the internal lists, as if it had never been set
600 
602 }
603 
604 
605 
611 
613 {
614  // Analyse comma-separated list of options given to TTree::Process
615  // and store all "option=value" pairs in fOptionList.
616  // Options can then be accessed using IsOptGiven(), GetOptString(), etc.
617  // This method is called by SlaveBegin
618 
619  fOptionList.Clear(); // clear list
620  KVString option = GetOption();
621  option.Begin(",");
622  while (!option.End()) {
623 
624  KVString opt = option.Next();
625  opt.Begin("=");
626  KVString param = opt.Next();
627  KVString val = opt.Next();
628  while (!opt.End()) {
629  val += "=";
630  val += opt.Next();
631  }
632 
633  SetOpt(param.Data(), val.Data());
634  }
635 
636  fOptionList.Print();
637 }
638 
639 
640 
643 
644 void KVPROOFSelector::Make(const Char_t* classname)
645 {
646  // Generate a new class derived from this one with given name
647 
648  KVClassFactory cf(classname, "User class for PROOF", "KVPROOFSelector");
650  cf.AddMethod("InitAnalysis", "void");
651  cf.AddMethod("Analysis", "Bool_t");
652  cf.AddMethodBody("Analysis", " // Write your code here\n return kTRUE;");
653  cf.AddMethod("EndAnalysis", "void");
654  cf.GenerateCode();
655 }
656 
657 
int Int_t
ClassImp(KVPartitionList) void KVPartitionList
Initialisation.
#define SafeDelete(p)
char Char_t
const Bool_t kFALSE
bool Bool_t
double Double_t
const Bool_t kTRUE
const char Option_t
#define gDirectory
R__EXTERN TProof * gProof
#define gROOT
R__EXTERN TSystem * gSystem
static void CombineFiles(const Char_t *file1, const Char_t *file2, const Char_t *newfilename, Bool_t keep=kTRUE)
Definition: KVBase.cpp:1527
Factory class for generating skeleton files for new classes.
void GenerateCode()
Generate header and implementation file for currently-defined class.
void SetInheritAllConstructors(Bool_t yes=kTRUE)
void AddMethodBody(const Char_t *method_name, const KVString &body)
KVClassMethod * AddMethod(const Char_t *name, const Char_t *return_type, const Char_t *access="public", Bool_t isVirtual=kFALSE, Bool_t isConst=kFALSE)
Extended version of ROOT THashList.
Definition: KVHashList.h:28
virtual void Print(Option_t *opt="") const
void SetValue(const Char_t *name, value_type value)
void RemoveParameter(const Char_t *name)
virtual void Clear(Option_t *opt="")
Bool_t HasParameter(const Char_t *name) const
TString GetTStringValue(const Char_t *name) const
General purpose class for running parallel tasks with PROOF.
void FillTree(const Char_t *sname="")
void FillTH1(TH1 *h1, Double_t one, Double_t two)
virtual void InitAnalysis()=0
void AddHisto(TH1 *histo)
void FillTProfile2D(TProfile2D *h2, Double_t one, Double_t two, Double_t three, Double_t four)
virtual void UnsetOpt(const Char_t *opt)
Removes the option 'opt' from the internal lists, as if it had never been set.
void AddTree(TTree *tree)
virtual void EndAnalysis()=0
Bool_t fDisableCreateTreeFile
used with PROOF
virtual void Terminate()
virtual Bool_t Analysis()=0
void FillTProfile(TProfile *h1, Double_t one, Double_t two, Double_t three)
KVHashList * GetHistoList() const
return the list of created trees
virtual TString GetOpt(const Char_t *option) const
KVString fCombinedOutputFile
optional name for single results file with trees and histos
void FillHisto(const Char_t *sname, Double_t one, Double_t two=1, Double_t three=1, Double_t four=1)
void FillTH2(TH2 *h2, Double_t one, Double_t two, Double_t three)
TTree * GetTree(const Char_t *name) const
return the tree named tree_name
virtual void SaveHistos(const Char_t *filename="", Option_t *option="recreate", Bool_t onlyfilled=kFALSE)
virtual void ParseOptions()
virtual void SlaveBegin(TTree *tree)
virtual void SetOpt(const Char_t *option, const Char_t *value)
Set a value for an option.
KVHashList * lhisto
!
static void Make(const Char_t *classname)
Generate a new class derived from this one with given name.
TH1 * GetHisto(const Char_t *name) const
TProofOutputFile * mergeFile
for merging with PROOF
Long64_t fEventsReadInterval
interval at which to print number of events read
KVNameValueList fOptionList
parsed list of options given to TTree::Process
void FillTH3(TH3 *h3, Double_t one, Double_t two, Double_t three, Double_t four)
Bool_t CreateTreeFile(const Char_t *filename="")
KVHashList * ltree
!
Long64_t fEventsRead
cycle number (argument 'entry' passed to Process(Long64_t))
virtual Bool_t Process(Long64_t entry)
KVHashList * GetTreeList() const
return the list of created trees
virtual Bool_t IsOptGiven(const Char_t *option)
Returns kTRUE if the option 'opt' has been set.
virtual void SlaveTerminate()
T * get_object(const TString &name) const
virtual TObject * At(Int_t idx) const
virtual void Execute(const char *method, const char *params, Int_t *error=0)
virtual void Add(TObject *obj)
virtual TObject * FindObject(const char *name) const
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:72
void Begin(TString delim) const
Definition: KVString.cpp:565
Bool_t End() const
Definition: KVString.cpp:634
KVString Next(Bool_t strip_whitespace=kFALSE) const
Definition: KVString.cpp:695
virtual Int_t GetEntries() const
const char * AsString() const
Bool_t cd(const char *path=nullptr) override
virtual Bool_t cd(const char *path=nullptr)
void Close(Option_t *option="") override
virtual Int_t Fill(const char *name, Double_t w)
virtual Int_t Fill(const char *namex, const char *namey, Double_t w)
virtual Int_t Fill(const char *namex, const char *namey, const char *namez, Double_t w)
TObject * FindObject(const char *name) const
virtual void Add(TObject *obj)
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
virtual const char * GetName() const
virtual const char * ClassName() const
virtual void Warning(const char *method, const char *msgfmt,...) const
virtual TObject * FindObject(const char *name) const
R__ALWAYS_INLINE Bool_t IsZombie() const
virtual Bool_t InheritsFrom(const char *classname) const
virtual void Info(const char *method, const char *msgfmt,...) const
virtual Int_t Fill(const char *namex, const char *namey, Double_t z, Double_t w=1.)
TFile * OpenFile(const char *opt)
void SetOutputFileName(const char *name)
void Print(Option_t *option="") const
TSelectorList * fOutput
virtual TList * GetOutputList() const
virtual const char * GetOption() const
const char * Data() const
void Form(const char *fmt,...)
virtual int GetProcInfo(ProcInfo_t *info) const
virtual int Rename(const char *from, const char *to)
long long Long64_t
TH1F * h1
Long_t fMemVirtual
Float_t fCpuSys
Long_t fMemResident
Float_t fCpuUser
auto * tt