00001 #include "RecoTracker/TkMSParametrization/interface/MSLayer.h"
00002 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00003 #include "TrackingTools/DetLayers/interface/BarrelDetLayer.h"
00004 #include "TrackingTools/DetLayers/interface/ForwardDetLayer.h"
00005 #include "RecoTracker/TkMSParametrization/interface/MSLayersKeeper.h"
00006
00007 using namespace GeomDetEnumerators;
00008 using namespace std;
00009 template <class T> T sqr( T t) {return t*t;}
00010
00011
00012 ostream& operator<<( ostream& s, const MSLayer & l)
00013 {
00014 s <<" face: "<<l.face()
00015 <<" pos:"<<l.position()<<", "
00016 <<" range:"<<l.range()<<", "
00017 <<l.theX0Data;
00018 return s;
00019 }
00020
00021 ostream& operator<<( ostream& s, const MSLayer::DataX0 & d)
00022 {
00023 if (d.hasX0) s << "x0="<<d.x0 <<" sumX0D="<<d.sumX0D;
00024 else if (d.allLayers) s << "x0 by MSLayersKeeper";
00025 else s <<"empty DataX0";
00026 return s;
00027 }
00028
00029
00030 MSLayer::MSLayer(const DetLayer* layer, DataX0 dataX0)
00031 : theFace(layer->location()), theX0Data(dataX0)
00032 {
00033 const BarrelDetLayer* bl; const ForwardDetLayer * fl;
00034 theHalfThickness = layer->surface().bounds().thickness()/2;
00035
00036 switch (theFace) {
00037 case barrel :
00038 bl = dynamic_cast<const BarrelDetLayer* >(layer);
00039 thePosition = bl->specificSurface().radius();
00040 theRange = Range(-bl->surface().bounds().length()/2,
00041 bl->surface().bounds().length()/2);
00042 break;
00043 case endcap :
00044 fl = dynamic_cast<const ForwardDetLayer* >(layer);
00045 thePosition = fl->position().z();
00046 theRange = Range(fl->specificSurface().innerRadius(),
00047 fl->specificSurface().outerRadius());
00048 break;
00049 default:
00050 cout << " ** MSLayer ** unknown part - will not work!" <<endl;
00051 break;
00052 }
00053 }
00054
00055 MSLayer::MSLayer(Location part, float position, Range range, float halfThickness,
00056 DataX0 dataX0)
00057 : theFace(part),
00058 thePosition(position),
00059 theRange(range),
00060 theHalfThickness(halfThickness),
00061 theX0Data(dataX0)
00062 { }
00063
00064
00065
00066 bool MSLayer::operator== (const MSLayer &o) const
00067 {
00068
00069 if ( theFace != o.theFace || fabs(thePosition-o.thePosition) > 1.e-3 )
00070 return false;
00071 else
00072 return true;
00073 }
00074
00075
00076 pair<PixelRecoPointRZ,bool> MSLayer::crossing(
00077 const PixelRecoLineRZ & line) const
00078 {
00079 const float eps = 1.e-5;
00080 bool inLayer = true;
00081 if (theFace==barrel) {
00082 float value = line.zAtR(thePosition);
00083 if (value > theRange.max()) {
00084 value = theRange.max()-eps;
00085 inLayer = false;
00086 }
00087 else if (value < theRange.min() ) {
00088 value = theRange.min()+eps;
00089 inLayer = false;
00090 }
00091 return make_pair( PixelRecoPointRZ(thePosition, value), inLayer) ;
00092 }
00093 else {
00094 float value = line.rAtZ(thePosition);
00095 if (value > theRange.max()) {
00096 value = theRange.max()-eps;
00097 inLayer = false;
00098 }
00099 else if (value < theRange.min() ) {
00100 value = theRange.min()+eps;
00101 inLayer = false;
00102 }
00103 return make_pair( PixelRecoPointRZ( value, thePosition), inLayer);
00104 }
00105 }
00106
00107 float MSLayer::distance(const PixelRecoPointRZ & point) const
00108 {
00109 float dr = 0;
00110 float dz = 0;
00111 switch(theFace) {
00112 case barrel:
00113 dr = fabs(point.r()-thePosition);
00114 if (theRange.inside(point.z())) {
00115 return (dr < theHalfThickness) ? 0. : dr;
00116 }
00117 else {
00118 dz = point.z() > theRange.max() ?
00119 point.z()-theRange.max() : theRange.min() - point.z();
00120 }
00121 break;
00122 case endcap:
00123 dz = fabs(point.z()-thePosition);
00124 if (theRange.inside(point.r())) {
00125 return (dz < theHalfThickness) ? 0. : dz;
00126 }
00127 else {
00128 dr = point.r() > theRange.max() ?
00129 point.r()-theRange.max() : theRange.min()-point.r();
00130 }
00131 break;
00132 }
00133 return sqrt(sqr(dr)+sqr(dz));
00134 }
00135
00136
00137 bool MSLayer::operator< (const MSLayer & o) const
00138 {
00139
00140 if (theFace==barrel && o.theFace==barrel)
00141 return thePosition < o.thePosition;
00142 else if (theFace==barrel && o.theFace==endcap)
00143 return thePosition < o.range().max();
00144 else if (theFace==endcap && o.theFace==endcap )
00145 return fabs(thePosition) < fabs(o.thePosition);
00146 else
00147 return range().max() < o.thePosition;
00148 }
00149
00150 float MSLayer::x0(float cotTheta) const
00151 {
00152 if (theX0Data.hasX0) {
00153 float sinTheta = 1/sqrt(1+cotTheta*cotTheta);
00154 switch(theFace) {
00155 case barrel: return theX0Data.x0/sinTheta;
00156 case endcap: return theX0Data.x0/fabs(cotTheta*sinTheta);
00157 }
00158 } else if (theX0Data.allLayers) {
00159 const MSLayer * dataLayer =
00160 theX0Data.allLayers->layers(cotTheta).findLayer(*this);
00161 if (dataLayer) return dataLayer->x0(cotTheta);
00162 }
00163 return 0.;
00164 }
00165
00166
00167 float MSLayer::sumX0D(float cotTheta) const
00168 {
00169 if (theX0Data.hasX0) {
00170 switch(theFace) {
00171 case barrel:
00172 return theX0Data.sumX0D
00173 *sqrt(sqrt( (1+cotTheta*cotTheta)
00174 / (1+theX0Data.cotTheta*theX0Data.cotTheta)));
00175 return theX0Data.sumX0D;
00176 case endcap:
00177 return (theX0Data.hasFSlope) ?
00178 theX0Data.sumX0D
00179 + theX0Data.slopeSumX0D * (1/cotTheta-1/theX0Data.cotTheta)
00180 : theX0Data.sumX0D;
00181 }
00182 } else if (theX0Data.allLayers) {
00183 const MSLayer* dataLayer =
00184 theX0Data.allLayers->layers(cotTheta).findLayer(*this);
00185 if (dataLayer) return dataLayer->sumX0D(cotTheta);
00186 }
00187 return 0.;
00188
00189 }