00001 #include "RecoMuon/MuonSeedGenerator/plugins/CosmicMuonSeedGenerator.h"
00012 #include "DataFormats/TrajectorySeed/interface/TrajectorySeed.h"
00013 #include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h"
00014 #include "DataFormats/Common/interface/Handle.h"
00015
00016 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00017
00018 #include "RecoMuon/MeasurementDet/interface/MuonDetLayerMeasurements.h"
00019 #include "RecoMuon/DetLayers/interface/MuonDetLayerGeometry.h"
00020 #include "RecoMuon/Records/interface/MuonRecoGeometryRecord.h"
00021 #include "RecoMuon/TrackingTools/interface/MuonPatternRecoDumper.h"
00022
00023 #include "FWCore/Framework/interface/EventSetup.h"
00024 #include "FWCore/Framework/interface/Event.h"
00025 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00026 #include "FWCore/Framework/interface/ESHandle.h"
00027 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00028
00029 #include "MagneticField/Engine/interface/MagneticField.h"
00030 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00031
00032 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00033 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00034 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
00035
00036 #include "DataFormats/Math/interface/deltaR.h"
00037
00038 #include <vector>
00039
00040 typedef MuonTransientTrackingRecHit::MuonRecHitPointer MuonRecHitPointer;
00041 typedef MuonTransientTrackingRecHit::MuonRecHitContainer MuonRecHitContainer;
00042
00043 using namespace edm;
00044 using namespace std;
00045
00046
00047 CosmicMuonSeedGenerator::CosmicMuonSeedGenerator(const edm::ParameterSet& pset){
00048 produces<TrajectorySeedCollection>();
00049
00050
00051 theEnableDTFlag = pset.getParameter<bool>("EnableDTMeasurement");
00052
00053 theEnableCSCFlag = pset.getParameter<bool>("EnableCSCMeasurement");
00054
00055 theDTRecSegmentLabel = pset.getParameter<InputTag>("DTRecSegmentLabel");
00056
00057 theCSCRecSegmentLabel = pset.getParameter<InputTag>("CSCRecSegmentLabel");
00058
00059
00060 theMaxSeeds = pset.getParameter<int>("MaxSeeds");
00061
00062 theMaxDTChi2 = pset.getParameter<double>("MaxDTChi2");
00063 theMaxCSCChi2 = pset.getParameter<double>("MaxCSCChi2");
00064
00065
00066 theParameters["topmb41"] = 0.87;
00067 theParameters["bottommb41"] = 1.2;
00068 theParameters["topmb42"] = 0.67;
00069 theParameters["bottommb42"] = 0.98;
00070 theParameters["topmb43"] = 0.34;
00071 theParameters["bottommb43"] = 0.58;
00072 theParameters["topmb31"] = 0.54;
00073 theParameters["bottommb31"] = 0.77;
00074 theParameters["topmb32"] = 0.35;
00075 theParameters["bottommb32"] = 0.55;
00076 theParameters["topmb21"] = 0.21;
00077 theParameters["bottommb21"] = 0.31;
00078
00079 }
00080
00081
00082 CosmicMuonSeedGenerator::~CosmicMuonSeedGenerator(){
00083 }
00084
00085
00086
00087 void CosmicMuonSeedGenerator::produce(edm::Event& event, const edm::EventSetup& eSetup){
00088
00089 eSetup.get<IdealMagneticFieldRecord>().get(theField);
00090
00091 auto_ptr<TrajectorySeedCollection> output(new TrajectorySeedCollection());
00092
00093 TrajectorySeedCollection seeds;
00094
00095 std::string category = "Muon|RecoMuon|CosmicMuonSeedGenerator";
00096
00097
00098 eSetup.get<MuonRecoGeometryRecord>().get(theMuonLayers);
00099
00100
00101 vector<DetLayer*> dtLayers = theMuonLayers->allDTLayers();
00102
00103
00104 vector<DetLayer*> cscForwardLayers = theMuonLayers->forwardCSCLayers();
00105 vector<DetLayer*> cscBackwardLayers = theMuonLayers->backwardCSCLayers();
00106
00107 MuonDetLayerMeasurements muonMeasurements(theDTRecSegmentLabel,theCSCRecSegmentLabel,
00108 InputTag(),
00109 theEnableDTFlag,theEnableCSCFlag,false);
00110
00111 muonMeasurements.setEvent(event);
00112
00113 MuonRecHitContainer allHits;
00114
00115 vector<MuonRecHitContainer> RHMBs;
00116 vector<MuonRecHitContainer> RHMEFs;
00117 vector<MuonRecHitContainer> RHMEBs;
00118
00119 stable_sort(allHits.begin(),allHits.end(),DecreasingGlobalY());
00120
00121 for (vector<DetLayer*>::reverse_iterator icsclayer = cscForwardLayers.rbegin();
00122 icsclayer != cscForwardLayers.rend() - 1; ++icsclayer) {
00123
00124 MuonRecHitContainer RHMF = muonMeasurements.recHits(*icsclayer);
00125 allHits.insert(allHits.end(),RHMF.begin(),RHMF.end());
00126
00127 }
00128
00129 for (vector<DetLayer*>::reverse_iterator icsclayer = cscBackwardLayers.rbegin();
00130 icsclayer != cscBackwardLayers.rend() - 1; ++icsclayer) {
00131
00132 MuonRecHitContainer RHMF = muonMeasurements.recHits(*icsclayer);
00133 allHits.insert(allHits.end(),RHMF.begin(),RHMF.end());
00134
00135 }
00136
00137 for (vector<DetLayer*>::reverse_iterator idtlayer = dtLayers.rbegin();
00138 idtlayer != dtLayers.rend(); ++idtlayer) {
00139
00140 MuonRecHitContainer RHMB = muonMeasurements.recHits(*idtlayer);
00141 RHMBs.push_back(RHMB);
00142
00143 if ( idtlayer != dtLayers.rbegin() ) allHits.insert(allHits.end(),RHMB.begin(),RHMB.end());
00144
00145 }
00146
00147
00148
00149 LogTrace(category)<<"all RecHits: "<<allHits.size();
00150
00151
00152
00153
00154
00155
00156
00157 CosmicMuonSeedGenerator::MuonRecHitPairVector mb42 = makeSegPairs(RHMBs[0],RHMBs[2], "mb42");
00158 createSeeds(seeds, mb42, eSetup);
00159
00160
00161
00162
00163 CosmicMuonSeedGenerator::MuonRecHitPairVector mb31 = makeSegPairs(RHMBs[1], RHMBs[3], "mb31");
00164 createSeeds(seeds, mb31, eSetup);
00165
00166
00167
00168
00169 if ( !allHits.empty() ) {
00170
00171 MuonRecHitContainer goodhits = selectSegments(allHits);
00172 LogTrace(category)<<"good RecHits: "<<goodhits.size();
00173
00174 if ( goodhits.empty() ) {
00175 LogTrace(category)<<"No qualified Segments in Event! ";
00176 LogTrace(category)<<"Use 2D RecHit";
00177
00178 createSeeds(seeds,allHits,eSetup);
00179
00180 }
00181 else {
00182 createSeeds(seeds,goodhits,eSetup);
00183 }
00184 }
00185
00186 LogTrace(category)<<"Seeds built: "<<seeds.size();
00187
00188 for(std::vector<TrajectorySeed>::iterator seed = seeds.begin();
00189 seed != seeds.end(); ++seed) {
00190 output->push_back(*seed);
00191 }
00192
00193 event.put(output);
00194 seeds.clear();
00195
00196 }
00197
00198
00199 bool CosmicMuonSeedGenerator::checkQuality(const MuonRecHitPointer& hit) const {
00200
00201 const std::string category = "Muon|RecoMuon|CosmicMuonSeedGenerator";
00202
00203
00204 if ( !hit->isValid() ) return false;
00205
00206 if (hit->dimension() < 4) {
00207 LogTrace(category)<<"dim < 4";
00208 return false;
00209 }
00210
00211 if (hit->isDT() && ( hit->chi2()> theMaxDTChi2 )) {
00212 LogTrace(category)<<"DT chi2 too large";
00213 return false;
00214 }
00215 else if (hit->isCSC() &&( hit->chi2()> theMaxCSCChi2 ) ) {
00216 LogTrace(category)<<"CSC chi2 too large";
00217 return false;
00218 }
00219 return true;
00220
00221 }
00222
00223 MuonRecHitContainer CosmicMuonSeedGenerator::selectSegments(const MuonRecHitContainer& hits) const {
00224
00225 MuonRecHitContainer result;
00226 const std::string category = "Muon|RecoMuon|CosmicMuonSeedGenerator";
00227
00228
00229 for (MuonRecHitContainer::const_iterator hit = hits.begin(); hit != hits.end(); hit++) {
00230 if ( checkQuality(*hit) ) result.push_back(*hit);
00231 }
00232
00233 if ( result.size() < 2 ) return result;
00234
00235 MuonRecHitContainer result2;
00236
00237
00238 for (MuonRecHitContainer::iterator hit = result.begin(); hit != result.end(); hit++) {
00239 if (*hit == 0) continue;
00240 if ( !(*hit)->isValid() ) continue;
00241 bool good = true;
00242
00243
00244 for (MuonRecHitContainer::iterator hit2 = hit + 1; hit2 != result.end(); hit2++) {
00245 if (*hit2 == 0) continue;
00246 if ( !(*hit2)->isValid() ) continue;
00247
00248
00249
00250
00251 if ( !areCorrelated((*hit),(*hit2)) ) continue;
00252
00253 if ( !leftIsBetter((*hit),(*hit2)) ) {
00254 good = false;
00255 } else (*hit2) = 0;
00256 }
00257
00258 if ( good ) result2.push_back(*hit);
00259 }
00260
00261 result.clear();
00262
00263 return result2;
00264
00265 }
00266
00267 void CosmicMuonSeedGenerator::createSeeds(TrajectorySeedCollection& results,
00268 const MuonRecHitContainer& hits,
00269 const edm::EventSetup& eSetup) const {
00270
00271 const std::string category = "Muon|RecoMuon|CosmicMuonSeedGenerator";
00272
00273 if (hits.size() == 0 || results.size() >= theMaxSeeds ) return;
00274 for (MuonRecHitContainer::const_iterator ihit = hits.begin(); ihit != hits.end(); ihit++) {
00275 const std::vector<TrajectorySeed>& sds = createSeed((*ihit),eSetup);
00276 LogTrace(category)<<"created seeds from rechit "<<sds.size();
00277 results.insert(results.end(),sds.begin(),sds.end());
00278 if ( results.size() >= theMaxSeeds ) break;
00279 }
00280 return;
00281 }
00282
00283 void CosmicMuonSeedGenerator::createSeeds(TrajectorySeedCollection& results,
00284 const CosmicMuonSeedGenerator::MuonRecHitPairVector& hitpairs,
00285 const edm::EventSetup& eSetup) const {
00286
00287 const std::string category = "Muon|RecoMuon|CosmicMuonSeedGenerator";
00288
00289 if (hitpairs.size() == 0 || results.size() >= theMaxSeeds ) return;
00290 for (CosmicMuonSeedGenerator::MuonRecHitPairVector::const_iterator ihitpair = hitpairs.begin(); ihitpair != hitpairs.end(); ihitpair++) {
00291 const std::vector<TrajectorySeed>& sds = createSeed((*ihitpair),eSetup);
00292 LogTrace(category)<<"created seeds from rechit "<<sds.size();
00293 results.insert(results.end(),sds.begin(),sds.end());
00294 if ( results.size() >= theMaxSeeds ) break;
00295 }
00296 return;
00297 }
00298
00299
00300 std::vector<TrajectorySeed> CosmicMuonSeedGenerator::createSeed(const MuonRecHitPointer& hit, const edm::EventSetup& eSetup) const {
00301
00302 std::vector<TrajectorySeed> result;
00303
00304 const std::string category = "Muon|RecoMuon|CosmicMuonSeedGenerator";
00305
00306 MuonPatternRecoDumper dumper;
00307
00308
00309 double pt = 10.0;
00310
00311
00312 AlgebraicSymMatrix mat(5,0);
00313
00314
00315 LocalPoint segPos=hit->localPosition();
00316
00317 GlobalVector polar(GlobalVector::Spherical(hit->globalDirection().theta(),
00318 hit->globalDirection().phi(),
00319 1.));
00320
00321 if (hit->geographicalId().subdetId() == MuonSubdetId::DT && fabs(hit->globalDirection().eta()) < 4.0 && hit->globalDirection().phi() > 0 )
00322 polar = - polar;
00323
00324 if (hit->geographicalId().subdetId() == MuonSubdetId::CSC && fabs(hit->globalDirection().eta()) > 2.3 ) {
00325 polar = - polar;
00326 }
00327
00328 polar *=fabs(pt)/polar.perp();
00329
00330 LocalVector segDir =hit->det()->toLocal(polar);
00331
00332 int charge= 1;
00333 LocalTrajectoryParameters param(segPos,segDir, charge);
00334
00335 charge= -1;
00336 LocalTrajectoryParameters param2(segPos,segDir, charge);
00337
00338 mat = hit->parametersError().similarityT( hit->projectionMatrix() );
00339
00340 float p_err = 0.2;
00341 mat[0][0]= p_err;
00342
00343 LocalTrajectoryError error(asSMatrix<5>(mat));
00344
00345
00346 TrajectoryStateOnSurface tsos(param, error, hit->det()->surface(), &*theField);
00347 TrajectoryStateOnSurface tsos2(param2, error, hit->det()->surface(), &*theField);
00348
00349 LogTrace(category)<<"Trajectory State on Surface of Seed";
00350 LogTrace(category)<<"mom: "<<tsos.globalMomentum()<<" phi: "<<tsos.globalMomentum().phi();
00351 LogTrace(category)<<"pos: " << tsos.globalPosition();
00352 LogTrace(category) << "The RecSegment relies on: ";
00353 LogTrace(category) << dumper.dumpMuonId(hit->geographicalId());
00354
00355 result.push_back( tsosToSeed(tsos, hit->geographicalId().rawId()) );
00356 result.push_back( tsosToSeed(tsos2, hit->geographicalId().rawId()) );
00357
00358 return result;
00359 }
00360
00361 bool CosmicMuonSeedGenerator::areCorrelated(const MuonRecHitPointer& lhs, const MuonRecHitPointer& rhs) const {
00362 bool result = false;
00363
00364 GlobalVector dir1 = lhs->globalDirection();
00365 GlobalPoint pos1 = lhs->globalPosition();
00366 GlobalVector dir2 = rhs->globalDirection();
00367 GlobalPoint pos2 = rhs->globalPosition();
00368
00369 GlobalVector dis = pos2 - pos1;
00370
00371 if ( (deltaR<double>(dir1.eta(), dir1.phi(), dir2.eta(), dir2.phi()) < 0.1 || deltaR<double>(dir1.eta(), dir1.phi(), -dir2.eta(), -dir2.phi()) < 0.1 )
00372 && dis.mag() < 5.0 )
00373 result = true;
00374
00375 if ( (deltaR<double>(dir1.eta(), dir1.phi(), dir2.eta(), dir2.phi()) < 0.1 || deltaR<double>(dir1.eta(), dir1.phi(), -dir2.eta(), -dir2.phi()) < 0.1 ) &&
00376 (deltaR<double>(dir1.eta(), dir1.phi(), dis.eta(), dis.phi()) < 0.1 || deltaR<double>(dir2.eta(), dir2.phi(), dis.eta(), dis.phi()) < 0.1 ) )
00377 result = true;
00378
00379 if ( fabs(dir1.eta()) > 4.0 || fabs(dir2.eta()) > 4.0 ) {
00380 if ( (fabs(dir1.theta() - dir2.theta()) < 0.07 ||
00381 fabs(dir1.theta() + dir2.theta()) > 3.07 ) &&
00382 (fabs(dir1.theta() - dis.theta()) < 0.07 ||
00383 fabs(dir1.theta() - dis.theta()) < 0.07 ||
00384 fabs(dir1.theta() + dis.theta()) > 3.07 ||
00385 fabs(dir1.theta() + dis.theta()) > 3.07 ) )
00386
00387 result = true;
00388 }
00389
00390 return result;
00391 }
00392
00393 bool CosmicMuonSeedGenerator::leftIsBetter(const MuonTransientTrackingRecHit::MuonRecHitPointer& lhs,
00394 const MuonTransientTrackingRecHit::MuonRecHitPointer& rhs) const{
00395
00396 if ( (lhs->degreesOfFreedom() > rhs->degreesOfFreedom() ) ||
00397 ( (lhs->degreesOfFreedom() == rhs->degreesOfFreedom() ) &&
00398 (lhs)->chi2() < (rhs)->chi2() ) ) return true;
00399 else return false;
00400
00401 }
00402
00403
00404 CosmicMuonSeedGenerator::MuonRecHitPairVector
00405 CosmicMuonSeedGenerator::makeSegPairs(const MuonTransientTrackingRecHit::MuonRecHitContainer& hits1, const MuonTransientTrackingRecHit::MuonRecHitContainer& hits2, std::string tag) const {
00406
00407 MuonRecHitPairVector result;
00408 const std::string category = "Muon|RecoMuon|CosmicMuonSeedGenerator";
00409
00410 if (hits1.empty() || hits2.empty() ) return result;
00411
00412 for (MuonRecHitContainer::const_iterator ihit1 = hits1.begin(); ihit1 != hits1.end(); ihit1++) {
00413 if ( !checkQuality(*ihit1) ) continue;
00414
00415 for (MuonRecHitContainer::const_iterator ihit2 = hits2.begin(); ihit2 != hits2.end(); ihit2++) {
00416 if ( !checkQuality(*ihit2) ) continue;
00417
00418 float dphi = deltaPhi((*ihit1)->globalPosition().phi(), (*ihit2)->globalPosition().phi());
00419 if ( dphi < 0.5 ) {
00420 if ((*ihit1)->globalPosition().y() > 0.0 && ( (*ihit1)->globalPosition().y() > (*ihit2)->globalPosition().y() ) ) {
00421 std::string tag2 = "top"+tag;
00422
00423 result.push_back(MuonRecHitPair(*ihit1, *ihit2, tag2));
00424 } else if ((*ihit1)->globalPosition().y() < 0.0 && ( (*ihit1)->globalPosition().y() < (*ihit2)->globalPosition().y() ) ) {
00425 std::string tag2 = "bottom"+tag;
00426 result.push_back(MuonRecHitPair(*ihit2, *ihit1, tag2));
00427
00428 }
00429 }
00430 }
00431 }
00432
00433 return result;
00434 }
00435
00436 std::vector<TrajectorySeed> CosmicMuonSeedGenerator::createSeed(const CosmicMuonSeedGenerator::MuonRecHitPair& hitpair,
00437 const edm::EventSetup& eSetup) const {
00438 std::vector<TrajectorySeed> result;
00439
00440 const std::string category = "Muon|RecoMuon|CosmicMuonSeedGenerator";
00441
00442 MuonPatternRecoDumper dumper;
00443
00444 float dphi = deltaPhi((hitpair.first)->globalDirection().phi(), (hitpair.second)->globalDirection().phi());
00445
00446 LogTrace(category)<<"hitpair.type "<<hitpair.type;
00447
00448 map<string, float>::const_iterator iterPar = theParameters.find(hitpair.type);
00449 if ( iterPar == theParameters.end() ) {
00450 return result;
00451 }
00452
00453
00454 int charge = (dphi > 0) ? -1 : 1;
00455
00456 double pt = 999.0;
00457 float paraC = (iterPar->second);
00458
00459 if (fabs(dphi) > 1e-5) {
00460 pt = paraC/fabs(dphi);
00461 }
00462
00463 if (pt < 10.0 ) { return result; }
00464
00465 AlgebraicVector t(4);
00466 AlgebraicSymMatrix mat(5,0) ;
00467
00468 MuonTransientTrackingRecHit::MuonRecHitPointer hit = hitpair.first;
00469 if ( hit->dimension() < (hitpair.second)->dimension() ) hit = hitpair.second;
00470
00471
00472 LocalPoint segPos=hit->localPosition();
00473
00474 GlobalVector polar(GlobalVector::Spherical(hit->globalDirection().theta(),
00475 hit->globalDirection().phi(),
00476 1.));
00477
00478 if (hit->geographicalId().subdetId() == MuonSubdetId::DT && fabs(hit->globalDirection().eta()) < 4.0 && hit->globalDirection().phi() > 0 )
00479 polar = - polar;
00480
00481 if (hit->geographicalId().subdetId() == MuonSubdetId::CSC && fabs(hit->globalDirection().eta()) > 2.3 ) {
00482 polar = - polar;
00483 }
00484
00485 polar *=fabs(pt)/polar.perp();
00486
00487 LocalVector segDir =hit->det()->toLocal(polar);
00488
00489 LocalTrajectoryParameters param(segPos,segDir, charge);
00490
00491 mat = hit->parametersError().similarityT( hit->projectionMatrix() );
00492
00493 float p_err = 0.004/paraC;
00494 if (pt < 10.01) p_err = 0.1;
00495 mat[0][0]= p_err;
00496
00497 LocalTrajectoryError error(asSMatrix<5>(mat));
00498
00499
00500 TrajectoryStateOnSurface tsos(param, error, hit->det()->surface(), &*theField);
00501
00502 LogTrace(category)<<"Trajectory State on Surface of Seed";
00503 LogTrace(category)<<"mom: "<<tsos.globalMomentum()<<" phi: "<<tsos.globalMomentum().phi();
00504 LogTrace(category)<<"pos: " << tsos.globalPosition();
00505 LogTrace(category) << "The RecSegment relies on: ";
00506 LogTrace(category) << dumper.dumpMuonId(hit->geographicalId());
00507
00508 result.push_back( tsosToSeed(tsos, hit->geographicalId().rawId()) );
00509
00510 return result;
00511 }
00512
00513 TrajectorySeed CosmicMuonSeedGenerator::tsosToSeed(const TrajectoryStateOnSurface& tsos, uint32_t id) const {
00514
00515 PTrajectoryStateOnDet const & seedTSOS = trajectoryStateTransform::persistentState(tsos, id);
00516
00517 edm::OwnVector<TrackingRecHit> container;
00518 TrajectorySeed seed(seedTSOS,container,alongMomentum);
00519 return seed;
00520 }
00521