Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:29:24

0001 //emacs settings:-*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil -*-"
0002 /*
0003  */
0004 
0005 #ifndef ECALSELECTIVEREADOUT_H
0006 #define ECALSELECTIVEREADOUT_H
0007 
0008 #include <vector>
0009 #include <iosfwd>
0010 #include "DataFormats/EcalDetId/interface/EBDetId.h"
0011 #include "DataFormats/EcalDetId/interface/EEDetId.h"
0012 #include "DataFormats/EcalDetId/interface/EcalScDetId.h"
0013 #include "DataFormats/EcalDetId/interface/EcalTrigTowerDetId.h"
0014 #include "Geometry/CaloTopology/interface/EcalTrigTowerConstituentsMap.h"
0015 #include "Geometry/EcalMapping/interface/EcalElectronicsMapping.h"
0016 
0017 #define ECALSELECTIVEREADOUT_NOGEOM  //version w/o geometry dependency.
0018 
0019 #ifndef ECALSELECTIVEREADOUT_NOGEOM
0020 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
0021 #endif  //ECALSELECTIVEREADOUT_NOGEOM not defined
0022 
0023 /** This class is used to run the selective readout processing on the
0024  * electromagnetic calorimeter. Normal user do not need to access directly this
0025  * class: the selective readout is made at digitization by the
0026  * CaloDataFrameFormatter class which uses the EcalSelectiveReadout class for
0027  * this purpose: see CaloDataFrameFormatter class documentation.
0028  * The ECAL event size must be reduced by a factor ~1/20th online at the LV1
0029  * rate. This reduction is achieved by suppressing channels whose energy,
0030  * evaluated on line by a FIR, is below a threshold ("zero suppression"). This
0031  * threshold is dynamic and determined for the channel of each readout unit.
0032  * A readout unit is a group of 5x5 crystals: a trigger tower for the barrel
0033  * and a supercrystal for the endcap) basis. The selective readout classifies
0034  * the readout units in three classes:<UL>
0035  * <LI>low interest
0036  * <LI>single
0037  * <LI>neighbour
0038  * <LI>center
0039  * </UL>. Single, neighbour and center classes consitute the "high interest"
0040  * readout units and their channels the "high interest" channels.
0041  * Two zero suppresion thresholds, eventually -/+ infinity, are defined: one
0042  * for the "Low interest" channels and one for the "high interest" channels.
0043  * The low interest threshold must be higher than the high interest one.
0044  *
0045  * Note: Forced bit processing:
0046  * ---------------------------
0047  *
0048  * The trigger tower flag (TTF) issued by the TCC and indicating the
0049  * level of transverse deposited energy (classified is three levels
0050  * called low interest, mid interest, high interest), the selective
0051  * readout flags (SRF) are made of 2 bits. An additionnal bit, called
0052  * force bit, is used to indicate if some information was missing to
0053  * compute the flag and if therefore some default value was used. TCC
0054  * can substitute a default value to a TTF. In such case the forced
0055  * bit is set. Similarly SRP can substitute a default value to a SRF
0056  * and set the forced bit accordingly.
0057  * If the TTF forced bit of a trigger tower is set the SRP propagates
0058  * it to the SRF by setting the forced bit of every readout unit
0059  * overlapping with the trigger tower.  Note that for the barrel
0060  * readout units match with trigger towers.
0061  */
0062 class EcalSelectiveReadout {
0063 public:
0064   static const int FORCED_MASK = 0x4;
0065 
0066   //type definitions
0067   /** trigger tower classification ("SRP flags")
0068    */
0069   typedef enum {
0070     UNKNOWN = -1 & ~FORCED_MASK,
0071     LOWINTEREST = 0x0,
0072     SINGLE = 0x1,
0073     NEIGHBOUR = 0x2,
0074     CENTER = 0x3,
0075     FORCED_LOWINTEREST = 0x4,  //0x0 | 0x4
0076     FORCED_SINGLE = 0x5,       //0x1 | 0x4
0077     FORCED_NEIGHBOUR = 0x6,    //0x2 | 0x4
0078     FORCED_CENTER = 0x7        //0x3 | 0x4
0079   } towerInterest_t;
0080 
0081   typedef enum {
0082     TTF_UNKNOWN = -1,
0083     TTF_LOW_INTEREST = 0x0,
0084     TTF_MID_INTEREST = 0x1,
0085     /* 0x2 not used */
0086     TTF_HIGH_INTEREST = 0X3,
0087     TTF_FORCED_LOW_INTEREST = 0x4,  //0x0 | 0x4
0088     TTF_FORCED_MID_INTEREST = 0x5,  //0x1 | 0x4
0089     /* 0x6 not used*/
0090     TTF_FORCED_HIGH_INTEREST = 0x7  //0x3 | 0x4
0091                                     //     TTF_FORCED_RO_LINK_SYNC_ERR = 0x4,
0092                                     //     TTF_FORCED_RO_HAMMING_ERR = 0X5,
0093                                     //     TTF_FORCED_RO_OTHER1 = 0X6,
0094                                     //     TTF_FORCED_RO_OTHER2 = 0X7
0095   } ttFlag_t;
0096 
0097   //deprecated. Use instead FORCED_MASK
0098   static const int TTF_FORCED_RO_MASK = FORCED_MASK;
0099 
0100   //constants
0101 public:
0102   /** Number of crystals along eta in barrel
0103    */
0104   const static size_t nBarrelEtaBins = 170;
0105   /** Number of crystals in a eta ring of the barrel
0106    */
0107   const static size_t nBarrelPhiBins = 360;
0108   /** Range of the x-index of endcap crystals (xman-xmin+1).
0109    */
0110   const static size_t nEndcapXBins = 100;
0111   /** Range of the y-index of endcap crystals (yman-ymin+1).
0112    */
0113   const static size_t nEndcapYBins = 100;
0114   /** Edge size of a supercrystal. A supercrystal is a tower of 5x5 crystals.
0115    */
0116   const static size_t supercrystalEdge = 5;
0117   /** Range of endcap supercrystal x-index (xmax-xmin+1)
0118    */
0119   const static size_t nSupercrystalXBins = nEndcapXBins / supercrystalEdge;
0120   /** Range of endcap supercrystal y-index (ymay-ymin+1)
0121    */
0122   const static size_t nSupercrystalYBins = nEndcapYBins / supercrystalEdge;
0123   /** Number of trigger tower along eta in the barrel
0124    */
0125   const static size_t nBarrelTowerEtaBins = nBarrelEtaBins / 5;
0126   /** Number of trigger tower in a eta ring of the barrel
0127    */
0128   const static size_t nBarrelTowerPhiBins = nBarrelPhiBins / 5;
0129   /** Number of endcap, obviously tow
0130    */
0131   const static size_t nEndcaps = 2;
0132   /** Number of trigger towers along eta in one endcap
0133    */
0134   const static size_t nEndcapTriggerTowersInEta = 11;
0135   /** Number of barrel trigger towers along eta
0136    */
0137   const static size_t nBarrelTriggerTowersInEta = 34;
0138   /** Number of trigger towers along eta for the whole ECAL
0139    */
0140   const static size_t nTriggerTowersInEta = 2 * nEndcapTriggerTowersInEta + nBarrelTriggerTowersInEta;
0141   /** Number of trigger towers in an eta ring
0142    */
0143   const static size_t nTriggerTowersInPhi = 72;
0144 
0145   /** Maximum number of DCC channels used from crystal channels
0146    * (channel #69 and #70 used for MEM are not counted here)
0147    */
0148   const static int maxDccChs = 68;
0149 
0150   /** Number of DCC per endcap
0151    */
0152   const static int nDccPerEe = 9;
0153 
0154   //constructor(s) and destructor(s)
0155 public:
0156   /** Constructs a ecalselectivereadout.
0157    * Neighbours are taken in a trigger tower matrix of size
0158    * 2(dEta+1))x2(dPhi+1) around a 'center' tower.
0159    * @param dEta neighborhood extend in number of trigger towers along eta
0160    * @param dPhi neighborgooh extend in number if trigger towers along phi
0161    * in 'low interest', 'single' or 'center. First element is the lower
0162    * threshold, second element is the higher one.
0163    */
0164   EcalSelectiveReadout(int dEta = 1, int dPhi = 1);
0165 
0166   //method(s)
0167 
0168   /// the mapping of which cell goes with which trigger tower
0169   void setTriggerMap(const EcalTrigTowerConstituentsMap* map) { theTriggerMap = map; }
0170 
0171   /// the electronics map, used to get information about
0172   /// the DCC and DCC channel used to read a crystal channel
0173   void setElecMap(const EcalElectronicsMapping* map) { theElecMap = map; }
0174 
0175 #ifndef ECALSELECTIVEREADOUT_NOGEOM
0176   void setGeometry(const CaloGeometry* caloGeometry) { theGeometry = caloGeometry; }
0177 #endif  //ECALSELECTIVEREADOUT_NOGEOM not defined
0178 
0179   /** Selective readout algorithm type 0.
0180    *  The algorithm is the following:
0181    *  <OL>
0182    *  <LI>A trigger tower (TT) with Et higher than the high threshold is
0183    *  classified as 'center'
0184    *  <LI>A trigger tower which is a neighbour of a 'center' TT and which
0185    *  is not itself a 'center' is classified as 'neighbour'
0186    *  <LI>A TT with Et between the two threshold and which is not a 'center'
0187    *  or a 'neighbour' is classified as 'single'
0188    *  <LI>Any other TT are classified as 'low interest'
0189    *  </OL>
0190    * For the barrel a crystal inherit the
0191    *  single/center/neighbour/low_interst classification of its TT.
0192    *  For the endcap,
0193    *  <UL>
0194    *     <LI>if the supercrystal overlaps with a 'center' TT, it's flagged
0195    *  as 'center'
0196    *     <LI>otherwise if it overlaps with a 'neighbour' TT, it's flagged
0197    *  as 'neighbour'
0198    *     <LI>else if it overlaps with a 'single' TT, it's flagged
0199    *  as 'single'
0200    *     <LI>the remaining SC are flagged as 'low interest'
0201    *  </UL>
0202    * An endcap crystal inherits the SRP flag of its SC.
0203    * @param triggerTowerEt array of the transverse enrgy deposited in the
0204    * trigger tower. First index is for eta,2nd index for phi.
0205    */
0206   void runSelectiveReadout0(const ttFlag_t towerFlags[nTriggerTowersInEta][nTriggerTowersInPhi]);
0207 
0208   /** Gets the SR interest classification of an EB channel
0209    * @param ebDetId id of the crystal
0210    * @param interest
0211    */
0212   towerInterest_t getCrystalInterest(const EBDetId& ebDetId) const;
0213 
0214   /** Gets the SR interest classification of an EE channel
0215    * @param eeDetId id of the crystal
0216    * @return interest
0217    */
0218   towerInterest_t getCrystalInterest(const EEDetId& eeDetId) const;
0219 
0220   /** Gets the SR interest classification of an EE supercrystal
0221    * @param scDetId id of the crystal
0222    * @return interest
0223    */
0224   towerInterest_t getSuperCrystalInterest(const EcalScDetId& scDetId) const;
0225 
0226   /**Gets the SR interest classification of a trigger tower (TT).
0227    * @param iEta index of the TT along eta
0228    * @param iPhi index of the TT along phi
0229    * @return interest
0230    */
0231   towerInterest_t getTowerInterest(const EcalTrigTowerDetId& towerId) const;
0232 
0233   /// print out header for the map: see print(std::ostream&)
0234   void printHeader(std::ostream& os) const;
0235 
0236   /// print out the map
0237   void print(std::ostream& os) const;
0238 
0239   void printBarrel(std::ostream& os) const;
0240   void printEndcap(int endcap, std::ostream& s) const;
0241 
0242 private:
0243   /** Get access to eeRuInterest element corresponding
0244    * to an EE det Id
0245    * @param id the EE det id
0246    * @return reference to the eeRuInterest array element
0247    */
0248   towerInterest_t& eeRuInterest(const EEDetId& id);
0249 
0250   /** Get access to eeRuInterest element corresponding
0251    * to an SC det Id
0252    * @param id the SC det id
0253    * @return reference to the eeRuInterest array element
0254    */
0255   towerInterest_t& eeRuInterest(const EcalScDetId& id);
0256 
0257   /** Classifies trigger tower in three classes:<UL>
0258    * <LI> low interest: value 'lowInterest'
0259    * <LI> middle interest: value 'single'
0260    * <LI> high interest: value 'center'
0261    * </UL>
0262    */
0263   void classifyTriggerTowers(const ttFlag_t ttFlags[nTriggerTowersInEta][nTriggerTowersInPhi]);
0264 
0265   /** Sets all endcap RU interest flags to 'unknown'
0266    */
0267   void resetEeRuInterest();
0268 
0269   /** Changes the value of a variable iff that has
0270    *  the effect to decrease the variable value
0271    *  var = min(var,val)
0272    *  @param var the variable
0273    *  @param val the new candidate value
0274    */
0275   void setLower(int& var, int val) const {
0276     if (val < var)
0277       var = val;
0278   }
0279 
0280   /** Changes the value of a variable iff that has
0281    *  the effect to increase the variable value
0282    *  var = max(var,val)
0283    *  @param var the variable
0284    *  @param val the new candidate value
0285    */
0286   template <class T>
0287   void setHigher(T& var, T val) const {
0288     if (val > var)
0289       var = val;
0290   }
0291 
0292   /** Combine two flags. Forced bit and actual flag fields are treated
0293    * separately. For both fields, the highst value is selected.
0294    * @param var [in,out] flag to change in place
0295    * @param val flag to combine with the first.
0296    * @tparam T towerInterest_t or
0297    */
0298   template <class T>
0299   void combineFlags(T& var, T val) const {
0300     var = (T)(std::max(val & ~TTF_FORCED_RO_MASK,  //actual flag value:
0301                        //                            take highest
0302                        var & ~TTF_FORCED_RO_MASK)  //beware: must work also
0303               //                                     for UNKNOW=-1
0304               //                                     ->compare the whole
0305               //                                     integer but with
0306               //                                     the forced bit masked.
0307               | ((val | var) & 0x4));  //forced bit: set it if any of the two is
0308     //                                 already set
0309 
0310     if (var < 0 || var > 7) {
0311       std::cout << __FILE__ << ":" << __LINE__ << ": ---------->" << var << " " << val << " "
0312                 << std::max(val & 0x3, var & 0x3) << " " << (val | var) << " " << ((val | var) & 0x4) << " "
0313                 << (std::max(val & 0x3, var & 0x3) | ((val | var) & 0x4)) << " "
0314                 << (T)(std::max(val & 0x3, var & 0x3) | ((val | var) & 0x4)) << "\n";
0315     }
0316   }
0317 
0318   //   /** Propagate TTF flag bit on towerInterest. TT interest forced bit is set
0319   //    * if TTF forced bit is set, otherwise it is not touched.
0320   //    * @param ttFlags TT flags
0321   //    */
0322   //   void propagateTtForcedBit(const ttFlag_t ttFlags[nTriggerTowersInEta][nTriggerTowersInPhi]);
0323 
0324   void printDccChMap(std::ostream& os) const;
0325 
0326   //attribute(s)
0327 private:
0328   const EcalTrigTowerConstituentsMap* theTriggerMap;
0329   const EcalElectronicsMapping* theElecMap;
0330 
0331 #ifndef ECALSELECTIVEREADOUT_NOGEOM
0332   const CaloGeometry* theGeometry;
0333 #endif  //ECALSELECTIVEREADOUT_NOGEOM not defined
0334   towerInterest_t towerInterest[nTriggerTowersInEta][nTriggerTowersInPhi];
0335   //towerInterest_t supercrystalInterest[nEndcaps][nSupercrystalXBins][nSupercrystalYBins];
0336   towerInterest_t eeRuInterest_[nEndcaps][nDccPerEe][maxDccChs];
0337   int dEta;
0338   int dPhi;
0339 
0340   // for printout
0341   const static char srpFlagMarker[];
0342 };
0343 
0344 std::ostream& operator<<(std::ostream& os, const EcalSelectiveReadout& selectiveReadout);
0345 
0346 #endif