5757#include " L1Trigger/L1TCaloLayer1/src/UCTLogging.hh"
5858#include < bitset>
5959
60+ // Anomaly detection includes
61+ #include " ap_fixed.h"
62+ #include " hls4ml/emulator.h"
63+
6064using namespace l1tcalo ;
6165using namespace l1extra ;
6266using namespace std ;
@@ -102,6 +106,9 @@ class L1TCaloSummary : public edm::stream::EDProducer<> {
102106 edm::EDGetTokenT<L1CaloRegionCollection> regionToken;
103107
104108 UCTLayer1* layer1;
109+
110+ hls4mlEmulator::ModelLoader loader;
111+ std::shared_ptr<hls4mlEmulator::Model> model;
105112};
106113
107114//
@@ -127,7 +134,8 @@ L1TCaloSummary::L1TCaloSummary(const edm::ParameterSet& iConfig)
127134 boostedJetPtFactor(iConfig.getParameter<double >(" boostedJetPtFactor" )),
128135 verbose(iConfig.getParameter<bool >(" verbose" )),
129136 fwVersion(iConfig.getParameter<int >(" firmwareVersion" )),
130- regionToken(consumes<L1CaloRegionCollection>(edm::InputTag(" simCaloStage2Layer1Digis" ))) {
137+ regionToken(consumes<L1CaloRegionCollection>(edm::InputTag(" simCaloStage2Layer1Digis" ))),
138+ loader(hls4mlEmulator::ModelLoader(iConfig.getParameter<string>(" CICADAModelVersion" ))) {
131139 std::vector<double > pumLUTData;
132140 char pumLUTString[10 ];
133141 for (uint32_t pumBin = 0 ; pumBin < nPumBins; pumBin++) {
@@ -147,6 +155,10 @@ L1TCaloSummary::L1TCaloSummary(const edm::ParameterSet& iConfig)
147155 }
148156 }
149157 produces<L1JetParticleCollection>(" Boosted" );
158+
159+ // anomaly trigger loading
160+ model = loader.load_model ();
161+ produces<float >(" anomalyScore" );
150162}
151163
152164L1TCaloSummary::~L1TCaloSummary () {}
@@ -161,6 +173,8 @@ void L1TCaloSummary::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
161173
162174 std::unique_ptr<L1JetParticleCollection> bJetCands (new L1JetParticleCollection);
163175
176+ std::unique_ptr<float > anomalyScore = std::make_unique<float >();
177+
164178 UCTGeometry g;
165179
166180 // Here we read region data from the region collection created by L1TCaloLayer1 instead of
@@ -175,6 +189,11 @@ void L1TCaloSummary::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
175189 if (!iEvent.getByToken (regionToken, regionCollection))
176190 edm::LogError (" L1TCaloSummary" ) << " UCT: Failed to get regions from region collection!" ;
177191 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 ];
178197 for (const L1CaloRegion& i : *regionCollection) {
179198 UCTRegionIndex r = g.getUCTRegionIndexFromL1CaloRegion (i.gctEta (), i.gctPhi ());
180199 UCTTowerIndex t = g.getUCTTowerIndexFromL1CaloRegion (r, i.raw ());
@@ -189,7 +208,22 @@ void L1TCaloSummary::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
189208 UCTRegion* test = new UCTRegion (crate, card, negativeEta, region, fwVersion);
190209 test->setRegionSummary (i.raw ());
191210 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 ();
192217 }
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+
193227 summaryCard.setRegionData (inputRegions);
194228
195229 if (!summaryCard.process ()) {
@@ -253,6 +287,8 @@ void L1TCaloSummary::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
253287 }
254288
255289 iEvent.put (std::move (bJetCands), " Boosted" );
290+ // Write out anomaly score
291+ iEvent.put (std::move (anomalyScore), " anomalyScore" );
256292}
257293
258294void L1TCaloSummary::print () {}
0 commit comments