Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 0.2.2 #24

Merged
merged 10 commits into from
Jun 15, 2023
3 changes: 2 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
dist/** -linguist-detectable
examples/** -linguist-detectable
tests/** -linguist-detectable
xcoll/scattering_routines/k2/FORTRAN_src/** linguist-vendored
dev/** linguist-vendored
duckcoll/scattering_routines/k2/FORTRAN_src/** linguist-vendored
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@

<!---![PyPI - Python Version](https://img.shields.io/pypi/pyversions/xcoll?logo=PyPI?style=plastic) ![PyPI - Wheel](https://img.shields.io/pypi/wheel/xcoll?logo=PyPI?style=plastic)-->

![GitHub release (latest by date)](https://img.shields.io/github/v/release/xsuite/xcoll?style=plastic) ![GitHub](https://img.shields.io/github/license/xsuite/xcoll?style=plastic) ![GitHub all releases](https://img.shields.io/github/downloads/xsuite/xcoll/total?logo=GitHub&style=plastic) ![GitHub issues](https://img.shields.io/github/issues/xsuite/xcoll?logo=GitHub&style=plastic) ![GitHub pull requests](https://img.shields.io/github/issues-pr/xsuite/xcoll?logo=GitHub&style=plastic) ![GitHub repo size](https://img.shields.io/github/repo-size/xsuite/xcoll?logo=GitHub&style=plastic)
![GitHub release (latest by date)](https://img.shields.io/github/v/release/xsuite/xcoll?style=plastic)
![GitHub](https://img.shields.io/github/license/xsuite/xcoll?style=plastic)
![PyPi](https://img.shields.io/pypi/dm/xcoll?logo=PyPI&style=plastic)
![GitHub all releases](https://img.shields.io/github/downloads/xsuite/xcoll/total?logo=GitHub&style=plastic)

![GitHub pull requests](https://img.shields.io/github/issues-pr/xsuite/xcoll?logo=GitHub&style=plastic)
![GitHub issues](https://img.shields.io/github/issues/xsuite/xcoll?logo=GitHub&style=plastic)
![GitHub repo size](https://img.shields.io/github/repo-size/xsuite/xcoll?logo=GitHub&style=plastic)

Collimation in xtrack simulations

Expand Down
23 changes: 14 additions & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "xcoll"
version = "0.2.1"
version = "0.2.2"
description = "Xsuite collimation package"
homepage = "https://github.com/xsuite/xcoll"
repository = "https://github.com/xsuite/xcoll"
Expand All @@ -17,16 +17,21 @@ include = [ "LICENSE", "NOTICE" ]

[tool.poetry.dependencies]
python = ">=3.8"
#numpy
#pandas
#scipy
#xobjects
#xdeps
#xpart
#xtrack
ruamel-yaml = { version = "^0.17.31", optional = true }
numpy = ">=1.0"
pandas = ">=1.4"
xobjects = "^0.2.6"
xdeps = "^0.1.1"
xpart = "^0.15.0"
xtrack = "^0.36.5"
xfields = "^0.12.1"
xcoll = "^0.2.1"

[tool.poetry.dev-dependencies]
pytest = "^5.2"
pytest = ">=7.3"

[tool.poetry.extras]
tests = ["pytest", "ruamel-yaml"]

[build-system]
# Needed for pip install -e (BTW: need pip version 22)
Expand Down
14 changes: 9 additions & 5 deletions tests/test_black_absorber.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def test_horizontal_parallel(test_context):
jaw_L, jaw_R, _, _, cox, _, L, coll = _make_absorber(_context=test_context)
part, x, _, _, _ = _generate_particles(_context=test_context)
coll.track(part)
part.move(_context=xo.ContextCpu())
part.sort(interleave_lost_particles=True)
# As the angles are zero, only particles that started in front of the jaw are lost
mask_hit = (x >= jaw_L + cox) | (x <= jaw_R + cox)
Expand All @@ -32,6 +33,7 @@ def test_horizontal(test_context):
jaw_L, jaw_R, _, _, cox, _, L, coll = _make_absorber(_context=test_context)
part, x, _, xp, _ = _generate_particles(four_dim=True, _context=test_context)
coll.track(part)
part.move(_context=xo.ContextCpu())
part.sort(interleave_lost_particles=True)
# Particles in front of the jaw are lost, ...
mask_hit_front = (x >= jaw_L + cox) | (x <= jaw_R + cox)
Expand Down Expand Up @@ -62,6 +64,7 @@ def test_horizontal_with_tilts(test_context):
jaw_L, jaw_R, jaw_LD, jaw_RD, cox, _, L, coll = _make_absorber(tilts=[0.0005, -0.00015], _context=test_context)
part, x, _, xp, _ = _generate_particles(four_dim=True, _context=test_context)
coll.track(part)
part.move(_context=xo.ContextCpu())
part.sort(interleave_lost_particles=True)
# Particles in front of the jaw are lost, ...
mask_hit_front = (x >= jaw_L + cox) | (x <= jaw_R + cox)
Expand Down Expand Up @@ -92,6 +95,7 @@ def test_vertical_parallel(test_context):
jaw_L, jaw_R, _, _, _, coy, L, coll = _make_absorber(angle=90, _context=test_context)
part, _, y, _, _ = _generate_particles(_context=test_context)
coll.track(part)
part.move(_context=xo.ContextCpu())
part.sort(interleave_lost_particles=True)
# As the angles are zero, only particles that started in front of the jaw are lost
mask_hit = (y >= jaw_L + coy) | (y <= jaw_R + coy)
Expand All @@ -111,6 +115,7 @@ def test_vertical(test_context):
jaw_L, jaw_R, _, _, _, coy, L, coll = _make_absorber(angle=90, _context=test_context)
part, _, y, _, yp = _generate_particles(four_dim=True, _context=test_context)
coll.track(part)
part.move(_context=xo.ContextCpu())
part.sort(interleave_lost_particles=True)
# Particles in front of the jaw are lost, ...
mask_hit_front = (y >= jaw_L + coy) | (y <= jaw_R + coy)
Expand Down Expand Up @@ -141,6 +146,7 @@ def test_vertical_with_tilts(test_context):
jaw_L, jaw_R, jaw_LD, jaw_RD, _, coy, L, coll = _make_absorber(angle=90, tilts=[0.0005, -0.00015], _context=test_context)
part, _, y, _, yp = _generate_particles(four_dim=True, _context=test_context)
coll.track(part)
part.move(_context=xo.ContextCpu())
part.sort(interleave_lost_particles=True)
# Particles in front of the jaw are lost, ...
mask_hit_front = (y >= jaw_L + coy) | (y <= jaw_R + coy)
Expand Down Expand Up @@ -172,6 +178,7 @@ def test_angled_parallel(test_context):
jaw_L, jaw_R, _, _, cox, _, L, coll = _make_absorber(angle=angle, rotate_co=True, _context=test_context)
part, x, _, _, _ = _generate_particles(angle=angle, _context=test_context)
coll.track(part)
part.move(_context=xo.ContextCpu())
part.sort(interleave_lost_particles=True)
# As the angles are zero, only particles that started in front of the jaw are lost
mask_hit = (x >= jaw_L + cox) | (x <= jaw_R + cox)
Expand All @@ -193,6 +200,7 @@ def test_angled(test_context):
jaw_L, jaw_R, _, _, cox, _, L, coll = _make_absorber(angle=angle, rotate_co=True, _context=test_context)
part, x, _, xp, _ = _generate_particles(four_dim=True, angle=angle, _context=test_context)
coll.track(part)
part.move(_context=xo.ContextCpu())
part.sort(interleave_lost_particles=True)
# Particles in front of the jaw are lost, ...
mask_hit_front = (x >= jaw_L + cox) | (x <= jaw_R + cox)
Expand Down Expand Up @@ -225,6 +233,7 @@ def test_angled_with_tilts(test_context):
jaw_L, jaw_R, jaw_LD, jaw_RD, cox, _, L, coll = _make_absorber(angle=angle, tilts=[0.0005, -0.00015], rotate_co=True, _context=test_context)
part, x, _, xp, _ = _generate_particles(four_dim=True,angle=angle, _context=test_context)
coll.track(part)
part.move(_context=xo.ContextCpu())
part.sort(interleave_lost_particles=True)
# Particles in front of the jaw are lost, ...
mask_hit_front = (x >= jaw_L + cox) | (x <= jaw_R + cox)
Expand All @@ -251,8 +260,6 @@ def test_angled_with_tilts(test_context):
assert np.allclose(part_x_rot[mask_hit_angle_R], jaw_R + cox + (jaw_RD-jaw_R)/L*s_hit_R, atol=1e-15, rtol=0)




def _make_absorber(angle=0, tilts=[0,0], rotate_co=False, _context=None):
if _context is None:
_context = xo.ContextCpu()
Expand Down Expand Up @@ -291,6 +298,3 @@ def _generate_particles(four_dim=False, angle=0, _context=None):
xp_rot = part_init.px * part_init.rpp * np.cos(angle/180.*np.pi) + part_init.py * part_init.rpp * np.sin(angle/180.*np.pi)
yp_rot = part_init.px * part_init.rpp * np.sin(angle/180.*np.pi) + part_init.py * part_init.rpp * np.cos(angle/180.*np.pi)
return part, x_rot, y_rot, xp_rot, yp_rot



2 changes: 1 addition & 1 deletion tests/test_colldb.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import xcoll as xc


path = Path.cwd() / 'data'
path = Path(__file__).parent / 'data'


def test_loading():
Expand Down
8 changes: 6 additions & 2 deletions tests/test_collimator_elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,9 @@ def test_black_absorber_length_instantiation(test_context):
elem = xc.BlackAbsorber(length=1.1, active_length=0.5, inactive_front=0.4, inactive_back=0.2, _context=test_context)


@for_all_test_contexts
@for_all_test_contexts(
excluding=('ContextCupy', 'ContextPyopencl') # Rutherford RNG not on GPU
)
def test_everest(test_context):
# Test instantiation
elem = xc.EverestCollimator(length=1, material=xc.materials.Carbon, _context=test_context)
Expand Down Expand Up @@ -287,7 +289,9 @@ def test_everest(test_context):
setattr(elem, field, 0.3)


@for_all_test_contexts
@for_all_test_contexts(
excluding=('ContextCupy', 'ContextPyopencl') # Rutherford RNG not on GPU
)
def test_everest_crystal(test_context):
# Test instantiation
elem = xc.EverestCrystal(length=1, material=xc.materials.SiliconCrystal, _context=test_context)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_everest.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
]


path = Path('./data_test_everest/')
path = Path(__file__).parent / 'data_test_everest'

def test_primaries():
_track_collimator('tcp.c6l7.b1')
Expand Down Expand Up @@ -124,7 +124,7 @@ def test_crystals():
_track_collimator(name)


def _track_collimator(name, atolx=1e-11, atoly=1e-11, atolpx=1e-11, atolpy=1e-11, atolz=1e-11, atold=1e-10):
def _track_collimator(name, atolx=3e-9, atoly=3e-10, atolpx=5e-9, atolpy=2e-9, atolz=1e-11, atold=2e-8):
with open(Path(path, 'initial.json'), 'r') as fid:
part = xp.Particles.from_dict(json.load(fid))
with open(Path(path, 'Collimators', name+'.json'), 'r') as fid:
Expand Down
21 changes: 3 additions & 18 deletions tests/test_lossmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
import pytest
from xpart.test_helpers import flaky_assertions, retry

path = Path.cwd() / 'data'
path = Path(__file__).parent / 'data'

# https://github.com/xsuite/xtrack/blob/18b1ac33d6a9d87a156e87bfb71cb2c8011085f6/tests/test_radiation.py#LL138C5-L138C29
@retry
@retry()
@pytest.mark.parametrize("beam, plane, npart, interpolation, ignore_crystals", [
[1, 'H', 25000, 0.2, True],
[2, 'V', 25000, 0.3, True],
Expand All @@ -36,7 +36,7 @@ def test_run_lossmap(beam, plane, npart, interpolation, ignore_crystals):
with flaky_assertions():
summ = coll_manager.summary(part, show_zeros=False)
assert list(summ.columns) == ['collname', 'nabs', 'length', 's', 'type']
assert len(summ) == 10
assert len(summ[summ.type=='EverestCollimator']) == 10
# We want at least 5% absorption on the primary
assert summ.loc[summ.collname==tcp,'nabs'].values[0] > 0.05*npart

Expand All @@ -63,21 +63,6 @@ def test_run_lossmap(beam, plane, npart, interpolation, ignore_crystals):
assert lm['reversed'] == line_is_reversed


# @retry
# def test_lossmap_B1H():
# _run_lossmap(1, 'H', 25000, 0.2)


# def test_lossmap_B2V():
# _run_lossmap(2, 'V', 25000, 0.3)


# def test_lossmap_crystals_B1V():
# _run_lossmap(1, 'V', 35000, 0.1, ignore_crystals=False)

# def test_lossmap_crystals_B2H():
# _run_lossmap(2, 'H', 30000, 0.15, ignore_crystals=False)



# def test_off_momentum_lossmap():
Expand Down
2 changes: 1 addition & 1 deletion tests/test_version.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from xcoll import __version__

def test_version():
assert __version__ == '0.2.1'
assert __version__ == '0.2.2'

1 change: 1 addition & 0 deletions version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ git switch main
git pull
PR=$( gh pr list --head $branch | tail -1 | awk '{print $1;}' )
gh pr merge ${PR} --merge --admin --delete-branch
git pull

# Make a tag
git tag v${new_ver}
Expand Down
2 changes: 1 addition & 1 deletion xcoll/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
from .manager import CollimatorManager
from .colldb import CollimatorDatabase, load_SixTrack_colldb

__version__ = '0.2.1'
__version__ = '0.2.2'
2 changes: 1 addition & 1 deletion xcoll/beam_elements/collimators_src/absorber.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void BlackAbsorber_track_local_particle(BlackAbsorberData el, LocalParticle* par
double const cos_zL = BlackAbsorberData_get_cos_zL(el);
double const sin_zR = BlackAbsorberData_get_sin_zR(el);
double const cos_zR = BlackAbsorberData_get_cos_zR(el);
if (abs(sin_zL-sin_zR) > 1.e-10 || abs(cos_zL-cos_zR) > 1.e-10 ){
if (fabs(sin_zL-sin_zR) > 1.e-10 || fabs(cos_zL-cos_zR) > 1.e-10 ){
kill_all_particles(part0, XC_ERR_NOT_IMPLEMENTED);
};
double const dx = BlackAbsorberData_get_ref_x(el);
Expand Down
2 changes: 1 addition & 1 deletion xcoll/beam_elements/collimators_src/everest_collimator.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void EverestCollimator_track_local_particle(EverestCollimatorData el, LocalParti
double const cos_zL = EverestCollimatorData_get_cos_zL(el);
double const sin_zR = EverestCollimatorData_get_sin_zR(el);
double const cos_zR = EverestCollimatorData_get_cos_zR(el);
if (abs(sin_zL-sin_zR) > 1.e-10 || abs(cos_zL-cos_zR) > 1.e-10 ){
if (fabs(sin_zL-sin_zR) > 1.e-10 || fabs(cos_zL-cos_zR) > 1.e-10 ){
kill_all_particles(part0, XC_ERR_NOT_IMPLEMENTED);
};
double const c_aperture = EverestCollimatorData_get_jaw_L(el) - EverestCollimatorData_get_jaw_R(el);
Expand Down
4 changes: 2 additions & 2 deletions xcoll/beam_elements/collimators_src/everest_crystal.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ void EverestCrystal_track_local_particle(EverestCrystalData el, LocalParticle* p
double const cos_zL = EverestCrystalData_get_cos_zL(el);
double const sin_zR = EverestCrystalData_get_sin_zR(el);
double const cos_zR = EverestCrystalData_get_cos_zR(el);
if (abs(sin_zL-sin_zR) > 1.e-10 || abs(cos_zL-cos_zR) > 1.e-10 ){
if (fabs(sin_zL-sin_zR) > 1.e-10 || fabs(cos_zL-cos_zR) > 1.e-10 ){
kill_all_particles(part0, XC_ERR_NOT_IMPLEMENTED);
};
double const c_aperture = EverestCrystalData_get_jaw_L(el) - EverestCrystalData_get_jaw_R(el);
double const c_offset = ( EverestCrystalData_get_jaw_L(el) + EverestCrystalData_get_jaw_R(el) ) /2;
double const c_tilt0 = asin(EverestCrystalData_get_sin_yL(el));
double const c_tilt1 = asin(EverestCrystalData_get_sin_yR(el));
if (abs(c_tilt1) > 1.e-10){
if (fabs(c_tilt1) > 1.e-10){
kill_all_particles(part0, XC_ERR_INVALID_XOFIELD);
};
int const side = EverestCrystalData_get__side(el);
Expand Down