Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:07

0001 #!/usr/bin/env python3
0002 
0003 from pathlib import Path
0004 from typing import Optional
0005 import argparse
0006 
0007 import acts
0008 from acts import UnitConstants as u
0009 from acts.examples import GenericDetector, RootParticleReader
0010 
0011 
0012 def getArgumentParser():
0013     """Get arguments from command line"""
0014     parser = argparse.ArgumentParser(description="Command line arguments for CKF")
0015     parser.add_argument(
0016         "-i",
0017         "--indir",
0018         dest="indir",
0019         help="Directory with input root files",
0020         default="./",
0021     )
0022     parser.add_argument(
0023         "-o",
0024         "--output",
0025         dest="outdir",
0026         help="Output directory for new ntuples",
0027         default="./",
0028     )
0029     parser.add_argument(
0030         "-n", "--nEvents", dest="nEvts", help="Number of events to run over", default=1
0031     )
0032     parser.add_argument(
0033         "--sf_maxSeedsPerSpM",
0034         dest="sf_maxSeedsPerSpM",
0035         help="Number of compatible seeds considered for middle seed",
0036         type=int,
0037         default=1,
0038     )
0039     parser.add_argument(
0040         "--sf_cotThetaMax",
0041         dest="sf_cotThetaMax",
0042         help="cot of maximum theta angle",
0043         type=float,
0044         default=7.40627,
0045     )
0046     parser.add_argument(
0047         "--sf_sigmaScattering",
0048         dest="sf_sigmaScattering",
0049         help="How many sigmas of scattering to include in seeds",
0050         type=float,
0051         default=5,
0052     )
0053     parser.add_argument(
0054         "--sf_radLengthPerSeed",
0055         dest="sf_radLengthPerSeed",
0056         help="Average Radiation Length",
0057         type=float,
0058         default=0.1,
0059     )
0060     parser.add_argument(
0061         "--sf_impactMax",
0062         dest="sf_impactMax",
0063         help="max impact parameter in mm",
0064         type=float,
0065         default=3.0,
0066     )
0067     parser.add_argument(
0068         "--sf_maxPtScattering",
0069         dest="sf_maxPtScattering",
0070         help="maximum Pt for scattering cut in GeV",
0071         type=float,
0072         default=10.0,
0073     )
0074     parser.add_argument(
0075         "--sf_deltaRMin",
0076         dest="sf_deltaRMin",
0077         help="minimum value for deltaR separation in mm",
0078         type=float,
0079         default=1.0,
0080     )
0081     parser.add_argument(
0082         "--sf_deltaRMax",
0083         dest="sf_deltaRMax",
0084         help="maximum value for deltaR separation in mm",
0085         type=float,
0086         default=60.0,
0087     )
0088 
0089     return parser
0090 
0091 
0092 def runCKFTracks(
0093     trackingGeometry,
0094     decorators,
0095     geometrySelection: Path,
0096     digiConfigFile: Path,
0097     field,
0098     outputDir: Path,
0099     NumEvents=1,
0100     truthSmearedSeeded=False,
0101     truthEstimatedSeeded=False,
0102     outputCsv=True,
0103     inputParticlePath: Optional[Path] = None,
0104     s=None,
0105     MaxSeedsPerSpM=1,
0106     CotThetaMax=7.40627,
0107     SigmaScattering=5,
0108     RadLengthPerSeed=0.1,
0109     ImpactMax=3.0,
0110     MaxPtScattering=10.0,
0111     DeltaRMin=1.0,
0112     DeltaRMax=60.0,
0113 ):
0114     from acts.examples.simulation import (
0115         addParticleGun,
0116         EtaConfig,
0117         PhiConfig,
0118         ParticleConfig,
0119         ParticleSelectorConfig,
0120         addFatras,
0121         addDigitization,
0122     )
0123 
0124     from acts.examples.reconstruction import (
0125         addSeeding,
0126         TrackSmearingSigmas,
0127         SeedFinderConfigArg,
0128         SeedFinderOptionsArg,
0129         SeedingAlgorithm,
0130         TruthEstimatedSeedingAlgorithmConfigArg,
0131         addCKFTracks,
0132     )
0133 
0134     s = s or acts.examples.Sequencer(
0135         events=int(NumEvents),
0136         numThreads=-1,
0137         logLevel=acts.logging.INFO,
0138         outputDir=outputDir,
0139     )
0140     for d in decorators:
0141         s.addContextDecorator(d)
0142     rnd = acts.examples.RandomNumbers(seed=42)
0143     outputDir = Path(outputDir)
0144 
0145     if inputParticlePath is None:
0146         addParticleGun(
0147             s,
0148             EtaConfig(-2.0, 2.0),
0149             ParticleConfig(4, acts.PdgParticle.eMuon, True),
0150             PhiConfig(0.0, 360.0 * u.degree),
0151             multiplicity=2,
0152             rnd=rnd,
0153         )
0154     else:
0155         acts.logging.getLogger("CKFExample").info(
0156             "Reading particles from %s", inputParticlePath.resolve()
0157         )
0158         assert inputParticlePath.exists()
0159         s.addReader(
0160             RootParticleReader(
0161                 level=acts.logging.INFO,
0162                 filePath=str(inputParticlePath.resolve()),
0163                 outputParticles="particles_input",
0164             )
0165         )
0166 
0167     addFatras(
0168         s,
0169         trackingGeometry,
0170         field,
0171         rnd=rnd,
0172         postSelectParticles=ParticleSelectorConfig(
0173             pt=(0.5 * u.GeV, None),
0174             hits=(9, None),
0175             removeNeutral=True,
0176         ),
0177     )
0178 
0179     addDigitization(
0180         s,
0181         trackingGeometry,
0182         field,
0183         digiConfigFile=digiConfigFile,
0184         rnd=rnd,
0185     )
0186 
0187     addSeeding(
0188         s,
0189         trackingGeometry,
0190         field,
0191         TrackSmearingSigmas(  # only used by SeedingAlgorithm.TruthSmeared
0192             # zero eveything so the CKF has a chance to find the measurements
0193             loc0=0,
0194             loc0PtA=0,
0195             loc0PtB=0,
0196             loc1=0,
0197             loc1PtA=0,
0198             loc1PtB=0,
0199             time=0,
0200             phi=0,
0201             theta=0,
0202             ptRel=0,
0203         ),
0204         SeedFinderConfigArg(
0205             r=(None, 200 * u.mm),  # rMin=default, 33mm
0206             deltaR=(DeltaRMin * u.mm, DeltaRMax * u.mm),
0207             collisionRegion=(-250 * u.mm, 250 * u.mm),
0208             z=(-2000 * u.mm, 2000 * u.mm),
0209             maxSeedsPerSpM=MaxSeedsPerSpM,
0210             cotThetaMax=CotThetaMax,
0211             sigmaScattering=SigmaScattering,
0212             radLengthPerSeed=RadLengthPerSeed,
0213             maxPtScattering=MaxPtScattering * u.GeV,
0214             minPt=500 * u.MeV,
0215             impactMax=ImpactMax * u.mm,
0216         ),
0217         SeedFinderOptionsArg(bFieldInZ=2 * u.T, beamPos=(0.0, 0, 0)),
0218         TruthEstimatedSeedingAlgorithmConfigArg(deltaR=(10.0 * u.mm, None)),
0219         seedingAlgorithm=(
0220             SeedingAlgorithm.TruthSmeared
0221             if truthSmearedSeeded
0222             else (
0223                 SeedingAlgorithm.TruthEstimated
0224                 if truthEstimatedSeeded
0225                 else SeedingAlgorithm.Default
0226             )
0227         ),
0228         initialSigmas=[
0229             1 * u.mm,
0230             1 * u.mm,
0231             1 * u.degree,
0232             1 * u.degree,
0233             0.1 * u.e / u.GeV,
0234             1 * u.ns,
0235         ],
0236         initialSigmaPtRel=0.01,
0237         initialVarInflation=[1.0] * 6,
0238         geoSelectionConfigFile=geometrySelection,
0239         outputDirRoot=outputDir,
0240         rnd=rnd,  # only used by SeedingAlgorithm.TruthSmeared
0241     )
0242 
0243     addCKFTracks(
0244         s,
0245         trackingGeometry,
0246         field,
0247         outputDirRoot=outputDir,
0248         outputDirCsv=outputDir / "csv" if outputCsv else None,
0249     )
0250 
0251     return s
0252 
0253 
0254 if "__main__" == __name__:
0255     options = getArgumentParser().parse_args()
0256 
0257     Inputdir = options.indir
0258     Outputdir = options.outdir
0259 
0260     srcdir = Path(__file__).resolve().parent.parent.parent.parent
0261 
0262     detector = GenericDetector()
0263     trackingGeometry = detector.trackingGeometry()
0264     decorators = detector.contextDecorators()
0265 
0266     field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T))
0267 
0268     inputParticlePath = Path(Inputdir) / "particles.root"
0269     if not inputParticlePath.exists():
0270         inputParticlePath = None
0271 
0272     runCKFTracks(
0273         trackingGeometry,
0274         decorators,
0275         field=field,
0276         geometrySelection=srcdir
0277         / "Examples/Algorithms/TrackFinding/share/geoSelection-genericDetector.json",
0278         digiConfigFile=srcdir
0279         / "Examples/Algorithms/Digitization/share/default-smearing-config-generic.json",
0280         outputCsv=True,
0281         truthSmearedSeeded=False,
0282         truthEstimatedSeeded=False,
0283         inputParticlePath=inputParticlePath,
0284         outputDir=Outputdir,
0285         NumEvents=options.nEvts,
0286         MaxSeedsPerSpM=options.sf_maxSeedsPerSpM,
0287         CotThetaMax=options.sf_cotThetaMax,
0288         SigmaScattering=options.sf_sigmaScattering,
0289         RadLengthPerSeed=options.sf_radLengthPerSeed,
0290         ImpactMax=options.sf_impactMax,
0291         MaxPtScattering=options.sf_maxPtScattering,
0292         DeltaRMin=options.sf_deltaRMin,
0293         DeltaRMax=options.sf_deltaRMax,
0294     ).run()