Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-11-06 23:38:15

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 2mm: 1 for 4mm)
0016    [24]    Free
0017    [25:25] z-side (0 for +z; 1 for -z)
0018    [26:27] Tile granularity and type (0 fine divisions of scintillators;
0019                                       1 coarse divisions of type "c";
0020                                       2 coarse divisions of type "m")
0021    [28:31] Detector type (HGCalHSc)
0022 */
0023 
0024 class HGCScintillatorDetId : public DetId {
0025 public:
0026   /** Create a null cellid*/
0027   constexpr HGCScintillatorDetId() : DetId() {}
0028   /** Create cellid from raw id (0=invalid tower id) */
0029   constexpr HGCScintillatorDetId(uint32_t rawid) : DetId(rawid) {}
0030   /** Constructor from subdetector, zplus, layer, module, cell numbers */
0031   constexpr HGCScintillatorDetId(int type, int layer, int ring, int phi, bool trigger = false, int sipm = 0)
0032       : DetId(HGCalHSc, ForwardEmpty) {
0033     int zside = (ring < 0) ? 1 : 0;
0034     int itrig = trigger ? 1 : 0;
0035     int ringAbs = std::abs(ring);
0036     id_ |= (((type & kHGCalTypeMask) << kHGCalTypeOffset) | ((zside & kHGCalZsideMask) << kHGCalZsideOffset) |
0037             ((sipm & kHGCalSiPMMask) << kHGCalSiPMOffset) | ((itrig & kHGCalTriggerMask) << kHGCalTriggerOffset) |
0038             ((layer & kHGCalLayerMask) << kHGCalLayerOffset) | ((ringAbs & kHGCalRadiusMask) << kHGCalRadiusOffset) |
0039             ((phi & kHGCalPhiMask) << kHGCalPhiOffset));
0040   }
0041 
0042   /** Constructor from a generic cell id */
0043   constexpr HGCScintillatorDetId(const DetId& gen) {
0044     if (!gen.null()) {
0045       if (gen.det() != HGCalHSc) {
0046         throw cms::Exception("Invalid DetId")
0047             << "Cannot initialize HGCScintillatorDetId from " << std::hex << gen.rawId() << std::dec;
0048       }
0049     }
0050     id_ = gen.rawId();
0051   }
0052 
0053   /** Assignment from a generic cell id */
0054   constexpr HGCScintillatorDetId& operator=(const DetId& gen) {
0055     if (!gen.null()) {
0056       if (gen.det() != HGCalHSc) {
0057         throw cms::Exception("Invalid DetId")
0058             << "Cannot assign HGCScintillatorDetId from " << std::hex << gen.rawId() << std::dec;
0059       }
0060     }
0061     id_ = gen.rawId();
0062     return (*this);
0063   }
0064 
0065   /** Converter for a geometry cell id */
0066   constexpr HGCScintillatorDetId geometryCell() const {
0067     if (trigger()) {
0068       return HGCScintillatorDetId(type(), layer(), iradiusTrigger(), iphiTrigger(), false);
0069     } else {
0070       return HGCScintillatorDetId(type(), layer(), iradius(), iphi(), false);
0071     }
0072   }
0073 
0074   /// get the subdetector
0075   constexpr DetId::Detector subdet() const { return det(); }
0076 
0077   /// get/set the type
0078   constexpr int type() const { return (id_ >> kHGCalTypeOffset) & kHGCalTypeMask; }
0079   constexpr void setType(int type) {
0080     id_ &= kHGCalTypeMask0;
0081     id_ |= ((type & kHGCalTypeMask) << kHGCalTypeOffset);
0082   }
0083 
0084   /// get the z-side of the cell (1/-1)
0085   constexpr int zside() const { return (((id_ >> kHGCalZsideOffset) & kHGCalZsideMask) ? -1 : 1); }
0086 
0087   /// get the layer #
0088   constexpr int layer() const { return (id_ >> kHGCalLayerOffset) & kHGCalLayerMask; }
0089 
0090   /// get the eta index
0091   constexpr int ring() const {
0092     if (trigger())
0093       return (2 * ((id_ >> kHGCalRadiusOffset) & kHGCalRadiusMask));
0094     else
0095       return ((id_ >> kHGCalRadiusOffset) & kHGCalRadiusMask);
0096   }
0097   constexpr int iradiusAbs() const { return ring(); }
0098   constexpr int iradius() const { return zside() * ring(); }
0099   constexpr int ietaAbs() const { return ring(); }
0100   constexpr int ieta() const { return zside() * ring(); }
0101 
0102   /// get the phi index
0103   constexpr int iphi() const {
0104     if (trigger())
0105       return (2 * ((id_ >> kHGCalPhiOffset) & kHGCalPhiMask));
0106     else
0107       return ((id_ >> kHGCalPhiOffset) & kHGCalPhiMask);
0108   }
0109   constexpr std::pair<int, int> ietaphi() const { return std::pair<int, int>(ieta(), iphi()); }
0110   constexpr std::pair<int, int> ringphi() const { return std::pair<int, int>(iradius(), iphi()); }
0111 
0112   /// get/set the sipm size
0113   constexpr int sipm() const { return (id_ >> kHGCalSiPMOffset) & kHGCalSiPMMask; }
0114   constexpr void setSiPM(int sipm) {
0115     id_ &= kHGCalSiPMMask0;
0116     id_ |= ((sipm & kHGCalSiPMMask) << kHGCalSiPMOffset);
0117   }
0118 
0119   /// trigger or detector cell
0120   std::vector<HGCScintillatorDetId> detectorCells() const;
0121 
0122   constexpr bool trigger() const { return (((id_ >> kHGCalTriggerOffset) & kHGCalTriggerMask) == 1); }
0123   constexpr HGCScintillatorDetId triggerCell() const {
0124     if (trigger())
0125       return HGCScintillatorDetId(type(), layer(), iradius(), iphi(), true);
0126     else
0127       return HGCScintillatorDetId(type(), layer(), iradiusTrigger(), iphiTrigger(), true);
0128   }
0129 
0130   /// consistency check : no bits left => no overhead
0131   constexpr bool isEE() const { return false; }
0132   constexpr bool isHE() const { return true; }
0133   constexpr bool isForward() const { return true; }
0134 
0135   static const HGCScintillatorDetId Undefined;
0136 
0137 public:
0138   static constexpr int kHGCalPhiOffset = 0;
0139   static constexpr int kHGCalPhiMask = 0x1FF;
0140   static constexpr int kHGCalRadiusOffset = 9;
0141   static constexpr int kHGCalRadiusMask = 0xFF;
0142   static constexpr int kHGCalLayerOffset = 17;
0143   static constexpr int kHGCalLayerMask = 0x1F;
0144   static constexpr int kHGCalTriggerOffset = 22;
0145   static constexpr int kHGCalTriggerMask = 0x1;
0146   static constexpr int kHGCalSiPMOffset = 23;
0147   static constexpr int kHGCalSiPMMask = 0x1;
0148   static constexpr int kHGCalSiPMMask0 = 0xFF7FFFFF;
0149   static constexpr int kHGCalZsideOffset = 25;
0150   static constexpr int kHGCalZsideMask = 0x1;
0151   static constexpr int kHGCalTypeOffset = 26;
0152   static constexpr int kHGCalTypeMask = 0x3;
0153   static constexpr int kHGCalTypeMask0 = 0xF3FFFFFF;
0154 
0155   constexpr int iradiusTriggerAbs() const {
0156     if (trigger())
0157       return ((ring() + 1) / 2);
0158     else
0159       return ring();
0160   }
0161   constexpr int iradiusTrigger() const { return zside() * iradiusTriggerAbs(); }
0162   constexpr int iphiTrigger() const {
0163     if (trigger())
0164       return ((iphi() + 1) / 2);
0165     else
0166       return iphi();
0167   }
0168 };
0169 
0170 std::ostream& operator<<(std::ostream&, const HGCScintillatorDetId& id);
0171 
0172 #endif