Skip to content

Commit

Permalink
feat: Vertexing mu scan and CI job that creates it (#1595)
Browse files Browse the repository at this point in the history
This PR adds a configuration + plotting script for this kind of plot produced by the CI:

![vertexing](https://user-images.githubusercontent.com/1058585/195329400-3f907dc3-2ad7-4b1d-8276-37a94ccbe377.png)


This currently runs on 25 events, but we might have to tune this to keep the runtime reasonable.
  • Loading branch information
paulgessinger committed Oct 20, 2022
1 parent a004eed commit 7a487eb
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CI/physmon/phys_perf_mon.sh
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,10 @@ run \
# -p $outdir/analysis_residuals_and_pulls \


Examples/Scripts/vertex_mu_scan.py \
$outdir/performance_vertexing_*mu*.root \
$outdir/vertexing_mu_scan.pdf

rm $outdir/performance_vertexing_*mu*

exit $ec
115 changes: 115 additions & 0 deletions CI/physmon/physmon.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import tempfile
import shutil
import os
import datetime
import sys
import subprocess

Expand Down Expand Up @@ -218,3 +219,117 @@
"",
]
)


### VERTEX MU SCAN

for fitter in (VertexFinder.Iterative, VertexFinder.AMVF):
for mu in (1, 10, 25, 50, 75, 100, 125, 150, 175, 200):
start = datetime.datetime.now()
s = acts.examples.Sequencer(events=5, numThreads=1, logLevel=acts.logging.INFO)

with tempfile.TemporaryDirectory() as temp:
tp = Path(temp)

for d in decorators:
s.addContextDecorator(d)

rnd = acts.examples.RandomNumbers(seed=42)

vtxGen = acts.examples.GaussianVertexGenerator(
stddev=acts.Vector4(10 * u.um, 10 * u.um, 50 * u.mm, 0),
mean=acts.Vector4(0, 0, 0, 0),
)

addParticleGun(
s,
EtaConfig(-4.0, 4.0),
ParticleConfig(4, acts.PdgParticle.eMuon, True),
PhiConfig(0.0, 360.0 * u.degree),
vtxGen=vtxGen,
multiplicity=mu,
rnd=rnd,
)

addFatras(
s,
trackingGeometry,
field,
rnd=rnd,
)

addDigitization(
s,
trackingGeometry,
field,
digiConfigFile=digiConfig,
rnd=rnd,
)

addSeeding(
s,
trackingGeometry,
field,
TruthSeedRanges(pt=(500.0 * u.MeV, None), nHits=(9, None)),
ParticleSmearingSigmas(
pRel=0.01
), # only used by SeedingAlgorithm.TruthSmeared
SeedfinderConfigArg(
r=(None, 200 * u.mm), # rMin=default, 33mm
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=500 * u.MeV,
bFieldInZ=1.99724 * u.T,
impactMax=3 * u.mm,
),
TrackParamsEstimationConfig(deltaR=(10.0 * u.mm, None)),
seedingAlgorithm=SeedingAlgorithm.Default,
geoSelectionConfigFile=geoSel,
outputDirRoot=None,
rnd=rnd, # only used by SeedingAlgorithm.TruthSmeared
)

addCKFTracks(
s,
trackingGeometry,
field,
CKFPerformanceConfig(ptMin=400.0 * u.MeV, nMeasurementsMin=6),
outputDirRoot=None,
outputDirCsv=None,
)

addVertexFitting(
s,
field,
TrackSelectorRanges(
removeNeutral=True,
absEta=(None, 2.5),
loc0=(None, 4.0 * u.mm),
pt=(500 * u.MeV, None),
),
vertexFinder=fitter,
trajectories="trajectories",
outputDirRoot=tp,
)

s.run()

delta = datetime.datetime.now() - start

duration = delta.total_seconds() / s.config.events

perf_file = tp / f"performance_vertexing.root"
assert perf_file.exists(), "Performance file not found"
shutil.copy(
perf_file, outdir / f"performance_vertexing_{fitter.name}_mu{mu}.root"
)

(
outdir / f"performance_vertexing_{fitter.name}_mu{mu}_time.txt"
).write_text(str(duration))

del s
81 changes: 81 additions & 0 deletions Examples/Scripts/vertex_mu_scan.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/bin/env python3
from pathlib import Path
from typing import List, Optional
import re

import uproot
import typer
import numpy
import matplotlib.pyplot


def main(files: List[Path], output: str, title: str = ""):

mus = []

for file in files:
m = re.match(".*mu(\d+).*", file.name)
mu = int(m.group(1))
mus.append(mu)

mus = list(sorted(mus))

fig, (ax, tax) = matplotlib.pyplot.subplots(
2, 1, gridspec_kw={"hspace": 0, "height_ratios": [2, 1]}
)

for fitter, color in zip(("Iterative", "AMVF"), ["tab:blue", "tab:orange"]):
mean = numpy.array([])
stddev = numpy.array([])
ntrue_mean = numpy.array([])
ntrue_stddev = numpy.array([])
time = numpy.array([])

for mu in mus:
for file in files:
if f"mu{mu}" in file.name and fitter in file.name:
break

time_file = file.parent / f"{file.stem}_time.txt"
if time_file.exists():
time = numpy.append(time, float(time_file.read_text()))
else:
fime.append(float("nan"))

rf = uproot.open(f"{file}:vertexing")

nreco = rf["nRecoVtx"].array(library="np")
ntrue = rf["nTrueVtx"].array(library="np")

nreco_mean = nreco.mean()

nreco_std = nreco.std()

mean = numpy.append(mean, nreco_mean)
stddev = numpy.append(stddev, nreco_std)

ntrue_mean = numpy.append(ntrue_mean, ntrue.mean())
ntrue_stddev = numpy.append(ntrue_stddev, ntrue.std())

ax.fill_between(mus, mean - stddev, mean + stddev, fc=color, alpha=0.2)
ax.plot(mus, mean, label=fitter, c=color)
tax.plot(mus, time, label=f"{fitter} time", c=color)

ax.plot(mus, mus, label="truth", c="gray", ls="--")

tax.set_xlabel("$\mu$")
ax.set_ylabel("Number of vertices")
tax.set_ylabel("wall time [s]")

fig.align_labels()

ax.legend()
tax.legend()
ax.set_title(title)

fig.tight_layout()
fig.savefig(output)


if __name__ == "__main__":
typer.run(main)

0 comments on commit 7a487eb

Please sign in to comment.