CMS 3D CMS Logo

TrackDetectorAssociator.cc

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

Generated on Tue Jun 9 17:48:29 2009 for CMSSW by  doxygen 1.5.4