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.15 by loizides, Fri Jul 17 20:47:43 2009 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 +    for(UInt_t i=0; i<fSkimmedIn->Entries(); ++i) {
277 +      const EventHeader *eh = fSkimmedIn->At(i);
278 +      fAllEventHeader->SetEvtNum(eh->EvtNum());
279 +      fAllEventHeader->SetLumiSec(eh->LumiSec());
280 +      fAllEventHeader->SetRunNum(eh->RunNum());
281 +      fAllEventHeader->SetRunEntry(eh->RunEntry());
282 +      fAllEventHeader->SetSkimmed(eh->Skimmed()+1);
283 +      fAllTree->Fill();
284 +    }
285 +  }
286 +
287    const EventHeader *eh = GetEventHeader();
288    fAllEventHeader->SetEvtNum(eh->EvtNum());
289    fAllEventHeader->SetLumiSec(eh->LumiSec());
290    fAllEventHeader->SetRunNum(eh->RunNum());
291 <  if (isremoved)
291 >  if (isremoved) {
292      fAllEventHeader->SetRunEntry(-1);
293 <  else
293 >    fAllEventHeader->SetSkimmed(eh->Skimmed()+1);
294 >  } else {
295      fAllEventHeader->SetRunEntry(eh->RunEntry());
296 <  fAllEventHeader->SetIsRemoved(isremoved);
296 >    fAllEventHeader->SetSkimmed(eh->Skimmed());
297 >  }
298  
299    fAllTree->Fill();
300   }
301  
302   //--------------------------------------------------------------------------------------------------
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 //--------------------------------------------------------------------------------------------------
303   void OutputMod::FillHltInfo()
304   {
305    // Write HLT trigger table if needed.
# Line 209 | Line 307 | void OutputMod::FillHltInfo()
307    if (!fHltTree)
308      return;
309  
310 <  if (fOrigHltEntry == GetHltFwkMod()->fCurEnt)
310 >  HLTFwkMod *hm = const_cast<HLTFwkMod*>(GetHltFwkMod());
311 >  vector<string> *trigtable = hm->fHLTTab;
312 >  vector<string> *labels = hm->fHLTLab;
313 >
314 >  Bool_t doCopy = kFALSE;
315 >  if (fHLTTab->size()==0) {
316 >    doCopy = kTRUE;
317 >  } else {
318 >    // check if existing table contains all necessary paths:
319 >    // if so keep it, otherwise store the new one  
320 >
321 >    if ((fHLTTab->size() != trigtable->size()) ||
322 >        (fHLTLab->size() != labels->size())) {
323 >      doCopy = kTRUE;
324 >    } else {
325 >      // need to check more thoroughly
326 >
327 >      for (UInt_t i=0; i<trigtable->size(); ++i) {
328 >        if (trigtable->at(i) != fHLTTab->at(i)) {
329 >          doCopy = kTRUE;
330 >          break;
331 >        }
332 >      }
333 >      if (!doCopy) {
334 >        for (UInt_t i=0; i<labels->size(); ++i) {
335 >        if (labels->at(i) != fHLTLab->at(i)) {
336 >            doCopy = kTRUE;
337 >            break;
338 >          }
339 >        }
340 >      }
341 >    }
342 >  }
343 >
344 >  if (!doCopy)
345      return;
346  
347 <  fHltTree->Fill();
348 <  fOrigHltEntry = GetHltFwkMod()->fCurEnt;
347 >  fHLTTab->resize(trigtable->size());
348 >  copy(trigtable->begin(),trigtable->end(), fHLTTab->begin());
349 >  fHLTLab->resize(labels->size());
350 >  copy(labels->begin(),labels->end(), fHLTLab->begin());
351 >
352    ++fHltEntries;
353 +  fHltTree->Fill();
354   }
355  
356   //--------------------------------------------------------------------------------------------------
# Line 246 | Line 382 | Bool_t OutputMod::Notify()
382    if (GetNEventsProcessed() != 0)
383      return kTRUE;
384  
385 <  TTree *tree=const_cast<TTree*>(GetSel()->GetTree());
385 >  const TTree *tree=GetSel()->GetTree();
386    if (!tree)
387      return kFALSE;
388  
389 <  TObjArray *arr = tree->GetTree()->GetListOfBranches();
389 >  const TObjArray *arr = tree->GetTree()->GetListOfBranches();
390    if (!arr)
391      return kFALSE;
392  
# Line 264 | Line 400 | Bool_t OutputMod::Notify()
400        continue;
401  
402      if (!cls->InheritsFrom("TObject")) {
403 <      Warning("Notify", "Found branch %s where class %s does not derive from TObject.",
403 >      Warning("Notify", "Found branch '%s' where class '%s' does not derive from TObject",
404                br->GetName(), br->GetClassName());
405        continue;
406      }
# Line 272 | Line 408 | Bool_t OutputMod::Notify()
408      CheckAndAddBranch(br->GetName(), br->GetClassName());
409    }
410  
411 +  if (fCheckBrDep && !CheckAndResolveBranchDep())
412 +    return kFALSE;
413 +
414 +  RequestBranches();
415    return kTRUE;
416   }
417  
# Line 305 | Line 445 | void OutputMod::Process()
445    ++fCounter;
446  
447    // prepare for tree filling
448 <  fTreeWriter->BeginEvent(fDoReset);
448 >  if (!fTreeWriter->BeginEvent(fDoReset)) {
449 >    SendError(kAbortAnalysis, "Process", "Begin event failed!");
450 >    return;
451 >  }
452  
453    if (GetNEventsProcessed() == 0 && fCheckTamBr) {
454 <    CheckAndResolveDep(fKeepTamBr);    
454 >    CheckAndResolveTAMDep(fKeepTamBr);
455    }
456  
457    // load all our branches
# Line 323 | Line 466 | void OutputMod::Process()
466    if (fTreeWriter->GetFileNumber()!=fFileNum) {
467      fRunmap.clear();
468      fRunEntries = 0;
469 <    fL1Entries  = -1;
327 <    fHltEntries = -1;
469 >    fHltEntries = 0;
470      fFileNum = fTreeWriter->GetFileNumber();
471 +    if (fBranchTable)
472 +      fTreeWriter->StoreObject(fBranchTable);
473    }
474  
475    UInt_t runnum = GetEventHeader()->RunNum();
# Line 342 | Line 486 | void OutputMod::Process()
486    fEventHeader->SetRunNum(runnum);
487  
488    // 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 ***
489    FillAllEventHeader(kFALSE);
490  
491    // look-up if entry is in map
# Line 364 | Line 506 | void OutputMod::Process()
506    fRunmap.insert(pair<UInt_t,Int_t>(runnum,runentry));
507    fRunInfo->SetRunNum(runnum);
508  
367  Int_t l1entry = fL1Entries;
368  FillL1Info();
369  fRunInfo->SetL1Entry(l1entry);
370
509    Int_t hltentry = fHltEntries;
510    FillHltInfo();
511 <  fRunInfo->SetHltEntry(hltentry);
511 >  if (hltentry < fHltEntries)
512 >    fRunInfo->SetHltEntry(hltentry);
513 >  else
514 >    fRunInfo->SetHltEntry(hltentry-1);
515    
516    fRunTree->Fill();
517 <  
517 >
518    IncNEventsProcessed();
519 <  fTreeWriter->EndEvent(fDoReset);
519 >
520 >  if (!fTreeWriter->EndEvent(fDoReset)) {
521 >    SendError(kAbortAnalysis, "Process", "End event failed!");
522 >    return;
523 >  }
524   }
525  
526   //--------------------------------------------------------------------------------------------------
# Line 385 | Line 530 | void OutputMod::ProcessAll()
530  
531    if (GetSel()->GetCurEvt() == fLastSeenEvt)
532      return;
533 +
534    fLastSeenEvt = GetSel()->GetCurEvt();
535    ++fCounter;
536  
537 +  // prepare for tree filling
538    FillAllEventHeader(kTRUE);
539   }
540  
541   //--------------------------------------------------------------------------------------------------
542 < void OutputMod::RequestBranch(const char *bname)
542 > void OutputMod::RequestBranches()
543   {
544 <  // Request given branch from TAM.
544 >  // Loop over requested branches and request them.
545  
546 <  if (GetNBranches()>=fNBranchesMax) {
547 <    Error("RequestBranch", "Can not request branch for %bname"
548 <          "since maximum number of branches [%d] is reached", bname, fNBranchesMax);
549 <    return;
546 >  for (UInt_t i=0; i<GetNBranches(); ++i) {
547 >    if (i>=fNBranchesMax) {
548 >      SendError(kAbortAnalysis, "RequestBranches", "Cannot request branch '%s' "
549 >                "since maximum number of branches [%d] is reached",
550 >                fBrNameList.at(i).c_str(), fNBranchesMax);
551 >      return;
552 >    }
553 >    fBranches[i] = 0;
554 >    TAModule::ReqBranch(fBrNameList.at(i).c_str(), fBranches[i]);
555    }
404  
405  fBranches[GetNBranches()-1] = 0;
406  TAModule::ReqBranch(bname, fBranches[GetNBranches()-1]);
556   }
557  
558   //--------------------------------------------------------------------------------------------------
# Line 415 | Line 564 | void OutputMod::SetupBranches()
564      const char *bname = fBrNameList.at(i).c_str();
565      const char *cname = fBrClassList.at(i).c_str();
566      if (!fBranches[i]) {
567 <      Error("SetupBranches", "Pointer for branch with name %s and class %s is NULL.",
568 <            bname, cname);
567 >      SendError(kWarning, "SetupBranches",
568 >                "Pointer for branch '%s' and class '%s' is NULL", bname, cname);
569        continue;
570      }
571 <    fTreeWriter->AddBranch(bname, cname, &fBranches[i]);
571 >    Int_t bsize = fBranchSize;
572 >    TString cnamestr(cname);
573 >    if ((bsize<128*1024) && (cnamestr.Contains("mithep::MCParticle"))) {
574 >      bsize=128*1024;
575 >    } else if ((bsize<32*1024) && (cnamestr.Contains("mithep::CaloTower"))) {
576 >      bsize=32*1024;
577 >    }
578 >
579 >    fTreeWriter->AddBranch(bname, cname, &fBranches[i], bsize);
580    }
581   }
582  
# Line 453 | Line 610 | void OutputMod::SlaveBegin()
610    fLaHeader = new LAHeader;
611    tname = GetSel()->GetLATreeName();
612    fTreeWriter->AddBranchToTree(tname, GetSel()->GetLAHdrName(), &fLaHeader);
613 <  fTreeWriter->SetAutoFill(tname,0);
613 >  fTreeWriter->SetAutoFill(tname, 0);
614    fLATree = fTreeWriter->GetTree(tname);
615    fAllEventHeader = new EventHeader;
616    tname = GetSel()->GetAllEvtTreeName();
617    fTreeWriter->AddBranchToTree(tname, GetSel()->GetAllEvtHdrBrn(), &fAllEventHeader);
618    fAllTree = fTreeWriter->GetTree(tname);
619 +  fTreeWriter->SetAutoFill(tname, 0);
620  
621 <  // get pointer to fAllTreeIn todo
622 <  // todo
465 <  // deal here with published objects
466 <  // todo
621 >  // get pointer to all event headers
622 >  fSkimmedIn = GetPublicObj<EventHeaderCol>(Names::gkSkimmedHeaders);
623  
624    // create TObject space for TAM
625 <  fBranches = new TObject*[fNBranchesMax];      
625 >  fBranches = new TObject*[fNBranchesMax + fAddList.size()];      
626 >
627 >  // deal here with additional published objects
628 >  for (UInt_t i=0; i<fAddList.size(); ++i) {
629 >    TString objname(fAddList.at(i));
630 >    TObject *obj = FindPublicObj(objname);
631 >    if (obj) {
632 >      fBranches[fNBranchesMax+i] = obj;
633 >      fTreeWriter->AddBranch(objname, &fBranches[fNBranchesMax+i]);
634 >      Info("SlaveBegin", "Adding additional branch named '%s' as requested", objname.Data());
635 >    } else {
636 >      SendError(kAbortAnalysis, "SlaveBegin",
637 >                "Object named '%s' for additional branch is NULL", objname.Data());
638 >    }
639 >  }
640  
641    // adjust checks for TAM branches
642    if (fKeepTamBr)
# Line 478 | Line 648 | void OutputMod::SlaveTerminate()
648   {
649    // Terminate tree writing and do cleanup.
650  
651 +  RetractObj(Names::gkSkimmedHeaders);
652 +
653    delete fTreeWriter;
654    fTreeWriter = 0;
655  
# Line 489 | Line 661 | void OutputMod::SlaveTerminate()
661    delete[] fBranches;
662  
663    Double_t frac =  100.*GetNEventsProcessed()/fCounter;
664 <  Info("SlaveTerminate", "Stored %.2g%% events (%ld out of %ld)",
664 >  Info("SlaveTerminate", "Stored %.2f%% events (%ld out of %ld)",
665         frac, GetNEventsProcessed(), fCounter);
666   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines