Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:26:19

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   //A class to fill a DetSetVector from data from different channels only sorting once
0015 
0016   //T is type of object in DetSetVector (SiStripRawDigi, SiStripDigi), dsvIsSparse should be false for raw digis so null digis are inserted
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;         //ID of DetSet in DetSetVector
0038       uint32_t startIndex;  //index of first item in data container
0039       uint16_t length;      //number of items
0040       uint16_t firstItem;   //index of first item in final DetSet
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 }  // namespace sistrip
0115 
0116 #endif  // EventFilter_SiStripRawToDigi_SiStripDetSetVectorFiller_H