00001 #include "RecoTracker/NuclearSeedGenerator/interface/NuclearInteractionFinder.h"
00002 #include "TrackingTools/TrackFitters/interface/TrajectoryStateWithArbitraryError.h"
00003 #include "TrackingTools/PatternTools/interface/TrajMeasLessEstim.h"
00004
00005 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00006
00007 #include "FWCore/Utilities/interface/Exception.h"
00008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00009
00010 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimatorBase.h"
00011 #include "RecoTracker/Record/interface/NavigationSchoolRecord.h"
00012
00013 #include "RecoTracker/Record/interface/CkfComponentsRecord.h"
00014
00015 #include "DataFormats/TrajectorySeed/interface/PropagationDirection.h"
00016
00017 #include "FWCore/Framework/interface/ESHandle.h"
00018
00019
00020 NuclearInteractionFinder::NuclearInteractionFinder(const edm::EventSetup& es, const edm::ParameterSet& iConfig) :
00021 maxHits(iConfig.getParameter<int>("maxHits")),
00022 rescaleErrorFactor(iConfig.getParameter<double>("rescaleErrorFactor")),
00023 checkCompletedTrack(iConfig.getParameter<bool>("checkCompletedTrack")),
00024 navigationSchoolName(iConfig.getParameter<std::string>("NavigationSchool"))
00025 {
00026
00027 std::string measurementTrackerName = iConfig.getParameter<std::string>("MeasurementTrackerName");
00028
00029 edm::ESHandle<Propagator> prop;
00030 edm::ESHandle<TrajectoryStateUpdator> upd;
00031 edm::ESHandle<Chi2MeasurementEstimatorBase> est;
00032 edm::ESHandle<MeasurementTracker> measurementTrackerHandle;
00033 edm::ESHandle<GeometricSearchTracker> theGeomSearchTrackerHandle;
00034 edm::ESHandle<TrackerGeometry> theTrackerGeom;
00035
00036 es.get<TrackerDigiGeometryRecord> ().get (theTrackerGeom);
00037 es.get<TrackingComponentsRecord>().get("PropagatorWithMaterial",prop);
00038 es.get<TrackingComponentsRecord>().get("Chi2",est);
00039 es.get<CkfComponentsRecord>().get(measurementTrackerName, measurementTrackerHandle);
00040 es.get<TrackerRecoGeometryRecord>().get(theGeomSearchTrackerHandle );
00041 es.get<IdealMagneticFieldRecord>().get(theMagField);
00042
00043 edm::ESHandle<NavigationSchool> nav;
00044 es.get<NavigationSchoolRecord>().get(navigationSchoolName, nav);
00045 theNavigationSchool = nav.product();
00046
00047 thePropagator = prop.product();
00048 theEstimator = est.product();
00049 theMeasurementTracker = measurementTrackerHandle.product();
00050 theLayerMeasurements = new LayerMeasurements(theMeasurementTracker);
00051 theGeomSearchTracker = theGeomSearchTrackerHandle.product();
00052
00053 LogDebug("NuclearSeedGenerator") << "New NuclearInteractionFinder instance with parameters : \n"
00054 << "maxHits : " << maxHits << "\n"
00055 << "rescaleErrorFactor : " << rescaleErrorFactor << "\n"
00056 << "checkCompletedTrack : " << checkCompletedTrack << "\n";
00057
00058 nuclTester = new NuclearTester(maxHits, theEstimator, theTrackerGeom.product() );
00059
00060 currentSeed = new SeedFromNuclearInteraction(thePropagator, theTrackerGeom.product(), iConfig) ;
00061
00062 thePrimaryHelix = new TangentHelix();
00063 }
00064
00065 void NuclearInteractionFinder::setEvent(const edm::Event& event) const
00066 {
00067 theMeasurementTracker->update(event);
00068 }
00069
00070
00071 NuclearInteractionFinder::~NuclearInteractionFinder() {
00072 delete theLayerMeasurements;
00073 delete nuclTester;
00074 delete currentSeed;
00075 delete thePrimaryHelix;
00076 }
00077
00078
00079 bool NuclearInteractionFinder::run(const Trajectory& traj) {
00080
00081 if(traj.empty() || !traj.isValid()) return false;
00082
00083 LogDebug("NuclearSeedGenerator") << "Analyzis of a new trajectory with a number of valid hits = " << traj.foundHits();
00084
00085 std::vector<TrajectoryMeasurement> measurements = traj.measurements();
00086
00087
00088 nuclTester->reset( measurements.size() );
00089 allSeeds.clear();
00090
00091
00092 if(traj.direction()==alongMomentum) {
00093 std::reverse(measurements.begin(), measurements.end());
00094 }
00095
00096 std::vector<TrajectoryMeasurement>::const_iterator it_meas = measurements.begin();
00097
00098 std::vector<double> ncompatibleHits;
00099 bool NIfound = false;
00100
00101
00102 while(!NIfound)
00103 {
00104 if(it_meas == measurements.end()) break;
00105
00106
00107 if(nuclTester->nHitsChecked() > maxHits) break;
00108
00109 nuclTester->push_back(*it_meas, findCompatibleMeasurements(*it_meas, rescaleErrorFactor));
00110
00111 LogDebug("NuclearSeedGenerator") << "Number of compatible meas:" << (nuclTester->back()).size() << "\n"
00112 << "Mean distance between hits :" << nuclTester->meanHitDistance() << "\n"
00113 << "Forward estimate :" << nuclTester->fwdEstimate() << "\n";
00114
00115
00116 if( checkCompletedTrack==false && (nuclTester->compatibleHits()).front()==0 ) break;
00117
00118 if(nuclTester->isNuclearInteraction()) NIfound=true;
00119
00120 ++it_meas;
00121 }
00122
00123 if(NIfound) {
00124 LogDebug("NuclearSeedGenerator") << "NUCLEAR INTERACTION FOUND at index : " << nuclTester->nuclearIndex() << "\n";
00125
00126
00127 definePrimaryHelix(measurements.begin()+nuclTester->nuclearIndex()-1);
00128
00129 this->fillSeeds( nuclTester->goodTMPair());
00130
00131 return true;
00132 }
00133
00134 return false;
00135 }
00136
00137 void NuclearInteractionFinder::definePrimaryHelix(std::vector<TrajectoryMeasurement>::const_iterator it_meas) {
00138
00139
00140 GlobalPoint pt[3];
00141 for(int i=0; i<3; i++) {
00142 pt[i] = (it_meas->updatedState()).globalParameters().position();
00143 it_meas++;
00144 }
00145 delete thePrimaryHelix;
00146 thePrimaryHelix = new TangentHelix( pt[0], pt[1], pt[2] );
00147 }
00148
00149 std::vector<TrajectoryMeasurement>
00150 NuclearInteractionFinder::findCompatibleMeasurements(const TM& lastMeas, double rescale) const
00151 {
00152 TSOS currentState = lastMeas.updatedState();
00153 LogDebug("NuclearSeedGenerator") << "currentState :" << currentState << "\n";
00154
00155 TSOS newState = rescaleError(rescale, currentState);
00156 return findMeasurementsFromTSOS(newState, lastMeas.recHit()->geographicalId());
00157 }
00158
00159 std::vector<TrajectoryMeasurement>
00160 NuclearInteractionFinder::findMeasurementsFromTSOS(const TSOS& currentState, DetId detid) const {
00161
00162 using namespace std;
00163 int invalidHits = 0;
00164 vector<TM> result;
00165 const DetLayer* lastLayer = theGeomSearchTracker->detLayer( detid );
00166 vector<const DetLayer*> nl;
00167
00168 if(lastLayer) {
00169 nl = lastLayer->nextLayers( *currentState.freeState(), alongMomentum);
00170 }
00171 else {
00172 edm::LogError("NuclearInteractionFinder") << "In findCompatibleMeasurements : lastLayer not accessible";
00173 return result;
00174 }
00175
00176 if (nl.empty()) {
00177 LogDebug("NuclearSeedGenerator") << "In findCompatibleMeasurements : no compatible layer found";
00178 return result;
00179 }
00180
00181 for (vector<const DetLayer*>::iterator il = nl.begin();
00182 il != nl.end(); il++) {
00183 vector<TM> tmp =
00184 theLayerMeasurements->measurements((**il),currentState, *thePropagator, *theEstimator);
00185 if ( !tmp.empty()) {
00186 if ( result.empty()) result = tmp;
00187 else {
00188
00189 result.insert( result.end()-invalidHits, tmp.begin(), tmp.end());
00190 }
00191 invalidHits++;
00192 }
00193 }
00194
00195
00196 if ( result.size() > 1) {
00197 sort( result.begin(), result.end()-invalidHits, TrajMeasLessEstim());
00198 }
00199 return result;
00200 }
00201
00202
00203 void NuclearInteractionFinder::fillSeeds( const std::pair<TrajectoryMeasurement, std::vector<TrajectoryMeasurement> >& tmPairs ) {
00204
00205
00206 const TM& innerTM = tmPairs.first;
00207 const std::vector<TM>& outerTMs = tmPairs.second;
00208
00209
00210 for(std::vector<TM>::const_iterator outtm = outerTMs.begin(); outtm!=outerTMs.end(); outtm++) {
00211 if((innerTM.recHit())->isValid() && (outtm->recHit())->isValid()) {
00212 currentSeed->setMeasurements(innerTM.updatedState(), innerTM.recHit(), outtm->recHit());
00213 allSeeds.push_back(*currentSeed);
00214 }
00215 else LogDebug("NuclearSeedGenerator") << "The initial hits for seeding are invalid" << "\n";
00216 }
00217 return;
00218 }
00219
00220 std::auto_ptr<TrajectorySeedCollection> NuclearInteractionFinder::getPersistentSeeds() {
00221 std::auto_ptr<TrajectorySeedCollection> output(new TrajectorySeedCollection);
00222 for(std::vector<SeedFromNuclearInteraction>::const_iterator it_seed = allSeeds.begin(); it_seed != allSeeds.end(); it_seed++) {
00223 if(it_seed->isValid()) {
00224 output->push_back( it_seed->TrajSeed() );
00225 }
00226 else LogDebug("NuclearSeedGenerator") << "The seed is invalid" << "\n";
00227 }
00228 return output;
00229 }
00230
00231 void NuclearInteractionFinder::improveSeeds() {
00232 std::vector<SeedFromNuclearInteraction> newSeedCollection;
00233
00234
00235 for(std::vector<SeedFromNuclearInteraction>::const_iterator it_seed = allSeeds.begin(); it_seed != allSeeds.end(); it_seed++) {
00236
00237 if( !it_seed->isValid() ) continue;
00238
00239
00240 std::vector<TM> thirdTMs = findMeasurementsFromTSOS( it_seed->updatedTSOS() , it_seed->outerHitDetId() );
00241
00242
00243 for(std::vector<TM>::const_iterator tm = thirdTMs.begin(); tm!= thirdTMs.end(); tm++) {
00244
00245 if( ! tm->recHit()->isValid() ) continue;
00246
00247
00248 currentSeed->setMeasurements(*thePrimaryHelix, it_seed->initialTSOS(), it_seed->outerHit(), tm->recHit() );
00249 newSeedCollection.push_back( *currentSeed );
00250 }
00251 }
00252 allSeeds.clear();
00253 allSeeds = newSeedCollection;
00254 }
00255
00256 TrajectoryStateOnSurface NuclearInteractionFinder::rescaleError(float rescale, const TSOS& state) const {
00257
00258 AlgebraicSymMatrix55 m(state.localError().matrix());
00259 AlgebraicSymMatrix55 mr;
00260 LocalTrajectoryParameters ltp = state.localParameters();
00261
00262
00263 mr(0,0) = (ltp.signedInverseMomentum()*0.2*rescale)*(ltp.signedInverseMomentum()*0.2*rescale);
00264
00265
00266 mr(1,1) = 1E-2*rescale*rescale;
00267 mr(2,2) = 1E-2*rescale*rescale;
00268
00269
00270 mr(3,3) = m(3,3);
00271 mr(4,4) = m(4,4);
00272
00273 return TSOS(ltp, mr, state.surface(), &(state.globalParameters().magneticField()), state.surfaceSide());
00274 }