CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/RecoTracker/TkHitPairs/src/InnerDeltaPhi.cc

Go to the documentation of this file.
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 //#define asin(X) checked_asin(X, #X, __FILE__, __LINE__)
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   // the maximal delta phi will be for the innermost hits
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   // compute crossing of stright track with inner layer
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   // compute crossing of track with layer
00113   // dHit - from VTX to outer hit
00114   // rLayer - layer radius
00115   // dLayer - distance from VTX to inner layer in direction of dHit
00116   // vect(rLayer) = vect(rVTX) + vect(dHit).unit * dLayer
00117   //     rLayer^2 = (ect(rVTX) + vect(dHit).unit * dLayer)^2 and we have square eqation for dLayer 
00118   //
00119   // barrel case
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)); //only the value along vector is OK. 
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   // track is crossing layer with angle such as:
00141   // this factor should be taken in computation of eror projection
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   // additinal angle due to not perpendicular stright line crossing  (for displaced beam)
00149   //  double dPhiCrossing = (cosCross > 0.9999) ? 0 : dL *  sqrt(1-sqr(cosCross))/ rLayer;
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.;  // something wrong?
00157   phicross2 = phicross1 + dphicross;
00158         
00159 
00160   // compute additional delta phi due to origin radius
00161   double deltaPhiOrig = cropped_asin( theROrigin * (dHitmag-dLayer) / (dHitmag*dLayer));
00162   deltaPhiOrig *= dLayer/(rLayer*cosCross);
00163 
00164   // inner hit error taken as constant
00165   double deltaPhiHit = theExtraTolerance / rLayer;
00166 
00167   // outer hit error
00168 //   double deltaPhiHitOuter = errRPhi/rLayer; 
00169     double deltaPhiHitOuter = errRPhi/hitXY.mag();
00170 
00171   double margin = deltaPhi+deltaPhiOrig+deltaPhiHit+deltaPhiHitOuter ;
00172 
00173   if (thePrecise) {
00174     // add multiple scattering correction
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   // alpha - angle between particle direction at vertex and position of hit.
00189   // (pi/2 - alpha) - angle hit-vertex-cernter_of_curvature
00190   // cos (pi/2 - alpha) = (hRhi/2) / theRCurvature
00191   // so:
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   // compute additional delta phi due to origin radius
00200   float deltaPhiOrig = asin( theROrigin * (rHit-rMin) / (rHit*rMin));
00201 
00202   // hit error taken as constant
00203   float deltaPhiHit = theExtraTolerance / rMin;
00204 
00205   if (!thePrecise) {
00206     return deltaPhi+deltaPhiOrig+deltaPhiHit;
00207   } else {
00208     // add multiple scattering correction
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 //     float phiM =  operator()( rHit,zHit,errRPhi);
00223 //     return PixelRecoRange<float>(phiHit-phiM,phiHit+phiM);
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