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