CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/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 namespace {
00016   template <class T> inline T sqr( T t) {return t*t;}
00017   template <class T> 
00018   inline T cropped_asin(T x) {
00019     return std::abs(x) <= 1 ? std::asin(x) : (x > 0 ? T(M_PI/2) : -T(M_PI/2));
00020   }
00021 }
00022 
00023 namespace {
00024   inline double checked_asin(double x, const char *expr, const char *file, int line) {
00025     if (fabs(x) >= 1.0) throw cms::Exception("CorruptData") <<  "asin(x) called with x = " << expr << " = " << x << "\n\tat " << file << ":" << line << "\n";
00026     return asin(x);
00027   }
00028 }
00029 
00030 //#define asin(X) checked_asin(X, #X, __FILE__, __LINE__)
00031 
00032 InnerDeltaPhi:: InnerDeltaPhi( const DetLayer& outlayer, const DetLayer& layer,
00033                  const TrackingRegion & region,
00034                  const edm::EventSetup& iSetup,
00035                  bool precise, float extraTolerance)
00036   : thePrecise(precise),
00037     ol( outlayer.seqNum()), 
00038     theROrigin(region.originRBound()),
00039     theRLayer(0),
00040     theThickness(0),
00041     theExtraTolerance(extraTolerance),
00042     theA(0),
00043     theB(0),
00044     theVtxZ(region.origin().z()),
00045     thePtMin(region.ptMin()),
00046     theVtx(region.origin().x(),region.origin().y()),
00047     sigma(&layer,iSetup)
00048 {
00049   float zMinOrigin = theVtxZ-region.originZBound();
00050   float zMaxOrigin = theVtxZ+region.originZBound();
00051   theRCurvature = PixelRecoUtilities::bendingRadius(thePtMin,iSetup);
00052  
00053 
00054   if (layer.isBarrel()) initBarrelLayer( layer);
00055   else initForwardLayer( layer, zMinOrigin, zMaxOrigin);
00056 
00057 }
00058 
00059 
00060 
00061 void InnerDeltaPhi::initBarrelLayer( const DetLayer& layer) 
00062 {
00063   const BarrelDetLayer& bl = static_cast<const BarrelDetLayer&>(layer); 
00064   float rLayer = bl.specificSurface().radius(); 
00065 
00066   // the maximal delta phi will be for the innermost hits
00067   theThickness = layer.surface().bounds().thickness();
00068   theRLayer = rLayer - 0.5f*theThickness;
00069   theRDefined = true;
00070 }
00071 
00072 void InnerDeltaPhi::initForwardLayer( const DetLayer& layer, 
00073                                  float zMinOrigin, float zMaxOrigin)
00074 {
00075   const ForwardDetLayer &fl = static_cast<const ForwardDetLayer&>(layer);
00076   theRLayer = fl.specificSurface().innerRadius();
00077   float layerZ = layer.position().z();
00078   theThickness = layer.surface().bounds().thickness();
00079   float layerZmin = layerZ > 0 ? layerZ-0.5f*theThickness: layerZ+0.5f*theThickness;
00080   theB = layerZ > 0 ? zMaxOrigin : zMinOrigin;
00081   theA = layerZmin - theB;
00082   theRDefined = false;
00083 }
00084 
00085 
00086 
00087 PixelRecoRange<float> InnerDeltaPhi::phiRange(const Point2D& hitXY,float hitZ,float errRPhi) const
00088 {
00089   float rLayer = theRLayer;
00090   bool checkCrossing = true;
00091   Point2D crossing;
00092 
00093   Point2D dHit = hitXY-theVtx;
00094   auto  dHitmag = dHit.mag();
00095   float  dLayer = 0.;
00096   float dL = 0.;
00097   //
00098   // compute crossing of stright track with inner layer
00099   //
00100   if (!theRDefined) {
00101     auto t = theA/(hitZ-theB); auto dt = std::abs(theThickness/(hitZ-theB));
00102     crossing = theVtx + t*dHit;
00103     rLayer =  crossing.mag();
00104     dLayer = t*dHitmag;           dL = dt * dHitmag; 
00105     checkCrossing = false;
00106     if (rLayer < theRLayer) {
00107       checkCrossing = true;
00108       rLayer = theRLayer;
00109       dL = 0.;
00110     } 
00111   }
00112 
00113   //
00114   // compute crossing of track with layer
00115   // dHit - from VTX to outer hit
00116   // rLayer - layer radius
00117   // dLayer - distance from VTX to inner layer in direction of dHit
00118   // vect(rLayer) = vect(rVTX) + vect(dHit).unit * dLayer
00119   //     rLayer^2 = (vect(rVTX) + vect(dHit).unit * dLayer)^2 and we have square eqation for dLayer 
00120   //
00121   // barrel case
00122   //
00123 
00124   if (checkCrossing) {
00125     auto vtxmag2 = theVtx.mag2();
00126     if (vtxmag2 < 1.e-10f) {
00127       dLayer = rLayer;
00128     }
00129     else { 
00130       // there are cancellation here....
00131       double var_c = vtxmag2-sqr(rLayer);
00132       double var_b = theVtx.dot(dHit.unit());
00133       double var_delta = sqr(var_b)-var_c;
00134       if (var_delta <=0.) var_delta = 0;
00135       dLayer = -var_b + std::sqrt(var_delta); //only the value along vector is OK. 
00136     }
00137     crossing = theVtx+ dHit.unit() * dLayer;
00138     float cosCross = std::abs( dHit.unit().dot(crossing.unit()));
00139     dL = theThickness/cosCross; 
00140   }
00141 
00142 
00143   // track is crossing layer with angle such as:
00144   // this factor should be taken in computation of eror projection
00145   auto cosCross = std::abs( dHit.unit().dot(crossing.unit()));
00146 
00147   auto alphaHit = cropped_asin( dHitmag/(2*theRCurvature)); 
00148   auto deltaPhi = std::abs( alphaHit - cropped_asin( dLayer/(2*theRCurvature)));
00149   deltaPhi *= dLayer/(rLayer*cosCross);  
00150 
00151   // additinal angle due to not perpendicular stright line crossing  (for displaced beam)
00152   //  double dPhiCrossing = (cosCross > 0.9999) ? 0 : dL *  sqrt(1-sqr(cosCross))/ rLayer;
00153   Point2D crossing2 = theVtx + dHit.unit()* (dLayer+dL);
00154   auto phicross2 = crossing2.barePhi();  
00155   auto phicross1 = crossing.barePhi();
00156   auto dphicross = phicross2-phicross1;
00157   if (dphicross < -float(M_PI)) dphicross += float(2*M_PI);
00158   if (dphicross >  float(M_PI)) dphicross -= float(2*M_PI);
00159   if (dphicross > float(M_PI/2)) dphicross = 0.;  // something wrong?
00160   phicross2 = phicross1 + dphicross;
00161         
00162 
00163   // compute additional delta phi due to origin radius
00164   auto deltaPhiOrig = cropped_asin( theROrigin * (dHitmag-dLayer) / (dHitmag*dLayer));
00165   deltaPhiOrig *= dLayer/(rLayer*cosCross);
00166 
00167   // inner hit error taken as constant
00168   auto deltaPhiHit = theExtraTolerance / rLayer;
00169 
00170   // outer hit error
00171 //   double deltaPhiHitOuter = errRPhi/rLayer; 
00172   auto deltaPhiHitOuter = errRPhi/hitXY.mag();
00173 
00174   auto margin = deltaPhi+deltaPhiOrig+deltaPhiHit+deltaPhiHitOuter ;
00175 
00176   if (thePrecise) {
00177     // add multiple scattering correction
00178     PixelRecoPointRZ zero(0., theVtxZ);
00179     PixelRecoPointRZ point(hitXY.mag(), hitZ);
00180     auto scatt = 3.f*sigma(thePtMin,zero, point, ol) / rLayer; 
00181    
00182     margin += scatt ;
00183   }
00184   
00185   return PixelRecoRange<float>( std::min(phicross1,phicross2)-margin, 
00186                                 std::max(phicross1,phicross2)+margin);
00187 }
00188 
00189 
00190 
00191 
00192 float InnerDeltaPhi::minRadius( float hitR, float hitZ) const 
00193 {
00194   if (theRDefined) return theRLayer;
00195   else {
00196     float rmin = (theA*hitR)/(hitZ-theB);
00197     return ( rmin> 0) ? std::max( rmin, theRLayer) : theRLayer;
00198   }
00199 }
00200 
00201