From ca3773de70dc3276714ca01c369aae13aabfa09a Mon Sep 17 00:00:00 2001
From: Soham Pal <dssohampal@gmail.com>
Date: Tue, 3 Dec 2024 15:48:40 -0700
Subject: [PATCH 1/4] Added a minimal pyproject.toml.

---
 pyproject.toml | 8 ++++++++
 1 file changed, 8 insertions(+)
 create mode 100644 pyproject.toml

diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..5391034
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,8 @@
+[project]
+name = "pynch"
+version = "1.0.0"
+dynamic = ["dependencies"]
+[tool.setuptools]
+package-dir = {"" = "pynch"}
+[tool.setuptools.dynamic]
+dependencies = {file = ["requirements.txt"]}
\ No newline at end of file

From 6e6d6a94b27da1caae02f5d732f44fbd5b8cf97e Mon Sep 17 00:00:00 2001
From: Soham Pal <dssohampal@gmail.com>
Date: Tue, 3 Dec 2024 16:04:20 -0700
Subject: [PATCH 2/4] Added `pip install` information.

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 47bf983..f547719 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,7 @@ No comparison or validation is done on common values.
 
 ## Additional uses
 
-If you want to do your own thing with the data, you could import this module, access `MassTable().full_data`, then sort, slice and filter the resultant dataframe to your heart's content.
+If you want to do your own thing with the data, you could install this package, import this module, access `MassTable().full_data`, then sort, slice and filter the resultant dataframe to your heart's content. You can install this package with `pip install git+<package-repo>` where `<package-repo>` is the git repository of this package.
 
 For example, track how the accuracy of the mass excess of 18B changes once it is experimentally measured
 ```python

From 791cd3de7969520eb491b6881ed8ea22cf0e5453 Mon Sep 17 00:00:00 2001
From: Soham Pal <dssohampal@gmail.com>
Date: Wed, 4 Dec 2024 10:26:37 -0700
Subject: [PATCH 3/4] Changed directory structure to 'src/pkg/data'

---
 {pynch => src/pynch}/__init__.py             |  0
 {pynch => src/pynch}/ame_mass_file.py        |  0
 {pynch => src/pynch}/ame_mass_parse.py       |  0
 {pynch => src/pynch}/ame_reaction_1_file.py  |  0
 {pynch => src/pynch}/ame_reaction_1_parse.py |  0
 {pynch => src/pynch}/ame_reaction_2_file.py  |  0
 {pynch => src/pynch}/ame_reaction_2_parse.py |  0
 {data => src/pynch/data}/2003/mass.mas03     |  0
 {data => src/pynch/data}/2003/nubtab03.asc   |  0
 {data => src/pynch/data}/2003/rct1.mas03     |  0
 {data => src/pynch/data}/2003/rct2.mas03     |  0
 {data => src/pynch/data}/2012/mass.mas12     |  0
 {data => src/pynch/data}/2012/nubtab12.asc   |  0
 {data => src/pynch/data}/2012/rct1.mas12     |  0
 {data => src/pynch/data}/2012/rct2.mas12     |  0
 {data => src/pynch/data}/2016/mass16.txt     |  0
 {data => src/pynch/data}/2016/nubase2016.txt |  0
 {data => src/pynch/data}/2016/rct1-16.txt    |  0
 {data => src/pynch/data}/2016/rct2-16.txt    |  0
 {data => src/pynch/data}/2020/mass.mas20     |  0
 {data => src/pynch/data}/2020/nubase_1.mas20 |  0
 {data => src/pynch/data}/2020/rct1.mas20     |  0
 {data => src/pynch/data}/2020/rct2.mas20     |  0
 {pynch => src/pynch}/mass_table.py           | 23 +++++++++++---------
 {pynch => src/pynch}/nubase_file.py          |  2 +-
 {pynch => src/pynch}/nubase_parse.py         |  8 +++----
 {pynch => src/pynch}/parse.py                |  0
 27 files changed, 18 insertions(+), 15 deletions(-)
 rename {pynch => src/pynch}/__init__.py (100%)
 rename {pynch => src/pynch}/ame_mass_file.py (100%)
 rename {pynch => src/pynch}/ame_mass_parse.py (100%)
 rename {pynch => src/pynch}/ame_reaction_1_file.py (100%)
 rename {pynch => src/pynch}/ame_reaction_1_parse.py (100%)
 rename {pynch => src/pynch}/ame_reaction_2_file.py (100%)
 rename {pynch => src/pynch}/ame_reaction_2_parse.py (100%)
 rename {data => src/pynch/data}/2003/mass.mas03 (100%)
 rename {data => src/pynch/data}/2003/nubtab03.asc (100%)
 rename {data => src/pynch/data}/2003/rct1.mas03 (100%)
 rename {data => src/pynch/data}/2003/rct2.mas03 (100%)
 rename {data => src/pynch/data}/2012/mass.mas12 (100%)
 rename {data => src/pynch/data}/2012/nubtab12.asc (100%)
 rename {data => src/pynch/data}/2012/rct1.mas12 (100%)
 rename {data => src/pynch/data}/2012/rct2.mas12 (100%)
 rename {data => src/pynch/data}/2016/mass16.txt (100%)
 rename {data => src/pynch/data}/2016/nubase2016.txt (100%)
 rename {data => src/pynch/data}/2016/rct1-16.txt (100%)
 rename {data => src/pynch/data}/2016/rct2-16.txt (100%)
 rename {data => src/pynch/data}/2020/mass.mas20 (100%)
 rename {data => src/pynch/data}/2020/nubase_1.mas20 (100%)
 rename {data => src/pynch/data}/2020/rct1.mas20 (100%)
 rename {data => src/pynch/data}/2020/rct2.mas20 (100%)
 rename {pynch => src/pynch}/mass_table.py (87%)
 rename {pynch => src/pynch}/nubase_file.py (99%)
 rename {pynch => src/pynch}/nubase_parse.py (96%)
 rename {pynch => src/pynch}/parse.py (100%)

diff --git a/pynch/__init__.py b/src/pynch/__init__.py
similarity index 100%
rename from pynch/__init__.py
rename to src/pynch/__init__.py
diff --git a/pynch/ame_mass_file.py b/src/pynch/ame_mass_file.py
similarity index 100%
rename from pynch/ame_mass_file.py
rename to src/pynch/ame_mass_file.py
diff --git a/pynch/ame_mass_parse.py b/src/pynch/ame_mass_parse.py
similarity index 100%
rename from pynch/ame_mass_parse.py
rename to src/pynch/ame_mass_parse.py
diff --git a/pynch/ame_reaction_1_file.py b/src/pynch/ame_reaction_1_file.py
similarity index 100%
rename from pynch/ame_reaction_1_file.py
rename to src/pynch/ame_reaction_1_file.py
diff --git a/pynch/ame_reaction_1_parse.py b/src/pynch/ame_reaction_1_parse.py
similarity index 100%
rename from pynch/ame_reaction_1_parse.py
rename to src/pynch/ame_reaction_1_parse.py
diff --git a/pynch/ame_reaction_2_file.py b/src/pynch/ame_reaction_2_file.py
similarity index 100%
rename from pynch/ame_reaction_2_file.py
rename to src/pynch/ame_reaction_2_file.py
diff --git a/pynch/ame_reaction_2_parse.py b/src/pynch/ame_reaction_2_parse.py
similarity index 100%
rename from pynch/ame_reaction_2_parse.py
rename to src/pynch/ame_reaction_2_parse.py
diff --git a/data/2003/mass.mas03 b/src/pynch/data/2003/mass.mas03
similarity index 100%
rename from data/2003/mass.mas03
rename to src/pynch/data/2003/mass.mas03
diff --git a/data/2003/nubtab03.asc b/src/pynch/data/2003/nubtab03.asc
similarity index 100%
rename from data/2003/nubtab03.asc
rename to src/pynch/data/2003/nubtab03.asc
diff --git a/data/2003/rct1.mas03 b/src/pynch/data/2003/rct1.mas03
similarity index 100%
rename from data/2003/rct1.mas03
rename to src/pynch/data/2003/rct1.mas03
diff --git a/data/2003/rct2.mas03 b/src/pynch/data/2003/rct2.mas03
similarity index 100%
rename from data/2003/rct2.mas03
rename to src/pynch/data/2003/rct2.mas03
diff --git a/data/2012/mass.mas12 b/src/pynch/data/2012/mass.mas12
similarity index 100%
rename from data/2012/mass.mas12
rename to src/pynch/data/2012/mass.mas12
diff --git a/data/2012/nubtab12.asc b/src/pynch/data/2012/nubtab12.asc
similarity index 100%
rename from data/2012/nubtab12.asc
rename to src/pynch/data/2012/nubtab12.asc
diff --git a/data/2012/rct1.mas12 b/src/pynch/data/2012/rct1.mas12
similarity index 100%
rename from data/2012/rct1.mas12
rename to src/pynch/data/2012/rct1.mas12
diff --git a/data/2012/rct2.mas12 b/src/pynch/data/2012/rct2.mas12
similarity index 100%
rename from data/2012/rct2.mas12
rename to src/pynch/data/2012/rct2.mas12
diff --git a/data/2016/mass16.txt b/src/pynch/data/2016/mass16.txt
similarity index 100%
rename from data/2016/mass16.txt
rename to src/pynch/data/2016/mass16.txt
diff --git a/data/2016/nubase2016.txt b/src/pynch/data/2016/nubase2016.txt
similarity index 100%
rename from data/2016/nubase2016.txt
rename to src/pynch/data/2016/nubase2016.txt
diff --git a/data/2016/rct1-16.txt b/src/pynch/data/2016/rct1-16.txt
similarity index 100%
rename from data/2016/rct1-16.txt
rename to src/pynch/data/2016/rct1-16.txt
diff --git a/data/2016/rct2-16.txt b/src/pynch/data/2016/rct2-16.txt
similarity index 100%
rename from data/2016/rct2-16.txt
rename to src/pynch/data/2016/rct2-16.txt
diff --git a/data/2020/mass.mas20 b/src/pynch/data/2020/mass.mas20
similarity index 100%
rename from data/2020/mass.mas20
rename to src/pynch/data/2020/mass.mas20
diff --git a/data/2020/nubase_1.mas20 b/src/pynch/data/2020/nubase_1.mas20
similarity index 100%
rename from data/2020/nubase_1.mas20
rename to src/pynch/data/2020/nubase_1.mas20
diff --git a/data/2020/rct1.mas20 b/src/pynch/data/2020/rct1.mas20
similarity index 100%
rename from data/2020/rct1.mas20
rename to src/pynch/data/2020/rct1.mas20
diff --git a/data/2020/rct2.mas20 b/src/pynch/data/2020/rct2.mas20
similarity index 100%
rename from data/2020/rct2.mas20
rename to src/pynch/data/2020/rct2.mas20
diff --git a/pynch/mass_table.py b/src/pynch/mass_table.py
similarity index 87%
rename from pynch/mass_table.py
rename to src/pynch/mass_table.py
index 1763506..aa1b355 100644
--- a/pynch/mass_table.py
+++ b/src/pynch/mass_table.py
@@ -1,4 +1,5 @@
 """Functionality to parse all data file into a single object."""
+import importlib.resources
 import logging
 import pathlib
 import typing
@@ -8,7 +9,7 @@
 from pynch.ame_mass_parse import AMEMassParser
 from pynch.ame_reaction_1_parse import AMEReactionParserOne
 from pynch.ame_reaction_2_parse import AMEReactionParserTwo
-from pynch.nubase_parse import NubaseParser
+from pynch.nubase_parse import NUBASEParser
 
 
 class MassTable:
@@ -20,7 +21,7 @@ class MassTable:
     def __init__(self):
         """Do all of the work at construction."""
         # Assume this file is some/path/pynch/pynch/mass_table.py
-        self.data_path = pathlib.Path(__file__) / ".." / ".." / "data"
+        self.data_path = "data"
         self.existing_years = [2003, 2012, 2016, 2020]
         self.nubase = pd.concat([self._parse_nubase_data(y) for y in self.existing_years], ignore_index=True)
         self.ame = pd.concat([self._parse_ame_data(y) for y in self.existing_years], ignore_index=True)
@@ -29,8 +30,9 @@ def __init__(self):
 
     def _get_nubase_datafile(self, year: int) -> pathlib.Path:
         """Use the given year to locate the nubase mass table file and return the absolute path."""
-        nubase_mass = self.data_path / pathlib.Path(str(year))
-        nubase_mass = nubase_mass.resolve()
+        with importlib.resources.path("pynch", self.data_path) as p:
+            nubase_mass = p / pathlib.Path(str(year))
+            nubase_mass = nubase_mass.resolve()
 
         if year == 2003:
             nubase_mass = nubase_mass / "nubtab03.asc"
@@ -45,8 +47,9 @@ def _get_nubase_datafile(self, year: int) -> pathlib.Path:
 
     def _get_ame_datafiles(self, year: int) -> typing.Tuple[pathlib.Path, pathlib.Path, pathlib.Path]:
         """Use the given year to locate the 3 AME data file and return the absolute path."""
-        data_dir = self.data_path / pathlib.Path(str(year))
-        data_dir = data_dir.resolve()
+        with importlib.resources.path("pynch", self.data_path) as p:
+            data_dir = p / pathlib.Path(str(year))
+            data_dir = data_dir.resolve()
 
         if year == 2003:
             ame_mass = data_dir / "mass.mas03"
@@ -78,7 +81,7 @@ def _validate_year(self, year: int) -> int:
     def _parse_nubase_data(self, year: int) -> pd.DataFrame:
         """Get the nubase for the given year as a pandas.DataFrame."""
         year = self._validate_year(year)
-        return NubaseParser(self._get_nubase_datafile(year), year).read_file()
+        return NUBASEParser(self._get_nubase_datafile(year), year).read_file()
 
     def _parse_ame_data(self, year: int) -> pd.DataFrame:
         """Combine all the AME files from the given year into a pandas.DataFrame."""
@@ -97,14 +100,14 @@ def _combine_all_data(self) -> pd.DataFrame:
         common_columns = ['A', 'Z', 'N', 'TableYear', 'Symbol']
         df = self.nubase.merge(self.ame, on=common_columns)
 
-        df["NubaseRelativeError"] = abs(
-            df["NubaseMassExcessError"] / df["NubaseMassExcess"]
+        df["NUBASERelativeError"] = abs(
+            df["NUBASEMassExcessError"] / df["NUBASEMassExcess"]
         )
         df["AMERelativeError"] = abs(df["AMEMassExcessError"] / df["AMEMassExcess"])
 
         # 12C has a 0.0 +/ 0.0 mass excess by definition so calculating relative error -> NaN
         # Set the value to 0.0 as that's what it is
-        df.loc[(df.Symbol == "C") & (df.A == 12), "NubaseRelativeError"] = 0.0
+        df.loc[(df.Symbol == "C") & (df.A == 12), "NUBASERelativeError"] = 0.0
         df.loc[(df.Symbol == "C") & (df.A == 12), "AMERelativeError"] = 0.0
 
         # 198Au has a typo in it's decay mode in the 2012 table. It is recorded as '-'
diff --git a/pynch/nubase_file.py b/src/pynch/nubase_file.py
similarity index 99%
rename from pynch/nubase_file.py
rename to src/pynch/nubase_file.py
index cbf7888..de5b3ec 100644
--- a/pynch/nubase_file.py
+++ b/src/pynch/nubase_file.py
@@ -2,7 +2,7 @@
 from pynch.parse import Parse
 
 
-class NubaseFile(Parse):
+class NUBASEFile(Parse):
     """Easy access to where variables are in the NUBASE file.
 
     The NUBASE data file is formatted by location in the line, values exist
diff --git a/pynch/nubase_parse.py b/src/pynch/nubase_parse.py
similarity index 96%
rename from pynch/nubase_parse.py
rename to src/pynch/nubase_parse.py
index 66bde04..e0bc4e2 100644
--- a/pynch/nubase_parse.py
+++ b/src/pynch/nubase_parse.py
@@ -6,10 +6,10 @@
 
 import pandas as pd
 
-from pynch.nubase_file import NubaseFile
+from pynch.nubase_file import NUBASEFile
 
 
-class NubaseParser(NubaseFile):
+class NUBASEParser(NUBASEFile):
     """Parse the NUBASE data file.
 
     A collection of functions to parse the weird format of the NUBASE file.
@@ -96,8 +96,8 @@ def _read_line(self, line: str) -> dict:
             "TableYear": self.year,
             "A": self._read_as_int(line, self.START_A, self.END_A),
             "Z": self._read_as_int(line, self.START_Z, self.END_Z),
-            "NubaseMassExcess": self._read_as_float(line, self.START_ME, self.END_ME),
-            "NubaseMassExcessError": self._read_as_float(line, self.START_DME, self.END_DME),
+            "NUBASEMassExcess": self._read_as_float(line, self.START_ME, self.END_ME),
+            "NUBASEMassExcessError": self._read_as_float(line, self.START_DME, self.END_DME),
             # "LevelEnergy" : self._read_as_float(,
             #     line, self.START_ISOMER, self.END_ISOMER
             # )
diff --git a/pynch/parse.py b/src/pynch/parse.py
similarity index 100%
rename from pynch/parse.py
rename to src/pynch/parse.py

From bbcd0965802495eb0db179a84859f6b4d2a26fae Mon Sep 17 00:00:00 2001
From: Soham Pal <dssohampal@gmail.com>
Date: Wed, 4 Dec 2024 13:15:38 -0700
Subject: [PATCH 4/4] Updated pyproject.toml to include data.

---
 README.md            |  2 +-
 pyproject.toml       | 14 +++++++++++---
 app.py => src/app.py |  2 +-
 3 files changed, 13 insertions(+), 5 deletions(-)
 rename app.py => src/app.py (98%)

diff --git a/README.md b/README.md
index f547719..b9da775 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@ pip install --user -r requirements.txt
 
 With all of the necessary requirements installed, the below will start the app
 ```bash
-python3 app.py
+python3 src/app.py
 ```
 The console will tell you where to point your browser - likely http://127.0.0.1:8050/.
 
diff --git a/pyproject.toml b/pyproject.toml
index 5391034..548d73b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,8 +1,16 @@
+[build-system]
+requires = ["setuptools>=64", "setuptools_scm>=8"]
+build-backend = "setuptools.build_meta"
+
 [project]
 name = "pynch"
-version = "1.0.0"
-dynamic = ["dependencies"]
+dynamic = ["dependencies", "version"]
+
 [tool.setuptools]
-package-dir = {"" = "pynch"}
+include-package-data = true
+
+[tool.setuptools.packages.find]
+where = ["src"]
+
 [tool.setuptools.dynamic]
 dependencies = {file = ["requirements.txt"]}
\ No newline at end of file
diff --git a/app.py b/src/app.py
similarity index 98%
rename from app.py
rename to src/app.py
index de9ddd8..e767251 100755
--- a/app.py
+++ b/src/app.py
@@ -53,7 +53,7 @@ def update_graph(y_var, x_value, year):
 
     logit = (
         True
-        if y_var in ["HalfLife", "NubaseRelativeError", "AMERelativeError"]
+        if y_var in ["HalfLife", "NUBASERelativeError", "AMERelativeError"]
         else False
     )