CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/EventFilter/SiStripRawToDigi/interface/SiStripDetSetVectorFiller.h

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   //A class to fill a DetSetVector from data from different channels only sorting once
00015   
00016   //T is type of object in DetSetVector (SiStripRawDigi, SiStripDigi), dsvIsSparse should be false for raw digis so null digis are inserted
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;      //ID of DetSet in DetSetVector
00034       uint32_t startIndex;  //index of first item in data container
00035       uint16_t length;      //number of items
00036       uint16_t firstItem;   //index of first item in final DetSet
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