00001 #include "RecoTracker/NuclearSeedGenerator/interface/NuclearTester.h" 00002 #include "RecoTracker/CkfPattern/src/RecHitIsInvalid.h" 00003 #include "FWCore/MessageLogger/interface/MessageLogger.h" 00004 00005 //---------------------------------------------------------------------- 00006 NuclearTester::NuclearTester(unsigned int max_hits, const MeasurementEstimator* est, const TrackerGeometry* track_geom) : 00007 maxHits(max_hits), theEstimator(est), trackerGeom(track_geom) { NuclearIndex=0; } 00008 00009 //---------------------------------------------------------------------- 00010 bool NuclearTester::isNuclearInteraction( ) { 00011 // TODO : if energy of primary track is below a threshold don't use checkWithMultiplicity but only checkwith compatible_hits.front 00012 00013 // 1. if momentum of the primary track is below 5 GeV and if the number of compatible hits >0 00014 // assume that a nuclear interaction occured at the end of the track 00015 if( allTM.front().first.updatedState().globalMomentum().mag() < 5.0 && compatible_hits.front()>0) { NuclearIndex=1; return true; } 00016 00017 // 2. else to use multiplicity we require at least 3 TM vectors to check if nuclear interactions occurs 00018 if(nHitsChecked()<3) return false; 00019 00020 // 2. check with multiplicity : 00021 if( checkWithMultiplicity() == true ) return true; 00022 else { 00023 // 3. last case : uncompleted track with at least 1 compatible hits in the last layer 00024 if( nHitsChecked() >= maxHits && compatible_hits.front()>0) {NuclearIndex=1; return true; } 00025 } 00026 00027 return false; 00028 } 00029 //---------------------------------------------------------------------- 00030 bool NuclearTester::checkWithMultiplicity() { 00031 //RQ: assume that the input vector of compatible hits has been filled from Outside to Inside the tracker ! 00032 00033 // find the first min nb of compatible TM : 00034 std::vector<int>::iterator min_it = min_element(compatible_hits.begin(), compatible_hits.end()); 00035 00036 // if the outermost hit has no compatible TM, min_it has to be recalculated : 00037 if(min_it == compatible_hits.begin() && *min_it!=0) return false; 00038 if(min_it == compatible_hits.begin() && *min_it==0) min_it=min_element(compatible_hits.begin()+1, compatible_hits.end()); 00039 00040 // this first min cannot be the innermost TM : 00041 if(min_it == compatible_hits.end()-1) return false; 00042 00043 // if the previous nb of compatible TM is > min+2 and if the next compatible TM is min+-1 -> NUCLEAR 00044 // example : Nhits = 5, 8, 2, 2, ... 00045 if((*(min_it-1) - *min_it) > 2 && (*(min_it+1) - *min_it) < 2 ) { 00046 NuclearIndex = min_it - compatible_hits.begin(); 00047 return true; 00048 } 00049 00050 // case of : Nhits = 5, 8, 3, 2, 2, ... 00051 if(min_it-1 != compatible_hits.begin()) //because min_it must be at least at the third position 00052 { 00053 if(min_it-1 != compatible_hits.begin() && (*(min_it-1) - *min_it) < 2 && (*(min_it-2) - *(min_it-1)) > 2 ) { 00054 NuclearIndex = min_it - 1 - compatible_hits.begin(); 00055 return true; 00056 } 00057 } 00058 00059 return false; 00060 } 00061 00062 //---------------------------------------------------------------------- 00063 double NuclearTester::meanHitDistance(const std::vector<TrajectoryMeasurement>& vecTM) const { 00064 std::vector<GlobalPoint> vgp = this->HitPositions(vecTM); 00065 double mean_dist=0; 00066 int ncomb=0; 00067 if(vgp.size()<2) return 0; 00068 for(std::vector<GlobalPoint>::iterator itp = vgp.begin(); itp != vgp.end()-1; itp++) { 00069 for(std::vector<GlobalPoint>::iterator itq = itp+1; itq != vgp.end(); itq++) { 00070 double dist = ((*itp) - (*itq)).mag(); 00071 // to calculate mean distance between particles and not hits (to not take into account twice stereo hits) 00072 if(dist > 1E-12) { 00073 mean_dist += dist; 00074 ncomb++; 00075 } 00076 } 00077 } 00078 return mean_dist/ncomb; 00079 } 00080 //---------------------------------------------------------------------- 00081 std::vector<GlobalPoint> NuclearTester::HitPositions(const std::vector<TrajectoryMeasurement>& vecTM) const { 00082 std::vector<GlobalPoint> gp; 00083 00084 std::vector<TM>::const_iterator last = this->lastValidTM(vecTM); 00085 00086 for(std::vector<TrajectoryMeasurement>::const_iterator itm = vecTM.begin(); itm!=last; itm++) { 00087 ConstRecHitPointer trh = itm->recHit(); 00088 if(trh->isValid()) gp.push_back(trackerGeom->idToDet(trh->geographicalId())->surface().toGlobal(trh->localPosition())); 00089 } 00090 return gp; 00091 } 00092 //---------------------------------------------------------------------- 00093 double NuclearTester::fwdEstimate(const std::vector<TrajectoryMeasurement>& vecTM) const { 00094 if(vecTM.empty()) return 0; 00095 00096 const TransientTrackingRecHit* hit = vecTM.front().recHit().get(); 00097 if( hit->isValid() ) 00098 return theEstimator->estimate( vecTM.front().forwardPredictedState(), *hit ).second; 00099 else return -1; 00100 /* 00101 double meanEst=0; 00102 int goodTM=0; 00103 std::vector<TM>::const_iterator last; 00104 //std::vector<TM>::const_iterator last = this->lastValidTM(vecTM); 00105 if(vecTM.size() > 2) last = vecTM.begin()+2; 00106 else last = vecTM.end(); 00107 00108 for(std::vector<TrajectoryMeasurement>::const_iterator itm = vecTM.begin(); itm!=last; itm++) { 00109 meanEst += itm->estimate(); 00110 goodTM++; 00111 } 00112 return meanEst/goodTM; 00113 */ 00114 } 00115 //---------------------------------------------------------------------- 00116 std::vector<TrajectoryMeasurement>::const_iterator NuclearTester::lastValidTM(const std::vector<TM>& vecTM) const { 00117 if (vecTM.empty()) return vecTM.end(); 00118 if (vecTM.front().recHit()->isValid()) 00119 return std::find_if( vecTM.begin(), vecTM.end(), RecHitIsInvalid()); 00120 else return vecTM.end(); 00121 } 00122 //----------------------------------------------------------------------