Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:27:49

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   /// Seeding parameters used to define the cuts on space-point doublets
0075 
0076   /// Minimum radial distance between two doublet components (prefer
0077   /// deltaRMinTopSP and deltaRMinBottomSP to set separate values for outer and
0078   /// inner space-points)
0079   float deltaRMin = 5 * Acts::UnitConstants::mm;
0080   /// Maximum radial distance between two doublet components (prefer
0081   /// deltaRMaxTopSP and deltaRMacBottomSP to set separate values for outer and
0082   /// inner space-points)
0083   float deltaRMax = 270 * Acts::UnitConstants::mm;
0084   /// Minimum radial distance between middle-outer doublet components
0085   float deltaRMinTopSP = std::numeric_limits<float>::quiet_NaN();
0086   /// Maximum radial distance between middle-outer doublet components
0087   float deltaRMaxTopSP = std::numeric_limits<float>::quiet_NaN();
0088   /// Minimum radial distance between inner-middle doublet components
0089   float deltaRMinBottomSP = std::numeric_limits<float>::quiet_NaN();
0090   /// Maximum radial distance between inner-middle doublet components
0091   float deltaRMaxBottomSP = std::numeric_limits<float>::quiet_NaN();
0092 
0093   /// Maximum value of z-distance between space-points in doublet
0094   float deltaZMax =
0095       std::numeric_limits<float>::infinity() * Acts::UnitConstants::mm;
0096 
0097   /// Maximum allowed cotTheta between two space-points in doublet, used to
0098   /// check if forward angle is within bounds
0099   float cotThetaMax = 10.01788;  // equivalent to eta = 3 (pseudorapidity)
0100 
0101   /// Limiting location of collision region in z-axis used to check if doublet
0102   /// origin is within reasonable bounds
0103   float collisionRegionMin = -150 * Acts::UnitConstants::mm;
0104   float collisionRegionMax = +150 * Acts::UnitConstants::mm;
0105 
0106   /// Enable cut on the compatibility between interaction point and doublet,
0107   /// this is an useful approximation to speed up the seeding
0108   bool interactionPointCut = false;
0109 
0110   /// Seeding parameters used to define the cuts on space-point triplets
0111 
0112   /// Minimum transverse momentum (pT) used to check the r-z slope compatibility
0113   /// of triplets with maximum multiple scattering effect (produced by the
0114   /// minimum allowed pT particle) + a certain uncertainty term. Check the
0115   /// documentation for more information
0116   /// https://acts.readthedocs.io/en/latest/core/reconstruction/pattern_recognition/seeding.html
0117   float minPt = 400. * Acts::UnitConstants::MeV;
0118   /// Number of sigmas of scattering angle to be considered in the minimum pT
0119   /// scattering term
0120   float sigmaScattering = 5;
0121   /// Term that accounts for the thickness of scattering medium in radiation
0122   /// lengths in the Lynch & Dahl correction to the Highland equation default is
0123   /// 5%
0124   /// TODO: necessary to make amount of material dependent on detector region?
0125   float radLengthPerSeed = 0.05;
0126   /// Maximum transverse momentum for scattering calculation
0127   float maxPtScattering = 10 * Acts::UnitConstants::GeV;
0128   /// Maximum value of impact parameter estimation of the seed candidates
0129   float impactMax = 20. * Acts::UnitConstants::mm;
0130   /// Parameter which can loosen the tolerance of the track seed to form a
0131   /// helix. This is useful for e.g. misaligned seeding.
0132   float helixCutTolerance = 1.;
0133 
0134   /// Seeding parameters used for quality seed confirmation
0135 
0136   /// Enable quality seed confirmation, this is different than default seeding
0137   /// confirmation because it can also be defined for different (r, z) regions
0138   /// of the detector (e.g. forward or central region) by SeedConfirmationRange.
0139   /// Seeds are classified as "high-quality" seeds and normal quality seeds.
0140   /// Normal quality seeds are only selected if no other "high-quality" seeds
0141   /// has been found for that inner-middle doublet.
0142   bool seedConfirmation = false;
0143   /// Contains parameters for central seed confirmation
0144   SeedConfirmationRangeConfig centralSeedConfirmationRange;
0145   /// Contains parameters for forward seed confirmation
0146   SeedConfirmationRangeConfig forwardSeedConfirmationRange;
0147   /// Maximum number (minus one) of accepted seeds per middle space-point
0148   unsigned int maxSeedsPerSpM = 5;
0149 
0150   /// Other parameters
0151 
0152   /// Alignment uncertainties, used for uncertainties in the
0153   /// non-measurement-plane of the modules
0154   /// which otherwise would be 0
0155   /// will be added to spacepoint measurement uncertainties (and therefore also
0156   /// multiplied by sigmaError)
0157   /// FIXME: call align1 and align2
0158   float zAlign = 0 * Acts::UnitConstants::mm;
0159   float rAlign = 0 * Acts::UnitConstants::mm;
0160   /// used for measurement (+alignment) uncertainties.
0161   /// find seeds within 5sigma error ellipse
0162   float sigmaError = 5;
0163 
0164   /// derived values, set on SeedFinder construction
0165   float highland = 0;
0166   float maxScatteringAngle2 = 0;
0167 
0168   /// only for Cuda plugin
0169   int maxBlockSize = 1024;
0170   int nTrplPerSpBLimit = 100;
0171   int nAvgTrplPerSpBLimit = 2;
0172 
0173   /// Delegates for accessors to detailed information on double measurement that
0174   /// produced the space point.
0175   /// This is mainly referring to space points produced when combining
0176   /// measurement from strips on back-to-back modules.
0177   /// Enables setting of the following delegates.
0178   bool useDetailedDoubleMeasurementInfo = false;
0179   /// Returns half of the length of the top strip.
0180   Delegate<float(const SpacePoint&)> getTopHalfStripLength;
0181   /// Returns half of the length of the bottom strip.
0182   Delegate<float(const SpacePoint&)> getBottomHalfStripLength;
0183   /// Returns direction of the top strip.
0184   Delegate<Acts::Vector3(const SpacePoint&)> getTopStripDirection;
0185   /// Returns direction of the bottom strip.
0186   Delegate<Acts::Vector3(const SpacePoint&)> getBottomStripDirection;
0187   /// Returns distance between the centers of the two strips.
0188   Delegate<Acts::Vector3(const SpacePoint&)> getStripCenterDistance;
0189   /// Returns position of the center of the top strip.
0190   Delegate<Acts::Vector3(const SpacePoint&)> getTopStripCenterPosition;
0191   /// Tolerance parameter used to check the compatibility of space-point
0192   /// coordinates in xyz. This is only used in a detector specific check for
0193   /// strip modules
0194   float toleranceParam = 1.1 * Acts::UnitConstants::mm;
0195 
0196   // Delegate to apply experiment specific cuts
0197   Delegate<bool(float /*bottomRadius*/, float /*cotTheta*/)> experimentCuts{
0198       DelegateFuncTag<&noopExperimentCuts>{}};
0199 
0200   bool isInInternalUnits = false;
0201 
0202   SeedFinderConfig toInternalUnits() const {
0203     if (isInInternalUnits) {
0204       throw std::runtime_error(
0205           "Repeated conversion to internal units for SeedFinderConfig");
0206     }
0207     // Make sure the shared ptr to the seed filter is not a nullptr
0208     // And make sure the seed filter config is in internal units as well
0209     if (!seedFilter) {
0210       throw std::runtime_error(
0211           "Invalid values for the seed filter inside the seed filter config: "
0212           "nullptr");
0213     }
0214     if (!seedFilter->getSeedFilterConfig().isInInternalUnits) {
0215       throw std::runtime_error(
0216           "The internal Seed Filter configuration, contained in the seed "
0217           "finder config, is not in internal units.");
0218     }
0219 
0220     using namespace Acts::UnitLiterals;
0221     SeedFinderConfig config = *this;
0222     config.isInInternalUnits = true;
0223     config.minPt /= 1_MeV;
0224     config.deltaRMin /= 1_mm;
0225     config.deltaRMax /= 1_mm;
0226     config.binSizeR /= 1_mm;
0227     config.deltaRMinTopSP /= 1_mm;
0228     config.deltaRMaxTopSP /= 1_mm;
0229     config.deltaRMinBottomSP /= 1_mm;
0230     config.deltaRMaxBottomSP /= 1_mm;
0231     config.deltaRMiddleMinSPRange /= 1_mm;
0232     config.deltaRMiddleMaxSPRange /= 1_mm;
0233     config.impactMax /= 1_mm;
0234     config.maxPtScattering /= 1_MeV;  // correct?
0235     config.collisionRegionMin /= 1_mm;
0236     config.collisionRegionMax /= 1_mm;
0237     config.zMin /= 1_mm;
0238     config.zMax /= 1_mm;
0239     config.rMax /= 1_mm;
0240     config.rMin /= 1_mm;
0241     config.deltaZMax /= 1_mm;
0242 
0243     config.zAlign /= 1_mm;
0244     config.rAlign /= 1_mm;
0245 
0246     config.toleranceParam /= 1_mm;
0247 
0248     return config;
0249   }
0250   SeedFinderConfig calculateDerivedQuantities() const {
0251     SeedFinderConfig config = *this;
0252     // calculation of scattering using the highland formula
0253     // convert pT to p once theta angle is known
0254     config.highland = 13.6 * std::sqrt(radLengthPerSeed) *
0255                       (1 + 0.038 * std::log(radLengthPerSeed));
0256     const float maxScatteringAngle = config.highland / minPt;
0257     config.maxScatteringAngle2 = maxScatteringAngle * maxScatteringAngle;
0258     return config;
0259   }
0260 };
0261 
0262 struct SeedFinderOptions {
0263   // location of beam in x,y plane.
0264   // used as offset for Space Points
0265   Acts::Vector2 beamPos{0 * Acts::UnitConstants::mm,
0266                         0 * Acts::UnitConstants::mm};
0267   // field induction
0268   float bFieldInZ = 2.08 * Acts::UnitConstants::T;
0269 
0270   // derived quantities
0271   float pTPerHelixRadius = std::numeric_limits<float>::quiet_NaN();
0272   float minHelixDiameter2 = std::numeric_limits<float>::quiet_NaN();
0273   float pT2perRadius = std::numeric_limits<float>::quiet_NaN();
0274   float sigmapT2perRadius = std::numeric_limits<float>::quiet_NaN();
0275   float multipleScattering2 = std::numeric_limits<float>::quiet_NaN();
0276 
0277   bool isInInternalUnits = false;
0278 
0279   SeedFinderOptions toInternalUnits() const {
0280     if (isInInternalUnits) {
0281       throw std::runtime_error(
0282           "Repeated conversion to internal units for SeedFinderOptions");
0283     }
0284     using namespace Acts::UnitLiterals;
0285     SeedFinderOptions options = *this;
0286     options.isInInternalUnits = true;
0287     options.beamPos[0] /= 1_mm;
0288     options.beamPos[1] /= 1_mm;
0289 
0290     options.bFieldInZ /= 1000. * 1_T;
0291     return options;
0292   }
0293 
0294   template <typename Config>
0295   SeedFinderOptions calculateDerivedQuantities(const Config& config) const {
0296     using namespace Acts::UnitLiterals;
0297 
0298     if (!isInInternalUnits) {
0299       throw std::runtime_error(
0300           "Derived quantities in SeedFinderOptions can only be calculated from "
0301           "Acts internal units");
0302     }
0303     SeedFinderOptions options = *this;
0304     // helix radius in homogeneous magnetic field. Units are Kilotesla, MeV and
0305     // millimeter
0306     // TODO: change using ACTS units
0307     options.pTPerHelixRadius = 1_T * 1e6 * options.bFieldInZ;
0308     options.minHelixDiameter2 =
0309         std::pow(config.minPt * 2 / options.pTPerHelixRadius, 2) *
0310         config.helixCutTolerance;
0311     options.pT2perRadius =
0312         std::pow(config.highland / options.pTPerHelixRadius, 2);
0313     options.sigmapT2perRadius =
0314         options.pT2perRadius * std::pow(2 * config.sigmaScattering, 2);
0315     options.multipleScattering2 =
0316         config.maxScatteringAngle2 * std::pow(config.sigmaScattering, 2);
0317     return options;
0318   }
0319 };
0320 
0321 }  // namespace Acts