CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/RecoTracker/SpecialSeedGenerators/src/GenericTripletGenerator.cc

Go to the documentation of this file.
00001 #include "RecoTracker/SpecialSeedGenerators/interface/GenericTripletGenerator.h"
00002 #include "RecoTracker/TkSeedGenerator/interface/FastCircle.h"
00003 #include "RecoTracker/TransientTrackingRecHit/interface/TkTransientTrackingRecHitBuilder.h"
00004 typedef TransientTrackingRecHit::ConstRecHitPointer SeedingHit;
00005 
00006 
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 #include <map>
00009 using namespace ctfseeding;
00010 
00011 
00012 GenericTripletGenerator::GenericTripletGenerator(const edm::ParameterSet& conf): 
00013         //conf_(conf),
00014         theLsb(conf.getParameter<edm::ParameterSet>("LayerPSet")){
00015         edm::LogInfo("CtfSpecialSeedGenerator|GenericTripletGenerator") << "Constructing GenericTripletGenerator";
00016 } 
00017 
00018 
00019 SeedingLayerSets GenericTripletGenerator::init(const edm::EventSetup& es){
00020         //edm::ParameterSet leyerPSet = conf_.getParameter<edm::ParameterSet>("LayerPSet");
00021         //SeedingLayerSetsBuilder lsBuilder(leyerPSet);
00022         SeedingLayerSets lss = theLsb.layers(es);
00023         return lss;     
00024 }
00025 
00026 
00027 const OrderedSeedingHits& GenericTripletGenerator::run(const TrackingRegion& region,
00028                                                              const edm::Event& e,
00029                                                              const edm::EventSetup& es){
00030         hitTriplets.clear();
00031         hitTriplets.reserve(0);
00032         SeedingLayerSets lss = init(es);
00033         SeedingLayerSets::const_iterator iLss;
00034         std::map<float, OrderedHitTriplet> radius_triplet_map;
00035         for (iLss = lss.begin(); iLss != lss.end(); iLss++){
00036                 SeedingLayers ls = *iLss;
00037                 if (ls.size() != 3){
00038                         throw cms::Exception("CtfSpecialSeedGenerator") << "You are using " << ls.size() <<" layers in set instead of 3 ";
00039                 }       
00040                 std::vector<SeedingHit> innerHits  = region.hits(e, es, &ls[0]);
00041                 //std::cout << "innerHits.size()=" << innerHits.size() << std::endl;
00042                 std::vector<SeedingHit> middleHits = region.hits(e, es, &ls[1]);
00043                 //std::cout << "middleHits.size()=" << middleHits.size() << std::endl;
00044                 std::vector<SeedingHit> outerHits  = region.hits(e, es, &ls[2]);
00045                 //std::cout << "outerHits.size()=" << outerHits.size() << std::endl;
00046                 //std::cout << "trying " << innerHits.size()*middleHits.size()*outerHits.size() << " combinations "<<std::endl;
00047                 std::vector<SeedingHit>::const_iterator iOuterHit;
00048                 for (iOuterHit = outerHits.begin(); iOuterHit != outerHits.end(); iOuterHit++){
00049                         std::vector<SeedingHit>::const_iterator iMiddleHit;
00050                         for (iMiddleHit = middleHits.begin(); iMiddleHit != middleHits.end(); iMiddleHit++){
00051                                 std::vector<SeedingHit>::const_iterator iInnerHit;
00052                                 for (iInnerHit = innerHits.begin(); iInnerHit != innerHits.end(); iInnerHit++){
00053                                         //GlobalPoint innerpos  = ls[0].hitBuilder()->build(&(**iInnerHit))->globalPosition();
00054                                         //GlobalPoint middlepos = ls[1].hitBuilder()->build(&(**iMiddleHit))->globalPosition();
00055                                         //GlobalPoint outerpos  = ls[2].hitBuilder()->build(&(**iOuterHit))->globalPosition();
00056                                         //FastCircle circle(innerpos,
00057                                         //                middlepos,
00058                                         //                  outerpos);
00059                                         //do a first check on the radius of curvature to reduce the combinatorics       
00060                                         OrderedHitTriplet oht(*iInnerHit,*iMiddleHit,*iOuterHit);
00061                                         std::pair<bool,float> val_radius = qualityFilter(oht,radius_triplet_map,ls);
00062                                         if (val_radius.first){
00063                                         //if (circle.rho() > 200 || circle.rho() == 0) { //0 radius means straight line
00064                                                 //hitTriplets.push_back(OrderedHitTriplet(*iInnerHit,
00065                                                 //                                      *iMiddleHit,
00066                                                 //                                      *iOuterHit));
00067                                                 hitTriplets.push_back(oht);
00068                                                 radius_triplet_map.insert(std::make_pair(val_radius.second,oht));
00069                                         }
00070                                 }
00071                         }
00072                 }
00073         }
00074         //std::cout << "ending with " << hitTriplets.size() << " triplets" << std::endl;
00075         return hitTriplets;
00076 }
00077 
00078 std::pair<bool,float> GenericTripletGenerator::qualityFilter(const OrderedHitTriplet& oht, 
00079                                                              const std::map<float, OrderedHitTriplet>& map,
00080                                                              const SeedingLayers& ls) const{
00081         //first check the radius
00082         GlobalPoint innerpos  = oht.inner()->globalPosition();
00083         GlobalPoint middlepos = oht.middle()->globalPosition();
00084         GlobalPoint outerpos  = oht.outer()->globalPosition();
00085         std::vector<const TrackingRecHit*> ohttrh;
00086         ohttrh.push_back(&(*(oht.inner()))); ohttrh.push_back(&(*(oht.middle()))); ohttrh.push_back(&(*(oht.outer()))); 
00087         std::vector<const TrackingRecHit*>::const_iterator ioht;
00088         //now chech that the change in phi is reasonable. the limiting angular distance is the one in case 
00089         //one of the two points is a tangent point.
00090         float limit_phi_distance1 = sqrt((middlepos.x()-outerpos.x())*(middlepos.x()-outerpos.x()) + 
00091                                         (middlepos.y()-outerpos.y())*(middlepos.y()-outerpos.y()))/middlepos.mag();//actually this is the tangent of the limiting angle          
00092         float limit_phi_distance2 = sqrt((middlepos.x()-innerpos.x())*(middlepos.x()-innerpos.x()) +
00093                                         (middlepos.y()-innerpos.y())*(middlepos.y()-innerpos.y()))/innerpos.mag();
00094         //if (fabs(tan(outerpos.phi()-middlepos.phi()))>limit_phi_distance1 || 
00095         //    fabs(tan(innerpos.phi()-middlepos.phi()))>limit_phi_distance2) {
00096         if (fabs(outerpos.phi()-middlepos.phi())>fabs(atan(limit_phi_distance1)) ||
00097             fabs(innerpos.phi()-middlepos.phi())>fabs(atan(limit_phi_distance2)) ) {    
00098                 //std::cout << "rejected because phi" << std::endl;
00099                 return std::make_pair(false, 0.);
00100         }
00101         //should we add a control on the r-z plane too?
00102         /*
00103         //now check that there is no big change in the r-z projection
00104         float dz1 = outerpos.z()-middlepos.z();
00105         float dr1 = sqrt(outerpos.x()*outerpos.x()+outerpos.y()*outerpos.y())-
00106                     sqrt(middlepos.x()*middlepos.x()+middlepos.y()*middlepos.y());              
00107         float dz2 = middlepos.z()-innerpos.z(); 
00108         float dr2 = sqrt(middlepos.x()*middlepos.x()+middlepos.y()*middlepos.y())-
00109                     sqrt(innerpos.x()*innerpos.x()+innerpos.y()*innerpos.y());
00110         float tan1 = dz1/dr1;
00111         float tan2 = dz2/dr2;
00112         //how much should we allow? should we make it configurable?
00113         if (fabs(tan1-tan2)/tan1>0.5){
00114                 //std::cout << "rejected because z" << std::endl;
00115                 return std::make_pair(false, 0.);       
00116         }
00117         */
00118         //now check the radius is not too small
00119         FastCircle circle(innerpos, middlepos, outerpos);
00120         if (circle.rho() < 200 && circle.rho() != 0) return std::make_pair(false, circle.rho()); //to small radius      
00121         //now check if at least 2 hits are shared with an existing triplet
00122         //look for similar radii in the map
00123         std::map<float, OrderedHitTriplet>::const_iterator lower_bound = map.lower_bound((1-0.01)*circle.rho());
00124         std::map<float, OrderedHitTriplet>::const_iterator upper_bound = map.upper_bound((1+0.01)*circle.rho());        
00125         std::map<float, OrderedHitTriplet>::const_iterator iter;
00126         for (iter = lower_bound; iter != upper_bound && iter->first <= upper_bound->first; iter++){
00127                 int shared=0;
00128                 std::vector<const TrackingRecHit*> curtrh;
00129                 curtrh.push_back(&*(iter->second.inner()));curtrh.push_back(&*(iter->second.middle()));curtrh.push_back(&*(iter->second.outer()));
00130                 std::vector<const TrackingRecHit*>::const_iterator curiter;
00131                 for (curiter = curtrh.begin(); curiter != curtrh.end(); curiter++){
00132                         for (ioht = ohttrh.begin(); ioht != ohttrh.end(); ioht++){
00133                                 if ((*ioht)->geographicalId()==(*curiter)->geographicalId() && 
00134                                     ((*ioht)->localPosition()-(*curiter)->localPosition()).mag()<1e-5) shared++;        
00135                         }
00136                 }
00137                 if (shared>1) return std::make_pair(false, circle.rho());       
00138         }       
00139 
00140         return std::make_pair(true,circle.rho());
00141 }