ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TreeMod/src/OutputMod.cc
Revision: 1.6
Committed: Mon Mar 2 13:26:45 2009 UTC (16 years, 2 months ago) by loizides
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_008pre1
Changes since 1.5: +13 -13 lines
Log Message:
Removed Vector<std:string>

File Contents

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