4
4
:Synopsis: Definition of the clik-based likelihoods using clipy
5
5
:Author: Jesus Torrado (initially based on MontePython's version
6
6
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
8
8
9
9
"""
10
10
11
11
import os
12
12
13
13
import numpy as np
14
- from packaging import version
15
14
16
15
from cobaya .component import ComponentNotInstalledError , load_external_module
17
16
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
19
18
from cobaya .likelihood import Likelihood
20
19
from cobaya .log import LoggedError , get_logger
21
- from cobaya .tools import (
22
- VersionCheckError ,
23
- are_different_params_lists ,
24
- create_banner ,
25
- )
26
20
27
21
_deprecation_msg_2015 = create_banner ("""
28
22
The likelihoods from the Planck 2015 data release have been superseded
29
23
by the 2018 ones, and will eventually be deprecated.
30
24
""" )
25
+ from cobaya .tools import VersionCheckError , are_different_params_lists
31
26
32
27
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"
34
32
35
33
last_version_supp_data_and_covmats = "v2.1"
36
- min_version_clipy = "0.11"
37
34
38
35
39
36
class PlanckClik (Likelihood ):
@@ -47,6 +44,7 @@ def initialize(self):
47
44
if "2015" in self .get_name ():
48
45
for line in _deprecation_msg_2015 .split ("\n " ):
49
46
self .log .warning (line )
47
+ msg_to_install = "run `cobaya-install planck_2018_highl_plik.TTTEEE`"
50
48
try :
51
49
install_path = (lambda p : self .get_code_path (p ) if p else None )(
52
50
self .packages_path
@@ -61,11 +59,13 @@ def initialize(self):
61
59
except ComponentNotInstalledError as excpt :
62
60
raise ComponentNotInstalledError (
63
61
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
69
69
# Loading the likelihood data
70
70
data_path = get_data_path (self .__class__ .get_qualified_class_name ())
71
71
if not os .path .isabs (self .clik_file ):
@@ -80,7 +80,7 @@ def initialize(self):
80
80
# Disable JAX to avoid dependency issues
81
81
os .environ ["CLIPY_NOJAX" ] = "1"
82
82
self .clik = clik .clik (self .clik_file )
83
- except Exception :
83
+ except Exception as excpt :
84
84
# Is it that the file was not found?
85
85
if not os .path .exists (self .clik_file ):
86
86
raise ComponentNotInstalledError (
@@ -90,7 +90,7 @@ def initialize(self):
90
90
"Maybe the 'path' given is not correct? The full path where"
91
91
" the .clik file was searched for is '%s'" ,
92
92
self .clik_file ,
93
- )
93
+ ) from excpt
94
94
# Else: unknown clipy error
95
95
self .log .error (
96
96
"An unexpected error occurred in clipy (possibly related to "
@@ -217,11 +217,11 @@ def install(
217
217
** _kwargs ,
218
218
):
219
219
name = cls .get_qualified_class_name ()
220
- log = get_logger (name )
220
+ logger = get_logger (name )
221
221
path_names = {"code" : common_path , "data" : get_data_path (name )}
222
222
global _clipy_install_failed
223
223
if _clipy_install_failed :
224
- log .info ("Previous clipy install failed, skipping" )
224
+ logger .info ("Previous clipy install failed, skipping" )
225
225
return False
226
226
# Create common folders: all planck likelihoods share install
227
227
# folder for code and data
@@ -233,19 +233,18 @@ def install(
233
233
os .makedirs (paths [s ])
234
234
success = True
235
235
# 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
245
244
if data :
246
245
# 2nd test, in case the code wasn't there but the data is:
247
246
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." )
249
248
product_id , _ = get_product_id_and_clik_file (name )
250
249
# Download and decompress the particular likelihood
251
250
url = pla_url_prefix + product_id
@@ -264,10 +263,10 @@ def install(
264
263
url ,
265
264
paths ["data" ],
266
265
size = size ,
267
- logger = log ,
266
+ logger = logger ,
268
267
no_progress_bars = no_progress_bars ,
269
268
):
270
- log .error ("Not possible to download this likelihood." )
269
+ logger .error ("Not possible to download this likelihood." )
271
270
success = False
272
271
# Additional data and covmats, stored in same repo as the
273
272
# 2018 python lensing likelihood
@@ -311,12 +310,10 @@ def get_clipy_import_path(path):
311
310
clipy_path = os .path .join (path , "clipy" )
312
311
if not os .path .exists (clipy_path ):
313
312
raise FileNotFoundError (f"clipy installation not found at { clipy_path } " )
314
-
315
313
# Check if it has the proper structure
316
314
init_file = os .path .join (clipy_path , "clipy" , "__init__.py" )
317
315
if not os .path .exists (init_file ):
318
316
raise FileNotFoundError (f"clipy package structure not found at { clipy_path } " )
319
-
320
317
return clipy_path
321
318
322
319
@@ -326,53 +323,75 @@ def load_clipy(
326
323
logger = None ,
327
324
not_installed_level = "error" ,
328
325
reload = False ,
329
- default_global = True ,
326
+ default_global = False ,
330
327
):
331
328
"""
332
329
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.
333
342
"""
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" ):
360
358
raise ComponentNotInstalledError (
361
359
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'." ,
363
362
)
363
+ return clipy
364
364
365
365
366
- def is_installed_clipy (path = None , reload = False ):
366
+ def is_installed_clipy (path = None , reload = False , logger = None ):
367
367
"""
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.
369
386
"""
387
+ if logger is None :
388
+ logger = get_logger ("clipy" )
370
389
try :
371
390
# If path is specified, don't fall back to global import
372
391
default_global = path is None
373
392
load_clipy (
374
- install_path = path ,
375
- logger = get_logger ( "clipy" ) ,
393
+ path = os . path . join ( path , "clipy" ) ,
394
+ logger = logger ,
376
395
not_installed_level = "debug" ,
377
396
reload = reload ,
378
397
default_global = default_global ,
@@ -382,67 +401,47 @@ def is_installed_clipy(path=None, reload=False):
382
401
return False
383
402
384
403
385
- def install_clipy (path , no_progress_bars = False ):
404
+ def install_clipy (path , logger = None , no_progress_bars = False ):
386
405
"""
387
406
Install clipy from GitHub repository to the specified path.
388
- """
389
- log = get_logger ("clipy" )
390
- log .info ("Installing clipy from GitHub repository..." )
391
407
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" )
392
426
# 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" , ):
395
429
exit_status = pip_install (req )
396
430
if exit_status :
397
- log .error ("Failed installing '%s'." , req )
431
+ logger .error ("Failed installing '%s'." , req )
398
432
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." )
404
443
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!" )
446
445
return True
447
446
448
447
0 commit comments