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()), 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 theX0Data(dataX0)
00066 { }
00067
00068
00069
00070 bool MSLayer::operator== (const MSLayer &o) const
00071 {
00072 return theFace == o.theFace && std::abs(thePosition-o.thePosition) < 1.e-3f;
00073 }
00074
00075 bool MSLayer::operator< (const MSLayer & o) const
00076 {
00077
00078 if (theFace==barrel && o.theFace==barrel)
00079 return thePosition < o.thePosition;
00080 else if (theFace==barrel && o.theFace==endcap)
00081 return thePosition < o.range().max();
00082 else if (theFace==endcap && o.theFace==endcap )
00083 return std::abs(thePosition) < std::abs(o.thePosition);
00084 else
00085 return range().max() < o.thePosition;
00086 }
00087
00088
00089 pair<PixelRecoPointRZ,bool> MSLayer::crossing( const PixelRecoLineRZ & line) const
00090 {
00091 const float eps = 1.e-5;
00092 bool inLayer = true;
00093 if (theFace==barrel) {
00094 float value = line.zAtR(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(thePosition, value), inLayer) ;
00104 }
00105 else {
00106 float value = line.rAtZ(thePosition);
00107 if (value > theRange.max()) {
00108 value = theRange.max()-eps;
00109 inLayer = false;
00110 }
00111 else if (value < theRange.min() ) {
00112 value = theRange.min()+eps;
00113 inLayer = false;
00114 }
00115 return make_pair( PixelRecoPointRZ( value, thePosition), inLayer);
00116 }
00117 }
00118
00119 float MSLayer::distance(const PixelRecoPointRZ & point) const
00120 {
00121 float dr = 0;
00122 float dz = 0;
00123 switch(theFace) {
00124 case barrel:
00125 dr = std::abs(point.r()-thePosition);
00126 if (theRange.inside(point.z())) {
00127 return (dr < theHalfThickness) ? 0.f : dr;
00128 }
00129 else {
00130 dz = point.z() > theRange.max() ?
00131 point.z()-theRange.max() : theRange.min() - point.z();
00132 }
00133 break;
00134 case endcap:
00135 dz = std::abs(point.z()-thePosition);
00136 if (theRange.inside(point.r())) {
00137 return (dz < theHalfThickness) ? 0. : dz;
00138 }
00139 else {
00140 dr = point.r() > theRange.max() ?
00141 point.r()-theRange.max() : theRange.min()-point.r();
00142 }
00143 break;
00144 case invalidLoc: break;
00145 }
00146 return std::sqrt(sqr(dr)+sqr(dz));
00147 }
00148
00149
00150
00151 float MSLayer::x0(float cotTheta) const
00152 {
00153 if (theX0Data.hasX0) {
00154 float OverSinTheta = std::sqrt(1.f+cotTheta*cotTheta);
00155 switch(theFace) {
00156 case barrel: return theX0Data.x0*OverSinTheta;
00157 case endcap: return theX0Data.x0*std::abs(OverSinTheta/cotTheta);
00158 case invalidLoc: return 0.;
00159 }
00160 } else if (theX0Data.allLayers) {
00161 const MSLayer * dataLayer =
00162 theX0Data.allLayers->layers(cotTheta).findLayer(*this);
00163 if (dataLayer) return dataLayer->x0(cotTheta);
00164 }
00165 return 0.;
00166 }
00167
00168
00169 float MSLayer::sumX0D(float cotTheta) const
00170 {
00171 if (theX0Data.hasX0) {
00172 switch(theFace) {
00173 case barrel:
00174 return theX0Data.sumX0D
00175 *std::sqrt( std::sqrt( (1.f+cotTheta*cotTheta)
00176 / (1.f+theX0Data.cotTheta*theX0Data.cotTheta)
00177 )
00178 );
00179 case endcap:
00180 return (theX0Data.hasFSlope) ?
00181 theX0Data.sumX0D
00182 + theX0Data.slopeSumX0D * (1.f/cotTheta-1.f/theX0Data.cotTheta)
00183 : theX0Data.sumX0D;
00184 case invalidLoc: break;
00185 }
00186 } else if (theX0Data.allLayers) {
00187 const MSLayer* dataLayer =
00188 theX0Data.allLayers->layers(cotTheta).findLayer(*this);
00189 if (dataLayer) return dataLayer->sumX0D(cotTheta);
00190 }
00191 return 0.;
00192
00193 }