diff --git a/DataFormats/ForwardDetId/interface/ForwardSubdetector.h b/DataFormats/ForwardDetId/interface/ForwardSubdetector.h index 38714ef1f944c..2d7421d1f5528 100644 --- a/DataFormats/ForwardDetId/interface/ForwardSubdetector.h +++ b/DataFormats/ForwardDetId/interface/ForwardSubdetector.h @@ -11,6 +11,6 @@ enum ForwardSubdetector { HFNose = 6, HGCTrigger = 7 }; -enum HGCalTriggerSubdetector { HGCalEmptyTrigger = 0, HGCalEETrigger = 1, HGCalHSiTrigger = 2, HGCalHScTrigger = 3 }; +enum HGCalTriggerSubdetector { HFNoseTrigger = 0, HGCalEETrigger = 1, HGCalHSiTrigger = 2, HGCalHScTrigger = 3 }; #endif diff --git a/DataFormats/ForwardDetId/interface/HFNoseDetId.h b/DataFormats/ForwardDetId/interface/HFNoseDetId.h index 6e14e6ccea300..877506b142244 100644 --- a/DataFormats/ForwardDetId/interface/HFNoseDetId.h +++ b/DataFormats/ForwardDetId/interface/HFNoseDetId.h @@ -81,6 +81,23 @@ class HFNoseDetId : public DetId { int waferY() const { return (2 * waferV()); } std::pair waferXY() const { return std::pair(waferX(), waferY()); } + // get trigger cell u,v + int triggerCellU() const { + int N = (type() == HFNoseFine) ? HFNoseFineN : HFNoseCoarseN; + int NT = (type() == HFNoseFine) ? HFNoseFineTrigger : HFNoseCoarseTrigger; + return (cellU() >= N && cellV() >= N) + ? cellU() / NT + : ((cellU() < N && cellU() <= cellV()) ? cellU() / NT : (1 + (cellU() - (cellV() % NT + 1)) / NT)); + } + int triggerCellV() const { + int N = (type() == HFNoseFine) ? HFNoseFineN : HFNoseCoarseN; + int NT = (type() == HFNoseFine) ? HFNoseFineTrigger : HFNoseCoarseTrigger; + return (cellU() >= N && cellV() >= N) + ? cellV() / NT + : ((cellU() < N && cellU() <= cellV()) ? ((cellV() - cellU()) / NT + cellU() / NT) : cellV() / NT); + } + std::pair triggerCellUV() const { return std::pair(triggerCellU(), triggerCellV()); } + /// consistency check : no bits left => no overhead bool isEE() const { return (layer() <= kHFNoseLayerEEmax); } bool isHE() const { return (layer() > kHFNoseLayerEEmax); } diff --git a/DataFormats/ForwardDetId/interface/HFNoseTriggerDetId.h b/DataFormats/ForwardDetId/interface/HFNoseTriggerDetId.h new file mode 100644 index 0000000000000..e6a2d819ff1d4 --- /dev/null +++ b/DataFormats/ForwardDetId/interface/HFNoseTriggerDetId.h @@ -0,0 +1,113 @@ +#ifndef DataFormats_ForwardDetId_HFNoseTriggerDetId_H +#define DataFormats_ForwardDetId_HFNoseTriggerDetId_H 1 + +#include +#include +#include "DataFormats/DetId/interface/DetId.h" +#include "DataFormats/ForwardDetId/interface/ForwardSubdetector.h" + +/* \brief description of the bit assigment + [0:3] u-coordinate of the cell (measured from the lower left + [4:7] v-coordinate of the cell corner of the wafer) + [8:11] abs(u) of the wafer (u-axis points along -x axis) + [12:12] sign of u (0:+u; 1:-u) (u=0 is at the center of beam line) + [13:16] abs(v) of the wafer (v-axis points 60-degree wrt x-axis) + [17:17] sign of v (0:+v; 1:-v) (v=0 is at the center of beam line) + [18:22] layer number + [23:24] Type (0 fine divisions of wafer with 120 mum thick silicon + 1 coarse divisions of wafer with 200 mum thick silicon + 2 coarse divisions of wafer with 300 mum thick silicon) + [25:26] Subdetector Type (HFNoseTrigger) + [27:27] z-side (0 for +z; 1 for -z) + [28:31] Detector type (HGCalTrigger) +*/ + +class HFNoseTriggerDetId : public DetId { +public: + static const int HFNoseTriggerCell = 4; + + /** Create a null cellid*/ + HFNoseTriggerDetId(); + /** Create cellid from raw id (0=invalid tower id) */ + HFNoseTriggerDetId(uint32_t rawid); + /** Constructor from subdetector, zplus, layer, module, cell numbers */ + HFNoseTriggerDetId(int subdet, int zp, int type, int layer, int waferU, int waferV, int cellU, int cellV); + /** Constructor from a generic cell id */ + HFNoseTriggerDetId(const DetId& id); + /** Assignment from a generic cell id */ + HFNoseTriggerDetId& operator=(const DetId& id); + + /// get the subdetector + HGCalTriggerSubdetector subdet() const { + return (HGCalTriggerSubdetector)((id_ >> kHFNoseSubdetOffset) & kHFNoseSubdetMask); + } + + /// get the type + int type() const { return (id_ >> kHFNoseTypeOffset) & kHFNoseTypeMask; } + + /// get the z-side of the cell (1/-1) + int zside() const { return (((id_ >> kHFNoseZsideOffset) & kHFNoseZsideMask) ? -1 : 1); } + + /// get the layer # + int layer() const { return (id_ >> kHFNoseLayerOffset) & kHFNoseLayerMask; } + + /// get the cell #'s in u,v or in x,y + int triggerCellU() const { return (id_ >> kHFNoseCellUOffset) & kHFNoseCellUMask; } + int triggerCellV() const { return (id_ >> kHFNoseCellVOffset) & kHFNoseCellVMask; } + std::pair triggerCellUV() const { return std::pair(triggerCellU(), triggerCellV()); } + int triggerCellX() const; + int triggerCellY() const; + std::pair triggerCellXY() const { return std::pair(triggerCellX(), triggerCellY()); } + + /// get the wafer #'s in u,v or in x,y + int waferUAbs() const { return (id_ >> kHFNoseWaferUOffset) & kHFNoseWaferUMask; } + int waferVAbs() const { return (id_ >> kHFNoseWaferVOffset) & kHFNoseWaferVMask; } + int waferU() const { + return (((id_ >> kHFNoseWaferUSignOffset) & kHFNoseWaferUSignMask) ? -waferUAbs() : waferUAbs()); + } + int waferV() const { + return (((id_ >> kHFNoseWaferVSignOffset) & kHFNoseWaferVSignMask) ? -waferVAbs() : waferVAbs()); + } + std::pair waferUV() const { return std::pair(waferU(), waferV()); } + int waferX() const { return (-2 * waferU() + waferV()); } + int waferY() const { return (2 * waferV()); } + std::pair waferXY() const { return std::pair(waferX(), waferY()); } + + // get trigger cell u,v + std::vector cellU() const; + std::vector cellV() const; + std::vector > cellUV() const; + + /// consistency check : no bits left => no overhead + bool isEE() const { return (layer() <= kHFNoseMaxEELayer); } + bool isHSilicon() const { return (layer() > kHFNoseMaxEELayer); } + bool isForward() const { return true; } + + static const HFNoseTriggerDetId Undefined; + + static const int kHFNoseCellUOffset = 0; + static const int kHFNoseCellUMask = 0xF; + static const int kHFNoseCellVOffset = 4; + static const int kHFNoseCellVMask = 0xF; + static const int kHFNoseWaferUOffset = 8; + static const int kHFNoseWaferUMask = 0xF; + static const int kHFNoseWaferUSignOffset = 12; + static const int kHFNoseWaferUSignMask = 0x1; + static const int kHFNoseWaferVOffset = 13; + static const int kHFNoseWaferVMask = 0xF; + static const int kHFNoseWaferVSignOffset = 17; + static const int kHFNoseWaferVSignMask = 0x1; + static const int kHFNoseLayerOffset = 18; + static const int kHFNoseLayerMask = 0x1F; + static const int kHFNoseTypeOffset = 23; + static const int kHFNoseTypeMask = 0x3; + static const int kHFNoseZsideOffset = 27; + static const int kHFNoseZsideMask = 0x1; + static const int kHFNoseSubdetOffset = 25; + static const int kHFNoseSubdetMask = 0x3; + static const int kHFNoseMaxEELayer = 6; +}; + +std::ostream& operator<<(std::ostream&, const HFNoseTriggerDetId& id); + +#endif diff --git a/DataFormats/ForwardDetId/src/HFNoseTriggerDetId.cc b/DataFormats/ForwardDetId/src/HFNoseTriggerDetId.cc new file mode 100644 index 0000000000000..24cada2914e6d --- /dev/null +++ b/DataFormats/ForwardDetId/src/HFNoseTriggerDetId.cc @@ -0,0 +1,147 @@ +#include "DataFormats/ForwardDetId/interface/HFNoseTriggerDetId.h" +#include "DataFormats/ForwardDetId/interface/HFNoseDetId.h" +#include "FWCore/Utilities/interface/Exception.h" +#include +#include + +const HFNoseTriggerDetId HFNoseTriggerDetId::Undefined(HFNoseTrigger, 0, 0, 0, 0, 0, 0, 0); + +HFNoseTriggerDetId::HFNoseTriggerDetId() : DetId() {} + +HFNoseTriggerDetId::HFNoseTriggerDetId(uint32_t rawid) : DetId(rawid) {} + +HFNoseTriggerDetId::HFNoseTriggerDetId( + int subdet, int zp, int type, int layer, int waferU, int waferV, int cellU, int cellV) + : DetId(HGCalTrigger, ForwardEmpty) { + int waferUabs(std::abs(waferU)), waferVabs(std::abs(waferV)); + int waferUsign = (waferU >= 0) ? 0 : 1; + int waferVsign = (waferV >= 0) ? 0 : 1; + int zside = (zp < 0) ? 1 : 0; + id_ |= (((cellU & kHFNoseCellUMask) << kHFNoseCellUOffset) | ((cellV & kHFNoseCellVMask) << kHFNoseCellVOffset) | + ((waferUabs & kHFNoseWaferUMask) << kHFNoseWaferUOffset) | + ((waferUsign & kHFNoseWaferUSignMask) << kHFNoseWaferUSignOffset) | + ((waferVabs & kHFNoseWaferVMask) << kHFNoseWaferVOffset) | + ((waferVsign & kHFNoseWaferVSignMask) << kHFNoseWaferVSignOffset) | + ((layer & kHFNoseLayerMask) << kHFNoseLayerOffset) | ((zside & kHFNoseZsideMask) << kHFNoseZsideOffset) | + ((type & kHFNoseTypeMask) << kHFNoseTypeOffset) | ((subdet & kHFNoseSubdetMask) << kHFNoseSubdetOffset)); +} + +HFNoseTriggerDetId::HFNoseTriggerDetId(const DetId& gen) { + if (!gen.null()) { + if ((gen.det() != HGCalTrigger) || ((gen.subdetId() & kHFNoseSubdetMask) != HFNoseTrigger)) { + throw cms::Exception("Invalid DetId") + << "Cannot initialize HFNoseTriggerDetId from " << std::hex << gen.rawId() << std::dec; + } + } + id_ = gen.rawId(); +} + +HFNoseTriggerDetId& HFNoseTriggerDetId::operator=(const DetId& gen) { + if (!gen.null()) { + if ((gen.det() != HGCalTrigger) || ((gen.subdetId() & kHFNoseSubdetMask) != HFNoseTrigger)) { + throw cms::Exception("Invalid DetId") + << "Cannot assign HFNoseTriggerDetId from " << std::hex << gen.rawId() << std::dec; + } + } + id_ = gen.rawId(); + return (*this); +} + +int HFNoseTriggerDetId::triggerCellX() const { + int nT = (type() == HFNoseDetId::HFNoseFine) ? HFNoseDetId::HFNoseFineTrigger : HFNoseDetId::HFNoseCoarseTrigger; + int N = nT * HFNoseTriggerCell; + std::vector vc = cellV(); + int x(0); + for (auto const& v : vc) { + x += (3 * (v - N) + 2); + } + return (x / static_cast(vc.size())); +} + +int HFNoseTriggerDetId::triggerCellY() const { + int nT = (type() == HFNoseDetId::HFNoseFine) ? HFNoseDetId::HFNoseFineTrigger : HFNoseDetId::HFNoseCoarseTrigger; + int N = nT * HFNoseTriggerCell; + std::vector uc = cellU(); + std::vector vc = cellV(); + int y(0); + for (unsigned int k = 0; k < uc.size(); ++k) { + y += (2 * uc[k] - (N + vc[k])); + } + return (y / static_cast(vc.size())); +} + +std::vector HFNoseTriggerDetId::cellU() const { + std::vector uc; + int nT = (type() == HFNoseDetId::HFNoseFine) ? HFNoseDetId::HFNoseFineTrigger : HFNoseDetId::HFNoseCoarseTrigger; + if ((triggerCellU() >= HFNoseTriggerCell) && (triggerCellV() >= HFNoseTriggerCell)) { + int u0 = nT * triggerCellU(); + for (int i = 0; i < nT; ++i) { + for (int j = 0; j < nT; ++j) { + uc.emplace_back(u0 + i); + } + } + } else if ((triggerCellU() < HFNoseTriggerCell) && (triggerCellU() <= triggerCellV())) { + int u0 = nT * triggerCellU(); + for (int i = 0; i < nT; ++i) { + for (int j = 0; j < nT; ++j) { + uc.emplace_back(u0 + i); + } + } + } else { + int u0 = nT * (triggerCellU() - 1) + 1; + for (int i = 0; i < nT; ++i) { + for (int j = 0; j < nT; ++j) { + uc.emplace_back(u0 + j); + } + ++u0; + } + } + return uc; +} + +std::vector HFNoseTriggerDetId::cellV() const { + std::vector vc; + int nT = (type() == HFNoseDetId::HFNoseFine) ? HFNoseDetId::HFNoseFineTrigger : HFNoseDetId::HFNoseCoarseTrigger; + if ((triggerCellU() >= HFNoseTriggerCell) && (triggerCellV() >= HFNoseTriggerCell)) { + int v0 = nT * triggerCellV(); + for (int i = 0; i < nT; ++i) { + for (int j = 0; j < nT; ++j) { + vc.emplace_back(v0 + j); + } + } + } else if ((triggerCellU() < HFNoseTriggerCell) && (triggerCellU() <= triggerCellV())) { + int v0 = nT * triggerCellV(); + for (int i = 0; i < nT; ++i) { + for (int j = 0; j < nT; ++j) { + vc.emplace_back(v0 + j); + } + ++v0; + } + } else { + int v0 = nT * triggerCellV(); + for (int i = 0; i < nT; ++i) { + for (int j = 0; j < nT; ++j) { + vc.emplace_back(v0 + i); + } + } + } + return vc; +} + +std::vector > HFNoseTriggerDetId::cellUV() const { + std::vector uc = cellU(); + std::vector vc = cellV(); + std::vector > uv; + for (unsigned int k = 0; k < uc.size(); ++k) { + uv.emplace_back(uc[k], vc[k]); + } + return uv; +} + +std::ostream& operator<<(std::ostream& s, const HFNoseTriggerDetId& id) { + return s << " EE:HSil= " << id.isEE() << ":" << id.isHSilicon() << " type= " << id.type() << " z= " << id.zside() + << " layer= " << id.layer() << " wafer(u,v:x,y)= (" << id.waferU() << "," << id.waferV() << ":" + << id.waferX() << "," << id.waferY() << ")" + << " triggerCell(u,v:x,y)= (" << id.triggerCellU() << "," << id.triggerCellV() << ":" << id.triggerCellX() + << "," << id.triggerCellY() << ")"; +} diff --git a/DataFormats/ForwardDetId/src/HGCalTriggerDetId.cc b/DataFormats/ForwardDetId/src/HGCalTriggerDetId.cc index 2a0b7b148045d..8cd139019f442 100644 --- a/DataFormats/ForwardDetId/src/HGCalTriggerDetId.cc +++ b/DataFormats/ForwardDetId/src/HGCalTriggerDetId.cc @@ -3,7 +3,7 @@ #include #include -const HGCalTriggerDetId HGCalTriggerDetId::Undefined(HGCalEE, 0, 0, 0, 0, 0, 0, 0); +const HGCalTriggerDetId HGCalTriggerDetId::Undefined(HGCalEETrigger, 0, 0, 0, 0, 0, 0, 0); HGCalTriggerDetId::HGCalTriggerDetId() : DetId() {} diff --git a/DataFormats/ForwardDetId/src/classes.h b/DataFormats/ForwardDetId/src/classes.h index 2b1121f245130..d2ed98aca1ba6 100644 --- a/DataFormats/ForwardDetId/src/classes.h +++ b/DataFormats/ForwardDetId/src/classes.h @@ -10,3 +10,4 @@ #include "DataFormats/ForwardDetId/interface/BTLDetId.h" #include "DataFormats/ForwardDetId/interface/ETLDetId.h" #include "DataFormats/ForwardDetId/interface/HFNoseDetId.h" +#include "DataFormats/ForwardDetId/interface/HFNoseTriggerDetId.h" diff --git a/DataFormats/ForwardDetId/src/classes_def.xml b/DataFormats/ForwardDetId/src/classes_def.xml index c5b98bfe1e295..483a7264a7838 100644 --- a/DataFormats/ForwardDetId/src/classes_def.xml +++ b/DataFormats/ForwardDetId/src/classes_def.xml @@ -36,4 +36,8 @@ + + + + diff --git a/DataFormats/ForwardDetId/test/BuildFile.xml b/DataFormats/ForwardDetId/test/BuildFile.xml index 4c9acbed36459..49dca96c385fb 100644 --- a/DataFormats/ForwardDetId/test/BuildFile.xml +++ b/DataFormats/ForwardDetId/test/BuildFile.xml @@ -1,3 +1,3 @@ - - + + diff --git a/DataFormats/ForwardDetId/test/testHFNoseDetId.cc b/DataFormats/ForwardDetId/test/testHFNoseDetId.cc new file mode 100644 index 0000000000000..1409eda157cb3 --- /dev/null +++ b/DataFormats/ForwardDetId/test/testHFNoseDetId.cc @@ -0,0 +1,147 @@ +#include "DataFormats/ForwardDetId/interface/HFNoseDetId.h" +#include "DataFormats/ForwardDetId/interface/HFNoseTriggerDetId.h" +#include "DataFormats/DetId/interface/DetId.h" + +#include +#include +#include +#include +#include + +void testCell(int type) { + int N = (type == 0) ? HFNoseDetId::HFNoseFineN : HFNoseDetId::HFNoseCoarseN; + const int waferu(0), waferv(0), layer(1), zside(1); + std::map, int> triggers; + int ntot(0); + for (int u = 0; u < 2 * N; ++u) { + for (int v = 0; v < 2 * N; ++v) { + if (((v - u) < N) && (u - v) <= N) { + HFNoseDetId id(zside, type, layer, waferu, waferv, u, v); + std::cout << "ID " << std::hex << id.rawId() << std::dec << " " << id << " Trigger: " << id.triggerCellU() + << ":" << id.triggerCellV() << std::endl; + std::pair trig = id.triggerCellUV(); + std::map, int>::iterator itr = triggers.find(trig); + if (itr == triggers.end()) { + triggers[trig] = 0; + itr = triggers.find(trig); + } + ++(itr->second); + ++ntot; + } + } + } + std::cout << "Total of " << ntot << " cells in type " << type << " with " << triggers.size() << " trigger cells" + << std::endl; + int k(0); + for (auto itr : triggers) { + std::cout << "Trigger[" << k << "] (" << (itr.first).first << ":" << (itr.first).second << ") " << itr.second + << std::endl; + ++k; + } +} + +void testWafer(int layer, double rin, double rout) { + const double waferSize(167.4408); + const double rMaxFine(750.0), rMaxMiddle(1200.0); + const int zside(1), cellu(0), cellv(0); + const std::string waferType[2] = {"Virtual", "Real "}; + double r = 0.5 * waferSize; + double R = 2.0 * r / std::sqrt(3.0); + double dy = 0.75 * R; + double xc[6], yc[6]; + int N = (int)(0.5 * rout / r) + 2; + int nreal(0), nvirtual(0); + int ntype[3] = {0, 0, 0}; + for (int v = -N; v <= N; ++v) { + for (int u = -N; u <= N; ++u) { + int nr = 2 * v; + int nc = -2 * u + v; + double xpos = nc * r; + double ypos = nr * dy; + xc[0] = xpos + r; + yc[0] = ypos + 0.5 * R; + xc[1] = xpos; + yc[1] = ypos + R; + xc[2] = xpos - r; + yc[2] = ypos + 0.5 * R; + xc[3] = xpos - r; + yc[3] = ypos - 0.5 * R; + xc[4] = xpos; + yc[4] = ypos - R; + xc[5] = xpos + r; + yc[5] = ypos - 0.5 * R; + int cornerOne(0), cornerAll(1); + for (int k = 0; k < 6; ++k) { + double rpos = std::sqrt(xc[k] * xc[k] + yc[k] * yc[k]); + if (rpos >= rin && rpos <= rout) + cornerOne = 1; + else + cornerAll = 0; + } + if (cornerOne > 0) { + double rr = std::sqrt(xpos * xpos + ypos * ypos); + int type = (rr < rMaxFine) ? 0 : ((rr < rMaxMiddle) ? 1 : 2); + HFNoseDetId id(zside, type, layer, u, v, cellu, cellv); + std::cout << waferType[cornerAll] << " Wafer " << id << std::endl; + if (cornerAll == 1) { + ++nreal; + ++ntype[type]; + } else { + ++nvirtual; + } + } + } + } + std::cout << nreal << " full wafers of type 0:" << ntype[0] << " 1:" << ntype[1] << " 2:" << ntype[2] << " and " + << nvirtual << " partial wafers for r-range " << rin << ":" << rout << std::endl; +} + +void testTriggerCell(int type) { + int N = (type == 0) ? HFNoseDetId::HFNoseFineN : HFNoseDetId::HFNoseCoarseN; + const int waferu(0), waferv(0), layer(1); + std::string error[2] = {"ERROR", "OK"}; + int ntot(0), nerror(0); + for (int iz = 0; iz <= 1; ++iz) { + int zside = 2 * iz - 1; + for (int u = 0; u < 2 * N; ++u) { + for (int v = 0; v < 2 * N; ++v) { + if (((v - u) < N) && (u - v) <= N) { + HFNoseDetId id(zside, type, layer, waferu, waferv, u, v); + HFNoseTriggerDetId idt((int)(HFNoseTrigger), + id.zside(), + id.type(), + id.layer(), + id.waferU(), + id.waferV(), + id.triggerCellU(), + id.triggerCellV()); + std::cout << "ID " << std::hex << id.rawId() << std::dec << " " << id << " Trigger: " << id.triggerCellU() + << ":" << id.triggerCellV() << " Trigger " << idt << std::endl; + int ok(0); + std::vector > uvs = idt.cellUV(); + for (auto const& uv : uvs) { + HFNoseDetId idn(idt.zside(), idt.type(), idt.layer(), idt.waferU(), idt.waferV(), uv.first, uv.second); + if (idn == id) { + ok = 1; + break; + } + } + std::cout << "Trigger Cell: " << idt << " obtained from cell (" << error[ok] << ")" << std::endl; + ++ntot; + if (ok == 0) + ++nerror; + } + } + } + } + std::cout << "Total of " << ntot << " cells in type " << type << " with " << nerror << " errors for trigger cells" + << std::endl; +} + +int main() { + testCell(0); + testWafer(1, 299.47, 1041.45); + testWafer(8, 312.55, 1086.97); + testTriggerCell(0); + return 0; +}