mirror of
https://github.com/cosmo-sims/cosmICweb-music.git
synced 2024-09-19 16:53:43 +02:00
add tests
This commit is contained in:
parent
d778a14651
commit
893a7e615a
7 changed files with 379 additions and 16 deletions
|
@ -85,7 +85,7 @@ def fetch_ellipsoids(url: str, api_token: str, attempts: int) -> list[Ellipsoid]
|
|||
|
||||
|
||||
def fetch_ellipsoid(
|
||||
url: str, api_token: str, traceback_radius, attempts: int = 3
|
||||
url: str, api_token: str, traceback_radius:float, attempts: int = 3
|
||||
) -> Ellipsoid | None:
|
||||
ellipsoids = fetch_ellipsoids(url, api_token, attempts)
|
||||
if ellipsoids:
|
||||
|
@ -214,6 +214,7 @@ def compose_template(
|
|||
config: DownloadConfig,
|
||||
halo_name: str,
|
||||
halo_id: int,
|
||||
now: datetime = None,
|
||||
) -> str:
|
||||
# TODO: add ellipsoid header (rtb, halo_name, etc)
|
||||
shape_0 = ", ".join(str(e) for e in ellipsoid.shape[0])
|
||||
|
@ -232,15 +233,17 @@ def compose_template(
|
|||
f"region_ellipsoid_center = {center}\n"
|
||||
)
|
||||
template = template.replace("<ELLIPSOID_TEMPLATE>", ellipsoid_lines)
|
||||
if now is None:
|
||||
now = datetime.now()
|
||||
config_header = (
|
||||
f"# Zoom Initial Conditions for halo {halo_id} ({halo_name}) in simulation {config.simulation_name} ({config.project_name} project)\n"
|
||||
f"# Details on this halo can be found on https://cosmicweb.eu/simulation/{config.simulation_name}/halo/{halo_id}\n"
|
||||
f"# This file has been generated by CosmICweb @{datetime.now().isoformat()}\n\n\n"
|
||||
f"# This file has been generated by CosmICweb @{now.isoformat()}\n\n\n"
|
||||
)
|
||||
return config_header + template
|
||||
return config_header + template + "\n"
|
||||
|
||||
|
||||
def write_music_file(output_file, music_config) -> None:
|
||||
def write_music_file(output_file: str, music_config: str) -> None:
|
||||
dirname = os.path.dirname(output_file)
|
||||
if not os.path.exists(dirname):
|
||||
logging.debug("Creating directory {}".format(dirname))
|
||||
|
@ -253,7 +256,7 @@ def call_music() -> None:
|
|||
pass
|
||||
|
||||
|
||||
def process_config(config: DownloadConfig, args: Args) -> None:
|
||||
def process_config(config: DownloadConfig, args: Args, store: bool) -> None:
|
||||
ellipsoids = []
|
||||
for halo_name, url in zip(config.halo_names, config.halo_urls):
|
||||
logging.info("Fetching ellipsoids from halo " + halo_name)
|
||||
|
@ -265,12 +268,12 @@ def process_config(config: DownloadConfig, args: Args) -> None:
|
|||
args.attempts,
|
||||
)
|
||||
)
|
||||
|
||||
# Edit template
|
||||
logging.info("Creating MUSIC template")
|
||||
music_template = music_config_to_template(config)
|
||||
output = []
|
||||
|
||||
if query_yes_no(
|
||||
if store and query_yes_no(
|
||||
"Do you want to edit the MUSIC template before creating the IC files?\n"
|
||||
"(changing zstart, levelmin, levelmax, etc.)",
|
||||
default="no",
|
||||
|
@ -300,22 +303,27 @@ def process_config(config: DownloadConfig, args: Args) -> None:
|
|||
halo_name, output_file
|
||||
)
|
||||
)
|
||||
write_music_file(output_file, music_config)
|
||||
|
||||
if store:
|
||||
write_music_file(output_file, music_config)
|
||||
else:
|
||||
output.append((output_file, music_config))
|
||||
return output
|
||||
# TODO: Execute MUSIC?
|
||||
|
||||
|
||||
def downloadstore_mode(args: Args, target: str) -> None:
|
||||
def downloadstore_mode(args: Args, target: str, store=True) -> None | str:
|
||||
logging.info("Fetching download configuration from the cosmICweb server")
|
||||
config = fetch_downloadstore(args.url, target)
|
||||
if args.output_path == "./":
|
||||
args = args._replace(output_path=f"./cosmICweb-zooms-{config.simulation_name}")
|
||||
logging.debug("Output directory set to " + args.output_path)
|
||||
logging.info("Download configuration successfully fetched")
|
||||
process_config(config, args)
|
||||
return process_config(config, args, store)
|
||||
|
||||
|
||||
def publication_mode(args: Args, publication_name: str, traceback_radius: int) -> None:
|
||||
def publication_mode(
|
||||
args: Args, publication_name: str, traceback_radius, store=True
|
||||
) -> None | str:
|
||||
logging.info(
|
||||
"Fetching publication " + publication_name + " from the cosmICweb server"
|
||||
)
|
||||
|
@ -323,7 +331,7 @@ def publication_mode(args: Args, publication_name: str, traceback_radius: int) -
|
|||
args = args._replace(output_path=os.path.join(args.output_path, publication_name))
|
||||
logging.debug("Output directory set to " + args.output_path)
|
||||
logging.info("Publication successfully fetched")
|
||||
process_config(config, args)
|
||||
return process_config(config, args, store)
|
||||
|
||||
|
||||
def dir_path(p: str) -> str:
|
||||
|
|
|
@ -26,6 +26,13 @@ class Configuration(TypedDict):
|
|||
tracebackRadius: int | float | str
|
||||
|
||||
|
||||
class ICSections(TypedDict):
|
||||
setup: str
|
||||
random: str
|
||||
cosmology: str
|
||||
poisson: str
|
||||
|
||||
|
||||
class DownloadConfig(NamedTuple):
|
||||
simulation_name: str
|
||||
project_name: str
|
||||
|
@ -34,7 +41,7 @@ class DownloadConfig(NamedTuple):
|
|||
halo_urls: List[str]
|
||||
traceback_radius: float
|
||||
api_token: str
|
||||
MUSIC: Dict[str, str]
|
||||
MUSIC: ICSections
|
||||
settings: Configuration | None
|
||||
accessed_at: datetime
|
||||
|
||||
|
@ -42,5 +49,5 @@ class DownloadConfig(NamedTuple):
|
|||
class Args(NamedTuple):
|
||||
url: str
|
||||
output_path: str
|
||||
common_directory: str
|
||||
common_directory: bool
|
||||
attempts: int
|
||||
|
|
86
poetry.lock
generated
86
poetry.lock
generated
|
@ -135,6 +135,20 @@ files = [
|
|||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "exceptiongroup"
|
||||
version = "1.2.1"
|
||||
description = "Backport of PEP 654 (exception groups)"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"},
|
||||
{file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
test = ["pytest (>=6)"]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.7"
|
||||
|
@ -146,6 +160,65 @@ files = [
|
|||
{file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iniconfig"
|
||||
version = "2.0.0"
|
||||
description = "brain-dead simple config-ini parsing"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
|
||||
{file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "24.0"
|
||||
description = "Core utilities for Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"},
|
||||
{file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.4.0"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"},
|
||||
{file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["pre-commit", "tox"]
|
||||
testing = ["pytest", "pytest-benchmark"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "8.1.1"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pytest-8.1.1-py3-none-any.whl", hash = "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7"},
|
||||
{file = "pytest-8.1.1.tar.gz", hash = "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
|
||||
iniconfig = "*"
|
||||
packaging = "*"
|
||||
pluggy = ">=1.4,<2.0"
|
||||
tomli = {version = ">=1", markers = "python_version < \"3.11\""}
|
||||
|
||||
[package.extras]
|
||||
testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.31.0"
|
||||
|
@ -167,6 +240,17 @@ urllib3 = ">=1.21.1,<3"
|
|||
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
|
||||
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "2.0.1"
|
||||
description = "A lil' TOML parser"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
|
||||
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.2.1"
|
||||
|
@ -187,4 +271,4 @@ zstd = ["zstandard (>=0.18.0)"]
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.9"
|
||||
content-hash = "77fb072556c86c1be54da4a6fcada5234ce37943166ee26a3fa19907fedfc8c6"
|
||||
content-hash = "3be6f3b93ec28b49943b98f17c6854993da146534477f47044346a461d868e31"
|
||||
|
|
|
@ -25,6 +25,9 @@ click = "^8.1.7"
|
|||
requests = "^2.31.0"
|
||||
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pytest = "^8.1.1"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
|
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
115
tests/test_config.py
Normal file
115
tests/test_config.py
Normal file
|
@ -0,0 +1,115 @@
|
|||
from datetime import datetime
|
||||
|
||||
from cosmicweb_music.cosmICweb import (
|
||||
apply_config_parameter,
|
||||
music_config_to_template,
|
||||
process_config,
|
||||
DEFAULT_URL,
|
||||
compose_template,
|
||||
)
|
||||
from cosmicweb_music.data_types import DownloadConfig, Args, Ellipsoid
|
||||
|
||||
some_config = """
|
||||
[setup]
|
||||
boxlength = 150
|
||||
zstart = 99
|
||||
levelmin = 8
|
||||
levelmin_TF = 8
|
||||
levelmax = 12
|
||||
padding = 16 # try reduce it at your own risk
|
||||
overlap = 4
|
||||
overlap = 4
|
||||
align_top = no
|
||||
baryons = no # switch on for baryon runs
|
||||
use_2LPT = no
|
||||
use_LLA = no # AMR codes might want to enable this
|
||||
""".strip()
|
||||
|
||||
some_config_modified = """
|
||||
[setup]
|
||||
boxlength = 150
|
||||
zstart = 123
|
||||
levelmin = 8
|
||||
levelmin_TF = 8
|
||||
levelmax = 12
|
||||
padding = 16 # try reduce it at your own risk
|
||||
overlap = 4
|
||||
overlap = 4
|
||||
align_top = no
|
||||
baryons = no # switch on for baryon runs
|
||||
use_2LPT = no
|
||||
use_LLA = no # AMR codes might want to enable this
|
||||
""".strip()
|
||||
|
||||
config = DownloadConfig(
|
||||
simulation_name="test",
|
||||
project_name="project",
|
||||
halo_names=["halo_1"],
|
||||
halo_ids=[1],
|
||||
halo_urls=["..."],
|
||||
traceback_radius=10,
|
||||
api_token="...",
|
||||
MUSIC={"cosmology": "", "poisson": "", "random": "", "setup": ""},
|
||||
settings=None,
|
||||
accessed_at=datetime.now(),
|
||||
)
|
||||
|
||||
args = Args(DEFAULT_URL, ".", False, 1)
|
||||
ellipsoid = Ellipsoid(
|
||||
radius_definition="Rvir",
|
||||
center=[0.42174551551333334, 0.42890526632, 0.27975938776000003],
|
||||
shape=[
|
||||
[872.2886068575001, -31.76815629375, 92.22811563824999],
|
||||
[-31.76815629375, 520.6134379275, 28.34206946775],
|
||||
[92.22811563824999, 28.34206946775, 165.70762251300002],
|
||||
],
|
||||
traceback_radius=10.0,
|
||||
)
|
||||
|
||||
generated_config = """
|
||||
# Zoom Initial Conditions for halo 1 (halo_1) in simulation test (project project)
|
||||
# Details on this halo can be found on https://cosmicweb.eu/simulation/test/halo/1
|
||||
# This file has been generated by CosmICweb @2021-01-01T00:00:00
|
||||
|
||||
|
||||
[setup]
|
||||
|
||||
|
||||
# Ellipsoidal refinement region defined on unity cube
|
||||
# This minimum bounding ellipsoid has been obtained from
|
||||
# particles within 10.0 Rvir of the halo center
|
||||
region = ellipsoid
|
||||
region_ellipsoid_matrix[0] = 872.2886068575001, -31.76815629375, 92.22811563824999
|
||||
region_ellipsoid_matrix[1] = -31.76815629375, 520.6134379275, 28.34206946775
|
||||
region_ellipsoid_matrix[2] = 92.22811563824999, 28.34206946775, 165.70762251300002
|
||||
region_ellipsoid_center = 0.42174551551333334, 0.42890526632, 0.27975938776000003
|
||||
|
||||
|
||||
[cosmology]
|
||||
|
||||
|
||||
[random]
|
||||
|
||||
|
||||
[poisson]
|
||||
|
||||
""".lstrip()
|
||||
|
||||
|
||||
def test_apply_config_parameter_empty():
|
||||
assert apply_config_parameter(some_config, {}) == some_config
|
||||
|
||||
|
||||
def test_apply_config_parameter():
|
||||
params = {"zstart": 123, "doesn't exist": 1}
|
||||
assert apply_config_parameter(some_config, params) == some_config_modified
|
||||
|
||||
|
||||
def test_music_config_to_template():
|
||||
halo_name = "halo_1"
|
||||
halo_id = 1
|
||||
music_template = music_config_to_template(config)
|
||||
music_config = compose_template(
|
||||
music_template, ellipsoid, config, halo_name, halo_id, now=datetime(2021, 1, 1)
|
||||
)
|
||||
assert music_config == generated_config
|
146
tests/test_e2e.py
Normal file
146
tests/test_e2e.py
Normal file
|
@ -0,0 +1,146 @@
|
|||
import re
|
||||
from datetime import datetime
|
||||
|
||||
from cosmicweb_music.cosmICweb import (
|
||||
apply_config_parameter,
|
||||
music_config_to_template,
|
||||
process_config,
|
||||
DEFAULT_URL,
|
||||
compose_template,
|
||||
downloadstore_mode,
|
||||
publication_mode,
|
||||
)
|
||||
from cosmicweb_music.data_types import DownloadConfig, Args, Ellipsoid
|
||||
|
||||
reference_output = """
|
||||
# Zoom Initial Conditions for halo 208416759 (halo_208416759) in simulation 150MPC (CosmOCA project)
|
||||
# Details on this halo can be found on https://cosmicweb.eu/simulation/150MPC/halo/208416759
|
||||
# This file has been generated by CosmICweb @2024-04-20T22:26:13.916577
|
||||
|
||||
|
||||
[setup]
|
||||
boxlength = 150
|
||||
zstart = 99
|
||||
levelmin = 8
|
||||
levelmin_TF = 8
|
||||
levelmax = 12
|
||||
padding = 16 # try reduce it at your own risk
|
||||
overlap = 4
|
||||
align_top = no
|
||||
baryons = no # switch on for baryon runs
|
||||
use_2LPT = no
|
||||
use_LLA = no # AMR codes might want to enable this
|
||||
|
||||
# Ellipsoidal refinement region defined on unity cube
|
||||
# This minimum bounding ellipsoid has been obtained from
|
||||
# particles within 10.0 Rvir of the halo center
|
||||
region = ellipsoid
|
||||
region_ellipsoid_matrix[0] = 872.2886068575001, -31.76815629375, 92.22811563824999
|
||||
region_ellipsoid_matrix[1] = -31.76815629375, 520.6134379275, 28.34206946775
|
||||
region_ellipsoid_matrix[2] = 92.22811563824999, 28.34206946775, 165.70762251300002
|
||||
region_ellipsoid_center = 0.42174551551333334, 0.42890526632, 0.27975938776000003
|
||||
|
||||
|
||||
[cosmology]
|
||||
Omega_m = 0.309
|
||||
Omega_L = 0.691
|
||||
Omega_b = 0.049
|
||||
H0 = 67.74
|
||||
sigma_8 = 0.816
|
||||
nspec = 0.9667
|
||||
transfer = eisenstein
|
||||
|
||||
[random]
|
||||
cubesize = 256
|
||||
seed[9] = 74927
|
||||
seed[10] = 21450
|
||||
|
||||
[poisson]
|
||||
fft_fine = true
|
||||
accuracy = 1e-5
|
||||
grad_order = 4
|
||||
laplace_order = 4
|
||||
""".lstrip()
|
||||
|
||||
reference_output_publication="""
|
||||
# Zoom Initial Conditions for halo 25505622 (1e11v) in simulation AGORA (RHAPSODY project)
|
||||
# Details on this halo can be found on https://cosmicweb.eu/simulation/AGORA/halo/25505622
|
||||
# This file has been generated by CosmICweb @2024-04-21T00:03:24.827918
|
||||
|
||||
|
||||
[setup]
|
||||
boxlength = 60
|
||||
zstart = 100
|
||||
levelmin = 9
|
||||
levelmin_TF = 9
|
||||
levelmax = 9
|
||||
padding = 16 # try reduce it at your own risk
|
||||
overlap = 4
|
||||
align_top = no
|
||||
baryons = no # switch on for baryon runs
|
||||
use_2LPT = no
|
||||
use_LLA = no # AMR codes might want to enable this
|
||||
|
||||
# Ellipsoidal refinement region defined on unity cube
|
||||
# This minimum bounding ellipsoid has been obtained from
|
||||
# particles within 2.0 Rvir of the halo center
|
||||
region = ellipsoid
|
||||
region_ellipsoid_matrix[0] = 1202.685817644, -224.73030332520003, 78.4954201104
|
||||
region_ellipsoid_matrix[1] = -224.73030332520003, 1126.675415484, -514.163771388
|
||||
region_ellipsoid_matrix[2] = 78.4954201104, -514.163771388, 859.827522564
|
||||
region_ellipsoid_center = 0.6253459789833333, 0.47749109738333334, 0.6903304682000001
|
||||
|
||||
|
||||
[cosmology]
|
||||
Omega_m = 0.272
|
||||
Omega_L = 0.728
|
||||
Omega_b = 0.0455
|
||||
H0 = 70.2
|
||||
sigma_8 = 0.807
|
||||
nspec = 0.961
|
||||
transfer = eisenstein
|
||||
#below are MUSIC defaults to initialize gas temperature for some codes
|
||||
#YHe = 0.248 # primordial He abundance
|
||||
#gamma = 1.6667 # adiabatic exponent (=5/3)
|
||||
|
||||
[random]
|
||||
cubesize = 256
|
||||
seed[8] = 95064
|
||||
seed[9] = 31415
|
||||
seed[10] = 27183
|
||||
# do not add higher seeds!
|
||||
|
||||
[poisson]
|
||||
fft_fine = yes
|
||||
accuracy = 1e-6
|
||||
grad_order = 6
|
||||
laplace_order = 6
|
||||
""".lstrip()
|
||||
|
||||
time_fix_regex = re.compile(r"@[\d\-T:.]+")
|
||||
|
||||
|
||||
def test_single_saved():
|
||||
id = "f5399734-ad67-432b-ba4d-61bc2088136a"
|
||||
args = Args(output_path="./", url=DEFAULT_URL, common_directory=True, attempts=1)
|
||||
output = downloadstore_mode(args, id, store=False)
|
||||
assert len(output) == 1
|
||||
output = output[0]
|
||||
assert output[0] == "./cosmICweb-zooms-150MPC/ics_halo_208416759.cfg"
|
||||
|
||||
assert time_fix_regex.sub("TIME", output[1]) == time_fix_regex.sub(
|
||||
"TIME", reference_output
|
||||
)
|
||||
|
||||
|
||||
def test_publication():
|
||||
id = "agora-halos"
|
||||
args = Args(output_path="./", url="http://127.0.0.1:5000", common_directory=True, attempts=1)
|
||||
output = publication_mode(args, id, store=False, traceback_radius=2.0)
|
||||
assert len(output) == 6
|
||||
output = output[0]
|
||||
assert output[0] == "./agora-halos/1e11v/ics.cfg"
|
||||
|
||||
assert time_fix_regex.sub("TIME", output[1]) == time_fix_regex.sub(
|
||||
"TIME", reference_output_publication
|
||||
)
|
Loading…
Reference in a new issue