Crombie Tools
CorrectorApplicator.cc
Go to the documentation of this file.
1 /**
2  @file CorrectorApplicator.cc
3  Defines functions in the CorrectorApplicator class.
4  @author Daniel Abercrombie <dabercro@mit.edu>
5 */
6 
7 #include <iostream>
8 #include <map>
9 
10 #include "TFile.h"
11 #include "TTree.h"
12 #include "TBranch.h"
13 #include "TMath.h"
14 
15 #include "CorrectorApplicator.h"
16 
18 
19 //--------------------------------------------------------------------
20 CorrectorApplicator::CorrectorApplicator(TString name, Bool_t saveAll) :
21  fName(name),
22  fSaveAll(saveAll)
23 { }
24 
25 //--------------------------------------------------------------------
27 { }
28 
29 //--------------------------------------------------------------------
30 
31 /**
32  Applies all of the Corrector objects to the input fileName.
33  The file name does not have to be an absolute path if fInDirectory is set.
34  Each unique name of the Corrector objects creates a new branch
35  if fSaveAll is true. If multiple correctors have the same name,
36  then the result of that branch is the product of the correctors.
37  A product of all Corrector object results and any branches labelled
38  to be merged are stored in a branch called fName.
39 */
40 
42 {
43  SetReportFile(fileName);
44  TFile* theFile = new TFile(AddInDir(fileName),"UPDATE");
45  TTree* theTree = (TTree*) theFile->Get(fInputTreeName);
46  TTree* outTree;
47  // If the input and output trees are the same, check if branches already exist
49  if (fName != "") {
50  if (theTree->GetBranch(fName)) {
51  std::cout << "Branch " << fName << " already exists in " << fileName << std::endl;
52  theFile->Close();
53  exit(0);
54  }
55  }
56  if (fSaveAll) {
57  for (UInt_t iCorrector = 0; iCorrector != fCorrectors.size(); ++iCorrector) {
58  if (theTree->GetBranch(fCorrectors[iCorrector]->GetName())) {
59  std::cout << "Branch " << fCorrectors[iCorrector]->GetName() << " already exists in " << fileName << std::endl;
60  theFile->Close();
61  exit(0);
62  }
63  if (fCorrectors[iCorrector]->GetName() == fName) {
64  std::cout << "Corrector has same name as merged name: " << fName << std::endl;
65  theFile->Close();
66  exit(0);
67  }
68  }
69  }
70  // If the branches don't exist, everything is good to go
71  outTree = theTree;
72  }
73  else
74  outTree = new TTree(fOutputTreeName,fOutputTreeName);
75 
76  // Now set the correctors and make branches for them
77  std::vector<TBranch*> fillBranches;
78  std::map<TString, Float_t> Addresses;
79  if (fName != "") {
80  if (fIsUncertainty)
81  Addresses[fName] = 0.0;
82  else
83  Addresses[fName] = 1.0;
84  fillBranches.push_back(outTree->Branch(fName, &(Addresses[fName]), fName + "/F"));
85  }
86  for (auto iCorrector : fCorrectors) {
87  iCorrector->CompareFileName(fileName);
88  iCorrector->SetInTree(theTree);
89  if (fSaveAll) {
90  TString checkName = iCorrector->GetName();
91  if (!outTree->GetBranch(checkName)) {
92  Addresses[checkName] = 1.0;
93  fillBranches.push_back(outTree->Branch(checkName, &(Addresses[checkName]), checkName + "/F"));
94  }
95  }
96  }
97 
98  // Get the addresses of factors to merge (will be just a branch)
99  std::map<TString,Float_t> mergeFactors;
100  for (UInt_t iMerge = 0; iMerge != fMergeFactors.size(); ++iMerge) {
101  mergeFactors[fMergeFactors[iMerge]] = 1.0;
102  theTree->SetBranchAddress(fMergeFactors[iMerge],&(mergeFactors[fMergeFactors[iMerge]]));
103  }
104 
105  // Now loop through the tree and apply the corrections
106  Long64_t nentries = SetNumberOfEntries(theTree);
107  Float_t tempValue = 1.0;
108  for (Long64_t iEntry = 0; iEntry != nentries; ++iEntry) {
109  ReportProgress(iEntry);
110 
111  theTree->GetEntry(iEntry);
112  // First reset all of the addressed floats, merge factors for master factor
113  if (fName != "") {
114  if (fIsUncertainty) {
115  Addresses[fName] = 0.0;
116  for (UInt_t iMerge = 0; iMerge != fMergeFactors.size(); ++iMerge)
117  Addresses[fName] += mergeFactors[fMergeFactors[iMerge]] *
118  mergeFactors[fMergeFactors[iMerge]];
119 
120  }
121  else {
122  Addresses[fName] = 1.0;
123  for (UInt_t iMerge = 0; iMerge != fMergeFactors.size(); ++iMerge)
124  Addresses[fName] *= mergeFactors[fMergeFactors[iMerge]];
125  }
126  }
127  if (fSaveAll) {
128  for (UInt_t iCorrector = 0; iCorrector != fCorrectors.size(); ++iCorrector)
129  Addresses[fCorrectors[iCorrector]->GetName()] = 1.0;
130  }
131 
132  // Evaluate the correctors and save the factor values
133  for (UInt_t iCorrector = 0; iCorrector != fCorrectors.size(); ++iCorrector) {
134  tempValue = fCorrectors[iCorrector]->Evaluate();
135  if (fName != "" && fCorrectors[iCorrector]->Merge) {
136  if (fIsUncertainty)
137  Addresses[fName] += tempValue * tempValue;
138  else
139  Addresses[fName] *= tempValue;
140  }
141  if (fSaveAll)
142  Addresses[fCorrectors[iCorrector]->GetName()] *= tempValue;
143  }
144 
145  if (fIsUncertainty)
146  Addresses[fName] = TMath::Sqrt(Addresses[fName]);
147 
148  // Fill all the branches
150  for (UInt_t iBranch = 0; iBranch != fillBranches.size(); ++iBranch)
151  fillBranches[iBranch]->Fill();
152  }
153  else
154  outTree->Fill();
155  }
156 
157  theFile->cd();
159  outTree->Write();
160  else
161  outTree->Write(fOutputTreeName,TObject::kOverwrite);
162  theFile->Close();
163 
164 }
165 
166 //--------------------------------------------------------------------
168 {
169  CorrectorApplicator *newCorrectorApplicator = new CorrectorApplicator();
170  *newCorrectorApplicator = *this;
171  for (UInt_t iCorrector = 0; iCorrector != this->fCorrectors.size(); ++iCorrector)
172  newCorrectorApplicator->fCorrectors[iCorrector] = this->fCorrectors[iCorrector]->Copy();
173  return newCorrectorApplicator;
174 }