HighLAND
ChargeIDEffSystematics.cxx
1 #include "ChargeIDEffSystematics.hxx"
2 #include "ND280AnalysisUtils.hxx"
3 #include "CutUtils.hxx"
4 #include "SystematicUtils.hxx"
5 #include "VersioningUtils.hxx"
6 #include "MultiThread.hxx"
7 #include "SystId.hxx"
8 #include "EventBoxId.hxx"
9 #include "Parameters.hxx"
10 
11 
12 //********************************************************************
13 ChargeIDEffSystematics::ChargeIDEffSystematics(bool comp):EventWeightBase(2){
14  //********************************************************************
15  _computecounters=comp;
16 
17  _globalCharge = new BinnedParams("globChargeIDEff", BinnedParams::k2D_EFF_SYMMETRIC, versionUtils::Extension());
18  //_globalCharge=BinnedParams("globTrueChargeIDEff",BinnedParams::k2D_EFF_SYMMETRIC,versionUtils::Extension());
19  _localCharge = new BinnedParams("localChargeIDEff",BinnedParams::k2D_EFF_SYMMETRIC, versionUtils::Extension());
20 
21  //the number of parameter is divided by 5(global), 4(local) because there are
22  //5(4) parameters to paremetrize the efficiency
23  int nbins= _globalCharge->GetNBins()/5.+_localCharge->GetNBins()/4;
24  if(versionUtils::prod6_systematics)
25  SetNParameters(nbins);
26  else
27  SetNParameters(_globalCharge->GetNBins()*2);
28  if( _computecounters)
29  _globalCharge->InitializeEfficiencyCounter();
30 
31  _full_correlations = ND::params().GetParameterI("psycheSystematics.Tracker.FullCorrelations");
32 }
33 
34 //********************************************************************
35 Weight_h ChargeIDEffSystematics::ComputeWeight(const ToyExperiment& toy, const AnaEventC& eventBB, const ToyBoxB& box, const SelectionBase& sel){
36 //********************************************************************
37 
38  const AnaEventB& event = *static_cast<const AnaEventB*>(&eventBB);
39 
40  if(_computecounters)
41  _globalCharge->InitializeEfficiencyCounter();
42 
43  // Get the SystBox for this event, and the appropriate selection and branch
45 
46  // Initial weight is one
47  Weight_h eventWeight=1;
48  Weight_h localWeight=1;
49 
50  for (Int_t itrack=0;itrack<SystBox->nRelevantRecObjects;itrack++){
51  AnaTrackB* track = static_cast<AnaTrackB*>(SystBox->RelevantRecObjects[itrack]);
52 
53  //TODO: has to be put here for now since it is not the same as puting it in the isRelevantRecObject method.
54  //in future we should consider putting it in the isRelevantRecObject method
55  if (!track->TrueObject) continue;
56  if (track->Momentum<0)continue;
57  if (track->nTPCSegments==0)continue;
58  if (!track->Original) continue;
59  // Only for tracks passing the quality cut
60  if (!cutUtils::TrackQualityCut(*track)) continue;
61  // std::cout<<" momorig "<<track->Original->Momentum<<" mom "<<track->Momentum<<std::endl;
62 
63 
64  // For example in numuCC inclusive selection, only the Candidate is important at first order
65  if (!sel.IsRelevantRecObjectForSystematicInToy(event,box,track,SystId::kChargeIDEff,box.SuccessfulBranch)) continue;
66 
67  // Get array of TPC segments, but only one per TPC, the one with more nodes, are ordered in increasing TPC number
68  AnaTPCParticleB* TPCSegments[3];
69  Int_t nTPCSegments = anaUtils::GetOneSegmentPerTPC(track->TPCSegments, track->nTPCSegments, TPCSegments);
70  if (nTPCSegments==0) continue;
71 
72  AnaTPCParticleB* tpcTrack1 = static_cast<AnaTPCParticleB*>(TPCSegments[0]);
73  const AnaTPCParticleB* tpcTrack1orig = static_cast<const AnaTPCParticleB*>(TPCSegments[0]->Original);
74  if (!tpcTrack1orig) continue;
75 
76  Float_t momerr = tpcTrack1->MomentumError;
77  Float_t momerrMAX = tpcTrack1->MomentumError;
78  Float_t momerrOrig = tpcTrack1orig->MomentumError;
79  Float_t momerrMAXOrig = tpcTrack1orig->MomentumError;
80  Float_t mom = tpcTrack1->Momentum;
81  Float_t momMAX = tpcTrack1->Momentum;
82  Float_t momorig = tpcTrack1orig->Momentum;
83  Float_t momMAXorig = tpcTrack1orig->Momentum;
84 
85  Int_t charge =track->Charge;
86  Int_t locCharge =tpcTrack1->Charge;
87  Int_t syst_case=-1;
88  Float_t globWeight_momerr=1;
89  Float_t locWeight_momerr=1;
90 
91  if (nTPCSegments==1){
92  if(momerr!=momerr || !TMath::Finite(momerr) || momerr < 0.00001) continue;
93  if(mom!=mom || !TMath::Finite(mom)) continue;
94  syst_case=0;
95  }else if(nTPCSegments==2){
96  AnaTPCParticleB* tpcTrack2 = static_cast<AnaTPCParticleB*>(TPCSegments[1]);
97  const AnaTPCParticleB* tpcTrack2orig = static_cast<const AnaTPCParticleB*>(TPCSegments[1]->Original);
98  if (!tpcTrack2orig) continue;
99  Float_t tmpmomerr2 =tpcTrack2->MomentumError;
100  Float_t tmpmomerr1 =tpcTrack1->MomentumError;
101  if(tmpmomerr1!=tmpmomerr1 || !TMath::Finite(tmpmomerr1) || tmpmomerr1 < 0.00001) tmpmomerr1 = 99999999;
102  if(tmpmomerr2!=tmpmomerr2 || !TMath::Finite(tmpmomerr2) || tmpmomerr2 < 0.00001) tmpmomerr2 = 99999999;
103  momerr=std::min(tmpmomerr1,tmpmomerr2);
104  if(tmpmomerr1==99999999)tmpmomerr1 = -99999999;
105  if(tmpmomerr2==99999999)tmpmomerr2 = -99999999;
106  momerrMAX=std::max(tmpmomerr1,tmpmomerr2);
107 
108  if(momerr==99999999)continue;
109  if(momerrMAX==-99999999)continue;
110 
111  if(momerr==tpcTrack2->MomentumError){
112  mom =tpcTrack2->Momentum;
113  momorig =tpcTrack2orig->Momentum;
114  locCharge =tpcTrack2->Charge;
115  momerrOrig=tpcTrack2orig->MomentumError;
116  }
117  if(mom!=mom || !TMath::Finite(mom) || mom < 0.00001) continue;
118  if(momerrMAX==tpcTrack2->MomentumError){
119  momMAX=tpcTrack2->Momentum;
120  momMAXorig =tpcTrack2orig->Momentum;
121  momerrMAXOrig=tpcTrack2orig->MomentumError;
122  }
123  Int_t Q1=tpcTrack1->Charge;
124  Int_t Q2=tpcTrack2->Charge;
125 
126  if(Q1==Q2)syst_case=1;
127  else syst_case=2;
128  }
129  else if (nTPCSegments==3){
130 
131  AnaTPCParticleB* tpcTrack2 = static_cast<AnaTPCParticleB*>(TPCSegments[1]);
132  AnaTPCParticleB* tpcTrack3 = static_cast<AnaTPCParticleB*>(TPCSegments[2]);
133  const AnaTPCParticleB* tpcTrack2orig = static_cast<const AnaTPCParticleB*>(TPCSegments[1]->Original);
134  const AnaTPCParticleB* tpcTrack3orig = static_cast<const AnaTPCParticleB*>(TPCSegments[2]->Original);
135  if (!tpcTrack2orig) continue;
136  if (!tpcTrack3orig) continue;
137 
138  Float_t tmpmomerr3 =tpcTrack3->MomentumError;
139  Float_t tmpmomerr2 =tpcTrack2->MomentumError;
140  Float_t tmpmomerr1 =tpcTrack1->MomentumError;
141  if(tmpmomerr1!=tmpmomerr1 || !TMath::Finite(tmpmomerr1) || tmpmomerr1 < 0.00001) tmpmomerr1 = 99999999;
142  if(tmpmomerr2!=tmpmomerr2 || !TMath::Finite(tmpmomerr2) || tmpmomerr2 < 0.00001) tmpmomerr2 = 99999999;
143  if(tmpmomerr3!=tmpmomerr3 || !TMath::Finite(tmpmomerr3) || tmpmomerr3 < 0.00001) tmpmomerr3 = 99999999;
144  Float_t momerr12=std::min(tmpmomerr1,tmpmomerr2);
145  momerr=std::min(momerr12,tmpmomerr3);
146  if(momerr==99999999)continue;
147  if(momerr==tpcTrack2->MomentumError){
148  mom=tpcTrack2->Momentum;
149  locCharge =tpcTrack2->Charge;
150  momorig =tpcTrack2orig->Momentum;
151  momerrOrig=tpcTrack2orig->MomentumError;
152 
153  }
154  else if(momerr==tpcTrack3->MomentumError){
155  mom=tpcTrack3->Momentum;
156  locCharge =tpcTrack3->Charge;
157  momorig =tpcTrack2orig->Momentum;
158  momerrOrig=tpcTrack3orig->MomentumError;
159  }
160  if(mom!=mom || !TMath::Finite(mom) || mom < 0.00001) continue;
161  if(tmpmomerr1==99999999)tmpmomerr1 = -99999999;
162  if(tmpmomerr2==99999999)tmpmomerr2 = -99999999;
163  if(tmpmomerr3==99999999)tmpmomerr3 = -99999999;
164  Float_t momerrMAX12=std::max(tmpmomerr1,tmpmomerr2);
165  momerrMAX=std::max(momerrMAX12,tmpmomerr3);
166  if(momerrMAX==-99999999)continue;
167  if(momerrMAX==tpcTrack2->MomentumError){
168  momMAX=tpcTrack2->Momentum;
169  momMAXorig =tpcTrack2orig->Momentum;
170  momerrMAXOrig=tpcTrack2orig->MomentumError;
171  }else if(momerrMAX==tpcTrack3->MomentumError){
172  momMAX=tpcTrack3->Momentum;
173  momMAXorig =tpcTrack3orig->Momentum;
174  momerrMAXOrig=tpcTrack3orig->MomentumError;
175  }
176 
177  Int_t Q1=tpcTrack1->Charge;
178  Int_t Q2=tpcTrack2->Charge;
179  Int_t Q3=tpcTrack3->Charge;
180  if( Q1==Q2 && Q2==Q3) syst_case=3;
181  if((Q1!=Q2 && Q2==Q3) || (Q1!=Q3 && Q1==Q2) || (Q1!=Q2 && Q1==Q3)) syst_case=4;
182  }
183  //compute weight for local charge systematics:
184  //we don't compute any systematics in case of local charge for 1 segment
185  if(versionUtils::prod6_systematics && syst_case>0){
186  if(momMAX<1 )continue; //those tracks are not selected
187  bool areEqual= (syst_case==1 || syst_case==3) ? true : false;
188  BinnedParamsParams parloc[4];
189  for(Int_t ipar=0;ipar<4;ipar++){
190  _localCharge->GetBinValues(syst_case,ipar, parloc[ipar]);
191  }
192  BinnedParamsParams paramsloc;
193  Int_t index_loc=0;//there are 8 parameters in the file but in fact only 2 errors...
194  if(syst_case>2) index_loc=1;
195  Float_t effmc=ComputeEffFromLocalParametrization(parloc,momMAX, momerrMAX);
196  Float_t effmcorig=ComputeEffFromLocalParametrization(parloc,momMAXorig, momerrMAXOrig);
197  Float_t ww= (areEqual) ? effmc/effmcorig : (1-effmc)/(1-effmcorig);
198  if(effmcorig==0 && areEqual) ww=1;
199  if(effmcorig==1 && !areEqual) ww=1;
200  // std::cout<<" mom "<<momMAX<<" err "<<momerrMAX<<" eff "<<effmc
201  // <<"\n momO "<<momMAXorig<<" errO "<<momerrMAXOrig<<" eff "<<effmcorig
202  // <<" ww "<<ww<<std::endl;
203  locWeight_momerr*=ww;
204 
205  ComputeEffFromLocalParametrization(parloc,momMAX,momerrMAX,paramsloc );
206  //the same variation is applied since it is a fake variation for the mc
207 
208  // override to ensure same variations for all params (see bugzilla 1271)
209  if (_full_correlations) index_loc = 0;
210 
211  localWeight *= systUtils::ComputeEffLikeWeight(areEqual, toy, GetIndex(), index_loc, paramsloc);
212  }
213 
214  if(localWeight.Correction!=0 ) eventWeight.Correction*=(localWeight.Correction);
215  if(localWeight.Systematic!=0 ) eventWeight.Systematic*=(localWeight.Systematic*locWeight_momerr);
216 
217  //NOW looking at global charge.
218  //for prod5:
219  Float_t p0 = track->Momentum;
220  // Get charge and true charge
221  Int_t trueCharge=track->GetTrueParticle()->Charge;
222  // Get rec and true direction in Z
223  Float_t dir = track->DirectionStart[2];
224  Float_t trueDir=track->GetTrueParticle()->Direction[2];
225 
226  BinnedParamsParams params;
227  Int_t index;
228  bool found;
229  if(!versionUtils::prod6_systematics){
230  // Get the charge confusion for this momentum
231  if(!_globalCharge->GetBinValues(0,p0, params, index)) continue;
232  // is the track correctly identified?
233  // correct when charge and direction are correct, or charge and direction are wrong
234  found= (trueCharge*charge>0 && trueDir*dir>0) || (trueCharge*charge<0 && trueDir*dir<0);
235  }
236  else{
237  // // this case is neglected for global charge
238  // if(syst_case==3)continue;
239  // BinnedParamsParams par[4];
240  // //get the parametrization values
241  // for(Int_t ipar=0;ipar<4;ipar++){
242  // _globalCharge->GetBinValues(syst_case,ipar, par[ipar], index);
243  // }
244  // ComputeEffFromGlobalParametrization(par,mom, momerr,params );
245  // found= (trueCharge*charge>0 && trueDir*dir>0) || (trueCharge*charge<0 && trueDir*dir<0);
246 
247  BinnedParamsParams par[5];
248  //get the parametrization values
249  for(Int_t ipar=0;ipar<5;ipar++){
250  _globalCharge->GetBinValues(syst_case,ipar, par[ipar]);
251  }
252  found = (charge*locCharge>0);
253  if(mom<1 )continue; //those tracks are not selected
254  Float_t effmc=ComputeEffFromGlobalLocalParametrization(par,mom, momerr);
255  Float_t effmcorig=ComputeEffFromGlobalLocalParametrization(par,momorig, momerrOrig);
256  Float_t ww= (found) ? effmc/effmcorig : (1-effmc)/(1-effmcorig);
257  if(effmcorig==0 && found) ww=1;
258  if(effmcorig==1 && !found) ww=1;
259 
260  globWeight_momerr*=ww;
261 
262  ComputeEffFromGlobalLocalParametrization(par,mom, momerr,params );
263 
264  //there 4 errors but 20 lines, one error for each case...
265  index = syst_case +_localCharge->GetNBins()/4;
266  }
267 
268  // override to ensure same variations for all params (see bugzilla 1271)
269  if (_full_correlations) index = 0;
270 
271  //the same variation is applied since it is a fake variation for the mc
272  Weight_h globWeight = systUtils::ComputeEffLikeWeight(found, toy, GetIndex(), index, params);
273 
274  if(globWeight!=globWeight){
275  /*
276  std::cout << "ChargeIDEffSystematics. globWeight for track " << itrack << " has value = "<< globWeight << " in run, event, subrun = "
277  << event.EventInfo.Run << " "
278  << event.EventInfo.Event << " "
279  << event.EventInfo.SubRun << " ==> Skip track. Problem under investigation !!!! " << std::endl;
280  continue;
281  */
282  }
283 
284  if(globWeight.Correction!=0 ) eventWeight.Correction*=(globWeight.Correction);
285  if(globWeight.Systematic!=0 ) eventWeight.Systematic*=(globWeight.Systematic*globWeight_momerr);
286 
287  // std::cout<<" evw "<<eventWeight<<" glob "<<globWeight<<" globmom "<<globWeight_momerr
288  // <<" loc "<<localWeight<<" locmom "<<locWeight_momerr
289  // <<std::endl;
290  if(_computecounters)
291  _globalCharge->UpdateEfficiencyCounter(index,found);
292 
293  }
294 
295  return eventWeight;
296 }
297 
298 //********************************************************************
299 void ChargeIDEffSystematics::ComputeEffFromGlobalParametrization(BinnedParamsParams *par,Float_t mom, Float_t momerr, BinnedParamsParams &params ){
300 //********************************************************************
301  //the hard coded values are here to get a pull with sigma=1
302  Float_t vvv=fabs((0.48+7.7E-4*mom)*momerr/mom);
303  if(vvv>2.5) vvv=2.5;
304  Float_t var=TMath::Log(vvv);
305  Float_t effMC = par[0].meanMC +par[1].meanMC*var +par[2].meanMC*pow(var,2) +par[3].meanMC*pow(var,3);
306 
307  Float_t ratio = par[0].meanDATA; // in charge misID .dat, meanDATA is the ratio between data and MC in the control sample.
308  Float_t err = par[0].sigmaDATAl; // in charge misID .dat, sigmaDATAl is the error on the data/MC ratio in the control sample
309  // if (1-ratio) i.e. is larger that err, let's use (1-ratio) as error!
310  if (fabs(1-ratio) > err) err = fabs(1-ratio);
311  Float_t effDATA = ratio * effMC;
312  Float_t effDATA_err= err *effMC;
313 
314  // if(effMC<0){
315  // std::cout<<" var "<<var<<" mom "<<mom<<" momerr "<<momerr
316  // <<" 0 "<<par[0].meanMC
317  // <<" 1 "<<par[1].meanMC*var
318  // <<" 2 "<<par[2].meanMC*pow(var,2)
319  // <<" 3 "<<par[3].meanMC*pow(var,3)<<std::endl;
320  // std::cout<<" =====> "<<effMC<<std::endl;
321  // }
322 
323  // pvar_data = effdata + efferrdata*var
324  // pvar_mc = effmc + efferrmc *var
325  // => ratiovar = ratio + ratio_err *var
326 
327  // pvar_data/pvar_mc *pmcANA ratiovar*pmcANA
328  //----------------------------- = -------------------
329  // pmcANA pmcANA
330 
331  // 1- pvar_data/pvar_mc *pmcANA 1-ratiovar*pmcANA
332  //----------------------------- = ---------------
333  // 1 - pmcANA 1-pmcANA
334 
335  //filling params as the following is equivalent:
336  params.meanDATA =effDATA;
337  params.sigmaDATAl=effDATA_err;
338  params.sigmaDATAh=effDATA_err;
339  params.meanMC =effMC;
340  params.sigmaMCl =0;
341  params.sigmaMCh =0;
342  params.meanMCANA =effMC;
343 }
344 
345 //********************************************************************
346 Float_t ChargeIDEffSystematics::ComputeEffFromGlobalLocalParametrization(BinnedParamsParams *par,Float_t mom, Float_t momerr ){
347 //********************************************************************
348  Float_t vvv=-999;
349  if(mom!=0)
350  vvv= fabs((0.48+7.7E-4*mom)*momerr/mom);
351  if(vvv>2.5) vvv=2.5;
352  Float_t var=TMath::Log(vvv);
353  Float_t effMC = (par[0].meanMC +par[1].meanMC*var +par[2].meanMC*pow(var,2) +par[3].meanMC*pow(var,3))*(1+par[4].meanMC*pow(vvv,2));
354  Float_t eff=std::max(effMC,(Float_t)0.);
355  eff=std::min(effMC,(Float_t)1.);
356 
357  return eff;
358 
359 }
360 
361 //********************************************************************
362 void ChargeIDEffSystematics::ComputeEffFromGlobalLocalParametrization(BinnedParamsParams *par,Float_t mom, Float_t momerr, BinnedParamsParams &params ){
363 //********************************************************************
364  //the hard coded values are here to get a pull with sigma=1
365  Float_t effMC = ComputeEffFromGlobalLocalParametrization(par,mom,momerr);
366 
367  Float_t ratio = par[0].meanDATA; // in charge misID .dat, meanDATA is the ratio between data and MC in the control sample.
368  Float_t err = par[0].sigmaDATAl; // in charge misID .dat, sigmaDATAl is the error on the data/MC ratio in the control sample
369  // if (1-ratio) i.e. is larger that err, let's use (1-ratio) as error!
370  if (fabs(1-ratio) > err) err = fabs(1-ratio);
371  Float_t effDATA = ratio * effMC;
372  Float_t effDATA_err= err *effMC;
373 
374  // if(effMC<0){
375  // std::cout<<" var "<<var<<" mom "<<mom<<" momerr "<<momerr
376  // <<" 0 "<<par[0].meanMC
377  // <<" 1 "<<par[1].meanMC*var
378  // <<" 2 "<<par[2].meanMC*pow(var,2)
379  // <<" 3 "<<par[3].meanMC*pow(var,3)
380  // <<" 4 "<<par[4].meanMC*pow(vvv,2)+1<<std::endl;
381  // std::cout<<" =====> "<<effMC<<std::endl;
382  // }
383  // pvar_data = effdata + efferrdata*var
384  // pvar_mc = effmc + efferrmc *var
385  // => ratiovar = ratio + ratio_err *var
386 
387  // pvar_data/pvar_mc *pmcANA ratiovar*pmcANA
388  //----------------------------- = -------------------
389  // pmcANA pmcANA
390 
391  // 1- pvar_data/pvar_mc *pmcANA 1-ratiovar*pmcANA
392  //----------------------------- = ---------------
393  // 1 - pmcANA 1-pmcANA
394 
395  //filling params as the following is equivalent:
396  params.meanDATA =effDATA;
397  params.sigmaDATAl=effDATA_err;
398  params.sigmaDATAh=effDATA_err;
399  params.meanMC =effMC;
400  params.sigmaMCl =0;
401  params.sigmaMCh =0;
402  params.meanMCANA =effMC;
403 }
404 //********************************************************************
405 Float_t ChargeIDEffSystematics::ComputeEffFromLocalParametrization(BinnedParamsParams *par,Float_t mom, Float_t momerr ){
406 //********************************************************************
407 
408  //the hard coded values are here to get a pull with sigma=1
409  Float_t var=-999;
410  if(mom!=0)
411  var=fabs((0.48+7.7E-4*mom)*momerr/mom);
412  if(var>2.5) var=2.5;//parametrization valid up to this range...
413  Float_t effMC = par[0].meanMC +(par[1].meanMC +par[2].meanMC*var)*exp(-par[3].meanMC/var);
414 
415  Float_t eff=std::max(effMC,(Float_t)0.);
416  eff=std::min(effMC,(Float_t)1.);
417  return eff;
418 
419 }
420 //********************************************************************
421 void ChargeIDEffSystematics::ComputeEffFromLocalParametrization(BinnedParamsParams *par,Float_t mom, Float_t momerr, BinnedParamsParams &params ){
422 //********************************************************************
423 
424  Float_t effMC = ComputeEffFromLocalParametrization(par,mom,momerr);
425 
426  Float_t ratio = par[0].meanDATA; // in charge misID .dat, meanDATA is the ratio between data and MC in the control sample.
427  Float_t err = par[0].sigmaDATAl; // in charge misID .dat, sigmaDATAl is the error on the data/MC ratio in the control sample
428  // if (1-ratio) i.e. is larger that err, let's use (1-ratio) as error!
429  if (fabs(1-ratio) > err) err = fabs(1-ratio);
430  Float_t effDATA = ratio * effMC;
431  Float_t effDATA_err= err *effMC;
432 
433  // pvar_data = effdata + efferrdata*var
434  // pvar_mc = effmc + efferrmc *var
435  // => ratiovar = ratio + ratio_err *var
436 
437  // pvar_data/pvar_mc *pmcANA ratiovar*pmcANA
438  //----------------------------- = -------------------
439  // pmcANA pmcANA
440 
441  // 1- pvar_data/pvar_mc *pmcANA 1-ratiovar*pmcANA
442  //----------------------------- = ---------------
443  // 1 - pmcANA 1-pmcANA
444 
445  //filling params as the following is equivalent:
446  params.meanDATA =effDATA;
447  params.sigmaDATAl=effDATA_err;
448  params.sigmaDATAh=effDATA_err;
449  params.meanMC =effMC;
450  params.sigmaMCl =0;
451  params.sigmaMCh =0;
452  params.meanMCANA =effMC;
453 
454 }
455 
456 //********************************************************************
457 void ChargeIDEffSystematics::FillSystBox(const AnaEventC& event, const SelectionBase& sel, Int_t ibranch){
458 //********************************************************************
459 
460  Int_t uniqueID = 0;
461 
462 #ifdef MULTITHREAD
463  uniqueID = event.UniqueID;
464 #endif
465 
466  // Get the selection index;
467  Int_t isel=sel.GetEnabledIndex();
468 
469  // Get the SystBox
470  SystBoxB& box = *_systBoxes[isel][ibranch][uniqueID];
471 
472  Int_t* groups;
473  anaUtils::CreateArray(groups,10);
474  Int_t nGroups = GetRelevantRecObjectGroups(sel, ibranch, groups);
475  anaUtils::ResizeArray(groups,nGroups);
476 
477  EventBoxB* EventBox = event.EventBoxes[EventBoxId::kEventBoxTracker];
478 
479  if (nGroups>0){
480  Int_t nMaxTracks=0;
481  for (Int_t g = 0; g<nGroups;g++)
482  nMaxTracks += EventBox->nRecObjectsInGroup[groups[g]];
483 
484  if (box.RelevantRecObjects) delete box.RelevantRecObjects;
485  anaUtils::CreateArray(box.RelevantRecObjects, nMaxTracks);
486  box.nRelevantRecObjects=0;
487 
488  for (Int_t g = 0; g<nGroups;g++){
489 
490  AnaRecObjectC** tracks0 = EventBox->RecObjectsInGroup[groups[g]];
491  int nOrig= EventBox->nRecObjectsInGroup[groups[g]];
492 
493  bool used[NMAXPARTICLES]={false};
494  bool used_forQC[NMAXPARTICLES]={true};
495  //take only into account 1 association between 1 track and trajectory.
496  for (Int_t it1=0;it1<nOrig;it1++){
497  if(it1>=99) break;
498  AnaTrackB* track1 = static_cast<AnaTrackB*>(tracks0[it1]);
499 
500  if (!IsRelevantRecObject(event,*track1)) continue;
501  if (!sel.IsRelevantRecObjectForSystematic(event,track1,_index)) continue;
502 
503  if(!track1) continue;
504  if(!track1->TrueObject) continue;
505  if(!used[it1]) used_forQC[it1]=true;
506  Float_t Q1=track1->Charge;
507  Float_t ID1=track1->TrueObject->ID;
508  for (Int_t it2 = it1+1; it2<nOrig; it2++){
509  if(it2>=99) break;
510  AnaTrackB* track2 = static_cast<AnaTrackB*>(tracks0[it2]);
511 
512  if (!IsRelevantRecObject(event,*track2)) continue;
513  if (!sel.IsRelevantRecObjectForSystematic(event,track2,_index)) continue;
514  if(!track2)continue;
515  if(!track2->TrueObject)continue;
516  Float_t Q2=track2->Charge;
517  Float_t trueQ2=track2->GetTrueParticle()->Charge;
518  Float_t ID2=track2->TrueObject->ID;
519  if(Q1*Q2<0 && ID1==ID2){
520  if(Q2*trueQ2>0 ){
521  used_forQC[it1]=false;
522  used_forQC[it2]=true;
523  used[it1]=used[it2]=true;
524  }
525  else{
526  used_forQC[it1]=true;
527  used_forQC[it2]=false;
528  used[it1]=used[it2]=true;
529  }
530  }
531  }
532  }
533  for (Int_t it1=0;it1<nOrig;it1++){
534  if(used_forQC[it1]){
535  box.RelevantRecObjects[box.nRelevantRecObjects++]= (tracks0[it1]);
536  }
537  }
538  }
539  if (box.nRelevantRecObjects != nMaxTracks)
540  anaUtils::ResizeArray(box.RelevantRecObjects, box.nRelevantRecObjects);
541  }
542 
543  if (groups) delete [] groups;
544 
545 }
546 
547 // //**************************************************
548 // bool ChargeIDEffSystematics::IsRelevantRecObject(const AnaEventC& event, const AnaRecObjectC& track) const{
549 // //**************************************************
550 
551 // // TODO. Commented out for the moment for validation purposes
552 
553 // (void)event;
554 
555 
556 
557 // // Only for tracks passing the quality cut (Put this condition first, since it is more restrictive)
558 // if (!cutUtils::TrackQualityCut(track)) return false;
559 
560 // if (!track.TrueObject) return false;
561 // if (track.Momentum<0) return false;
562 // // if (track.nTPCSegments==0) return false;
563 // if (!track.Original) return false;
564 
565 // return true;
566 // }
567 
568 //********************************************************************
569 Int_t ChargeIDEffSystematics::GetRelevantRecObjectGroups(const SelectionBase& sel, Int_t ibranch, Int_t* IDs) const{
570 //********************************************************************
571 
572  SubDetId_h det = sel.GetDetectorFV(ibranch);
573 
574  if (det == SubDetId::kFGD1){
575  //IDs[0] = EventBoxTracker::kTracksWithGoodQualityTPCInFGD1FV;
576  IDs[0] = EventBoxTracker::kTracksWithTPCInFGD1FV;
577  return 1;
578  }
579  else if (det == SubDetId::kFGD2){
580  //IDs[0] = EventBoxTracker::kTracksWithGoodQualityTPCInFGD2FV;
581  IDs[0] = EventBoxTracker::kTracksWithTPCInFGD2FV;
582  return 1;
583  }
584  else if (det == SubDetId::kFGD){
585  //IDs[0] = EventBoxTracker::kTracksWithGoodQualityTPCInFGD1FV;
586  //IDs[1] = EventBoxTracker::kTracksWithGoodQualityTPCInFGD2FV;
587  IDs[0] = EventBoxTracker::kTracksWithTPCInFGD1FV;
588  IDs[1] = EventBoxTracker::kTracksWithTPCInFGD2FV;
589  return 2;
590  }else if (det == SubDetId::kP0D){
591  IDs[0] = EventBoxTracker::kTracksWithTPCInP0DFV;
592  return 1;
593  }
594 
595  return 0;
596 }
Int_t _index
The index of this systematic (needed by SystematicsManager);.
Int_t GetRelevantRecObjectGroups(const SelectionBase &sel, Int_t *IDs) const
Get the TrackGroup IDs array for this systematic.
Int_t GetRelevantRecObjectGroups(const SelectionBase &sel, Int_t ibranch, Int_t *IDs) const
Is this track relevant for this systematic ?
Int_t GetIndex() const
Return the index of this systematic.
int GetParameterI(std::string)
Get parameter. Value is returned as integer.
Definition: Parameters.cxx:217
Int_t SelectionEnabledIndex
The enabled index of this selection this ToyBox belongs to.
Definition: ToyBoxB.hxx:49
SystBoxB * GetSystBox(const AnaEventC &event, Int_t isel=0, Int_t ibranch=0) const
Get the SystBox corresponding to a selection, branch and event.
AnaTPCParticleB * TPCSegments[NMAXTPCS]
The TPC segments that contributed to this global track.
void SetNParameters(int N)
Set the number of systematic parameters associated to this systematic.
AnaTrueObjectC * TrueObject
The link to the true oject that most likely generated this reconstructed object.
Float_t Charge
The reconstructed charge of the particle.
Int_t ID
The ID of the trueObj, which corresponds to the ID of the TTruthParticle that created it...
Float_t MomentumError
Error of the momentum at the start of the segment.
Float_t meanDATA
The mean value for each of the systematic parameters of the control sample.
Int_t nRecObjectsInGroup[NMAXRECOBJECTGROUPS]
----—— RecObjects and TrueRecObjects used in the selection and systematics ------------—— ...
Float_t Momentum
The reconstructed momentum of the particle, at the start position.
int nTPCSegments
How many TPC tracks are associated with this track.
virtual bool IsRelevantRecObjectForSystematicInToy(const AnaEventC &, const ToyBoxB &, AnaRecObjectC *, SystId_h syst_index, Int_t branch=0) const
Is this track relevant for a given systematic (after selection, called for each toy) ...
const AnaParticleB * Original
void FillSystBox(const AnaEventC &event, const SelectionBase &sel, Int_t ibranch)
Fill the SystBox for this event, selection and branch.
Weight_h ComputeWeight(const ToyExperiment &, const AnaEventC &, const ToyBoxB &)
Apply the systematic.
Int_t SuccessfulBranch
The branch that is successful for this toy in the selection this ToyBox belongs to.
Definition: ToyBoxB.hxx:46
Float_t meanMC
The mean value for each of the systematic parameters of the control sample.
Representation of a global track.
Representation of a TPC segment of a global track.
Float_t DirectionStart[3]
The reconstructed start direction of the particle.
virtual bool IsRelevantRecObjectForSystematic(const AnaEventC &, AnaRecObjectC *, SystId_h syst_index, Int_t branch=0) const
Is this track relevant for a given systematic (prior to selection, call when initializing the event...
Float_t meanMCANA
The mean value for each of the systematic parameters of the analysis sample.
Float_t sigmaDATAl
The sigma value for each of the systematic parameters of the control sample /// with possibility of a...
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.
Float_t Charge
The true charge of the particle.
SystBoxB **** _systBoxes
----—— Relevant objects for this systematic ------------——
Float_t Direction[3]
The initial direction of the true particle.
virtual bool IsRelevantRecObject(const AnaEventC &, const AnaRecObjectC &) const
Check whether a AnaRecObject is relevant for this systematic or not.
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.