ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TreeMod/src/Analysis.cc
Revision: 1.41
Committed: Sun Oct 3 02:26:30 2010 UTC (14 years, 7 months ago) by paus
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_018, Mit_017, Mit_017pre3, Mit_017pre2, Mit_017pre1, Mit_016, Mit_015b, Mit_015a, Mit_015, Mit_014e, Mit_014d, Mit_014c
Changes since 1.40: +17 -9 lines
Log Message:
Patching a mysterious bug....

File Contents

# Content
1 // $Id: Analysis.cc,v 1.40 2010/05/10 16:16:39 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 = kTRUE;
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 //================================================================================================
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(fileName);
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->SetDoProxy(fDoProxy);
487 sel->SetDoObjTabClean(fDoObjTabClean);
488 sel->SetDoRunInfo(kTRUE);
489 sel->SetAllEvtHdrBrn(GetAllEvtHdrBrn());
490 sel->SetAllEvtTreeName(GetAllEvtTreeName());
491 sel->SetEvtHdrName(GetEvtHdrName());
492 sel->SetLAHdrName(GetLAHdrName());
493 sel->SetLATreeName(GetLATreeName());
494 sel->SetRunInfoName(GetRunInfoName());
495 sel->SetRunTreeName(GetRunTreeName());
496 sel->AddInput(anamod);
497 fSelector = sel;
498
499 if (hltmod)
500 fSelector->AddInput(hltmod);
501
502 TIter iter(fSuperMods->MakeIterator());
503 while (1) {
504 TAModule *next = dynamic_cast<TAModule*>(iter.Next());
505 if (!next) break;
506 fSelector->AddInput(next);
507 }
508
509 MDB(kAnalysis, 2)
510 fSelector->SetVerbosity(1);
511
512 // pass loaders to selector
513 TIter next(fLoaders);
514 while (TAMVirtualLoader *l = dynamic_cast<TAMVirtualLoader*>(next()))
515 fSelector->AddLoader(l);
516 }
517
518 fState = kInit;
519 return kTRUE;
520 }
521
522 //--------------------------------------------------------------------------------------------------
523 Bool_t Analysis::InitProof()
524 {
525 // Initialize PROOF connection.
526
527 if (fProof && fProof->IsValid())
528 return kTRUE;
529
530 delete fProof;
531
532 if (fMaster.Contains("rcf.bnl.gov")) {
533 for (Int_t i=0; i<5; ++i) {
534 Warning("InitProof", "*** DID YOU RUN PROOF_KINIT? %d (5) ***", i);
535 gSystem->Sleep(1000);
536 }
537 }
538
539 MDB(kAnalysis, 1)
540 Info("InitProof", "Starting PROOF on master %s with config %s",
541 fMaster.Data(), fConfig.Data());
542
543 fProof = dynamic_cast<TProof*>(TProof::Open(fMaster, fConfig));
544 if (!fProof) {
545 Error("InitProof", "Could not start PROOF!");
546 return kFALSE;
547 }
548
549 MDB(kAnalysis, 3)
550 gROOT->Print();
551
552 //fProof->AddInput(new TNamed("PROOF_NewPacketizer",""));
553
554 Bool_t ret=kTRUE;
555 if (fPackages) {
556 // tell Proof what additional libraries we will need on each worker computer
557 ret = UploadPackages(fPackages);
558 }
559
560 return ret;
561 }
562
563 //--------------------------------------------------------------------------------------------------
564 void Analysis::Run()
565 {
566 // Run the analysis on the created file set.
567
568 if (fState == kPristine || fState == kRun) {
569 Error("Run", "Run in state %d is not possible! Call Init() first.",
570 Int_t(fState));
571 }
572
573 if (fUseProof) {
574
575 MDB(kAnalysis, 1)
576 Info("Run", "Start processing with PROOF...");
577
578 fSet->Process("Selector","",fDoNEvents);
579
580 } else {
581
582 MDB(kAnalysis, 1)
583 Info("Run", "Start processing (no PROOF)...");
584
585 fChain->Process(fSelector,"",fDoNEvents);
586 }
587
588 MDB(kAnalysis, 1)
589 Info("Run", "Processing complete!");
590
591 fState = kRun;
592 }
593
594 //--------------------------------------------------------------------------------------------------
595 Bool_t Analysis::Run(Bool_t browse)
596 {
597 // Execute analysis and open TBrowser if requested.
598
599 if (Init()) {
600 Run();
601 Terminate();
602 if (browse) {
603 new TBrowser;
604 }
605 return kTRUE;
606 }
607
608 Error("Execute", "Could not initialize analysis.");
609 return kFALSE;
610 }
611
612 //--------------------------------------------------------------------------------------------------
613 void Analysis::SetSuperModule(TAModule *mod)
614 {
615 // Set the first top-level module in the list of top-level (super) modules.
616
617 fSuperMods->AddFirst(mod);
618 }
619
620 //--------------------------------------------------------------------------------------------------
621 void Analysis::Terminate()
622 {
623 // Terminate current analysis run.
624
625 if (fState == kPristine || fState == kTerminate) {
626 Error("Terminate", "Terminate in state %d is not possible! Call Init() first.",
627 Int_t(fState));
628 return;
629 }
630
631 if (fState == kRun) {
632
633 if (fUseProof) {
634 // the output list from Proof can (in principal) contain other objects
635 // besides the module output hierarchy.
636 TList* outputlist = fProof->GetOutputList();
637 TIter nextOut(outputlist);
638 while (TObject *obj = nextOut()) {
639 if (obj->InheritsFrom(TAMOutput::Class())) {
640 fOutput = dynamic_cast<TList*>(obj);
641 break;
642 }
643 }
644
645 } else {
646 fOutput = fSelector->GetModOutput();
647 }
648
649
650
651 if (fOutput && !fAnaOutput.IsNull()) {
652 TDirectory::TContext context(0); // automatically restore gDirectory
653
654 std::auto_ptr<TFile> outf(TFile::Open(fAnaOutput,"recreate","", fCompLevel));
655 if (outf.get() == 0) {
656 Error("Terminate", "Could not open file %s for output!", fAnaOutput.Data());
657 } else {
658 MDB(kAnalysis, 1)
659 Info("Terminate", "Saving output to %s!", fAnaOutput.Data());
660
661 if (fHierarchy)
662 fOutput->Write(0,-99);
663 else
664 fOutput->Write();
665 }
666 }
667 // set state to terminate
668 fState = kTerminate;
669 }
670
671 delete fChain;
672 delete fSet;
673 fDeleteList->Delete();
674 }
675
676 //--------------------------------------------------------------------------------------------------
677 Bool_t Analysis::UploadPackages(TList *packages)
678 {
679 // Upload list of par files to the server.
680
681 MitAssert("UploadPackages", packages != 0);
682
683 for (Int_t i=0; i<packages->GetEntries(); ++i) {
684
685 TObject* objstr = packages->At(i);
686 if (!objstr) {
687 Error("InitProof", "Problem at package number %d!", i);
688 return kFALSE;
689 }
690
691 TString packname = objstr->GetName();
692 Int_t en = 0;
693 if (packname.EndsWith("+")) {
694 en=1;
695 packname.Resize(packname.Length()-1);
696 }
697
698 ifstream ftest(gSystem->ExpandPathName(packname.Data()),ios_base::binary);
699 if (!ftest.good()) {
700 Error("InitProof", "Could not open %s for upload!", packname.Data());
701 return kFALSE;
702 }
703
704 if (fProof->UploadPackage(packname)<0) {
705 Error("UploadPackage", "Upload for %s failed!", packname.Data());
706 return kFALSE;
707 }
708
709 if (en == 1) {
710 Int_t pos=packname.Last('/')+1;
711 if (pos)
712 packname.Remove(0,pos);
713 if (fProof->EnablePackage(packname)<0) {
714 Error("UploadPackage", "Enabling for %s failed!", packname.Data());
715 return kFALSE;
716 }
717 }
718 }
719
720 return kTRUE;
721 }