CMS 3D CMS Logo

DiscretePFInputs.h
Go to the documentation of this file.
1 #ifndef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_H
2 #define L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_H
3 
4 #if defined(__GXX_EXPERIMENTAL_CXX0X__) or defined(CMSSW)
5 #include <cstdint>
6 #include <limits>
7 #define L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE
8 #else
9 #include <stdint.h>
10 #endif
11 
12 namespace l1t {
13  class PFTrack;
14  class PFCluster;
15  class PFCandidate;
16  class Muon;
17 } // namespace l1t
18 
19 // the serialization may be hidden if needed
20 #include <cmath>
21 #include <vector>
22 
23 namespace l1tpf_impl {
24 
25  struct CaloCluster {
26  int16_t hwPt;
27  int16_t hwEmPt;
28  int16_t hwPtErr;
29  int16_t hwEta;
30  int16_t hwPhi;
31  uint16_t hwFlags;
32  bool isEM, used;
34 
35  // sorting
36  bool operator<(const CaloCluster &other) const { return hwPt > other.hwPt; }
37 
38 #ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE
39  static constexpr float PT_SCALE = 4.0; // quantize in units of 0.25 GeV (can be changed)
40  static constexpr float ETAPHI_FACTOR = 4; // size of an ecal crystal in phi in integer units (our choice)
41  static constexpr float ETAPHI_SCALE =
42  ETAPHI_FACTOR *
43  (180. / M_PI); // M_PI/180 is the size of an ECal crystal; we make a grid that is 4 times that size
44  static constexpr int16_t PHI_WRAP = 360 * ETAPHI_FACTOR; // what is 3.14 in integer
45 
46  static int16_t ptToInt16(float pt) { // avoid overflows
47  return std::min<float>(round(pt * CaloCluster::PT_SCALE), std::numeric_limits<int16_t>::max());
48  }
49 
50  // filling from floating point
51  void fill(float pt,
52  float emPt,
53  float ptErr,
54  float eta,
55  float phi,
56  bool em,
57  unsigned int flags,
58  const l1t::PFCluster *source = nullptr) {
59  hwPt = CaloCluster::ptToInt16(pt);
60  hwEmPt = CaloCluster::ptToInt16(emPt);
61  hwPtErr = CaloCluster::ptToInt16(ptErr);
62  hwEta = round(eta * CaloCluster::ETAPHI_SCALE);
63  hwPhi = int16_t(round(phi * CaloCluster::ETAPHI_SCALE)) % CaloCluster::PHI_WRAP;
64  isEM = em;
65  used = false;
66  hwFlags = flags;
67  src = source;
68  }
69 
70  float floatPt() const { return float(hwPt) / CaloCluster::PT_SCALE; }
71  float floatEmPt() const { return float(hwEmPt) / CaloCluster::PT_SCALE; }
72  float floatPtErr() const { return float(hwPtErr) / CaloCluster::PT_SCALE; }
73  static float minFloatPt() { return float(1.0) / CaloCluster::PT_SCALE; }
74  float floatEta() const { return float(hwEta) / CaloCluster::ETAPHI_SCALE; }
75  float floatPhi() const { return float(hwPhi) / CaloCluster::ETAPHI_SCALE; }
76  void setFloatPt(float pt) { hwPt = round(pt * CaloCluster::PT_SCALE); }
77  void setFloatEmPt(float emPt) { hwEmPt = round(emPt * CaloCluster::PT_SCALE); }
78 #endif
79  };
80 
81  // https://twiki.cern.ch/twiki/bin/view/CMS/L1TriggerPhase2InterfaceSpecifications
82  struct InputTrack {
83  uint16_t hwInvpt;
84  int32_t hwVtxEta;
85  int32_t hwVtxPhi;
86  bool hwCharge;
87  int16_t hwZ0;
88  uint16_t hwChi2, hwStubs;
89  uint16_t hwFlags;
90  const l1t::PFTrack *src;
91 
92 #ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE
93  static constexpr float INVPT_SCALE = 2E4; // 1%/pt @ 100 GeV is 2 bits
94  static constexpr float VTX_PHI_SCALE = 1 / 1.6E-3; // 5 micro rad is 2 bits
95  static constexpr float VTX_ETA_SCALE = 1 / 1E-4; // no idea, but assume it's somewhat worse than phi
96  static constexpr float Z0_SCALE = 20; // 1mm is 2 bits
97  static constexpr int32_t VTX_ETA_1p3 = 1.3 * InputTrack::VTX_ETA_SCALE;
98 
99  // filling from floating point
100  void fillInput(
101  float pt, float eta, float phi, int charge, float dz, unsigned int flags, const l1t::PFTrack *source = nullptr) {
102  hwInvpt = std::min<double>(round(1 / pt * InputTrack::INVPT_SCALE), std::numeric_limits<uint16_t>::max());
103  hwVtxEta = round(eta * InputTrack::VTX_ETA_SCALE);
104  hwVtxPhi = round(phi * InputTrack::VTX_PHI_SCALE);
105  hwCharge = (charge > 0);
106  hwZ0 = round(dz * InputTrack::Z0_SCALE);
107  hwFlags = flags;
108  src = source;
109  }
110 
111  float floatVtxPt() const { return 1 / (float(hwInvpt) / InputTrack::INVPT_SCALE); }
112  float floatVtxEta() const { return float(hwVtxEta) / InputTrack::VTX_ETA_SCALE; }
113  float floatVtxPhi() const { return float(hwVtxPhi) / InputTrack::VTX_PHI_SCALE; }
114  float floatDZ() const { return float(hwZ0) / InputTrack::Z0_SCALE; }
115  int intCharge() const { return hwCharge ? +1 : -1; }
116 #endif
117  };
118 
119  struct PropagatedTrack : public InputTrack {
120  int16_t hwPt;
121  int16_t hwPtErr;
122  int16_t hwCaloPtErr;
123  int16_t hwEta; // at calo
124  int16_t hwPhi; // at calo
125  bool muonLink;
126  bool used; // note: this flag is not used in the default PF, but is used in alternative algos
127  bool fromPV;
128 
129  // sorting
130  bool operator<(const PropagatedTrack &other) const { return hwPt > other.hwPt; }
131 
132 #ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE
133  void fillPropagated(
134  float pt, float ptErr, float caloPtErr, float caloEta, float caloPhi, unsigned int quality, bool isMuon) {
135  hwPt = CaloCluster::ptToInt16(pt);
136  hwPtErr = CaloCluster::ptToInt16(ptErr);
137  hwCaloPtErr = CaloCluster::ptToInt16(caloPtErr);
138  // saturation protection
140  hwCaloPtErr = hwPt / 4;
141  }
142  hwEta = round(caloEta * CaloCluster::ETAPHI_SCALE);
143  hwPhi = int16_t(round(caloPhi * CaloCluster::ETAPHI_SCALE)) % CaloCluster::PHI_WRAP;
144  muonLink = isMuon;
145  used = false;
146  }
147 
148  float floatPt() const { return float(hwPt) / CaloCluster::PT_SCALE; }
149  float floatPtErr() const { return float(hwPtErr) / CaloCluster::PT_SCALE; }
150  float floatCaloPtErr() const { return float(hwCaloPtErr) / CaloCluster::PT_SCALE; }
151  float floatEta() const { return float(hwEta) / CaloCluster::ETAPHI_SCALE; }
152  float floatPhi() const { return float(hwPhi) / CaloCluster::ETAPHI_SCALE; }
153 #endif
154  };
155 
156  struct Muon {
157  int16_t hwPt;
158  int16_t hwEta; // at calo
159  int16_t hwPhi; // at calo
160  uint16_t hwFlags;
161  bool hwCharge;
162  const l1t::Muon *src;
163 
164  // sorting
165  bool operator<(const Muon &other) const { return hwPt > other.hwPt; }
166 
167 #ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE
168  void fill(float pt, float eta, float phi, int charge, unsigned int flags, const l1t::Muon *source = nullptr) {
169  // we assume we use the same discrete ieta, iphi grid for all particles
170  hwPt = round(pt * CaloCluster::PT_SCALE);
171  hwEta = round(eta * CaloCluster::ETAPHI_SCALE);
172  hwPhi = int16_t(round(phi * CaloCluster::ETAPHI_SCALE)) % CaloCluster::PHI_WRAP;
173  hwCharge = (charge > 0);
174  hwFlags = flags;
175  src = source;
176  }
177  float floatPt() const { return float(hwPt) / CaloCluster::PT_SCALE; }
178  float floatEta() const { return float(hwEta) / CaloCluster::ETAPHI_SCALE; }
179  float floatPhi() const { return float(hwPhi) / CaloCluster::ETAPHI_SCALE; }
180  int intCharge() const { return hwCharge ? +1 : -1; }
181 #endif
182  };
183 
184  struct PFParticle {
185  int16_t hwPt;
186  int16_t hwEta; // at calo face
187  int16_t hwPhi;
188  uint8_t hwId; // CH=0, EL=1, NH=2, GAMMA=3, MU=4
189  int16_t hwVtxEta; // propagate back to Vtx for charged particles (if useful?)
190  int16_t hwVtxPhi;
191  uint16_t hwFlags;
194  bool chargedPV;
195  uint16_t hwPuppiWeight;
196  uint16_t hwStatus; // for debugging
199 
200  // sorting
201  bool operator<(const PFParticle &other) const { return hwPt > other.hwPt; }
202 
203 #ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE
204  static constexpr float PUPPI_SCALE = 100;
205 
206  float floatPt() const { return float(hwPt) / CaloCluster::PT_SCALE; }
207  float floatEta() const { return float(hwEta) / CaloCluster::ETAPHI_SCALE; }
208  float floatPhi() const { return float(hwPhi) / CaloCluster::ETAPHI_SCALE; }
209  float floatVtxEta() const {
210  return (track.hwPt > 0 ? track.floatVtxEta() : float(hwVtxEta) / CaloCluster::ETAPHI_SCALE);
211  }
212  float floatVtxPhi() const {
213  return (track.hwPt > 0 ? track.floatVtxPhi() : float(hwVtxPhi) / CaloCluster::ETAPHI_SCALE);
214  }
215  float floatDZ() const { return float(track.hwZ0) / InputTrack::Z0_SCALE; }
216  float floatPuppiW() const { return float(hwPuppiWeight) / PUPPI_SCALE; }
217  int intCharge() const { return (track.hwPt > 0 ? track.intCharge() : 0); }
218  void setPuppiW(float w) { hwPuppiWeight = std::round(w * PUPPI_SCALE); }
219  void setFloatPt(float pt) { hwPt = round(pt * CaloCluster::PT_SCALE); }
220 #endif
221  };
222 
223  struct InputRegion {
226  std::vector<CaloCluster> calo;
227  std::vector<CaloCluster> emcalo;
228  std::vector<PropagatedTrack> track;
229  std::vector<Muon> muon;
230 
232  : etaCenter(),
233  etaMin(),
234  etaMax(),
235  phiCenter(),
236  phiHalfWidth(),
237  etaExtra(),
238  phiExtra(),
239  calo(),
240  emcalo(),
241  track(),
242  muon() {}
244  float etacenter, float etamin, float etamax, float phicenter, float phihalfwidth, float etaextra, float phiextra)
245  : etaCenter(etacenter),
246  etaMin(etamin),
247  etaMax(etamax),
248  phiCenter(phicenter),
249  phiHalfWidth(phihalfwidth),
250  etaExtra(etaextra),
251  phiExtra(phiextra),
252  calo(),
253  emcalo(),
254  track(),
255  muon() {}
256  };
257 
258 } // namespace l1tpf_impl
259 #endif
bool isMuon(const Candidate &part)
Definition: pdgIdUtils.h:9
float floatPt(pt_intern pt)
T w() const
bool operator<(const CaloCluster &other) const
const l1t::Muon * src
delete x;
Definition: CaloConfig.h:22
std::vector< CaloCluster > calo
bool operator<(const PropagatedTrack &other) const
std::vector< Muon > muon
Definition: Muon.py:1
const l1t::PFTrack * src
float floatEta(glbeta_intern eta)
#define M_PI
Definition: Muon.h:21
float floatPhi(glbphi_intern phi)
InputRegion(float etacenter, float etamin, float etamax, float phicenter, float phihalfwidth, float etaextra, float phiextra)
std::vector< PropagatedTrack > track
std::vector< CaloCluster > emcalo
bool operator<(const PFParticle &other) const
const l1t::Muon * muonsrc
bool operator<(const Muon &other) const
string quality
static std::string const source
Definition: EdmProvDump.cc:46
const l1t::PFCandidate * src
const l1t::PFCluster * src
Definition: Common.h:9