Repository: nanograv/enterprise (language: python)

Issue:
Remove soft replacement for missing sksparse
In two places there are try-except statements that try to import sksparse and replace it with scipy otherwise. This prints or logs a message but I think we should get rid of this and require sksparse.

Especially after #257 is merged and `scikit-sparse` becomes an official dependency


Discussion / hints:
I support requiring sksparse and not defaulting to scipy: it's too confusing to support sparse cholesky through different libraries. Please go ahead with a PR if you have the code ready.
@vallis I'll get to this soon. I was off last week, hence the burst of activity but now it may have to wait til the weekend.

Fix patch:
diff --git a/README.rst b/README.rst
index 2c80810e..698ef35c 100644
--- a/README.rst
+++ b/README.rst
@@ -12,7 +12,7 @@ enterprise
 .. image:: https://codecov.io/gh/nanograv/enterprise/branch/master/graph/badge.svg?token=YXSX3293VF
         :target: https://codecov.io/gh/nanograv/enterprise
         :alt: Test Coverage
-.. image:: https://img.shields.io/badge/python-3.6%2C%203.7%2C%203.8-blue.svg
+.. image:: https://img.shields.io/badge/python-3.6%2C%203.7%2C%203.8%2C%203.9-blue.svg
         :alt: Python Versions
 
 .. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.4059815.svg
diff --git a/enterprise/signals/signal_base.py b/enterprise/signals/signal_base.py
index 306db7e2..58ac1375 100644
--- a/enterprise/signals/signal_base.py
+++ b/enterprise/signals/signal_base.py
@@ -17,6 +17,7 @@
 import scipy.linalg as sl
 import scipy.sparse as sps
 import six
+from sksparse.cholmod import cholesky
 
 # these are defined in parameter.py, but currently imported
 # in various places from signal_base.py
@@ -29,28 +30,6 @@
 logger = logging.getLogger(__name__)
 
 
-try:
-    from sksparse.cholmod import cholesky
-except ImportError:
-    msg = "No sksparse library. Using scipy instead!"
-    logger.warning(msg)
-
-    class cholesky(object):
-        def __init__(self, x):
-            if sps.issparse(x):
-                x = x.toarray()
-            self.cf = sl.cho_factor(x)
-
-        def __call__(self, other):
-            return sl.cho_solve(self.cf, other)
-
-        def logdet(self):
-            return np.sum(2 * np.log(np.diag(self.cf[0])))
-
-        def inv(self):
-            return sl.cho_solve(self.cf, np.eye(len(self.cf[0])))
-
-
 class MetaSignal(type):
     """Metaclass for Signals. Allows addition of ``Signal`` classes."""
 
diff --git a/enterprise/signals/utils.py b/enterprise/signals/utils.py
index 045ff9d4..55b1d545 100644
--- a/enterprise/signals/utils.py
+++ b/enterprise/signals/utils.py
@@ -13,6 +13,7 @@
 from pkg_resources import Requirement, resource_filename
 from scipy.integrate import odeint
 from scipy.interpolate import interp1d
+from sksparse.cholmod import cholesky
 
 import enterprise
 from enterprise import constants as const
@@ -29,11 +30,6 @@
 
 logger = logging.getLogger(__name__)
 
-try:
-    from sksparse.cholmod import cholesky
-except ImportError:  # pragma no cover
-    logger.warning("sksparse not installed. You'll need sksparse for get_coefficients() with common signals!")
-
 
 def get_coefficients(pta, params, n=1, phiinv_method="cliques", common_sparse=False):
     ret = []
diff --git a/requirements.txt b/requirements.txt
index 692e4acd..4912ca8c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,6 +3,6 @@ scipy>=1.2.0
 ephem>=3.7.6.0
 jplephem==2.6
 healpy>=1.14.0
-scikit-sparse>=0.4.2
+sksparse>=0.4.5
 pint-pulsar>=0.8.2
 libstempo>=2.4.0
diff --git a/setup.py b/setup.py
index 5ab831a4..70ea0554 100644
--- a/setup.py
+++ b/setup.py
@@ -15,7 +15,7 @@
     "ephem>=3.7.6.0",
     "jplephem==2.6",
     "healpy>=1.14.0",
-    "scikit-sparse>=0.4.2",
+    "scikit-sparse>=0.4.5",
     "pint-pulsar>=0.8.2",
     "libstempo>=2.4.0",
 ]
@@ -35,7 +35,7 @@
     package_dir={"enterprise": "enterprise"},
     include_package_data=True,
     package_data={"enterprise": ["datafiles/*", "datafiles/ephemeris/*", "datafiles/ng9/*", "datafiles/mdc_open1/*"]},
-    python_requires=">=3.6, <3.9",
+    python_requires=">=3.6, <3.10",
     install_requires=requirements,
     license="MIT license",
     zip_safe=False,
@@ -50,6 +50,7 @@
         "Programming Language :: Python :: 3.6",
         "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: 3.8",
+        "Programming Language :: Python :: 3.9",
         "Topic :: Scientific/Engineering :: Astronomy",
         "Topic :: Scientific/Engineering :: Physics",
     ],


Test patch:
diff --git a/.github/workflows/ci_test.yml b/.github/workflows/ci_test.yml
index b07cfcb3..2c964604 100644
--- a/.github/workflows/ci_test.yml
+++ b/.github/workflows/ci_test.yml
@@ -17,7 +17,7 @@ jobs:
       fail-fast: false
       matrix:
         os: [ubuntu-latest, macos-latest]
-        python-version: [3.6, 3.7, 3.8]
+        python-version: [3.6, 3.7, 3.8, 3.9]
 
     steps:
     - name: Checkout repository
@@ -41,7 +41,6 @@ jobs:
       run: |
         python -m pip install --upgrade pip setuptools wheel
         python -m pip install flake8 pytest black pytest-cov
-        python -m pip install numpy cython
         python -m pip install -e .
     - name: Display Python, pip, setuptools, and all installed versions
       run: |
@@ -78,7 +77,6 @@ jobs:
     - name: Build
       run: |
         python -m pip install --upgrade pip setuptools wheel
-        pip install numpy==1.16.3 cython
         pip install -r requirements.txt
         make dist
     - name: Test the sdist
@@ -87,7 +85,6 @@ jobs:
         cd tmp
         python -m venv venv-sdist
         venv-sdist/bin/python -m pip install --upgrade pip setuptools wheel
-        venv-sdist/bin/python -m pip install numpy cython
         venv-sdist/bin/python -m pip install ../dist/enterprise*.tar.gz
         venv-sdist/bin/python -c "import enterprise;print(enterprise.__version__)"
     - name: Test the wheel
@@ -96,7 +93,6 @@ jobs:
         cd tmp2
         python -m venv venv-wheel
         venv-wheel/bin/python -m pip install --upgrade pip setuptools
-        venv-wheel/bin/python -m pip install numpy cython
         venv-wheel/bin/python -m pip install ../dist/enterprise*.whl
         venv-wheel/bin/python -c "import enterprise;print(enterprise.__version__)"
     - uses: actions/upload-artifact@v2