ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TreeMod/src/Analysis.cc
Revision: 1.33
Committed: Fri Jun 19 07:39:01 2009 UTC (15 years, 10 months ago) by loizides
Content type: text/plain
Branch: MAIN
Changes since 1.32: +3 -1 lines
Log Message:
Allow to set scale of printouts.

File Contents

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