00001
00014 #include "RecoMuon/MuonIdentification/interface/MuonShowerInformationFiller.h"
00015
00016
00017 #include <memory>
00018 #include <algorithm>
00019 #include <iostream>
00020
00021
00022 #include "FWCore/Framework/interface/Event.h"
00023 #include "FWCore/PluginManager/interface/PluginManager.h"
00024 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00025 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00026 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
00027 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
00028 #include "DataFormats/DetId/interface/DetId.h"
00029 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00030 #include "TrackingTools/GeomPropagators/interface/Propagator.h"
00031 #include "DataFormats/GeometrySurface/interface/SimpleDiskBounds.h"
00032 #include "DataFormats/GeometrySurface/interface/BoundDisk.h"
00033 #include "DataFormats/GeometrySurface/interface/Bounds.h"
00034 #include "RecoMuon/MeasurementDet/interface/MuonDetLayerMeasurements.h"
00035 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
00036 #include "Geometry/CommonDetUnit/interface/GlobalTrackingGeometry.h"
00037 #include "MagneticField/Engine/interface/MagneticField.h"
00038 #include "Geometry/Records/interface/GlobalTrackingGeometryRecord.h"
00039 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00040 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00041 #include "TrackingTools/DetLayers/interface/BarrelDetLayer.h"
00042 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00043 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHit.h"
00044 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00045 #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHitBuilder.h"
00046 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHitBuilder.h"
00047 #include "TrackingTools/Records/interface/TransientRecHitRecord.h"
00048 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00049 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHitBreaker.h"
00050 #include "RecoMuon/TrackingTools/interface/MuonTrajectoryBuilder.h"
00051 #include "RecoTracker/TkDetLayers/interface/GeometricSearchTracker.h"
00052 #include "RecoMuon/DetLayers/interface/MuonDetLayerGeometry.h"
00053 #include "RecoMuon/Records/interface/MuonRecoGeometryRecord.h"
00054 #include "RecoTracker/Record/interface/TrackerRecoGeometryRecord.h"
00055 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00056
00057 #include "DataFormats/MuonReco/interface/MuonShower.h"
00058 #include "DataFormats/MuonReco/interface/MuonFwd.h"
00059 #include "DataFormats/MuonReco/interface/Muon.h"
00060 #include "DataFormats/TrackReco/interface/Track.h"
00061 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00062
00063 using namespace std;
00064 using namespace edm;
00065
00066
00067
00068
00069
00070 MuonShowerInformationFiller::MuonShowerInformationFiller(const edm::ParameterSet& par) :
00071 theService(0),
00072 theDTRecHitLabel(par.getParameter<InputTag>("DTRecSegmentLabel")),
00073 theCSCRecHitLabel(par.getParameter<InputTag>("CSCRecSegmentLabel")),
00074 theCSCSegmentsLabel(par.getParameter<InputTag>("CSCSegmentLabel")),
00075 theDT4DRecSegmentLabel(par.getParameter<InputTag>("DT4DRecSegmentLabel"))
00076 {
00077
00078 edm::ParameterSet serviceParameters = par.getParameter<edm::ParameterSet>("ServiceParameters");
00079 theService = new MuonServiceProxy(serviceParameters);
00080
00081 theTrackerRecHitBuilderName = par.getParameter<string>("TrackerRecHitBuilder");
00082 theMuonRecHitBuilderName = par.getParameter<string>("MuonRecHitBuilder");
00083
00084 theCacheId_TRH = 0;
00085 theCacheId_MT = 0;
00086
00087 category_ = "MuonShowerInformationFiller";
00088
00089 for (int istat = 0; istat < 4; istat++) {
00090 theStationShowerDeltaR.push_back(0.);
00091 theStationShowerTSize.push_back(0.);
00092 theAllStationHits.push_back(0);
00093 theCorrelatedStationHits.push_back(0);
00094 }
00095
00096 }
00097
00098
00099
00100
00101 MuonShowerInformationFiller::~MuonShowerInformationFiller() {
00102 if (theService) delete theService;
00103 }
00104
00105
00106
00107
00108 reco::MuonShower MuonShowerInformationFiller::fillShowerInformation( const reco::Muon& muon, const edm::Event& iEvent, const edm::EventSetup& iSetup) {
00109
00110 reco::MuonShower returnShower;
00111
00112
00113 theService->update(iSetup);
00114 setEvent(iEvent);
00115 setServices(theService->eventSetup());
00116
00117 fillHitsByStation(muon);
00118 std::vector<int> nStationHits = theAllStationHits;
00119 std::vector<int> nStationCorrelatedHits = theCorrelatedStationHits;
00120 std::vector<float> stationShowerSizeT = theStationShowerTSize;
00121 std::vector<float> stationShowerDeltaR = theStationShowerDeltaR;
00122
00123 returnShower.nStationHits = nStationHits;
00124 returnShower.nStationCorrelatedHits = nStationCorrelatedHits;
00125 returnShower.stationShowerSizeT = stationShowerSizeT;
00126 returnShower.stationShowerDeltaR = stationShowerDeltaR;
00127
00128 return returnShower;
00129
00130 }
00131
00132
00133
00134
00135 void MuonShowerInformationFiller::setEvent(const edm::Event& event) {
00136
00137
00138 event.getByLabel(theDTRecHitLabel, theDTRecHits);
00139 event.getByLabel(theCSCRecHitLabel, theCSCRecHits);
00140 event.getByLabel(theCSCSegmentsLabel, theCSCSegments);
00141 event.getByLabel(theDT4DRecSegmentLabel, theDT4DRecSegments);
00142
00143 for (int istat = 0; istat < 4; istat++) {
00144 theStationShowerDeltaR.at(istat) = 0.;
00145 theStationShowerTSize.at(istat) = 0.;
00146 theAllStationHits.at(istat) = 0;
00147 theCorrelatedStationHits.at(istat) = 0;
00148 }
00149 }
00150
00151
00152
00153
00154
00155 void MuonShowerInformationFiller::setServices(const EventSetup& setup) {
00156
00157
00158 setup.get<GlobalTrackingGeometryRecord>().get(theTrackingGeometry);
00159 setup.get<IdealMagneticFieldRecord>().get(theField);
00160 setup.get<TrackerRecoGeometryRecord>().get(theTracker);
00161 setup.get<MuonRecoGeometryRecord>().get(theMuonGeometry);
00162
00163
00164 unsigned long long newCacheId_TRH = setup.get<TransientRecHitRecord>().cacheIdentifier();
00165 if ( newCacheId_TRH != theCacheId_TRH ) {
00166 setup.get<TransientRecHitRecord>().get(theTrackerRecHitBuilderName,theTrackerRecHitBuilder);
00167 setup.get<TransientRecHitRecord>().get(theMuonRecHitBuilderName,theMuonRecHitBuilder);
00168 }
00169
00170 }
00171
00172
00173
00174
00175
00176 MuonTransientTrackingRecHit::MuonRecHitContainer
00177 MuonShowerInformationFiller::recHits4D(const GeomDet* geomDet,
00178 edm::Handle<DTRecSegment4DCollection> dtSegments,
00179 edm::Handle<CSCSegmentCollection> cscSegments) const {
00180
00181 MuonTransientTrackingRecHit::MuonRecHitContainer result;
00182
00183 DetId geoId = geomDet->geographicalId();
00184
00185 if (geoId.subdetId() == MuonSubdetId::DT) {
00186
00187 DTChamberId chamberId(geoId.rawId());
00188 DTRecSegment4DCollection::range range = dtSegments->get(chamberId);
00189 for (DTRecSegment4DCollection::const_iterator rechit = range.first;
00190 rechit!=range.second;++rechit) {
00191 result.push_back(MuonTransientTrackingRecHit::specificBuild(geomDet,&*rechit));
00192 }
00193 }
00194 else if (geoId.subdetId() == MuonSubdetId::CSC) {
00195
00196 CSCDetId did(geoId.rawId());
00197 CSCSegmentCollection::range range = cscSegments->get(did);
00198
00199 for (CSCSegmentCollection::const_iterator rechit = range.first;
00200 rechit!=range.second;++rechit) {
00201 result.push_back(MuonTransientTrackingRecHit::specificBuild(geomDet,&*rechit));
00202 }
00203 }
00204 else if (geoId.subdetId() == MuonSubdetId::RPC) {
00205 LogTrace(category_) << "Wrong subdet id" << endl;
00206 }
00207
00208 return result;
00209
00210 }
00211
00212 int MuonShowerInformationFiller::numberOfCorrelatedHits(const MuonTransientTrackingRecHit::MuonRecHitContainer& hits4d) const {
00213
00214 if (hits4d.empty()) return 0;
00215
00216 TransientTrackingRecHit::ConstRecHitPointer muonRecHit(hits4d.front().get());
00217 TransientTrackingRecHit::ConstRecHitContainer allhits1dcorrelated = MuonTransientTrackingRecHitBreaker::breakInSubRecHits(muonRecHit,2);
00218
00219 if (hits4d.size() == 1) return allhits1dcorrelated.size();
00220
00221 for (MuonTransientTrackingRecHit::MuonRecHitContainer::const_iterator ihit4d = hits4d.begin() + 1;
00222 ihit4d != hits4d.end(); ++ihit4d) {
00223
00224 TransientTrackingRecHit::ConstRecHitPointer muonRecHit((*ihit4d).get());
00225 TransientTrackingRecHit::ConstRecHitContainer hits1 =
00226 MuonTransientTrackingRecHitBreaker::breakInSubRecHits(muonRecHit,2);
00227
00228 for (TransientTrackingRecHit::ConstRecHitContainer::const_iterator ihit1 = hits1.begin();
00229 ihit1 != hits1.end(); ++ihit1 ) {
00230
00231 bool usedbefore = false;
00232 DetId thisID = (*ihit1)->geographicalId();
00233 LocalPoint lp1din4d = (*ihit1)->localPosition();
00234 GlobalPoint gp1din4d = (*ihit1)->globalPosition();
00235
00236 for (TransientTrackingRecHit::ConstRecHitContainer::const_iterator ihit2 = allhits1dcorrelated.begin();
00237 ihit2 != allhits1dcorrelated.end(); ++ihit2 ) {
00238
00239 DetId thisID2 = (*ihit2)->geographicalId();
00240 LocalPoint lp1din4d2 = (*ihit2)->localPosition();
00241 GlobalPoint gp1din4d2 = (*ihit2)->globalPosition();
00242
00243 if ( (gp1din4d2 - gp1din4d).mag() < 1.0 ) usedbefore = true;
00244
00245 }
00246 if ( !usedbefore ) allhits1dcorrelated.push_back(*ihit1);
00247 }
00248 }
00249
00250 return allhits1dcorrelated.size();
00251
00252 }
00253
00254
00255
00256
00257
00258 MuonTransientTrackingRecHit::MuonRecHitContainer
00259 MuonShowerInformationFiller::findPhiCluster(MuonTransientTrackingRecHit::MuonRecHitContainer& muonRecHits,
00260 const GlobalPoint& refpoint) const {
00261
00262 if ( muonRecHits.empty() ) return muonRecHits;
00263
00264
00265 float step = 0.05;
00266 MuonTransientTrackingRecHit::MuonRecHitContainer result;
00267
00268 stable_sort(muonRecHits.begin(), muonRecHits.end(), AbsLessDPhi(refpoint));
00269
00270 for (MuonTransientTrackingRecHit::MuonRecHitContainer::const_iterator ihit = muonRecHits.begin(); ihit != muonRecHits.end() - 1; ++ihit) {
00271 if (fabs(deltaPhi((*(ihit+1))->globalPosition().phi(), (*ihit)->globalPosition().phi() )) < step) {
00272 result.push_back(*ihit);
00273 } else {
00274 break;
00275 }
00276 }
00277
00278 LogTrace(category_) << "phi front: " << muonRecHits.front()->globalPosition().phi() << endl;
00279 LogTrace(category_) << "phi back: " << muonRecHits.back()->globalPosition().phi() << endl;
00280
00281 return result;
00282
00283 }
00284
00285
00286
00287
00288 MuonTransientTrackingRecHit::MuonRecHitContainer
00289 MuonShowerInformationFiller::findThetaCluster(MuonTransientTrackingRecHit::MuonRecHitContainer& muonRecHits,
00290 const GlobalPoint& refpoint) const {
00291
00292 if ( muonRecHits.empty() ) return muonRecHits;
00293
00294
00295 float step = 0.05;
00296 MuonTransientTrackingRecHit::MuonRecHitContainer result;
00297
00298 stable_sort(muonRecHits.begin(), muonRecHits.end(), AbsLessDTheta(refpoint));
00299
00300 for (MuonTransientTrackingRecHit::MuonRecHitContainer::const_iterator ihit = muonRecHits.begin(); ihit != muonRecHits.end() - 1; ++ihit) {
00301 if (fabs((*(ihit+1))->globalPosition().theta() - (*ihit)->globalPosition().theta() ) < step) {
00302 result.push_back(*ihit);
00303 } else {
00304 break;
00305 }
00306 }
00307
00308 return result;
00309
00310 }
00311
00312
00313
00314
00315 MuonTransientTrackingRecHit::MuonRecHitContainer
00316 MuonShowerInformationFiller::findPerpCluster(MuonTransientTrackingRecHit::MuonRecHitContainer& muonRecHits) const {
00317
00318 if ( muonRecHits.empty() ) return muonRecHits;
00319
00320 stable_sort(muonRecHits.begin(), muonRecHits.end(), LessPerp());
00321
00322 MuonTransientTrackingRecHit::MuonRecHitContainer::const_iterator
00323 seedhit = min_element(muonRecHits.begin(), muonRecHits.end(), LessPerp());
00324
00325 MuonTransientTrackingRecHit::MuonRecHitContainer::const_iterator ihigh = seedhit;
00326 MuonTransientTrackingRecHit::MuonRecHitContainer::const_iterator ilow = seedhit;
00327
00328 float step = 0.1;
00329 while (ihigh != muonRecHits.end()-1 && ( fabs((*(ihigh+1))->globalPosition().perp() - (*ihigh)->globalPosition().perp() ) < step) ) {
00330 ihigh++;
00331 }
00332 while (ilow != muonRecHits.begin() && ( fabs((*ilow)->globalPosition().perp() - (*(ilow -1))->globalPosition().perp()) < step ) ) {
00333 ilow--;
00334 }
00335
00336 MuonTransientTrackingRecHit::MuonRecHitContainer result(ilow, ihigh);
00337
00338 return result;
00339
00340 }
00341
00342
00343
00344
00345 vector<const GeomDet*> MuonShowerInformationFiller::getCompatibleDets(const reco::Track& track) const {
00346
00347 vector<const GeomDet*> total;
00348 total.reserve(1000);
00349
00350 LogTrace(category_) << "Consider a track " << track.p() << " eta: " << track.eta() << " phi " << track.phi() << endl;
00351
00352 TrajectoryStateTransform tsTrans;
00353 TrajectoryStateOnSurface innerTsos = tsTrans.innerStateOnSurface(track, *theService->trackingGeometry(), &*theService->magneticField());
00354 TrajectoryStateOnSurface outerTsos = tsTrans.outerStateOnSurface(track, *theService->trackingGeometry(), &*theService->magneticField());
00355
00356 GlobalPoint innerPos = innerTsos.globalPosition();
00357 GlobalPoint outerPos = outerTsos.globalPosition();
00358
00359 vector<GlobalPoint> allCrossingPoints;
00360
00361
00362 const vector<DetLayer*>& dtlayers = theService->detLayerGeometry()->allDTLayers();
00363
00364 for (vector<DetLayer*>::const_iterator iLayer = dtlayers.begin(); iLayer != dtlayers.end(); ++iLayer) {
00365
00366
00367 GlobalPoint xPoint = crossingPoint(innerPos, outerPos, dynamic_cast<const BarrelDetLayer*>(*iLayer));
00368
00369
00370 if ((fabs(xPoint.y()) < 1000.0) && (fabs(xPoint.z()) < 1500 ) &&
00371 (!(xPoint.y() == 0 && xPoint.x() == 0 && xPoint.z() == 0))) allCrossingPoints.push_back(xPoint);
00372 }
00373
00374 stable_sort(allCrossingPoints.begin(), allCrossingPoints.end(), LessMag(innerPos) );
00375
00376 vector<const GeomDet*> tempDT;
00377
00378 for (vector<GlobalPoint>::const_iterator ipos = allCrossingPoints.begin(); ipos != allCrossingPoints.end(); ++ipos) {
00379
00380 tempDT = dtPositionToDets(*ipos);
00381 vector<const GeomDet*>::const_iterator begin = tempDT.begin();
00382 vector<const GeomDet*>::const_iterator end = tempDT.end();
00383
00384 for (; begin!=end;++begin) {
00385 total.push_back(*begin);
00386 }
00387
00388 }
00389 allCrossingPoints.clear();
00390
00391 const vector<DetLayer*>& csclayers = theService->detLayerGeometry()->allCSCLayers();
00392 for (vector<DetLayer*>::const_iterator iLayer = csclayers.begin(); iLayer != csclayers.end(); ++iLayer) {
00393
00394 GlobalPoint xPoint = crossingPoint(innerPos, outerPos, dynamic_cast<const ForwardDetLayer*>(*iLayer));
00395
00396
00397 if ((fabs(xPoint.y()) < 1000.0) && (fabs(xPoint.z()) < 1500.0)
00398 && (!(xPoint.y() == 0 && xPoint.x() == 0 && xPoint.z() == 0))) allCrossingPoints.push_back(xPoint);
00399 }
00400 stable_sort(allCrossingPoints.begin(), allCrossingPoints.end(), LessMag(innerPos) );
00401
00402 vector<const GeomDet*> tempCSC;
00403 for (vector<GlobalPoint>::const_iterator ipos = allCrossingPoints.begin(); ipos != allCrossingPoints.end(); ++ipos) {
00404
00405 tempCSC = cscPositionToDets(*ipos);
00406 vector<const GeomDet*>::const_iterator begin = tempCSC.begin();
00407 vector<const GeomDet*>::const_iterator end = tempCSC.end();
00408
00409 for (; begin!=end;++begin) {
00410 total.push_back(*begin);
00411 }
00412
00413 }
00414
00415 return total;
00416
00417 }
00418
00419
00420
00421
00422
00423 GlobalPoint MuonShowerInformationFiller::crossingPoint(const GlobalPoint& p1,
00424 const GlobalPoint& p2,
00425 const BarrelDetLayer* dl) const {
00426
00427 const BoundCylinder& bc = dl->specificSurface();
00428 return crossingPoint(p1, p2, bc);
00429
00430 }
00431
00432 GlobalPoint MuonShowerInformationFiller::crossingPoint(const GlobalPoint& p1,
00433 const GlobalPoint& p2,
00434 const Cylinder& cyl) const {
00435
00436 float radius = cyl.radius();
00437
00438 GlobalVector dp = p1 - p2;
00439 float slope = dp.x()/dp.y();
00440 float a = p1.x() - slope * p1.y();
00441
00442 float n2 = (1 + slope * slope);
00443 float n1 = 2*a*slope;
00444 float n0 = a*a - radius*radius;
00445
00446 float y1 = 9999;
00447 float y2 = 9999;
00448 if ( n1*n1 - 4*n2*n0 > 0 ) {
00449 y1 = (-n1 + sqrt(n1*n1 - 4*n2*n0) ) / (2 * n2);
00450 y2 = (-n1 - sqrt(n1*n1 - 4*n2*n0) ) / (2 * n2);
00451 }
00452
00453 float x1 = p1.x() + slope * (y1 - p1.y());
00454 float x2 = p1.x() + slope * (y2 - p1.y());
00455
00456 float slopeZ = dp.z()/dp.y();
00457
00458 float z1 = p1.z() + slopeZ * (y1 - p1.y());
00459 float z2 = p1.z() + slopeZ * (y2 - p1.y());
00460
00461
00462 if ((p2.x()*x1 > 0) && (y1*p2.y() > 0) && (z1*p2.z() > 0)) {
00463 return GlobalPoint(x1, y1, z1);
00464 } else {
00465 return GlobalPoint(x2, y2, z2);
00466 }
00467
00468 }
00469
00470
00471
00472
00473
00474 GlobalPoint MuonShowerInformationFiller::crossingPoint(const GlobalPoint& p1,
00475 const GlobalPoint& p2,
00476 const ForwardDetLayer* dl) const {
00477
00478 const BoundDisk& bc = dl->specificSurface();
00479 return crossingPoint(p1, p2, bc);
00480
00481 }
00482
00483 GlobalPoint MuonShowerInformationFiller::crossingPoint(const GlobalPoint& p1,
00484 const GlobalPoint& p2,
00485 const BoundDisk& disk) const {
00486
00487 float diskZ = disk.position().z();
00488 int endcap = diskZ > 0 ? 1 : (diskZ < 0 ? -1 : 0);
00489 diskZ = diskZ + endcap*dynamic_cast<const SimpleDiskBounds&>(disk.bounds()).thickness()/2.;
00490
00491 GlobalVector dp = p1 - p2;
00492
00493 float slopeZ = dp.z()/dp.y();
00494 float y1 = diskZ / slopeZ;
00495
00496 float slopeX = dp.z()/dp.x();
00497 float x1 = diskZ / slopeX;
00498
00499 float z1 = diskZ;
00500
00501 if (p2.z()*z1 > 0) {
00502 return GlobalPoint(x1, y1, z1);
00503 } else {
00504 return GlobalPoint(0, 0, 0);
00505 }
00506
00507 }
00508
00509
00510
00511
00512
00513 vector<const GeomDet*> MuonShowerInformationFiller::dtPositionToDets(const GlobalPoint& gp) const {
00514
00515 int minwheel = -3;
00516 int maxwheel = -3;
00517 if ( gp.z() < -680.0 ) { minwheel = -3; maxwheel = -3;}
00518 else if ( gp.z() < -396.0 ) { minwheel = -2; maxwheel = -1;}
00519 else if (gp.z() < -126.8) { minwheel = -2; maxwheel = 0; }
00520 else if (gp.z() < 126.8) { minwheel = -1; maxwheel = 1; }
00521 else if (gp.z() < 396.0) { minwheel = 0; maxwheel = 2; }
00522 else if (gp.z() < 680.0) { minwheel = 1; maxwheel = 2; }
00523 else { minwheel = 3; maxwheel = 3; }
00524
00525 int station = 5;
00526 if ( gp.perp() > 680.0 && gp.perp() < 755.0 ) station = 4;
00527 else if ( gp.perp() > 580.0 ) station = 3;
00528 else if ( gp.perp() > 480.0 ) station = 2;
00529 else if ( gp.perp() > 380.0 ) station = 1;
00530 else station = 0;
00531
00532 vector<int> sectors;
00533
00534 float phistep = M_PI/6;
00535
00536 float phigp = (float)gp.phi();
00537
00538 if ( fabs(deltaPhi(phigp, 0*phistep)) < phistep ) sectors.push_back(1);
00539 if ( fabs(deltaPhi(phigp, phistep)) < phistep ) sectors.push_back(2);
00540 if ( fabs(deltaPhi(phigp, 2*phistep)) < phistep ) sectors.push_back(3);
00541 if ( fabs(deltaPhi(phigp, 3*phistep)) < phistep ) {
00542 sectors.push_back(4);
00543 if (station == 4) sectors.push_back(13);
00544 }
00545 if ( fabs(deltaPhi(phigp, 4*phistep)) < phistep ) sectors.push_back(5);
00546 if ( fabs(deltaPhi(phigp, 5*phistep)) < phistep ) sectors.push_back(6);
00547 if ( fabs(deltaPhi(phigp, 6*phistep)) < phistep ) sectors.push_back(7);
00548 if ( fabs(deltaPhi(phigp, 7*phistep)) < phistep ) sectors.push_back(8);
00549 if ( fabs(deltaPhi(phigp, 8*phistep)) < phistep ) sectors.push_back(9);
00550 if ( fabs(deltaPhi(phigp, 9*phistep)) < phistep ) {
00551 sectors.push_back(10);
00552 if (station == 4) sectors.push_back(14);
00553 }
00554 if ( fabs(deltaPhi(phigp, 10*phistep)) < phistep ) sectors.push_back(11);
00555 if ( fabs(deltaPhi(phigp, 11*phistep)) < phistep ) sectors.push_back(12);
00556
00557 LogTrace(category_) << "DT position to dets" << endl;
00558 LogTrace(category_) << "number of sectors to consider: " << sectors.size() << endl;
00559 LogTrace(category_) << "station: " << station << " wheels: " << minwheel << " " << maxwheel << endl;
00560
00561 vector<const GeomDet*> result;
00562 if (station > 4 || station < 1) return result;
00563 if (minwheel > 2 || maxwheel < -2) return result;
00564
00565 for (vector<int>::const_iterator isector = sectors.begin(); isector != sectors.end(); ++isector ) {
00566 for (int iwheel = minwheel; iwheel != maxwheel + 1; ++iwheel) {
00567 DTChamberId chamberid(iwheel, station, (*isector));
00568 result.push_back(theService->trackingGeometry()->idToDet(chamberid));
00569 }
00570 }
00571
00572 LogTrace(category_) << "number of GeomDets for this track: " << result.size() << endl;
00573
00574 return result;
00575
00576 }
00577
00578
00579
00580
00581
00582 vector<const GeomDet*> MuonShowerInformationFiller::cscPositionToDets(const GlobalPoint& gp) const {
00583
00584
00585 int endcap = 0;
00586 if (gp.z() > 0) {endcap = 1;} else {endcap = 2;}
00587
00588
00589 int station = 5;
00590
00591
00592 if ( fabs(gp.z()) > 1000. && fabs(gp.z()) < 1055.0 ) {
00593 station = 4;
00594 }
00595 else if ( fabs(gp.z()) > 910.0 && fabs(gp.z()) < 965.0) {
00596 station = 3;
00597 }
00598 else if ( fabs(gp.z()) > 800.0 && fabs(gp.z()) < 860.0) {
00599 station = 2;
00600 }
00601 else if ( fabs(gp.z()) > 570.0 && fabs(gp.z()) < 730.0) {
00602 station = 1;
00603 }
00604
00605 vector<int> sectors;
00606
00607 float phistep1 = M_PI/18.;
00608 float phistep2 = M_PI/9.;
00609 float phigp = (float)gp.phi();
00610
00611 int ring = -1;
00612
00613
00614 if (station == 1) {
00615
00616
00617 if (gp.perp() > 100 && gp.perp() < 270) ring = 1;
00618 else if (gp.perp() > 270 && gp.perp() < 450) ring = 2;
00619 else if (gp.perp() > 450 && gp.perp() < 695) ring = 3;
00620 else if (gp.perp() > 100 && gp.perp() < 270) ring = 4;
00621
00622 }
00623 else if (station == 2) {
00624
00625 if (gp.perp() > 140 && gp.perp() < 350) ring = 1;
00626 else if (gp.perp() > 350 && gp.perp() < 700) ring = 2;
00627
00628 }
00629 else if (station == 3) {
00630
00631 if (gp.perp() > 160 && gp.perp() < 350) ring = 1;
00632 else if (gp.perp() > 350 && gp.perp() < 700) ring = 2;
00633
00634 }
00635 else if (station == 4) {
00636
00637 if (gp.perp() > 175 && gp.perp() < 350) ring = 1;
00638 else if (gp.perp() > 350 && gp.perp() < 700) ring = 2;
00639
00640 }
00641
00642 if (station > 1 && ring == 1) {
00643
00644
00645 for (int i = 0; i < 18; i++) {
00646 if ( fabs(deltaPhi(phigp, i*phistep2)) < phistep2 ) sectors.push_back(i+1);
00647 }
00648
00649 } else {
00650
00651
00652 for (int i = 0; i < 36; i++) {
00653 if ( fabs(deltaPhi(phigp, i*phistep1)) < phistep1 ) sectors.push_back(i+1);
00654 }
00655 }
00656
00657 LogTrace(category_) << "CSC position to dets" << endl;
00658 LogTrace(category_) << "ring: " << ring << endl;
00659 LogTrace(category_) << "endcap: " << endcap << endl;
00660 LogTrace(category_) << "station: " << station << endl;
00661 LogTrace(category_) << "CSC number of sectors to consider: " << sectors.size() << endl;
00662
00663
00664
00665 vector<const GeomDet*> result;
00666 if (station > 4 || station < 1) return result;
00667 if (endcap == 0) return result;
00668 if (ring == -1) return result;
00669
00670 int minlayer = 1;
00671 int maxlayer = 6;
00672
00673 for (vector<int>::const_iterator isector = sectors.begin(); isector != sectors.end(); ++isector) {
00674 for (int ilayer = minlayer; ilayer != maxlayer + 1; ++ ilayer) {
00675 CSCDetId cscid(endcap, station, ring, (*isector), ilayer);
00676 result.push_back(theService->trackingGeometry()->idToDet(cscid));
00677 }
00678 }
00679
00680 return result;
00681
00682 }
00683
00684
00685
00686
00687 void MuonShowerInformationFiller::fillHitsByStation(const reco::Muon& muon) {
00688
00689 reco::TrackRef track;
00690 if ( muon.isGlobalMuon() ) track = muon.globalTrack();
00691 else if ( muon.isStandAloneMuon() ) track = muon.outerTrack();
00692 else return;
00693
00694
00695 vector<MuonRecHitContainer> muonRecHits(4);
00696
00697
00698 MuonRecHitContainer muSegments[4];
00699
00700
00701 vector<const GeomDet*> compatibleLayers = getCompatibleDets(*track);
00702
00703
00704 MuonRecHitContainer tmpCSC1;
00705 bool dtOverlapToCheck = false;
00706 bool cscOverlapToCheck = false;
00707
00708 for (vector<const GeomDet*>::const_iterator igd = compatibleLayers.begin(); igd != compatibleLayers.end(); igd++ ) {
00709
00710
00711 DetId geoId = (*igd)->geographicalId();
00712
00713
00714 if (geoId.det()!= DetId::Muon) continue;
00715
00716
00717 if ( geoId.subdetId() == MuonSubdetId::DT ) {
00718
00719
00720 DTChamberId detid(geoId.rawId());
00721 int station = detid.station();
00722 int wheel = detid.wheel();
00723
00724
00725 muSegments[station-1] = recHits4D(*igd, theDT4DRecSegments, theCSCSegments);
00726
00727
00728 if (abs(wheel) == 2 && station != 4 && station != 1) dtOverlapToCheck = true;
00729
00730
00731 for (int isuperlayer = DTChamberId::minSuperLayerId; isuperlayer != DTChamberId::maxSuperLayerId + 1; ++isuperlayer) {
00732
00733 for (int ilayer = DTChamberId::minLayerId; ilayer != DTChamberId::maxLayerId+1; ++ilayer) {
00734 DTLayerId lid(detid, isuperlayer, ilayer);
00735 DTRecHitCollection::range dRecHits = theDTRecHits->get(lid);
00736 for (DTRecHitCollection::const_iterator rechit = dRecHits.first; rechit != dRecHits.second;++rechit) {
00737 vector<const TrackingRecHit*> subrechits = (*rechit).recHits();
00738
00739 for (vector<const TrackingRecHit*>::iterator irechit = subrechits.begin(); irechit != subrechits.end(); ++irechit) {
00740 muonRecHits.at(station-1).push_back(MuonTransientTrackingRecHit::specificBuild((&**igd),&**irechit));
00741 }
00742 }
00743 }
00744 }
00745 }
00746 else if (geoId.subdetId() == MuonSubdetId::CSC) {
00747
00748
00749 CSCDetId did(geoId.rawId());
00750 int station = did.station();
00751 int ring = did.ring();
00752
00753
00754 muSegments[station-1] = recHits4D(*igd, theDT4DRecSegments, theCSCSegments);
00755
00756 if ((station == 1 && ring == 3) && dtOverlapToCheck) cscOverlapToCheck = true;
00757
00758
00759 CSCRecHit2DCollection::range dRecHits = theCSCRecHits->get(did);
00760 for (CSCRecHit2DCollection::const_iterator rechit = dRecHits.first; rechit != dRecHits.second; ++rechit) {
00761
00762 if (!cscOverlapToCheck) {
00763 muonRecHits.at(station-1).push_back(MuonTransientTrackingRecHit::specificBuild((&**igd),&*rechit));
00764 } else {
00765 tmpCSC1.push_back(MuonTransientTrackingRecHit::specificBuild((&**igd),&*rechit));
00766
00767
00768 MuonRecHitContainer temp = findPerpCluster(tmpCSC1);
00769 if (temp.empty()) continue;
00770
00771 float center;
00772 if (temp.size() > 1) {
00773 center = (temp.front()->globalPosition().perp() + temp.back()->globalPosition().perp())/2.;
00774 } else {
00775 center = temp.front()->globalPosition().perp();
00776 }
00777 temp.clear();
00778
00779 if (center > 550.) {
00780 muonRecHits.at(2).insert(muonRecHits.at(2).end(),tmpCSC1.begin(),tmpCSC1.end());
00781 } else {
00782 muonRecHits.at(1).insert(muonRecHits.at(1).end(),tmpCSC1.begin(),tmpCSC1.end());
00783 }
00784 tmpCSC1.clear();
00785 }
00786 }
00787 } else if (geoId.subdetId() == MuonSubdetId::RPC) {
00788 LogTrace(category_) << "Wrong subdet id" << endl;
00789 }
00790 }
00791
00792 LogTrace(category_) << "Number of hits from DT 4D segments or 2D CSC segments, by station "
00793 << muSegments[0].size() << " "
00794 << muSegments[1].size() << " "
00795 << muSegments[2].size() << " "
00796 << muSegments[3].size() << endl;
00797
00798
00799 for (int stat = 0; stat < 4; stat++) {
00800 theCorrelatedStationHits[stat] = numberOfCorrelatedHits(muSegments[stat]);
00801 theAllStationHits[stat] = muonRecHits[stat].size();
00802 }
00803 LogTrace(category_) << "Hits used by the segments, by station "
00804 << theCorrelatedStationHits.at(0) << " "
00805 << theCorrelatedStationHits.at(1) << " "
00806 << theCorrelatedStationHits.at(2) << " "
00807 << theCorrelatedStationHits.at(3) << endl;
00808
00809 LogTrace(category_) << "All 1D hits, by station "
00810 << theAllStationHits.at(0) << " "
00811 << theAllStationHits.at(1) << " "
00812 << theAllStationHits.at(2) << " "
00813 << theAllStationHits.at(3) << endl;
00814
00815
00816 MuonTransientTrackingRecHit::MuonRecHitContainer muonRecHitsPhiTemp, muonRecHitsThetaTemp, muonRecHitsPhiBest, muonRecHitsThetaBest;
00817
00818 for ( int stat = 0; stat != 4; stat++ ) {
00819 if (!muonRecHits[stat].empty()) {
00820 stable_sort(muonRecHits[stat].begin(), muonRecHits[stat].end(), LessPhi());
00821
00822 float dphimax = 0;
00823 float dthetamax = 0;
00824 for (MuonTransientTrackingRecHit::MuonRecHitContainer::const_iterator iseed = muonRecHits[stat].begin(); iseed != muonRecHits[stat].end(); ++iseed) {
00825 if (!(*iseed)->isValid()) continue;
00826 GlobalPoint refpoint = (*iseed)->globalPosition();
00827 muonRecHitsPhiTemp.clear();
00828 muonRecHitsThetaTemp.clear();
00829 muonRecHitsPhiTemp = findPhiCluster(muonRecHits[stat], refpoint);
00830 muonRecHitsThetaTemp = findThetaCluster(muonRecHits[stat], refpoint);
00831 if (muonRecHitsPhiTemp.size() > 1) {
00832 float dphi = fabs(deltaPhi((float)muonRecHitsPhiTemp.back()->globalPosition().phi(), (float)muonRecHitsPhiTemp.front()->globalPosition().phi()));
00833 if (dphi > dphimax) {
00834 dphimax = dphi;
00835 muonRecHitsPhiBest = muonRecHitsPhiTemp;
00836 }
00837 }
00838 }
00839 if (muonRecHitsThetaTemp.size() > 1) {
00840 float dtheta = fabs((float)muonRecHitsThetaTemp.back()->globalPosition().theta() - (float)muonRecHitsThetaTemp.front()->globalPosition().theta());
00841 if (dtheta > dthetamax) {
00842 dthetamax = dtheta;
00843 muonRecHitsThetaBest = muonRecHitsThetaTemp;
00844 }
00845 }
00846
00847 if (muonRecHitsThetaBest.size() > 1 && muonRecHitsPhiBest.size() > 1)
00848 theStationShowerDeltaR.at(stat) = pow(pow(muonRecHitsPhiBest.front()->globalPosition().phi()-muonRecHitsPhiBest.back()->globalPosition().phi(),2)+pow(muonRecHitsThetaBest.front()->globalPosition().theta()-muonRecHitsThetaBest.back()->globalPosition().theta(),2),0.5);
00849
00850 LogTrace(category_) << "deltaR around a track containing all the station hits, by station "
00851 << theStationShowerDeltaR.at(0) << " "
00852 << theStationShowerDeltaR.at(1) << " "
00853 << theStationShowerDeltaR.at(2) << " "
00854 << theStationShowerDeltaR.at(3) << endl;
00855
00856
00857 if (!muonRecHitsPhiBest.empty()) {
00858 muonRecHits[stat] = muonRecHitsPhiBest;
00859 stable_sort(muonRecHits[stat].begin(), muonRecHits[stat].end(), LessAbsMag());
00860 muonRecHits[stat].front();
00861 GlobalPoint refpoint = muonRecHits[stat].front()->globalPosition();
00862 theStationShowerTSize.at(stat) = refpoint.mag() * dphimax;
00863 }
00864 }
00865 }
00866
00867 LogTrace(category_) << "Transverse cluster size, by station "
00868 << theStationShowerTSize.at(0) << " "
00869 << theStationShowerTSize.at(1) << " "
00870 << theStationShowerTSize.at(2) << " "
00871 << theStationShowerTSize.at(3) << endl;
00872
00873 return;
00874
00875 }