Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:04:03

0001 #ifndef ECALDETID_EEDETID_H
0002 #define ECALDETID_EEDETID_H
0003 
0004 #include <iosfwd>
0005 #include "DataFormats/DetId/interface/DetId.h"
0006 #include "DataFormats/EcalDetId/interface/EcalScDetId.h"
0007 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
0008 
0009 /** \class EEDetId
0010  *  Crystal/cell identifier class for the ECAL endcap
0011  *
0012  *
0013  */
0014 class EEDetId : public DetId {
0015 public:
0016   enum {
0017     /** Sudetector type. Here it is ECAL endcap.
0018      */
0019     Subdet = EcalEndcap
0020   };
0021 
0022   /** Constructor of a null id
0023    */
0024   EEDetId() {}
0025 
0026   /** Constructor from a raw value
0027    * @param rawid det ID number
0028    */
0029   EEDetId(uint32_t rawid) : DetId(rawid) {}
0030 
0031   /** Constructor from crystal ix,iy,iz (iz=+1/-1) (mode = XYMODE)
0032    * or from sc,cr,iz (mode = SCCRYSTALMODE).
0033    * <p>ix runs from 1 to 100 along x-axis of standard CMS coordinates<br>
0034    * iy runs from 1 to 100 along y-axis of standard CMS coordinates<br>
0035    * iz is -1 for EE- and +1 for EE+<br>
0036    * <p>For isc see isc(), for ic see ic()
0037    * @see isc(), ic()
0038    * @param i ix or isc index
0039    * @param j iy or isc index
0040    * @param iz iz/zside index: -1 for EE-, +1 for EE+
0041    * @param mode pass XYMODE if i j refer to ix, iy, SCCRYSTALMODE if thery refer to isc, ic
0042    */
0043   // fast
0044   EEDetId(int crystal_ix, int crystal_iy, int iz) : DetId(Ecal, EcalEndcap) {
0045     id_ |= (crystal_iy & 0x7f) | ((crystal_ix & 0x7f) << 7) | ((iz > 0) ? (0x4000) : (0));
0046   }
0047   // slow
0048   EEDetId(int i, int j, int iz, int mode);
0049 
0050   /** Constructor from a generic cell id
0051    * @param id source detid
0052    */
0053   EEDetId(const DetId& id) : DetId(id) {}
0054 
0055   /** Assignment operator
0056    * @param id source det id
0057    */
0058   EEDetId& operator=(const DetId& id) {
0059     id_ = id.rawId();
0060     return *this;
0061   }
0062 
0063   /** Gets the subdetector
0064    * @return subdetectot ID, that is EcalEndcap
0065    */
0066   static EcalSubdetector subdet() { return EcalEndcap; }
0067 
0068   /** Gets the z-side of the crystal (1/-1)
0069    * @return -1 for EE-, +1 for EE+
0070    */
0071   int zside() const { return (id_ & 0x4000) ? (1) : (-1); }
0072 
0073   /** Gets the crystal x-index.
0074    * @see EEDetId(int, int, int, int) for x-index definition
0075    * @return x-index
0076    */
0077   int ix() const { return (id_ >> 7) & 0x7F; }
0078 
0079   /** Get the crystal y-index
0080    * @see EEDetId(int, int, int, int) for y-index definition.
0081    * @return y-index
0082    */
0083   int iy() const { return id_ & 0x7F; }
0084 
0085   /** Gets the DetId of the supercrystal the crystal belong to.
0086    * @return the supercrystal det id
0087    * @throw cms::Exception if the crystal det id is invalid 
0088    */
0089   EcalScDetId sc() const {
0090     const int scEdge = 5;
0091     return EcalScDetId(1 + (ix() - 1) / scEdge, 1 + (iy() - 1) / scEdge, zside());
0092   }
0093 
0094   /** Gets the SuperCrystal number within the endcap. This number runs from 1 to 316,
0095    * numbers 70 149 228 307 are not used.
0096    *
0097    * BEWARE: This number is not consistent with indices used in constructor:  see details below.
0098    *
0099    * Numbering in quadrant 1 of EE+ is the following
0100    * \verbatim 
0101    *  08 17 27        
0102    *  07 16 26 36 45 54     
0103    *  06 15 25 35 44 53 62    
0104    *  05 14 24 34 43 52 61 69   
0105    *  04 13 23 33 42 51 60 68 76  
0106    *  03 12 22 32 41 50 59 67 75  
0107    *  02 11 21 31 40 49 58 66 74  
0108    *  01 10 20 30 39 48 57 65 73 79 
0109    *     09 19 29 38 47 56 64 72 78 
0110    *        18 28 37 46 55 63 71 77
0111    *  
0112    *        == THERE IS NO INDEX 70! ==
0113    * \endverbatim
0114    *
0115    * Quadrant 2 indices are deduced by a symetry about y-axis and by adding an offset
0116    * of 79.<br>
0117    * Quadrant 3 and 4 indices are deduced from quadrant 1 and 2 by a symetry
0118    * about x-axis and adding an offset. Quadrant N starts with index 1 + (N-1)*79.
0119    *
0120    * <p>EE- indices are deduced from EE+ by a symetry about (x,y)-plane (mirrored view). <b>It is
0121    * inconsistent with indices used in constructor EEDetId(int, int,int) in
0122    * SCCRYSTALMODE</b>. Indices of constructor uses a symetry along y-axis: in principal it
0123    * considers the isc as a local index. The discrepancy is most probably due to a bug in the
0124    * implementation of this isc() method.
0125    */
0126   int isc() const;
0127 
0128   /** Gets crystal number inside SuperCrystal.
0129    * Crystal numbering withing a supercrystal in each quadrant:
0130    * \verbatim
0131    *                       A y
0132    *  (Q2)                 |                    (Q1)
0133    *       25 20 15 10 5   |     5 10 15 20 25
0134    *       24 19 14  9 4   |     4  9 14 19 24
0135    *       23 18 13  8 3   |     3  8 13 18 23
0136    *       22 17 12  7 2   |     2  7 12 17 22
0137    *       21 16 11  6 1   |     1  6 11 16 21
0138    *                       |
0139    * ----------------------o---------------------------> x
0140    *                       |
0141    *       21 16 11  6 1   |     1  6 11 16 21
0142    *       22 17 12  7 2   |     2  7 12 17 22
0143    *       23 18 13  8 3   |     3  8 13 18 23
0144    *       24 19 14  9 4   |     4  9 14 19 24
0145    *       25 20 15 10 5   |     5 10 15 20 25
0146    *  (Q3)                                       (Q4)
0147    * \endverbatim
0148    *
0149    * @return crystal number from 1 to 25
0150    */
0151   int ic() const;
0152 
0153   /** Gets the quadrant of the DetId.
0154    * Quadrant number definition, x and y in std CMS coordinates, for EE+:
0155    *
0156    * \verbatim
0157    *                 A y
0158    *                 |
0159    *          Q2     |    Q1
0160    *                 |
0161    *       ----------o---------> x
0162    *                 |
0163    *          Q3     |    Q4
0164    *                 |
0165    * \endverbatim
0166    *
0167    * @return quadrant number
0168    */
0169   int iquadrant() const;
0170 
0171   /** Checks if crystal is in EE+
0172    * @return true for EE+, false for EE-
0173    */
0174   bool positiveZ() const { return id_ & 0x4000; }
0175 
0176   int iPhiOuterRing() const;  // 1-360 else==0 if not on outer ring!
0177 
0178   static EEDetId idOuterRing(int iPhi, int zEnd);
0179 
0180   /** Gets a compact index for arrays
0181    * @return compact index from 0 to kSizeForDenseIndexing-1
0182    */
0183   int hashedIndex() const {
0184     const uint32_t jx(ix());
0185     const uint32_t jd(2 * (iy() - 1) + (jx - 1) / 50);
0186     return ((positiveZ() ? kEEhalf : 0) + kdi[jd] + jx - kxf[jd]);
0187   }
0188 
0189   /** Same as hashedIndex()
0190    * @return compact index from 0 to kSizeForDenseIndexing-1
0191    */
0192   uint32_t denseIndex() const { return hashedIndex(); }
0193 
0194   /** returns a new EEDetId offset by nrStepsX and nrStepsY (can be negative),
0195    * returns EEDetId(0) if invalid */
0196   EEDetId offsetBy(int nrStepsX, int nrStepsY) const;
0197 
0198   /** returns a new EEDetId swapped (same iX, iY) to the other endcap, 
0199        * returns EEDetId(0) if invalid (shouldnt happen) */
0200   EEDetId switchZSide() const;
0201 
0202   /** following are static member functions of the above two functions
0203    *  which take and return a DetId, returns DetId(0) if invalid 
0204    */
0205   static DetId offsetBy(const DetId startId, int nrStepsX, int nrStepsY);
0206   static DetId switchZSide(const DetId startId);
0207 
0208   /** Checks validity of a dense/hashed index
0209    * @param din dense/hashed index as returned by hashedIndex() or denseIndex()
0210    * method
0211    * @return true if index is valid, false otherwise
0212    */
0213   static bool validDenseIndex(uint32_t din) { return validHashIndex(din); }
0214 
0215   /** Converts a hashed/dense index as defined in hashedIndex() and denseIndex()
0216    * methods to a det id.
0217    * @param din hashed/dense index
0218    * @return det id
0219    */
0220   static EEDetId detIdFromDenseIndex(uint32_t din) { return unhashIndex(din); }
0221 
0222   static bool isNextToBoundary(EEDetId id);
0223 
0224   static bool isNextToDBoundary(EEDetId id);
0225 
0226   static bool isNextToRingBoundary(EEDetId id);
0227 
0228   /** Gets a DetId from a compact index for arrays. Converse of hashedIndex() method.
0229    * @param hi dense/hashed index
0230    * @return det id
0231    */
0232   static EEDetId unhashIndex(int hi);
0233 
0234   /** Checks if a hashed/dense index is valid
0235    * @see hashedIndex(), denseIndex()
0236    * @param i hashed/dense index
0237    * @return true if the index is valid, false otherwise
0238    */
0239   static bool validHashIndex(int i) { return (i < kSizeForDenseIndexing); }
0240 
0241   /** Checks validity of a crystal (x,y.z) index triplet.
0242    * @param crystal_ix crystal x-index
0243    * @param crystal_iy crystal y-index
0244    * @param iz crystal z-index
0245    * @see EEDetId(int, int, int, int) for index definition
0246    * @return true if valid, false otherwise
0247    */
0248   static bool validDetId(int crystal_ix, int crystal_iy, int iz) {
0249     return crystal_ix >= IX_MIN && crystal_ix <= IX_MAX && crystal_iy >= IY_MIN && crystal_iy <= IY_MAX &&
0250            std::abs(iz) == 1 && (fastValidDetId(crystal_ix, crystal_iy) || slowValidDetId(crystal_ix, crystal_iy));
0251   }
0252   static bool slowValidDetId(int crystal_ix, int crystal_iy);
0253 
0254   /**  check if ix and iy is in a "ring" inscribed in EE
0255    *   if is inside is valid for sure
0256    *   if not the slow version shall be called
0257    */
0258   static bool fastValidDetId(int crystal_ix, int crystal_iy) {
0259     float x = crystal_ix;
0260     float y = crystal_iy;
0261     float r = (x - 50.5f) * (x - 50.5f) + (y - 50.5f) * (y - 50.5f);
0262     return r > 12.f * 12.f && r < 48.f * 48.f;
0263   }
0264 
0265   /** Returns the distance along x-axis in crystal units between two EEDetId
0266    * @param a det id of first crystal
0267    * @param b det id of second crystal
0268    * @return distance
0269    */
0270   static int distanceX(const EEDetId& a, const EEDetId& b);
0271 
0272   /** Returns the distance along y-axis in crystal units between two EEDetId
0273    * @param a det id of first crystal
0274    * @param b det id of second crystal
0275    * @return distance
0276    */
0277   static int distanceY(const EEDetId& a, const EEDetId& b);
0278 
0279   /** Gives supercrystal index from endcap *supercrystal* x and y indexes.
0280    * @see isc() for the index definition
0281    * @param iscCol supercrystal column number: supecrystal x-index for EE+
0282    * @param iscRow: supecrystal y-index
0283    * @return supercystal index
0284    */
0285   static int isc(int iscCol,   // output is 1-316
0286                  int iscRow);  //
0287 
0288   /** Lower bound of EE crystal x-index
0289    */
0290   static const int IX_MIN = 1;
0291 
0292   /** Lower bound of EE crystal y-index
0293    */
0294   static const int IY_MIN = 1;
0295 
0296   /** Upper bound of EE crystal y-index
0297    */
0298   static const int IX_MAX = 100;
0299 
0300   /** Upper bound of EE crystal y-index
0301    */
0302   static const int IY_MAX = 100;
0303 
0304   /** Lower bound of supercystal index as defined in isc()
0305    */
0306   static const int ISC_MIN = 1;
0307 
0308   /** Lower bound of crystal index within a supercrystal
0309    */
0310   static const int ICR_MIN = 1;
0311 
0312   /** Upper bound of supercystal index defined in isc()
0313    * <p>Beware it differs from the number of supercrystals in one endcap,
0314    * which is 312, because the numbering is not dense.
0315    */
0316   static const int ISC_MAX = 316;
0317 
0318   /** Upper bound of crystal index within a supercrystal
0319    */
0320   static const int ICR_MAX = 25;
0321 
0322   /** Number of crystals per Dee
0323    */
0324   static constexpr int kEEhalf = 7324;
0325   /** Number of dense crystal indices, that is number of
0326      * crystals per endcap.
0327      */
0328   static constexpr int kSizeForDenseIndexing = 2 * kEEhalf;
0329 
0330   /*@{*/
0331   /** function modes for EEDetId(int, int, int, int) constructor
0332    */
0333   static const int XYMODE = 0;
0334   static const int SCCRYSTALMODE = 1;
0335   /*@}*/
0336 
0337 private:
0338   bool isOuterRing() const;
0339 
0340   static bool isOuterRingXY(int ax, int ay);
0341 
0342   //Functions from B. Kennedy to retrieve ix and iy from SC and Crystal number
0343 
0344   static const int nCols = 10;
0345   static const int nCrys = 5; /* Number of crystals per row in SC */
0346   static const int QuadColLimits[nCols + 1];
0347   static const int iYoffset[nCols + 1];
0348 
0349   static const unsigned short kxf[2 * IY_MAX];
0350   static const unsigned short kdi[2 * IY_MAX];
0351 
0352   int ix(int iSC, int iCrys) const;
0353   int iy(int iSC, int iCrys) const;
0354   int ixQuadrantOne() const;
0355   int iyQuadrantOne() const;
0356 };
0357 
0358 std::ostream& operator<<(std::ostream& s, const EEDetId& id);
0359 
0360 #endif