diff --git a/docs/getting_started.md b/docs/getting_started.md index 7f3ff51..de956ad 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -27,6 +27,12 @@ janus download stellar ## Environment variables +To see all environment variables and locations, use: + +```console +janus env +``` + ### `SOCRATES` By default, SOCRATES is installed to the default location based on the [XDG specification](https://specifications.freedesktop.org/basedir-spec/latest/). @@ -37,3 +43,12 @@ you can override the path using the `SOCRATES` environment variable, e.g. ```console SOCRATES=/home/user/path/to/SOCRATES pytest ``` + +### `FWL_DATA` + +Set this variable to modify where janus stores its stellar and spectral data. By default this is based on the [XDG specification](https://specifications.freedesktop.org/basedir-spec/latest/). +You can override the path using the `FWL_DATA` environment variable, e.g. + +```console +FWL_DATA=/home/user/path/to/fwl_data pytest +``` diff --git a/examples/SocRadConv.py b/examples/SocRadConv.py index cfc9749..be14184 100755 --- a/examples/SocRadConv.py +++ b/examples/SocRadConv.py @@ -3,9 +3,9 @@ """ Created on Mon Jan 23 12:20:27 2023 -@authors: +@authors: Mark Hammond (MH) -Tim Lichtenberg (TL) +Tim Lichtenberg (TL) Ryan Boukrouche (RB) Harrison Nicholls (HN) @@ -24,6 +24,10 @@ from janus.utils import atmos, CleanOutputDir, DownloadSpectralFiles, DownloadStellarSpectra, plot_adiabats, ReadBandEdges, StellarSpectrum import mors +import logging + +from janus.utils.data import FWL_DATA_DIR + #################################### ##### Stand-alone initial conditions #################################### @@ -34,8 +38,6 @@ # Set up dirs if os.environ.get('RAD_DIR') == None: raise Exception("Socrates environment variables not set! Have you installed Socrates and sourced set_rad_env?") - if os.environ.get('FWL_DATA') == None: - raise Exception("The FWL_DATA environment variable where spectral and evolution tracks data will be downloaded needs to be set up!") dirs = { "janus": str(files("janus"))+"/", "output": os.path.abspath(os.getcwd())+"/output/" @@ -45,13 +47,13 @@ ##### Settings cfg_file = dirs["janus"]+"data/tests/config_janus.toml" with open(cfg_file, 'r'): - cfg = toml.load(cfg_file) + cfg = toml.load(cfg_file) # Planet time = { "planet": cfg['planet']['time'], "star": cfg['star']['time']} star_mass = cfg['star']['star_mass'] mean_distance = cfg['star']['mean_distance'] - + # Define volatiles by partial pressures vol_mixing = {} vol_partial = { @@ -74,16 +76,16 @@ # Read spectrum spec = mors.Spectrum() - spec.LoadTSV(os.environ.get('FWL_DATA')+"/stellar_spectra/Named/sun.txt") + spec.LoadTSV(str(FWL_DATA_DIR / 'stellar_spectra' / 'Named' / 'sun.txt')) - # Convert to SOCRATES format + # Convert to SOCRATES format socstar = os.path.join(dirs["output"], "socstar.txt") StellarSpectrum.PrepareStellarSpectrum(spec.wl, spec.fl, socstar) # Move/prepare spectral file print("Inserting stellar spectrum") StellarSpectrum.InsertStellarSpectrum( - os.environ.get('FWL_DATA')+"/spectral_files/Dayspring/256/Dayspring.sf", + str(FWL_DATA_DIR / 'spectral_files'/'Oak'/'318'/'Oak.sf'), socstar, dirs["output"] ) @@ -94,12 +96,12 @@ atm = atmos.from_file(cfg_file, band_edges, vol_mixing=vol_mixing, vol_partial=vol_partial) # Set stellar heating on or off - if cfg['star']['stellar_heating'] == False: + if cfg['star']['stellar_heating'] == False: atm.instellation = 0. else: mors.DownloadEvolutionTracks("/Baraffe") baraffe = mors.BaraffeTrack(star_mass) - atm.instellation = baraffe.BaraffeSolarConstant(time['star'], mean_distance) + atm.instellation = baraffe.BaraffeSolarConstant(time['star'], mean_distance) print("Instellation:", round(atm.instellation), "W/m^2") # Set up atmosphere with general adiabat @@ -131,4 +133,3 @@ end = t.time() print("Runtime:", round(end - start,2), "s") - diff --git a/examples/demo_instellation.py b/examples/demo_instellation.py index e498ec5..ce6a565 100755 --- a/examples/demo_instellation.py +++ b/examples/demo_instellation.py @@ -16,6 +16,8 @@ import mors +from janus.utils.data import FWL_DATA_DIR + if __name__=='__main__': print("Start") @@ -23,8 +25,7 @@ # Set up dirs if os.environ.get('RAD_DIR') == None: raise Exception("Socrates environment variables not set! Have you installed Socrates and sourced set_rad_env?") - if os.environ.get('FWL_DATA') == None: - raise Exception("The FWL_DATA environment variable where spectral and evolution tracks data will be downloaded needs to be set up!") + dirs = { "janus": str(files("janus"))+"/", "output": os.path.abspath(os.getcwd())+"/output/" @@ -41,9 +42,9 @@ # Read spectrum spec = mors.Spectrum() - spec.LoadTSV(os.environ.get('FWL_DATA')+"/stellar_spectra/Named/sun.txt") + spec.LoadTSV(str(FWL_DATA_DIR / 'stellar_spectra' / 'Named' / 'sun.txt')) - # Convert to SOCRATES format + # Convert to SOCRATES format socstar = os.path.join(dirs["output"], "socstar.txt") StellarSpectrum.PrepareStellarSpectrum(spec.wl, spec.fl, socstar) @@ -51,7 +52,7 @@ # Setup spectral file print("Inserting stellar spectrum") StellarSpectrum.InsertStellarSpectrum( - os.environ.get('FWL_DATA')+"/spectral_files/Oak/318/Oak.sf", + str(FWL_DATA_DIR / 'spectral_files'/'Oak'/'318'/'Oak.sf'), socstar, dirs["output"] ) @@ -86,7 +87,7 @@ T_magma = atm.tmp_magma #get default value 3000 K but this could be a config option r_arr = np.linspace(0.3, 1.4, 7) # orbital distance range [AU] - + asf_arr = [] # ASF OLR_arr = [] # OLR net_arr = [] # net flux at TOA @@ -95,7 +96,7 @@ for i in range(7): print("Orbital separation = %.2f AU" % r_arr[i]) - atm.instellation = baraffe.BaraffeSolarConstant(time['star'], r_arr[i]) + atm.instellation = baraffe.BaraffeSolarConstant(time['star'], r_arr[i]) atmos.setTropopauseTemperature(atm) atm = MCPA_CBL(dirs, atm, False, rscatter = True, T_surf_max=9.0e99, T_surf_guess = atm.trppT+100) @@ -106,7 +107,7 @@ ts_arr.append(atm.ts) tr_arr.append(atm.trppT) - # Plot case + # Plot case plt.ioff() fig,ax = plt.subplots(1,1) ax.plot(atm.tmpl, atm.pl, color='black', lw=2) @@ -123,10 +124,10 @@ print(" ") save_arr = [r_arr, asf_arr, OLR_arr, net_arr, ts_arr, tr_arr] - np.savetxt(dirs["output"]+"/data_%dK.csv"%T_magma, + np.savetxt(dirs["output"]+"/data_%dK.csv"%T_magma, np.array(save_arr).T, fmt="%.5e", delimiter=",", header="r [AU], S_0 [W m-2], OLR [W m-2], net [W m-2], ts [K], tr[K] ") - + print("Making plots") plt.ioff() @@ -170,7 +171,7 @@ arr_magma = np.ones(len(r_arr))*T_magma ax2.plot(r_arr, np.zeros(len(r_arr)), zorder=6, color='silver', lw=2.5, label=r"$\tilde{T}_s$") # magma temperature - ax2.plot(r_arr, ts_arr - arr_magma, zorder=6, color='black', lw=2.5, label=r"$T_s$") # surface solution temperature + ax2.plot(r_arr, ts_arr - arr_magma, zorder=6, color='black', lw=2.5, label=r"$T_s$") # surface solution temperature ax2.legend(loc='center right', framealpha=1.0) ax2.set_ylabel(r"$T - \tilde{T_s}$ [K]") @@ -180,7 +181,7 @@ ax2.set_xlabel("Orbital separation [AU]") fig.subplots_adjust(hspace=0.08) fig.savefig(dirs["output"]+"inst_%dK.pdf"%T_magma, bbox_inches='tight') - + # Tidy CleanOutputDir(os.getcwd()) @@ -188,4 +189,3 @@ # Done print("Done!") - diff --git a/examples/demo_runaway_greenhouse.py b/examples/demo_runaway_greenhouse.py index 47ab9d2..e77f914 100755 --- a/examples/demo_runaway_greenhouse.py +++ b/examples/demo_runaway_greenhouse.py @@ -14,6 +14,8 @@ from janus.utils import atmos, CleanOutputDir, DownloadSpectralFiles, DownloadStellarSpectra, ReadBandEdges, StellarSpectrum import mors +from janus.utils.data import FWL_DATA_DIR + if __name__=='__main__': print("Start") @@ -22,8 +24,7 @@ # Set up dirs if os.environ.get('RAD_DIR') == None: raise Exception("Socrates environment variables not set! Have you installed Socrates and sourced set_rad_env?") - if os.environ.get('FWL_DATA') == None: - raise Exception("The FWL_DATA environment variable where spectral and evolution tracks data will be downloaded needs to be set up!") + dirs = { "janus": str(files("janus"))+"/", "output": os.path.abspath(os.getcwd())+"/output/" @@ -40,9 +41,9 @@ # Read spectrum spec = mors.Spectrum() - spec.LoadTSV(os.environ.get('FWL_DATA')+"/stellar_spectra/Named/sun.txt") + spec.LoadTSV(str(FWL_DATA_DIR / 'stellar_spectra' / 'Named' / 'sun.txt')) - # Convert to SOCRATES format + # Convert to SOCRATES format socstar = os.path.join(dirs["output"], "socstar.txt") StellarSpectrum.PrepareStellarSpectrum(spec.wl, spec.fl, socstar) @@ -50,7 +51,7 @@ # Setup spectral file print("Inserting stellar spectrum") StellarSpectrum.InsertStellarSpectrum( - os.environ.get('FWL_DATA')+"/spectral_files/Oak/318/Oak.sf", + str(FWL_DATA_DIR / 'spectral_files'/'Oak'/'318'/'Oak.sf'), socstar, dirs["output"] ) @@ -78,10 +79,10 @@ # Compute stellar heating mors.DownloadEvolutionTracks("/Baraffe") baraffe = mors.BaraffeTrack(star_mass) - atm.instellation = baraffe.BaraffeSolarConstant(time['star'], mean_distance) + atm.instellation = baraffe.BaraffeSolarConstant(time['star'], mean_distance) #Run Janus - + # Run JANUS in a loop to generate runaway curve print("Running JANUS...") Ts_arr = np.linspace(200, 2800, 20) @@ -100,13 +101,13 @@ # Get literature data g2013 = np.loadtxt(dirs["janus"]+"data/comparison_data/Goldblatt13_data.txt", - dtype=float, skiprows=2, delimiter=',').T + dtype=float, skiprows=2, delimiter=',').T k2013 = np.loadtxt(dirs["janus"]+"data/comparison_data/Kopparapu13_data.txt", - dtype=float, skiprows=2, delimiter=',').T + dtype=float, skiprows=2, delimiter=',').T h2015 = np.loadtxt(dirs["janus"]+"data/comparison_data/Hamano15_data.txt", - dtype=float, skiprows=2, delimiter=',').T + dtype=float, skiprows=2, delimiter=',').T s2023 = np.loadtxt(dirs["janus"]+"data/comparison_data/Selsis23_convective.txt", - dtype=float, skiprows=2, delimiter=',').T + dtype=float, skiprows=2, delimiter=',').T # Setup plot print("Making plot") @@ -125,11 +126,11 @@ ax.set_xlabel("Surface temperature [K]") ax.xaxis.set_minor_locator(MultipleLocator(100.0)) - ax.set_xlim(200.0, 2700.0) + ax.set_xlim(200.0, 2700.0) ax.set_ylabel("OLR [W m$^{-2}$]") ax.set_ylim(np.amin(OLR_arr) - 10.0, 500.0) - ax.yaxis.set_minor_locator(MultipleLocator(25.0)) + ax.yaxis.set_minor_locator(MultipleLocator(25.0)) fig.savefig(dirs["output"]+"runaway_demo.pdf", bbox_inches='tight') fig.savefig(dirs["output"]+"runaway_demo.png", bbox_inches='tight', dpi=190) @@ -141,4 +142,3 @@ # Done print("Done!") - diff --git a/src/janus/cli.py b/src/janus/cli.py index ce1081e..2f54ccd 100644 --- a/src/janus/cli.py +++ b/src/janus/cli.py @@ -42,10 +42,21 @@ def socrates(**kwargs): download_socrates(**kwargs) +@click.command() +def env(): + """Show environment variables and locations""" + from janus.socrates import SOCRATES_DIR + from janus.utils.data import FWL_DATA_DIR + + click.echo(f'RAD_DIR location: {SOCRATES_DIR}') + click.echo(f'FWL_DATA location: {FWL_DATA_DIR}') + + cli.add_command(download) download.add_command(spectral) download.add_command(stellar) download.add_command(socrates) +cli.add_command(env) if __name__ == '__main__': cli() diff --git a/src/janus/set_socrates_env.py b/src/janus/set_socrates_env.py index bcb6c4f..08a59db 100644 --- a/src/janus/set_socrates_env.py +++ b/src/janus/set_socrates_env.py @@ -12,19 +12,22 @@ import sys import zipfile from pathlib import Path +import logging import click import platformdirs import requests +logger = logging.getLogger(__name__) + if not SOCRATES_DIR.exists(): raise RuntimeError(f'Cannot find SOCRATES in this location: {SOCRATES_DIR}') with open(SOCRATES_DIR / 'version') as f: - version = f.readline() + SOCRATES_VERSION = f.readline() -print(f'socrates location: {SOCRATES_DIR}') -print(f'socrates version: {version}') +logger.info(f'socrates location: %s', SOCRATES_DIR) +logger.info('socrates version: %s', SOCRATES_VERSION) sep = os.pathsep diff --git a/src/janus/utils/data.py b/src/janus/utils/data.py index 6c5c7f0..fb7b73a 100644 --- a/src/janus/utils/data.py +++ b/src/janus/utils/data.py @@ -1,6 +1,15 @@ import os -from osfclient.api import OSF from pathlib import Path +import logging + +import platformdirs +from osfclient.api import OSF + +logger = logging.getLogger(__name__) + +FWL_DATA_DIR = Path(os.environ.get('FWL_DATA', platformdirs.user_data_dir('fwl_data'))) + +logger.info(f'FWL data location: {FWL_DATA_DIR}') basic_list = ( "Dayspring/256", @@ -14,9 +23,9 @@ def download_folder(*, storage, folders: list[str], data_dir: Path): """ Download a specific folder in the OSF repository - + Inputs : - - storage : OSF storage name + - storage : OSF storage name - folders : folder names to download - data_dir : local repository where data are saved """ @@ -37,19 +46,16 @@ def GetFWLData() -> Path: """ Get path to FWL data directory on the disk """ - fwl_data_dir = os.getenv('FWL_DATA') - if not os.environ.get("FWL_DATA"): - raise Exception("The FWL_DATA environment variable where spectral data will be downloaded needs to be set up!") - return Path(fwl_data_dir).absolute() + return FWL_DATA_DIR.absolute() def DownloadStellarSpectra(): """ Download stellar spectra """ - #project ID of the stellar spectra on OSF + #project ID of the stellar spectra on OSF project_id = '8r2sw' folder_name = 'Named' - + osf = OSF() project = osf.project(project_id) storage = project.storage('osfstorage') @@ -58,21 +64,21 @@ def DownloadStellarSpectra(): data_dir.mkdir(parents=True, exist_ok=True) if not (data_dir / folder_name).exists(): - print("Downloading stellar spectra") + print(f"Downloading stellar spectra to {data_dir}") download_folder(storage=storage, folders=[folder_name], data_dir=data_dir) def DownloadSpectralFiles(fname: str="",nband: int=256): """ Download spectral files data - + Inputs : - fname (optional) : folder name, i.e. "/Dayspring" - if not provided download all the basic list - - nband (optional) : number of band = 16, 48, 256, 4096 + if not provided download all the basic list + - nband (optional) : number of band = 16, 48, 256, 4096 (only relevant for Dayspring, Frostflow and Honeyside) """ - #project ID of the spectral files on OSF + #project ID of the spectral files on OSF project_id = 'vehxg' #Create spectral file data repository if not existing @@ -97,5 +103,5 @@ def DownloadSpectralFiles(fname: str="",nband: int=256): folders = [folder for folder in folder_list if not (data_dir / folder).exists()] if folders: - print("Downloading SOCRATES spectral files") + print(f"Downloading SOCRATES spectral files to {data_dir}") download_folder(storage=storage, folders=folders, data_dir=data_dir) diff --git a/tests/conftest.py b/tests/conftest.py index 11684d6..21b405d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1 @@ import os - -if not os.environ.get('FWL_DATA'): - raise Exception( - 'The FWL_DATA environment variable where spectral and evolution tracks data will be downloaded needs to be set up!' - ) diff --git a/tests/helpers/__init__.py b/tests/helpers/__init__.py index 32232c5..d744047 100644 --- a/tests/helpers/__init__.py +++ b/tests/helpers/__init__.py @@ -13,8 +13,9 @@ atmos, ) +from janus.utils.data import FWL_DATA_DIR + DATA_DRC = files('janus') / 'data' / 'tests' -FWL_DATA = os.environ.get('FWL_DATA') @contextmanager @@ -39,12 +40,12 @@ def get_spectrum_data(drc): DownloadStellarSpectra() spec = mors.Spectrum() - spec.LoadTSV(FWL_DATA + '/stellar_spectra/Named/sun.txt') + spec.LoadTSV(str(FWL_DATA_DIR / 'stellar_spectra' / 'Named' / 'sun.txt')) socstar = os.path.join(drc, 'socstar.txt') StellarSpectrum.PrepareStellarSpectrum(spec.wl, spec.fl, socstar) StellarSpectrum.InsertStellarSpectrum( - FWL_DATA + '/spectral_files/Oak/318/Oak.sf', + str(FWL_DATA_DIR / 'spectral_files'/'Oak'/'318'/'Oak.sf'), socstar, drc, ) diff --git a/tests/test_instellation.py b/tests/test_instellation.py index 997e0b5..66fa1d4 100755 --- a/tests/test_instellation.py +++ b/tests/test_instellation.py @@ -1,8 +1,7 @@ -from numpy.testing import assert_allclose +import pytest from helpers import get_atmosphere_config, get_spectrum_data, work_directory from janus.modules import MCPA_CBL -import pytest - +from numpy.testing import assert_allclose TEST_DATA = ( (0.3, (2.34297e03, 1.94397e03, -4.67185e01, 3.00023e03, 4.19568e02)), diff --git a/tests/test_runaway_greenhouse.py b/tests/test_runaway_greenhouse.py index 5816f4d..acb2bc4 100755 --- a/tests/test_runaway_greenhouse.py +++ b/tests/test_runaway_greenhouse.py @@ -1,8 +1,7 @@ import numpy as np +import pytest from helpers import get_atmosphere_config, get_spectrum_data, work_directory from janus.modules import RadConvEqm -import pytest - TEST_DATA = ( (200.00000000,9.07314e+01),