CMS 3D CMS Logo

L1TrackerEtMissEmulatorProducer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: L1Trigger/L1TTrackMatch
4 // Class: L1TrackerEtMissEmulatorProducer
5 //
12 //
13 // Original Author: Christopher Brown
14 // Created: Fri, 19 Feb 2021
15 // Updated: Wed, 16 Jun 2021
16 //
17 //
18 
19 // system include files
20 #include <memory>
21 #include <numeric>
22 // user include files
38 
39 using namespace l1t;
40 
42 public:
44  typedef std::vector<L1TTTrackType> L1TTTrackCollectionType;
48 
49  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
50 
53 
54 private:
55  virtual void beginJob();
56  void produce(edm::Event&, const edm::EventSetup&) override;
57  virtual void endJob();
58 
59  // ----------member data ---------------------------
60 
61  std::vector<l1tmetemu::global_phi_t> cosLUT_; // Cos LUT array
62  std::vector<l1tmetemu::global_phi_t> phiQuadrants_;
63  std::vector<l1tmetemu::global_phi_t> phiShifts_;
64 
65  l1tmetemu::z_t deltaZ0_ = 0;
66 
68  int debug_;
69  bool cordicDebug_ = false;
70 
71  bool GTTinput_ = false;
72 
74 
76 
80 };
81 
82 // constructor//
84  : pvToken_(consumes<L1VertexCollectionType>(iConfig.getParameter<edm::InputTag>("L1VertexInputTag"))),
85  trackToken_(consumes<L1TTTrackRefCollectionType>(iConfig.getParameter<edm::InputTag>("L1TrackInputTag"))),
86  vtxAssocTrackToken_(
87  consumes<L1TTTrackRefCollectionType>(iConfig.getParameter<edm::InputTag>("L1TrackAssociatedInputTag"))) {
88  // Setup LUTs
92 
93  // Get Emulator config parameters
94  cordicSteps_ = (int)iConfig.getParameter<int>("nCordicSteps");
95  debug_ = (int)iConfig.getParameter<int>("debug");
96 
97  GTTinput_ = (bool)iConfig.getParameter<bool>("useGTTinput");
98 
100 
101  // Name of output ED Product
102  L1MetCollectionName_ = (std::string)iConfig.getParameter<std::string>("L1MetCollectionName");
103 
104  if (debug_ == 5) {
105  cordicDebug_ = true;
106  }
107 
108  // To have same bin spacing between 0 and pi/2 as between original phi
109  // granularity
110  int cosLUTbins = floor(l1tmetemu::kMaxCosLUTPhi / l1tmetemu::kStepPhi);
111 
112  // Compute LUTs
113  cosLUT_ = l1tmetemu::generateCosLUT(cosLUTbins);
114 
115  produces<std::vector<EtSum>>(L1MetCollectionName_);
116 }
117 
119 
121  using namespace edm;
122 
123  std::unique_ptr<std::vector<l1t::EtSum>> METCollection(new std::vector<l1t::EtSum>(0));
124 
126  iEvent.getByToken(pvToken_, L1VertexHandle);
127 
129  iEvent.getByToken(trackToken_, L1TTTrackHandle);
130 
131  edm::Handle<L1TTTrackRefCollectionType> L1TTTrackAssociatedHandle;
132  iEvent.getByToken(vtxAssocTrackToken_, L1TTTrackAssociatedHandle);
133 
134  // Initialize cordic class
136 
137  if (!L1VertexHandle.isValid()) {
138  LogError("L1TrackerEtMissEmulatorProducer") << "\nWarning: VertexCollection not found in the event. Exit\n";
139  return;
140  }
141 
142  if (!L1TTTrackHandle.isValid()) {
143  LogError("L1TrackerEtMissEmulatorProducer") << "\nWarning: L1TTTrackCollection not found in the event. Exit\n";
144  return;
145  }
146 
147  if (!L1TTTrackAssociatedHandle.isValid()) {
148  LogError("L1TrackerEtMissEmulatorProducer")
149  << "\nWarning: L1TTTrackAssociatedCollection not found in the event. Exit\n";
150  return;
151  }
152 
153  // Initialize sector sums, need 0 initialization in case a sector has no
154  // tracks
155  l1tmetemu::Et_t sumPx[l1tmetemu::kNSector * 2] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
156  l1tmetemu::Et_t sumPy[l1tmetemu::kNSector * 2] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
157  int sector_totals[l1tmetemu::kNSector] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
158 
159  // Track counters
160  int num_quality_tracks{0};
161  int num_assoc_tracks{0};
162 
163  // Get reference to first vertex in event vertex collection
164  L1VertexType& vtx = const_cast<L1VertexType&>(L1VertexHandle->at(0));
165 
166  for (const auto& track : *L1TTTrackHandle) {
167  num_quality_tracks++;
168  L1TTTrackType& track_ref = const_cast<L1TTTrackType&>(*track); // Get Reference to track to pass to TrackTransform
169 
170  // Convert to internal track representation
172 
173  if (std::find(L1TTTrackAssociatedHandle->begin(), L1TTTrackAssociatedHandle->end(), track) !=
174  L1TTTrackAssociatedHandle->end()) {
175  num_assoc_tracks++;
176  if (debug_ == 7) {
177  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
178  << "Track to Vertex ID: " << num_quality_tracks << "\n"
179  << "Phi Sector: " << EtTrack.Sector << " pT: " << EtTrack.pt << " Phi: " << EtTrack.globalPhi
180  << " TanL: " << EtTrack.eta << " Z0: " << EtTrack.z0 << " Nstub: " << EtTrack.nstubs
181  << " Chi2rphi: " << EtTrack.chi2rphidof << " Chi2rz: " << EtTrack.chi2rzdof
182  << " bendChi2: " << EtTrack.bendChi2 << " PV: " << EtTrack.pV << "\n"
183  << "--------------------------------------------------------------\n";
184  }
185 
186  if (debug_ == 2) {
187  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
188  << "========================Phi debug=================================\n"
189  << "Int pT: " << EtTrack.pt << "\n"
190  << "Int Phi: " << EtTrack.globalPhi << " Float Phi: " << EtTrack.phi
191  << " Actual Float Cos(Phi): " << cos(EtTrack.phi) << " Actual Float Sin(Phi): " << sin(EtTrack.phi) << "\n";
192  }
193  l1tmetemu::Et_t temppx = 0;
194  l1tmetemu::Et_t temppy = 0;
195 
196  // Split tracks in phi quadrants and access cosLUT_, backwards iteration
197  // through cosLUT_ gives sin Sum sector Et -ve when cos or sin phi are -ve
198  sector_totals[EtTrack.Sector] += 1;
199  if (EtTrack.globalPhi >= phiQuadrants_[0] && EtTrack.globalPhi < phiQuadrants_[1]) {
200  temppx = (EtTrack.pt * cosLUT_[EtTrack.globalPhi]);
201  temppy = (EtTrack.pt * cosLUT_[phiQuadrants_[1] - 1 - EtTrack.globalPhi]);
202 
203  if (debug_ == 2) {
204  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
205  << "Sector: " << EtTrack.Sector << " Quadrant: " << 1 << "\n"
206  << "Int Phi: " << EtTrack.globalPhi << " Int Cos(Phi): " << cosLUT_[EtTrack.globalPhi]
207  << " Int Sin(Phi): " << cosLUT_[phiQuadrants_[1] - 1 - EtTrack.globalPhi] << "\n"
208 
209  << "Float Phi: " << (float)EtTrack.globalPhi / l1tmetemu::kGlobalPhiBins
210  << " Float Cos(Phi): " << (float)cosLUT_[EtTrack.globalPhi] / l1tmetemu::kGlobalPhiBins
211  << " Float Sin(Phi): "
212  << (float)cosLUT_[phiQuadrants_[1] - 1 - EtTrack.globalPhi] / l1tmetemu::kGlobalPhiBins << "\n";
213  }
214  } else if (EtTrack.globalPhi >= phiQuadrants_[1] && EtTrack.globalPhi < phiQuadrants_[2]) {
215  temppx = -(EtTrack.pt * cosLUT_[phiQuadrants_[2] - 1 - EtTrack.globalPhi]);
216  temppy = (EtTrack.pt * cosLUT_[EtTrack.globalPhi - phiQuadrants_[1]]);
217 
218  if (debug_ == 2) {
219  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
220  << "Sector: " << EtTrack.Sector << " Quadrant: " << 2 << "\n"
221  << "Int Phi: " << EtTrack.globalPhi << " Int Cos(Phi): -"
222  << cosLUT_[phiQuadrants_[2] - 1 - EtTrack.globalPhi]
223  << " Int Sin(Phi): " << cosLUT_[EtTrack.globalPhi - phiQuadrants_[1]] << "\n"
224 
225  << "Float Phi: " << (float)EtTrack.globalPhi / l1tmetemu::kGlobalPhiBins << " Float Cos(Phi): -"
226  << (float)cosLUT_[phiQuadrants_[2] - 1 - EtTrack.globalPhi] / l1tmetemu::kGlobalPhiBins
227  << " Float Sin(Phi): " << (float)cosLUT_[EtTrack.globalPhi - phiQuadrants_[1]] / l1tmetemu::kGlobalPhiBins
228  << "\n";
229  }
230  } else if (EtTrack.globalPhi >= phiQuadrants_[2] && EtTrack.globalPhi < phiQuadrants_[3]) {
231  temppx = -(EtTrack.pt * cosLUT_[EtTrack.globalPhi - phiQuadrants_[2]]);
232  temppy = -(EtTrack.pt * cosLUT_[phiQuadrants_[3] - 1 - EtTrack.globalPhi]);
233 
234  if (debug_ == 2) {
235  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
236  << "Sector: " << EtTrack.Sector << " Quadrant: " << 3 << "\n"
237  << "Int Phi: " << EtTrack.globalPhi << " Int Cos(Phi): -" << cosLUT_[EtTrack.globalPhi - phiQuadrants_[2]]
238  << " Int Sin(Phi): -" << cosLUT_[phiQuadrants_[3] - 1 - EtTrack.globalPhi] << "\n"
239 
240  << "Float Phi: " << (float)EtTrack.globalPhi / l1tmetemu::kGlobalPhiBins << " Float Cos(Phi): -"
241  << (float)cosLUT_[EtTrack.globalPhi - phiQuadrants_[2]] / l1tmetemu::kGlobalPhiBins
242  << " Float Sin(Phi): -"
243  << (float)cosLUT_[phiQuadrants_[3] - 1 - EtTrack.globalPhi] / l1tmetemu::kGlobalPhiBins << "\n";
244  }
245 
246  } else if (EtTrack.globalPhi >= phiQuadrants_[3] && EtTrack.globalPhi < phiQuadrants_[4]) {
247  temppx = (EtTrack.pt * cosLUT_[phiQuadrants_[4] - 1 - EtTrack.globalPhi]);
248  temppy = -(EtTrack.pt * cosLUT_[EtTrack.globalPhi - phiQuadrants_[3]]);
249 
250  if (debug_ == 2) {
251  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
252  << "Sector: " << EtTrack.Sector << " Quadrant: " << 4 << "\n"
253  << "Int Phi: " << EtTrack.globalPhi
254  << " Int Cos(Phi): " << cosLUT_[phiQuadrants_[4] - 1 - EtTrack.globalPhi] << " Int Sin(Phi): -"
255  << cosLUT_[EtTrack.globalPhi - phiQuadrants_[3]] << "\n"
256 
257  << "Float Phi: " << (float)EtTrack.globalPhi / l1tmetemu::kGlobalPhiBins << " Float Cos(Phi): "
258  << (float)cosLUT_[phiQuadrants_[4] - 1 - EtTrack.globalPhi] / l1tmetemu::kGlobalPhiBins
259  << " Float Sin(Phi): -"
260  << (float)cosLUT_[EtTrack.globalPhi - phiQuadrants_[3]] / l1tmetemu::kGlobalPhiBins << "\n";
261  }
262  } else {
263  temppx = 0;
264  temppy = 0;
265  }
266  if (EtTrack.EtaSector) {
267  sumPx[EtTrack.Sector] = sumPx[EtTrack.Sector] + temppx;
268  sumPy[EtTrack.Sector] = sumPy[EtTrack.Sector] + temppy;
269  } else {
270  sumPx[l1tmetemu::kNSector + EtTrack.Sector] = sumPx[l1tmetemu::kNSector + EtTrack.Sector] + temppx;
271  sumPy[l1tmetemu::kNSector + EtTrack.Sector] = sumPy[l1tmetemu::kNSector + EtTrack.Sector] + temppy;
272  }
273  }
274 
275  } // end loop over tracks
276 
277  l1tmetemu::Et_t GlobalPx = 0;
278  l1tmetemu::Et_t GlobalPy = 0;
279 
280  float tempsumPx = 0;
281  float tempsumPy = 0;
282 
283  // Global Et sum as floats to emulate rounding in HW
284  for (unsigned int i = 0; i < l1tmetemu::kNSector * 2; i++) {
285  tempsumPx += floor((float)sumPx[i] / (float)l1tmetemu::kGlobalPhiBins);
286  tempsumPy += floor((float)sumPy[i] / (float)l1tmetemu::kGlobalPhiBins);
287  }
288 
289  // Recast rounded temporary sums into Et_t datatype
290  GlobalPx = tempsumPx;
291  GlobalPy = tempsumPy;
292 
293  // Perform cordic sqrt, take x,y and converts to polar coordinate r,phi where
294  // r=sqrt(x**2+y**2) and phi = atan(y/x)
295  l1tmetemu::EtMiss EtMiss = cordicSqrt.toPolar(GlobalPx, GlobalPy);
296 
297  // Recentre phi
298  l1tmetemu::METphi_t tempPhi = 0;
299 
300  if ((GlobalPx < 0) && (GlobalPy < 0))
301  tempPhi = EtMiss.Phi - l1tmetemu::kMETPhiBins / 2;
302  else if ((GlobalPx >= 0) && (GlobalPy >= 0))
303  tempPhi = (EtMiss.Phi) + l1tmetemu::kMETPhiBins / 2;
304  else if ((GlobalPx >= 0) && (GlobalPy < 0))
305  tempPhi = EtMiss.Phi - l1tmetemu::kMETPhiBins / 2;
306  else if ((GlobalPx < 0) && (GlobalPy >= 0))
307  tempPhi = EtMiss.Phi - 3 * l1tmetemu::kMETPhiBins / 2;
308 
309  if (debug_ == 6) {
310  std::string flpxarray[l1tmetemu::kNSector * 2];
311  std::string flpyarray[l1tmetemu::kNSector * 2];
312 
313  std::string intpxarray[l1tmetemu::kNSector * 2];
314  std::string intpyarray[l1tmetemu::kNSector * 2];
315 
316  std::string totalsarray[l1tmetemu::kNSector * 2];
317 
318  for (unsigned int i = 0; i < l1tmetemu::kNSector * 2; i++) {
319  flpxarray[i] = to_string(sumPx[i] * l1tmetemu::kStepPt) + "|";
320  flpyarray[i] = to_string(sumPy[i] * l1tmetemu::kStepPt) + "|";
321  intpxarray[i] = to_string(floor((float)sumPx[i] / (float)l1tmetemu::kGlobalPhiBins)) + "|";
322  intpyarray[i] = to_string(floor((float)sumPy[i] / (float)l1tmetemu::kGlobalPhiBins)) + "|";
323  totalsarray[i] = to_string(sector_totals[i]) + "|";
324  }
325 
326  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
327  << "====Sector Pt====\n"
328  << "Float Px: " << flpxarray << "Float Py: " << flpyarray << "Integer Px: " << intpyarray
329  << "Integer Px: " << intpyarray << "Sector Totals: " << totalsarray
330 
331  << "====Global Pt====\n"
332  << "Integer Global Px: " << GlobalPx << "| Integer Global Py: " << GlobalPy << "\n"
333  << "Float Global Px: " << GlobalPx * l1tmetemu::kStepPt
334  << "| Float Global Py: " << GlobalPy * l1tmetemu::kStepPt << "\n";
335  }
336 
337  if (debug_ == 6) {
338  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
339  << "====MET===\n"
340  << "Integer MET: " << EtMiss.Et << "| Integer MET phi: " << EtMiss.Phi << "\n"
341  << "Float MET: " << (EtMiss.Et) * l1tmetemu::kStepMET
342  << "| Float MET phi: " << (float)tempPhi * l1tmetemu::kStepMETPhi - M_PI << "\n"
343  << "# Tracks after Quality Cuts: " << num_quality_tracks << "\n"
344  << "# Tracks Associated to Vertex: " << num_assoc_tracks << "\n"
345  << "========================================================\n";
346  }
347 
348  math::XYZTLorentzVector missingEt(-GlobalPx, -GlobalPy, 0, EtMiss.Et);
349  EtSum L1EtSum(missingEt, EtSum::EtSumType::kMissingEt, (int)EtMiss.Et, 0, (int)tempPhi, (int)num_assoc_tracks);
350 
351  METCollection->push_back(L1EtSum);
352 
354 } // end producer
355 
357 
359 
360 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
362  //The following says we do not know what parameters are allowed so do no validation
363  // Please change this to state exactly what you do use, even if it is no parameters
365  desc.setUnknown();
366  descriptions.addDefault(desc);
367 }
368 
369 // define this as a plug-in
const unsigned int kGlobalPhiBins
Log< level::Info, true > LogVerbatim
ap_uint< kMETPhiSize > METphi_t
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
TTTrack< Ref_Phase2TrackerDigi_ > L1TTTrackType
TTTrack_TrackWord::chi2rphi_t chi2rphidof
std::vector< l1tmetemu::global_phi_t > phiQuadrants_
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
std::vector< l1tmetemu::global_phi_t > getPhiShift() const
ap_uint< kInternalVTXWidth > z_t
std::string to_string(const V &value)
Definition: OMSAccess.h:71
delete x;
Definition: CaloConfig.h:22
EtMiss cordicSqrt(Et_t x, Et_t y, int cordicSteps, std::vector< l1tmhtemu::MHTphi_t > atanLUT, std::vector< Et_t > magNormalisationLUT)
const double kStepPt
const double kStepMET
Log< level::Error, false > LogError
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
std::vector< reco::MET > METCollection
collection of MET objects
Definition: METCollection.h:22
TTTrack_TrackWord::chi2rz_t chi2rzdof
const edm::EDGetTokenT< L1VertexCollectionType > pvToken_
void beginJob()
Definition: Breakpoints.cc:14
const unsigned int kNSector
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
int iEvent
Definition: GenABIO.cc:224
void addDefault(ParameterSetDescription const &psetDescription)
void produce(edm::Event &, const edm::EventSetup &) override
std::vector< l1tmetemu::global_phi_t > getPhiQuad() const
const edm::EDGetTokenT< L1TTTrackRefCollectionType > vtxAssocTrackToken_
L1TrackerEtMissEmulatorProducer(const edm::ParameterSet &)
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
const edm::EDGetTokenT< L1TTTrackRefCollectionType > trackToken_
const unsigned int kMETPhiBins
Definition: Cordic.h:7
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
const unsigned int kMETSize
std::vector< VertexWord > VertexWordCollection
Definition: VertexWord.h:195
Collection of MET.
#define M_PI
std::vector< l1tmetemu::global_phi_t > phiShifts_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
l1tmetemu::nstub_t nstubs
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Class to store the L1 Track Trigger tracks.
Definition: TTTrack.h:29
std::vector< global_phi_t > generateCosLUT(unsigned int size)
l1tmetemu::global_phi_t globalPhi
bool isValid() const
Definition: HandleBase.h:70
const float kMaxCosLUTPhi
std::vector< l1tmetemu::global_phi_t > cosLUT_
HLT enums.
TTTrack_TrackWord::bendChi2_t bendChi2
edm::RefVector< L1TTTrackCollectionType > L1TTTrackRefCollectionType
std::vector< L1TTTrackType > L1TTTrackCollectionType
InternalEtWord transformTrack(track &track_ref, vertex &PV)
def move(src, dest)
Definition: eostools.py:511
ap_int< kInternalPtWidth+kEtExtra > Et_t
const double kStepPhi
const double kStepMETPhi