File indexing completed on 2023-03-17 11:21:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "RecoPPS/Local/interface/TotemTimingConversions.h"
0013 #include "FWCore/Utilities/interface/Exception.h"
0014
0015
0016
0017 TotemTimingConversions::TotemTimingConversions(double sampicSamplingPeriodNs,
0018 bool mergeTimePeaks,
0019 const PPSTimingCalibration& calibration)
0020 : calibration_(calibration),
0021 sampicSamplingPeriodNs_(sampicSamplingPeriodNs),
0022 mergeTimePeaks_(mergeTimePeaks),
0023 calibrationFunction_(calibration_.formula()) {}
0024
0025
0026
0027 float TotemTimingConversions::timeOfFirstSample(const TotemTimingDigi& digi) const {
0028 unsigned int offsetOfSamples = digi.eventInfo().offsetOfSamples();
0029
0030 unsigned int timestamp =
0031 (digi.cellInfo() <= SAMPIC_MAX_NUMBER_OF_SAMPLES / 2) ? digi.timestampA() : digi.timestampB();
0032
0033 int cell0TimeClock = timestamp + ((digi.fpgaTimestamp() - timestamp) & CELL0_MASK) - digi.eventInfo().l1ATimestamp() +
0034 digi.eventInfo().l1ALatency();
0035
0036
0037 float cell0TimeInstant = SAMPIC_MAX_NUMBER_OF_SAMPLES * sampicSamplingPeriodNs_ * cell0TimeClock;
0038
0039
0040 float firstCellTimeInstant =
0041 (digi.cellInfo() < offsetOfSamples)
0042 ? cell0TimeInstant + digi.cellInfo() * sampicSamplingPeriodNs_
0043 : cell0TimeInstant - (SAMPIC_MAX_NUMBER_OF_SAMPLES - digi.cellInfo()) * sampicSamplingPeriodNs_;
0044
0045 int db = digi.hardwareBoardId();
0046 int sampic = digi.hardwareSampicId();
0047 int channel = digi.hardwareChannelId();
0048 float t = firstCellTimeInstant + calibration_.timeOffset(db, sampic, channel);
0049
0050
0051 if (mergeTimePeaks_) {
0052 if (t < -ACCEPTED_TIME_RADIUS)
0053 t += SAMPIC_MAX_NUMBER_OF_SAMPLES * sampicSamplingPeriodNs_;
0054 if (t > ACCEPTED_TIME_RADIUS)
0055 t -= SAMPIC_MAX_NUMBER_OF_SAMPLES * sampicSamplingPeriodNs_;
0056 }
0057
0058 return t;
0059 }
0060
0061
0062
0063 float TotemTimingConversions::triggerTime(const TotemTimingDigi& digi) const {
0064 unsigned int offsetOfSamples = digi.eventInfo().offsetOfSamples();
0065 return timeOfFirstSample(digi) + (SAMPIC_MAX_NUMBER_OF_SAMPLES - offsetOfSamples) * sampicSamplingPeriodNs_;
0066 }
0067
0068
0069
0070 float TotemTimingConversions::timePrecision(const TotemTimingDigi& digi) const {
0071 int db = digi.hardwareBoardId();
0072 int sampic = digi.hardwareSampicId();
0073 int channel = digi.hardwareChannelId();
0074 return calibration_.timePrecision(db, sampic, channel);
0075 }
0076
0077
0078
0079 std::vector<float> TotemTimingConversions::timeSamples(const TotemTimingDigi& digi) const {
0080 std::vector<float> time(digi.numberOfSamples());
0081 for (unsigned int i = 0; i < time.size(); ++i)
0082 time.at(i) = timeOfFirstSample(digi) + i * sampicSamplingPeriodNs_;
0083 return time;
0084 }
0085
0086
0087
0088
0089 std::vector<float> TotemTimingConversions::voltSamples(const TotemTimingDigi& digi) const {
0090 std::vector<float> data;
0091 if (calibrationFunction_.numberOfVariables() != 1)
0092 for (const auto& sample : digi.samples())
0093 data.emplace_back(SAMPIC_ADC_V * sample);
0094 else {
0095 unsigned int db = digi.hardwareBoardId();
0096 unsigned int sampic = digi.hardwareSampicId();
0097 unsigned int channel = digi.hardwareChannelId();
0098 unsigned int cell = digi.cellInfo();
0099 for (const auto& sample : digi.samples()) {
0100
0101 const unsigned short sample_cell = (cell++) % SAMPIC_MAX_NUMBER_OF_SAMPLES;
0102 auto parameters = calibration_.parameters(db, sampic, channel, sample_cell);
0103 if (parameters.empty() || parameters.size() != calibrationFunction_.numberOfParameters())
0104 throw cms::Exception("TotemTimingConversions:voltSamples")
0105 << "Invalid calibrations retrieved for Sampic digi"
0106 << " (" << db << ", " << sampic << ", " << channel << ", " << sample_cell << ")!";
0107 data.emplace_back(calibrationFunction_.evaluate(std::vector<double>{(double)sample}, parameters));
0108 }
0109 }
0110 return data;
0111 }