Skip to content

Instantly share code, notes, and snippets.

@paulgessinger
Last active November 21, 2024 15:48
Show Gist options
  • Save paulgessinger/0d1f3e63ebd4275854fa934e3d541add to your computer and use it in GitHub Desktop.
Save paulgessinger/0d1f3e63ebd4275854fa934e3d541add to your computer and use it in GitHub Desktop.
ACTS profiling cookbook

ACTS Profiling Cookbook

Instructions can be found on this CodiMD.

#!/usr/bin/env python3
from pathlib import Path
import csv
import acts
import acts.examples
from acts.examples.simulation import (
MomentumConfig,
EtaConfig,
PhiConfig,
ParticleConfig,
addParticleGun,
addPythia8,
ParticleSelectorConfig,
addFatras,
addGeant4,
addDigitization,
)
from acts.examples.reconstruction import (
SeedFinderConfigArg,
addSeeding,
TrackSelectorConfig,
CkfConfig,
addCKFTracks,
)
from acts.examples.odd import getOpenDataDetector, getOpenDataDetectorDirectory
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("outputDir", help="Output directory", type=Path)
parser.add_argument("--ttbar", help="Use ttbar events", action="store_true")
parser.add_argument("--geant4", help="Use geant4 simulation", action="store_true")
parser.add_argument(
"--nockf", help="Run track finding", action="store_true", default=False
)
args = parser.parse_args()
u = acts.UnitConstants
geoDir = getOpenDataDetectorDirectory()
outputDir = Path.cwd() / args.outputDir
outputDir.mkdir(parents=True, exist_ok=True)
oddMaterialMap = geoDir / "data/odd-material-maps.root"
oddDigiConfig = geoDir / "config/odd-digi-smearing-config.json"
oddSeedingSel = geoDir / "config/odd-seeding-config.json"
oddMaterialDeco = acts.IMaterialDecorator.fromFile(oddMaterialMap)
detector, trackingGeometry, decorators = getOpenDataDetector(
odd_dir=geoDir, mdecorator=oddMaterialDeco
)
field = acts.ConstantBField(acts.Vector3(0.0, 0.0, 2.0 * u.T))
rnd = acts.examples.RandomNumbers(seed=42)
events = 20
runs = 50
if args.ttbar:
events = 3
runs = 30
if args.nockf:
events *= 2
runs *= 2
def create_sequencer():
s = acts.examples.Sequencer(
events=events,
numThreads=1,
outputDir=str(outputDir),
trackFpes=False,
# logLevel=acts.logging.WARNING,
)
if not args.ttbar:
addParticleGun(
s,
MomentumConfig(1.0 * u.GeV, 10.0 * u.GeV, transverse=True),
EtaConfig(-3.0, 3.0, uniform=True),
PhiConfig(0.0, 360.0 * u.degree),
ParticleConfig(4, acts.PdgParticle.eMuon, randomizeCharge=True),
vtxGen=acts.examples.GaussianVertexGenerator(
mean=acts.Vector4(0, 0, 0, 0),
stddev=acts.Vector4(
0.0125 * u.mm, 0.0125 * u.mm, 55.5 * u.mm, 1.0 * u.ns
),
),
multiplicity=50,
rnd=rnd,
# outputDirRoot=outputDir,
# outputDirCsv=outputDir,
)
else:
addPythia8(
s,
hardProcess=["Top:qqbar2ttbar=on"],
npileup=200,
vtxGen=acts.examples.GaussianVertexGenerator(
mean=acts.Vector4(0, 0, 0, 0),
stddev=acts.Vector4(
0.0125 * u.mm, 0.0125 * u.mm, 55.5 * u.mm, 5.0 * u.ns
),
),
rnd=rnd,
# outputDirRoot=outputDir,
# outputDirCsv=outputDir,
)
if not args.geant4:
addFatras(
s,
trackingGeometry,
field,
preSelectParticles=ParticleSelectorConfig(
rho=(0.0, 24 * u.mm),
absZ=(0.0, 1.0 * u.m),
),
postSelectParticles=ParticleSelectorConfig(
eta=(-3.0, 3.0),
pt=(150 * u.MeV, None),
removeNeutral=True,
),
enableInteractions=True,
# outputDirRoot=outputDir,
# outputDirCsv=outputDir,
rnd=rnd,
)
else:
addGeant4(
s,
detector,
trackingGeometry,
field,
preSelectParticles=ParticleSelectorConfig(
rho=(0.0, 24 * u.mm),
absZ=(0.0, 1.0 * u.m),
),
postSelectParticles=ParticleSelectorConfig(
eta=(-3.0, 3.0),
pt=(150 * u.MeV, None),
removeNeutral=True,
),
outputDirRoot=outputDir,
# outputDirCsv=outputDir,
rnd=rnd,
killVolume=trackingGeometry.worldVolume,
killAfterTime=25 * u.ns,
)
addDigitization(
s,
trackingGeometry,
field,
digiConfigFile=oddDigiConfig,
# outputDirRoot=outputDir,
# outputDirCsv=outputDir,
rnd=rnd,
)
addSeeding(
s,
trackingGeometry,
field,
geoSelectionConfigFile=oddSeedingSel,
seedFinderConfigArg=SeedFinderConfigArg(
# r=(33 * u.mm, 200 * u.mm),
# deltaR=(1 * u.mm, 60 * u.mm),
# collisionRegion=(-250 * u.mm, 250 * u.mm),
# z=(-2000 * u.mm, 2000 * u.mm),
# maxSeedsPerSpM=1,
# sigmaScattering=5,
# radLengthPerSeed=0.1,
minPt=0.9 * u.GeV,
# impactMax=3 * u.mm,
),
# outputDirRoot=outputDir,
# outputDirCsv=outputDir,
)
if not args.nockf:
addCKFTracks(
s,
trackingGeometry,
field,
TrackSelectorConfig(
pt=(1.0 * u.GeV, None),
absEta=(None, 3.0),
loc0=(-4.0 * u.mm, 4.0 * u.mm),
nMeasurementsMin=7,
maxHoles=2,
maxOutliers=2,
maxHolesAndOutliers=4,
),
CkfConfig(
chi2CutOffMeasurement=9,
chi2CutOffOutlier=15,
numMeasurementsCutOff=1,
seedDeduplication=True,
stayOnSeed=True,
),
# writeCovMat=True,
# outputDirCsv=outputDir,
# outputDirRoot=outputDir,
# logLevel=acts.logging.VERBOSE,
)
return s
s = create_sequencer()
times = []
outputCsv = outputDir / "timing.csv"
for i in range(runs):
print(f"start round {i}")
s.run()
with outputCsv.open("r") as fh:
reader = csv.DictReader(fh)
t = {}
for row in reader:
for alg, key in [
("seeding", "Algorithm:SeedingAlgorithm"),
("ckf", "Algorithm:TrackFindingAlgorithm"),
("fatras", "Algorithm:FatrasSimulation"),
("geant4", "Algorithm:Geant4Simulation"),
]:
if row["identifier"] == key:
t[alg] = row["time_perevent_s"]
print(f"finished and got times {t}")
times.append(t)
with outputCsv.open("w") as fh:
writer = csv.DictWriter(fh, fieldnames=times[0].keys())
writer.writeheader()
for times in times:
writer.writerow(times)
#!/bin/bash
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
# You need to modify the `setup.sh` script
source $SCRIPT_DIR/setup.sh
tmp=$(mktemp -d)
{ while kill -0 $$ 2> /dev/null; do sleep 0.5; done; echo "Cleaning up"; rm -rf "$tmp"; } &
exec python3 $SCRIPT_DIR/full_chain_perf.py "$tmp" --ttbar "$@"
#!/bin/bash
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
exec $SCRIPT_DIR/full_chain_perf.sh --nockf "$@"
#!/usr/bin/env python3
from pathlib import Path
from typing import Optional
import acts
import acts.examples
u = acts.UnitConstants
def runTruthTrackingGx2f(
trackingGeometry: acts.TrackingGeometry,
field: acts.MagneticFieldProvider,
digiConfigFile: Path,
outputDir: Path,
s: acts.examples.Sequencer = None,
):
from acts.examples.simulation import (
addParticleGun,
ParticleConfig,
EtaConfig,
PhiConfig,
MomentumConfig,
ParticleSelectorConfig,
addFatras,
addDigitization,
)
from acts.examples.reconstruction import (
addSeeding,
SeedingAlgorithm,
addGx2fTracks,
)
s = s or acts.examples.Sequencer(
events=100, numThreads=-1, logLevel=acts.logging.INFO
)
rnd = acts.examples.RandomNumbers(seed=42)
outputDir = Path(outputDir)
addParticleGun(
s,
ParticleConfig(num=1, pdg=acts.PdgParticle.eMuon, randomizeCharge=True),
EtaConfig(-3.0, 3.0, uniform=True),
MomentumConfig(1.0 * u.GeV, 100.0 * u.GeV, transverse=True),
PhiConfig(0.0, 360.0 * u.degree),
vtxGen=acts.examples.GaussianVertexGenerator(
mean=acts.Vector4(0, 0, 0, 0),
stddev=acts.Vector4(0, 0, 0, 0),
),
multiplicity=1,
rnd=rnd,
outputDirRoot=outputDir,
)
addFatras(
s,
trackingGeometry,
field,
rnd=rnd,
enableInteractions=True,
postSelectParticles=ParticleSelectorConfig(
pt=(0.9 * u.GeV, None),
measurements=(7, None),
removeNeutral=True,
removeSecondaries=True,
),
)
addDigitization(
s,
trackingGeometry,
field,
digiConfigFile=digiConfigFile,
rnd=rnd,
)
addSeeding(
s,
trackingGeometry,
field,
rnd=rnd,
inputParticles="particles_input",
seedingAlgorithm=SeedingAlgorithm.TruthSmeared,
particleHypothesis=acts.ParticleHypothesis.muon,
)
addGx2fTracks(
s,
trackingGeometry,
field,
nUpdateMax=17,
relChi2changeCutOff=1e-7,
multipleScattering=True,
)
s.addAlgorithm(
acts.examples.TrackSelectorAlgorithm(
level=acts.logging.INFO,
inputTracks="tracks",
outputTracks="selected-tracks",
selectorConfig=acts.TrackSelector.Config(
minMeasurements=7,
),
)
)
s.addWhiteboardAlias("tracks", "selected-tracks")
return s
if "__main__" == __name__:
# ODD
from acts.examples.odd import getOpenDataDetector, getOpenDataDetectorDirectory
geoDir = getOpenDataDetectorDirectory()
detector, trackingGeometry, decorators = getOpenDataDetector()
digiConfigFile = geoDir / "config/odd-digi-smearing-config.json"
## GenericDetector
# detector, trackingGeometry, _ = acts.examples.GenericDetector.create()
# digiConfigFile = (
# srcdir
# / "Examples/Algorithms/Digitization/share/default-smearing-config-generic.json"
# )
field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T))
events = 20000
runs = 10
s = acts.examples.Sequencer(events=events, numThreads=1, logLevel=acts.logging.INFO)
runTruthTrackingGx2f(
s=s,
trackingGeometry=trackingGeometry,
field=field,
digiConfigFile=digiConfigFile,
outputDir=Path.cwd(),
)
for run in range(runs):
print("Run", run, "/", runs)
s.run()
#!/bin/bash
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
cd $SCRIPT_DIR
# You need to modify the `setup.sh` script
source $SCRIPT_DIR/setup.sh
tmp=$(mktemp -d)
{ while kill -0 $$ 2> /dev/null; do sleep 0.5; done; echo "Cleaning up"; rm -rf "$tmp"; } &
exec python3 $SCRIPT_DIR/gx2f_perf.py "$tmp" "$@"
#!/bin/bash
cmd="$@"
echo $cmd
$cmd > stdout.txt 2>&1 &
pid=$!
_term() {
echo "Caught SIGTERM signal!"
kill -TERM "$pid" 2>/dev/null
}
trap _term SIGTERM
sample $pid 60 -wait -f output.prof
filtercalltree output.prof > output.ctree
stackcollapse-sample.awk output.ctree > output.folded
flamegraph.pl output.folded > output.svg
echo "Waiting for pid $pid"
wait $pid
# This file needs to contain steps that are needed to put you in a working environment.
# For the ODD tests that means sourcing the `build/this_acts_withdeps.sh` file in the ACTS build folder
source $PWD/build/this_acts_withdeps.sh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment