00001 00008 #include "PolyFit3DParametrizedMagneticField.h" 00009 #include <FWCore/ParameterSet/interface/ParameterSet.h> 00010 #include <FWCore/MessageLogger/interface/MessageLogger.h> 00011 00012 #include "BFit3D.h" 00013 00014 00015 using namespace std; 00016 using namespace magfieldparam; 00017 00018 PolyFit3DParametrizedMagneticField::PolyFit3DParametrizedMagneticField(double bVal) : 00019 theParam(new BFit3D()) 00020 { 00021 theParam->SetField(bVal); 00022 } 00023 00024 00025 PolyFit3DParametrizedMagneticField::PolyFit3DParametrizedMagneticField(const edm::ParameterSet& parameters) : theParam(new BFit3D()) { 00026 theParam->SetField(parameters.getParameter<double>("BValue")); 00027 00028 // Additional options (documentation by Vassili): 00029 00030 // By default, the package accepts signed value of "r". That means, 00031 // one can cross r=0 and orientation of the coordinate "orts" 00032 // e_r and e_phi will not be flipped over. 00033 // In other words for an r<0 the e_r points inward, in the direction r=0. 00034 // This is a "natural" mode. However, the default behavior may be 00035 // changed by the call 00036 00037 // theParam->UseSignedRad(false); 00038 00039 // In that case with crossing of r=0 e_r and e_phi will be flipped in 00040 // such a way that e_r always points outward. In other words instead of 00041 // (r<0, phi) the (abs(r), phi+PI) will be used in this mode. 00042 00043 // The expansion coefficients for a nominal field in between measurement 00044 // field values (2.0T, 3.5T, 3.8T and 4.0T) by default are calculated by 00045 // means of a linear piecewise interpolation. Another provided 00046 // interpolation mode is cubic spline. This mode can be switched 00047 // on by the call: 00048 00049 // theParam->UseSpline(true); 00050 00051 // From practical point of view the use of spline interpolation doesn't 00052 // change much, but it makes the coefficients' behavior a bit more 00053 // physical at very low/high field values. 00054 } 00055 00056 00057 PolyFit3DParametrizedMagneticField::~PolyFit3DParametrizedMagneticField() { 00058 delete theParam; 00059 } 00060 00061 00062 GlobalVector 00063 PolyFit3DParametrizedMagneticField::inTesla(const GlobalPoint& gp) const { 00064 00065 if (isDefined(gp)) { 00066 return inTeslaUnchecked(gp); 00067 } else { 00068 edm::LogWarning("MagneticField|FieldOutsideValidity") << " Point " << gp << " is outside the validity region of PolyFit3DParametrizedMagneticField"; 00069 return GlobalVector(); 00070 } 00071 } 00072 00073 GlobalVector 00074 PolyFit3DParametrizedMagneticField::inTeslaUnchecked(const GlobalPoint& gp) const { 00075 double Br, Bz, Bphi; 00076 theParam->GetField(gp.perp()/100., gp.z()/100., gp.phi(), 00077 Br, Bz, Bphi); 00078 00079 double cosphi = cos(gp.phi()); 00080 double sinphi = sin(gp.phi()); 00081 00082 return GlobalVector(Br*cosphi - Bphi*sinphi, 00083 Br*sinphi + Bphi*cosphi, 00084 Bz); 00085 } 00086 00087 bool 00088 PolyFit3DParametrizedMagneticField::isDefined(const GlobalPoint& gp) const { 00089 double z = fabs(gp.z()); 00090 double r = gp.perp(); 00091 //"rectangle" |z|<3.5, r<1.9 _except_ the "corners" |z|+2.5*r>6.7, everything in meters 00092 if (z>350. || r>190 || z+2.5*r>670.) return false; 00093 return true; 00094 }