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 <iomanip>
21 #include <memory>
22 #include <numeric>
23 #include <sstream>
24 // user include files
39 
40 using namespace l1t;
41 
43 public:
45  typedef std::vector<L1TTTrackType> L1TTTrackCollectionType;
47 
48  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
49 
52 
53 private:
54  virtual void beginJob();
55  void produce(edm::Event&, const edm::EventSetup&) override;
56  virtual void endJob();
57 
58  // ----------member data ---------------------------
59 
60  std::vector<l1tmetemu::cos_lut_fixed_t> cosLUT_; // Cos LUT array
61  std::vector<l1tmetemu::global_phi_t> phiQuadrants_;
62  std::vector<l1tmetemu::global_phi_t> phiShifts_;
63 
65  int debug_;
66  bool cordicDebug_ = false;
67 
69 
72 };
73 
74 // constructor//
76  : trackToken_(consumes<L1TTTrackRefCollectionType>(iConfig.getParameter<edm::InputTag>("L1TrackInputTag"))),
77  vtxAssocTrackToken_(
78  consumes<L1TTTrackRefCollectionType>(iConfig.getParameter<edm::InputTag>("L1TrackAssociatedInputTag"))) {
81 
82  // Get Emulator config parameters
83  cordicSteps_ = (int)iConfig.getParameter<int>("nCordicSteps");
84  debug_ = (int)iConfig.getParameter<int>("debug");
85  // Name of output ED Product
86  L1MetCollectionName_ = (std::string)iConfig.getParameter<std::string>("L1MetCollectionName");
87 
88  if (debug_ == 5) {
89  cordicDebug_ = true;
90  }
91 
92  // Compute LUTs
94 
95  // Print LUTs
96  if (debug_ == 1) {
97  l1tmetemu::printLUT(phiQuadrants_, "L1TrackerEtMissEmulatorProducer", "phiQuadrants_");
98  l1tmetemu::printLUT(phiShifts_, "L1TrackerEtMissEmulatorProducer", "phiShifts_");
99  l1tmetemu::printLUT(cosLUT_, "L1TrackerEtMissEmulatorProducer", "cosLUT_");
100  }
101 
102  produces<std::vector<EtSum>>(L1MetCollectionName_);
103 }
104 
106 
108  using namespace edm;
109 
110  std::unique_ptr<std::vector<l1t::EtSum>> METCollection(new std::vector<l1t::EtSum>(0));
111 
113  iEvent.getByToken(trackToken_, L1TTTrackHandle);
114 
115  edm::Handle<L1TTTrackRefCollectionType> L1TTTrackAssociatedHandle;
116  iEvent.getByToken(vtxAssocTrackToken_, L1TTTrackAssociatedHandle);
117 
118  // Initialize cordic class
120 
121  if (!L1TTTrackHandle.isValid()) {
122  LogError("L1TrackerEtMissEmulatorProducer") << "\nWarning: L1TTTrackCollection not found in the event. Exit\n";
123  return;
124  }
125 
126  if (!L1TTTrackAssociatedHandle.isValid()) {
127  LogError("L1TrackerEtMissEmulatorProducer")
128  << "\nWarning: L1TTTrackAssociatedCollection not found in the event. Exit\n";
129  return;
130  }
131 
132  // Initialize sector sums, need 0 initialization in case a sector has no
133  // tracks
134  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};
135  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};
136  int link_totals[l1tmetemu::kNSector * 2] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
137  int sector_totals[l1tmetemu::kNSector] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
138 
139  // Track counters
140  int num_assoc_tracks{0};
141 
142  for (const auto& track : *L1TTTrackHandle) {
143  if (std::find(L1TTTrackAssociatedHandle->begin(), L1TTTrackAssociatedHandle->end(), track) !=
144  L1TTTrackAssociatedHandle->end()) {
145  bool EtaSector = (track->getTanlWord() & (1 << (TTTrack_TrackWord::TrackBitWidths::kTanlSize - 1)));
146 
147  ap_uint<TTTrack_TrackWord::TrackBitWidths::kRinvSize - 1> ptEmulationBits = track->getTrackWord()(
148  TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1, TTTrack_TrackWord::TrackBitLocations::kRinvLSB);
149  ap_ufixed<TTTrack_TrackWord::TrackBitWidths::kRinvSize - 1, l1tmetemu::kPtMagSize> ptEmulation;
150  ptEmulation.V = ptEmulationBits.range();
151 
152  l1tmetemu::global_phi_t globalPhi =
153  l1tmetemu::localToGlobalPhi(track->getPhiWord(), phiShifts_[track->phiSector()]);
154 
155  num_assoc_tracks++;
156  if (debug_ == 7) {
157  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
158  << "Track to Vertex ID: " << num_assoc_tracks << "\n"
159  << "Phi Sector: " << track->phiSector() << " pT: " << track->getRinvWord()
160  << " Phi: " << track->getPhiWord() << " TanL: " << track->getTanlWord() << " Z0: " << track->getZ0Word()
161  << " Chi2rphi: " << track->getChi2RPhiWord() << " Chi2rz: " << track->getChi2RZWord()
162  << " bendChi2: " << track->getBendChi2Word() << " Emu pT " << ptEmulation.to_double() << "\n"
163  << "--------------------------------------------------------------\n";
164  }
165 
166  if (debug_ == 2) {
167  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
168  << "========================Phi debug=================================\n"
169  << "Emu pT: " << ptEmulation.to_double() << " float pT: " << track->momentum().perp() << "\n"
170  << "Int Phi: " << globalPhi << " Float Phi: " << track->phi() << " Float Cos(Phi): " << cos(track->phi())
171  << " Float Sin(Phi): " << sin(track->phi())
172  << " Float Px: " << track->momentum().perp() * cos(track->phi())
173  << " Float Py: " << track->momentum().perp() * sin(track->phi()) << "\n";
174  }
175 
176  l1tmetemu::Et_t temppx = 0;
177  l1tmetemu::Et_t temppy = 0;
178 
179  // Split tracks in phi quadrants and access cosLUT_, backwards iteration
180  // through cosLUT_ gives sin Sum sector Et -ve when cos or sin phi are -ve
181  sector_totals[track->phiSector()] += 1;
182  if (globalPhi >= phiQuadrants_[0] && globalPhi < phiQuadrants_[1]) {
183  temppx = ((l1tmetemu::Et_t)ptEmulation * cosLUT_[(globalPhi) >> l1tmetemu::kCosLUTShift]);
184  temppy =
185  ((l1tmetemu::Et_t)ptEmulation * cosLUT_[(phiQuadrants_[1] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift]);
186 
187  if (debug_ == 2) {
188  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
189  << "Sector: " << track->phiSector() << " Quadrant: " << 1 << "\n"
190  << "Emu Phi: " << globalPhi << " Emu Cos(Phi): " << cosLUT_[(globalPhi) >> l1tmetemu::kCosLUTShift]
191  << " Emu Sin(Phi): " << cosLUT_[(phiQuadrants_[1] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift] << "\n";
192  }
193  } else if (globalPhi >= phiQuadrants_[1] && globalPhi < phiQuadrants_[2]) {
194  temppx =
195  -((l1tmetemu::Et_t)ptEmulation * cosLUT_[(phiQuadrants_[2] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift]);
196  temppy = ((l1tmetemu::Et_t)ptEmulation * cosLUT_[(globalPhi - phiQuadrants_[1]) >> l1tmetemu::kCosLUTShift]);
197 
198  if (debug_ == 2) {
199  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
200  << "Sector: " << track->phiSector() << " Quadrant: " << 2 << "\n"
201  << "Emu Phi: " << globalPhi << " Emu Cos(Phi): -"
202  << cosLUT_[(phiQuadrants_[2] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift]
203  << " Emu Sin(Phi): " << cosLUT_[(globalPhi - phiQuadrants_[1]) >> l1tmetemu::kCosLUTShift] << "\n";
204  }
205  } else if (globalPhi >= phiQuadrants_[2] && globalPhi < phiQuadrants_[3]) {
206  temppx = -((l1tmetemu::Et_t)ptEmulation * cosLUT_[(globalPhi - phiQuadrants_[2]) >> l1tmetemu::kCosLUTShift]);
207  temppy =
208  -((l1tmetemu::Et_t)ptEmulation * cosLUT_[(phiQuadrants_[3] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift]);
209 
210  if (debug_ == 2) {
211  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
212  << "Sector: " << track->phiSector() << " Quadrant: " << 3 << "\n"
213  << "Emu Phi: " << globalPhi << " Emu Cos(Phi): -"
214  << cosLUT_[(globalPhi - phiQuadrants_[2]) >> l1tmetemu::kCosLUTShift] << " Emu Sin(Phi): -"
215  << cosLUT_[(phiQuadrants_[3] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift] << "\n";
216  }
217 
218  } else if (globalPhi >= phiQuadrants_[3] && globalPhi < phiQuadrants_[4]) {
219  temppx =
220  ((l1tmetemu::Et_t)ptEmulation * cosLUT_[(phiQuadrants_[4] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift]);
221  temppy = -((l1tmetemu::Et_t)ptEmulation * cosLUT_[(globalPhi - phiQuadrants_[3]) >> l1tmetemu::kCosLUTShift]);
222 
223  if (debug_ == 2) {
224  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
225  << "Sector: " << track->phiSector() << " Quadrant: " << 4 << "\n"
226  << " Emu Phi: " << globalPhi
227  << " Emu Cos(Phi): " << cosLUT_[(phiQuadrants_[4] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift]
228  << " Emu Sin(Phi): -" << cosLUT_[(globalPhi - phiQuadrants_[3]) >> l1tmetemu::kCosLUTShift] << "\n";
229  }
230  }
231 
232  int link_number = (track->phiSector() * 2) + ((EtaSector) ? 0 : 1);
233  link_totals[link_number] += 1;
234  sumPx[link_number] += temppx;
235  sumPy[link_number] += temppy;
236 
237  if (debug_ == 4) {
238  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
239  << std::setprecision(8) << "Sector: " << track->phiSector() << " Eta sector: " << EtaSector << "\n"
240  << "Track Ref Pt: " << track->momentum().perp() << " Track Ref Px: " << track->momentum().x()
241  << " Track Ref Py: " << track->momentum().y() << "\n"
242  << "Track Pt: " << ptEmulation << " Track phi: " << globalPhi << " Track Px: " << temppx
243  << " Track Py: " << temppy << "\n"
244  << "Sector Sum Px: " << sumPx[link_number] << " Sector Sum Py: " << sumPy[link_number] << "\n";
245  }
246  }
247  } // end loop over tracks
248 
249  l1tmetemu::Et_t GlobalPx = 0;
250  l1tmetemu::Et_t GlobalPy = 0;
251 
252  // Global Et sum as floats to emulate rounding in HW
253  for (unsigned int i = 0; i < l1tmetemu::kNSector * 2; i++) {
254  GlobalPx += sumPx[i];
255  GlobalPy += sumPy[i];
256  }
257 
258  // Perform cordic sqrt, take x,y and converts to polar coordinate r,phi where
259  // r=sqrt(x**2+y**2) and phi = atan(y/x)
260  l1tmetemu::EtMiss EtMiss = cordicSqrt.toPolar(-GlobalPx, -GlobalPy);
261 
262  if (debug_ == 4 || debug_ == 6) {
263  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer") << "====Sector Pt====\n";
264 
265  for (unsigned int i = 0; i < l1tmetemu::kNSector * 2; i++) {
266  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
267  << "Sector " << i << "\n"
268  << "Px: " << sumPx[i] << " | Py: " << sumPy[i] << " | Link Totals: " << link_totals[i]
269  << " | Sector Totals: " << sector_totals[(int)(i / 2)] << "\n";
270  }
271 
272  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
273  << "====Global Pt====\n"
274  << "Global Px: " << GlobalPx << "| Global Py: " << GlobalPy << "\n";
275 
276  edm::LogVerbatim("L1TrackerEtMissEmulatorProducer")
277  << "====MET===\n"
278  << "MET word Et: " << EtMiss.Et.range() * l1tmetemu::kStepMETwordEt << "| MET word phi: " << EtMiss.Phi << "\n"
279  << "MET: " << EtMiss.Et.to_double() << "| MET phi: " << EtMiss.Phi.to_double() * l1tmetemu::kStepMETwordPhi
280  << "\n"
281  << "Word MET: " << EtMiss.Et.to_string(2) << " | Word MET phi: " << EtMiss.Phi.to_string(2) << "\n"
282  << "# Tracks Associated to Vertex: " << num_assoc_tracks << "\n"
283  << "========================================================\n";
284  }
285 
286  math::XYZTLorentzVector missingEt(-GlobalPx, -GlobalPy, 0, EtMiss.Et);
287  EtSum L1EtSum(missingEt, EtSum::EtSumType::kMissingEt, EtMiss.Et.range(), 0, EtMiss.Phi, num_assoc_tracks);
288 
289  METCollection->push_back(L1EtSum);
290 
292 } // end producer
293 
295 
297 
298 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
300  //The following says we do not know what parameters are allowed so do no validation
301  // Please change this to state exactly what you do use, even if it is no parameters
303  desc.setUnknown();
304  descriptions.addDefault(desc);
305 }
306 
307 // define this as a plug-in
Log< level::Info, true > LogVerbatim
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
ap_fixed< kMETSize+kEtExtra, kMETMagSize+kEtExtra, AP_RND_CONV, AP_SAT > Et_t
TTTrack< Ref_Phase2TrackerDigi_ > L1TTTrackType
ap_int< TTTrack_TrackWord::TrackBitWidths::kPhiSize+kGlobalPhiExtra > global_phi_t
std::vector< l1tmetemu::global_phi_t > phiQuadrants_
void printLUT(std::vector< T > lut, std::string module="", std::string name="")
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
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)
global_phi_t localToGlobalPhi(TTTrack_TrackWord::phi_t local_phi, global_phi_t sector_shift)
const double kStepMETwordEt
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
const unsigned int kNQuadrants
std::vector< reco::MET > METCollection
collection of MET objects
Definition: METCollection.h:22
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
const edm::EDGetTokenT< L1TTTrackRefCollectionType > vtxAssocTrackToken_
L1TrackerEtMissEmulatorProducer(const edm::ParameterSet &)
const double kStepMETwordPhi
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
const edm::EDGetTokenT< L1TTTrackRefCollectionType > trackToken_
Definition: Cordic.h:7
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
Collection of MET.
std::vector< l1tmetemu::global_phi_t > phiShifts_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
const unsigned int kCosLUTShift
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Class to store the L1 Track Trigger tracks.
Definition: TTTrack.h:29
std::vector< global_phi_t > generatePhiSliceLUT(unsigned int N)
std::vector< l1tmetemu::cos_lut_fixed_t > cosLUT_
const unsigned int kPtMagSize
bool isValid() const
Definition: HandleBase.h:70
std::vector< cos_lut_fixed_t > generateCosLUT()
HLT enums.
edm::RefVector< L1TTTrackCollectionType > L1TTTrackRefCollectionType
std::vector< L1TTTrackType > L1TTTrackCollectionType
def move(src, dest)
Definition: eostools.py:511