CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/RecoMuon/MuonIdentification/src/MuonShowerInformationFiller.cc

Go to the documentation of this file.
00001 
00014 #include "RecoMuon/MuonIdentification/interface/MuonShowerInformationFiller.h"
00015 
00016 // system include files
00017 #include <memory>
00018 #include <algorithm>
00019 #include <iostream>
00020 
00021 // user include files
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 // Constructor
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 // Destructor
00100 //
00101 MuonShowerInformationFiller::~MuonShowerInformationFiller() {
00102   if (theService) delete theService;
00103 }
00104 
00105 //
00106 //Fill the MuonShower struct
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   // Update the services
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 // Set Event
00134 //
00135 void MuonShowerInformationFiller::setEvent(const edm::Event& event) {
00136 
00137   // get all the necesary products
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 // Set services
00154 //
00155 void MuonShowerInformationFiller::setServices(const EventSetup& setup) {
00156 
00157   // DetLayer Geometry
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   // Transient Rechit Builders
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 // Get hits owned by segments
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 // Find cluster
00257 //
00258 MuonTransientTrackingRecHit::MuonRecHitContainer 
00259 MuonShowerInformationFiller::findPhiCluster(MuonTransientTrackingRecHit::MuonRecHitContainer& muonRecHits, 
00260                               const GlobalPoint& refpoint) const {
00261 
00262   if ( muonRecHits.empty() ) return muonRecHits;
00263 
00264   //clustering step by phi
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   //clustering step by theta
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 //Used to treat overlap region
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 // Get compatible dets
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   // first take DT
00362   const vector<DetLayer*>& dtlayers = theService->detLayerGeometry()->allDTLayers();
00363 
00364   for (vector<DetLayer*>::const_iterator iLayer = dtlayers.begin(); iLayer != dtlayers.end(); ++iLayer) {
00365 
00366     // crossing points of track with cylinder
00367     GlobalPoint xPoint = crossingPoint(innerPos, outerPos, dynamic_cast<const BarrelDetLayer*>(*iLayer));
00368       
00369     // check if point is inside the detector
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     // check if point is inside the detector
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 // Intersection point of track with barrel layer
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   // there are two crossing points, return the one that is in the same quadrant as point of extrapolation
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 // Intersection point of track with a forward layer
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 // GeomDets along the track in DT
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 // GeomDets along the track in CSC
00581 //
00582 vector<const GeomDet*> MuonShowerInformationFiller::cscPositionToDets(const GlobalPoint& gp) const {
00583 
00584   // determine the endcap side
00585   int endcap = 0;
00586   if (gp.z() > 0) {endcap = 1;} else {endcap = 2;} 
00587 
00588   // determine the csc station and range of rings
00589   int station = 5;
00590 
00591   // check all rings in a station
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.; //for all the rings except first rings for stations > 1
00608   float phistep2 = M_PI/9.;
00609   float phigp = (float)gp.phi();
00610 
00611   int ring = -1;
00612 
00613   // determine the ring
00614   if (station == 1) {
00615 
00616 //FIX ME!!! 
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    // we have 18 sectors in that case
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    // we have 36 sectors in that case
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  // check exceptional cases
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 //Set class members
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   // split 1D rechits by station
00695   vector<MuonRecHitContainer> muonRecHits(4);
00696 
00697   // split 4D rechits by station
00698   MuonRecHitContainer muSegments[4];
00699 
00700   // get vector of GeomDets compatible with a track
00701   vector<const GeomDet*> compatibleLayers = getCompatibleDets(*track);
00702 
00703   // for special cases: CSC station 1
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     // get det id
00711     DetId geoId = (*igd)->geographicalId();
00712 
00713     // skip tracker hits
00714     if (geoId.det()!= DetId::Muon) continue;
00715 
00716     // DT 
00717     if ( geoId.subdetId() == MuonSubdetId::DT ) {
00718 
00719       // get station
00720       DTChamberId detid(geoId.rawId());
00721       int station = detid.station();
00722       int wheel = detid.wheel();
00723 
00724       // get 4D rechits per station
00725       muSegments[station-1] = recHits4D(*igd, theDT4DRecSegments, theCSCSegments);
00726 
00727       //check overlap certain wheels and stations
00728       if (abs(wheel) == 2 && station != 4 &&  station != 1) dtOverlapToCheck = true;
00729 
00730       // loop over all superlayers of a DT chamber
00731       for (int isuperlayer = DTChamberId::minSuperLayerId; isuperlayer != DTChamberId::maxSuperLayerId + 1; ++isuperlayer) {
00732         // loop over all layers inside the superlayer
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             // loop over rechits and put it into the vectors corresponding to superlayers
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       // get station
00749       CSCDetId did(geoId.rawId());
00750       int station = did.station();
00751       int ring = did.ring();
00752 
00753       //get 4D rechits by station
00754       muSegments[station-1] = recHits4D(*igd, theDT4DRecSegments, theCSCSegments);
00755 
00756       if ((station == 1 && ring == 3) && dtOverlapToCheck) cscOverlapToCheck = true;
00757 
00758       // split 1D rechits by station
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              //sort by perp, then insert to appropriate container
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   }//loop over GeomDets compatible with a track
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   // calculate number of all and correlated hits    
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   //station shower sizes
00816   MuonTransientTrackingRecHit::MuonRecHitContainer muonRecHitsPhiTemp, muonRecHitsThetaTemp, muonRecHitsPhiBest, muonRecHitsThetaBest;
00817   // send station hits to the clustering algorithm
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(); //starting from the one with smallest value of phi
00827           muonRecHitsPhiTemp.clear();
00828           muonRecHitsThetaTemp.clear();
00829           muonRecHitsPhiTemp = findPhiCluster(muonRecHits[stat], refpoint); //get clustered hits for this iseed
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          } //at least two hits
00838       }//loop over seeds 
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          } //at least two hits
00846      //fill deltaRs
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      //fill showerTs
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     }//not empty container
00865   }//loop over stations
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 }