File indexing completed on 2024-04-06 12:04:09
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
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
0064
0065
0066
0067
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
0105 const_iterator(const PMTDSimAccumulator* acc)
0106 : acc_(acc), iDet_(0), iData_(0), endData_(acc->detIdSize_.empty() ? 0 : acc->detIdSize_.front().size()) {}
0107
0108
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