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