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