00001 #include "RecoTracker/TkHitPairs/src/InnerDeltaPhi.h"
00002 #include "TrackingTools/DetLayers/interface/BarrelDetLayer.h"
00003 #include "TrackingTools/DetLayers/interface/ForwardDetLayer.h"
00004 #include "RecoTracker/TkMSParametrization/interface/PixelRecoUtilities.h"
00005 #include "RecoTracker/TkMSParametrization/interface/PixelRecoPointRZ.h"
00006 #include "RecoTracker/TkTrackingRegions/interface/TrackingRegionBase.h"
00007 #include "RecoTracker/TkMSParametrization/interface/PixelRecoRange.h"
00008 #include "DataFormats/GeometryVector/interface/Basic2DVector.h"
00009
00010
00011 using namespace std;
00012
00013 #include "RecoTracker/TkSeedGenerator/interface/FastCircle.h"
00014
00015 template <class T> inline T sqr( T t) {return t*t;}
00016
00017 inline double cropped_asin(double x) {
00018 return abs(x) <= 1 ? asin(x) : (x > 0 ? M_PI/2 : -M_PI/2);
00019 }
00020
00021 namespace {
00022 double checked_asin(double x, const char *expr, const char *file, int line) {
00023 if (fabs(x) >= 1.0) throw cms::Exception("CorruptData") << "asin(x) called with x = " << expr << " = " << x << "\n\tat " << file << ":" << line << "\n";
00024 return asin(x);
00025 }
00026 }
00027
00028
00029
00030 InnerDeltaPhi:: InnerDeltaPhi( const DetLayer& layer,
00031 const TrackingRegion & region,
00032 const edm::EventSetup& iSetup,
00033 bool precise, float extraTolerance)
00034 : thePrecise(precise),
00035 theROrigin(region.originRBound()),
00036 theRLayer(0),
00037 theThickness(0),
00038 theExtraTolerance(extraTolerance),
00039 theA(0),
00040 theB(0),
00041 theVtxZ(region.origin().z()),
00042 thePtMin(region.ptMin()),
00043 theVtx(region.origin().x(),region.origin().y()),
00044 sigma(&layer,iSetup)
00045 {
00046 float zMinOrigin = theVtxZ-region.originZBound();
00047 float zMaxOrigin = theVtxZ+region.originZBound();
00048 theRCurvature = PixelRecoUtilities::bendingRadius(thePtMin,iSetup);
00049
00050
00051 if (layer.location() == GeomDetEnumerators::barrel) initBarrelLayer( layer);
00052 else initForwardLayer( layer, zMinOrigin, zMaxOrigin);
00053
00054 }
00055
00056
00057 InnerDeltaPhi::~InnerDeltaPhi() {}
00058
00059 void InnerDeltaPhi::initBarrelLayer( const DetLayer& layer)
00060 {
00061 const BarrelDetLayer& bl = static_cast<const BarrelDetLayer&>(layer);
00062 float rLayer = bl.specificSurface().radius();
00063
00064
00065 theThickness = layer.surface().bounds().thickness();
00066 theRLayer = rLayer - 0.5f*theThickness;
00067 theRDefined = true;
00068 }
00069
00070 void InnerDeltaPhi::initForwardLayer( const DetLayer& layer,
00071 float zMinOrigin, float zMaxOrigin)
00072 {
00073 const ForwardDetLayer &fl = static_cast<const ForwardDetLayer&>(layer);
00074 theRLayer = fl.specificSurface().innerRadius();
00075 float layerZ = layer.position().z();
00076 theThickness = layer.surface().bounds().thickness();
00077 float layerZmin = layerZ > 0 ? layerZ-0.5f*theThickness: layerZ+0.5f*theThickness;
00078 theB = layerZ > 0 ? zMaxOrigin : zMinOrigin;
00079 theA = layerZmin - theB;
00080 theRDefined = false;
00081 }
00082
00083
00084
00085 PixelRecoRange<float> InnerDeltaPhi::phiRange(const Point2D& hitXY,float hitZ,float errRPhi) const
00086 {
00087 double rLayer = theRLayer;
00088 bool checkCrossing = true;
00089 Point2D crossing;
00090
00091 Point2D dHit = hitXY-theVtx;
00092 double dHitmag = dHit.mag();
00093 double dLayer = 0.;
00094 double dL = 0.;
00095
00096
00097
00098 if (!theRDefined) {
00099 double t = theA/(hitZ-theB); double dt = std::abs(theThickness/(hitZ-theB));
00100 crossing = theVtx + t*dHit;
00101 rLayer = crossing.mag();
00102 dLayer = t*dHitmag; dL = dt * dHitmag;
00103 checkCrossing = false;
00104 if (rLayer < theRLayer) {
00105 checkCrossing = true;
00106 rLayer = theRLayer;
00107 dL = 0.;
00108 }
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 if (checkCrossing) {
00123 double vtxmag2 = theVtx.mag2();
00124 if (vtxmag2 < 1.e-10) {
00125 dLayer = rLayer;
00126 }
00127 else {
00128 double var_c = theVtx.mag2()-sqr(rLayer);
00129 double var_b = 2*theVtx.dot(dHit.unit());
00130 double var_delta = sqr(var_b)-4*var_c;
00131 if (var_delta <=0.) var_delta = 0;
00132 dLayer = 0.5*(-var_b + std::sqrt(var_delta));
00133 }
00134 crossing = theVtx+ dHit.unit() * dLayer;
00135 double cosCross = std::abs( dHit.unit().dot(crossing.unit()));
00136 dL = theThickness/cosCross;
00137 }
00138
00139
00140
00141
00142 double cosCross = std::abs( dHit.unit().dot(crossing.unit()));
00143
00144 double alphaHit = cropped_asin( dHitmag/(2*theRCurvature));
00145 double deltaPhi = fabs( alphaHit - cropped_asin( dLayer/(2*theRCurvature)));
00146 deltaPhi *= dLayer/(rLayer*cosCross);
00147
00148
00149
00150 Point2D crossing2 = theVtx + dHit.unit()* (dLayer+dL);
00151 double phicross2 = crossing2.phi();
00152 double phicross1 = crossing.phi();
00153 double dphicross = phicross2-phicross1;
00154 if (dphicross < -M_PI) dphicross += 2*M_PI;
00155 if (dphicross > M_PI) dphicross -= 2*M_PI;
00156 if (dphicross > M_PI/2) dphicross = 0.;
00157 phicross2 = phicross1 + dphicross;
00158
00159
00160
00161 double deltaPhiOrig = cropped_asin( theROrigin * (dHitmag-dLayer) / (dHitmag*dLayer));
00162 deltaPhiOrig *= dLayer/(rLayer*cosCross);
00163
00164
00165 double deltaPhiHit = theExtraTolerance / rLayer;
00166
00167
00168
00169 double deltaPhiHitOuter = errRPhi/hitXY.mag();
00170
00171 double margin = deltaPhi+deltaPhiOrig+deltaPhiHit+deltaPhiHitOuter ;
00172
00173 if (thePrecise) {
00174
00175 PixelRecoPointRZ zero(0., theVtxZ);
00176 PixelRecoPointRZ point(hitXY.mag(), hitZ);
00177 double scatt = 3.f*sigma(thePtMin,zero, point) / rLayer;
00178
00179 margin += scatt ;
00180 }
00181
00182 return PixelRecoRange<float>( std::min(phicross1,phicross2)-margin,
00183 std::max(phicross1,phicross2)+margin);
00184 }
00185
00186 float InnerDeltaPhi::operator()( float rHit, float zHit, float errRPhi) const
00187 {
00188
00189
00190
00191
00192
00193 float alphaHit = std::asin( rHit/(2*theRCurvature));
00194
00195
00196 float rMin = minRadius( rHit, zHit);
00197 float deltaPhi = std::abs( alphaHit - std::asin( rMin/(2*theRCurvature)));
00198
00199
00200 float deltaPhiOrig = asin( theROrigin * (rHit-rMin) / (rHit*rMin));
00201
00202
00203 float deltaPhiHit = theExtraTolerance / rMin;
00204
00205 if (!thePrecise) {
00206 return deltaPhi+deltaPhiOrig+deltaPhiHit;
00207 } else {
00208
00209 PixelRecoPointRZ zero(0., theVtxZ);
00210 PixelRecoPointRZ point(rHit, zHit);
00211 float scatt = 3.f*sigma(thePtMin,zero, point) / rMin;
00212 float deltaPhiHitOuter = errRPhi/rMin;
00213
00214 return deltaPhi+deltaPhiOrig+deltaPhiHit + scatt + deltaPhiHitOuter;
00215 }
00216
00217 }
00218
00219 PixelRecoRange<float> InnerDeltaPhi::operator()(
00220 float rHit, float phiHit, float zHit, float errRPhi) const
00221 {
00222
00223
00224
00225 Point2D hitXY( rHit*std::cos(phiHit), rHit*std::sin(phiHit));
00226 return phiRange(hitXY,zHit,errRPhi);
00227 }
00228
00229 float InnerDeltaPhi::minRadius( float hitR, float hitZ) const
00230 {
00231 if (theRDefined) return theRLayer;
00232 else {
00233 float rmin = (theA*hitR)/(hitZ-theB);
00234 return ( rmin> 0) ? std::max( rmin, theRLayer) : theRLayer;
00235 }
00236 }
00237
00238