CMS 3D CMS Logo

TotemTimingRecHitProducerAlgorithm.cc
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * This is a part of CTPPS offline software.
4  * Authors:
5  * Laurent Forthomme (laurent.forthomme@cern.ch)
6  * Nicola Minafra
7  *
8  ****************************************************************************/
9 
11 
12 //----------------------------------------------------------------------------------------------------
13 
14 const float TotemTimingRecHitProducerAlgorithm::SINC_COEFFICIENT = std::acos(-1) * 2 / 7.8;
15 
16 //----------------------------------------------------------------------------------------------------
17 
19  const edm::ParameterSet &iConfig)
20  : sampicConversions_(iConfig.getParameter<std::string>("calibrationFile")),
21  baselinePoints_(iConfig.getParameter<int>("baselinePoints")),
22  saturationLimit_(iConfig.getParameter<double>("saturationLimit")),
23  cfdFraction_(iConfig.getParameter<double>("cfdFraction")),
24  smoothingPoints_(iConfig.getParameter<int>("smoothingPoints")),
25  lowPassFrequency_(iConfig.getParameter<double>("lowPassFrequency")),
26  hysteresis_(iConfig.getParameter<double>("hysteresis")) {}
27 
31  for (const auto &vec : input) {
32  const TotemTimingDetId detid(vec.detId());
33 
34  float x_pos = 0, y_pos = 0, z_pos = 0, x_width = 0, y_width = 0,
35  z_width = 0;
36 
37  // retrieve the geometry element associated to this DetID ( if present )
38  const DetGeomDesc *det = nullptr;
39  try { // no other efficient way to check presence
40  det = geom->getSensor(detid);
41  } catch (const cms::Exception &) {
42  det = nullptr;
43  }
44 
45  if (det) {
46  x_pos = det->translation().x(), y_pos = det->translation().y();
47  if (det->parents().empty())
48  edm::LogWarning("TotemTimingRecHitProducerAlgorithm")
49  << "The geometry element for " << detid
50  << " has no parents. Check the geometry hierarchy!";
51  else
52  z_pos = det->parents()[det->parents().size() - 1]
53  .absTranslation()
54  .z(); // retrieve the plane position;
55 
56  x_width = 2.0 * det->params().at(0), // parameters stand for half the size
57  y_width = 2.0 * det->params().at(1),
58  z_width = 2.0 * det->params().at(2);
59  } else
60  edm::LogWarning("TotemTimingRecHitProducerAlgorithm")
61  << "Failed to retrieve a sensor for " << detid;
62 
63  edm::DetSet<TotemTimingRecHit> &rec_hits = output.find_or_insert(detid);
64 
65  for (const auto &digi : vec) {
66  const float triggerCellTimeInstant(
68  const std::vector<float> time(sampicConversions_.getTimeSamples(digi));
69  std::vector<float> data(sampicConversions_.getVoltSamples(digi));
70 
71  auto max_it = std::max_element(data.begin(), data.end());
72 
73  RegressionResults baselineRegression =
75 
76  // remove baseline
77  std::vector<float> dataCorrected(data.size());
78  for (unsigned int i = 0; i < data.size(); ++i)
79  dataCorrected.at(i) = data.at(i) -
80  (baselineRegression.q + baselineRegression.m * time.at(i));
81  auto max_corrected_it =
82  std::max_element(dataCorrected.begin(), dataCorrected.end());
83 
85  if (*max_it < saturationLimit_)
86  t = constantFractionDiscriminator(time, dataCorrected);
87 
89 
91  x_pos, x_width, y_pos, y_width, z_pos, z_width, // spatial information
92  t, triggerCellTimeInstant, .0, *max_corrected_it,
93  baselineRegression.rms, mode_));
94  }
95  }
96 }
97 
100  const std::vector<float> &time, const std::vector<float> &data,
101  const unsigned int start_at, const unsigned int points) const {
103  if (time.size() != data.size()) {
104  return results;
105  }
106  if (start_at > time.size()) {
107  return results;
108  }
109  unsigned int stop_at = std::min((unsigned int)time.size(), start_at + points);
110  unsigned int realPoints = stop_at - start_at;
111  auto t_begin = std::next(time.begin(), start_at);
112  auto t_end = std::next(time.begin(), stop_at);
113  auto d_begin = std::next(data.begin(), start_at);
114  auto d_end = std::next(data.begin(), stop_at);
115 
116  float sx = .0;
117  std::for_each(t_begin, t_end, [&](float value) { sx += value; });
118  float sxx = .0;
119  std::for_each(t_begin, t_end, [&](float value) { sxx += value * value; });
120 
121  float sy = .0;
122  std::for_each(d_begin, d_end, [&](float value) { sy += value; });
123  float syy = .0;
124  std::for_each(d_begin, d_end, [&](float value) { syy += value * value; });
125 
126  float sxy = .0;
127  for (unsigned int i = 0; i < realPoints; ++i)
128  sxy += (time.at(i)) * (data.at(i));
129 
130  // y = mx + q
131  results.m = (sxy * realPoints - sx * sy) / (sxx * realPoints - sx * sx);
132  results.q = sy / realPoints - results.m * sx / realPoints;
133 
134  float correctedSyy = .0;
135  for (unsigned int i = 0; i < realPoints; ++i)
136  correctedSyy += pow(data.at(i) - (results.m * time.at(i) + results.q), 2);
137  results.rms = sqrt(correctedSyy / realPoints);
138 
139  return results;
140 }
141 
143  const std::vector<float> &data, const float &threshold) const {
144  int threholdCrossingIndex = -1;
145  bool above = false;
146  bool lockForHysteresis = false;
147 
148  for (unsigned int i = 0; i < data.size(); ++i) {
149  // Look for first edge
150  if (!above && !lockForHysteresis && data.at(i) > threshold) {
151  threholdCrossingIndex = i;
152  above = true;
153  lockForHysteresis = true;
154  }
155  if (above && lockForHysteresis) // NOTE: not else if!, "above" can be set in
156  // the previous if
157  {
158  // Lock until above threshold_+hysteresis
159  if (lockForHysteresis && data.at(i) > threshold + hysteresis_) {
160  lockForHysteresis = false;
161  }
162  // Ignore noise peaks
163  if (lockForHysteresis && data.at(i) < threshold) {
164  above = false;
165  lockForHysteresis = false;
166  threholdCrossingIndex = -1; // assigned because of noise
167  }
168  }
169  }
170 
171  return threholdCrossingIndex;
172 }
173 
175  const std::vector<float> &time, const std::vector<float> &data) {
176  std::vector<float> dataProcessed(data);
177  if (lowPassFrequency_ != 0) {
178  // Smoothing
179  for (int i = 0; i < (int)data.size(); ++i) {
180  for (int j = -smoothingPoints_ / 2;
181  j <= +smoothingPoints_ / 2; ++j) {
182  if ((i + j) >= 0 && (i + j) < (int)data.size() && j != 0) {
183  float x = SINC_COEFFICIENT * lowPassFrequency_ * j;
184  dataProcessed.at(i) += data.at(i + j) * std::sin(x) / x;
185  }
186  }
187  }
188  }
189  auto max_it = std::max_element(dataProcessed.begin(), dataProcessed.end());
190  float max = *max_it;
191 
192  float threshold = cfdFraction_ * max;
193  int indexOfThresholdCrossing = fastDiscriminator(dataProcessed, threshold);
194 
196  if (indexOfThresholdCrossing >= baselinePoints_ &&
197  indexOfThresholdCrossing < (int)time.size()) {
198  t = (time.at(indexOfThresholdCrossing - 1) -
199  time.at(indexOfThresholdCrossing)) /
200  (dataProcessed.at(indexOfThresholdCrossing - 1) -
201  dataProcessed.at(indexOfThresholdCrossing)) *
202  (threshold - dataProcessed.at(indexOfThresholdCrossing)) +
203  time.at(indexOfThresholdCrossing);
204  }
205 
206  return t;
207 }
void push_back(const T &t)
Definition: DetSet.h:68
std::vector< float > getTimeSamples(const TotemTimingDigi &digi) const
std::vector< float > getVoltSamples(const TotemTimingDigi &digi) const
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
const float getTriggerTime(const TotemTimingDigi &digi) const
static std::string const input
Definition: EdmProvDump.cc:44
reference find_or_insert(det_id_type id)
Definition: DetSetVector.h:254
const DetGeomDesc * getSensor(unsigned int id) const
returns geometry of a detector performs necessary checks, returns NULL if fails
float constantFractionDiscriminator(const std::vector< float > &time, const std::vector< float > &data)
T sqrt(T t)
Definition: SSEVec.h:18
Geometrical description of a sensor.
Definition: DetGeomDesc.h:37
virtual std::vector< DDExpandedNode > parents() const
returns all the components below
Definition: DetGeomDesc.h:67
DDTranslation translation() const
Definition: DetGeomDesc.h:84
TotemTimingRecHitProducerAlgorithm(const edm::ParameterSet &conf)
Definition: value.py:1
T min(T a, T b)
Definition: MathUtil.h:58
RegressionResults simplifiedLinearRegression(const std::vector< float > &time, const std::vector< float > &data, const unsigned int start_at, const unsigned int points) const
The manager class for TOTEM RP geometry.
Definition: CTPPSGeometry.h:33
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
std::vector< double > params() const
Definition: DetGeomDesc.h:89
void build(const CTPPSGeometry *, const edm::DetSetVector< TotemTimingDigi > &, edm::DetSetVector< TotemTimingRecHit > &)
int fastDiscriminator(const std::vector< float > &data, const float &threshold) const
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
Detector ID class for CTPPS Totem Timing detectors. Bits [19:31] : Assigend in CTPPSDetId Calss Bits ...