00001 #include "RecoMuon/MuonIdentification/interface/MuonMesh.h"
00002 #include "DataFormats/CSCRecHit/interface/CSCSegmentCollection.h"
00003 #include "DataFormats/DTRecHit/interface/DTRecSegment4DCollection.h"
00004 #include "Geometry/CSCGeometry/interface/CSCGeometry.h"
00005
00006 #include <utility>
00007 #include <algorithm>
00008
00009 MuonMesh::MuonMesh(const edm::ParameterSet& parm) : doME1a(parm.getParameter<bool>("ME1a")),
00010 doOverlaps(parm.getParameter<bool>("Overlap")),
00011 doClustering(parm.getParameter<bool>("Clustering")),
00012 OverlapDPhi(parm.getParameter<double>("OverlapDPhi")),
00013 OverlapDTheta(parm.getParameter<double>("OverlapDTheta")),
00014 ClusterDPhi(parm.getParameter<double>("ClusterDPhi")),
00015 ClusterDTheta(parm.getParameter<double>("ClusterDTheta")) {
00016 }
00017
00018 void MuonMesh::fillMesh(std::vector<reco::Muon>* inputMuons) {
00019
00020 for(std::vector<reco::Muon>::iterator muonIter1 = inputMuons->begin();
00021 muonIter1 != inputMuons->end();
00022 ++muonIter1) {
00023 if(muonIter1->isTrackerMuon()){
00024
00025 mesh_[&*muonIter1];
00026 for(std::vector<reco::Muon>::iterator muonIter2 = inputMuons->begin();
00027 muonIter2 != inputMuons->end();
00028 ++muonIter2) {
00029 if(muonIter2->isTrackerMuon()) {
00030 if(muonIter2 != muonIter1) {
00031
00032
00033 for(std::vector<reco::MuonChamberMatch>::iterator chamberIter1 = muonIter1->matches().begin();
00034 chamberIter1 != muonIter1->matches().end();
00035 ++chamberIter1) {
00036 for(std::vector<reco::MuonSegmentMatch>::iterator segmentIter1 = chamberIter1->segmentMatches.begin();
00037 segmentIter1 != chamberIter1->segmentMatches.end();
00038 ++segmentIter1) {
00039 for(std::vector<reco::MuonChamberMatch>::iterator chamberIter2 = muonIter2->matches().begin();
00040 chamberIter2 != muonIter2->matches().end();
00041 ++chamberIter2) {
00042 for(std::vector<reco::MuonSegmentMatch>::iterator segmentIter2 = chamberIter2->segmentMatches.begin();
00043 segmentIter2 != chamberIter2->segmentMatches.end();
00044 ++segmentIter2) {
00045
00046
00047
00048
00049 bool addsegment(false);
00050
00051 if( segmentIter1->cscSegmentRef.isNonnull() && segmentIter2->cscSegmentRef.isNonnull() ) {
00052
00053 if( doME1a &&
00054 isDuplicateOf(segmentIter1->cscSegmentRef,segmentIter2->cscSegmentRef) &&
00055 CSCDetId(chamberIter1->id).ring() == 4 && CSCDetId(chamberIter2->id).ring() == 4 &&
00056 chamberIter1->id == chamberIter2->id ) {
00057 addsegment = true;
00058
00059 }
00060
00061 if( doOverlaps &&
00062 isDuplicateOf(std::make_pair(CSCDetId(chamberIter1->id),segmentIter1->cscSegmentRef),
00063 std::make_pair(CSCDetId(chamberIter2->id),segmentIter2->cscSegmentRef)) ) {
00064 addsegment = true;
00065
00066 }
00067
00068 if( doClustering &&
00069 isClusteredWith(std::make_pair(CSCDetId(chamberIter1->id),segmentIter1->cscSegmentRef),
00070 std::make_pair(CSCDetId(chamberIter2->id),segmentIter2->cscSegmentRef)) ) {
00071 addsegment = true;
00072
00073 }
00074
00075 }
00076
00077 if(addsegment) {
00078
00079 if(find(mesh_[&*muonIter1].begin(),
00080 mesh_[&*muonIter1].end(),
00081 std::make_pair(&*muonIter2,
00082 std::make_pair(&*chamberIter2,
00083 &*segmentIter2)
00084 )
00085 ) == mesh_[&*muonIter1].end()) {
00086 mesh_[&*muonIter1].push_back(std::make_pair(&*muonIter2,
00087 std::make_pair(&*chamberIter2,
00088 &*segmentIter2)
00089 )
00090 );
00091 }
00092 }
00093
00094 }
00095 }
00096 }
00097 }
00098
00099 }
00100 }
00101 }
00102
00103 }
00104 }
00105
00106
00107
00108
00109 if(mesh_.size() == 1) {
00110 for(std::vector<reco::MuonChamberMatch>::iterator chamberIter1 = mesh_.begin()->first->matches().begin();
00111 chamberIter1 != mesh_.begin()->first->matches().end();
00112 ++chamberIter1) {
00113 for(std::vector<reco::MuonSegmentMatch>::iterator segmentIter1 = chamberIter1->segmentMatches.begin();
00114 segmentIter1 != chamberIter1->segmentMatches.end();
00115 ++segmentIter1) {
00116 segmentIter1->setMask(reco::MuonSegmentMatch::BelongsToTrackByCleaning);
00117 }
00118 }
00119 }
00120
00121
00122
00123 if(mesh_.size() > 1) {
00124 for( MeshType::iterator i = mesh_.begin(); i != mesh_.end(); ++i ) {
00125 for( std::vector<reco::MuonChamberMatch>::iterator chamberIter1 = i->first->matches().begin();
00126 chamberIter1 != i->first->matches().end();
00127 ++chamberIter1 ) {
00128 for(std::vector<reco::MuonSegmentMatch>::iterator segmentIter1 = chamberIter1->segmentMatches.begin();
00129 segmentIter1 != chamberIter1->segmentMatches.end();
00130 ++segmentIter1) {
00131
00132 bool shared(false);
00133
00134 for( AssociationType::iterator j = i->second.begin();
00135 j != i->second.end();
00136 ++j ) {
00137
00138 if( segmentIter1->cscSegmentRef.isNonnull() &&
00139 j->second.second->cscSegmentRef.isNonnull() ) {
00140 if(chamberIter1->id.subdetId() == MuonSubdetId::CSC &&
00141 j->second.first->id.subdetId() == MuonSubdetId::CSC ) {
00142 CSCDetId segIterId(chamberIter1->id), shareId(j->second.first->id);
00143
00144 if( doOverlaps &&
00145 isDuplicateOf(std::make_pair(segIterId,segmentIter1->cscSegmentRef),
00146 std::make_pair(shareId,j->second.second->cscSegmentRef)) )
00147 shared = true;
00148
00149 if( doME1a &&
00150 isDuplicateOf(segmentIter1->cscSegmentRef,j->second.second->cscSegmentRef) &&
00151 segIterId.ring() == 4 && shareId.ring() == 4 &&
00152 segIterId == segIterId)
00153 shared = true;
00154
00155 if( doClustering &&
00156 isClusteredWith(std::make_pair(CSCDetId(chamberIter1->id),segmentIter1->cscSegmentRef),
00157 std::make_pair(CSCDetId(j->second.first->id),j->second.second->cscSegmentRef)) )
00158 shared = true;
00159 }
00160 }
00161 }
00162
00163
00164 if( ((segmentIter1->mask&0x1e0000) == 0x1e0000 && !shared) ||
00165 (chamberIter1->id.subdetId() == MuonSubdetId::DT && (segmentIter1->mask&0x1e0000)) )
00166 segmentIter1->setMask(reco::MuonSegmentMatch::BelongsToTrackByCleaning);
00167
00168 }
00169 }
00170 }
00171 }
00172
00173 }
00174
00175 void MuonMesh::pruneMesh() {
00176
00177 for( MeshType::iterator i = mesh_.begin(); i != mesh_.end(); ++i ) {
00178
00179 for( AssociationType::iterator j = i->second.begin();
00180 j != i->second.end();
00181 ++j ) {
00182
00183 for( std::vector<reco::MuonChamberMatch>::iterator chamberIter1 = i->first->matches().begin();
00184 chamberIter1 != i->first->matches().end();
00185 ++chamberIter1 ) {
00186 for(std::vector<reco::MuonSegmentMatch>::iterator segmentIter1 = chamberIter1->segmentMatches.begin();
00187 segmentIter1 != chamberIter1->segmentMatches.end();
00188 ++segmentIter1) {
00189
00190 if(j->second.second->cscSegmentRef.isNonnull() && segmentIter1->cscSegmentRef.isNonnull()) {
00191
00192 bool me1a(false), overlap(false), cluster(false);
00193
00194
00195 if( doOverlaps &&
00196 isDuplicateOf(std::make_pair(CSCDetId(chamberIter1->id),segmentIter1->cscSegmentRef),
00197 std::make_pair(CSCDetId(j->second.first->id),j->second.second->cscSegmentRef)) ) {
00198
00199 if ( i->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) >
00200 j->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) ) {
00201
00202 segmentIter1->setMask(reco::MuonSegmentMatch::BelongsToTrackByOvlClean);
00203 segmentIter1->setMask(reco::MuonSegmentMatch::BelongsToTrackByCleaning);
00204
00205 overlap = true;
00206 } else if ( i->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) ==
00207 j->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) ) {
00208
00209 if((segmentIter1->mask & 0x1e0000) > (j->second.second->mask & 0x1e0000)) {
00210
00211 segmentIter1->setMask(reco::MuonSegmentMatch::BelongsToTrackByOvlClean);
00212 segmentIter1->setMask(reco::MuonSegmentMatch::BelongsToTrackByCleaning);
00213
00214 overlap = true;
00215 } else {
00216
00217 }
00218 }
00219 }
00220
00221
00222
00223
00224 if( doME1a &&
00225 isDuplicateOf(segmentIter1->cscSegmentRef,j->second.second->cscSegmentRef) &&
00226 CSCDetId(chamberIter1->id).ring() == 4 && CSCDetId(j->second.first->id).ring() == 4 &&
00227 chamberIter1->id == j->second.first->id ) {
00228
00229 if( j->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) <
00230 i->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) ) {
00231
00232 for(AssociationType::iterator AsscIter1 = i->second.begin();
00233 AsscIter1 != i->second.end();
00234 ++AsscIter1) {
00235 if(AsscIter1->second.second->cscSegmentRef.isNonnull())
00236 if(j->first == AsscIter1->first &&
00237 j->second.first == AsscIter1->second.first &&
00238 isDuplicateOf(segmentIter1->cscSegmentRef,AsscIter1->second.second->cscSegmentRef)) {
00239 AsscIter1->second.second->mask &= ~reco::MuonSegmentMatch::BelongsToTrackByME1aClean;
00240 }
00241 }
00242
00243 me1a = true;
00244 } else if ( j->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) ==
00245 i->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) ) {
00246
00247 bool bestArb(true);
00248
00249 for(AssociationType::iterator AsscIter1 = i->second.begin();
00250 AsscIter1 != i->second.end();
00251 ++AsscIter1) {
00252 if(AsscIter1->second.second->cscSegmentRef.isNonnull())
00253 if(j->first == AsscIter1->first &&
00254 j->second.first == AsscIter1->second.first &&
00255 isDuplicateOf(segmentIter1->cscSegmentRef,AsscIter1->second.second->cscSegmentRef) &&
00256 (segmentIter1->mask & 0x1e0000) < (AsscIter1->second.second->mask & 0x1e0000))
00257 bestArb = false;
00258 }
00259
00260 if(bestArb) {
00261
00262 for(AssociationType::iterator AsscIter1 = i->second.begin();
00263 AsscIter1 != i->second.end();
00264 ++AsscIter1) {
00265 if(AsscIter1->second.second->cscSegmentRef.isNonnull())
00266 if(j->first == AsscIter1->first &&
00267 j->second.first == AsscIter1->second.first &&
00268 isDuplicateOf(segmentIter1->cscSegmentRef,AsscIter1->second.second->cscSegmentRef)) {
00269 AsscIter1->second.second->mask &= ~reco::MuonSegmentMatch::BelongsToTrackByME1aClean;
00270 }
00271 }
00272
00273 }
00274 me1a = true;
00275
00276 }
00277 }
00278
00279 if(doClustering &&
00280 isClusteredWith(std::make_pair(CSCDetId(chamberIter1->id),segmentIter1->cscSegmentRef),
00281 std::make_pair(CSCDetId(j->second.first->id),j->second.second->cscSegmentRef))) {
00282
00283 if (i->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) >
00284 j->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) ) {
00285
00286 segmentIter1->setMask(reco::MuonSegmentMatch::BelongsToTrackByClusClean);
00287 segmentIter1->setMask(reco::MuonSegmentMatch::BelongsToTrackByCleaning);
00288
00289 cluster = true;
00290 } else if (i->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) <
00291 j->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000)) {
00292
00293 j->second.second->setMask(reco::MuonSegmentMatch::BelongsToTrackByClusClean);
00294 j->second.second->setMask(reco::MuonSegmentMatch::BelongsToTrackByCleaning);
00295
00296 cluster = true;
00297 } else {
00298
00299 if((segmentIter1->mask & 0x1e0000) > (j->second.second->mask & 0x1e0000)) {
00300
00301 segmentIter1->setMask(reco::MuonSegmentMatch::BelongsToTrackByClusClean);
00302 segmentIter1->setMask(reco::MuonSegmentMatch::BelongsToTrackByCleaning);
00303
00304 cluster = true;
00305 } else if ((segmentIter1->mask & 0x1e0000) < (j->second.second->mask & 0x1e0000)){
00306
00307 j->second.second->setMask(reco::MuonSegmentMatch::BelongsToTrackByClusClean);
00308 j->second.second->setMask(reco::MuonSegmentMatch::BelongsToTrackByCleaning);
00309
00310 cluster = true;
00311 } else {
00312 }
00313 }
00314
00315 }
00316
00317 }
00318 }
00319 }
00320 }
00321 }
00322
00323
00324
00325 for( MeshType::iterator i = mesh_.begin(); i != mesh_.end(); ++i ) {
00326 for( std::vector<reco::MuonChamberMatch>::iterator chamberIter1 = i->first->matches().begin();
00327 chamberIter1 != i->first->matches().end();
00328 ++chamberIter1 ) {
00329 for(std::vector<reco::MuonSegmentMatch>::iterator segmentIter1 = chamberIter1->segmentMatches.begin();
00330 segmentIter1 != chamberIter1->segmentMatches.end();
00331 ++segmentIter1) {
00332
00333 if( !segmentIter1->isMask(reco::MuonSegmentMatch::BelongsToTrackByCleaning) &&
00334 segmentIter1->isMask(0xe00000) )
00335 segmentIter1->setMask(reco::MuonSegmentMatch::BelongsToTrackByCleaning);
00336 }
00337 }
00338 }
00339
00340 }
00341
00342 bool MuonMesh::isDuplicateOf(const CSCSegmentRef& lhs, const CSCSegmentRef& rhs) const
00343 {
00344 bool result(false);
00345
00346 if(!lhs->isME11a_duplicate())
00347 return result;
00348
00349 std::vector<CSCSegment> lhs_duplicates = lhs->duplicateSegments();
00350
00351 if(fabs(lhs->localPosition().x() - rhs->localPosition().x() ) < 1E-3 &&
00352 fabs(lhs->localPosition().y() - rhs->localPosition().y() ) < 1E-3 &&
00353 fabs(lhs->localDirection().x()/lhs->localDirection().z() - rhs->localDirection().x()/rhs->localDirection().z() ) < 1E-3 &&
00354 fabs(lhs->localDirection().y()/lhs->localDirection().z() - rhs->localDirection().y()/rhs->localDirection().z() ) < 1E-3 &&
00355 fabs(lhs->localPositionError().xx() - rhs->localPositionError().xx() ) < 1E-3 &&
00356 fabs(lhs->localPositionError().yy() - rhs->localPositionError().yy() ) < 1E-3 &&
00357 fabs(lhs->localDirectionError().xx() - rhs->localDirectionError().xx()) < 1E-3 &&
00358 fabs(lhs->localDirectionError().yy() - rhs->localDirectionError().yy()) < 1E-3)
00359 result = true;
00360
00361 for( std::vector<CSCSegment>::const_iterator segIter1 = lhs_duplicates.begin();
00362 segIter1 != lhs_duplicates.end();
00363 ++segIter1 ) {
00364
00365 if(fabs(segIter1->localPosition().x() - rhs->localPosition().x() ) < 1E-3 &&
00366 fabs(segIter1->localPosition().y() - rhs->localPosition().y() ) < 1E-3 &&
00367 fabs(segIter1->localDirection().x()/segIter1->localDirection().z() - rhs->localDirection().x()/rhs->localDirection().z() ) < 1E-3 &&
00368 fabs(segIter1->localDirection().y()/segIter1->localDirection().z() - rhs->localDirection().y()/rhs->localDirection().z() ) < 1E-3 &&
00369 fabs(segIter1->localPositionError().xx() - rhs->localPositionError().xx() ) < 1E-3 &&
00370 fabs(segIter1->localPositionError().yy() - rhs->localPositionError().yy() ) < 1E-3 &&
00371 fabs(segIter1->localDirectionError().xx() - rhs->localDirectionError().xx()) < 1E-3 &&
00372 fabs(segIter1->localDirectionError().yy() - rhs->localDirectionError().yy()) < 1E-3)
00373 result = true;
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 }
00385
00386 return result;
00387 }
00388
00389 bool MuonMesh::isDuplicateOf(const std::pair<CSCDetId,CSCSegmentRef>& rhs,
00390 const std::pair<CSCDetId,CSCSegmentRef>& lhs) const
00391 {
00392 bool result(false);
00393
00394
00395
00396
00397 if(rhs.first.endcap() == lhs.first.endcap() &&
00398 rhs.first.station() == lhs.first.station() &&
00399 rhs.first.ring() == lhs.first.ring()) {
00400
00401
00402
00403
00404
00405
00406
00407 unsigned modulus = ((rhs.first.ring() != 1 || rhs.first.station() == 1) ? 36 : 18);
00408 int left_neighbor = (((rhs.first.chamber() - 1 + modulus)%modulus == 0 ) ? modulus : (rhs.first.chamber() - 1 + modulus)%modulus );
00409 int right_neighbor = (((rhs.first.chamber() + 1)%modulus == 0 ) ? modulus : (rhs.first.chamber() + 1)%modulus );
00410
00411 if(lhs.first.chamber() == left_neighbor ||
00412 lhs.first.chamber() == right_neighbor) {
00413
00414 std::vector<CSCSegment> thesegments;
00415 thesegments.push_back(*(lhs.second));
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 double rhs_phi = geometry_->chamber(rhs.first)->toGlobal(rhs.second->localPosition()).phi();
00437 double rhs_theta = geometry_->chamber(rhs.first)->toGlobal(rhs.second->localPosition()).theta();
00438 double rhs_z = geometry_->chamber(rhs.first)->toGlobal(rhs.second->localPosition()).z();
00439
00440 for(std::vector<CSCSegment>::const_iterator ilhs = thesegments.begin(); ilhs != thesegments.end(); ++ilhs) {
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453 double lhs_phi = geometry_->chamber(lhs.first)->toGlobal(ilhs->localPosition()).phi();
00454 double lhs_theta = geometry_->chamber(lhs.first)->toGlobal(ilhs->localPosition()).theta();
00455 double lhs_z = geometry_->chamber(lhs.first)->toGlobal(ilhs->localPosition()).z();
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 double phidiff = (fabs(rhs_phi - lhs_phi) > 2*M_PI ? fabs(rhs_phi - lhs_phi) - 2*M_PI : fabs(rhs_phi - lhs_phi));
00471
00472 if(phidiff < OverlapDPhi && fabs(rhs_theta - lhs_theta) < OverlapDTheta &&
00473 fabs(rhs_z) < fabs(lhs_z) && rhs_z*lhs_z > 0)
00474 result = true;
00475 }
00476 }
00477 }
00478
00479 return result;
00480 }
00481
00482 bool MuonMesh::isClusteredWith(const std::pair<CSCDetId,CSCSegmentRef>& lhs,
00483 const std::pair<CSCDetId,CSCSegmentRef>& rhs) const
00484 {
00485 bool result(false);
00486
00487
00488
00489
00490
00491
00492 if(rhs.first.endcap() == lhs.first.endcap() && lhs.first.station() < rhs.first.station()) {
00493
00494 std::vector<CSCSegment> thesegments;
00495 thesegments.push_back(*(lhs.second));
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515 double rhs_phi = geometry_->chamber(rhs.first)->toGlobal(rhs.second->localPosition()).phi();
00516 double rhs_theta = geometry_->chamber(rhs.first)->toGlobal(rhs.second->localPosition()).theta();
00517
00518 for(std::vector<CSCSegment>::const_iterator ilhs = thesegments.begin(); ilhs != thesegments.end(); ++ilhs) {
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531 double lhs_phi = geometry_->chamber(lhs.first)->toGlobal(ilhs->localPosition()).phi();
00532 double lhs_theta = geometry_->chamber(lhs.first)->toGlobal(ilhs->localPosition()).theta();
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 double phidiff = (fabs(rhs_phi - lhs_phi) > 2*M_PI ? fabs(rhs_phi - lhs_phi) - 2*M_PI : fabs(rhs_phi - lhs_phi));
00548
00549 if(phidiff < ClusterDPhi && fabs(rhs_theta - lhs_theta) < ClusterDTheta)
00550 result = true;
00551 }
00552 }
00553
00554 return result;
00555 }