File indexing completed on 2025-07-12 07:55:39
0001
0002
0003
0004
0005
0006
0007 #include <DDRec/CellIDPositionConverter.h>
0008 #include <podio/RelationRange.h>
0009 #include <cmath>
0010 #include <gsl/pointers>
0011 #include <unordered_map>
0012 #include <unordered_set>
0013 #include <utility>
0014
0015 #include "SiliconPulseDiscretization.h"
0016
0017 #include "TGraph.h"
0018
0019 namespace eicrecon {
0020
0021 void SiliconPulseDiscretization::init() {}
0022
0023 double SiliconPulseDiscretization::_interpolateOrZero(const TGraph& graph, double t, double tMin,
0024 double tMax) const {
0025
0026
0027 if (t < tMin || t > tMax) {
0028 return 0;
0029 }
0030 double height = graph.Eval(t, nullptr, "S");
0031 if (!std::isfinite(height)) {
0032 error("Pulse interpolation returns nan. This happen mostly because there are multiple "
0033 "pulse height values at the same time. Did you call PulseCombiner?");
0034 }
0035 return height;
0036 }
0037
0038 void SiliconPulseDiscretization::process(const SiliconPulseDiscretization::Input& input,
0039 const SiliconPulseDiscretization::Output& output) const {
0040 const auto [inPulses] = input;
0041 auto [outPulses] = output;
0042
0043
0044
0045
0046
0047
0048 std::unordered_map<dd4hep::rec::CellID, std::pair<TGraph, std::unordered_set<int>>>
0049 graphAndCycle4Cells;
0050
0051 for (const auto& pulse : *inPulses) {
0052
0053 auto cellID = pulse.getCellID();
0054 auto time = pulse.getTime();
0055 auto interval = pulse.getInterval();
0056
0057
0058
0059 auto& graph = graphAndCycle4Cells[cellID].first;
0060 auto& activeCycles = graphAndCycle4Cells[cellID].second;
0061 for (unsigned int i = 0; i < pulse.getAmplitude().size(); i++) {
0062 auto currTime = time + i * interval;
0063
0064 int EICROCCycle = std::floor(currTime / m_cfg.EICROC_period);
0065 activeCycles.insert(EICROCCycle);
0066 graph.SetPoint(graph.GetN(), currTime + m_cfg.global_offset, pulse.getAmplitude()[i]);
0067 }
0068 }
0069
0070
0071 for (auto& [_, graphAndCycle] : graphAndCycle4Cells) {
0072 graphAndCycle.first.Sort();
0073 graphAndCycle.first.SetBit(TGraph::kIsSortedX);
0074 }
0075
0076
0077 for (const auto& [cellID, graphAndCycle] : graphAndCycle4Cells) {
0078 const auto& graph = graphAndCycle.first;
0079 const auto& activeCycle = graphAndCycle.second;
0080 double tMin = NAN;
0081 double tMax = NAN;
0082 double temp = NAN;
0083 graph.ComputeRange(tMin, temp, tMax, temp);
0084
0085 for (int curriEICRocCycle : activeCycle) {
0086
0087 double startTime = curriEICRocCycle * m_cfg.EICROC_period;
0088
0089 auto outPulse = outPulses->create();
0090 outPulse.setCellID(cellID);
0091 outPulse.setInterval(m_cfg.local_period);
0092 outPulse.setTime(startTime);
0093
0094
0095 for (double currTime = startTime; currTime < startTime + m_cfg.EICROC_period;
0096 currTime += m_cfg.local_period)
0097 outPulse.addToAdcCounts(this->_interpolateOrZero(graph, currTime, tMin, tMax));
0098 }
0099 }
0100 }
0101 }