Repository: JaimeRosado/ShowerModel (language: python)

Issue:
Add package data
I think toml files within the constant folder were not included when installing the library in the GH actions CI workflow. I added them to the `package_data` in `setup.py` so they are included when installing the package.

I also updated the tests for the `Telescope` class since IACT does not exist anymore.
Use nblink to avoid using duplicated notebooks
The package nblink allows using notebooks that do not live inside the sphinx doc directory. In this way, we are able to use the notebooks under the `notebook` directory and avoid duplicated notebooks.

- `nblink` was added as dependency for building the docs in `setup.py`
- In docs/tutorials, relative paths are used instead of copying the original notebooks


Discussion / hints:

# [Codecov](https://codecov.io/gh/JaimeRosado/ShowerModel/pull/33?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
> Merging [#33](https://codecov.io/gh/JaimeRosado/ShowerModel/pull/33?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (0dc2d5a) into [master](https://codecov.io/gh/JaimeRosado/ShowerModel/commit/f0ecdac05f37473993238bd82f24d6346c6c6934?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (f0ecdac) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/JaimeRosado/ShowerModel/pull/33/graphs/tree.svg?width=650&height=150&src=pr&token=EN78UL546D&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)](https://codecov.io/gh/JaimeRosado/ShowerModel/pull/33?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)

```diff
@@           Coverage Diff           @@
##           master      #33   +/-   ##
=======================================
  Coverage   30.08%   30.08%           
=======================================
  Files          21       21           
  Lines        1765     1765           
=======================================
  Hits          531      531           
  Misses       1234     1234           
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `30.08% <ø> (ø)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/JaimeRosado/ShowerModel/pull/33?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | |
|---|---|---|
| [setup.py](https://codecov.io/gh/JaimeRosado/ShowerModel/pull/33/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c2V0dXAucHk=) | `0.00% <ø> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/JaimeRosado/ShowerModel/pull/33?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/JaimeRosado/ShowerModel/pull/33?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None). Last update [f0ecdac...0dc2d5a](https://codecov.io/gh/JaimeRosado/ShowerModel/pull/33?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).


Fix patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index db88e8c..e2d2b53 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,6 +1,12 @@
 name: CI
 
-on: [push, pull_request]
+on:
+  push:
+    branches:
+      - master
+    tags:
+      - '**'
+  pull_request:
 
 env:
   MPLBACKEND: Agg
@@ -8,30 +14,40 @@ env:
 
 jobs:
   tests:
-    runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: [3.7, 3.8]
+        python-version:
+          - "3.7"
+          - "3.8"
+          - "3.9"
+          - "3.10"
+        os:
+          - ubuntu-latest
+          - macos-latest
+          - windows-latest
+
+    runs-on: ${{ matrix.os }}
 
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
+
       - name: Set up Python ${{ matrix.python-version }}
-        uses: actions/setup-python@v2
+        uses: actions/setup-python@v4
         with:
           python-version: ${{ matrix.python-version }}
+
       - name: Install dependencies
         run: |
           python -m pip install --upgrade pip
-          pip install pytest pytest-cov
-          python -m pip install .
-          python -m pip freeze
+          python -m pip install .[tests]
+
       - name: Test with pytest
         run: |
-          pytest -v --cov=./ --cov-report=xml
+          pytest -vv src/showermodel --cov=showermodel --cov-report=xml
+
       - name: Upload coverage to Codecov
-        uses: codecov/codecov-action@v1
+        uses: codecov/codecov-action@v3
+        if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.8'
         with:
           file: ./coverage.xml
-          flags: unittests
-          name: codecov-umbrella
           fail_ci_if_error: true
diff --git a/MANIFEST.in b/MANIFEST.in
index 854a0af..64ca818 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,2 +1,3 @@
-exclude showermodel/_dev_version.py
-global-exclude *.pyc *.o
\ No newline at end of file
+prune src/showermodel/_dev_version
+prune .github
+recursive-include extra *.dat *.toml *.xlsx
\ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
index 9b124b5..9d28a1e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,3 +1,6 @@
 [build-system]
-requires = ["setuptools >= 45", "wheel", "setuptools_scm[toml]>=6.0"]
-build-backend = "setuptools.build_meta"
\ No newline at end of file
+requires = ["setuptools>=45", "setuptools_scm[toml]>=6.2"]
+build-backend = "setuptools.build_meta"
+
+[tool.setuptools_scm]
+write_to = 'src/showermodel/_version.py'
diff --git a/setup.cfg b/setup.cfg
index ea6a681..b4dbe9a 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,12 +1,3 @@
-[build_sphinx]
-source-dir = docs
-build-dir = docs/_build
-all_files = 1
-
-[upload_docs]
-upload-dir = docs/_build/html
-show-response = 1
-
 [metadata]
 name = ShowerModel
 description = Modelling cosmic-ray showers, their light production and its detection
@@ -17,3 +8,55 @@ url=https://github.com/JaimeRosado/ShowerModel
 long_description = file: README.md
 long_description_content_type = text/markdown
 github_project = JaimeRosado/ShowerModel
+classifiers =
+    Intended Audience :: Science/Research
+    License :: OSI Approved :: GNU General Public License v3 (GPLv3)
+    Programming Language :: Python :: 3.7
+    Programming Language :: Python :: 3.8
+    Programming Language :: Python :: 3.9
+    Programming Language :: Python :: 3.10
+    Topic :: Scientific/Engineering :: Astronomy
+    Topic :: Scientific/Engineering :: Physics
+
+[options]
+packages = find:
+package_dir =
+	= src
+python_requires = >=3.7
+install_requires =
+    numpy
+    pandas
+    matplotlib
+    scipy
+    toml
+    ipython
+    openpyxl
+
+[options.packages.find]
+where = src
+exclude = showermodel._dev_version
+
+[options.package_data]
+showermodel.constants = *.toml
+
+[options.extras_require]
+tests =
+  pytest
+  pytest-cov
+
+docs =
+    sphinx ~= 5.0
+    sphinx_rtd_theme
+    sphinx_automodapi
+    sphinx
+    nbsphinx
+    nbsphinx-link
+    numpydoc
+    jupyter
+    notebook
+    graphviz
+
+dev =
+  %(tests)s
+  %(docs)s
+  setuptools_scm
diff --git a/setup.py b/setup.py
index 0ad453d..43518d5 100644
--- a/setup.py
+++ b/setup.py
@@ -1,50 +1,17 @@
-from setuptools import setup, find_packages
-import os
+"""
+Empty setup.py file to enable editable installation.
+Do not change. Use setup.cfg.
+Based on https://github.com/cta-observatory/project-template-python-pure
+"""
 
-docs_require = [
-    "sphinx_rtd_theme",
-    "sphinx_automodapi",
-    "sphinx",
-    "nbsphinx",
-    "nbsphinx-link",
-    "numpydoc",
-    "jupyter",
-    "notebook",
-    "graphviz",
-]
+from setuptools import setup
 
-setup(
-    packages=find_packages(),
-    python_requires=">=3.7",
-    install_requires=[
-        "numpy",
-        "pandas",
-        "matplotlib",
-        "scipy",
-        "toml",
-        "ipython",
-        "setuptools_scm"
-    ],
-    package_data={
-        'showermodel': [
-            'extra/atm_models.toml',
-            'extra/averaged_profile_5sh_100TeV.dat',
-            'extra/Edep_profile_1000GeV_1000sh_0deg.dat',
-            'extra/mean_annual_global_reference_atmosphere.xlsx',
-            'extra/showermodel_config.toml',
-            'extra/tel_data.toml'
-        ],
-    },
-    # here are optional dependencies (as "tag" : "dependency spec")
-    extras_require={"docs": docs_require},
-    use_scm_version={"write_to": os.path.join("showermodel", "_version.py")},
-    classifiers=[
-        "Intended Audience :: Science/Research",
-        "License :: OSI Approved :: BSD License",
-        "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.7",
-        "Programming Language :: Python :: 3.8",
-        "Programming Language :: Python :: 3.9",
-        "Topic :: Scientific/Engineering :: Astronomy",
-    ],
-)
+# this is a workaround for an issue in pip that prevents editable installation
+# with --user, see https://github.com/pypa/pip/issues/7953
+import site
+import sys
+
+
+site.ENABLE_USER_SITE = "--user" in sys.argv[1:]
+
+setup()
diff --git a/showermodel/__init__.py b/src/showermodel/__init__.py
similarity index 100%
rename from showermodel/__init__.py
rename to src/showermodel/__init__.py
diff --git a/showermodel/_dev_version.py b/src/showermodel/_dev_version/__init__.py
similarity index 71%
rename from showermodel/_dev_version.py
rename to src/showermodel/_dev_version/__init__.py
index 3b5fea9..418cbaa 100644
--- a/showermodel/_dev_version.py
+++ b/src/showermodel/_dev_version/__init__.py
@@ -1,9 +1,9 @@
 # Try to use setuptools_scm to get the current version; this is only used
 # in development installations from the git repository.
-# see showermodel/version.py for details
+# see ../version.py for details
 try:
     from setuptools_scm import get_version
 
-    version = get_version(root="..", relative_to=__file__)
+    version = get_version(root="../..", relative_to=__file__)
 except Exception as e:
-    raise ImportError(f"setuptools_scm broken or not installed: {e}")
+    raise ImportError(f"setuptools_scm broken or not installed: {e}") from e
diff --git a/showermodel/_tools.py b/src/showermodel/_tools.py
similarity index 100%
rename from showermodel/_tools.py
rename to src/showermodel/_tools.py
diff --git a/showermodel/atmosphere.py b/src/showermodel/atmosphere.py
similarity index 100%
rename from showermodel/atmosphere.py
rename to src/showermodel/atmosphere.py
diff --git a/showermodel/cherenkov.py b/src/showermodel/cherenkov.py
similarity index 100%
rename from showermodel/cherenkov.py
rename to src/showermodel/cherenkov.py
diff --git a/showermodel/constants/__init__.py b/src/showermodel/constants/__init__.py
similarity index 100%
rename from showermodel/constants/__init__.py
rename to src/showermodel/constants/__init__.py
diff --git a/showermodel/constants/atm_models.toml b/src/showermodel/constants/atm_models.toml
similarity index 100%
rename from showermodel/constants/atm_models.toml
rename to src/showermodel/constants/atm_models.toml
diff --git a/showermodel/constants/fluorescence_model.toml b/src/showermodel/constants/fluorescence_model.toml
similarity index 100%
rename from showermodel/constants/fluorescence_model.toml
rename to src/showermodel/constants/fluorescence_model.toml
diff --git a/showermodel/constants/showermodel_config.toml b/src/showermodel/constants/showermodel_config.toml
similarity index 100%
rename from showermodel/constants/showermodel_config.toml
rename to src/showermodel/constants/showermodel_config.toml
diff --git a/showermodel/constants/tel_data.toml b/src/showermodel/constants/tel_data.toml
similarity index 100%
rename from showermodel/constants/tel_data.toml
rename to src/showermodel/constants/tel_data.toml
diff --git a/showermodel/event.py b/src/showermodel/event.py
similarity index 100%
rename from showermodel/event.py
rename to src/showermodel/event.py
diff --git a/showermodel/fluorescence.py b/src/showermodel/fluorescence.py
similarity index 100%
rename from showermodel/fluorescence.py
rename to src/showermodel/fluorescence.py
diff --git a/showermodel/image.py b/src/showermodel/image.py
similarity index 100%
rename from showermodel/image.py
rename to src/showermodel/image.py
diff --git a/showermodel/observatory.py b/src/showermodel/observatory.py
similarity index 100%
rename from showermodel/observatory.py
rename to src/showermodel/observatory.py
diff --git a/showermodel/profile.py b/src/showermodel/profile.py
similarity index 100%
rename from showermodel/profile.py
rename to src/showermodel/profile.py
diff --git a/showermodel/projection.py b/src/showermodel/projection.py
similarity index 100%
rename from showermodel/projection.py
rename to src/showermodel/projection.py
diff --git a/showermodel/shower.py b/src/showermodel/shower.py
similarity index 100%
rename from showermodel/shower.py
rename to src/showermodel/shower.py
diff --git a/showermodel/signal.py b/src/showermodel/signal.py
similarity index 100%
rename from showermodel/signal.py
rename to src/showermodel/signal.py
diff --git a/showermodel/telescope.py b/src/showermodel/telescope.py
similarity index 100%
rename from showermodel/telescope.py
rename to src/showermodel/telescope.py
diff --git a/showermodel/track.py b/src/showermodel/track.py
similarity index 100%
rename from showermodel/track.py
rename to src/showermodel/track.py
diff --git a/showermodel/version.py b/src/showermodel/version.py
similarity index 75%
rename from showermodel/version.py
rename to src/showermodel/version.py
index a7e386c..0b0ec37 100644
--- a/showermodel/version.py
+++ b/src/showermodel/version.py
@@ -1,4 +1,4 @@
-# this is adapted from https://github.com/astropy/astropy/blob/master/astropy/version.py
+# this is adapted from https://github.com/astropy/astropy/blob/main/astropy/version.py
 # see https://github.com/astropy/astropy/pull/10774 for a discussion on why this needed.
 
 try:
@@ -10,8 +10,8 @@
     import warnings
 
     warnings.warn(
-        "Could not determine ShowerModel version; this indicates a broken installation."
-        " Install ShowerModel from a local git repository."
+        "Could not determine version; this indicates a broken installation."
+        " Install from PyPI, using conda or from a local git repository."
         " Installing github's autogenerated source release tarballs "
         " does not include version information and should be avoided."
     )


Test patch:
diff --git a/showermodel/tests/test_telescope.py b/showermodel/tests/test_telescope.py
deleted file mode 100644
index 1f4d8c2..0000000
--- a/showermodel/tests/test_telescope.py
+++ /dev/null
@@ -1,11 +0,0 @@
-def test_telescope():
-    from showermodel import IACT
-
-    # Default telescope type: IACT
-    # Default angular aperture in degrees: 8.0
-    # Default detection area in m2: 113.097
-    telescope = IACT()
-    assert telescope.tel_type == 'IACT'
-    assert telescope.apert == 8.0
-    assert telescope.area == 113.097
-
diff --git a/showermodel/tests/test_shower.py b/src/showermodel/tests/test_shower.py
similarity index 54%
rename from showermodel/tests/test_shower.py
rename to src/showermodel/tests/test_shower.py
index e749c89..6648857 100644
--- a/showermodel/tests/test_shower.py
+++ b/src/showermodel/tests/test_shower.py
@@ -1,3 +1,5 @@
+import numpy as np
+
 def test_shower():
     from showermodel import Shower
     theta = 20.0
@@ -7,7 +9,7 @@ def test_shower():
     assert shower.alt == 90.0 - theta
     assert shower.az == 45.0
     assert shower.h_top == h_top
-    assert shower.atmosphere.P[100] == 49.69842905334434
-    assert shower.track.t[200] == 254.50685251195043
-    assert shower.profile.s[10] == 1.6504072224436146
-    assert shower.cherenkov.N_ph[50] == 757147.620313149
+    assert np.isclose(shower.atmosphere.P[100], 49.69842905334434)
+    assert np.isclose(shower.track.t[200], 254.50685251195043)
+    assert np.isclose(shower.profile.s[10], 1.6504072224436146)
+    assert np.isclose(shower.cherenkov.N_ph[50], 757147.620313149)
diff --git a/showermodel/tests/test_showermodel.py b/src/showermodel/tests/test_showermodel.py
similarity index 100%
rename from showermodel/tests/test_showermodel.py
rename to src/showermodel/tests/test_showermodel.py
diff --git a/src/showermodel/tests/test_telescope.py b/src/showermodel/tests/test_telescope.py
new file mode 100644
index 0000000..bd2cc1f
--- /dev/null
+++ b/src/showermodel/tests/test_telescope.py
@@ -0,0 +1,10 @@
+def test_telescope():
+    from showermodel.telescope import Telescope
+
+    # Default telescope type: IACT
+    # Default angular aperture in degrees: 8.0
+    # Default detection area in m2: 113.097
+    telescope = Telescope()
+    assert telescope.tel_type == 'generic'
+    assert telescope.apert == 10.0
+    assert telescope.area == 100.0