Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef DataFormats_HcalRecHit_HBHEChannelInfo_h_
0002 #define DataFormats_HcalRecHit_HBHEChannelInfo_h_
0003 
0004 #include <cfloat>
0005 #include <iostream>
0006 
0007 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
0008 #include "DataFormats/HcalRecHit/interface/HcalSpecialTimes.h"
0009 
0010 /** \class HBHEChannelInfo
0011  *
0012  * Unpacked charge and TDC information in a format which works
0013  * for both QIE8 and QIE11
0014  */
0015 class HBHEChannelInfo {
0016 public:
0017   typedef HcalDetId key_type;
0018 
0019   static const unsigned MAXSAMPLES = 10;
0020 
0021   constexpr HBHEChannelInfo()
0022       : id_(),
0023         rawCharge_{0.},
0024         pedestal_{0.},
0025         pedestalWidth_{0.},
0026         gain_{0.},
0027         gainWidth_{0.},
0028         darkCurrent_{0},
0029         fcByPE_{0},
0030         lambda_{0},
0031         noisecorr_{0},
0032         riseTime_{0.f},
0033         adc_{0},
0034         dFcPerADC_{0.f},
0035         recoShape_{0},
0036         nSamples_{0},
0037         soi_{0},
0038         capid_{0},
0039         hasTimeInfo_{false},
0040         hasEffectivePedestals_{false},
0041         dropped_{true},
0042         hasLinkError_{false},
0043         hasCapidError_{false} {}
0044 
0045   constexpr explicit HBHEChannelInfo(const bool hasTimeFromTDC, const bool hasEffectivePed)
0046       : id_(),
0047         rawCharge_{0.},
0048         pedestal_{0.},
0049         pedestalWidth_{0.},
0050         gain_{0.},
0051         gainWidth_{0.},
0052         darkCurrent_{0},
0053         fcByPE_{0},
0054         lambda_{0},
0055         noisecorr_{0},
0056         riseTime_{0.f},
0057         adc_{0},
0058         dFcPerADC_{0.f},
0059         recoShape_{0},
0060         nSamples_{0},
0061         soi_{0},
0062         capid_{0},
0063         hasTimeInfo_(hasTimeFromTDC),
0064         hasEffectivePedestals_(hasEffectivePed),
0065         dropped_{true},
0066         hasLinkError_{false},
0067         hasCapidError_{false} {}
0068 
0069   constexpr void clear() {
0070     id_ = HcalDetId(0U);
0071     recoShape_ = 0;
0072     nSamples_ = 0;
0073     soi_ = 0;
0074     capid_ = 0;
0075     darkCurrent_ = 0;
0076     fcByPE_ = 0;
0077     lambda_ = 0, dropped_ = true;
0078     noisecorr_ = 0;
0079     hasLinkError_ = false;
0080     hasCapidError_ = false;
0081   }
0082 
0083   constexpr void setChannelInfo(const HcalDetId& detId,
0084                                 const int recoShape,
0085                                 const unsigned nSamp,
0086                                 const unsigned iSoi,
0087                                 const int iCapid,
0088                                 const double darkCurrent,
0089                                 const double fcByPE,
0090                                 const double lambda,
0091                                 const double noisecorr,
0092                                 const bool linkError,
0093                                 const bool capidError,
0094                                 const bool dropThisChannel) {
0095     recoShape_ = recoShape;
0096     id_ = detId;
0097     nSamples_ = nSamp < MAXSAMPLES ? nSamp : MAXSAMPLES;
0098     soi_ = iSoi;
0099     capid_ = iCapid;
0100     darkCurrent_ = darkCurrent;
0101     fcByPE_ = fcByPE;
0102     lambda_ = lambda, dropped_ = dropThisChannel;
0103     noisecorr_ = noisecorr;
0104     hasLinkError_ = linkError;
0105     hasCapidError_ = capidError;
0106   }
0107 
0108   constexpr void tagAsDropped() { dropped_ = true; }
0109 
0110   // For speed, the "setSample" function does not perform bounds checking
0111   constexpr void setSample(const unsigned ts,
0112                            const uint8_t rawADC,
0113                            const float differentialChargeGain,
0114                            const double q,
0115                            const double ped,
0116                            const double pedWidth,
0117                            const double g,
0118                            const double gainWidth,
0119                            const float t) {
0120     rawCharge_[ts] = q;
0121     riseTime_[ts] = t;
0122     adc_[ts] = rawADC;
0123     dFcPerADC_[ts] = differentialChargeGain;
0124     pedestal_[ts] = ped;
0125     gain_[ts] = g;
0126     pedestalWidth_[ts] = pedWidth;
0127     gainWidth_[ts] = gainWidth;
0128   }
0129 
0130   // Inspectors
0131   constexpr HcalDetId id() const { return id_; }
0132 
0133   // access the recoShape
0134   constexpr int recoShape() const { return recoShape_; }
0135 
0136   constexpr unsigned nSamples() const { return nSamples_; }
0137   constexpr unsigned soi() const { return soi_; }
0138   constexpr int capid() const { return capid_; }
0139   constexpr bool hasTimeInfo() const { return hasTimeInfo_; }
0140   constexpr bool hasEffectivePedestals() const { return hasEffectivePedestals_; }
0141   constexpr double darkCurrent() const { return darkCurrent_; }
0142   constexpr double fcByPE() const { return fcByPE_; }
0143   constexpr double lambda() const { return lambda_; }
0144   constexpr double noisecorr() const { return noisecorr_; }
0145   constexpr bool isDropped() const { return dropped_; }
0146   constexpr bool hasLinkError() const { return hasLinkError_; }
0147   constexpr bool hasCapidError() const { return hasCapidError_; }
0148 
0149   // Direct read-only access to time slice arrays
0150   constexpr double const* rawCharge() const { return rawCharge_; }
0151   constexpr double const* pedestal() const { return pedestal_; }
0152   constexpr double const* pedestalWidth() const { return pedestalWidth_; }
0153   constexpr double const* gain() const { return gain_; }
0154   constexpr double const* gainWidth() const { return gainWidth_; }
0155   constexpr uint8_t const* adc() const { return adc_; }
0156   constexpr float const* dFcPerADC() const { return dFcPerADC_; }
0157   constexpr float const* riseTime() const {
0158     if (hasTimeInfo_)
0159       return riseTime_;
0160     else
0161       return nullptr;
0162   }
0163 
0164   // Indexed access to time slice quantities. No bounds checking.
0165   constexpr double tsRawCharge(const unsigned ts) const { return rawCharge_[ts]; }
0166   constexpr double tsPedestal(const unsigned ts) const { return pedestal_[ts]; }
0167   constexpr double tsPedestalWidth(const unsigned ts) const { return pedestalWidth_[ts]; }
0168   constexpr double tsGain(const unsigned ts) const { return gain_[ts]; }
0169   constexpr double tsGainWidth(const unsigned ts) const { return gainWidth_[ts]; }
0170   constexpr double tsCharge(const unsigned ts) const { return rawCharge_[ts] - pedestal_[ts]; }
0171   constexpr double tsEnergy(const unsigned ts) const { return (rawCharge_[ts] - pedestal_[ts]) * gain_[ts]; }
0172   constexpr uint8_t tsAdc(const unsigned ts) const { return adc_[ts]; }
0173   constexpr float tsDFcPerADC(const unsigned ts) const { return dFcPerADC_[ts]; }
0174   constexpr float tsRiseTime(const unsigned ts) const {
0175     return hasTimeInfo_ ? riseTime_[ts] : HcalSpecialTimes::UNKNOWN_T_NOTDC;
0176   }
0177 
0178   // Signal rise time measurement for the SOI, if available
0179   constexpr float soiRiseTime() const {
0180     return (hasTimeInfo_ && soi_ < nSamples_) ? riseTime_[soi_] : HcalSpecialTimes::UNKNOWN_T_NOTDC;
0181   }
0182 
0183   // The TS with the "end" index is not included in the window
0184   constexpr double chargeInWindow(const unsigned begin, const unsigned end) const {
0185     double sum = 0.0;
0186     const unsigned imax = end < nSamples_ ? end : nSamples_;
0187     for (unsigned i = begin; i < imax; ++i)
0188       sum += (rawCharge_[i] - pedestal_[i]);
0189     return sum;
0190   }
0191 
0192   constexpr double energyInWindow(const unsigned begin, const unsigned end) const {
0193     double sum = 0.0;
0194     const unsigned imax = end < nSamples_ ? end : nSamples_;
0195     for (unsigned i = begin; i < imax; ++i)
0196       sum += (rawCharge_[i] - pedestal_[i]) * gain_[i];
0197     return sum;
0198   }
0199 
0200   // The two following methods return MAXSAMPLES if the specified
0201   // window does not overlap with the samples stored
0202   constexpr unsigned peakChargeTS(const unsigned begin, const unsigned end) const {
0203     unsigned iPeak = MAXSAMPLES;
0204     double dmax = -DBL_MAX;
0205     const unsigned imax = end < nSamples_ ? end : nSamples_;
0206     for (unsigned i = begin; i < imax; ++i) {
0207       const double q = rawCharge_[i] - pedestal_[i];
0208       if (q > dmax) {
0209         dmax = q;
0210         iPeak = i;
0211       }
0212     }
0213     return iPeak;
0214   }
0215 
0216   constexpr unsigned peakEnergyTS(const unsigned begin, const unsigned end) const {
0217     unsigned iPeak = MAXSAMPLES;
0218     double dmax = -DBL_MAX;
0219     const unsigned imax = end < nSamples_ ? end : nSamples_;
0220     for (unsigned i = begin; i < imax; ++i) {
0221       const double e = (rawCharge_[i] - pedestal_[i]) * gain_[i];
0222       if (e > dmax) {
0223         dmax = e;
0224         iPeak = i;
0225       }
0226     }
0227     return iPeak;
0228   }
0229 
0230   // The following function can be used, for example,
0231   // in a check for presence of saturated ADC values
0232   constexpr uint8_t peakAdcValue(const unsigned begin, const unsigned end) const {
0233     uint8_t peak = 0;
0234     const unsigned imax = end < nSamples_ ? end : nSamples_;
0235     for (unsigned i = begin; i < imax; ++i)
0236       if (adc_[i] > peak)
0237         peak = adc_[i];
0238     return peak;
0239   }
0240 
0241 private:
0242   HcalDetId id_;
0243 
0244   // Charge in fC for all time slices
0245   double rawCharge_[MAXSAMPLES];
0246 
0247   // Pedestal in fC
0248   double pedestal_[MAXSAMPLES];
0249 
0250   // Pedestal Width in fC
0251   double pedestalWidth_[MAXSAMPLES];
0252 
0253   // fC to GeV conversion factor
0254   double gain_[MAXSAMPLES];
0255 
0256   // fC to GeV conversion factor
0257   double gainWidth_[MAXSAMPLES];
0258 
0259   // needed for the dark current
0260   double darkCurrent_;
0261   double fcByPE_;
0262   double lambda_;
0263   double noisecorr_;
0264 
0265   // Signal rise time from TDC in ns (if provided)
0266   float riseTime_[MAXSAMPLES];
0267 
0268   // Raw QIE ADC values
0269   uint8_t adc_[MAXSAMPLES];
0270 
0271   // Differential fC/ADC gain. Needed for proper determination
0272   // of the ADC quantization error.
0273   float dFcPerADC_[MAXSAMPLES];
0274 
0275   // Reco Shapes
0276   int32_t recoShape_;
0277 
0278   // Number of time slices actually filled
0279   uint32_t nSamples_;
0280 
0281   // "Sample of interest" in the array of time slices
0282   uint32_t soi_;
0283 
0284   // QIE8 or QIE11 CAPID for the sample of interest
0285   int32_t capid_;
0286 
0287   // Flag indicating presence of the time info from TDC (QIE11)
0288   bool hasTimeInfo_;
0289 
0290   // Flag indicating use of effective pedestals
0291   bool hasEffectivePedestals_;
0292 
0293   // Flag indicating that this channel should be dropped
0294   // (typically, tagged bad from DB or zero-suppressed)
0295   bool dropped_;
0296 
0297   // Flags indicating presence of hardware errors
0298   bool hasLinkError_;
0299   bool hasCapidError_;
0300 };
0301 
0302 std::ostream& operator<<(std::ostream& s, const HBHEChannelInfo& inf);
0303 
0304 #endif  // DataFormats_HcalRecHit_HBHEChannelInfo_h_