Data

DetIdSize

PMTDSimAccumulator

TmpElem

const_iterator

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
#ifndef DataFormats_FTLDigi_PMTDSimAccumulator_h
#define DataFormats_FTLDigi_PMTDSimAccumulator_h

#include "DataFormats/DetId/interface/DetId.h"

#include <vector>
#include <cassert>

class PMTDSimAccumulator {
public:
  // These two structs are public only because of dictionary generation
  class DetIdSize {
  public:
    DetIdSize() {}
    DetIdSize(unsigned int detId, unsigned char row, unsigned char col) : detId_(detId), row_(row), column_(col) {}

    void increaseSize() { ++size_; }

    unsigned int detId() const { return detId_; }
    unsigned char row() const { return row_; }
    unsigned char column() const { return column_; }
    unsigned int size() const { return size_; }

  private:
    unsigned int detId_ = 0;
    unsigned char row_ = 0;
    unsigned char column_ = 0;
    unsigned char size_ = 0;
  };
  class Data {
  public:
    constexpr static unsigned energyOffset = 4;
    constexpr static unsigned energyMask = 0x3;
    constexpr static unsigned sampleMask = 0xf;
    constexpr static unsigned dataMask = 0xffff;

    Data() : data_(0), indices_(0) {}
    Data(unsigned short ei, unsigned short si, unsigned short d) : data_(d), indices_((ei << energyOffset) | si) {}

    unsigned int energyIndex() const { return indices_ >> energyOffset; }
    unsigned int sampleIndex() const { return indices_ & sampleMask; }
    unsigned int data() const { return data_ & dataMask; }

  private:
    unsigned short data_;
    unsigned char indices_;
  };

  PMTDSimAccumulator() = default;
  ~PMTDSimAccumulator() = default;

  void reserve(size_t size) {
    detIdSize_.reserve(size);
    data_.reserve(size);
  }

  void shrink_to_fit() {
    detIdSize_.shrink_to_fit();
    data_.shrink_to_fit();
  }

  /**
   * Adds data for a given detId, energyIndex, and sampleIndex.
   *
   * It is the caller's responsibility to ensure that energyIndex,
   * sampleIndex, and data fit in the space reserved for them in the
   * Data bitfield above.
   */
  void emplace_back(unsigned int detId,
                    unsigned char row,
                    unsigned char column,
                    unsigned short energyIndex,
                    unsigned short sampleIndex,
                    unsigned short data) {
    if (detIdSize_.empty() || detIdSize_.back().detId() != detId || detIdSize_.back().row() != row ||
        detIdSize_.back().column() != column) {
      detIdSize_.emplace_back(detId, row, column);
    }
    data_.emplace_back(energyIndex, sampleIndex, data);
    detIdSize_.back().increaseSize();
  }

  class TmpElem {
  public:
    TmpElem(unsigned int detId, unsigned char row, unsigned char column, Data data)
        : detId_(detId), data_(data), row_(row), column_(column) {}

    unsigned int detId() const { return detId_; }
    unsigned char row() const { return row_; }
    unsigned char column() const { return column_; }
    unsigned short energyIndex() const { return data_.energyIndex(); }
    unsigned short sampleIndex() const { return data_.sampleIndex(); }
    unsigned short data() const { return data_.data(); }

  private:
    unsigned int detId_;
    Data data_;
    unsigned char row_;
    unsigned char column_;
  };

  class const_iterator {
  public:
    // begin
    const_iterator(const PMTDSimAccumulator* acc)
        : acc_(acc), iDet_(0), iData_(0), endData_(acc->detIdSize_.empty() ? 0 : acc->detIdSize_.front().size()) {}

    // end
    const_iterator(const PMTDSimAccumulator* acc, unsigned int detSize, unsigned int dataSize)
        : acc_(acc), iDet_(detSize), iData_(dataSize), endData_(0) {}

    bool operator==(const const_iterator& other) const { return iDet_ == other.iDet_ && iData_ == other.iData_; }
    bool operator!=(const const_iterator& other) const { return !operator==(other); }
    const_iterator& operator++() {
      ++iData_;
      if (iData_ == endData_) {
        ++iDet_;
        endData_ += (iDet_ == acc_->detIdSize_.size()) ? 0 : acc_->detIdSize_[iDet_].size();
      }
      return *this;
    }
    const_iterator operator++(int) {
      auto tmp = *this;
      ++(*this);
      return tmp;
    }
    TmpElem operator*() {
      const auto& id = acc_->detIdSize_[iDet_];
      return TmpElem(id.detId(), id.row(), id.column(), acc_->data_[iData_]);
    }

  private:
    const PMTDSimAccumulator* acc_;
    unsigned int iDet_;
    unsigned int iData_;
    unsigned int endData_;
  };

  TmpElem back() const {
    const auto& id = detIdSize_.back();
    return TmpElem(id.detId(), id.row(), id.column(), data_.back());
  }

  const_iterator cbegin() const { return const_iterator(this); }
  const_iterator begin() const { return cbegin(); }
  const_iterator cend() const { return const_iterator(this, detIdSize_.size(), data_.size()); }
  const_iterator end() const { return cend(); }

private:
  std::vector<DetIdSize> detIdSize_;
  std::vector<Data> data_;
};

#endif