CMS 3D CMS Logo

HFSimpleTimeCheck.cc
Go to the documentation of this file.
1 #include <cstring>
2 #include <climits>
3 
5 
8 
9 // Phase 1 rechit status bit assignments
11 
12 namespace {
13  inline float build_rechit_time(const float weightedEnergySum,
14  const float weightedSum,
15  const float sum,
16  const unsigned count,
17  const float valueIfNothingWorks,
18  bool* resultComesFromTDC) {
19  if (weightedEnergySum > 0.f) {
20  *resultComesFromTDC = true;
21  return weightedSum / weightedEnergySum;
22  } else if (count) {
23  *resultComesFromTDC = true;
24  return sum / count;
25  } else {
26  *resultComesFromTDC = false;
27  return valueIfNothingWorks;
28  }
29  }
30 } // namespace
31 
32 HFSimpleTimeCheck::HFSimpleTimeCheck(const std::pair<float, float> tlimits[2],
33  const float energyWeights[2 * HFAnodeStatus::N_POSSIBLE_STATES - 1][2],
34  const unsigned i_soiPhase,
35  const float i_timeShift,
36  const float i_triseIfNoTDC,
37  const float i_tfallIfNoTDC,
38  const float i_minChargeForUndershoot,
39  const float i_minChargeForOvershoot,
40  const bool rejectAllFailures,
41  const bool alwaysCalculateQAsymmetry)
42  : soiPhase_(i_soiPhase),
43  timeShift_(i_timeShift),
44  triseIfNoTDC_(i_triseIfNoTDC),
45  tfallIfNoTDC_(i_tfallIfNoTDC),
46  minChargeForUndershoot_(i_minChargeForUndershoot),
47  minChargeForOvershoot_(i_minChargeForOvershoot),
48  rejectAllFailures_(rejectAllFailures),
49  alwaysQAsym_(alwaysCalculateQAsymmetry) {
50  tlimits_[0] = tlimits[0];
51  tlimits_[1] = tlimits[1];
52  float* to = &energyWeights_[0][0];
53  const float* from = &energyWeights[0][0];
54  memcpy(to, from, sizeof(energyWeights_));
55 }
56 
57 unsigned HFSimpleTimeCheck::determineAnodeStatus(const unsigned ianode, const HFQIE10Info& anode, bool*) const {
58  // Check if this anode has a dataframe error
59  if (!anode.isDataframeOK())
61 
62  // Check the time limits
63  float trise = anode.timeRising();
64  const bool timeIsKnown = !HcalSpecialTimes::isSpecial(trise);
65  trise += timeShift_;
66  if (timeIsKnown && tlimits_[ianode].first <= trise && trise <= tlimits_[ianode].second)
67  return HFAnodeStatus::OK;
68  else
70 }
71 
72 unsigned HFSimpleTimeCheck::mapStatusIntoIndex(const unsigned states[2]) const {
73  unsigned eStates[2];
74  eStates[0] = states[0];
75  eStates[1] = states[1];
76  if (!rejectAllFailures_)
77  for (unsigned i = 0; i < 2; ++i)
78  if (eStates[i] == HFAnodeStatus::FAILED_TIMING || eStates[i] == HFAnodeStatus::FAILED_OTHER)
79  eStates[i] = HFAnodeStatus::OK;
80  if (eStates[0] == HFAnodeStatus::OK)
81  return eStates[1];
82  else if (eStates[1] == HFAnodeStatus::OK)
83  return HFAnodeStatus::N_POSSIBLE_STATES + eStates[0] - 1;
84  else
85  return UINT_MAX;
86 }
87 
89  const HcalCalibrations& /* calibs */,
90  const bool flaggedBadInDB[2],
91  const bool expectSingleAnodePMT) {
92  HFRecHit rh;
93 
94  // Determine the status of each anode
96  if (expectSingleAnodePMT)
97  states[1] = HFAnodeStatus::NOT_DUAL;
98 
99  bool isTimingReliable[2] = {true, true};
100  for (unsigned ianode = 0; ianode < 2; ++ianode) {
101  if (flaggedBadInDB[ianode])
102  states[ianode] = HFAnodeStatus::FLAGGED_BAD;
103  else {
104  const HFQIE10Info* anodeInfo = prehit.getHFQIE10Info(ianode);
105  if (anodeInfo)
106  states[ianode] = determineAnodeStatus(ianode, *anodeInfo, &isTimingReliable[ianode]);
107  }
108  }
109 
110  // Reconstruct energy and time
111  const unsigned lookupInd = mapStatusIntoIndex(states);
112  if (lookupInd != UINT_MAX) {
113  // In this scope, at least one of states[i] is HFAnodeStatus::OK
114  // or was mapped into that status by "mapStatusIntoIndex" method
115  //
116  const float* weights = &energyWeights_[lookupInd][0];
117  float energy = 0.f, tfallWeightedEnergySum = 0.f, triseWeightedEnergySum = 0.f;
118  float tfallWeightedSum = 0.f, triseWeightedSum = 0.f;
119  float tfallSum = 0.f, triseSum = 0.f;
120  unsigned tfallCount = 0, triseCount = 0;
121 
122  for (unsigned ianode = 0; ianode < 2; ++ianode) {
123  const HFQIE10Info* anodeInfo = prehit.getHFQIE10Info(ianode);
124  if (anodeInfo && weights[ianode] > 0.f) {
125  const float weightedEnergy = weights[ianode] * anodeInfo->energy();
126  energy += weightedEnergy;
127 
128  if (isTimingReliable[ianode] && states[ianode] != HFAnodeStatus::FAILED_TIMING) {
129  float trise = anodeInfo->timeRising();
130  if (!HcalSpecialTimes::isSpecial(trise)) {
131  trise += timeShift_;
132  triseSum += trise;
133  ++triseCount;
134  if (weightedEnergy > 0.f) {
135  triseWeightedSum += trise * weightedEnergy;
136  triseWeightedEnergySum += weightedEnergy;
137  }
138  }
139 
140  float tfall = anodeInfo->timeFalling();
141  if (!HcalSpecialTimes::isSpecial(tfall)) {
142  tfall += timeShift_;
143  tfallSum += tfall;
144  ++tfallCount;
145  if (weightedEnergy > 0.f) {
146  tfallWeightedSum += tfall * weightedEnergy;
147  tfallWeightedEnergySum += weightedEnergy;
148  }
149  }
150  }
151  }
152  }
153 
154  bool triseFromTDC = false;
155  const float trise =
156  build_rechit_time(triseWeightedEnergySum, triseWeightedSum, triseSum, triseCount, triseIfNoTDC_, &triseFromTDC);
157 
158  bool tfallFromTDC = false;
159  const float tfall =
160  build_rechit_time(tfallWeightedEnergySum, tfallWeightedSum, tfallSum, tfallCount, tfallIfNoTDC_, &tfallFromTDC);
161 
162  rh = HFRecHit(prehit.id(), energy, trise, tfall);
163  HFRecHitAuxSetter::setAux(prehit, states, soiPhase_, &rh);
164 
165  // Set the "timing from TDC" flag
166  const uint32_t flag = triseFromTDC ? 1U : 0U;
168  }
169 
170  return rh;
171 }
constexpr float energy() const
Definition: HFQIE10Info.h:80
constexpr void setFlagField(uint32_t value, int base, int width=1)
Definition: CaloRecHit.h:36
constexpr HFQIE10Info const * getHFQIE10Info(unsigned index) const
Definition: HFPreRecHit.h:39
unsigned mapStatusIntoIndex(const unsigned states[2]) const
U second(std::pair< T, U > const &p)
constexpr float timeFalling() const
Definition: HFQIE10Info.h:82
constexpr float timeRising() const
Definition: HFQIE10Info.h:81
std::pair< float, float > tlimits_[2]
double f[11][100]
constexpr bool isSpecial(const float t)
float energyWeights_[2 *HFAnodeStatus::N_POSSIBLE_STATES - 1][2]
HFSimpleTimeCheck(const std::pair< float, float > tlimits[2], const float energyWeights[2 *HFAnodeStatus::N_POSSIBLE_STATES - 1][2], unsigned soiPhase, float timeShift, float triseIfNoTDC, float tfallIfNoTDC, float minChargeForUndershoot, float minChargeForOvershoot, bool rejectAllFailures=true, bool alwaysCalculateChargeAsymmetry=true)
HFRecHit reconstruct(const HFPreRecHit &prehit, const HcalCalibrations &calibs, const bool flaggedBadInDB[2], bool expectSingleAnodePMT) override
constexpr HcalDetId id() const
Definition: HFPreRecHit.h:34
static void setAux(const HFPreRecHit &prehit, const unsigned anodeStates[2], unsigned soiPhase, HFRecHit *rechit)
bool isDataframeOK(bool checkAllTimeSlices=false) const
Definition: HFQIE10Info.h:94
virtual unsigned determineAnodeStatus(unsigned anodeNumber, const HFQIE10Info &anode, bool *isTimingReliable) const
alwaysCalculateQAsymmetry
Definition: hfreco_cfi.py:113