Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef DATAFORMATS_SISTRIPCLUSTER_H
0002 #define DATAFORMATS_SISTRIPCLUSTER_H
0003 
0004 #include "DataFormats/SiStripDigi/interface/SiStripDigi.h"
0005 #include "DataFormats/SiStripCluster/interface/SiStripApproximateCluster.h"
0006 #include <vector>
0007 #include <numeric>
0008 #include <iostream>
0009 
0010 class SiStripApproximateCluster;
0011 
0012 class SiStripCluster {
0013 public:
0014   typedef std::vector<SiStripDigi>::const_iterator SiStripDigiIter;
0015   typedef std::pair<SiStripDigiIter, SiStripDigiIter> SiStripDigiRange;
0016 
0017   static const uint16_t stripIndexMask = 0x7FFF;   // The first strip index is in the low 15 bits of firstStrip_
0018   static const uint16_t mergedValueMask = 0x8000;  // The merged state is given by the high bit of firstStrip_
0019 
0020   /** Construct from a range of digis that form a cluster and from 
0021    *  a DetID. The range is assumed to be non-empty.
0022    */
0023 
0024   SiStripCluster() {}
0025 
0026   explicit SiStripCluster(const SiStripDigiRange& range);
0027 
0028   SiStripCluster(uint16_t firstStrip, std::vector<uint8_t>&& data)
0029       : amplitudes_(std::move(data)), firstStrip_(firstStrip) {}
0030 
0031   template <typename Iter>
0032   SiStripCluster(const uint16_t& firstStrip, Iter begin, Iter end) : amplitudes_(begin, end), firstStrip_(firstStrip) {}
0033 
0034   template <typename Iter>
0035   SiStripCluster(const uint16_t& firstStrip, Iter begin, Iter end, bool merged)
0036       : amplitudes_(begin, end), firstStrip_(firstStrip) {
0037     if (merged)
0038       firstStrip_ |= mergedValueMask;  // if this is a candidate merged cluster
0039   }
0040 
0041   SiStripCluster(const SiStripApproximateCluster cluster, const uint16_t maxStrips);
0042 
0043   // extend the cluster
0044   template <typename Iter>
0045   void extend(Iter begin, Iter end) {
0046     amplitudes_.insert(amplitudes_.end(), begin, end);
0047   }
0048 
0049   /** The amplitudes of the strips forming the cluster.
0050    *  The amplitudes are on consecutive strips; if a strip is missing
0051    *  the amplitude is set to zero.
0052    *  A strip may be missing in the middle of a cluster because of a
0053    *  clusterizer that accepts holes.
0054    *  A strip may also be missing anywhere in the cluster, including the 
0055    *  edge, to record a dead/noisy channel.
0056    *
0057    *  You can find the special meanings of values { 0, 254, 255} in section 3.4.1 of
0058    *  http://www.te.rl.ac.uk/esdg/cms-fed/firmware/Documents/FE_FPGA_Technical_Description.pdf
0059    */
0060   auto size() const { return amplitudes_.size(); }
0061   auto const* begin() const { return amplitudes_.data(); }
0062   auto const* end() const { return begin() + size(); }
0063   auto operator[](int i) const { return *(begin() + i); }
0064   bool empty() const { return amplitudes_.empty(); }
0065   bool full() const { return false; }
0066 
0067   SiStripCluster const& amplitudes() const { return *this; }
0068 
0069   /** The number of the first strip in the cluster.
0070    *  The high bit of firstStrip_ indicates whether the cluster is a candidate for being merged.
0071    */
0072   uint16_t firstStrip() const { return firstStrip_ & stripIndexMask; }
0073   uint16_t endStrip() const { return firstStrip() + size(); }
0074 
0075   /** The barycenter of the cluster, not corrected for Lorentz shift;
0076    *  should not be used as position estimate for tracking.
0077    */
0078   float barycenter() const;
0079 
0080   /** total charge
0081    *
0082    */
0083   int charge() const;
0084 
0085   bool filter() const;
0086 
0087   bool isFromApprox() const;
0088 
0089   /** Test (set) the merged status of the cluster
0090    *
0091    */
0092   bool isMerged() const { return (firstStrip_ & mergedValueMask) != 0; }
0093   void setMerged(bool mergedState) { mergedState ? firstStrip_ |= mergedValueMask : firstStrip_ &= stripIndexMask; }
0094 
0095   float getSplitClusterError() const { return error_x; }
0096   void setSplitClusterError(float errx) { error_x = errx; }
0097 
0098 private:
0099   std::vector<uint8_t> amplitudes_;
0100 
0101   uint16_t firstStrip_ = 0;
0102 
0103   //these are used if amplitude information is not available (using approximate cluster constructor)
0104   float barycenter_ = 0;
0105   int charge_ = 0;
0106   bool filter_ = false;
0107 
0108   // ggiurgiu@fnal.gov, 01/05/12
0109   // Add cluster errors to be used by rechits from split clusters.
0110   // A rechit from a split cluster has larger errors than rechits from normal clusters.
0111   // However, when presented with a cluster, the CPE does not know if the cluster comes
0112   // from a splitting procedure or not. That's why we have to instruct the CPE to use
0113   // appropriate errors for split clusters.
0114   // To avoid increase of data size on disk,these new data members are set as transient in:
0115   // DataFormats/SiStripCluster/src/classes_def.xml
0116   float error_x = -99999.9;
0117 
0118   // ggiurgiu@fnal.gov, 01/05/12
0119   // Initialize the split cluster errors to un-physical values.
0120   // The CPE will check these errors and if they are not un-physical,
0121   // it will recognize the clusters as split and assign these (increased)
0122   // errors to the corresponding rechit.
0123 };
0124 
0125 // Comparison operators
0126 inline bool operator<(const SiStripCluster& one, const SiStripCluster& other) {
0127   return one.firstStrip() < other.firstStrip();
0128 }
0129 
0130 inline bool operator<(const SiStripCluster& cluster, const uint16_t& firstStrip) {
0131   return cluster.firstStrip() < firstStrip;
0132 }
0133 
0134 inline bool operator<(const uint16_t& firstStrip, const SiStripCluster& cluster) {
0135   return firstStrip < cluster.firstStrip();
0136 }
0137 #endif  // DATAFORMATS_SISTRIPCLUSTER_H