ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TreeMod/src/Analysis.cc
Revision: 1.43
Committed: Tue Mar 29 01:35:08 2011 UTC (14 years, 1 month ago) by paus
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_025c_branch2, Mit_025c_branch1, Mit_028a, Mit_025c_branch0, Mit_028, Mit_027a, Mit_027, Mit_026, Mit_025e, Mit_025d, Mit_025c, Mit_025b, Mit_025a, Mit_025, Mit_025pre2, Mit_024b, Mit_025pre1, Mit_024a, Mit_024, Mit_023, Mit_022a, Mit_022, Mit_020d, TMit_020d, Mit_020c, Mit_021, Mit_021pre2, Mit_021pre1, Mit_020b, Mit_020a, Mit_020, Mit_020pre1
Branch point for: Mit_025c_branch
Changes since 1.42: +8 -8 lines
Log Message:
Bug fix in FileUrl -- found by Guillelmo et al.

File Contents

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