File indexing completed on 2025-08-28 08:12:14
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/TrackFindingGnn/PrototracksToParameters.hpp"
0010
0011 #include "Acts/Seeding/BinnedGroup.hpp"
0012 #include "Acts/Seeding/EstimateTrackParamsFromSeed.hpp"
0013 #include "Acts/Seeding/SeedFilter.hpp"
0014 #include "Acts/Seeding/SeedFinder.hpp"
0015 #include "Acts/Seeding/SeedFinderConfig.hpp"
0016 #include "Acts/Utilities/Zip.hpp"
0017 #include "ActsExamples/EventData/IndexSourceLink.hpp"
0018 #include "ActsExamples/EventData/ProtoTrack.hpp"
0019 #include "ActsExamples/EventData/SimSeed.hpp"
0020 #include "ActsExamples/Framework/WhiteBoard.hpp"
0021 #include "ActsExamples/Utilities/EventDataTransforms.hpp"
0022
0023 #include <algorithm>
0024 #include <tuple>
0025
0026 using namespace ActsExamples;
0027 using namespace Acts::UnitLiterals;
0028
0029 namespace ActsExamples {
0030
0031 PrototracksToParameters::PrototracksToParameters(Config cfg,
0032 Acts::Logging::Level lvl)
0033 : IAlgorithm("PrototracksToParsAndSeeds", lvl), m_cfg(std::move(cfg)) {
0034 m_outputSeeds.initialize(m_cfg.outputSeeds);
0035 m_outputProtoTracks.initialize(m_cfg.outputProtoTracks);
0036 m_inputProtoTracks.initialize(m_cfg.inputProtoTracks);
0037 m_inputSpacePoints.initialize(m_cfg.inputSpacePoints);
0038 m_outputParameters.initialize(m_cfg.outputParameters);
0039
0040 if (m_cfg.geometry == nullptr) {
0041 throw std::invalid_argument("No geometry given");
0042 }
0043 if (m_cfg.magneticField == nullptr) {
0044 throw std::invalid_argument("No magnetic field given");
0045 }
0046
0047
0048 for (std::size_t i = Acts::eBoundLoc0; i < Acts::eBoundSize; ++i) {
0049 m_covariance(i, i) = m_cfg.initialVarInflation[i] * m_cfg.initialSigmas[i] *
0050 m_cfg.initialSigmas[i];
0051 }
0052 }
0053
0054 PrototracksToParameters::~PrototracksToParameters() {}
0055
0056 ProcessCode PrototracksToParameters::execute(
0057 const AlgorithmContext &ctx) const {
0058 auto bCache = m_cfg.magneticField->makeCache(ctx.magFieldContext);
0059 const auto &sps = m_inputSpacePoints(ctx);
0060 auto prototracks = m_inputProtoTracks(ctx);
0061
0062
0063
0064
0065 std::vector<const SimSpacePoint *> indexToSpacepoint(2 * sps.size(), nullptr);
0066 std::vector<Acts::GeometryIdentifier> indexToGeoId(
0067 2 * sps.size(), Acts::GeometryIdentifier{0});
0068
0069 for (const auto &sp : sps) {
0070 for (const auto &sl : sp.sourceLinks()) {
0071 const auto &isl = sl.template get<IndexSourceLink>();
0072 if (isl.index() >= indexToSpacepoint.size()) {
0073 indexToSpacepoint.resize(isl.index() + 1, nullptr);
0074 indexToGeoId.resize(isl.index() + 1, Acts::GeometryIdentifier{0});
0075 }
0076 indexToSpacepoint.at(isl.index()) = &sp;
0077 indexToGeoId.at(isl.index()) = isl.geometryId();
0078 }
0079 }
0080
0081 ProtoTrackContainer seededTracks;
0082 seededTracks.reserve(prototracks.size());
0083
0084 SimSeedContainer seeds;
0085 seeds.reserve(prototracks.size());
0086
0087 TrackParametersContainer parameters;
0088 parameters.reserve(prototracks.size());
0089
0090
0091 ProtoTrack tmpTrack;
0092 std::vector<const SimSpacePoint *> tmpSps;
0093 std::size_t skippedTracks = 0;
0094 for (auto &track : prototracks) {
0095 ACTS_VERBOSE("Try to get seed from prototrack with " << track.size()
0096 << " hits");
0097
0098
0099
0100
0101
0102
0103
0104 std::ranges::sort(track, {}, [&](const auto &t) {
0105 return std::make_tuple(indexToGeoId[t].volume(), indexToGeoId[t].layer());
0106 });
0107
0108 tmpTrack.clear();
0109 std::unique_copy(
0110 track.begin(), track.end(), std::back_inserter(tmpTrack),
0111 [&](auto a, auto b) {
0112 return indexToGeoId[a].volume() == indexToGeoId[b].volume() &&
0113 indexToGeoId[a].layer() == indexToGeoId[b].layer();
0114 });
0115
0116
0117 if (tmpTrack.size() < 3) {
0118 ACTS_DEBUG(
0119 "Cannot seed because less then three hits with unique (layer, "
0120 "volume)");
0121 skippedTracks++;
0122 continue;
0123 }
0124
0125
0126 auto result =
0127 track | std::views::filter([&](auto i) {
0128 return i < indexToSpacepoint.size() &&
0129 indexToSpacepoint.at(i) != nullptr;
0130 }) |
0131 std::views::transform([&](auto i) { return indexToSpacepoint.at(i); });
0132 tmpSps.clear();
0133 std::ranges::copy(result, std::back_inserter(tmpSps));
0134
0135 if (tmpSps.size() < 3) {
0136 ACTS_WARNING("Could not find all spacepoints, skip");
0137 skippedTracks++;
0138 continue;
0139 }
0140
0141 std::ranges::sort(tmpSps, {}, [](const auto &t) { return t->r(); });
0142
0143
0144
0145 const auto m = (tmpSps.back()->r() - tmpSps.front()->r()) /
0146 (tmpSps.back()->z() - tmpSps.front()->z());
0147 const auto t = tmpSps.front()->r() - m * tmpSps.front()->z();
0148 const auto z_vertex = -t / m;
0149 const auto s = tmpSps.size();
0150
0151 SimSeed seed =
0152 m_cfg.buildTightSeeds
0153 ? SimSeed(*tmpSps.at(0), *tmpSps.at(1), *tmpSps.at(2))
0154 : SimSeed(*tmpSps.at(0), *tmpSps.at(s / 2), *tmpSps.at(s - 1));
0155 seed.setVertexZ(z_vertex);
0156
0157
0158 const auto &bottomSP = seed.sp().front();
0159 const auto geoId = bottomSP->sourceLinks()
0160 .front()
0161 .template get<IndexSourceLink>()
0162 .geometryId();
0163 const auto &surface = *m_cfg.geometry->findSurface(geoId);
0164
0165 auto fieldRes = m_cfg.magneticField->getField(
0166 {bottomSP->x(), bottomSP->y(), bottomSP->z()}, bCache);
0167 if (!fieldRes.ok()) {
0168 ACTS_ERROR("Field lookup error: " << fieldRes.error());
0169 return ProcessCode::ABORT;
0170 }
0171 Acts::Vector3 field = *fieldRes;
0172
0173 if (field.norm() < m_cfg.bFieldMin) {
0174 ACTS_WARNING("Magnetic field at seed is too small " << field.norm());
0175 continue;
0176 }
0177
0178 auto parsResult = Acts::estimateTrackParamsFromSeed(
0179 ctx.geoContext, seed.sp(), surface, field);
0180 if (!parsResult.ok()) {
0181 ACTS_WARNING("Skip track because of bad params");
0182 }
0183 const auto &pars = *parsResult;
0184
0185 seededTracks.push_back(track);
0186 seeds.emplace_back(std::move(seed));
0187 parameters.push_back(Acts::BoundTrackParameters(
0188 surface.getSharedPtr(), pars, m_covariance, m_cfg.particleHypothesis));
0189 }
0190
0191 if (skippedTracks > 0) {
0192 ACTS_WARNING("Skipped seeding of " << skippedTracks);
0193 }
0194
0195 ACTS_DEBUG("Seeded " << seeds.size() << " out of " << prototracks.size()
0196 << " prototracks");
0197
0198 m_outputSeeds(ctx, std::move(seeds));
0199 m_outputProtoTracks(ctx, std::move(seededTracks));
0200 m_outputParameters(ctx, std::move(parameters));
0201
0202 return ProcessCode::SUCCESS;
0203 }
0204
0205 }