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 #include "DataFormats/Math/interface/deltaR.h"
00037
00038 #include "CLHEP/Vector/ThreeVector.h"
00039
00040 #include "Geometry/CommonDetUnit/interface/GeomDetEnumerators.h"
00041
00042
00043 #include "FWCore/Framework/interface/EventSetup.h"
00044 #include "FWCore/Framework/interface/Event.h"
00045 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00046 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00047
00048 #include "TrackingTools/TrajectoryParametrization/interface/GlobalTrajectoryParameters.h"
00049 #include "TrackingTools/TrajectoryParametrization/interface/CurvilinearTrajectoryError.h"
00050 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00051 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
00052 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00053 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
00054 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00055
00056 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
00057 #include "RecoMuon/TrackingTools/interface/MuonPatternRecoDumper.h"
00058
00059 using namespace std;
00060 using namespace edm;
00061 using namespace l1extra;
00062
00063
00064 L2MuonSeedGenerator::L2MuonSeedGenerator(const edm::ParameterSet& iConfig) :
00065 theSource(iConfig.getParameter<InputTag>("InputObjects")),
00066 theL1GMTReadoutCollection(iConfig.getParameter<InputTag>("GMTReadoutCollection")),
00067 thePropagatorName(iConfig.getParameter<string>("Propagator")),
00068 theL1MinPt(iConfig.getParameter<double>("L1MinPt")),
00069 theL1MaxEta(iConfig.getParameter<double>("L1MaxEta")),
00070 theL1MinQuality(iConfig.getParameter<unsigned int>("L1MinQuality")),
00071 useOfflineSeed(iConfig.getUntrackedParameter<bool>("UseOfflineSeed", false)){
00072
00073
00074 ParameterSet serviceParameters = iConfig.getParameter<ParameterSet>("ServiceParameters");
00075
00076
00077 theService = new MuonServiceProxy(serviceParameters);
00078
00079
00080 theEstimator = new Chi2MeasurementEstimator(10000.);
00081
00082 if(useOfflineSeed)
00083 theOfflineSeedLabel = iConfig.getUntrackedParameter<InputTag>("OfflineSeedLabel");
00084
00085 produces<L2MuonTrajectorySeedCollection>();
00086 }
00087
00088
00089 L2MuonSeedGenerator::~L2MuonSeedGenerator(){
00090 if (theService) delete theService;
00091 if (theEstimator) delete theEstimator;
00092 }
00093
00094 void L2MuonSeedGenerator::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00095 {
00096 const std::string metname = "Muon|RecoMuon|L2MuonSeedGenerator";
00097 MuonPatternRecoDumper debug;
00098
00099 auto_ptr<L2MuonTrajectorySeedCollection> output(new L2MuonTrajectorySeedCollection());
00100
00101
00102 edm::Handle<L1MuGMTReadoutCollection> gmtrc_handle;
00103 iEvent.getByLabel(theL1GMTReadoutCollection,gmtrc_handle);
00104 L1MuGMTReadoutRecord const& gmtrr = gmtrc_handle.product()->getRecord(0);
00105
00106 edm::Handle<L1MuonParticleCollection> muColl;
00107 iEvent.getByLabel(theSource, muColl);
00108 LogTrace(metname) << "Number of muons " << muColl->size() << endl;
00109
00110 edm::Handle<edm::View<TrajectorySeed> > offlineSeedHandle;
00111 vector<int> offlineSeedMap;
00112 if(useOfflineSeed) {
00113 iEvent.getByLabel(theOfflineSeedLabel, offlineSeedHandle);
00114 LogTrace(metname) << "Number of offline seeds " << offlineSeedHandle->size() << endl;
00115 offlineSeedMap = vector<int>(offlineSeedHandle->size(), 0);
00116 }
00117
00118 L1MuonParticleCollection::const_iterator it;
00119 L1MuonParticleRef::key_type l1ParticleIndex = 0;
00120
00121 for(it = muColl->begin(); it != muColl->end(); ++it,++l1ParticleIndex) {
00122
00123 const L1MuGMTExtendedCand muonCand = (*it).gmtMuonCand();
00124 unsigned int quality = 0;
00125 bool valid_charge = false;;
00126
00127 if ( muonCand.empty() ) {
00128 LogWarning(metname) << "L2MuonSeedGenerator: WARNING, no L1MuGMTCand! " << endl;
00129 LogWarning(metname) << "L2MuonSeedGenerator: this should make sense only within MC tests" << endl;
00130
00131 quality = 7;
00132 valid_charge = true;
00133 }
00134 else {
00135 quality = muonCand.quality();
00136 valid_charge = muonCand.charge_valid();
00137 }
00138
00139 float pt = (*it).pt();
00140 float eta = (*it).eta();
00141 float theta = 2*atan(exp(-eta));
00142 float phi = (*it).phi();
00143 int charge = (*it).charge();
00144
00145 if (!valid_charge) charge = 0;
00146 bool barrel = !(*it).isForward();
00147
00148
00149
00150 if ( !(muonCand.empty()) ) {
00151 int idx = -1;
00152 vector<L1MuRegionalCand> rmc;
00153 if ( !muonCand.isRPC() ) {
00154 idx = muonCand.getDTCSCIndex();
00155 if (muonCand.isFwd()) rmc = gmtrr.getCSCCands();
00156 else rmc = gmtrr.getDTBXCands();
00157 } else {
00158 idx = muonCand.getRPCIndex();
00159 if (muonCand.isFwd()) rmc = gmtrr.getFwdRPCCands();
00160 else rmc = gmtrr.getBrlRPCCands();
00161 }
00162 if (idx>=0) {
00163 eta = rmc[idx].etaValue();
00164
00165
00166 if (!valid_charge) charge = rmc[idx].chargeValue();
00167 }
00168 }
00169
00170 if ( pt < theL1MinPt || fabs(eta) > theL1MaxEta ) continue;
00171
00172 LogTrace(metname) << "New L2 Muon Seed";
00173 LogTrace(metname) << "Pt = " << pt << " GeV/c";
00174 LogTrace(metname) << "eta = " << eta;
00175 LogTrace(metname) << "theta = " << theta << " rad";
00176 LogTrace(metname) << "phi = " << phi << " rad";
00177 LogTrace(metname) << "charge = "<< charge;
00178 LogTrace(metname) << "In Barrel? = "<< barrel;
00179
00180 if ( quality <= theL1MinQuality ) continue;
00181 LogTrace(metname) << "quality = "<< quality;
00182
00183
00184 theService->update(iSetup);
00185
00186 const DetLayer *detLayer = 0;
00187 float radius = 0.;
00188
00189 CLHEP::Hep3Vector vec(0.,1.,0.);
00190 vec.setTheta(theta);
00191 vec.setPhi(phi);
00192
00193
00194 if ( barrel ){
00195 LogTrace(metname) << "The seed is in the barrel";
00196
00197
00198 DetId id = DTChamberId(0,2,0);
00199 detLayer = theService->detLayerGeometry()->idToLayer(id);
00200 LogTrace(metname) << "L2 Layer: " << debug.dumpLayer(detLayer);
00201
00202 const BoundSurface* sur = &(detLayer->surface());
00203 const BoundCylinder* bc = dynamic_cast<const BoundCylinder*>(sur);
00204
00205 radius = fabs(bc->radius()/sin(theta));
00206
00207 LogTrace(metname) << "radius "<<radius;
00208
00209 if ( pt < 3.5 ) pt = 3.5;
00210 }
00211 else {
00212 LogTrace(metname) << "The seed is in the endcap";
00213
00214 DetId id;
00215
00216 if ( theta < Geom::pi()/2. )
00217 id = CSCDetId(1,2,0,0,0);
00218 else
00219 id = CSCDetId(2,2,0,0,0);
00220
00221 detLayer = theService->detLayerGeometry()->idToLayer(id);
00222 LogTrace(metname) << "L2 Layer: " << debug.dumpLayer(detLayer);
00223
00224 radius = fabs(detLayer->position().z()/cos(theta));
00225
00226 if( pt < 1.0) pt = 1.0;
00227 }
00228
00229 vec.setMag(radius);
00230
00231 GlobalPoint pos(vec.x(),vec.y(),vec.z());
00232
00233 GlobalVector mom(pt*cos(phi), pt*sin(phi), pt*cos(theta)/sin(theta));
00234
00235 GlobalTrajectoryParameters param(pos,mom,charge,&*theService->magneticField());
00236 AlgebraicSymMatrix55 mat;
00237
00238 mat[0][0] = (0.25/pt)*(0.25/pt);
00239 if ( !barrel ) mat[0][0] = (0.4/pt)*(0.4/pt);
00240
00241
00242 if (!valid_charge) mat[0][0] = (1./pt)*(1./pt);
00243
00244 mat[1][1] = 0.05*0.05;
00245 mat[2][2] = 0.2*0.2;
00246 mat[3][3] = 20.*20.;
00247 mat[4][4] = 20.*20.;
00248
00249 CurvilinearTrajectoryError error(mat);
00250
00251 const FreeTrajectoryState state(param,error);
00252
00253 LogTrace(metname) << "Free trajectory State from the parameters";
00254 LogTrace(metname) << debug.dumpFTS(state);
00255
00256
00257 TrajectoryStateOnSurface tsos = theService->propagator(thePropagatorName)->propagate(state, detLayer->surface());
00258
00259 LogTrace(metname) << "State after the propagation on the layer";
00260 LogTrace(metname) << debug.dumpLayer(detLayer);
00261 LogTrace(metname) << debug.dumpFTS(state);
00262
00263 if (tsos.isValid()) {
00264
00265 std::vector< pair<const GeomDet*,TrajectoryStateOnSurface> >
00266 detsWithStates = detLayer->compatibleDets(tsos,
00267 *theService->propagator(thePropagatorName),
00268 *theEstimator);
00269 if (detsWithStates.size()){
00270
00271 TrajectoryStateOnSurface newTSOS = detsWithStates.front().second;
00272 const GeomDet *newTSOSDet = detsWithStates.front().first;
00273
00274 LogTrace(metname) << "Most compatible det";
00275 LogTrace(metname) << debug.dumpMuonId(newTSOSDet->geographicalId());
00276
00277 LogDebug(metname) << "L1 info: Det and State:";
00278 LogDebug(metname) << debug.dumpMuonId(newTSOSDet->geographicalId());
00279
00280 if (newTSOS.isValid()){
00281
00282
00283
00284 LogDebug(metname) << "pos: (r=" << newTSOS.globalPosition().mag() << ", phi="
00285 << newTSOS.globalPosition().phi() << ", eta=" << newTSOS.globalPosition().eta() << ")";
00286 LogDebug(metname) << "mom: (q*pt=" << newTSOS.charge()*newTSOS.globalMomentum().perp() << ", phi="
00287 << newTSOS.globalMomentum().phi() << ", eta=" << newTSOS.globalMomentum().eta() << ")";
00288
00289
00290
00291
00292
00293 edm::OwnVector<TrackingRecHit> container;
00294
00295 if(useOfflineSeed) {
00296 const TrajectorySeed *assoOffseed =
00297 associateOfflineSeedToL1(offlineSeedHandle, offlineSeedMap, newTSOS);
00298
00299 if(assoOffseed!=0) {
00300 PTrajectoryStateOnDet const & seedTSOS = assoOffseed->startingState();
00301 TrajectorySeed::const_iterator
00302 tsci = assoOffseed->recHits().first,
00303 tscie = assoOffseed->recHits().second;
00304 for(; tsci!=tscie; ++tsci) {
00305 container.push_back(*tsci);
00306 }
00307 output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum,
00308 L1MuonParticleRef(muColl,l1ParticleIndex)));
00309 }
00310 else {
00311
00312 PTrajectoryStateOnDet const & seedTSOS = trajectoryStateTransform::persistentState( newTSOS,newTSOSDet->geographicalId().rawId());
00313 output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum,
00314 L1MuonParticleRef(muColl,l1ParticleIndex)));
00315 }
00316 }
00317 else {
00318
00319 PTrajectoryStateOnDet const & seedTSOS = trajectoryStateTransform::persistentState( newTSOS,newTSOSDet->geographicalId().rawId());
00320 output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum,
00321 L1MuonParticleRef(muColl,l1ParticleIndex)));
00322 }
00323 }
00324 }
00325 }
00326 }
00327
00328 iEvent.put(output);
00329 }
00330
00331
00332
00333 const TrajectorySeed* L2MuonSeedGenerator::associateOfflineSeedToL1( edm::Handle<edm::View<TrajectorySeed> > & offseeds,
00334 std::vector<int> & offseedMap,
00335 TrajectoryStateOnSurface & newTsos) {
00336
00337 const std::string metlabel = "Muon|RecoMuon|L2MuonSeedGenerator";
00338 MuonPatternRecoDumper debugtmp;
00339
00340 edm::View<TrajectorySeed>::const_iterator offseed, endOffseed = offseeds->end();
00341 const TrajectorySeed *selOffseed = 0;
00342 double bestDr = 99999.;
00343 unsigned int nOffseed(0);
00344 int lastOffseed(-1);
00345
00346 for(offseed=offseeds->begin(); offseed!=endOffseed; ++offseed, ++nOffseed) {
00347 if(offseedMap[nOffseed]!=0) continue;
00348 GlobalPoint glbPos = theService->trackingGeometry()->idToDet(offseed->startingState().detId())->surface().toGlobal(offseed->startingState().parameters().position());
00349 GlobalVector glbMom = theService->trackingGeometry()->idToDet(offseed->startingState().detId())->surface().toGlobal(offseed->startingState().parameters().momentum());
00350
00351
00352 double preDr = deltaR( newTsos.globalPosition().eta(), newTsos.globalPosition().phi(), glbPos.eta(), glbPos.phi() );
00353 if(preDr > 1.0) continue;
00354
00355 const FreeTrajectoryState offseedFTS(glbPos, glbMom, offseed->startingState().parameters().charge(), &*theService->magneticField());
00356 TrajectoryStateOnSurface offseedTsos = theService->propagator(thePropagatorName)->propagate(offseedFTS, newTsos.surface());
00357 LogDebug(metlabel) << "Offline seed info: Det and State" << std::endl;
00358 LogDebug(metlabel) << debugtmp.dumpMuonId(offseed->startingState().detId()) << std::endl;
00359
00360
00361 LogDebug(metlabel) << "pos: (r=" << offseedFTS.position().mag() << ", phi="
00362 << offseedFTS.position().phi() << ", eta=" << offseedFTS.position().eta() << ")" << std::endl;
00363 LogDebug(metlabel) << "mom: (q*pt=" << offseedFTS.charge()*offseedFTS.momentum().perp() << ", phi="
00364 << offseedFTS.momentum().phi() << ", eta=" << offseedFTS.momentum().eta() << ")" << std::endl << std::endl;
00365
00366
00367 if(offseedTsos.isValid()) {
00368 LogDebug(metlabel) << "Offline seed info after propagation to L1 layer:" << std::endl;
00369
00370
00371 LogDebug(metlabel) << "pos: (r=" << offseedTsos.globalPosition().mag() << ", phi="
00372 << offseedTsos.globalPosition().phi() << ", eta=" << offseedTsos.globalPosition().eta() << ")" << std::endl;
00373 LogDebug(metlabel) << "mom: (q*pt=" << offseedTsos.charge()*offseedTsos.globalMomentum().perp() << ", phi="
00374 << offseedTsos.globalMomentum().phi() << ", eta=" << offseedTsos.globalMomentum().eta() << ")" << std::endl << std::endl;
00375
00376 double newDr = deltaR( newTsos.globalPosition().eta(), newTsos.globalPosition().phi(),
00377 offseedTsos.globalPosition().eta(), offseedTsos.globalPosition().phi() );
00378 LogDebug(metlabel) << " -- DR = " << newDr << std::endl;
00379 if( newDr<0.3 && newDr<bestDr ) {
00380 LogDebug(metlabel) << " --> OK! " << newDr << std::endl << std::endl;
00381 selOffseed = &*offseed;
00382 bestDr = newDr;
00383 offseedMap[nOffseed] = 1;
00384 if(lastOffseed>-1) offseedMap[lastOffseed] = 0;
00385 lastOffseed = nOffseed;
00386 }
00387 else {
00388 LogDebug(metlabel) << " --> Rejected. " << newDr << std::endl << std::endl;
00389 }
00390 }
00391 else {
00392 LogDebug(metlabel) << "Invalid offline seed TSOS after propagation!" << std::endl << std::endl;
00393 }
00394 }
00395
00396 return selOffseed;
00397 }