00001
00002 #include "RecoTracker/TkMSParametrization/interface/MSLayersAtAngle.h"
00003
00004 #include "RecoTracker/TkMSParametrization/interface/PixelRecoLineRZ.h"
00005 using namespace std;
00006
00007 template <class T> T sqr( T t) {return t*t;}
00008
00009
00010 MSLayersAtAngle::MSLayersAtAngle(const vector<MSLayer> & layers)
00011 : theLayers(layers)
00012 { sort(theLayers.begin(), theLayers.end()); }
00013
00014 const MSLayer * MSLayersAtAngle::findLayer(const MSLayer & layer) const
00015 {
00016 vector<MSLayer>::const_iterator it =
00017 find(theLayers.begin(), theLayers.end(), layer);
00018 return it==theLayers.end() ? 0 : &(*it);
00019 }
00020
00021
00022 void MSLayersAtAngle::update(const MSLayer & layer)
00023 {
00024 vector<MSLayer>::iterator it = find(theLayers.begin(),theLayers.end(),layer);
00025 if (it == theLayers.end()) {
00026 theLayers.push_back(layer);
00027 sort(theLayers.begin(), theLayers.end());
00028 } else {
00029 *it = layer;
00030 }
00031 }
00032
00033
00034 float MSLayersAtAngle::sumX0D(
00035 const PixelRecoPointRZ & pointI,
00036 const PixelRecoPointRZ & pointO) const
00037 {
00038 LayerItr iO = findLayer(pointO, theLayers.begin(), theLayers.end());
00039
00040 LayerItr iI = findLayer(pointI, theLayers.begin(), iO);
00041
00042
00043 return sqrt(sum2RmRn(iI,iO, pointO.r(),
00044 PixelRecoLineRZ(pointI,pointO)));
00045 }
00046
00047 float MSLayersAtAngle::sumX0D(
00048 const PixelRecoPointRZ & pointI,
00049 const PixelRecoPointRZ & pointM,
00050 const PixelRecoPointRZ & pointO) const
00051 {
00052 LayerItr iO = findLayer(pointO, theLayers.begin(), theLayers.end());
00053 LayerItr iI = findLayer(pointI, theLayers.begin(), iO);
00054 LayerItr iM = findLayer(pointM, iI, iO);
00055
00056 float drOI = pointO.r() - pointI.r();
00057 float drMO = pointO.r() - pointM.r();
00058 float drMI = pointM.r() - pointI.r();
00059
00060 PixelRecoLineRZ line(pointI,pointO);
00061 float sum2I = sum2RmRn(iI+1,iM, pointI.r(), line);
00062 float sum2O = sum2RmRn(iM, iO, pointO.r(), line);
00063
00064 return sqrt( sum2I* sqr(drMO) + sum2O*sqr(drMI) )/drOI;
00065 }
00066
00067
00068 float MSLayersAtAngle::sum2RmRn(
00069 MSLayersAtAngle::LayerItr i1,
00070 MSLayersAtAngle::LayerItr i2,
00071 float rTarget,
00072 const PixelRecoLineRZ & line) const
00073 {
00074 float sum2 = 0.;
00075 float cotTh = line.cotLine();
00076 for (LayerItr it = i1; it < i2; it++) {
00077 pair<PixelRecoPointRZ,bool> cross = it->crossing(line);
00078 if (cross.second) {
00079 float x0 = it->x0(cotTh);
00080 float dr = rTarget-cross.first.r();
00081 if (x0 > 1.e-5) dr *= 1+0.038*log(x0);
00082 sum2 += x0*dr*dr;
00083 }
00084
00085 }
00086 return sum2;
00087 }
00088
00089 MSLayersAtAngle::LayerItr MSLayersAtAngle::findLayer(
00090 const PixelRecoPointRZ & point,
00091 MSLayersAtAngle::LayerItr ibeg,
00092 MSLayersAtAngle::LayerItr iend) const
00093 {
00094 const float BIG=99999.;
00095 const float EPSILON = 1.e-4;
00096 LayerItr theIt = ibeg; float dist = BIG;
00097 for (LayerItr it = ibeg; it < iend; it++) {
00098 float d = it->distance(point);
00099 if (d < dist) {
00100 if (d < EPSILON) return it;
00101 dist = d;
00102 theIt = it;
00103 }
00104 }
00105 return theIt;
00106 }
00107
00108
00109 void MSLayersAtAngle::print() const
00110 {
00111 for (LayerItr it = theLayers.begin(); it != theLayers.end(); it++)
00112 cout <<*it<<endl;
00113 }
00114