Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:14:36

0001 #ifndef ECALELECTRONICSMAPPING_H
0002 #define ECALELECTRONICSMAPPING_H 1
0003 
0004 #include <memory>
0005 #include <iostream>
0006 #include <string>
0007 
0008 #include "DataFormats/EcalDetId/interface/EcalDetIdCollections.h"
0009 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
0010 
0011 #include <boost/multi_index_container.hpp>
0012 #include <boost/multi_index/member.hpp>
0013 #include <boost/multi_index/ordered_index.hpp>
0014 #include <boost/tuple/tuple.hpp>
0015 #include <boost/multi_index/mem_fun.hpp>
0016 #include <boost/multi_index/composite_key.hpp>
0017 
0018 #include "DataFormats/Math/interface/RectangularEtaPhiRegion.h"
0019 
0020 #include <vector>
0021 #include <map>
0022 
0023 /** \class EcalElectronicsMapping
0024   *  
0025   * \author P.Meridiani (INFN Roma1),  E. Perez (CERN)  
0026   */
0027 
0028 class EcalElectronicsMapping {
0029 public:
0030   EcalElectronicsMapping();
0031 
0032   /// Get the electronics id for this det id
0033   EcalElectronicsId getElectronicsId(const DetId& id) const;
0034 
0035   /// Get the trigger electronics id for this det id
0036   EcalTriggerElectronicsId getTriggerElectronicsId(const DetId& id) const;
0037 
0038   /// Get the detid  given an electronicsId
0039   DetId getDetId(const EcalElectronicsId& id) const;
0040 
0041   /// Get the trigger electronics id  given an electronicsId
0042   EcalTriggerElectronicsId getTriggerElectronicsId(const EcalElectronicsId& id) const;
0043 
0044   /// Get the detid  given a trigger electronicsId
0045   DetId getDetId(const EcalTriggerElectronicsId& id) const;
0046 
0047   /// Get the electronics id given a trigger electronicsId
0048   EcalElectronicsId getElectronicsId(const EcalTriggerElectronicsId& id) const;
0049 
0050   /// Get the constituent detids for this dccId
0051   std::vector<DetId> dccConstituents(int dccId) const;
0052 
0053   /// Get the constituent detids for this dccId
0054   std::vector<DetId> dccTowerConstituents(int dccId, int tower) const;
0055 
0056   /// Get the constituent detids for this dccId
0057   std::vector<DetId> stripConstituents(int dccId, int tower, int strip) const;
0058 
0059   /// Get the constituent detids for this dccId
0060   std::vector<DetId> tccConstituents(int tccId) const;
0061 
0062   /// Get the constituent detids for this dccId
0063   std::vector<DetId> ttConstituents(int tccId, int tt) const;
0064 
0065   /// Get the constituent detids for this dccId
0066   std::vector<DetId> pseudoStripConstituents(int tccId, int tt, int pseudostrip) const;
0067 
0068   /// set the association between a DetId and a tower
0069   void assign(const DetId& cell, const EcalElectronicsId&, const EcalTriggerElectronicsId& tower);
0070 
0071   /** Retrieves the DCC channel that reads the crystals constituting an ECAL supercystal (SC).
0072    * For standard 5x5 complete SCs, there is a one-to-one matching between DCC channel and
0073    * SC. For partial SCs, the relation from SC to DCC channel is N-to-N.
0074    * The 3-2-1 partial SC type has 1 crystal read by a DCC channel and the others read by
0075    * another DCC channel. If the former crystal is ignored for the DCC channel matching,
0076    * then the SC-to-DCC channel association is simplified to 1-to-N relation.
0077    * This method uses this prescription and therefore returns a single DCC channel.
0078    * @param id SC identifier
0079    * @return DCC channel. .first: DCC ID (from 1 to 54); .second: channel within the DCC (from 1 to 68).
0080    * See http://hepwww.rl.ac.uk/CMSecal/Dee-layout.html, https://twiki.cern.ch/twiki/bin/view/CMS/EcalIndices,
0081    * and references thereby.
0082    */
0083   std::pair<int, int> getDCCandSC(EcalScDetId id) const;
0084 
0085   /** builds EcalScDetId's from (DCC, DCC_channel)
0086    *  Most of the time there is only one SC read-out by the DCC channel,
0087    * but few DCC channels read VPTs coming from two different partial SCs.
0088    * There are also 4 SCs per endcap whose one crystal is read out
0089    * by a different DCC channel than the others. In such case, the SC will be
0090    * assiociated to the DCC channel reading most of the crystals,
0091    * the DCC channel reading only one crystal being ignored.
0092    * @param ignoreSingleCrystal. There are four partial SCs per endcap
0093    * whose one crystal is read out by a different DCC channel than for the
0094    * other crystals. If this parameter is true these single crystals will
0095    * be ignored: if a SC has only one crystal read out by the DCC channel,
0096    * then the SC will not be included in the returned list.
0097    * a differentsimplification, SC read out by two different DCC channels
0098    * @return vector of SCs associated to the DCC channel.
0099    */
0100   std::vector<EcalScDetId> getEcalScDetId(int DCCid, int DCC_Channel, bool ignoreSingleCrystal = true) const;
0101 
0102   /// returns the DCC of an EBDetId
0103   int DCCid(const EBDetId& id) const;
0104 
0105   /// returns the TCCid of an EBDetId
0106   int TCCid(const EBDetId& id) const;
0107 
0108   /// returns the index of a Trigger Tower within its TCC.
0109   int iTT(const EcalTrigTowerDetId& id) const;
0110 
0111   /// returns the TCCid of a Trigger Tower
0112   int TCCid(const EcalTrigTowerDetId& id) const;
0113 
0114   /// returns the DCCid (i.e. the FED) of a Trigger Tower
0115   int DCCid(const EcalTrigTowerDetId& id) const;
0116 
0117   /// Builds a EcalTrigTowerDetID from the TCCid & TriggerTower index in TCC
0118   EcalTrigTowerDetId getTrigTowerDetId(int TCCid, int iTT) const;
0119 
0120   EcalSubdetector subdet(int dccid, int mode) const;
0121   int zside(int dcctcc, int mode) const;
0122 
0123   bool rightTower(int tower) const;
0124 
0125   // methods used for regional unpacking :
0126   std::vector<int> GetListofFEDs(const RectangularEtaPhiRegion& region) const;
0127   void GetListofFEDs(const RectangularEtaPhiRegion& region, std::vector<int>& FEDs) const;
0128   int GetFED(double eta, double phi) const;
0129   int DCCBoundary(int FED) const;
0130 
0131   // methods for retrieving the Laser Monitoring readout number
0132 
0133   int getLMNumber(const DetId& id) const;
0134 
0135   // Geometry of SM in EB :
0136   static const int kCrystalsInPhi = EBDetId::kCrystalsInPhi;  // per SM
0137   static const int kTowersInPhi = EBDetId::kTowersInPhi;      // per SM
0138 
0139   // Geometry of the Trigger Towers :
0140 
0141   static const int kEBTowersInPhi = EcalTrigTowerDetId::kEBTowersInPhi;                        // per SM (in the Barrel)
0142   static const int kEBTowersPerSM = EcalTrigTowerDetId::kEBTowersPerSM;                        // per SM (in the Barrel)
0143   static const int kEBTowersInEta = EcalTrigTowerDetId::kEBTowersInEta;                        // per SM (in the Barrel)
0144   static const int kEETowersInEta = EcalTrigTowerDetId::kEETowersInEta;                        // Endcap
0145   static const int kEETowersInPhiPerQuadrant = EcalTrigTowerDetId::kEETowersInPhiPerQuadrant;  // per Quadrant (EE)
0146 
0147   static const int kEETowersInPhiPerTCC = 4;       // each TCC contains 4 towers in phi
0148   static const int kEETowersInEtaPerInnerTCC = 7;  // each inner TCC contains 7 towers in eta
0149   static const int kEETowersInEtaPerOuterTCC = 4;  // each outer TCC contains 4 towers in eta
0150   static const int iEEEtaMinOuter = 18;            // outer TCC : ieta = 18 -> 21
0151   static const int iEEEtaMinInner = 22;            // inner TCC : ieta = 22 -> 28
0152 
0153   // DCC values :
0154   static const int MAX_DCCID = EcalElectronicsId::MAX_DCCID;  //To be updated with correct and final number
0155   static const int MIN_DCCID = EcalElectronicsId::MIN_DCCID;
0156   static const int MIN_DCCID_EEM = EcalElectronicsId::MIN_DCCID_EEM;
0157   static const int MAX_DCCID_EEM = EcalElectronicsId::MAX_DCCID_EEM;
0158   static const int MIN_DCCID_EBM = EcalElectronicsId::MIN_DCCID_EBM;
0159   static const int MAX_DCCID_EBM = EcalElectronicsId::MAX_DCCID_EBM;
0160   static const int MIN_DCCID_EBP = EcalElectronicsId::MIN_DCCID_EBP;
0161   static const int MAX_DCCID_EBP = EcalElectronicsId::MAX_DCCID_EBP;
0162   static const int MIN_DCCID_EEP = EcalElectronicsId::MIN_DCCID_EEP;
0163   static const int MAX_DCCID_EEP = EcalElectronicsId::MAX_DCCID_EEP;
0164 
0165   static const int DCCID_PHI0_EBM = EcalElectronicsId::DCCID_PHI0_EBM;  // contains phi = 0 deg.
0166   static const int DCCID_PHI0_EBP = EcalElectronicsId::DCCID_PHI0_EBP;
0167 
0168   // TCC values :
0169   static const int MAX_TCCID = EcalTriggerElectronicsId::MAX_TCCID;  //To be updated with correct and final number
0170   static const int MIN_TCCID = EcalTriggerElectronicsId::MIN_TCCID;
0171   static const int MIN_TCCID_EEM = EcalTriggerElectronicsId::MIN_TCCID_EEM;
0172   static const int MAX_TCCID_EEM = EcalTriggerElectronicsId::MAX_TCCID_EEM;
0173   static const int MIN_TCCID_EBM = EcalTriggerElectronicsId::MIN_TCCID_EBM;
0174   static const int MAX_TCCID_EBM = EcalTriggerElectronicsId::MAX_TCCID_EBM;
0175   static const int MIN_TCCID_EBP = EcalTriggerElectronicsId::MIN_TCCID_EBP;
0176   static const int MAX_TCCID_EBP = EcalTriggerElectronicsId::MAX_TCCID_EBP;
0177   static const int MIN_TCCID_EEP = EcalTriggerElectronicsId::MIN_TCCID_EEP;
0178   static const int MAX_TCCID_EEP = EcalTriggerElectronicsId::MAX_TCCID_EEP;
0179 
0180   static const int TCCID_PHI0_EBM = EcalTriggerElectronicsId::TCCID_PHI0_EBM;
0181   static const int TCCID_PHI0_EBP = EcalTriggerElectronicsId::TCCID_PHI0_EBP;
0182 
0183   static const int TCCID_PHI0_EEM_IN = EcalTriggerElectronicsId::TCCID_PHI0_EEM_IN;
0184   static const int TCCID_PHI0_EEM_OUT = EcalTriggerElectronicsId::TCCID_PHI0_EEM_OUT;
0185   static const int TCCID_PHI0_EEP_IN = EcalTriggerElectronicsId::TCCID_PHI0_EEP_IN;
0186   static const int TCCID_PHI0_EEP_OUT = EcalTriggerElectronicsId::TCCID_PHI0_EEP_OUT;
0187 
0188   static const int kTCCinPhi = 18;  // Number of TCC "sectors" in phi
0189 
0190   // LaserMonitoring readout numbers :
0191   static const int MIN_LM_EEM = 73;  // corresponds to MIN_DCCID_EEM
0192   static const int MIN_LM_EBM = 1;   // corresponds to MIN_DCCID_EBM
0193   static const int MIN_LM_EBP = 37;  // corresponds to MIN_DCCID_EBP
0194   static const int MIN_LM_EEP = 83;  // corresponds to MIN_DCCID_EEP
0195   static const int MAX_LM = 92;      // Total number of LaserModules
0196 
0197 private:
0198   static const int DCCMODE = 0;
0199   static const int TCCMODE = 1;
0200 
0201   /// Maybe these are needed
0202   /// Wrap a generic EEDetId to the equivalent one in z+ Quadrant 1 (from 0 < phi < pi/2)
0203   //  DetId wrapEEDetId(const DetId& id) const;
0204   /// Wrap a generic EcalTrigTowerDetId to the equivalent one in z+ Quadrant 1 (from 0 < phi < pi/2)
0205   //DetId wrapEcalTrigTowerDetId(const DetId& id) const;
0206   //DetId changeEEDetIdQuadrantAndZ(const DetId& fromid, const int& toQuadrant,const int& tozside) const;
0207   //  int changeTowerQuadrant(int phiTower, int fromQuadrant, int toQuadrant) const;
0208 
0209   struct MapItem {
0210     MapItem(const DetId& acell, const EcalElectronicsId& aelid, const EcalTriggerElectronicsId& atrelid)
0211         : cell(acell), elid(aelid), trelid(atrelid) {}
0212     DetId cell;
0213     EcalElectronicsId elid;
0214     EcalTriggerElectronicsId trelid;
0215     int dccId() const { return elid.dccId(); }
0216     int towerId() const { return elid.towerId(); }
0217     int stripId() const { return elid.stripId(); }
0218     int tccId() const { return trelid.tccId(); }
0219     int ttId() const { return trelid.ttId(); }
0220     int pseudoStripId() const { return trelid.pseudoStripId(); }
0221   };
0222 
0223   //hashed indexes to be preferred to ordered (faster for lookup, here we are not interested in ordering...)
0224   typedef boost::multi_index::multi_index_container<
0225       MapItem,
0226       boost::multi_index::indexed_by<
0227           // hashed_unique< member < MapItem,DetId,&MapItem::cell > >,
0228           // hashed_unique< member < MapItem,EcalElectronicsId,&MapItem::elid > >,
0229           // hashed_unique< member < MapItem,EcalTriggerElectronicsId,&MapItem::trelid > >
0230           boost::multi_index::ordered_unique<boost::multi_index::member<MapItem, DetId, &MapItem::cell> >,
0231           boost::multi_index::ordered_unique<boost::multi_index::member<MapItem, EcalElectronicsId, &MapItem::elid> >,
0232           boost::multi_index::ordered_unique<
0233               boost::multi_index::member<MapItem, EcalTriggerElectronicsId, &MapItem::trelid> >,
0234           boost::multi_index::ordered_non_unique<boost::multi_index::const_mem_fun<MapItem, int, &MapItem::dccId> >,
0235           boost::multi_index::ordered_non_unique<
0236               boost::multi_index::composite_key<MapItem,
0237                                                 boost::multi_index::const_mem_fun<MapItem, int, &MapItem::dccId>,
0238                                                 boost::multi_index::const_mem_fun<MapItem, int, &MapItem::towerId> > >,
0239           boost::multi_index::ordered_non_unique<
0240               boost::multi_index::composite_key<MapItem,
0241                                                 boost::multi_index::const_mem_fun<MapItem, int, &MapItem::dccId>,
0242                                                 boost::multi_index::const_mem_fun<MapItem, int, &MapItem::towerId>,
0243                                                 boost::multi_index::const_mem_fun<MapItem, int, &MapItem::stripId> > >,
0244           boost::multi_index::ordered_non_unique<boost::multi_index::const_mem_fun<MapItem, int, &MapItem::tccId> >,
0245           boost::multi_index::ordered_non_unique<
0246               boost::multi_index::composite_key<MapItem,
0247                                                 boost::multi_index::const_mem_fun<MapItem, int, &MapItem::tccId>,
0248                                                 boost::multi_index::const_mem_fun<MapItem, int, &MapItem::ttId> > >,
0249           boost::multi_index::ordered_non_unique<boost::multi_index::composite_key<
0250               MapItem,
0251               boost::multi_index::const_mem_fun<MapItem, int, &MapItem::tccId>,
0252               boost::multi_index::const_mem_fun<MapItem, int, &MapItem::ttId>,
0253               boost::multi_index::const_mem_fun<MapItem, int, &MapItem::pseudoStripId> > > > >
0254       EcalElectronicsMap;
0255 
0256   typedef EcalElectronicsMap::nth_index<0>::type EcalElectronicsMap_by_DetId;
0257   typedef EcalElectronicsMap::nth_index<1>::type EcalElectronicsMap_by_ElectronicsId;
0258   typedef EcalElectronicsMap::nth_index<2>::type EcalElectronicsMap_by_TriggerElectronicsId;
0259 
0260   typedef EcalElectronicsMap::nth_index<3>::type EcalElectronicsMap_by_DccId;
0261   typedef EcalElectronicsMap::nth_index<4>::type EcalElectronicsMap_by_DccId_and_TowerId;
0262   typedef EcalElectronicsMap::nth_index<5>::type EcalElectronicsMap_by_DccId_TowerId_and_StripId;
0263 
0264   typedef EcalElectronicsMap::nth_index<6>::type EcalElectronicsMap_by_TccId;
0265   typedef EcalElectronicsMap::nth_index<7>::type EcalElectronicsMap_by_TccId_and_TtId;
0266   typedef EcalElectronicsMap::nth_index<8>::type EcalElectronicsMap_by_TccId_TtId_and_PseudostripId;
0267 
0268   //Needed only in the EE (contains only first quadrant object)
0269   EcalElectronicsMap m_items;
0270 
0271   // Maps between DCC and LaserMonitoring readout numbers (take care that EB DCCs and two EE DCCs
0272   // actually correspond to two LMs. The map contain only the first one).
0273   // The maps are filled in the constructor of EcalElectronicsMapping.
0274 
0275   std::map<int, int> LaserMonitoringMap_EB;
0276   std::map<int, int> LaserMonitoringMap_EE;
0277 };
0278 
0279 #endif