00001
00002
00017
00018
00019
00020
00021 #include "RecoMuon/L2MuonSeedGenerator/src/L2MuonSeedGenerator.h"
00022
00023
00024 #include "DataFormats/MuonSeed/interface/L2MuonTrajectorySeed.h"
00025 #include "DataFormats/MuonSeed/interface/L2MuonTrajectorySeedCollection.h"
00026 #include "DataFormats/TrajectoryState/interface/PTrajectoryStateOnDet.h"
00027 #include "DataFormats/MuonDetId/interface/DTChamberId.h"
00028 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00029 #include "DataFormats/L1GlobalMuonTrigger/interface/L1MuGMTExtendedCand.h"
00030 #include "DataFormats/L1GlobalMuonTrigger/interface/L1MuGMTReadoutCollection.h"
00031 #include "DataFormats/L1GlobalMuonTrigger/interface/L1MuRegionalCand.h"
00032 #include "DataFormats/L1Trigger/interface/L1MuonParticle.h"
00033 #include "DataFormats/L1Trigger/interface/L1MuonParticleFwd.h"
00034 #include "DataFormats/Common/interface/Handle.h"
00035 #include "DataFormats/GeometrySurface/interface/BoundCylinder.h"
00036
00037 #include "CLHEP/Vector/ThreeVector.h"
00038
00039 #include "Geometry/CommonDetUnit/interface/GeomDetEnumerators.h"
00040
00041
00042 #include "FWCore/Framework/interface/EventSetup.h"
00043 #include "FWCore/Framework/interface/Event.h"
00044 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00045 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00046
00047 #include "TrackingTools/TrajectoryParametrization/interface/GlobalTrajectoryParameters.h"
00048 #include "TrackingTools/TrajectoryParametrization/interface/CurvilinearTrajectoryError.h"
00049 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00050 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
00051 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00052 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
00053 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00054
00055 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
00056 #include "RecoMuon/TrackingTools/interface/MuonPatternRecoDumper.h"
00057
00058 using namespace std;
00059 using namespace edm;
00060 using namespace l1extra;
00061
00062
00063 L2MuonSeedGenerator::L2MuonSeedGenerator(const edm::ParameterSet& iConfig) :
00064 theSource(iConfig.getParameter<InputTag>("InputObjects")),
00065 theL1GMTReadoutCollection(iConfig.getParameter<InputTag>("GMTReadoutCollection")),
00066 thePropagatorName(iConfig.getParameter<string>("Propagator")),
00067 theL1MinPt(iConfig.getParameter<double>("L1MinPt")),
00068 theL1MaxEta(iConfig.getParameter<double>("L1MaxEta")),
00069 theL1MinQuality(iConfig.getParameter<unsigned int>("L1MinQuality")){
00070
00071
00072 ParameterSet serviceParameters = iConfig.getParameter<ParameterSet>("ServiceParameters");
00073
00074
00075 theService = new MuonServiceProxy(serviceParameters);
00076
00077
00078 theEstimator = new Chi2MeasurementEstimator(10000.);
00079
00080 produces<L2MuonTrajectorySeedCollection>();
00081 }
00082
00083
00084 L2MuonSeedGenerator::~L2MuonSeedGenerator(){
00085 if (theService) delete theService;
00086 if (theEstimator) delete theEstimator;
00087 }
00088
00089 void L2MuonSeedGenerator::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00090 {
00091 const std::string metname = "Muon|RecoMuon|L2MuonSeedGenerator";
00092 MuonPatternRecoDumper debug;
00093
00094 auto_ptr<L2MuonTrajectorySeedCollection> output(new L2MuonTrajectorySeedCollection());
00095
00096
00097 edm::Handle<L1MuGMTReadoutCollection> gmtrc_handle;
00098 iEvent.getByLabel(theL1GMTReadoutCollection,gmtrc_handle);
00099 L1MuGMTReadoutRecord const& gmtrr = gmtrc_handle.product()->getRecord(0);
00100
00101 edm::Handle<L1MuonParticleCollection> muColl;
00102 iEvent.getByLabel(theSource, muColl);
00103 LogTrace(metname) << "Number of muons " << muColl->size() << endl;
00104
00105 L1MuonParticleCollection::const_iterator it;
00106 L1MuonParticleRef::key_type l1ParticleIndex = 0;
00107
00108 for(it = muColl->begin(); it != muColl->end(); ++it,++l1ParticleIndex) {
00109
00110 const L1MuGMTExtendedCand muonCand = (*it).gmtMuonCand();
00111 unsigned int quality = 0;
00112 bool valid_charge = false;;
00113
00114 if ( muonCand.empty() ) {
00115 LogWarning(metname) << "L2MuonSeedGenerator: WARNING, no L1MuGMTCand! " << endl;
00116 LogWarning(metname) << "L2MuonSeedGenerator: this should make sense only within MC tests" << endl;
00117
00118 quality = 7;
00119 valid_charge = true;
00120 }
00121 else {
00122 quality = muonCand.quality();
00123 valid_charge = muonCand.charge_valid();
00124 }
00125
00126 float pt = (*it).pt();
00127 float eta = (*it).eta();
00128 float theta = 2*atan(exp(-eta));
00129 float phi = (*it).phi();
00130 int charge = (*it).charge();
00131
00132 if (!valid_charge) charge = 0;
00133 bool barrel = !(*it).isForward();
00134
00135
00136
00137 if ( !(muonCand.empty()) ) {
00138 int idx = -1;
00139 vector<L1MuRegionalCand> rmc;
00140 if ( !muonCand.isRPC() ) {
00141 idx = muonCand.getDTCSCIndex();
00142 if (muonCand.isFwd()) rmc = gmtrr.getCSCCands();
00143 else rmc = gmtrr.getDTBXCands();
00144 } else {
00145 idx = muonCand.getRPCIndex();
00146 if (muonCand.isFwd()) rmc = gmtrr.getFwdRPCCands();
00147 else rmc = gmtrr.getBrlRPCCands();
00148 }
00149 if (idx>=0) {
00150 eta = rmc[idx].etaValue();
00151
00152
00153 if (!valid_charge) charge = rmc[idx].chargeValue();
00154 }
00155 }
00156
00157 if ( pt < theL1MinPt || fabs(eta) > theL1MaxEta ) continue;
00158
00159 LogTrace(metname) << "New L2 Muon Seed";
00160 LogTrace(metname) << "Pt = " << pt << " GeV/c";
00161 LogTrace(metname) << "eta = " << eta;
00162 LogTrace(metname) << "theta = " << theta << " rad";
00163 LogTrace(metname) << "phi = " << phi << " rad";
00164 LogTrace(metname) << "charge = "<< charge;
00165 LogTrace(metname) << "In Barrel? = "<< barrel;
00166
00167 if ( quality <= theL1MinQuality ) continue;
00168 LogTrace(metname) << "quality = "<< quality;
00169
00170
00171 theService->update(iSetup);
00172
00173 const DetLayer *detLayer = 0;
00174 float radius = 0.;
00175
00176 Hep3Vector vec(0.,1.,0.);
00177 vec.setTheta(theta);
00178 vec.setPhi(phi);
00179
00180
00181 if ( barrel ){
00182 LogTrace(metname) << "The seed is in the barrel";
00183
00184
00185 DetId id = DTChamberId(0,2,0);
00186 detLayer = theService->detLayerGeometry()->idToLayer(id);
00187 LogTrace(metname) << "L2 Layer: " << debug.dumpLayer(detLayer);
00188
00189 const BoundSurface* sur = &(detLayer->surface());
00190 const BoundCylinder* bc = dynamic_cast<const BoundCylinder*>(sur);
00191
00192 radius = fabs(bc->radius()/sin(theta));
00193
00194 LogTrace(metname) << "radius "<<radius;
00195
00196 if ( pt < 3.5 ) pt = 3.5;
00197 }
00198 else {
00199 LogTrace(metname) << "The seed is in the endcap";
00200
00201 DetId id;
00202
00203 if ( theta < Geom::pi()/2. )
00204 id = CSCDetId(1,2,0,0,0);
00205 else
00206 id = CSCDetId(2,2,0,0,0);
00207
00208 detLayer = theService->detLayerGeometry()->idToLayer(id);
00209 LogTrace(metname) << "L2 Layer: " << debug.dumpLayer(detLayer);
00210
00211 radius = fabs(detLayer->position().z()/cos(theta));
00212
00213 if( pt < 1.0) pt = 1.0;
00214 }
00215
00216 vec.setMag(radius);
00217
00218 GlobalPoint pos(vec.x(),vec.y(),vec.z());
00219
00220 GlobalVector mom(pt*cos(phi), pt*sin(phi), pt*cos(theta)/sin(theta));
00221
00222 GlobalTrajectoryParameters param(pos,mom,charge,&*theService->magneticField());
00223 AlgebraicSymMatrix mat(5,0);
00224
00225 mat[0][0] = (0.25/pt)*(0.25/pt);
00226 if ( !barrel ) mat[0][0] = (0.4/pt)*(0.4/pt);
00227
00228
00229 if (!valid_charge) mat[0][0] = (1./pt)*(1./pt);
00230
00231 mat[1][1] = 0.05*0.05;
00232 mat[2][2] = 0.2*0.2;
00233 mat[3][3] = 20.*20.;
00234 mat[4][4] = 20.*20.;
00235
00236 CurvilinearTrajectoryError error(mat);
00237
00238 const FreeTrajectoryState state(param,error);
00239
00240 LogTrace(metname) << "Free trajectory State from the parameters";
00241 LogTrace(metname) << debug.dumpFTS(state);
00242
00243
00244 TrajectoryStateOnSurface tsos = theService->propagator(thePropagatorName)->propagate(state, detLayer->surface());
00245
00246 LogTrace(metname) << "State after the propagation on the layer";
00247 LogTrace(metname) << debug.dumpLayer(detLayer);
00248 LogTrace(metname) << debug.dumpFTS(state);
00249
00250 if (tsos.isValid()) {
00251
00252 std::vector< pair<const GeomDet*,TrajectoryStateOnSurface> >
00253 detsWithStates = detLayer->compatibleDets(tsos,
00254 *theService->propagator(thePropagatorName),
00255 *theEstimator);
00256 if (detsWithStates.size()){
00257 TrajectoryStateTransform tsTransform;
00258
00259 TrajectoryStateOnSurface newTSOS = detsWithStates.front().second;
00260 const GeomDet *newTSOSDet = detsWithStates.front().first;
00261
00262 LogTrace(metname) << "Most compatible det";
00263 LogTrace(metname) << debug.dumpMuonId(newTSOSDet->geographicalId());
00264
00265 if (newTSOS.isValid()){
00266
00267 LogTrace(metname) << "State on it";
00268 LogTrace(metname) << debug.dumpTSOS(newTSOS);
00269
00270
00271 PTrajectoryStateOnDet *seedTSOS = tsTransform.persistentState( newTSOS,newTSOSDet->geographicalId().rawId());
00272
00273 edm::OwnVector<TrackingRecHit> container;
00274
00275 output->push_back(L2MuonTrajectorySeed(*seedTSOS,container,alongMomentum,
00276 L1MuonParticleRef(muColl,l1ParticleIndex)));
00277 }
00278 }
00279 }
00280
00281 }
00282
00283 iEvent.put(output);
00284 }
00285