ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TreeMod/src/Analysis.cc
Revision: 1.40
Committed: Mon May 10 16:16:39 2010 UTC (15 years ago) by bendavid
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_014b, Mit_014a, Mit_014, Mit_014pre3, Mit_014pre2, Mit_014pre1
Changes since 1.39: +3 -3 lines
Log Message:
move to xrootd

File Contents

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