HighLAND
SIProtonSystematics.cxx
1 #include "SIProtonSystematics.hxx"
2 #include "ND280AnalysisUtils.hxx"
3 #include "MultiThread.hxx"
4 #include "SystId.hxx"
5 
6 //#define DEBUG
7 
8 //********************************************************************
9 SIProtonSystematics::SIProtonSystematics():EventWeightBase(1),BinnedParams("ProtonSI",k1D_SYMMETRIC){
10  //********************************************************************
11 
13 
14  // Get the systematic source values
15  GetParametersForBin(0, _xsecScale, _xsecError);
16 
17  _ProtonInteractionsInfo = NULL;
18 }
19 
20 //********************************************************************
21 SIProtonSystematics::~SIProtonSystematics(){
22  //********************************************************************
23 
24  if (_ProtonInteractionsInfo){
25  for (Int_t k= 0; k<_nevents; k++){
26  if(_ProtonInteractionsInfo[k])
27  delete _ProtonInteractionsInfo[k];
28  _ProtonInteractionsInfo[k] =NULL;
29  }
30  }
31 
32  delete [] _ProtonInteractionsInfo;
33 
34 }
35 
36 //********************************************************************
38  const ToyBoxB& box, const SelectionBase& sel){
39  //********************************************************************
40 
41  (void)box;
42 
43  Weight_h eventWeightFinal;
44 
45  Float_t eventWeight = 1.;
46 
47  Float_t totalReWeight = 1.;
48 
49  Int_t uniqueID = 0;
50 
51 #ifdef MULTITHREAD
52  uniqueID = event.UniqueID;
53 #else
54  (void)event;
55 #endif
56 
57  // Retrieve the proton secondary interaction information for the event
58  si_syst::SISystInput& protonSI = *_ProtonInteractionsInfo[uniqueID];
59 
60 #ifdef DEBUG
61  std::cout << " ===== " << std::endl;
62  std::cout << " SIProtonSystematics::Apply" << std::endl;
63  std::cout << "nProtons = " << protonSI.nParticles << std::endl;
64 #endif
65 
66  // Only bother doing anything if there is at least one proton in the event.
67  if (protonSI.nParticles == 0) return eventWeight;
68 
69  // Loop over the protons
70  for (int i = 0; i < protonSI.nParticles; i++){
71 
72 
73  // Weight for survivial probability
74  Float_t survWeight_tmp = 0.;
75 
76  // Weight for interactions
77  Float_t intWeight_tmp = 1.;
78 
79  // Fine-tuning on whether a track is relevant for the selection
80  if (!sel.IsRelevantTrueObjectForSystematicInToy(event, box, const_cast<AnaTrueParticleB*>(protonSI.Particles[i].trueTrack),
81  SystId::kSIProton, box.SuccessfulBranch)){
82 
83 #ifdef DEBUG
84  std::cout << " Not relevant object " << std::endl;
85 #endif
86  continue;
87 
88 
89  }
90 
91 
92  // Start with survival probability, consider the steps available for each proton
93 
94  size_t nSteps = protonSI.Particles[i].propSteps.size();
95 
96 #ifdef DEBUG
97  std::cout << "nSteps = " << nSteps << std::endl;
98 #endif
99 
100  for (size_t ns = 0; ns < nSteps; ns++){
101  // For each step loop over the interactions
102  size_t nInts = protonSI.Particles[i].propSteps[ns].size();
103  for (size_t nint = 0; nint < nInts; nint++){
104  // Get the variation index depending on particle and interaction type -->ToDo
105  // ToDo: add interaction type into the cross-section data
106  Float_t xsec_tmp = protonSI.Particles[i].propSteps[ns][nint].XSec +
107  protonSI.Particles[i].propSteps[ns][nint].XSecErr * toy.GetToyVariations(_index)->Variations[0];
108  survWeight_tmp += std::max<Double_t>(xsec_tmp, 0.) -
109  protonSI.Particles[i].propSteps[ns][nint].XSec;
110  }
111  }
112 
113 
114  // Get the variation index depending on particle and interaction type
115  Float_t var = toy.GetToyVariations(_index)->Variations[0]; // one for the moment
116 
117  intWeight_tmp *= 1 + protonSI.Particles[i].XSecData.XSecErr * var;
118 
119  totalReWeight *= protonSI.Particles[i].Weight;
120 
121 #ifdef DEBUG
122  std::cout << " ===== Particle weight ===== " << std::endl;
123  std::cout << "survWeight \t= " << survWeight_tmp << std::endl;
124  std::cout << "exp(-survWeight) \t= " << exp(-survWeight_tmp) << std::endl;
125  std::cout << "intWeight \t= " << intWeight_tmp << std::endl;
126  std::cout << "ReWeight \t= " << protonSI.Particles[i].Weight << std::endl;
127  std::cout << " ========== " << std::endl;
128 #endif
129 
130  Float_t factor = exp(-survWeight_tmp) * intWeight_tmp;
131  if (factor == 0 || !TMath::Finite(factor) || factor != factor)
132  factor = 1.;
133 
134  eventWeight *= factor;
135 
136  }//loop over protons
137 
138 #ifdef DEBUG
139  std::cout << " ===== Total weight ===== " << std::endl;
140  std::cout << " eventWeight \t= " << eventWeight << std::endl;
141  std::cout << " totalReWeight \t= " << totalReWeight << std::endl;
142  std::cout << " ========== " << std::endl;
143 #endif
144 
145 
146 
147  if (eventWeight == 0 || !TMath::Finite(eventWeight) || eventWeight != eventWeight)
148  eventWeight = 1.;
149 
150 #ifdef DEBUG
151  std::cout << " eventWeight \t= " << eventWeight << std::endl;
152  std::cout << " totalReWeight \t= " << totalReWeight << std::endl;
153  std::cout << " finalWeightt \t= " << totalReWeight * eventWeight << std::endl;
154  std::cout << " ===== " << std::endl;
155 #endif
156 
157 
158  eventWeightFinal.Correction = totalReWeight;
159  eventWeightFinal.Systematic = totalReWeight * eventWeight;
160 
161 
162  return eventWeightFinal;
163 
164 }
165 
166 
167 //********************************************************************
168 void SIProtonSystematics::FillSystBox(const AnaEventC& eventC, const SelectionBase& sel, Int_t ibranch){
169  //********************************************************************
170 
171  Int_t uniqueID = 0;
172 #ifdef MULTITHREAD
173  uniqueID = eventC.UniqueID;
174 #endif
175 
176  const AnaEventB& event = *static_cast<const AnaEventB*>(&eventC);
177 
178  // TODO:Need a better way of doing this
179  AnaTrueParticleB* allTrajInBunch[NMAXTRUEPARTICLES];
180  int count = 0;
181  count = anaUtils::GetAllTrajInBunch(event, allTrajInBunch);
182  if((UInt_t)count > NMAXTRUEPARTICLES) count = NMAXTRUEPARTICLES;
183 
184  // Compute Proton weight info needed by ProtonSISystematics (TODO, only when this systematic is enabled)
185  // if (ProtonWeightInfo) delete ProtonWeightInfo;
186 
187  _ProtonInteractionsInfo[uniqueID] = _pInfoManager.CollectParticleInteractions(allTrajInBunch, count,
188  static_cast<SubDetId::SubDetEnum>(sel.GetDetectorFV(ibranch)));
189 
190 }
191 
192 //********************************************************************
193 void SIProtonSystematics::Initialize(Int_t nsel, Int_t isel, Int_t nbranches, Int_t nevents){
194  //********************************************************************
195 
196  // TODO: This is a temporary solution to make this work with multithreading. Instead we would need a derived SystBox
197 
198  // Although the SystBox is actually not used we need to create it because SystematicBase::InitializeEvent uses it
199  EventWeightBase::Initialize(nsel,isel,nbranches,nevents);
200 
201  // Since this is called for several selections use for the moment a single one for all selections
202  if (_ProtonInteractionsInfo) return;
203 
204 #ifndef MULTITHREAD
205  nevents=1;
206 #endif
207 
208  _ProtonInteractionsInfo = new si_syst::SISystInput*[nevents];
209  _nevents = nevents;
210  for (Int_t k = 0; k < nevents; k++)
211  _ProtonInteractionsInfo[k] = NULL;
212 
213 }
214 
215 
216 //********************************************************************
218  //********************************************************************
219 
220  // TODO: This is a temporary solution to make this work with multithreading. Instead we would need a derived SystBox
221 
222  // Although the SystBox is actually not used we need to create it because SystematicBase::FinalizeEvent uses it
224 
225  Int_t uniqueID = 0;
226 #ifdef MULTITHREAD
227  uniqueID = event.UniqueID;
228 #endif
229 
230  if (_ProtonInteractionsInfo[uniqueID])
231  delete _ProtonInteractionsInfo[uniqueID];
232  _ProtonInteractionsInfo[uniqueID] = NULL;
233 
234 }
Int_t _index
The index of this systematic (needed by SystematicsManager);.
Float_t * Variations
the vector of Variations, one for each of the systematic parameters
void FillSystBox(const AnaEventC &event, const SelectionBase &sel, Int_t ibranch)
Fill the SystBox for this event, selection and branch.
void FinalizeEvent(const AnaEventC &event)
Delete the ProtonInteractionSystematic for this event.
void Initialize(Int_t nsel, Int_t isel, Int_t nbranch, Int_t nevents)
Create the array of ProtonInteractionSystematic.
int GetAllTrajInBunch(const AnaEventB &event, AnaTrueParticleB *traj[])
Definition: SubDetUtils.cxx:12
void SetNParameters(int N)
Set the number of systematic parameters associated to this systematic.
si_syst::SIXSecData XSecData
Store both the cross-section and error.
virtual void Initialize(Int_t nsel, Int_t isel, Int_t nbranch, Int_t nevents)
Create the array of SystBox.
virtual void FinalizeEvent(const AnaEventC &event)
Delete the SystBox for this event.
Representation of a true Monte Carlo trajectory/particle.
Int_t UniqueID
The event unique ID.
Int_t SuccessfulBranch
The branch that is successful for this toy in the selection this ToyBox belongs to.
Definition: ToyBoxB.hxx:46
Float_t Weight
Weight for this particle, to be applied to correspond to a reference cross-section.
const AnaTrueParticleB * trueTrack
A pointer to the original true track.
ToyVariations * GetToyVariations(UInt_t index) const
returns the variations for a given systematic (index)
std::vector< StepInfo > propSteps
Vector of steps considered with the corresponding info.
A simple class to provide the data for the systematic itself: a collection of particles with the rele...
bool GetParametersForBin(Int_t index, Float_t &mean, Float_t &sigma)
Gets the bin values for a source provided the bin index.
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) ...
Weight_h ComputeWeight(const ToyExperiment &, const AnaEventC &, const ToyBoxB &)
Apply the systematic.
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.