Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:01

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