CMS 3D CMS Logo

L2MuonSeedGeneratorFromL1T.cc
Go to the documentation of this file.
1 //-------------------------------------------------
2 //
15 //
16 //--------------------------------------------------
17 
18 // Class Header
20 
21 
22 // Framework
28 
36 
39 
40 using namespace std;
41 using namespace edm;
42 using namespace l1t;
43 
44 // constructors
46  theSource(iConfig.getParameter<InputTag>("InputObjects")),
47  theL1GMTReadoutCollection(iConfig.getParameter<InputTag>("GMTReadoutCollection")), // to be removed
48  thePropagatorName(iConfig.getParameter<string>("Propagator")),
49  theL1MinPt(iConfig.getParameter<double>("L1MinPt")),
50  theL1MaxEta(iConfig.getParameter<double>("L1MaxEta")),
51  theL1MinQuality(iConfig.getParameter<unsigned int>("L1MinQuality")),
52  useOfflineSeed(iConfig.getUntrackedParameter<bool>("UseOfflineSeed", false)),
53  useUnassociatedL1(iConfig.existsAs<bool>("UseUnassociatedL1") ?
54  iConfig.getParameter<bool>("UseUnassociatedL1") : true),
55  matchingDR(iConfig.getParameter<std::vector<double> >("MatchDR")),
56  etaBins(iConfig.getParameter<std::vector<double> >("EtaMatchingBins")),
57  centralBxOnly_( iConfig.getParameter<bool>("CentralBxOnly") )
58  {
59 
60  muCollToken_ = consumes<MuonBxCollection>(theSource);
61 
62  if(useOfflineSeed) {
63  theOfflineSeedLabel = iConfig.getUntrackedParameter<InputTag>("OfflineSeedLabel");
64  offlineSeedToken_ = consumes<edm::View<TrajectorySeed> >(theOfflineSeedLabel);
65 
66  // check that number of eta bins -1 matches number of dR cones
67  if( matchingDR.size()!=etaBins.size() - 1 ) {
68  throw cms::Exception("Configuration") << "Size of MatchDR "
69  << "does not match number of eta bins." << endl;
70  }
71 
72 
73  }
74 
75  // service parameters
76  ParameterSet serviceParameters = iConfig.getParameter<ParameterSet>("ServiceParameters");
77 
78  // the services
79  theService = new MuonServiceProxy(serviceParameters);
80 
81  // the estimator
83 
84 
85  produces<L2MuonTrajectorySeedCollection>();
86 }
87 
88 // destructor
90  if (theService) delete theService;
91  if (theEstimator) delete theEstimator;
92 }
93 
94 void
97  desc.add<edm::InputTag>("GMTReadoutCollection", edm::InputTag("")); // to be removed
98  desc.add<edm::InputTag>("InputObjects",edm::InputTag("hltGmtStage2Digis"));
99  desc.add<string>("Propagator", "");
100  desc.add<double>("L1MinPt",-1.);
101  desc.add<double>("L1MaxEta",5.0);
102  desc.add<unsigned int>("L1MinQuality",0);
103  desc.addUntracked<bool>("UseOfflineSeed",false);
104  desc.add<bool>("UseUnassociatedL1", true);
105  desc.add<std::vector<double>>("MatchDR", {0.3});
106  desc.add<std::vector<double>>("EtaMatchingBins", {0., 2.5});
107  desc.add<bool>("CentralBxOnly", true);
108  desc.addUntracked<edm::InputTag>("OfflineSeedLabel", edm::InputTag(""));
109 
111  psd0.addUntracked<std::vector<std::string>>("Propagators", {
112  "SteppingHelixPropagatorAny"
113  });
114  psd0.add<bool>("RPCLayers", true);
115  psd0.addUntracked<bool>("UseMuonNavigation", true);
116  desc.add<edm::ParameterSetDescription>("ServiceParameters", psd0);
117  descriptions.add("L2MuonSeedGeneratorFromL1T",desc);
118 }
119 
121 {
122  const std::string metname = "Muon|RecoMuon|L2MuonSeedGeneratorFromL1T";
124 
125  auto output = std::make_unique<L2MuonTrajectorySeedCollection>();
126 
128  iEvent.getByToken(muCollToken_, muColl);
129  LogTrace(metname) << "Number of muons " << muColl->size() << endl;
130 
131  edm::Handle<edm::View<TrajectorySeed> > offlineSeedHandle;
132  vector<int> offlineSeedMap;
133  if(useOfflineSeed) {
134  iEvent.getByToken(offlineSeedToken_, offlineSeedHandle);
135  LogTrace(metname) << "Number of offline seeds " << offlineSeedHandle->size() << endl;
136  offlineSeedMap = vector<int>(offlineSeedHandle->size(), 0);
137  }
138 
139  for (int ibx = muColl->getFirstBX(); ibx <= muColl->getLastBX(); ++ibx) {
140  if (centralBxOnly_ && (ibx != 0)) continue;
141  for (auto it = muColl->begin(ibx); it != muColl->end(ibx); it++){
142 
143  unsigned int quality = it->hwQual();
144  int valid_charge = it->hwChargeValid();
145 
146  float pt = it->pt();
147  float eta = it->eta();
148  float theta = 2*atan(exp(-eta));
149  float phi = it->phi();
150  int charge = it->charge();
151  // Set charge=0 for the time being if the valid charge bit is zero
152  if (!valid_charge) charge = 0;
153 
154  int link = 36 + (int)(it -> tfMuonIndex() / 3.);
155  bool barrel = true;
156  if ( (link >= 36 && link <= 41) || (link >= 66 && link <= 71)) barrel = false;
157 
158  if ( pt < theL1MinPt || fabs(eta) > theL1MaxEta ) continue;
159 
160  LogTrace(metname) << "New L2 Muon Seed" ;
161  LogTrace(metname) << "Pt = " << pt << " GeV/c";
162  LogTrace(metname) << "eta = " << eta;
163  LogTrace(metname) << "theta = " << theta << " rad";
164  LogTrace(metname) << "phi = " << phi << " rad";
165  LogTrace(metname) << "charge = " << charge;
166  LogTrace(metname) << "In Barrel? = " << barrel;
167 
168  if ( quality <= theL1MinQuality ) continue;
169  LogTrace(metname) << "quality = "<< quality;
170 
171  // Update the services
172  theService->update(iSetup);
173 
174  const DetLayer *detLayer = nullptr;
175  float radius = 0.;
176 
177  CLHEP::Hep3Vector vec(0.,1.,0.);
178  vec.setTheta(theta);
179  vec.setPhi(phi);
180 
181  DetId theid;
182  // Get the det layer on which the state should be put
183  if ( barrel ){
184  LogTrace(metname) << "The seed is in the barrel";
185 
186  // MB2
187  DetId id = DTChamberId(0,2,0);
188  detLayer = theService->detLayerGeometry()->idToLayer(id);
189  LogTrace(metname) << "L2 Layer: " << debug.dumpLayer(detLayer);
190 
191  const BoundSurface* sur = &(detLayer->surface());
192  const BoundCylinder* bc = dynamic_cast<const BoundCylinder*>(sur);
193 
194  radius = fabs(bc->radius()/sin(theta));
195  theid = id;
196 
197  LogTrace(metname) << "radius "<<radius;
198 
199  if ( pt < 3.5 ) pt = 3.5;
200  }
201  else {
202  LogTrace(metname) << "The seed is in the endcap";
203 
204  DetId id;
205  // ME2
206  if ( theta < Geom::pi()/2. )
207  id = CSCDetId(1,2,0,0,0);
208  else
209  id = CSCDetId(2,2,0,0,0);
210 
211  detLayer = theService->detLayerGeometry()->idToLayer(id);
212  LogTrace(metname) << "L2 Layer: " << debug.dumpLayer(detLayer);
213 
214  radius = fabs(detLayer->position().z()/cos(theta));
215  theid = id;
216 
217  if( pt < 1.0) pt = 1.0;
218  }
219 
220  // Fallback solution using ME2
221  DetId fallback_id;
222  theta < Geom::pi()/2. ? fallback_id = CSCDetId(1,2,0,0,0) : fallback_id = CSCDetId(2,2,0,0,0);
223  const DetLayer* ME2DetLayer = theService->detLayerGeometry()->idToLayer(fallback_id);
224 
225  vec.setMag(radius);
226 
227  GlobalPoint pos(vec.x(),vec.y(),vec.z());
228 
229  GlobalVector mom(pt*cos(phi), pt*sin(phi), pt*cos(theta)/sin(theta));
230 
231  GlobalTrajectoryParameters param(pos,mom,charge,&*theService->magneticField());
233 
234  mat[0][0] = (0.25/pt)*(0.25/pt); // sigma^2(charge/abs_momentum)
235  if ( !barrel ) mat[0][0] = (0.4/pt)*(0.4/pt);
236 
237  //Assign q/pt = 0 +- 1/pt if charge has been declared invalid
238  if (!valid_charge) mat[0][0] = (1./pt)*(1./pt);
239 
240  mat[1][1] = 0.05*0.05; // sigma^2(lambda)
241  mat[2][2] = 0.2*0.2; // sigma^2(phi)
242  mat[3][3] = 20.*20.; // sigma^2(x_transverse))
243  mat[4][4] = 20.*20.; // sigma^2(y_transverse))
244 
246 
247  const FreeTrajectoryState state(param,error);
248 
249  LogTrace(metname) << "Free trajectory State from the parameters";
250  LogTrace(metname) << debug.dumpFTS(state);
251 
252  // Propagate the state on the MB2/ME2 surface
253  TrajectoryStateOnSurface tsos = theService->propagator(thePropagatorName)->propagate(state, detLayer->surface());
254 
255  LogTrace(metname) << "State after the propagation on the layer";
256  LogTrace(metname) << debug.dumpLayer(detLayer);
257  LogTrace(metname) << debug.dumpTSOS(tsos);
258 
259  double dRcone = matchingDR[0];
260  if ( fabs(eta) < etaBins.back() ){
261  std::vector<double>::iterator lowEdge = std::upper_bound (etaBins.begin(), etaBins.end(), fabs(eta));
262  dRcone = matchingDR.at( lowEdge - etaBins.begin() - 1);
263  }
264 
265  if (tsos.isValid()) {
266 
268 
269  if(useOfflineSeed && ( !valid_charge || charge == 0) ) {
270 
271  const TrajectorySeed *assoOffseed =
272  associateOfflineSeedToL1(offlineSeedHandle, offlineSeedMap, tsos, dRcone );
273 
274  if(assoOffseed!=nullptr) {
275  PTrajectoryStateOnDet const & seedTSOS = assoOffseed->startingState();
277  tsci = assoOffseed->recHits().first,
278  tscie = assoOffseed->recHits().second;
279  for(; tsci!=tscie; ++tsci) {
280  container.push_back(*tsci);
281  }
282  output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum,
283  MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) )));
284  }
285  else {
286  if(useUnassociatedL1) {
287  // convert the TSOS into a PTSOD
288  PTrajectoryStateOnDet const & seedTSOS = trajectoryStateTransform::persistentState( tsos, theid.rawId());
289  output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum,
290  MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) )));
291  }
292  }
293  }
294  else if (useOfflineSeed && valid_charge){
295  // Get the compatible dets on the layer
296  std::vector< pair<const GeomDet*,TrajectoryStateOnSurface> >
297  detsWithStates = detLayer->compatibleDets(tsos,
298  *theService->propagator(thePropagatorName),
299  *theEstimator);
300 
301  if (detsWithStates.empty() && barrel ) {
302  // try again to propagate but using ME2 as reference
303  tsos = theService->propagator(thePropagatorName)->propagate(state, ME2DetLayer->surface());
304  detsWithStates = ME2DetLayer->compatibleDets(tsos,
305  *theService->propagator(thePropagatorName),
306  *theEstimator);
307  }
308 
309  if (!detsWithStates.empty()){
310 
311  TrajectoryStateOnSurface newTSOS = detsWithStates.front().second;
312  const GeomDet *newTSOSDet = detsWithStates.front().first;
313 
314  LogTrace(metname) << "Most compatible det";
315  LogTrace(metname) << debug.dumpMuonId(newTSOSDet->geographicalId());
316 
317  LogDebug(metname) << "L1 info: Det and State:";
318  LogDebug(metname) << debug.dumpMuonId(newTSOSDet->geographicalId());
319 
320  if (newTSOS.isValid()){
321 
322  //LogDebug(metname) << "(x, y, z) = (" << newTSOS.globalPosition().x() << ", "
323  // << newTSOS.globalPosition().y() << ", " << newTSOS.globalPosition().z() << ")";
324  LogDebug(metname) << "pos: (r=" << newTSOS.globalPosition().mag() << ", phi="
325  << newTSOS.globalPosition().phi() << ", eta=" << newTSOS.globalPosition().eta() << ")";
326  LogDebug(metname) << "mom: (q*pt=" << newTSOS.charge()*newTSOS.globalMomentum().perp() << ", phi="
327  << newTSOS.globalMomentum().phi() << ", eta=" << newTSOS.globalMomentum().eta() << ")";
328 
329  //LogDebug(metname) << "State on it";
330  //LogDebug(metname) << debug.dumpTSOS(newTSOS);
331 
332  const TrajectorySeed *assoOffseed =
333  associateOfflineSeedToL1(offlineSeedHandle, offlineSeedMap, newTSOS, dRcone);
334 
335  if(assoOffseed!=nullptr) {
336  PTrajectoryStateOnDet const & seedTSOS = assoOffseed->startingState();
338  tsci = assoOffseed->recHits().first,
339  tscie = assoOffseed->recHits().second;
340  for(; tsci!=tscie; ++tsci) {
341  container.push_back(*tsci);
342  }
343  output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum,
344  MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) )));
345  }
346  else {
347  if(useUnassociatedL1) {
348  // convert the TSOS into a PTSOD
349  PTrajectoryStateOnDet const & seedTSOS = trajectoryStateTransform::persistentState( newTSOS,newTSOSDet->geographicalId().rawId());
350  output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum,
351  MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) )));
352  }
353  }
354  }
355  }
356  }
357  else {
358  // convert the TSOS into a PTSOD
359  PTrajectoryStateOnDet const & seedTSOS = trajectoryStateTransform::persistentState( tsos, theid.rawId());
360  output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum,
361  MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) )));
362  }
363  }
364  }
365  }
366 
367  iEvent.put(std::move(output));
368 }
369 
370 
371 // FIXME: does not resolve ambiguities yet!
373  std::vector<int> & offseedMap,
374  TrajectoryStateOnSurface & newTsos,
375  double dRcone ) {
376 
377  const std::string metlabel = "Muon|RecoMuon|L2MuonSeedGeneratorFromL1T";
378  MuonPatternRecoDumper debugtmp;
379 
380  edm::View<TrajectorySeed>::const_iterator offseed, endOffseed = offseeds->end();
381  const TrajectorySeed *selOffseed = nullptr;
382  double bestDr = 99999.;
383  unsigned int nOffseed(0);
384  int lastOffseed(-1);
385 
386  for(offseed=offseeds->begin(); offseed!=endOffseed; ++offseed, ++nOffseed) {
387  if(offseedMap[nOffseed]!=0) continue;
388  GlobalPoint glbPos = theService->trackingGeometry()->idToDet(offseed->startingState().detId())->surface().toGlobal(offseed->startingState().parameters().position());
389  GlobalVector glbMom = theService->trackingGeometry()->idToDet(offseed->startingState().detId())->surface().toGlobal(offseed->startingState().parameters().momentum());
390 
391  // Preliminary check
392  double preDr = deltaR( newTsos.globalPosition().eta(), newTsos.globalPosition().phi(), glbPos.eta(), glbPos.phi() );
393  if(preDr > 1.0) continue;
394 
395  const FreeTrajectoryState offseedFTS(glbPos, glbMom, offseed->startingState().parameters().charge(), &*theService->magneticField());
396  TrajectoryStateOnSurface offseedTsos = theService->propagator(thePropagatorName)->propagate(offseedFTS, newTsos.surface());
397  LogDebug(metlabel) << "Offline seed info: Det and State" << std::endl;
398  LogDebug(metlabel) << debugtmp.dumpMuonId(offseed->startingState().detId()) << std::endl;
399  //LogDebug(metlabel) << "(x, y, z) = (" << newTSOS.globalPosition().x() << ", "
400  // << newTSOS.globalPosition().y() << ", " << newTSOS.globalPosition().z() << ")" << std::endl;
401  LogDebug(metlabel) << "pos: (r=" << offseedFTS.position().mag() << ", phi="
402  << offseedFTS.position().phi() << ", eta=" << offseedFTS.position().eta() << ")" << std::endl;
403  LogDebug(metlabel) << "mom: (q*pt=" << offseedFTS.charge()*offseedFTS.momentum().perp() << ", phi="
404  << offseedFTS.momentum().phi() << ", eta=" << offseedFTS.momentum().eta() << ")" << std::endl << std::endl;
405  //LogDebug(metlabel) << debugtmp.dumpFTS(offseedFTS) << std::endl;
406 
407  if(offseedTsos.isValid()) {
408  LogDebug(metlabel) << "Offline seed info after propagation to L1 layer:" << std::endl;
409  //LogDebug(metlabel) << "(x, y, z) = (" << offseedTsos.globalPosition().x() << ", "
410  // << offseedTsos.globalPosition().y() << ", " << offseedTsos.globalPosition().z() << ")" << std::endl;
411  LogDebug(metlabel) << "pos: (r=" << offseedTsos.globalPosition().mag() << ", phi="
412  << offseedTsos.globalPosition().phi() << ", eta=" << offseedTsos.globalPosition().eta() << ")" << std::endl;
413  LogDebug(metlabel) << "mom: (q*pt=" << offseedTsos.charge()*offseedTsos.globalMomentum().perp() << ", phi="
414  << offseedTsos.globalMomentum().phi() << ", eta=" << offseedTsos.globalMomentum().eta() << ")" << std::endl << std::endl;
415  //LogDebug(metlabel) << debugtmp.dumpTSOS(offseedTsos) << std::endl;
416  double newDr = deltaR( newTsos.globalPosition().eta(), newTsos.globalPosition().phi(),
417  offseedTsos.globalPosition().eta(), offseedTsos.globalPosition().phi() );
418  LogDebug(metlabel) << " -- DR = " << newDr << std::endl;
419  if( newDr < dRcone && newDr<bestDr ) {
420  LogDebug(metlabel) << " --> OK! " << newDr << std::endl << std::endl;
421  selOffseed = &*offseed;
422  bestDr = newDr;
423  offseedMap[nOffseed] = 1;
424  if(lastOffseed>-1) offseedMap[lastOffseed] = 0;
425  lastOffseed = nOffseed;
426  }
427  else {
428  LogDebug(metlabel) << " --> Rejected. " << newDr << std::endl << std::endl;
429  }
430  }
431  else {
432  LogDebug(metlabel) << "Invalid offline seed TSOS after propagation!" << std::endl << std::endl;
433  }
434  }
435 
436  return selOffseed;
437 }
#define LogDebug(id)
edm::EDGetTokenT< edm::View< TrajectorySeed > > offlineSeedToken_
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:127
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
T perp() const
Definition: PV3DBase.h:72
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
bool centralBxOnly_
use central bx only muons
std::string dumpLayer(const DetLayer *layer) const
const TrajectorySeed * associateOfflineSeedToL1(edm::Handle< edm::View< TrajectorySeed > > &, std::vector< int > &, TrajectoryStateOnSurface &, double)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:508
const std::string metname
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
PTrajectoryStateOnDet persistentState(const TrajectoryStateOnSurface &ts, unsigned int detid)
Geom::Theta< T > theta() const
GlobalPoint globalPosition() const
L2MuonSeedGeneratorFromL1T(const edm::ParameterSet &)
Constructor.
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepSym< double, 5 > > AlgebraicSymMatrix55
delete x;
Definition: CaloConfig.h:22
virtual std::vector< DetWithState > compatibleDets(const TrajectoryStateOnSurface &startingState, const Propagator &prop, const MeasurementEstimator &est) const
edm::Ref< MuonBxCollection > MuonRef
Definition: Muon.h:12
std::string dumpMuonId(const DetId &id) const
std::string dumpFTS(const FreeTrajectoryState &fts) const
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
~L2MuonSeedGeneratorFromL1T() override
Destructor.
std::string dumpTSOS(const TrajectoryStateOnSurface &tsos) const
void push_back(D *&d)
Definition: OwnVector.h:290
int iEvent
Definition: GenABIO.cc:230
const SurfaceType & surface() const
T mag() const
Definition: PV3DBase.h:67
const_iterator begin() const
MuonServiceProxy * theService
the event setup proxy, it takes care the services update
recHitContainer::const_iterator const_iterator
T z() const
Definition: PV3DBase.h:64
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
virtual const BoundSurface & surface() const =0
The surface of the GeometricSearchDet.
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:79
ParameterDescriptionBase * add(U const &iLabel, T const &value)
#define LogTrace(id)
double deltaR(double eta1, double eta2, double phi1, double phi2)
Definition: TreeUtility.cc:17
Definition: DetId.h:18
PTrajectoryStateOnDet const & startingState() const
#define debug
Definition: HDRShower.cc:19
virtual const Surface::PositionType & position() const
Returns position of the surface.
range recHits() const
edm::EDGetTokenT< l1t::MuonBxCollection > muCollToken_
void add(std::string const &label, ParameterSetDescription const &psetDescription)
T eta() const
Definition: PV3DBase.h:76
HLT enums.
GlobalVector globalMomentum() const
boost::indirect_iterator< typename seq_t::const_iterator > const_iterator
Definition: View.h:86
void produce(edm::Event &, const edm::EventSetup &) override
constexpr double pi()
Definition: Pi.h:31
def move(src, dest)
Definition: eostools.py:510