CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2/src/RecoPixelVertexing/PixelTriplets/plugins/PixelTripletHLTGenerator.cc

Go to the documentation of this file.
00001 #include "RecoPixelVertexing/PixelTriplets/plugins/PixelTripletHLTGenerator.h"
00002 
00003 #include "RecoPixelVertexing/PixelTriplets/interface/ThirdHitPredictionFromInvParabola.h"
00004 #include "RecoPixelVertexing/PixelTriplets/interface/ThirdHitRZPrediction.h"
00005 #include "RecoTracker/TkMSParametrization/interface/PixelRecoUtilities.h"
00006 #include "FWCore/Framework/interface/ESHandle.h"
00007 
00008 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00009 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00010 #include "ThirdHitCorrection.h"
00011 #include "RecoTracker/TkHitPairs/interface/RecHitsSortedInPhi.h"
00012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00013 #include <iostream>
00014 
00015 #include "RecoTracker/TkSeedingLayers/interface/SeedComparitorFactory.h"
00016 #include "RecoTracker/TkSeedingLayers/interface/SeedComparitor.h"
00017 
00018 #include "DataFormats/GeometryVector/interface/Pi.h"
00019 //#include "RecoParticleFlow/PFProducer/interface/KDTreeLinkerAlgo.h"
00020 //#include "RecoParticleFlow/PFProducer/interface/KDTreeLinkerTools.h"
00021 #include "RecoPixelVertexing/PixelTriplets/plugins/KDTreeLinkerAlgo.h" //amend to point at your copy...
00022 #include "RecoPixelVertexing/PixelTriplets/plugins/KDTreeLinkerTools.h"
00023 
00024 using pixelrecoutilities::LongitudinalBendingCorrection;
00025 typedef PixelRecoRange<float> Range;
00026 
00027 using namespace std;
00028 using namespace ctfseeding;
00029 
00030 PixelTripletHLTGenerator:: PixelTripletHLTGenerator(const edm::ParameterSet& cfg)
00031   : thePairGenerator(0),
00032     theLayerCache(0),
00033     useFixedPreFiltering(cfg.getParameter<bool>("useFixedPreFiltering")),
00034     extraHitRZtolerance(cfg.getParameter<double>("extraHitRZtolerance")),
00035     extraHitRPhitolerance(cfg.getParameter<double>("extraHitRPhitolerance")),
00036     useMScat(cfg.getParameter<bool>("useMultScattering")),
00037     useBend(cfg.getParameter<bool>("useBending"))
00038 {
00039   theMaxElement=cfg.getParameter<unsigned int>("maxElement");
00040   dphi =  (useFixedPreFiltering) ?  cfg.getParameter<double>("phiPreFiltering") : 0;
00041   
00042   edm::ParameterSet comparitorPSet =
00043     cfg.getParameter<edm::ParameterSet>("SeedComparitorPSet");
00044   std::string comparitorName = comparitorPSet.getParameter<std::string>("ComponentName");
00045   theComparitor = (comparitorName == "none") ?
00046     0 :  SeedComparitorFactory::get()->create( comparitorName, comparitorPSet);
00047 }
00048 
00049 PixelTripletHLTGenerator::~PixelTripletHLTGenerator()
00050   
00051 { delete thePairGenerator;
00052   delete theComparitor;
00053 }
00054 
00055 void PixelTripletHLTGenerator::init( const HitPairGenerator & pairs,
00056                                      const std::vector<SeedingLayer> & layers,
00057                                      LayerCacheType* layerCache)
00058 {
00059   thePairGenerator = pairs.clone();
00060   theLayers = layers;
00061   theLayerCache = layerCache;
00062 }
00063 
00064 void PixelTripletHLTGenerator::hitTriplets(const TrackingRegion& region, 
00065                                            OrderedHitTriplets & result,
00066                                            const edm::Event & ev,
00067                                            const edm::EventSetup& es)
00068 {
00069   if (theComparitor) theComparitor->init(es);
00070   OrderedHitPairs pairs; pairs.reserve(30000);
00071   OrderedHitPairs::const_iterator ip;
00072   
00073   thePairGenerator->hitPairs(region,pairs,ev,es);
00074   
00075   if (pairs.empty()) return;
00076   
00077   float regOffset = region.origin().perp(); //try to take account of non-centrality (?)
00078   int size = theLayers.size();
00079   
00080   typedef std::vector<ThirdHitRZPrediction<PixelRecoLineRZ> >  Preds;
00081   Preds preds(size);
00082   
00083   std::vector<const RecHitsSortedInPhi *> thirdHitMap(size);
00084   typedef RecHitsSortedInPhi::Hit Hit;
00085  
00086   std::vector<KDTreeNodeInfo<RecHitsSortedInPhi::HitIter> > layerTree; // re-used throughout
00087   std::vector<KDTreeLinkerAlgo<RecHitsSortedInPhi::HitIter> > hitTree(size);
00088   std::vector<float> rzError(size,0.0f); //save maximum errors
00089   double maxphi = Geom::twoPi(), minphi = -maxphi; // increase to cater for any range
00090   
00091   // fill the prediction vector
00092   for (int il=0; il!=size; ++il) {
00093     thirdHitMap[il] = &(*theLayerCache)(&theLayers[il], region, ev, es);
00094     ThirdHitRZPrediction<PixelRecoLineRZ> & pred = preds[il];
00095     pred.initLayer(theLayers[il].detLayer());
00096     pred.initTolerance(extraHitRZtolerance);
00097     
00098     RecHitsSortedInPhi::Range hitRange = thirdHitMap[il]->all(); // Get iterators
00099     layerTree.clear();
00100     double minz=999999.0, maxz= -999999.0; // Initialise to extreme values in case no hits
00101     float maxErr=0.0f;
00102     bool barrelLayer = (theLayers[il].detLayer()->location() == GeomDetEnumerators::barrel);
00103     if (hitRange.first != hitRange.second)
00104       { minz = barrelLayer? hitRange.first->hit()->globalPosition().z() : hitRange.first->hit()->globalPosition().perp();
00105         maxz = minz; //In case there's only one hit on the layer
00106         for (RecHitsSortedInPhi::HitIter hi=hitRange.first; hi != hitRange.second; ++hi)
00107           { double angle = hi->phi();
00108             double myz = barrelLayer? hi->hit()->globalPosition().z() : hi->hit()->globalPosition().perp();
00109             //use (phi,r) for endcaps rather than (phi,z)
00110             if (myz < minz) { minz = myz;} else { if (myz > maxz) {maxz = myz;}}
00111             float myerr = barrelLayer? hi->hit()->errorGlobalZ(): hi->hit()->errorGlobalR();
00112             if (myerr > maxErr) { maxErr = myerr;}
00113             layerTree.push_back(KDTreeNodeInfo<RecHitsSortedInPhi::HitIter>(hi, angle, myz)); // save it
00114             if (angle < 0)  // wrap all points in phi
00115               { layerTree.push_back(KDTreeNodeInfo<RecHitsSortedInPhi::HitIter>(hi, angle+Geom::twoPi(), myz));}
00116             else
00117               { layerTree.push_back(KDTreeNodeInfo<RecHitsSortedInPhi::HitIter>(hi, angle-Geom::twoPi(), myz));}
00118           }
00119       }
00120     KDTreeBox phiZ(minphi, maxphi, minz-0.01, maxz+0.01);  // declare our bounds
00121     //add fudge factors in case only one hit and also for floating-point inaccuracy
00122     hitTree[il].build(layerTree, phiZ); // make KDtree
00123     rzError[il] = maxErr; //save error
00124   }
00125   
00126   double imppar = region.originRBound();
00127   double curv = PixelRecoUtilities::curvature(1/region.ptMin(), es);
00128   
00129   for (ip = pairs.begin(); ip != pairs.end(); ip++) {
00130     
00131    GlobalPoint gp1tmp = (*ip).inner()->globalPosition();
00132    GlobalPoint gp2tmp = (*ip).outer()->globalPosition();
00133    GlobalPoint gp1(gp1tmp.x()-region.origin().x(), gp1tmp.y()-region.origin().y(), gp1tmp.z());
00134    GlobalPoint gp2(gp2tmp.x()-region.origin().x(), gp2tmp.y()-region.origin().y(), gp2tmp.z());
00135    
00136    PixelRecoPointRZ point1(gp1.perp(), gp1.z());
00137    PixelRecoPointRZ point2(gp2.perp(), gp2.z());
00138    PixelRecoLineRZ  line(point1, point2);
00139    ThirdHitPredictionFromInvParabola predictionRPhi(gp1,gp2,imppar,curv,extraHitRPhitolerance);
00140    ThirdHitPredictionFromInvParabola predictionRPhitmp(gp1tmp,gp2tmp,imppar+region.origin().perp(),curv,extraHitRPhitolerance);
00141    
00142    for (int il=0; il!=size; ++il) {
00143      if (hitTree[il].empty()) continue; // Don't bother if no hits
00144      const DetLayer * layer = theLayers[il].detLayer();
00145      bool barrelLayer = (layer->location() == GeomDetEnumerators::barrel);
00146      
00147      ThirdHitCorrection correction(es, region.ptMin(), layer, line, point2, useMScat, useBend); 
00148      
00149      ThirdHitRZPrediction<PixelRecoLineRZ> & predictionRZ =  preds[il];
00150      
00151      predictionRZ.initPropagator(&line);
00152      Range rzRange = predictionRZ();
00153      correction.correctRZRange(rzRange);
00154      
00155      Range phiRange;
00156      if (useFixedPreFiltering) { 
00157        float phi0 = (*ip).outer()->globalPosition().phi();
00158        phiRange = Range(phi0-dphi,phi0+dphi);
00159      }
00160      else {
00161        Range radius;
00162        if (barrelLayer) {
00163          radius =  predictionRZ.detRange();
00164        } else {
00165          radius = Range(max(rzRange.min(), predictionRZ.detSize().min()),
00166                         min(rzRange.max(), predictionRZ.detSize().max()) );
00167        }
00168        if (radius.empty()) continue;
00169        Range rPhi1m = predictionRPhitmp(radius.max(), -1);
00170        Range rPhi1p = predictionRPhitmp(radius.max(),  1);
00171        Range rPhi2m = predictionRPhitmp(radius.min(), -1);
00172        Range rPhi2p = predictionRPhitmp(radius.min(),  1);
00173        Range rPhi1 = rPhi1m.sum(rPhi1p);
00174        Range rPhi2 = rPhi2m.sum(rPhi2p);
00175        correction.correctRPhiRange(rPhi1);
00176        correction.correctRPhiRange(rPhi2);
00177        rPhi1.first  /= radius.max();
00178        rPhi1.second /= radius.max();
00179        rPhi2.first  /= radius.min();
00180        rPhi2.second /= radius.min();
00181        phiRange = mergePhiRanges(rPhi1,rPhi2);
00182      }
00183      
00184      static float nSigmaRZ = std::sqrt(12.f); // ...and continue as before
00185      static float nSigmaPhi = 3.f;
00186 
00187      layerTree.clear(); // Now recover hits in bounding box...
00188      float prmin=phiRange.min(), prmax=phiRange.max();
00189      if ((prmax-prmin) > Geom::twoPi())
00190        { prmax=Geom::pi(); prmin = -Geom::pi();}
00191      else
00192        { while (prmax>maxphi) { prmin -= Geom::twoPi(); prmax -= Geom::twoPi();}
00193          while (prmin<minphi) { prmin += Geom::twoPi(); prmax += Geom::twoPi();}
00194          // This needs range -twoPi to +twoPi to work
00195        }
00196      if (barrelLayer)
00197        {
00198          Range regMax = predictionRZ.detRange();
00199          Range regMin = predictionRZ(regMax.min()-regOffset);
00200          regMax = predictionRZ(regMax.max()+regOffset);
00201          correction.correctRZRange(regMin);
00202          correction.correctRZRange(regMax);
00203          if (regMax.min() < regMin.min()) { swap(regMax, regMin);}
00204          KDTreeBox phiZ(prmin, prmax, regMin.min()-nSigmaRZ*rzError[il], regMax.max()+nSigmaRZ*rzError[il]);
00205          hitTree[il].search(phiZ, layerTree);
00206        }
00207      else
00208        {
00209          KDTreeBox phiZ(prmin, prmax,
00210                         rzRange.min()-regOffset-nSigmaRZ*rzError[il],
00211                         rzRange.max()+regOffset+nSigmaRZ*rzError[il]);
00212          hitTree[il].search(phiZ, layerTree);
00213        }
00214      for (std::vector<KDTreeNodeInfo<RecHitsSortedInPhi::HitIter> >::iterator ih = layerTree.begin();
00215           ih !=layerTree.end(); ++ih) {
00216        
00217        if (theMaxElement!=0 && result.size() >= theMaxElement){
00218          result.clear();
00219          edm::LogError("TooManyTriplets")<<" number of triples exceeds maximum. no triplets produced.";
00220          return;
00221        }
00222        
00223        const RecHitsSortedInPhi::HitIter KDdata = (*ih).data;
00224        GlobalPoint point(KDdata->hit()->globalPosition().x()-region.origin().x(),
00225                          KDdata->hit()->globalPosition().y()-region.origin().y(),
00226                          KDdata->hit()->globalPosition().z() ); 
00227        float p3_r = point.perp();
00228        float p3_z = point.z();
00229        float p3_phi = point.phi();
00230        if (barrelLayer) {
00231          Range allowedZ = predictionRZ(p3_r);
00232          correction.correctRZRange(allowedZ);
00233          float zErr = nSigmaRZ * KDdata->hit()->errorGlobalZ();
00234          Range hitRange(p3_z-zErr, p3_z+zErr);
00235          Range crossingRange = allowedZ.intersection(hitRange);
00236          if (crossingRange.empty())  continue;
00237        } else {
00238          Range allowedR = predictionRZ(p3_z);
00239          correction.correctRZRange(allowedR); 
00240          float rErr = nSigmaRZ * KDdata->hit()->errorGlobalR();
00241          Range hitRange(p3_r-rErr, p3_r+rErr);
00242          Range crossingRange = allowedR.intersection(hitRange);
00243          if ( crossingRange.empty())  continue;
00244        }
00245        
00246        float phiErr = nSigmaPhi * KDdata->hit()->errorGlobalRPhi()/p3_r;
00247        for (int icharge=-1; icharge <=1; icharge+=2) {
00248          Range rangeRPhi = predictionRPhi(p3_r, icharge);
00249          correction.correctRPhiRange(rangeRPhi);
00250          if (checkPhiInRange(p3_phi, rangeRPhi.first/p3_r-phiErr, rangeRPhi.second/p3_r+phiErr)) {
00251            // insert here check with comparitor
00252            OrderedHitTriplet hittriplet( (*ip).inner(), (*ip).outer(), KDdata->hit());
00253            if (!theComparitor  || theComparitor->compatible(hittriplet,region) ) {
00254              result.push_back( hittriplet );
00255            } else {
00256              LogDebug("RejectedTriplet") << "rejected triplet from comparitor "
00257                                          << hittriplet.outer()->globalPosition().x() << " "
00258                                          << hittriplet.outer()->globalPosition().y() << " "
00259                                          << hittriplet.outer()->globalPosition().z();
00260            }
00261            break;
00262          } 
00263        }
00264      }
00265    }
00266   }
00267 }
00268 
00269 bool PixelTripletHLTGenerator::checkPhiInRange(float phi, float phi1, float phi2) const
00270 {
00271   while (phi > phi2) phi -=  Geom::ftwoPi();
00272   while (phi < phi1) phi +=  Geom::ftwoPi();
00273   return (  (phi1 <= phi) && (phi <= phi2) );
00274 }  
00275 
00276 std::pair<float,float> PixelTripletHLTGenerator::mergePhiRanges(const std::pair<float,float>& r1,
00277                                                                 const std::pair<float,float>& r2) const 
00278 { float r2_min=r2.first;
00279   float r2_max=r2.second;
00280   while (r1.first-r2_min > Geom::fpi()) { r2_min += Geom::ftwoPi(); r2_max += Geom::ftwoPi();}
00281   while (r1.first-r2_min < -Geom::fpi()) { r2_min -= Geom::ftwoPi();  r2_max -= Geom::ftwoPi(); }
00282   
00283   return std::make_pair(min(r1.first,r2_min),max(r1.second,r2_max));
00284 }