File indexing completed on 2024-04-06 12:11:01
0001 #ifndef EventFilter_SiStripRawToDigi_SiStripDetSetVectorFiller_H
0002 #define EventFilter_SiStripRawToDigi_SiStripDetSetVectorFiller_H
0003
0004 #include "DataFormats/Common/interface/DetSetVector.h"
0005 #include <vector>
0006 #include <algorithm>
0007 #include <memory>
0008 #include <cstdint>
0009 class SiStripRawDigi;
0010 class SiStripDigi;
0011
0012 namespace sistrip {
0013
0014
0015
0016
0017 template <typename T, bool dsvIsSparse>
0018 class DetSetVectorFiller {
0019 public:
0020 DetSetVectorFiller(const size_t registrySize, const size_t dataSize);
0021 ~DetSetVectorFiller();
0022
0023 void newChannel(const uint32_t key, const uint16_t firstItem = 0);
0024 void addItem(const T& item);
0025 std::unique_ptr<edm::DetSetVector<T> > createDetSetVector();
0026
0027 private:
0028 struct ChannelRegistryItem {
0029 ChannelRegistryItem(const uint32_t theKey,
0030 const uint32_t theStartIndex,
0031 const uint16_t theLength,
0032 const uint16_t theFirstItem)
0033 : key(theKey), startIndex(theStartIndex), length(theLength), firstItem(theFirstItem) {}
0034 bool operator<(const ChannelRegistryItem& other) const {
0035 return ((this->key != other.key) ? (this->key < other.key) : (this->firstItem < other.firstItem));
0036 }
0037 uint32_t key;
0038 uint32_t startIndex;
0039 uint16_t length;
0040 uint16_t firstItem;
0041 };
0042 typedef std::vector<ChannelRegistryItem> Registry;
0043 typedef std::vector<T> Data;
0044
0045 Registry registry_;
0046 Data data_;
0047 };
0048
0049 template <typename T, bool dsvIsSparse>
0050 inline DetSetVectorFiller<T, dsvIsSparse>::DetSetVectorFiller(const size_t registrySize, const size_t dataSize) {
0051 registry_.reserve(registrySize);
0052 data_.reserve(dataSize);
0053 }
0054
0055 template <typename T, bool dsvIsSparse>
0056 inline DetSetVectorFiller<T, dsvIsSparse>::~DetSetVectorFiller() {}
0057
0058 template <typename T, bool dsvIsSparse>
0059 inline void DetSetVectorFiller<T, dsvIsSparse>::newChannel(const uint32_t key, const uint16_t firstItem) {
0060 registry_.push_back(ChannelRegistryItem(key, data_.size(), 0, firstItem));
0061 }
0062
0063 template <typename T, bool dsvIsSparse>
0064 inline void DetSetVectorFiller<T, dsvIsSparse>::addItem(const T& item) {
0065 data_.push_back(item);
0066 registry_.back().length++;
0067 }
0068
0069 template <typename T, bool dsvIsSparse>
0070 std::unique_ptr<edm::DetSetVector<T> > DetSetVectorFiller<T, dsvIsSparse>::createDetSetVector() {
0071 std::sort(registry_.begin(), registry_.end());
0072 std::vector<edm::DetSet<T> > sorted_and_merged;
0073 sorted_and_merged.reserve(registry_.size());
0074 typename Registry::const_iterator iReg = registry_.begin();
0075 const typename Registry::const_iterator endReg = registry_.end();
0076 while (iReg != endReg) {
0077 sorted_and_merged.push_back(edm::DetSet<T>(iReg->key));
0078 std::vector<T>& detSetData = sorted_and_merged.back().data;
0079 typename Registry::const_iterator jReg;
0080 if (dsvIsSparse) {
0081 uint16_t length = 0;
0082 for (jReg = iReg; (jReg != endReg) && (jReg->key == iReg->key); ++jReg)
0083 length += jReg->length;
0084 detSetData.reserve(length);
0085 for (jReg = iReg; (jReg != endReg) && (jReg->key == iReg->key); ++jReg) {
0086 detSetData.insert(
0087 detSetData.end(), data_.begin() + jReg->startIndex, data_.begin() + jReg->startIndex + jReg->length);
0088 }
0089 } else {
0090 uint16_t detLength = 0;
0091 uint16_t firstItemOfLastChannel = 0;
0092 for (jReg = iReg; (jReg != endReg) && (jReg->key == iReg->key); ++jReg) {
0093 if (!detLength)
0094 detLength = jReg->length;
0095 else if (detLength != jReg->length)
0096 throw cms::Exception("DetSetVectorFiller")
0097 << "Cannot fill non-sparse DetSet if channels are not unformly sized.";
0098 firstItemOfLastChannel = jReg->firstItem;
0099 }
0100 detSetData.resize(firstItemOfLastChannel + detLength);
0101 for (jReg = iReg; (jReg != endReg) && (jReg->key == iReg->key); ++jReg) {
0102 std::copy(data_.begin() + jReg->startIndex,
0103 data_.begin() + jReg->startIndex + jReg->length,
0104 detSetData.begin() + jReg->firstItem);
0105 }
0106 }
0107 iReg = jReg;
0108 }
0109 return typename std::unique_ptr<edm::DetSetVector<T> >(new edm::DetSetVector<T>(sorted_and_merged, true));
0110 }
0111
0112 typedef DetSetVectorFiller<SiStripRawDigi, false> RawDigiDetSetVectorFiller;
0113 typedef DetSetVectorFiller<SiStripDigi, true> ZSDigiDetSetVectorFiller;
0114 }
0115
0116 #endif