Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:53:23

0001 #ifndef DataFormats_FTLDigi_PMTDSimAccumulator_h
0002 #define DataFormats_FTLDigi_PMTDSimAccumulator_h
0003 
0004 #include "DataFormats/DetId/interface/DetId.h"
0005 
0006 #include <vector>
0007 #include <cassert>
0008 
0009 class PMTDSimAccumulator {
0010 public:
0011   // These two structs are public only because of dictionary generation
0012   class DetIdSize {
0013   public:
0014     DetIdSize() {}
0015     DetIdSize(unsigned int detId, unsigned char row, unsigned char col) : detId_(detId), row_(row), column_(col) {}
0016 
0017     void increaseSize() { ++size_; }
0018 
0019     unsigned int detId() const { return detId_; }
0020     unsigned char row() const { return row_; }
0021     unsigned char column() const { return column_; }
0022     unsigned int size() const { return size_; }
0023 
0024   private:
0025     unsigned int detId_ = 0;
0026     unsigned char row_ = 0;
0027     unsigned char column_ = 0;
0028     unsigned char size_ = 0;
0029   };
0030   class Data {
0031   public:
0032     constexpr static unsigned energyOffset = 4;
0033     constexpr static unsigned energyMask = 0x3;
0034     constexpr static unsigned sampleMask = 0xf;
0035     constexpr static unsigned dataMask = 0xffff;
0036 
0037     Data() : data_(0), indices_(0) {}
0038     Data(unsigned short ei, unsigned short si, unsigned short d) : data_(d), indices_((ei << energyOffset) | si) {}
0039 
0040     unsigned int energyIndex() const { return indices_ >> energyOffset; }
0041     unsigned int sampleIndex() const { return indices_ & sampleMask; }
0042     unsigned int data() const { return data_ & dataMask; }
0043 
0044   private:
0045     unsigned short data_;
0046     unsigned char indices_;
0047   };
0048 
0049   PMTDSimAccumulator() = default;
0050   ~PMTDSimAccumulator() = default;
0051 
0052   void reserve(size_t size) {
0053     detIdSize_.reserve(size);
0054     data_.reserve(size);
0055   }
0056 
0057   void shrink_to_fit() {
0058     detIdSize_.shrink_to_fit();
0059     data_.shrink_to_fit();
0060   }
0061 
0062   /**
0063    * Adds data for a given detId, energyIndex, and sampleIndex.
0064    *
0065    * It is the caller's responsibility to ensure that energyIndex,
0066    * sampleIndex, and data fit in the space reserved for them in the
0067    * Data bitfield above.
0068    */
0069   void emplace_back(unsigned int detId,
0070                     unsigned char row,
0071                     unsigned char column,
0072                     unsigned short energyIndex,
0073                     unsigned short sampleIndex,
0074                     unsigned short data) {
0075     if (detIdSize_.empty() || detIdSize_.back().detId() != detId || detIdSize_.back().row() != row ||
0076         detIdSize_.back().column() != column) {
0077       detIdSize_.emplace_back(detId, row, column);
0078     }
0079     data_.emplace_back(energyIndex, sampleIndex, data);
0080     detIdSize_.back().increaseSize();
0081   }
0082 
0083   class TmpElem {
0084   public:
0085     TmpElem(unsigned int detId, unsigned char row, unsigned char column, Data data)
0086         : detId_(detId), data_(data), row_(row), column_(column) {}
0087 
0088     unsigned int detId() const { return detId_; }
0089     unsigned char row() const { return row_; }
0090     unsigned char column() const { return column_; }
0091     unsigned short energyIndex() const { return data_.energyIndex(); }
0092     unsigned short sampleIndex() const { return data_.sampleIndex(); }
0093     unsigned short data() const { return data_.data(); }
0094 
0095   private:
0096     unsigned int detId_;
0097     Data data_;
0098     unsigned char row_;
0099     unsigned char column_;
0100   };
0101 
0102   class const_iterator {
0103   public:
0104     // begin
0105     const_iterator(const PMTDSimAccumulator* acc)
0106         : acc_(acc), iDet_(0), iData_(0), endData_(acc->detIdSize_.empty() ? 0 : acc->detIdSize_.front().size()) {}
0107 
0108     // end
0109     const_iterator(const PMTDSimAccumulator* acc, unsigned int detSize, unsigned int dataSize)
0110         : acc_(acc), iDet_(detSize), iData_(dataSize), endData_(0) {}
0111 
0112     bool operator==(const const_iterator& other) const { return iDet_ == other.iDet_ && iData_ == other.iData_; }
0113     bool operator!=(const const_iterator& other) const { return !operator==(other); }
0114     const_iterator& operator++() {
0115       ++iData_;
0116       if (iData_ == endData_) {
0117         ++iDet_;
0118         endData_ += (iDet_ == acc_->detIdSize_.size()) ? 0 : acc_->detIdSize_[iDet_].size();
0119       }
0120       return *this;
0121     }
0122     const_iterator operator++(int) {
0123       auto tmp = *this;
0124       ++(*this);
0125       return tmp;
0126     }
0127     TmpElem operator*() {
0128       const auto& id = acc_->detIdSize_[iDet_];
0129       return TmpElem(id.detId(), id.row(), id.column(), acc_->data_[iData_]);
0130     }
0131 
0132   private:
0133     const PMTDSimAccumulator* acc_;
0134     unsigned int iDet_;
0135     unsigned int iData_;
0136     unsigned int endData_;
0137   };
0138 
0139   TmpElem back() const {
0140     const auto& id = detIdSize_.back();
0141     return TmpElem(id.detId(), id.row(), id.column(), data_.back());
0142   }
0143 
0144   const_iterator cbegin() const { return const_iterator(this); }
0145   const_iterator begin() const { return cbegin(); }
0146   const_iterator cend() const { return const_iterator(this, detIdSize_.size(), data_.size()); }
0147   const_iterator end() const { return cend(); }
0148 
0149 private:
0150   std::vector<DetIdSize> detIdSize_;
0151   std::vector<Data> data_;
0152 };
0153 
0154 #endif