ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TreeMod/src/Analysis.cc
Revision: 1.25
Committed: Tue Jan 20 15:08:32 2009 UTC (16 years, 3 months ago) by loizides
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_006b, Mit_006a
Changes since 1.24: +19 -12 lines
Log Message:
Fix

File Contents

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