CMS 3D CMS Logo

L2MuonSeedGeneratorFromL1T.cc
Go to the documentation of this file.
1 //-------------------------------------------------
2 //
17 //
18 //--------------------------------------------------
19 
20 // Class Header
22 
23 
24 // Framework
30 
38 
41 
42 using namespace std;
43 using namespace edm;
44 using namespace l1t;
45 
46 //--- Functions used in output sorting
48  l1t::MuonRef Ref_L1A = A.l1tParticle();
49  l1t::MuonRef Ref_L1B = B.l1tParticle();
50  return (Ref_L1A->pt() > Ref_L1B->pt());
51 };
52 
54  l1t::MuonRef Ref_L1A = A.l1tParticle();
55  l1t::MuonRef Ref_L1B = B.l1tParticle();
56 
57  // Compare quality first
58  if (Ref_L1A->hwQual() > Ref_L1B->hwQual()) return true;
59  if (Ref_L1A->hwQual() < Ref_L1B->hwQual()) return false;
60 
61  // For same quality L1s compare pT
62  return (Ref_L1A->pt() > Ref_L1B->pt());
63 };
64 
65 // constructors
67  theSource(iConfig.getParameter<InputTag>("InputObjects")),
68  theL1GMTReadoutCollection(iConfig.getParameter<InputTag>("GMTReadoutCollection")), // to be removed
69  thePropagatorName(iConfig.getParameter<string>("Propagator")),
70  theL1MinPt(iConfig.getParameter<double>("L1MinPt")),
71  theL1MaxEta(iConfig.getParameter<double>("L1MaxEta")),
72  theL1MinQuality(iConfig.getParameter<unsigned int>("L1MinQuality")),
73  theMinPtBarrel(iConfig.getParameter<double>("SetMinPtBarrelTo")),
74  theMinPtEndcap(iConfig.getParameter<double>("SetMinPtEndcapTo")),
75  useOfflineSeed(iConfig.getUntrackedParameter<bool>("UseOfflineSeed", false)),
76  useUnassociatedL1(iConfig.getParameter<bool>("UseUnassociatedL1")),
77  matchingDR(iConfig.getParameter<std::vector<double> >("MatchDR")),
78  etaBins(iConfig.getParameter<std::vector<double> >("EtaMatchingBins")),
79  centralBxOnly_( iConfig.getParameter<bool>("CentralBxOnly") ),
80  matchType( iConfig.getParameter<unsigned int>("MatchType") ),
81  sortType( iConfig.getParameter<unsigned int>("SortType") )
82  {
83 
84  muCollToken_ = consumes<MuonBxCollection>(theSource);
85 
86  if(useOfflineSeed) {
87  theOfflineSeedLabel = iConfig.getUntrackedParameter<InputTag>("OfflineSeedLabel");
88  offlineSeedToken_ = consumes<edm::View<TrajectorySeed> >(theOfflineSeedLabel);
89 
90  // check that number of eta bins -1 matches number of dR cones
91  if( matchingDR.size()!=etaBins.size() - 1 ) {
92  throw cms::Exception("Configuration") << "Size of MatchDR "
93  << "does not match number of eta bins." << endl;
94  }
95 
96 
97  }
98 
99  if(matchType>4 || sortType>3) {
100  throw cms::Exception("Configuration") << "Wrong MatchType or SortType" << endl;
101  }
102 
103  // service parameters
104  ParameterSet serviceParameters = iConfig.getParameter<ParameterSet>("ServiceParameters");
105 
106  // the services
107  theService = new MuonServiceProxy(serviceParameters);
108 
109  // the estimator
111 
112 
113  produces<L2MuonTrajectorySeedCollection>();
114 }
115 
116 // destructor
118  if (theService) delete theService;
119  if (theEstimator) delete theEstimator;
120 }
121 
122 void
125  desc.add<edm::InputTag>("GMTReadoutCollection", edm::InputTag("")); // to be removed
126  desc.add<edm::InputTag>("InputObjects",edm::InputTag("hltGmtStage2Digis"));
127  desc.add<string>("Propagator", "");
128  desc.add<double>("L1MinPt",-1.);
129  desc.add<double>("L1MaxEta",5.0);
130  desc.add<unsigned int>("L1MinQuality",0);
131  desc.add<double>("SetMinPtBarrelTo",3.5);
132  desc.add<double>("SetMinPtEndcapTo",1.0);
133  desc.addUntracked<bool>("UseOfflineSeed",false);
134  desc.add<bool>("UseUnassociatedL1", true);
135  desc.add<std::vector<double>>("MatchDR", {0.3});
136  desc.add<std::vector<double>>("EtaMatchingBins", {0., 2.5});
137  desc.add<bool>("CentralBxOnly", true);
138  desc.add<unsigned int>("MatchType", 0)->setComment("MatchType : 0 Old matching, 1 L1 Order(1to1), 2 Min dR(1to1), 3 Higher Q(1to1), 4 All matched L1");
139  desc.add<unsigned int>("SortType", 0)->setComment("SortType : 0 not sort, 1 Pt, 2 Q and Pt");
140  desc.addUntracked<edm::InputTag>("OfflineSeedLabel", edm::InputTag(""));
141 
143  psd0.addUntracked<std::vector<std::string>>("Propagators", {
144  "SteppingHelixPropagatorAny"
145  });
146  psd0.add<bool>("RPCLayers", true);
147  psd0.addUntracked<bool>("UseMuonNavigation", true);
148  desc.add<edm::ParameterSetDescription>("ServiceParameters", psd0);
149  descriptions.add("L2MuonSeedGeneratorFromL1T",desc);
150 }
151 
153 {
154  const std::string metname = "Muon|RecoMuon|L2MuonSeedGeneratorFromL1T";
156 
157  auto output = std::make_unique<L2MuonTrajectorySeedCollection>();
158 
160  iEvent.getByToken(muCollToken_, muColl);
161  LogDebug(metname) << "Number of muons " << muColl->size() << endl;
162 
163 
164  //--- matchType 0 : Old logic
165  if(matchType == 0) {
166 
167  edm::Handle<edm::View<TrajectorySeed> > offlineSeedHandle;
168  vector<int> offlineSeedMap;
169  if(useOfflineSeed) {
170  iEvent.getByToken(offlineSeedToken_, offlineSeedHandle);
171  LogDebug(metname) << "Number of offline seeds " << offlineSeedHandle->size() << endl;
172  offlineSeedMap = vector<int>(offlineSeedHandle->size(), 0);
173  }
174 
175  for (int ibx = muColl->getFirstBX(); ibx <= muColl->getLastBX(); ++ibx) {
176  if (centralBxOnly_ && (ibx != 0)) continue;
177  for (auto it = muColl->begin(ibx); it != muColl->end(ibx); it++){
178 
179  unsigned int quality = it->hwQual();
180  int valid_charge = it->hwChargeValid();
181 
182  float pt = it->pt();
183  float eta = it->eta();
184  float theta = 2*atan(exp(-eta));
185  float phi = it->phi();
186  int charge = it->charge();
187  // Set charge=0 for the time being if the valid charge bit is zero
188  if (!valid_charge) charge = 0;
189 
190  // link number indices of the optical fibres that connect the uGMT with the track finders
191  //EMTF+ : 36-41, OMTF+ : 42-47, BMTF : 48-59, OMTF- : 60-65, EMTF- : 66-71
192  int link = 36 + (int)(it -> tfMuonIndex() / 3.);
193  bool barrel = true;
194  if ( (link >= 36 && link <= 41) || (link >= 66 && link <= 71)) barrel = false;
195 
196  if ( pt < theL1MinPt || fabs(eta) > theL1MaxEta ) continue;
197 
198  LogDebug(metname) << "New L2 Muon Seed" ;
199  LogDebug(metname) << "Pt = " << pt << " GeV/c";
200  LogDebug(metname) << "eta = " << eta;
201  LogDebug(metname) << "theta = " << theta << " rad";
202  LogDebug(metname) << "phi = " << phi << " rad";
203  LogDebug(metname) << "charge = " << charge;
204  LogDebug(metname) << "In Barrel? = " << barrel;
205 
206  if ( quality <= theL1MinQuality ) continue;
207  LogDebug(metname) << "quality = "<< quality;
208 
209  // Update the services
210  theService->update(iSetup);
211 
212  const DetLayer *detLayer = nullptr;
213  float radius = 0.;
214 
215  CLHEP::Hep3Vector vec(0.,1.,0.);
216  vec.setTheta(theta);
217  vec.setPhi(phi);
218 
219  DetId theid;
220  // Get the det layer on which the state should be put
221  if ( barrel ){
222  LogDebug(metname) << "The seed is in the barrel";
223 
224  // MB2
225  theid = DTChamberId(0,2,0);
226  detLayer = theService->detLayerGeometry()->idToLayer(theid);
227  LogDebug(metname) << "L2 Layer: " << debug.dumpLayer(detLayer);
228 
229  const BoundSurface* sur = &(detLayer->surface());
230  const BoundCylinder* bc = dynamic_cast<const BoundCylinder*>(sur);
231 
232  radius = fabs(bc->radius()/sin(theta));
233 
234  LogDebug(metname) << "radius "<<radius;
235 
236  if ( pt < theMinPtBarrel ) pt = theMinPtBarrel;
237  }
238  else {
239  LogDebug(metname) << "The seed is in the endcap";
240 
241  // ME2
242  theid = theta < Geom::pi()/2. ? CSCDetId(1,2,0,0,0) : CSCDetId(2,2,0,0,0);
243 
244  detLayer = theService->detLayerGeometry()->idToLayer(theid);
245  LogDebug(metname) << "L2 Layer: " << debug.dumpLayer(detLayer);
246 
247  radius = fabs(detLayer->position().z()/cos(theta));
248 
249  if( pt < theMinPtEndcap) pt = theMinPtEndcap;
250  }
251 
252  vec.setMag(radius);
253 
254  GlobalPoint pos(vec.x(),vec.y(),vec.z());
255 
256  GlobalVector mom(pt*cos(phi), pt*sin(phi), pt*cos(theta)/sin(theta));
257 
258  GlobalTrajectoryParameters param(pos,mom,charge,&*theService->magneticField());
260 
261  mat[0][0] = (0.25/pt)*(0.25/pt); // sigma^2(charge/abs_momentum)
262  if ( !barrel ) mat[0][0] = (0.4/pt)*(0.4/pt);
263 
264  //Assign q/pt = 0 +- 1/pt if charge has been declared invalid
265  if (!valid_charge) mat[0][0] = (1./pt)*(1./pt);
266 
267  mat[1][1] = 0.05*0.05; // sigma^2(lambda)
268  mat[2][2] = 0.2*0.2; // sigma^2(phi)
269  mat[3][3] = 20.*20.; // sigma^2(x_transverse))
270  mat[4][4] = 20.*20.; // sigma^2(y_transverse))
271 
273 
274  const FreeTrajectoryState state(param,error);
275 
276  LogDebug(metname) << "Free trajectory State from the parameters";
277  LogDebug(metname) << debug.dumpFTS(state);
278 
279  // Propagate the state on the MB2/ME2 surface
280  TrajectoryStateOnSurface tsos = theService->propagator(thePropagatorName)->propagate(state, detLayer->surface());
281 
282  LogDebug(metname) << "State after the propagation on the layer";
283  LogDebug(metname) << debug.dumpLayer(detLayer);
284  LogDebug(metname) << debug.dumpTSOS(tsos);
285 
286  double dRcone = matchingDR[0];
287  if ( fabs(eta) < etaBins.back() ){
288  std::vector<double>::iterator lowEdge = std::upper_bound (etaBins.begin(), etaBins.end(), fabs(eta));
289  dRcone = matchingDR.at( lowEdge - etaBins.begin() - 1);
290  }
291 
292  if (tsos.isValid()) {
293 
295 
296  if(useOfflineSeed && ( !valid_charge || charge == 0) ) {
297 
298  const TrajectorySeed *assoOffseed =
299  associateOfflineSeedToL1(offlineSeedHandle, offlineSeedMap, tsos, dRcone );
300 
301  if(assoOffseed!=nullptr) {
302  PTrajectoryStateOnDet const & seedTSOS = assoOffseed->startingState();
304  tsci = assoOffseed->recHits().first,
305  tscie = assoOffseed->recHits().second;
306  for(; tsci!=tscie; ++tsci) {
307  container.push_back(*tsci);
308  }
309  output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum,
310  MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) )));
311  }
312  else {
313  if(useUnassociatedL1) {
314  // convert the TSOS into a PTSOD
315  PTrajectoryStateOnDet const & seedTSOS = trajectoryStateTransform::persistentState( tsos, theid.rawId());
316  output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum,
317  MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) )));
318  }
319  }
320  }
321  else if (useOfflineSeed && valid_charge){
322  // Get the compatible dets on the layer
323  std::vector< pair<const GeomDet*,TrajectoryStateOnSurface> >
324  detsWithStates = detLayer->compatibleDets(tsos,
325  *theService->propagator(thePropagatorName),
326  *theEstimator);
327 
328  if (detsWithStates.empty() && barrel ) {
329  // Fallback solution using ME2, try again to propagate but using ME2 as reference
330  DetId fallback_id;
331  theta < Geom::pi()/2. ? fallback_id = CSCDetId(1,2,0,0,0) : fallback_id = CSCDetId(2,2,0,0,0);
332  const DetLayer* ME2DetLayer = theService->detLayerGeometry()->idToLayer(fallback_id);
333 
334  tsos = theService->propagator(thePropagatorName)->propagate(state, ME2DetLayer->surface());
335  detsWithStates = ME2DetLayer->compatibleDets(tsos,
336  *theService->propagator(thePropagatorName),
337  *theEstimator);
338  }
339 
340  if (!detsWithStates.empty()){
341 
342  TrajectoryStateOnSurface newTSOS = detsWithStates.front().second;
343  const GeomDet *newTSOSDet = detsWithStates.front().first;
344 
345  LogDebug(metname) << "Most compatible det";
346  LogDebug(metname) << debug.dumpMuonId(newTSOSDet->geographicalId());
347 
348  if (newTSOS.isValid()){
349 
350  LogDebug(metname) << "pos: (r=" << newTSOS.globalPosition().mag() << ", phi="
351  << newTSOS.globalPosition().phi() << ", eta=" << newTSOS.globalPosition().eta() << ")";
352  LogDebug(metname) << "mom: (q*pt=" << newTSOS.charge()*newTSOS.globalMomentum().perp() << ", phi="
353  << newTSOS.globalMomentum().phi() << ", eta=" << newTSOS.globalMomentum().eta() << ")";
354 
355  const TrajectorySeed *assoOffseed =
356  associateOfflineSeedToL1(offlineSeedHandle, offlineSeedMap, newTSOS, dRcone);
357 
358  if(assoOffseed!=nullptr) {
359  PTrajectoryStateOnDet const & seedTSOS = assoOffseed->startingState();
361  tsci = assoOffseed->recHits().first,
362  tscie = assoOffseed->recHits().second;
363  for(; tsci!=tscie; ++tsci) {
364  container.push_back(*tsci);
365  }
366  output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum,
367  MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) )));
368  }
369  else {
370  if(useUnassociatedL1) {
371  // convert the TSOS into a PTSOD
372  PTrajectoryStateOnDet const & seedTSOS = trajectoryStateTransform::persistentState( newTSOS,newTSOSDet->geographicalId().rawId());
373  output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum,
374  MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) )));
375  }
376  }
377  }
378  }
379  }
380  else {
381  // convert the TSOS into a PTSOD
382  PTrajectoryStateOnDet const & seedTSOS = trajectoryStateTransform::persistentState( tsos, theid.rawId());
383  output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum,
384  MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) )));
385  }
386  }
387  }
388  }
389 
390  } // End of matchType 0
391 
392  //--- matchType > 0 : Updated logics
393  else if(matchType > 0) {
394 
395  unsigned int nMuColl = muColl->size();
396 
397  vector< vector<double> > dRmtx;
398  vector< vector<const TrajectorySeed *> > selOffseeds;
399 
400  edm::Handle<edm::View<TrajectorySeed> > offlineSeedHandle;
401  if(useOfflineSeed) {
402  iEvent.getByToken(offlineSeedToken_, offlineSeedHandle);
403  unsigned int nOfflineSeed = offlineSeedHandle->size();
404  LogDebug(metname) << "Number of offline seeds " << nOfflineSeed << endl;
405 
406  // Initialize dRmtx and selOffseeds
407  dRmtx = vector< vector<double> >(nMuColl, vector<double>(nOfflineSeed, 999.0));
408  selOffseeds = vector< vector <const TrajectorySeed *> >(nMuColl, vector<const TrajectorySeed *>(nOfflineSeed, nullptr));
409  }
410 
411  // At least one L1 muons are associated with offSeed
412  bool isAsso = false;
413 
414  //--- Fill dR matrix
415  for (int ibx = muColl->getFirstBX(); ibx <= muColl->getLastBX(); ++ibx) {
416  if (centralBxOnly_ && (ibx != 0)) continue;
417  for (auto it = muColl->begin(ibx); it != muColl->end(ibx); it++){
418 
419  //Position of given L1mu
420  unsigned int imu = distance(muColl->begin(muColl->getFirstBX()),it);
421 
422  unsigned int quality = it->hwQual();
423  int valid_charge = it->hwChargeValid();
424 
425  float pt = it->pt();
426  float eta = it->eta();
427  float theta = 2*atan(exp(-eta));
428  float phi = it->phi();
429  int charge = it->charge();
430  // Set charge=0 for the time being if the valid charge bit is zero
431  if (!valid_charge) charge = 0;
432 
433  // link number indices of the optical fibres that connect the uGMT with the track finders
434  //EMTF+ : 36-41, OMTF+ : 42-47, BMTF : 48-59, OMTF- : 60-65, EMTF- : 66-71
435  int link = 36 + (int)(it -> tfMuonIndex() / 3.);
436  bool barrel = true;
437  if ( (link >= 36 && link <= 41) || (link >= 66 && link <= 71)) barrel = false;
438 
439  if ( pt < theL1MinPt || fabs(eta) > theL1MaxEta ) continue;
440 
441  LogDebug(metname) << "New L2 Muon Seed" ;
442  LogDebug(metname) << "Pt = " << pt << " GeV/c";
443  LogDebug(metname) << "eta = " << eta;
444  LogDebug(metname) << "theta = " << theta << " rad";
445  LogDebug(metname) << "phi = " << phi << " rad";
446  LogDebug(metname) << "charge = " << charge;
447  LogDebug(metname) << "In Barrel? = " << barrel;
448 
449  if ( quality <= theL1MinQuality ) continue;
450  LogDebug(metname) << "quality = "<< quality;
451 
452  // Update the services
453  theService->update(iSetup);
454 
455  const DetLayer *detLayer = nullptr;
456  float radius = 0.;
457 
458  CLHEP::Hep3Vector vec(0.,1.,0.);
459  vec.setTheta(theta);
460  vec.setPhi(phi);
461 
462  DetId theid;
463  // Get the det layer on which the state should be put
464  if ( barrel ){
465  LogDebug(metname) << "The seed is in the barrel";
466 
467  // MB2
468  theid = DTChamberId(0,2,0);
469  detLayer = theService->detLayerGeometry()->idToLayer(theid);
470  LogDebug(metname) << "L2 Layer: " << debug.dumpLayer(detLayer);
471 
472  const BoundSurface* sur = &(detLayer->surface());
473  const BoundCylinder* bc = dynamic_cast<const BoundCylinder*>(sur);
474 
475  radius = fabs(bc->radius()/sin(theta));
476 
477  LogDebug(metname) << "radius "<<radius;
478 
479  if ( pt < theMinPtBarrel ) pt = theMinPtBarrel;
480  }
481  else {
482  LogDebug(metname) << "The seed is in the endcap";
483 
484  // ME2
485  theid = theta < Geom::pi()/2. ? CSCDetId(1,2,0,0,0) : CSCDetId(2,2,0,0,0);
486 
487  detLayer = theService->detLayerGeometry()->idToLayer(theid);
488  LogDebug(metname) << "L2 Layer: " << debug.dumpLayer(detLayer);
489 
490  radius = fabs(detLayer->position().z()/cos(theta));
491 
492  if( pt < theMinPtEndcap) pt = theMinPtEndcap;
493  }
494 
495  vec.setMag(radius);
496 
497  GlobalPoint pos(vec.x(),vec.y(),vec.z());
498 
499  GlobalVector mom(pt*cos(phi), pt*sin(phi), pt*cos(theta)/sin(theta));
500 
501  GlobalTrajectoryParameters param(pos,mom,charge,&*theService->magneticField());
503 
504  mat[0][0] = (0.25/pt)*(0.25/pt); // sigma^2(charge/abs_momentum)
505  if ( !barrel ) mat[0][0] = (0.4/pt)*(0.4/pt);
506 
507  //Assign q/pt = 0 +- 1/pt if charge has been declared invalid
508  if (!valid_charge) mat[0][0] = (1./pt)*(1./pt);
509 
510  mat[1][1] = 0.05*0.05; // sigma^2(lambda)
511  mat[2][2] = 0.2*0.2; // sigma^2(phi)
512  mat[3][3] = 20.*20.; // sigma^2(x_transverse))
513  mat[4][4] = 20.*20.; // sigma^2(y_transverse))
514 
516 
517  const FreeTrajectoryState state(param,error);
518 
519  LogDebug(metname) << "Free trajectory State from the parameters";
520  LogDebug(metname) << debug.dumpFTS(state);
521 
522  // Propagate the state on the MB2/ME2 surface
523  TrajectoryStateOnSurface tsos = theService->propagator(thePropagatorName)->propagate(state, detLayer->surface());
524 
525  LogDebug(metname) << "State after the propagation on the layer";
526  LogDebug(metname) << debug.dumpLayer(detLayer);
527  LogDebug(metname) << debug.dumpTSOS(tsos);
528 
529  double dRcone = matchingDR[0];
530  if ( fabs(eta) < etaBins.back() ){
531  std::vector<double>::iterator lowEdge = std::upper_bound (etaBins.begin(), etaBins.end(), fabs(eta));
532  dRcone = matchingDR.at( lowEdge - etaBins.begin() - 1);
533  }
534 
535  if (tsos.isValid()) {
536 
538 
539  if(useOfflineSeed) {
540 
541  if( ( !valid_charge || charge == 0 ) ) {
542 
543  bool isAssoOffseed = isAssociateOfflineSeedToL1(offlineSeedHandle, dRmtx, tsos, imu, selOffseeds, dRcone );
544 
545  if(isAssoOffseed) {
546  isAsso = true;
547  }
548 
549  // Using old way
550  else {
551  if(useUnassociatedL1) {
552  // convert the TSOS into a PTSOD
553  PTrajectoryStateOnDet const & seedTSOS = trajectoryStateTransform::persistentState( tsos, theid.rawId());
554  output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum,
555  MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) )));
556  }
557  }
558 
559  }
560 
561  else if( valid_charge ) {
562 
563  // Get the compatible dets on the layer
564  std::vector< pair<const GeomDet*,TrajectoryStateOnSurface> >
565  detsWithStates = detLayer->compatibleDets(tsos,
566  *theService->propagator(thePropagatorName),
567  *theEstimator);
568 
569  if (detsWithStates.empty() && barrel ) {
570  // Fallback solution using ME2, try again to propagate but using ME2 as reference
571  DetId fallback_id;
572  theta < Geom::pi()/2. ? fallback_id = CSCDetId(1,2,0,0,0) : fallback_id = CSCDetId(2,2,0,0,0);
573  const DetLayer* ME2DetLayer = theService->detLayerGeometry()->idToLayer(fallback_id);
574 
575  tsos = theService->propagator(thePropagatorName)->propagate(state, ME2DetLayer->surface());
576  detsWithStates = ME2DetLayer->compatibleDets(tsos,
577  *theService->propagator(thePropagatorName),
578  *theEstimator);
579  }
580 
581  if (!detsWithStates.empty()){
582 
583  TrajectoryStateOnSurface newTSOS = detsWithStates.front().second;
584  const GeomDet *newTSOSDet = detsWithStates.front().first;
585 
586  LogDebug(metname) << "Most compatible det";
587  LogDebug(metname) << debug.dumpMuonId(newTSOSDet->geographicalId());
588 
589  if (newTSOS.isValid()){
590 
591  LogDebug(metname) << "pos: (r=" << newTSOS.globalPosition().mag() << ", phi="
592  << newTSOS.globalPosition().phi() << ", eta=" << newTSOS.globalPosition().eta() << ")";
593  LogDebug(metname) << "mom: (q*pt=" << newTSOS.charge()*newTSOS.globalMomentum().perp() << ", phi="
594  << newTSOS.globalMomentum().phi() << ", eta=" << newTSOS.globalMomentum().eta() << ")";
595 
596  bool isAssoOffseed = isAssociateOfflineSeedToL1(offlineSeedHandle, dRmtx, newTSOS, imu, selOffseeds, dRcone );
597 
598  if(isAssoOffseed) {
599  isAsso = true;
600  }
601 
602  // Using old way
603  else {
604  if(useUnassociatedL1) {
605  // convert the TSOS into a PTSOD
606  PTrajectoryStateOnDet const & seedTSOS = trajectoryStateTransform::persistentState( newTSOS,newTSOSDet->geographicalId().rawId());
607  output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum,
608  MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) )));
609  }
610  }
611 
612  }
613  }
614  }
615  } // useOfflineSeed
616 
617  else {
618  // convert the TSOS into a PTSOD
619  PTrajectoryStateOnDet const & seedTSOS = trajectoryStateTransform::persistentState( tsos, theid.rawId());
620  output->push_back(L2MuonTrajectorySeed(seedTSOS,container,alongMomentum,
621  MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) )));
622  }
623 
624  }
625  }
626  }
627 
628  // MatchType : 0 Old matching, 1 L1 Order(1to1), 2 Min dR(1to1), 3 Higher Q(1to1), 4 All matched L1
629  if(useOfflineSeed && isAsso) {
630  unsigned int nOfflineSeed1 = offlineSeedHandle->size();
631  unsigned int nL1;
632  unsigned int i, j; // for the matrix element
633 
634  if(matchType==1) {
635  vector<bool> removed_col = vector<bool>(nOfflineSeed1, false);
636 
637  for(nL1=0; nL1 < nMuColl; ++nL1) {
638  double tempDR = 99.;
639  unsigned int theOffs = 0;
640 
641  for(j=0; j<nOfflineSeed1; ++j) {
642  if(removed_col[j]) continue;
643  if( tempDR > dRmtx[nL1][j] ) {
644  tempDR = dRmtx[nL1][j];
645  theOffs = j;
646  }
647  }
648 
649  auto it = muColl->begin(muColl->getFirstBX()) + nL1;
650 
651  double newDRcone = matchingDR[0];
652  if ( fabs(it->eta()) < etaBins.back() ){
653  std::vector<double>::iterator lowEdge = std::upper_bound (etaBins.begin(), etaBins.end(), fabs(it->eta()));
654  newDRcone = matchingDR.at( lowEdge - etaBins.begin() - 1);
655  }
656 
657  if( !(tempDR < newDRcone) ) continue;
658 
659  // Remove column for given offSeed
660  removed_col[theOffs] = true;
661 
662  if( selOffseeds[nL1][theOffs] != nullptr ) {
663  //put given L1mu and offSeed to output
664  edm::OwnVector<TrackingRecHit> newContainer;
665 
666  PTrajectoryStateOnDet const & seedTSOS = selOffseeds[nL1][theOffs] ->startingState();
668  tsci = selOffseeds[nL1][theOffs]->recHits().first,
669  tscie = selOffseeds[nL1][theOffs]->recHits().second;
670  for(; tsci!=tscie; ++tsci) {
671  newContainer.push_back(*tsci);
672  }
673  output->push_back(L2MuonTrajectorySeed(seedTSOS,newContainer,alongMomentum,
674  MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) )));
675  }
676  }
677  }
678 
679  else if(matchType==2) {
680  vector<bool> removed_row = vector<bool>(nMuColl, false);
681  vector<bool> removed_col = vector<bool>(nOfflineSeed1, false);
682 
683  for(nL1=0; nL1 < nMuColl; ++nL1) {
684  double tempDR = 99.;
685  unsigned int theL1 = 0;
686  unsigned int theOffs = 0;
687 
688  for(i=0; i<nMuColl; ++i) {
689  if(removed_row[i]) continue;
690  for(j=0; j<nOfflineSeed1; ++j) {
691  if(removed_col[j]) continue;
692  if(tempDR > dRmtx[i][j]) {
693  tempDR = dRmtx[i][j];
694  theL1 = i;
695  theOffs = j;
696  }
697  }
698  }
699 
700  auto it = muColl->begin(muColl->getFirstBX()) + theL1;
701 
702  double newDRcone = matchingDR[0];
703  if ( fabs(it->eta()) < etaBins.back() ){
704  std::vector<double>::iterator lowEdge = std::upper_bound (etaBins.begin(), etaBins.end(), fabs(it->eta()));
705  newDRcone = matchingDR.at( lowEdge - etaBins.begin() - 1);
706  }
707 
708  if( !(tempDR < newDRcone) ) continue;
709 
710  // Remove row and column for given (L1mu, offSeed)
711  removed_col[theOffs] = true;
712  removed_row[theL1] = true;
713 
714  if( selOffseeds[theL1][theOffs] != nullptr ) {
715  //put given L1mu and offSeed to output
716  edm::OwnVector<TrackingRecHit> newContainer;
717 
718  PTrajectoryStateOnDet const & seedTSOS = selOffseeds[theL1][theOffs] ->startingState();
720  tsci = selOffseeds[theL1][theOffs]->recHits().first,
721  tscie = selOffseeds[theL1][theOffs]->recHits().second;
722  for(; tsci!=tscie; ++tsci) {
723  newContainer.push_back(*tsci);
724  }
725  output->push_back(L2MuonTrajectorySeed(seedTSOS,newContainer,alongMomentum,
726  MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) )));
727  }
728  }
729  }
730 
731  else if(matchType==3) {
732  vector<bool> removed_row = vector<bool>(nMuColl, false);
733  vector<bool> removed_col = vector<bool>(nOfflineSeed1, false);
734 
735  for(nL1=0; nL1 < nMuColl; ++nL1) {
736  double tempDR = 99.;
737  unsigned int theL1 = 0;
738  unsigned int theOffs = 0;
739  auto theit = muColl->begin(muColl->getFirstBX());
740 
741  // L1Q > 10 (L1Q = 12)
742  for(i=0; i<nMuColl; ++i) {
743  if(removed_row[i]) continue;
744  theit = muColl->begin(muColl->getFirstBX()) + i;
745  if (theit->hwQual() > 10) {
746  for(j=0; j<nOfflineSeed1; ++j) {
747  if(removed_col[j]) continue;
748  if(tempDR > dRmtx[i][j]) {
749  tempDR = dRmtx[i][j];
750  theL1 = i;
751  theOffs = j;
752  }
753  }
754  }
755  }
756 
757  // 6 < L1Q <= 10 (L1Q = 8)
758  if (tempDR == 99.) {
759  for(i=0; i<nMuColl; ++i) {
760  if(removed_row[i]) continue;
761  theit = muColl->begin(muColl->getFirstBX()) + i;
762  if ( (theit->hwQual() <= 10) && (theit->hwQual() > 6) ) {
763  for(j=0; j<nOfflineSeed1; ++j) {
764  if(removed_col[j]) continue;
765  if(tempDR > dRmtx[i][j]) {
766  tempDR = dRmtx[i][j];
767  theL1 = i;
768  theOffs = j;
769  }
770  }
771  }
772  }
773  }
774 
775  // L1Q <= 6 (L1Q = 4)
776  if (tempDR == 99.) {
777  for(i=0; i<nMuColl; ++i) {
778  if(removed_row[i]) continue;
779  theit = muColl->begin(muColl->getFirstBX()) + i;
780  if (theit->hwQual() <= 6) {
781  for(j=0; j<nOfflineSeed1; ++j) {
782  if(removed_col[j]) continue;
783  if(tempDR > dRmtx[i][j]) {
784  tempDR = dRmtx[i][j];
785  theL1 = i;
786  theOffs = j;
787  }
788  }
789  }
790  }
791  }
792 
793  auto it = muColl->begin(muColl->getFirstBX()) + theL1;
794 
795  double newDRcone = matchingDR[0];
796  if ( fabs(it->eta()) < etaBins.back() ){
797  std::vector<double>::iterator lowEdge = std::upper_bound (etaBins.begin(), etaBins.end(), fabs(it->eta()));
798  newDRcone = matchingDR.at( lowEdge - etaBins.begin() - 1);
799  }
800 
801  if( !(tempDR < newDRcone) ) continue;
802 
803  // Remove row and column for given (L1mu, offSeed)
804  removed_col[theOffs] = true;
805  removed_row[theL1] = true;
806 
807  if( selOffseeds[theL1][theOffs] != nullptr ) {
808  //put given L1mu and offSeed to output
809  edm::OwnVector<TrackingRecHit> newContainer;
810 
811  PTrajectoryStateOnDet const & seedTSOS = selOffseeds[theL1][theOffs] ->startingState();
813  tsci = selOffseeds[theL1][theOffs]->recHits().first,
814  tscie = selOffseeds[theL1][theOffs]->recHits().second;
815  for(; tsci!=tscie; ++tsci) {
816  newContainer.push_back(*tsci);
817  }
818  output->push_back(L2MuonTrajectorySeed(seedTSOS,newContainer,alongMomentum,
819  MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) )));
820  }
821  }
822  }
823 
824  else if(matchType==4) {
825 
826  for(i=0; i<nMuColl; ++i) {
827 
828  auto it = muColl->begin(muColl->getFirstBX()) + i;
829 
830  double tempDR = 99.;
831  unsigned int theOffs = 0;
832 
833  double newDRcone = matchingDR[0];
834  if ( fabs(it->eta()) < etaBins.back() ){
835  std::vector<double>::iterator lowEdge = std::upper_bound (etaBins.begin(), etaBins.end(), fabs(it->eta()));
836  newDRcone = matchingDR.at( lowEdge - etaBins.begin() - 1);
837  }
838 
839  for(j=0; j<nOfflineSeed1; ++j) {
840  if( tempDR > dRmtx[i][j] ) {
841  tempDR = dRmtx[i][j];
842  theOffs = j;
843  }
844  }
845 
846  if( !(tempDR < newDRcone) ) continue;
847 
848  if( selOffseeds[i][theOffs] != nullptr ) {
849  //put given L1mu and offSeed to output
850  edm::OwnVector<TrackingRecHit> newContainer;
851 
852  PTrajectoryStateOnDet const & seedTSOS = selOffseeds[i][theOffs] ->startingState();
854  tsci = selOffseeds[i][theOffs]->recHits().first,
855  tscie = selOffseeds[i][theOffs]->recHits().second;
856  for(; tsci!=tscie; ++tsci) {
857  newContainer.push_back(*tsci);
858  }
859  output->push_back(L2MuonTrajectorySeed(seedTSOS,newContainer,alongMomentum,
860  MuonRef(muColl, distance(muColl->begin(muColl->getFirstBX()),it) )));
861  }
862  }
863  }
864 
865  } // useOfflineSeed && isAsso
866 
867  } // matchType > 0
868 
869  //--- SortType 1 : by L1 pT
870  if(sortType == 1) {
871  sort(output->begin(),output->end(),sortByL1Pt);
872  }
873 
874  //--- SortType 2 : by L1 quality and pT
875  else if(sortType == 2) {
876  sort(output->begin(),output->end(),sortByL1QandPt);
877  }
878 
879 
880  iEvent.put(std::move(output));
881 }
882 
883 
884 // FIXME: does not resolve ambiguities yet!
886  std::vector<int> & offseedMap,
887  TrajectoryStateOnSurface & newTsos,
888  double dRcone ) {
889 
890  const std::string metlabel = "Muon|RecoMuon|L2MuonSeedGeneratorFromL1T";
891  MuonPatternRecoDumper debugtmp;
892 
893  edm::View<TrajectorySeed>::const_iterator offseed, endOffseed = offseeds->end();
894  const TrajectorySeed *selOffseed = nullptr;
895  double bestDr = 99999.;
896  unsigned int nOffseed(0);
897  int lastOffseed(-1);
898 
899  for(offseed=offseeds->begin(); offseed!=endOffseed; ++offseed, ++nOffseed) {
900  if(offseedMap[nOffseed]!=0) continue;
901  GlobalPoint glbPos = theService->trackingGeometry()->idToDet(offseed->startingState().detId())->surface().toGlobal(offseed->startingState().parameters().position());
902  GlobalVector glbMom = theService->trackingGeometry()->idToDet(offseed->startingState().detId())->surface().toGlobal(offseed->startingState().parameters().momentum());
903 
904  // Preliminary check
905  double preDr = deltaR( newTsos.globalPosition().eta(), newTsos.globalPosition().phi(), glbPos.eta(), glbPos.phi() );
906  if(preDr > 1.0) continue;
907 
908  const FreeTrajectoryState offseedFTS(glbPos, glbMom, offseed->startingState().parameters().charge(), &*theService->magneticField());
909  TrajectoryStateOnSurface offseedTsos = theService->propagator(thePropagatorName)->propagate(offseedFTS, newTsos.surface());
910  LogDebug(metlabel) << "Offline seed info: Det and State" << std::endl;
911  LogDebug(metlabel) << debugtmp.dumpMuonId(offseed->startingState().detId()) << std::endl;
912  LogDebug(metlabel) << "pos: (r=" << offseedFTS.position().mag() << ", phi="
913  << offseedFTS.position().phi() << ", eta=" << offseedFTS.position().eta() << ")" << std::endl;
914  LogDebug(metlabel) << "mom: (q*pt=" << offseedFTS.charge()*offseedFTS.momentum().perp() << ", phi="
915  << offseedFTS.momentum().phi() << ", eta=" << offseedFTS.momentum().eta() << ")" << std::endl << std::endl;
916 
917  if(offseedTsos.isValid()) {
918  LogDebug(metlabel) << "Offline seed info after propagation to L1 layer:" << std::endl;
919  LogDebug(metlabel) << "pos: (r=" << offseedTsos.globalPosition().mag() << ", phi="
920  << offseedTsos.globalPosition().phi() << ", eta=" << offseedTsos.globalPosition().eta() << ")" << std::endl;
921  LogDebug(metlabel) << "mom: (q*pt=" << offseedTsos.charge()*offseedTsos.globalMomentum().perp() << ", phi="
922  << offseedTsos.globalMomentum().phi() << ", eta=" << offseedTsos.globalMomentum().eta() << ")" << std::endl << std::endl;
923  double newDr = deltaR( newTsos.globalPosition().eta(), newTsos.globalPosition().phi(),
924  offseedTsos.globalPosition().eta(), offseedTsos.globalPosition().phi() );
925  LogDebug(metlabel) << " -- DR = " << newDr << std::endl;
926  if( newDr < dRcone && newDr<bestDr ) {
927  LogDebug(metlabel) << " --> OK! " << newDr << std::endl << std::endl;
928  selOffseed = &*offseed;
929  bestDr = newDr;
930  offseedMap[nOffseed] = 1;
931  if(lastOffseed>-1) offseedMap[lastOffseed] = 0;
932  lastOffseed = nOffseed;
933  }
934  else {
935  LogDebug(metlabel) << " --> Rejected. " << newDr << std::endl << std::endl;
936  }
937  }
938  else {
939  LogDebug(metlabel) << "Invalid offline seed TSOS after propagation!" << std::endl << std::endl;
940  }
941  }
942 
943  return selOffseed;
944 }
945 
946 
948  std::vector< std::vector<double> > & dRmtx,
949  TrajectoryStateOnSurface & newTsos,
950  unsigned int imu,
951  std::vector< std::vector<const TrajectorySeed *> > & selOffseeds,
952  double dRcone ) {
953 
954  const std::string metlabel = "Muon|RecoMuon|L2MuonSeedGeneratorFromL1T";
955  bool isAssociated = false;
956  MuonPatternRecoDumper debugtmp;
957 
958  edm::View<TrajectorySeed>::const_iterator offseed, endOffseed = offseeds->end();
959  unsigned int nOffseed(0);
960 
961  for(offseed=offseeds->begin(); offseed!=endOffseed; ++offseed, ++nOffseed) {
962  GlobalPoint glbPos = theService->trackingGeometry()->idToDet(offseed->startingState().detId())->surface().toGlobal(offseed->startingState().parameters().position());
963  GlobalVector glbMom = theService->trackingGeometry()->idToDet(offseed->startingState().detId())->surface().toGlobal(offseed->startingState().parameters().momentum());
964 
965  // Preliminary check
966  double preDr = deltaR( newTsos.globalPosition().eta(), newTsos.globalPosition().phi(), glbPos.eta(), glbPos.phi() );
967  if(preDr > 1.0) continue;
968 
969  const FreeTrajectoryState offseedFTS(glbPos, glbMom, offseed->startingState().parameters().charge(), &*theService->magneticField());
970  TrajectoryStateOnSurface offseedTsos = theService->propagator(thePropagatorName)->propagate(offseedFTS, newTsos.surface());
971  LogDebug(metlabel) << "Offline seed info: Det and State" << std::endl;
972  LogDebug(metlabel) << debugtmp.dumpMuonId(offseed->startingState().detId()) << std::endl;
973  LogDebug(metlabel) << "pos: (r=" << offseedFTS.position().mag() <<
974  ", phi=" << offseedFTS.position().phi() <<
975  ", eta=" << offseedFTS.position().eta() << ")" << std::endl;
976  LogDebug(metlabel) << "mom: (q*pt=" << offseedFTS.charge()*offseedFTS.momentum().perp() <<
977  ", phi=" << offseedFTS.momentum().phi() <<
978  ", eta=" << offseedFTS.momentum().eta() << ")" << std::endl << std::endl;
979 
980  if(offseedTsos.isValid()) {
981  LogDebug(metlabel) << "Offline seed info after propagation to L1 layer:" << std::endl;
982  LogDebug(metlabel) << "pos: (r=" << offseedTsos.globalPosition().mag() <<
983  ", phi=" << offseedTsos.globalPosition().phi() <<
984  ", eta=" << offseedTsos.globalPosition().eta() << ")" << std::endl;
985  LogDebug(metlabel) << "mom: (q*pt=" << offseedTsos.charge()*offseedTsos.globalMomentum().perp() <<
986  ", phi=" << offseedTsos.globalMomentum().phi() <<
987  ", eta=" << offseedTsos.globalMomentum().eta() << ")" << std::endl << std::endl;
988  double newDr = deltaR( newTsos.globalPosition().eta(), newTsos.globalPosition().phi(),
989  offseedTsos.globalPosition().eta(), offseedTsos.globalPosition().phi() );
990 
991 
992  LogDebug(metlabel) << " -- DR = " << newDr << std::endl;
993  if( newDr < dRcone ) {
994  LogDebug(metlabel) << " --> OK! " << newDr << std::endl << std::endl;
995 
996  dRmtx[imu][nOffseed] = newDr;
997  selOffseeds[imu][nOffseed] = &*offseed;
998 
999  isAssociated = true;
1000  }
1001  else {
1002  LogDebug(metlabel) << " --> Rejected. " << newDr << std::endl << std::endl;
1003  }
1004  }
1005  else {
1006  LogDebug(metlabel) << "Invalid offline seed TSOS after propagation!" << std::endl << std::endl;
1007  }
1008  }
1009 
1010  return isAssociated;
1011 }
#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:137
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:579
bool sortByL1Pt(L2MuonTrajectorySeed &A, L2MuonTrajectorySeed &B)
const std::string metname
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:47
PTrajectoryStateOnDet persistentState(const TrajectoryStateOnSurface &ts, unsigned int detid)
Geom::Theta< T > theta() const
l1t::MuonRef l1tParticle() 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:13
std::string dumpMuonId(const DetId &id) const
std::string dumpFTS(const FreeTrajectoryState &fts) const
~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
bool isAssociateOfflineSeedToL1(edm::Handle< edm::View< TrajectorySeed > > &, std::vector< std::vector< double > > &, TrajectoryStateOnSurface &, unsigned int, std::vector< std::vector< const TrajectorySeed * > > &, double)
virtual const BoundSurface & surface() const =0
The surface of the GeometricSearchDet.
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:79
bool sortByL1QandPt(L2MuonTrajectorySeed &A, L2MuonTrajectorySeed &B)
static const std::string B
ParameterDescriptionBase * add(U const &iLabel, T const &value)
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:511