Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef DataFormats_SiPixelRecHitQuality_h
0002 #define DataFormats_SiPixelRecHitQuality_h 1
0003 
0004 #include <cmath>
0005 
0006 class SiPixelRecHitQuality {
0007 public:
0008   typedef unsigned int QualWordType;
0009 
0010 public:
0011   class Packing {
0012   public:
0013     // Constructor: pre-computes masks and shifts from field widths
0014     Packing();
0015 
0016   public:
0017     QualWordType probX_mask;
0018     int probX_shift;
0019     float probX_units;
0020     double probX_1_over_log_units;
0021     char probX_width;
0022     //
0023     QualWordType probY_mask;
0024     int probY_shift;
0025     float probY_units;
0026     double probY_1_over_log_units;
0027     char probY_width;
0028     //
0029     QualWordType qBin_mask;
0030     int qBin_shift;
0031     char qBin_width;
0032     //
0033     QualWordType edge_mask;
0034     int edge_shift;
0035     char edge_width;
0036     //
0037     QualWordType bad_mask;
0038     int bad_shift;
0039     char bad_width;
0040     //
0041     QualWordType twoROC_mask;
0042     int twoROC_shift;
0043     char twoROC_width;
0044     //
0045     QualWordType hasFilledProb_mask;
0046     int hasFilledProb_shift;
0047     char hasFilledProb_width;
0048 
0049     char spare_width;
0050 
0051     //--- Template fit probability, in X and Y directions
0052     //    To pack: int raw = - log(prob)/log(prob_units)
0053     //    Unpack : prob = prob_units^{-raw}
0054     //
0055     //--- We've obsoleted probX and probY in favor of probXY and probQ as of 09/10
0056     inline float probabilityX(QualWordType qualWord) const {
0057       warningObsolete();
0058       return -10;
0059     }
0060     inline float probabilityY(QualWordType qualWord) const {
0061       warningObsolete();
0062       return -10;
0063     }
0064 
0065     inline float probabilityXY(QualWordType qualWord) const {
0066       int raw = (qualWord >> probX_shift) & probX_mask;
0067       if (raw < 0 || raw > 16383) {
0068         warningOutOfBoundRaw("XY", raw, qualWord);
0069         raw = 16383;
0070       }
0071       float prob = (raw == 16383) ? 0 : pow(probX_units, (float)(-raw));
0072       // cout << "Bits = " << raw << " --> Prob = " << prob << endl;
0073       return prob;
0074     }
0075     inline float probabilityQ(QualWordType qualWord) const {
0076       int raw = (qualWord >> probY_shift) & probY_mask;
0077       if (raw < 0 || raw > 255) {
0078         warningOutOfBoundRaw("Q", raw, qualWord);
0079         raw = 255;
0080       }
0081       float prob = (raw == 255) ? 0 : pow(probY_units, (float)(-raw));
0082       // cout << "Bits = " << raw << " --> Prob = " << prob << endl;
0083       return prob;
0084     }
0085     //
0086     //--- Charge `bin' (0,1,2,3 ~ charge, qBin==4 is a new minimum charge state, qBin=5 is unphysical, qBin6,7 = unused)
0087     inline int qBin(QualWordType qualWord) const {
0088       int qbin = (qualWord >> qBin_shift) & qBin_mask;
0089       if (qbin < 0 || qbin > 7) {
0090         warningOutOfBoundQbin(qbin, qualWord);
0091         qbin = 0;
0092       }
0093       return qbin;
0094     }
0095     //--- Quality flags (true or false):
0096     //--- cluster is on the edge of the module, or straddles a dead ROC
0097     inline bool isOnEdge(QualWordType qualWord) const { return (qualWord >> edge_shift) & edge_mask; }
0098     //--- cluster contains bad pixels, or straddles bad column or two-column
0099     inline bool hasBadPixels(QualWordType qualWord) const { return (qualWord >> bad_shift) & bad_mask; }
0100     //--- the cluster spans two ROCS (and thus contains big pixels)
0101     inline bool spansTwoROCs(QualWordType qualWord) const { return (qualWord >> twoROC_shift) & twoROC_mask; }
0102     //--- the probability is filled
0103     inline bool hasFilledProb(QualWordType qualWord) const {
0104       return (qualWord >> hasFilledProb_shift) & hasFilledProb_mask;
0105     }
0106 
0107     //------------------------------------------------------
0108     //--- Setters: the inverse of the above.
0109     //------------------------------------------------------
0110     //
0111     inline void setProbabilityXY(float prob, QualWordType& qualWord) const {
0112       if (prob > 1.0f && prob <= 1.0f + std::numeric_limits<float>::epsilon()) {
0113         prob = 1;
0114       } else if (prob < 0.0f || prob > 1.0f + std::numeric_limits<float>::epsilon()) {
0115         warningOutOfBoundProb("XY", prob, qualWord);
0116         prob = 0;
0117       }
0118       double draw = (prob <= 1.6E-13) ? 16383 : -log((double)prob) * probX_1_over_log_units;
0119       unsigned int raw = (int)(draw + 0.5);  // convert to integer, round correctly
0120       // cout << "Prob = " << prob << " --> Bits = " << raw << endl;
0121       qualWord |= ((raw & probX_mask) << probX_shift);
0122     }
0123     inline void setProbabilityQ(float prob, QualWordType& qualWord) const {
0124       if (prob > 1.0f && prob <= 1.0f + std::numeric_limits<float>::epsilon()) {
0125         prob = 1;
0126       } else if (prob == -1.0f) {
0127         // default prob in absence of Q probability computation is -1 --> set to 0
0128         prob = 0;
0129       } else if (prob < 0.0f || prob > 1.0f + std::numeric_limits<float>::epsilon()) {
0130         warningOutOfBoundProb("Q", prob, qualWord);
0131         prob = 0;
0132       }
0133       double draw = (prob <= 1E-5) ? 255 : -log((double)prob) * probY_1_over_log_units;
0134       unsigned int raw = (int)(draw + 0.5);  // convert to integer, round correctly
0135       // cout << "Prob = " << prob << " --> Bits = " << raw << endl;
0136       qualWord |= ((raw & probY_mask) << probY_shift);
0137     }
0138 
0139     inline void setQBin(int qbin, QualWordType& qualWord) const {
0140       if (qbin < 0 || qbin > 7) {
0141         warningOutOfBoundQbin(qbin, qualWord);
0142         qbin = 0;
0143       }
0144       qualWord |= ((qbin & qBin_mask) << qBin_shift);
0145     }
0146 
0147     inline void setIsOnEdge(bool flag, QualWordType& qualWord) const { qualWord |= ((flag & edge_mask) << edge_shift); }
0148     inline void setHasBadPixels(bool flag, QualWordType& qualWord) const {
0149       qualWord |= ((flag & bad_mask) << bad_shift);
0150     }
0151     inline void setSpansTwoROCs(bool flag, QualWordType& qualWord) const {
0152       qualWord |= ((flag & twoROC_mask) << twoROC_shift);
0153     }
0154     inline void setHasFilledProb(bool flag, QualWordType& qualWord) const {
0155       qualWord |= ((flag & hasFilledProb_mask) << hasFilledProb_shift);
0156     }
0157   };
0158 
0159 public:
0160   static const Packing thePacking;
0161 
0162 private:
0163   static void warningObsolete();
0164   static void warningOutOfBoundQbin(int, QualWordType const&);
0165   static void warningOutOfBoundProb(const char* iVariable, float, QualWordType const&);
0166   static void warningOutOfBoundRaw(const char* iVariable, int iRaw, QualWordType const&);
0167 };
0168 
0169 #endif