Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ckf.py
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ckf.py
1 #!/usr/bin/env python3
2 from pathlib import Path
3 from typing import Optional, Union
4 from collections import namedtuple
5 import argparse
6 import sys
7 import os
8 
9 from acts.examples import Sequencer, GenericDetector, RootParticleReader
10 
11 import acts
12 
13 from acts import UnitConstants as u
14 
15 
17  """Get arguments from command line"""
18  parser = argparse.ArgumentParser(description="Command line arguments for CKF")
19  parser.add_argument(
20  "-i",
21  "--indir",
22  dest="indir",
23  help="Directory with input root files",
24  default="./",
25  )
26  parser.add_argument(
27  "-o",
28  "--output",
29  dest="outdir",
30  help="Output directory for new ntuples",
31  default="./",
32  )
33  parser.add_argument(
34  "-n", "--nEvents", dest="nEvts", help="Number of events to run over", default=1
35  )
36  parser.add_argument(
37  "--sf_maxSeedsPerSpM",
38  dest="sf_maxSeedsPerSpM",
39  help="Number of compatible seeds considered for middle seed",
40  type=int,
41  default=1,
42  )
43  parser.add_argument(
44  "--sf_cotThetaMax",
45  dest="sf_cotThetaMax",
46  help="cot of maximum theta angle",
47  type=float,
48  default=7.40627,
49  )
50  parser.add_argument(
51  "--sf_sigmaScattering",
52  dest="sf_sigmaScattering",
53  help="How many sigmas of scattering to include in seeds",
54  type=float,
55  default=5,
56  )
57  parser.add_argument(
58  "--sf_radLengthPerSeed",
59  dest="sf_radLengthPerSeed",
60  help="Average Radiation Length",
61  type=float,
62  default=0.1,
63  )
64  parser.add_argument(
65  "--sf_impactMax",
66  dest="sf_impactMax",
67  help="max impact parameter in mm",
68  type=float,
69  default=3.0,
70  )
71  parser.add_argument(
72  "--sf_maxPtScattering",
73  dest="sf_maxPtScattering",
74  help="maximum Pt for scattering cut in GeV",
75  type=float,
76  default=10.0,
77  )
78  parser.add_argument(
79  "--sf_deltaRMin",
80  dest="sf_deltaRMin",
81  help="minimum value for deltaR separation in mm",
82  type=float,
83  default=1.0,
84  )
85  parser.add_argument(
86  "--sf_deltaRMax",
87  dest="sf_deltaRMax",
88  help="maximum value for deltaR separation in mm",
89  type=float,
90  default=60.0,
91  )
92 
93  return parser
94 
95 
96 def runCKFTracks(
97  trackingGeometry,
98  decorators,
99  geometrySelection: Path,
100  digiConfigFile: Path,
101  field,
102  outputDir: Path,
103  NumEvents=1,
104  truthSmearedSeeded=False,
105  truthEstimatedSeeded=False,
106  outputCsv=True,
107  inputParticlePath: Optional[Path] = None,
108  s=None,
109  MaxSeedsPerSpM=1,
110  CotThetaMax=7.40627,
111  SigmaScattering=5,
112  RadLengthPerSeed=0.1,
113  ImpactMax=3.0,
114  MaxPtScattering=10.0,
115  DeltaRMin=1.0,
116  DeltaRMax=60.0,
117 ):
118 
119  from acts.examples.simulation import (
120  addParticleGun,
121  EtaConfig,
122  PhiConfig,
123  ParticleConfig,
124  addFatras,
125  addDigitization,
126  )
127 
128  from acts.examples.reconstruction import (
129  addSeeding,
130  TruthSeedRanges,
131  ParticleSmearingSigmas,
132  SeedFinderConfigArg,
133  SeedFinderOptionsArg,
134  SeedingAlgorithm,
135  TruthEstimatedSeedingAlgorithmConfigArg,
136  addCKFTracks,
137  )
138 
139  s = s or acts.examples.Sequencer(
140  events=int(NumEvents),
141  numThreads=-1,
142  logLevel=acts.logging.INFO,
143  outputDir=outputDir,
144  )
145  for d in decorators:
146  s.addContextDecorator(d)
147  rnd = acts.examples.RandomNumbers(seed=42)
148  outputDir = Path(outputDir)
149 
150  if inputParticlePath is None:
152  s,
153  EtaConfig(-2.0, 2.0),
154  ParticleConfig(4, acts.PdgParticle.eMuon, True),
155  PhiConfig(0.0, 360.0 * u.degree),
156  multiplicity=2,
157  rnd=rnd,
158  )
159  else:
160  acts.logging.getLogger("CKFExample").info(
161  "Reading particles from %s", inputParticlePath.resolve()
162  )
163  assert inputParticlePath.exists()
164  s.addReader(
165  RootParticleReader(
166  level=acts.logging.INFO,
167  filePath=str(inputParticlePath.resolve()),
168  particleCollection="particles_input",
169  orderedEvents=False,
170  )
171  )
172 
173  addFatras(
174  s,
175  trackingGeometry,
176  field,
177  rnd=rnd,
178  )
179 
181  s,
182  trackingGeometry,
183  field,
184  digiConfigFile=digiConfigFile,
185  rnd=rnd,
186  )
187 
188  addSeeding(
189  s,
190  trackingGeometry,
191  field,
192  TruthSeedRanges(pt=(500.0 * u.MeV, None), nHits=(9, None)),
193  ParticleSmearingSigmas(pRel=0.01), # only used by SeedingAlgorithm.TruthSmeared
195  r=(None, 200 * u.mm), # rMin=default, 33mm
196  deltaR=(DeltaRMin * u.mm, DeltaRMax * u.mm),
197  collisionRegion=(-250 * u.mm, 250 * u.mm),
198  z=(-2000 * u.mm, 2000 * u.mm),
199  maxSeedsPerSpM=MaxSeedsPerSpM,
200  cotThetaMax=CotThetaMax,
201  sigmaScattering=SigmaScattering,
202  radLengthPerSeed=RadLengthPerSeed,
203  maxPtScattering=MaxPtScattering * u.GeV,
204  minPt=500 * u.MeV,
205  impactMax=ImpactMax * u.mm,
206  ),
207  SeedFinderOptionsArg(bFieldInZ=1.99724 * u.T, beamPos=(0.0, 0, 0)),
208  TruthEstimatedSeedingAlgorithmConfigArg(deltaR=(10.0 * u.mm, None)),
209  seedingAlgorithm=SeedingAlgorithm.TruthSmeared
210  if truthSmearedSeeded
211  else SeedingAlgorithm.TruthEstimated
212  if truthEstimatedSeeded
213  else SeedingAlgorithm.Default,
214  geoSelectionConfigFile=geometrySelection,
215  outputDirRoot=outputDir,
216  rnd=rnd, # only used by SeedingAlgorithm.TruthSmeared
217  )
218 
219  addCKFTracks(
220  s,
221  trackingGeometry,
222  field,
223  outputDirRoot=outputDir,
224  outputDirCsv=outputDir / "csv" if outputCsv else None,
225  )
226 
227  return s
228 
229 
230 if "__main__" == __name__:
231  options = getArgumentParser().parse_args()
232 
233  Inputdir = options.indir
234  Outputdir = options.outdir
235 
236  srcdir = Path(__file__).resolve().parent.parent.parent.parent
237 
238  detector, trackingGeometry, decorators = GenericDetector.create()
239 
240  field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T))
241 
242  inputParticlePath = Path(Inputdir) / "pythia8_particles.root"
243  if not inputParticlePath.exists():
244  inputParticlePath = None
245 
246  runCKFTracks(
247  trackingGeometry,
248  decorators,
249  field=field,
250  geometrySelection=srcdir
251  / "Examples/Algorithms/TrackFinding/share/geoSelection-genericDetector.json",
252  digiConfigFile=srcdir
253  / "Examples/Algorithms/Digitization/share/default-smearing-config-generic.json",
254  outputCsv=True,
255  truthSmearedSeeded=False,
256  truthEstimatedSeeded=False,
257  inputParticlePath=inputParticlePath,
258  outputDir=Outputdir,
259  NumEvents=options.nEvts,
260  MaxSeedsPerSpM=options.sf_maxSeedsPerSpM,
261  CotThetaMax=options.sf_cotThetaMax,
262  SigmaScattering=options.sf_sigmaScattering,
263  RadLengthPerSeed=options.sf_radLengthPerSeed,
264  ImpactMax=options.sf_impactMax,
265  MaxPtScattering=options.sf_maxPtScattering,
266  DeltaRMin=options.sf_deltaRMin,
267  DeltaRMax=options.sf_deltaRMax,
268  ).run()