HighLAND
ECalEMEnergyResolSystematics.cxx
1 #include "ECalEMEnergyResolSystematics.hxx"
2 #include "ND280AnalysisUtils.hxx"
3 #include "HEPConstants.hxx"
4 #include "Parameters.hxx"
5 #include "TRandom3.h"
6 
7 
8 //#define DEBUG
9 //#define TRUECROSS
10 
11 //********************************************************************
12 SystBoxECalEMResol::SystBoxECalEMResol(){
13 //********************************************************************
14 
15  RelevantCrossings = NULL;
16 }
17 
18 //********************************************************************
19 SystBoxECalEMResol::~SystBoxECalEMResol(){
20 //********************************************************************
21 
22  if (RelevantCrossings)
23  delete [] RelevantCrossings;
24  RelevantCrossings = NULL;
25 }
26 
27 
28 //********************************************************************
29 ECalEMEnergyResolSystematics::~ECalEMEnergyResolSystematics() {
30 //********************************************************************
31  if (_RandomGenerator)
32  delete _RandomGenerator;
33 }
34 
35 //********************************************************************
37 //********************************************************************
38  if (!_RandomGenerator){
39  _RandomGenerator = new TRandom3();
40  SetRandomSeed(ND::params().GetParameterI("psycheSystematics.ECalEMResol.RandomSeed"));
41  }
42 }
43 
44 //********************************************************************
46 //********************************************************************
47  if (_RandomGenerator)
48  return _RandomGenerator->GetSeed();
49  return 0XDEADBEEF;
50 }
51 
52 //********************************************************************
54 //********************************************************************
55  if (_RandomGenerator)
56  _RandomGenerator->SetSeed(seed);
57 }
58 
59 //********************************************************************
61 //********************************************************************
62 
63  Int_t uniqueID = 0;
64 
65 #ifdef MULTITHREAD
66  uniqueID = event.UniqueID;
67 #endif
68 
69  // Delete the SystBox when it exists and create a new one.
70  // TODO: It is probably faster to just reset the arrays
71 
72  // Create the box
73  if(!_systBoxes[0][0][uniqueID])
74  _systBoxes[0][0][uniqueID] = new SystBoxECalEMResol();
75 
76  // Fill the SystBox with the relevant tracks and true tracks tor this systematic
77  FillSystBox(event, sel, *_systBoxes[0][0][uniqueID]);
78 }
79 
80 //********************************************************************
82 //********************************************************************
83 
84  Int_t uniqueID = 0;
85 
86 #ifdef MULTITHREAD
87  uniqueID = event.UniqueID;
88 #else
89  (void)event;
90 #endif
91 
92 #ifndef TRUECROSS
94 #endif
95 
96  SystBoxECalEMResol& box = static_cast<SystBoxECalEMResol&>(*(_systBoxes[0][0][uniqueID]));
97  int ntracks = box.RelevantRecObjectsSet.size();
98  if (box.RelevantRecObjects) delete [] box.RelevantRecObjects;
99  if (box.RelevantCrossings) delete [] box.RelevantCrossings;
100  anaUtils::CreateArray(box.RelevantRecObjects, ntracks);
101  anaUtils::CreateArray(box.RelevantCrossings, ntracks);
102 
103  box.nRelevantRecObjects=0;
104  for (std::set<AnaRecObjectC*>::iterator it = box.RelevantRecObjectsSet.begin();it!=box.RelevantRecObjectsSet.end();it++){
105  box.RelevantRecObjects[box.nRelevantRecObjects] = *it;
106 
107 
108  AnaDetCrossingB* cross = NULL;
109 
110  // get true track
111  // TODO!!: should be careful here, may work ok for ecal-tracker tracks, but for iso ones and showers, true track should be
112  // retrieved in another way
113  AnaTrueParticleB* trueTrack = static_cast<AnaTrueParticleB*>((*it)->TrueObject);
114 
115  if (trueTrack){
116  //get detector crossing in ECal
117  for (int i=0; i<trueTrack->nDetCrossings; i++){
118  AnaDetCrossingB* cross_tmp = trueTrack->DetCrossings[i];
119  if (!cross_tmp) continue;
120  if (((cross_tmp->Detector & (1<<SubDetId::kTECAL)) || (cross_tmp->Detector & (1<<SubDetId::kDSECAL))) &&
121  cross_tmp->InActive){
122  cross = cross_tmp;
123  break;
124  }
125  }
126  } //trueTrack
127 
128  box.RelevantCrossings[box.nRelevantRecObjects] = cross;
129 
130  box.nRelevantRecObjects++;
131 
132  }
133 
134 }
135 
136 //********************************************************************
138  //********************************************************************
139 
140  // Get the SystBox for this event
141  SystBoxB* box = GetSystBox(event);
142 
143 #ifdef DEBUG
144  std::cout << "ECalEMEnergyResolSystematics::ApplyVariation(): " << box->nRelevantRecObjects << std::endl;
145 #endif
146 
147  // Loop over relevant tracks for this systematic
148  for (Int_t itrk=0;itrk<box->nRelevantRecObjects;itrk++){
149 
150  AnaTrackB* track = static_cast<AnaTrackB*>(box->RelevantRecObjects[itrk]);
151 
152  if (!track) continue;
153 
154  AnaECALParticleB* ecalTrack = track->ECALSegments[0];
155 
156 #ifdef TRUECROSS
157 
158  //should have true track
159  if(!track->TrueObject) continue;
160 
161 
162  //should have valid ECal crossing
163  AnaDetCrossingB* cross = static_cast<SystBoxECalEM*>(box)->RelevantCrossings[itrk];
164  if (!cross) continue;
165 
166 # ifdef DEBUG
167  std::cout << itrk << std::endl;
168  track->Print();
169  std::cout<<"\n"<<std::endl;
170  track->TrueObject->Print();
171 
172 # endif
173 
174  // Get the true energy loss
175  // For the momentum assume the true track stops in ECal: ToDo (collect info from all track and its daughters` chain?)
176  Float_t p0_true_entrance = anaUtils::ArrayToTVector3(cross->EntranceMomentum).Mag();
177  // Float_t p0_true_exit2 = anaUtils::ArrayToTVector3(cross->ExitMomentum).Mag2();
178 
179 
180  //Get mass
181  Float_t mass = 0.;
182 
183  TParticlePDG* particle = units::pdgBase->GetParticle(track->GetTrueParticle()->PDG);
184 
185  if (particle)
186  mass = particle->Mass()*units::GeV;
187 
188  Float_t em0_true = sqrt(p0_true_entrance*p0_true_entrance + mass*mass) - mass;
189 
190 
191 # ifdef DEBUG
192  std::cout << "track true mom entrance in ECal -- " << anaUtils::ArrayToTVector3(cross->EntranceMomentum).Mag() << std::endl;
193  std::cout << "track true mom exit in ECal -- " << anaUtils::ArrayToTVector3(cross->ExitMomentum).Mag() << std::endl;
194  std::cout << "track true mass -- " << mass << std::endl;
195  std::cout << "track true eloss in ECal -- " << em0_true << std::endl;
196 # endif
197 
198 #endif
199 
200  // Get reco value
201  Float_t em0 = ecalTrack->EMEnergy;
202 
203 #ifdef DEBUG
204  std::cout << "ecal track EM Energy -- " << em0 << std::endl;
205 #endif
206 
207  // Get the extra resolution values: bins are defined by EM energy
208  Float_t sigma;
209  Int_t index;
210 
211  if (!GetBinSigmaValue(em0, sigma, index)) continue;
212 
213 #ifdef DEBUG
214  std::cout << " bin values: sigma " << sigma << " index " << index << std::endl;
215 #endif
216 
217 
218 #ifdef TRUECROSS
219  // Apply the additional resolution smearing, ie smear around mean with a sigma=x
220  Float_t emv = (1 + sigma*toy.GetToyVariations(_index)->Variations[index])*(em0 - em0_true) + em0_true;
221 #else
222  //Note one will have to take care of meaning of the parameters
223  // Apply the additional resolution smearing with a gaussian throw
224  Float_t emv = em0 + _RandomGenerator->Gaus(0., (sigma*toy.GetToyVariations(_index)->Variations[index])*em0);
225 
226 #endif
227 
228 
229 #ifdef DEBUG
230  std::cout << "candidate EM Energy after tweak = "<< emv << std::endl;
231 #endif
232 
233  // Apply the variation
234  ecalTrack->EMEnergy = emv;
235  }
236 
237 }
238 
bool InActive
If the particle passes through an active part of the subdetector.
Float_t * Variations
the vector of Variations, one for each of the systematic parameters
unsigned long Detector
int nDetCrossings
The number of DetCrossing objects.
AnaECALParticleB * ECALSegments[NMAXECALS]
The ECAL segments that contributed to this global track.
Representation of an ECAL segment of a global track.
virtual void Print() const
Dump the object to screen.
UInt_t GetRandomSeed() const
The only thing we allow for the generator is to get the seed.
AnaTrueObjectC * TrueObject
The link to the true oject that most likely generated this reconstructed object.
virtual void InitializeEvent(const AnaEventC &event, const SelectionBase &sel)
Initialize the SystBox for this event.
void InitializeRandomGenerator()
Initialze random generator.
Representation of a true Monte Carlo trajectory/particle.
void SetRandomSeed(UInt_t seed)
And change the seed.
AnaDetCrossingB ** DetCrossings
Representation of a detector crossing info for a true particle (G4 trajectory).
Int_t PDG
The PDG code of this particle.
std::set< AnaRecObjectC * > RelevantRecObjectsSet
Definition: SystBoxB.hxx:33
Representation of a global track.
Float_t ExitMomentum[3]
for each subdetector tell the exit momentum
ToyVariations * GetToyVariations(UInt_t index) const
returns the variations for a given systematic (index)
void InitializeEvent(const AnaEventC &event, const SelectionBase &sel)
Initialize the SystBox for this event.
Int_t nRelevantRecObjects
----—— Relevant rec objects and true objects for each systematic ------------—— ...
Definition: SystBoxB.hxx:20
AnaTrueParticleB * GetTrueParticle() const
Return a casted version of the AnaTrueObject associated.
void Print() const
Dump the object to screen.
virtual void Apply(const ToyExperiment &toy, AnaEventC &event)
Apply the systematic.
Float_t EntranceMomentum[3]
for each subdetector tell the entrance momentum