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