Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:04:30

0001 #ifndef DataFormats_L1Scouting_OrbitCollection_h
0002 #define DataFormats_L1Scouting_OrbitCollection_h
0003 
0004 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0006 #include "FWCore/Utilities/interface/Span.h"
0007 
0008 #include <cstdint>
0009 #include <vector>
0010 
0011 template <class T>
0012 class OrbitCollection {
0013 public:
0014   typedef typename std::vector<T>::iterator iterator;
0015   typedef typename std::vector<T>::const_iterator const_iterator;
0016   typedef T value_type;
0017   typedef typename std::vector<T>::size_type size_type;
0018 
0019   // Initialize the offset vector with 0s from 0 to 3565.
0020   // BX range is [1,3564], an extra entry is needed for the offserts of the last BX
0021   OrbitCollection() : bxOffsets_(orbitBufferSize_ + 1, 0), data_(0) {}
0022   // Construct the flat orbit collection starting from an OrbitBuffer.
0023   // The method fillAndClear will be used, meaning that, after copying the objects,
0024   // orbitBuffer's vectors will be cleared.
0025   OrbitCollection(std::vector<std::vector<T>>& orbitBuffer, unsigned nObjects = 0)
0026       : bxOffsets_(orbitBufferSize_ + 1, 0), data_(nObjects) {
0027     fillAndClear(orbitBuffer, nObjects);
0028   }
0029 
0030   OrbitCollection(const OrbitCollection& other) = default;
0031   OrbitCollection(OrbitCollection&& other) = default;
0032   OrbitCollection& operator=(const OrbitCollection& other) = default;
0033   OrbitCollection& operator=(OrbitCollection&& other) = default;
0034 
0035   // Fill the orbit collection starting from a vector of vectors, one per BX.
0036   // Objects are copied into a flat data vector, and a second vector is used to keep track
0037   // of the starting index in the data vector for every BX.
0038   // After the copy, the original input buffer is cleared.
0039   // Input vector must be sorted with increasing BX and contain 3565 elements (BX in [1,3564])
0040   void fillAndClear(std::vector<std::vector<T>>& orbitBuffer, unsigned nObjects = 0) {
0041     if (orbitBuffer.size() != orbitBufferSize_)
0042       throw cms::Exception("OrbitCollection::fillAndClear")
0043           << "Trying to fill the collection by passing an orbit buffer with incorrect size. "
0044           << "Passed " << orbitBuffer.size() << ", expected 3565";
0045     data_.reserve(nObjects);
0046     bxOffsets_[0] = 0;
0047     unsigned bxIdx = 1;
0048     for (auto& bxVec : orbitBuffer) {
0049       // increase offset by the currect vec size
0050       bxOffsets_[bxIdx] = bxOffsets_[bxIdx - 1] + bxVec.size();
0051 
0052       // if bxVec contains something, copy it into the data_ vector
0053       // and clear original bxVec objects
0054       if (bxVec.size() > 0) {
0055         data_.insert(data_.end(), bxVec.begin(), bxVec.end());
0056         bxVec.clear();
0057       }
0058 
0059       // increment bx index
0060       bxIdx++;
0061     }
0062   }
0063 
0064   // iterate over all elements contained in data
0065   const_iterator begin() const { return data_.begin(); }
0066   const_iterator end() const { return data_.end(); }
0067 
0068   // iterate over elements of a bx
0069   edm::Span<const_iterator> bxIterator(unsigned bx) const {
0070     if (bx >= orbitBufferSize_)
0071       throw cms::Exception("OrbitCollection::bxIterator") << "Trying to access and object outside the orbit range. "
0072                                                           << " BX = " << bx;
0073     if (getBxSize(bx) > 0) {
0074       return edm::Span(data_.begin() + bxOffsets_[bx], data_.begin() + bxOffsets_[bx + 1]);
0075     } else {
0076       return edm::Span(end(), end());
0077     }
0078   }
0079 
0080   // get number of objects stored in a BX
0081   unsigned getBxSize(unsigned bx) const {
0082     if (bx >= orbitBufferSize_) {
0083       cms::Exception("OrbitCollection") << "Called getBxSize() of a bx out of the orbit range."
0084                                         << " BX = " << bx;
0085       return 0;
0086     }
0087     return bxOffsets_[bx + 1] - bxOffsets_[bx];
0088   }
0089 
0090   // get i-th object from BX
0091   const T& getBxObject(unsigned bx, unsigned i) const {
0092     if (bx >= orbitBufferSize_)
0093       throw cms::Exception("OrbitCollection::getBxObject") << "Trying to access and object outside the orbit range. "
0094                                                            << " BX = " << bx;
0095     if (i >= getBxSize(bx))
0096       throw cms::Exception("OrbitCollection::getBxObject")
0097           << "Trying to get element " << i << " but for"
0098           << " BX = " << bx << " there are " << getBxSize(bx) << " elements.";
0099 
0100     return data_[bxOffsets_[bx] + i];
0101   }
0102 
0103   // get the list of non empty BXs
0104   std::vector<unsigned> getFilledBxs() const {
0105     std::vector<unsigned> filledBxVec;
0106     if (!data_.empty()) {
0107       for (unsigned bx = 0; bx < orbitBufferSize_; bx++) {
0108         if ((bxOffsets_[bx + 1] - bxOffsets_[bx]) > 0)
0109           filledBxVec.push_back(bx);
0110       }
0111     }
0112     return filledBxVec;
0113   }
0114 
0115   int size() const { return data_.size(); }
0116 
0117   T& operator[](std::size_t i) { return data_[i]; }
0118   const T& operator[](std::size_t i) const { return data_[i]; }
0119 
0120   // used by ROOT storage
0121   CMS_CLASS_VERSION(3)
0122 
0123 private:
0124   // store data vector and BX offsets as flat vectors.
0125   // offset contains one entry per BX, indicating the starting index
0126   // of the objects for that BX.
0127   std::vector<unsigned> bxOffsets_;
0128   std::vector<T> data_;
0129 
0130   // there are 3564 BX in one orbtit [1,3564], one extra
0131   // count added to keep first entry of the vector
0132   static constexpr int orbitBufferSize_ = 3565;
0133 };
0134 
0135 #endif  // DataFormats_L1Scouting_OrbitCollection_h