ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TreeMod/src/Analysis.cc
Revision: 1.36
Committed: Tue Aug 11 15:24:39 2009 UTC (15 years, 9 months ago) by loizides
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_011a, Mit_011, Mit_010a
Changes since 1.35: +28 -9 lines
Log Message:
Support different HLT menus

File Contents

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