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 
54 
56 
57 #include "L1Trigger/L1TCaloLayer1/src/UCTLogging.hh"
58 #include <bitset>
59 
60 //Anomaly detection includes
61 #include "ap_fixed.h"
62 #include "hls4ml/emulator.h"
63 
64 using namespace l1tcalo;
65 using namespace l1extra;
66 using namespace std;
67 
68 //
69 // class declaration
70 //
71 
73 public:
74  explicit L1TCaloSummary(const edm::ParameterSet&);
75  ~L1TCaloSummary() override;
76 
77  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
78 
79 private:
80  //void beginJob() override;
81  void produce(edm::Event&, const edm::EventSetup&) override;
82  //void endJob() override;
83 
84  void beginRun(edm::Run const&, edm::EventSetup const&) override;
85 
86  void print();
87 
88  // ----------member data ---------------------------
89 
90  uint32_t nPumBins;
91 
92  std::vector<std::vector<std::vector<uint32_t>>> pumLUT;
93 
95 
96  uint32_t jetSeed;
97  uint32_t tauSeed;
99  uint32_t eGammaSeed;
102 
103  bool verbose;
105 
107 
108  UCTLayer1* layer1;
109 
110  hls4mlEmulator::ModelLoader loader;
111  std::shared_ptr<hls4mlEmulator::Model> model;
112 };
113 
114 //
115 // constants, enums and typedefs
116 //
117 
118 //
119 // static data member definitions
120 //
121 
122 //
123 // constructors and destructor
124 //
126  : nPumBins(iConfig.getParameter<unsigned int>("nPumBins")),
127  pumLUT(nPumBins, std::vector<std::vector<uint32_t>>(2, std::vector<uint32_t>(13))),
128  caloScaleFactor(iConfig.getParameter<double>("caloScaleFactor")),
129  jetSeed(iConfig.getParameter<unsigned int>("jetSeed")),
130  tauSeed(iConfig.getParameter<unsigned int>("tauSeed")),
131  tauIsolationFactor(iConfig.getParameter<double>("tauIsolationFactor")),
132  eGammaSeed(iConfig.getParameter<unsigned int>("eGammaSeed")),
133  eGammaIsolationFactor(iConfig.getParameter<double>("eGammaIsolationFactor")),
134  boostedJetPtFactor(iConfig.getParameter<double>("boostedJetPtFactor")),
135  verbose(iConfig.getParameter<bool>("verbose")),
136  fwVersion(iConfig.getParameter<int>("firmwareVersion")),
137  regionToken(consumes<L1CaloRegionCollection>(edm::InputTag("simCaloStage2Layer1Digis"))),
138  loader(hls4mlEmulator::ModelLoader(iConfig.getParameter<string>("CICADAModelVersion"))) {
139  std::vector<double> pumLUTData;
140  char pumLUTString[10];
141  for (uint32_t pumBin = 0; pumBin < nPumBins; pumBin++) {
142  for (uint32_t side = 0; side < 2; side++) {
143  if (side == 0)
144  sprintf(pumLUTString, "pumLUT%2.2dp", pumBin);
145  else
146  sprintf(pumLUTString, "pumLUT%2.2dn", pumBin);
147  pumLUTData = iConfig.getParameter<std::vector<double>>(pumLUTString);
148  for (uint32_t iEta = 0; iEta < std::max((uint32_t)pumLUTData.size(), MaxUCTRegionsEta); iEta++) {
149  pumLUT[pumBin][side][iEta] = (uint32_t)round(pumLUTData[iEta] / caloScaleFactor);
150  }
151  if (pumLUTData.size() != (MaxUCTRegionsEta))
152  edm::LogError("L1TCaloSummary") << "PUM LUT Data size integrity check failed; Expected size = "
153  << MaxUCTRegionsEta << "; Provided size = " << pumLUTData.size()
154  << "; Will use what is provided :(" << std::endl;
155  }
156  }
157  produces<L1JetParticleCollection>("Boosted");
158 
159  //anomaly trigger loading
160  model = loader.load_model();
161  produces<float>("anomalyScore");
162 }
163 
165 
166 //
167 // member functions
168 //
169 
170 // ------------ method called to produce the data ------------
172  using namespace edm;
173 
174  std::unique_ptr<L1JetParticleCollection> bJetCands(new L1JetParticleCollection);
175 
176  std::unique_ptr<float> anomalyScore = std::make_unique<float>();
177 
178  UCTGeometry g;
179 
180  // Here we read region data from the region collection created by L1TCaloLayer1 instead of
181  // independently creating regions from TPGs for processing by the summary card. This results
182  // in a single region vector of size 252 whereas from independent creation we had 3*6 vectors
183  // of size 7*2. Indices are mapped in UCTSummaryCard accordingly.
184  UCTSummaryCard summaryCard =
186  std::vector<UCTRegion*> inputRegions;
187  inputRegions.clear();
188  edm::Handle<std::vector<L1CaloRegion>> regionCollection;
189  if (!iEvent.getByToken(regionToken, regionCollection))
190  edm::LogError("L1TCaloSummary") << "UCT: Failed to get regions from region collection!";
191  iEvent.getByToken(regionToken, regionCollection);
192  //Model input
193  //This is done as a flat vector input, but future versions may involve 2D input
194  //This will have to be handled later
195  //Would also be good to be able to configure the precision of the ap_fixed type
196  ap_ufixed<10, 10> modelInput[252];
197  for (const L1CaloRegion& i : *regionCollection) {
198  UCTRegionIndex r = g.getUCTRegionIndexFromL1CaloRegion(i.gctEta(), i.gctPhi());
199  UCTTowerIndex t = g.getUCTTowerIndexFromL1CaloRegion(r, i.raw());
200  uint32_t absCaloEta = std::abs(t.first);
201  uint32_t absCaloPhi = std::abs(t.second);
202  bool negativeEta = false;
203  if (t.first < 0)
204  negativeEta = true;
205  uint32_t crate = g.getCrate(t.first, t.second);
206  uint32_t card = g.getCard(t.first, t.second);
207  uint32_t region = g.getRegion(absCaloEta, absCaloPhi);
208  UCTRegion* test = new UCTRegion(crate, card, negativeEta, region, fwVersion);
209  test->setRegionSummary(i.raw());
210  inputRegions.push_back(test);
211  //This *should* fill the tensor in the proper order to be fed to the anomaly model
212  //We take 4 off of the GCT eta/iEta.
213  //iEta taken from this ranges from 4-17, (I assume reserving lower and higher for forward regions)
214  //So our first index, index 0, is technically iEta=4, and so-on.
215  //CICADA v1 reads this as a flat vector
216  modelInput[14 * i.gctPhi() + (i.gctEta() - 4)] = i.et();
217  }
218  //Extract model output
219  //Would be good to be able to configure the precision of the result
220  ap_fixed<11, 5> modelResult[1];
221  model->prepare_input(modelInput);
222  model->predict();
223  model->read_result(modelResult);
224 
225  *anomalyScore = modelResult[0].to_float();
226 
227  summaryCard.setRegionData(inputRegions);
228 
229  if (!summaryCard.process()) {
230  edm::LogError("L1TCaloSummary") << "UCT: Failed to process summary card" << std::endl;
231  exit(1);
232  }
233 
234  double pt = 0;
235  double eta = -999.;
236  double phi = -999.;
237  double mass = 0;
238 
239  std::list<UCTObject*> boostedJetObjs = summaryCard.getBoostedJetObjs();
240  for (std::list<UCTObject*>::const_iterator i = boostedJetObjs.begin(); i != boostedJetObjs.end(); i++) {
241  const UCTObject* object = *i;
242  pt = ((double)object->et()) * caloScaleFactor * boostedJetPtFactor;
243  eta = g.getUCTTowerEta(object->iEta());
244  phi = g.getUCTTowerPhi(object->iPhi());
245  bitset<3> activeRegionEtaPattern = 0;
246  for (uint32_t iEta = 0; iEta < 3; iEta++) {
247  bool activeStrip = false;
248  for (uint32_t iPhi = 0; iPhi < 3; iPhi++) {
249  if (object->boostedJetRegionET()[3 * iEta + iPhi] > 30 &&
250  object->boostedJetRegionET()[3 * iEta + iPhi] > object->et() * 0.0625)
251  activeStrip = true;
252  }
253  if (activeStrip)
254  activeRegionEtaPattern |= (0x1 << iEta);
255  }
256  bitset<3> activeRegionPhiPattern = 0;
257  for (uint32_t iPhi = 0; iPhi < 3; iPhi++) {
258  bool activeStrip = false;
259  for (uint32_t iEta = 0; iEta < 3; iEta++) {
260  if (object->boostedJetRegionET()[3 * iEta + iPhi] > 30 &&
261  object->boostedJetRegionET()[3 * iEta + iPhi] > object->et() * 0.0625)
262  activeStrip = true;
263  }
264  if (activeStrip)
265  activeRegionPhiPattern |= (0x1 << iPhi);
266  }
267  string regionEta = activeRegionEtaPattern.to_string<char, std::string::traits_type, std::string::allocator_type>();
268  string regionPhi = activeRegionPhiPattern.to_string<char, std::string::traits_type, std::string::allocator_type>();
269 
270  bool centralHighest = object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[0] &&
271  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[1] &&
272  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[2] &&
273  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[3] &&
274  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[5] &&
275  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[6] &&
276  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[7] &&
277  object->boostedJetRegionET()[4] >= object->boostedJetRegionET()[8];
278 
279  if (abs(eta) < 2.5 && ((regionEta == "101" && (regionPhi == "110" || regionPhi == "101" || regionPhi == "010")) ||
280  ((regionEta == "110" || regionEta == "101" || regionEta == "010") && regionPhi == "101") ||
281  (regionEta == "111" && (regionPhi == "110" || regionPhi == "010")) ||
282  ((regionEta == "110" || regionEta == "010") && regionPhi == "111") ||
283  ((regionEta == "010" || regionPhi == "010" || regionEta == "110" || regionPhi == "110" ||
284  regionEta == "011" || regionPhi == "011") &&
285  centralHighest)))
286  bJetCands->push_back(L1JetParticle(math::PtEtaPhiMLorentzVector(pt, eta, phi, mass), L1JetParticle::kCentral));
287  }
288 
289  iEvent.put(std::move(bJetCands), "Boosted");
290  //Write out anomaly score
291  iEvent.put(std::move(anomalyScore), "anomalyScore");
292 }
293 
295 
296 // ------------ method called once each job just before starting event loop ------------
297 //void L1TCaloSummary::beginJob() {}
298 
299 // ------------ method called once each job just after ending the event loop ------------
300 //void L1TCaloSummary::endJob() {}
301 
302 // ------------ method called when starting to processes a run ------------
303 
304 void L1TCaloSummary::beginRun(edm::Run const& iRun, edm::EventSetup const& iSetup) {}
305 
306 // ------------ method called when ending the processing of a run ------------
307 /*
308  void
309  L1TCaloSummary::endRun(edm::Run const&, edm::EventSetup const&)
310  {
311  }
312 */
313 
314 // ------------ method called when starting to processes a luminosity block ------------
315 /*
316  void
317  L1TCaloSummary::beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
318  {
319  }
320 */
321 
322 // ------------ method called when ending the processing of a luminosity block ------------
323 /*
324  void
325  L1TCaloSummary::endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
326  {
327  }
328 */
329 
330 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
332  //The following says we do not know what parameters are allowed so do no validation
333  // Please change this to state exactly what you do use, even if it is no parameters
335  desc.setUnknown();
336  descriptions.addDefault(desc);
337 }
338 
339 //define this as a plug-in
double caloScaleFactor
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
void produce(edm::Event &, const edm::EventSetup &) override
bool verbose
L1TCaloSummary(const edm::ParameterSet &)
std::shared_ptr< hls4mlEmulator::Model > model
uint32_t eGammaSeed
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
double eGammaIsolationFactor
~L1TCaloSummary() override
PtEtaPhiMLorentzVectorD PtEtaPhiMLorentzVector
Lorentz vector with cartesian internal representation.
Definition: LorentzVector.h:25
int iEvent
Definition: GenABIO.cc:224
void addDefault(ParameterSetDescription const &psetDescription)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
float tauIsolationFactor
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
std::vector< std::vector< std::vector< uint32_t > > > pumLUT
double boostedJetPtFactor
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
void beginRun(edm::Run const &, edm::EventSetup const &) override
HLT enums.
hls4mlEmulator::ModelLoader loader
UCTLayer1 * layer1
A calorimeter trigger region (sum of 4x4 trigger towers)
Definition: L1CaloRegion.h:21
std::vector< L1CaloRegion > L1CaloRegionCollection
def move(src, dest)
Definition: eostools.py:511
Definition: Run.h:45
def exit(msg="")
edm::EDGetTokenT< L1CaloRegionCollection > regionToken