-
Notifications
You must be signed in to change notification settings - Fork 157
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
A number of unit tests based on the ``pytest`` library are shipped with the repository. They are located under ``$REPO_ROOT/Examples/Python/tests``, and intend to cover the public API of the python bindings. A set of tests also executed the standalone example scripts. To run these python based tests, ``pytest`` needs to be installed. It can be installed via ``pip install pytest``. It is recommended to install this package in [virtual environment](https://realpython.com/python-virtual-environments-a-primer/). You can then simply run ``pytest`` from the repository root.
- Loading branch information
1 parent
162bad9
commit 51b62f8
Showing
14 changed files
with
1,638 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
from pathlib import Path | ||
import sys | ||
import os | ||
import tempfile | ||
|
||
|
||
sys.path += [ | ||
str(Path(__file__).parent.parent.parent.parent / "Examples/Scripts/Python/"), | ||
str(Path(__file__).parent), | ||
] | ||
|
||
import helpers | ||
|
||
import pytest | ||
|
||
import acts | ||
import acts.examples | ||
|
||
u = acts.UnitConstants | ||
|
||
|
||
def kwargsConstructor(cls, *args, **kwargs): | ||
return cls(*args, **kwargs) | ||
|
||
|
||
def configKwConstructor(cls, *args, **kwargs): | ||
assert hasattr(cls, "Config") | ||
_kwargs = {} | ||
if "level" in kwargs: | ||
_kwargs["level"] = kwargs.pop("level") | ||
config = cls.Config() | ||
for k, v in kwargs.items(): | ||
setattr(config, k, v) | ||
return cls(*args, config=config, **_kwargs) | ||
|
||
|
||
def configPosConstructor(cls, *args, **kwargs): | ||
assert hasattr(cls, "Config") | ||
_kwargs = {} | ||
if "level" in kwargs: | ||
_kwargs["level"] = kwargs.pop("level") | ||
config = cls.Config() | ||
for k, v in kwargs.items(): | ||
setattr(config, k, v) | ||
|
||
return cls(config, *args, **_kwargs) | ||
|
||
|
||
@pytest.fixture(params=[configPosConstructor, configKwConstructor, kwargsConstructor]) | ||
def conf_const(request): | ||
return request.param | ||
|
||
|
||
@pytest.fixture | ||
def rng(): | ||
return acts.examples.RandomNumbers(seed=42) | ||
|
||
|
||
@pytest.fixture | ||
def basic_prop_seq(rng): | ||
def _basic_prop_seq_factory(geo, s=None): | ||
if s is None: | ||
s = acts.examples.Sequencer(events=10, numThreads=1) | ||
|
||
nav = acts.Navigator(trackingGeometry=geo) | ||
stepper = acts.StraightLineStepper() | ||
|
||
prop = acts.examples.ConcretePropagator(acts.Propagator(stepper, nav)) | ||
alg = acts.examples.PropagationAlgorithm( | ||
propagatorImpl=prop, | ||
level=acts.logging.INFO, | ||
randomNumberSvc=rng, | ||
ntests=10, | ||
sterileLogger=False, | ||
propagationStepCollection="propagation-steps", | ||
) | ||
s.addAlgorithm(alg) | ||
return s, alg | ||
|
||
return _basic_prop_seq_factory | ||
|
||
|
||
@pytest.fixture | ||
def trk_geo(request): | ||
detector, geo, contextDecorators = acts.examples.GenericDetector.create() | ||
yield geo | ||
|
||
|
||
@pytest.fixture | ||
def ptcl_gun(rng): | ||
def _factory(s): | ||
evGen = acts.examples.EventGenerator( | ||
level=acts.logging.INFO, | ||
generators=[ | ||
acts.examples.EventGenerator.Generator( | ||
multiplicity=acts.examples.FixedMultiplicityGenerator(n=2), | ||
vertex=acts.examples.GaussianVertexGenerator( | ||
stddev=acts.Vector4(0, 0, 0, 0), mean=acts.Vector4(0, 0, 0, 0) | ||
), | ||
particles=acts.examples.ParametricParticleGenerator( | ||
p=(1 * u.GeV, 10 * u.GeV), | ||
eta=(-2, 2), | ||
phi=(0, 360 * u.degree), | ||
randomizeCharge=True, | ||
numParticles=2, | ||
), | ||
) | ||
], | ||
outputParticles="particles_input", | ||
randomNumbers=rng, | ||
) | ||
|
||
s.addReader(evGen) | ||
|
||
return evGen | ||
|
||
return _factory | ||
|
||
|
||
@pytest.fixture | ||
def fatras(ptcl_gun, trk_geo, rng): | ||
def _factory(s): | ||
evGen = ptcl_gun(s) | ||
|
||
field = acts.ConstantBField(acts.Vector3(0, 0, 2 * acts.UnitConstants.T)) | ||
simAlg = acts.examples.FatrasSimulation( | ||
level=acts.logging.INFO, | ||
inputParticles=evGen.config.outputParticles, | ||
outputParticlesInitial="particles_initial", | ||
outputParticlesFinal="particles_final", | ||
outputSimHits="simhits", | ||
randomNumbers=rng, | ||
trackingGeometry=trk_geo, | ||
magneticField=field, | ||
generateHitsOnSensitive=True, | ||
) | ||
|
||
s.addAlgorithm(simAlg) | ||
|
||
# Digitization | ||
digiCfg = acts.examples.DigitizationConfig( | ||
acts.examples.readDigiConfigFromJson( | ||
"Examples/Algorithms/Digitization/share/default-smearing-config-generic.json" | ||
), | ||
trackingGeometry=trk_geo, | ||
randomNumbers=rng, | ||
inputSimHits=simAlg.config.outputSimHits, | ||
) | ||
digiAlg = acts.examples.DigitizationAlgorithm(digiCfg, acts.logging.INFO) | ||
|
||
s.addAlgorithm(digiAlg) | ||
|
||
return evGen, simAlg, digiAlg | ||
|
||
return _factory |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import os | ||
from typing import List, Union | ||
|
||
from acts.examples import BareAlgorithm | ||
|
||
try: | ||
import ROOT | ||
|
||
rootEnabled = True | ||
except ImportError: | ||
rootEnabled = False | ||
|
||
if "ROOTSYS" in os.environ: # ROOT seems to be set up, but no PyROOT | ||
import warnings | ||
|
||
warnings.warn( | ||
"ROOT likely built without/with incompatible PyROOT. Skipping tests that need ROOT" | ||
) | ||
|
||
dd4hepEnabled = "DD4hep_DIR" in os.environ | ||
|
||
if dd4hepEnabled: | ||
try: | ||
import acts.examples.dd4hep | ||
except ImportError: | ||
dd4hepEnabled = False | ||
|
||
try: | ||
import acts.examples.hepmc3 | ||
|
||
hepmc3Enabled = True | ||
except ImportError: | ||
hepmc3Enabled = False | ||
|
||
isCI = os.environ.get("CI", "false") == "true" | ||
|
||
|
||
class AssertCollectionExistsAlg(BareAlgorithm): | ||
events_seen = 0 | ||
collections: List[str] | ||
|
||
def __init__( | ||
self, | ||
collections: Union[List[str], str], | ||
name="check_alg", | ||
level=acts.logging.INFO, | ||
*args, | ||
**kwargs, | ||
): | ||
if isinstance(collections, str): | ||
self.collections = [collections] | ||
else: | ||
self.collections = collections | ||
BareAlgorithm.__init__(self, name=name, level=level, *args, **kwargs) | ||
|
||
def execute(self, ctx): | ||
for collection in self.collections: | ||
assert ctx.eventStore.exists(collection), f"{collection} does not exist" | ||
self.events_seen += 1 | ||
return acts.examples.ProcessCode.SUCCESS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import pytest | ||
|
||
import acts | ||
|
||
from acts.examples import ( | ||
TutorialVertexFinderAlgorithm, | ||
AdaptiveMultiVertexFinderAlgorithm, | ||
VertexFitterAlgorithm, | ||
IterativeVertexFinderAlgorithm, | ||
SpacePointMaker, | ||
TrackFindingAlgorithm, | ||
SeedingAlgorithm, | ||
TrackParamsEstimationAlgorithm, | ||
EventGenerator, | ||
FatrasSimulation, | ||
MaterialMapping, | ||
TruthSeedSelector, | ||
TruthTrackFinder, | ||
ParticleSelector, | ||
TruthVertexFinder, | ||
ParticleSmearing, | ||
TrackSelector, | ||
TrackFittingAlgorithm, | ||
SurfaceSortingAlgorithm, | ||
ParticlesPrinter, | ||
HitsPrinter, | ||
TrackParametersPrinter, | ||
PropagationAlgorithm, | ||
DigitizationAlgorithm, | ||
SmearingAlgorithm, | ||
PlanarSteppingAlgorithm, | ||
) | ||
|
||
|
||
from helpers import hepmc3Enabled | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"alg", | ||
[ | ||
TutorialVertexFinderAlgorithm, | ||
AdaptiveMultiVertexFinderAlgorithm, | ||
VertexFitterAlgorithm, | ||
IterativeVertexFinderAlgorithm, | ||
SpacePointMaker, | ||
TrackFindingAlgorithm, | ||
SeedingAlgorithm, | ||
TrackParamsEstimationAlgorithm, | ||
EventGenerator, | ||
FatrasSimulation, | ||
MaterialMapping, | ||
TruthSeedSelector, | ||
TruthTrackFinder, | ||
ParticleSelector, | ||
TruthVertexFinder, | ||
ParticleSmearing, | ||
TrackSelector, | ||
TrackFittingAlgorithm, | ||
SurfaceSortingAlgorithm, | ||
ParticlesPrinter, | ||
HitsPrinter, | ||
TrackParametersPrinter, | ||
PropagationAlgorithm, | ||
# GeantinoRecording, | ||
PlanarSteppingAlgorithm, | ||
# EventRecording, | ||
], | ||
) | ||
def test_algorithm_interface(alg): | ||
assert hasattr(alg, "Config") | ||
|
||
|
||
@pytest.mark.skipif(not hepmc3Enabled, reason="HepMC3 not set up") | ||
def test_hepmc_algorithms(): | ||
from acts.examples.hepmc3 import HepMCProcessExtractor | ||
|
||
assert hasattr(HepMCProcessExtractor, "Config") | ||
|
||
|
||
def test_special_algorithm_interfaces(): | ||
# just assert they exists | ||
assert DigitizationAlgorithm | ||
assert SmearingAlgorithm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import pytest | ||
|
||
import acts | ||
|
||
import acts.examples | ||
|
||
|
||
def test_logging(): | ||
for l in ("VERBOSE", "DEBUG", "INFO", "WARNING", "ERROR", "FATAL"): | ||
assert hasattr(acts.logging, l) | ||
assert hasattr(acts.logging.Level, l) | ||
|
||
|
||
def test_pgd_particle(): | ||
assert len(acts.PdgParticle.__members__) == 16 | ||
|
||
|
||
def test_algebra(): | ||
v3 = acts.Vector3(1, 2, 3) | ||
with pytest.raises(TypeError): | ||
acts.Vector3(1, 2, 3, 4) | ||
with pytest.raises(TypeError): | ||
acts.Vector3(1, 2) | ||
|
||
v3 = acts.Vector3([1, 2, 3]) | ||
with pytest.raises(TypeError): | ||
acts.Vector3([1, 2, 3, 4]) | ||
with pytest.raises(TypeError): | ||
acts.Vector3([1, 2]) | ||
with pytest.raises(TypeError): | ||
acts.Vector3() | ||
|
||
v4 = acts.Vector4(1, 2, 3, 4) | ||
with pytest.raises(TypeError): | ||
v4 = acts.Vector4(1, 2, 3) | ||
v4 = acts.Vector4([1, 2, 3, 4]) | ||
with pytest.raises(TypeError): | ||
acts.Vector4([1, 2, 3]) | ||
with pytest.raises(TypeError): | ||
acts.Vector4() | ||
|
||
|
||
def test_empty_sequencer(conf_const): | ||
s = acts.examples.Sequencer() | ||
with pytest.raises(RuntimeError): | ||
s.run() | ||
|
||
s = conf_const(acts.examples.Sequencer, events=1) | ||
s.run() | ||
|
||
|
||
def test_random_number(): | ||
rnd = acts.examples.RandomNumbers(seed=42) | ||
|
||
|
||
def test_constructors(): | ||
s1 = acts.examples.Sequencer() | ||
print(s1) | ||
s2 = acts.examples.Sequencer() | ||
print(s2) |
Oops, something went wrong.