ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TreeMod/src/Analysis.cc
Revision: 1.23
Committed: Thu Dec 11 15:53:26 2008 UTC (16 years, 4 months ago) by loizides
Content type: text/plain
Branch: MAIN
Changes since 1.22: +3 -3 lines
Log Message:
Updated docu.

File Contents

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