ATLAS Offline Software
Loading...
Searching...
No Matches
MissingMassProb.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Class handling the probability calculation of the MissingMassCalculator
6// author Michael Huebner <michael.huebner@no.spam.cern.ch>
7
8// Local include(s):
12
14#include <TFile.h>
15#include <cmath>
16
17namespace {
18 constexpr double GEV = 1000.0;
19}
20
21using namespace DiTauMassTools;
22using ROOT::Math::PtEtaPhiMVector;
23using ROOT::Math::VectorUtil::Phi_mpi_pi;
24
25// The wrapper functions make use of the ignore template defined in HelperFunctions.h.
26// This is to avoid warnings during compilation.
27// All wrapper functions need to have the same structure such that they can be
28// handled within the probList vectors and the "user" from the Calculator only
29// has to call Prob->apply() to have a common handling of all probability calculations.
30
31double MissingMassProb::MetProbabilityWrapper( MissingMassProb* prob, MissingMassInput& preparedInput, const int & tau_type1, const int & tau_type2, const PtEtaPhiMVector & tauvec1, const PtEtaPhiMVector & tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector & nuvec2 ){
32 ignore(tau_type1);
33 ignore(tau_type2);
34 ignore(tauvec1);
35 ignore(tauvec2);
36 ignore(nuvec1);
37 ignore(nuvec2);
38 return prob->MetProbability(preparedInput, 1.,1.,1.,1.);
39}
40
41double MissingMassProb::mEtAndTauProbabilityWrapper( MissingMassProb* prob, MissingMassInput& preparedInput, const int & tau_type1, const int & tau_type2, const PtEtaPhiMVector & tauvec1, const PtEtaPhiMVector & tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector & nuvec2 ){
42 ignore(tau_type1);
43 ignore(tau_type2);
44 ignore(tauvec1);
45 ignore(tauvec2);
46 ignore(nuvec1);
47 ignore(nuvec2);
48 return prob->mEtAndTauProbability(preparedInput);
49}
50
51double MissingMassProb::dTheta3d_probabilityFastWrapper( MissingMassProb* prob, MissingMassInput& preparedInput, const int & tau_type1, const int & tau_type2, const PtEtaPhiMVector & tauvec1, const PtEtaPhiMVector & tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector & nuvec2 ){
52 double Prob = 1.;
53 if (tau_type1>=0) {
54 PtEtaPhiMVector totalTau1;
55 totalTau1+=tauvec1;
56 totalTau1+=nuvec1;
57 const double tau1_tmpp = totalTau1.P();
58 const double angle1 = Angle(nuvec1,tauvec1);
59 Prob*=prob->dTheta3d_probabilityFast(preparedInput, tau_type1, angle1, tau1_tmpp);
60 }
61 if (tau_type2>=0) {
62 PtEtaPhiMVector totalTau2;
63 totalTau2+=tauvec2;
64 totalTau2+=nuvec2;
65 const double tau2_tmpp = totalTau2.P();
66 const double angle2 = Angle(nuvec2,tauvec2);
67 Prob*=prob->dTheta3d_probabilityFast(preparedInput, tau_type2, angle2, tau2_tmpp);
68 }
69 return Prob;
70}
71
72double MissingMassProb::TauProbabilityWrapper( MissingMassProb* prob, MissingMassInput& preparedInput, const int & tau_type1, const int & tau_type2, const PtEtaPhiMVector & tauvec1, const PtEtaPhiMVector & tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector & nuvec2 ){
73 if( prob->GetUseHT() || (preparedInput.m_tauTypes==TauTypes::hh) ) {
74 return prob->TauProbability(preparedInput, tau_type1, tauvec1, nuvec1, tau_type2, tauvec2, nuvec2, preparedInput.m_MetVec.R()); // customized prob for Njet25=0
75 } else {
76 return prob->TauProbability(preparedInput, tau_type1, tauvec1, nuvec1, tau_type2, tauvec2, nuvec2);
77 }
78}
79
80double MissingMassProb::MnuProbabilityWrapper( MissingMassProb* prob, MissingMassInput& preparedInput, const int & tau_type1, const int & tau_type2, const PtEtaPhiMVector & tauvec1, const PtEtaPhiMVector & tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector & nuvec2 ){
81 ignore(tauvec1);
82 ignore(tauvec2);
83 if(prob->GetUseMnuProbability()==1){
84 if(preparedInput.m_tauTypes==TauTypes::ll) return prob->MnuProbability(preparedInput, nuvec1.M())*prob->MnuProbability(preparedInput, nuvec2.M()); // lep-lep
85 else if(tau_type1==8 && (tau_type2>=0 && tau_type2<=5)) return prob->MnuProbability(preparedInput, nuvec1.M()); // lep-had: tau1==lepton
86 else if((tau_type1>=0 && tau_type1<=5) && tau_type2==8) return prob->MnuProbability(preparedInput, nuvec2.M()); // lep-had: tau2==lepton
87 else {
88 Warning("DiTauMassTools", "something went really wrong in MNuProb...");
89 return 1.;
90 }
91 } else {
92 return 1.;
93 }
94}
95
96double MissingMassProb::dTheta3d_probabilityNewWrapper( MissingMassProb* prob, MissingMassInput& preparedInput, const int & tau_type1, const int & tau_type2, const PtEtaPhiMVector & tauvec1, const PtEtaPhiMVector & tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector & nuvec2 ){
97 ignore(preparedInput);
98 double Prob = 1.;
99 if (tau_type1>=0) {
100 PtEtaPhiMVector totalTau1;
101 totalTau1+=tauvec1;
102 totalTau1+=nuvec1;
103 const double angle1 = Angle(nuvec1,tauvec1);
104 double prob_tmp = 1e-10;
105 if (angle1!=0.) prob_tmp=prob->GetFormulaAngle1()->Eval(angle1);
106 if (prob_tmp<=0.) prob_tmp=1e-10;
107 Prob*=prob_tmp;
108 }
109 if (tau_type2>=0) {
110 PtEtaPhiMVector totalTau2;
111 totalTau2+=tauvec2;
112 totalTau2+=nuvec2;
113 const double angle2 = Angle(nuvec2,tauvec2);
114 double prob_tmp = 1e-10;
115 if (angle2!=0.) prob_tmp=prob->GetFormulaAngle2()->Eval(angle2);
116 if (prob_tmp<=0.) prob_tmp=1e-10;
117 Prob*=prob_tmp;
118 }
119 // very rare cases where parametrisation flips
120 if (std::isnan(Prob)) Prob = 0.;
121 return Prob;
122}
123
124double MissingMassProb::TauProbabilityNewWrapper( MissingMassProb* prob, MissingMassInput& preparedInput, const int & tau_type1, const int & tau_type2, const PtEtaPhiMVector & tauvec1, const PtEtaPhiMVector & tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector & nuvec2 ){
125 ignore(preparedInput);
126 ignore(tau_type1);
127 ignore(tau_type2);
128 double Prob = 1.;
129 double R1 = nuvec1.P()/tauvec1.P();
130 double R2 = nuvec2.P()/tauvec2.P();
131 Prob*=prob->GetFormulaRatio1()->Eval(R1);
132 Prob*=prob->GetFormulaRatio2()->Eval(R2);
133 // not observed, just a protection
134 if (std::isnan(Prob)) Prob = 0.;
135 return Prob;
136}
137
138double MissingMassProb::MnuProbabilityNewWrapper( MissingMassProb* prob, MissingMassInput& preparedInput, const int & tau_type1, const int & tau_type2, const PtEtaPhiMVector & tauvec1, const PtEtaPhiMVector & tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector & nuvec2 ){
139 ignore(tauvec1);
140 ignore(tauvec2);
141 double Prob = 1.;
142 if(prob->GetUseMnuProbability()==1){
143 if(preparedInput.m_tauTypes==TauTypes::ll) Prob*=(prob->GetFormulaNuMass()->Eval(nuvec1.M())*prob->GetFormulaNuMass()->Eval(nuvec2.M()));
144 else if(tau_type1==8 && (tau_type2>=0 && tau_type2<=5)) Prob*=prob->GetFormulaNuMass()->Eval(nuvec1.M());
145 else if((tau_type1>=0 && tau_type1<=5) && tau_type2==8) Prob*=prob->GetFormulaNuMass()->Eval(nuvec2.M());
146 else {
147 Warning("DiTauMassTools", "something went really wrong in MNuProb...");
148 }
149 }
150 // not observed, just a protection
151 if (std::isnan(Prob)) Prob = 0.;
152 return Prob;
153}
154
156 if (m_paramVectorNuMass.size() > 0){
157 for(int i=0; i<m_formulaNuMass->GetNpar(); i++){
158 m_formulaNuMass->SetParameter(i, m_paramVectorNuMass[0]->GetParameter(i));
159 }
160 }
161}
162
163void MissingMassProb::setParamAngle(const PtEtaPhiMVector& tauvec, int tau, int tautype) {
164 double Pt_tau = tauvec.Pt();
165 int type = tautype;
166 if (tautype > 4 && tautype < 8) type = 4;
167 if (tautype <= 5){
168 if (m_paramVectorAngle.size() > 0){
169 for(int i=0; i<=3; i++){
170 double par = m_paramVectorAngle[i+(type)*4]->Eval(Pt_tau);
171 if (tau==1){
172 m_formulaAngle1->SetParameter(i, par);
173 } else {
174 m_formulaAngle2->SetParameter(i, par);
175 }
176 }
177 }
178 } else {
179 if (m_paramVectorAngleLep.size() > 0){
180 for(int i=0; i<=3; i++){
181 double par = m_paramVectorAngleLep[i]->Eval(Pt_tau);
182 if (tau==1){
183 m_formulaAngle1->SetParameter(i, par);
184 } else {
185 m_formulaAngle2->SetParameter(i, par);
186 }
187 }
188 }
189 }
190}
191
192void MissingMassProb::setParamRatio(int tau, int tautype) {
193 int type = tautype;
194 if(tautype > 4 && tautype < 8) type = 4;
195 if (tautype <= 5){
196 if(tau==1){
198 for(int i=0; i<m_formulaRatio1->GetNpar(); i++){
199 m_formulaRatio1->SetParameter(i, m_paramVectorRatio[5*(tau-1)+type]->GetParameter(i));
200 }
201 } else {
203 for(int i=0; i<m_formulaRatio2->GetNpar(); i++){
204 m_formulaRatio2->SetParameter(i, m_paramVectorRatio[5*(tau-1)+type]->GetParameter(i));
205 }
206 }
207 } else {
208 if(tau==1){
210 for(int i=0; i<m_formulaRatio1->GetNpar(); i++){
211 m_formulaRatio1->SetParameter(i, m_paramVectorRatioLep[0]->GetParameter(i));
212 }
213 } else {
215 for(int i=0; i<m_formulaRatio2->GetNpar(); i++){
216 m_formulaRatio2->SetParameter(i, m_paramVectorRatioLep[0]->GetParameter(i));
217 }
218 }
219 }
220}
221
222// Default Constructor
223MissingMassProb::MissingMassProb(MMCCalibrationSet::e aset, const std::string& paramFilePath) {
224 m_mmcCalibrationSet = aset;
225 m_allowUseHT = false;
226 m_UseHT = false;
227
228 m_fParams = NULL;
229 if (!paramFilePath.empty()){
230 std::string total_path = "DiTauMassTools/"+paramFilePath;
231 m_fParams = TFile::Open( (const char*) PathResolverFindCalibFile(total_path).c_str() ,"READ");
232 }
234 m_probListConstant.push_back( std::bind(&mEtAndTauProbabilityWrapper, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7) );
235 m_probListOneTau.push_back( std::bind(&dTheta3d_probabilityNewWrapper, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7) );
236 m_probListTwoTau.push_back( std::bind(&TauProbabilityNewWrapper, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7) );
237 m_probListTwoTau.push_back( std::bind(&MnuProbabilityNewWrapper, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7) );
238 if (m_fParams){
240 }
241 }
242 else {
243 m_probListConstant.push_back( std::bind(&mEtAndTauProbabilityWrapper, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7) );
244 m_probListOneTau.push_back( std::bind(&dTheta3d_probabilityFastWrapper, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7) );
245 m_probListTwoTau.push_back( std::bind(&TauProbabilityWrapper, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7) );
246 m_probListTwoTau.push_back( std::bind(&MnuProbabilityWrapper, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7) );
247 }
248
249 if (m_fParams) if (m_fParams->IsOpen()) m_fParams->Close();
250
252 // [tau_type][parLG][par]
253 // leptonic tau
254 //-par[0]
255 s_fit_param[0][0][0][0]=-9.82013E-1;
256 s_fit_param[0][0][0][1]=9.09874E-1;
257 s_fit_param[0][0][0][2]=0.0;
258 s_fit_param[0][0][0][3]=0.0;
259 //-par[1]
260 s_fit_param[0][0][1][0]=9.96303E1;
261 s_fit_param[0][0][1][1]=1.68873E1;
262 s_fit_param[0][0][1][2]=3.23798E-2;
263 s_fit_param[0][0][1][3]=0.0;
264 //-par[2]
265 s_fit_param[0][0][2][0]=0.0;
266 s_fit_param[0][0][2][1]=0.0;
267 s_fit_param[0][0][2][2]=0.0;
268 s_fit_param[0][0][2][3]=0.3; // fit value is 2.8898E-1, I use 0.3
269 //-par[3]
270 s_fit_param[0][0][3][0]=9.70055E1;
271 s_fit_param[0][0][3][1]=6.46175E1;
272 s_fit_param[0][0][3][2]=3.20679E-2;
273 s_fit_param[0][0][3][3]=0.0;
274 //-par[4]
275 s_fit_param[0][0][4][0]=1.56865;
276 s_fit_param[0][0][4][1]=2.28336E-1;
277 s_fit_param[0][0][4][2]=1.09396E-1;
278 s_fit_param[0][0][4][3]=1.99975E-3;
279 //-par[5]
280 s_fit_param[0][0][5][0]=0.0;
281 s_fit_param[0][0][5][1]=0.0;
282 s_fit_param[0][0][5][2]=0.0;
283 s_fit_param[0][0][5][3]=0.66;
284 //-----------------------------------------------------------------
285 // 1-prong hadronic tau
286 //-par[0]
287 s_fit_param[0][1][0][0]=-2.42674;
288 s_fit_param[0][1][0][1]=7.69124E-1;
289 s_fit_param[0][1][0][2]=0.0;
290 s_fit_param[0][1][0][3]=0.0;
291 //-par[1]
292 s_fit_param[0][1][1][0]=9.52747E1;
293 s_fit_param[0][1][1][1]=1.26319E1;
294 s_fit_param[0][1][1][2]=3.09643E-2;
295 s_fit_param[0][1][1][3]=0.0;
296 //-par[2]
297 s_fit_param[0][1][2][0]=1.71302E1;
298 s_fit_param[0][1][2][1]=3.00455E1;
299 s_fit_param[0][1][2][2]=7.49445E-2;
300 s_fit_param[0][1][2][3]=0.0;
301 //-par[3]
302 s_fit_param[0][1][3][0]=1.06137E2;
303 s_fit_param[0][1][3][1]=6.01548E1;
304 s_fit_param[0][1][3][2]=3.50867E-2;
305 s_fit_param[0][1][3][3]=0.0;
306 //-par[4]
307 s_fit_param[0][1][4][0]=4.26079E-1;
308 s_fit_param[0][1][4][1]=1.76978E-1;
309 s_fit_param[0][1][4][2]=1.43419;
310 s_fit_param[0][1][4][3]=0.0;
311 //-par[5]
312 s_fit_param[0][1][5][0]=0.0;
313 s_fit_param[0][1][5][1]=0.0;
314 s_fit_param[0][1][5][2]=0.0;
315 s_fit_param[0][1][5][3]=0.4;
316 //-----------------------------------------------------------------
317 // 3-prong hadronic tau
318 //-par[0]
319 s_fit_param[0][2][0][0]=-2.43533;
320 s_fit_param[0][2][0][1]=6.12947E-1;
321 s_fit_param[0][2][0][2]=0.0;
322 s_fit_param[0][2][0][3]=0.0;
323 //-par[1]
324 s_fit_param[0][2][1][0]=9.54202;
325 s_fit_param[0][2][1][1]=2.80011E-1;
326 s_fit_param[0][2][1][2]=2.49782E-1;
327 s_fit_param[0][2][1][3]=0.0;
328 //-par[2]
329 s_fit_param[0][2][2][0]=1.61325E1;
330 s_fit_param[0][2][2][1]=1.74892E1;
331 s_fit_param[0][2][2][2]=7.05797E-2;
332 s_fit_param[0][2][2][3]=0.0;
333 //-par[3]
334 s_fit_param[0][2][3][0]=1.17093E2;
335 s_fit_param[0][2][3][1]=4.70000E1;
336 s_fit_param[0][2][3][2]=3.87085E-2;
337 s_fit_param[0][2][3][3]=0.0;
338 //-par[4]
339 s_fit_param[0][2][4][0]=4.16557E-1;
340 s_fit_param[0][2][4][1]=1.58902E-1;
341 s_fit_param[0][2][4][2]=1.53516;
342 s_fit_param[0][2][4][3]=0.0;
343 //-par[5]
344 s_fit_param[0][2][5][0]=0.0;
345 s_fit_param[0][2][5][1]=0.0;
346 s_fit_param[0][2][5][2]=0.0;
347 s_fit_param[0][2][5][3]=0.95;
348
349
351 // [tau_type][parLG][par]
352 // leptonic tau
353 //-par[0]
354 s_fit_param[1][0][0][0]=-9.82013E-1;
355 s_fit_param[1][0][0][1]=9.09874E-1;
356 s_fit_param[1][0][0][2]=0.0;
357 s_fit_param[1][0][0][3]=0.0;
358 s_fit_param[1][0][0][4]=0.0;
359 //-par[1]
360 s_fit_param[1][0][1][0]=9.96303E1;
361 s_fit_param[1][0][1][1]=1.68873E1;
362 s_fit_param[1][0][1][2]=3.23798E-2;
363 s_fit_param[1][0][1][3]=0.0;
364 s_fit_param[1][0][1][4]=0.0;
365 //-par[2]
366 s_fit_param[1][0][2][0]=0.0;
367 s_fit_param[1][0][2][1]=0.0;
368 s_fit_param[1][0][2][2]=0.0;
369 s_fit_param[1][0][2][3]=0.3; // fit value is 2.8898E-1, I use 0.3
370 s_fit_param[1][0][2][4]=0.0;
371 //-par[3]
372 s_fit_param[1][0][3][0]=9.70055E1;
373 s_fit_param[1][0][3][1]=6.46175E1;
374 s_fit_param[1][0][3][2]=3.20679E-2;
375 s_fit_param[1][0][3][3]=0.0;
376 s_fit_param[1][0][3][4]=0.0;
377 //-par[4]
378 s_fit_param[1][0][4][0]=1.56865;
379 s_fit_param[1][0][4][1]=2.28336E-1;
380 s_fit_param[1][0][4][2]=1.09396E-1;
381 s_fit_param[1][0][4][3]=1.99975E-3;
382 s_fit_param[1][0][4][4]=0.0;
383 //-par[5]
384 s_fit_param[1][0][5][0]=0.0;
385 s_fit_param[1][0][5][1]=0.0;
386 s_fit_param[1][0][5][2]=0.0;
387 s_fit_param[1][0][5][3]=0.66;
388 s_fit_param[1][0][5][4]=0.0;
389 //-----------------------------------------------------------------
390 //-----------------------
391 // Only hadronic tau's were re-parametrized in MC12. The parameterization now
392 // goes to P(tau)=1 TeV.
393 //-----------------------------------------------------------------
394 // 1-prong hadronic tau
395 //---par[0]
396 s_fit_param[1][1][0][0]=0.7568;
397 s_fit_param[1][1][0][1]=-0.0001469;
398 s_fit_param[1][1][0][2]=5.413E-7;
399 s_fit_param[1][1][0][3]=-6.754E-10;
400 s_fit_param[1][1][0][4]=2.269E-13;
401 //---par[1]
402 s_fit_param[1][1][1][0]=-0.0288208;
403 s_fit_param[1][1][1][1]=0.134174;
404 s_fit_param[1][1][1][2]=-142.588;
405 s_fit_param[1][1][1][3]=-0.00035606;
406 s_fit_param[1][1][1][4]=-6.94567E-20;
407 //---par[2]
408 s_fit_param[1][1][2][0]=-0.00468927;
409 s_fit_param[1][1][2][1]=0.0378737;
410 s_fit_param[1][1][2][2]=-260.284;
411 s_fit_param[1][1][2][3]=0.00241158;
412 s_fit_param[1][1][2][4]=-6.01766E-7;
413 //---par[3]
414 s_fit_param[1][1][3][0]=-0.170424;
415 s_fit_param[1][1][3][1]=0.135764;
416 s_fit_param[1][1][3][2]=-50.2361;
417 s_fit_param[1][1][3][3]=0.00735544;
418 s_fit_param[1][1][3][4]=-7.34073E-6;
419 //---par[4]
420 s_fit_param[1][1][4][0]=-0.0081364;
421 s_fit_param[1][1][4][1]=0.0391428;
422 s_fit_param[1][1][4][2]=-141.936;
423 s_fit_param[1][1][4][3]=0.0035034;
424 s_fit_param[1][1][4][4]=-1.21956E-6;
425 //-par[5]
426 s_fit_param[1][1][5][0]=0.0;
427 s_fit_param[1][1][5][1]=0.0;
428 s_fit_param[1][1][5][2]=0.0;
429 s_fit_param[1][1][5][3]=0.624*0.00125; // multiplied by a bin size
430 s_fit_param[1][1][5][4]=0.0;
431 //-----------------------------------------------------------------
432 // 3-prong hadronic tau
433 //---par[0]
434 s_fit_param[1][2][0][0]=0.7562;
435 s_fit_param[1][2][0][1]=-1.168E-5;
436 s_fit_param[1][2][0][2]=0.0;
437 s_fit_param[1][2][0][3]=0.0;
438 s_fit_param[1][2][0][4]=0.0;
439 //---par[1]
440 s_fit_param[1][2][1][0]=-0.0420458;
441 s_fit_param[1][2][1][1]=0.15917;
442 s_fit_param[1][2][1][2]=-80.3259;
443 s_fit_param[1][2][1][3]=0.000125729;
444 s_fit_param[1][2][1][4]=-2.43945E-18;
445 //---par[2]
446 s_fit_param[1][2][2][0]=-0.0216898;
447 s_fit_param[1][2][2][1]=0.0243497;
448 s_fit_param[1][2][2][2]=-63.8273;
449 s_fit_param[1][2][2][3]=0.0148339;
450 s_fit_param[1][2][2][4]=-4.45351E-6;
451 //---par[3]
452 s_fit_param[1][2][3][0]=-0.0879411;
453 s_fit_param[1][2][3][1]=0.110092;
454 s_fit_param[1][2][3][2]=-75.4901;
455 s_fit_param[1][2][3][3]=0.0116915;
456 s_fit_param[1][2][3][4]=-1E-5;
457 //---par[4]
458 s_fit_param[1][2][4][0]=-0.0118324;
459 s_fit_param[1][2][4][1]=0.0280538;
460 s_fit_param[1][2][4][2]=-85.127;
461 s_fit_param[1][2][4][3]=0.00724948;
462 s_fit_param[1][2][4][4]=-2.38792E-6;
463 //-par[5]
464 s_fit_param[1][2][5][0]=0.0;
465 s_fit_param[1][2][5][1]=0.0;
466 s_fit_param[1][2][5][2]=0.0;
467 s_fit_param[1][2][5][3]=0.6167*0.00125; // multiplied by a bin size
468 s_fit_param[1][2][5][4]=0.0;
469
470}
471
472// Default Destructor
475
476double MissingMassProb::apply(MissingMassInput& preparedInput, const int & tau_type1, const int & tau_type2, const PtEtaPhiMVector & tauvec1, const PtEtaPhiMVector & tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector & nuvec2, bool constant, bool oneTau, bool twoTau) {
477 double prob = 1.;
478 if (constant == true) {
479 for (auto& f: m_probListConstant) {
480 prob*=f(preparedInput, tau_type1, tau_type2, tauvec1, tauvec2, nuvec1, nuvec2);
481 }
482 } else if (oneTau == true) {
483 for (auto& f: m_probListOneTau) {
484 prob*=f(preparedInput, tau_type1, tau_type2, tauvec1, tauvec2, nuvec1, nuvec2);
485 }
486 } else if (twoTau == true) {
487 for (auto& f: m_probListTwoTau) {
488 prob*=f(preparedInput, tau_type1, tau_type2, tauvec1, tauvec2, nuvec1, nuvec2);
489 }
490 }
491 return prob;
492}
493
494
495double MissingMassProb::MetProbability(MissingMassInput& preparedInput, const double & met1,const double & met2,const double & MetSigma1,const double & MetSigma2) {
496
497
498 double metprob;
499 if(MetSigma1>1.0 && MetSigma2>1.0) // it doesn't make sense if MET resolution sigma is <1 GeV
500 {
501 //SpeedUp
502 metprob=exp(-0.5*(met1*met1/(MetSigma1*MetSigma1)+met2*met2/(MetSigma2*MetSigma2)))/(MetSigma1*MetSigma2*2*TMath::Pi());
503 }
504 else
505 {
506 if(preparedInput.m_fUseVerbose==1) Warning("DiTauMassTools", "MissingMassCalculator::MetProbability: either MetSigma1 or MetSigma2 are <1 GeV--- too low, returning prob=1");
507 metprob=1.;
508 }
509
510
511 return metprob;
512
513
514}
515
517{
518 double proba=1.;
519 double metprob;
520
521 // deltaMEt is the difference between the neutrino sum and the MEt (or -HT if useHT),
522 //corrected possibly from tau E scanning
523
524 double deltaMetX=preparedInput.m_metVec.X()-preparedInput.m_inputMEtX;
525 double deltaMetY=preparedInput.m_metVec.Y()-preparedInput.m_inputMEtY;
526
527 // possibly correct for subtract tau scanning here
528 // const double met_smearL=(deltaMetVec.X()*m_metCovPhiCos+deltaMetVec.Y()*m_metCovPhiSin;
529 // const double met_smearP=-deltaMetVec.X()*m_metCovPhiSin+deltaMetVec.Y()*m_metCovPhiCos;
530
531 // rotate into error ellipse axis
532 const double met_smearL=deltaMetX*cos(preparedInput.m_METcovphi)+deltaMetY*sin(preparedInput.m_METcovphi);
533 const double met_smearP=-deltaMetX*sin(preparedInput.m_METcovphi)+deltaMetY*cos(preparedInput.m_METcovphi);
534
535
536 if (m_UseHT)
537 {
538 if ( preparedInput.m_tauTypes==TauTypes::hh ) {
539
540 metprob=MHtProbabilityHH(preparedInput, met_smearL,met_smearP,preparedInput.m_inputMEtT,preparedInput.m_MEtT,preparedInput.m_htOffset); // for had-had
541 }
542 else {
543 metprob=MHtProbability(preparedInput, met_smearL,met_smearP,preparedInput.m_inputMEtT,preparedInput.m_MEtT,preparedInput.m_htOffset); // for lep-had Winter 2012 analysis
544 }
545 }
546 else {
547 metprob=MetProbability(preparedInput, met_smearL,met_smearP,preparedInput.m_METsigmaL,preparedInput.m_METsigmaP);
548 }
549
550 proba=metprob;
551
552 return proba;
553}
554
555//------------------- simple TauProbability for LFV
556double MissingMassProb::TauProbabilityLFV(MissingMassInput& preparedInput, const int & type1, const PtEtaPhiMVector & vis1, const PtEtaPhiMVector & nu1)
557{
558 double prob=1.0;
559 if(m_fUseTauProbability==0) return prob; // don't apply TauProbability
560 double prob1=1.0;
561 const double mtau=ParticleConstants::tauMassInMeV / GEV;
562 const double R1=nu1.E()/vis1.E();
563 //--- dealing with 1st tau
564 double m1=nu1.M();
565 double m2=vis1.M();
566 double E1=0.5*(mtau*mtau+m1*m1-m2*m2)/mtau;
567 double E2=mtau-E1;
568 if(E1<=m1 || E1>=mtau)
569 {
570 if(preparedInput.m_fUseVerbose==1) Warning("DiTauMassTools", "Warning in MissingMassCalculator::TauProbability: bad E1, returning 0 ");
571 return 0.0;
572 }
573 if(E2<=m2 || E2>=mtau)
574 {
575 if(preparedInput.m_fUseVerbose==1) Warning("DiTauMassTools", "Warning in MissingMassCalculator::TauProbability: bad E2, returning 0 ");
576 return 0.0;
577 }
578 preparedInput.m_tlv_tmp.SetPxPyPzE(0.,0.,0.,0.);
579 preparedInput.m_tlv_tmp+=nu1;
580 preparedInput.m_tlv_tmp+=vis1;
581 // double p=(nu1+vis1).P();
582 double p=preparedInput.m_tlv_tmp.P();
583 double V=p/sqrt(p*p+mtau*mtau);
584 double p0;
585 if(type1==8) p0=sqrt(E2*E2-m2*m2); // leptonic tau
586 else p0=E1; // hadronic tau
587 prob1=0.5*mtau/(p0*V*pow(R1+1.0,2));
588 // avoid too large values
589 prob=std::min(prob1,1.);
590 return prob;
591}
592
593double MissingMassProb::TauProbability(MissingMassInput& preparedInput, const int & type1, const PtEtaPhiMVector & vis1, const PtEtaPhiMVector & nu1,
594 const int & type2, const PtEtaPhiMVector & vis2, const PtEtaPhiMVector & nu2)
595{
596 double prob=1.0;
597 if(m_fUseTauProbability==0) return prob; // don't apply TauProbability
598 double prob1=1.0;
599 double prob2=1.0;
600 const double mtau=ParticleConstants::tauMassInMeV / GEV;
601 const double R1=nu1.E()/vis1.E();
602 const double R2=nu2.E()/vis2.E();
603 //--- dealing with 1st tau
604 double m1=nu1.M();
605 double m2=vis1.M();
606 double E1=0.5*(mtau*mtau+m1*m1-m2*m2)/mtau;
607 double E2=mtau-E1;
608 if(E1<=m1 || E1>=mtau)
609 {
610 if(preparedInput.m_fUseVerbose==1) Warning("DiTauMassTools", "Warning in MissingMassCalculator::TauProbability: bad E1, returning 0 ");
611 return 0.0;
612 }
613 if(E2<=m2 || E2>=mtau)
614 {
615 if(preparedInput.m_fUseVerbose==1) Warning("DiTauMassTools", "Warning in MissingMassCalculator::TauProbability: bad E2, returning 0 ");
616 return 0.0;
617 }
618 preparedInput.m_tlv_tmp.SetPxPyPzE(0.,0.,0.,0.);
619 preparedInput.m_tlv_tmp+=nu1;
620 preparedInput.m_tlv_tmp+=vis1;
621 // double p=(nu1+vis1).P();
622 double p=preparedInput.m_tlv_tmp.P();
623 double V=p/sqrt(p*p+mtau*mtau);
624 double p0;
625 if(type1==8) p0=sqrt(E2*E2-m2*m2); // leptonic tau
626 else p0=E1; // hadronic tau
627 prob1=0.5*mtau/(p0*V*pow(R1+1.0,2));
628 // avoid too large values
629 prob1=std::min(prob1,1.);
630
631
632 //--- dealing with 2nd tau
633 m1=nu2.M();
634 m2=vis2.M();
635 E1=0.5*(mtau*mtau+m1*m1-m2*m2)/mtau;
636 E2=mtau-E1;
637 if(E1<=m1 || E1>=mtau)
638 {
639 if(preparedInput.m_fUseVerbose==1) Warning("DiTauMassTools", "Warning in MissingMassCalculator::TauProbability: bad E1, returning 0 ");
640 return 0.0;
641 }
642 if(E2<=m2 || E2>=mtau)
643 {
644 if(preparedInput.m_fUseVerbose==1) Warning("DiTauMassTools", "Warning in MissingMassCalculator::TauProbability: bad E2, returning 0 ");
645 return 0.0;
646 }
647 preparedInput.m_tlv_tmp.SetPxPyPzE(0.,0.,0.,0.);
648 preparedInput.m_tlv_tmp+=nu2;
649 preparedInput.m_tlv_tmp+=vis2;
650 // p=(nu2+vis2).P();
651 p=preparedInput.m_tlv_tmp.P();
652
653
654 V=p/sqrt(p*p+mtau*mtau);
655 if(type2==8) p0=sqrt(E2*E2-m2*m2); // leptonic tau
656 else p0=E1; // hadronic tau
657 prob2=0.5*mtau/(p0*V*pow(R2+1.0,2));
658 // avoid too large values
659 prob2=std::min(prob2,1.);
660 prob=prob1*prob2;
661 return prob;
662}
663
664
665// --------- Updated version of TauProbability for lep-had events with Njet25=0, takes into account Winter-2012 analysis cuts
666double MissingMassProb::TauProbability(MissingMassInput& preparedInput, const int & type1, const PtEtaPhiMVector & vis1, const PtEtaPhiMVector & nu1,
667 const int & type2, const PtEtaPhiMVector & vis2, const PtEtaPhiMVector & nu2, const double & detmet) {
668 double prob=1.0;
669
670 if(m_fUseTauProbability==0) return prob; // don't apply TauProbability
671
672 if(m_UseHT)
673 {
674 if(detmet<20.0) // low MET Njet=0 category
675 {
676 const double R1=nu1.P()/vis1.P();
677 const double R2=nu2.P()/vis2.P();
678 const double lep_p1[4]={0.417,0.64,0.52,0.678};
679 const double lep_p2[4]={0.23,0.17,0.315,0.319};
680 const double lep_p3[4]={0.18,0.33,0.41,0.299};
681 const double lep_p4[4]={0.033,0.109,0.129,0.096};
682 const double lep_p5[4]={0.145,0.107,0.259,0.304};
683 int ind=3;
684 int indT=3;
685 const double n_1pr[4]={-0.15,-0.13,-0.25,-0.114};
686 const double s_1pr[4]={0.40,0.54,0.62,0.57};
687 const double n_3pr[4]={-1.08,-1.57,-0.46,-0.39};
688 const double s_3pr[4]={0.53,0.85,0.61,0.53};
689 double Ptau=0.0;
690 double Plep=0.0;
691 if(type1>=0 && type1<=5)
692 {
693 Ptau=(nu1+vis1).P();
694 Plep=(nu2+vis2).P();
695 }
696 if(type2>=0 && type2<=5)
697 {
698 Ptau=(nu2+vis2).P();
699 Plep=(nu1+vis1).P();
700 }
701 if(Plep<50.0 && Plep>=45.0) ind=2;
702 if(Plep<45.0 && Plep>=40.0) ind=1;
703 if(Plep<40.0) ind=0;
704 if(Ptau<50.0 && Ptau>=45.0) indT=2;
705 if(Ptau<45.0 && Ptau>=40.0) indT=1;
706 if(Ptau<40.0) indT=0;
707 if(type1==8) prob=prob*(lep_p5[ind]*TMath::Gaus(R1,lep_p1[ind],lep_p2[ind])+TMath::Landau(R1,lep_p3[ind],lep_p4[ind]))/(1+lep_p5[ind]);
708 if(type2==8) prob=prob*(lep_p5[ind]*TMath::Gaus(R2,lep_p1[ind],lep_p2[ind])+TMath::Landau(R2,lep_p3[ind],lep_p4[ind]))/(1+lep_p5[ind]);
709
710 if(type1>=0 && type1<=2) prob=prob*TMath::Gaus(R1,n_1pr[indT],s_1pr[indT]);
711 if(type2>=0 && type2<=2) prob=prob*TMath::Gaus(R2,n_1pr[indT],s_1pr[indT]);
712 if(type1>=3 && type1<=5) prob=prob*TMath::Gaus(R1,n_3pr[indT],s_3pr[indT]);
713 if(type2>=3 && type2<=5) prob=prob*TMath::Gaus(R2,n_3pr[indT],s_3pr[indT]);
714
715 }
716 else // high MET Njet=0 category
717 {
718 const double R1=nu1.P()/vis1.P();
719 const double R2=nu2.P()/vis2.P();
720 const double lep_p1[4]={0.441,0.64,0.79,0.8692};
721 const double lep_p2[4]={0.218,0.28,0.29,0.3304};
722 const double lep_p3[4]={0.256,0.33,0.395,0.4105};
723 const double lep_p4[4]={0.048,0.072,0.148,0.1335};
724 const double lep_p5[4]={0.25,0.68,0.10,0.2872};
725 int ind=3;
726 const double p_1prong=-3.706;
727 const double p_3prong=-5.845;
728 double Ptau=0.0;
729 double Plep=0.0;
730 if(type1>=0 && type1<=5)
731 {
732 Ptau=(nu1+vis1).P();
733 Plep=(nu2+vis2).P();
734 }
735 if(type2>=0 && type2<=5)
736 {
737 Ptau=(nu2+vis2).P();
738 Plep=(nu1+vis1).P();
739 }
740 if(Plep<50.0 && Plep>=45.0) ind=2;
741 if(Plep<45.0 && Plep>=40.0) ind=1;
742 if(Plep<40.0) ind=0;
743 const double scale1prong=Ptau>45.0 ? 1.0 : -1.019/((Ptau*0.0074-0.059)*p_1prong);
744 const double scale3prong=Ptau>40.0 ? 1.0 : -1.24/((Ptau*0.0062-0.033)*p_3prong);
745 if(type1==8) prob=prob*(lep_p5[ind]*TMath::Gaus(R1,lep_p1[ind],lep_p2[ind])+TMath::Landau(R1,lep_p3[ind],lep_p4[ind]))/(1+lep_p5[ind]);
746 if(type2==8) prob=prob*(lep_p5[ind]*TMath::Gaus(R2,lep_p1[ind],lep_p2[ind])+TMath::Landau(R2,lep_p3[ind],lep_p4[ind]))/(1+lep_p5[ind]);
747
748 if(type1>=0 && type1<=2) prob=prob*exp(p_1prong*R1*scale1prong)*std::abs(p_1prong*scale1prong)*0.02; // introduced normalization to account for sharpening of probability at low E(tau)
749 if(type2>=0 && type2<=2) prob=prob*exp(p_1prong*R2*scale1prong)*std::abs(p_1prong*scale1prong)*0.02;
750 if(type1>=3 && type1<=5) prob=prob*exp(p_3prong*R1*scale3prong)*std::abs(p_3prong*scale3prong)*0.02;
751 if(type2>=3 && type2<=5) prob=prob*exp(p_3prong*R2*scale3prong)*std::abs(p_3prong*scale3prong)*0.02;
752 }
753 }
754 //----------------- had-had channel ---------------------------------------
755 if( preparedInput.m_tauTypes==TauTypes::hh )
756 {
757
758 if(m_UseHT) // Events with no jets
759 {
760
761 const double R[2]={nu1.P()/vis1.P(),nu2.P()/vis2.P()};
762 const double E[2]={(nu1+vis1).E(),(nu2+vis2).E()};
763 const int tau_type[2]={type1,type2};
764 int order1= vis1.Pt()>vis2.Pt() ? 0 : 1;
765 int order2= vis1.Pt()>vis2.Pt() ? 1 : 0;
766
767 double par_1p[2][6]; // P(tau)-scaling; lead, sub-lead
768 double par_3p[2][6]; // P(tau)-scaling; lead, sub-lead
769
770 par_1p[0][0]=0.1273; par_1p[0][1]=-0.2479; par_1p[0][2]=1.0; par_1p[0][3]=-43.16; par_1p[0][4]=0.0; par_1p[0][5]=0.0;
771 par_1p[1][0]=0.3736; par_1p[1][1]=-1.441; par_1p[1][2]=1.0; par_1p[1][3]=-29.82; par_1p[1][4]=0.0; par_1p[1][5]=0.0;
772 par_3p[0][0]=0.1167; par_3p[0][1]=-0.1388; par_3p[0][2]=1.0; par_3p[0][3]=-44.77; par_3p[0][4]=0.0; par_3p[0][5]=0.0;
773 par_3p[1][0]=0.3056; par_3p[1][1]=-2.18; par_3p[1][2]=1.0; par_3p[1][3]=-19.09; par_3p[1][4]=0.0; par_3p[1][5]=0.0;
774 // parameters for sub-leading tau
775 const double C1p=0.062;
776 const double C3p=0.052;
777 const double G1p=1.055;
778 const double G3p=1.093;
779 // Probability for leading tau
780
781 if( tau_type[order1]>=0 && tau_type[order1]<=2 ) // 1-prong
782 {
783 //double x=std::min(300.,std::max(E[order1],45.0));
784 // 50 to be safe. TO be finalised.
785 // double x=std::min(300.,std::max(E[order1],50.0));
786 double x=std::min(E[order1],300.0);
787 const double slope=par_1p[0][0]+par_1p[0][1]/(par_1p[0][2]*x+par_1p[0][3])+par_1p[0][4]*x > 0.01 ?
788 par_1p[0][0]+par_1p[0][1]/(par_1p[0][2]*x+par_1p[0][3])+par_1p[0][4]*x : 0.01;
789 prob=prob*exp(-R[order1]/slope)*0.04/std::abs(slope);
790 }
791 if( tau_type[order1]>=3 && tau_type[order1]<=5 ) // 3-prong
792 {
793 //double x=std::min(300.,std::max(E[order1],45.0));
794 // double x=std::min(300.,std::max(E[order1],50.0));
795 double x=std::min(E[order1],300.0);
796 const double slope=par_3p[0][0]+par_3p[0][1]/(par_3p[0][2]*x+par_3p[0][3])+par_3p[0][4]*x > 0.01 ?
797 par_3p[0][0]+par_3p[0][1]/(par_3p[0][2]*x+par_3p[0][3])+par_3p[0][4]*x : 0.01;
798 prob=prob*exp(-R[order1]/slope)*0.04/std::abs(slope);
799 }
800 // Probability for sub-leading tau
801 if( tau_type[order2]>=0 && tau_type[order2]<=2 ) // 1-prong
802 {
803 const double par[4]={0.1147,-0.09675,-35.0,3.711E-11};
804 double x=std::min(300.,std::max(E[order2],30.0));
805 // double x=std::min(300.,std::max(E[order2],50.0));
806 const double sigma=G1p*(par_1p[1][0]+par_1p[1][1]/(par_1p[1][2]*x+par_1p[1][3])+par_1p[1][4]*x+par_1p[1][5]*x*x) > 0.01 ?
807 G1p*(par_1p[1][0]+par_1p[1][1]/(par_1p[1][2]*x+par_1p[1][3])+par_1p[1][4]*x+par_1p[1][5]*x*x) : 0.01;
808 if(x<36.0) x=36.0;
809 const double mean=par[0]+par[1]/(x+par[2])+par[3]*pow(x,4);
810 prob=prob*C1p*TMath::Gaus(R[order2],mean,sigma);
811 }
812 if( tau_type[order2]>=3 && tau_type[order2]<=5 ) // 3-prong
813 {
814 double x=std::min(300.,std::max(E[order2],20.0));
815 // double x=std::min(300.,std::max(E[order2],50.0));
816 const double sigma=G3p*(par_3p[1][0]+par_3p[1][1]/(par_3p[1][2]*x+par_3p[1][3])+par_3p[1][4]*x+par_3p[1][5]*x*x) > 0.01 ?
817 G3p*(par_3p[1][0]+par_3p[1][1]/(par_3p[1][2]*x+par_3p[1][3])+par_3p[1][4]*x+par_3p[1][5]*x*x) : 0.01;
818 const double par[4]={0.2302,-2.012,-36.08,-0.000373};
819 if(x<37.0) x=37.0;
820 const double mean=par[0]+par[1]/(x+par[2])+par[3]*x;
821 prob=prob*C3p*TMath::Gaus(R[order2],mean,sigma);
822 }
823 }
824 if(!m_UseHT) // Events with jets
825 {
826 const double R1=nu1.P()/vis1.P();
827 const double R2=nu2.P()/vis2.P();
828 const double E1=(nu1+vis1).E();
829 const double E2=(nu2+vis2).E();
830 int order1= vis1.Pt()>vis2.Pt() ? 0 : 1;
831 int order2= vis1.Pt()>vis2.Pt() ? 1 : 0;
832 const double slope_1p[2]={-3.185,-2.052}; // lead, sub-lead
833 const double slope_3p[2]={-3.876,-2.853}; // lead, sub-lead
834 double par_1p[2][3]; // scaling below 100 GeV; lead, sub-lead
835 double par_3p[2][3]; // scaling below 100 GeV; lead, sub-lead
836 par_1p[0][0]=-0.3745; par_1p[0][1]=0.01417; par_1p[0][2]=-7.285E-5; // [0][i] is always adjusted to match slope at 100 GeV
837 par_1p[1][0]=-0.3683; par_1p[1][1]=0.01807; par_1p[1][2]=-9.514E-5;
838 par_3p[0][0]=-0.3055; par_3p[0][1]=0.01149; par_3p[0][2]=-5.855E-5;
839 par_3p[1][0]=-0.3410; par_3p[1][1]=0.01638; par_3p[1][2]=-9.465E-5;
840 double scale1;
841 double scale2;
842 if(type1>=0 && type1<=2) // 1-prong
843 {
844 scale1=E1>100.0 ? 1.0 : 1.0/std::abs((par_1p[order1][0]+par_1p[order1][1]*E1+par_1p[order1][2]*E1*E1)*slope_1p[order1]);
845 if(scale1<1.0) scale1=1.0;
846 if(scale1>100.0) scale1=100.0;
847 prob=prob*std::abs(slope_1p[order1])*scale1*exp(slope_1p[order1]*scale1*R1)*0.04;
848 }
849 if(type1>=3 && type1<=5) // 3-prong
850 {
851 scale1=E1>100.0 ? 1.0 : 1.0/std::abs((par_3p[order1][0]+par_3p[order1][1]*E1+par_3p[order1][2]*E1*E1)*slope_3p[order1]);
852 if(scale1<1.0) scale1=1.0;
853 if(scale1>100.0) scale1=100.0;
854 prob=prob*std::abs(slope_3p[order1])*scale1*exp(slope_3p[order1]*scale1*R1)*0.04;
855 }
856 if(type2>=0 && type2<=2) // 1-prong
857 {
858 scale2=E2>100.0 ? 1.0 : 1.0/std::abs((par_1p[order2][0]+par_1p[order2][1]*E2+par_1p[order2][2]*E2*E2)*slope_1p[order2]);
859 if(scale2<1.0) scale2=1.0;
860 if(scale2>100.0) scale2=100.0;
861 prob=prob*std::abs(slope_1p[order2])*scale2*exp(slope_1p[order2]*scale2*R2)*0.04;
862 }
863 if(type2>=3 && type2<=5) // 3-prong
864 {
865 scale2=E2>100.0 ? 1.0 : 1.0/std::abs((par_3p[order2][0]+par_3p[order2][1]*E2+par_3p[order2][2]*E2*E2)*slope_3p[order2]);
866 if(scale2<1.0) scale2=1.0;
867 if(scale2>100.0) scale2=100.0;
868 prob=prob*std::abs(slope_3p[order2])*scale2*exp(slope_3p[order2]*scale2*R2)*0.04;
869
870 }
871 }
872
873 }
874 // prob=std::min(prob,1.); // Sasha commented out this line, it was introduced by David. Have to ask about its purpose.
875
876 return prob;
877}
878
879
880// returns Mnu probability according pol6 parameterization
881double MissingMassProb::MnuProbability(MissingMassInput& preparedInput, double mnu, double binsize)
882{
883 double prob=1.0;
884 double norm=4851900.0;
885 double p[7];
886 p[0]=-288.6/norm; p[1]=6.217E4/(2.0*norm); p[2]=2.122E4/(3.0*norm); p[3]=-9.067E4/(4.0*norm);
887 p[4]=1.433E5/(5.0*norm); p[5]=-1.229E5/(6.0*norm); p[6]=3.434E4/(7.0*norm);
888 double int1=0.0;
889 double int2=0.0;
890 double x1= mnu+0.5*binsize < 1.777-0.113 ? mnu+0.5*binsize : 1.777-0.113;
891 double x2= mnu-0.5*binsize > 0.0 ? mnu-0.5*binsize : 0.0;
892 for(int i=0; i<7; i++)
893 {
894 int1=p[i]*pow(x1,i+1)+int1;
895 int2=p[i]*pow(x2,i+1)+int2;
896 }
897 prob=int1-int2;
898 if(prob<0.0)
899 {
900 if(preparedInput.m_fUseVerbose==1) Warning("DiTauMassTools", "Warning in MissingMassCalculator::MnuProbability: negative probability!!! ");
901 return 0.0;
902 }
903 if(prob>1.0)
904 {
905 if(preparedInput.m_fUseVerbose==1) Warning("DiTauMassTools", "Warning in MissingMassCalculator::MnuProbability: probability > 1!!! ");
906 return 1.0;
907 }
908 return prob;
909}
910
911// returns Mnu probability according pol6 parameterization
912double MissingMassProb::MnuProbability(MissingMassInput& preparedInput, double mnu)
913{
914 if(m_fUseMnuProbability==0) return 1.0;
915 double prob=1.0;
916 const double norm=4851900.0;
917 double p[7];
918 p[0]=-288.6; p[1]=6.217E4; p[2]=2.122E4; p[3]=-9.067E4;
919 p[4]=1.433E5; p[5]=-1.229E5; p[6]=3.434E4;
920 double int1=0.0;
921 for(int i=0; i<7; i++)
922 {
923 int1+=p[i]*pow(mnu,i);
924 }
925 prob=int1/norm;
926 if(prob<0.0)
927 {
928 if(preparedInput.m_fUseVerbose==1) Warning("DiTauMassTools", "Warning in MissingMassCalculator::MnuProbability: negative probability!!! ");
929 return 0.0;
930 }
931 if(prob>1.0)
932 {
933 if(preparedInput.m_fUseVerbose==1) Warning("DiTauMassTools", "Warning in MissingMassCalculator::MnuProbability: probability > 1!!! ");
934 return 1.0;
935 }
936 return prob;
937}
938
939double MissingMassProb::MHtProbability(MissingMassInput& preparedInput, const double & d_mhtX, const double & d_mhtY, const double & mht,
940 const double & trueMetGuess, const double & mht_offset) {
941 // all param except trueMetguess unchanged in one event. So can cache agaisnt this one.
942 //disable cache if (trueMetGuess==trueMetGuesscache) return mhtprobcache;
943 double mhtprob;
944 // if(MHtSigma1>0.0 && MHtSigma2>0.0 && MHtGaussFr>0.0)
945
946 // if RANDOMNONUNIF MET already follow the double gaussian parameterisation. So weight should not include it to avoid double counting
947 // formula to be checked IMHO the two gaussian should be correlated
948 mhtprob=exp(-0.5*pow(d_mhtX/preparedInput.m_MHtSigma1,2))+preparedInput.m_MHtGaussFr*exp(-0.5*pow(d_mhtX/preparedInput.m_MHtSigma2,2));
949 mhtprob*=(exp(-0.5*pow(d_mhtY/preparedInput.m_MHtSigma1,2))+preparedInput.m_MHtGaussFr*exp(-0.5*pow(d_mhtY/preparedInput.m_MHtSigma2,2)));
950
951 const double n_arg=(mht-trueMetGuess-mht_offset)/preparedInput.m_MHtSigma1;
952 mhtprob*=exp(-0.25*pow(n_arg,2)); // assuming sqrt(2)*sigma
953 return mhtprob;
954}
955
956double MissingMassProb::MHtProbabilityHH(MissingMassInput& preparedInput, const double & d_mhtX, const double & d_mhtY, const double & mht,
957 const double & trueMetGuess, const double & mht_offset) {
958 double prob=1.0;
959
960 // updated for final cuts, May 21 2012
961 // should be merged
962 prob=prob*(0.0256*TMath::Gaus(d_mhtX,0.0,preparedInput.m_MHtSigma1)+0.01754*TMath::Gaus(d_mhtX,0.0,preparedInput.m_MHtSigma2));
963 prob=prob*(0.0256*TMath::Gaus(d_mhtY,0.0,preparedInput.m_MHtSigma1)+0.01754*TMath::Gaus(d_mhtY,0.0,preparedInput.m_MHtSigma2));
964 const double n_arg=(mht-trueMetGuess-mht_offset)/5.7; // this sigma is different from MHtSigma1; actually it depends on dPhi
965 prob=prob*exp(-0.5*pow(n_arg,2))/(5.7*sqrt(2.0*TMath::Pi())); // assuming sigma from above line
966
967 return prob;
968}
969
970//SpeedUp static instantation
971// first index is the calibration set : 0: MMC2011, 1:MMC2012
972// second index is the decay 0 : lepton, 1 : 1 prong, 2 3 prong
973thread_local double MissingMassProb::s_fit_param[2][3][6][5];
974
975// returns dTheta3D probability based on ATLAS parameterization
976double MissingMassProb::dTheta3d_probabilityFast(MissingMassInput& preparedInput, const int & tau_type,const double & dTheta3d,const double & P_tau) {
977 double prob=1.0E-10;
978 int tau_code; // 0: l, 1:1-prong, 2:3-prong
979 if(tau_type==8) tau_code = 0;
980 else if(tau_type>=0 && tau_type<=2) tau_code = 1;
981 else if(tau_type>=3 && tau_type<=5) tau_code = 2;
982 else if(tau_type==6) return prob;
983 else
984 {
985 Warning("DiTauMassTools", "---- WARNING in MissingMassCalculator::dTheta3d_probabilityFast() ----");
986 Warning("DiTauMassTools", "%s", ("..... wrong tau_type="+std::to_string(tau_type)).c_str());
987 Warning("DiTauMassTools", "%s", ("..... returning prob="+std::to_string(prob)).c_str());
988 Warning("DiTauMassTools", "____________________________________________________________");
989 return prob;
990 }
991
992
993 double myDelThetaParam[6]{};
994
995 for (int i=0;i<6;++i)
996 {
1000 myDelThetaParam[i]=dTheta3Dparam(i,tau_code,P_tau,s_fit_param[1][tau_code][i]);
1001 }
1002 double dTheta3dVal=dTheta3d;
1003
1004 if (tau_type==8) prob=myDelThetaLepFunc(&dTheta3dVal, myDelThetaParam);
1005 else prob=myDelThetaHadFunc(&dTheta3dVal, myDelThetaParam);
1006
1007 if (false)
1008 {
1009
1010 if( preparedInput.m_fUseVerbose==1 && (prob>1.0 || prob<0.0))
1011 {
1012 Warning("DiTauMassTools", "---- WARNING in MissingMassCalculator::dTheta3d_probabilityFast() ----");
1013 Warning("DiTauMassTools", "%s", ("..... wrong probability="+std::to_string(prob)).c_str());
1014 Warning("DiTauMassTools", "%s", ("..... debugging: tau_type="+std::to_string(tau_type)+"dTheta3d="+std::to_string(dTheta3d)+" P_tau="+std::to_string(P_tau)).c_str());
1015 Warning("DiTauMassTools", "____________________________________________________________");
1016 prob=1.0E-10;
1017 }
1018 }
1019
1020 return prob;
1021}
1022
1023// dTheta probability density function for hadronic taus
1024double MissingMassProb::myDelThetaHadFunc(double *x, double *par)
1025{
1026 double fitval=1.0E-10;
1027 if(x[0]>TMath::Pi() || x[0]<0.0) return fitval;
1028 const double arg=x[0];
1029 const double arg_L=arg;
1030 const double mean=par[1];
1031 const double sigmaG=par[2];
1032 const double mpv=par[3];
1033 const double sigmaL=par[4];
1034
1038 const double norm=sqrt(2.0*TMath::Pi());
1039 const double g1=TMath::Gaus(arg,mean,sigmaG)/norm;
1040 const double g2=TMath::Landau(arg_L,mpv,sigmaL)/norm;
1041 fitval=par[0]*g1/sigmaG+par[5]*g2/sigmaL;
1042 }
1043
1044 if(fitval<0.0) return 0.0;
1045 return fitval;
1046}
1047
1048// dTheta probability density function for leptonic taus
1049double MissingMassProb::myDelThetaLepFunc(double *x, double *par)
1050{
1051 double fitval=1.0E-10;
1052 if(x[0]>TMath::Pi() || x[0]<0.0) return fitval;
1053 double arg=x[0]/par[1];
1054
1055 double normL=par[5];
1056 if(normL<0.0) normL=0.0;
1057
1058 if(arg<1) arg=sqrt(std::abs(arg));
1059 else arg=arg*arg;
1060 const double arg_L=x[0];
1061 const double mean=1.0;
1062 const double sigmaG=par[2];
1063 const double mpv=par[3];
1064 const double sigmaL=par[4];
1065 const double g1=normL*TMath::Gaus(arg,mean,sigmaG);
1066 const double g2=TMath::Landau(arg_L,mpv,sigmaL);
1067 fitval=par[0]*(g1+g2)/(1.0+normL);
1068 if(fitval<0.0) return 0.0;
1069 return fitval;
1070}
1071
1072// returns parameters for dTheta3D pdf
1073double MissingMassProb::dTheta3Dparam(const int & parInd, const int & tau_type, const double & P_tau, const double *par) {
1074 //tau_type 0: l, 1:1-prong, 3:3-prong
1075 if(P_tau<0.0) return 0.0;
1076
1077
1078 if(parInd==0) {
1082 return (par[0]+par[1]*P_tau+par[2]*pow(P_tau,2)+par[3]*pow(P_tau,3)+par[4]*pow(P_tau,4))*0.00125;
1083 }
1084 }
1085 else { // parInd==0
1089 if(tau_type==0) return par[0]*(exp(-par[1]*P_tau)+par[2]/P_tau)+par[3]+par[4]*P_tau;
1090 else return par[0]*(exp(-par[1]*sqrt(P_tau))+par[2]/P_tau)+par[3]+par[4]*P_tau;
1091 }
1092 }
1093 return 0.;
1094}
1095
1097 // compute MET resolution (eventually use HT)
1098 if(preparedInput.m_METsigmaP<0.1 || preparedInput.m_METsigmaL<0.1)
1099 {
1101 {
1102 if(preparedInput.m_fUseVerbose==1) { Info("DiTauMassTools", "Attempting to set LFV MMC settings"); }
1103 double mT1 = mT(preparedInput.m_vistau1,preparedInput.m_MetVec);
1104 double mT2 = mT(preparedInput.m_vistau2,preparedInput.m_MetVec);
1105 int sr_switch = 0;
1106 if(preparedInput.m_vistau1.M()<0.12 && preparedInput.m_vistau2.M()<0.12) // lep-lep case
1107 {
1108 if(preparedInput.m_LFVmode==0) // e+tau(->mu) case
1109 {
1110 if(preparedInput.m_vistau1.M()<0.05 && preparedInput.m_vistau2.M()>0.05)
1111 {
1112 if(mT1>mT2) sr_switch = 0; // SR1
1113 else sr_switch = 1; // SR2
1114 }
1115 else
1116 {
1117 if(mT1>mT2) sr_switch = 1; // SR2
1118 else sr_switch = 0; // SR1
1119 }
1120 }
1121 if(preparedInput.m_LFVmode==1) // mu+tau(->e) case
1122 {
1123 if(preparedInput.m_vistau1.M()>0.05 && preparedInput.m_vistau2.M()<0.05)
1124 {
1125 if(mT1>mT2) sr_switch = 0; // SR1
1126 else sr_switch = 1; // SR2
1127 }
1128 else
1129 {
1130 if(mT1>mT2) sr_switch = 1; // SR2
1131 else sr_switch = 0; // SR1
1132 }
1133 }
1134 }
1135 if((preparedInput.m_vistau1.M()<0.12 && preparedInput.m_vistau2.M()>0.12) || (preparedInput.m_vistau2.M()<0.12 && preparedInput.m_vistau1.M()>0.12)) // lep-had case
1136 {
1137 if(preparedInput.m_vistau1.M()<0.12 && preparedInput.m_vistau2.M()>0.12)
1138 {
1139 if(mT1>mT2) sr_switch = 0; // SR1
1140 else sr_switch = 1; // SR2
1141 }
1142 else
1143 {
1144 if(mT1>mT2) sr_switch = 1; // SR2
1145 else sr_switch = 0; // SR1
1146 }
1147 }
1148
1149 m_UseHT = false;
1150 if(preparedInput.m_Njet25==0) // 0-jet
1151 {
1152 double sigmaSyst = 0.10; // 10% systematics for now (be conservative)
1153 double METresScale;
1154 double METoffset;
1155 if(sr_switch==0)
1156 {
1157 METresScale = 0.41*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1158 METoffset = 7.36*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1159 }
1160 else
1161 {
1162 METresScale = 0.34*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1163 METoffset = 6.61*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1164 }
1165 if(preparedInput.m_fUseVerbose==1) {
1166 Info("DiTauMassTools", "%s", ("SumEt = "+std::to_string(preparedInput.m_SumEt)).c_str());
1167 Info("DiTauMassTools", "%s", ("METoffset = "+std::to_string(METoffset)).c_str());
1168 Info("DiTauMassTools", "%s", ("METresScale = "+std::to_string(METresScale)).c_str());
1169 }
1170
1171 double sigma = preparedInput.m_SumEt>0.0 ? METoffset+METresScale*sqrt(preparedInput.m_SumEt) : METoffset;
1172 preparedInput.m_METsigmaP = sigma;
1173 preparedInput.m_METsigmaL = sigma;
1174 if(preparedInput.m_fUseVerbose==1) {
1175 Info("DiTauMassTools", "%s", ("=> METsigmaP = "+std::to_string(preparedInput.m_METsigmaP)).c_str());
1176 Info("DiTauMassTools", "%s", ("=> METsigmaL = "+std::to_string(preparedInput.m_METsigmaL)).c_str());
1177 }
1178 }
1179 if(preparedInput.m_Njet25>0) // Inclusive 1-jet
1180 {
1181 double sigmaSyst = 0.10; // 10% systematics for now (be conservative)
1182 double sigma = 0.;
1183 double METresScale;
1184 double METoffset;
1185 if(sr_switch==0)
1186 {
1187 METresScale = 0.38*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1188 METoffset = 7.96*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1189 }
1190 else
1191 {
1192 METresScale = 0.39*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1193 METoffset = 6.61*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1194 }
1195
1196 // MET resolution can't be perfect in presence of other objects (i.e., electrons, jets, taus), so assume minSumEt = 5.0 for now
1197 sigma = preparedInput.m_SumEt>0.0 ? METoffset+METresScale*sqrt(preparedInput.m_SumEt) : METoffset;
1198 preparedInput.m_METsigmaP = sigma;
1199 preparedInput.m_METsigmaL = sigma;
1200 } // Njet25>0
1201 }
1202 else //LFV
1203 {
1204 //DRDRMERGE end addition
1205
1206 if(preparedInput.m_METScanScheme==1) // default for Winter 2012 and further
1207 {
1208 //LEP-HAD
1209 if ( preparedInput.m_tauTypes==TauTypes::lh ) // lephad case
1210 {
1211 //0-jet
1212 if(preparedInput.m_Njet25==0)//0-jet
1213 {
1214 // placeholder for 2019 tune
1217 if(preparedInput.m_MetVec.R()<20.0) // 0-jet low MET case
1218 {
1219 if(std::abs(preparedInput.m_DelPhiTT)>2.95 && m_allowUseHT) // use mHt only if dPhi(lep-tau)>2.95
1220 {
1221 m_UseHT = true;
1222 // giving priority to external settings
1223 if(preparedInput.m_MHtSigma1<0.0) preparedInput.m_MHtSigma1 = 4.822;
1224 if(preparedInput.m_MHtSigma2<0.0) preparedInput.m_MHtSigma2 = 10.31;
1225 if(preparedInput.m_MHtGaussFr<0.0) preparedInput.m_MHtGaussFr = 6.34E-5;
1226 }
1227 else
1228 {
1229 m_UseHT = false;
1230 double sigmaSyst = 0.10; // 10% systematics for now (be conservative)
1231 double METresScale = 0.32*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1232 double METoffset = 5.38*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1233 double sigma = preparedInput.m_SumEt>0.0 ? METoffset+METresScale*sqrt(preparedInput.m_SumEt) : METoffset;
1234 preparedInput.m_METsigmaP = sigma;
1235 preparedInput.m_METsigmaL = sigma;
1236 }
1237 }
1238 else // 0-jet high MET case
1239 {
1240 if(std::abs(preparedInput.m_DelPhiTT)>2.8 && m_allowUseHT) // use mHt only if dPhi(lep-tau)>2.8
1241 {
1242 m_UseHT = true;
1243 // giving priority to external settings
1244 if(preparedInput.m_MHtSigma1<0.0) preparedInput.m_MHtSigma1 = 7.5;
1245 if(preparedInput.m_MHtSigma2<0.0) preparedInput.m_MHtSigma2 = 13.51;
1246 if(preparedInput.m_MHtGaussFr<0.0) preparedInput.m_MHtGaussFr = 6.81E-4;
1247 preparedInput.m_METsigmaP = preparedInput.m_MHtSigma2; // sigma of 2nd Gaussian for missing Ht resolution
1248 preparedInput.m_METsigmaL = preparedInput.m_MHtSigma2;
1249 }
1250 else
1251 {
1252 m_UseHT = false;
1253 double sigmaSyst = 0.10; // 10% systematics for now (be conservative)
1254 double METresScale = 0.87*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1255 double METoffset = 4.16*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1256 double sigma = preparedInput.m_SumEt>0.0 ? METoffset+METresScale*sqrt(preparedInput.m_SumEt) : METoffset;
1257 preparedInput.m_METsigmaP = sigma;
1258 preparedInput.m_METsigmaL = sigma;
1259 }
1260 } // high MET
1261 } // MMC2019
1262 // 2015 high-mass tune; avergare MET resolution for Mh=600,1000 mass points
1264 {
1265 m_UseHT = false;
1266 double sigmaSyst = 0.10; // 10% systematics for now (be conservative)
1267 double METresScale = 0.65*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1268 double METoffset = 5.0*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1269 double sigma = preparedInput.m_SumEt>0.0 ? METoffset+METresScale*sqrt(preparedInput.m_SumEt) : METoffset;
1270 preparedInput.m_METsigmaP = sigma;
1271 preparedInput.m_METsigmaL = sigma;
1272 } // MMC2015HIGHMASS
1273 } // 0 jet
1274 //1-jet
1275 else if(preparedInput.m_Njet25>0) // Inclusive 1-jet and VBF lep-had categories for Winter 2012
1276 {
1277 double sigmaSyst=0.10; // 10% systematics for now (be conservative)
1278 double sigma=0.;
1279 // 2015 high-mass tune; average MET resolution for Mh=400,600 mass points (they look consistent);
1281 {
1282 double METresScale=0.86*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1283 double METoffset=3.0*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1284 // MET resolution can't be perfect in presence of other objects (i.e., electrons, jets, taus), so assume minSumEt=5.0 for now
1285 sigma= preparedInput.m_SumEt>0.0 ? METoffset+METresScale*sqrt(preparedInput.m_SumEt) : METoffset;
1286 }
1287 //2019
1290 {
1291 double x = preparedInput.m_DelPhiTT;
1292 double dphi_scale = x > 0.3 ? 0.9429 - 0.059*x + 0.054*x*x : 0.728;
1293 double METoffset = 1.875*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1294 double METresScale1 = 8.914*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1295 double METresScale2 = -8.53*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1296
1297
1298 sigma = preparedInput.m_SumEt > 80.0 ? METoffset + METresScale1*TMath::Log(sqrt(preparedInput.m_SumEt)+METresScale2) : 5.0;
1299 sigma = sigma * dphi_scale;
1300 }
1301 //
1302
1303 preparedInput.m_METsigmaP=sigma;
1304 preparedInput.m_METsigmaL=sigma;
1305 } // Njet25>0
1306
1307 } // lep-had
1308
1309 //HAD-HAD
1310 else if(preparedInput.m_tauTypes==TauTypes::hh) // had-had events
1311 {
1312 if(preparedInput.m_Njet25==0 && m_mmcCalibrationSet==MMCCalibrationSet::MMC2015HIGHMASS) //0-jet high mass hadhad
1313 {
1314 // 2015 high-mass tune; average of all mass points
1315 // double METresScale=-1.;
1316 // double METoffset=-1.;
1317 double sigmaSyst=0.10; // 10% systematics for now (be conservative)
1318
1319 double METresScale=0.9*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1320 double METoffset=-1.8*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1321 double sigma= preparedInput.m_SumEt>0.0 ? METoffset+METresScale*sqrt(preparedInput.m_SumEt) : std::abs(METoffset);
1322 preparedInput.m_METsigmaP=sigma;
1323 preparedInput.m_METsigmaL=sigma;
1324
1325 }
1326 else if(preparedInput.m_Njet25==0 &&
1329 {
1330 double sigmaSyst=0.10; // 10% systematics for now (be conservative)
1331 double x = preparedInput.m_DelPhiTT;
1332 double dphi_scale = x > 2.5 ? 11.0796 - 4.61236*x + 0.423617*x*x : 2.;
1333 double METoffset = -8.51013*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1334 double METresScale1 = 8.54378*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1335 double METresScale2 = -3.97146*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1336 double sigma= preparedInput.m_SumEt>80.0 ? METoffset+METresScale1*TMath::Log(sqrt(preparedInput.m_SumEt)+METresScale2) : 5.;
1337 sigma = sigma*dphi_scale;
1338
1339 preparedInput.m_METsigmaP=sigma;
1340 preparedInput.m_METsigmaL=sigma;
1341
1342 }
1343 else if(preparedInput.m_Njet25==0 && m_allowUseHT) // 0-jet high MET had-had category for Winter 2012
1344 {
1345
1346 m_UseHT=true; // uncomment this line to enable HT also for HH (crucial)
1347 // updated for final cuts, may 21 2012
1348 if(preparedInput.m_MHtSigma1<0.0) preparedInput.m_MHtSigma1=5.972;
1349 if(preparedInput.m_MHtSigma2<0.0) preparedInput.m_MHtSigma2=13.85;
1350 // if(MHtGaussFr<0.0) MHtGaussFr=0.4767; // don't directly use 2nd fraction
1351 }
1352 //1-jet
1353 else // Inclusive 1-jet and VBF categories
1354 {
1355 double METresScale=-1.;
1356 double METoffset=-1.;
1357 double sigmaSyst=0.10; // 10% systematics for now (be conservative)
1358
1359 // previous value in trunk
1361 // 2015 high-mass tune; average of all mass points
1362 METresScale = 1.1*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1363 METoffset = -5.0*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1364 }
1365 // MET resolution can't be perfect in presence of other objects (i.e., electrons, jets, taus), so assume minSumEt=5.0 for now
1366 double sigma = preparedInput.m_SumEt>0.0 ? METoffset+METresScale*sqrt(preparedInput.m_SumEt) : std::abs(METoffset);
1367
1370 double x = preparedInput.m_DelPhiTT;
1371 double dphi_scale = x > 0.6 ? 1.42047 - 0.666644*x + 0.199986*x*x : 1.02;
1372 METoffset = 1.19769*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1373 double METresScale1 = 5.61687*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1374 double METresScale2 = -4.2076*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1375 sigma= preparedInput.m_SumEt>115.0 ? METoffset+METresScale1*TMath::Log(sqrt(preparedInput.m_SumEt)+METresScale2) : 12.1;
1376 sigma = sigma*dphi_scale;
1377 } //for hh 2016 mc15c
1378
1379 preparedInput.m_METsigmaP = sigma;
1380 preparedInput.m_METsigmaL = sigma;
1381
1382 }// 1 jet
1383 } // had-had
1384 //LEP-LEP
1385 else if(preparedInput.m_tauTypes==TauTypes::ll) // setup for LEP-LEP channel
1386 {
1387 if(m_mmcCalibrationSet==MMCCalibrationSet::MMC2015HIGHMASS) // placeholder for 2015 high-mass tune; for now it is the same as 2012
1388 {
1389 m_UseHT = false;
1390 double sigmaSyst = 0.10; // 10% systematics for now (be conservative)
1391 double METresScale = -1.0;
1392 double METoffset = -1.0;
1393 double sigma = 5.0;
1394 // tune is based on cuts for Run-1 paper analysis
1395 if(preparedInput.m_Njet25==0)
1396 {
1397 // use tune for emebedding
1398 METresScale=-0.4307*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1399 METoffset=7.06*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1400 double METresScale2=0.07693*(1.0+preparedInput.m_METresSyst*sigmaSyst); // quadratic term
1401 // this is a tune for Higgs125
1402 // METresScale=-0.5355*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1403 // METoffset=11.5*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1404 // double METresScale2=0.07196*(1.0+preparedInput.m_METresSyst*sigmaSyst); // quadratic term
1405 sigma= preparedInput.m_SumEt>0.0 ? METoffset+METresScale*sqrt(preparedInput.m_SumEt)+METresScale2*preparedInput.m_SumEt : METoffset;
1406 }
1407 if(preparedInput.m_Njet25>0)
1408 {
1409 // use tune for embedding
1410 METresScale=0.8149*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1411 METoffset=5.343*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1412 // this is a tune for Higgs125
1413 // METresScale=0.599*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1414 // METoffset=8.223*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1415 sigma= preparedInput.m_SumEt>0.0 ? METoffset+METresScale*sqrt(preparedInput.m_SumEt) : METoffset;
1416 }
1417 preparedInput.m_METsigmaP = sigma;
1418 preparedInput.m_METsigmaL = sigma;
1419 } // end of MMC2015HIGHMASS
1420
1423 // 2019 leplep
1424 {
1425 m_UseHT=false;
1426 double sigmaSyst=0.10; // 10% systematics for now (be conservative)
1427 double METresScale=-1.0;
1428 double METoffset=-1.0;
1429 double sigma=5.0;
1430 double min_sigma = 2.0;
1431 // tune is based on cuts for Run-1 paper analysis
1432 if(preparedInput.m_Njet25==0)
1433 {
1434 // Madgraph Ztautau MET param
1435 METoffset = 4.22581*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1436 METresScale = 0.03818*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1437 double METresScale2= 0.12623;
1438 sigma= preparedInput.m_SumEt>0.0 ? METoffset+METresScale*sqrt(preparedInput.m_SumEt)+METresScale2*preparedInput.m_SumEt : min_sigma;
1439 if (m_fUseDphiLL) {
1440 double p0 = 2.60131;
1441 double p1const = 1.22427;
1442 double p2quad = -1.71261;
1443 double DphiLL = std::abs(Phi_mpi_pi(preparedInput.m_vistau1.Phi()-preparedInput.m_vistau2.Phi()));
1444 sigma *= (DphiLL < p0) ? p1const : p1const+
1445 p2quad*p0*p0 - 2*p2quad*p0*DphiLL+p2quad*DphiLL*DphiLL;
1446 }
1447 if (sigma < min_sigma) sigma = min_sigma;
1448 }
1449 if(preparedInput.m_Njet25>0)
1450 {
1451 // Madgraph Ztautau MET param
1452 METoffset = 5.42506*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1453 METresScale = 5.36760*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1454 double METoffset2 = -4.86808*(1.0+preparedInput.m_METresSyst*sigmaSyst);
1455 if (preparedInput.m_SumEt > 0.0) {
1456 double x = sqrt(preparedInput.m_SumEt);
1457 sigma = (x+METoffset2 > 1) ? METoffset+METresScale*log(x+METoffset2) : METoffset;
1458 } else {
1459 sigma = METoffset;
1460 }
1461 if (m_fUseDphiLL) {
1462 double p0 = 2.24786;
1463 double p1const = 0.908597;
1464 double p2quad = 0.544577;
1465 double DphiLL = std::abs(Phi_mpi_pi(preparedInput.m_vistau1.Phi()-preparedInput.m_vistau2.Phi()));
1466 sigma *= (DphiLL < p0) ? p1const : p1const+
1467 p2quad*p0*p0 - 2*p2quad*p0*DphiLL+p2quad*DphiLL*DphiLL;
1468 }
1469 if (sigma < min_sigma) sigma = min_sigma;
1470 }
1471 preparedInput.m_METsigmaP=sigma;
1472 preparedInput.m_METsigmaL=sigma;
1473 }//2016 mc15c
1474
1475 } // lep-lep
1476
1477 } //preparedInput.METScanScheme
1478
1479 if(preparedInput.m_METScanScheme==0) // old scheme with JER
1480 {
1481 if(preparedInput.m_dataType==0 || preparedInput.m_dataType==1) preparedInput.SetMetScanParamsUE(preparedInput.m_SumEt,preparedInput.m_METcovphi,preparedInput.m_dataType);
1482 else preparedInput.SetMetScanParamsUE(preparedInput.m_SumEt,preparedInput.m_METcovphi,0);
1483 }
1484 }
1485 } // end else LFV
1486
1487 return;
1488}
__HOSTDEV__ double Phi_mpi_pi(double)
Definition GeoRegion.cxx:10
#define scale2
#define scale1
static Double_t P(Double_t *tt, Double_t *par)
A number of constexpr particle constants to avoid hardcoding them directly in various places.
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
#define GEV
#define x
void SetMetScanParamsUE(double sumEt, double phi_scan=0.0, int data_code=0)
std::vector< TF1 * > m_paramVectorRatioLep
double TauProbabilityLFV(MissingMassInput &preparedInput, const int &type1, const PtEtaPhiMVector &vis1, const PtEtaPhiMVector &nu1)
static double dTheta3d_probabilityFastWrapper(MissingMassProb *prob, MissingMassInput &preparedInput, const int &tau_type1, const int &tau_type2, const PtEtaPhiMVector &tauvec1, const PtEtaPhiMVector &tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector &nuvec2)
double MHtProbabilityHH(MissingMassInput &preparedInput, const double &d_mhtX, const double &d_mhtY, const double &mht, const double &trueMetGuess, const double &mht_offset)
std::vector< TF1 * > m_paramVectorNuMass
double MHtProbability(MissingMassInput &preparedInput, const double &d_mhtX, const double &d_mhtY, const double &mht, const double &trueMetGuess, const double &mht_offset)
MissingMassProb(MMCCalibrationSet::e aset, const std::string &paramFilePath)
void MET(MissingMassInput &preparedInput)
double dTheta3d_probabilityFast(MissingMassInput &preparedInput, const int &tau_type, const double &dTheta3d, const double &P_tau)
std::list< std::function< double(MissingMassInput &preparedInput, const int &tau_type1, const int &tau_type2, const PtEtaPhiMVector &tauvec1, const PtEtaPhiMVector &tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector &nuvec2)> > m_probListConstant
double myDelThetaLepFunc(double *x, double *par)
double dTheta3Dparam(const int &parInd, const int &tau_type, const double &P_tau, const double *par)
void setParamRatio(int tau, int tautype)
double TauProbability(MissingMassInput &preparedInput, const int &type1, const PtEtaPhiMVector &vis1, const PtEtaPhiMVector &nu1, const int &type2, const PtEtaPhiMVector &vis2, const PtEtaPhiMVector &nu2)
std::vector< TF1 * > m_paramVectorAngle
static double TauProbabilityWrapper(MissingMassProb *prob, MissingMassInput &preparedInput, const int &tau_type1, const int &tau_type2, const PtEtaPhiMVector &tauvec1, const PtEtaPhiMVector &tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector &nuvec2)
double MetProbability(MissingMassInput &preparedInput, const double &met1, const double &met2, const double &MetSigma1, const double &MetSigma2)
static double MnuProbabilityNewWrapper(MissingMassProb *prob, MissingMassInput &preparedInput, const int &tau_type1, const int &tau_type2, const PtEtaPhiMVector &tauvec1, const PtEtaPhiMVector &tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector &nuvec2)
static double mEtAndTauProbabilityWrapper(MissingMassProb *prob, MissingMassInput &preparedInput, const int &tau_type1, const int &tau_type2, const PtEtaPhiMVector &tauvec1, const PtEtaPhiMVector &tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector &nuvec2)
static double MetProbabilityWrapper(MissingMassProb *prob, MissingMassInput &preparedInput, const int &tau_type1, const int &tau_type2, const PtEtaPhiMVector &tauvec1, const PtEtaPhiMVector &tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector &nuvec2)
static double s_fit_param[2][3][6][5]
static double dTheta3d_probabilityNewWrapper(MissingMassProb *prob, MissingMassInput &preparedInput, const int &tau_type1, const int &tau_type2, const PtEtaPhiMVector &tauvec1, const PtEtaPhiMVector &tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector &nuvec2)
std::vector< TF1 * > m_paramVectorRatio
static double MnuProbabilityWrapper(MissingMassProb *prob, MissingMassInput &preparedInput, const int &tau_type1, const int &tau_type2, const PtEtaPhiMVector &tauvec1, const PtEtaPhiMVector &tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector &nuvec2)
double mEtAndTauProbability(MissingMassInput &preparedInput)
double MnuProbability(MissingMassInput &preparedInput, double mnu, double binsize)
void setParamAngle(const PtEtaPhiMVector &tauvec, int tau, int tautype)
std::vector< TF1 * > m_paramVectorAngleLep
MMCCalibrationSet::e m_mmcCalibrationSet
double apply(MissingMassInput &preparedInput, const int &tau_type1, const int &tau_type2, const PtEtaPhiMVector &tauvec1, const PtEtaPhiMVector &tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector &nuvec2, bool constant=false, bool oneTau=false, bool twoTau=false)
static double TauProbabilityNewWrapper(MissingMassProb *prob, MissingMassInput &preparedInput, const int &tau_type1, const int &tau_type2, const PtEtaPhiMVector &tauvec1, const PtEtaPhiMVector &tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector &nuvec2)
std::list< std::function< double(MissingMassInput &preparedInput, const int &tau_type1, const int &tau_type2, const PtEtaPhiMVector &tauvec1, const PtEtaPhiMVector &tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector &nuvec2)> > m_probListOneTau
std::list< std::function< double(MissingMassInput &preparedInput, const int &tau_type1, const int &tau_type2, const PtEtaPhiMVector &tauvec1, const PtEtaPhiMVector &tauvec2, const PtEtaPhiMVector nuvec1, const PtEtaPhiMVector &nuvec2)> > m_probListTwoTau
double myDelThetaHadFunc(double *x, double *par)
void mean(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
double Angle(const VectorType1 &vec1, const VectorType2 &vec2)
double mT(const VectorType &vec, const XYVector &met_vec)
void readInParams(TDirectory *dir, MMCCalibrationSet::e aset, std::vector< TF1 * > &lep_numass, std::vector< TF1 * > &lep_angle, std::vector< TF1 * > &lep_ratio, std::vector< TF1 * > &had_angle, std::vector< TF1 * > &had_ratio)
constexpr double tauMassInMeV
the mass of the tau (in MeV)