00001
00002 #include "MSLayersAtAngle.h"
00003
00004 #include "RecoTracker/TkMSParametrization/interface/PixelRecoLineRZ.h"
00005 #include "DataFormats/Math/interface/approx_log.h"
00006
00007 using namespace std;
00008
00009 namespace {
00010 template <class T> inline T sqr( T t) {return t*t;}
00011 }
00012
00013
00014 void
00015 MSLayersAtAngle::init() {
00016 std::sort(theLayers.begin(), theLayers.end());
00017 int i = -1; indeces.clear();
00018 for ( auto const & l : theLayers ) {
00019 ++i;
00020 int sq = l.seqNum();
00021 if (sq<0) continue;
00022 if (sq>=int(indeces.size())) indeces.resize(sq+1,-1);
00023 indeces[sq]=i;
00024 }
00025 }
00026
00027
00028 MSLayersAtAngle::MSLayersAtAngle(const vector<MSLayer> & layers)
00029 : theLayers(layers)
00030 {
00031 init();
00032 }
00033
00034 const MSLayer * MSLayersAtAngle::findLayer(const MSLayer & layer) const
00035 {
00036 vector<MSLayer>::const_iterator it =
00037 find(theLayers.begin(), theLayers.end(), layer);
00038 return it==theLayers.end() ? 0 : &(*it);
00039 }
00040
00041
00042 void MSLayersAtAngle::update(const MSLayer & layer)
00043 {
00044 vector<MSLayer>::iterator it = find(theLayers.begin(),theLayers.end(),layer);
00045 if (it == theLayers.end()) {
00046 theLayers.push_back(layer);
00047 init();
00048 } else {
00049 *it = layer;
00050 }
00051 }
00052
00053
00054 float MSLayersAtAngle::sumX0D(
00055 const PixelRecoPointRZ & pointI,
00056 const PixelRecoPointRZ & pointO) const
00057 {
00058 LayerItr iO = findLayer(pointO, theLayers.begin(), theLayers.end());
00059
00060 LayerItr iI = findLayer(pointI, theLayers.begin(), iO);
00061
00062
00063 return sqrt(sum2RmRn(iI,iO, pointO.r(),
00064 SimpleLineRZ(pointI, pointO)));
00065 }
00066
00067
00068 float MSLayersAtAngle::sumX0D( int il, int ol,
00069 const PixelRecoPointRZ & pointI,
00070 const PixelRecoPointRZ & pointO) const
00071 {
00072
00073 if (il>=int(indeces.size()) || ol>=int(indeces.size()) ||
00074 indeces[il]<0 || indeces[ol] < 0) return sumX0D(pointI,pointO);
00075
00076 LayerItr iI = theLayers.begin() + indeces[il];
00077 LayerItr iO = theLayers.begin() + indeces[ol];
00078
00079
00080 return sqrt(sum2RmRn(iI,iO, pointO.r(),
00081 SimpleLineRZ(pointI, pointO)));
00082 }
00083
00084
00085
00086 bool doPrint=false;
00087
00088 float MSLayersAtAngle::sumX0D(
00089 const PixelRecoPointRZ & pointI,
00090 const PixelRecoPointRZ & pointM,
00091 const PixelRecoPointRZ & pointO) const
00092 {
00093 LayerItr iO = findLayer(pointO, theLayers.begin(), theLayers.end());
00094 LayerItr iI = findLayer(pointI, theLayers.begin(), iO);
00095 LayerItr iM = findLayer(pointM, iI, iO);
00096
00097
00098 float drOI = pointO.r() - pointI.r();
00099 float drMO = pointO.r() - pointM.r();
00100 float drMI = pointM.r() - pointI.r();
00101
00102 SimpleLineRZ line(pointI, pointO);
00103 float sum2I = sum2RmRn(iI+1, iM, pointI.r(), line);
00104 float sum2O = sum2RmRn(iM, iO, pointO.r(), line);
00105
00106 float sum = std::sqrt( sum2I* sqr(drMO) + sum2O*sqr(drMI) )/drOI;
00107
00108
00109
00110 if (doPrint)
00111 std::cout << "old " << (*iI).seqNum() << " " << iI-theLayers.begin() << ", "
00112 << (*iM).seqNum() << " " << iM-theLayers.begin() << ", "
00113 << (*iO).seqNum() << " " << iO-theLayers.begin() << " "
00114 << pointI.r() << " " << pointI.z()
00115 << " " << sum
00116 << std::endl;
00117
00118
00119 return sum;
00120 }
00121
00122
00123 float MSLayersAtAngle::sumX0D(float zV, int il, int ol,
00124 const PixelRecoPointRZ & pointI,
00125 const PixelRecoPointRZ & pointO) const {
00126
00127 PixelRecoPointRZ pointV(0.f,zV);
00128
00129
00130 if (il>=int(indeces.size()) || ol>=int(indeces.size()) ||
00131 indeces[il]<0 || indeces[ol] < 0) return sumX0D(pointV,pointI,pointO);
00132
00133 LayerItr iI = theLayers.begin() + indeces[il];
00134 LayerItr iO = theLayers.begin() + indeces[ol];
00135
00136
00137
00138 float drOI = pointO.r();
00139 float drMO = pointO.r() - pointI.r();
00140 float drMI = pointI.r();
00141
00142 SimpleLineRZ line(pointV, pointO);
00143 float sum2I = sum2RmRn(theLayers.begin()+1, iI, pointV.r(), line);
00144 float sum2O = sum2RmRn(iI, iO, pointO.r(), line);
00145
00146 float sum = std::sqrt( sum2I* sqr(drMO) + sum2O*sqr(drMI) )/drOI;
00147
00148 if (doPrint)
00149 std::cout << "new " << il << " " << (*iI).seqNum() << " " << iI-theLayers.begin() << ", "
00150 << ol << " " << (*iO).seqNum() << " " << iO-theLayers.begin() << " " << zV
00151 << " " << sum
00152 << std::endl;
00153
00154 return sum;
00155
00156 }
00157
00158
00159
00160 float MSLayersAtAngle::sum2RmRn(
00161 MSLayersAtAngle::LayerItr i1,
00162 MSLayersAtAngle::LayerItr i2,
00163 float rTarget,
00164 const SimpleLineRZ & line) const
00165 {
00166 float sum2 = 0.f;
00167 float cotTh = line.cotLine();
00168 for (LayerItr it = i1; it < i2; it++) {
00169 std::pair<PixelRecoPointRZ,bool> cross = it->crossing(line);
00170 if (cross.second) {
00171 float x0 = it->x0(cotTh);
00172 float dr = rTarget-cross.first.r();
00173 if (x0 > 1.e-5f) dr *= 1.f+0.038f*unsafe_logf<2>(x0);
00174 sum2 += x0*dr*dr;
00175 }
00176
00177 }
00178 return sum2;
00179 }
00180
00181 MSLayersAtAngle::LayerItr MSLayersAtAngle::findLayer(
00182 const PixelRecoPointRZ & point,
00183 MSLayersAtAngle::LayerItr ibeg,
00184 MSLayersAtAngle::LayerItr iend) const
00185 {
00186 const float BIG=99999.f;
00187 const float EPSILON = 1.e-8f;
00188 LayerItr theIt = ibeg; float dist = BIG;
00189 for (LayerItr it = ibeg; it < iend; it++) {
00190 float d = it->distance2(point);
00191 if (d < dist) {
00192 if (d < EPSILON) return it;
00193 dist = d;
00194 theIt = it;
00195 }
00196 }
00197 return theIt;
00198 }
00199
00200
00201 void MSLayersAtAngle::print() const
00202 {
00203 for (LayerItr it = theLayers.begin(); it != theLayers.end(); it++)
00204 cout <<*it<<endl;
00205 }
00206