ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/TreeMod/src/OutputMod.cc
(Generate patch)

Comparing UserCode/MitAna/TreeMod/src/OutputMod.cc (file contents):
Revision 1.6 by loizides, Mon Mar 2 13:26:45 2009 UTC vs.
Revision 1.19 by bendavid, Fri Mar 11 04:03:54 2011 UTC

# Line 3 | Line 3
3   #include "MitAna/TreeMod/interface/OutputMod.h"
4   #include "MitAna/TreeMod/interface/HLTFwkMod.h"
5   #include "MitAna/DataUtil/interface/Debug.h"
6 + #include "MitAna/DataTree/interface/BranchTable.h"
7 + #include "MitAna/DataTree/interface/EventHeaderCol.h"
8   #include "MitAna/DataTree/interface/Names.h"
9   #include "MitAna/DataUtil/interface/TreeWriter.h"
10   #include "MitAna/TreeMod/interface/TreeBranchLoader.h"
# Line 21 | Line 23 | OutputMod::OutputMod(const char *name, c
23    fMaxSize(1024),
24    fCompLevel(9),
25    fSplitLevel(99),
26 <  fBranchSize(32*1024),
26 >  fBranchSize(16*1024),
27    fDoReset(kFALSE),
28 +  fCheckBrDep(kTRUE),
29 +  fUseBrDep(kTRUE),
30    fCheckTamBr(kTRUE),
31 <  fKeepTamBr(kTRUE),
31 >  fKeepTamBr(kFALSE),
32    fTreeWriter(0),
33    fEventHeader(0),
34    fAllEventHeader(0),
35    fRunInfo(0),
36    fLaHeader(0),
37 +  fBranchTable(0),
38 +  fBranches(0),
39    fNBranchesMax(1024),
40    fRunTree(0),
41    fLATree(0),
42    fAllTree(0),
43 <  fL1Tree(0),
43 >  fSkimmedIn(0),
44    fHltTree(0),
45 +  fHLTTab(new vector<string>),
46 +  fHLTLab(new vector<string>),
47    fRunEntries(0),
40  fOrigL1Entry(-1),
41  fL1Entries(0),
42  fOrigHltEntry(-1),
48    fHltEntries(0),
49 <  fFileNum(0),
49 >  fFileNum(-1),
50    fLastWrittenEvt(-1),
51    fLastSeenEvt(-1),
52    fCounter(0)
# Line 59 | Line 64 | void OutputMod::BeginRun()
64  
65    if (!fHltTree) {
66      HLTFwkMod *hm = const_cast<HLTFwkMod*>(GetHltFwkMod());
67 <    fTreeWriter->AddBranchToTree(hm->HLTTreeName(), hm->HLTTabName(), &(hm->fHLTTab), 32000, 0);
68 <    fTreeWriter->AddBranchToTree(hm->HLTTreeName(), hm->HLTLabName(), &(hm->fHLTLab), 32000, 0);
67 >    fTreeWriter->AddBranchToTree(hm->HLTTreeName(), hm->HLTTabName(),
68 >                                 TClass::GetClass(typeid(*fHLTTab))->GetName(),
69 >                                 &fHLTTab, 32000, 0);
70 >    fTreeWriter->AddBranchToTree(hm->HLTTreeName(), hm->HLTLabName(),
71 >                                 TClass::GetClass(typeid(*fHLTLab))->GetName(),
72 >                                 &fHLTLab, 32000, 0);
73      fTreeWriter->SetAutoFill(hm->HLTTreeName(), 0);
74      fHltTree = fTreeWriter->GetTree(hm->HLTTreeName());
75    }
# Line 101 | Line 110 | void OutputMod::CheckAndAddBranch(const
110  
111    if (!decision_found) { // no decision found: still drop branch
112      Warning("CheckAndAddBranch",
113 <            "No decision found for branch with name %s and class %s. Branch therefore dropped!",
113 >            "No decision found for branch '%s' and class '%s'. Branch therefore dropped!",
114              bname, cname);
115      return;
116    }
117  
118    if (!decision) { // drop branch according to request
119 <    Info("CheckAndAddBranch", "Dropped branch with name %s and class %s.", bname, cname);
119 >    Info("CheckAndAddBranch",
120 >         "Dropped branch '%s' and class '%s'", bname, cname);
121      return;
122    }
123  
124    // add branch to accepted branch list
125 <  Info("CheckAndAddBranch", "Kept branch with name %s and class %s.", bname, cname);
125 >  Info("CheckAndAddBranch",
126 >       "Kept branch '%s' and class '%s'", bname, cname);
127  
128    fBrNameList.push_back(string(bname));
129    fBrClassList.push_back(string(cname));
130 + }
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 +  if (!cfile) {
139 +    SendError(kAbortAnalysis, "CheckAndResolveBranchDep", "Could not get pointer to current file!");
140 +    return kFALSE;
141 +  }
142 +
143 +  BranchTable *br = dynamic_cast<BranchTable*>(cfile->Get(Names::gkBranchTable));
144 +  if (!br) {
145 +    SendError(kAbortAnalysis, "CheckAndResolveBranchDep", "Could not get pointer to branch table!");
146 +    return kFALSE;
147 +  }
148 +
149 +  TList *blist = br->GetBranches();
150 +  if (!blist) {
151 +    SendError(kAbortAnalysis, "CheckAndResolveBranchDep", "Could not get list of branches!");
152 +    return kFALSE;
153 +  }
154 +
155 +  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 +    TString brname(fBrNameList.at(i));
167 +    if (!blist->FindObject(brname))
168 +      continue;
169 +    TList *bdeps = br->GetDepBranches(brname);
170 +    if (!bdeps)
171 +      continue;
172  
173 <  // request branch
174 <  RequestBranch(bname);
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   }
210  
211   //--------------------------------------------------------------------------------------------------
212 < void OutputMod::CheckAndResolveDep(Bool_t solve)
212 > void OutputMod::CheckAndResolveTAMDep(Bool_t solve)
213   {
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.
# Line 154 | Line 241 | void OutputMod::CheckAndResolveDep(Bool_
241      const char *cname = br->GetClassName();
242  
243      if (solve) {
244 <      Info("CheckAndResolveDep", "Resolving dependency for loaded branch %s and class %s",
245 <           bname,cname);
244 >      Info("CheckAndResolveTAMDep",
245 >           "Resolving dependency for loaded branch '%s' and class '%s'", bname,cname);
246  
247        fBrNameList.push_back(string(bname));
248        fBrClassList.push_back(string(cname));
249        fBranches[GetNBranches()-1] = reinterpret_cast<TObject*>(loader->GetAddress());
250  
251      } else {
252 <      Warning("CheckAndResolveDep", "Unresolved dependency for loaded branch %s and class %s",
252 >      Warning("CheckAndResolveTAMDep",
253 >              "Unresolved dependency for loaded branch '%s' and class '%s'",
254                bname,cname);
255      }
256    }
# Line 171 | Line 259 | void OutputMod::CheckAndResolveDep(Bool_
259   //--------------------------------------------------------------------------------------------------
260   void OutputMod::EndRun()
261   {
262 <  // Todo
262 >  // Nothing to be done at this point.
263   }
264  
265   //--------------------------------------------------------------------------------------------------
# Line 179 | Line 267 | void OutputMod::FillAllEventHeader(Bool_
267   {
268    // Fill event header into the all-event-header tree.
269  
270 +  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 +    const UInt_t n = fSkimmedIn->GetEntries();
277 +    for(UInt_t i=0; i<n; ++i) {
278 +      const EventHeader *eh = fSkimmedIn->At(i);
279 +      *fAllEventHeader = *eh;
280 +      fAllEventHeader->SetSkimmed(eh->Skimmed()+1);
281 +      fAllTree->Fill();
282 +    }
283 +  }
284 +
285    const EventHeader *eh = GetEventHeader();
286 <  fAllEventHeader->SetEvtNum(eh->EvtNum());
287 <  fAllEventHeader->SetLumiSec(eh->LumiSec());
185 <  fAllEventHeader->SetRunNum(eh->RunNum());
186 <  if (isremoved)
286 >  *fAllEventHeader = *eh;
287 >  if (isremoved) {
288      fAllEventHeader->SetRunEntry(-1);
289 <  else
289 >    fAllEventHeader->SetSkimmed(eh->Skimmed()+1);
290 >  } else {
291      fAllEventHeader->SetRunEntry(eh->RunEntry());
292 <  fAllEventHeader->SetIsRemoved(isremoved);
292 >    fAllEventHeader->SetSkimmed(eh->Skimmed());
293 >  }
294  
295    fAllTree->Fill();
296   }
297  
298   //--------------------------------------------------------------------------------------------------
196 void OutputMod::FillL1Info()
197 {
198  // Not doing anything here until the production writes out L1 information.
199
200  if (!fL1Tree)
201    return;
202 }
203
204 //--------------------------------------------------------------------------------------------------
299   void OutputMod::FillHltInfo()
300   {
301    // Write HLT trigger table if needed.
# Line 209 | Line 303 | void OutputMod::FillHltInfo()
303    if (!fHltTree)
304      return;
305  
306 <  if (fOrigHltEntry == GetHltFwkMod()->fCurEnt)
306 >  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      return;
342  
343 <  fHltTree->Fill();
344 <  fOrigHltEntry = GetHltFwkMod()->fCurEnt;
343 >  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 +  fHltTree->Fill();
350   }
351  
352   //--------------------------------------------------------------------------------------------------
# Line 246 | Line 378 | Bool_t OutputMod::Notify()
378    if (GetNEventsProcessed() != 0)
379      return kTRUE;
380  
381 <  TTree *tree=const_cast<TTree*>(GetSel()->GetTree());
381 >  const TTree *tree=GetSel()->GetTree();
382    if (!tree)
383      return kFALSE;
384  
385 <  TObjArray *arr = tree->GetTree()->GetListOfBranches();
385 >  const TObjArray *arr = tree->GetTree()->GetListOfBranches();
386    if (!arr)
387      return kFALSE;
388  
# Line 264 | Line 396 | Bool_t OutputMod::Notify()
396        continue;
397  
398      if (!cls->InheritsFrom("TObject")) {
399 <      Warning("Notify", "Found branch %s where class %s does not derive from TObject.",
399 >      Warning("Notify", "Found branch '%s' where class '%s' does not derive from TObject",
400                br->GetName(), br->GetClassName());
401        continue;
402      }
# Line 272 | Line 404 | Bool_t OutputMod::Notify()
404      CheckAndAddBranch(br->GetName(), br->GetClassName());
405    }
406  
407 +  if (fCheckBrDep && !CheckAndResolveBranchDep())
408 +    return kFALSE;
409 +
410 +  RequestBranches();
411    return kTRUE;
412   }
413  
# Line 292 | Line 428 | void OutputMod::Process()
428    // correctly updated.
429  
430    if (GetSel()->GetCurEvt() == fLastSeenEvt) {
431 <    Warning("Process", "Event with %ul already seen", fLastSeenEvt);
431 >    Warning("Process", "Event with %lld 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);
437 >    Warning("Process", "Event with %lld already written", fLastWrittenEvt);
438      return;
439    }
440    fLastWrittenEvt = GetSel()->GetCurEvt();
441    ++fCounter;
442  
443    // prepare for tree filling
444 <  fTreeWriter->BeginEvent(fDoReset);
444 >  if (!fTreeWriter->BeginEvent(fDoReset)) {
445 >    SendError(kAbortAnalysis, "Process", "Begin event failed!");
446 >    return;
447 >  }
448  
449    if (GetNEventsProcessed() == 0 && fCheckTamBr) {
450 <    CheckAndResolveDep(fKeepTamBr);    
450 >    CheckAndResolveTAMDep(fKeepTamBr);
451    }
452  
453    // load all our branches
# Line 322 | Line 461 | void OutputMod::Process()
461    // reset per file quantities if a new file was opened
462    if (fTreeWriter->GetFileNumber()!=fFileNum) {
463      fRunmap.clear();
464 +    fHLTTab->clear();
465 +    fHLTLab->clear();
466      fRunEntries = 0;
467 <    fL1Entries  = -1;
327 <    fHltEntries = -1;
467 >    fHltEntries = 0;
468      fFileNum = fTreeWriter->GetFileNumber();
469 +    if (fBranchTable)
470 +      fTreeWriter->StoreObject(fBranchTable);
471    }
472  
473    UInt_t runnum = GetEventHeader()->RunNum();
# Line 337 | Line 479 | void OutputMod::Process()
479    }
480  
481    // fill event header
482 <  fEventHeader->SetEvtNum(GetEventHeader()->EvtNum());
341 <  fEventHeader->SetLumiSec(GetEventHeader()->LumiSec());
342 <  fEventHeader->SetRunNum(runnum);
482 >  *fEventHeader = *GetEventHeader();
483  
484    // 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 ***
485    FillAllEventHeader(kFALSE);
486  
487    // look-up if entry is in map
# Line 364 | Line 502 | void OutputMod::Process()
502    fRunmap.insert(pair<UInt_t,Int_t>(runnum,runentry));
503    fRunInfo->SetRunNum(runnum);
504  
367  Int_t l1entry = fL1Entries;
368  FillL1Info();
369  fRunInfo->SetL1Entry(l1entry);
370
505    Int_t hltentry = fHltEntries;
506    FillHltInfo();
507 <  fRunInfo->SetHltEntry(hltentry);
507 >  if (hltentry < fHltEntries)
508 >    fRunInfo->SetHltEntry(hltentry);
509 >  else
510 >    fRunInfo->SetHltEntry(hltentry-1);
511    
512    fRunTree->Fill();
513 <  
513 >
514    IncNEventsProcessed();
515 <  fTreeWriter->EndEvent(fDoReset);
515 >
516 >  if (!fTreeWriter->EndEvent(fDoReset)) {
517 >    SendError(kAbortAnalysis, "Process", "End event failed!");
518 >    return;
519 >  }
520   }
521  
522   //--------------------------------------------------------------------------------------------------
# Line 385 | Line 526 | void OutputMod::ProcessAll()
526  
527    if (GetSel()->GetCurEvt() == fLastSeenEvt)
528      return;
529 +
530    fLastSeenEvt = GetSel()->GetCurEvt();
531    ++fCounter;
532  
533 +  // prepare for tree filling
534    FillAllEventHeader(kTRUE);
535   }
536  
537   //--------------------------------------------------------------------------------------------------
538 < void OutputMod::RequestBranch(const char *bname)
538 > void OutputMod::RequestBranches()
539   {
540 <  // Request given branch from TAM.
540 >  // Loop over requested branches and request them.
541  
542 <  if (GetNBranches()>=fNBranchesMax) {
543 <    Error("RequestBranch", "Can not request branch for %bname"
544 <          "since maximum number of branches [%d] is reached", bname, fNBranchesMax);
545 <    return;
542 >  for (UInt_t i=0; i<GetNBranches(); ++i) {
543 >    if (i>=fNBranchesMax) {
544 >      SendError(kAbortAnalysis, "RequestBranches", "Cannot request branch '%s' "
545 >                "since maximum number of branches [%d] is reached",
546 >                fBrNameList.at(i).c_str(), fNBranchesMax);
547 >      return;
548 >    }
549 >    fBranches[i] = 0;
550 >    TAModule::ReqBranch(fBrNameList.at(i).c_str(), fBranches[i]);
551    }
404  
405  fBranches[GetNBranches()-1] = 0;
406  TAModule::ReqBranch(bname, fBranches[GetNBranches()-1]);
552   }
553  
554   //--------------------------------------------------------------------------------------------------
# Line 415 | Line 560 | void OutputMod::SetupBranches()
560      const char *bname = fBrNameList.at(i).c_str();
561      const char *cname = fBrClassList.at(i).c_str();
562      if (!fBranches[i]) {
563 <      Error("SetupBranches", "Pointer for branch with name %s and class %s is NULL.",
564 <            bname, cname);
563 >      SendError(kWarning, "SetupBranches",
564 >                "Pointer for branch '%s' and class '%s' is NULL", bname, cname);
565        continue;
566      }
567 <    fTreeWriter->AddBranch(bname, cname, &fBranches[i]);
567 >    Int_t bsize = fBranchSize;
568 >    TString cnamestr(cname);
569 >    if ((bsize<128*1024) && (cnamestr.Contains("mithep::MCParticle"))) {
570 >      bsize=128*1024;
571 >    } else if ((bsize<32*1024) && (cnamestr.Contains("mithep::CaloTower"))) {
572 >      bsize=32*1024;
573 >    }
574 >
575 >    fTreeWriter->AddBranch(bname, cname, &fBranches[i], bsize);
576    }
577   }
578  
# Line 453 | Line 606 | void OutputMod::SlaveBegin()
606    fLaHeader = new LAHeader;
607    tname = GetSel()->GetLATreeName();
608    fTreeWriter->AddBranchToTree(tname, GetSel()->GetLAHdrName(), &fLaHeader);
609 <  fTreeWriter->SetAutoFill(tname,0);
609 >  fTreeWriter->SetAutoFill(tname, 0);
610    fLATree = fTreeWriter->GetTree(tname);
611    fAllEventHeader = new EventHeader;
612    tname = GetSel()->GetAllEvtTreeName();
613    fTreeWriter->AddBranchToTree(tname, GetSel()->GetAllEvtHdrBrn(), &fAllEventHeader);
614    fAllTree = fTreeWriter->GetTree(tname);
615 +  fTreeWriter->SetAutoFill(tname, 0);
616  
617 <  // get pointer to fAllTreeIn todo
618 <  // todo
465 <  // deal here with published objects
466 <  // todo
617 >  // get pointer to all event headers
618 >  fSkimmedIn = GetPublicObj<EventHeaderCol>(Names::gkSkimmedHeaders);
619  
620    // create TObject space for TAM
621 <  fBranches = new TObject*[fNBranchesMax];      
621 >  fBranches = new TObject*[fNBranchesMax + fAddList.size()];      
622 >
623 >  // deal here with additional published objects
624 >  for (UInt_t i=0; i<fAddList.size(); ++i) {
625 >    TString objname(fAddList.at(i));
626 >    TObject *obj = FindPublicObj(objname);
627 >    if (obj) {
628 >      fBranches[fNBranchesMax+i] = obj;
629 >      fTreeWriter->AddBranch(objname, &fBranches[fNBranchesMax+i]);
630 >      Info("SlaveBegin", "Adding additional branch named '%s' as requested", objname.Data());
631 >    } else {
632 >      SendError(kAbortAnalysis, "SlaveBegin",
633 >                "Object named '%s' for additional branch is NULL", objname.Data());
634 >    }
635 >  }
636  
637    // adjust checks for TAM branches
638    if (fKeepTamBr)
# Line 478 | Line 644 | void OutputMod::SlaveTerminate()
644   {
645    // Terminate tree writing and do cleanup.
646  
647 +  RetractObj(Names::gkSkimmedHeaders);
648 +
649    delete fTreeWriter;
650    fTreeWriter = 0;
651  
# Line 489 | Line 657 | void OutputMod::SlaveTerminate()
657    delete[] fBranches;
658  
659    Double_t frac =  100.*GetNEventsProcessed()/fCounter;
660 <  Info("SlaveTerminate", "Stored %.2g%% events (%ld out of %ld)",
660 >  Info("SlaveTerminate", "Stored %.2f%% events (%d out of %lld)",
661         frac, GetNEventsProcessed(), fCounter);
662   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines