CMS 3D CMS Logo

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