Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:09:21

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2018-2020 CERN for the benefit of the Acts project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Units.hpp"
0013 #include "Acts/Seeding/SeedConfirmationRangeConfig.hpp"
0014 #include "Acts/Utilities/Delegate.hpp"
0015 
0016 #include <limits>
0017 #include <memory>
0018 #include <vector>
0019 
0020 namespace Acts {
0021 
0022 // forward declaration to avoid cyclic dependence
0023 template <typename T>
0024 class SeedFilter;
0025 
0026 /// @brief Structure that holds configuration parameters for the seed finder algorithm
0027 template <typename SpacePoint>
0028 struct SeedFinderConfig {
0029   std::shared_ptr<Acts::SeedFilter<SpacePoint>> seedFilter;
0030 
0031   /// Seeding parameters used in the space-point grid creation and bin finding
0032 
0033   /// Geometry Settings + Detector ROI
0034   /// (r, z, phi) range for limiting location of all measurements and grid
0035   /// creation
0036   float phiMin = -M_PI;
0037   float phiMax = M_PI;
0038   float zMin = -2800 * Acts::UnitConstants::mm;
0039   float zMax = 2800 * Acts::UnitConstants::mm;
0040   float rMax = 600 * Acts::UnitConstants::mm;
0041   /// WARNING: if rMin is smaller than impactMax, the bin size will be 2*pi,
0042   /// which will make seeding very slow!
0043   float rMin = 33 * Acts::UnitConstants::mm;
0044 
0045   /// Vector containing the z-bin edges for non equidistant binning in z
0046   std::vector<float> zBinEdges;
0047 
0048   /// Order of z bins to loop over when searching for SPs
0049   std::vector<std::size_t> zBinsCustomLooping = {};
0050 
0051   /// Radial bin size used in space-point grid
0052   float binSizeR = 1. * Acts::UnitConstants::mm;
0053 
0054   /// Seeding parameters used to define the region of interest for middle
0055   /// space-point
0056 
0057   /// Radial range for middle space-point
0058   /// The range can be defined manually with (rMinMiddle, rMaxMiddle). If
0059   /// useVariableMiddleSPRange is set to false and the vector rRangeMiddleSP is
0060   /// empty, we use (rMinMiddle, rMaxMiddle) to cut the middle space-points
0061   float rMinMiddle = 60.f * Acts::UnitConstants::mm;
0062   float rMaxMiddle = 120.f * Acts::UnitConstants::mm;
0063   /// If useVariableMiddleSPRange is set to false, the vector rRangeMiddleSP can
0064   /// be used to define a fixed r range for each z bin: {{rMin, rMax}, ...}
0065   bool useVariableMiddleSPRange = false;
0066   /// Range defined in vector for each z bin
0067   std::vector<std::vector<float>> rRangeMiddleSP;
0068   /// If useVariableMiddleSPRange is true, the radial range will be calculated
0069   /// based on the maximum and minimum r values of the space-points in the event
0070   /// and a deltaR (deltaRMiddleMinSPRange, deltaRMiddleMaxSPRange)
0071   float deltaRMiddleMinSPRange = 10. * Acts::UnitConstants::mm;
0072   float deltaRMiddleMaxSPRange = 10. * Acts::UnitConstants::mm;
0073 
0074   /// Vector containing minimum and maximum z boundaries for cutting middle
0075   /// space-points
0076   std::pair<float, float> zOutermostLayers{-2700 * Acts::UnitConstants::mm,
0077                                            2700 * Acts::UnitConstants::mm};
0078 
0079   /// Seeding parameters used to define the cuts on space-point doublets
0080 
0081   /// Minimum radial distance between two doublet components (prefer
0082   /// deltaRMinTopSP and deltaRMinBottomSP to set separate values for outer and
0083   /// inner space-points)
0084   float deltaRMin = 5 * Acts::UnitConstants::mm;
0085   /// Maximum radial distance between two doublet components (prefer
0086   /// deltaRMaxTopSP and deltaRMacBottomSP to set separate values for outer and
0087   /// inner space-points)
0088   float deltaRMax = 270 * Acts::UnitConstants::mm;
0089   /// Minimum radial distance between middle-outer doublet components
0090   float deltaRMinTopSP = std::numeric_limits<float>::quiet_NaN();
0091   /// Maximum radial distance between middle-outer doublet components
0092   float deltaRMaxTopSP = std::numeric_limits<float>::quiet_NaN();
0093   /// Minimum radial distance between inner-middle doublet components
0094   float deltaRMinBottomSP = std::numeric_limits<float>::quiet_NaN();
0095   /// Maximum radial distance between inner-middle doublet components
0096   float deltaRMaxBottomSP = std::numeric_limits<float>::quiet_NaN();
0097 
0098   /// Maximum value of z-distance between space-points in doublet
0099   float deltaZMax =
0100       std::numeric_limits<float>::infinity() * Acts::UnitConstants::mm;
0101 
0102   /// Maximum allowed cotTheta between two space-points in doublet, used to
0103   /// check if forward angle is within bounds
0104   float cotThetaMax = 10.01788;  // equivalent to eta = 3 (pseudorapidity)
0105 
0106   /// Limiting location of collision region in z-axis used to check if doublet
0107   /// origin is within reasonable bounds
0108   float collisionRegionMin = -150 * Acts::UnitConstants::mm;
0109   float collisionRegionMax = +150 * Acts::UnitConstants::mm;
0110 
0111   /// Enable cut on the compatibility between interaction point and doublet,
0112   /// this is an useful approximation to speed up the seeding
0113   bool interactionPointCut = false;
0114 
0115   /// Seeding parameters used to define the cuts on space-point triplets
0116 
0117   /// Minimum transverse momentum (pT) used to check the r-z slope compatibility
0118   /// of triplets with maximum multiple scattering effect (produced by the
0119   /// minimum allowed pT particle) + a certain uncertainty term. Check the
0120   /// documentation for more information
0121   /// https://acts.readthedocs.io/en/latest/core/reconstruction/pattern_recognition/seeding.html
0122   float minPt = 400. * Acts::UnitConstants::MeV;
0123   /// Number of sigmas of scattering angle to be considered in the minimum pT
0124   /// scattering term
0125   float sigmaScattering = 5;
0126   /// Term that accounts for the thickness of scattering medium in radiation
0127   /// lengths in the Lynch & Dahl correction to the Highland equation default is
0128   /// 5%
0129   /// TODO: necessary to make amount of material dependent on detector region?
0130   float radLengthPerSeed = 0.05;
0131   /// Maximum transverse momentum for scattering calculation
0132   float maxPtScattering = 10 * Acts::UnitConstants::GeV;
0133   /// Maximum value of impact parameter estimation of the seed candidates
0134   float impactMax = 20. * Acts::UnitConstants::mm;
0135   /// Parameter which can loosen the tolerance of the track seed to form a
0136   /// helix. This is useful for e.g. misaligned seeding.
0137   float helixCutTolerance = 1.;
0138 
0139   /// Seeding parameters used for quality seed confirmation
0140 
0141   /// Enable quality seed confirmation, this is different than default seeding
0142   /// confirmation because it can also be defined for different (r, z) regions
0143   /// of the detector (e.g. forward or central region) by SeedConfirmationRange.
0144   /// Seeds are classified as "high-quality" seeds and normal quality seeds.
0145   /// Normal quality seeds are only selected if no other "high-quality" seeds
0146   /// has been found for that inner-middle doublet.
0147   bool seedConfirmation = false;
0148   /// Contains parameters for central seed confirmation
0149   SeedConfirmationRangeConfig centralSeedConfirmationRange;
0150   /// Contains parameters for forward seed confirmation
0151   SeedConfirmationRangeConfig forwardSeedConfirmationRange;
0152   /// Maximum number (minus one) of accepted seeds per middle space-point
0153   unsigned int maxSeedsPerSpM = 5;
0154 
0155   /// Other parameters
0156 
0157   /// Alignment uncertainties, used for uncertainties in the
0158   /// non-measurement-plane of the modules
0159   /// which otherwise would be 0
0160   /// will be added to spacepoint measurement uncertainties (and therefore also
0161   /// multiplied by sigmaError)
0162   /// FIXME: call align1 and align2
0163   float zAlign = 0 * Acts::UnitConstants::mm;
0164   float rAlign = 0 * Acts::UnitConstants::mm;
0165   /// used for measurement (+alignment) uncertainties.
0166   /// find seeds within 5sigma error ellipse
0167   float sigmaError = 5;
0168 
0169   /// derived values, set on SeedFinder construction
0170   float highland = 0;
0171   float maxScatteringAngle2 = 0;
0172 
0173   /// only for Cuda plugin
0174   int maxBlockSize = 1024;
0175   int nTrplPerSpBLimit = 100;
0176   int nAvgTrplPerSpBLimit = 2;
0177 
0178   /// Delegates for accessors to detailed information on double measurement that
0179   /// produced the space point.
0180   /// This is mainly referring to space points produced when combining
0181   /// measurement from strips on back-to-back modules.
0182   /// Enables setting of the following delegates.
0183   bool useDetailedDoubleMeasurementInfo = false;
0184   /// Returns half of the length of the top strip.
0185   Delegate<float(const SpacePoint&)> getTopHalfStripLength;
0186   /// Returns half of the length of the bottom strip.
0187   Delegate<float(const SpacePoint&)> getBottomHalfStripLength;
0188   /// Returns direction of the top strip.
0189   Delegate<Acts::Vector3(const SpacePoint&)> getTopStripDirection;
0190   /// Returns direction of the bottom strip.
0191   Delegate<Acts::Vector3(const SpacePoint&)> getBottomStripDirection;
0192   /// Returns distance between the centers of the two strips.
0193   Delegate<Acts::Vector3(const SpacePoint&)> getStripCenterDistance;
0194   /// Returns position of the center of the top strip.
0195   Delegate<Acts::Vector3(const SpacePoint&)> getTopStripCenterPosition;
0196   /// Tolerance parameter used to check the compatibility of space-point
0197   /// coordinates in xyz. This is only used in a detector specific check for
0198   /// strip modules
0199   float toleranceParam = 1.1 * Acts::UnitConstants::mm;
0200 
0201   // Delegate to apply experiment specific cuts
0202   Delegate<bool(float /*bottomRadius*/, float /*cotTheta*/)> experimentCuts{
0203       DelegateFuncTag<&noopExperimentCuts>{}};
0204 
0205   bool isInInternalUnits = false;
0206 
0207   SeedFinderConfig toInternalUnits() const {
0208     if (isInInternalUnits) {
0209       throw std::runtime_error(
0210           "Repeated conversion to internal units for SeedFinderConfig");
0211     }
0212     // Make sure the shared ptr to the seed filter is not a nullptr
0213     // And make sure the seed filter config is in internal units as well
0214     if (!seedFilter) {
0215       throw std::runtime_error(
0216           "Invalid values for the seed filter inside the seed filter config: "
0217           "nullptr");
0218     }
0219     if (!seedFilter->getSeedFilterConfig().isInInternalUnits) {
0220       throw std::runtime_error(
0221           "The internal Seed Filter configuration, contained in the seed "
0222           "finder config, is not in internal units.");
0223     }
0224 
0225     using namespace Acts::UnitLiterals;
0226     SeedFinderConfig config = *this;
0227     config.isInInternalUnits = true;
0228     config.minPt /= 1_MeV;
0229     config.deltaRMin /= 1_mm;
0230     config.deltaRMax /= 1_mm;
0231     config.binSizeR /= 1_mm;
0232     config.deltaRMinTopSP /= 1_mm;
0233     config.deltaRMaxTopSP /= 1_mm;
0234     config.deltaRMinBottomSP /= 1_mm;
0235     config.deltaRMaxBottomSP /= 1_mm;
0236     config.deltaRMiddleMinSPRange /= 1_mm;
0237     config.deltaRMiddleMaxSPRange /= 1_mm;
0238     config.impactMax /= 1_mm;
0239     config.maxPtScattering /= 1_MeV;  // correct?
0240     config.collisionRegionMin /= 1_mm;
0241     config.collisionRegionMax /= 1_mm;
0242     config.zMin /= 1_mm;
0243     config.zMax /= 1_mm;
0244     config.rMax /= 1_mm;
0245     config.rMin /= 1_mm;
0246     config.deltaZMax /= 1_mm;
0247 
0248     config.zAlign /= 1_mm;
0249     config.rAlign /= 1_mm;
0250 
0251     config.toleranceParam /= 1_mm;
0252 
0253     return config;
0254   }
0255   SeedFinderConfig calculateDerivedQuantities() const {
0256     SeedFinderConfig config = *this;
0257     // calculation of scattering using the highland formula
0258     // convert pT to p once theta angle is known
0259     config.highland = 13.6 * std::sqrt(radLengthPerSeed) *
0260                       (1 + 0.038 * std::log(radLengthPerSeed));
0261     const float maxScatteringAngle = config.highland / minPt;
0262     config.maxScatteringAngle2 = maxScatteringAngle * maxScatteringAngle;
0263     return config;
0264   }
0265 };
0266 
0267 struct SeedFinderOptions {
0268   // location of beam in x,y plane.
0269   // used as offset for Space Points
0270   Acts::Vector2 beamPos{0 * Acts::UnitConstants::mm,
0271                         0 * Acts::UnitConstants::mm};
0272   // field induction
0273   float bFieldInZ = 2.08 * Acts::UnitConstants::T;
0274 
0275   // derived quantities
0276   float pTPerHelixRadius = std::numeric_limits<float>::quiet_NaN();
0277   float minHelixDiameter2 = std::numeric_limits<float>::quiet_NaN();
0278   float pT2perRadius = std::numeric_limits<float>::quiet_NaN();
0279   float sigmapT2perRadius = std::numeric_limits<float>::quiet_NaN();
0280   float multipleScattering2 = std::numeric_limits<float>::quiet_NaN();
0281 
0282   bool isInInternalUnits = false;
0283 
0284   SeedFinderOptions toInternalUnits() const {
0285     if (isInInternalUnits) {
0286       throw std::runtime_error(
0287           "Repeated conversion to internal units for SeedFinderOptions");
0288     }
0289     using namespace Acts::UnitLiterals;
0290     SeedFinderOptions options = *this;
0291     options.isInInternalUnits = true;
0292     options.beamPos[0] /= 1_mm;
0293     options.beamPos[1] /= 1_mm;
0294 
0295     options.bFieldInZ /= 1000. * 1_T;
0296     return options;
0297   }
0298 
0299   template <typename Config>
0300   SeedFinderOptions calculateDerivedQuantities(const Config& config) const {
0301     using namespace Acts::UnitLiterals;
0302 
0303     if (!isInInternalUnits) {
0304       throw std::runtime_error(
0305           "Derived quantities in SeedFinderOptions can only be calculated from "
0306           "Acts internal units");
0307     }
0308     SeedFinderOptions options = *this;
0309     // helix radius in homogeneous magnetic field. Units are Kilotesla, MeV and
0310     // millimeter
0311     // TODO: change using ACTS units
0312     options.pTPerHelixRadius = 1_T * 1e6 * options.bFieldInZ;
0313     options.minHelixDiameter2 =
0314         std::pow(config.minPt * 2 / options.pTPerHelixRadius, 2) *
0315         config.helixCutTolerance;
0316     options.pT2perRadius =
0317         std::pow(config.highland / options.pTPerHelixRadius, 2);
0318     options.sigmapT2perRadius =
0319         options.pT2perRadius * std::pow(2 * config.sigmaScattering, 2);
0320     options.multipleScattering2 =
0321         config.maxScatteringAngle2 * std::pow(config.sigmaScattering, 2);
0322     return options;
0323   }
0324 };
0325 
0326 }  // namespace Acts