ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TreeMod/src/OutputMod.cc
Revision: 1.7
Committed: Sat Mar 7 08:32:40 2009 UTC (16 years, 2 months ago) by loizides
Content type: text/plain
Branch: MAIN
Changes since 1.6: +8 -4 lines
Log Message:
Fixes for 008.

File Contents

# User Rev Content
1 loizides 1.7 // $Id: OutputMod.cc,v 1.6 2009/03/02 13:26:45 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     Info("CheckAndAddBranch", "Dropped branch with name %s and class %s.", bname, cname);
115     return;
116     }
117    
118     // add branch to accepted branch list
119     Info("CheckAndAddBranch", "Kept branch with name %s and class %s.", bname, cname);
120    
121 loizides 1.6 fBrNameList.push_back(string(bname));
122     fBrClassList.push_back(string(cname));
123 loizides 1.1
124     // request branch
125     RequestBranch(bname);
126     }
127    
128     //--------------------------------------------------------------------------------------------------
129 loizides 1.2 void OutputMod::CheckAndResolveDep(Bool_t solve)
130     {
131     // Check if TAM has loaded additional branches. If requested try to solve the the dependency
132     // by adding the branch to the list of branches.
133    
134     const THashTable &ht = GetSel()->GetBranchTable();
135    
136 loizides 1.5 TIter iter(ht.MakeIterator());
137     const TAMBranchInfo *next = dynamic_cast<const TAMBranchInfo*>(iter.Next());
138 loizides 1.2
139     while (next) {
140     const TAMBranchInfo *cur = next;
141 loizides 1.5 next = dynamic_cast<const TAMBranchInfo*>(iter.Next());
142 loizides 1.2 Bool_t isloaded = cur->IsLoaded();
143     if (!isloaded)
144     continue;
145    
146     const char *bname = cur->GetName();
147     if (IsAcceptedBranch(bname))
148     continue;
149    
150     TreeBranchLoader *loader = dynamic_cast<TreeBranchLoader*>(cur->GetLoader());
151     if (!loader)
152     continue;
153    
154     TBranch *br = loader->GetBranch();
155     if (!br)
156     continue;
157    
158     const char *cname = br->GetClassName();
159    
160     if (solve) {
161     Info("CheckAndResolveDep", "Resolving dependency for loaded branch %s and class %s",
162     bname,cname);
163    
164 loizides 1.6 fBrNameList.push_back(string(bname));
165     fBrClassList.push_back(string(cname));
166 loizides 1.2 fBranches[GetNBranches()-1] = reinterpret_cast<TObject*>(loader->GetAddress());
167    
168     } else {
169     Warning("CheckAndResolveDep", "Unresolved dependency for loaded branch %s and class %s",
170     bname,cname);
171     }
172     }
173     }
174    
175     //--------------------------------------------------------------------------------------------------
176 loizides 1.4 void OutputMod::EndRun()
177     {
178     // Todo
179     }
180    
181     //--------------------------------------------------------------------------------------------------
182 loizides 1.3 void OutputMod::FillAllEventHeader(Bool_t isremoved)
183     {
184     // Fill event header into the all-event-header tree.
185    
186     const EventHeader *eh = GetEventHeader();
187     fAllEventHeader->SetEvtNum(eh->EvtNum());
188     fAllEventHeader->SetLumiSec(eh->LumiSec());
189     fAllEventHeader->SetRunNum(eh->RunNum());
190     if (isremoved)
191     fAllEventHeader->SetRunEntry(-1);
192     else
193     fAllEventHeader->SetRunEntry(eh->RunEntry());
194     fAllEventHeader->SetIsRemoved(isremoved);
195    
196     fAllTree->Fill();
197     }
198    
199     //--------------------------------------------------------------------------------------------------
200     void OutputMod::FillL1Info()
201 loizides 1.1 {
202 loizides 1.3 // Not doing anything here until the production writes out L1 information.
203 loizides 1.1
204 loizides 1.3 if (!fL1Tree)
205 loizides 1.1 return;
206     }
207    
208     //--------------------------------------------------------------------------------------------------
209 loizides 1.3 void OutputMod::FillHltInfo()
210 loizides 1.1 {
211 loizides 1.4 // Write HLT trigger table if needed.
212 loizides 1.1
213 loizides 1.3 if (!fHltTree)
214     return;
215    
216     if (fOrigHltEntry == GetHltFwkMod()->fCurEnt)
217     return;
218    
219     fHltTree->Fill();
220     fOrigHltEntry = GetHltFwkMod()->fCurEnt;
221     ++fHltEntries;
222 loizides 1.1 }
223    
224     //--------------------------------------------------------------------------------------------------
225     Bool_t OutputMod::IsAcceptedBranch(const char *bname)
226     {
227     // Return true if given branch is already in branch list. Also return true if a special
228     // branch like the "EventHeader" branch is reqested.
229    
230     // search in branch list
231     for (UInt_t i=0; i<GetNBranches(); ++i) {
232 loizides 1.6 if (fBrNameList.at(i).compare(bname) == 0)
233 loizides 1.1 return kTRUE;
234     }
235    
236     // check if special branch that we take care of ourselves
237     string name(bname);
238     if (name.compare("EventHeader") == 0) {
239     return kTRUE;
240     }
241    
242     return kFALSE;
243     }
244    
245     //--------------------------------------------------------------------------------------------------
246     Bool_t OutputMod::Notify()
247     {
248 loizides 1.2 // On first notify, loop over list of branches to determine the list of kept branches.
249    
250     if (GetNEventsProcessed() != 0)
251     return kTRUE;
252 loizides 1.1
253     TTree *tree=const_cast<TTree*>(GetSel()->GetTree());
254     if (!tree)
255     return kFALSE;
256    
257     TObjArray *arr = tree->GetTree()->GetListOfBranches();
258     if (!arr)
259     return kFALSE;
260    
261     for (Int_t i=0; i<arr->GetEntries(); ++i) {
262     TBranch *br = dynamic_cast<TBranch*>(arr->At(i));
263     if (!br && !br->GetMother())
264     continue;
265     br = br->GetMother();
266     TClass *cls = TClass::GetClass(br->GetClassName());
267     if (!cls)
268     continue;
269    
270     if (!cls->InheritsFrom("TObject")) {
271     Warning("Notify", "Found branch %s where class %s does not derive from TObject.",
272     br->GetName(), br->GetClassName());
273     continue;
274     }
275    
276     CheckAndAddBranch(br->GetName(), br->GetClassName());
277     }
278    
279     return kTRUE;
280     }
281    
282     //--------------------------------------------------------------------------------------------------
283     void OutputMod::LoadBranches()
284     {
285     // Loop over requested branches and load them.
286    
287     for (UInt_t i=0; i<GetNBranches(); ++i) {
288 loizides 1.6 LoadBranch(fBrNameList.at(i).c_str());
289 loizides 1.1 }
290     }
291    
292     //--------------------------------------------------------------------------------------------------
293     void OutputMod::Process()
294     {
295 loizides 1.3 // Write out the kept branches of the current event. Make sure the meta information is
296     // correctly updated.
297 loizides 1.1
298 loizides 1.4 if (GetSel()->GetCurEvt() == fLastSeenEvt) {
299     Warning("Process", "Event with %ul already seen", fLastSeenEvt);
300     return;
301     }
302     fLastSeenEvt = GetSel()->GetCurEvt();
303    
304     if (GetSel()->GetCurEvt() == fLastWrittenEvt) {
305     Warning("Process", "Event with %ul already written", fLastWrittenEvt);
306     return;
307     }
308     fLastWrittenEvt = GetSel()->GetCurEvt();
309     ++fCounter;
310    
311     // prepare for tree filling
312 loizides 1.1 fTreeWriter->BeginEvent(fDoReset);
313    
314 loizides 1.2 if (GetNEventsProcessed() == 0 && fCheckTamBr) {
315     CheckAndResolveDep(fKeepTamBr);
316 loizides 1.1 }
317    
318 loizides 1.4 // load all our branches
319 loizides 1.1 LoadBranches();
320    
321 loizides 1.4 // pass our branches to tree writer if on first event
322 loizides 1.1 if (GetNEventsProcessed() == 0) {
323 loizides 1.4 SetupBranches();
324 loizides 1.1 }
325    
326 loizides 1.3 // reset per file quantities if a new file was opened
327     if (fTreeWriter->GetFileNumber()!=fFileNum) {
328     fRunmap.clear();
329     fRunEntries = 0;
330     fL1Entries = -1;
331     fHltEntries = -1;
332     fFileNum = fTreeWriter->GetFileNumber();
333     }
334    
335     UInt_t runnum = GetEventHeader()->RunNum();
336    
337     // store look ahead information
338     if (fRunEntries>0) {
339     fLaHeader->SetRunNum(runnum);
340     fLATree->Fill();
341     }
342    
343     // fill event header
344     fEventHeader->SetEvtNum(GetEventHeader()->EvtNum());
345     fEventHeader->SetLumiSec(GetEventHeader()->LumiSec());
346     fEventHeader->SetRunNum(runnum);
347    
348     // fill all event header
349     // *** note that we need to read an existing tree in
350     // the future to make sure we can do skims of skims ***
351     FillAllEventHeader(kFALSE);
352    
353     // look-up if entry is in map
354     map<UInt_t,Int_t>::iterator riter = fRunmap.find(runnum);
355     if (riter != fRunmap.end()) { // found existing run info
356     Int_t runentry = riter->second;
357     fEventHeader->SetRunEntry(runentry);
358    
359     IncNEventsProcessed();
360     fTreeWriter->EndEvent(fDoReset);
361     return;
362     }
363 loizides 1.2
364 loizides 1.3 // fill new run info
365     Int_t runentry = fRunEntries;
366     ++fRunEntries;
367     fEventHeader->SetRunEntry(runentry);
368     fRunmap.insert(pair<UInt_t,Int_t>(runnum,runentry));
369     fRunInfo->SetRunNum(runnum);
370    
371     Int_t l1entry = fL1Entries;
372     FillL1Info();
373     fRunInfo->SetL1Entry(l1entry);
374    
375     Int_t hltentry = fHltEntries;
376     FillHltInfo();
377     fRunInfo->SetHltEntry(hltentry);
378    
379     fRunTree->Fill();
380    
381 loizides 1.1 IncNEventsProcessed();
382     fTreeWriter->EndEvent(fDoReset);
383     }
384    
385     //--------------------------------------------------------------------------------------------------
386 loizides 1.3 void OutputMod::ProcessAll()
387     {
388     // Called by the Selector class for events that were skipped.
389    
390 loizides 1.4 if (GetSel()->GetCurEvt() == fLastSeenEvt)
391     return;
392     fLastSeenEvt = GetSel()->GetCurEvt();
393     ++fCounter;
394    
395 loizides 1.3 FillAllEventHeader(kTRUE);
396     }
397    
398     //--------------------------------------------------------------------------------------------------
399     void OutputMod::RequestBranch(const char *bname)
400     {
401     // Request given branch from TAM.
402    
403     if (GetNBranches()>=fNBranchesMax) {
404     Error("RequestBranch", "Can not request branch for %bname"
405     "since maximum number of branches [%d] is reached", bname, fNBranchesMax);
406     return;
407     }
408    
409     fBranches[GetNBranches()-1] = 0;
410 loizides 1.4 TAModule::ReqBranch(bname, fBranches[GetNBranches()-1]);
411 loizides 1.3 }
412    
413     //--------------------------------------------------------------------------------------------------
414 loizides 1.1 void OutputMod::SetupBranches()
415     {
416     // Setup branches in tree writer.
417    
418     for (UInt_t i=0; i<GetNBranches(); ++i) {
419 loizides 1.6 const char *bname = fBrNameList.at(i).c_str();
420     const char *cname = fBrClassList.at(i).c_str();
421 loizides 1.1 if (!fBranches[i]) {
422     Error("SetupBranches", "Pointer for branch with name %s and class %s is NULL.",
423     bname, cname);
424     continue;
425     }
426 loizides 1.2 fTreeWriter->AddBranch(bname, cname, &fBranches[i]);
427 loizides 1.1 }
428     }
429    
430     //--------------------------------------------------------------------------------------------------
431     void OutputMod::SlaveBegin()
432     {
433 loizides 1.3 // Setup the tree writer and create branches that can already be created at this point.
434 loizides 1.1
435     // setup tree writer
436     fTreeWriter = new TreeWriter(fTreeName, kFALSE);
437     fTreeWriter->SetBaseURL(fPathName);
438     fTreeWriter->SetPrefix(fPrefix);
439     fTreeWriter->SetMaxSize(fMaxSize*1024*1024);
440     fTreeWriter->SetCompressLevel(fCompLevel);
441     fTreeWriter->SetDefaultSL(fSplitLevel);
442     fTreeWriter->SetDefaultBrSize(fBranchSize);
443     fTreeWriter->AddTree(fTreeName);
444     fTreeWriter->DoBranchRef(fTreeName);
445    
446 loizides 1.2 // deal with my own tree objects
447 loizides 1.3 fEventHeader = new EventHeader;
448     fTreeWriter->AddBranch(GetSel()->GetEvtHdrName(), &fEventHeader);
449    
450     // deal with other trees
451     const char *tname = 0;
452     fRunInfo = new RunInfo;
453     tname = GetSel()->GetRunTreeName();
454     fTreeWriter->AddBranchToTree(tname, GetSel()->GetRunInfoName(), &fRunInfo);
455     fTreeWriter->SetAutoFill(tname, 0);
456     fRunTree = fTreeWriter->GetTree(tname);
457     fLaHeader = new LAHeader;
458     tname = GetSel()->GetLATreeName();
459     fTreeWriter->AddBranchToTree(tname, GetSel()->GetLAHdrName(), &fLaHeader);
460     fTreeWriter->SetAutoFill(tname,0);
461     fLATree = fTreeWriter->GetTree(tname);
462     fAllEventHeader = new EventHeader;
463     tname = GetSel()->GetAllEvtTreeName();
464     fTreeWriter->AddBranchToTree(tname, GetSel()->GetAllEvtHdrBrn(), &fAllEventHeader);
465     fAllTree = fTreeWriter->GetTree(tname);
466 loizides 1.2
467 loizides 1.3 // get pointer to fAllTreeIn todo
468     // todo
469 loizides 1.1 // deal here with published objects
470 loizides 1.3 // todo
471 loizides 1.1
472     // create TObject space for TAM
473     fBranches = new TObject*[fNBranchesMax];
474 loizides 1.2
475     // adjust checks for TAM branches
476     if (fKeepTamBr)
477     fCheckTamBr = kTRUE;
478 loizides 1.1 }
479    
480     //--------------------------------------------------------------------------------------------------
481     void OutputMod::SlaveTerminate()
482     {
483 loizides 1.3 // Terminate tree writing and do cleanup.
484 loizides 1.1
485     delete fTreeWriter;
486     fTreeWriter = 0;
487    
488 loizides 1.3 delete fEventHeader;
489     delete fRunInfo;
490     delete fLaHeader;
491     delete fAllEventHeader;
492 loizides 1.2
493 loizides 1.1 delete[] fBranches;
494 loizides 1.4
495     Double_t frac = 100.*GetNEventsProcessed()/fCounter;
496     Info("SlaveTerminate", "Stored %.2g%% events (%ld out of %ld)",
497     frac, GetNEventsProcessed(), fCounter);
498 loizides 1.1 }