ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TreeMod/src/Analysis.cc
Revision: 1.21
Committed: Tue Dec 9 10:13:01 2008 UTC (16 years, 4 months ago) by loizides
Content type: text/plain
Branch: MAIN
Changes since 1.20: +36 -7 lines
Log Message:
Allow users to pass several top (super) modules to the analysis chain.

File Contents

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