checkmate is hosted by Hepforge, IPPP Durham
mctlib.cc
Go to the documentation of this file.
1 
2 #include "mctlib.h"
3 
4 
5 namespace mctlib
6 {
8 {}
9 
10 double mct::mctcorr(const double v1[4],const double v2[4]
11  ,const double vds[4],const double ptm[2]
12  ,const double ecm,const double mxlo)
13 {
14 // v1, v2 are the 4-vectors of the two aggregated decay products
15 // vds is the 4-vector of the downstream objects (excluding v1 and v2)
16 // ptm is the pTmiss 2-vector {pxmiss,pymiss}
17 // ecm is the centre-of-mass energy (D=14TeV)
18 // mxlo is a lower bound on the mass of each invisible decay product (D=0)
19 
20  double ptus[2] = {-v1[1]-v2[1]-vds[1]-ptm[0],-v1[2]-v2[2]-vds[2]-ptm[1]};
21  m_pb = sqrt(pow(ptus[0],2)+pow(ptus[1],2));
22 
23  if (m_pb==0) {
24 
25  return mctnorm(v1,v2);
26 
27  } else {
28 
29 // Transform to new basis in transverse plane
30 // ISR goes in +ve x direction
31 
32  double vb1[4] = {v1[0],(v1[1]*ptus[0]+v1[2]*ptus[1])/m_pb
33  ,(v1[1]*ptus[1]-v1[2]*ptus[0])/m_pb,v1[3]};
34  double vb2[4] = {v2[0],(v2[1]*ptus[0]+v2[2]*ptus[1])/m_pb
35  ,(v2[1]*ptus[1]-v2[2]*ptus[0])/m_pb,v2[3]};
36  double vey1 = sqrt(fmax(pow(vb1[0],2)-pow(vb1[1],2)-pow(vb1[3],2),0.0));
37  double vey2 = sqrt(fmax(pow(vb2[0],2)-pow(vb2[1],2)-pow(vb2[3],2),0.0));
38  double ax = vb1[1]*vey2+vb2[1]*vey1;
39 
40 // Boost v1 and v2 with Ecm
41 // v1 and v2 were boosted in -ve x direction,
42 // so to correct we boost v1 and v2 in +ve x direction
43 
44  double beta = m_pb/ecm;
45  double gamma = 1.0/sqrt(1.0-beta*beta);
46  double vb1p[4] = {gamma*(vb1[0]+vb1[1]*beta),gamma*(vb1[1]+vb1[0]*beta)
47  ,vb1[2],vb1[3]};
48  double vb2p[4] = {gamma*(vb2[0]+vb2[1]*beta),gamma*(vb2[1]+vb2[0]*beta)
49  ,vb2[2],vb2[3]};
50  double vey1p = sqrt(fmax(pow(vb1p[0],2)-pow(vb1p[1],2)
51  -pow(vb1p[3],2),0.0));
52  double vey2p = sqrt(fmax(pow(vb2p[0],2)-pow(vb2p[1],2)
53  -pow(vb2p[3],2),0.0));
54  double axecm = vb1p[1]*vey2p+vb2p[1]*vey1p;
55  m_mctecm = mctnorm(vb1p,vb2p);
56 
57 // Boost v1 and v2 with e0
58 // v1 and v2 were boosted in -ve x direction,
59 // so to correct we boost v1 and v2 in +ve x direction
60 
61  beta = m_pb/(v1[0]+v2[0]+vds[0]
62  +sqrt(pow(ptm[0],2)+pow(ptm[1],2)+4.0*pow(mxlo,2)));
63  gamma = 1.0/sqrt(1.0-beta*beta);
64  double vb1pp[4] = {gamma*(vb1[0]+vb1[1]*beta),gamma*(vb1[1]+vb1[0]*beta)
65  ,vb1[2],vb1[3]};
66  double vb2pp[4] = {gamma*(vb2[0]+vb2[1]*beta),gamma*(vb2[1]+vb2[0]*beta)
67  ,vb2[2],vb2[3]};
68  double vey1pp = sqrt(fmax(pow(vb1pp[0],2)-pow(vb1pp[1],2)
69  -pow(vb1pp[3],2),0.0));
70  double vey2pp = sqrt(fmax(pow(vb2pp[0],2)-pow(vb2pp[1],2)
71  -pow(vb2pp[3],2),0.0));
72  double axehat = vb1pp[1]*vey2pp+vb2pp[1]*vey1pp;
73  m_mctehat = mctnorm(vb1pp,vb2pp);
74 
75  if ( (ax>=0) || (axecm>=0) ) {
76  return m_mctecm;
77  } else {
78  if (axehat<0) {
79  return m_mctehat;
80  } else {
81  return sqrt(fmax(pow(vey1+vey2,2)-pow(vb1[2]-vb2[2],2),0.0));
82  }
83  }
84  }
85 }
86 
87 double mct::mctnorm(const double v1[4],const double v2[4])
88 {
89  double et1 = sqrt(fmax(v1[0]*v1[0]-v1[3]*v1[3],0.0));
90  double et2 = sqrt(fmax(v2[0]*v2[0]-v2[3]*v2[3],0.0));
91  return sqrt(fmax(pow(et1+et2,2)-pow(v1[1]-v2[1],2)
92  -pow(v1[2]-v2[2],2),0.0));
93 }
94 
95 double mct::mt2(const double v1[4],const double v2[4]
96  ,const double vds[4],const double ptm[2]
97  ,const double ecm,const double mxlo)
98 {
99  // Boost corrected analytical mt2
100  double m1sqr = pow(v1[0],2)-pow(v1[1],2)-pow(v1[2],2)-pow(v1[3],2);
101  double m2sqr = pow(v2[0],2)-pow(v2[1],2)-pow(v2[2],2)-pow(v2[3],2);
102  double chisqr = pow(mxlo,2);
103  double m1 = sqrt(fmax(m1sqr,0.0));
104  double m2 = sqrt(fmax(m2sqr,0.0));
105  double chi = mxlo;
106 
107  double qtest[3] = {0.0,ptm[0]-(chi/m1)*v1[1],ptm[1]-(chi/m1)*v1[2]};
108  qtest[0] = sqrt(chisqr+pow(qtest[1],2)+pow(qtest[2],2));
109  double ptest[3] = {0.0,ptm[0]-(chi/m2)*v2[1],ptm[1]-(chi/m2)*v2[2]};
110  ptest[0] = sqrt(chisqr+pow(ptest[1],2)+pow(ptest[2],2));
111 
112  double et1 = sqrt(fmax(v1[0]*v1[0]-v1[3]*v1[3],0.0));
113  double et2 = sqrt(fmax(v2[0]*v2[0]-v2[3]*v2[3],0.0));
114 
115  double bq[3] = {et2+qtest[0],v2[1]+qtest[1],v2[2]+qtest[2]};
116  double ap[3] = {et1+ptest[0],v1[1]+ptest[1],v1[2]+ptest[2]};
117 
118  // Use unbalanced solutions
119  // This is an approximation as we haven't boost-corrected bq and ap
120 
121  if (pow(m1+chi,2)>=pow(bq[0],2)-pow(bq[1],2)-pow(bq[2],2)) {
122  return m1+chi;
123  } else if (pow(m2+chi,2)>=pow(ap[0],2)-pow(ap[1],2)-pow(ap[2],2)) {
124  return m2+chi;
125  }
126 
127  // Else use balanced solution
128  // Note that call to mctcorr also sets m_mctehat, m_mctecm and m_pb
129 
130  double mctminsqr = pow(mctcorr(v1,v2,vds,ptm,ecm,mxlo),2);
131  double mdmin = mctminmt2(mctminsqr,m1sqr,m2sqr,chisqr);
132  if (m_pb == 0) return mdmin;
133 
134  double mctecmsqr = pow(m_mctecm,2);
135  double mctehatsqr = pow(m_mctehat,2);
136  double mctmaxsqr = fmax(mctecmsqr,mctehatsqr);
137 
138  double mctdsqr[4] = {(chi*(3.0*m1sqr+m2sqr)+2.0*m1*(m1sqr+m2sqr))/(chi+m1),
139  (chi*(3.0*m1sqr+m2sqr)-2.0*m1*(m1sqr+m2sqr))/(chi-m1),
140  (chi*(3.0*m2sqr+m1sqr)+2.0*m2*(m2sqr+m1sqr))/(chi+m2),
141  (chi*(3.0*m2sqr+m1sqr)-2.0*m2*(m2sqr+m1sqr))/(chi-m2)};
142  mdmin = fmin(mdmin,mctminmt2(mctmaxsqr,m1sqr,m2sqr,chisqr));
143 
144  for (int i=0;i<4;i++)
145  if ( (mctdsqr[i]>mctminsqr) && (mctdsqr[i]<mctmaxsqr) )
146  mdmin = fmin(mdmin,mctminmt2(mctdsqr[i],m1sqr,m2sqr,chisqr));
147 
148  return fmax(fmax(mdmin,m1+chi),m2+chi);
149 }
150 
151 double mct::mctminmt2(const double mctsqr,const double m1sqr,
152  const double m2sqr, const double chisqr)
153 {
154  double at = 0.5*(mctsqr - m1sqr - m2sqr);
155  return sqrt(fmax(chisqr+at+sqrt(fmax((1.0+(4.0*chisqr)/(2.0*at-m1sqr-m2sqr))
156  *(pow(at,2)-m1sqr*m2sqr),0.0)),0.0));
157 }
158 
159 double mct::mt2neg(const double v1[4],const double v2[4]
160  ,const double ptm[2],const double mxlo)
161 {
162  // Non boost-corrected analytical mt2
163  double m1sqr = pow(v1[0],2)-pow(v1[1],2)-pow(v1[2],2)-pow(v1[3],2);
164  double m2sqr = pow(v2[0],2)-pow(v2[1],2)-pow(v2[2],2)-pow(v2[3],2);
165  double chisqr = pow(mxlo,2);
166  double m1 = sqrt(fmax(m1sqr,0.0));
167  double m2 = sqrt(fmax(m2sqr,0.0));
168  double chi = mxlo;
169 
170  double qtest[3] = {0.0,ptm[0]-(chi/m1)*v1[1],ptm[1]-(chi/m1)*v1[2]};
171  qtest[0] = sqrt(chisqr+pow(qtest[1],2)+pow(qtest[2],2));
172  double ptest[3] = {0.0,ptm[0]-(chi/m2)*v2[1],ptm[1]-(chi/m2)*v2[2]};
173  ptest[0] = sqrt(chisqr+pow(ptest[1],2)+pow(ptest[2],2));
174 
175  double et1 = sqrt(fmax(v1[0]*v1[0]-v1[3]*v1[3],0.0));
176  double et2 = sqrt(fmax(v2[0]*v2[0]-v2[3]*v2[3],0.0));
177 
178  double bq[3] = {et2+qtest[0],v2[1]+qtest[1],v2[2]+qtest[2]};
179  double ap[3] = {et1+ptest[0],v1[1]+ptest[1],v1[2]+ptest[2]};
180 
181  // Use unbalanced solutions
182  if (pow(m1+chi,2)>=pow(bq[0],2)-pow(bq[1],2)-pow(bq[2],2)) {
183  return m1+chi;
184  } else if (pow(m2+chi,2)>=pow(ap[0],2)-pow(ap[1],2)-pow(ap[2],2)) {
185  return m2+chi;
186  }
187 
188  // Else use balanced solution
189  double mctminsqr = pow(mctnorm(v1,v2),2);
190  double mdmin = mctminmt2(mctminsqr,m1sqr,m2sqr,chisqr);
191 
192  return fmax(fmax(mdmin,m1+chi),m2+chi);
193 }
194 
195 
196 double mct::mcy(const double v1[4],const double v2[4]
197  ,const double vds[4],const double ptm[2])
198 {
199 // v1, v2 are the 4-vectors of the two aggregated decay products
200 // vds is the 4-vector of the downstream objects (excluding v1 and v2)
201 // ptm is the pTmiss 2-vector {pxmiss,pymiss}
202 
203  double ptus[2] = {-v1[1]-v2[1]-vds[1]-ptm[0],-v1[2]-v2[2]-vds[2]-ptm[1]};
204  double pb = sqrt(pow(ptus[0],2)+pow(ptus[1],2));
205 
206  if (pb==0) {
207 
208  return mctnorm(v1,v2);
209 
210  } else {
211 
212 // Transform to new basis in transverse plane
213 // ISR goes in +ve x direction
214 
215  double vb1[4] = {v1[0],(v1[1]*ptus[0]+v1[2]*ptus[1])/pb
216  ,(v1[1]*ptus[1]-v1[2]*ptus[0])/pb,v1[3]};
217  double vb2[4] = {v2[0],(v2[1]*ptus[0]+v2[2]*ptus[1])/pb
218  ,(v2[1]*ptus[1]-v2[2]*ptus[0])/pb,v2[3]};
219  double vey1 = sqrt(fmax(pow(vb1[0],2)-pow(vb1[1],2)-pow(vb1[3],2),0.0));
220  double vey2 = sqrt(fmax(pow(vb2[0],2)-pow(vb2[1],2)-pow(vb2[3],2),0.0));
221  return sqrt(fmax(pow(vey1+vey2,2)-pow(vb1[2]-vb2[2],2),0.0));
222  }
223 }
224 
225 double mct::mcx(const double v1[4],const double v2[4]
226  ,const double vds[4],const double ptm[2])
227 {
228 // v1, v2 are the 4-vectors of the two aggregated decay products
229 // vds is the 4-vector of the downstream objects (excluding v1 and v2)
230 // ptm is the pTmiss 2-vector {pxmiss,pymiss}
231 
232  double ptus[2] = {-v1[1]-v2[1]-vds[1]-ptm[0],-v1[2]-v2[2]-vds[2]-ptm[1]};
233  double pb = sqrt(pow(ptus[0],2)+pow(ptus[1],2));
234 
235  if (pb==0) {
236 
237  return mctnorm(v1,v2);
238 
239  } else {
240 
241 // Transform to new basis in transverse plane
242 // ISR goes in +ve x direction
243 
244  double vb1[4] = {v1[0],(v1[1]*ptus[0]+v1[2]*ptus[1])/pb
245  ,(v1[1]*ptus[1]-v1[2]*ptus[0])/pb,v1[3]};
246  double vb2[4] = {v2[0],(v2[1]*ptus[0]+v2[2]*ptus[1])/pb
247  ,(v2[1]*ptus[1]-v2[2]*ptus[0])/pb,v2[3]};
248  double vex1 = sqrt(fmax(pow(vb1[0],2)-pow(vb1[2],2)-pow(vb1[3],2),0.0));
249  double vex2 = sqrt(fmax(pow(vb2[0],2)-pow(vb2[2],2)-pow(vb2[3],2),0.0));
250  return sqrt(fmax(pow(vex1+vex2,2)-pow(vb1[1]-vb2[1],2),0.0));
251  }
252 }
253 
254 }//end namespace mctlib
double mctminmt2(const double mctsqr, const double m1sqr, const double m2sqr, const double chisqr=0.0)
Definition: mctlib.cc:151
double mctnorm(const double v1[4], const double v2[4])
Definition: mctlib.cc:87
double mctcorr(const double v1[4], const double v2[4], const double vds[4], const double ptm[2], const double ecm=14000.0, const double mxlo=0.0)
Definition: mctlib.cc:10
double mt2(const double v1[4], const double v2[4], const double vds[4], const double ptm[2], const double ecm=14000.0, const double mxlo=0.0)
Definition: mctlib.cc:95
double mt2neg(const double v1[4], const double v2[4], const double ptm[2], const double mxlo=0.0)
Definition: mctlib.cc:159
double mcx(const double v1[4], const double v2[4], const double vds[4], const double ptm[2])
Definition: mctlib.cc:225
double mcy(const double v1[4], const double v2[4], const double vds[4], const double ptm[2])
Definition: mctlib.cc:196