CMS 3D CMS Logo

L2MuonSeedGenerator.cc

Go to the documentation of this file.
00001 //-------------------------------------------------
00002 //
00017 //
00018 //--------------------------------------------------
00019 
00020 // Class Header
00021 #include "RecoMuon/L2MuonSeedGenerator/src/L2MuonSeedGenerator.h"
00022 
00023 // Data Formats 
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 // Framework
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 // constructors
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   // service parameters
00072   ParameterSet serviceParameters = iConfig.getParameter<ParameterSet>("ServiceParameters");
00073   
00074   // the services
00075   theService = new MuonServiceProxy(serviceParameters);
00076 
00077   // the estimator
00078   theEstimator = new Chi2MeasurementEstimator(10000.);
00079 
00080   produces<L2MuonTrajectorySeedCollection>(); 
00081 }
00082 
00083 // destructor
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   // Muon particles and GMT readout collection
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       // FIXME! Temporary to handle the MC input
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     // Set charge=0 for the time being if the valid charge bit is zero
00132     if (!valid_charge) charge = 0;
00133     bool barrel = !(*it).isForward();
00134 
00135     // Get a better eta and charge from regional information
00136     // Phi has the same resolution in GMT than regionally, is not it?
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             //phi = rmc[idx].phiValue();
00152             // Use this charge if the valid charge bit is zero
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     // Update the services
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     // Get the det layer on which the state should be put
00181     if ( barrel ){
00182       LogTrace(metname) << "The seed is in the barrel";
00183       
00184       // MB2
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       // ME2
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);  // sigma^2(charge/abs_momentum)
00226     if ( !barrel ) mat[0][0] = (0.4/pt)*(0.4/pt);
00227 
00228     //Assign q/pt = 0 +- 1/pt if charge has been declared invalid
00229     if (!valid_charge) mat[0][0] = (1./pt)*(1./pt);
00230     
00231     mat[1][1] = 0.05*0.05;        // sigma^2(lambda)
00232     mat[2][2] = 0.2*0.2;          // sigma^2(phi)
00233     mat[3][3] = 20.*20.;          // sigma^2(x_transverse))
00234     mat[4][4] = 20.*20.;          // sigma^2(y_transverse))
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     // Propagate the state on the MB2/ME2 surface
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       // Get the compatible dets on the layer
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           // convert the TSOS into a PTSOD
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 

Generated on Tue Jun 9 17:44:16 2009 for CMSSW by  doxygen 1.5.4