HBHEChannelInfo

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
#ifndef DataFormats_HcalRecHit_HBHEChannelInfo_h_
#define DataFormats_HcalRecHit_HBHEChannelInfo_h_

#include <cfloat>
#include <iostream>

#include "DataFormats/HcalDetId/interface/HcalDetId.h"
#include "DataFormats/HcalRecHit/interface/HcalSpecialTimes.h"

/** \class HBHEChannelInfo
 *
 * Unpacked charge and TDC information in a format which works
 * for both QIE8 and QIE11
 */
class HBHEChannelInfo {
public:
  typedef HcalDetId key_type;

  static const unsigned MAXSAMPLES = 10;

  constexpr HBHEChannelInfo()
      : id_(),
        rawCharge_{0.},
        pedestal_{0.},
        pedestalWidth_{0.},
        gain_{0.},
        gainWidth_{0.},
        darkCurrent_{0},
        fcByPE_{0},
        lambda_{0},
        noisecorr_{0},
        riseTime_{0.f},
        adc_{0},
        dFcPerADC_{0.f},
        recoShape_{0},
        nSamples_{0},
        soi_{0},
        capid_{0},
        hasTimeInfo_{false},
        hasEffectivePedestals_{false},
        dropped_{true},
        hasLinkError_{false},
        hasCapidError_{false} {}

  constexpr explicit HBHEChannelInfo(const bool hasTimeFromTDC, const bool hasEffectivePed)
      : id_(),
        rawCharge_{0.},
        pedestal_{0.},
        pedestalWidth_{0.},
        gain_{0.},
        gainWidth_{0.},
        darkCurrent_{0},
        fcByPE_{0},
        lambda_{0},
        noisecorr_{0},
        riseTime_{0.f},
        adc_{0},
        dFcPerADC_{0.f},
        recoShape_{0},
        nSamples_{0},
        soi_{0},
        capid_{0},
        hasTimeInfo_(hasTimeFromTDC),
        hasEffectivePedestals_(hasEffectivePed),
        dropped_{true},
        hasLinkError_{false},
        hasCapidError_{false} {}

  constexpr void clear() {
    id_ = HcalDetId(0U);
    recoShape_ = 0;
    nSamples_ = 0;
    soi_ = 0;
    capid_ = 0;
    darkCurrent_ = 0;
    fcByPE_ = 0;
    lambda_ = 0, dropped_ = true;
    noisecorr_ = 0;
    hasLinkError_ = false;
    hasCapidError_ = false;
  }

  constexpr void setChannelInfo(const HcalDetId& detId,
                                const int recoShape,
                                const unsigned nSamp,
                                const unsigned iSoi,
                                const int iCapid,
                                const double darkCurrent,
                                const double fcByPE,
                                const double lambda,
                                const double noisecorr,
                                const bool linkError,
                                const bool capidError,
                                const bool dropThisChannel) {
    recoShape_ = recoShape;
    id_ = detId;
    nSamples_ = nSamp < MAXSAMPLES ? nSamp : MAXSAMPLES;
    soi_ = iSoi;
    capid_ = iCapid;
    darkCurrent_ = darkCurrent;
    fcByPE_ = fcByPE;
    lambda_ = lambda, dropped_ = dropThisChannel;
    noisecorr_ = noisecorr;
    hasLinkError_ = linkError;
    hasCapidError_ = capidError;
  }

  constexpr void tagAsDropped() { dropped_ = true; }

  // For speed, the "setSample" function does not perform bounds checking
  constexpr void setSample(const unsigned ts,
                           const uint8_t rawADC,
                           const float differentialChargeGain,
                           const double q,
                           const double ped,
                           const double pedWidth,
                           const double g,
                           const double gainWidth,
                           const float t) {
    rawCharge_[ts] = q;
    riseTime_[ts] = t;
    adc_[ts] = rawADC;
    dFcPerADC_[ts] = differentialChargeGain;
    pedestal_[ts] = ped;
    gain_[ts] = g;
    pedestalWidth_[ts] = pedWidth;
    gainWidth_[ts] = gainWidth;
  }

  // Inspectors
  constexpr HcalDetId id() const { return id_; }

  // access the recoShape
  constexpr int recoShape() const { return recoShape_; }

  constexpr unsigned nSamples() const { return nSamples_; }
  constexpr unsigned soi() const { return soi_; }
  constexpr int capid() const { return capid_; }
  constexpr bool hasTimeInfo() const { return hasTimeInfo_; }
  constexpr bool hasEffectivePedestals() const { return hasEffectivePedestals_; }
  constexpr double darkCurrent() const { return darkCurrent_; }
  constexpr double fcByPE() const { return fcByPE_; }
  constexpr double lambda() const { return lambda_; }
  constexpr double noisecorr() const { return noisecorr_; }
  constexpr bool isDropped() const { return dropped_; }
  constexpr bool hasLinkError() const { return hasLinkError_; }
  constexpr bool hasCapidError() const { return hasCapidError_; }

  // Direct read-only access to time slice arrays
  constexpr double const* rawCharge() const { return rawCharge_; }
  constexpr double const* pedestal() const { return pedestal_; }
  constexpr double const* pedestalWidth() const { return pedestalWidth_; }
  constexpr double const* gain() const { return gain_; }
  constexpr double const* gainWidth() const { return gainWidth_; }
  constexpr uint8_t const* adc() const { return adc_; }
  constexpr float const* dFcPerADC() const { return dFcPerADC_; }
  constexpr float const* riseTime() const {
    if (hasTimeInfo_)
      return riseTime_;
    else
      return nullptr;
  }

  // Indexed access to time slice quantities. No bounds checking.
  constexpr double tsRawCharge(const unsigned ts) const { return rawCharge_[ts]; }
  constexpr double tsPedestal(const unsigned ts) const { return pedestal_[ts]; }
  constexpr double tsPedestalWidth(const unsigned ts) const { return pedestalWidth_[ts]; }
  constexpr double tsGain(const unsigned ts) const { return gain_[ts]; }
  constexpr double tsGainWidth(const unsigned ts) const { return gainWidth_[ts]; }
  constexpr double tsCharge(const unsigned ts) const { return rawCharge_[ts] - pedestal_[ts]; }
  constexpr double tsEnergy(const unsigned ts) const { return (rawCharge_[ts] - pedestal_[ts]) * gain_[ts]; }
  constexpr uint8_t tsAdc(const unsigned ts) const { return adc_[ts]; }
  constexpr float tsDFcPerADC(const unsigned ts) const { return dFcPerADC_[ts]; }
  constexpr float tsRiseTime(const unsigned ts) const {
    return hasTimeInfo_ ? riseTime_[ts] : HcalSpecialTimes::UNKNOWN_T_NOTDC;
  }

  // Signal rise time measurement for the SOI, if available
  constexpr float soiRiseTime() const {
    return (hasTimeInfo_ && soi_ < nSamples_) ? riseTime_[soi_] : HcalSpecialTimes::UNKNOWN_T_NOTDC;
  }

  // The TS with the "end" index is not included in the window
  constexpr double chargeInWindow(const unsigned begin, const unsigned end) const {
    double sum = 0.0;
    const unsigned imax = end < nSamples_ ? end : nSamples_;
    for (unsigned i = begin; i < imax; ++i)
      sum += (rawCharge_[i] - pedestal_[i]);
    return sum;
  }

  constexpr double energyInWindow(const unsigned begin, const unsigned end) const {
    double sum = 0.0;
    const unsigned imax = end < nSamples_ ? end : nSamples_;
    for (unsigned i = begin; i < imax; ++i)
      sum += (rawCharge_[i] - pedestal_[i]) * gain_[i];
    return sum;
  }

  // The two following methods return MAXSAMPLES if the specified
  // window does not overlap with the samples stored
  constexpr unsigned peakChargeTS(const unsigned begin, const unsigned end) const {
    unsigned iPeak = MAXSAMPLES;
    double dmax = -DBL_MAX;
    const unsigned imax = end < nSamples_ ? end : nSamples_;
    for (unsigned i = begin; i < imax; ++i) {
      const double q = rawCharge_[i] - pedestal_[i];
      if (q > dmax) {
        dmax = q;
        iPeak = i;
      }
    }
    return iPeak;
  }

  constexpr unsigned peakEnergyTS(const unsigned begin, const unsigned end) const {
    unsigned iPeak = MAXSAMPLES;
    double dmax = -DBL_MAX;
    const unsigned imax = end < nSamples_ ? end : nSamples_;
    for (unsigned i = begin; i < imax; ++i) {
      const double e = (rawCharge_[i] - pedestal_[i]) * gain_[i];
      if (e > dmax) {
        dmax = e;
        iPeak = i;
      }
    }
    return iPeak;
  }

  // The following function can be used, for example,
  // in a check for presence of saturated ADC values
  constexpr uint8_t peakAdcValue(const unsigned begin, const unsigned end) const {
    uint8_t peak = 0;
    const unsigned imax = end < nSamples_ ? end : nSamples_;
    for (unsigned i = begin; i < imax; ++i)
      if (adc_[i] > peak)
        peak = adc_[i];
    return peak;
  }

private:
  HcalDetId id_;

  // Charge in fC for all time slices
  double rawCharge_[MAXSAMPLES];

  // Pedestal in fC
  double pedestal_[MAXSAMPLES];

  // Pedestal Width in fC
  double pedestalWidth_[MAXSAMPLES];

  // fC to GeV conversion factor
  double gain_[MAXSAMPLES];

  // fC to GeV conversion factor
  double gainWidth_[MAXSAMPLES];

  // needed for the dark current
  double darkCurrent_;
  double fcByPE_;
  double lambda_;
  double noisecorr_;

  // Signal rise time from TDC in ns (if provided)
  float riseTime_[MAXSAMPLES];

  // Raw QIE ADC values
  uint8_t adc_[MAXSAMPLES];

  // Differential fC/ADC gain. Needed for proper determination
  // of the ADC quantization error.
  float dFcPerADC_[MAXSAMPLES];

  // Reco Shapes
  int32_t recoShape_;

  // Number of time slices actually filled
  uint32_t nSamples_;

  // "Sample of interest" in the array of time slices
  uint32_t soi_;

  // QIE8 or QIE11 CAPID for the sample of interest
  int32_t capid_;

  // Flag indicating presence of the time info from TDC (QIE11)
  bool hasTimeInfo_;

  // Flag indicating use of effective pedestals
  bool hasEffectivePedestals_;

  // Flag indicating that this channel should be dropped
  // (typically, tagged bad from DB or zero-suppressed)
  bool dropped_;

  // Flags indicating presence of hardware errors
  bool hasLinkError_;
  bool hasCapidError_;
};

std::ostream& operator<<(std::ostream& s, const HBHEChannelInfo& inf);

#endif  // DataFormats_HcalRecHit_HBHEChannelInfo_h_