CMS 3D CMS Logo

L1TCaloSummary.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: L1Trigger/L1TCaloSummary
4 // Class: L1TCaloSummary
5 //
13 //
14 // Original Author: Sridhara Dasu
15 // Created: Sat, 14 Nov 2015 14:18:27 GMT
16 //
17 //
18 
19 // system include files
20 #include <memory>
21 
22 // user include files
25 
28 
30 
33 
34 #include "L1Trigger/L1TCaloLayer1/src/UCTLayer1.hh"
35 #include "L1Trigger/L1TCaloLayer1/src/UCTCrate.hh"
36 #include "L1Trigger/L1TCaloLayer1/src/UCTCard.hh"
37 #include "L1Trigger/L1TCaloLayer1/src/UCTRegion.hh"
38 #include "L1Trigger/L1TCaloLayer1/src/UCTTower.hh"
39 #include "L1Trigger/L1TCaloLayer1/src/UCTGeometry.hh"
40 
41 #include "L1Trigger/L1TCaloLayer1/src/UCTObject.hh"
42 #include "L1Trigger/L1TCaloLayer1/src/UCTSummaryCard.hh"
43 #include "L1Trigger/L1TCaloLayer1/src/UCTGeometryExtended.hh"
44 
51 
55 
57 
58 #include "L1Trigger/L1TCaloLayer1/src/UCTLogging.hh"
59 #include <bitset>
60 
61 #include <string>
62 #include <sstream>
63 
64 //Anomaly detection includes
65 #include "ap_fixed.h"
66 #include "hls4ml/emulator.h"
67 
68 using namespace l1tcalo;
69 using namespace l1extra;
70 using namespace std;
71 
72 //
73 // class declaration
74 //
75 
76 template <class INPUT, class OUTPUT>
78 public:
79  explicit L1TCaloSummary(const edm::ParameterSet&);
80  ~L1TCaloSummary() override = default;
81 
82  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
83 
84 private:
85  //void beginJob() override;
86  void produce(edm::Event&, const edm::EventSetup&) override;
87  //void endJob() override;
88 
89  void print();
90 
91  // ----------member data ---------------------------
92 
93  uint32_t nPumBins;
94 
95  std::vector<std::vector<std::vector<uint32_t>>> pumLUT;
96 
98 
99  uint32_t jetSeed;
100  uint32_t tauSeed;
102  uint32_t eGammaSeed;
105 
106  bool verbose;
108 
111 
112  UCTLayer1* layer1;
113 
114  hls4mlEmulator::ModelLoader loader;
115  std::shared_ptr<hls4mlEmulator::Model> model;
116 
118  std::vector<edm::ParameterSet> testPatterns;
119 };
120 
121 //
122 // constants, enums and typedefs
123 //
124 
125 //
126 // static data member definitions
127 //
128 
129 //
130 // constructors and destructor
131 //
132 template <class INPUT, class OUTPUT>
134  : nPumBins(iConfig.getParameter<unsigned int>("nPumBins")),
135  pumLUT(nPumBins, std::vector<std::vector<uint32_t>>(2, std::vector<uint32_t>(13))),
136  caloScaleFactor(iConfig.getParameter<double>("caloScaleFactor")),
137  jetSeed(iConfig.getParameter<unsigned int>("jetSeed")),
138  tauSeed(iConfig.getParameter<unsigned int>("tauSeed")),
139  tauIsolationFactor(iConfig.getParameter<double>("tauIsolationFactor")),
140  eGammaSeed(iConfig.getParameter<unsigned int>("eGammaSeed")),
141  eGammaIsolationFactor(iConfig.getParameter<double>("eGammaIsolationFactor")),
142  boostedJetPtFactor(iConfig.getParameter<double>("boostedJetPtFactor")),
143  verbose(iConfig.getParameter<bool>("verbose")),
144  fwVersion(iConfig.getParameter<int>("firmwareVersion")),
145  regionToken(consumes<L1CaloRegionCollection>(iConfig.getParameter<edm::InputTag>("caloLayer1Regions"))),
146  //backupRegionToken(consumes<L1CaloRegionCollection>(edm::InputTag("simCaloStage2Layer1Digis"))),
147  backupRegionToken(consumes<L1CaloRegionCollection>(iConfig.getParameter<edm::InputTag>("backupRegionToken"))),
148  loader(hls4mlEmulator::ModelLoader(iConfig.getParameter<string>("CICADAModelVersion"))),
149  overwriteWithTestPatterns(iConfig.getParameter<bool>("useTestPatterns")),
150  testPatterns(iConfig.getParameter<std::vector<edm::ParameterSet>>("testPatterns")) {
151  std::vector<double> pumLUTData;
152  char pumLUTString[10];
153  for (uint32_t pumBin = 0; pumBin < nPumBins; pumBin++) {
154  for (uint32_t side = 0; side < 2; side++) {
155  if (side == 0)
156  sprintf(pumLUTString, "pumLUT%2.2dp", pumBin);
157  else
158  sprintf(pumLUTString, "pumLUT%2.2dn", pumBin);
159  pumLUTData = iConfig.getParameter<std::vector<double>>(pumLUTString);
160  for (uint32_t iEta = 0; iEta < std::max((uint32_t)pumLUTData.size(), MaxUCTRegionsEta); iEta++) {
161  pumLUT[pumBin][side][iEta] = (uint32_t)round(pumLUTData[iEta] / caloScaleFactor);
162  }
163  if (pumLUTData.size() != (MaxUCTRegionsEta))
164  edm::LogError("L1TCaloSummary") << "PUM LUT Data size integrity check failed; Expected size = "
165  << MaxUCTRegionsEta << "; Provided size = " << pumLUTData.size()
166  << "; Will use what is provided :(" << std::endl;
167  }
168  }
169  produces<L1JetParticleCollection>("Boosted");
170 
171  //anomaly trigger loading
172  model = loader.load_model();
173  produces<l1t::CICADABxCollection>("CICADAScore");
174 }
175 
176 //
177 // member functions
178 //
179 
180 // ------------ method called to produce the data ------------
181 template <class INPUT, class OUTPUT>
183  using namespace edm;
184 
185  std::unique_ptr<L1JetParticleCollection> bJetCands(new L1JetParticleCollection);
186 
187  std::unique_ptr<l1t::CICADABxCollection> CICADAScore = std::make_unique<l1t::CICADABxCollection>();
188  CICADAScore->setBXRange(-2, 2);
189 
190  UCTGeometry g;
191 
192  // Here we read region data from the region collection created by L1TCaloLayer1 instead of
193  // independently creating regions from TPGs for processing by the summary card. This results
194  // in a single region vector of size 252 whereas from independent creation we had 3*6 vectors
195  // of size 7*2. Indices are mapped in UCTSummaryCard accordingly.
196  UCTSummaryCard summaryCard =
198  std::vector<UCTRegion> inputRegions;
199  inputRegions.reserve(252); // 252 calorimeter regions. 18 phi * 14 eta
200  edm::Handle<std::vector<L1CaloRegion>> regionCollection;
201  if (!iEvent.getByToken(regionToken, regionCollection))
202  edm::LogError("L1TCaloSummary") << "UCT: Failed to get regions from region collection!";
203  iEvent.getByToken(regionToken, regionCollection);
204 
205  if (regionCollection->size() == 0) {
206  iEvent.getByToken(backupRegionToken, regionCollection);
207  edm::LogWarning("L1TCaloSummary") << "Switched to emulated regions since data regions was empty.\n";
208  }
209 
210  //Model input
211  //This is done as a flat vector input, but future versions may involve 2D input
212  //This will have to be handled later
213  INPUT modelInput[252];
214  for (const L1CaloRegion& i : *regionCollection) {
215  UCTRegionIndex r = g.getUCTRegionIndexFromL1CaloRegion(i.gctEta(), i.gctPhi());
216  UCTTowerIndex t = g.getUCTTowerIndexFromL1CaloRegion(r, i.raw());
217  uint32_t absCaloEta = std::abs(t.first);
218  uint32_t absCaloPhi = std::abs(t.second);
219  bool negativeEta = false;
220  if (t.first < 0)
221  negativeEta = true;
222  uint32_t crate = g.getCrate(t.first, t.second);
223  uint32_t card = g.getCard(t.first, t.second);
224  uint32_t region = g.getRegion(absCaloEta, absCaloPhi);
225  UCTRegion test = UCTRegion(crate, card, negativeEta, region, fwVersion);
226  test.setRegionSummary(i.raw());
227  inputRegions.push_back(test);
228  //This *should* fill the tensor in the proper order to be fed to the anomaly model
229  //We take 4 off of the GCT eta/iEta.
230  //iEta taken from this ranges from 4-17, (I assume reserving lower and higher for forward regions)
231  //So our first index, index 0, is technically iEta=4, and so-on.
232  //CICADA reads this as a flat vector
233  modelInput[14 * i.gctPhi() + (i.gctEta() - 4)] = i.et();
234  }
235  // Check if we're using test patterns. If so, we overwrite the inputs with a test pattern
236  if (overwriteWithTestPatterns) {
237  unsigned int evt = iEvent.id().event();
238  unsigned int totalTestPatterns = testPatterns.size();
239  unsigned int patternElement = evt % totalTestPatterns;
240  const edm::ParameterSet& element = testPatterns.at(patternElement);
241  std::stringstream inputStream;
242  std::string PhiRowString;
243 
244  edm::LogWarning("L1TCaloSummary") << "Overwriting existing CICADA input with test pattern!\n";
245 
246  for (unsigned short int iPhi = 1; iPhi <= 18; ++iPhi) {
247  PhiRowString = "";
248  std::stringstream PhiRowStringStream;
249  PhiRowStringStream << "iPhi_" << iPhi;
250  PhiRowString = PhiRowStringStream.str();
251  std::vector<unsigned int> phiRow = element.getParameter<std::vector<unsigned int>>(PhiRowString);
252  for (unsigned short int iEta = 1; iEta <= 14; ++iEta) {
253  modelInput[14 * (iPhi - 1) + (iEta - 1)] = phiRow.at(iEta - 1);
254  inputStream << phiRow.at(iEta - 1) << " ";
255  }
256  inputStream << "\n";
257  }
258  edm::LogInfo("L1TCaloSummary") << "Input Stream:\n" << inputStream.str();
259  }
260 
261  //Extract model output
262  OUTPUT modelResult[1] = {
263  OUTPUT("0.0", 10)}; //the 10 here refers to the fact that we read in "0.0" as a decimal number
264  model->prepare_input(modelInput);
265  model->predict();
266  model->read_result(modelResult);
267 
268  CICADAScore->push_back(0, modelResult[0].to_float());
269 
270  if (overwriteWithTestPatterns)
271  edm::LogInfo("L1TCaloSummary") << "Test Pattern Output: " << CICADAScore->at(0, 0);
272 
273  summaryCard.setRegionData(inputRegions);
274 
275  if (!summaryCard.process()) {
276  edm::LogError("L1TCaloSummary") << "UCT: Failed to process summary card" << std::endl;
277  exit(1);
278  }
279 
280  double pt = 0;
281  double eta = -999.;
282  double phi = -999.;
283  double mass = 0;
284 
285  std::list<std::shared_ptr<UCTObject>> boostedJetObjs = summaryCard.getBoostedJetObjs();
286  for (std::list<std::shared_ptr<UCTObject>>::const_iterator i = boostedJetObjs.begin(); i != boostedJetObjs.end();
287  i++) {
288  const std::shared_ptr<UCTObject> object = *i;
289  pt = ((double)object->et()) * caloScaleFactor * boostedJetPtFactor;
290  eta = g.getUCTTowerEta(object->iEta());
291  phi = g.getUCTTowerPhi(object->iPhi());
292  bitset<3> activeRegionEtaPattern = 0;
293  for (uint32_t iEta = 0; iEta < 3; iEta++) {
294  bool activeStrip = false;
295  for (uint32_t iPhi = 0; iPhi < 3; iPhi++) {
296  if (object->boostedJetRegionET()[3 * iEta + iPhi] > 30 &&
297  object->boostedJetRegionET()[3 * iEta + iPhi] > object->et() * 0.0625)
298  activeStrip = true;
299  }
300  if (activeStrip)
301  activeRegionEtaPattern |= (0x1 << iEta);
302  }
303  bitset<3> activeRegionPhiPattern = 0;
304  for (uint32_t iPhi = 0; iPhi < 3; iPhi++) {
305  bool activeStrip = false;
306  for (uint32_t iEta = 0; iEta < 3; iEta++) {
307  if (object->boostedJetRegionET()[3 * iEta + iPhi] > 30 &&
308  object->boostedJetRegionET()[3 * iEta + iPhi] > object->et() * 0.0625)
309  activeStrip = true;
310  }
311  if (activeStrip)
312  activeRegionPhiPattern |= (0x1 << iPhi);
313  }
314  string regionEta = activeRegionEtaPattern.to_string<char, std::string::traits_type, std::string::allocator_type>();
315  string regionPhi = activeRegionPhiPattern.to_string<char, std::string::traits_type, std::string::allocator_type>();
316 
317  bool centralHighest = object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[0] &&
318  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[1] &&
319  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[2] &&
320  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[3] &&
321  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[5] &&
322  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[6] &&
323  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[7] &&
324  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[8];
325 
326  if (abs(eta) < 2.5 && ((regionEta == "101" && (regionPhi == "110" || regionPhi == "101" || regionPhi == "010")) ||
327  ((regionEta == "110" || regionEta == "101" || regionEta == "010") && regionPhi == "101") ||
328  (regionEta == "111" && (regionPhi == "110" || regionPhi == "010")) ||
329  ((regionEta == "110" || regionEta == "010") && regionPhi == "111") ||
330  ((regionEta == "010" || regionPhi == "010" || regionEta == "110" || regionPhi == "110" ||
331  regionEta == "011" || regionPhi == "011") &&
332  centralHighest)))
333  bJetCands->push_back(L1JetParticle(math::PtEtaPhiMLorentzVector(pt, eta, phi, mass), L1JetParticle::kCentral));
334  }
335 
336  iEvent.put(std::move(bJetCands), "Boosted");
337  //Write out anomaly score
338  iEvent.put(std::move(CICADAScore), "CICADAScore");
339 }
340 
341 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
342 template <class INPUT, class OUTPUT>
344  //The following says we do not know what parameters are allowed so do no validation
345  // Please change this to state exactly what you do use, even if it is no parameters
347  desc.setUnknown();
348  descriptions.addDefault(desc);
349 }
350 
351 // Initial version, X.0.0, input/output typing
356 // X.1.0 version input.output typing
361 // X.1.1 version input/output typing
362 typedef L1TCaloSummary<ap_uint<10>, ap_ufixed<16, 8, AP_RND, AP_SAT, AP_SAT>> L1TCaloSummary_CICADA_vXp1p1;
364 // X.1.2 version input/output typing
365 typedef L1TCaloSummary<ap_uint<10>, ap_ufixed<16, 8, AP_RND_CONV, AP_SAT>> L1TCaloSummary_CICADA_vXp1p2;
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
bool verbose
bool overwriteWithTestPatterns
Log< level::Error, false > LogError
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
L1TCaloSummary< ap_uint< 10 >, ap_ufixed< 16, 8 > > L1TCaloSummary_CICADA_v2p1p0
PtEtaPhiMLorentzVectorD PtEtaPhiMLorentzVector
Lorentz vector with cartesian internal representation.
Definition: LorentzVector.h:25
L1TCaloSummary< ap_uint< 10 >, ap_ufixed< 16, 8, AP_RND_CONV, AP_SAT > > L1TCaloSummary_CICADA_vXp1p2
L1TCaloSummary(const edm::ParameterSet &)
int iEvent
Definition: GenABIO.cc:224
void addDefault(ParameterSetDescription const &psetDescription)
UCTLayer1 * layer1
void produce(edm::Event &, const edm::EventSetup &) override
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
L1TCaloSummary< ap_ufixed< 10, 10 >, ap_fixed< 11, 5 > > L1TCaloSummary_CICADA_v1p0p0
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
std::vector< edm::ParameterSet > testPatterns
edm::EDGetTokenT< L1CaloRegionCollection > regionToken
Log< level::Info, false > LogInfo
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
L1TCaloSummary< ap_ufixed< 10, 10 >, ap_fixed< 11, 5 > > L1TCaloSummary_CICADA_v1p1p0
edm::EDGetTokenT< L1CaloRegionCollection > backupRegionToken
std::shared_ptr< hls4mlEmulator::Model > model
L1TCaloSummary< ap_uint< 10 >, ap_ufixed< 16, 8 > > L1TCaloSummary_CICADA_v2p0p0
double boostedJetPtFactor
L1TCaloSummary< ap_uint< 10 >, ap_ufixed< 16, 8, AP_RND, AP_SAT, AP_SAT > > L1TCaloSummary_CICADA_vXp1p1
double eGammaIsolationFactor
hls4mlEmulator::ModelLoader loader
HLT enums.
std::vector< std::vector< std::vector< uint32_t > > > pumLUT
A calorimeter trigger region (sum of 4x4 trigger towers)
Definition: L1CaloRegion.h:21
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
std::vector< L1CaloRegion > L1CaloRegionCollection
double caloScaleFactor
Log< level::Warning, false > LogWarning
def move(src, dest)
Definition: eostools.py:511
def exit(msg="")