Skip to content

Commit 08b0462

Browse files
committed
clipy: reworked installed/checker
1 parent ee048c7 commit 08b0462

File tree

2 files changed

+118
-119
lines changed

2 files changed

+118
-119
lines changed

cobaya/install.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ def _imported_class():
468468
bullet + bullet.join(obsolete_components),
469469
)
470470
if incompatible_components:
471-
logger.info(
471+
logger.warning(
472472
"The following components were skipped because they are not compatible "
473473
"with your OS: %s",
474474
bullet + bullet.join(incompatible_components),

cobaya/likelihoods/base_classes/planck_clik.py

Lines changed: 117 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,33 @@
44
:Synopsis: Definition of the clik-based likelihoods using clipy
55
:Author: Jesus Torrado (initially based on MontePython's version
66
by Julien Lesgourgues and Benjamin Audren)
7-
Updated to use clipy by Antony Lewis
7+
Updated to use clipy by Antony Lewis and Jesus Torrado
88
99
"""
1010

1111
import os
1212

1313
import numpy as np
14-
from packaging import version
1514

1615
from cobaya.component import ComponentNotInstalledError, load_external_module
1716
from cobaya.input import get_default_info
18-
from cobaya.install import download_file, pip_install
17+
from cobaya.install import download_github_release, pip_install
1918
from cobaya.likelihood import Likelihood
2019
from cobaya.log import LoggedError, get_logger
21-
from cobaya.tools import (
22-
VersionCheckError,
23-
are_different_params_lists,
24-
create_banner,
25-
)
2620

2721
_deprecation_msg_2015 = create_banner("""
2822
The likelihoods from the Planck 2015 data release have been superseded
2923
by the 2018 ones, and will eventually be deprecated.
3024
""")
25+
from cobaya.tools import VersionCheckError, are_different_params_lists
3126

3227
pla_url_prefix = r"https://pla.esac.esa.int/pla-sl/data-action?COSMOLOGY.COSMOLOGY_OID="
33-
clipy_url = "https://github.com/benabed/clipy/archive/refs/heads/main.zip"
28+
29+
# Clipy installation
30+
clipy_repo_name = "benabed/clipy"
31+
clipy_repo_min_version = "0.15"
3432

3533
last_version_supp_data_and_covmats = "v2.1"
36-
min_version_clipy = "0.11"
3734

3835

3936
class PlanckClik(Likelihood):
@@ -47,6 +44,7 @@ def initialize(self):
4744
if "2015" in self.get_name():
4845
for line in _deprecation_msg_2015.split("\n"):
4946
self.log.warning(line)
47+
msg_to_install = "run `cobaya-install planck_2018_highl_plik.TTTEEE`"
5048
try:
5149
install_path = (lambda p: self.get_code_path(p) if p else None)(
5250
self.packages_path
@@ -61,11 +59,13 @@ def initialize(self):
6159
except ComponentNotInstalledError as excpt:
6260
raise ComponentNotInstalledError(
6361
self.log,
64-
(
65-
f"Could not find clipy: {excpt}. To install it, "
66-
f"run `cobaya-install planck_2018_highl_plik.TTTEEE`"
67-
),
68-
)
62+
f"Could not find clipy: {excpt}. To install it, {msg_to_install}",
63+
) from excpt
64+
except VersionCheckError as excpt:
65+
raise VersionCheckError(
66+
self.log,
67+
f"{excpt}. To install a new version, {msg_to_install} with `--upgrade`.",
68+
) from excpt
6969
# Loading the likelihood data
7070
data_path = get_data_path(self.__class__.get_qualified_class_name())
7171
if not os.path.isabs(self.clik_file):
@@ -80,7 +80,7 @@ def initialize(self):
8080
# Disable JAX to avoid dependency issues
8181
os.environ["CLIPY_NOJAX"] = "1"
8282
self.clik = clik.clik(self.clik_file)
83-
except Exception:
83+
except Exception as excpt:
8484
# Is it that the file was not found?
8585
if not os.path.exists(self.clik_file):
8686
raise ComponentNotInstalledError(
@@ -90,7 +90,7 @@ def initialize(self):
9090
"Maybe the 'path' given is not correct? The full path where"
9191
" the .clik file was searched for is '%s'",
9292
self.clik_file,
93-
)
93+
) from excpt
9494
# Else: unknown clipy error
9595
self.log.error(
9696
"An unexpected error occurred in clipy (possibly related to "
@@ -217,11 +217,11 @@ def install(
217217
**_kwargs,
218218
):
219219
name = cls.get_qualified_class_name()
220-
log = get_logger(name)
220+
logger = get_logger(name)
221221
path_names = {"code": common_path, "data": get_data_path(name)}
222222
global _clipy_install_failed
223223
if _clipy_install_failed:
224-
log.info("Previous clipy install failed, skipping")
224+
logger.info("Previous clipy install failed, skipping")
225225
return False
226226
# Create common folders: all planck likelihoods share install
227227
# folder for code and data
@@ -233,19 +233,18 @@ def install(
233233
os.makedirs(paths[s])
234234
success = True
235235
# Install clipy to packages path (don't rely on global installation)
236-
if code:
237-
# Check if clipy is installed in the packages path specifically
238-
clipy_path = os.path.join(paths["code"], "clipy")
239-
if not os.path.exists(clipy_path) or force:
240-
log.info("Installing clipy.")
241-
success *= install_clipy(paths["code"], no_progress_bars=no_progress_bars)
242-
if not success:
243-
log.warning("clipy installation failed!")
244-
_clipy_install_failed = True
236+
if code and (not is_installed_clipy(paths["code"], logger=logger) or force):
237+
logger.info("Installing clipy.")
238+
success *= install_clipy(
239+
paths["code"], no_progress_bars=no_progress_bars, logger=logger
240+
)
241+
if not success:
242+
logger.warning("clipy installation failed!")
243+
_clipy_install_failed = True
245244
if data:
246245
# 2nd test, in case the code wasn't there but the data is:
247246
if force or not cls.is_installed(path=path, code=False, data=True):
248-
log.info("Downloading the likelihood data.")
247+
logger.info("Downloading the likelihood data.")
249248
product_id, _ = get_product_id_and_clik_file(name)
250249
# Download and decompress the particular likelihood
251250
url = pla_url_prefix + product_id
@@ -264,10 +263,10 @@ def install(
264263
url,
265264
paths["data"],
266265
size=size,
267-
logger=log,
266+
logger=logger,
268267
no_progress_bars=no_progress_bars,
269268
):
270-
log.error("Not possible to download this likelihood.")
269+
logger.error("Not possible to download this likelihood.")
271270
success = False
272271
# Additional data and covmats, stored in same repo as the
273272
# 2018 python lensing likelihood
@@ -311,12 +310,10 @@ def get_clipy_import_path(path):
311310
clipy_path = os.path.join(path, "clipy")
312311
if not os.path.exists(clipy_path):
313312
raise FileNotFoundError(f"clipy installation not found at {clipy_path}")
314-
315313
# Check if it has the proper structure
316314
init_file = os.path.join(clipy_path, "clipy", "__init__.py")
317315
if not os.path.exists(init_file):
318316
raise FileNotFoundError(f"clipy package structure not found at {clipy_path}")
319-
320317
return clipy_path
321318

322319

@@ -326,53 +323,75 @@ def load_clipy(
326323
logger=None,
327324
not_installed_level="error",
328325
reload=False,
329-
default_global=True,
326+
default_global=False,
330327
):
331328
"""
332329
Load clipy module and check that it's the correct one.
330+
331+
Returns
332+
-------
333+
clipy: module
334+
The imported clipy module
335+
336+
Raises
337+
------
338+
ComponentNotInstalledError
339+
If clipy has not been installed
340+
VersionCheckError
341+
If clipy is found, but with a smaller version number.
333342
"""
334-
try:
335-
clipy = load_external_module(
336-
module_name="clipy",
337-
path=path,
338-
install_path=install_path,
339-
get_import_path=get_clipy_import_path if install_path else None,
340-
logger=logger,
341-
not_installed_level=not_installed_level,
342-
reload=reload,
343-
default_global=default_global,
344-
)
345-
# Check that it has the expected clipy interface
346-
if not hasattr(clipy, "clik"):
347-
raise ComponentNotInstalledError(
348-
logger, "Loaded wrong clipy: missing clik class"
349-
)
350-
# Check version if possible
351-
if hasattr(clipy, "__version__"):
352-
installed_version = version.parse(clipy.__version__)
353-
if installed_version < version.parse(min_version_clipy):
354-
raise VersionCheckError(
355-
f"Installed version of clipy ({installed_version}) "
356-
f"older than minimum required one ({min_version_clipy})."
357-
)
358-
return clipy
359-
except ImportError:
343+
if logger is None:
344+
logger = get_logger("clipy")
345+
clipy = load_external_module(
346+
module_name="clipy",
347+
path=path,
348+
install_path=install_path,
349+
get_import_path=get_clipy_import_path if install_path else None,
350+
min_version=clipy_repo_min_version,
351+
logger=logger,
352+
not_installed_level=not_installed_level,
353+
reload=reload,
354+
default_global=default_global,
355+
)
356+
# Check that it has the expected clipy interface
357+
if not hasattr(clipy, "clik"):
360358
raise ComponentNotInstalledError(
361359
logger,
362-
"clipy not installed. Install with: cobaya-install planck_2018_highl_plik.TTTEEE",
360+
"Loaded wrong clipy: you may have pip-installed 'clipy' instead of "
361+
"'clipy-like'.",
363362
)
363+
return clipy
364364

365365

366-
def is_installed_clipy(path=None, reload=False):
366+
def is_installed_clipy(path=None, reload=False, logger=None):
367367
"""
368-
Check if clipy is installed and working in the specified path.
368+
Check if clipy is installed and working in the specified path. It should not raise any
369+
exception.
370+
371+
Parameters
372+
----------
373+
path: str, optional
374+
Path where the clipy installation is tested, to which ``clipy`` will be appended
375+
before testing. If not defined, a test for a global python installation will be
376+
performed instead (``default_global=True`` will be passed to the module loader).
377+
reload: bool
378+
Whether to attemp to reload the ``clipy`` module before checking.
379+
logger: logging.Logger, optional
380+
Initialized logger. If note passed, one named ``clipy`` will be created.
381+
382+
Returns
383+
-------
384+
bool
385+
``True`` if the installation was successful, and ``False`` otherwise.
369386
"""
387+
if logger is None:
388+
logger = get_logger("clipy")
370389
try:
371390
# If path is specified, don't fall back to global import
372391
default_global = path is None
373392
load_clipy(
374-
install_path=path,
375-
logger=get_logger("clipy"),
393+
path=os.path.join(path, "clipy"),
394+
logger=logger,
376395
not_installed_level="debug",
377396
reload=reload,
378397
default_global=default_global,
@@ -382,67 +401,47 @@ def is_installed_clipy(path=None, reload=False):
382401
return False
383402

384403

385-
def install_clipy(path, no_progress_bars=False):
404+
def install_clipy(path, logger=None, no_progress_bars=False):
386405
"""
387406
Install clipy from GitHub repository to the specified path.
388-
"""
389-
log = get_logger("clipy")
390-
log.info("Installing clipy from GitHub repository...")
391407
408+
Parameters
409+
----------
410+
path: str
411+
Path where clipy will be downloaded into, to which ``clipy`` will be appended.
412+
413+
logger: logging.Logger, optional
414+
Initialized logger. If note passed, one named ``clipy`` will be created.
415+
416+
no_progress_bars: bool
417+
Whether to show download/install progress bars.
418+
419+
Returns
420+
-------
421+
bool
422+
``True`` if the installation was successful, and ``False`` otherwise.
423+
"""
424+
if logger is None:
425+
logger = get_logger("clipy")
392426
# Install pre-requisites
393-
log.info("Installing pre-requisites...")
394-
for req in ("numpy", "astropy"):
427+
logger.info("Installing pre-requisites...")
428+
for req in ("astropy",):
395429
exit_status = pip_install(req)
396430
if exit_status:
397-
log.error("Failed installing '%s'.", req)
431+
logger.error("Failed installing '%s'.", req)
398432
return False
399-
400-
# Download clipy from GitHub
401-
log.info("Downloading clipy...")
402-
if not download_file(clipy_url, path, no_progress_bars=no_progress_bars, logger=log):
403-
log.error("Not possible to download clipy.")
433+
logger.info("Installing clipy from GitHub repository...")
434+
success = download_github_release(
435+
path,
436+
clipy_repo_name,
437+
"clipy_" + clipy_repo_min_version, # TODO: check if "clipy_" still in release
438+
no_progress_bars=no_progress_bars,
439+
logger=logger,
440+
)
441+
if not success:
442+
logger.error("Could not download clipy from GitHub.")
404443
return False
405-
406-
# Extract and move clipy to the correct location
407-
import shutil
408-
import zipfile
409-
410-
# The download_file function may name the file differently
411-
zip_files = [os.path.join(path, "main.zip"), os.path.join(path, "clipy-main.zip")]
412-
413-
zip_file = None
414-
for potential_zip in zip_files:
415-
if os.path.exists(potential_zip):
416-
zip_file = potential_zip
417-
break
418-
419-
if zip_file:
420-
with zipfile.ZipFile(zip_file, "r") as zip_ref:
421-
zip_ref.extractall(path)
422-
# Move clipy-main to clipy
423-
clipy_main_path = os.path.join(path, "clipy-main")
424-
clipy_path = os.path.join(path, "clipy")
425-
if os.path.exists(clipy_main_path):
426-
if os.path.exists(clipy_path):
427-
shutil.rmtree(clipy_path)
428-
shutil.move(clipy_main_path, clipy_path)
429-
# Clean up zip file
430-
os.remove(zip_file)
431-
else:
432-
# If no zip file found, check if clipy-main directory already exists
433-
clipy_main_path = os.path.join(path, "clipy-main")
434-
clipy_path = os.path.join(path, "clipy")
435-
if os.path.exists(clipy_main_path):
436-
if os.path.exists(clipy_path):
437-
shutil.rmtree(clipy_path)
438-
shutil.move(clipy_main_path, clipy_path)
439-
440-
# Verify installation
441-
if not is_installed_clipy(path):
442-
log.error("clipy installation verification failed.")
443-
return False
444-
445-
log.info("clipy installation finished!")
444+
logger.info("clipy installation finished!")
446445
return True
447446

448447

0 commit comments

Comments
 (0)