CMS 3D CMS Logo

AXOL1TLCondition.cc
Go to the documentation of this file.
1 
11 // this class header
13 
14 // system include files
15 #include <iostream>
16 #include <iomanip>
17 
18 #include <string>
19 #include <vector>
20 #include <algorithm>
21 #include "ap_fixed.h"
22 #include "hls4ml/emulator.h"
23 
24 // user include files
25 // base classes
28 
37 
39 
41 
44 
45 // constructors
46 // default
48  // empty
49 }
50 
51 // from base template condition (from event setup usually)
54  m_gtAXOL1TLTemplate(static_cast<const AXOL1TLTemplate*>(axol1tlTemplate)),
55  m_gtGTB(ptrGTB) {}
56 
57 // copy constructor
59  m_gtAXOL1TLTemplate = cp.gtAXOL1TLTemplate();
60  m_gtGTB = cp.gtGTB();
61 
62  m_condMaxNumberObjects = cp.condMaxNumberObjects();
63  m_condLastResult = cp.condLastResult();
64  m_combinationsInCond = cp.getCombinationsInCond();
65 
66  m_verbosity = cp.m_verbosity;
67 }
68 
70 
71 // destructor
73  // empty
74 }
75 
76 // equal operator
78  copy(cp);
79  return *this;
80 }
81 
82 // methods
83 void l1t::AXOL1TLCondition::setGtAXOL1TLTemplate(const AXOL1TLTemplate* caloTempl) { m_gtAXOL1TLTemplate = caloTempl; }
84 
86 void l1t::AXOL1TLCondition::setuGtB(const GlobalBoard* ptrGTB) { m_gtGTB = ptrGTB; }
87 
88 const bool l1t::AXOL1TLCondition::evaluateCondition(const int bxEval) const {
89  bool condResult = false;
90  int useBx = bxEval + m_gtAXOL1TLTemplate->condRelativeBx();
91 
92  //HLS4ML stuff
93  std::string AXOL1TLmodelversion = m_AXOL1TLmodelversion; //config loading method
94  hls4mlEmulator::ModelLoader loader(AXOL1TLmodelversion);
95  std::shared_ptr<hls4mlEmulator::Model> model;
96  model = loader.load_model();
97 
98  // //pointers to objects
99  const BXVector<const l1t::Muon*>* candMuVec = m_gtGTB->getCandL1Mu();
100  const BXVector<const l1t::L1Candidate*>* candJetVec = m_gtGTB->getCandL1Jet();
101  const BXVector<const l1t::L1Candidate*>* candEGVec = m_gtGTB->getCandL1EG();
102  const BXVector<const l1t::EtSum*>* candEtSumVec = m_gtGTB->getCandL1EtSum();
103 
104  const int NMuons = 4;
105  const int NJets = 10;
106  const int NEgammas = 4;
107  //const int NEtSums = 1;
108 
109  //number of indices in vector is #objects * 3 for et, eta, phi
110  const int MuVecSize = 12; //NMuons * 3; //so 12
111  const int JVecSize = 30; //NJets * 3; //so 30
112  const int EGVecSize = 12; //NEgammas * 3; //so 12
113  const int EtSumVecSize = 3; //NEtSums * 3; //so 3
114 
115  //total # inputs in vector is (4+10+4+1)*3 = 57
116  const int NInputs = 57;
117 
118  //types of inputs and outputs
119  typedef ap_fixed<18, 13> inputtype;
120  typedef std::array<ap_fixed<10, 7, AP_RND_CONV, AP_SAT>, 8> resulttype; //v3
121  typedef ap_ufixed<18, 14> losstype;
122  typedef std::pair<resulttype, losstype> pairtype;
123  // typedef std::array<ap_fixed<10, 7>, 13> resulttype; //deprecated v1 type:
124 
125  //define zero
126  inputtype fillzero = 0.0;
127 
128  //AD vector declaration, will fill later
129  inputtype ADModelInput[NInputs] = {};
130 
131  //initializing vector by type for my sanity
132  inputtype MuInput[MuVecSize];
133  inputtype JetInput[JVecSize];
134  inputtype EgammaInput[EGVecSize];
135  inputtype EtSumInput[EtSumVecSize];
136 
137  //declare result vectors +score
138  resulttype result;
139  losstype loss;
140  pairtype ADModelResult; //model outputs a pair of the (result vector, loss)
141  float score = -1.0; //not sure what the best default is hm??
142 
143  //check number of input objects we actually have (muons, jets etc)
144  int NCandMu = candMuVec->size(useBx);
145  int NCandJet = candJetVec->size(useBx);
146  int NCandEG = candEGVec->size(useBx);
147  int NCandEtSum = candEtSumVec->size(useBx);
148 
149  //initialize arrays to zero (std::fill(first, last, value);)
150  std::fill(EtSumInput, EtSumInput + EtSumVecSize, fillzero);
151  std::fill(MuInput, MuInput + MuVecSize, fillzero);
152  std::fill(JetInput, JetInput + JVecSize, fillzero);
153  std::fill(EgammaInput, EgammaInput + EGVecSize, fillzero);
154  std::fill(ADModelInput, ADModelInput + NInputs, fillzero);
155 
156  //then fill the object vectors
157  //NOTE assume candidates are already sorted by pt
158  //loop over EtSums first, easy because there is max 1 of them
159  if (NCandEtSum > 0) { //check if not empty
160  for (int iEtSum = 0; iEtSum < NCandEtSum; iEtSum++) {
161  if ((candEtSumVec->at(useBx, iEtSum))->getType() == l1t::EtSum::EtSumType::kMissingEt) {
162  EtSumInput[0] =
163  ((candEtSumVec->at(useBx, iEtSum))->hwPt()) / 2; //have to do hwPt/2 in order to match original et inputs
164  // EtSumInput[1] = (candEtSumVec->at(useBx, iEtSum))->hwEta(); //this one is zero, so leave it zero
165  EtSumInput[2] = (candEtSumVec->at(useBx, iEtSum))->hwPhi();
166  }
167  }
168  }
169 
170  //next egammas
171  if (NCandEG > 0) { //check if not empty
172  for (int iEG = 0; iEG < NCandEG; iEG++) {
173  if (iEG < NEgammas) { //stop if fill the Nobjects we need
174  EgammaInput[0 + (3 * iEG)] = ((candEGVec->at(useBx, iEG))->hwPt()) /
175  2; //index 0,3,6,9 //have to do hwPt/2 in order to match original et inputs
176  EgammaInput[1 + (3 * iEG)] = (candEGVec->at(useBx, iEG))->hwEta(); //index 1,4,7,10
177  EgammaInput[2 + (3 * iEG)] = (candEGVec->at(useBx, iEG))->hwPhi(); //index 2,5,8,11
178  }
179  }
180  }
181 
182  //next muons
183  if (NCandMu > 0) { //check if not empty
184  for (int iMu = 0; iMu < NCandMu; iMu++) {
185  if (iMu < NMuons) { //stop if fill the Nobjects we need
186  MuInput[0 + (3 * iMu)] = ((candMuVec->at(useBx, iMu))->hwPt()) /
187  2; //index 0,3,6,9 //have to do hwPt/2 in order to match original et inputs
188  MuInput[1 + (3 * iMu)] = (candMuVec->at(useBx, iMu))->hwEta(); //index 1,4,7,10
189  MuInput[2 + (3 * iMu)] = (candMuVec->at(useBx, iMu))->hwPhi(); //index 2,5,8,11
190  }
191  }
192  }
193 
194  //next jets
195  if (NCandJet > 0) { //check if not empty
196  for (int iJet = 0; iJet < NCandJet; iJet++) {
197  if (iJet < NJets) { //stop if fill the Nobjects we need
198  JetInput[0 + (3 * iJet)] = ((candJetVec->at(useBx, iJet))->hwPt()) /
199  2; //index 0,3,6,9...27 //have to do hwPt/2 in order to match original et inputs
200  JetInput[1 + (3 * iJet)] = (candJetVec->at(useBx, iJet))->hwEta(); //index 1,4,7,10...28
201  JetInput[2 + (3 * iJet)] = (candJetVec->at(useBx, iJet))->hwPhi(); //index 2,5,8,11...29
202  }
203  }
204  }
205 
206  //now put it all together-> EtSum+EGamma+Muon+Jet into ADModelInput
207  int index = 0;
208  for (int idET = 0; idET < EtSumVecSize; idET++) {
209  ADModelInput[index++] = EtSumInput[idET];
210  }
211  for (int idEG = 0; idEG < EGVecSize; idEG++) {
212  ADModelInput[index++] = EgammaInput[idEG];
213  }
214  for (int idMu = 0; idMu < MuVecSize; idMu++) {
215  ADModelInput[index++] = MuInput[idMu];
216  }
217  for (int idJ = 0; idJ < JVecSize; idJ++) {
218  ADModelInput[index++] = JetInput[idJ];
219  }
220 
221  //now run the inference
222  model->prepare_input(ADModelInput); //scaling internal here
223  model->predict();
224  model->read_result(&ADModelResult); // this should be the square sum model result
225 
226  result = ADModelResult.first;
227  loss = ADModelResult.second;
228  score = ((loss).to_float()) * 16.0; //scaling to match threshold
229 
230  //number of objects/thrsholds to check
231  int iCondition = 0; // number of conditions: there is only one
232  int nObjInCond = m_gtAXOL1TLTemplate->nrObjects();
233 
234  if (iCondition >= nObjInCond || iCondition < 0) {
235  return false;
236  }
237 
238  const AXOL1TLTemplate::ObjectParameter objPar = (*(m_gtAXOL1TLTemplate->objectParameter()))[iCondition];
239 
240  // condGEqVal indicates the operator used for the condition (>=, =): true for >=
241  bool condGEqVal = m_gtAXOL1TLTemplate->condGEq();
242  bool passCondition = false;
243 
244  passCondition = checkCut(objPar.minAXOL1TLThreshold, score, condGEqVal);
245 
246  condResult |= passCondition; //condresult true if passCondition true else it is false
247 
248  //return result
249  return condResult;
250 }
251 
252 //in order to set model version from config
254  m_AXOL1TLmodelversion = modelversionname;
255 }
256 
257 void l1t::AXOL1TLCondition::print(std::ostream& myCout) const {
258  myCout << "Dummy Print for AXOL1TLCondition" << std::endl;
259  m_gtAXOL1TLTemplate->print(myCout);
260 
262 }
void print(std::ostream &myCout) const override
print condition
void setModelVersion(const std::string modelversionname)
unsigned size(int bx) const
void setGtAXOL1TLTemplate(const AXOL1TLTemplate *)
const T & at(int bx, unsigned i) const
virtual void print(std::ostream &myCout) const
print condition
void copy(const AXOL1TLCondition &cp)
copy function for copy constructor and operator=
AXOL1TLCondition & operator=(const AXOL1TLCondition &)
void setuGtB(const GlobalBoard *)
set the pointer to uGT GlobalBoard
const bool evaluateCondition(const int bxEval) const override
the core function to check if the condition matches