Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-07-10 02:34:31

0001 #ifndef DataFormats_ForwardDetId_HGCScintillatorDetId_H
0002 #define DataFormats_ForwardDetId_HGCScintillatorDetId_H 1
0003 
0004 #include <iosfwd>
0005 #include <vector>
0006 #include "DataFormats/DetId/interface/DetId.h"
0007 #include "DataFormats/ForwardDetId/interface/ForwardSubdetector.h"
0008 #include "FWCore/Utilities/interface/Exception.h"
0009 
0010 /* \brief description of the bit assigment
0011    [0:8]   iphi index wrt x-axis on +z side
0012    [9:16]  |ring| index (starting from a minimum radius depending on type)
0013    [17:21] Layer #
0014    [22]    Trigger(1)/Detector(0) cell
0015    [23]    SiPM type (0 for Small: 1 for Large)
0016    [24]    Granularity of the tile (0 normal; 1 fine)
0017    [25:25] z-side (0 for +z; 1 for -z)
0018    [26:27] Tile make (1 of type "c"; 2 of type "m")
0019    [28:31] Detector type (HGCalHSc)
0020 */
0021 
0022 class HGCScintillatorDetId : public DetId {
0023 public:
0024   enum tileGranularity { HGCalTileNormal = 0, HGCalTileFine = 1 };
0025   enum sipmType { HGCalSiPMSmall = 0, HGCalSiPMLarge = 1 };
0026   enum tileType { HGCalTileTypeUnknown = 0, HGCalTileTypeCaste = 1, HGCalTileTypeMould = 2 };
0027   /** Create a null cellid*/
0028   constexpr HGCScintillatorDetId() : DetId() {}
0029   /** Create cellid from raw id (0=invalid tower id) */
0030   constexpr HGCScintillatorDetId(uint32_t rawid) : DetId(rawid) {}
0031   /** Constructor from subdetector, zplus, layer, module, cell numbers */
0032   constexpr HGCScintillatorDetId(
0033       int type, int layer, int ring, int phi, bool trigger = false, int sipm = 0, int granularity = 0)
0034       : DetId(HGCalHSc, ForwardEmpty) {
0035     int zside = (ring < 0) ? 1 : 0;
0036     int itrig = trigger ? 1 : 0;
0037     int ringAbs = std::abs(ring);
0038     id_ |= (((type & kHGCalTypeMask) << kHGCalTypeOffset) | ((zside & kHGCalZsideMask) << kHGCalZsideOffset) |
0039             ((sipm & kHGCalSiPMMask) << kHGCalSiPMOffset) | ((itrig & kHGCalTriggerMask) << kHGCalTriggerOffset) |
0040             ((layer & kHGCalLayerMask) << kHGCalLayerOffset) | ((ringAbs & kHGCalRadiusMask) << kHGCalRadiusOffset) |
0041             ((phi & kHGCalPhiMask) << kHGCalPhiOffset) |
0042             ((granularity & kHGCalGranularityMask) << kHGCalGranularityOffset));
0043   }
0044 
0045   /** Constructor from a generic cell id */
0046   constexpr HGCScintillatorDetId(const DetId& gen) {
0047     if (!gen.null()) {
0048       if (gen.det() != HGCalHSc) {
0049         throw cms::Exception("Invalid DetId")
0050             << "Cannot initialize HGCScintillatorDetId from " << std::hex << gen.rawId() << std::dec;
0051       }
0052     }
0053     id_ = gen.rawId();
0054   }
0055 
0056   /** Assignment from a generic cell id */
0057   constexpr HGCScintillatorDetId& operator=(const DetId& gen) {
0058     if (!gen.null()) {
0059       if (gen.det() != HGCalHSc) {
0060         throw cms::Exception("Invalid DetId")
0061             << "Cannot assign HGCScintillatorDetId from " << std::hex << gen.rawId() << std::dec;
0062       }
0063     }
0064     id_ = gen.rawId();
0065     return (*this);
0066   }
0067 
0068   /** Converter for a geometry cell id */
0069   constexpr HGCScintillatorDetId geometryCell() const {
0070     if (trigger()) {
0071       return HGCScintillatorDetId(type(), layer(), iradiusTrigger(), iphiTrigger(), false);
0072     } else {
0073       return HGCScintillatorDetId(type(), layer(), iradius(), iphi(), false);
0074     }
0075   }
0076 
0077   /// get the subdetector
0078   constexpr DetId::Detector subdet() const { return det(); }
0079 
0080   /// get/set the type
0081   constexpr int type() const { return (id_ >> kHGCalTypeOffset) & kHGCalTypeMask; }
0082   constexpr void setType(int type) {
0083     id_ &= kHGCalTypeMask0;
0084     id_ |= ((type & kHGCalTypeMask) << kHGCalTypeOffset);
0085   }
0086   constexpr int granularity() const { return (id_ >> kHGCalGranularityOffset) & kHGCalGranularityMask; }
0087   constexpr void setGranularity(int granularity) {
0088     id_ &= kHGCalGranularityMask0;
0089     id_ |= ((granularity & kHGCalGranularityMask) << kHGCalGranularityOffset);
0090   }
0091 
0092   /// get the z-side of the cell (1/-1)
0093   constexpr int zside() const { return (((id_ >> kHGCalZsideOffset) & kHGCalZsideMask) ? -1 : 1); }
0094 
0095   /// get the layer #
0096   constexpr int layer() const { return (id_ >> kHGCalLayerOffset) & kHGCalLayerMask; }
0097 
0098   /// get the eta index
0099   constexpr int ring() const {
0100     if (trigger())
0101       return (2 * ((id_ >> kHGCalRadiusOffset) & kHGCalRadiusMask));
0102     else
0103       return ((id_ >> kHGCalRadiusOffset) & kHGCalRadiusMask);
0104   }
0105   constexpr int iradiusAbs() const { return ring(); }
0106   constexpr int iradius() const { return zside() * ring(); }
0107   constexpr int ietaAbs() const { return ring(); }
0108   constexpr int ieta() const { return zside() * ring(); }
0109 
0110   /// get the phi index
0111   constexpr int iphi() const {
0112     if (trigger())
0113       return (2 * ((id_ >> kHGCalPhiOffset) & kHGCalPhiMask));
0114     else
0115       return ((id_ >> kHGCalPhiOffset) & kHGCalPhiMask);
0116   }
0117   constexpr std::pair<int, int> ietaphi() const { return std::pair<int, int>(ieta(), iphi()); }
0118   constexpr std::pair<int, int> ringphi() const { return std::pair<int, int>(iradius(), iphi()); }
0119 
0120   /// get/set the sipm size
0121   constexpr int sipm() const { return (id_ >> kHGCalSiPMOffset) & kHGCalSiPMMask; }
0122   constexpr void setSiPM(int sipm) {
0123     id_ &= kHGCalSiPMMask0;
0124     id_ |= ((sipm & kHGCalSiPMMask) << kHGCalSiPMOffset);
0125   }
0126 
0127   /// trigger or detector cell
0128   std::vector<HGCScintillatorDetId> detectorCells() const;
0129 
0130   constexpr bool trigger() const { return (((id_ >> kHGCalTriggerOffset) & kHGCalTriggerMask) == 1); }
0131   constexpr HGCScintillatorDetId triggerCell() const {
0132     if (trigger())
0133       return HGCScintillatorDetId(type(), layer(), iradius(), iphi(), true);
0134     else
0135       return HGCScintillatorDetId(type(), layer(), iradiusTrigger(), iphiTrigger(), true);
0136   }
0137 
0138   /// consistency check : no bits left => no overhead
0139   constexpr bool isEE() const { return false; }
0140   constexpr bool isHE() const { return true; }
0141   constexpr bool isForward() const { return true; }
0142 
0143   static const HGCScintillatorDetId Undefined;
0144 
0145 public:
0146   static constexpr int kHGCalPhiOffset = 0;
0147   static constexpr int kHGCalPhiMask = 0x1FF;
0148   static constexpr int kHGCalRadiusOffset = 9;
0149   static constexpr int kHGCalRadiusMask = 0xFF;
0150   static constexpr int kHGCalLayerOffset = 17;
0151   static constexpr int kHGCalLayerMask = 0x1F;
0152   static constexpr int kHGCalTriggerOffset = 22;
0153   static constexpr int kHGCalTriggerMask = 0x1;
0154   static constexpr int kHGCalSiPMOffset = 23;
0155   static constexpr int kHGCalSiPMMask = 0x1;
0156   static constexpr int kHGCalGranularityOffset = 24;
0157   static constexpr int kHGCalGranularityMask = 0x1;
0158   static constexpr int kHGCalGranularityMask0 = 0xFFDFFFFF;
0159   static constexpr int kHGCalSiPMMask0 = 0xFF7FFFFF;
0160   static constexpr int kHGCalZsideOffset = 25;
0161   static constexpr int kHGCalZsideMask = 0x1;
0162   static constexpr int kHGCalTypeOffset = 26;
0163   static constexpr int kHGCalTypeMask = 0x3;
0164   static constexpr int kHGCalTypeMask0 = 0xF3FFFFFF;
0165 
0166   constexpr int iradiusTriggerAbs() const {
0167     if (trigger())
0168       return ((ring() + 1) / 2);
0169     else
0170       return ring();
0171   }
0172   constexpr int iradiusTrigger() const { return zside() * iradiusTriggerAbs(); }
0173   constexpr int iphiTrigger() const {
0174     if (trigger())
0175       return ((iphi() + 1) / 2);
0176     else
0177       return iphi();
0178   }
0179 };
0180 
0181 std::ostream& operator<<(std::ostream&, const HGCScintillatorDetId& id);
0182 
0183 #endif