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