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>
20 static map<string,Parametrization> parMaps;
21 if (parMaps.empty()) {
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() <<
"'";
60 default:
return "UNKNOWN";
69 ROOT::Math::CylindricalEta3D<double> converter;
71 switch (parametrization) {
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]);
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());
94 converter = ROOT::Math::Polar3D<double>(parameters[0], parameters[1], 0);
95 ret.SetCoordinates(converter.Rho(),converter.Eta(),parameters[2],parameters[3]);
98 converter = ROOT::Math::Polar3D<double>(parameters[0], parameters[1], 0);
99 ret.SetCoordinates(converter.Rho(),converter.Eta(),parameters[2],initialP4.mass());
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));
107 converter = ROOT::Math::Polar3D<double>(1.0/parameters[0], parameters[1], 0);
108 ret.SetCoordinates(converter.Rho(),converter.Eta(),parameters[2],initialP4.mass());
112 converter = ROOT::Math::Polar3D<double>(1.0, parameters[1], 0);
113 ret.SetCoordinates(parameters[0],converter.Eta(),parameters[2],0);
116 ret.SetCoordinates(parameters[0], parameters[1], parameters[2], 0);
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();
128 p += uth * parameters[1] + uph * parameters[2];
130 ret.SetCoordinates(p.Rho(), p.Eta(), p.Phi(), initialP4.mass() * parameters[3]);
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));
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));
138 ret.SetCoordinates(p.Rho(), p.Eta(), p.Phi(), initialP4.mass());
144 throw cms::Exception(
"Invalid parametrization") << parametrization;
146 throw cms::Exception(
"Not Implemented") <<
"getResolEta not yet implemented for parametrization " << parametrization ;
156 switch (parametrization) {
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]) );
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()) );
173 ret.SetCoordinates(parameters[0], parameters[1], parameters[2], parameters[3]);
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();
185 p += uth * parameters[1] + uph * parameters[2];
187 ret.SetCoordinates(p.X(), p.Y(), p.Z(),
sqrt(p.Mag2() + ROOT::Math::Square(initialP4.mass() * parameters[3])) );
189 ret.SetCoordinates(p.X(), p.Y(), p.Z(), parameters[3] * initialP4.energy());
191 ret.SetCoordinates(p.X(), p.Y(), p.Z(), p.R() * initialP4.E()/initialP4.P());
193 ret.SetCoordinates(p.X(), p.Y(), p.Z(),
sqrt(p.Mag2() + initialP4.mass()*initialP4.mass()));
204 template <
typename T>
209 switch (parametrization) {
212 ret[0] = p4.px(); ret[1] = p4.py(); ret[2] = p4.pz(); ret[3] = p4.mass();
215 ret[0] = p4.px(); ret[1] = p4.py(); ret[2] = p4.pz(); ret[3] = p4.mass();
218 ret[0] = p4.px(); ret[1] = p4.py(); ret[2] = p4.pz(); ret[3] = p4.energy();
222 ret[0] = p4.P(); ret[1] = p4.theta(); ret[2] = p4.phi(); ret[3] = p4.mass();
225 ret[0] = p4.P(); ret[1] = p4.theta(); ret[2] = p4.phi(); ret[3] = p4.mass();
228 ret[0] = p4.P(); ret[1] = p4.theta(); ret[2] = p4.phi(); ret[3] = p4.energy();
231 ret[0] = 1.0/p4.P(); ret[1] = p4.theta(); ret[2] = p4.phi(); ret[3] = p4.mass();
235 ret[0] = p4.pt(); ret[1] = p4.theta(); ret[2] = p4.phi(); ret[3] = 0;
238 ret[0] = p4.pt(); ret[1] = p4.eta(); ret[2] = p4.phi(); ret[3] = 0;
243 ret[0] = 1.0; ret[1] = 0.0; ret[2] = 0.0; ret[3] = 1.0;
246 ret[0] = 1.0; ret[1] = 0.0; ret[2] = 0.0; ret[3] = p4.mass();
249 ret[0] = 1.0; ret[1] = 0.0; ret[2] = 0.0; ret[3] = p4.E()/p4.P();
253 throw cms::Exception(
"Invalid parametrization") << parametrization;
255 throw cms::Exception(
"Not Implemented") <<
"getResolEta not yet implemented for parametrization " << parametrization ;
290 switch (parametrization) {
303 while(ret[2] > +
M_PI) ret[2] -= (2*
M_PI);
304 while(ret[2] < -
M_PI) ret[2] += (2*
M_PI);
314 throw cms::Exception(
"Invalid parametrization") << parametrization;
316 throw cms::Exception(
"Not Implemented") <<
"diffToParameters not yet implemented for parametrization " << parametrization ;
327 switch (parametrization) {
340 while(ret[2] > +
M_PI) ret[2] -= (2*
M_PI);
341 while(ret[2] < -
M_PI) ret[2] += (2*
M_PI);
348 typedef ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D<double> > V3Cart;
349 V3Cart
p1 = p4ini.Vect(),
p2 = p4fin.Vect();
350 V3Cart ur = p1.Unit();
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);
358 ret[3] = p4fin.mass()/p4ini.mass() - 1.0;
360 ret[3] = p4fin.energy()/p4ini.energy() - 1.0;
365 throw cms::Exception(
"Invalid parametrization") << parametrization;
367 throw cms::Exception(
"Not Implemented") <<
"diffToParameters not yet implemented for parametrization " << parametrization ;
375 switch (parametrization) {
392 throw cms::Exception(
"Invalid parametrization") << parametrization;
394 throw cms::Exception(
"Not Implemented") <<
"isAlwaysMassless not yet implemented for parametrization " << parametrization ;
401 switch (parametrization) {
418 throw cms::Exception(
"Invalid parametrization") << parametrization;
420 throw cms::Exception(
"Not Implemented") <<
"isAlwaysMassless not yet implemented for parametrization " << parametrization ;
427 switch (parametrization) {
444 throw cms::Exception(
"Invalid parametrization") << parametrization;
446 throw cms::Exception(
"Not Implemented") <<
"isAlwaysMassless not yet implemented for parametrization " << parametrization ;
454 switch (parametrization) {
457 return parameters[3] >= 0;
461 return (parameters[0]*parameters[0] + parameters[1]*parameters[1] + parameters[2]*parameters[2] <= parameters[3]*parameters[3]);
463 return (parameters[0] >= 0 ) &&
464 (parameters[3] >= 0 ) &&
465 (parameters[1] >= 0 ) &&
466 (parameters[1] <=
M_PI);
468 return (parameters[0] >= 0 ) &&
469 (parameters[1] >= 0 ) &&
470 (parameters[1] <=
M_PI);
472 return (parameters[0] >= 0 ) &&
473 (parameters[3] >= parameters[0]) &&
474 (parameters[1] >= 0 ) &&
475 (parameters[1] <=
M_PI ) ;
477 return (parameters[0] > 0 ) &&
478 (parameters[1] >= 0 ) &&
479 (parameters[1] <=
M_PI);
482 return (parameters[0] > 0 ) &&
483 (parameters[1] >= 0 ) &&
484 (parameters[1] <=
M_PI);
486 return (parameters[0] > 0);
489 return (parameters[0] >= 0) &&
490 (parameters[3] >= 0);
492 return (parameters[0] >= 0);
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();
501 p += uth * parameters[1] + uph * parameters[2];
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;
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;
515 throw cms::Exception(
"Invalid parametrization") << parametrization;
517 throw cms::Exception(
"Not Implemented") <<
"getResolEta not yet implemented for parametrization " << parametrization ;
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.
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
void setParametersFromP4(pat::CandKinResolution::Parametrization parametrization, AlgebraicVector4 &pars, const math::XYZTLorentzVector &p4)
Set the values of the parameters for a given 4-momentum.
bool isAlwaysMassive(pat::CandKinResolution::Parametrization parametrization)
Is this parametrization usable only with massive objects?
math::PtEtaPhiMLorentzVector polarP4fromParameters(pat::CandKinResolution::Parametrization parametrization, const AlgebraicVector4 ¶meters, 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 ¶meters, const math::XYZTLorentzVector &initialP4)
void setParametersFromAnyVector(pat::CandKinResolution::Parametrization parametrization, AlgebraicVector4 &pars, const T &p4)
For internal use only, so we provide only the interface. Use the 'setParametersFromP4'.
pat::CandKinResolution::Parametrization fromString(const std::string &name)
Convert a name into a parametrization code.
ROOT::Math::SVector< double, 4 > AlgebraicVector4
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 'isAlwaysMassless' case) ...