Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:51:38

0001 #ifndef SiStripLatency_h
0002 #define SiStripLatency_h
0003 
0004 #include "CondFormats/Serialization/interface/Serializable.h"
0005 
0006 #include <vector>
0007 #include <algorithm>
0008 #include <cstdint>
0009 #include <sstream>
0010 
0011 class TrackerTopology;
0012 
0013 #define READMODEMASK 8
0014 
0015 /**
0016  * Holds the latency and the mode of the run. <br>
0017  * The latency is stored per apv and the information is compressed by reducing
0018  * sequences of apvs with the same latency to a single value plus information on the
0019  * start and end of the sequence. <br>
0020  * The mode is a single value, stored as a char. The actual operation mode bit is bit number
0021  * 3 starting from 0. The bitmask to retrieve the information in the number 8 (1000). <br>
0022  * - (mode & 8) == 0 : deconvolution mode <br>
0023  * - (mode & 8) == 8 : peak mode <br>
0024  * See here http://cdsweb.cern.ch/record/1069892
0025  * page 13 section 5.5 table 7 for the definition of possible modes. <br>
0026  * The put method requires the latency and mode values for a given apv and detId. <br>
0027  * <br>
0028  * The internal Latency object stores the detId and apv value in a compressed
0029  * (bit shifted) uint32_t holding both the values. It stores the latency value
0030  * in a uint8_t (unsigned char). The APV user guide reports a maximum value of 191
0031  * for the latency, so the uint8_t (0-255) is enough. If the value is not filled or
0032  * the detId is not found it will return latency = 255. <br>
0033  * The mode value is also stored in an unsigned char (possible values 0-255). The invalid
0034  * case returns mode = 0 in this case. <br>
0035  * To save space, since typically the latency and mode is the same for all apvs, the ranges
0036  * of consecutive detIds and apvs are collapsed in the last value, so that the lower_bound
0037  * binary search will return the correct latency and mode. <br>
0038  * <br>
0039  * Methods are provided to extract latency and mode (separately or together in a pair)
0040  * for each apv. <br>
0041  * If the value of latency (mode) is the same for the whole Tracker, the singleLatency()
0042  * (singleMode()) method will return it, otherwise it will return 255 (0). <br>
0043  * <br>
0044  * The method allLatencyAndModes() returns the internal vector<Latency> (by value).
0045  * <br>
0046  * The method allUniqueLatencyAndModes() returns all the combinations of latency and mode present. <br>
0047  * ATTENTION: This method assumes that latency and mode are stored in a unsinged short. <br>
0048  * The method singleReadOutMode() returns: 1 if all the Tracker is in peak, 0 if it is in deco, -1 if it is in mixed mode <br>
0049  * <br>
0050  * The method allModes (allLatencies) fill the passed vector with all different modes
0051  * (latencies) in the Tracker. <br>
0052  * ATTENTION: the biggest possible detId value that can be stored is 536870911 because
0053  * 29 bits out of 32 are reserved for the detId and the remaining 3 for the apv value (1-6). <br>
0054  * The biggest possible Tracker detId at this moment is 470178036 so this is not a problem.
0055  * In any case the code will throw an "InsertFailure" cms::Exception if trying to insert a detId
0056  * above the maximum and output a detailed LogError message about the problem.
0057  */
0058 
0059 class SiStripLatency {
0060 public:
0061   SiStripLatency() {}
0062 
0063   // Defined as public for genreflex
0064   struct Latency {
0065     Latency(const uint32_t inputDetIdAndApv, const uint16_t inputLatency, const uint16_t inputMode)
0066         : detIdAndApv(inputDetIdAndApv), latency(inputLatency), mode(inputMode) {}
0067     /// Default constructor needed by genreflex
0068     Latency() : detIdAndApv(0), latency(255), mode(0) {}
0069     uint32_t detIdAndApv;
0070     unsigned char latency;
0071     unsigned char mode;
0072 
0073     COND_SERIALIZABLE;
0074   };
0075   typedef std::vector<Latency>::iterator latIt;
0076   typedef std::vector<Latency>::const_iterator latConstIt;
0077 
0078   /** Saves the detIdAndApv and latency values in the vector of Latency objects.
0079    * At the end of the filling phase, the compress method should be called to
0080    * collapse all ranges in single values. Note that everything would work even
0081    * if the compress method is not called, only the space used would be more than
0082    * needed.
0083    */
0084   bool put(const uint32_t detId, const uint16_t apv, const uint16_t latency, const uint16_t mode);
0085   uint16_t latency(const uint32_t detId, const uint16_t apv) const;
0086   uint16_t mode(const uint32_t detId, const uint16_t apv) const;
0087   std::pair<uint16_t, uint16_t> latencyAndMode(const uint32_t detId, const uint16_t apv) const;
0088   inline std::vector<Latency> allLatencyAndModes() const { return latencies_; }
0089 
0090   /// Fills the passed vector with all the possible latencies in the Tracker
0091   void allLatencies(std::vector<uint16_t>& allLatenciesVector) const;
0092   /// Fills the passed vector with all the possible modes in the Tracker
0093   void allModes(std::vector<uint16_t>& allModesVector) const;
0094   int16_t singleReadOutMode() const;
0095   //   bool allPeak() const;
0096 
0097   std::vector<Latency> allUniqueLatencyAndModes();
0098 
0099   /** Reduce ranges of consecutive detIdsAndApvs with the same latency and mode to
0100    * one value (the latest) so that lower_bound will return the correct value for
0101    * latency and mode.
0102    */
0103   void compress();
0104   /// If all the latency values stored are equal return that value, otherwise return -1
0105   uint16_t singleLatency() const;
0106   uint16_t singleMode() const;
0107 
0108   /// Prints the number of ranges as well as the value of singleLatency and singleMode
0109   void printSummary(std::stringstream& ss, const TrackerTopology* trackerTopo) const;
0110   /// Prints the full list of all ranges and corresponding values of latency and mode
0111   void printDebug(std::stringstream& ss, const TrackerTopology* trackerTopo) const;
0112 
0113   struct OrderByDetIdAndApv {
0114     bool operator()(const Latency& lat1, const uint32_t detIdAndApv) const { return lat1.detIdAndApv < detIdAndApv; }
0115   };
0116 
0117   struct OrderByLatencyAndMode {
0118     bool operator()(const Latency& lat1, const Latency& lat2) {
0119       // latency and mode are unsigned short that cannot exceed 255.
0120       // Sum them multiplying the mode by 1000 to get a single ordering number.
0121       int latencyAndModeSortValue1 = int(lat1.latency) + 1000 * int(lat1.mode);
0122       int latencyAndModeSortValue2 = int(lat2.latency) + 1000 * int(lat2.mode);
0123       return (latencyAndModeSortValue1 < latencyAndModeSortValue2);
0124     }
0125   };
0126   struct EqualByLatencyAndMode {
0127     bool operator()(const Latency& lat1, const Latency& lat2) {
0128       return ((lat1.latency == lat2.latency) && (lat1.mode == lat2.mode));
0129     }
0130   };
0131 
0132 private:
0133   /// Used to compute the position with the lower_bound binary search
0134   // If put in the cc file it will not know about the typedefs and the Latency class
0135   const latConstIt position(const uint32_t detId, const uint16_t apv) const {
0136     if (latencies_.empty()) {
0137       // std::cout << "SiStripLatency: Error, range is empty" << std::endl;
0138       return latencies_.end();
0139     }
0140     uint32_t detIdAndApv = (detId << 3) | apv;
0141     latConstIt pos = lower_bound(latencies_.begin(), latencies_.end(), detIdAndApv, OrderByDetIdAndApv());
0142     return pos;
0143   }
0144   std::vector<Latency> latencies_;
0145 
0146   COND_SERIALIZABLE;
0147 };
0148 
0149 #endif