00001 00002 00003 00004 00005 00006 00007 #include "Geometry/CommonTopologies/interface/TwoBowedSurfacesDeformation.h" 00008 #include "Geometry/CommonTopologies/interface/SurfaceDeformationFactory.h" 00009 00010 #include "FWCore/MessageLogger/interface/MessageLogger.h" 00011 00012 // already included via header: 00013 // #include <vector> 00014 00015 //------------------------------------------------------------------------------ 00016 TwoBowedSurfacesDeformation::TwoBowedSurfacesDeformation(const std::vector<double> &pars) 00017 : theParameters(pars) 00018 { 00019 if (pars.size() != minParameterSize()) { 00020 edm::LogError("BadSetup") << "@SUB=TwoBowedSurfacesDeformation" 00021 << "Input vector of wrong size " << pars.size() 00022 << " instead of " << minParameterSize() << ", add zeros to fill up!"; 00023 } 00024 while (theParameters.size() < minParameterSize()) theParameters.push_back(0.); 00025 } 00026 00027 //------------------------------------------------------------------------------ 00028 TwoBowedSurfacesDeformation* TwoBowedSurfacesDeformation::clone() const 00029 { 00030 return new TwoBowedSurfacesDeformation(theParameters); 00031 } 00032 00033 //------------------------------------------------------------------------------ 00034 int TwoBowedSurfacesDeformation::type() const 00035 { 00036 return SurfaceDeformationFactory::kTwoBowedSurfaces; 00037 } 00038 00039 //------------------------------------------------------------------------------ 00040 SurfaceDeformation::Local2DVector 00041 TwoBowedSurfacesDeformation::positionCorrection(const Local2DPoint &localPos, 00042 const LocalTrackAngles &localAngles, 00043 double length, double width) const 00044 { 00045 const double ySplit = this->parameters().back(); 00046 00047 // treatment of different widthes at high/low y could be done by theRelWidthLowY or so 00048 // if (widthLowY > 0. && widthHighY != widthLowY) { 00049 // std::cout << "SurfaceDeformation::positionCorrection2Bowed: Cannot yet deal " 00050 // << " with different widthes, take " << widthHighY << " not " << widthLowY 00051 // << std::endl; 00052 // } 00053 // const double width = widthHighY; 00054 00055 // Some signs depend on whether we are in surface part below or above ySplit: 00056 const double sign = (localPos.y() < ySplit ? +1. : -1.); 00057 const double yMiddle = ySplit * 0.5 - sign * length * .25; 00058 // 'calibrate' y length and transform y to be w.r.t. surface middle 00059 const double myY = localPos.y() - yMiddle; 00060 const double myLength = length * 0.5 + sign * ySplit; 00061 00062 double uRel = 2. * localPos.x() / width; // relative u (-1 .. +1) 00063 double vRel = 2. * myY / myLength; // relative v (-1 .. +1) 00064 // 'range check': 00065 const double cutOff = 1.5; 00066 if (uRel < -cutOff) { uRel = -cutOff; } else if (uRel > cutOff) { uRel = cutOff; } 00067 if (vRel < -cutOff) { vRel = -cutOff; } else if (vRel > cutOff) { vRel = cutOff; } 00068 00069 const std::vector<double> &pars = this->parameters(); 00070 // 1st, get dw effect depending 00071 // - on the surface sagittas (Legendre polynomials), 00072 // see BowedSurfaceAlignmentDerivatives::operator()(..) 00073 // - relative dw 00074 // - surface specific dalpha (note that this shifts surface specific dw) 00075 // - surface specific dbeta 00076 const double dw 00077 = (uRel * uRel - 1./3.) * (pars[0] + sign * pars[9]) // sagittaX 00078 + uRel * vRel * (pars[1] + sign * pars[10]) // sagittaXY 00079 + (vRel * vRel - 1./3.) * (pars[2] + sign * pars[11]) // sagittaY 00080 + sign * pars[5] // different dw 00081 + myY * sign * pars[6] // different dalpha 00082 - localPos.x() * sign * pars[7]; // different dbeta 00083 // 2nd, translate the dw effect to shifts in x and y 00084 // Positive dxdz/dydz and positive dw mean negative shift in x/y: 00085 Local2DVector::ScalarType x = -dw * localAngles.dxdz(); 00086 Local2DVector::ScalarType y = -dw * localAngles.dydz(); 00087 // 3rd, treat in-plane differences depending on surface from xy-shifts... 00088 x += (sign * pars[3]); // different du 00089 y += (sign * pars[4]); // different dv 00090 // ...and gamma-rotation 00091 x -= myY * (sign * pars[8]); // different dgamma for u 00092 y += localPos.x() * (sign * pars[8]); // different dgamma for v 00093 00094 return Local2DVector(x, y); 00095 } 00096 00097 //------------------------------------------------------------------------------ 00098 bool TwoBowedSurfacesDeformation::add(const SurfaceDeformation &other) 00099 { 00100 if (this->type() == other.type()) { 00101 const std::vector<double> otherParameters(other.parameters()); 00102 if (otherParameters.size() == theParameters.size()) { 00103 if (theParameters.back() == otherParameters.back()) { 00104 for (unsigned int i = 0; i < theParameters.size() - 1; ++i) {// -1 for ySplit 00105 // mean bows, delta shifts, delta angles and delta bows can simply be added up 00106 theParameters[i] += otherParameters[i]; 00107 } 00108 return true; 00109 } else { // ySplit values are different! 00110 LogDebug("Alignment") << "@SUB=TwoBowedSurfacesDeformation::add" 00111 << "Different ySplit: this " << theParameters.back() 00112 << ", to add " << otherParameters.back(); 00113 } 00114 } // same size 00115 } // same type 00116 00117 return false; 00118 } 00119 00120 //------------------------------------------------------------------------------ 00121 std::vector<double> TwoBowedSurfacesDeformation::parameters() const 00122 { 00123 return theParameters; 00124 }