CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Stage2Layer2JetAlgorithmFirmwareImp1.cc
Go to the documentation of this file.
1 //
7 
14 
15 #include <vector>
16 #include <algorithm>
17 #include <math.h>
18 
19 namespace l1t {
21  {
22  if ( a.hwPt() > b.hwPt() ) {
23  return true;
24  } else {
25  return false;
26  }
27  }
28 }
29 
30 // jet mask, needs to be configurable at some point
31 // just a square for now
32 // for 1 do greater than, for 2 do greater than equal to
33 
34 int mask_[9][9] = {
35  { 1,2,2,2,2,2,2,2,2 },
36  { 1,1,2,2,2,2,2,2,2 },
37  { 1,1,1,2,2,2,2,2,2 },
38  { 1,1,1,1,2,2,2,2,2 },
39  { 1,1,1,1,0,2,2,2,2 },
40  { 1,1,1,1,1,2,2,2,2 },
41  { 1,1,1,1,1,1,2,2,2 },
42  { 1,1,1,1,1,1,1,2,2 },
43  { 1,1,1,1,1,1,1,1,2 },
44 };
45 
46 std::vector<l1t::Jet>::iterator start_, end_;
47 
49  params_(params){}
50 
51 
53 
54 void l1t::Stage2Layer2JetAlgorithmFirmwareImp1::processEvent(const std::vector<l1t::CaloTower> & towers,
55  std::vector<l1t::Jet> & jets, std::vector<l1t::Jet> & alljets) {
56 
57  // find jets
58  create(towers, jets, alljets, params_->jetPUSType());
59 
60  // jet energy corrections
61  calibrate(jets, 10/params_->jetLsb()); // pass the jet collection and the hw threshold above which to calibrate
62 
63 }
64 
65 
66 void l1t::Stage2Layer2JetAlgorithmFirmwareImp1::create(const std::vector<l1t::CaloTower> & towers, std::vector<l1t::Jet> & jets,
67  std::vector<l1t::Jet> & alljets, std::string PUSubMethod) {
68 
69  int etaMax=40, etaMin=1, phiMax=72, phiMin=1;
70 
71  // etaSide=1 is positive eta, etaSide=-1 is negative eta
72  for (int etaSide=1; etaSide>=-1; etaSide-=2) {
73 
74  // the 4 groups of rings
75  std::vector<int> ringGroup1, ringGroup2, ringGroup3, ringGroup4;
76  for (int i=etaMin; i<=etaMax; i++) {
77  if ( ! ((i-1)%4) ) ringGroup1.push_back( i * etaSide );
78  else if ( ! ((i-2)%4) ) ringGroup2.push_back( i * etaSide );
79  else if ( ! ((i-3)%4) ) ringGroup3.push_back( i * etaSide );
80  else if ( ! ((i-4)%4) ) ringGroup4.push_back( i * etaSide );
81  }
82  std::vector< std::vector<int> > theRings = { ringGroup1, ringGroup2, ringGroup3, ringGroup4 };
83 
84  // the 24 jets in this eta side
85  std::vector<l1t::Jet> jetsHalf;
86 
87  // loop over the 4 groups of rings
88  for ( unsigned ringGroupIt=1; ringGroupIt<=theRings.size(); ringGroupIt++ ) {
89 
90  // the 6 accumulated jets
91  std::vector<l1t::Jet> jetsAccu;
92 
93  // loop over the 10 rings in this group
94  for ( unsigned ringIt=0; ringIt<theRings.at(ringGroupIt-1).size(); ringIt++ ) {
95 
96  int ieta = theRings.at(ringGroupIt-1).at(ringIt);
97 
98  // the jets in this ring
99  std::vector<l1t::Jet> jetsRing;
100 
101  // loop over phi in the ring
102  for ( int iphi=phiMin; iphi<=phiMax; ++iphi ) {
103 
104  // no more than 18 jets per ring
105  if (jetsRing.size()==18) break;
106 
107  // seed tower
108  const CaloTower& tow = CaloTools::getTower(towers, ieta, iphi);
109 
110  int seedEt = tow.hwPt();
111  int iEt = seedEt;
112  bool vetoCandidate = false;
113 
114  // check it passes the seed threshold
115  if(iEt < floor(params_->jetSeedThreshold()/params_->towerLsbSum())) continue;
116 
117  // loop over towers in this jet
118  for( int deta = -4; deta < 5; ++deta ) {
119  for( int dphi = -4; dphi < 5; ++dphi ) {
120 
121  int towEt = 0;
122  int ietaTest = ieta+deta;
123  int iphiTest = iphi+dphi;
124 
125  // wrap around phi
126  while ( iphiTest > phiMax ) iphiTest -= phiMax;
127  while ( iphiTest < phiMin ) iphiTest += phiMax;
128 
129  // wrap over eta=0
130  if (ieta > 0 && ietaTest <=0) ietaTest -= 1;
131  if (ieta < 0 && ietaTest >=0) ietaTest += 1;
132 
133  // check jet mask and sum tower et
134  const CaloTower& towTest = CaloTools::getTower(towers, ietaTest, iphiTest);
135  towEt = towTest.hwPt();
136 
137  if (mask_[8-(dphi+4)][deta+4] == 0) continue;
138  else if (mask_[8-(dphi+4)][deta+4] == 1) vetoCandidate = (seedEt < towEt);
139  else if (mask_[8-(dphi+4)][deta+4] == 2) vetoCandidate = (seedEt <= towEt);
140 
141  if (vetoCandidate) break;
142  else iEt += towEt;
143 
144  }
145  if(vetoCandidate) break;
146  }
147 
148  // add the jet to the list
149  if (!vetoCandidate) {
150 
151  if (PUSubMethod == "Donut") iEt -= donutPUEstimate(ieta, iphi, 5, towers);
152  if (PUSubMethod == "ChunkyDonut") iEt -= chunkyDonutPUEstimate(ieta, iphi, 5, towers);
153 
154  if (iEt<=0) continue;
155 
157  l1t::Jet jet( p4, iEt, ieta, iphi, 0);
158 
159  jetsRing.push_back(jet);
160  alljets.push_back(jet);
161 
162  }
163 
164  }
165 
166  // sort these jets and keep top 6
167  start_ = jetsRing.begin();
168  end_ = jetsRing.end();
169  BitonicSort<l1t::Jet>(down, start_, end_);
170  if (jetsRing.size()>6) jetsRing.resize(6);
171 
172  // merge with the accumulated jets
173  std::vector<l1t::Jet> jetsSort;
174  jetsSort.insert(jetsSort.end(), jetsAccu.begin(), jetsAccu.end());
175  jetsSort.insert(jetsSort.end(), jetsRing.begin(), jetsRing.end());
176 
177  // sort and truncate
178  start_ = jetsSort.begin();
179  end_ = jetsSort.end();
180  BitonicSort<l1t::Jet>(down, start_, end_); // or just use BitonicMerge
181  if (jetsSort.size()>6) jetsSort.resize(6);
182 
183  // update accumulated jets
184  jetsAccu = jetsSort;
185 
186  }
187 
188  // add to final jets in this eta side
189  jetsHalf.insert(jetsHalf.end(), jetsAccu.begin(), jetsAccu.end());
190 
191  }
192 
193  // sort the 24 jets and keep top 6
194  start_ = jetsHalf.begin();
195  end_ = jetsHalf.end();
196  BitonicSort<l1t::Jet>(down, start_, end_);
197  if (jetsHalf.size()>6) jetsHalf.resize(6);
198 
199  // add to final jets
200  jets.insert(jets.end(), jetsHalf.begin(), jetsHalf.end());
201 
202  }
203 
204 }
205 
206 //A function to return the value for donut subtraction around an ieta and iphi position for donut subtraction
207 //Also pass it a vector to store the individual values of the strip for later testing
208 //The size is the number of ieta/iphi units out the ring is (ie for 9x9 jets, we want the 11x11 for PUS therefore we want to go 5 out, so size is 5)
209 int l1t::Stage2Layer2JetAlgorithmFirmwareImp1::donutPUEstimate(int jetEta, int jetPhi, int size, const std::vector<l1t::CaloTower> & towers){
210 
211  //Declare the range to carry out the algorithm over
212  int etaMax=40, etaMin=-40, phiMax=72, phiMin=1;
213 
214  //ring is a vector with 4 ring strips, one for each side of the ring
215  std::vector<int> ring(4,0);
216 
217  int iphiUp = jetPhi + size;
218  while ( iphiUp > phiMax ) iphiUp -= phiMax;
219  int iphiDown = jetPhi - size;
220  while ( iphiDown < phiMin ) iphiDown += phiMax;
221 
222  int ietaUp = (jetEta + size > etaMax) ? 999 : jetEta+size;
223  int ietaDown = (jetEta - size < etaMin) ? 999 : jetEta-size;
224 
225  for (int ieta = jetEta - size+1; ieta < jetEta + size; ++ieta)
226  {
227 
228  if (ieta > etaMax || ieta < etaMin) continue;
229  int towerEta;
230 
231  if (jetEta > 0 && ieta <=0){
232  towerEta = ieta-1;
233  } else if (jetEta < 0 && ieta >=0){
234  towerEta = ieta+1;
235  } else {
236  towerEta=ieta;
237  }
238 
239  const CaloTower& tow = CaloTools::getTower(towers, towerEta, iphiUp);
240  int towEt = tow.hwPt();
241  ring[0]+=towEt;
242 
243  const CaloTower& tow2 = CaloTools::getTower(towers, towerEta, iphiDown);
244  towEt = tow2.hwPt();
245  ring[1]+=towEt;
246 
247  }
248 
249  for (int iphi = jetPhi - size+1; iphi < jetPhi + size; ++iphi)
250  {
251 
252  int towerPhi = iphi;
253  while ( towerPhi > phiMax ) towerPhi -= phiMax;
254  while ( towerPhi < phiMin ) towerPhi += phiMax;
255 
256  const CaloTower& tow = CaloTools::getTower(towers, ietaUp, towerPhi);
257  int towEt = tow.hwPt();
258  ring[2]+=towEt;
259 
260  const CaloTower& tow2 = CaloTools::getTower(towers, ietaDown, towerPhi);
261  towEt = tow2.hwPt();
262  ring[3]+=towEt;
263  }
264 
265  //for the Donut Subtraction we only use the middle 2 (in energy) ring strips
266  std::sort(ring.begin(), ring.end(), std::greater<int>());
267 
268  return 4*( ring[1]+ring[2] ); // This should really be multiplied by 4.5 not 4.
269 }
270 
271 int l1t::Stage2Layer2JetAlgorithmFirmwareImp1::chunkyDonutPUEstimate(int jetEta, int jetPhi, int size, const std::vector<l1t::CaloTower> & towers){
272 
273  // the range to carry out the algorithm over
274  int etaMax=40, etaMin=-40, phiMax=72, phiMin=1;
275 
276  // ring is a vector with 4 ring strips, one for each side of the ring
277  // order is PhiUp, PhiDown, EtaUp, EtaDown
278  std::vector<int> ring(4,0);
279 
280  // number of strips in donut - should make this configurable
281  int nStrips = 3;
282 
283  // loop over strips
284  for (int stripIt=0; stripIt<nStrips; stripIt++) {
285 
286  int iphiUp = jetPhi + size + stripIt;
287  int iphiDown = jetPhi - size - stripIt;
288  while ( iphiUp > phiMax ) iphiUp -= phiMax;
289  while ( iphiDown < phiMin ) iphiDown += phiMax;
290 
291  int ietaUp = jetEta + size + stripIt;
292  int ietaDown = jetEta - size - stripIt;
293  if ( jetEta<0 && ietaUp>=0 ) ietaUp += 1;
294  if ( jetEta>0 && ietaDown<=0 ) ietaDown -= 1;
295 
296  // do PhiUp and PhiDown
297  for (int ieta=jetEta-size+1; ieta<jetEta+size; ++ieta) {
298 
299  if (ieta>etaMax || ieta<etaMin) continue;
300 
301  int towEta = ieta;
302  if (jetEta>0 && towEta<=0) towEta-=1;
303  if (jetEta<0 && towEta>=0) towEta+=1;
304 
305  const CaloTower& towPhiUp = CaloTools::getTower(towers, towEta, iphiUp);
306  int towEt = towPhiUp.hwPt();
307  ring[0] += towEt;
308 
309  const CaloTower& towPhiDown = CaloTools::getTower(towers, towEta, iphiDown);
310  towEt = towPhiDown.hwPt();
311  ring[1] += towEt;
312 
313  }
314 
315  // do EtaUp and EtaDown
316  for (int iphi=jetPhi-size+1; iphi<jetPhi+size; ++iphi) {
317 
318  int towPhi = iphi;
319  while ( towPhi > phiMax ) towPhi -= phiMax;
320  while ( towPhi < phiMin ) towPhi += phiMax;
321 
322  if (ietaUp>=etaMin && ietaUp<=etaMax) {
323  const CaloTower& towEtaUp = CaloTools::getTower(towers, ietaUp, towPhi);
324  int towEt = towEtaUp.hwPt();
325  ring[2] += towEt;
326  }
327 
328  if (ietaDown>=etaMin && ietaDown<=etaMax) {
329  const CaloTower& towEtaDown = CaloTools::getTower(towers, ietaDown, towPhi);
330  int towEt = towEtaDown.hwPt();
331  ring[3] += towEt;
332  }
333 
334  }
335 
336  }
337 
338  // for donut subtraction we only use the middle 2 (in energy) ring strips
339  std::sort(ring.begin(), ring.end(), std::greater<int>());
340  return ( ring[1]+ring[2] );
341 
342 }
343 
344 
345 
346 void l1t::Stage2Layer2JetAlgorithmFirmwareImp1::calibrate(std::vector<l1t::Jet> & jets, int calibThreshold) {
347 
348  if( params_->jetCalibrationType() == "function6PtParams22EtaBins" ){ //One eta bin per region
349 
350  //Check the vector of calibration parameters is the correct size
351  //Order the vector in terms of the parameters per eta bin, starting in -ve eta
352  //So first 6 entries are very negative eta, next 6 are the next bin etc.
353 
354  if( params_->jetCalibrationParams().size() != 132){
355  edm::LogError("l1t|stage 2") << "Invalid input vector to calo params. Input vector of size: " <<
356  params_->jetCalibrationParams().size() << " Require size: 132 Not calibrating Stage 2 Jets" << std::endl;
357  return;
358  }
359 
360  //Loop over jets and apply corrections
361  for(std::vector<l1t::Jet>::iterator jet = jets.begin(); jet!=jets.end(); jet++){
362 
363  //Check jet is above the calibration threshold, if not do nothing
364  if(jet->hwPt() < calibThreshold) continue;
365 
366  //Make a map for the trigger towers eta to the RCT region eta
367  //80 TT to 22 RCT regions
368  int ttToRct[80];
369  int tt=0;
370  for(int rct=0; rct<22; rct++){
371  if(rct<4 || rct>17){
372  for(int i=0; i<3; i++){
373  ttToRct[tt] = rct;
374  tt++;
375  }
376  }else{
377  for(int i=0; i<4; i++){
378  ttToRct[tt] = rct;
379  tt++;
380  }
381  }
382  }
383 
384  int etaBin;
385  if(jet->hwEta() < 0) //Account for a lack of 0
386  etaBin = ttToRct[ jet->hwEta() + 40 ];
387  else
388  etaBin = ttToRct[ jet->hwEta() + 39 ];
389 
390  double params[6]; //These are the parameters of the fit
391  double ptValue[1]; //This is the pt value to be corrected
392 
393  ptValue[0] = jet->hwPt()*params_->jetLsb(); //Corrections derived in terms of physical pt
394 
395  //Get the parameters from the vector
396  //Each 6 values are the parameters for an eta bin
397  for(int i=0; i<6; i++){
398  params[i] = params_->jetCalibrationParams()[etaBin*6 + i];
399  }
400 
401  //Perform the correction based on the calibration function defined
402  //in calibFit
403  //This is derived from the actual pt of the jets, not the hwEt
404  //This needs to be addressed in the future
405  double correction = calibFit(ptValue,params);
406 
408  *jet = l1t::Jet( p4, correction*jet->hwPt(), jet->hwEta(), jet->hwPhi(), 0);
409 
410  }
411 
412 
413  } else if( params_->jetCalibrationType() == "function6PtParams80EtaBins" ) { // If we want TT level calibration
414 
415  if( params_->jetCalibrationParams().size() != 480){
416  edm::LogError("l1t|stage 2") << "Invalid input vector to calo params. Input vector of size: " <<
417  params_->jetCalibrationParams().size() << " Require size: 480 Not calibrating Stage 2 Jets" << std::endl;
418  return;
419  }
420 
421  //Loop over jets and apply corrections
422  for(std::vector<l1t::Jet>::iterator jet = jets.begin(); jet!=jets.end(); jet++){
423 
424  int etaBin;
425  if(jet->hwEta() < 0) //Account for a lack of 0
426  etaBin = jet->hwEta() + 40;
427  else
428  etaBin = jet->hwEta() + 39;
429 
430 
431  double params[6]; //These are the parameters of the fit
432  double ptValue[1]; //This is the pt value to be corrected
433 
434  ptValue[0] = jet->hwPt()*params_->jetLsb(); //Corrections derived in terms of physical pt
435 
436  //Get the parameters from the vector
437  //Each 6 values are the parameters for an eta bin
438  for(int i=0; i<6; i++){
439  params[i] = params_->jetCalibrationParams()[etaBin*6 + i];
440  }
441 
442  //Perform the correction based on the calibration function defined
443  //in calibFit
444  double correction = calibFit(ptValue,params);
445 
447  *jet = l1t::Jet( p4, correction*jet->hwPt(), jet->hwEta(), jet->hwPhi(), 0);
448 
449  }
450 
451  } else if( params_->jetCalibrationType() == "lut6PtBins22EtaBins" ) { // If we want to use a LUT instead
452 
453  edm::LogError("l1t|stage 2") << "No LUT implementation for the calibration yet" << std::endl;
454  return;
455 
456  } else {
457  if(params_->jetCalibrationType() != "None" && params_->jetCalibrationType() != "none")
458  edm::LogError("l1t|stage 2") << "Invalid calibration type in calo params. Not calibrating Stage 2 Jets" << std::endl;
459  return;
460  }
461 
462 
463 }
464 
465 //Function for the calibration, correct as a function of pT in bins of eta
467 
468  // JETMET uses log10 rather than the ln used here...
469  double logX = log(v[0]);
470 
471  double term1 = par[1] / ( logX * logX + par[2] );
472  double term2 = par[3] * exp( -par[4]*((logX - par[5])*(logX - par[5])) );
473 
474  // Final fitting function
475  double f = par[0] + term1 + term2;
476 
477  return f;
478 }
void calibrate(std::vector< Jet > &jets, int calibThreshold)
int i
Definition: DBlmapReader.cc:9
std::vector< l1t::Jet >::iterator end_
bool operator>(l1t::Jet &a, l1t::Jet &b)
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
Definition: Jet.h:13
std::vector< l1t::Jet >::iterator start_
int donutPUEstimate(int jetEta, int jetPhi, int size, const std::vector< l1t::CaloTower > &towers)
double p4[4]
Definition: TauolaWrapper.h:92
vector< PseudoJet > jets
double f[11][100]
virtual void processEvent(const std::vector< CaloTower > &towers, std::vector< Jet > &jets, std::vector< Jet > &alljets)
int hwPt() const
Definition: L1Candidate.cc:69
double b
Definition: hdecay.h:120
void create(const std::vector< CaloTower > &towers, std::vector< Jet > &jets, std::vector< Jet > &alljets, std::string PUSubMethod)
static const l1t::CaloTower & getTower(const std::vector< l1t::CaloTower > &towers, int iEta, int iPhi)
Definition: CaloTools.cc:11
double a
Definition: hdecay.h:121
SurfaceDeformation * create(int type, const std::vector< double > &params)
tuple size
Write out results.
int chunkyDonutPUEstimate(int jetEta, int jetPhi, int pos, const std::vector< l1t::CaloTower > &towers)
tuple log
Definition: cmsBatch.py:341