diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 84599c4..5f2e2b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,8 +4,8 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: 3.9 - name: Install dependencies @@ -26,7 +26,7 @@ jobs: coverage report -m coverage xml - name: Upload coverage report to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} files: coverage.xml diff --git a/README.md b/README.md index bc1fa3e..8f07bc1 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,8 @@ pyPAHdb can be directly installed from the `pip install git+https://github.com/PAHdb/pyPAHdb.git` +Note that upon first run a pre-computed matrix will be automatically downloaded. + ## Supported data formats pyPAHdb supports reading IPAC tables, _Spitzer_ FITS files and _JWST_ FITS files. diff --git a/pypahdb/decomposer_base.py b/pypahdb/decomposer_base.py index 30023c8..6eaf591 100644 --- a/pypahdb/decomposer_base.py +++ b/pypahdb/decomposer_base.py @@ -15,9 +15,11 @@ import os import pickle from functools import partial +from urllib.request import urlretrieve +import importlib_resources import numpy as np -import pkg_resources +from tqdm import tqdm from astropy import units as u from scipy import optimize from specutils import Spectrum1D @@ -115,16 +117,38 @@ def __init__(self, spectrum): print("spectral data is all zeros.") return None - # Retrieve the precomputed data and raise error if file is - # not found. - file_name = "resources/precomputed.pkl" - file_path = pkg_resources.resource_filename("pypahdb", file_name) - with open(file_path, "rb") as f: - try: - self._precomputed = pickle.load(f, encoding="latin1") - except Exception as e: - print("Python 3 is required for pypahdb.") - raise (e) + # Download the precomputed data if not present + remote_pkl = "https://www.astrochemistry.org/pahdb/pypahdb/pickle.php" + if os.getenv("GITHUB_ACTIONS") == "true": + remote_pkl += "?github_actions=true" + local_pkl = ( + importlib_resources.files("pypahdb") / "resources/precomputed.pkl" + ) + if not os.path.isfile(local_pkl): + + def hook(t): + last_b = [0] + + def inner(b=1, bsize=1, tsize=None): + if tsize is not None: + t.total = tsize + t.update((b - last_b[0]) * bsize) + last_b[0] = b + return inner + + print("downloading pre-computed matrix") + with tqdm( + unit="B", + unit_scale=True, + leave=True, + miniters=1, + ) as t: + urlretrieve( + remote_pkl, filename=local_pkl, reporthook=hook(t), data=None + ) + + with open(local_pkl, "rb") as f: + self._precomputed = pickle.load(f, encoding="latin1") # Linearly interpolate the precomputed spectra onto the # frequency grid of the input spectrum. diff --git a/requirements.txt b/requirements.txt index 773ce1c..17cb00f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,5 @@ scipy astropy specutils matplotlib +importlib_resources +tqdm \ No newline at end of file diff --git a/setup.py b/setup.py index 634069d..fec2fd6 100644 --- a/setup.py +++ b/setup.py @@ -1,13 +1,7 @@ -from os import path -from os import getenv from setuptools import setup, find_packages -from setuptools.command.build_py import build_py import versioneer -try: - from urllib.request import urlopen -except ImportError: - from urllib2 import urlopen +from os import path """ NOTE: This file must remain Python 2 compatible for the foreseeable future, @@ -39,21 +33,6 @@ requirements = [line for line in requirements_file.read().splitlines() if not line.startswith('#')] - -class BuildPyCommand(build_py): - def run(self): - remote_pkl = 'https://www.astrochemistry.org/pahdb/pypahdb/pickle.php' - if getenv('GITHUB_ACTIONS') == 'true': - remote_pkl += '?github_actions=true' - local_pkl = 'pypahdb/resources/precomputed.pkl' - # honor the --dry-run flag - if not self.dry_run and not path.isfile(local_pkl): - response = urlopen(remote_pkl) - with open(path.join(here, local_pkl), 'wb') as f: - f.write(response.read()) - versioneer.get_cmdclass()['build_py'].run(self) - build_py.run(self) - # Arguments marked as "Required" below must be included for upload to PyPI. # Fields marked as "Optional" may be commented out. @@ -222,6 +201,5 @@ def run(self): # Run custom commands cmdclass={ # Optional - 'build_py': BuildPyCommand, }, )