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