ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TreeMod/src/OutputMod.cc
Revision: 1.3
Committed: Wed Dec 3 17:44:05 2008 UTC (16 years, 5 months ago) by loizides
Content type: text/plain
Branch: MAIN
Changes since 1.2: +165 -49 lines
Log Message:
First quite complete implementation. Needs tests.

File Contents

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