File indexing completed on 2026-05-04 08:04:45
0001
0002
0003
0004 #include "TrackerMeasurementFromHits.h"
0005
0006 #include <Acts/Definitions/Algebra.hpp>
0007 #include <Acts/Definitions/TrackParametrization.hpp>
0008 #include <Acts/Definitions/Units.hpp>
0009 #include <Acts/Geometry/GeometryIdentifier.hpp>
0010 #include <Acts/Surfaces/Surface.hpp>
0011 #include <Acts/Utilities/Result.hpp>
0012 #include <DD4hep/Alignments.h>
0013 #include <DD4hep/DetElement.h>
0014 #include <DD4hep/Readout.h>
0015 #include <DD4hep/Segmentations.h>
0016 #include <DD4hep/VolumeManager.h>
0017 #include <DD4hep/detail/SegmentationsInterna.h>
0018 #include <DDRec/CellIDPositionConverter.h>
0019 #include <DDSegmentation/CartesianGridUV.h>
0020 #include <DDSegmentation/MultiSegmentation.h>
0021 #include <DDSegmentation/Segmentation.h>
0022 #include <Evaluator/DD4hepUnits.h>
0023 #include <Math/GenVector/Cartesian3D.h>
0024 #include <Math/GenVector/DisplacementVector3D.h>
0025
0026 #include <algorithms/geo.h>
0027 #include <algorithms/logger.h>
0028 #include <edm4eic/Cov3f.h>
0029 #include <edm4eic/CovDiag3f.h>
0030 #include <edm4hep/Vector2f.h>
0031 #include <edm4hep/Vector3f.h>
0032 #include <Eigen/Core>
0033 #include <cmath>
0034 #include <exception>
0035 #include <stdexcept>
0036 #include <tuple>
0037 #include <unordered_map>
0038 #include <utility>
0039 #include <vector>
0040
0041 #include "ActsGeometryProvider.h"
0042
0043 namespace eicrecon {
0044
0045 void TrackerMeasurementFromHits::init() {
0046
0047 m_detid_b0tracker = m_dd4hepGeo->constant<unsigned long>("B0Tracker_Station_1_ID");
0048
0049 std::string readout = "OuterMPGDBarrelHits";
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 const dd4hep::Detector* detector = algorithms::GeoSvc::instance().detector();
0060 dd4hep::Segmentation seg;
0061 m_outermpgd_UVsegmentation_mode = true;
0062 try {
0063 seg = detector->readout(readout).segmentation();
0064 } catch (const std::runtime_error&) {
0065 debug(R"(Failed to load Segmentation for "{}" readout.)", readout);
0066 m_outermpgd_UVsegmentation_mode = false;
0067 }
0068 if (m_outermpgd_UVsegmentation_mode) {
0069 debug(R"(Parsing Segmentation for "{}" readout: is it UV?)", readout);
0070
0071 using Segmentation = dd4hep::DDSegmentation::Segmentation;
0072 const Segmentation* segmentation = seg->segmentation;
0073 if (segmentation->type() == "MultiSegmentation") {
0074
0075
0076
0077
0078
0079
0080
0081 using MultiSegmentation = dd4hep::DDSegmentation::MultiSegmentation;
0082 const auto* multiSeg = dynamic_cast<const MultiSegmentation*>(segmentation);
0083 unsigned int subSegPattern = 0;
0084 for (const auto entry : multiSeg->subSegmentations()) {
0085 const Segmentation* subSegmentation = entry.segmentation;
0086 if (subSegmentation->type() == "CartesianGridUV") {
0087 const dd4hep::DDSegmentation::CartesianGridUV* gridUV =
0088 dynamic_cast<const dd4hep::DDSegmentation::CartesianGridUV*>(subSegmentation);
0089 double gridAngle = gridUV->gridAngle();
0090 if ((subSegPattern & 0x1) && fabs(gridAngle - m_gridAngle) > 1e-6) {
0091 critical(R"(Inconsistent Segmentation for "{}" readout: UV gridAngle not unique.)",
0092 readout);
0093 throw std::runtime_error("Inconsistent MultiSegmentation");
0094 }
0095 subSegPattern |= 0x1;
0096 m_gridAngle = gridAngle;
0097 } else {
0098 subSegPattern |= 0x2;
0099 }
0100 }
0101 if (subSegPattern == 0x3) {
0102 critical(R"(Inconsistent Segmentation for "{}" readout: only partially UV.)", readout);
0103 throw std::runtime_error("Inconsistent MultiSegmentation");
0104 } else if (subSegPattern == 0x2) {
0105 m_outermpgd_UVsegmentation_mode = false;
0106 }
0107 } else {
0108 if (segmentation->type() != "CartesianGridUV") {
0109 m_outermpgd_UVsegmentation_mode = false;
0110 }
0111 }
0112 if (m_outermpgd_UVsegmentation_mode) {
0113 m_detid_OuterMPGD = m_dd4hepGeo->constant<unsigned long>("TrackerBarrel_5_ID");
0114 }
0115 }
0116 }
0117
0118 void TrackerMeasurementFromHits::process(const Input& input, const Output& output) const {
0119 const auto [trk_hits] = input;
0120 auto [meas2Ds] = output;
0121
0122 constexpr double mm_acts = Acts::UnitConstants::mm;
0123 constexpr double mm_conv = mm_acts / dd4hep::mm;
0124
0125
0126 const auto& gctx = m_acts_context->getActsGeometryContext();
0127
0128
0129 auto const& surfaceMap = m_acts_context->surfaceMap();
0130
0131
0132
0133 for (const auto& hit : *trk_hits) {
0134
0135 auto hit_det = hit.getCellID() & 0xFF;
0136
0137 Acts::SquareMatrix2 cov = Acts::SquareMatrix2::Zero();
0138 cov(0, 0) = hit.getPositionError().xx * mm_acts * mm_acts;
0139 cov(1, 1) = hit.getPositionError().yy * mm_acts * mm_acts;
0140 cov(0, 1) = cov(1, 0) = 0.0;
0141 if (m_outermpgd_UVsegmentation_mode && hit_det == m_detid_OuterMPGD) {
0142
0143
0144
0145 const double sA = sin(m_gridAngle), cA = cos(m_gridAngle);
0146 const Acts::RotationMatrix2 rot2{{cA, sA}, {-sA, cA}};
0147 const Acts::RotationMatrix2 inv2{{cA, -sA}, {sA, cA}};
0148 cov = rot2 * cov * inv2;
0149 }
0150
0151 const auto* vol_ctx = m_converter->findContext(hit.getCellID());
0152 auto vol_id = vol_ctx->identifier;
0153
0154
0155 trace(" System id: {}, Cell id: {}", hit.getCellID() & 0xFF, hit.getCellID());
0156 trace(" cov matrix: {:>12.2e} {:>12.2e}", cov(0, 0), cov(0, 1));
0157 trace(" {:>12.2e} {:>12.2e}", cov(1, 0), cov(1, 1));
0158 trace(" surfaceMap size: {}", surfaceMap.size());
0159
0160 const auto is = surfaceMap.find(vol_id);
0161 if (is == surfaceMap.end()) {
0162 warning(" WARNING: vol_id ({}) not found in m_surfaces.", vol_id);
0163 continue;
0164 }
0165 const Acts::Surface* surface = is->second;
0166
0167
0168 const auto& hit_pos = hit.getPosition();
0169
0170 Acts::Vector2 pos;
0171 auto onSurfaceTolerance =
0172 0.1 *
0173 Acts::UnitConstants::um;
0174 if (hit_det == m_detid_b0tracker) {
0175 onSurfaceTolerance =
0176 1 *
0177 Acts::UnitConstants::
0178 um;
0179 }
0180
0181 try {
0182
0183 pos = surface
0184 ->globalToLocal(gctx, {hit_pos.x, hit_pos.y, hit_pos.z}, {0, 0, 0},
0185 onSurfaceTolerance)
0186 .value();
0187
0188 } catch (std::exception& ex) {
0189 warning("Can't convert globalToLocal for hit: vol_id={} det_id={} CellID={} x={} y={} z={}",
0190 vol_id, hit.getCellID() & 0xFF, hit.getCellID(), hit_pos.x, hit_pos.y, hit_pos.z);
0191 continue;
0192 }
0193
0194 if (level() <= algorithms::LogLevel::kTrace) {
0195
0196 Acts::Vector2 loc = Acts::Vector2::Zero();
0197 loc[Acts::eBoundLoc0] = pos[0];
0198 loc[Acts::eBoundLoc1] = pos[1];
0199
0200 auto volman = m_acts_context->dd4hepDetector()->volumeManager();
0201 auto alignment = volman.lookupDetElement(vol_id).nominal();
0202 auto local_position = (alignment.worldToLocal(
0203 {hit_pos.x / mm_conv, hit_pos.y / mm_conv, hit_pos.z / mm_conv})) *
0204 mm_conv;
0205 double surf_center_x = surface->center(gctx).transpose()[0];
0206 double surf_center_y = surface->center(gctx).transpose()[1];
0207 double surf_center_z = surface->center(gctx).transpose()[2];
0208 trace(" hit position : {:>10.2f} {:>10.2f} {:>10.2f}", hit_pos.x, hit_pos.y, hit_pos.z);
0209 trace(" local position : {:>10.2f} {:>10.2f} {:>10.2f}", local_position.x(),
0210 local_position.y(), local_position.z());
0211 trace(" surface center : {:>10.2f} {:>10.2f} {:>10.2f}", surf_center_x, surf_center_y,
0212 surf_center_z);
0213 trace(" acts local center: {:>10.2f} {:>10.2f}", pos.transpose()[0], pos.transpose()[1]);
0214 trace(" acts loc pos : {:>10.2f} {:>10.2f}", loc[Acts::eBoundLoc0],
0215 loc[Acts::eBoundLoc1]);
0216 }
0217
0218 auto meas2D = meas2Ds->create();
0219 meas2D.setSurface(surface->geometryId().value());
0220 meas2D.setLoc(
0221 {static_cast<float>(pos[0]), static_cast<float>(pos[1])});
0222 meas2D.setTime(hit.getTime());
0223
0224 meas2D.setCovariance({cov(0, 0), cov(1, 1), hit.getTimeError() * hit.getTimeError(),
0225 cov(0, 1)});
0226 meas2D.addToWeights(1.0);
0227 meas2D.addToHits(hit);
0228 }
0229
0230 debug("All hits processed. Hits size: {} measurements->size: {}", trk_hits->size(),
0231 meas2Ds->size());
0232 }
0233
0234 }