ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TreeMod/src/Analysis.cc
Revision: 1.45
Committed: Sat Sep 29 11:26:40 2012 UTC (12 years, 7 months ago) by ceballos
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_030, Mit_029c, Mit_029b, Mit_030_pre1, Mit_029a
Changes since 1.44: +7 -3 lines
Log Message:
using root://castorcms

File Contents

# Content
1 // $Id: Analysis.cc,v 1.44 2012/07/23 15:47:24 ceballos Exp $
2
3 #include "MitAna/TreeMod/interface/Analysis.h"
4 #include <memory>
5 #include <Riostream.h>
6 #include <TFile.h>
7 #include <TList.h>
8 #include <TDSet.h>
9 #include <TChain.h>
10 #include <TObjString.h>
11 #include <TSystem.h>
12 #include <TProof.h>
13 #include <TROOT.h>
14 #include <TBrowser.h>
15 #include <TTreeCacheUnzip.h>
16 #include "MitAna/DataUtil/interface/Debug.h"
17 #include "MitAna/DataTree/interface/Names.h"
18 #include "MitAna/TAM/interface/TAMVirtualLoader.h"
19 #include "MitAna/TAM/interface/TAModule.h"
20 #include "MitAna/TreeMod/interface/Selector.h"
21 #include "MitAna/TreeMod/interface/TreeLoader.h"
22 #include "MitAna/TreeMod/interface/AnaFwkMod.h"
23 #include "MitAna/TreeMod/interface/HLTFwkMod.h"
24 #include "MitAna/Catalog/interface/Catalog.h"
25 #include "MitAna/Catalog/interface/Dataset.h"
26
27 ClassImp(mithep::Analysis)
28
29 using namespace mithep;
30
31 //--------------------------------------------------------------------------------------------------
32 Analysis::Analysis(Bool_t useproof) :
33 fUseProof(useproof),
34 fUseHLT(kTRUE),
35 fHierarchy(kTRUE),
36 fDoProxy(kFALSE),
37 fDoObjTabClean(kTRUE),
38 fParallel(kFALSE),
39 fState(kPristine),
40 fNFriends(0),
41 fList(new TList),
42 fOutput(0),
43 fPackages(new TList),
44 fLoaders(new TList),
45 fSuperMods(new TList),
46 fSelector(0),
47 fChain(0),
48 fSet(0),
49 fDeleteList(new TList),
50 fCompLevel(7),
51 fProof(0),
52 fDoNEvents(TChain::kBigNumber),
53 fSkipNEvents(0),
54 fPrintScale(1),
55 fCacheSize(-1),
56 fTreeName(Names::gkEvtTreeName),
57 fEvtHdrName(Names::gkEvtHeaderBrn),
58 fRunTreeName(Names::gkRunTreeName),
59 fRunInfoName(Names::gkRunInfoBrn),
60 fAllEvtHdrBrn(Names::gkAllEvtHeaderBrn),
61 fLATreeName(Names::gkLATreeName),
62 fLAHdrName(Names::gkLAHeaderBrn),
63 fHLTTreeName(Names::gkHltTreeName),
64 fAllEvtTreeName(Names::gkAllEvtTreeName),
65 fHLTObjsName(Names::gkHltObjBrn)
66 {
67 // Default constructor.
68
69 fList->SetOwner();
70 fDeleteList->SetOwner();
71
72 /* default packages for PROOF upload */
73 fPackages->SetOwner();
74 // nothing to be done since we do not use par files (yet?)
75 }
76
77 //--------------------------------------------------------------------------------------------------
78 Analysis::~Analysis()
79 {
80 // Destructor.
81
82 if (fState == kInit || fState == kRun)
83 Terminate();
84
85 delete fList;
86 delete fPackages;
87 delete fLoaders;
88 delete fDeleteList;
89 delete fSelector;
90 delete fSuperMods;
91 fOutput = 0; // owned by TAM
92
93 delete fProof;
94 }
95
96 //--------------------------------------------------------------------------------------------------
97 Bool_t Analysis::AddDataset(const Dataset *dataset)
98 {
99 // Add a full dataset to the analysis.
100
101 Bool_t status = kTRUE;
102
103 for (UInt_t i=0; i<dataset->NFiles(); ++i)
104 status = (status && AddFile((dataset->FileUrl(i)).Data()));
105
106 return status;
107 }
108
109 //--------------------------------------------------------------------------------------------------
110 Bool_t Analysis::AddFile(const char *pname)
111 {
112 // Add file with given name to the list of files to be processed. Using the token "|", you can
113 // specify an arbritray number of paths to tree files that will be concatenated as friend trees.
114
115 if (fState != kPristine) {
116 Error("AddFile", "Analysis already initialized");
117 return kFALSE;
118 }
119
120 ////================================================================================================
121 //// Please do not ask me why I need to do this but I have to?! (CP - Oct02, 2010)
122 //char fileName[4096];
123 //strcpy(fileName,pname);
124 ////================================================================================================
125
126 TString pnamestr(pname);
127
128 if (pnamestr.IsNull())
129 return kFALSE;
130
131 TString tok("|");
132 TObjArray *arr = pnamestr.Tokenize(tok);
133 if (!arr)
134 return kFALSE;
135
136 TString msg;
137 for (Int_t i=0; i<arr->GetEntries(); ++i) {
138
139 TObjString *dummy = dynamic_cast<TObjString*>(arr->At(i));
140 if (!dummy)
141 continue;
142
143 AddFile(dummy->GetName(),i);
144 if (i==0)
145 msg=dummy->GetName();
146 else
147 Info("AddFile", "Add file %s as friend to %s", dummy->GetName(), msg.Data());
148 }
149 delete arr;
150
151 return kTRUE;
152 }
153
154 //--------------------------------------------------------------------------------------------------
155 void Analysis::AddFile(const char *pname, Int_t eventlist)
156 {
157 // Add file name to the event list specified by eventlist. The lists are used to hold filenames of
158 // different types of events. In case you dont want friend trees, just give no eventlist argument
159 // (default 0).
160
161 MitAssert("AddFile", pname != 0);
162
163 TList *l = 0;
164 if (eventlist >= 0 && eventlist < fNFriends) {
165
166 l = dynamic_cast<TList*>(fList->At(eventlist));
167 if (!l) {
168 Fatal("AddFile", "Requested list %d not found!", eventlist);
169 return;
170 }
171
172 } else if (eventlist == fNFriends) {
173
174 l = new TList;
175 l->SetOwner();
176 fList->Add(l);
177 ++fNFriends;
178
179 } else if (eventlist < 0 || eventlist > fNFriends) {
180 Error("AddFile", "Specified list %d not in [0,%d]", eventlist, fNFriends);
181 return;
182 }
183
184 if (! IsValidName(pname))
185 return;
186
187 TString theFile(pname);
188 //if ( theFile.BeginsWith("castor:") )
189 // theFile.ReplaceAll("castor:","rfio:");
190 //if ( theFile.BeginsWith("/castor/"))
191 // theFile.ReplaceAll("/castor/","rfio:/castor/");
192 if ( theFile.BeginsWith("castor:") )
193 theFile.ReplaceAll("castor:","root://castorcms/");
194 if ( theFile.BeginsWith("/castor/"))
195 theFile.Prepend("root://castorcms/");
196 printf("Adding file with path: %s\n",theFile.Data());
197 l->Add(new TObjString(theFile.Data()));
198
199 MDB(kAnalysis, 2)
200 Info("AddFile", "Added %s to list of files.", pname);
201 }
202
203 //--------------------------------------------------------------------------------------------------
204 void Analysis::AddFile(const TObject *oname, Int_t eventlist)
205 {
206 // Add file name to the event list specified by eventlist. The lists are used to hold filenames of
207 // different types of events. In case you dont want mixing, just give no eventlist argument
208 // (default 0).
209
210 MitAssert("AddFile", oname != 0);
211
212 return AddFile(oname->GetName(), eventlist);
213 }
214
215 //________________________________________________________________________
216 Bool_t Analysis::AddFiles(const char *pname, Int_t nmax)
217 {
218 // Add files from text file with given name. If nmax>0, maximum nmax files will be added.
219
220 MitAssert("AddFiles", pname != 0);
221
222 ifstream in;
223 in.open(pname);
224 if (!in) {
225 Error("AddFiles", "Cannot open file with name %s", pname);
226 return kFALSE;
227 }
228
229 Int_t fc = 0;
230 while (in) {
231 TString line;
232 line.ReadLine(in);
233 if (!line.EndsWith(".root"))
234 continue;
235
236 if (!AddFile(line)) {
237 Error("AddFiles", "Error adding file with name %s", line.Data());
238 return kFALSE;
239 }
240
241 ++fc;
242 if (nmax>0 && fc>=nmax) {
243 Info("AddFiles", "Maximal number (%d) of files added", nmax);
244 break;
245 }
246 }
247
248 return kTRUE;
249 }
250
251 //--------------------------------------------------------------------------------------------------
252 void Analysis::AddList(TList *list, Int_t eventlist)
253 {
254 // Add file name to the event list specified by eventlist. The lists are used to hold filenames of
255 // different types of events. In case you dont want mixing, just give no eventlist argument
256 // (default 0).
257
258 MitAssert("AddList", list != 0);
259
260 TIter next(list);
261 while (TObject *obj = next())
262 AddFile(obj->GetName(), eventlist);
263 }
264
265 //--------------------------------------------------------------------------------------------------
266 void Analysis::AddLoader(TAMVirtualLoader *l)
267 {
268 // Add loader to the list of loaders.
269
270 fLoaders->Add(l);
271 }
272
273 //--------------------------------------------------------------------------------------------------
274 void Analysis::AddPackage(const char* name)
275 {
276 // Add package to the list of uploaded packages.
277
278 MitAssert("AddPackage", name != 0);
279 fPackages->Add(new TObjString(name));
280 }
281
282 //--------------------------------------------------------------------------------------------------
283 void Analysis::AddPackages(TList *list)
284 {
285 // Add list of packages to the list of uploaded packages.
286
287 MitAssert("AddPackage", list != 0);
288
289 TIter next(list);
290 while (TObject *obj = next()) {
291 fPackages->Add(new TObjString(obj->GetName()));
292 }
293 }
294
295 //--------------------------------------------------------------------------------------------------
296 void Analysis::AddSuperModule(TAModule *mod)
297 {
298 // Add a top-level module to list of top-level (super) modules.
299
300 fSuperMods->Add(mod);
301 }
302
303 //--------------------------------------------------------------------------------------------------
304 void Analysis::FileInputFromEnv()
305 {
306 // Attempt to get list of filesets/files from environment.
307
308 TString catalog (gSystem->Getenv("MIT_CATALOG"));
309 TString book (gSystem->Getenv("MIT_BOOK"));
310 TString dataset (gSystem->Getenv("MIT_DATASET"));
311 TString filesets(gSystem->Getenv("MIT_FILESETS"));
312 TString files (gSystem->Getenv("MIT_FILES"));
313
314 if ((catalog.IsNull() || book.IsNull() || dataset.IsNull()) && files.IsNull()) {
315 Warning("FileInputFromEnv", "Called to get file info from environment, but did not get"
316 " consistent set of variables:\n\tMIT_CATALOG=%s\n\tMIT_BOOK=%s\n\t"
317 "MIT_DATASET=%s\n\tMIT_FILESETS=%s\n\tMIT_FILES=%s\n",
318 catalog.Data(), book.Data(), dataset.Data(), filesets.Data(), files.Data());
319 return;
320 }
321
322 if (!files.IsNull()) { // add local files
323 Info("FileInputFromEnv", "Got from environment:\n"
324 "\n\tMIT_FILES=%s\n", files.Data());
325 TString tok(";");
326 TObjArray *arr = files.Tokenize(tok);
327 if (arr) {
328 for (Int_t i=0; i<arr->GetEntries(); ++i) {
329 TObjString *dummy = dynamic_cast<TObjString*>(arr->At(i));
330 if (!dummy) continue;
331 AddFile(dummy->GetName(),0);
332 }
333 delete arr;
334 }
335 return;
336 }
337
338 Info("FileInputFromEnv", "Got from environment:\n"
339 "\tMIT_CATALOG=%s\n\tMIT_BOOK=%s\n\tMIT_DATASET=%s\n\tMIT_FILESETS=%s\n",
340 catalog.Data(), book.Data(), dataset.Data(), filesets.Data());
341
342 Catalog cat(catalog);
343 if (filesets.IsNull()) {
344 Dataset *d = cat.FindDataset(book, dataset);
345 if (d) {
346 AddDataset(d);
347 delete d;
348 }
349 } else {
350 TString tok(";");
351 TObjArray *arr = filesets.Tokenize(tok);
352 if (arr) {
353 for (Int_t i=0; i<arr->GetEntries(); ++i) {
354 TObjString *fileset = dynamic_cast<TObjString*>(arr->At(i));
355 if (!fileset) continue;
356 Dataset *d = cat.FindDataset(book, dataset, fileset->String());
357 if (!d)
358 continue;
359 AddDataset(d);
360 delete d;
361 }
362 delete arr;
363 }
364 }
365 }
366
367 //--------------------------------------------------------------------------------------------------
368 Bool_t Analysis::Init()
369 {
370 // Setup the TDSet and TChain to be used for the analysis with or without PROOF. If more than one
371 // list of file names was given, friend trees are supported.
372
373 if (fState == kRun || fState == kInit) {
374 Error("Init", "Init in state %d is not possible! Call Terminate() first.",
375 Int_t(fState));
376 return kFALSE;
377 }
378
379 // check if we should attempt to get filesets/filenames from environment
380 if (fNFriends == 0)
381 FileInputFromEnv();
382
383 if (fNFriends <= 0) {
384 Error("Init", "List of friend lists is empty!");
385 return kFALSE;
386 }
387
388 if (!fSuperMods->First()) {
389 Error("Init", "Top-level TAM module is NULL!");
390 return kFALSE;
391 }
392
393 if (fUseProof) { // first init our PROOF session
394 if (!InitProof())
395 return kFALSE;
396 }
397
398 // we do this here instead in Terminate() so that
399 // we can browse the output even after Terminate()
400 delete fSelector;
401 fSelector = 0;
402
403 fChain = new TChain(fTreeName);
404 fSet = new TDSet("TTree",fTreeName);
405
406 for (Int_t i=0; i<fNFriends; ++i) {
407 TList *l = dynamic_cast<TList*>(fList->At(i));
408 if (!l) {
409 Fatal("Init", "List %d not found!", i);
410 return kFALSE;
411 }
412
413 if (i == 0) {
414 TIter next(l);
415 while (TObjString *obj = dynamic_cast<TObjString*>(next())) {
416 fChain->Add(obj->GetName());
417 fSet->Add(obj->GetName());
418 if (fCacheSize<0 && obj->GetString().Contains("/castor/"))
419 fCacheSize = 64*1024*1024;
420 }
421 } else {
422 TChain *chain = new TChain(fTreeName);
423 TDSet *set = new TDSet("TTree",fTreeName);
424
425 TIter next(l);
426 while (TObjString *obj = dynamic_cast<TObjString*>(next())) {
427 chain->Add(obj->GetName());
428 set->Add(obj->GetName());
429 if (fCacheSize<0 && obj->GetString().Contains("/castor/"))
430 fCacheSize = 64*1024*1024;
431 }
432
433 TString alias("TAMTREE_"); // aliases currently not used
434 alias+=i;
435
436 fChain->AddFriend(chain,alias.Data());
437 fSet->AddFriend(set,alias.Data());
438
439 fDeleteList->Add(chain);
440 fDeleteList->Add(set);
441 }
442 }
443
444 if (fParallel)
445 TTreeCacheUnzip::SetParallelUnzip(TTreeCacheUnzip::kEnable);
446
447 //if (fCacheSize>=0)
448 // fChain->SetCacheSize(fCacheSize);
449
450 // create our customized loader plugin for TAM
451 TreeLoader *bl = new TreeLoader;
452 fLoaders->Add(bl);
453 fDeleteList->Add(bl);
454
455 // create our ana framework module
456 AnaFwkMod *anamod = new AnaFwkMod;
457 anamod->SetSkipNEvents(fSkipNEvents);
458 anamod->SetPrintScale(fPrintScale);
459 fDeleteList->Add(anamod);
460
461 // create our HLT framework module
462 HLTFwkMod *hltmod = 0;
463 if (fUseHLT) {
464 hltmod = new HLTFwkMod;
465 hltmod->SetHLTObjsName(GetHLTObjsName());
466 hltmod->SetHLTTreeName(GetHLTTreeName());
467 fDeleteList->Add(hltmod);
468 }
469
470 if (fUseProof) {
471
472 fProof->AddInput(anamod);
473 if (hltmod)
474 fProof->AddInput(hltmod);
475
476 TIter iter(fSuperMods->MakeIterator());
477 while (1) {
478 TAModule *next = dynamic_cast<TAModule*>(iter.Next());
479 if (!next) break;
480 fProof->AddInput(next);
481 }
482
483 fLoaders->SetName("TAM_LOADERS");
484 fProof->AddInput(fLoaders);
485
486 } else {
487
488 // when not running Proof, we must make a selector
489 Selector *sel = new Selector;
490 sel->SetCacheSize(fCacheSize);
491 sel->SetDoProxy(fDoProxy);
492 sel->SetDoObjTabClean(fDoObjTabClean);
493 sel->SetDoRunInfo(kTRUE);
494 sel->SetAllEvtHdrBrn(GetAllEvtHdrBrn());
495 sel->SetAllEvtTreeName(GetAllEvtTreeName());
496 sel->SetEvtHdrName(GetEvtHdrName());
497 sel->SetLAHdrName(GetLAHdrName());
498 sel->SetLATreeName(GetLATreeName());
499 sel->SetRunInfoName(GetRunInfoName());
500 sel->SetRunTreeName(GetRunTreeName());
501 sel->AddInput(anamod);
502 fSelector = sel;
503
504 if (hltmod)
505 fSelector->AddInput(hltmod);
506
507 TIter iter(fSuperMods->MakeIterator());
508 while (1) {
509 TAModule *next = dynamic_cast<TAModule*>(iter.Next());
510 if (!next) break;
511 fSelector->AddInput(next);
512 }
513
514 MDB(kAnalysis, 2)
515 fSelector->SetVerbosity(1);
516
517 // pass loaders to selector
518 TIter next(fLoaders);
519 while (TAMVirtualLoader *l = dynamic_cast<TAMVirtualLoader*>(next()))
520 fSelector->AddLoader(l);
521 }
522
523 fState = kInit;
524 return kTRUE;
525 }
526
527 //--------------------------------------------------------------------------------------------------
528 Bool_t Analysis::InitProof()
529 {
530 // Initialize PROOF connection.
531
532 if (fProof && fProof->IsValid())
533 return kTRUE;
534
535 delete fProof;
536
537 if (fMaster.Contains("rcf.bnl.gov")) {
538 for (Int_t i=0; i<5; ++i) {
539 Warning("InitProof", "*** DID YOU RUN PROOF_KINIT? %d (5) ***", i);
540 gSystem->Sleep(1000);
541 }
542 }
543
544 MDB(kAnalysis, 1)
545 Info("InitProof", "Starting PROOF on master %s with config %s",
546 fMaster.Data(), fConfig.Data());
547
548 fProof = dynamic_cast<TProof*>(TProof::Open(fMaster, fConfig));
549 if (!fProof) {
550 Error("InitProof", "Could not start PROOF!");
551 return kFALSE;
552 }
553
554 MDB(kAnalysis, 3)
555 gROOT->Print();
556
557 //fProof->AddInput(new TNamed("PROOF_NewPacketizer",""));
558
559 Bool_t ret=kTRUE;
560 if (fPackages) {
561 // tell Proof what additional libraries we will need on each worker computer
562 ret = UploadPackages(fPackages);
563 }
564
565 return ret;
566 }
567
568 //--------------------------------------------------------------------------------------------------
569 void Analysis::Run()
570 {
571 // Run the analysis on the created file set.
572
573 if (fState == kPristine || fState == kRun) {
574 Error("Run", "Run in state %d is not possible! Call Init() first.",
575 Int_t(fState));
576 }
577
578 if (fUseProof) {
579
580 MDB(kAnalysis, 1)
581 Info("Run", "Start processing with PROOF...");
582
583 fSet->Process("Selector","",fDoNEvents);
584
585 } else {
586
587 MDB(kAnalysis, 1)
588 Info("Run", "Start processing (no PROOF)...");
589
590 fChain->Process(fSelector,"",fDoNEvents);
591 }
592
593 MDB(kAnalysis, 1)
594 Info("Run", "Processing complete!");
595
596 fState = kRun;
597 }
598
599 //--------------------------------------------------------------------------------------------------
600 Bool_t Analysis::Run(Bool_t browse)
601 {
602 // Execute analysis and open TBrowser if requested.
603
604 if (Init()) {
605 Run();
606 Terminate();
607 if (browse) {
608 new TBrowser;
609 }
610 return kTRUE;
611 }
612
613 Error("Execute", "Could not initialize analysis.");
614 return kFALSE;
615 }
616
617 //--------------------------------------------------------------------------------------------------
618 void Analysis::SetSuperModule(TAModule *mod)
619 {
620 // Set the first top-level module in the list of top-level (super) modules.
621
622 fSuperMods->AddFirst(mod);
623 }
624
625 //--------------------------------------------------------------------------------------------------
626 void Analysis::Terminate()
627 {
628 // Terminate current analysis run.
629
630 if (fState == kPristine || fState == kTerminate) {
631 Error("Terminate", "Terminate in state %d is not possible! Call Init() first.",
632 Int_t(fState));
633 return;
634 }
635
636 if (fState == kRun) {
637
638 if (fUseProof) {
639 // the output list from Proof can (in principal) contain other objects
640 // besides the module output hierarchy.
641 TList* outputlist = fProof->GetOutputList();
642 TIter nextOut(outputlist);
643 while (TObject *obj = nextOut()) {
644 if (obj->InheritsFrom(TAMOutput::Class())) {
645 fOutput = dynamic_cast<TList*>(obj);
646 break;
647 }
648 }
649
650 } else {
651 fOutput = fSelector->GetModOutput();
652 }
653
654
655
656 if (fOutput && !fAnaOutput.IsNull()) {
657 TDirectory::TContext context(0); // automatically restore gDirectory
658
659 std::auto_ptr<TFile> outf(TFile::Open(fAnaOutput,"recreate","", fCompLevel));
660 if (outf.get() == 0) {
661 Error("Terminate", "Could not open file %s for output!", fAnaOutput.Data());
662 } else {
663 MDB(kAnalysis, 1)
664 Info("Terminate", "Saving output to %s!", fAnaOutput.Data());
665
666 if (fHierarchy)
667 fOutput->Write(0,-99);
668 else
669 fOutput->Write();
670 }
671 }
672 // set state to terminate
673 fState = kTerminate;
674 }
675
676 delete fChain;
677 delete fSet;
678 fDeleteList->Delete();
679 }
680
681 //--------------------------------------------------------------------------------------------------
682 Bool_t Analysis::UploadPackages(TList *packages)
683 {
684 // Upload list of par files to the server.
685
686 MitAssert("UploadPackages", packages != 0);
687
688 for (Int_t i=0; i<packages->GetEntries(); ++i) {
689
690 TObject* objstr = packages->At(i);
691 if (!objstr) {
692 Error("InitProof", "Problem at package number %d!", i);
693 return kFALSE;
694 }
695
696 TString packname = objstr->GetName();
697 Int_t en = 0;
698 if (packname.EndsWith("+")) {
699 en=1;
700 packname.Resize(packname.Length()-1);
701 }
702
703 ifstream ftest(gSystem->ExpandPathName(packname.Data()),ios_base::binary);
704 if (!ftest.good()) {
705 Error("InitProof", "Could not open %s for upload!", packname.Data());
706 return kFALSE;
707 }
708
709 if (fProof->UploadPackage(packname)<0) {
710 Error("UploadPackage", "Upload for %s failed!", packname.Data());
711 return kFALSE;
712 }
713
714 if (en == 1) {
715 Int_t pos=packname.Last('/')+1;
716 if (pos)
717 packname.Remove(0,pos);
718 if (fProof->EnablePackage(packname)<0) {
719 Error("UploadPackage", "Enabling for %s failed!", packname.Data());
720 return kFALSE;
721 }
722 }
723 }
724
725 return kTRUE;
726 }