File indexing completed on 2025-07-03 08:57:50
0001
0002
0003
0004 #include <algorithm>
0005 #include <cmath>
0006 #include <fmt/format.h>
0007
0008 #include "Gaudi/Algorithm.h"
0009 #include "GaudiKernel/RndmGenerators.h"
0010
0011 #include <k4FWCore/DataHandle.h>
0012
0013
0014 #include "edm4eic/ReconstructedParticleCollection.h"
0015 #include "edm4eic/TrackerHitCollection.h"
0016 #include <edm4hep/utils/vector_utils.h>
0017
0018 namespace Jug::Reco {
0019
0020 class FarForwardParticlesOMD : public Gaudi::Algorithm {
0021 private:
0022 mutable DataHandle<edm4eic::TrackerHitCollection> m_inputHitCollection{"FarForwardTrackerHits", Gaudi::DataHandle::Reader, this};
0023 mutable DataHandle<edm4eic::ReconstructedParticleCollection> m_outputParticles{"outputParticles", Gaudi::DataHandle::Writer,
0024 this};
0025
0026
0027
0028 Gaudi::Property<double> local_x_offset_station_1{this, "localXOffsetSta1", -762.5006104};
0029 Gaudi::Property<double> local_x_offset_station_2{this, "localXOffsetSta2", -881.9621277};
0030 Gaudi::Property<double> local_x_slope_offset{this, "localXSlopeOffset", -59.73075865};
0031 Gaudi::Property<double> local_y_slope_offset{this, "localYSlopeOffset", 0.0012755};
0032 Gaudi::Property<double> crossingAngle{this, "crossingAngle", -0.025};
0033 Gaudi::Property<double> nomMomentum{this, "beamMomentum", 137.5};
0034
0035 const double aXOMD[2][2] = {{1.6229248, 12.9519653}, {-2.86056525, 0.1830292}};
0036 const double aYOMD[2][2] = {{0.0000185, -28.599739}, {0.00000925, -2.8795791}};
0037
0038 double aXOMDinv[2][2] = {{0.0, 0.0}, {0.0, 0.0}};
0039 double aYOMDinv[2][2] = {{0.0, 0.0}, {0.0, 0.0}};
0040
0041 public:
0042 FarForwardParticlesOMD(const std::string& name, ISvcLocator* svcLoc)
0043 : Gaudi::Algorithm(name, svcLoc) {
0044 declareProperty("inputCollection", m_inputHitCollection, "FarForwardTrackerHits");
0045 declareProperty("outputCollection", m_outputParticles, "ReconstructedParticles");
0046 }
0047
0048 StatusCode initialize() override {
0049 if (Gaudi::Algorithm::initialize().isFailure()) {
0050 return StatusCode::FAILURE;
0051 }
0052 double det = aXOMD[0][0] * aXOMD[1][1] - aXOMD[0][1] * aXOMD[1][0];
0053
0054 if (det == 0) {
0055 error() << "Reco matrix determinant = 0!"
0056 << "Matrix cannot be inverted! Double-check matrix!" << endmsg;
0057 return StatusCode::FAILURE;
0058 }
0059
0060 aXOMDinv[0][0] = aXOMD[1][1] / det;
0061 aXOMDinv[0][1] = -aXOMD[0][1] / det;
0062 aXOMDinv[1][0] = -aXOMD[1][0] / det;
0063 aXOMDinv[1][1] = aXOMD[0][0] / det;
0064
0065 det = aYOMD[0][0] * aYOMD[1][1] - aYOMD[0][1] * aYOMD[1][0];
0066 aYOMDinv[0][0] = aYOMD[1][1] / det;
0067 aYOMDinv[0][1] = -aYOMD[0][1] / det;
0068 aYOMDinv[1][0] = -aYOMD[1][0] / det;
0069 aYOMDinv[1][1] = aYOMD[0][0] / det;
0070
0071 return StatusCode::SUCCESS;
0072 }
0073
0074 StatusCode execute(const EventContext&) const override {
0075 const edm4eic::TrackerHitCollection* rawhits = m_inputHitCollection.get();
0076 auto& rc = *(m_outputParticles.createAndPut());
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 int eventReset = 0;
0089 std::vector<double> hitx;
0090 std::vector<double> hity;
0091 std::vector<double> hitz;
0092
0093 for (const auto& h : *rawhits) {
0094
0095
0096 auto pos0 = h.getPosition();
0097
0098
0099 auto eDep = h.getEdep();
0100
0101 if (eDep < 0.00001) {
0102 continue;
0103 }
0104
0105 if (eventReset < 2) {
0106 hitx.push_back(pos0.x - local_x_offset_station_2);
0107 }
0108 else {
0109 hitx.push_back(pos0.x - local_x_offset_station_2);
0110 }
0111
0112 hity.push_back(pos0.y);
0113 hitz.push_back(pos0.z);
0114
0115 eventReset++;
0116 }
0117
0118
0119
0120
0121
0122 if (eventReset == 4) {
0123
0124
0125 double XL[2] = {hitx[0], hitx[2]};
0126 double YL[2] = {hity[0], hity[2]};
0127
0128 double base = hitz[2] - hitz[0];
0129
0130 if (base == 0) {
0131 warning() << "Detector separation = 0!"
0132 << "Cannot calculate slope!" << endmsg;
0133 return StatusCode::SUCCESS;
0134 }
0135
0136 double Xomd[2] = {XL[1], (1000 * (XL[1] - XL[0]) / (base)) - local_x_slope_offset};
0137 double Xip[2] = {0.0, 0.0};
0138 double Yomd[2] = {YL[1], (1000 * (YL[1] - YL[0]) / (base)) - local_y_slope_offset};
0139 double Yip[2] = {0.0, 0.0};
0140
0141
0142
0143
0144 for (unsigned i0 = 0; i0 < 2; i0++) {
0145 for (unsigned i1 = 0; i1 < 2; i1++) {
0146 Xip[i0] += aXOMDinv[i0][i1] * Xomd[i1];
0147 Yip[i0] += aYOMDinv[i0][i1] * Yomd[i1];
0148 }
0149 }
0150
0151
0152 double rsx = Xip[1] / 1000.;
0153 double rsy = Yip[1] / 1000.;
0154
0155
0156 double p = nomMomentum * (1 + 0.01 * Xip[0]);
0157 double norm = std::sqrt(1.0 + rsx * rsx + rsy * rsy);
0158
0159 const float prec[3] = {static_cast<float>(p * rsx / norm), static_cast<float>(p * rsy / norm),
0160 static_cast<float>(p / norm)};
0161
0162
0163
0164 edm4eic::MutableReconstructedParticle rpTrack;
0165 rpTrack.setType(0);
0166 rpTrack.setMomentum({prec});
0167 rpTrack.setEnergy(std::hypot(edm4hep::utils::magnitude(rpTrack.getMomentum()), .938272));
0168 rpTrack.setReferencePoint({0, 0, 0});
0169 rpTrack.setCharge(1);
0170 rpTrack.setMass(.938272);
0171 rpTrack.setGoodnessOfPID(1.);
0172 rpTrack.setPDG(2122);
0173
0174 rc->push_back(rpTrack);
0175
0176 }
0177
0178 return StatusCode::SUCCESS;
0179 }
0180 };
0181
0182
0183 DECLARE_COMPONENT(FarForwardParticlesOMD)
0184
0185 }