CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Stage1Layer2EtSumAlgorithmImpHW.cc
Go to the documentation of this file.
1 
17 #include <cassert>
18 
20 {
21  //now do what ever initialization is needed
22  for(size_t i=0; i<cordicPhiValues.size(); ++i) {
23  cordicPhiValues[i] = static_cast<int>(pow(2.,16)*(((float) i)-36)*M_PI/36);
24  }
25  for(size_t i=0; i<sines.size(); ++i) {
26  sines[i] = static_cast<long>(pow(2,30)*sin(i*20*M_PI/180));
27  cosines[i] = static_cast<long>(pow(2,30)*cos(i*20*M_PI/180));
28  }
29 }
30 
31 
33 
34 
35 }
36 
37 void l1t::Stage1Layer2EtSumAlgorithmImpHW::processEvent(const std::vector<l1t::CaloRegion> & regions,
38  const std::vector<l1t::CaloEmCand> & EMCands,
39  const std::vector<l1t::Jet> * jets,
40  std::vector<l1t::EtSum> * etsums) {
41 
42  std::vector<l1t::CaloRegion> *subRegions = new std::vector<l1t::CaloRegion>();
43 
44 
45  //Region Correction will return uncorrected subregions if
46  //regionPUSType is set to None in the config
47  double jetLsb=params_->jetLsb();
48 
49  int etSumEtaMinEt = params_->etSumEtaMin(0);
50  int etSumEtaMaxEt = params_->etSumEtaMax(0);
51  //double etSumEtThresholdEt = params_->etSumEtThreshold(0);
52  int etSumEtThresholdEt = (int) (params_->etSumEtThreshold(0) / jetLsb);
53 
54  int etSumEtaMinHt = params_->etSumEtaMin(1);
55  int etSumEtaMaxHt = params_->etSumEtaMax(1);
56  //double etSumEtThresholdHt = params_->etSumEtThreshold(1);
57  int etSumEtThresholdHt = (int) (params_->etSumEtThreshold(1) / jetLsb);
58 
59  RegionCorrection(regions, subRegions, params_);
60 
61  std::vector<SimpleRegion> regionEtVect;
62  std::vector<SimpleRegion> regionHtVect;
63 
64  // check the un-subtracted regions for overflow
65  bool regionOverflowEt(false);
66  bool regionOverflowHt(false);
67  for (auto& region : regions) {
68  if(region.hwEta() >= etSumEtaMinEt && region.hwEta() <= etSumEtaMaxEt)
69  {
70  if(region.hwPt() >= 1023)
71  {
72  regionOverflowEt = true;
73  }
74  }
75  if ( region.hwEta() >= etSumEtaMinHt && region.hwEta() <= etSumEtaMaxHt)
76  {
77  if(region.hwPt() >= 1023)
78  {
79  regionOverflowHt = true;
80  }
81  }
82  }
83 
84  // hwPt() is the sum ET+HT in region, for stage 1 this will be
85  // the region sum input to MET algorithm
86  // In stage 2, we would move to hwEtEm() and hwEtHad() for separate MET/MHT
87  // Thresholds will be hardware values not physical
88  for (auto& region : *subRegions) {
89  if ( region.hwEta() >= etSumEtaMinEt && region.hwEta() <= etSumEtaMaxEt)
90  {
91  if(region.hwPt() >= etSumEtThresholdEt)
92  {
94  r.ieta = region.hwEta();
95  r.iphi = region.hwPhi();
96  r.et = region.hwPt();
97  regionEtVect.push_back(r);
98  }
99  }
100  if ( region.hwEta() >= etSumEtaMinHt && region.hwEta() <= etSumEtaMaxHt)
101  {
102  if(region.hwPt() >= etSumEtThresholdHt)
103  {
104  SimpleRegion r;
105  r.ieta = region.hwEta();
106  r.iphi = region.hwPhi();
107  r.et = region.hwPt();
108  regionHtVect.push_back(r);
109  }
110  }
111  }
112 
113  int sumET, MET, iPhiET;
114  std::tie(sumET, MET, iPhiET) = doSumAndMET(regionEtVect, ETSumType::kEmSum);
115 
116  int sumHT, MHT, iPhiHT;
117  std::tie(sumHT, MHT, iPhiHT) = doSumAndMET(regionHtVect, ETSumType::kHadronicSum);
118 
119  // Set quality (i.e. overflow) bits appropriately
120  int METqual = 0;
121  int MHTqual = 0;
122  int ETTqual = 0;
123  int HTTqual = 0;
124  if(MET > 0xfff || regionOverflowEt) // MET 12 bits
125  METqual = 1;
126  if(MHT > 0x7f || regionOverflowHt) // MHT 7 bits
127  MHTqual = 1;
128  if(sumET > 0xfff || regionOverflowEt)
129  ETTqual = 1;
130  if(sumHT > 0xfff || regionOverflowHt)
131  HTTqual = 1;
132 
133  MHT &= 127; // limit MHT to 7 bits as the firmware does, but only after checking for overflow.
134  //MHT is replaced with MHT/HT
135  uint16_t MHToHT=MHToverHT(MHT,sumHT);
136  //iPhiHt is replaced by the dPhi between two most energetic jets
137  iPhiHT = DiJetPhi(jets);
138 
139  const ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<double> > etLorentz(0,0,0,0);
140  l1t::EtSum etMiss(*&etLorentz,EtSum::EtSumType::kMissingEt,MET&0xfff,0,iPhiET,METqual);
141  l1t::EtSum htMiss(*&etLorentz,EtSum::EtSumType::kMissingHt,MHToHT&0x7f,0,iPhiHT,MHTqual);
142  l1t::EtSum etTot (*&etLorentz,EtSum::EtSumType::kTotalEt,sumET&0xfff,0,0,ETTqual);
143  l1t::EtSum htTot (*&etLorentz,EtSum::EtSumType::kTotalHt,sumHT&0xfff,0,0,HTTqual);
144 
145  std::vector<l1t::EtSum> *preGtEtSums = new std::vector<l1t::EtSum>();
146 
147  preGtEtSums->push_back(etMiss);
148  preGtEtSums->push_back(htMiss);
149  preGtEtSums->push_back(etTot);
150  preGtEtSums->push_back(htTot);
151 
152  EtSumToGtScales(params_, preGtEtSums, etsums);
153 
154  delete subRegions;
155  delete preGtEtSums;
156 
157  // Emulator - HDL simulation comparison printout
158  const bool verbose = false;
159  if(verbose)
160  {
161  for(std::vector<l1t::EtSum>::const_iterator itetsum = etsums->begin();
162  itetsum != etsums->end(); ++itetsum){
163  if(EtSum::EtSumType::kMissingEt == itetsum->getType())
164  {
165  cout << "Missing Et" << endl;
166  cout << bitset<7>(itetsum->hwPhi()).to_string() << bitset<1>(itetsum->hwQual()).to_string() << bitset<12>(itetsum->hwPt()).to_string() << endl;
167  }
168  if(EtSum::EtSumType::kMissingHt == itetsum->getType())
169  {
170  cout << "Missing Ht" << endl;
171  cout << bitset<1>(itetsum->hwQual()).to_string() << bitset<7>(itetsum->hwPt()).to_string() << bitset<5>(itetsum->hwPhi()).to_string() << endl;
172  }
173  if(EtSum::EtSumType::kTotalEt == itetsum->getType())
174  {
175  cout << "Total Et" << endl;
176  cout << bitset<1>(itetsum->hwQual()).to_string() << bitset<12>(itetsum->hwPt()).to_string() << endl;
177  }
178  if(EtSum::EtSumType::kTotalHt == itetsum->getType())
179  {
180  cout << "Total Ht" << endl;
181  cout << bitset<1>(itetsum->hwQual()).to_string() << bitset<12>(itetsum->hwPt()).to_string() << endl;
182  }
183  }
184  }
185 }
186 
187 std::tuple<int, int, int>
188 l1t::Stage1Layer2EtSumAlgorithmImpHW::doSumAndMET(const std::vector<SimpleRegion>& regionEt, ETSumType sumType)
189 {
190  std::array<int, 18> sumEtaPos{};
191  std::array<int, 18> sumEtaNeg{};
192  for (const auto& r : regionEt)
193  {
194  if ( r.ieta < 11 )
195  sumEtaNeg[r.iphi] += r.et;
196  else
197  sumEtaPos[r.iphi] += r.et;
198  }
199 
200  std::array<int, 18> sumEta{};
201  int sumEt(0);
202  for(size_t i=0; i<sumEta.size(); ++i)
203  {
204  assert(sumEtaPos[i] >= 0 && sumEtaNeg[i] >= 0);
205  sumEta[i] = sumEtaPos[i] + sumEtaNeg[i];
206  sumEt += sumEta[i];
207  }
208 
209  // 0, 20, 40, 60, 80 degrees
210  std::array<int, 5> sumsForCos{};
211  std::array<int, 5> sumsForSin{};
212  for(size_t iphi=0; iphi<sumEta.size(); ++iphi)
213  {
214  if ( iphi < 5 )
215  {
216  sumsForCos[iphi] += sumEta[iphi];
217  sumsForSin[iphi] += sumEta[iphi];
218  }
219  else if ( iphi < 9 )
220  {
221  sumsForCos[9-iphi] -= sumEta[iphi];
222  sumsForSin[9-iphi] += sumEta[iphi];
223  }
224  else if ( iphi < 14 )
225  {
226  sumsForCos[iphi-9] -= sumEta[iphi];
227  sumsForSin[iphi-9] -= sumEta[iphi];
228  }
229  else
230  {
231  sumsForCos[18-iphi] += sumEta[iphi];
232  sumsForSin[18-iphi] -= sumEta[iphi];
233  }
234  }
235 
236  long sumX(0l);
237  long sumY(0l);
238  for(int i=0; i<5; ++i)
239  {
240  sumX += sumsForCos[i]*cosines[i];
241  sumY += sumsForSin[i]*sines[i];
242  }
243  assert(abs(sumX)<(1l<<48) && abs(sumY)<(1l<<48));
244  int cordicX = sumX>>25;
245  int cordicY = sumY>>25;
246 
247  uint32_t cordicMag(0);
248  int cordicPhase(0);
249  cordic(cordicX, cordicY, cordicPhase, cordicMag);
250 
251  int met(0);
252  int metPhi(0);
253  if ( sumType == ETSumType::kHadronicSum )
254  {
255  met = (cordicMag % (1<<7)) | ((cordicMag >= (1<<7)) ? (1<<7):0);
256  metPhi = cordicToMETPhi(cordicPhase) >> 2;
257  assert(metPhi >=0 && metPhi < 18);
258  }
259  else
260  {
261  met = (cordicMag % (1<<12)) | ((cordicMag >= (1<<12)) ? (1<<12):0);
262  metPhi = cordicToMETPhi(cordicPhase);
263  assert(metPhi >=0 && metPhi < 72);
264  }
265 
266  return std::make_tuple(sumEt, met, metPhi);
267 }
268 
269 // converts phase from 3Q16 to 0-71
270 // Expects abs(phase) <= 205887 (pi*2^16)
271 int
273 {
274  assert(abs(phase)<=205887);
275  for(size_t i=0; i<cordicPhiValues.size()-1; ++i)
276  if ( phase >= cordicPhiValues[i] && phase < cordicPhiValues[i+1] )
277  return i;
278  // if phase == +205887 (+pi), return zero
279  return 0;
280 }
281 
282 int l1t::Stage1Layer2EtSumAlgorithmImpHW::DiJetPhi(const std::vector<l1t::Jet> * jets) const {
283 
284  // cout << "Number of jets: " << jets->size() << endl;
285 
286  int dphi = 10; // initialize to negative physical dphi value
287  if (jets->size()<2) return dphi; // size() not really reliable as we pad the size to 8 (4cen+4for) in the sorter
288  if ((*jets).at(0).hwPt() == 0) return dphi;
289  if ((*jets).at(1).hwPt() == 0) return dphi;
290 
291 
292  int iphi1 = (*jets).at(0).hwPhi();
293  int iphi2 = (*jets).at(1).hwPhi();
294 
295  int difference=abs(iphi1-iphi2);
296 
297  if ( difference > 9 ) difference= L1CaloRegionDetId::N_PHI - difference ; // make Physical dphi always positive
298  return difference;
299 }
300 
301 uint16_t l1t::Stage1Layer2EtSumAlgorithmImpHW::MHToverHT(uint16_t num,uint16_t den) const {
302 
303  uint16_t result;
304  uint32_t numerator(num),denominator(den);
305 
306  if(numerator == denominator)
307  result = 0x7f;
308  else
309  {
310  numerator = numerator << 7;
311  result = numerator/denominator;
312  result = result & 0x7f;
313  }
314  // cout << "Result: " << result << endl;
315 
316  return result;
317 }
std::tuple< int, int, int > doSumAndMET(const std::vector< SimpleRegion > &regionEt, ETSumType sumType)
int i
Definition: DBlmapReader.cc:9
void RegionCorrection(const std::vector< l1t::CaloRegion > &regions, std::vector< l1t::CaloRegion > *subRegions, CaloParamsHelper *params)
------— New region correction (PUsub, no response correction at the moment) --------— ...
list numerator
Definition: cuy.py:483
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
assert(m_qm.get())
int DiJetPhi(const std::vector< l1t::Jet > *jets) const
void EtSumToGtScales(CaloParamsHelper *params, const std::vector< l1t::EtSum > *input, std::vector< l1t::EtSum > *output)
std::string to_string(const T &t)
Definition: Logger.cc:26
list denominator
Definition: cuy.py:484
vector< PseudoJet > jets
tuple result
Definition: query.py:137
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define M_PI
uint16_t MHToverHT(uint16_t, uint16_t) const
virtual void processEvent(const std::vector< l1t::CaloRegion > &regions, const std::vector< l1t::CaloEmCand > &EMCands, const std::vector< l1t::Jet > *jets, std::vector< l1t::EtSum > *sums)
tuple cout
Definition: gather_cfg.py:121
static const unsigned N_PHI
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40