ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TreeMod/src/Analysis.cc
Revision: 1.15
Committed: Sun Sep 28 02:36:23 2008 UTC (16 years, 7 months ago) by loizides
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_004
Changes since 1.14: +17 -3 lines
Log Message:
Use HLTFwkMod

File Contents

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