00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00021 #include "TrackingTools/TrackAssociator/interface/TrackDetectorAssociator.h"
00022 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00023
00024
00025 #include "FWCore/Framework/interface/Frameworkfwd.h"
00026
00027 #include "FWCore/Framework/interface/Event.h"
00028 #include "FWCore/Framework/interface/EventSetup.h"
00029 #include "FWCore/Framework/interface/MakerMacros.h"
00030 #include "DataFormats/Common/interface/Handle.h"
00031 #include "FWCore/Framework/interface/ESHandle.h"
00032 #include "DataFormats/Common/interface/OrphanHandle.h"
00033
00034 #include "DataFormats/TrackReco/interface/Track.h"
00035 #include "DataFormats/TrackReco/interface/TrackExtra.h"
00036 #include "DataFormats/CaloTowers/interface/CaloTower.h"
00037 #include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
00038 #include "DataFormats/HcalRecHit/interface/HcalRecHitCollections.h"
00039 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
00040 #include "DataFormats/DTRecHit/interface/DTRecHitCollection.h"
00041 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00042 #include "DataFormats/DetId/interface/DetId.h"
00043
00044
00045 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00046 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00047 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00048 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00049 #include "DataFormats/HcalDetId/interface/HcalSubdetector.h"
00050 #include "DataFormats/EcalRecHit/interface/EcalRecHitCollections.h"
00051
00052 #include "Geometry/DTGeometry/interface/DTLayer.h"
00053 #include "Geometry/DTGeometry/interface/DTGeometry.h"
00054 #include "Geometry/Records/interface/MuonGeometryRecord.h"
00055
00056 #include "Geometry/CSCGeometry/interface/CSCGeometry.h"
00057 #include "Geometry/CSCGeometry/interface/CSCChamberSpecs.h"
00058
00059 #include "DataFormats/GeometrySurface/interface/Cylinder.h"
00060 #include "DataFormats/GeometrySurface/interface/Plane.h"
00061
00062 #include "Geometry/CommonDetUnit/interface/GeomDetUnit.h"
00063
00064
00065 #include "MagneticField/Engine/interface/MagneticField.h"
00066 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00067
00068 #include "TrackPropagation/SteppingHelixPropagator/interface/SteppingHelixPropagator.h"
00069 #include "Utilities/Timing/interface/TimingReport.h"
00070 #include <stack>
00071 #include <set>
00072
00073 #include "DataFormats/Math/interface/LorentzVector.h"
00074 #include "Math/VectorUtil.h"
00075 #include <algorithm>
00076
00077 #include "TrackingTools/TrackAssociator/interface/CaloDetIdAssociator.h"
00078 #include "TrackingTools/TrackAssociator/interface/EcalDetIdAssociator.h"
00079 #include "TrackingTools/TrackAssociator/interface/PreshowerDetIdAssociator.h"
00080
00081
00082 #include "DataFormats/DTRecHit/interface/DTRecSegment4DCollection.h"
00083 #include "DataFormats/DTRecHit/interface/DTRecSegment2D.h"
00084 #include "DataFormats/CSCRecHit/interface/CSCSegmentCollection.h"
00085 #include "DataFormats/GeometryCommonDetAlgo/interface/ErrorFrameTransformer.h"
00086
00087 #include "SimDataFormats/TrackingHit/interface/PSimHit.h"
00088 #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h"
00089 #include "SimDataFormats/Track/interface/SimTrack.h"
00090 #include "SimDataFormats/Track/interface/SimTrackContainer.h"
00091 #include "SimDataFormats/Vertex/interface/SimVertex.h"
00092 #include "SimDataFormats/Vertex/interface/SimVertexContainer.h"
00093 #include "SimDataFormats/CaloHit/interface/PCaloHit.h"
00094 #include "SimDataFormats/CaloHit/interface/PCaloHitContainer.h"
00095
00096 #include "TrackingTools/Records/interface/DetIdAssociatorRecord.h"
00097
00098 using namespace reco;
00099
00100 TrackDetectorAssociator::TrackDetectorAssociator()
00101 {
00102 ivProp_ = 0;
00103 defProp_ = 0;
00104 useDefaultPropagator_ = false;
00105 }
00106
00107 TrackDetectorAssociator::~TrackDetectorAssociator()
00108 {
00109 if (defProp_) delete defProp_;
00110 }
00111
00112 void TrackDetectorAssociator::setPropagator( const Propagator* ptr)
00113 {
00114 ivProp_ = ptr;
00115 cachedTrajectory_.setPropagator(ivProp_);
00116 }
00117
00118 void TrackDetectorAssociator::useDefaultPropagator()
00119 {
00120 useDefaultPropagator_ = true;
00121 }
00122
00123
00124 void TrackDetectorAssociator::init( const edm::EventSetup& iSetup )
00125 {
00126
00127 iSetup.get<CaloGeometryRecord>().get(theCaloGeometry_);
00128 if (!theCaloGeometry_.isValid())
00129 throw cms::Exception("FatalError") << "Unable to find CaloGeometryRecord in event!\n";
00130
00131
00132 iSetup.get<GlobalTrackingGeometryRecord>().get(theTrackingGeometry_);
00133 if (!theTrackingGeometry_.isValid())
00134 throw cms::Exception("FatalError") << "Unable to find GlobalTrackingGeometryRecord in event!\n";
00135
00136 if (useDefaultPropagator_ && (! defProp_ || theMagneticFeildWatcher_.check(iSetup) ) ) {
00137
00138 edm::ESHandle<MagneticField> bField;
00139 iSetup.get<IdealMagneticFieldRecord>().get(bField);
00140
00141 SteppingHelixPropagator* prop = new SteppingHelixPropagator(&*bField,anyDirection);
00142 prop->setMaterialMode(false);
00143 prop->applyRadX0Correction(true);
00144
00145 defProp_ = prop;
00146 setPropagator(defProp_);
00147 }
00148
00149 iSetup.get<DetIdAssociatorRecord>().get("EcalDetIdAssociator", ecalDetIdAssociator_);
00150 iSetup.get<DetIdAssociatorRecord>().get("HcalDetIdAssociator", hcalDetIdAssociator_);
00151 iSetup.get<DetIdAssociatorRecord>().get("HODetIdAssociator", hoDetIdAssociator_);
00152 iSetup.get<DetIdAssociatorRecord>().get("CaloDetIdAssociator", caloDetIdAssociator_);
00153 iSetup.get<DetIdAssociatorRecord>().get("MuonDetIdAssociator", muonDetIdAssociator_);
00154 iSetup.get<DetIdAssociatorRecord>().get("PreshowerDetIdAssociator", preshowerDetIdAssociator_);
00155 }
00156
00157 TrackDetMatchInfo TrackDetectorAssociator::associate( const edm::Event& iEvent,
00158 const edm::EventSetup& iSetup,
00159 const FreeTrajectoryState& fts,
00160 const AssociatorParameters& parameters )
00161 {
00162 return associate(iEvent,iSetup,parameters,&fts);
00163 }
00164
00165 TrackDetMatchInfo TrackDetectorAssociator::associate( const edm::Event& iEvent,
00166 const edm::EventSetup& iSetup,
00167 const AssociatorParameters& parameters,
00168 const FreeTrajectoryState* innerState,
00169 const FreeTrajectoryState* outerState)
00170 {
00171 TrackDetMatchInfo info;
00172 if (! parameters.useEcal && ! parameters.useCalo && ! parameters.useHcal &&
00173 ! parameters.useHO && ! parameters.useMuon && !parameters.usePreshower)
00174 throw cms::Exception("ConfigurationError") <<
00175 "Configuration error! No subdetector was selected for the track association.";
00176
00177
00178
00179 SteppingHelixStateInfo trackOrigin(*innerState);
00180 info.stateAtIP = *innerState;
00181 cachedTrajectory_.setStateAtIP(trackOrigin);
00182
00183 init( iSetup );
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 info.setCaloGeometry(theCaloGeometry_);
00195
00196
00197 cachedTrajectory_.reset_trajectory();
00198
00199
00200
00201
00202 double HOmaxR = hoDetIdAssociator_->volume().maxR();
00203 double HOmaxZ = hoDetIdAssociator_->volume().maxZ();
00204 double minR = ecalDetIdAssociator_->volume().minR();
00205 double minZ = preshowerDetIdAssociator_->volume().minZ();
00206 cachedTrajectory_.setMaxHORadius(HOmaxR);
00207 cachedTrajectory_.setMaxHOLength(HOmaxZ*2.);
00208 cachedTrajectory_.setMinDetectorRadius(minR);
00209 cachedTrajectory_.setMinDetectorLength(minZ*2.);
00210
00211 double maxR(0);
00212 double maxZ(0);
00213
00214 if (parameters.useMuon) {
00215 maxR = muonDetIdAssociator_->volume().maxR();
00216 maxZ = muonDetIdAssociator_->volume().maxZ();
00217 cachedTrajectory_.setMaxDetectorRadius(maxR);
00218 cachedTrajectory_.setMaxDetectorLength(maxZ*2.);
00219 }
00220 else {
00221 maxR = HOmaxR;
00222 maxZ = HOmaxZ;
00223 cachedTrajectory_.setMaxDetectorRadius(HOmaxR);
00224 cachedTrajectory_.setMaxDetectorLength(HOmaxZ*2.);
00225 }
00226
00227
00228 if (outerState) {
00229 if (outerState->position().perp()<HOmaxR && fabs(outerState->position().z())<HOmaxZ) {
00230 LogTrace("TrackAssociator") << "Using outerState as trackOrigin at Rho=" << outerState->position().perp()
00231 << " Z=" << outerState->position().z() << "\n";
00232 trackOrigin = SteppingHelixStateInfo(*outerState);
00233 }
00234 else if(innerState) {
00235 LogTrace("TrackAssociator") << "Using innerState as trackOrigin at Rho=" << innerState->position().perp()
00236 << " Z=" << innerState->position().z() << "\n";
00237 trackOrigin = SteppingHelixStateInfo(*innerState);
00238 }
00239 }
00240
00241 if ( ! cachedTrajectory_.propagateAll(trackOrigin) ) return info;
00242
00243
00244 cachedTrajectory_.findEcalTrajectory( ecalDetIdAssociator_->volume() );
00245 cachedTrajectory_.findHcalTrajectory( hcalDetIdAssociator_->volume() );
00246 cachedTrajectory_.findHOTrajectory( hoDetIdAssociator_->volume() );
00247 cachedTrajectory_.findPreshowerTrajectory( preshowerDetIdAssociator_->volume() );
00248
00249 info.trkGlobPosAtEcal = getPoint( cachedTrajectory_.getStateAtEcal().position() );
00250 info.trkGlobPosAtHcal = getPoint( cachedTrajectory_.getStateAtHcal().position() );
00251 info.trkGlobPosAtHO = getPoint( cachedTrajectory_.getStateAtHO().position() );
00252
00253 info.trkMomAtEcal = cachedTrajectory_.getStateAtEcal().momentum();
00254 info.trkMomAtHcal = cachedTrajectory_.getStateAtHcal().momentum();
00255 info.trkMomAtHO = cachedTrajectory_.getStateAtHO().momentum();
00256
00257
00258
00259 if (parameters.useEcal) fillEcal( iEvent, info, parameters);
00260 if (parameters.useCalo) fillCaloTowers( iEvent, info, parameters);
00261 if (parameters.useHcal) fillHcal( iEvent, info, parameters);
00262 if (parameters.useHO) fillHO( iEvent, info, parameters);
00263 if (parameters.usePreshower) fillPreshower( iEvent, info, parameters);
00264 if (parameters.useMuon) fillMuon( iEvent, info, parameters);
00265 if (parameters.truthMatch) fillCaloTruth( iEvent, info, parameters);
00266
00267 return info;
00268 }
00269
00270 void TrackDetectorAssociator::fillEcal( const edm::Event& iEvent,
00271 TrackDetMatchInfo& info,
00272 const AssociatorParameters& parameters)
00273 {
00274
00275
00276
00277 const std::vector<SteppingHelixStateInfo>& trajectoryStates = cachedTrajectory_.getEcalTrajectory();
00278
00279 for(std::vector<SteppingHelixStateInfo>::const_iterator itr = trajectoryStates.begin();
00280 itr != trajectoryStates.end(); itr++)
00281 LogTrace("TrackAssociator") << "ECAL trajectory point (rho, z, phi): " << itr->position().perp() <<
00282 ", " << itr->position().z() << ", " << itr->position().phi();
00283
00284 std::vector<GlobalPoint> coreTrajectory;
00285 for(std::vector<SteppingHelixStateInfo>::const_iterator itr = trajectoryStates.begin();
00286 itr != trajectoryStates.end(); itr++) coreTrajectory.push_back(itr->position());
00287
00288 if(coreTrajectory.empty()) {
00289 LogTrace("TrackAssociator") << "ECAL track trajectory is empty; moving on\n";
00290 info.isGoodEcal = 0;
00291 return;
00292 }
00293 info.isGoodEcal = 1;
00294
00295
00296
00297 edm::Handle<EBRecHitCollection> EBRecHits;
00298 iEvent.getByLabel( parameters.theEBRecHitCollectionLabel, EBRecHits );
00299 if (!EBRecHits.isValid()) throw cms::Exception("FatalError") << "Unable to find EBRecHitCollection in the event!\n";
00300
00301
00302 edm::Handle<EERecHitCollection> EERecHits;
00303 iEvent.getByLabel( parameters.theEERecHitCollectionLabel, EERecHits );
00304 if (!EERecHits.isValid()) throw cms::Exception("FatalError") << "Unable to find EERecHitCollection in event!\n";
00305
00306
00307
00308 std::set<DetId> ecalIdsInRegion;
00309 if (parameters.accountForTrajectoryChangeCalo){
00310
00311 DetIdAssociator::MapRange mapRange = getMapRange(cachedTrajectory_.trajectoryDelta(CachedTrajectory::IpToEcal),
00312 parameters.dREcalPreselection);
00313 ecalIdsInRegion = ecalDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0],mapRange);
00314 } else ecalIdsInRegion = ecalDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0], parameters.dREcalPreselection);
00315
00316 LogTrace("TrackAssociator") << "ECAL hits in the region: " << ecalIdsInRegion.size();
00317 if (parameters.dREcalPreselection > parameters.dREcal)
00318 ecalIdsInRegion = ecalDetIdAssociator_->getDetIdsInACone(ecalIdsInRegion, coreTrajectory, parameters.dREcal);
00319 LogTrace("TrackAssociator") << "ECAL hits in the cone: " << ecalIdsInRegion.size();
00320 std::vector<DetId> crossedEcalIds =
00321 ecalDetIdAssociator_->getCrossedDetIds(ecalIdsInRegion, coreTrajectory);
00322 LogTrace("TrackAssociator") << "ECAL crossed hits " << crossedEcalIds.size();
00323
00324 info.crossedEcalIds = crossedEcalIds;
00325
00326
00327
00328 for(std::vector<DetId>::const_iterator itr=crossedEcalIds.begin(); itr!=crossedEcalIds.end();itr++)
00329 {
00330 std::vector<EcalRecHit>::const_iterator ebHit = (*EBRecHits).find(*itr);
00331 std::vector<EcalRecHit>::const_iterator eeHit = (*EERecHits).find(*itr);
00332 if(ebHit != (*EBRecHits).end())
00333 info.crossedEcalRecHits.push_back(&*ebHit);
00334 else if(eeHit != (*EERecHits).end())
00335 info.crossedEcalRecHits.push_back(&*eeHit);
00336 else
00337 LogTrace("TrackAssociator") << "Crossed EcalRecHit is not found for DetId: " << itr->rawId();
00338 }
00339
00340 for(std::set<DetId>::const_iterator itr=ecalIdsInRegion.begin(); itr!=ecalIdsInRegion.end();itr++)
00341 {
00342 std::vector<EcalRecHit>::const_iterator ebHit = (*EBRecHits).find(*itr);
00343 std::vector<EcalRecHit>::const_iterator eeHit = (*EERecHits).find(*itr);
00344 if(ebHit != (*EBRecHits).end())
00345 info.ecalRecHits.push_back(&*ebHit);
00346 else if(eeHit != (*EERecHits).end())
00347 info.ecalRecHits.push_back(&*eeHit);
00348 else
00349 LogTrace("TrackAssociator") << "EcalRecHit from the cone is not found for DetId: " << itr->rawId();
00350 }
00351 }
00352
00353 void TrackDetectorAssociator::fillCaloTowers( const edm::Event& iEvent,
00354 TrackDetMatchInfo& info,
00355 const AssociatorParameters& parameters)
00356 {
00357
00358
00359
00360
00361 std::vector<GlobalPoint> trajectory;
00362 const std::vector<SteppingHelixStateInfo>& ecalTrajectoryStates = cachedTrajectory_.getEcalTrajectory();
00363 const std::vector<SteppingHelixStateInfo>& hcalTrajectoryStates = cachedTrajectory_.getHcalTrajectory();
00364 for(std::vector<SteppingHelixStateInfo>::const_iterator itr = ecalTrajectoryStates.begin();
00365 itr != ecalTrajectoryStates.end(); itr++) trajectory.push_back(itr->position());
00366 for(std::vector<SteppingHelixStateInfo>::const_iterator itr = hcalTrajectoryStates.begin();
00367 itr != hcalTrajectoryStates.end(); itr++) trajectory.push_back(itr->position());
00368
00369 if(trajectory.empty()) {
00370 LogTrace("TrackAssociator") << "HCAL trajectory is empty; moving on\n";
00371 info.isGoodCalo = 0;
00372 return;
00373 }
00374 info.isGoodCalo = 1;
00375
00376
00377
00378 edm::Handle<CaloTowerCollection> caloTowers;
00379
00380 iEvent.getByLabel( parameters.theCaloTowerCollectionLabel, caloTowers );
00381 if (!caloTowers.isValid()) throw cms::Exception("FatalError") << "Unable to find CaloTowers in event!\n";
00382
00383
00384 std::set<DetId> caloTowerIdsInRegion;
00385 if (parameters.accountForTrajectoryChangeCalo){
00386
00387 DetIdAssociator::MapRange mapRange = getMapRange(cachedTrajectory_.trajectoryDelta(CachedTrajectory::IpToHcal),
00388 parameters.dRHcalPreselection);
00389 caloTowerIdsInRegion = caloDetIdAssociator_->getDetIdsCloseToAPoint(trajectory[0],mapRange);
00390 } else caloTowerIdsInRegion = caloDetIdAssociator_->getDetIdsCloseToAPoint(trajectory[0], parameters.dRHcalPreselection);
00391
00392 LogTrace("TrackAssociator") << "Towers in the region: " << caloTowerIdsInRegion.size();
00393 std::set<DetId> caloTowerIdsInACone = caloDetIdAssociator_->getDetIdsInACone(caloTowerIdsInRegion, trajectory, parameters.dRHcal);
00394 LogTrace("TrackAssociator") << "Towers in the cone: " << caloTowerIdsInACone.size();
00395 std::vector<DetId> crossedCaloTowerIds = caloDetIdAssociator_->getCrossedDetIds(caloTowerIdsInRegion, trajectory);
00396 LogTrace("TrackAssociator") << "Towers crossed: " << crossedCaloTowerIds.size();
00397
00398 info.crossedTowerIds = crossedCaloTowerIds;
00399
00400
00401
00402 for(std::vector<DetId>::const_iterator itr=crossedCaloTowerIds.begin(); itr!=crossedCaloTowerIds.end();itr++)
00403 {
00404 CaloTowerCollection::const_iterator tower = (*caloTowers).find(*itr);
00405 if(tower != (*caloTowers).end())
00406 info.crossedTowers.push_back(&*tower);
00407 else
00408 LogTrace("TrackAssociator") << "Crossed CaloTower is not found for DetId: " << (*itr).rawId();
00409 }
00410
00411
00412 for(std::set<DetId>::const_iterator itr=caloTowerIdsInACone.begin(); itr!=caloTowerIdsInACone.end();itr++)
00413 {
00414 CaloTowerCollection::const_iterator tower = (*caloTowers).find(*itr);
00415 if(tower != (*caloTowers).end())
00416 info.towers.push_back(&*tower);
00417 else
00418 LogTrace("TrackAssociator") << "CaloTower from the cone is not found for DetId: " << (*itr).rawId();
00419 }
00420
00421 }
00422
00423 void TrackDetectorAssociator::fillPreshower( const edm::Event& iEvent,
00424 TrackDetMatchInfo& info,
00425 const AssociatorParameters& parameters)
00426 {
00427 std::vector<GlobalPoint> trajectory;
00428 const std::vector<SteppingHelixStateInfo>& trajectoryStates = cachedTrajectory_.getPreshowerTrajectory();
00429 for(std::vector<SteppingHelixStateInfo>::const_iterator itr = trajectoryStates.begin();
00430 itr != trajectoryStates.end(); itr++) trajectory.push_back(itr->position());
00431
00432 if(trajectory.empty()) {
00433 LogTrace("TrackAssociator") << "Preshower trajectory is empty; moving on\n";
00434 return;
00435 }
00436
00437 std::set<DetId> idsInRegion =
00438 preshowerDetIdAssociator_->getDetIdsCloseToAPoint(trajectory[0],
00439 parameters.dRPreshowerPreselection);
00440
00441 LogTrace("TrackAssociator") << "Number of Preshower Ids in the region: " << idsInRegion.size();
00442 std::vector<DetId> crossedIds = preshowerDetIdAssociator_->getCrossedDetIds(idsInRegion, trajectory);
00443 LogTrace("TrackAssociator") << "Number of Preshower Ids in crossed: " << crossedIds.size();
00444 info.crossedPreshowerIds = crossedIds;
00445 }
00446
00447
00448 void TrackDetectorAssociator::fillHcal( const edm::Event& iEvent,
00449 TrackDetMatchInfo& info,
00450 const AssociatorParameters& parameters)
00451 {
00452
00453
00454
00455 const std::vector<SteppingHelixStateInfo>& trajectoryStates = cachedTrajectory_.getHcalTrajectory();
00456
00457 std::vector<GlobalPoint> coreTrajectory;
00458 for(std::vector<SteppingHelixStateInfo>::const_iterator itr = trajectoryStates.begin();
00459 itr != trajectoryStates.end(); itr++) coreTrajectory.push_back(itr->position());
00460
00461 if(coreTrajectory.empty()) {
00462 LogTrace("TrackAssociator") << "HCAL trajectory is empty; moving on\n";
00463 info.isGoodHcal = 0;
00464 return;
00465 }
00466 info.isGoodHcal = 1;
00467
00468
00469
00470 edm::Handle<HBHERecHitCollection> collection;
00471
00472 iEvent.getByLabel( parameters.theHBHERecHitCollectionLabel, collection );
00473 if ( ! collection.isValid() ) throw cms::Exception("FatalError") << "Unable to find HBHERecHits in event!\n";
00474
00475
00476 std::set<DetId> idsInRegion;
00477 if (parameters.accountForTrajectoryChangeCalo){
00478
00479 DetIdAssociator::MapRange mapRange = getMapRange(cachedTrajectory_.trajectoryDelta(CachedTrajectory::IpToHcal),
00480 parameters.dRHcalPreselection);
00481 idsInRegion = hcalDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0], mapRange);
00482 } else idsInRegion = hcalDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0], parameters.dRHcalPreselection);
00483
00484 LogTrace("TrackAssociator") << "HCAL hits in the region: " << idsInRegion.size() << "\n" << DetIdInfo::info(idsInRegion);
00485 std::set<DetId> idsInACone = hcalDetIdAssociator_->getDetIdsInACone(idsInRegion, coreTrajectory, parameters.dRHcal);
00486 LogTrace("TrackAssociator") << "HCAL hits in the cone: " << idsInACone.size() << "\n" << DetIdInfo::info(idsInACone);
00487 std::vector<DetId> crossedIds =
00488 hcalDetIdAssociator_->getCrossedDetIds(idsInRegion, coreTrajectory);
00489 LogTrace("TrackAssociator") << "HCAL hits crossed: " << crossedIds.size() << "\n" << DetIdInfo::info(crossedIds);
00490
00491 info.crossedHcalIds = crossedIds;
00492
00493
00494
00495 for(std::vector<DetId>::const_iterator itr=crossedIds.begin(); itr!=crossedIds.end();itr++)
00496 {
00497 HBHERecHitCollection::const_iterator hit = (*collection).find(*itr);
00498 if( hit != (*collection).end() )
00499 info.crossedHcalRecHits.push_back(&*hit);
00500 else
00501 LogTrace("TrackAssociator") << "Crossed HBHERecHit is not found for DetId: " << itr->rawId();
00502 }
00503
00504 for(std::set<DetId>::const_iterator itr=idsInACone.begin(); itr!=idsInACone.end();itr++)
00505 {
00506 HBHERecHitCollection::const_iterator hit = (*collection).find(*itr);
00507 if( hit != (*collection).end() )
00508 info.hcalRecHits.push_back(&*hit);
00509 else
00510 LogTrace("TrackAssociator") << "HBHERecHit from the cone is not found for DetId: " << itr->rawId();
00511 }
00512 }
00513
00514 void TrackDetectorAssociator::fillHO( const edm::Event& iEvent,
00515 TrackDetMatchInfo& info,
00516 const AssociatorParameters& parameters)
00517 {
00518
00519
00520
00521 const std::vector<SteppingHelixStateInfo>& trajectoryStates = cachedTrajectory_.getHOTrajectory();
00522
00523 std::vector<GlobalPoint> coreTrajectory;
00524 for(std::vector<SteppingHelixStateInfo>::const_iterator itr = trajectoryStates.begin();
00525 itr != trajectoryStates.end(); itr++) coreTrajectory.push_back(itr->position());
00526
00527 if(coreTrajectory.empty()) {
00528 LogTrace("TrackAssociator") << "HO trajectory is empty; moving on\n";
00529 info.isGoodHO = 0;
00530 return;
00531 }
00532 info.isGoodHO = 1;
00533
00534
00535
00536 edm::Handle<HORecHitCollection> collection;
00537
00538 iEvent.getByLabel( parameters.theHORecHitCollectionLabel, collection );
00539 if ( ! collection.isValid() ) throw cms::Exception("FatalError") << "Unable to find HORecHits in event!\n";
00540
00541
00542 std::set<DetId> idsInRegion;
00543 if (parameters.accountForTrajectoryChangeCalo){
00544
00545 DetIdAssociator::MapRange mapRange = getMapRange(cachedTrajectory_.trajectoryDelta(CachedTrajectory::IpToHO),
00546 parameters.dRHcalPreselection);
00547 idsInRegion = hoDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0], mapRange);
00548 } else idsInRegion = hoDetIdAssociator_->getDetIdsCloseToAPoint(coreTrajectory[0], parameters.dRHcalPreselection);
00549
00550 LogTrace("TrackAssociator") << "idsInRegion.size(): " << idsInRegion.size();
00551 std::set<DetId> idsInACone = hoDetIdAssociator_->getDetIdsInACone(idsInRegion, coreTrajectory, parameters.dRHcal);
00552 LogTrace("TrackAssociator") << "idsInACone.size(): " << idsInACone.size();
00553 std::vector<DetId> crossedIds =
00554 hoDetIdAssociator_->getCrossedDetIds(idsInRegion, coreTrajectory);
00555
00556 info.crossedHOIds = crossedIds;
00557
00558
00559
00560 for(std::vector<DetId>::const_iterator itr=crossedIds.begin(); itr!=crossedIds.end();itr++)
00561 {
00562 HORecHitCollection::const_iterator hit = (*collection).find(*itr);
00563 if( hit != (*collection).end() )
00564 info.crossedHORecHits.push_back(&*hit);
00565 else
00566 LogTrace("TrackAssociator") << "Crossed HORecHit is not found for DetId: " << itr->rawId();
00567 }
00568
00569
00570 for(std::set<DetId>::const_iterator itr=idsInACone.begin(); itr!=idsInACone.end();itr++)
00571 {
00572 HORecHitCollection::const_iterator hit = (*collection).find(*itr);
00573 if( hit != (*collection).end() )
00574 info.hoRecHits.push_back(&*hit);
00575 else
00576 LogTrace("TrackAssociator") << "HORecHit from the cone is not found for DetId: " << itr->rawId();
00577 }
00578 }
00579
00580 FreeTrajectoryState TrackDetectorAssociator::getFreeTrajectoryState( const edm::EventSetup& iSetup,
00581 const SimTrack& track,
00582 const SimVertex& vertex )
00583 {
00584 GlobalVector vector( track.momentum().x(), track.momentum().y(), track.momentum().z() );
00585 GlobalPoint point( vertex.position().x(), vertex.position().y(), vertex.position().z() );
00586
00587 int charge = track.type( )> 0 ? -1 : 1;
00588 if ( abs(track.type( )) == 211 ||
00589 abs(track.type( )) == 321 ||
00590 abs(track.type( )) == 2212 )
00591 charge = track.type( )< 0 ? -1 : 1;
00592 return getFreeTrajectoryState(iSetup, vector, point, charge);
00593 }
00594
00595 FreeTrajectoryState TrackDetectorAssociator::getFreeTrajectoryState( const edm::EventSetup& iSetup,
00596 const GlobalVector& momentum,
00597 const GlobalPoint& vertex,
00598 const int charge)
00599 {
00600 edm::ESHandle<MagneticField> bField;
00601 iSetup.get<IdealMagneticFieldRecord>().get(bField);
00602
00603 GlobalTrajectoryParameters tPars(vertex, momentum, charge, &*bField);
00604
00605 CLHEP::HepSymMatrix covT(6,1); covT *= 1e-6;
00606 CartesianTrajectoryError tCov(covT);
00607
00608 return FreeTrajectoryState(tPars, tCov);
00609 }
00610
00611
00612 FreeTrajectoryState TrackDetectorAssociator::getFreeTrajectoryState( const edm::EventSetup& iSetup,
00613 const reco::Track& track )
00614 {
00615 edm::ESHandle<MagneticField> bField;
00616 iSetup.get<IdealMagneticFieldRecord>().get(bField);
00617
00618 GlobalVector vector( track.momentum().x(), track.momentum().y(), track.momentum().z() );
00619
00620 GlobalPoint point( track.vertex().x(), track.vertex().y(), track.vertex().z() );
00621
00622 GlobalTrajectoryParameters tPars(point, vector, track.charge(), &*bField);
00623
00624
00625
00626
00627 CLHEP::HepSymMatrix covT(6,1); covT *= 1e-6;
00628 CartesianTrajectoryError tCov(covT);
00629
00630 return FreeTrajectoryState(tPars, tCov);
00631 }
00632
00633 DetIdAssociator::MapRange TrackDetectorAssociator::getMapRange( const std::pair<float,float>& delta,
00634 const float dR )
00635 {
00636 DetIdAssociator::MapRange mapRange;
00637 mapRange.dThetaPlus = dR;
00638 mapRange.dThetaMinus = dR;
00639 mapRange.dPhiPlus = dR;
00640 mapRange.dPhiMinus = dR;
00641 if ( delta.first > 0 )
00642 mapRange.dThetaPlus += delta.first;
00643 else
00644 mapRange.dThetaMinus += fabs(delta.first);
00645 if ( delta.second > 0 )
00646 mapRange.dPhiPlus += delta.second;
00647 else
00648 mapRange.dPhiMinus += fabs(delta.second);
00649 LogTrace("TrackAssociator") << "Selection range: (dThetaPlus, dThetaMinus, dPhiPlus, dPhiMinus, dRPreselection): " <<
00650 mapRange.dThetaPlus << ", " << mapRange.dThetaMinus << ", " <<
00651 mapRange.dPhiPlus << ", " << mapRange.dPhiMinus << ", " << dR;
00652 return mapRange;
00653 }
00654
00655 void TrackDetectorAssociator::getTAMuonChamberMatches(std::vector<TAMuonChamberMatch>& matches,
00656 const AssociatorParameters& parameters)
00657 {
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669 SteppingHelixStateInfo trajectoryPoint = cachedTrajectory_.getStateAtHcal();
00670
00671
00672 if(! trajectoryPoint.isValid() ) trajectoryPoint = cachedTrajectory_.getOuterState();
00673 if(! trajectoryPoint.isValid() ) {
00674 LogTrace("TrackAssociator") <<
00675 "trajectory position at HCAL is not valid. Assume the track cannot reach muon detectors and skip it";
00676 return;
00677 }
00678
00679 GlobalVector direction = trajectoryPoint.momentum().unit();
00680 LogTrace("TrackAssociator") << "muon direction: " << direction << "\n\t and corresponding point: " <<
00681 trajectoryPoint.position() <<"\n";
00682
00683 DetIdAssociator::MapRange mapRange = getMapRange(cachedTrajectory_.trajectoryDelta(CachedTrajectory::FullTrajectory),
00684 parameters.dRMuonPreselection);
00685
00686
00687
00688
00689 std::set<DetId> muonIdsInRegion =
00690 muonDetIdAssociator_->getDetIdsCloseToAPoint(trajectoryPoint.position(), mapRange);
00691
00692 LogTrace("TrackAssociator") << "Number of chambers to check: " << muonIdsInRegion.size();
00693 for(std::set<DetId>::const_iterator detId = muonIdsInRegion.begin(); detId != muonIdsInRegion.end(); detId++)
00694 {
00695 const GeomDet* geomDet = muonDetIdAssociator_->getGeomDet(*detId);
00696
00697 TrajectoryStateOnSurface stateOnSurface = cachedTrajectory_.propagate( &geomDet->surface() );
00698 if (! stateOnSurface.isValid()) {
00699 LogTrace("TrackAssociator") << "Failed to propagate the track; moving on\n\t"<<
00700 detId->rawId() << " not crossed\n";
00701 continue;
00702 }
00703
00704 LocalPoint localPoint = geomDet->surface().toLocal(stateOnSurface.freeState()->position());
00705 LocalError localError = stateOnSurface.localError().positionError();
00706 float distanceX = 0;
00707 float distanceY = 0;
00708 float sigmaX = 0.0;
00709 float sigmaY = 0.0;
00710 if(const CSCChamber* cscChamber = dynamic_cast<const CSCChamber*>(geomDet) ) {
00711 const CSCChamberSpecs* chamberSpecs = cscChamber->specs();
00712 if(! chamberSpecs) {
00713 LogTrace("TrackAssociator") << "Failed to get CSCChamberSpecs from CSCChamber; moving on\n";
00714 continue;
00715 }
00716 const CSCLayerGeometry* layerGeometry = chamberSpecs->oddLayerGeometry(1);
00717 if(! layerGeometry) {
00718 LogTrace("TrackAssociator") << "Failed to get CSCLayerGeometry from CSCChamberSpecs; moving on\n";
00719 continue;
00720 }
00721 const CSCWireTopology* wireTopology = layerGeometry->wireTopology();
00722 if(! wireTopology) {
00723 LogTrace("TrackAssociator") << "Failed to get CSCWireTopology from CSCLayerGeometry; moving on\n";
00724 continue;
00725 }
00726
00727 float wideWidth = wireTopology->wideWidthOfPlane();
00728 float narrowWidth = wireTopology->narrowWidthOfPlane();
00729 float length = wireTopology->lengthOfPlane();
00730
00731 float yOfFirstWire = fabs(wireTopology->wireAngle())>1.E-06 ? -0.5*length : wireTopology->yOfWire(1);
00732
00733 float yCOWPOffset = yOfFirstWire+0.5*length;
00734
00735
00736 float tangent = (wideWidth-narrowWidth)/(2.*length);
00737
00738 float yPrime = localPoint.y()+fabs(yOfFirstWire);
00739
00740 float halfWidthAtYPrime = 0.5*narrowWidth+yPrime*tangent;
00741 distanceX = fabs(localPoint.x()) - halfWidthAtYPrime;
00742 distanceY = fabs(localPoint.y()-yCOWPOffset) - 0.5*length;
00743 sigmaX = distanceX/sqrt(localError.xx());
00744 sigmaY = distanceY/sqrt(localError.yy());
00745 } else {
00746 distanceX = fabs(localPoint.x()) - geomDet->surface().bounds().width()/2.;
00747 distanceY = fabs(localPoint.y()) - geomDet->surface().bounds().length()/2.;
00748 sigmaX = distanceX/sqrt(localError.xx());
00749 sigmaY = distanceY/sqrt(localError.yy());
00750 }
00751
00752 if ( (distanceX < parameters.muonMaxDistanceX && distanceY < parameters.muonMaxDistanceY) ||
00753 (sigmaX < parameters.muonMaxDistanceSigmaX && sigmaY < parameters.muonMaxDistanceSigmaY) ) {
00754 LogTrace("TrackAssociator") << "found a match, DetId: " << detId->rawId();
00755 TAMuonChamberMatch match;
00756 match.tState = stateOnSurface;
00757 match.localDistanceX = distanceX;
00758 match.localDistanceY = distanceY;
00759 match.id = *detId;
00760 matches.push_back(match);
00761 }
00762
00763 }
00764
00765
00766 }
00767
00768 void TrackDetectorAssociator::fillMuon( const edm::Event& iEvent,
00769 TrackDetMatchInfo& info,
00770 const AssociatorParameters& parameters)
00771 {
00772
00773
00774
00775
00776
00777 edm::Handle<DTRecSegment4DCollection> dtSegments;
00778 iEvent.getByLabel( parameters.theDTRecSegment4DCollectionLabel, dtSegments );
00779 if (! dtSegments.isValid())
00780 throw cms::Exception("FatalError") << "Unable to find DTRecSegment4DCollection in event!\n";
00781
00782 edm::Handle<CSCSegmentCollection> cscSegments;
00783 iEvent.getByLabel( parameters.theCSCSegmentCollectionLabel, cscSegments );
00784 if (! cscSegments.isValid())
00785 throw cms::Exception("FatalError") << "Unable to find CSCSegmentCollection in event!\n";
00786
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800 std::vector<TAMuonChamberMatch> matchedChambers;
00801 LogTrace("TrackAssociator") << "Trying to Get ChamberMatches" << std::endl;
00802 getTAMuonChamberMatches(matchedChambers, parameters);
00803 LogTrace("TrackAssociator") << "Chambers matched: " << matchedChambers.size() << "\n";
00804
00805
00806
00807
00808 for(std::vector<TAMuonChamberMatch>::iterator matchedChamber = matchedChambers.begin();
00809 matchedChamber != matchedChambers.end(); matchedChamber++)
00810 {
00811 const GeomDet* geomDet = muonDetIdAssociator_->getGeomDet((*matchedChamber).id);
00812
00813 if(const DTChamber* chamber = dynamic_cast<const DTChamber*>(geomDet) ) {
00814
00815 DTRecSegment4DCollection::range range = dtSegments->get(chamber->id());
00816
00817 for (DTRecSegment4DCollection::const_iterator segment = range.first; segment!=range.second; segment++) {
00818 if (addTAMuonSegmentMatch(*matchedChamber, &(*segment), parameters)) {
00819 matchedChamber->segments.back().dtSegmentRef = DTRecSegment4DRef(dtSegments, segment - dtSegments->begin());
00820 }
00821 }
00822 }else{
00823
00824 if(const CSCChamber* chamber = dynamic_cast<const CSCChamber*>(geomDet) ) {
00825
00826 CSCSegmentCollection::range range = cscSegments->get(chamber->id());
00827
00828 for (CSCSegmentCollection::const_iterator segment = range.first; segment!=range.second; segment++) {
00829 if (addTAMuonSegmentMatch(*matchedChamber, &(*segment), parameters)) {
00830 matchedChamber->segments.back().cscSegmentRef = CSCSegmentRef(cscSegments, segment - cscSegments->begin());
00831 }
00832 }
00833 }else{
00834 throw cms::Exception("FatalError") << "Failed to cast GeomDet object to either DTChamber or CSCChamber. Who is this guy anyway?\n";
00835 }
00836 }
00837 info.chambers.push_back(*matchedChamber);
00838 }
00839 }
00840
00841
00842 bool TrackDetectorAssociator::addTAMuonSegmentMatch(TAMuonChamberMatch& matchedChamber,
00843 const RecSegment* segment,
00844 const AssociatorParameters& parameters)
00845 {
00846 LogTrace("TrackAssociator")
00847 << "Segment local position: " << segment->localPosition() << "\n"
00848 << std::hex << segment->geographicalId().rawId() << "\n";
00849
00850 const GeomDet* chamber = muonDetIdAssociator_->getGeomDet(matchedChamber.id);
00851 TrajectoryStateOnSurface trajectoryStateOnSurface = matchedChamber.tState;
00852 GlobalPoint segmentGlobalPosition = chamber->toGlobal(segment->localPosition());
00853
00854 LogTrace("TrackAssociator")
00855 << "Segment global position: " << segmentGlobalPosition << " \t (R_xy,eta,phi): "
00856 << segmentGlobalPosition.perp() << "," << segmentGlobalPosition.eta() << "," << segmentGlobalPosition.phi() << "\n";
00857
00858 LogTrace("TrackAssociator")
00859 << "\teta hit: " << segmentGlobalPosition.eta() << " \tpropagator: " << trajectoryStateOnSurface.freeState()->position().eta() << "\n"
00860 << "\tphi hit: " << segmentGlobalPosition.phi() << " \tpropagator: " << trajectoryStateOnSurface.freeState()->position().phi() << std::endl;
00861
00862 bool isGood = false;
00863 bool isDTWithoutY = false;
00864 const DTRecSegment4D* dtseg = dynamic_cast<const DTRecSegment4D*>(segment);
00865 if ( dtseg && (! dtseg->hasZed()) )
00866 isDTWithoutY = true;
00867
00868 double deltaPhi(fabs(segmentGlobalPosition.phi()-trajectoryStateOnSurface.freeState()->position().phi()));
00869 if(deltaPhi>M_PI) deltaPhi = fabs(deltaPhi-M_PI*2.);
00870
00871 if( isDTWithoutY )
00872 {
00873 isGood = deltaPhi < parameters.dRMuon;
00874
00875 isGood &= fabs(segmentGlobalPosition.eta()-trajectoryStateOnSurface.freeState()->position().eta()) < .3;
00876 } else isGood = sqrt( pow(segmentGlobalPosition.eta()-trajectoryStateOnSurface.freeState()->position().eta(),2) +
00877 deltaPhi*deltaPhi) < parameters.dRMuon;
00878
00879 if(isGood) {
00880 TAMuonSegmentMatch muonSegment;
00881 muonSegment.segmentGlobalPosition = getPoint(segmentGlobalPosition);
00882 muonSegment.segmentLocalPosition = getPoint( segment->localPosition() );
00883 muonSegment.segmentLocalDirection = getVector( segment->localDirection() );
00884 muonSegment.segmentLocalErrorXX = segment->localPositionError().xx();
00885 muonSegment.segmentLocalErrorYY = segment->localPositionError().yy();
00886 muonSegment.segmentLocalErrorXY = segment->localPositionError().xy();
00887 muonSegment.segmentLocalErrorDxDz = segment->localDirectionError().xx();
00888 muonSegment.segmentLocalErrorDyDz = segment->localDirectionError().yy();
00889
00890
00891
00892
00893
00894 muonSegment.segmentLocalErrorXDxDz = -999;
00895 muonSegment.segmentLocalErrorYDyDz = -999;
00896 muonSegment.hasZed = true;
00897 muonSegment.hasPhi = true;
00898
00899
00900 muonSegment.t0 = 0;
00901 if ( dtseg ) {
00902 if ( (dtseg->hasPhi()) && (! isDTWithoutY) ) {
00903 int phiHits = dtseg->phiSegment()->specificRecHits().size();
00904
00905 int hits=0;
00906 double t0=0.;
00907
00908 if (phiHits>5 && dtseg->phiSegment()->ist0Valid()) {
00909 t0+=dtseg->phiSegment()->t0()*phiHits;
00910 hits+=phiHits;
00911 LogTrace("TrackAssociator") << " Phi t0: " << dtseg->phiSegment()->t0() << " hits: " << phiHits;
00912 }
00913
00914
00915
00916
00917
00918
00919 if (hits) muonSegment.t0 = t0/hits;
00920
00921 } else {
00922
00923 if (isDTWithoutY) muonSegment.hasZed = false;
00924 if (! dtseg->hasPhi()) muonSegment.hasPhi = false;
00925 }
00926 }
00927 matchedChamber.segments.push_back(muonSegment);
00928 }
00929
00930 return isGood;
00931 }
00932
00933
00934
00935 void TrackDetectorAssociator::fillCaloTruth( const edm::Event& iEvent,
00936 TrackDetMatchInfo& info,
00937 const AssociatorParameters& parameters)
00938 {
00939
00940 using namespace edm;
00941 Handle<SimTrackContainer> simTracks;
00942 iEvent.getByType<SimTrackContainer>(simTracks);
00943 if (! simTracks.isValid() ) throw cms::Exception("FatalError") << "No simulated tracks found\n";
00944
00945 Handle<SimVertexContainer> simVertices;
00946 iEvent.getByType<SimVertexContainer>(simVertices);
00947 if (! simVertices.isValid() ) throw cms::Exception("FatalError") << "No simulated vertices found\n";
00948
00949
00950 Handle<PCaloHitContainer> simEcalHitsEB;
00951 iEvent.getByLabel("g4SimHits","EcalHitsEB",simEcalHitsEB);
00952 if (! simEcalHitsEB.isValid() ) throw cms::Exception("FatalError") << "No simulated ECAL EB hits found\n";
00953
00954 Handle<PCaloHitContainer> simEcalHitsEE;
00955 iEvent.getByLabel("g4SimHits","EcalHitsEE",simEcalHitsEE);
00956 if (! simEcalHitsEE.isValid() ) throw cms::Exception("FatalError") << "No simulated ECAL EE hits found\n";
00957
00958 Handle<PCaloHitContainer> simHcalHits;
00959 iEvent.getByLabel("g4SimHits","HcalHits",simHcalHits);
00960 if (! simHcalHits.isValid() ) throw cms::Exception("FatalError") << "No simulated HCAL hits found\n";
00961
00962
00963 SimTrackContainer::const_iterator simTrack = simTracks->begin();
00964 for( ; simTrack != simTracks->end(); ++simTrack){
00965 math::XYZVector simP3( simTrack->momentum().x(), simTrack->momentum().y(), simTrack->momentum().z() );
00966 math::XYZVector recoP3( info.stateAtIP.momentum().x(), info.stateAtIP.momentum().y(), info.stateAtIP.momentum().z() );
00967 if ( ROOT::Math::VectorUtil::DeltaR(recoP3, simP3) < 0.1 ) break;
00968 }
00969 if ( simTrack != simTracks->end() ) {
00970 info.simTrack = &(*simTrack);
00971 double ecalTrueEnergy(0);
00972 double hcalTrueEnergy(0);
00973
00974
00975 for( PCaloHitContainer::const_iterator hit = simEcalHitsEB->begin(); hit != simEcalHitsEB->end(); ++hit )
00976 if ( hit->geantTrackId() == info.simTrack->genpartIndex() ) ecalTrueEnergy += hit->energy();
00977
00978 for( PCaloHitContainer::const_iterator hit = simEcalHitsEE->begin(); hit != simEcalHitsEE->end(); ++hit )
00979 if ( hit->geantTrackId() == info.simTrack->genpartIndex() ) ecalTrueEnergy += hit->energy();
00980
00981 for( PCaloHitContainer::const_iterator hit = simHcalHits->begin(); hit != simHcalHits->end(); ++hit )
00982 if ( hit->geantTrackId() == info.simTrack->genpartIndex() ) hcalTrueEnergy += hit->energy();
00983
00984 info.ecalTrueEnergy = ecalTrueEnergy;
00985 info.hcalTrueEnergy = hcalTrueEnergy;
00986 info.hcalTrueEnergyCorrected = hcalTrueEnergy;
00987 if ( fabs(info.trkGlobPosAtHcal.eta()) < 1.3 )
00988 info.hcalTrueEnergyCorrected = hcalTrueEnergy*113.2;
00989 else
00990 if ( fabs(info.trkGlobPosAtHcal.eta()) < 3.0 )
00991 info.hcalTrueEnergyCorrected = hcalTrueEnergy*167.2;
00992 }
00993 }
00994
00995 TrackDetMatchInfo TrackDetectorAssociator::associate( const edm::Event& iEvent,
00996 const edm::EventSetup& iSetup,
00997 const reco::Track& track,
00998 const AssociatorParameters& parameters,
00999 Direction direction )
01000 {
01001 double currentStepSize = cachedTrajectory_.getPropagationStep();
01002 TrajectoryStateTransform tsTransform;
01003 edm::ESHandle<MagneticField> bField;
01004 iSetup.get<IdealMagneticFieldRecord>().get(bField);
01005
01006 if(track.extra().isNull()) {
01007 if ( direction != InsideOut )
01008 throw cms::Exception("FatalError") <<
01009 "No TrackExtra information is available and association is done with something else than InsideOut track.\n" <<
01010 "Either change the parameter or provide needed data!\n";
01011 LogTrace("TrackAssociator") << "Track Extras not found\n";
01012 FreeTrajectoryState initialState = tsTransform.initialFreeState(track,&*bField);
01013 return associate(iEvent, iSetup, parameters, &initialState);
01014 }
01015
01016 LogTrace("TrackAssociator") << "Track Extras found\n";
01017 FreeTrajectoryState innerState = tsTransform.innerFreeState(track,&*bField);
01018 FreeTrajectoryState outerState = tsTransform.outerFreeState(track,&*bField);
01019 FreeTrajectoryState referenceState = tsTransform.initialFreeState(track,&*bField);
01020
01021 LogTrace("TrackAssociator") << "inner track state (rho, z, phi):" <<
01022 track.innerPosition().Rho() << ", " << track.innerPosition().z() <<
01023 ", " << track.innerPosition().phi() << "\n";
01024 LogTrace("TrackAssociator") << "innerFreeState (rho, z, phi):" <<
01025 innerState.position().perp() << ", " << innerState.position().z() <<
01026 ", " << innerState.position().phi() << "\n";
01027
01028 LogTrace("TrackAssociator") << "outer track state (rho, z, phi):" <<
01029 track.outerPosition().Rho() << ", " << track.outerPosition().z() <<
01030 ", " << track.outerPosition().phi() << "\n";
01031 LogTrace("TrackAssociator") << "outerFreeState (rho, z, phi):" <<
01032 outerState.position().perp() << ", " << outerState.position().z() <<
01033 ", " << outerState.position().phi() << "\n";
01034
01035
01036 if ( crossedIP( track ) ) {
01037 switch ( direction ) {
01038 case InsideOut:
01039 case Any:
01040 return associate(iEvent, iSetup, parameters, &referenceState, &outerState);
01041 break;
01042 case OutsideIn:
01043 {
01044 cachedTrajectory_.setPropagationStep( -fabs(currentStepSize) );
01045 TrackDetMatchInfo result = associate(iEvent, iSetup, parameters, &innerState, &referenceState);
01046 cachedTrajectory_.setPropagationStep( currentStepSize );
01047 return result;
01048 break;
01049 }
01050 }
01051 } else {
01052 switch ( direction ) {
01053 case InsideOut:
01054 return associate(iEvent, iSetup, parameters, &innerState, &outerState);
01055 break;
01056 case OutsideIn:
01057 {
01058 cachedTrajectory_.setPropagationStep( -fabs(currentStepSize) );
01059 TrackDetMatchInfo result = associate(iEvent, iSetup, parameters, &outerState, &innerState);
01060 cachedTrajectory_.setPropagationStep( currentStepSize );
01061 return result;
01062 break;
01063 }
01064 case Any:
01065 {
01066
01067 if ( track.innerPosition().Dot( track.innerMomentum() ) < 0 &&
01068 track.outerPosition().Dot( track.outerMomentum() ) < 0 )
01069 {
01070 cachedTrajectory_.setPropagationStep( -fabs(currentStepSize) );
01071 TrackDetMatchInfo result;
01072 if ( track.innerPosition().R() < track.outerPosition().R() )
01073 result = associate(iEvent, iSetup, parameters, &innerState, &outerState);
01074 else
01075 result = associate(iEvent, iSetup, parameters, &outerState, &innerState);
01076 cachedTrajectory_.setPropagationStep( currentStepSize );
01077 return result;
01078 }
01079 }
01080 }
01081 }
01082
01083
01084 return associate(iEvent, iSetup, parameters, &innerState, &outerState);
01085 }
01086
01087 TrackDetMatchInfo TrackDetectorAssociator::associate( const edm::Event& iEvent,
01088 const edm::EventSetup& iSetup,
01089 const SimTrack& track,
01090 const SimVertex& vertex,
01091 const AssociatorParameters& parameters)
01092 {
01093 return associate(iEvent, iSetup, getFreeTrajectoryState(iSetup, track, vertex), parameters);
01094 }
01095
01096 TrackDetMatchInfo TrackDetectorAssociator::associate( const edm::Event& iEvent,
01097 const edm::EventSetup& iSetup,
01098 const GlobalVector& momentum,
01099 const GlobalPoint& vertex,
01100 const int charge,
01101 const AssociatorParameters& parameters)
01102 {
01103 return associate(iEvent, iSetup, getFreeTrajectoryState(iSetup, momentum, vertex, charge), parameters);
01104 }
01105
01106 bool TrackDetectorAssociator::crossedIP( const reco::Track& track )
01107 {
01108 bool crossed = true;
01109 crossed &= (track.innerPosition().rho() > 3 );
01110 crossed &= (track.outerPosition().rho() > 3 );
01111 crossed &= ( ( track.innerPosition().x()*track.innerMomentum().x() +
01112 track.innerPosition().y()*track.innerMomentum().y() < 0 ) !=
01113 ( track.outerPosition().x()*track.outerMomentum().x() +
01114 track.outerPosition().y()*track.outerMomentum().y() < 0 ) );
01115 return crossed;
01116 }