CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ParametrizationHelper.cc
Go to the documentation of this file.
2 #include <cmath>
3 #include <Math/CylindricalEta3D.h>
4 #include <Math/Polar3D.h>
5 #include <Math/Cartesian3D.h>
6 #include <Math/DisplacementVector3D.h>
7 #include <Math/Functions.h>
8 
9 using namespace std;
10 
11 //pat::helper::ParametrizationHelper::POLAR_ZERO();
12 //pat::helper::ParametrizationHelper::CARTESIAN_ZERO();
13 
16  using namespace std;
17 
18  typedef pat::CandKinResolution::Parametrization Parametrization;
19 
20  static map<string,Parametrization> parMaps;
21  if (parMaps.empty()) {
22  parMaps["Cart"] = pat::CandKinResolution::Cart;
23  parMaps["ECart"] = pat::CandKinResolution::ECart;
24  parMaps["MCCart"] = pat::CandKinResolution::MCCart;
25  parMaps["Spher"] = pat::CandKinResolution::Spher;
26  parMaps["ESpher"] = pat::CandKinResolution::ESpher;
27  parMaps["MCSpher"] = pat::CandKinResolution::MCSpher;
28  parMaps["MCPInvSpher"] = pat::CandKinResolution::MCPInvSpher;
29  parMaps["EtEtaPhi"] = pat::CandKinResolution::EtEtaPhi;
30  parMaps["EtThetaPhi"] = pat::CandKinResolution::EtThetaPhi;
31  parMaps["MomDev"] = pat::CandKinResolution::MomDev;
32  parMaps["EMomDev"] = pat::CandKinResolution::EMomDev;
33  parMaps["MCMomDev"] = pat::CandKinResolution::MCMomDev;
34  parMaps["EScaledMomDev"] = pat::CandKinResolution::EScaledMomDev;
35  }
36  map<string,Parametrization>::const_iterator itP = parMaps.find(name);
37  if (itP == parMaps.end()) {
38  throw cms::Exception("StringResolutionProvider") << "Bad parametrization '" << name.c_str() << "'";
39  }
40  return itP->second;
41 }
42 
43 const char *
45  switch (param) {
46  case pat::CandKinResolution::Cart: return "Cart";
47  case pat::CandKinResolution::ECart: return "ECart";
48  case pat::CandKinResolution::MCCart: return "MCCart";
49  case pat::CandKinResolution::Spher: return "Spher";
50  case pat::CandKinResolution::ESpher: return "ESpher";
51  case pat::CandKinResolution::MCSpher: return "MCSpher";
52  case pat::CandKinResolution::MCPInvSpher: return "MCPInvSpher";
53  case pat::CandKinResolution::EtEtaPhi: return "EtEtaPhi";
54  case pat::CandKinResolution::EtThetaPhi: return "EtThetaPhi";
55  case pat::CandKinResolution::MomDev: return "MomDev";
56  case pat::CandKinResolution::EMomDev: return "EMomDev";
57  case pat::CandKinResolution::MCMomDev: return "MCMomDev";
58  case pat::CandKinResolution::EScaledMomDev: return "EScaledMomDev";
59  case pat::CandKinResolution::Invalid: return "Invalid";
60  default: return "UNKNOWN";
61  }
62 }
63 
67  const math::PtEtaPhiMLorentzVector &initialP4) {
69  ROOT::Math::CylindricalEta3D<double> converter;
70  double m2;
71  switch (parametrization) {
72  // ======= CARTESIAN ==========
74  ret = math::XYZTLorentzVector(parameters[0], parameters[1], parameters[2],
75  sqrt(parameters[0]*parameters[0] +
76  parameters[1]*parameters[1] +
77  parameters[2]*parameters[2] +
78  parameters[3]*parameters[3]) );
79  ret.SetM(parameters[3]); // to be sure about roundoffs
80  break;
82  ret = math::XYZTLorentzVector(parameters[0], parameters[1], parameters[2],
83  sqrt(parameters[0]*parameters[0] +
84  parameters[1]*parameters[1] +
85  parameters[2]*parameters[2] +
86  initialP4.mass()*initialP4.mass()) );
87  ret.SetM(initialP4.mass()); // to be sure about roundoffs
88  break;
90  ret = math::XYZTLorentzVector(parameters[0], parameters[1], parameters[2], parameters[3]);
91  break;
92  // ======= SPHERICAL ==========
94  converter = ROOT::Math::Polar3D<double>(parameters[0], parameters[1], 0);
95  ret.SetCoordinates(converter.Rho(),converter.Eta(),parameters[2],parameters[3]);
96  break;
97  case pat::CandKinResolution::MCSpher: // same as above
98  converter = ROOT::Math::Polar3D<double>(parameters[0], parameters[1], 0);
99  ret.SetCoordinates(converter.Rho(),converter.Eta(),parameters[2],initialP4.mass());
100  break;
102  converter = ROOT::Math::Polar3D<double>(parameters[0], parameters[1], 0);
103  m2 = - parameters[0]*parameters[0] + parameters[3]*parameters[3];
104  ret.SetCoordinates(converter.Rho(),converter.Eta(),parameters[2],(m2 > 0 ? sqrt(m2) : 0.0));
105  break;
107  converter = ROOT::Math::Polar3D<double>(1.0/parameters[0], parameters[1], 0);
108  ret.SetCoordinates(converter.Rho(),converter.Eta(),parameters[2],initialP4.mass());
109  break;
110  // ======= HEP CYLINDRICAL ==========
112  converter = ROOT::Math::Polar3D<double>(1.0, parameters[1], 0);
113  ret.SetCoordinates(parameters[0],converter.Eta(),parameters[2],0);
114  break;
115  case pat::CandKinResolution::EtEtaPhi: // as simple as that
116  ret.SetCoordinates(parameters[0], parameters[1], parameters[2], 0);
117  break;
118  // ======= MomentumDeviates ==========
123  {
124  ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D<double> > p = initialP4.Vect(), uz(0,0,1), uph, uth;
125  uph = uz.Cross(p).Unit();
126  uth = p.Cross(uph).Unit();
127  p *= parameters[0];
128  p += uth * parameters[1] + uph * parameters[2];
129  if (parametrization == pat::CandKinResolution::MomDev) {
130  ret.SetCoordinates(p.Rho(), p.Eta(), p.Phi(), initialP4.mass() * parameters[3]);
131  } else if (parametrization == pat::CandKinResolution::EMomDev) {
132  double m2 = ROOT::Math::Square(parameters[3] * initialP4.energy()) - p.Mag2();
133  ret.SetCoordinates(p.Rho(), p.Eta(), p.Phi(), (m2 > 0 ? sqrt(m2) : 0.0));
134  } else if (parametrization == pat::CandKinResolution::EScaledMomDev) {
135  double m2 = ROOT::Math::Square(p.R()*initialP4.E()/initialP4.P()) - p.Mag2();
136  ret.SetCoordinates(p.Rho(), p.Eta(), p.Phi(), (m2 > 0 ? sqrt(m2) : 0.0));
137  } else if (parametrization == pat::CandKinResolution::MCMomDev) {
138  ret.SetCoordinates(p.Rho(), p.Eta(), p.Phi(), initialP4.mass());
139  }
140  break;
141  }
142  // ======= OTHER ==========
144  throw cms::Exception("Invalid parametrization") << parametrization;
145  default:
146  throw cms::Exception("Not Implemented") << "getResolEta not yet implemented for parametrization " << parametrization ;
147  }
148  return ret;
149 }
150 
154  const math::XYZTLorentzVector &initialP4) {
156  switch (parametrization) {
157  // ======= CARTESIAN ==========
159  ret.SetCoordinates(parameters[0], parameters[1], parameters[2],
160  sqrt(parameters[0]*parameters[0] +
161  parameters[1]*parameters[1] +
162  parameters[2]*parameters[2] +
163  parameters[3]*parameters[3]) );
164  break;
165  case pat::CandKinResolution::MCCart: // same as above
166  ret.SetCoordinates(parameters[0], parameters[1], parameters[2],
167  sqrt(parameters[0]*parameters[0] +
168  parameters[1]*parameters[1] +
169  parameters[2]*parameters[2] +
170  initialP4.mass()*initialP4.mass()) );
171  break;
173  ret.SetCoordinates(parameters[0], parameters[1], parameters[2], parameters[3]);
174  break;
175  // ======= MomentumDeviates ==========
180  {
181  ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D<double> > p = initialP4.Vect(), uz(0,0,1), uph, uth;
182  uph = uz.Cross(p).Unit();
183  uth = p.Cross(uph).Unit();
184  p *= parameters[0];
185  p += uth * parameters[1] + uph * parameters[2];
186  if (parametrization == pat::CandKinResolution::MomDev) {
187  ret.SetCoordinates(p.X(), p.Y(), p.Z(), sqrt(p.Mag2() + ROOT::Math::Square(initialP4.mass() * parameters[3])) );
188  } else if (parametrization == pat::CandKinResolution::EMomDev) {
189  ret.SetCoordinates(p.X(), p.Y(), p.Z(), parameters[3] * initialP4.energy());
190  } else if (parametrization == pat::CandKinResolution::EMomDev) {
191  ret.SetCoordinates(p.X(), p.Y(), p.Z(), p.R() * initialP4.E()/initialP4.P());
192  } else {
193  ret.SetCoordinates(p.X(), p.Y(), p.Z(), sqrt(p.Mag2() + initialP4.mass()*initialP4.mass()));
194  }
195  break;
196  }
197  // ======= ALL OTHERS ==========
198  default:
199  ret = polarP4fromParameters(parametrization, parameters, math::PtEtaPhiMLorentzVector(initialP4));
200  }
201  return ret;
202 }
203 
204 template <typename T>
205 void
208  const T &p4) {
209  switch (parametrization) {
210  // ======= CARTESIAN ==========
212  ret[0] = p4.px(); ret[1] = p4.py(); ret[2] = p4.pz(); ret[3] = p4.mass();
213  break;
215  ret[0] = p4.px(); ret[1] = p4.py(); ret[2] = p4.pz(); ret[3] = p4.mass();
216  break;
218  ret[0] = p4.px(); ret[1] = p4.py(); ret[2] = p4.pz(); ret[3] = p4.energy();
219  break;
220  // ======= SPHERICAL ==========
222  ret[0] = p4.P(); ret[1] = p4.theta(); ret[2] = p4.phi(); ret[3] = p4.mass();
223  break;
225  ret[0] = p4.P(); ret[1] = p4.theta(); ret[2] = p4.phi(); ret[3] = p4.mass();
226  break;
228  ret[0] = p4.P(); ret[1] = p4.theta(); ret[2] = p4.phi(); ret[3] = p4.energy();
229  break;
231  ret[0] = 1.0/p4.P(); ret[1] = p4.theta(); ret[2] = p4.phi(); ret[3] = p4.mass();
232  break;
233  // ======= HEP CYLINDRICAL ==========
235  ret[0] = p4.pt(); ret[1] = p4.theta(); ret[2] = p4.phi(); ret[3] = 0;
236  break;
238  ret[0] = p4.pt(); ret[1] = p4.eta(); ret[2] = p4.phi(); ret[3] = 0;
239  break;
240  // ======= DEVIATES ==========
243  ret[0] = 1.0; ret[1] = 0.0; ret[2] = 0.0; ret[3] = 1.0;
244  break;
246  ret[0] = 1.0; ret[1] = 0.0; ret[2] = 0.0; ret[3] = p4.mass();
247  break;
249  ret[0] = 1.0; ret[1] = 0.0; ret[2] = 0.0; ret[3] = p4.E()/p4.P();
250  break;
251  // ======= OTHER ==========
253  throw cms::Exception("Invalid parametrization") << parametrization;
254  default:
255  throw cms::Exception("Not Implemented") << "getResolEta not yet implemented for parametrization " << parametrization ;
256  }
257 }
258 
259 void
262  setParametersFromAnyVector(parametrization, v, p4);
263 }
264 
265 void
268  setParametersFromAnyVector(parametrization, v, p4);
269 }
270 
274  setParametersFromP4(parametrization, ret, p4);
275  return ret;
276 }
277 
281  setParametersFromP4(parametrization, ret, p4);
282  return ret;
283 }
284 
288 {
290  switch (parametrization) {
294  ret = parametersFromP4(parametrization,p4fin) - parametersFromP4(parametrization,p4ini);
295  break;
302  ret = parametersFromP4(parametrization,p4fin) - parametersFromP4(parametrization,p4ini);
303  while(ret[2] > +M_PI) ret[2] -= (2*M_PI);
304  while(ret[2] < -M_PI) ret[2] += (2*M_PI);
305  break;
310  return diffToParameters(parametrization,
312  math::XYZTLorentzVector(p4fin));
314  throw cms::Exception("Invalid parametrization") << parametrization;
315  default:
316  throw cms::Exception("Not Implemented") << "diffToParameters not yet implemented for parametrization " << parametrization ;
317  }
318  return ret;
319 }
320 
321 
324  const math::XYZTLorentzVector &p4ini, const math::XYZTLorentzVector &p4fin)
325 {
327  switch (parametrization) {
332  ret = parametersFromP4(parametrization,p4fin) - parametersFromP4(parametrization,p4ini);
333  break;
339  ret = parametersFromP4(parametrization,p4fin) - parametersFromP4(parametrization,p4ini);
340  while(ret[2] > +M_PI) ret[2] -= (2*M_PI);
341  while(ret[2] < -M_PI) ret[2] += (2*M_PI);
342  break;
347  {
348  typedef ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D<double> > V3Cart;
349  V3Cart p1 = p4ini.Vect(), p2 = p4fin.Vect();
350  V3Cart ur = p1.Unit();
351  V3Cart uz(0,0,1);
352  V3Cart uph = uz.Cross(ur).Unit();
353  V3Cart uth = ur.Cross(uph).Unit();
354  ret[0] = p2.Dot(ur)/p1.R() - 1.0;
355  ret[1] = (p2 - p1).Dot(uth);
356  ret[2] = (p2 - p1).Dot(uph);
357  if (parametrization == pat::CandKinResolution::MomDev) {
358  ret[3] = p4fin.mass()/p4ini.mass() - 1.0;
359  } else if (parametrization == pat::CandKinResolution::EMomDev) {
360  ret[3] = p4fin.energy()/p4ini.energy() - 1.0;
361  }
362  }
363  break;
365  throw cms::Exception("Invalid parametrization") << parametrization;
366  default:
367  throw cms::Exception("Not Implemented") << "diffToParameters not yet implemented for parametrization " << parametrization ;
368  }
369  return ret;
370 }
371 
372 bool
374 {
375  switch (parametrization) {
387  return false;
390  return true;
392  throw cms::Exception("Invalid parametrization") << parametrization;
393  default:
394  throw cms::Exception("Not Implemented") << "isAlwaysMassless not yet implemented for parametrization " << parametrization ;
395  }
396 }
397 
398 bool
400 {
401  switch (parametrization) {
414  return false;
416  return true;
418  throw cms::Exception("Invalid parametrization") << parametrization;
419  default:
420  throw cms::Exception("Not Implemented") << "isAlwaysMassless not yet implemented for parametrization " << parametrization ;
421  }
422 }
423 
424 bool
426 {
427  switch (parametrization) {
437  return false;
442  return true;
444  throw cms::Exception("Invalid parametrization") << parametrization;
445  default:
446  throw cms::Exception("Not Implemented") << "isAlwaysMassless not yet implemented for parametrization " << parametrization ;
447  }
448 }
449 
450 bool
453  const math::PtEtaPhiMLorentzVector &initialP4) {
454  switch (parametrization) {
455  // ======= CARTESIAN ==========
457  return parameters[3] >= 0; // M >= 0
459  return true;
461  return (parameters[0]*parameters[0] + parameters[1]*parameters[1] + parameters[2]*parameters[2] <= parameters[3]*parameters[3]); // E >= P
463  return (parameters[0] >= 0 ) && // P >= 0
464  (parameters[3] >= 0 ) && // M >= 0
465  (parameters[1] >= 0 ) && // theta >= 0
466  (parameters[1] <= M_PI); // theta <= pi
468  return (parameters[0] >= 0 ) && // P >= 0
469  (parameters[1] >= 0 ) && // theta >= 0
470  (parameters[1] <= M_PI); // theta <= pi
472  return (parameters[0] >= 0 ) && // P >= 0
473  (parameters[3] >= parameters[0]) && // E >= P
474  (parameters[1] >= 0 ) && // theta >= 0
475  (parameters[1] <= M_PI ) ; // theta <= PI
477  return (parameters[0] > 0 ) && // 1/P > 0
478  (parameters[1] >= 0 ) && // theta >= 0
479  (parameters[1] <= M_PI); // theta <= pi
480  // ======= HEP CYLINDRICAL ==========
482  return (parameters[0] > 0 ) && // Et >= 0
483  (parameters[1] >= 0 ) && // theta >= 0
484  (parameters[1] <= M_PI); // theta <= pi
485  case pat::CandKinResolution::EtEtaPhi: // as simple as that
486  return (parameters[0] > 0); // Et >= 0
487  // ======= MomentumDeviates ==========
489  return (parameters[0] >= 0) && // P >= 0
490  (parameters[3] >= 0); // m/M0 >= 0
492  return (parameters[0] >= 0); // P >= 0
495  {
496  if (parameters[0] <= 0) return false;
497  ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D<double> > p = initialP4.Vect(), uz(0,0,1), uph, uth;
498  uph = uz.Cross(p).Unit();
499  uth = p.Cross(uph).Unit();
500  p *= parameters[0];
501  p += uth * parameters[1] + uph * parameters[2];
502  if (parametrization == pat::CandKinResolution::EMomDev) {
503  if (parameters[3] < 0) return false;
504  double m2 = ROOT::Math::Square(parameters[3] * initialP4.energy()) - p.Mag2();
505  if (m2 < 0) return false;
506  } else if (parametrization == pat::CandKinResolution::EScaledMomDev) {
507  if (parameters[3] < 0) return false;
508  double m2 = ROOT::Math::Square(p.R()*initialP4.E()/initialP4.P()) - p.Mag2();
509  if (m2 < 0) return false;
510  }
511  return true;
512  }
513  // ======= OTHER ==========
515  throw cms::Exception("Invalid parametrization") << parametrization;
516  default:
517  throw cms::Exception("Not Implemented") << "getResolEta not yet implemented for parametrization " << parametrization ;
518  }
519 }
520 
521 
AlgebraicVector4 parametersFromP4(pat::CandKinResolution::Parametrization parametrization, const math::XYZTLorentzVector &p4)
Returns a vector of coordinates values given a coordinate frame and a 4-vector.
const char * name(pat::CandKinResolution::Parametrization param)
Convert a number into a string.
PtEtaPhiMLorentzVectorD PtEtaPhiMLorentzVector
Lorentz vector with cartesian internal representation.
Definition: LorentzVector.h:26
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:30
T sqrt(T t)
Definition: SSEVec.h:28
double p4[4]
Definition: TauolaWrapper.h:92
void setParametersFromP4(pat::CandKinResolution::Parametrization parametrization, AlgebraicVector4 &pars, const math::XYZTLorentzVector &p4)
Set the values of the parameters for a given 4-momentum.
double p2[4]
Definition: TauolaWrapper.h:90
bool isAlwaysMassive(pat::CandKinResolution::Parametrization parametrization)
Is this parametrization usable only with massive objects?
#define M_PI
Definition: BFit3D.cc:3
math::PtEtaPhiMLorentzVector polarP4fromParameters(pat::CandKinResolution::Parametrization parametrization, const AlgebraicVector4 &parameters, const math::PtEtaPhiMLorentzVector &initialP4)
AlgebraicVector4 diffToParameters(pat::CandKinResolution::Parametrization parametrization, const math::XYZTLorentzVector &p4ini, const math::XYZTLorentzVector &p4fin)
Expresses the difference between two 4-momentum vectors as a shift in coordinates in a given frame...
bool isPhysical(pat::CandKinResolution::Parametrization parametrization, const AlgebraicVector4 &v4, const math::PtEtaPhiMLorentzVector &initialP4)
math::XYZTLorentzVector p4fromParameters(pat::CandKinResolution::Parametrization parametrization, const AlgebraicVector4 &parameters, const math::XYZTLorentzVector &initialP4)
double p1[4]
Definition: TauolaWrapper.h:89
void setParametersFromAnyVector(pat::CandKinResolution::Parametrization parametrization, AlgebraicVector4 &pars, const T &p4)
For internal use only, so we provide only the interface. Use the &#39;setParametersFromP4&#39;.
pat::CandKinResolution::Parametrization fromString(const std::string &name)
Convert a name into a parametrization code.
ROOT::Math::SVector< double, 4 > AlgebraicVector4
mathSSE::Vec4< T > v
bool isAlwaysMassless(pat::CandKinResolution::Parametrization parametrization)
Is this parametrization usable only with massless objects?
bool isMassConstrained(pat::CandKinResolution::Parametrization parametrization)
If this parametrization has a mass constraint (including the &#39;isAlwaysMassless&#39; case) ...