00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <memory>
00015
00016
00017 #include "FWCore/Framework/interface/Frameworkfwd.h"
00018 #include "FWCore/Framework/interface/EDProducer.h"
00019
00020 #include "FWCore/Framework/interface/Event.h"
00021 #include "FWCore/Framework/interface/EventSetup.h"
00022
00023 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00024
00025 #include "DataFormats/Common/interface/Handle.h"
00026 #include "DataFormats/TrackReco/interface/Track.h"
00027 #include "DataFormats/MuonReco/interface/Muon.h"
00028 #include "DataFormats/MuonReco/interface/CaloMuon.h"
00029 #include "DataFormats/MuonReco/interface/MuonTime.h"
00030 #include "DataFormats/MuonReco/interface/MuonTimeExtra.h"
00031 #include "DataFormats/MuonReco/interface/MuonTimeExtraMap.h"
00032 #include "DataFormats/RecoCandidate/interface/IsoDeposit.h"
00033 #include "DataFormats/RecoCandidate/interface/IsoDepositFwd.h"
00034
00035 #include "TrackingTools/TrackAssociator/interface/TrackDetectorAssociator.h"
00036 #include "Utilities/Timing/interface/TimerStack.h"
00037
00038 #include <boost/regex.hpp>
00039 #include "RecoMuon/MuonIdentification/plugins/MuonIdProducer.h"
00040 #include "RecoMuon/MuonIdentification/interface/MuonIdTruthInfo.h"
00041 #include "RecoMuon/MuonIdentification/interface/MuonArbitrationMethods.h"
00042 #include "RecoMuon/MuonIdentification/interface/MuonMesh.h"
00043
00044 #include "PhysicsTools/IsolationAlgos/interface/IsoDepositExtractorFactory.h"
00045 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00046
00047 #include <algorithm>
00048
00049 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
00050 #include "DataFormats/MuonDetId/interface/DTChamberId.h"
00051 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00052 #include "DataFormats/MuonDetId/interface/RPCDetId.h"
00053
00054 #include "DataFormats/Common/interface/ValueMap.h"
00055
00056 MuonIdProducer::MuonIdProducer(const edm::ParameterSet& iConfig):
00057 muIsoExtractorCalo_(0),muIsoExtractorTrack_(0),muIsoExtractorJet_(0)
00058 {
00059 produces<reco::MuonCollection>();
00060 produces<reco::CaloMuonCollection>();
00061 produces<reco::MuonTimeExtraMap>("combined");
00062 produces<reco::MuonTimeExtraMap>("dt");
00063 produces<reco::MuonTimeExtraMap>("csc");
00064
00065 minPt_ = iConfig.getParameter<double>("minPt");
00066 minP_ = iConfig.getParameter<double>("minP");
00067 minPCaloMuon_ = iConfig.getParameter<double>("minPCaloMuon");
00068 minNumberOfMatches_ = iConfig.getParameter<int>("minNumberOfMatches");
00069 addExtraSoftMuons_ = iConfig.getParameter<bool>("addExtraSoftMuons");
00070 maxAbsEta_ = iConfig.getParameter<double>("maxAbsEta");
00071 maxAbsDx_ = iConfig.getParameter<double>("maxAbsDx");
00072 maxAbsPullX_ = iConfig.getParameter<double>("maxAbsPullX");
00073 maxAbsDy_ = iConfig.getParameter<double>("maxAbsDy");
00074 maxAbsPullY_ = iConfig.getParameter<double>("maxAbsPullY");
00075 fillCaloCompatibility_ = iConfig.getParameter<bool>("fillCaloCompatibility");
00076 fillEnergy_ = iConfig.getParameter<bool>("fillEnergy");
00077 fillMatching_ = iConfig.getParameter<bool>("fillMatching");
00078 fillIsolation_ = iConfig.getParameter<bool>("fillIsolation");
00079 writeIsoDeposits_ = iConfig.getParameter<bool>("writeIsoDeposits");
00080 fillGlobalTrackQuality_ = iConfig.getParameter<bool>("fillGlobalTrackQuality");
00081 ptThresholdToFillCandidateP4WithGlobalFit_ = iConfig.getParameter<double>("ptThresholdToFillCandidateP4WithGlobalFit");
00082 sigmaThresholdToFillCandidateP4WithGlobalFit_ = iConfig.getParameter<double>("sigmaThresholdToFillCandidateP4WithGlobalFit");
00083 caloCut_ = iConfig.getParameter<double>("minCaloCompatibility");
00084 arbClean_ = iConfig.getParameter<bool>("runArbitrationCleaner");
00085
00086
00087 edm::ParameterSet parameters = iConfig.getParameter<edm::ParameterSet>("TrackAssociatorParameters");
00088 parameters_.loadParameters( parameters );
00089
00090
00091 edm::ParameterSet timingParameters = iConfig.getParameter<edm::ParameterSet>("TimingFillerParameters");
00092 theTimingFiller_ = new MuonTimingFiller(timingParameters);
00093
00094 if (fillCaloCompatibility_){
00095
00096 parameters = iConfig.getParameter<edm::ParameterSet>("MuonCaloCompatibility");
00097 muonCaloCompatibility_.configure( parameters );
00098 }
00099
00100 if (fillIsolation_){
00101
00102 edm::ParameterSet caloExtractorPSet = iConfig.getParameter<edm::ParameterSet>("CaloExtractorPSet");
00103 std::string caloExtractorName = caloExtractorPSet.getParameter<std::string>("ComponentName");
00104 muIsoExtractorCalo_ = IsoDepositExtractorFactory::get()->create( caloExtractorName, caloExtractorPSet);
00105
00106 edm::ParameterSet trackExtractorPSet = iConfig.getParameter<edm::ParameterSet>("TrackExtractorPSet");
00107 std::string trackExtractorName = trackExtractorPSet.getParameter<std::string>("ComponentName");
00108 muIsoExtractorTrack_ = IsoDepositExtractorFactory::get()->create( trackExtractorName, trackExtractorPSet);
00109
00110 edm::ParameterSet jetExtractorPSet = iConfig.getParameter<edm::ParameterSet>("JetExtractorPSet");
00111 std::string jetExtractorName = jetExtractorPSet.getParameter<std::string>("ComponentName");
00112 muIsoExtractorJet_ = IsoDepositExtractorFactory::get()->create( jetExtractorName, jetExtractorPSet);
00113 }
00114 if (fillIsolation_ && writeIsoDeposits_){
00115 trackDepositName_ = iConfig.getParameter<std::string>("trackDepositName");
00116 produces<reco::IsoDepositMap>(trackDepositName_);
00117 ecalDepositName_ = iConfig.getParameter<std::string>("ecalDepositName");
00118 produces<reco::IsoDepositMap>(ecalDepositName_);
00119 hcalDepositName_ = iConfig.getParameter<std::string>("hcalDepositName");
00120 produces<reco::IsoDepositMap>(hcalDepositName_);
00121 hoDepositName_ = iConfig.getParameter<std::string>("hoDepositName");
00122 produces<reco::IsoDepositMap>(hoDepositName_);
00123 jetDepositName_ = iConfig.getParameter<std::string>("jetDepositName");
00124 produces<reco::IsoDepositMap>(jetDepositName_);
00125 }
00126
00127 inputCollectionLabels_ = iConfig.getParameter<std::vector<edm::InputTag> >("inputCollectionLabels");
00128 inputCollectionTypes_ = iConfig.getParameter<std::vector<std::string> >("inputCollectionTypes");
00129 if (inputCollectionLabels_.size() != inputCollectionTypes_.size())
00130 throw cms::Exception("ConfigurationError") << "Number of input collection labels is different from number of types. " <<
00131 "For each collection label there should be exactly one collection type specified.";
00132 if (inputCollectionLabels_.size()>4 ||inputCollectionLabels_.empty())
00133 throw cms::Exception("ConfigurationError") << "Number of input collections should be from 1 to 4.";
00134
00135 debugWithTruthMatching_ = iConfig.getParameter<bool>("debugWithTruthMatching");
00136 if (debugWithTruthMatching_) edm::LogWarning("MuonIdentification")
00137 << "========================================================================\n"
00138 << "Debugging mode with truth matching is turned on!!! Make sure you understand what you are doing!\n"
00139 << "========================================================================\n";
00140 if (fillGlobalTrackQuality_){
00141 globalTrackQualityInputTag_ = iConfig.getParameter<edm::InputTag>("globalTrackQualityInputTag");
00142 }
00143
00144
00145 meshAlgo_ = new MuonMesh(iConfig.getParameter<edm::ParameterSet>("arbitrationCleanerOptions"));
00146 }
00147
00148
00149 MuonIdProducer::~MuonIdProducer()
00150 {
00151 if (muIsoExtractorCalo_) delete muIsoExtractorCalo_;
00152 if (muIsoExtractorTrack_) delete muIsoExtractorTrack_;
00153 if (muIsoExtractorJet_) delete muIsoExtractorJet_;
00154 if (theTimingFiller_) delete theTimingFiller_;
00155 if (meshAlgo_) delete meshAlgo_;
00156
00157 }
00158
00159 void MuonIdProducer::init(edm::Event& iEvent, const edm::EventSetup& iSetup)
00160 {
00161
00162
00163
00164 innerTrackCollectionHandle_.clear();
00165 outerTrackCollectionHandle_.clear();
00166 linkCollectionHandle_.clear();
00167 muonCollectionHandle_.clear();
00168
00169
00170 edm::ESHandle<Propagator> propagator;
00171 iSetup.get<TrackingComponentsRecord>().get("SteppingHelixPropagatorAny", propagator);
00172 trackAssociator_.setPropagator(propagator.product());
00173
00174
00175 for ( unsigned int i = 0; i < inputCollectionLabels_.size(); ++i ) {
00176 if ( inputCollectionTypes_[i] == "inner tracks" ) {
00177 iEvent.getByLabel(inputCollectionLabels_[i], innerTrackCollectionHandle_);
00178 if (! innerTrackCollectionHandle_.isValid())
00179 throw cms::Exception("FatalError") << "Failed to get input track collection with label: " << inputCollectionLabels_[i];
00180 LogTrace("MuonIdentification") << "Number of input inner tracks: " << innerTrackCollectionHandle_->size();
00181 continue;
00182 }
00183 if ( inputCollectionTypes_[i] == "outer tracks" ) {
00184 iEvent.getByLabel(inputCollectionLabels_[i], outerTrackCollectionHandle_);
00185 if (! outerTrackCollectionHandle_.isValid())
00186 throw cms::Exception("FatalError") << "Failed to get input track collection with label: " << inputCollectionLabels_[i];
00187 LogTrace("MuonIdentification") << "Number of input outer tracks: " << outerTrackCollectionHandle_->size();
00188 continue;
00189 }
00190 if ( inputCollectionTypes_[i] == "links" ) {
00191 iEvent.getByLabel(inputCollectionLabels_[i], linkCollectionHandle_);
00192 if (! linkCollectionHandle_.isValid())
00193 throw cms::Exception("FatalError") << "Failed to get input link collection with label: " << inputCollectionLabels_[i];
00194 LogTrace("MuonIdentification") << "Number of input links: " << linkCollectionHandle_->size();
00195 continue;
00196 }
00197 if ( inputCollectionTypes_[i] == "muons" ) {
00198 iEvent.getByLabel(inputCollectionLabels_[i], muonCollectionHandle_);
00199 if (! muonCollectionHandle_.isValid())
00200 throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputCollectionLabels_[i];
00201 LogTrace("MuonIdentification") << "Number of input muons: " << muonCollectionHandle_->size();
00202 continue;
00203 }
00204 throw cms::Exception("FatalError") << "Unknown input collection type: " << inputCollectionTypes_[i];
00205 }
00206 }
00207
00208 reco::Muon MuonIdProducer::makeMuon(edm::Event& iEvent, const edm::EventSetup& iSetup,
00209 const reco::TrackRef& track, MuonIdProducer::TrackType type)
00210 {
00211 LogTrace("MuonIdentification") << "Creating a muon from a track " << track.get()->pt() <<
00212 " Pt (GeV), eta: " << track.get()->eta();
00213 reco::Muon aMuon( makeMuon( *(track.get()) ) );
00214 switch (type) {
00215 case InnerTrack:
00216 aMuon.setInnerTrack( track );
00217 break;
00218 case OuterTrack:
00219 aMuon.setOuterTrack( track );
00220 break;
00221 case CombinedTrack:
00222 aMuon.setGlobalTrack( track );
00223 break;
00224 }
00225 return aMuon;
00226 }
00227
00228
00229 reco::CaloMuon MuonIdProducer::makeCaloMuon( const reco::Muon& muon )
00230 {
00231 reco::CaloMuon aMuon;
00232 aMuon.setInnerTrack( muon.innerTrack() );
00233
00234 if (muon.isEnergyValid()) aMuon.setCalEnergy( muon.calEnergy() );
00235
00236 if (fillCaloCompatibility_) aMuon.setCaloCompatibility( muonCaloCompatibility_.evaluate(muon) );
00237 return aMuon;
00238 }
00239
00240
00241 reco::Muon MuonIdProducer::makeMuon( const reco::MuonTrackLinks& links )
00242 {
00243 LogTrace("MuonIdentification") << "Creating a muon from a link to tracks object";
00244 reco::Muon aMuon;
00245 if ( links.trackerTrack()->pt() > ptThresholdToFillCandidateP4WithGlobalFit_ &&
00246 links.globalTrack()->pt() > ptThresholdToFillCandidateP4WithGlobalFit_ &&
00247 ( fabs(links.trackerTrack()->qoverp()-links.globalTrack()->qoverp()) <
00248 sigmaThresholdToFillCandidateP4WithGlobalFit_ * links.trackerTrack()->qoverpError() ) )
00249 aMuon = makeMuon( *(links.globalTrack()) );
00250 else
00251 aMuon = makeMuon( *(links.trackerTrack()) );
00252
00253 aMuon.setInnerTrack( links.trackerTrack() );
00254 aMuon.setOuterTrack( links.standAloneTrack() );
00255 aMuon.setGlobalTrack( links.globalTrack() );
00256 return aMuon;
00257 }
00258
00259 bool MuonIdProducer::isGoodTrack( const reco::Track& track )
00260 {
00261
00262 if (track.pt() < minPt_ || (track.p() < minP_ && track.p() < minPCaloMuon_)){
00263 LogTrace("MuonIdentification") << "Skipped low momentum track (Pt,P): " << track.pt() <<
00264 ", " << track.p() << " GeV";
00265 return false;
00266 }
00267
00268
00269 if ( fabs(track.eta()) > maxAbsEta_ ){
00270 LogTrace("MuonIdentification") << "Skipped track with large pseudo rapidity (Eta: " << track.eta() << " )";
00271 return false;
00272 }
00273 return true;
00274 }
00275
00276 unsigned int MuonIdProducer::chamberId( const DetId& id )
00277 {
00278 switch ( id.det() ) {
00279 case DetId::Muon:
00280 switch ( id.subdetId() ) {
00281 case MuonSubdetId::DT:
00282 {
00283 DTChamberId detId(id.rawId());
00284 return detId.rawId();
00285 }
00286 break;
00287 case MuonSubdetId::CSC:
00288 {
00289 CSCDetId detId(id.rawId());
00290 return detId.chamberId().rawId();
00291 }
00292 break;
00293 default:
00294 return 0;
00295 }
00296 default:
00297 return 0;
00298 }
00299 return 0;
00300 }
00301
00302
00303 int MuonIdProducer::overlap(const reco::Muon& muon, const reco::Track& track)
00304 {
00305 int numberOfCommonDetIds = 0;
00306 if ( ! muon.isMatchesValid() ||
00307 track.extra().isNull() ||
00308 track.extra()->recHits().isNull() ) return numberOfCommonDetIds;
00309 const std::vector<reco::MuonChamberMatch>& matches( muon.matches() );
00310 for ( std::vector<reco::MuonChamberMatch>::const_iterator match = matches.begin();
00311 match != matches.end(); ++match )
00312 {
00313 if ( match->segmentMatches.empty() ) continue;
00314 bool foundCommonDetId = false;
00315
00316 for ( TrackingRecHitRefVector::const_iterator hit = track.extra()->recHitsBegin();
00317 hit != track.extra()->recHitsEnd(); ++hit )
00318 {
00319
00320
00321
00322
00323 if ( chamberId(hit->get()->geographicalId()) == match->id.rawId() ) {
00324 foundCommonDetId = true;
00325 break;
00326 }
00327 }
00328 if ( foundCommonDetId ) {
00329 numberOfCommonDetIds++;
00330 break;
00331 }
00332 }
00333 return numberOfCommonDetIds;
00334 }
00335
00336 void MuonIdProducer::beginRun(edm::Run& iRun, const edm::EventSetup& iSetup)
00337 {
00338 edm::ESHandle<CSCGeometry> geomHandle;
00339 iSetup.get<MuonGeometryRecord>().get(geomHandle);
00340
00341 meshAlgo_->setCSCGeometry(geomHandle.product());
00342
00343 }
00344
00345 bool validateGlobalMuonPair( const reco::MuonTrackLinks& goodMuon,
00346 const reco::MuonTrackLinks& badMuon )
00347 {
00348 if ( std::min(goodMuon.globalTrack()->hitPattern().numberOfValidMuonHits(),
00349 badMuon.globalTrack()->hitPattern().numberOfValidMuonHits()) > 10 ){
00350 if ( goodMuon.globalTrack()->normalizedChi2() >
00351 badMuon.globalTrack()->normalizedChi2() )
00352 return false;
00353 else
00354 return true;
00355 }
00356 if ( goodMuon.globalTrack()->hitPattern().numberOfValidMuonHits() <
00357 badMuon.globalTrack()->hitPattern().numberOfValidMuonHits() ) return false;
00358 return true;
00359 }
00360
00361 void MuonIdProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00362 {
00363
00364
00365
00366 std::auto_ptr<reco::MuonCollection> outputMuons(new reco::MuonCollection);
00367 std::auto_ptr<reco::CaloMuonCollection> caloMuons( new reco::CaloMuonCollection );
00368
00369 init(iEvent, iSetup);
00370
00371 std::auto_ptr<reco::MuonTimeExtraMap> muonTimeMap(new reco::MuonTimeExtraMap());
00372 reco::MuonTimeExtraMap::Filler filler(*muonTimeMap);
00373 std::auto_ptr<reco::MuonTimeExtraMap> muonTimeMapDT(new reco::MuonTimeExtraMap());
00374 reco::MuonTimeExtraMap::Filler fillerDT(*muonTimeMapDT);
00375 std::auto_ptr<reco::MuonTimeExtraMap> muonTimeMapCSC(new reco::MuonTimeExtraMap());
00376 reco::MuonTimeExtraMap::Filler fillerCSC(*muonTimeMapCSC);
00377
00378 std::auto_ptr<reco::IsoDepositMap> trackDepMap(new reco::IsoDepositMap());
00379 reco::IsoDepositMap::Filler trackDepFiller(*trackDepMap);
00380 std::auto_ptr<reco::IsoDepositMap> ecalDepMap(new reco::IsoDepositMap());
00381 reco::IsoDepositMap::Filler ecalDepFiller(*ecalDepMap);
00382 std::auto_ptr<reco::IsoDepositMap> hcalDepMap(new reco::IsoDepositMap());
00383 reco::IsoDepositMap::Filler hcalDepFiller(*hcalDepMap);
00384 std::auto_ptr<reco::IsoDepositMap> hoDepMap(new reco::IsoDepositMap());
00385 reco::IsoDepositMap::Filler hoDepFiller(*hoDepMap);
00386 std::auto_ptr<reco::IsoDepositMap> jetDepMap(new reco::IsoDepositMap());
00387 reco::IsoDepositMap::Filler jetDepFiller(*jetDepMap);
00388
00389
00390
00391
00392 if ( muonCollectionHandle_.isValid() )
00393 for ( reco::MuonCollection::const_iterator muon = muonCollectionHandle_->begin();
00394 muon != muonCollectionHandle_->end(); ++muon )
00395 outputMuons->push_back(*muon);
00396
00397
00398 if ( linkCollectionHandle_.isValid() ){
00399 std::vector<bool> goodmuons(linkCollectionHandle_->size(),true);
00400 if ( goodmuons.size()>1 ){
00401
00402 for ( unsigned int i=0; i<linkCollectionHandle_->size()-1; ++i ){
00403 if (!checkLinks(&linkCollectionHandle_->at(i))) continue;
00404 for ( unsigned int j=i+1; j<linkCollectionHandle_->size(); ++j ){
00405 if (!checkLinks(&linkCollectionHandle_->at(j))) continue;
00406 if ( linkCollectionHandle_->at(i).trackerTrack().isNonnull() &&
00407 linkCollectionHandle_->at(i).trackerTrack() ==
00408 linkCollectionHandle_->at(j).trackerTrack() )
00409 {
00410
00411
00412
00413
00414 if ( validateGlobalMuonPair(linkCollectionHandle_->at(i),linkCollectionHandle_->at(j)) )
00415 goodmuons[j] = false;
00416 else
00417 goodmuons[i] = false;
00418 }
00419 }
00420 }
00421
00422 for ( unsigned int i=0; i<linkCollectionHandle_->size()-1; ++i ){
00423 if ( !goodmuons[i] ) continue;
00424 if (!checkLinks(&linkCollectionHandle_->at(i))) continue;
00425 for ( unsigned int j=i+1; j<linkCollectionHandle_->size(); ++j ){
00426 if ( !goodmuons[j] ) continue;
00427 if (!checkLinks(&linkCollectionHandle_->at(j))) continue;
00428 if ( linkCollectionHandle_->at(i).standAloneTrack().isNonnull() &&
00429 linkCollectionHandle_->at(i).standAloneTrack() ==
00430 linkCollectionHandle_->at(j).standAloneTrack() )
00431 {
00432 if ( validateGlobalMuonPair(linkCollectionHandle_->at(i),linkCollectionHandle_->at(j)) )
00433 goodmuons[j] = false;
00434 else
00435 goodmuons[i] = false;
00436 }
00437 }
00438 }
00439 }
00440
00441 for ( unsigned int i=0; i<linkCollectionHandle_->size(); ++i ){
00442 if ( !goodmuons[i] ) continue;
00443 const reco::MuonTrackLinks* links = &linkCollectionHandle_->at(i);
00444 if ( ! checkLinks(links)) continue;
00445
00446 bool newMuon = true;
00447 for ( reco::MuonCollection::const_iterator muon = outputMuons->begin();
00448 muon != outputMuons->end(); ++muon )
00449 if ( muon->track() == links->trackerTrack() &&
00450 muon->standAloneMuon() == links->standAloneTrack() &&
00451 muon->combinedMuon() == links->globalTrack() )
00452 newMuon = false;
00453 if ( newMuon ) {
00454 outputMuons->push_back( makeMuon( *links ) );
00455 outputMuons->back().setType(reco::Muon::GlobalMuon | reco::Muon::StandAloneMuon);
00456 }
00457 }
00458 }
00459
00460
00461 if ( innerTrackCollectionHandle_.isValid() ) {
00462 LogTrace("MuonIdentification") << "Creating tracker muons";
00463 for ( unsigned int i = 0; i < innerTrackCollectionHandle_->size(); ++i )
00464 {
00465 const reco::Track& track = innerTrackCollectionHandle_->at(i);
00466 if ( ! isGoodTrack( track ) ) continue;
00467 bool splitTrack = false;
00468 if ( track.extra().isAvailable() &&
00469 TrackDetectorAssociator::crossedIP( track ) ) splitTrack = true;
00470 std::vector<TrackDetectorAssociator::Direction> directions;
00471 if ( splitTrack ) {
00472 directions.push_back(TrackDetectorAssociator::InsideOut);
00473 directions.push_back(TrackDetectorAssociator::OutsideIn);
00474 } else {
00475 directions.push_back(TrackDetectorAssociator::Any);
00476 }
00477 for ( std::vector<TrackDetectorAssociator::Direction>::const_iterator direction = directions.begin();
00478 direction != directions.end(); ++direction )
00479 {
00480
00481
00482 reco::Muon trackerMuon( makeMuon(iEvent, iSetup, reco::TrackRef( innerTrackCollectionHandle_, i ), InnerTrack ) );
00483 trackerMuon.setType( reco::Muon::TrackerMuon );
00484 fillMuonId(iEvent, iSetup, trackerMuon, *direction);
00485
00486
00487 if ( debugWithTruthMatching_ ) {
00488
00489
00490 MuonIdTruthInfo::truthMatchMuon(iEvent, iSetup, trackerMuon);
00491 }
00492
00493
00494
00495
00496 bool newMuon = true;
00497 bool goodTrackerMuon = isGoodTrackerMuon( trackerMuon );
00498 for ( reco::MuonCollection::iterator muon = outputMuons->begin();
00499 muon != outputMuons->end(); ++muon )
00500 {
00501 if ( muon->innerTrack().get() == trackerMuon.innerTrack().get() &&
00502 cos(phiOfMuonIneteractionRegion(*muon) -
00503 phiOfMuonIneteractionRegion(trackerMuon)) > 0 )
00504 {
00505 newMuon = false;
00506 muon->setMatches( trackerMuon.matches() );
00507 if (trackerMuon.isTimeValid()) muon->setTime( trackerMuon.time() );
00508 if (trackerMuon.isEnergyValid()) muon->setCalEnergy( trackerMuon.calEnergy() );
00509 if (goodTrackerMuon) muon->setType( muon->type() | reco::Muon::TrackerMuon );
00510 LogTrace("MuonIdentification") << "Found a corresponding global muon. Set energy, matches and move on";
00511 break;
00512 }
00513 }
00514 if ( newMuon ) {
00515 if ( goodTrackerMuon ){
00516 outputMuons->push_back( trackerMuon );
00517 } else {
00518 LogTrace("MuonIdentification") << "track failed minimal number of muon matches requirement";
00519 const reco::CaloMuon& caloMuon = makeCaloMuon(trackerMuon);
00520 if ( ! caloMuon.isCaloCompatibilityValid() || caloMuon.caloCompatibility() < caloCut_ || caloMuon.p() < minPCaloMuon_) continue;
00521 caloMuons->push_back( caloMuon );
00522 }
00523 }
00524 }
00525 }
00526 }
00527
00528
00529 if ( outerTrackCollectionHandle_.isValid() ) {
00530 LogTrace("MuonIdentification") << "Looking for new muons among stand alone muon tracks";
00531 for ( unsigned int i = 0; i < outerTrackCollectionHandle_->size(); ++i )
00532 {
00533
00534 bool newMuon = true;
00535 for ( reco::MuonCollection::iterator muon = outputMuons->begin();
00536 muon != outputMuons->end(); ++muon )
00537 {
00538 if ( ! muon->standAloneMuon().isNull() ) {
00539
00540 if ( muon->standAloneMuon().get() == &(outerTrackCollectionHandle_->at(i)) ) {
00541 newMuon = false;
00542 break;
00543 }
00544 } else {
00545
00546
00547
00548
00549
00550
00551
00552 if ( overlap(*muon,outerTrackCollectionHandle_->at(i))>0 ) {
00553 LogTrace("MuonIdentification") << "Found associated tracker muon. Set a reference and move on";
00554 newMuon = false;
00555 muon->setOuterTrack( reco::TrackRef( outerTrackCollectionHandle_, i ) );
00556 muon->setType( muon->type() | reco::Muon::StandAloneMuon );
00557 break;
00558 }
00559 }
00560 }
00561 if ( newMuon ) {
00562 LogTrace("MuonIdentification") << "No associated stand alone track is found. Making a muon";
00563 outputMuons->push_back( makeMuon(iEvent, iSetup,
00564 reco::TrackRef( outerTrackCollectionHandle_, i ), OuterTrack ) );
00565 outputMuons->back().setType( reco::Muon::StandAloneMuon );
00566 }
00567 }
00568 }
00569
00570 LogTrace("MuonIdentification") << "Dress up muons if it's necessary";
00571
00572 int nMuons=outputMuons->size();
00573
00574 std::vector<reco::MuonTimeExtra> dtTimeColl(nMuons);
00575 std::vector<reco::MuonTimeExtra> cscTimeColl(nMuons);
00576 std::vector<reco::MuonTimeExtra> combinedTimeColl(nMuons);
00577 std::vector<reco::IsoDeposit> trackDepColl(nMuons);
00578 std::vector<reco::IsoDeposit> ecalDepColl(nMuons);
00579 std::vector<reco::IsoDeposit> hcalDepColl(nMuons);
00580 std::vector<reco::IsoDeposit> hoDepColl(nMuons);
00581 std::vector<reco::IsoDeposit> jetDepColl(nMuons);
00582
00583
00584 unsigned int i=0;
00585 for ( reco::MuonCollection::iterator muon = outputMuons->begin(); muon != outputMuons->end(); ++muon )
00586 {
00587
00588
00589 if ( ( fillMatching_ && ! muon->isMatchesValid() ) ||
00590 ( fillEnergy_ && !muon->isEnergyValid() ) )
00591 {
00592
00593
00594 if ( muon->isStandAloneMuon() ) {
00595 if ( cos(phiOfMuonIneteractionRegion(*muon) - muon->phi()) > 0 )
00596 fillMuonId(iEvent, iSetup, *muon, TrackDetectorAssociator::InsideOut);
00597 else
00598 fillMuonId(iEvent, iSetup, *muon, TrackDetectorAssociator::OutsideIn);
00599 } else {
00600 LogTrace("MuonIdentification") << "THIS SHOULD NEVER HAPPEN";
00601 fillMuonId(iEvent, iSetup, *muon);
00602 }
00603 }
00604
00605 if (fillGlobalTrackQuality_){
00606
00607 fillGlbQuality(iEvent, iSetup, *muon);
00608 }
00609 LogDebug("MuonIdentification");
00610
00611
00612 if ( fillCaloCompatibility_ ) muon->setCaloCompatibility( muonCaloCompatibility_.evaluate(*muon) );
00613
00614
00615
00616 if ( fillIsolation_ ) fillMuonIsolation(iEvent, iSetup, *muon,
00617 trackDepColl[i], ecalDepColl[i], hcalDepColl[i], hoDepColl[i], jetDepColl[i]);
00618
00619
00620
00621 reco::MuonTime muonTime;
00622 reco::MuonTimeExtra dtTime;
00623 reco::MuonTimeExtra cscTime;
00624 reco::MuonTimeExtra combinedTime;
00625
00626 theTimingFiller_->fillTiming(*muon, dtTime, cscTime, combinedTime, iEvent, iSetup);
00627
00628 muonTime.nDof=combinedTime.nDof();
00629 muonTime.timeAtIpInOut=combinedTime.timeAtIpInOut();
00630 muonTime.timeAtIpInOutErr=combinedTime.timeAtIpInOutErr();
00631 muonTime.timeAtIpOutIn=combinedTime.timeAtIpOutIn();
00632 muonTime.timeAtIpOutInErr=combinedTime.timeAtIpOutInErr();
00633
00634 muon->setTime( muonTime);
00635 dtTimeColl[i] = dtTime;
00636 cscTimeColl[i] = cscTime;
00637 combinedTimeColl[i] = combinedTime;
00638
00639 i++;
00640
00641 }
00642
00643 LogTrace("MuonIdentification") << "number of muons produced: " << outputMuons->size();
00644
00645 if ( fillMatching_ ) fillArbitrationInfo( outputMuons.get() );
00646
00647 edm::OrphanHandle<reco::MuonCollection> muonHandle = iEvent.put(outputMuons);
00648
00649 filler.insert(muonHandle, combinedTimeColl.begin(), combinedTimeColl.end());
00650 filler.fill();
00651 fillerDT.insert(muonHandle, dtTimeColl.begin(), dtTimeColl.end());
00652 fillerDT.fill();
00653 fillerCSC.insert(muonHandle, cscTimeColl.begin(), cscTimeColl.end());
00654 fillerCSC.fill();
00655
00656 iEvent.put(muonTimeMap,"combined");
00657 iEvent.put(muonTimeMapDT,"dt");
00658 iEvent.put(muonTimeMapCSC,"csc");
00659
00660 if (writeIsoDeposits_ && fillIsolation_){
00661 trackDepFiller.insert(muonHandle, trackDepColl.begin(), trackDepColl.end());
00662 trackDepFiller.fill();
00663 iEvent.put(trackDepMap, trackDepositName_);
00664 ecalDepFiller.insert(muonHandle, ecalDepColl.begin(), ecalDepColl.end());
00665 ecalDepFiller.fill();
00666 iEvent.put(ecalDepMap, ecalDepositName_);
00667 hcalDepFiller.insert(muonHandle, hcalDepColl.begin(), hcalDepColl.end());
00668 hcalDepFiller.fill();
00669 iEvent.put(hcalDepMap, hcalDepositName_);
00670 hoDepFiller.insert(muonHandle, hoDepColl.begin(), hoDepColl.end());
00671 hoDepFiller.fill();
00672 iEvent.put(hoDepMap, hoDepositName_);
00673 jetDepFiller.insert(muonHandle, jetDepColl.begin(), jetDepColl.end());
00674 jetDepFiller.fill();
00675 iEvent.put(jetDepMap, jetDepositName_);
00676 }
00677
00678 iEvent.put(caloMuons);
00679 }
00680
00681
00682 bool MuonIdProducer::isGoodTrackerMuon( const reco::Muon& muon )
00683 {
00684 if(muon.track()->pt() < minPt_ || muon.track()->p() < minP_) return false;
00685 if ( addExtraSoftMuons_ &&
00686 muon.pt()<5 && fabs(muon.eta())<1.5 &&
00687 muon.numberOfMatches( reco::Muon::NoArbitration ) >= 1 ) return true;
00688 return ( muon.numberOfMatches( reco::Muon::NoArbitration ) >= minNumberOfMatches_ );
00689 }
00690
00691 void MuonIdProducer::fillMuonId(edm::Event& iEvent, const edm::EventSetup& iSetup,
00692 reco::Muon& aMuon,
00693 TrackDetectorAssociator::Direction direction)
00694 {
00695
00696 const reco::Track* track = 0;
00697 if ( ! aMuon.track().isNull() )
00698 track = aMuon.track().get();
00699 else
00700 {
00701 if ( ! aMuon.standAloneMuon().isNull() )
00702 track = aMuon.standAloneMuon().get();
00703 else
00704 throw cms::Exception("FatalError") << "Failed to fill muon id information for a muon with undefined references to tracks";
00705 }
00706
00707 TrackDetMatchInfo info = trackAssociator_.associate(iEvent, iSetup, *track, parameters_, direction);
00708
00709 if ( fillEnergy_ ) {
00710 reco::MuonEnergy muonEnergy;
00711 muonEnergy.em = info.crossedEnergy(TrackDetMatchInfo::EcalRecHits);
00712 muonEnergy.had = info.crossedEnergy(TrackDetMatchInfo::HcalRecHits);
00713 muonEnergy.ho = info.crossedEnergy(TrackDetMatchInfo::HORecHits);
00714 muonEnergy.tower = info.crossedEnergy(TrackDetMatchInfo::TowerTotal);
00715 muonEnergy.emS9 = info.nXnEnergy(TrackDetMatchInfo::EcalRecHits,1);
00716 muonEnergy.emS25 = info.nXnEnergy(TrackDetMatchInfo::EcalRecHits,2);
00717 muonEnergy.hadS9 = info.nXnEnergy(TrackDetMatchInfo::HcalRecHits,1);
00718 muonEnergy.hoS9 = info.nXnEnergy(TrackDetMatchInfo::HORecHits,1);
00719 muonEnergy.towerS9 = info.nXnEnergy(TrackDetMatchInfo::TowerTotal,1);
00720 muonEnergy.ecal_position = info.trkGlobPosAtEcal;
00721 muonEnergy.hcal_position = info.trkGlobPosAtHcal;
00722 if (! info.crossedEcalIds.empty() ) muonEnergy.ecal_id = info.crossedEcalIds.front();
00723 if (! info.crossedHcalIds.empty() ) muonEnergy.hcal_id = info.crossedHcalIds.front();
00724
00725 DetId emMaxId = info.findMaxDeposition(TrackDetMatchInfo::EcalRecHits,2);
00726 for(std::vector<const EcalRecHit*>::const_iterator hit=info.ecalRecHits.begin();
00727 hit!=info.ecalRecHits.end(); ++hit) {
00728 if ((*hit)->id() != emMaxId) continue;
00729 muonEnergy.emMax = (*hit)->energy();
00730 muonEnergy.ecal_time = (*hit)->time();
00731 }
00732 DetId hadMaxId = info.findMaxDeposition(TrackDetMatchInfo::HcalRecHits,1);
00733 for(std::vector<const HBHERecHit*>::const_iterator hit=info.hcalRecHits.begin();
00734 hit!=info.hcalRecHits.end(); ++hit) {
00735 if ((*hit)->id() != hadMaxId) continue;
00736 muonEnergy.hadMax = (*hit)->energy();
00737 muonEnergy.hcal_time = (*hit)->time();
00738 }
00739 aMuon.setCalEnergy( muonEnergy );
00740 }
00741 if ( ! fillMatching_ && ! aMuon.isTrackerMuon() ) return;
00742
00743
00744 std::vector<reco::MuonChamberMatch> muonChamberMatches;
00745 unsigned int nubmerOfMatchesAccordingToTrackAssociator = 0;
00746 for( std::vector<TAMuonChamberMatch>::const_iterator chamber=info.chambers.begin();
00747 chamber!=info.chambers.end(); chamber++ )
00748 {
00749 reco::MuonChamberMatch matchedChamber;
00750
00751 LocalError localError = chamber->tState.localError().positionError();
00752 matchedChamber.x = chamber->tState.localPosition().x();
00753 matchedChamber.y = chamber->tState.localPosition().y();
00754 matchedChamber.xErr = sqrt( localError.xx() );
00755 matchedChamber.yErr = sqrt( localError.yy() );
00756
00757 matchedChamber.dXdZ = chamber->tState.localDirection().z()!=0?chamber->tState.localDirection().x()/chamber->tState.localDirection().z():9999;
00758 matchedChamber.dYdZ = chamber->tState.localDirection().z()!=0?chamber->tState.localDirection().y()/chamber->tState.localDirection().z():9999;
00759
00760 AlgebraicSymMatrix55 trajectoryCovMatrix = chamber->tState.localError().matrix();
00761 matchedChamber.dXdZErr = trajectoryCovMatrix(1,1)>0?sqrt(trajectoryCovMatrix(1,1)):0;
00762 matchedChamber.dYdZErr = trajectoryCovMatrix(2,2)>0?sqrt(trajectoryCovMatrix(2,2)):0;
00763
00764 matchedChamber.edgeX = chamber->localDistanceX;
00765 matchedChamber.edgeY = chamber->localDistanceY;
00766
00767 matchedChamber.id = chamber->id;
00768 if ( ! chamber->segments.empty() ) ++nubmerOfMatchesAccordingToTrackAssociator;
00769
00770
00771 for( std::vector<TAMuonSegmentMatch>::const_iterator segment = chamber->segments.begin();
00772 segment != chamber->segments.end(); segment++ )
00773 {
00774 reco::MuonSegmentMatch matchedSegment;
00775 matchedSegment.x = segment->segmentLocalPosition.x();
00776 matchedSegment.y = segment->segmentLocalPosition.y();
00777 matchedSegment.dXdZ = segment->segmentLocalDirection.z()?segment->segmentLocalDirection.x()/segment->segmentLocalDirection.z():0;
00778 matchedSegment.dYdZ = segment->segmentLocalDirection.z()?segment->segmentLocalDirection.y()/segment->segmentLocalDirection.z():0;
00779 matchedSegment.xErr = segment->segmentLocalErrorXX>0?sqrt(segment->segmentLocalErrorXX):0;
00780 matchedSegment.yErr = segment->segmentLocalErrorYY>0?sqrt(segment->segmentLocalErrorYY):0;
00781 matchedSegment.dXdZErr = segment->segmentLocalErrorDxDz>0?sqrt(segment->segmentLocalErrorDxDz):0;
00782 matchedSegment.dYdZErr = segment->segmentLocalErrorDyDz>0?sqrt(segment->segmentLocalErrorDyDz):0;
00783 matchedSegment.t0 = segment->t0;
00784 matchedSegment.mask = 0;
00785 matchedSegment.dtSegmentRef = segment->dtSegmentRef;
00786 matchedSegment.cscSegmentRef = segment->cscSegmentRef;
00787 matchedSegment.hasZed_ = segment->hasZed;
00788 matchedSegment.hasPhi_ = segment->hasPhi;
00789
00790 bool matchedX = false;
00791 bool matchedY = false;
00792 LogTrace("MuonIdentification") << " matching local x, segment x: " << matchedSegment.x <<
00793 ", chamber x: " << matchedChamber.x << ", max: " << maxAbsDx_;
00794 LogTrace("MuonIdentification") << " matching local y, segment y: " << matchedSegment.y <<
00795 ", chamber y: " << matchedChamber.y << ", max: " << maxAbsDy_;
00796 if (matchedSegment.xErr>0 && matchedChamber.xErr>0 )
00797 LogTrace("MuonIdentification") << " xpull: " <<
00798 fabs(matchedSegment.x - matchedChamber.x)/sqrt(pow(matchedSegment.xErr,2) + pow(matchedChamber.xErr,2));
00799 if (matchedSegment.yErr>0 && matchedChamber.yErr>0 )
00800 LogTrace("MuonIdentification") << " ypull: " <<
00801 fabs(matchedSegment.y - matchedChamber.y)/sqrt(pow(matchedSegment.yErr,2) + pow(matchedChamber.yErr,2));
00802
00803 if (fabs(matchedSegment.x - matchedChamber.x) < maxAbsDx_) matchedX = true;
00804 if (fabs(matchedSegment.y - matchedChamber.y) < maxAbsDy_) matchedY = true;
00805 if (matchedSegment.xErr>0 && matchedChamber.xErr>0 &&
00806 fabs(matchedSegment.x - matchedChamber.x)/sqrt(pow(matchedSegment.xErr,2) + pow(matchedChamber.xErr,2)) < maxAbsPullX_) matchedX = true;
00807 if (matchedSegment.yErr>0 && matchedChamber.yErr>0 &&
00808 fabs(matchedSegment.y - matchedChamber.y)/sqrt(pow(matchedSegment.yErr,2) + pow(matchedChamber.yErr,2)) < maxAbsPullY_) matchedY = true;
00809 if (matchedX && matchedY) matchedChamber.segmentMatches.push_back(matchedSegment);
00810 }
00811 muonChamberMatches.push_back(matchedChamber);
00812 }
00813 aMuon.setMatches(muonChamberMatches);
00814
00815 LogTrace("MuonIdentification") << "number of muon chambers: " << aMuon.matches().size() << "\n"
00816 << "number of chambers with segments according to the associator requirements: " <<
00817 nubmerOfMatchesAccordingToTrackAssociator;
00818 LogTrace("MuonIdentification") << "number of segment matches with the producer requirements: " <<
00819 aMuon.numberOfMatches( reco::Muon::NoArbitration );
00820
00821
00822 }
00823
00824 void MuonIdProducer::fillArbitrationInfo( reco::MuonCollection* pOutputMuons )
00825 {
00826
00827
00828
00829 std::vector<std::pair<reco::MuonChamberMatch*,reco::MuonSegmentMatch*> > chamberPairs;
00830 std::vector<std::pair<reco::MuonChamberMatch*,reco::MuonSegmentMatch*> > stationPairs;
00831 std::vector<std::pair<reco::MuonChamberMatch*,reco::MuonSegmentMatch*> > arbitrationPairs;
00832
00833
00834 for( unsigned int muonIndex1 = 0; muonIndex1 < pOutputMuons->size(); ++muonIndex1 )
00835 {
00836
00837 for( std::vector<reco::MuonChamberMatch>::iterator chamberIter1 = pOutputMuons->at(muonIndex1).matches().begin();
00838 chamberIter1 != pOutputMuons->at(muonIndex1).matches().end(); ++chamberIter1 )
00839 {
00840 if(chamberIter1->segmentMatches.empty()) continue;
00841 chamberPairs.clear();
00842
00843
00844 for( std::vector<reco::MuonSegmentMatch>::iterator segmentIter1 = chamberIter1->segmentMatches.begin();
00845 segmentIter1 != chamberIter1->segmentMatches.end(); ++segmentIter1 )
00846 {
00847 chamberPairs.push_back(std::make_pair(&(*chamberIter1), &(*segmentIter1)));
00848 if(!segmentIter1->isMask())
00849 {
00850 arbitrationPairs.clear();
00851 arbitrationPairs.push_back(std::make_pair(&(*chamberIter1), &(*segmentIter1)));
00852
00853
00854
00855
00856
00857 if (pOutputMuons->at(muonIndex1).isTrackerMuon()) {
00858
00859 for( unsigned int muonIndex2 = muonIndex1+1; muonIndex2 < pOutputMuons->size(); ++muonIndex2 )
00860 {
00861
00862 if (! pOutputMuons->at(muonIndex2).isTrackerMuon()) continue;
00863
00864 for( std::vector<reco::MuonChamberMatch>::iterator chamberIter2 = pOutputMuons->at(muonIndex2).matches().begin();
00865 chamberIter2 != pOutputMuons->at(muonIndex2).matches().end(); ++chamberIter2 )
00866 {
00867
00868 for( std::vector<reco::MuonSegmentMatch>::iterator segmentIter2 = chamberIter2->segmentMatches.begin();
00869 segmentIter2 != chamberIter2->segmentMatches.end(); ++segmentIter2 )
00870 {
00871 if(segmentIter2->isMask()) continue;
00872 if(fabs(segmentIter2->x - segmentIter1->x ) < 1E-3 &&
00873 fabs(segmentIter2->y - segmentIter1->y ) < 1E-3 &&
00874 fabs(segmentIter2->dXdZ - segmentIter1->dXdZ ) < 1E-3 &&
00875 fabs(segmentIter2->dYdZ - segmentIter1->dYdZ ) < 1E-3 &&
00876 fabs(segmentIter2->xErr - segmentIter1->xErr ) < 1E-3 &&
00877 fabs(segmentIter2->yErr - segmentIter1->yErr ) < 1E-3 &&
00878 fabs(segmentIter2->dXdZErr - segmentIter1->dXdZErr) < 1E-3 &&
00879 fabs(segmentIter2->dYdZErr - segmentIter1->dYdZErr) < 1E-3)
00880 arbitrationPairs.push_back(std::make_pair(&(*chamberIter2), &(*segmentIter2)));
00881 }
00882 }
00883 }
00884 }
00885
00886
00887 if(arbitrationPairs.empty()) continue;
00888 if(arbitrationPairs.size()==1) {
00889 arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDRSlope);
00890 arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDXSlope);
00891 arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDR);
00892 arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDX);
00893 arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::Arbitrated);
00894 } else {
00895 sort(arbitrationPairs.begin(), arbitrationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BelongsToTrackByDRSlope));
00896 arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDRSlope);
00897 sort(arbitrationPairs.begin(), arbitrationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BelongsToTrackByDXSlope));
00898 arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDXSlope);
00899 sort(arbitrationPairs.begin(), arbitrationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BelongsToTrackByDR));
00900 arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDR);
00901 sort(arbitrationPairs.begin(), arbitrationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BelongsToTrackByDX));
00902 arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDX);
00903 for( unsigned int it = 0; it < arbitrationPairs.size(); ++it )
00904 arbitrationPairs.at(it).second->setMask(reco::MuonSegmentMatch::Arbitrated);
00905 }
00906 }
00907
00908
00909 if( chamberIter1->id.subdetId() == MuonSubdetId::CSC && arbClean_ ) {
00910 CSCDetId cscid(chamberIter1->id);
00911 if(cscid.ring() == 4)
00912 for( std::vector<reco::MuonSegmentMatch>::iterator segmentIter2 = chamberIter1->segmentMatches.begin();
00913 segmentIter2 != chamberIter1->segmentMatches.end(); ++segmentIter2 ) {
00914 if( segmentIter1->cscSegmentRef.isNonnull() && segmentIter2->cscSegmentRef.isNonnull() )
00915 if( meshAlgo_->isDuplicateOf(segmentIter1->cscSegmentRef,segmentIter2->cscSegmentRef) &&
00916 (segmentIter2->mask & 0x1e0000) &&
00917 (segmentIter1->mask & 0x1e0000) )
00918 segmentIter2->setMask(reco::MuonSegmentMatch::BelongsToTrackByME1aClean);
00919
00920 }
00921 }
00922
00923 }
00924
00925
00926 if(chamberPairs.empty()) continue;
00927 if(chamberPairs.size()==1) {
00928 chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDRSlope);
00929 chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDXSlope);
00930 chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDR);
00931 chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDX);
00932 } else {
00933 sort(chamberPairs.begin(), chamberPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInChamberByDRSlope));
00934 chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDRSlope);
00935 sort(chamberPairs.begin(), chamberPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInChamberByDXSlope));
00936 chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDXSlope);
00937 sort(chamberPairs.begin(), chamberPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInChamberByDR));
00938 chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDR);
00939 sort(chamberPairs.begin(), chamberPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInChamberByDX));
00940 chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDX);
00941 }
00942 }
00943
00944
00945 for( int stationIndex = 1; stationIndex < 5; ++stationIndex )
00946 for( int detectorIndex = 1; detectorIndex < 4; ++detectorIndex )
00947 {
00948 stationPairs.clear();
00949
00950
00951 for( std::vector<reco::MuonChamberMatch>::iterator chamberIter = pOutputMuons->at(muonIndex1).matches().begin();
00952 chamberIter != pOutputMuons->at(muonIndex1).matches().end(); ++chamberIter )
00953 {
00954 if(!(chamberIter->station()==stationIndex && chamberIter->detector()==detectorIndex)) continue;
00955 if(chamberIter->segmentMatches.empty()) continue;
00956
00957 for( std::vector<reco::MuonSegmentMatch>::iterator segmentIter = chamberIter->segmentMatches.begin();
00958 segmentIter != chamberIter->segmentMatches.end(); ++segmentIter )
00959 stationPairs.push_back(std::make_pair(&(*chamberIter), &(*segmentIter)));
00960 }
00961
00962 if(stationPairs.empty()) continue;
00963 if(stationPairs.size()==1) {
00964 stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDRSlope);
00965 stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDXSlope);
00966 stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDR);
00967 stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDX);
00968 } else {
00969 sort(stationPairs.begin(), stationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInStationByDRSlope));
00970 stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDRSlope);
00971 sort(stationPairs.begin(), stationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInStationByDXSlope));
00972 stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDXSlope);
00973 sort(stationPairs.begin(), stationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInStationByDR));
00974 stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDR);
00975 sort(stationPairs.begin(), stationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInStationByDX));
00976 stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDX);
00977 }
00978 }
00979
00980 }
00981
00982 if(arbClean_) {
00983
00984 meshAlgo_->clearMesh();
00985 meshAlgo_->runMesh(pOutputMuons);
00986 }
00987 }
00988
00989 void MuonIdProducer::fillMuonIsolation(edm::Event& iEvent, const edm::EventSetup& iSetup, reco::Muon& aMuon,
00990 reco::IsoDeposit& trackDep, reco::IsoDeposit& ecalDep, reco::IsoDeposit& hcalDep, reco::IsoDeposit& hoDep,
00991 reco::IsoDeposit& jetDep)
00992 {
00993 reco::MuonIsolation isoR03, isoR05;
00994 const reco::Track* track = 0;
00995 if ( ! aMuon.track().isNull() )
00996 track = aMuon.track().get();
00997 else
00998 {
00999 if ( ! aMuon.standAloneMuon().isNull() )
01000 track = aMuon.standAloneMuon().get();
01001 else
01002 throw cms::Exception("FatalError") << "Failed to compute muon isolation information for a muon with undefined references to tracks";
01003 }
01004
01005
01006 reco::IsoDeposit depTrk = muIsoExtractorTrack_->deposit(iEvent, iSetup, *track );
01007 std::vector<reco::IsoDeposit> caloDeps = muIsoExtractorCalo_->deposits(iEvent, iSetup, *track);
01008 reco::IsoDeposit depJet = muIsoExtractorJet_->deposit(iEvent, iSetup, *track );
01009
01010 if(caloDeps.size()!=3) {
01011 LogTrace("MuonIdentification") << "Failed to fill vector of calorimeter isolation deposits!";
01012 return;
01013 }
01014
01015 reco::IsoDeposit depEcal = caloDeps.at(0);
01016 reco::IsoDeposit depHcal = caloDeps.at(1);
01017 reco::IsoDeposit depHo = caloDeps.at(2);
01018
01019 trackDep = depTrk;
01020 ecalDep = depEcal;
01021 hcalDep = depHcal;
01022 hoDep = depHo;
01023 jetDep = depJet;
01024
01025 isoR03.sumPt = depTrk.depositWithin(0.3);
01026 isoR03.emEt = depEcal.depositWithin(0.3);
01027 isoR03.hadEt = depHcal.depositWithin(0.3);
01028 isoR03.hoEt = depHo.depositWithin(0.3);
01029 isoR03.nTracks = depTrk.depositAndCountWithin(0.3).second;
01030 isoR03.nJets = depJet.depositAndCountWithin(0.3).second;
01031 isoR03.trackerVetoPt = depTrk.candEnergy();
01032 isoR03.emVetoEt = depEcal.candEnergy();
01033 isoR03.hadVetoEt = depHcal.candEnergy();
01034 isoR03.hoVetoEt = depHo.candEnergy();
01035
01036 isoR05.sumPt = depTrk.depositWithin(0.5);
01037 isoR05.emEt = depEcal.depositWithin(0.5);
01038 isoR05.hadEt = depHcal.depositWithin(0.5);
01039 isoR05.hoEt = depHo.depositWithin(0.5);
01040 isoR05.nTracks = depTrk.depositAndCountWithin(0.5).second;
01041 isoR05.nJets = depJet.depositAndCountWithin(0.5).second;
01042 isoR05.trackerVetoPt = depTrk.candEnergy();
01043 isoR05.emVetoEt = depEcal.candEnergy();
01044 isoR05.hadVetoEt = depHcal.candEnergy();
01045 isoR05.hoVetoEt = depHo.candEnergy();
01046
01047
01048 aMuon.setIsolation(isoR03, isoR05);
01049
01050 }
01051
01052 reco::Muon MuonIdProducer::makeMuon( const reco::Track& track )
01053 {
01054
01055 double energy = sqrt(track.p() * track.p() + 0.011163691);
01056 math::XYZTLorentzVector p4(track.px(),
01057 track.py(),
01058 track.pz(),
01059 energy);
01060 return reco::Muon( track.charge(), p4, track.vertex() );
01061 }
01062
01063 double MuonIdProducer::sectorPhi( const DetId& id )
01064 {
01065 double phi = 0;
01066 if( id.subdetId() == MuonSubdetId::DT ) {
01067 DTChamberId muonId(id.rawId());
01068 if ( muonId.sector() <= 12 )
01069 phi = (muonId.sector()-1)/6.*M_PI;
01070 if ( muonId.sector() == 13 ) phi = 3/6.*M_PI;
01071 if ( muonId.sector() == 14 ) phi = 9/6.*M_PI;
01072 }
01073 if( id.subdetId() == MuonSubdetId::CSC ) {
01074 CSCDetId muonId(id.rawId());
01075 phi = M_PI/4+(muonId.triggerSector()-1)/3.*M_PI;
01076 }
01077 if ( phi > M_PI ) phi -= 2*M_PI;
01078 return phi;
01079 }
01080
01081 double MuonIdProducer::phiOfMuonIneteractionRegion( const reco::Muon& muon ) const
01082 {
01083 if ( muon.isStandAloneMuon() ) return muon.standAloneMuon()->innerPosition().phi();
01084
01085 if ( muon.matches().empty() ){
01086 if ( muon.innerTrack().isAvailable() &&
01087 muon.innerTrack()->extra().isAvailable() )
01088 return muon.innerTrack()->outerPosition().phi();
01089 else
01090 return muon.phi();
01091 }
01092 return sectorPhi(muon.matches().at(0).id);
01093 }
01094
01095 void MuonIdProducer::fillGlbQuality(edm::Event& iEvent, const edm::EventSetup& iSetup, reco::Muon& aMuon)
01096 {
01097 edm::Handle<edm::ValueMap<reco::MuonQuality> > glbQualH;
01098 iEvent.getByLabel(globalTrackQualityInputTag_, glbQualH);
01099
01100 if(aMuon.isGlobalMuon() && !glbQualH.failedToGet()) {
01101 aMuon.setCombinedQuality((*glbQualH)[aMuon.combinedMuon()]);
01102 }
01103
01104 LogDebug("MuonIdentification") << "tkChiVal " << aMuon.combinedQuality().trkRelChi2;
01105
01106 }
01107
01108
01109 bool MuonIdProducer::checkLinks(const reco::MuonTrackLinks* links) const {
01110 bool trackBAD = links->trackerTrack().isNull();
01111 bool staBAD = links->standAloneTrack().isNull();
01112 bool glbBAD = links->globalTrack().isNull();
01113 if (trackBAD || staBAD || glbBAD )
01114 {
01115 edm::LogWarning("muonIDbadLinks") << "Global muon links to constituent tracks are invalid: trkBad "
01116 <<trackBAD <<" standaloneBad "<<staBAD<<" globalBad "<<glbBAD
01117 <<". There should be no such object. Muon is skipped.";
01118 return false;
01119 }
01120 return true;
01121 }