ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TreeMod/src/OutputMod.cc
Revision: 1.8
Committed: Wed Mar 11 10:07:12 2009 UTC (16 years, 1 month ago) by loizides
Content type: text/plain
Branch: MAIN
Changes since 1.7: +30 -14 lines
Log Message:
Adapt to new eventheader

File Contents

# User Rev Content
1 loizides 1.8 // $Id: OutputMod.cc,v 1.7 2009/03/07 08:32:40 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     #include "MitAna/DataTree/interface/Names.h"
7     #include "MitAna/DataUtil/interface/TreeWriter.h"
8     #include "MitAna/TreeMod/interface/TreeBranchLoader.h"
9    
10     using namespace mithep;
11     using namespace std;
12    
13     ClassImp(mithep::OutputMod)
14    
15     //--------------------------------------------------------------------------------------------------
16     OutputMod::OutputMod(const char *name, const char *title) :
17     BaseMod(name,title),
18     fTreeName(Names::gkEvtTreeName),
19     fPrefix("skimtest"),
20     fPathName("."),
21     fMaxSize(1024),
22     fCompLevel(9),
23     fSplitLevel(99),
24 loizides 1.7 fBranchSize(64*1024),
25 loizides 1.1 fDoReset(kFALSE),
26 loizides 1.2 fCheckTamBr(kTRUE),
27     fKeepTamBr(kTRUE),
28 loizides 1.1 fTreeWriter(0),
29 loizides 1.3 fEventHeader(0),
30     fAllEventHeader(0),
31     fRunInfo(0),
32     fLaHeader(0),
33 loizides 1.2 fNBranchesMax(1024),
34 loizides 1.3 fRunTree(0),
35     fLATree(0),
36     fAllTree(0),
37     fL1Tree(0),
38     fHltTree(0),
39     fRunEntries(0),
40     fOrigL1Entry(-1),
41     fL1Entries(0),
42     fOrigHltEntry(-1),
43     fHltEntries(0),
44 loizides 1.4 fFileNum(0),
45     fLastWrittenEvt(-1),
46     fLastSeenEvt(-1),
47     fCounter(0)
48 loizides 1.1 {
49 loizides 1.2 // Constructor.
50 loizides 1.1 }
51    
52     //--------------------------------------------------------------------------------------------------
53     void OutputMod::BeginRun()
54     {
55 loizides 1.3 // Create HLT tree if HLTFwkMod is being run.
56    
57     if (!HasHLTInfo())
58     return;
59 loizides 1.1
60 loizides 1.3 if (!fHltTree) {
61     HLTFwkMod *hm = const_cast<HLTFwkMod*>(GetHltFwkMod());
62 loizides 1.7 fTreeWriter->AddBranchToTree(hm->HLTTreeName(), hm->HLTTabName(),
63     TClass::GetClass(typeid(*hm->fHLTTab))->GetName(),
64     &(hm->fHLTTab), 32000, 0);
65     fTreeWriter->AddBranchToTree(hm->HLTTreeName(), hm->HLTLabName(),
66     TClass::GetClass(typeid(*hm->fHLTLab))->GetName(),
67     &(hm->fHLTLab), 32000, 0);
68 loizides 1.3 fTreeWriter->SetAutoFill(hm->HLTTreeName(), 0);
69     fHltTree = fTreeWriter->GetTree(hm->HLTTreeName());
70     }
71 loizides 1.1 }
72    
73     //--------------------------------------------------------------------------------------------------
74     void OutputMod::CheckAndAddBranch(const char *bname, const char *cname)
75     {
76 loizides 1.2 // Check if the given branch should be kept or dropped.
77 loizides 1.4
78 loizides 1.1 if (IsAcceptedBranch(bname))
79     return;
80    
81     // populate regular expression list if this was not yet done
82 loizides 1.6 if (fCmdReList.size() != fCmdList.size()) {
83     for (UInt_t i=0; i<fCmdList.size(); ++i) {
84     const char *ptr = fCmdList.at(i).c_str();
85 loizides 1.1 fCmdReList.push_back(TRegexp(ptr+5,kTRUE));
86     if (ptr[0]=='k')
87     fCmdDeList.push_back(kTRUE);
88     else
89     fCmdDeList.push_back(kFALSE);
90     }
91     }
92    
93     // decide whether given branch name should be kept or dropped
94     TString brname(bname);
95     Bool_t decision = kFALSE;
96     Bool_t decision_found = kFALSE;
97    
98 loizides 1.6 for (UInt_t i=0; i<fCmdList.size(); ++i) {
99 loizides 1.1 TRegexp &re(fCmdReList.at(i));
100     if (brname.Index(re) == kNPOS)
101     continue;
102     decision = fCmdDeList.at(i);
103     decision_found = kTRUE;
104     }
105    
106     if (!decision_found) { // no decision found: still drop branch
107     Warning("CheckAndAddBranch",
108     "No decision found for branch with name %s and class %s. Branch therefore dropped!",
109     bname, cname);
110     return;
111     }
112    
113     if (!decision) { // drop branch according to request
114 loizides 1.8 SendError(kWarning, "CheckAndAddBranch",
115     "Dropped branch with name %s and class %s.", bname, cname);
116 loizides 1.1 return;
117     }
118    
119     // add branch to accepted branch list
120 loizides 1.8 SendError(kWarning, "CheckAndAddBranch",
121     "Kept branch with name %s and class %s.", bname, cname);
122 loizides 1.1
123 loizides 1.6 fBrNameList.push_back(string(bname));
124     fBrClassList.push_back(string(cname));
125 loizides 1.1
126     // request branch
127     RequestBranch(bname);
128     }
129    
130     //--------------------------------------------------------------------------------------------------
131 loizides 1.2 void OutputMod::CheckAndResolveDep(Bool_t solve)
132     {
133     // Check if TAM has loaded additional branches. If requested try to solve the the dependency
134     // by adding the branch to the list of branches.
135    
136     const THashTable &ht = GetSel()->GetBranchTable();
137    
138 loizides 1.5 TIter iter(ht.MakeIterator());
139     const TAMBranchInfo *next = dynamic_cast<const TAMBranchInfo*>(iter.Next());
140 loizides 1.2
141     while (next) {
142     const TAMBranchInfo *cur = next;
143 loizides 1.5 next = dynamic_cast<const TAMBranchInfo*>(iter.Next());
144 loizides 1.2 Bool_t isloaded = cur->IsLoaded();
145     if (!isloaded)
146     continue;
147    
148     const char *bname = cur->GetName();
149     if (IsAcceptedBranch(bname))
150     continue;
151    
152     TreeBranchLoader *loader = dynamic_cast<TreeBranchLoader*>(cur->GetLoader());
153     if (!loader)
154     continue;
155    
156     TBranch *br = loader->GetBranch();
157     if (!br)
158     continue;
159    
160     const char *cname = br->GetClassName();
161    
162     if (solve) {
163 loizides 1.8 SendError(kWarning, "CheckAndResolveDep",
164     "Resolving dependency for loaded branch %s and class %s", bname,cname);
165 loizides 1.2
166 loizides 1.6 fBrNameList.push_back(string(bname));
167     fBrClassList.push_back(string(cname));
168 loizides 1.2 fBranches[GetNBranches()-1] = reinterpret_cast<TObject*>(loader->GetAddress());
169    
170     } else {
171     Warning("CheckAndResolveDep", "Unresolved dependency for loaded branch %s and class %s",
172     bname,cname);
173     }
174     }
175     }
176    
177     //--------------------------------------------------------------------------------------------------
178 loizides 1.4 void OutputMod::EndRun()
179     {
180     // Todo
181     }
182    
183     //--------------------------------------------------------------------------------------------------
184 loizides 1.3 void OutputMod::FillAllEventHeader(Bool_t isremoved)
185     {
186     // Fill event header into the all-event-header tree.
187    
188     const EventHeader *eh = GetEventHeader();
189     fAllEventHeader->SetEvtNum(eh->EvtNum());
190     fAllEventHeader->SetLumiSec(eh->LumiSec());
191     fAllEventHeader->SetRunNum(eh->RunNum());
192     if (isremoved)
193     fAllEventHeader->SetRunEntry(-1);
194     else
195     fAllEventHeader->SetRunEntry(eh->RunEntry());
196 loizides 1.8 fAllEventHeader->SetSkimmed(eh->Skimmed()+1);
197 loizides 1.3
198     fAllTree->Fill();
199     }
200    
201     //--------------------------------------------------------------------------------------------------
202     void OutputMod::FillL1Info()
203 loizides 1.1 {
204 loizides 1.3 // Not doing anything here until the production writes out L1 information.
205 loizides 1.1
206 loizides 1.3 if (!fL1Tree)
207 loizides 1.1 return;
208     }
209    
210     //--------------------------------------------------------------------------------------------------
211 loizides 1.3 void OutputMod::FillHltInfo()
212 loizides 1.1 {
213 loizides 1.4 // Write HLT trigger table if needed.
214 loizides 1.1
215 loizides 1.3 if (!fHltTree)
216     return;
217    
218     if (fOrigHltEntry == GetHltFwkMod()->fCurEnt)
219     return;
220    
221     fHltTree->Fill();
222     fOrigHltEntry = GetHltFwkMod()->fCurEnt;
223     ++fHltEntries;
224 loizides 1.1 }
225    
226     //--------------------------------------------------------------------------------------------------
227     Bool_t OutputMod::IsAcceptedBranch(const char *bname)
228     {
229     // Return true if given branch is already in branch list. Also return true if a special
230     // branch like the "EventHeader" branch is reqested.
231    
232     // search in branch list
233     for (UInt_t i=0; i<GetNBranches(); ++i) {
234 loizides 1.6 if (fBrNameList.at(i).compare(bname) == 0)
235 loizides 1.1 return kTRUE;
236     }
237    
238     // check if special branch that we take care of ourselves
239     string name(bname);
240     if (name.compare("EventHeader") == 0) {
241     return kTRUE;
242     }
243    
244     return kFALSE;
245     }
246    
247     //--------------------------------------------------------------------------------------------------
248     Bool_t OutputMod::Notify()
249     {
250 loizides 1.2 // On first notify, loop over list of branches to determine the list of kept branches.
251    
252     if (GetNEventsProcessed() != 0)
253     return kTRUE;
254 loizides 1.1
255     TTree *tree=const_cast<TTree*>(GetSel()->GetTree());
256     if (!tree)
257     return kFALSE;
258    
259     TObjArray *arr = tree->GetTree()->GetListOfBranches();
260     if (!arr)
261     return kFALSE;
262    
263     for (Int_t i=0; i<arr->GetEntries(); ++i) {
264     TBranch *br = dynamic_cast<TBranch*>(arr->At(i));
265     if (!br && !br->GetMother())
266     continue;
267     br = br->GetMother();
268     TClass *cls = TClass::GetClass(br->GetClassName());
269     if (!cls)
270     continue;
271    
272     if (!cls->InheritsFrom("TObject")) {
273     Warning("Notify", "Found branch %s where class %s does not derive from TObject.",
274     br->GetName(), br->GetClassName());
275     continue;
276     }
277    
278     CheckAndAddBranch(br->GetName(), br->GetClassName());
279     }
280    
281     return kTRUE;
282     }
283    
284     //--------------------------------------------------------------------------------------------------
285     void OutputMod::LoadBranches()
286     {
287     // Loop over requested branches and load them.
288    
289     for (UInt_t i=0; i<GetNBranches(); ++i) {
290 loizides 1.6 LoadBranch(fBrNameList.at(i).c_str());
291 loizides 1.1 }
292     }
293    
294     //--------------------------------------------------------------------------------------------------
295     void OutputMod::Process()
296     {
297 loizides 1.3 // Write out the kept branches of the current event. Make sure the meta information is
298     // correctly updated.
299 loizides 1.1
300 loizides 1.4 if (GetSel()->GetCurEvt() == fLastSeenEvt) {
301     Warning("Process", "Event with %ul already seen", fLastSeenEvt);
302     return;
303     }
304     fLastSeenEvt = GetSel()->GetCurEvt();
305    
306     if (GetSel()->GetCurEvt() == fLastWrittenEvt) {
307     Warning("Process", "Event with %ul already written", fLastWrittenEvt);
308     return;
309     }
310     fLastWrittenEvt = GetSel()->GetCurEvt();
311     ++fCounter;
312    
313     // prepare for tree filling
314 loizides 1.8 if (!fTreeWriter->BeginEvent(fDoReset)) {
315     SendError(kAbortAnalysis, "Process", "Begin event failed!");
316     return;
317     }
318 loizides 1.1
319 loizides 1.2 if (GetNEventsProcessed() == 0 && fCheckTamBr) {
320     CheckAndResolveDep(fKeepTamBr);
321 loizides 1.1 }
322    
323 loizides 1.4 // load all our branches
324 loizides 1.1 LoadBranches();
325    
326 loizides 1.4 // pass our branches to tree writer if on first event
327 loizides 1.1 if (GetNEventsProcessed() == 0) {
328 loizides 1.4 SetupBranches();
329 loizides 1.1 }
330    
331 loizides 1.3 // reset per file quantities if a new file was opened
332     if (fTreeWriter->GetFileNumber()!=fFileNum) {
333     fRunmap.clear();
334     fRunEntries = 0;
335     fL1Entries = -1;
336     fHltEntries = -1;
337     fFileNum = fTreeWriter->GetFileNumber();
338     }
339    
340     UInt_t runnum = GetEventHeader()->RunNum();
341    
342     // store look ahead information
343     if (fRunEntries>0) {
344     fLaHeader->SetRunNum(runnum);
345     fLATree->Fill();
346     }
347    
348     // fill event header
349     fEventHeader->SetEvtNum(GetEventHeader()->EvtNum());
350     fEventHeader->SetLumiSec(GetEventHeader()->LumiSec());
351     fEventHeader->SetRunNum(runnum);
352    
353     // fill all event header
354     // *** note that we need to read an existing tree in
355     // the future to make sure we can do skims of skims ***
356     FillAllEventHeader(kFALSE);
357    
358     // look-up if entry is in map
359     map<UInt_t,Int_t>::iterator riter = fRunmap.find(runnum);
360     if (riter != fRunmap.end()) { // found existing run info
361     Int_t runentry = riter->second;
362     fEventHeader->SetRunEntry(runentry);
363    
364     IncNEventsProcessed();
365     fTreeWriter->EndEvent(fDoReset);
366     return;
367     }
368 loizides 1.2
369 loizides 1.3 // fill new run info
370     Int_t runentry = fRunEntries;
371     ++fRunEntries;
372     fEventHeader->SetRunEntry(runentry);
373     fRunmap.insert(pair<UInt_t,Int_t>(runnum,runentry));
374     fRunInfo->SetRunNum(runnum);
375    
376     Int_t l1entry = fL1Entries;
377     FillL1Info();
378     fRunInfo->SetL1Entry(l1entry);
379    
380     Int_t hltentry = fHltEntries;
381     FillHltInfo();
382     fRunInfo->SetHltEntry(hltentry);
383    
384     fRunTree->Fill();
385    
386 loizides 1.1 IncNEventsProcessed();
387 loizides 1.8
388     if (!fTreeWriter->EndEvent(fDoReset)) {
389     SendError(kAbortAnalysis, "Process", "End event failed!");
390     return;
391     }
392 loizides 1.1 }
393    
394     //--------------------------------------------------------------------------------------------------
395 loizides 1.3 void OutputMod::ProcessAll()
396     {
397     // Called by the Selector class for events that were skipped.
398    
399 loizides 1.4 if (GetSel()->GetCurEvt() == fLastSeenEvt)
400     return;
401 loizides 1.8
402 loizides 1.4 fLastSeenEvt = GetSel()->GetCurEvt();
403     ++fCounter;
404    
405 loizides 1.8 // prepare for tree filling
406     if (!fTreeWriter->BeginEvent(kFALSE)) {
407     SendError(kAbortAnalysis, "ProcessAll", "Begin event failed!");
408     return;
409     }
410    
411 loizides 1.3 FillAllEventHeader(kTRUE);
412     }
413    
414     //--------------------------------------------------------------------------------------------------
415     void OutputMod::RequestBranch(const char *bname)
416     {
417     // Request given branch from TAM.
418    
419     if (GetNBranches()>=fNBranchesMax) {
420 loizides 1.8 SendError(kAbortAnalysis, "RequestBranch", "Can not request branch for %bname"
421     "since maximum number of branches [%d] is reached", bname, fNBranchesMax);
422 loizides 1.3 return;
423     }
424    
425     fBranches[GetNBranches()-1] = 0;
426 loizides 1.4 TAModule::ReqBranch(bname, fBranches[GetNBranches()-1]);
427 loizides 1.3 }
428    
429     //--------------------------------------------------------------------------------------------------
430 loizides 1.1 void OutputMod::SetupBranches()
431     {
432     // Setup branches in tree writer.
433    
434     for (UInt_t i=0; i<GetNBranches(); ++i) {
435 loizides 1.6 const char *bname = fBrNameList.at(i).c_str();
436     const char *cname = fBrClassList.at(i).c_str();
437 loizides 1.1 if (!fBranches[i]) {
438 loizides 1.8 SendError(kWarning, "SetupBranches",
439     "Pointer for branch with name %s and class %s is NULL.", bname, cname);
440 loizides 1.1 continue;
441     }
442 loizides 1.2 fTreeWriter->AddBranch(bname, cname, &fBranches[i]);
443 loizides 1.1 }
444     }
445    
446     //--------------------------------------------------------------------------------------------------
447     void OutputMod::SlaveBegin()
448     {
449 loizides 1.3 // Setup the tree writer and create branches that can already be created at this point.
450 loizides 1.1
451     // setup tree writer
452     fTreeWriter = new TreeWriter(fTreeName, kFALSE);
453     fTreeWriter->SetBaseURL(fPathName);
454     fTreeWriter->SetPrefix(fPrefix);
455     fTreeWriter->SetMaxSize(fMaxSize*1024*1024);
456     fTreeWriter->SetCompressLevel(fCompLevel);
457     fTreeWriter->SetDefaultSL(fSplitLevel);
458     fTreeWriter->SetDefaultBrSize(fBranchSize);
459     fTreeWriter->AddTree(fTreeName);
460     fTreeWriter->DoBranchRef(fTreeName);
461    
462 loizides 1.2 // deal with my own tree objects
463 loizides 1.3 fEventHeader = new EventHeader;
464     fTreeWriter->AddBranch(GetSel()->GetEvtHdrName(), &fEventHeader);
465    
466     // deal with other trees
467     const char *tname = 0;
468     fRunInfo = new RunInfo;
469     tname = GetSel()->GetRunTreeName();
470     fTreeWriter->AddBranchToTree(tname, GetSel()->GetRunInfoName(), &fRunInfo);
471     fTreeWriter->SetAutoFill(tname, 0);
472     fRunTree = fTreeWriter->GetTree(tname);
473     fLaHeader = new LAHeader;
474     tname = GetSel()->GetLATreeName();
475     fTreeWriter->AddBranchToTree(tname, GetSel()->GetLAHdrName(), &fLaHeader);
476     fTreeWriter->SetAutoFill(tname,0);
477     fLATree = fTreeWriter->GetTree(tname);
478     fAllEventHeader = new EventHeader;
479     tname = GetSel()->GetAllEvtTreeName();
480     fTreeWriter->AddBranchToTree(tname, GetSel()->GetAllEvtHdrBrn(), &fAllEventHeader);
481     fAllTree = fTreeWriter->GetTree(tname);
482 loizides 1.2
483 loizides 1.3 // get pointer to fAllTreeIn todo
484     // todo
485 loizides 1.1 // deal here with published objects
486 loizides 1.3 // todo
487 loizides 1.1
488     // create TObject space for TAM
489     fBranches = new TObject*[fNBranchesMax];
490 loizides 1.2
491     // adjust checks for TAM branches
492     if (fKeepTamBr)
493     fCheckTamBr = kTRUE;
494 loizides 1.1 }
495    
496     //--------------------------------------------------------------------------------------------------
497     void OutputMod::SlaveTerminate()
498     {
499 loizides 1.3 // Terminate tree writing and do cleanup.
500 loizides 1.1
501     delete fTreeWriter;
502     fTreeWriter = 0;
503    
504 loizides 1.3 delete fEventHeader;
505     delete fRunInfo;
506     delete fLaHeader;
507     delete fAllEventHeader;
508 loizides 1.2
509 loizides 1.1 delete[] fBranches;
510 loizides 1.4
511     Double_t frac = 100.*GetNEventsProcessed()/fCounter;
512 loizides 1.8 SendError(kWarning, "SlaveTerminate", "Stored %.2g%% events (%ld out of %ld)",
513     frac, GetNEventsProcessed(), fCounter);
514 loizides 1.1 }