File indexing completed on 2024-04-06 12:04:36
0001 #include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h"
0002 #include <cmath>
0003 #include <iostream>
0004 #include <cstdlib>
0005 #include <algorithm>
0006
0007 #ifdef CMSSW_GIT_HASH
0008 #include "DataFormats/Math/interface/deltaPhi.h"
0009 #else
0010 namespace reco {
0011 template <typename T>
0012 inline T reduceRange(T x) {
0013 T o2pi = 1. / (2. * M_PI);
0014 if (std::abs(x) <= T(M_PI))
0015 return x;
0016 T n = std::round(x * o2pi);
0017 return x - n * T(2. * M_PI);
0018 }
0019 inline double deltaPhi(double phi1, double phi2) { return reduceRange(phi1 - phi2); }
0020 }
0021 #endif
0022
0023 bool l1ct::HadCaloObjEmu::read(std::fstream& from) {
0024 src = nullptr;
0025 return readObj<HadCaloObj>(from, *this);
0026 }
0027 bool l1ct::HadCaloObjEmu::write(std::fstream& to) const { return writeObj<HadCaloObj>(*this, to); }
0028
0029 bool l1ct::EmCaloObjEmu::read(std::fstream& from) {
0030 src = nullptr;
0031 return readObj<EmCaloObj>(from, *this);
0032 }
0033 bool l1ct::EmCaloObjEmu::write(std::fstream& to) const { return writeObj<EmCaloObj>(*this, to); }
0034
0035 bool l1ct::TkObjEmu::read(std::fstream& from) {
0036 src = nullptr;
0037 return readObj<TkObj>(from, *this) && readVar(from, hwChi2) && readVar(from, simPt) && readVar(from, simCaloEta) &&
0038 readVar(from, simCaloPhi) && readVar(from, simVtxEta) && readVar(from, simVtxPhi) && readVar(from, simZ0) &&
0039 readVar(from, simD0);
0040 }
0041 bool l1ct::TkObjEmu::write(std::fstream& to) const {
0042 return writeObj<TkObj>(*this, to) && writeVar(hwChi2, to) && writeVar(simPt, to) && writeVar(simCaloEta, to) &&
0043 writeVar(simCaloPhi, to) && writeVar(simVtxEta, to) && writeVar(simVtxPhi, to) && writeVar(simZ0, to) &&
0044 writeVar(simD0, to);
0045 }
0046
0047 bool l1ct::MuObjEmu::read(std::fstream& from) {
0048 src = nullptr;
0049 return readObj<MuObj>(from, *this);
0050 }
0051 bool l1ct::MuObjEmu::write(std::fstream& to) const { return writeObj<MuObj>(*this, to); }
0052
0053 bool l1ct::PFChargedObjEmu::read(std::fstream& from) {
0054 srcTrack = nullptr;
0055 srcCluster = nullptr;
0056 srcMu = nullptr;
0057 srcCand = nullptr;
0058 return readObj<PFChargedObj>(from, *this);
0059 }
0060 bool l1ct::PFChargedObjEmu::write(std::fstream& to) const { return writeObj<PFChargedObj>(*this, to); }
0061
0062 bool l1ct::PFNeutralObjEmu::read(std::fstream& from) {
0063 srcCluster = nullptr;
0064 srcCand = nullptr;
0065 return readObj<PFNeutralObj>(from, *this);
0066 }
0067 bool l1ct::PFNeutralObjEmu::write(std::fstream& to) const { return writeObj<PFNeutralObj>(*this, to); }
0068
0069 bool l1ct::PuppiObjEmu::read(std::fstream& from) {
0070 srcTrack = nullptr;
0071 srcCluster = nullptr;
0072 srcMu = nullptr;
0073 srcCand = nullptr;
0074 return readObj<PuppiObj>(from, *this);
0075 }
0076 bool l1ct::PuppiObjEmu::write(std::fstream& to) const { return writeObj<PuppiObj>(*this, to); }
0077
0078 bool l1ct::EGIsoObjEmu::read(std::fstream& from) {
0079 srcCluster = nullptr;
0080 src_idx = -1;
0081 clearIsoVars();
0082 return readObj<EGIsoObj>(from, *this);
0083 }
0084
0085 bool l1ct::EGIsoObjEmu::write(std::fstream& to) const { return writeObj<EGIsoObj>(*this, to); }
0086
0087 bool l1ct::EGIsoEleObjEmu::read(std::fstream& from) {
0088 srcCluster = nullptr;
0089 srcTrack = nullptr;
0090 src_idx = -1;
0091 clearIsoVars();
0092 return readObj<EGIsoEleObj>(from, *this);
0093 }
0094
0095 bool l1ct::EGIsoEleObjEmu::write(std::fstream& to) const { return writeObj<EGIsoEleObj>(*this, to); }
0096
0097 l1ct::PFRegionEmu::PFRegionEmu(float etaCenter, float phicenter) {
0098 hwEtaCenter = Scales::makeGlbEta(etaCenter);
0099 hwPhiCenter = Scales::makeGlbPhi(phicenter);
0100 hwEtaHalfWidth = 0;
0101 hwPhiHalfWidth = 0;
0102 hwEtaExtra = 0;
0103 hwPhiExtra = 0;
0104 }
0105 l1ct::PFRegionEmu::PFRegionEmu(
0106 float etamin, float etamax, float phicenter, float phiwidth, float etaextra, float phiextra) {
0107 glbeta_t hwEtaMin = Scales::makeGlbEtaRoundEven(etamin);
0108 glbeta_t hwEtaMax = Scales::makeGlbEtaRoundEven(etamax);
0109
0110 hwEtaCenter = glbeta_t((hwEtaMin + hwEtaMax) / 2);
0111 hwPhiCenter = Scales::makeGlbPhi(phicenter);
0112 hwEtaHalfWidth = hwEtaCenter - hwEtaMin;
0113 hwPhiHalfWidth = Scales::makeGlbPhi(0.5 * phiwidth);
0114 hwEtaExtra = Scales::makeGlbEta(etaextra);
0115 hwPhiExtra = Scales::makeGlbPhi(phiextra);
0116 }
0117
0118 bool l1ct::PFRegionEmu::contains(float eta, float phi) const {
0119 float dphi = reco::deltaPhi(phi, floatPhiCenter());
0120 return (floatEtaMinExtra() <= eta && eta <= floatEtaMaxExtra() && -floatPhiHalfWidthExtra() <= dphi &&
0121 dphi <= floatPhiHalfWidthExtra());
0122 }
0123 bool l1ct::PFRegionEmu::containsHw(glbeta_t glbeta, glbphi_t glbphi) const {
0124 glbeta_t loceta = glbeta - hwEtaCenter;
0125 ap_int<glbphi_t::width + 1> locphi = glbphi - hwPhiCenter;
0126 if (locphi > Scales::INTPHI_PI)
0127 locphi -= Scales::INTPHI_TWOPI;
0128 else if (locphi <= -Scales::INTPHI_PI)
0129 locphi += Scales::INTPHI_TWOPI;
0130 return isInside(loceta, locphi);
0131 }
0132
0133 float l1ct::PFRegionEmu::localEta(float globalEta) const { return globalEta - floatEtaCenter(); }
0134 float l1ct::PFRegionEmu::localPhi(float globalPhi) const { return reco::deltaPhi(globalPhi, floatPhiCenter()); }
0135
0136 bool l1ct::PFRegionEmu::read(std::fstream& from) { return readObj<PFRegion>(from, *this); }
0137 bool l1ct::PFRegionEmu::write(std::fstream& to) const { return writeObj<PFRegion>(*this, to); }
0138
0139 bool l1ct::PVObjEmu::read(std::fstream& from) { return readObj<PVObj>(from, *this); }
0140 bool l1ct::PVObjEmu::write(std::fstream& to) const { return writeObj<PVObj>(*this, to); }
0141
0142 bool l1ct::RawInputs::read(std::fstream& from) {
0143 uint32_t number;
0144
0145 if (!readVar(from, number))
0146 return false;
0147 track.resize(number);
0148 for (auto& v : track) {
0149 if (!(v.region.read(from) && readMany(from, v.obj)))
0150 return false;
0151 }
0152
0153 if (!(muon.region.read(from) && readMany(from, muon.obj)))
0154 return false;
0155
0156 if (!readVar(from, number))
0157 return false;
0158 hgcalcluster.resize(number);
0159 for (auto& v : hgcalcluster) {
0160 if (!(v.region.read(from) && readMany(from, v.obj)))
0161 return false;
0162 }
0163
0164 return true;
0165 }
0166
0167 bool l1ct::RawInputs::write(std::fstream& to) const {
0168 uint32_t number;
0169
0170 number = track.size();
0171 if (!writeVar(number, to))
0172 return false;
0173 for (const auto& v : track) {
0174 if (!(v.region.write(to) && writeMany(v.obj, to)))
0175 return false;
0176 }
0177
0178 if (!(muon.region.write(to) && writeMany(muon.obj, to)))
0179 return false;
0180
0181 number = hgcalcluster.size();
0182 if (!writeVar(number, to))
0183 return false;
0184 for (const auto& v : hgcalcluster) {
0185 if (!(v.region.write(to) && writeMany(v.obj, to)))
0186 return false;
0187 }
0188
0189 return true;
0190 }
0191 void l1ct::RawInputs::clear() {
0192 for (auto& r : track)
0193 r.clear();
0194 muon.clear();
0195 for (auto& h : hgcalcluster)
0196 h.clear();
0197 }
0198
0199 bool l1ct::RegionizerDecodedInputs::read(std::fstream& from) {
0200 uint32_t number;
0201
0202 if (!readVar(from, number))
0203 return false;
0204 hadcalo.resize(number);
0205 for (auto& v : hadcalo) {
0206 if (!(v.region.read(from) && readMany(from, v.obj)))
0207 return false;
0208 }
0209
0210 if (!readVar(from, number))
0211 return false;
0212 emcalo.resize(number);
0213 for (auto& v : emcalo) {
0214 if (!(v.region.read(from) && readMany(from, v.obj)))
0215 return false;
0216 }
0217
0218 if (!readVar(from, number))
0219 return false;
0220 track.resize(number);
0221 for (auto& v : track) {
0222 if (!(v.region.read(from) && readMany(from, v.obj)))
0223 return false;
0224 }
0225
0226 if (!(muon.region.read(from) && readMany(from, muon.obj)))
0227 return false;
0228
0229 return true;
0230 }
0231
0232 bool l1ct::RegionizerDecodedInputs::write(std::fstream& to) const {
0233 uint32_t number;
0234
0235 number = hadcalo.size();
0236 if (!writeVar(number, to))
0237 return false;
0238 for (const auto& v : hadcalo) {
0239 if (!(v.region.write(to) && writeMany(v.obj, to)))
0240 return false;
0241 }
0242
0243 number = emcalo.size();
0244 if (!writeVar(number, to))
0245 return false;
0246 for (const auto& v : emcalo) {
0247 if (!(v.region.write(to) && writeMany(v.obj, to)))
0248 return false;
0249 }
0250
0251 number = track.size();
0252 if (!writeVar(number, to))
0253 return false;
0254 for (const auto& v : track) {
0255 if (!(v.region.write(to) && writeMany(v.obj, to)))
0256 return false;
0257 }
0258
0259 if (!(muon.region.write(to) && writeMany(muon.obj, to)))
0260 return false;
0261
0262 return true;
0263 }
0264 void l1ct::RegionizerDecodedInputs::clear() {
0265 for (auto& r : hadcalo)
0266 r.clear();
0267 for (auto& r : emcalo)
0268 r.clear();
0269 for (auto& r : track)
0270 r.clear();
0271 muon.clear();
0272 }
0273
0274 bool l1ct::PFInputRegion::read(std::fstream& from) {
0275 return region.read(from) && readMany(from, hadcalo) && readMany(from, emcalo) && readMany(from, track) &&
0276 readMany(from, muon);
0277 }
0278 bool l1ct::PFInputRegion::write(std::fstream& to) const {
0279 return region.write(to) && writeMany(hadcalo, to) && writeMany(emcalo, to) && writeMany(track, to) &&
0280 writeMany(muon, to);
0281 }
0282 void l1ct::PFInputRegion::clear() {
0283 hadcalo.clear();
0284 emcalo.clear();
0285 track.clear();
0286 muon.clear();
0287 }
0288
0289 bool l1ct::OutputRegion::read(std::fstream& from) {
0290 return readMany(from, pfcharged) && readMany(from, pfneutral) && readMany(from, pfphoton) && readMany(from, pfmuon) &&
0291 readMany(from, puppi) && readMany(from, egphoton) && readMany(from, egelectron);
0292 }
0293 bool l1ct::OutputRegion::write(std::fstream& to) const {
0294 return writeMany(pfcharged, to) && writeMany(pfneutral, to) && writeMany(pfphoton, to) && writeMany(pfmuon, to) &&
0295 writeMany(puppi, to) && writeMany(egphoton, to) && writeMany(egelectron, to);
0296 }
0297
0298 void l1ct::OutputRegion::clear() {
0299 pfcharged.clear();
0300 pfphoton.clear();
0301 pfneutral.clear();
0302 pfmuon.clear();
0303 puppi.clear();
0304 egsta.clear();
0305 egphoton.clear();
0306 egelectron.clear();
0307 }
0308
0309
0310 namespace {
0311 template <typename TV>
0312 unsigned int count_nonnull(const TV& v) {
0313 typedef typename TV::value_type T;
0314 return std::count_if(v.begin(), v.end(), [](const T& p) { return p.hwPt > 0; });
0315 }
0316 template <typename TV, typename F>
0317 unsigned int count_nonnull_if(const TV& v, F pred) {
0318 unsigned int n = 0;
0319 for (auto& p : v) {
0320 if (p.hwPt > 0 && pred(p.hwId))
0321 ++n;
0322 }
0323 return n;
0324 }
0325 }
0326
0327 unsigned int l1ct::OutputRegion::nObj(ObjType type, bool usePuppi) const {
0328 switch (type) {
0329 case anyType:
0330 if (usePuppi)
0331 return ::count_nonnull(puppi);
0332 else
0333 return ::count_nonnull(pfcharged) + ::count_nonnull(pfphoton) + ::count_nonnull(pfneutral);
0334 case chargedType:
0335 if (usePuppi)
0336 return ::count_nonnull_if(puppi, [](const l1ct::ParticleID& i) { return i.charged(); });
0337 else
0338 return ::count_nonnull(pfcharged);
0339 case neutralType:
0340 if (usePuppi)
0341 return ::count_nonnull_if(puppi, [](const l1ct::ParticleID& i) { return i.neutral(); });
0342 else
0343 return ::count_nonnull(pfphoton) + ::count_nonnull(pfneutral);
0344 case electronType:
0345 if (usePuppi)
0346 return ::count_nonnull_if(puppi, [](const l1ct::ParticleID& i) { return i.isElectron(); });
0347 else
0348 return ::count_nonnull_if(pfcharged, [](const l1ct::ParticleID& i) { return i.isElectron(); });
0349 case muonType:
0350 if (usePuppi)
0351 return ::count_nonnull_if(puppi, [](const l1ct::ParticleID& i) { return i.isMuon(); });
0352 else
0353 return ::count_nonnull_if(pfcharged, [](const l1ct::ParticleID& i) { return i.isMuon(); });
0354 case chargedHadronType:
0355 if (usePuppi)
0356 return ::count_nonnull_if(puppi, [](const l1ct::ParticleID& i) { return i.isChargedHadron(); });
0357 else
0358 return ::count_nonnull_if(pfcharged, [](const l1ct::ParticleID& i) { return i.isChargedHadron(); });
0359 case neutralHadronType:
0360 if (usePuppi)
0361 return ::count_nonnull_if(puppi,
0362 [](const l1ct::ParticleID& i) { return i.rawId() == l1ct::ParticleID::HADZERO; });
0363 else
0364 return ::count_nonnull_if(pfneutral,
0365 [](const l1ct::ParticleID& i) { return i.rawId() == l1ct::ParticleID::HADZERO; });
0366 case photonType:
0367 if (usePuppi)
0368 return ::count_nonnull_if(puppi,
0369 [](const l1ct::ParticleID& i) { return i.rawId() == l1ct::ParticleID::PHOTON; });
0370 else
0371 return ::count_nonnull_if(pfneutral,
0372 [](const l1ct::ParticleID& i) { return i.rawId() == l1ct::ParticleID::PHOTON; }) +
0373 ::count_nonnull_if(pfphoton,
0374 [](const l1ct::ParticleID& i) { return i.rawId() == l1ct::ParticleID::PHOTON; });
0375 case egisoType:
0376 assert(!usePuppi);
0377 return ::count_nonnull(egphoton);
0378 case egisoeleType:
0379 assert(!usePuppi);
0380 return ::count_nonnull(egelectron);
0381 default:
0382 assert(false);
0383 }
0384 }
0385
0386 bool l1ct::OutputBoard::read(std::fstream& from) {
0387 return readVar(from, eta) && readVar(from, phi) && readMany(from, egphoton) && readMany(from, egelectron);
0388 }
0389 bool l1ct::OutputBoard::write(std::fstream& to) const {
0390 return writeVar(eta, to) && writeVar(phi, to) && writeMany(egphoton, to) && writeMany(egelectron, to);
0391 }
0392
0393 void l1ct::OutputBoard::clear() {
0394 egphoton.clear();
0395 egelectron.clear();
0396 }
0397
0398 bool l1ct::Event::read(std::fstream& from) {
0399 uint32_t version;
0400 if (!readVar(from, version))
0401 return false;
0402 if (version != VERSION) {
0403
0404
0405
0406
0407 abort();
0408 }
0409 return readVar(from, run) && readVar(from, lumi) && readVar(from, event) && raw.read(from) && decoded.read(from) &&
0410 readMany(from, pfinputs) && readMany(from, pvs) && readMany(from, pvs_emu) && readMany(from, out) &&
0411 readMany(from, board_out);
0412 }
0413 bool l1ct::Event::write(std::fstream& to) const {
0414 uint32_t version = VERSION;
0415 return writeVar(version, to) && writeVar(run, to) && writeVar(lumi, to) && writeVar(event, to) && raw.write(to) &&
0416 decoded.write(to) && writeMany(pfinputs, to) && writeMany(pvs, to) && writeMany(pvs_emu, to) &&
0417 writeMany(out, to) && writeMany(board_out, to);
0418 }
0419 void l1ct::Event::init(uint32_t arun, uint32_t alumi, uint64_t anevent) {
0420 clear();
0421 run = arun;
0422 lumi = alumi;
0423 event = anevent;
0424 }
0425 void l1ct::Event::clear() {
0426 run = 0;
0427 lumi = 0;
0428 event = 0;
0429 raw.clear();
0430 decoded.clear();
0431 for (auto& i : pfinputs)
0432 i.clear();
0433 pvs.clear();
0434 pvs_emu.clear();
0435 for (auto& i : out)
0436 i.clear();
0437 for (auto& i : board_out)
0438 i.clear();
0439 }