ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TreeMod/src/OutputMod.cc
Revision: 1.17
Committed: Wed Dec 9 09:46:25 2009 UTC (15 years, 4 months ago) by loizides
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_012e
Changes since 1.16: +4 -11 lines
Log Message:
Bugfix

File Contents

# User Rev Content
1 loizides 1.17 // $Id: OutputMod.cc,v 1.16 2009/10/26 11:04:56 loizides Exp $
2 loizides 1.1
3     #include "MitAna/TreeMod/interface/OutputMod.h"
4 loizides 1.2 #include "MitAna/TreeMod/interface/HLTFwkMod.h"
5 loizides 1.1 #include "MitAna/DataUtil/interface/Debug.h"
6 loizides 1.12 #include "MitAna/DataTree/interface/BranchTable.h"
7 loizides 1.13 #include "MitAna/DataTree/interface/EventHeaderCol.h"
8 loizides 1.1 #include "MitAna/DataTree/interface/Names.h"
9     #include "MitAna/DataUtil/interface/TreeWriter.h"
10     #include "MitAna/TreeMod/interface/TreeBranchLoader.h"
11    
12     using namespace mithep;
13     using namespace std;
14    
15     ClassImp(mithep::OutputMod)
16    
17     //--------------------------------------------------------------------------------------------------
18     OutputMod::OutputMod(const char *name, const char *title) :
19     BaseMod(name,title),
20     fTreeName(Names::gkEvtTreeName),
21     fPrefix("skimtest"),
22     fPathName("."),
23     fMaxSize(1024),
24     fCompLevel(9),
25     fSplitLevel(99),
26 loizides 1.12 fBranchSize(16*1024),
27 loizides 1.1 fDoReset(kFALSE),
28 loizides 1.15 fCheckBrDep(kTRUE),
29 loizides 1.12 fUseBrDep(kTRUE),
30 loizides 1.2 fCheckTamBr(kTRUE),
31 loizides 1.12 fKeepTamBr(kFALSE),
32 loizides 1.1 fTreeWriter(0),
33 loizides 1.3 fEventHeader(0),
34     fAllEventHeader(0),
35     fRunInfo(0),
36     fLaHeader(0),
37 loizides 1.12 fBranchTable(0),
38 loizides 1.9 fBranches(0),
39 loizides 1.2 fNBranchesMax(1024),
40 loizides 1.3 fRunTree(0),
41     fLATree(0),
42     fAllTree(0),
43 loizides 1.9 fSkimmedIn(0),
44 loizides 1.3 fHltTree(0),
45 loizides 1.12 fHLTTab(new vector<string>),
46     fHLTLab(new vector<string>),
47 loizides 1.3 fRunEntries(0),
48     fHltEntries(0),
49 loizides 1.12 fFileNum(-1),
50 loizides 1.4 fLastWrittenEvt(-1),
51     fLastSeenEvt(-1),
52 loizides 1.14 fCounter(0)
53 loizides 1.1 {
54 loizides 1.2 // Constructor.
55 loizides 1.1 }
56    
57     //--------------------------------------------------------------------------------------------------
58     void OutputMod::BeginRun()
59     {
60 loizides 1.3 // Create HLT tree if HLTFwkMod is being run.
61    
62     if (!HasHLTInfo())
63     return;
64 loizides 1.1
65 loizides 1.3 if (!fHltTree) {
66     HLTFwkMod *hm = const_cast<HLTFwkMod*>(GetHltFwkMod());
67 loizides 1.7 fTreeWriter->AddBranchToTree(hm->HLTTreeName(), hm->HLTTabName(),
68 loizides 1.12 TClass::GetClass(typeid(*fHLTTab))->GetName(),
69     &fHLTTab, 32000, 0);
70 loizides 1.7 fTreeWriter->AddBranchToTree(hm->HLTTreeName(), hm->HLTLabName(),
71 loizides 1.12 TClass::GetClass(typeid(*fHLTLab))->GetName(),
72     &fHLTLab, 32000, 0);
73 loizides 1.3 fTreeWriter->SetAutoFill(hm->HLTTreeName(), 0);
74     fHltTree = fTreeWriter->GetTree(hm->HLTTreeName());
75     }
76 loizides 1.1 }
77    
78     //--------------------------------------------------------------------------------------------------
79     void OutputMod::CheckAndAddBranch(const char *bname, const char *cname)
80     {
81 loizides 1.2 // Check if the given branch should be kept or dropped.
82 loizides 1.4
83 loizides 1.1 if (IsAcceptedBranch(bname))
84     return;
85    
86     // populate regular expression list if this was not yet done
87 loizides 1.6 if (fCmdReList.size() != fCmdList.size()) {
88     for (UInt_t i=0; i<fCmdList.size(); ++i) {
89     const char *ptr = fCmdList.at(i).c_str();
90 loizides 1.1 fCmdReList.push_back(TRegexp(ptr+5,kTRUE));
91     if (ptr[0]=='k')
92     fCmdDeList.push_back(kTRUE);
93     else
94     fCmdDeList.push_back(kFALSE);
95     }
96     }
97    
98     // decide whether given branch name should be kept or dropped
99     TString brname(bname);
100     Bool_t decision = kFALSE;
101     Bool_t decision_found = kFALSE;
102    
103 loizides 1.6 for (UInt_t i=0; i<fCmdList.size(); ++i) {
104 loizides 1.1 TRegexp &re(fCmdReList.at(i));
105     if (brname.Index(re) == kNPOS)
106     continue;
107     decision = fCmdDeList.at(i);
108     decision_found = kTRUE;
109     }
110    
111     if (!decision_found) { // no decision found: still drop branch
112     Warning("CheckAndAddBranch",
113 loizides 1.9 "No decision found for branch '%s' and class '%s'. Branch therefore dropped!",
114 loizides 1.1 bname, cname);
115     return;
116     }
117    
118     if (!decision) { // drop branch according to request
119 loizides 1.11 Info("CheckAndAddBranch",
120 loizides 1.12 "Dropped branch '%s' and class '%s'", bname, cname);
121 loizides 1.1 return;
122     }
123    
124     // add branch to accepted branch list
125 loizides 1.11 Info("CheckAndAddBranch",
126 loizides 1.12 "Kept branch '%s' and class '%s'", bname, cname);
127 loizides 1.1
128 loizides 1.6 fBrNameList.push_back(string(bname));
129     fBrClassList.push_back(string(cname));
130 loizides 1.12 }
131    
132     //--------------------------------------------------------------------------------------------------
133     Bool_t OutputMod::CheckAndResolveBranchDep()
134     {
135     // Checks dependency in BranchTable. Resolve dependency automatically if fUserBrDep is kTRUE.
136    
137     TFile *cfile = const_cast<TFile*>(GetSel()->GetCurrentFile());
138 loizides 1.15 if (!cfile) {
139     SendError(kAbortAnalysis, "CheckAndResolveBranchDep", "Could not get pointer to current file!");
140 loizides 1.12 return kFALSE;
141 loizides 1.15 }
142 loizides 1.12
143     BranchTable *br = dynamic_cast<BranchTable*>(cfile->Get(Names::gkBranchTable));
144 loizides 1.15 if (!br) {
145     SendError(kAbortAnalysis, "CheckAndResolveBranchDep", "Could not get pointer to branch table!");
146 loizides 1.12 return kFALSE;
147 loizides 1.15 }
148 loizides 1.12
149     TList *blist = br->GetBranches();
150 loizides 1.15 if (!blist) {
151     SendError(kAbortAnalysis, "CheckAndResolveBranchDep", "Could not get list of branches!");
152 loizides 1.12 return kFALSE;
153 loizides 1.15 }
154 loizides 1.1
155 loizides 1.12 fBranchTable = new BranchTable;
156     fBranchTable->SetName(Names::gkBranchTable);
157     fBranchTable->SetOwner();
158    
159     TList sht;
160     sht.SetOwner(kTRUE);
161     for (UInt_t i=0; i<fBrNameList.size(); ++i) {
162     sht.Add(new TObjString(fBrNameList.at(i).c_str()));
163     }
164    
165     for (UInt_t i=0; i<fBrNameList.size(); ++i) {
166 loizides 1.14 TString brname(fBrNameList.at(i));
167 loizides 1.12 if (!blist->FindObject(brname))
168     continue;
169     TList *bdeps = br->GetDepBranches(brname);
170     if (!bdeps)
171     continue;
172    
173     // check dependency
174     TIter iter(bdeps->MakeIterator());
175     const TObjString *n = dynamic_cast<const TObjString*>(iter.Next());
176     while (n) {
177     if (sht.FindObject(n->GetName())) {
178     // dependent branch is already accepted
179     fBranchTable->Add(new BranchName(brname,n->GetName()));
180     } else {
181     if (fUseBrDep) {
182     const TObjArray *arr = GetSel()->GetTree()->GetTree()->GetListOfBranches();
183     TBranch *br = dynamic_cast<TBranch*>(arr->FindObject(n->GetName()));
184     if (!br) {
185     Error("CheckAndResolveBranchDep",
186     "Could not get branch '%s' to resolve dependency for branch '%s'",
187     n->GetName(), brname.Data());
188     } else {
189     Info("CheckAndResolveBranchDep",
190     "Adding branch '%s' to resolve dependency for branch '%s'",
191     n->GetName(), brname.Data());
192     fBrNameList.push_back(string(n->GetName()));
193     fBrClassList.push_back(br->GetClassName());
194     sht.Add(new TObjString(n->GetName()));
195     fBranchTable->Add(new BranchName(brname,n->GetName()));
196     }
197     } else {
198     Warning("CheckAndResolveBranchDep",
199     "Unresolved dependency of branch '%s' and '%s' ",
200     n->GetName(), brname.Data());
201     }
202     }
203     n = dynamic_cast<const TObjString*>(iter.Next());
204     }
205     delete bdeps;
206     }
207     delete blist;
208     return kTRUE;
209 loizides 1.1 }
210    
211     //--------------------------------------------------------------------------------------------------
212 loizides 1.12 void OutputMod::CheckAndResolveTAMDep(Bool_t solve)
213 loizides 1.2 {
214     // Check if TAM has loaded additional branches. If requested try to solve the the dependency
215     // by adding the branch to the list of branches.
216    
217     const THashTable &ht = GetSel()->GetBranchTable();
218    
219 loizides 1.5 TIter iter(ht.MakeIterator());
220     const TAMBranchInfo *next = dynamic_cast<const TAMBranchInfo*>(iter.Next());
221 loizides 1.2
222     while (next) {
223     const TAMBranchInfo *cur = next;
224 loizides 1.5 next = dynamic_cast<const TAMBranchInfo*>(iter.Next());
225 loizides 1.2 Bool_t isloaded = cur->IsLoaded();
226     if (!isloaded)
227     continue;
228    
229     const char *bname = cur->GetName();
230     if (IsAcceptedBranch(bname))
231     continue;
232    
233     TreeBranchLoader *loader = dynamic_cast<TreeBranchLoader*>(cur->GetLoader());
234     if (!loader)
235     continue;
236    
237     TBranch *br = loader->GetBranch();
238     if (!br)
239     continue;
240    
241     const char *cname = br->GetClassName();
242    
243     if (solve) {
244 loizides 1.12 Info("CheckAndResolveTAMDep",
245 loizides 1.11 "Resolving dependency for loaded branch '%s' and class '%s'", bname,cname);
246 loizides 1.2
247 loizides 1.6 fBrNameList.push_back(string(bname));
248     fBrClassList.push_back(string(cname));
249 loizides 1.2 fBranches[GetNBranches()-1] = reinterpret_cast<TObject*>(loader->GetAddress());
250    
251     } else {
252 loizides 1.12 Warning("CheckAndResolveTAMDep",
253     "Unresolved dependency for loaded branch '%s' and class '%s'",
254 loizides 1.2 bname,cname);
255     }
256     }
257     }
258    
259     //--------------------------------------------------------------------------------------------------
260 loizides 1.4 void OutputMod::EndRun()
261     {
262 loizides 1.9 // Nothing to be done at this point.
263 loizides 1.4 }
264    
265     //--------------------------------------------------------------------------------------------------
266 loizides 1.3 void OutputMod::FillAllEventHeader(Bool_t isremoved)
267     {
268     // Fill event header into the all-event-header tree.
269    
270 loizides 1.9 if (!fTreeWriter->BeginEvent(kFALSE)) {
271     SendError(kAbortAnalysis, "FillAllEventHeader", "Begin event failed!");
272     return;
273     }
274    
275     if (fSkimmedIn) { // copy alread skimmed headers if any there
276 loizides 1.16 const UInt_t n = fSkimmedIn->GetEntries();
277     for(UInt_t i=0; i<n; ++i) {
278 loizides 1.9 const EventHeader *eh = fSkimmedIn->At(i);
279 loizides 1.17 *fAllEventHeader = *eh;
280 loizides 1.9 fAllEventHeader->SetSkimmed(eh->Skimmed()+1);
281     fAllTree->Fill();
282     }
283     }
284    
285 loizides 1.3 const EventHeader *eh = GetEventHeader();
286 loizides 1.17 *fAllEventHeader = *eh;
287 loizides 1.9 if (isremoved) {
288 loizides 1.3 fAllEventHeader->SetRunEntry(-1);
289 loizides 1.9 fAllEventHeader->SetSkimmed(eh->Skimmed()+1);
290     } else {
291 loizides 1.3 fAllEventHeader->SetRunEntry(eh->RunEntry());
292 loizides 1.9 fAllEventHeader->SetSkimmed(eh->Skimmed());
293     }
294 loizides 1.3
295     fAllTree->Fill();
296     }
297    
298     //--------------------------------------------------------------------------------------------------
299     void OutputMod::FillHltInfo()
300 loizides 1.1 {
301 loizides 1.4 // Write HLT trigger table if needed.
302 loizides 1.1
303 loizides 1.3 if (!fHltTree)
304     return;
305    
306 loizides 1.12 HLTFwkMod *hm = const_cast<HLTFwkMod*>(GetHltFwkMod());
307     vector<string> *trigtable = hm->fHLTTab;
308     vector<string> *labels = hm->fHLTLab;
309    
310     Bool_t doCopy = kFALSE;
311     if (fHLTTab->size()==0) {
312     doCopy = kTRUE;
313     } else {
314     // check if existing table contains all necessary paths:
315     // if so keep it, otherwise store the new one
316    
317     if ((fHLTTab->size() != trigtable->size()) ||
318     (fHLTLab->size() != labels->size())) {
319     doCopy = kTRUE;
320     } else {
321     // need to check more thoroughly
322    
323     for (UInt_t i=0; i<trigtable->size(); ++i) {
324     if (trigtable->at(i) != fHLTTab->at(i)) {
325     doCopy = kTRUE;
326     break;
327     }
328     }
329     if (!doCopy) {
330     for (UInt_t i=0; i<labels->size(); ++i) {
331     if (labels->at(i) != fHLTLab->at(i)) {
332     doCopy = kTRUE;
333     break;
334     }
335     }
336     }
337     }
338     }
339    
340     if (!doCopy)
341 loizides 1.3 return;
342    
343 loizides 1.12 fHLTTab->resize(trigtable->size());
344     copy(trigtable->begin(),trigtable->end(), fHLTTab->begin());
345     fHLTLab->resize(labels->size());
346     copy(labels->begin(),labels->end(), fHLTLab->begin());
347    
348     ++fHltEntries;
349 loizides 1.3 fHltTree->Fill();
350 loizides 1.1 }
351    
352     //--------------------------------------------------------------------------------------------------
353     Bool_t OutputMod::IsAcceptedBranch(const char *bname)
354     {
355     // Return true if given branch is already in branch list. Also return true if a special
356     // branch like the "EventHeader" branch is reqested.
357    
358     // search in branch list
359     for (UInt_t i=0; i<GetNBranches(); ++i) {
360 loizides 1.6 if (fBrNameList.at(i).compare(bname) == 0)
361 loizides 1.1 return kTRUE;
362     }
363    
364     // check if special branch that we take care of ourselves
365     string name(bname);
366     if (name.compare("EventHeader") == 0) {
367     return kTRUE;
368     }
369    
370     return kFALSE;
371     }
372    
373     //--------------------------------------------------------------------------------------------------
374     Bool_t OutputMod::Notify()
375     {
376 loizides 1.2 // On first notify, loop over list of branches to determine the list of kept branches.
377 loizides 1.15
378 loizides 1.2 if (GetNEventsProcessed() != 0)
379     return kTRUE;
380 loizides 1.1
381 loizides 1.12 const TTree *tree=GetSel()->GetTree();
382 loizides 1.1 if (!tree)
383     return kFALSE;
384    
385 loizides 1.12 const TObjArray *arr = tree->GetTree()->GetListOfBranches();
386 loizides 1.1 if (!arr)
387     return kFALSE;
388    
389     for (Int_t i=0; i<arr->GetEntries(); ++i) {
390     TBranch *br = dynamic_cast<TBranch*>(arr->At(i));
391     if (!br && !br->GetMother())
392     continue;
393     br = br->GetMother();
394     TClass *cls = TClass::GetClass(br->GetClassName());
395     if (!cls)
396     continue;
397    
398     if (!cls->InheritsFrom("TObject")) {
399 loizides 1.12 Warning("Notify", "Found branch '%s' where class '%s' does not derive from TObject",
400 loizides 1.1 br->GetName(), br->GetClassName());
401     continue;
402     }
403    
404     CheckAndAddBranch(br->GetName(), br->GetClassName());
405     }
406    
407 loizides 1.15 if (fCheckBrDep && !CheckAndResolveBranchDep())
408 loizides 1.12 return kFALSE;
409    
410     RequestBranches();
411 loizides 1.1 return kTRUE;
412     }
413    
414     //--------------------------------------------------------------------------------------------------
415     void OutputMod::LoadBranches()
416     {
417     // Loop over requested branches and load them.
418    
419     for (UInt_t i=0; i<GetNBranches(); ++i) {
420 loizides 1.6 LoadBranch(fBrNameList.at(i).c_str());
421 loizides 1.1 }
422     }
423    
424     //--------------------------------------------------------------------------------------------------
425     void OutputMod::Process()
426     {
427 loizides 1.3 // Write out the kept branches of the current event. Make sure the meta information is
428     // correctly updated.
429 loizides 1.1
430 loizides 1.4 if (GetSel()->GetCurEvt() == fLastSeenEvt) {
431     Warning("Process", "Event with %ul already seen", fLastSeenEvt);
432     return;
433     }
434     fLastSeenEvt = GetSel()->GetCurEvt();
435    
436     if (GetSel()->GetCurEvt() == fLastWrittenEvt) {
437     Warning("Process", "Event with %ul already written", fLastWrittenEvt);
438     return;
439     }
440     fLastWrittenEvt = GetSel()->GetCurEvt();
441     ++fCounter;
442    
443     // prepare for tree filling
444 loizides 1.8 if (!fTreeWriter->BeginEvent(fDoReset)) {
445     SendError(kAbortAnalysis, "Process", "Begin event failed!");
446     return;
447     }
448 loizides 1.1
449 loizides 1.2 if (GetNEventsProcessed() == 0 && fCheckTamBr) {
450 loizides 1.15 CheckAndResolveTAMDep(fKeepTamBr);
451 loizides 1.1 }
452    
453 loizides 1.4 // load all our branches
454 loizides 1.1 LoadBranches();
455    
456 loizides 1.4 // pass our branches to tree writer if on first event
457 loizides 1.1 if (GetNEventsProcessed() == 0) {
458 loizides 1.4 SetupBranches();
459 loizides 1.1 }
460    
461 loizides 1.3 // reset per file quantities if a new file was opened
462     if (fTreeWriter->GetFileNumber()!=fFileNum) {
463     fRunmap.clear();
464     fRunEntries = 0;
465 loizides 1.12 fHltEntries = 0;
466 loizides 1.3 fFileNum = fTreeWriter->GetFileNumber();
467 loizides 1.15 if (fBranchTable)
468     fTreeWriter->StoreObject(fBranchTable);
469 loizides 1.3 }
470    
471     UInt_t runnum = GetEventHeader()->RunNum();
472    
473     // store look ahead information
474     if (fRunEntries>0) {
475     fLaHeader->SetRunNum(runnum);
476     fLATree->Fill();
477     }
478    
479     // fill event header
480 loizides 1.17 *fEventHeader = *GetEventHeader();
481 loizides 1.3
482     // fill all event header
483     FillAllEventHeader(kFALSE);
484    
485     // look-up if entry is in map
486     map<UInt_t,Int_t>::iterator riter = fRunmap.find(runnum);
487     if (riter != fRunmap.end()) { // found existing run info
488     Int_t runentry = riter->second;
489     fEventHeader->SetRunEntry(runentry);
490    
491     IncNEventsProcessed();
492     fTreeWriter->EndEvent(fDoReset);
493     return;
494     }
495 loizides 1.2
496 loizides 1.3 // fill new run info
497     Int_t runentry = fRunEntries;
498     ++fRunEntries;
499     fEventHeader->SetRunEntry(runentry);
500     fRunmap.insert(pair<UInt_t,Int_t>(runnum,runentry));
501     fRunInfo->SetRunNum(runnum);
502    
503     Int_t hltentry = fHltEntries;
504     FillHltInfo();
505 loizides 1.12 if (hltentry < fHltEntries)
506     fRunInfo->SetHltEntry(hltentry);
507     else
508     fRunInfo->SetHltEntry(hltentry-1);
509 loizides 1.3
510     fRunTree->Fill();
511 loizides 1.12
512 loizides 1.1 IncNEventsProcessed();
513 loizides 1.8
514     if (!fTreeWriter->EndEvent(fDoReset)) {
515     SendError(kAbortAnalysis, "Process", "End event failed!");
516     return;
517     }
518 loizides 1.1 }
519    
520     //--------------------------------------------------------------------------------------------------
521 loizides 1.3 void OutputMod::ProcessAll()
522     {
523     // Called by the Selector class for events that were skipped.
524    
525 loizides 1.4 if (GetSel()->GetCurEvt() == fLastSeenEvt)
526     return;
527 loizides 1.8
528 loizides 1.4 fLastSeenEvt = GetSel()->GetCurEvt();
529     ++fCounter;
530    
531 loizides 1.8 // prepare for tree filling
532 loizides 1.3 FillAllEventHeader(kTRUE);
533     }
534    
535     //--------------------------------------------------------------------------------------------------
536 loizides 1.12 void OutputMod::RequestBranches()
537 loizides 1.3 {
538 loizides 1.12 // Loop over requested branches and request them.
539 loizides 1.3
540 loizides 1.12 for (UInt_t i=0; i<GetNBranches(); ++i) {
541     if (i>=fNBranchesMax) {
542 loizides 1.14 SendError(kAbortAnalysis, "RequestBranches", "Cannot request branch '%s' "
543 loizides 1.12 "since maximum number of branches [%d] is reached",
544     fBrNameList.at(i).c_str(), fNBranchesMax);
545     return;
546     }
547     fBranches[i] = 0;
548     TAModule::ReqBranch(fBrNameList.at(i).c_str(), fBranches[i]);
549 loizides 1.3 }
550     }
551    
552     //--------------------------------------------------------------------------------------------------
553 loizides 1.1 void OutputMod::SetupBranches()
554     {
555     // Setup branches in tree writer.
556    
557     for (UInt_t i=0; i<GetNBranches(); ++i) {
558 loizides 1.6 const char *bname = fBrNameList.at(i).c_str();
559     const char *cname = fBrClassList.at(i).c_str();
560 loizides 1.1 if (!fBranches[i]) {
561 loizides 1.8 SendError(kWarning, "SetupBranches",
562 loizides 1.12 "Pointer for branch '%s' and class '%s' is NULL", bname, cname);
563 loizides 1.1 continue;
564     }
565 loizides 1.12 Int_t bsize = fBranchSize;
566     TString cnamestr(cname);
567     if ((bsize<128*1024) && (cnamestr.Contains("mithep::MCParticle"))) {
568     bsize=128*1024;
569     } else if ((bsize<32*1024) && (cnamestr.Contains("mithep::CaloTower"))) {
570     bsize=32*1024;
571     }
572    
573     fTreeWriter->AddBranch(bname, cname, &fBranches[i], bsize);
574 loizides 1.1 }
575     }
576    
577     //--------------------------------------------------------------------------------------------------
578     void OutputMod::SlaveBegin()
579     {
580 loizides 1.3 // Setup the tree writer and create branches that can already be created at this point.
581 loizides 1.1
582     // setup tree writer
583     fTreeWriter = new TreeWriter(fTreeName, kFALSE);
584     fTreeWriter->SetBaseURL(fPathName);
585     fTreeWriter->SetPrefix(fPrefix);
586     fTreeWriter->SetMaxSize(fMaxSize*1024*1024);
587     fTreeWriter->SetCompressLevel(fCompLevel);
588     fTreeWriter->SetDefaultSL(fSplitLevel);
589     fTreeWriter->SetDefaultBrSize(fBranchSize);
590     fTreeWriter->AddTree(fTreeName);
591     fTreeWriter->DoBranchRef(fTreeName);
592    
593 loizides 1.2 // deal with my own tree objects
594 loizides 1.3 fEventHeader = new EventHeader;
595     fTreeWriter->AddBranch(GetSel()->GetEvtHdrName(), &fEventHeader);
596    
597     // deal with other trees
598     const char *tname = 0;
599     fRunInfo = new RunInfo;
600     tname = GetSel()->GetRunTreeName();
601     fTreeWriter->AddBranchToTree(tname, GetSel()->GetRunInfoName(), &fRunInfo);
602     fTreeWriter->SetAutoFill(tname, 0);
603     fRunTree = fTreeWriter->GetTree(tname);
604     fLaHeader = new LAHeader;
605     tname = GetSel()->GetLATreeName();
606     fTreeWriter->AddBranchToTree(tname, GetSel()->GetLAHdrName(), &fLaHeader);
607 loizides 1.9 fTreeWriter->SetAutoFill(tname, 0);
608 loizides 1.3 fLATree = fTreeWriter->GetTree(tname);
609     fAllEventHeader = new EventHeader;
610     tname = GetSel()->GetAllEvtTreeName();
611     fTreeWriter->AddBranchToTree(tname, GetSel()->GetAllEvtHdrBrn(), &fAllEventHeader);
612     fAllTree = fTreeWriter->GetTree(tname);
613 loizides 1.9 fTreeWriter->SetAutoFill(tname, 0);
614    
615     // get pointer to all event headers
616     fSkimmedIn = GetPublicObj<EventHeaderCol>(Names::gkSkimmedHeaders);
617 loizides 1.2
618 loizides 1.1 // create TObject space for TAM
619 loizides 1.14 fBranches = new TObject*[fNBranchesMax + fAddList.size()];
620    
621     // deal here with additional published objects
622     for (UInt_t i=0; i<fAddList.size(); ++i) {
623     TString objname(fAddList.at(i));
624     TObject *obj = FindPublicObj(objname);
625     if (obj) {
626     fBranches[fNBranchesMax+i] = obj;
627     fTreeWriter->AddBranch(objname, &fBranches[fNBranchesMax+i]);
628     Info("SlaveBegin", "Adding additional branch named '%s' as requested", objname.Data());
629     } else {
630     SendError(kAbortAnalysis, "SlaveBegin",
631     "Object named '%s' for additional branch is NULL", objname.Data());
632     }
633     }
634 loizides 1.2
635     // adjust checks for TAM branches
636     if (fKeepTamBr)
637     fCheckTamBr = kTRUE;
638 loizides 1.1 }
639    
640     //--------------------------------------------------------------------------------------------------
641     void OutputMod::SlaveTerminate()
642     {
643 loizides 1.3 // Terminate tree writing and do cleanup.
644 loizides 1.1
645 loizides 1.9 RetractObj(Names::gkSkimmedHeaders);
646    
647 loizides 1.1 delete fTreeWriter;
648     fTreeWriter = 0;
649    
650 loizides 1.3 delete fEventHeader;
651     delete fRunInfo;
652     delete fLaHeader;
653     delete fAllEventHeader;
654 loizides 1.2
655 loizides 1.1 delete[] fBranches;
656 loizides 1.4
657     Double_t frac = 100.*GetNEventsProcessed()/fCounter;
658 loizides 1.12 Info("SlaveTerminate", "Stored %.2f%% events (%ld out of %ld)",
659 loizides 1.11 frac, GetNEventsProcessed(), fCounter);
660 loizides 1.1 }