Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-11-29 01:33:13

0001 #ifndef CROSSING_FRAME_H
0002 #define CROSSING_FRAME_H
0003 
0004 /** \class CrossingFrame
0005  *
0006  * CrossingFrame is the result of the Sim Mixing Module
0007  *
0008  * \author Ursula Berthon, Claude Charlot,  LLR Palaiseau
0009  *
0010  * \version   1st Version July 2005
0011  * \version   2nd Version Sep 2005
0012  * \version   3rd Version Nov 2007
0013  *
0014  ************************************************************/
0015 
0016 #include "SimDataFormats/Track/interface/SimTrackContainer.h"
0017 #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h"
0018 #include "SimDataFormats/CaloHit/interface/PCaloHitContainer.h"
0019 #include "SimDataFormats/Vertex/interface/SimVertexContainer.h"
0020 #include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h"
0021 
0022 #include "DataFormats/Provenance/interface/EventID.h"
0023 #include "DataFormats/Common/interface/Wrapper.h"
0024 #include "SimDataFormats/EncodedEventId/interface/EncodedEventId.h"
0025 
0026 template <class T>
0027 class PCrossingFrame;
0028 
0029 #include <vector>
0030 #include <string>
0031 #include <iostream>
0032 #include <utility>
0033 #include <algorithm>
0034 #include <memory>
0035 
0036 template <class T>
0037 class CrossingFrame {
0038 public:
0039   // con- and destructors
0040 
0041   CrossingFrame() : firstCrossing_(0), lastCrossing_(0), bunchSpace_(75), subdet_(""), maxNbSources_(0) {}
0042   CrossingFrame(int minb, int maxb, int bunchsp, std::string subdet, unsigned int maxNbSources);
0043   CrossingFrame(const CrossingFrame& v) = default;
0044 
0045   ~CrossingFrame() { ; }
0046 
0047   void swap(CrossingFrame& other);
0048 
0049   CrossingFrame& operator=(CrossingFrame const& rhs);
0050 
0051   //standard version
0052   void addSignals(const std::vector<T>* vec, edm::EventID id);
0053   // version for HepMCProduct
0054   void addSignals(const T* vec, edm::EventID id);
0055 
0056   // standard version
0057   void addPileups(std::vector<T> const& vec);
0058   // version for HepMCProduct
0059   void addPileups(T const& product);
0060 
0061   void setTof();
0062 
0063   // we keep the shared pointer in the object that will be only destroyed at the end of the event (transient object!)
0064   // because of HepMCProduct, we need 2 versions...
0065   /*   void setPileupPtr(std::shared_ptr<edm::Wrapper<std::vector<T> > const> shPtr) {shPtrPileups_=shPtr;} */
0066   /*   void setPileupPtr(std::shared_ptr<edm::Wrapper<T> const> shPtr) {shPtrPileups2_=shPtr;} */
0067   void setPileupPtr(std::shared_ptr<edm::Wrapper<std::vector<T> > const> shPtr) { shPtrPileups_.push_back(shPtr); }
0068   void setPileupPtr(std::shared_ptr<edm::Wrapper<T> const> shPtr) { shPtrPileups2_.push_back(shPtr); }
0069   // used in the Step2 to set the PCrossingFrame
0070   void setPileupPtr(std::shared_ptr<edm::Wrapper<PCrossingFrame<T> > const> shPtr);
0071 
0072   void print(int level = 0) const;
0073 
0074   void setBcrOffset() { pileupOffsetsBcr_.push_back(pileups_.size()); }
0075 
0076   void setSourceOffset(const unsigned int s) { pileupOffsetsSource_[s].push_back(pileups_.size()); }
0077 
0078   //getters
0079   edm::EventID getEventID() const { return id_; }
0080   std::pair<int, int> getBunchRange() const { return std::pair<int, int>(firstCrossing_, lastCrossing_); }
0081   int getBunchSpace() const { return bunchSpace_; }
0082   unsigned int getMaxNbSources() const { return maxNbSources_; }
0083   std::string getSubDet() const { return subdet_; }
0084   unsigned int getPileupFileNr() const { return pileupFileNr_; }
0085   edm::EventID getIdFirstPileup() const { return idFirstPileup_; }
0086   const std::vector<unsigned int>& getPileupOffsetsBcr() const { return pileupOffsetsBcr_; }
0087   const std::vector<std::vector<unsigned int> >& getPileupOffsetsSource() const {
0088     return pileupOffsetsSource_;
0089   }  //one per source
0090   const std::vector<const T*>& getPileups() const { return pileups_; }
0091   const std::vector<const T*>& getSignal() const { return signals_; }
0092 
0093   void getSignal(typename std::vector<const T*>::const_iterator& first,
0094                  typename std::vector<const T*>::const_iterator& last) const {
0095     first = signals_.begin();
0096     last = signals_.end();
0097   }
0098   void getPileups(typename std::vector<const T*>::const_iterator& first,
0099                   typename std::vector<const T*>::const_iterator& last) const;
0100   unsigned int getNrSignals() const { return signals_.size(); }
0101   unsigned int getNrPileups() const { return pileups_.size(); }
0102   unsigned int getNrPileups(int bcr) const {
0103     return bcr == lastCrossing_ ? pileups_.size() - pileupOffsetsBcr_[lastCrossing_ - firstCrossing_]
0104                                 : pileupOffsetsBcr_[bcr - firstCrossing_ + 1] - pileupOffsetsBcr_[bcr - firstCrossing_];
0105   }
0106 
0107   // get pileup information in dependency from internal pointer
0108   int getBunchCrossing(unsigned int ip) const;
0109 
0110   int getSourceType(unsigned int ip) const;
0111 
0112   // get object in pileup when position in the vector is known (for DigiSimLink typically)
0113 
0114   const T& getObject(unsigned int ip) const {
0115     //ip is position in the MixCollection (i.e. signal + pileup)
0116     if (ip > getNrSignals() + getNrPileups())
0117       throw cms::Exception("BadIndex") << "CrossingFrame::getObject called with an invalid index- index was " << ip
0118                                        << "!";  // ip >=0, since ip is unsigned
0119     if (ip < getNrSignals()) {
0120       return *(signals_[ip]);
0121     } else {
0122       return *(pileups_[ip - getNrSignals()]);
0123     }
0124   }
0125 
0126   // setters needed for step2 when using mixed secondary source
0127   void setEventID(edm::EventID evId) { id_ = evId; }
0128   void setPileups(const std::vector<const T*>& p) { pileups_ = p; }
0129   void setBunchSpace(int bSpace) { bunchSpace_ = bSpace; }
0130   void setMaxNbSources(unsigned int mNbS) { maxNbSources_ = mNbS; }
0131   void setSubDet(std::string det) { subdet_ = det; }
0132   void setPileupFileNr(unsigned int pFileNr) { pileupFileNr_ = pFileNr; }
0133   void setIdFirstPileup(edm::EventID idFP) { idFirstPileup_ = idFP; }
0134   void setPileupOffsetsBcr(const std::vector<unsigned int>& pOffsetsBcr) { pileupOffsetsBcr_ = pOffsetsBcr; }
0135   void setPileupOffsetsSource(const std::vector<std::vector<unsigned int> >& pOffsetsS) {
0136     pileupOffsetsSource_ = pOffsetsS;
0137   }  //one per source
0138   void setBunchRange(std::pair<int, int> bunchRange) {
0139     firstCrossing_ = bunchRange.first;
0140     lastCrossing_ = bunchRange.second;
0141   }
0142 
0143 private:
0144   // please update the swap() function below if any data members are added.
0145   // general information
0146   int firstCrossing_;
0147   int lastCrossing_;
0148   int bunchSpace_;      //in nsec
0149   std::string subdet_;  // for PSimHits/PCaloHits
0150   edm::EventID id_;     // event id of the signal event
0151 
0152   // for playback option
0153   edm::EventID idFirstPileup_;  // EventId fof the first pileup event used for this signal event
0154   unsigned int pileupFileNr_;   // ordinal number of the pileup file this event was in
0155 
0156   unsigned int maxNbSources_;
0157 
0158   // signal
0159   std::vector<const T*> signals_;
0160 
0161   //pileup
0162   std::vector<const T*> pileups_;
0163   std::vector<std::shared_ptr<edm::Wrapper<std::vector<T> > const> > shPtrPileups_;
0164   std::vector<std::shared_ptr<edm::Wrapper<T> const> > shPtrPileups2_;  // fore HepMCProduct
0165   /*   std::shared_ptr<edm::Wrapper<std::vector<T> > const> shPtrPileups_;  */
0166   /*   std::shared_ptr<edm::Wrapper<T> const> shPtrPileups2_;   // fore HepMCProduct */
0167   std::shared_ptr<edm::Wrapper<PCrossingFrame<T> > const> shPtrPileupsPCF_;
0168   //  std::shared_ptr<edm::Wrapper<PCrossingFrame<edm::HepMCProduct> const> shPtrPileupsHepMCProductPCF_;
0169 
0170   // these are informations stored in order to be able to have information
0171   // as a function of the position of an object in the pileups_ vector
0172   std::vector<unsigned int> pileupOffsetsBcr_;
0173   std::vector<std::vector<unsigned int> > pileupOffsetsSource_;  //one per source
0174 };
0175 
0176 //==============================================================================
0177 //                              implementations
0178 //==============================================================================
0179 
0180 template <class T>
0181 CrossingFrame<T>::CrossingFrame(int minb, int maxb, int bunchsp, std::string subdet, unsigned int maxNbSources)
0182     : firstCrossing_(minb), lastCrossing_(maxb), bunchSpace_(bunchsp), subdet_(subdet), maxNbSources_(maxNbSources) {
0183   pileupOffsetsSource_.resize(maxNbSources_);
0184   for (unsigned int i = 0; i < maxNbSources_; ++i)
0185     pileupOffsetsSource_[i].reserve(-firstCrossing_ + lastCrossing_ + 1);
0186 
0187   //FIXME: should we force around 0 or so??
0188   pileupOffsetsBcr_.reserve(-firstCrossing_ + lastCrossing_ + 1);
0189 }
0190 
0191 template <typename T>
0192 inline void CrossingFrame<T>::swap(CrossingFrame<T>& other) {
0193   std::swap(firstCrossing_, other.firstCrossing_);
0194   std::swap(lastCrossing_, other.lastCrossing_);
0195   std::swap(bunchSpace_, other.bunchSpace_);
0196   subdet_.swap(other.subdet_);
0197   std::swap(id_, other.id_);
0198   std::swap(idFirstPileup_, other.idFirstPileup_);
0199   std::swap(pileupFileNr_, other.pileupFileNr_);
0200   std::swap(maxNbSources_, other.maxNbSources_);
0201   signals_.swap(other.signals_);
0202   pileups_.swap(other.pileups_);
0203   shPtrPileups_.swap(other.shPtrPileups_);
0204   shPtrPileups2_.swap(other.shPtrPileups2_);
0205   shPtrPileupsPCF_.swap(other.shPtrPileupsPCF_);
0206   pileupOffsetsBcr_.swap(other.pileupOffsetsBcr_);
0207   pileupOffsetsSource_.resize(maxNbSources_);
0208   for (unsigned int i = 0; i < pileupOffsetsSource_.size(); ++i) {
0209     pileupOffsetsSource_[i].swap(other.pileupOffsetsSource_[i]);
0210   }
0211 }
0212 
0213 template <typename T>
0214 inline CrossingFrame<T>& CrossingFrame<T>::operator=(CrossingFrame<T> const& rhs) {
0215   CrossingFrame<T> temp(rhs);
0216   this->swap(temp);
0217   return *this;
0218 }
0219 
0220 template <class T>
0221 void CrossingFrame<T>::getPileups(typename std::vector<const T*>::const_iterator& first,
0222                                   typename std::vector<const T*>::const_iterator& last) const {
0223   first = pileups_.begin();
0224   last = pileups_.end();
0225 }
0226 
0227 template <class T>
0228 void CrossingFrame<T>::print(int level) const {}
0229 
0230 template <class T>
0231 int CrossingFrame<T>::getSourceType(unsigned int ip) const {
0232   // ip is position in the pileup vector
0233   // decide to which source belongs object with index ip in the pileup vector
0234   // pileup=0, cosmics=1, beam halo+ =2, beam halo- =3 forward =4
0235   unsigned int bcr = getBunchCrossing(ip) - firstCrossing_;  //starts at 0
0236   for (unsigned int i = 0; i < pileupOffsetsSource_.size() - 1; ++i) {
0237     if (ip >= (pileupOffsetsSource_[i])[bcr] && ip < (pileupOffsetsSource_[i + 1])[bcr])
0238       return i;
0239   }
0240   return pileupOffsetsSource_.size() - 1;
0241 }
0242 
0243 template <class T>
0244 int CrossingFrame<T>::getBunchCrossing(unsigned int ip) const {
0245   // return the bcr for a certain position in the pileup vector
0246   for (unsigned int ii = 1; ii < pileupOffsetsBcr_.size(); ii++) {
0247     if (ip >= pileupOffsetsBcr_[ii - 1] && ip < pileupOffsetsBcr_[ii])
0248       return ii + firstCrossing_ - 1;
0249   }
0250   if (ip < pileups_.size())
0251     return lastCrossing_;
0252   else
0253     return 999;
0254 }
0255 
0256 // Free swap function
0257 template <typename T>
0258 inline void swap(CrossingFrame<T>& lhs, CrossingFrame<T>& rhs) {
0259   lhs.swap(rhs);
0260 }
0261 
0262 #include <iosfwd>
0263 #include <iostream>
0264 
0265 template <class T>
0266 std::ostream& operator<<(std::ostream& o, const CrossingFrame<T>& cf) {
0267   std::pair<int, int> range = cf.getBunchRange();
0268   o << "\nCrossingFrame for subdet " << cf.getEventID() << ",  bunchrange = " << range.first << "," << range.second
0269     << ", bunchSpace " << cf.getBunchSpace();
0270 
0271   return o;
0272 }
0273 
0274 #include "SimDataFormats/CrossingFrame/interface/PCrossingFrame.h"
0275 template <class T>
0276 void CrossingFrame<T>::setPileupPtr(std::shared_ptr<edm::Wrapper<PCrossingFrame<T> > const> shPtr) {
0277   shPtrPileupsPCF_ = shPtr;
0278 }
0279 
0280 template <class T>
0281 void CrossingFrame<T>::addPileups(T const& product) {
0282   // default, valid for HepMCProduct
0283   pileups_.push_back(&product);
0284 }
0285 
0286 #ifndef __GCCXML__
0287 template <class T>
0288 void CrossingFrame<T>::addPileups(std::vector<T> const& product) {
0289   for (auto const& item : product) {
0290     pileups_.push_back(&item);
0291   }
0292 }
0293 #endif
0294 
0295 template <class T>
0296 void CrossingFrame<T>::addSignals(const std::vector<T>* vec, edm::EventID id) {
0297   // valid (called) for all except HepMCProduct
0298   id_ = id;
0299   for (unsigned int i = 0; i < vec->size(); ++i) {
0300     signals_.push_back(&((*vec)[i]));
0301   }
0302 }
0303 
0304 template <class T>
0305 void CrossingFrame<T>::addSignals(const T* product, edm::EventID id) {
0306   // valid (called) for all except HepMCProduct
0307   id_ = id;
0308   signals_.push_back(product);
0309 }
0310 
0311 template <class T>
0312 void CrossingFrame<T>::setTof() {
0313   ;
0314 }
0315 
0316 #endif