From d9d83d95862dfc1ec81846318477f81fb73e39ae Mon Sep 17 00:00:00 2001 From: Dan Foreman-Mackey Date: Mon, 31 Jul 2023 17:26:19 -0400 Subject: [PATCH] Building docs on Read the Docs, adding pre-commit formatting (#219) --- .cirrus.yml | 2 +- .github/workflows/build_docs.sh | 31 ---- .github/workflows/release.yml | 39 +++-- .github/workflows/tests.yml | 25 --- .github/workflows/update-fsps.yml | 6 +- .pre-commit-config.yaml | 17 ++ CMakeLists.txt | 2 +- LICENSE.rst | 2 +- demos/dao69.py | 22 ++- demos/feature_demo.py | 71 ++++---- demos/plot_sdss_2mass_transmission.py | 47 ++++-- demos/specbymass.py | 88 +++++----- docs/README.rst | 29 ---- docs/_themes/LICENSE | 4 +- docs/_themes/dfm/theme.conf | 2 +- docs/_themes/flask_theme_support.py | 147 ++++++++-------- docs/conf.py | 21 +-- docs/filter_table.rst | 230 +++++++++++++------------- docs/index.rst | 2 +- pyproject.toml | 34 +++- readthedocs.yml | 23 +++ scripts/fsps_filter_table.py | 43 +++-- src/fsps/CMakeLists.txt | 2 +- src/fsps/__init__.py | 7 +- src/fsps/filters.py | 3 +- src/fsps/fsps.py | 56 +++---- tests/options.py | 4 +- tests/tests.py | 11 +- tools/f2py_include.py | 2 +- tools/version.py | 17 -- 30 files changed, 500 insertions(+), 489 deletions(-) delete mode 100755 .github/workflows/build_docs.sh create mode 100644 .pre-commit-config.yaml delete mode 100644 docs/README.rst create mode 100644 readthedocs.yml delete mode 100755 tools/version.py diff --git a/.cirrus.yml b/.cirrus.yml index cd15700e..cdf89881 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -5,7 +5,7 @@ cirrus_wheels_macos_arm64_task: PATH: /opt/homebrew/opt/python@3.10/bin:$PATH CIBW_ENVIRONMENT: > MACOSX_DEPLOYMENT_TARGET=12.0 - _PYTHON_HOST_PLATFORM="macosx-12.0-arm64" + _PYTHON_HOST_PLATFORM="macosx-12.0-arm64" SPS_HOME="${CIRRUS_WORKING_DIR}/src/fsps/libfsps" PKG_CONFIG_PATH: /opt/arm64-builds/lib/pkgconfig CMAKE_PREFIX_PATH: /opt/arm64-builds/ diff --git a/.github/workflows/build_docs.sh b/.github/workflows/build_docs.sh deleted file mode 100755 index 7973f30d..00000000 --- a/.github/workflows/build_docs.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh -l -set -e - -echo "Stable: $STABLE" -VERSION=`python -c 'import fsps;print(fsps.__version__)'` -echo "Version: $VERSION" - -# Build the docs -cd docs -make dirhtml - -# Update the gh-pages branch -git clone --branch=gh-pages https://github.com/$GITHUB_REPOSITORY _output -cd _output -rm -rf latest -mkdir -p latest -cp -r ../_build/dirhtml/* latest/ -git add latest - -if [ "$STABLE" = "true" ]; then - rm -rf $VERSION - cp -r latest $VERSION - git add $VERSION -fi - -# Push the results to GitHub -if git -c user.name='gh-actions' -c user.email='gh-actions' commit -m "Updated docs [ci skip]"; then - git push --force https://x-access-token:$GITHUB_TOKEN@github.com/$GITHUB_REPOSITORY gh-pages -else - echo "No changes" -fi diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9e5fb2aa..22dabec3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,10 +1,18 @@ name: Release on: - release: - types: [published] push: - branches: [main] - pull_request: + branches: + - main + tags: + - "*" + # pull_request: + workflow_dispatch: + inputs: + prerelease: + description: "Run a pre-release, testing the build" + required: false + type: boolean + default: false concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -17,7 +25,7 @@ jobs: strategy: fail-fast: false matrix: - os: + os: - "ubuntu-latest" - "macos-latest" # - "windows-latest" @@ -64,20 +72,27 @@ jobs: with: task: cirrus_wheels_macos_arm64 commit: ${{ github.event.pull_request.head.sha || github.sha }} - timeout-minutes: 15 + timeout-minutes: 15 - run: ls dist - upload_pypi: + publish: + environment: + name: pypi + url: https://pypi.org/p/fsps + permissions: + id-token: write needs: [build_wheels, build_sdist] runs-on: ubuntu-latest - if: github.event_name == 'release' && github.event.action == 'published' + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') steps: + - name: Get macOS arm64 wheels from Cirrus CI + uses: getsentry/action-wait-for-cirrus@v1.0.0 + with: + task: cirrus_wheels_macos_arm64 + commit: ${{ github.event.pull_request.head.sha || github.sha }} + timeout-minutes: 15 - uses: actions/download-artifact@v3 with: name: artifact path: dist - uses: pypa/gh-action-pypi-publish@v1.8.7 - with: - user: __token__ - password: ${{ secrets.pypi_password }} - # To test: repository_url: https://test.pypi.org/legacy/ diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6579cdb4..57781b5d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -70,28 +70,3 @@ jobs: run: python -m nox --non-interactive --no-error-on-missing-interpreters -s ${{ matrix.nox-session }}-${{ matrix.python-version }} env: SPS_HOME: ${{ github.workspace }}/src/fsps/libfsps - - docs: - if: github.event_name != 'pull_request' - name: "docs" - runs-on: ubuntu-latest - steps: - - name: Clone the repo - uses: actions/checkout@v3 - with: - fetch-depth: 0 - submodules: recursive - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: "3.9" - - name: Install dependencies - run: | - python -m pip install -U pip sphinx - python -m pip install . - - name: Build documentation - run: .github/workflows/build_docs.sh - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SPS_HOME: ${{ github.workspace }}/src/fsps/libfsps - STABLE: ${{ github.event_name == 'release' && github.event.action == 'published' }} diff --git a/.github/workflows/update-fsps.yml b/.github/workflows/update-fsps.yml index f552dd71..6bfdc86a 100644 --- a/.github/workflows/update-fsps.yml +++ b/.github/workflows/update-fsps.yml @@ -12,10 +12,10 @@ jobs: with: submodules: true fetch-depth: 0 - + - name: Update the submodule run: git submodule foreach git pull origin master - + - name: Create a PR uses: peter-evans/create-pull-request@v5 with: @@ -25,5 +25,5 @@ jobs: title: Updating FSPS body: | Automatically updating the FSPS submodule - + **Maintainers should close and then re-open this PR to get the tests to run.** diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..589a40a9 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,17 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: "v4.4.0" + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + exclude_types: [json, binary] + - id: check-yaml + - repo: https://github.com/psf/black + rev: "23.1.0" + hooks: + - id: black-jupyter + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: "v0.0.277" + hooks: + - id: ruff + args: [--fix, --exit-non-zero-on-fix] diff --git a/CMakeLists.txt b/CMakeLists.txt index c5229d8f..9629b461 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ find_package( # Find the f2py headers execute_process( - COMMAND "${PYTHON_EXECUTABLE}" + COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tools/f2py_include.py" OUTPUT_VARIABLE F2PY_INCLUDE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) diff --git a/LICENSE.rst b/LICENSE.rst index 8f8d9842..b5891cec 100644 --- a/LICENSE.rst +++ b/LICENSE.rst @@ -1,4 +1,4 @@ -Copyright 2013-2021 Python-FSPS developers. +Copyright 2013-2023 Python-FSPS developers. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/demos/dao69.py b/demos/dao69.py index 4ee3673a..052315ee 100644 --- a/demos/dao69.py +++ b/demos/dao69.py @@ -1,15 +1,16 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from __future__ import (division, print_function, absolute_import, - unicode_literals) -import pyfits -import numpy as np +from __future__ import absolute_import, division, print_function, unicode_literals + import matplotlib.pyplot as pl +import numpy as np +import pyfits + import fsps # Measurements of cluster parameters. -tage = 10. ** (8.04 - 9) +tage = 10.0 ** (8.04 - 9) logmass = 4.09 dist_mod = 24.5 @@ -17,9 +18,7 @@ sp = fsps.StellarPopulation(imf_type=2, dust_type=1, mwr=3.1, dust2=0.3) # The measured magnitudes from the literature. -data = {"wfc3_f160w": 16.386, - "wfc3_f275w": 17.398, - "wfc_acs_f814w": 17.155} +data = {"wfc3_f160w": 16.386, "wfc3_f275w": 17.398, "wfc_acs_f814w": 17.155} # There are also a few filters that we have data for but aren't included in # the standard FSPS install: @@ -39,15 +38,14 @@ # Compute the model magnitudes. for b, v in data.iteritems(): - print(b, v, sp.get_mags(zmet=20, tage=tage, band=b) - 2.5 * logmass - + dist_mod) + print(b, v, sp.get_mags(zmet=20, tage=tage, band=b) - 2.5 * logmass + dist_mod) # Compute the model spectrum in ``L_sun / A``. lam, spec = sp.get_spectrum(zmet=20, tage=tage, peraa=True) -spec *= 3.839e33 * 10. ** (logmass - dist_mod / 2.5) +spec *= 3.839e33 * 10.0 ** (logmass - dist_mod / 2.5) f = 1.0 # obs_spec[0, obs_lambda < 5000.][-1] / spec[lam < 5000.][-1] -print(obs_spec[0, obs_lambda < 5000.][-1] / spec[lam < 5000.][-1]) +print(obs_spec[0, obs_lambda < 5000.0][-1] / spec[lam < 5000.0][-1]) pl.loglog(obs_lambda, obs_spec[0], "k") pl.loglog(lam, spec * f, "r") diff --git a/demos/feature_demo.py b/demos/feature_demo.py index a6b39ca1..98a74dec 100644 --- a/demos/feature_demo.py +++ b/demos/feature_demo.py @@ -7,7 +7,7 @@ """ import os -import numpy as np + import matplotlib.pyplot as pl from matplotlib.backends.backend_pdf import PdfPages @@ -18,19 +18,19 @@ def makefig(sps, tage=13.7, oldspec=None, **plotkwargs): w, spec = sps.get_spectrum(tage=tage) fig, ax = pl.subplots() if oldspec is not None: - ax.plot(w, oldspec / w * 1e19, color='gray', linewidth=2, alpha=0.5) - ax.plot(w, spec / w * 1e19, 'C2', linewidth=2) + ax.plot(w, oldspec / w * 1e19, color="gray", linewidth=2, alpha=0.5) + ax.plot(w, spec / w * 1e19, "C2", linewidth=2) return fig, ax, spec def prettify(fig, ax, label=None): ax.set_xlim(0.9e3, 1e6) - ax.set_xscale('log') + ax.set_xscale("log") ax.set_ylim(0.01, 2) - #ax.set_yscale('log') - ax.set_xlabel(r'rest-frame $\lambda$ ($\AA$)', fontsize=20) - ax.set_ylabel(r'$\lambda \, f_\lambda$', fontsize=20) - ax.tick_params(axis='both', which='major', labelsize=16) + # ax.set_yscale('log') + ax.set_xlabel(r"rest-frame $\lambda$ ($\AA$)", fontsize=20) + ax.set_ylabel(r"$\lambda \, f_\lambda$", fontsize=20) + ax.tick_params(axis="both", which="major", labelsize=16) if label is not None: ax.text(0.63, 0.85, label, transform=ax.transAxes, fontsize=16) @@ -39,94 +39,93 @@ def prettify(fig, ax, label=None): if __name__ == "__main__": - - pl.rc('text', usetex=True) - pl.rc('font', family='serif') - pl.rc('axes', grid=False) - pl.rc('xtick', direction='in') - pl.rc('ytick', direction='in') - pl.rc('xtick', top=True) - pl.rc('ytick', right=True) + pl.rc("text", usetex=True) + pl.rc("font", family="serif") + pl.rc("axes", grid=False) + pl.rc("xtick", direction="in") + pl.rc("ytick", direction="in") + pl.rc("xtick", top=True) + pl.rc("ytick", right=True) sps = fsps.StellarPopulation(zcontinuous=1) ilib, slib, dlib = sps.libraries print(ilib, slib) os.makedirs("./figures", exist_ok=True) - pdf = PdfPages('./figures/features.pdf') + pdf = PdfPages("./figures/features.pdf") # Basic spectrum - sps.params['sfh'] = 4 - sps.params['tau'] = 5.0 - sps.params['logzsol'] = 0.0 - sps.params['dust_type'] = 4 # kriek and Conroy - sps.params['imf_type'] = 2 # kroupa - sps.params['imf3'] = 2.3 + sps.params["sfh"] = 4 + sps.params["tau"] = 5.0 + sps.params["logzsol"] = 0.0 + sps.params["dust_type"] = 4 # kriek and Conroy + sps.params["imf_type"] = 2 # kroupa + sps.params["imf3"] = 2.3 fig, ax, spec = makefig(sps) fig, ax = prettify(fig, ax, label=r"$\tau=5$, Age$=13.7$,\\n$\log Z/Z_\odot=0.0$") pdf.savefig(fig) pl.close(fig) # change IMF - sps.params['imf3'] = 2.5 + sps.params["imf3"] = 2.5 fig, ax, spec = makefig(sps, oldspec=spec) fig, ax = prettify(fig, ax, label=r"IMF slope") pdf.savefig(fig) # Attenuate - sps.params['add_dust_emission'] = False - sps.params['dust2'] = 0.2 + sps.params["add_dust_emission"] = False + sps.params["dust2"] = 0.2 fig, ax, spec = makefig(sps, oldspec=spec) fig, ax = prettify(fig, ax, label=r"Dust Attenuation") pdf.savefig(fig) pl.close(fig) # Dust emission - sps.params['add_dust_emission'] = True + sps.params["add_dust_emission"] = True fig, ax, spec = makefig(sps, oldspec=spec) fig, ax = prettify(fig, ax, label=r"Dust Emission") pdf.savefig(fig) pl.close(fig) # Dust temperature - sps.params['duste_umin'] = 10 + sps.params["duste_umin"] = 10 fig, ax, spec = makefig(sps, oldspec=spec) fig, ax = prettify(fig, ax, label=r"Dust SED\\n({})".format(dlib)) pdf.savefig(fig) pl.close(fig) # AGN emission - sps.params['fagn'] = 0.3 + sps.params["fagn"] = 0.3 fig, ax, spec = makefig(sps, oldspec=spec) fig, ax = prettify(fig, ax, label=r"AGN dust\\n(Nenkova)") pdf.savefig(fig) pl.close(fig) # Nebular emission - sps.params['add_neb_emission'] = True - sps.params['gas_logu'] = -3.5 + sps.params["add_neb_emission"] = True + sps.params["gas_logu"] = -3.5 fig, ax, spec = makefig(sps, oldspec=spec) fig, ax = prettify(fig, ax, label=r"Neb. emission\\n(Byler)") pdf.savefig(fig) pl.close(fig) # change logu - sps.params['gas_logu'] = -1.0 + sps.params["gas_logu"] = -1.0 fig, ax, spec = makefig(sps, oldspec=spec) fig, ax = prettify(fig, ax, label=r"Change U$_{neb}$") pdf.savefig(fig) pl.close(fig) # change logz - sps.params['logzsol'] = -0.5 - sps.params['gas_logz'] = -0.5 + sps.params["logzsol"] = -0.5 + sps.params["gas_logz"] = -0.5 fig, ax, spec = makefig(sps, oldspec=spec) fig, ax = prettify(fig, ax, label=r"$\log Z/Z_\odot=-0.5$") pdf.savefig(fig) pl.close(fig) # IGM absorption - sps.params['zred'] = 6.0 - sps.params['add_igm_absorption'] = True + sps.params["zred"] = 6.0 + sps.params["add_igm_absorption"] = True fig, ax, spec = makefig(sps, oldspec=spec) fig, ax = prettify(fig, ax, label=r"IGM attenuation\\n(Madau, $z=6$)") pdf.savefig(fig) diff --git a/demos/plot_sdss_2mass_transmission.py b/demos/plot_sdss_2mass_transmission.py index 02b37fd3..26222a62 100755 --- a/demos/plot_sdss_2mass_transmission.py +++ b/demos/plot_sdss_2mass_transmission.py @@ -5,36 +5,47 @@ (i.e., contents of $SPS_HOME/data/all_filters.dat). """ -import fsps - -from matplotlib.figure import Figure +from matplotlib import gridspec from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas -import matplotlib.gridspec as gridspec +from matplotlib.figure import Figure +import fsps -names = ['sdss_u', 'sdss_g', 'sdss_r', 'sdss_i', - '2mass_J', '2mass_H', '2mass_Ks'] -shortnames = ['u', 'g', 'r', 'i', 'J', 'H', 'Ks'] -colors = ['violet', 'dodgerblue', 'maroon', 'black', 'c', 'm', 'y'] +names = ["sdss_u", "sdss_g", "sdss_r", "sdss_i", "2mass_J", "2mass_H", "2mass_Ks"] +shortnames = ["u", "g", "r", "i", "J", "H", "Ks"] +colors = ["violet", "dodgerblue", "maroon", "black", "c", "m", "y"] filters = [fsps.get_filter(n) for n in names] fig = Figure(figsize=(3.5, 3.5)) canvas = FigureCanvas(fig) gs = gridspec.GridSpec( - 1, 1, left=0.17, right=0.95, bottom=0.15, top=0.95, - wspace=None, hspace=None, width_ratios=None, height_ratios=None) + 1, + 1, + left=0.17, + right=0.95, + bottom=0.15, + top=0.95, + wspace=None, + hspace=None, + width_ratios=None, + height_ratios=None, +) ax = fig.add_subplot(gs[0]) -for name, fltr, c, shortname in zip(names, filters, colors, shortnames): +for _name, fltr, c, shortname in zip(names, filters, colors, shortnames): lmbd, trans = fltr.transmission - lambda_eff = fltr.lambda_eff / 10000. # µm - ax.plot(lmbd / 10000., trans, ls='-', lw=1., c=c) - ax.annotate(shortname, (lambda_eff, trans.max()), - textcoords='offset points', - xytext=(0., 5.), - ha='center', va='bottom') + lambda_eff = fltr.lambda_eff / 10000.0 # µm + ax.plot(lmbd / 10000.0, trans, ls="-", lw=1.0, c=c) + ax.annotate( + shortname, + (lambda_eff, trans.max()), + textcoords="offset points", + xytext=(0.0, 5.0), + ha="center", + va="bottom", + ) -ax.set_ylim(0., 1.1) +ax.set_ylim(0.0, 1.1) ax.set_xlabel(r"$\lambda~\mu\mathrm{m}$") ax.set_ylabel(r"$T$") gs.tight_layout(fig, pad=1.08, h_pad=None, w_pad=None, rect=None) diff --git a/demos/specbymass.py b/demos/specbymass.py index 5869efaf..e569bcd8 100644 --- a/demos/specbymass.py +++ b/demos/specbymass.py @@ -3,26 +3,42 @@ # stellar population. There is also some use of the filter objects. from itertools import product -import numpy as np + import matplotlib.pyplot as pl +import numpy as np + import fsps # make an SPS object with interpolation in metallicity enabled, and # set a few parameters sps = fsps.StellarPopulation(zcontinuous=1) -sps.params['imf_type'] = 0 # Salpeter IMF -sps.params['sfh'] = 1 # Tau model SFH +sps.params["imf_type"] = 0 # Salpeter IMF +sps.params["sfh"] = 1 # Tau model SFH # Get a few filter transmission curves -filterlist = {'galex_fuv': 'FUV', 'galex_nuv': 'NUV', 'sdss_u': 'u', - 'sdss_g': 'g', 'sdss_i': 'i', '2mass_j': 'J'} +filterlist = { + "galex_fuv": "FUV", + "galex_nuv": "NUV", + "sdss_u": "u", + "sdss_g": "g", + "sdss_i": "i", + "2mass_j": "J", +} filters = [fsps.filters.get_filter(f) for f in filterlist] # This is the main function -def specplots(tage=10.0, const=1.0, tau=1.0, neb=False, z=0.0, savefig=True, - masslims=[1.0, 3.0, 15.0, 30.0, 120.0], **kwargs): - """Make a number of plots showing the fraction of the total light due to +def specplots( + tage=10.0, + const=1.0, + tau=1.0, + neb=False, + z=0.0, + savefig=True, + masslims=[1.0, 3.0, 15.0, 30.0, 120.0], + **kwargs, +): + r"""Make a number of plots showing the fraction of the total light due to stars within certain stellar mass ranges. :param tage: @@ -60,22 +76,22 @@ def specplots(tage=10.0, const=1.0, tau=1.0, neb=False, z=0.0, savefig=True, stars in given mass ranges, as a function of wavelength. """ # Set the FSPS params - sps.params['const'] = const - sps.params['tau'] = tau - sps.params['add_neb_emission'] = neb - sps.params['masscut'] = 120 - sps.params['logzsol'] = z + sps.params["const"] = const + sps.params["tau"] = tau + sps.params["add_neb_emission"] = neb + sps.params["masscut"] = 120 + sps.params["logzsol"] = z # Try to set any extra params for k, v in kwargs.items(): try: sps.params[k] = v - except(KeyError): + except KeyError: pass # Make a pretty string with the FSPS parameters - sfh = {1: 'Constant SFR', 0: r'$\tau_{{SF}}={}$'.format(sps.params['tau'])} - sfhname = {1: 'const', 0: 'tau{}'.format(sps.params['tau'])} - name = '{}_z{}_neb{}'.format(sfhname[int(const)], z, neb) + sfh = {1: "Constant SFR", 0: r"$\tau_{{SF}}={}$".format(sps.params["tau"])} + sfhname = {1: "const", 0: "tau{}".format(sps.params["tau"])} + name = "{}_z{}_neb{}".format(sfhname[int(const)], z, neb) # get the total spectrum due to *all* stars wave, spec_tot = sps.get_spectrum(tage=tage) @@ -93,64 +109,62 @@ def specplots(tage=10.0, const=1.0, tau=1.0, neb=False, z=0.0, savefig=True, # Loop over upper mass limits, generating spectrum for each one for i, mc in enumerate(masslims): # set the upper stellar mass limit - sps.params['masscut'] = mc + sps.params["masscut"] = mc # get the spectrum at age = tage and store it w, spec = sps.get_spectrum(tage=tage) mspec[:, i] = spec.copy() # plot the spectrum due to stars less massive than the limit - cax.plot(w, spec, label='M < {}'.format(mc)) + cax.plot(w, spec, label="M < {}".format(mc)) if i == 0: # Plot the lowest mass bin spectrum - dax.plot(w, spec, label='{} < M < {}'.format(0.08, mc)) - fax.plot(w, spec / spec_tot, label='{} < M < {}'.format(0.08, mc)) + dax.plot(w, spec, label="{} < M < {}".format(0.08, mc)) + fax.plot(w, spec / spec_tot, label="{} < M < {}".format(0.08, mc)) # skip the rest of the loop continue # Subtract the spectrum from the last upper limit to ge tthe # spectrum due to stars within the bin - dmspec[:, i] = spec - mspec[:, i-1] + dmspec[:, i] = spec - mspec[:, i - 1] # Plot it - label = '{} < M < {}'.format(masslims[i-1], mc) + label = "{} < M < {}".format(masslims[i - 1], mc) dax.plot(w, dmspec[:, i], label=label) # Plot the total spectrum if mc == masslims[-1]: - dax.plot(w, spec, label='Total', color='black') + dax.plot(w, spec, label="Total", color="black") # plot the fractional fax.plot(w, dmspec[:, i] / spec_tot, label=label) # prettify the axes, titles, etc [ax.legend(loc=0) for ax in [cax, dax, fax]] - [ax.set_xlabel('$\lambda (\AA)$') for ax in [cax, dax, fax]] - [ax.set_ylabel('$F_\lambda$') for ax in [cax, dax]] - [ax.set_yscale('log') for ax in [cax, dax]] + [ax.set_xlabel(r"$\lambda (\AA)$") for ax in [cax, dax, fax]] + [ax.set_ylabel(r"$F_\lambda$") for ax in [cax, dax]] + [ax.set_yscale("log") for ax in [cax, dax]] [ax.set_ylim(1e-20, 1e-14) for ax in [cax, dax]] - fstring = 'Age = {} Gyr, {}, log$Z/Z_\odot$={}' - vals = 10.0, sfh[int(sps.params['const'])], sps.params['logzsol'] + fstring = r"Age = {} Gyr, {}, log$Z/Z_\odot$={}" + vals = 10.0, sfh[int(sps.params["const"])], sps.params["logzsol"] [ax.set_title(fstring.format(*vals)) for ax in [cax, dax, fax]] - fax.set_ylabel('$F/F_{tot}$') + fax.set_ylabel("$F/F_{tot}$") # plot filter transmission curves as shaded regions for f in filters: wavelength, transmission = f.transmission tmax = transmission.max() wmax = wavelength[transmission.argmax()] - fax.fill_between(wavelength, transmission / tmax * 0.8, - alpha=0.3, color='grey') - fax.text(wmax, 0.83, filterlist[f.name], fontdict={'size': 16}) + fax.fill_between(wavelength, transmission / tmax * 0.8, alpha=0.3, color="grey") + fax.text(wmax, 0.83, filterlist[f.name], fontdict={"size": 16}) if savefig: # save to pdf - cfig.savefig('cspec_'+name+'.pdf') - dfig.savefig('dspec_'+name+'.pdf') - ffig.savefig('fspec_'+name+'.pdf') + cfig.savefig("cspec_" + name + ".pdf") + dfig.savefig("dspec_" + name + ".pdf") + ffig.savefig("fspec_" + name + ".pdf") return cfig, dfig, ffig if __name__ == "__main__": - # set the stellar population age tage = 10.0 # in Gyr diff --git a/docs/README.rst b/docs/README.rst deleted file mode 100644 index 898bc160..00000000 --- a/docs/README.rst +++ /dev/null @@ -1,29 +0,0 @@ -Building the documentation --------------------------- - -The docs are now built using GitHub actions so you shouldn't ever need to build -them. But, to test, you can use the following steps: - -1. In this directory, run:: - - make clean - make dirhtml - -2. Confirm that the results in ``_build/dirhtml`` look sensible. -3. Change to the root directory of the repository and run (changing - ``VERSION`` to the correct version number):: - - git checkout gh-pages - mkdir VERSION - cp -r docs/_build/dirhtml/* VERSION/ - git add VERSION - git commit -m "Updated docs for version VERSION" - git push - -4. If you want to release this version as the default (stable) version, run:: - - rm current - ln -s VERSION current - git add current - git commit -m "Updating stable version to VERSION" - git push diff --git a/docs/_themes/LICENSE b/docs/_themes/LICENSE index eebef675..eb2e303f 100755 --- a/docs/_themes/LICENSE +++ b/docs/_themes/LICENSE @@ -3,12 +3,12 @@ Further modifications: Copyright 2012 Dan Foreman-Mackey -Modifications: +Modifications: Copyright (c) 2011 Kenneth Reitz. -Original Project: +Original Project: Copyright (c) 2010 by Armin Ronacher. diff --git a/docs/_themes/dfm/theme.conf b/docs/_themes/dfm/theme.conf index 307a1f0d..07698f6f 100755 --- a/docs/_themes/dfm/theme.conf +++ b/docs/_themes/dfm/theme.conf @@ -4,4 +4,4 @@ stylesheet = flasky.css pygments_style = flask_theme_support.FlaskyStyle [options] -touch_icon = +touch_icon = diff --git a/docs/_themes/flask_theme_support.py b/docs/_themes/flask_theme_support.py index 33f47449..64e24996 100755 --- a/docs/_themes/flask_theme_support.py +++ b/docs/_themes/flask_theme_support.py @@ -1,7 +1,19 @@ # flasky extensions. flasky pygments style based on tango style from pygments.style import Style -from pygments.token import Keyword, Name, Comment, String, Error, \ - Number, Operator, Generic, Whitespace, Punctuation, Other, Literal +from pygments.token import ( + Comment, + Error, + Generic, + Keyword, + Literal, + Name, + Number, + Operator, + Other, + Punctuation, + String, + Whitespace, +) class FlaskyStyle(Style): @@ -10,77 +22,68 @@ class FlaskyStyle(Style): styles = { # No corresponding class for the following: - #Text: "", # class: '' - Whitespace: "underline #f8f8f8", # class: 'w' - Error: "#a40000 border:#ef2929", # class: 'err' - Other: "#000000", # class 'x' - - Comment: "italic #8f5902", # class: 'c' - Comment.Preproc: "noitalic", # class: 'cp' - - Keyword: "bold #004461", # class: 'k' - Keyword.Constant: "bold #004461", # class: 'kc' - Keyword.Declaration: "bold #004461", # class: 'kd' - Keyword.Namespace: "bold #004461", # class: 'kn' - Keyword.Pseudo: "bold #004461", # class: 'kp' - Keyword.Reserved: "bold #004461", # class: 'kr' - Keyword.Type: "bold #004461", # class: 'kt' - - Operator: "#582800", # class: 'o' - Operator.Word: "bold #004461", # class: 'ow' - like keywords - - Punctuation: "bold #000000", # class: 'p' - + # Text: "", # class: '' + Whitespace: "underline #f8f8f8", # class: 'w' + Error: "#a40000 border:#ef2929", # class: 'err' + Other: "#000000", # class 'x' + Comment: "italic #8f5902", # class: 'c' + Comment.Preproc: "noitalic", # class: 'cp' + Keyword: "bold #004461", # class: 'k' + Keyword.Constant: "bold #004461", # class: 'kc' + Keyword.Declaration: "bold #004461", # class: 'kd' + Keyword.Namespace: "bold #004461", # class: 'kn' + Keyword.Pseudo: "bold #004461", # class: 'kp' + Keyword.Reserved: "bold #004461", # class: 'kr' + Keyword.Type: "bold #004461", # class: 'kt' + Operator: "#582800", # class: 'o' + Operator.Word: "bold #004461", # class: 'ow' - like keywords + Punctuation: "bold #000000", # class: 'p' # because special names such as Name.Class, Name.Function, etc. # are not recognized as such later in the parsing, we choose them # to look the same as ordinary variables. - Name: "#000000", # class: 'n' - Name.Attribute: "#c4a000", # class: 'na' - to be revised - Name.Builtin: "#004461", # class: 'nb' - Name.Builtin.Pseudo: "#3465a4", # class: 'bp' - Name.Class: "#000000", # class: 'nc' - to be revised - Name.Constant: "#000000", # class: 'no' - to be revised - Name.Decorator: "#888", # class: 'nd' - to be revised - Name.Entity: "#ce5c00", # class: 'ni' - Name.Exception: "bold #cc0000", # class: 'ne' - Name.Function: "#000000", # class: 'nf' - Name.Property: "#000000", # class: 'py' - Name.Label: "#f57900", # class: 'nl' - Name.Namespace: "#000000", # class: 'nn' - to be revised - Name.Other: "#000000", # class: 'nx' - Name.Tag: "bold #004461", # class: 'nt' - like a keyword - Name.Variable: "#000000", # class: 'nv' - to be revised - Name.Variable.Class: "#000000", # class: 'vc' - to be revised - Name.Variable.Global: "#000000", # class: 'vg' - to be revised - Name.Variable.Instance: "#000000", # class: 'vi' - to be revised - - Number: "#990000", # class: 'm' - - Literal: "#000000", # class: 'l' - Literal.Date: "#000000", # class: 'ld' - - String: "#4e9a06", # class: 's' - String.Backtick: "#4e9a06", # class: 'sb' - String.Char: "#4e9a06", # class: 'sc' - String.Doc: "italic #8f5902", # class: 'sd' - like a comment - String.Double: "#4e9a06", # class: 's2' - String.Escape: "#4e9a06", # class: 'se' - String.Heredoc: "#4e9a06", # class: 'sh' - String.Interpol: "#4e9a06", # class: 'si' - String.Other: "#4e9a06", # class: 'sx' - String.Regex: "#4e9a06", # class: 'sr' - String.Single: "#4e9a06", # class: 's1' - String.Symbol: "#4e9a06", # class: 'ss' - - Generic: "#000000", # class: 'g' - Generic.Deleted: "#a40000", # class: 'gd' - Generic.Emph: "italic #000000", # class: 'ge' - Generic.Error: "#ef2929", # class: 'gr' - Generic.Heading: "bold #000080", # class: 'gh' - Generic.Inserted: "#00A000", # class: 'gi' - Generic.Output: "#888", # class: 'go' - Generic.Prompt: "#745334", # class: 'gp' - Generic.Strong: "bold #000000", # class: 'gs' - Generic.Subheading: "bold #800080", # class: 'gu' - Generic.Traceback: "bold #a40000", # class: 'gt' + Name: "#000000", # class: 'n' + Name.Attribute: "#c4a000", # class: 'na' - to be revised + Name.Builtin: "#004461", # class: 'nb' + Name.Builtin.Pseudo: "#3465a4", # class: 'bp' + Name.Class: "#000000", # class: 'nc' - to be revised + Name.Constant: "#000000", # class: 'no' - to be revised + Name.Decorator: "#888", # class: 'nd' - to be revised + Name.Entity: "#ce5c00", # class: 'ni' + Name.Exception: "bold #cc0000", # class: 'ne' + Name.Function: "#000000", # class: 'nf' + Name.Property: "#000000", # class: 'py' + Name.Label: "#f57900", # class: 'nl' + Name.Namespace: "#000000", # class: 'nn' - to be revised + Name.Other: "#000000", # class: 'nx' + Name.Tag: "bold #004461", # class: 'nt' - like a keyword + Name.Variable: "#000000", # class: 'nv' - to be revised + Name.Variable.Class: "#000000", # class: 'vc' - to be revised + Name.Variable.Global: "#000000", # class: 'vg' - to be revised + Name.Variable.Instance: "#000000", # class: 'vi' - to be revised + Number: "#990000", # class: 'm' + Literal: "#000000", # class: 'l' + Literal.Date: "#000000", # class: 'ld' + String: "#4e9a06", # class: 's' + String.Backtick: "#4e9a06", # class: 'sb' + String.Char: "#4e9a06", # class: 'sc' + String.Doc: "italic #8f5902", # class: 'sd' - like a comment + String.Double: "#4e9a06", # class: 's2' + String.Escape: "#4e9a06", # class: 'se' + String.Heredoc: "#4e9a06", # class: 'sh' + String.Interpol: "#4e9a06", # class: 'si' + String.Other: "#4e9a06", # class: 'sx' + String.Regex: "#4e9a06", # class: 'sr' + String.Single: "#4e9a06", # class: 's1' + String.Symbol: "#4e9a06", # class: 'ss' + Generic: "#000000", # class: 'g' + Generic.Deleted: "#a40000", # class: 'gd' + Generic.Emph: "italic #000000", # class: 'ge' + Generic.Error: "#ef2929", # class: 'gr' + Generic.Heading: "bold #000080", # class: 'gh' + Generic.Inserted: "#00A000", # class: 'gi' + Generic.Output: "#888", # class: 'go' + Generic.Prompt: "#745334", # class: 'gp' + Generic.Strong: "bold #000000", # class: 'gs' + Generic.Subheading: "bold #800080", # class: 'gu' + Generic.Traceback: "bold #a40000", # class: 'gt' } diff --git a/docs/conf.py b/docs/conf.py index ebe72a7a..ee27118a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,19 +1,15 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from __future__ import ( - division, - print_function, - absolute_import, - unicode_literals, -) - import os import sys +from importlib.metadata import version as get_version +from pathlib import Path -# Patch the path to get the local version. -d = os.path.dirname -sys.path.insert(0, d(d(os.path.abspath(__file__)))) +if "SPS_HOME" not in os.environ: + path = Path(__file__).absolute() + sps_home = path.parent.parent / "src" / "fsps" / "libfsps" + os.environ["SPS_HOME"] = str(sps_home) extensions = [ "sphinx.ext.autodoc", @@ -30,9 +26,8 @@ # General information about the project. project = "Python FSPS" -copyright = "2013-2021 Python-FSPS developers" -# version = -# release = +copyright = "2013-2023 Python-FSPS developers" +version = get_version("fsps") html_show_sphinx = True html_show_sourcelink = False diff --git a/docs/filter_table.rst b/docs/filter_table.rst index 78f1ae15..806664c5 100644 --- a/docs/filter_table.rst +++ b/docs/filter_table.rst @@ -1,120 +1,120 @@ === ================ ========== ======== =============== ======================================================================================== -ID Name M_sun Vega M_sun AB lambda_eff (Å) Description +ID Name M_sun Vega M_sun AB lambda_eff (Å) Description === ================ ========== ======== =============== ======================================================================================== -1 v 4.81 4.81 5477.6 Johnson V (from Bessell 1990 via M. Blanton) - this defines the Vega system -2 u 5.55 6.35 3584.8 Johnson U (from Bessell 1990 via M. Blanton) -3 b 5.46 5.35 4370.9 Johnson B (from Bessell 1990 via M. Blanton) -4 buser_b2 5.41 5.30 4433.5 Buser B2 (from BC03) -5 cousins_r 4.41 4.60 6576.9 Cousins R (from Bessell 1990 via M. Blanton) -6 cousins_i 4.10 4.52 7891.2 Cousins I (from Bessell 1990 via M. Blanton) -7 cfht_b 5.41 5.28 4418.6 CFHT B-band (from Blanton's kcorrect) -8 cfht_r 4.37 4.59 6616.0 CFHT R-band (from Blanton's kcorrect) -9 cfht_i 4.08 4.52 8166.0 CFHT I-band (from Blanton's kcorrect) -10 2mass_j 3.67 4.56 12387.7 2MASS J filter (total response w/atm) -11 2mass_h 3.34 4.70 16488.9 2MASS H filter (total response w/atm) -12 2mass_ks 3.30 5.14 21635.6 2MASS Ks filter (total response w/atm) -13 sdss_u 5.47 6.39 3556.5 SDSS Camera u Response Function, airmass = 1.3 (June 2001) -14 sdss_g 5.23 5.12 4702.5 SDSS Camera g Response Function, airmass = 1.3 (June 2001) -15 sdss_r 4.50 4.64 6175.6 SDSS Camera r Response Function, airmass = 1.3 (June 2001) -16 sdss_i 4.18 4.53 7489.9 SDSS Camera i Response Function, airmass = 1.3 (June 2001) -17 sdss_z 4.00 4.51 8946.8 SDSS Camera z Response Function, airmass = 1.3 (June 2001) -18 wfpc2_f255w 7.44 9.06 2601.0 HST WFPC2 F255W (``_) -19 wfpc2_f300w 6.05 7.40 2994.3 HST WFPC2 F300W (``_) -20 wfpc2_f336w 5.46 6.64 3359.2 HST WFPC2 F336W (``_) -21 wfpc2_f439w 5.51 5.36 4311.7 HST WFPC2 F439W (``_) -22 wfpc2_f450w 5.31 5.22 4555.6 HST WFPC2 F450W (``_) -23 wfpc2_f555w 4.83 4.82 5438.9 HST WFPC2 F555W (``_) -24 wfpc2_f606w 4.61 4.70 5996.8 HST WFPC2 F606W (``_) -25 wfpc2_f814w 4.11 4.52 8012.3 HST WFPC2 F814W (``_) -26 wfpc2_f850lp 4.00 4.52 9129.0 HST WFPC2 F850LP (``_) -27 wfc_acs_f435w 5.48 5.38 4318.1 HST ACS F435W (``_) -28 wfc_acs_f475w 5.21 5.10 4744.3 HST ACS F475W (``_) -29 wfc_acs_f555w 4.85 4.84 5359.5 HST ACS F555W (``_) -30 wfc_acs_f606w 4.64 4.72 5912.4 HST ACS F606W (``_) -31 wfc_acs_f625w 4.47 4.63 6310.5 HST ACS F625W (``_) -32 wfc_acs_f775w 4.14 4.53 7693.3 HST ACS F775W (``_) -33 wfc_acs_f814w 4.10 4.52 8059.6 HST ACS F814W (``_) -34 wfc_acs_f850lp 4.00 4.51 9054.5 HST ACS F850LP (``_) -35 wfc3_uvis_f218w 8.95 10.71 2226.5 HST WFC3 UVIS F218W (``_) Chip #1 -36 wfc3_uvis_f225w 8.37 10.10 2372.5 HST WFC3 UVIS F225W (``_) Chip #1 -37 wfc3_uvis_f275w 6.99 8.54 2710.1 HST WFC3 UVIS F275W (``_) Chip #1 -38 wfc3_uvis_f336w 5.47 6.65 3355.1 HST WFC3 UVIS F336W (``_) Chip #1 -39 wfc3_uvis_f390w 5.64 5.85 3924.4 HST WFC3 UVIS F390W (``_) Chip #1 -40 wfc3_uvis_f438w 5.49 5.34 4326.5 HST WFC3 UVIS F438W (``_) Chip #1 -41 wfc3_uvis_f475w 5.19 5.08 4773.7 HST WFC3 UVIS F475W (``_) Chip #1 -42 wfc3_uvis_f555w 4.89 4.86 5308.2 HST WFC3 UVIS F555W (``_) Chip #1 -43 wfc3_uvis_f606w 4.65 4.73 5887.4 HST WFC3 UVIS F606W (``_) Chip #1 -44 wfc3_uvis_f775w 4.15 4.53 7648.5 HST WFC3 UVIS F775W (``_) Chip #1 -45 wfc3_uvis_f814w 4.11 4.52 8029.5 HST WFC3 UVIS F814W (``_) Chip #1 -46 wfc3_uvis_f850lp 4.00 4.52 9168.9 HST WFC3 UVIS F850LP (``_) Chip #1 -47 wfc3_ir_f098m 3.96 4.51 9862.9 HST WFC3 IR F098M (``_) -48 wfc3_ir_f105w 3.89 4.53 10550.7 HST WFC3 IR F105W (``_) -49 wfc3_ir_f110w 3.79 4.54 11534.4 HST WFC3 IR F110W (``_) -50 wfc3_ir_f125w 3.67 4.56 12486.1 HST WFC3 IR F125W (``_) -51 wfc3_ir_f140w 3.52 4.60 13923.9 HST WFC3 IR F140W (``_) -52 wfc3_ir_f160w 3.40 4.65 15370.8 HST WFC3 IR F160W (``_) -53 irac_1 3.21 5.99 35569.7 Spitzer IRAC Channel 1 (3.6um) -54 irac_2 3.16 6.41 45020.4 Spitzer IRAC Channel 2 (4.5um) -55 irac_3 3.12 6.87 57454.1 Spitzer IRAC Channel 3 (5.8um) -56 irac_4 3.09 7.47 79162.1 Spitzer IRAC Channel 4 (8.0um) -57 isaac_ks 3.30 5.13 21622.1 ISAAC Ks -58 fors_v 4.78 4.79 5536.1 FORS V -59 fors_r 4.41 4.60 6564.6 FORS R -60 nicmos_f110w 3.82 4.54 11248.6 HST NICMOS F110W -61 nicmos_f160w 3.37 4.68 16060.4 HST NICMOS F160W -62 galex_fuv 14.91 17.24 1535.1 GALEX FUV -63 galex_nuv 8.41 10.15 2300.7 GALEX NUV -64 des_g 5.17 5.08 4800.9 DES g (from Huan Lin, for DES camera) -65 des_r 4.46 4.62 6362.6 DES r (from Huan Lin, for DES camera) -66 des_i 4.13 4.52 7750.1 DES i (from Huan Lin, for DES camera) -67 des_z 4.00 4.52 9153.7 DES z (from Huan Lin, for DES camera) -68 des_y 3.96 4.51 9907.8 DES Y (from Huan Lin, for DES camera) -69 wfcam_z 4.01 4.52 8826.3 WFCAM (UKIRT) Z (from Hewett et al. 2006, via A. Smith) -70 wfcam_y 3.91 4.51 10314.1 WFCAM (UKIRT) Y (from Hewett et al. 2006, via A. Smith) -71 wfcam_j 3.65 4.56 12500.9 WFCAM (UKIRT) J (from Hewett et al. 2006, via A. Smith) -72 wfcam_h 3.35 4.70 16359.1 WFCAM (UKIRT) H (from Hewett et al. 2006, via A. Smith) -73 wfcam_k 3.30 5.17 22084.0 WFCAM (UKIRT) K (from Hewett et al. 2006, via A. Smith) -74 steidel_un 5.44 6.34 3602.5 Steidel Un (via A. Shapley; see Steidel et al. 2003) -75 steidel_g 5.19 5.08 4753.2 Steidel G (via A. Shapley; see Steidel et al. 2003) -76 steidel_rs 4.33 4.58 6781.4 Steidel Rs (via A. Shapley; see Steidel et al. 2003) -77 steidel_i 4.09 4.52 7985.7 Steidel I (via A. Shapley; see Steidel et al. 2003) -78 megacam_u 5.68 6.03 3802.9 CFHT MegaCam u* (``_, Dec 2010) -79 megacam_g 5.14 5.05 4844.4 CFHT MegaCam g' (``_, Dec 2010) -80 megacam_r 4.48 4.63 6247.7 CFHT MegaCam r' (``_, Dec 2010) -81 megacam_i 4.17 4.53 7538.7 CFHT MegaCam i' (``_, Dec 2010) -82 megacam_z 4.00 4.51 8860.0 CFHT MegaCam z' (``_, Dec 2010) -83 wise_w1 3.22 5.89 33682.1 WISE W1, 3.4um (``_) -84 wise_w2 3.16 6.45 46178.9 WISE W2, 4.6um (``_) -85 wise_w3 3.06 8.19 120717.6 WISE W3, 12um (``_) -86 wise_w4 3.01 9.62 221933.5 WISE W4, 22um (``_) -87 uvot_w2 8.47 10.29 2057.9 UVOT W2 (from Erik Hoversten, 2011) -88 uvot_m2 8.84 10.60 2246.9 UVOT M2 (from Erik Hoversten, 2011) -89 uvot_w1 6.91 8.47 2582.6 UVOT W1 (from Erik Hoversten, 2011) -90 mips_24 3.00 9.74 235917.9 Spitzer MIPS 24um -91 mips_70 2.95 12.05 708981.4 Spitzer MIPS 70um -92 mips_160 2.92 13.78 1553640.7 Spitzer MIPS 160um -93 scuba_450wb 2.87 16.13 4561884.3 SCUBA 450WB (``_) -94 scuba_850wb 2.84 17.50 8563901.9 SCUBA 850WB (``_) -95 pacs_70 2.95 12.07 707688.0 Herschel PACS 70um -96 pacs_100 2.94 12.82 1007889.7 Herschel PACS 100um -97 pacs_160 2.92 13.81 1618854.2 Herschel PACS 160um -98 spire_250 2.90 14.78 2482638.8 Herschel SPIRE 250um -99 spire_350 2.88 15.52 3483962.4 Herschel SPIRE 350um -100 spire_500 2.86 16.27 5000972.5 Herschel SPIRE 500um -101 iras_12 3.06 8.05 110332.1 IRAS 12um -102 iras_25 3.01 9.62 230701.4 IRAS 25um -103 iras_60 2.97 11.50 581751.6 IRAS 60um -104 iras_100 2.94 12.77 994956.5 IRAS 100um -105 bessell_l 3.21 5.96 34800.1 Bessell L band (Bessell & Brett 1988) -106 bessell_lp 3.19 6.12 38275.9 Bessell L' band (Bessell & Brett 1988) -107 bessell_m 3.15 6.51 47328.3 Bessell M band (Bessell & Brett 1988) -108 stromgren_u 5.34 6.47 3478.5 Stromgren u (Bessell 2011) -109 stromgren_v 5.67 5.53 4107.9 Stromgren v (Bessell 2011) -110 stromgren_b 5.22 5.06 4665.3 Stromgren b (Bessell 2011) -111 stromgren_y 4.81 4.80 5459.0 Stromgren y (Bessell 2011) -112 1500a 15.67 18.05 1498.5 Idealized 1500A bandpass with 15% bandwidth, FWHM = 225A from M. Dickinson -113 2300a 8.85 10.62 2297.7 Idealized 2300A bandpass with 15% bandwidth, FWHM = 345A from M. Dickinson -114 2800a 6.72 8.20 2797.1 Idealized 2800A bandpass with 15% bandwidth, FWHM = 420A from M. Dickinson +1 v 4.81 4.81 5477.6 Johnson V (from Bessell 1990 via M. Blanton) - this defines the Vega system +2 u 5.55 6.35 3584.8 Johnson U (from Bessell 1990 via M. Blanton) +3 b 5.46 5.35 4370.9 Johnson B (from Bessell 1990 via M. Blanton) +4 buser_b2 5.41 5.30 4433.5 Buser B2 (from BC03) +5 cousins_r 4.41 4.60 6576.9 Cousins R (from Bessell 1990 via M. Blanton) +6 cousins_i 4.10 4.52 7891.2 Cousins I (from Bessell 1990 via M. Blanton) +7 cfht_b 5.41 5.28 4418.6 CFHT B-band (from Blanton's kcorrect) +8 cfht_r 4.37 4.59 6616.0 CFHT R-band (from Blanton's kcorrect) +9 cfht_i 4.08 4.52 8166.0 CFHT I-band (from Blanton's kcorrect) +10 2mass_j 3.67 4.56 12387.7 2MASS J filter (total response w/atm) +11 2mass_h 3.34 4.70 16488.9 2MASS H filter (total response w/atm) +12 2mass_ks 3.30 5.14 21635.6 2MASS Ks filter (total response w/atm) +13 sdss_u 5.47 6.39 3556.5 SDSS Camera u Response Function, airmass = 1.3 (June 2001) +14 sdss_g 5.23 5.12 4702.5 SDSS Camera g Response Function, airmass = 1.3 (June 2001) +15 sdss_r 4.50 4.64 6175.6 SDSS Camera r Response Function, airmass = 1.3 (June 2001) +16 sdss_i 4.18 4.53 7489.9 SDSS Camera i Response Function, airmass = 1.3 (June 2001) +17 sdss_z 4.00 4.51 8946.8 SDSS Camera z Response Function, airmass = 1.3 (June 2001) +18 wfpc2_f255w 7.44 9.06 2601.0 HST WFPC2 F255W (``_) +19 wfpc2_f300w 6.05 7.40 2994.3 HST WFPC2 F300W (``_) +20 wfpc2_f336w 5.46 6.64 3359.2 HST WFPC2 F336W (``_) +21 wfpc2_f439w 5.51 5.36 4311.7 HST WFPC2 F439W (``_) +22 wfpc2_f450w 5.31 5.22 4555.6 HST WFPC2 F450W (``_) +23 wfpc2_f555w 4.83 4.82 5438.9 HST WFPC2 F555W (``_) +24 wfpc2_f606w 4.61 4.70 5996.8 HST WFPC2 F606W (``_) +25 wfpc2_f814w 4.11 4.52 8012.3 HST WFPC2 F814W (``_) +26 wfpc2_f850lp 4.00 4.52 9129.0 HST WFPC2 F850LP (``_) +27 wfc_acs_f435w 5.48 5.38 4318.1 HST ACS F435W (``_) +28 wfc_acs_f475w 5.21 5.10 4744.3 HST ACS F475W (``_) +29 wfc_acs_f555w 4.85 4.84 5359.5 HST ACS F555W (``_) +30 wfc_acs_f606w 4.64 4.72 5912.4 HST ACS F606W (``_) +31 wfc_acs_f625w 4.47 4.63 6310.5 HST ACS F625W (``_) +32 wfc_acs_f775w 4.14 4.53 7693.3 HST ACS F775W (``_) +33 wfc_acs_f814w 4.10 4.52 8059.6 HST ACS F814W (``_) +34 wfc_acs_f850lp 4.00 4.51 9054.5 HST ACS F850LP (``_) +35 wfc3_uvis_f218w 8.95 10.71 2226.5 HST WFC3 UVIS F218W (``_) Chip #1 +36 wfc3_uvis_f225w 8.37 10.10 2372.5 HST WFC3 UVIS F225W (``_) Chip #1 +37 wfc3_uvis_f275w 6.99 8.54 2710.1 HST WFC3 UVIS F275W (``_) Chip #1 +38 wfc3_uvis_f336w 5.47 6.65 3355.1 HST WFC3 UVIS F336W (``_) Chip #1 +39 wfc3_uvis_f390w 5.64 5.85 3924.4 HST WFC3 UVIS F390W (``_) Chip #1 +40 wfc3_uvis_f438w 5.49 5.34 4326.5 HST WFC3 UVIS F438W (``_) Chip #1 +41 wfc3_uvis_f475w 5.19 5.08 4773.7 HST WFC3 UVIS F475W (``_) Chip #1 +42 wfc3_uvis_f555w 4.89 4.86 5308.2 HST WFC3 UVIS F555W (``_) Chip #1 +43 wfc3_uvis_f606w 4.65 4.73 5887.4 HST WFC3 UVIS F606W (``_) Chip #1 +44 wfc3_uvis_f775w 4.15 4.53 7648.5 HST WFC3 UVIS F775W (``_) Chip #1 +45 wfc3_uvis_f814w 4.11 4.52 8029.5 HST WFC3 UVIS F814W (``_) Chip #1 +46 wfc3_uvis_f850lp 4.00 4.52 9168.9 HST WFC3 UVIS F850LP (``_) Chip #1 +47 wfc3_ir_f098m 3.96 4.51 9862.9 HST WFC3 IR F098M (``_) +48 wfc3_ir_f105w 3.89 4.53 10550.7 HST WFC3 IR F105W (``_) +49 wfc3_ir_f110w 3.79 4.54 11534.4 HST WFC3 IR F110W (``_) +50 wfc3_ir_f125w 3.67 4.56 12486.1 HST WFC3 IR F125W (``_) +51 wfc3_ir_f140w 3.52 4.60 13923.9 HST WFC3 IR F140W (``_) +52 wfc3_ir_f160w 3.40 4.65 15370.8 HST WFC3 IR F160W (``_) +53 irac_1 3.21 5.99 35569.7 Spitzer IRAC Channel 1 (3.6um) +54 irac_2 3.16 6.41 45020.4 Spitzer IRAC Channel 2 (4.5um) +55 irac_3 3.12 6.87 57454.1 Spitzer IRAC Channel 3 (5.8um) +56 irac_4 3.09 7.47 79162.1 Spitzer IRAC Channel 4 (8.0um) +57 isaac_ks 3.30 5.13 21622.1 ISAAC Ks +58 fors_v 4.78 4.79 5536.1 FORS V +59 fors_r 4.41 4.60 6564.6 FORS R +60 nicmos_f110w 3.82 4.54 11248.6 HST NICMOS F110W +61 nicmos_f160w 3.37 4.68 16060.4 HST NICMOS F160W +62 galex_fuv 14.91 17.24 1535.1 GALEX FUV +63 galex_nuv 8.41 10.15 2300.7 GALEX NUV +64 des_g 5.17 5.08 4800.9 DES g (from Huan Lin, for DES camera) +65 des_r 4.46 4.62 6362.6 DES r (from Huan Lin, for DES camera) +66 des_i 4.13 4.52 7750.1 DES i (from Huan Lin, for DES camera) +67 des_z 4.00 4.52 9153.7 DES z (from Huan Lin, for DES camera) +68 des_y 3.96 4.51 9907.8 DES Y (from Huan Lin, for DES camera) +69 wfcam_z 4.01 4.52 8826.3 WFCAM (UKIRT) Z (from Hewett et al. 2006, via A. Smith) +70 wfcam_y 3.91 4.51 10314.1 WFCAM (UKIRT) Y (from Hewett et al. 2006, via A. Smith) +71 wfcam_j 3.65 4.56 12500.9 WFCAM (UKIRT) J (from Hewett et al. 2006, via A. Smith) +72 wfcam_h 3.35 4.70 16359.1 WFCAM (UKIRT) H (from Hewett et al. 2006, via A. Smith) +73 wfcam_k 3.30 5.17 22084.0 WFCAM (UKIRT) K (from Hewett et al. 2006, via A. Smith) +74 steidel_un 5.44 6.34 3602.5 Steidel Un (via A. Shapley; see Steidel et al. 2003) +75 steidel_g 5.19 5.08 4753.2 Steidel G (via A. Shapley; see Steidel et al. 2003) +76 steidel_rs 4.33 4.58 6781.4 Steidel Rs (via A. Shapley; see Steidel et al. 2003) +77 steidel_i 4.09 4.52 7985.7 Steidel I (via A. Shapley; see Steidel et al. 2003) +78 megacam_u 5.68 6.03 3802.9 CFHT MegaCam u* (``_, Dec 2010) +79 megacam_g 5.14 5.05 4844.4 CFHT MegaCam g' (``_, Dec 2010) +80 megacam_r 4.48 4.63 6247.7 CFHT MegaCam r' (``_, Dec 2010) +81 megacam_i 4.17 4.53 7538.7 CFHT MegaCam i' (``_, Dec 2010) +82 megacam_z 4.00 4.51 8860.0 CFHT MegaCam z' (``_, Dec 2010) +83 wise_w1 3.22 5.89 33682.1 WISE W1, 3.4um (``_) +84 wise_w2 3.16 6.45 46178.9 WISE W2, 4.6um (``_) +85 wise_w3 3.06 8.19 120717.6 WISE W3, 12um (``_) +86 wise_w4 3.01 9.62 221933.5 WISE W4, 22um (``_) +87 uvot_w2 8.47 10.29 2057.9 UVOT W2 (from Erik Hoversten, 2011) +88 uvot_m2 8.84 10.60 2246.9 UVOT M2 (from Erik Hoversten, 2011) +89 uvot_w1 6.91 8.47 2582.6 UVOT W1 (from Erik Hoversten, 2011) +90 mips_24 3.00 9.74 235917.9 Spitzer MIPS 24um +91 mips_70 2.95 12.05 708981.4 Spitzer MIPS 70um +92 mips_160 2.92 13.78 1553640.7 Spitzer MIPS 160um +93 scuba_450wb 2.87 16.13 4561884.3 SCUBA 450WB (``_) +94 scuba_850wb 2.84 17.50 8563901.9 SCUBA 850WB (``_) +95 pacs_70 2.95 12.07 707688.0 Herschel PACS 70um +96 pacs_100 2.94 12.82 1007889.7 Herschel PACS 100um +97 pacs_160 2.92 13.81 1618854.2 Herschel PACS 160um +98 spire_250 2.90 14.78 2482638.8 Herschel SPIRE 250um +99 spire_350 2.88 15.52 3483962.4 Herschel SPIRE 350um +100 spire_500 2.86 16.27 5000972.5 Herschel SPIRE 500um +101 iras_12 3.06 8.05 110332.1 IRAS 12um +102 iras_25 3.01 9.62 230701.4 IRAS 25um +103 iras_60 2.97 11.50 581751.6 IRAS 60um +104 iras_100 2.94 12.77 994956.5 IRAS 100um +105 bessell_l 3.21 5.96 34800.1 Bessell L band (Bessell & Brett 1988) +106 bessell_lp 3.19 6.12 38275.9 Bessell L' band (Bessell & Brett 1988) +107 bessell_m 3.15 6.51 47328.3 Bessell M band (Bessell & Brett 1988) +108 stromgren_u 5.34 6.47 3478.5 Stromgren u (Bessell 2011) +109 stromgren_v 5.67 5.53 4107.9 Stromgren v (Bessell 2011) +110 stromgren_b 5.22 5.06 4665.3 Stromgren b (Bessell 2011) +111 stromgren_y 4.81 4.80 5459.0 Stromgren y (Bessell 2011) +112 1500a 15.67 18.05 1498.5 Idealized 1500A bandpass with 15% bandwidth, FWHM = 225A from M. Dickinson +113 2300a 8.85 10.62 2297.7 Idealized 2300A bandpass with 15% bandwidth, FWHM = 345A from M. Dickinson +114 2800a 6.72 8.20 2797.1 Idealized 2800A bandpass with 15% bandwidth, FWHM = 420A from M. Dickinson 115 jwst_f070w nan nan nan JWST F070W (``_) 116 jwst_f090w nan nan nan JWST F090W (``_) 117 jwst_f115w nan nan nan JWST F115W (``_) diff --git a/docs/index.rst b/docs/index.rst index b6e4089e..92a74446 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -31,7 +31,7 @@ Contributors License ------- -*Copyright 2013-2021 Python-FSPS developers.* +*Copyright 2013-2023 Python-FSPS developers.* These bindings are available under the `MIT License `_. diff --git a/pyproject.toml b/pyproject.toml index 22758a55..d9d5b581 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,9 +1,7 @@ [project] name = "fsps" description = "Python bindings for Charlie Conroy's FSPS" -authors = [ - { name="Dan Foreman-Mackey", email="foreman.mackey@gmail.com" }, -] +authors = [{ name = "Dan Foreman-Mackey", email = "foreman.mackey@gmail.com" }] readme = "README.rst" requires-python = ">=3.9" license = { text = "MIT License" } @@ -34,7 +32,12 @@ build-backend = "scikit_build_core.build" ninja.minimum-version = "1.10" cmake.minimum-version = "3.17.2" sdist.exclude = ["src/fsps/libfsps"] -sdist.include = ["src/fsps/libfsps/src/*.f90", "src/fsps/libfsps/LICENSE", "src/fsps/libfsps/README", "src/fsps/fsps_version.py"] +sdist.include = [ + "src/fsps/libfsps/src/*.f90", + "src/fsps/libfsps/LICENSE", + "src/fsps/libfsps/README", + "src/fsps/fsps_version.py", +] metadata.version.provider = "scikit_build_core.metadata.setuptools_scm" [tool.setuptools_scm] @@ -43,4 +46,25 @@ write_to = "src/fsps/fsps_version.py" [tool.cibuildwheel] skip = "pp* *-win32 *-musllinux_* *-manylinux_i686" test-command = "python {project}/tests/simple.py" -environment = {SPS_HOME = "$(pwd)/src/fsps/libfsps"} +environment = { SPS_HOME = "$(pwd)/src/fsps/libfsps" } + +[tool.black] +target-version = ["py38", "py39"] +line-length = 88 + +[tool.ruff] +line-length = 88 +target-version = "py39" +select = ["F", "I", "E", "W", "YTT", "B", "Q", "PLE", "PLR", "PLW"] +ignore = [ + "E402", # Allow module level imports below top of file + "E741", # Allow ambiguous variable names + "PLW0603", # Allow global statements + "PLR0912", # Allow many branches + "PLR0913", # Allow many arguments to function calls + "PLR2004", # Allow magic numbers +] +exclude = ["demos/*"] + +[tool.ruff.isort] +known-first-party = ["fsps"] diff --git a/readthedocs.yml b/readthedocs.yml new file mode 100644 index 00000000..4cbeff25 --- /dev/null +++ b/readthedocs.yml @@ -0,0 +1,23 @@ +version: 2 + +submodules: + include: all + +build: + os: ubuntu-20.04 + apt_packages: + - gcc + - g++ + - gfortran + tools: + python: "3.10" + +python: + install: + - method: pip + path: . + +sphinx: + builder: dirhtml + configuration: docs/conf.py + fail_on_warning: true diff --git a/scripts/fsps_filter_table.py b/scripts/fsps_filter_table.py index 0b260257..fcec729c 100755 --- a/scripts/fsps_filter_table.py +++ b/scripts/fsps_filter_table.py @@ -7,18 +7,20 @@ Sphinx documentation. """ -from __future__ import print_function, absolute_import +from __future__ import absolute_import, print_function import re + import fsps # Pattern via https://gist.github.com/uogbuji/705383 -URL_P = re.compile(ur'(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?\xab\xbb\u201c\u201d\u2018\u2019]))') # NOQA +URL_P = re.compile( + r'(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?\xab\xbb\u201c\u201d\u2018\u2019]))' +) def main(): - colnames = ("ID", "Name", "M_sun Vega", "M_sun AB", "lambda_eff (Å)", - "Description") + colnames = ("ID", "Name", "M_sun Vega", "M_sun AB", "lambda_eff (Å)", "Description") filters = [fsps.get_filter(name) for name in fsps.list_filters()] filter_list = make_filter_list(filters) txt = make_table(filter_list, colnames) @@ -31,14 +33,21 @@ def make_filter_list(filters): filter_ids = [] for f in filters: filter_ids.append(f.index) - fullname = URL_P.sub(r'`<\1>`_', f.fullname) - filter_list.append((str(f.index + 1), - f.name, - "{0:.2f}".format(f.msun_vega), - "{0:.2f}".format(f.msun_ab), - "{0:.1f}".format(f.lambda_eff), - fullname)) - sortf = lambda item: int(item[0]) + fullname = URL_P.sub(r"`<\1>`_", f.fullname) + filter_list.append( + ( + str(f.index + 1), + f.name, + "{0:.2f}".format(f.msun_vega), + "{0:.2f}".format(f.msun_ab), + "{0:.1f}".format(f.lambda_eff), + fullname, + ) + ) + + def sortf(item): + return int(item[0]) + filter_list.sort(key=sortf) return filter_list @@ -53,13 +62,13 @@ def make_table(data, col_names): for i, cname in enumerate(col_names): if col_sizes[i] < len(cname): col_sizes[i] = len(cname) - formatter = ' '.join('{:<%d}' % c for c in col_sizes) - rows = '\n'.join([formatter.format(*row) for row in data]) + formatter = " ".join("{:<%d}" % c for c in col_sizes) + rows = "\n".join([formatter.format(*row) for row in data]) header = formatter.format(*col_names) - divider = formatter.format(*['=' * c for c in col_sizes]) - output = '\n'.join((divider, header, divider, rows, divider)) + divider = formatter.format(*["=" * c for c in col_sizes]) + output = "\n".join((divider, header, divider, rows, divider)) return output -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/src/fsps/CMakeLists.txt b/src/fsps/CMakeLists.txt index c45ef899..42632aff 100644 --- a/src/fsps/CMakeLists.txt +++ b/src/fsps/CMakeLists.txt @@ -70,5 +70,5 @@ python_add_library( "${F2PY_INCLUDE_DIR}/fortranobject.c" WITH_SOABI) target_link_libraries(_fsps PUBLIC Python::NumPy) -target_include_directories(_fsps PUBLIC "${F2PY_INCLUDE_DIR}") +target_include_directories(_fsps PUBLIC "${F2PY_INCLUDE_DIR}") install(TARGETS _fsps DESTINATION ${SKBUILD_PROJECT_NAME}) diff --git a/src/fsps/__init__.py b/src/fsps/__init__.py index ddc995a5..d97fb909 100644 --- a/src/fsps/__init__.py +++ b/src/fsps/__init__.py @@ -6,10 +6,13 @@ del check_sps_home # End check -from fsps.fsps_version import version as __version__ -from fsps.fsps import StellarPopulation as StellarPopulation from fsps.filters import ( find_filter as find_filter, +) +from fsps.filters import ( get_filter as get_filter, +) +from fsps.filters import ( list_filters as list_filters, ) +from fsps.fsps import StellarPopulation as StellarPopulation diff --git a/src/fsps/filters.py b/src/fsps/filters.py index 14e316f0..a2df5261 100755 --- a/src/fsps/filters.py +++ b/src/fsps/filters.py @@ -8,6 +8,7 @@ __all__ = ["find_filter", "FILTERS", "get_filter", "list_filters"] import os + import numpy as np # Cache for $SPS_HOME/data/magsun.dat parsed by numpy @@ -117,7 +118,7 @@ def _load_transmission_cache(self): l, t = line.split() lambdas.append(float(l)) trans.append(float(t)) - except (ValueError): + except ValueError: pass # Close out the last filter TRANS_CACHE[names[filter_index]] = (np.array(lambdas), np.array(trans)) diff --git a/src/fsps/fsps.py b/src/fsps/fsps.py index 21133f39..fd7a1b8d 100644 --- a/src/fsps/fsps.py +++ b/src/fsps/fsps.py @@ -1,6 +1,7 @@ __all__ = ["StellarPopulation"] import os + import numpy as np from fsps._fsps import driver @@ -97,8 +98,8 @@ class StellarPopulation(object): :param nebemlineinspec: (default: True) Flag to include the emission line fluxes in the spectrum. Turning this off - is a significant speedup in model calculation time. If not set, the line luminosities - are still computed. + is a significant speedup in model calculation time. If not set, the line + luminosities are still computed. :param smooth_velocity: (default: True) Switch to choose smoothing in velocity space (``True``) or wavelength @@ -218,8 +219,9 @@ class StellarPopulation(object): M_\odot`. Only used if ``imf_type=2``. :param imf3: (default: 2.3) - Logarithmic slope of the IMF over the range :math:`1.0 < M < \mathrm{imf\_upper\_limit} - M_\odot`. Only used if ``imf_type=2``. + Logarithmic slope of the IMF over the range + :math:`1.0 < M < \mathrm{imf\_upper\_limit} M_\odot`. + Only used if ``imf_type=2``. :param vdmc: (default: 0.08) IMF parameter defined in van Dokkum (2008). Only used if @@ -446,7 +448,6 @@ class StellarPopulation(object): def __init__( self, compute_vega_mags=False, vactoair_flag=False, zcontinuous=0, **kwargs ): - # Set up the parameters to their default values. self.params = ParameterSet( add_agb_dust_model=True, @@ -609,7 +610,7 @@ def get_spectrum(self, zmet=None, tage=0.0, peraa=False): wavegrid = self.wavelengths if peraa: - factor = 3e18 / wavegrid ** 2 + factor = 3e18 / wavegrid**2 else: factor = np.ones_like(wavegrid) @@ -693,11 +694,10 @@ def get_mags(self, zmet=None, tage=0.0, redshift=None, bands=None): return mags[0, user_sorted_inds] else: return mags[0, :] + elif bands is not None: + return mags[:, user_sorted_inds] else: - if bands is not None: - return mags[:, user_sorted_inds] - else: - return mags + return mags def _ztinterp(self, zpos, tpos, peraa=False): r""" @@ -735,7 +735,7 @@ def _ztinterp(self, zpos, tpos, peraa=False): if peraa: wavegrid = self.wavelengths - factor = 3e18 / wavegrid ** 2 + factor = 3e18 / wavegrid**2 spec *= factor return spec, mass, lbol @@ -776,7 +776,7 @@ def _all_ssp_spec(self, update=True, peraa=False): if peraa: wavegrid = self.wavelengths - factor = 3e18 / wavegrid ** 2 + factor = 3e18 / wavegrid**2 spec *= factor[:, None, None] return spec, mass, lbol @@ -799,19 +799,19 @@ def _csp_young_old(self): @property def _ssp_weights(self): - """Get the weights of the SSPs for the CSP + r"""Get the weights of the SSPs for the CSP - :returns weights: - The weights ``w`` of each SSP s.t. the total spectrum is the sum - :math:`L_{\lambda} = \sum_i,j w_i,j \, S_{i,j,\lambda}` where - math:`i,j` run over age and metallicity. - """ + :returns weights: + The weights ``w`` of each SSP s.t. the total spectrum is the sum + :math:`L_{\lambda} = \sum_i,j w_i,j \, S_{i,j,\lambda}` where + math:`i,j` run over age and metallicity. + """ - NTFULL = driver.get_ntfull() - NZ = driver.get_nz() - weights = np.zeros([NTFULL, NZ], order="F") - driver.get_ssp_weights(weights) - return weights + NTFULL = driver.get_ntfull() + NZ = driver.get_nz() + weights = np.zeros([NTFULL, NZ], order="F") + driver.get_ssp_weights(weights) + return weights def _get_stellar_spectrum( self, @@ -875,7 +875,7 @@ def _get_stellar_spectrum( ) if peraa: wavegrid = self.wavelengths - factor = 3e18 / wavegrid ** 2 + factor = 3e18 / wavegrid**2 outspec *= factor return outspec @@ -1082,8 +1082,8 @@ def wavelengths(self): @property def resolutions(self): r"""The resolution array, in km/s dispersion. Negative numbers indicate - poorly defined, approximate, resolution (based on coarse opacity - binning in theoretical spectra)""" + poorly defined, approximate, resolution (based on coarse opacity + binning in theoretical spectra)""" if self._resolutions is None: NSPEC = driver.get_nspec() self._resolutions = driver.get_res(NSPEC) @@ -1231,7 +1231,8 @@ def sfr_avg(self, times=None, dt=0.1): avsfr = (mass[..., 0] - mass[..., 1]) / dt / 1e9 # Msun/yr - # These lines change behavior when you request sfrs outside the range (sf_start + dt, tage) + # These lines change behavior when you request sfrs outside the range + # (sf_start + dt, tage) # avsfr[times > tage] = np.nan # does not work for scalars avsfr *= times <= tage # avsfr[np.isfinite(avsfr)] = 0.0 # does not work for scalars @@ -1261,7 +1262,6 @@ def libraries(self): class ParameterSet(object): - ssp_params = [ "imf_type", "imf_upper_limit", diff --git a/tests/options.py b/tests/options.py index b54bcc61..70cf7fca 100644 --- a/tests/options.py +++ b/tests/options.py @@ -1,5 +1,5 @@ import fsps sps = fsps.StellarPopulation() -assert sps.libraries[0] == b'pdva', "Incorrect isochrone library" -assert sps.libraries[1] == b'basel', "Incorrect spectral library" +assert sps.libraries[0] == b"pdva", "Incorrect isochrone library" +assert sps.libraries[1] == b"basel", "Incorrect spectral library" diff --git a/tests/tests.py b/tests/tests.py index 44b7f6ab..19a60635 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -2,11 +2,13 @@ import os import sys + import numpy as np import pytest -from fsps import StellarPopulation, filters from numpy.testing import assert_allclose +from fsps import StellarPopulation, filters + skip_slow_tests = pytest.mark.skipif( (sys.platform.startswith("win") or sys.platform.startswith("darwin")) and "CI" in os.environ, @@ -36,7 +38,7 @@ def test_isochrones(pop_and_params): pop, params = pop_and_params _reset_default_params(pop, params) pop.params["imf_type"] = 0 - iso = pop.isochrones() + pop.isochrones() @skip_slow_tests @@ -68,7 +70,6 @@ def test_imf3(pop_and_params): def test_param_checks(pop_and_params): - # recomputes SSPs pop, params = pop_and_params @@ -92,7 +93,6 @@ def test_param_checks(pop_and_params): def test_smooth_lsf(pop_and_params): - # recomputes SSPs pop, params = pop_and_params @@ -385,12 +385,13 @@ def test_ssp_weights(pop_and_params): _reset_default_params(pop, params) import os + fn = os.path.join(os.environ["SPS_HOME"], "data/sfh.dat") age, sfr, z = np.genfromtxt(fn, unpack=True, skip_header=0) pop.params["sfh"] = 3 pop.set_tabular_sfh(age, sfr) zind = -3 - pop.params["logzsol"] = np.log10(pop.zlegend[zind]/pop.solar_metallicity) + pop.params["logzsol"] = np.log10(pop.zlegend[zind] / pop.solar_metallicity) wave, spec = pop.get_spectrum(tage=age.max()) mstar = pop.stellar_mass diff --git a/tools/f2py_include.py b/tools/f2py_include.py index 5a5a3470..3f997fe4 100755 --- a/tools/f2py_include.py +++ b/tools/f2py_include.py @@ -7,4 +7,4 @@ except AttributeError: import os - print(os.path.join(os.path.dirname(numpy.f2py.__file__), 'src')) + print(os.path.join(os.path.dirname(numpy.f2py.__file__), "src")) diff --git a/tools/version.py b/tools/version.py deleted file mode 100755 index 8afa9d7a..00000000 --- a/tools/version.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python3 - -from pathlib import Path - -if Path(".git").exists(): - from setuptools_scm._cli import main - - main() - -elif Path("src/fsps/fsps_version.py").exists(): - with open("src/fsps/fsps_version.py", "r") as f: - exec(f.read()) - - print(version) - -else: - print("unknown")