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 
12 
13 //----------------------------------------------------------------------------------------------------
14 
15 const float TotemTimingRecHitProducerAlgorithm::SINC_COEFFICIENT = std::acos(-1) * 2 / 7.8;
16 
17 //----------------------------------------------------------------------------------------------------
18 
20  const edm::ParameterSet &iConfig)
21  : sampicConversions_(iConfig.getParameter<std::string>("calibrationFile")),
22  baselinePoints_(iConfig.getParameter<int>("baselinePoints")),
23  saturationLimit_(iConfig.getParameter<double>("saturationLimit")),
24  cfdFraction_(iConfig.getParameter<double>("cfdFraction")),
25  smoothingPoints_(iConfig.getParameter<int>("smoothingPoints")),
26  lowPassFrequency_(iConfig.getParameter<double>("lowPassFrequency")),
27  hysteresis_(iConfig.getParameter<double>("hysteresis")) {}
28 
32  for (const auto &vec : input) {
33  const TotemTimingDetId detid(vec.detId());
34 
35  float x_pos = 0.0f, y_pos = 0.0f, z_pos = 0.0f, x_width = 0.0f, y_width = 0.0f,
36  z_width = 0.0f;
37 
38  // retrieve the geometry element associated to this DetID ( if present )
39  const DetGeomDesc *det = geom->getSensorNoThrow(detid);
40 
41  if (det) {
42  x_pos = det->translation().x(), y_pos = det->translation().y();
43  z_pos = det->parentZPosition(); // retrieve the plane position;
44 
45  x_width = 2.0 * det->params()[0], // parameters stand for half the size
46  y_width = 2.0 * det->params()[1],
47  z_width = 2.0 * det->params()[2];
48  } else
49  edm::LogWarning("TotemTimingRecHitProducerAlgorithm")
50  << "Failed to retrieve a sensor for " << detid;
51 
52  edm::DetSet<TotemTimingRecHit> &rec_hits = output.find_or_insert(detid);
53 
54  for (const auto &digi : vec) {
55  const float triggerCellTimeInstant(
57  const std::vector<float> time(sampicConversions_.getTimeSamples(digi));
58  std::vector<float> data(sampicConversions_.getVoltSamples(digi));
59 
60  auto max_it = std::max_element(data.begin(), data.end());
61 
62  RegressionResults baselineRegression =
64 
65  // remove baseline
66  std::vector<float> dataCorrected(data.size());
67  for (unsigned int i = 0; i < data.size(); ++i)
68  dataCorrected[i] = data[i] -
69  (baselineRegression.q + baselineRegression.m * time[i]);
70  auto max_corrected_it =
71  std::max_element(dataCorrected.begin(), dataCorrected.end());
72 
74  if (*max_it < saturationLimit_)
75  t = constantFractionDiscriminator(time, dataCorrected);
76 
78 
80  x_pos, x_width, y_pos, y_width, z_pos, z_width, // spatial information
81  t, triggerCellTimeInstant, .0, *max_corrected_it,
82  baselineRegression.rms, mode_));
83  }
84  }
85 }
86 
89  const std::vector<float> &time, const std::vector<float> &data,
90  const unsigned int start_at, const unsigned int points) const {
92  if (time.size() != data.size()) {
93  return results;
94  }
95  if (start_at > time.size()) {
96  return results;
97  }
98  unsigned int stop_at = std::min((unsigned int)time.size(), start_at + points);
99  unsigned int realPoints = stop_at - start_at;
100  auto t_begin = std::next(time.begin(), start_at);
101  auto t_end = std::next(time.begin(), stop_at);
102  auto d_begin = std::next(data.begin(), start_at);
103  auto d_end = std::next(data.begin(), stop_at);
104 
105  float sx = .0f;
106  std::for_each(t_begin, t_end, [&](float value) { sx += value; });
107  float sxx = .0f;
108  std::for_each(t_begin, t_end, [&](float value) { sxx += value * value; });
109 
110  float sy = .0f;
111  std::for_each(d_begin, d_end, [&](float value) { sy += value; });
112  float syy = .0f;
113  std::for_each(d_begin, d_end, [&](float value) { syy += value * value; });
114 
115  float sxy = .0f;
116  for (unsigned int i = 0; i < realPoints; ++i)
117  sxy += (time[i]) * (data[i]);
118 
119  // y = mx + q
120  results.m = (sxy * realPoints - sx * sy) / (sxx * realPoints - sx * sx);
121  results.q = sy / realPoints - results.m * sx / realPoints;
122 
123  float correctedSyy = .0f;
124  for (unsigned int i = 0; i < realPoints; ++i)
125  correctedSyy += pow(data[i] - (results.m * time[i] + results.q), 2);
126  results.rms = sqrt(correctedSyy / realPoints);
127 
128  return results;
129 }
130 
132  const std::vector<float> &data, const float &threshold) const {
133  int threholdCrossingIndex = -1;
134  bool above = false;
135  bool lockForHysteresis = false;
136 
137  for (unsigned int i = 0; i < data.size(); ++i) {
138  // Look for first edge
139  if (!above && !lockForHysteresis && data[i] > threshold) {
140  threholdCrossingIndex = i;
141  above = true;
142  lockForHysteresis = true;
143  }
144  if (above && lockForHysteresis) // NOTE: not else if!, "above" can be set in
145  // the previous if
146  {
147  // Lock until above threshold_+hysteresis
148  if (lockForHysteresis && data[i] > threshold + hysteresis_) {
149  lockForHysteresis = false;
150  }
151  // Ignore noise peaks
152  if (lockForHysteresis && data[i] < threshold) {
153  above = false;
154  lockForHysteresis = false;
155  threholdCrossingIndex = -1; // assigned because of noise
156  }
157  }
158  }
159 
160  return threholdCrossingIndex;
161 }
162 
164  const std::vector<float> &time, const std::vector<float> &data) {
165  std::vector<float> dataProcessed(data);
166  if (lowPassFrequency_ != 0) {
167  // Smoothing
168  for (int i = 0; i < (int)data.size(); ++i) {
169  for (int j = -smoothingPoints_ / 2;
170  j <= +smoothingPoints_ / 2; ++j) {
171  if ((i + j) >= 0 && (i + j) < (int)data.size() && j != 0) {
172  float x = SINC_COEFFICIENT * lowPassFrequency_ * j;
173  dataProcessed[i] += data[i + j] * std::sin(x) / x;
174  }
175  }
176  }
177  }
178  auto max_it = std::max_element(dataProcessed.begin(), dataProcessed.end());
179  float max = *max_it;
180 
181  float threshold = cfdFraction_ * max;
182  int indexOfThresholdCrossing = fastDiscriminator(dataProcessed, threshold);
183 
185  if (indexOfThresholdCrossing >= baselinePoints_ &&
186  indexOfThresholdCrossing < (int)time.size()) {
187  t = (time[indexOfThresholdCrossing - 1] -
188  time[indexOfThresholdCrossing]) /
189  (dataProcessed[indexOfThresholdCrossing - 1] -
190  dataProcessed[indexOfThresholdCrossing]) *
191  (threshold - dataProcessed[indexOfThresholdCrossing]) +
192  time[indexOfThresholdCrossing];
193  }
194 
195  return t;
196 }
Translation translation() const
Definition: DetGeomDesc.h:66
void push_back(const T &t)
Definition: DetSet.h:68
std::vector< float > getTimeSamples(const TotemTimingDigi &digi) const
const DetGeomDesc * getSensorNoThrow(unsigned int id) 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:45
reference find_or_insert(det_id_type id)
Definition: DetSetVector.h:254
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:35
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
float parentZPosition() const
Definition: DetGeomDesc.h:58
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
std::vector< double > params() const
Definition: DetGeomDesc.h:68
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 ...