HighLAND
TPCECalMatchEffSystematics.cxx
1 #include "TPCECalMatchEffSystematics.hxx"
2 #include "CutUtils.hxx"
3 #include "SystematicUtils.hxx"
4 #include "SystId.hxx"
5 #include <cmath>
6 
7 //#define DEBUG
8 
9 //********************************************************************
10 SystBoxTPCECalMatchEff::SystBoxTPCECalMatchEff(){
11 //********************************************************************
12 
13  RelevantTrueECalDetCrossed = NULL;
14 }
15 
16 //********************************************************************
17 SystBoxTPCECalMatchEff::~SystBoxTPCECalMatchEff(){
18 //********************************************************************
19 
20  if (RelevantTrueECalDetCrossed)
21  delete [] RelevantTrueECalDetCrossed;
22  RelevantTrueECalDetCrossed = NULL;
23 }
24 
25 //********************************************************************
26 TPCECalMatchEffSystematics::TPCECalMatchEffSystematics(bool comp):BinnedParams("TPCECalMatchEff",k3D_EFF_ASSYMMETRIC){
27  //********************************************************************
28 
29  _computecounters=comp;
31  if(_computecounters)
33 }
34 
35 //********************************************************************
36 void TPCECalMatchEffSystematics::InitializeEvent(const AnaEventC& event, const SelectionBase& sel, Int_t ibranch){
37 //********************************************************************
38 
39  Int_t uniqueID = 0;
40 
41 #ifdef MULTITHREAD
42  uniqueID = event.UniqueID;
43 #endif
44 
45  // Delete the SystBox when it exists and create a new one.
46  // TODO: It is probably faster to just reset the arrays
47 
48  // Get the selection index;
49  Int_t isel=sel.GetEnabledIndex();
50 
51  // Nothing to do when this box already created and filled
52  if(_systBoxes[isel][ibranch][uniqueID]) return;
53 
54  // Create the box
55  _systBoxes[isel][ibranch][uniqueID] = new SystBoxTPCECalMatchEff();
56 
57  // Fill the SystBox with the relevant tracks and true tracks tor this systematic
58  FillSystBox(event, sel, ibranch);
59 }
60 
61 //********************************************************************
62 void TPCECalMatchEffSystematics::FillSystBox(const AnaEventC& event, const SelectionBase& sel, Int_t ibranch){
63 //********************************************************************
64  //call the base method
65  EventWeightBase::FillSystBox(event, sel, ibranch);
66 
67  Int_t uniqueID = 0;
68 #ifdef MULTITHREAD
69  uniqueID = event.UniqueID;
70 #endif
71 
72  // Get the selection index;
73  Int_t isel=sel.GetEnabledIndex();
74 
75  // Get the SystBox
76  SystBoxTPCECalMatchEff& box = static_cast<SystBoxTPCECalMatchEff&>(*_systBoxes[isel][ibranch][uniqueID]);
77 
78  if (box.nRelevantTrueObjects==0) return;
79 
80  // create the array of RelevantTrueObjects
81  if (box.RelevantTrueECalDetCrossed) delete box.RelevantTrueECalDetCrossed;
82  anaUtils::CreateArray(box.RelevantTrueECalDetCrossed, box.nRelevantTrueObjects);
83 
84  // Loop over relevant true tracks
85  for (Int_t itrk=0; itrk<box.nRelevantTrueObjects; itrk++){
86 
87  AnaTrueParticleB* trueTrack = static_cast<AnaTrueParticleB*>(box.RelevantTrueObjects[itrk]);
88  box.RelevantTrueECalDetCrossed[itrk] = SubDetId::kInvalid;
89 
90  if (!trueTrack) continue;
91  SubDetId::SubDetEnum det[10];
92 
93  int ndet = anaUtils::GetECalDetCrossed(trueTrack, det);
94  if (ndet<1) continue;
95  box.RelevantTrueECalDetCrossed[itrk] = det[0];
96  }
97 }
98 
99 
100 
101 //********************************************************************
103  //********************************************************************
104 
105 
106  if(_computecounters)
108 
109  (void)event;
110 
111  // Get the SystBox for this event, and the appropriate selection and branch
113 
114 
115  Weight_h eventWeight = 1.;
116 
117 #ifdef DEBUG
118  std::cout << "TPCECalMatchEffSystematics::Apply(): " << SystBox->nRelevantTrueObjects<< std::endl;
119 #endif
120 
121  // Loop over relevant true tracks
122  for (Int_t itrk=0;itrk<SystBox->nRelevantTrueObjects;itrk++){
123 
124  AnaTrueParticleB* truePart = static_cast<AnaTrueParticleB*>(SystBox->RelevantTrueObjects[itrk]);
125 
126  AnaTrackB* recoTrack = static_cast<AnaTrackB*>(SystBox->RelevantTrueObjectsReco[itrk]);
127 
128  if (!truePart || !recoTrack) continue;
129 
130  // Do fine-tuning of the track relevance via the selection
131  if (!sel.IsRelevantTrueObjectForSystematicInToy(event, box, truePart, SystId::kTpcECalMatchEff, box.SuccessfulBranch)) continue;
132 
133 
134  //get relevant ECal detector crossed
135  SubDetId::SubDetEnum ecal_det = SystBox->RelevantTrueECalDetCrossed[itrk];
136 
137  if (ecal_det==SubDetId::kInvalid) continue;
138 
139  // Get TPC closest to the stopping point (may be should also do at box filling level)
140  AnaTPCParticleB* tpcTrack = static_cast<AnaTPCParticleB*>(anaUtils::GetSegmentWithMostNodesInClosestTpc(*recoTrack, truePart->PositionEnd));
141 
142  if (!tpcTrack) continue;
143 
144  BinnedParamsParams params;
145  int index;
146 
147  int pdg = truePart->PDG;
148 
149  // Pions are treated as muons for the moment
150  if(pdg == 211)
151  pdg = 13;
152  else if(pdg == -211)
153  pdg = -13;
154  // One bin for electron
155  else if(pdg == -11)
156  pdg = 11;
157  // One bin for protons
158  else if(pdg == -2212)
159  pdg = 2212;
160 
161  if (!GetBinValues(pdg, ecal_det, tpcTrack->Momentum, params, index)) continue;
162 
163  // Now check detector bits
164  bool found = SubDetId::GetDetectorUsed(recoTrack->Detector, ecal_det);
165 
166 #if useNewWeights
167  eventWeight *= systUtils::ComputeEffLikeWeight(found, toy.GetToyVariations(_index)->Variations[index], params); // New way including data-mc diff
168 #else
169  eventWeight *= systUtils::ComputeEffLikeWeight(found, toy.GetToyVariations(_index)->Variations[2*index],
170  toy.GetToyVariations(_index)->Variations[2*index+1], params);
171 #endif
172 
173 
174 #ifdef DEBUG
175  std::cout<<"tpc-ecal found "<< found<<" eventWeight "<<eventWeight<<std::endl;
176 #endif
177 
178  if(_computecounters)
179  UpdateEfficiencyCounter(index,found);
180 
181  }
182 
183  return eventWeight;
184 }
185 
186 //********************************************************************
188  //********************************************************************
189 
190  (void)event;
191 
192  //this is tricky, a track should have a potential to be reconstructed in ECal, hence probably enough momentum on entrance point
193  //this can be PID dependent
194 
195  //for the moment just require a point of interest
196 
197  //a track should cross only one ECal sub-detector: these are the ones we want for analysis
198  SubDetId::SubDetEnum det[20];
199 
200  int necal_det = anaUtils::GetECalDetCrossed(static_cast<const AnaTrueParticleB*>(&track), det);
201 
202  if(necal_det!=1) return false;
203 
204  if (SubDetId::IsTECALDetector(det[0]) || det[0] == SubDetId::kDSECAL)
205  return true;
206 
207  return false;
208 
209 }
210 
211 //**************************************************
213  //**************************************************
214 
215  (void)event;
216 
217  //should use TPC: probably good quality as well?
218  if (!cutUtils::TrackQualityCut(*static_cast<const AnaTrackB*>(&track))) return false;
219  return true;
220 }
221 
222 //********************************************************************
223 Int_t TPCECalMatchEffSystematics::GetRelevantRecObjectGroups(const SelectionBase& sel, Int_t ibranch, Int_t* IDs) const{
224  //********************************************************************
225 
226  SubDetId_h det = sel.GetDetectorFV(ibranch);
227 
228  if (det == SubDetId::kFGD1){
229  IDs[0] = EventBoxTracker::kTracksWithTPCAndFGD1;
230  return 1;
231  }
232  else if (det == SubDetId::kFGD2){
233  IDs[0] = EventBoxTracker::kTracksWithTPCAndFGD2;
234  return 1;
235  }
236  else if (det == SubDetId::kFGD){
237  IDs[0] = EventBoxTracker::kTracksWithTPCAndFGD1;
238  IDs[1] = EventBoxTracker::kTracksWithTPCAndFGD2;
239  return 2;
240  }
241 
242  return 0;
243 
244 }
245 
246 //********************************************************************
247 Int_t TPCECalMatchEffSystematics::GetRelevantTrueObjectGroups(const SelectionBase& sel, Int_t ibranch, Int_t* IDs) const{
248  //********************************************************************
249 
250  (void)sel;
251  (void)ibranch;
252 
253  IDs[0] = EventBoxTracker::kTrueParticlesChargedInTPCInBunch;
254 
255  return 1;
256 }
Int_t _index
The index of this systematic (needed by SystematicsManager);.
unsigned long Detector
Float_t * Variations
the vector of Variations, one for each of the systematic parameters
int GetECalDetCrossed(const AnaTrueParticleB *track, SubDetId::SubDetEnum det[])
ECal detectors crossed: split based on geom info PECal and TECal sub-detectors, this may not be very ...
Definition: TruthUtils.cxx:315
Int_t SelectionEnabledIndex
The enabled index of this selection this ToyBox belongs to.
Definition: ToyBoxB.hxx:49
bool IsRelevantRecObject(const AnaEventC &event, const AnaRecObjectC &track) const
Is this track relevant for this systematic ?
SystBoxB * GetSystBox(const AnaEventC &event, Int_t isel=0, Int_t ibranch=0) const
Get the SystBox corresponding to a selection, branch and event.
void SetNParameters(int N)
Set the number of systematic parameters associated to this systematic.
Int_t GetRelevantRecObjectGroups(const SelectionBase &sel, Int_t ibranch, Int_t *IDs) const
Get the TrackGroup IDs array for this systematic.
static bool GetDetectorUsed(unsigned long BitField, SubDetId::SubDetEnum det)
Method to see if a certain subdetector or subdetector system is used.
Definition: SubDetId.cxx:40
Weight_h ComputeWeight(const ToyExperiment &, const AnaEventC &, const ToyBoxB &)
Apply the systematic.
bool GetBinValues(Float_t value, Float_t &mean, Float_t &sigma)
Gets the bin values for a 1D source.
bool UpdateEfficiencyCounter(Int_t index, bool correct)
Update the efficiency variables _ncorrect and _nwrong.
Float_t Momentum
The reconstructed momentum of the particle, at the start position.
virtual void FillSystBox(const AnaEventC &event, const SelectionBase &sel, Int_t ibranch)
Fills the SystBox.
Representation of a true Monte Carlo trajectory/particle.
Int_t SuccessfulBranch
The branch that is successful for this toy in the selection this ToyBox belongs to.
Definition: ToyBoxB.hxx:46
SubDetEnum
Enumeration of all detector systems and subdetectors.
Definition: SubDetId.hxx:25
Int_t PDG
The PDG code of this particle.
virtual void InitializeEvent(const AnaEventC &event, const SelectionBase &sel, Int_t ibranch)
Initialize the SystBox for this event.
Representation of a global track.
Int_t nRelevantTrueObjects
Array of Relevant True RecObjects for each systematic.
Definition: SystBoxB.hxx:24
static bool IsTECALDetector(SubDetId::SubDetEnum det)
Check if a detector enumeration refers to a Tracker ECAL or not.
Definition: SubDetId.cxx:134
Representation of a TPC segment of a global track.
bool IsRelevantTrueObject(const AnaEventC &event, const AnaTrueObjectC &track) const
Is this track relevant for this systematic ?
ToyVariations * GetToyVariations(UInt_t index) const
returns the variations for a given systematic (index)
AnaRecObjectC ** RelevantTrueObjectsReco
Definition: SystBoxB.hxx:29
Int_t GetRelevantTrueObjectGroups(const SelectionBase &sel, Int_t ibranch, Int_t *IDs) const
Get the TrueTrackGroup IDs array for this systematic.
Float_t PositionEnd[4]
The end position of the true particle.
void InitializeEfficiencyCounter()
Initialize counters.
AnaParticleB * GetSegmentWithMostNodesInClosestTpc(const AnaTrackB &track)
Combined function to address NuMu selection needs as efficiently as possible - gets the TPC segment w...
virtual bool IsRelevantTrueObjectForSystematicInToy(const AnaEventC &, const ToyBoxB &, AnaTrueObjectC *, SystId_h syst_index, Int_t branch=0) const
Is this true track relevant for a given systematic (after selection, called for each toy) ...
SystBoxB **** _systBoxes
----—— Relevant objects for this systematic ------------——
void FillSystBox(const AnaEventC &event, const SelectionBase &sel, Int_t ibranch)
Fills the SystBox.
Int_t GetNBins()
Get the number of bins.
SubDetId_h GetDetectorFV(Int_t ibranch=0) const
Get the detector in which the Fiducial Volume is defined.
Int_t GetEnabledIndex() const
Get the Selection index.