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  loader(hls4mlEmulator::ModelLoader(iConfig.getParameter<string>("CICADAModelVersion"))),
148  overwriteWithTestPatterns(iConfig.getParameter<bool>("useTestPatterns")),
149  testPatterns(iConfig.getParameter<std::vector<edm::ParameterSet>>("testPatterns")) {
150  std::vector<double> pumLUTData;
151  char pumLUTString[10];
152  for (uint32_t pumBin = 0; pumBin < nPumBins; pumBin++) {
153  for (uint32_t side = 0; side < 2; side++) {
154  if (side == 0)
155  sprintf(pumLUTString, "pumLUT%2.2dp", pumBin);
156  else
157  sprintf(pumLUTString, "pumLUT%2.2dn", pumBin);
158  pumLUTData = iConfig.getParameter<std::vector<double>>(pumLUTString);
159  for (uint32_t iEta = 0; iEta < std::max((uint32_t)pumLUTData.size(), MaxUCTRegionsEta); iEta++) {
160  pumLUT[pumBin][side][iEta] = (uint32_t)round(pumLUTData[iEta] / caloScaleFactor);
161  }
162  if (pumLUTData.size() != (MaxUCTRegionsEta))
163  edm::LogError("L1TCaloSummary") << "PUM LUT Data size integrity check failed; Expected size = "
164  << MaxUCTRegionsEta << "; Provided size = " << pumLUTData.size()
165  << "; Will use what is provided :(" << std::endl;
166  }
167  }
168  produces<L1JetParticleCollection>("Boosted");
169 
170  //anomaly trigger loading
171  model = loader.load_model();
172  produces<l1t::CICADABxCollection>("CICADAScore");
173 }
174 
175 //
176 // member functions
177 //
178 
179 // ------------ method called to produce the data ------------
180 template <class INPUT, class OUTPUT>
182  using namespace edm;
183 
184  std::unique_ptr<L1JetParticleCollection> bJetCands(new L1JetParticleCollection);
185 
186  std::unique_ptr<l1t::CICADABxCollection> CICADAScore = std::make_unique<l1t::CICADABxCollection>();
187  CICADAScore->setBXRange(-2, 2);
188 
189  UCTGeometry g;
190 
191  // Here we read region data from the region collection created by L1TCaloLayer1 instead of
192  // independently creating regions from TPGs for processing by the summary card. This results
193  // in a single region vector of size 252 whereas from independent creation we had 3*6 vectors
194  // of size 7*2. Indices are mapped in UCTSummaryCard accordingly.
195  UCTSummaryCard summaryCard =
197  std::vector<UCTRegion*> inputRegions;
198  inputRegions.clear();
199  edm::Handle<std::vector<L1CaloRegion>> regionCollection;
200  if (!iEvent.getByToken(regionToken, regionCollection))
201  edm::LogError("L1TCaloSummary") << "UCT: Failed to get regions from region collection!";
202  iEvent.getByToken(regionToken, regionCollection);
203 
204  if (regionCollection->size() == 0) {
205  iEvent.getByToken(backupRegionToken, regionCollection);
206  edm::LogWarning("L1TCaloSummary") << "Switched to emulated regions since data regions was empty.\n";
207  }
208 
209  //Model input
210  //This is done as a flat vector input, but future versions may involve 2D input
211  //This will have to be handled later
212  INPUT modelInput[252];
213  for (const L1CaloRegion& i : *regionCollection) {
214  UCTRegionIndex r = g.getUCTRegionIndexFromL1CaloRegion(i.gctEta(), i.gctPhi());
215  UCTTowerIndex t = g.getUCTTowerIndexFromL1CaloRegion(r, i.raw());
216  uint32_t absCaloEta = std::abs(t.first);
217  uint32_t absCaloPhi = std::abs(t.second);
218  bool negativeEta = false;
219  if (t.first < 0)
220  negativeEta = true;
221  uint32_t crate = g.getCrate(t.first, t.second);
222  uint32_t card = g.getCard(t.first, t.second);
223  uint32_t region = g.getRegion(absCaloEta, absCaloPhi);
224  UCTRegion* test = new UCTRegion(crate, card, negativeEta, region, fwVersion);
225  test->setRegionSummary(i.raw());
226  inputRegions.push_back(test);
227  //This *should* fill the tensor in the proper order to be fed to the anomaly model
228  //We take 4 off of the GCT eta/iEta.
229  //iEta taken from this ranges from 4-17, (I assume reserving lower and higher for forward regions)
230  //So our first index, index 0, is technically iEta=4, and so-on.
231  //CICADA reads this as a flat vector
232  modelInput[14 * i.gctPhi() + (i.gctEta() - 4)] = i.et();
233  }
234  // Check if we're using test patterns. If so, we overwrite the inputs with a test pattern
235  if (overwriteWithTestPatterns) {
236  unsigned int evt = iEvent.id().event();
237  unsigned int totalTestPatterns = testPatterns.size();
238  unsigned int patternElement = evt % totalTestPatterns;
239  const edm::ParameterSet& element = testPatterns.at(patternElement);
240  std::stringstream inputStream;
241  std::string PhiRowString;
242 
243  edm::LogWarning("L1TCaloSummary") << "Overwriting existing CICADA input with test pattern!\n";
244 
245  for (unsigned short int iPhi = 1; iPhi <= 18; ++iPhi) {
246  PhiRowString = "";
247  std::stringstream PhiRowStringStream;
248  PhiRowStringStream << "iPhi_" << iPhi;
249  PhiRowString = PhiRowStringStream.str();
250  std::vector<unsigned int> phiRow = element.getParameter<std::vector<unsigned int>>(PhiRowString);
251  for (unsigned short int iEta = 1; iEta <= 14; ++iEta) {
252  modelInput[14 * (iPhi - 1) + (iEta - 1)] = phiRow.at(iEta - 1);
253  inputStream << phiRow.at(iEta - 1) << " ";
254  }
255  inputStream << "\n";
256  }
257  edm::LogInfo("L1TCaloSummary") << "Input Stream:\n" << inputStream.str();
258  }
259 
260  //Extract model output
261  OUTPUT modelResult[1] = {
262  OUTPUT("0.0", 10)}; //the 10 here refers to the fact that we read in "0.0" as a decimal number
263  model->prepare_input(modelInput);
264  model->predict();
265  model->read_result(modelResult);
266 
267  CICADAScore->push_back(0, modelResult[0].to_float());
268 
269  if (overwriteWithTestPatterns)
270  edm::LogInfo("L1TCaloSummary") << "Test Pattern Output: " << CICADAScore->at(0, 0);
271 
272  summaryCard.setRegionData(inputRegions);
273 
274  if (!summaryCard.process()) {
275  edm::LogError("L1TCaloSummary") << "UCT: Failed to process summary card" << std::endl;
276  exit(1);
277  }
278 
279  double pt = 0;
280  double eta = -999.;
281  double phi = -999.;
282  double mass = 0;
283 
284  std::list<UCTObject*> boostedJetObjs = summaryCard.getBoostedJetObjs();
285  for (std::list<UCTObject*>::const_iterator i = boostedJetObjs.begin(); i != boostedJetObjs.end(); i++) {
286  const UCTObject* object = *i;
287  pt = ((double)object->et()) * caloScaleFactor * boostedJetPtFactor;
288  eta = g.getUCTTowerEta(object->iEta());
289  phi = g.getUCTTowerPhi(object->iPhi());
290  bitset<3> activeRegionEtaPattern = 0;
291  for (uint32_t iEta = 0; iEta < 3; iEta++) {
292  bool activeStrip = false;
293  for (uint32_t iPhi = 0; iPhi < 3; iPhi++) {
294  if (object->boostedJetRegionET()[3 * iEta + iPhi] > 30 &&
295  object->boostedJetRegionET()[3 * iEta + iPhi] > object->et() * 0.0625)
296  activeStrip = true;
297  }
298  if (activeStrip)
299  activeRegionEtaPattern |= (0x1 << iEta);
300  }
301  bitset<3> activeRegionPhiPattern = 0;
302  for (uint32_t iPhi = 0; iPhi < 3; iPhi++) {
303  bool activeStrip = false;
304  for (uint32_t iEta = 0; iEta < 3; iEta++) {
305  if (object->boostedJetRegionET()[3 * iEta + iPhi] > 30 &&
306  object->boostedJetRegionET()[3 * iEta + iPhi] > object->et() * 0.0625)
307  activeStrip = true;
308  }
309  if (activeStrip)
310  activeRegionPhiPattern |= (0x1 << iPhi);
311  }
312  string regionEta = activeRegionEtaPattern.to_string<char, std::string::traits_type, std::string::allocator_type>();
313  string regionPhi = activeRegionPhiPattern.to_string<char, std::string::traits_type, std::string::allocator_type>();
314 
315  bool centralHighest = object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[0] &&
316  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[1] &&
317  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[2] &&
318  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[3] &&
319  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[5] &&
320  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[6] &&
321  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[7] &&
322  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[8];
323 
324  if (abs(eta) < 2.5 && ((regionEta == "101" && (regionPhi == "110" || regionPhi == "101" || regionPhi == "010")) ||
325  ((regionEta == "110" || regionEta == "101" || regionEta == "010") && regionPhi == "101") ||
326  (regionEta == "111" && (regionPhi == "110" || regionPhi == "010")) ||
327  ((regionEta == "110" || regionEta == "010") && regionPhi == "111") ||
328  ((regionEta == "010" || regionPhi == "010" || regionEta == "110" || regionPhi == "110" ||
329  regionEta == "011" || regionPhi == "011") &&
330  centralHighest)))
331  bJetCands->push_back(L1JetParticle(math::PtEtaPhiMLorentzVector(pt, eta, phi, mass), L1JetParticle::kCentral));
332  }
333 
334  iEvent.put(std::move(bJetCands), "Boosted");
335  //Write out anomaly score
336  iEvent.put(std::move(CICADAScore), "CICADAScore");
337 }
338 
339 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
340 template <class INPUT, class OUTPUT>
342  //The following says we do not know what parameters are allowed so do no validation
343  // Please change this to state exactly what you do use, even if it is no parameters
345  desc.setUnknown();
346  descriptions.addDefault(desc);
347 }
348 
349 // Initial version, X.0.0, input/output typing
354 // X.1.0 version input.output typing
359 // X.1.1 version input/output typing
360 typedef L1TCaloSummary<ap_uint<10>, ap_ufixed<16, 8, AP_RND, AP_SAT, AP_SAT>> L1TCaloSummary_CICADA_vXp1p1;
362 // X.1.2 version input/output typing
363 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="")