Go to the documentation of this file.00001 #ifndef EventFilter_SiStripRawToDigi_SiStripDetSetVectorFiller_H
00002 #define EventFilter_SiStripRawToDigi_SiStripDetSetVectorFiller_H
00003
00004 #include "DataFormats/Common/interface/DetSetVector.h"
00005 #include "boost/cstdint.hpp"
00006 #include <vector>
00007 #include <algorithm>
00008 #include <memory>
00009 class SiStripRawDigi;
00010 class SiStripDigi;
00011
00012 namespace sistrip {
00013
00014
00015
00016
00017 template<typename T, bool dsvIsSparse> class DetSetVectorFiller
00018 {
00019 public:
00020 DetSetVectorFiller(const size_t registrySize, const size_t dataSize);
00021 ~DetSetVectorFiller();
00022
00023 void newChannel(const uint32_t key, const uint16_t firstItem = 0);
00024 void addItem(const T& item);
00025 std::auto_ptr< edm::DetSetVector<T> > createDetSetVector();
00026 private:
00027 struct ChannelRegistryItem
00028 {
00029 ChannelRegistryItem(const uint32_t theKey, const uint32_t theStartIndex, const uint16_t theLength, const uint16_t theFirstItem)
00030 : key(theKey), startIndex(theStartIndex), length(theLength), firstItem(theFirstItem) {}
00031 bool operator < (const ChannelRegistryItem& other) const
00032 { return ( (this->key != other.key) ? (this->key < other.key) : (this->firstItem < other.firstItem) ); }
00033 uint32_t key;
00034 uint32_t startIndex;
00035 uint16_t length;
00036 uint16_t firstItem;
00037 };
00038 typedef std::vector<ChannelRegistryItem> Registry;
00039 typedef std::vector<T> Data;
00040
00041 Registry registry_;
00042 Data data_;
00043 };
00044
00045 template<typename T, bool dsvIsSparse> inline DetSetVectorFiller<T,dsvIsSparse>::DetSetVectorFiller(const size_t registrySize, const size_t dataSize)
00046 {
00047 registry_.reserve(registrySize);
00048 data_.reserve(dataSize);
00049 }
00050
00051 template<typename T, bool dsvIsSparse> inline DetSetVectorFiller<T,dsvIsSparse>::~DetSetVectorFiller()
00052 {}
00053
00054 template<typename T, bool dsvIsSparse> inline void DetSetVectorFiller<T,dsvIsSparse>::newChannel(const uint32_t key, const uint16_t firstItem)
00055 {
00056 registry_.push_back( ChannelRegistryItem(key,data_.size(),0,firstItem) );
00057 }
00058
00059 template<typename T, bool dsvIsSparse> inline void DetSetVectorFiller<T,dsvIsSparse>::addItem(const T& item)
00060 {
00061 data_.push_back(item);
00062 registry_.back().length++;
00063 }
00064
00065 template<typename T, bool dsvIsSparse> std::auto_ptr< edm::DetSetVector<T> > DetSetVectorFiller<T,dsvIsSparse>::createDetSetVector()
00066 {
00067 std::sort(registry_.begin(),registry_.end());
00068 std::vector< edm::DetSet<T> > sorted_and_merged;
00069 sorted_and_merged.reserve(registry_.size());
00070 typename Registry::const_iterator iReg = registry_.begin();
00071 const typename Registry::const_iterator endReg = registry_.end();
00072 while (iReg != endReg) {
00073 sorted_and_merged.push_back( edm::DetSet<T>(iReg->key) );
00074 std::vector<T>& detSetData = sorted_and_merged.back().data;
00075 typename Registry::const_iterator jReg;
00076 if (dsvIsSparse) {
00077 uint16_t length = 0;
00078 for (jReg = iReg; (jReg != endReg) && (jReg->key == iReg->key); ++jReg) length += jReg->length;
00079 detSetData.reserve(length);
00080 for (jReg = iReg; (jReg != endReg) && (jReg->key == iReg->key); ++jReg) {
00081 detSetData.insert(detSetData.end(), data_.begin()+jReg->startIndex, data_.begin()+jReg->startIndex+jReg->length);
00082 }
00083 } else {
00084 uint16_t detLength = 0;
00085 uint16_t firstItemOfLastChannel = 0;
00086 for (jReg = iReg; (jReg != endReg) && (jReg->key == iReg->key); ++jReg) {
00087 if (!detLength) detLength = jReg->length;
00088 else if (detLength != jReg->length) throw cms::Exception("DetSetVectorFiller") << "Cannot fill non-sparse DetSet if channels are not unformly sized.";
00089 firstItemOfLastChannel = jReg->firstItem;
00090 }
00091 detSetData.resize(firstItemOfLastChannel+detLength);
00092 for (jReg = iReg; (jReg != endReg) && (jReg->key == iReg->key); ++jReg) {
00093 std::copy(data_.begin()+jReg->startIndex, data_.begin()+jReg->startIndex+jReg->length, detSetData.begin()+jReg->firstItem);
00094 }
00095 }
00096 iReg = jReg;
00097 }
00098 return typename std::auto_ptr< edm::DetSetVector<T> >( new edm::DetSetVector<T>(sorted_and_merged, true) );
00099 }
00100
00101 typedef DetSetVectorFiller<SiStripRawDigi,false> RawDigiDetSetVectorFiller;
00102 typedef DetSetVectorFiller<SiStripDigi,true> ZSDigiDetSetVectorFiller;
00103 }
00104
00105 #endif // EventFilter_SiStripRawToDigi_SiStripDetSetVectorFiller_H