diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 0000000..8b3e681
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,42 @@
+// For format details, see https://aka.ms/devcontainer.json. For config options, see the
+// README at: https://github.com/devcontainers/templates/tree/main/src/python
+{
+ "name": "Python 3",
+ // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
+ "image": "mcr.microsoft.com/devcontainers/python:1-3.11",
+ "features": {
+ "ghcr.io/rocker-org/devcontainer-features/quarto-cli:1": {
+ "version": "latest"
+ },
+ "ghcr.io/devcontainers-contrib/features/poetry:2": {
+ "version": "latest"
+ }
+ },
+
+ // Features to add to the dev container. More info: https://containers.dev/features.
+ // "features": {},
+
+ // Use 'forwardPorts' to make a list of ports inside the container available locally.
+ // "forwardPorts": [],
+
+ // Use 'postCreateCommand' to run commands after the container is created.
+ "postCreateCommand": "poetry install",
+
+ // Configure tool-specific properties.
+ "customizations": {
+ "vscode": {
+ "extensions":
+ ["ms-toolsai.jupyter",
+ "ms-python.vscode-pylance",
+ "njpwerner.autodocstring"],
+ "settings": {"python.testing.pytestArgs": [
+ "tests"
+ ],
+ "python.testing.unittestEnabled": false,
+ "python.testing.pytestEnabled": true}
+ }
+ }
+
+ // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
+ // "remoteUser": "root"
+}
diff --git a/.github/workflows/test-and-run.yml b/.github/workflows/test-and-run.yml
index e76c721..0767718 100644
--- a/.github/workflows/test-and-run.yml
+++ b/.github/workflows/test-and-run.yml
@@ -22,7 +22,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
@@ -41,6 +41,6 @@ jobs:
run: |
python -m pytest --cov=./ --cov-report=xml tests/
- name: Upload coverage reports to Codecov
- uses: codecov/codecov-action@v3
+ uses: codecov/codecov-action@v4
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 76c97eb..e787476 100644
--- a/.gitignore
+++ b/.gitignore
@@ -160,4 +160,5 @@ cython_debug/
#.idea/
.vscode
-poetry.lock
\ No newline at end of file
+poetry.lock
+.DS_Store
\ No newline at end of file
diff --git a/CITATION.cff b/CITATION.cff
new file mode 100644
index 0000000..9f0e6fe
--- /dev/null
+++ b/CITATION.cff
@@ -0,0 +1,26 @@
+# This CITATION.cff file was generated with cffinit.
+# Visit https://bit.ly/cffinit to generate yours today!
+
+cff-version: 1.2.0
+title: fasttrackpy
+message: >-
+ If you use this software, please cite it using the
+ metadata from this file.
+type: software
+authors:
+ - given-names: Josef
+ family-names: Fruehwald
+ orcid: 'https://orcid.org/0000-0001-8480-9461'
+ affiliation: University of Kentucky
+ - given-names: Santiago
+ family-names: Barreda
+ affiliation: UC Davis
+ orcid: 'https://orcid.org/0000-0002-1552-083X'
+identifiers:
+ - type: doi
+ value: 10.5281/zenodo.10212100
+ description: zenodo
+repository-code: 'https://github.com/FastTrackiverse/fasttrackpy'
+url: 'https://fasttrackiverse.github.io/fasttrackpy/'
+abstract: A python implementation of FastTrack
+license: MIT
diff --git a/README.md b/README.md
index f968530..0c98302 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
# FastTrackPy
[![PyPI](https://img.shields.io/pypi/v/fasttrackpy)](https://pypi.org/project/fasttrackpy/)
-[![Python CI](https://github.com/JoFrhwld/fasttrackpy/actions/workflows/test-and-run.yml/badge.svg)](https://github.com/JoFrhwld/fasttrackpy/actions/workflows/test-and-run.yml) [![codecov](https://codecov.io/gh/FastTrackiverse/fasttrackpy/graph/badge.svg?token=GOAWY4B5C8)](https://codecov.io/gh/FastTrackiverse/fasttrackpy)
+[![Python CI](https://github.com/JoFrhwld/fasttrackpy/actions/workflows/test-and-run.yml/badge.svg)](https://github.com/JoFrhwld/fasttrackpy/actions/workflows/test-and-run.yml) [![codecov](https://codecov.io/gh/FastTrackiverse/fasttrackpy/graph/badge.svg?token=GOAWY4B5C8)](https://codecov.io/gh/FastTrackiverse/fasttrackpy) [![DOI](https://zenodo.org/badge/580169086.svg)](https://zenodo.org/doi/10.5281/zenodo.10212099)
+
Goal: A FastTrack python implementation with importable modules
@@ -14,4 +15,4 @@ pip install fasttrackpy
```bash
fasttrack --file audio.wav --output formants.csv
-```
\ No newline at end of file
+```
diff --git a/poetry.toml b/poetry.toml
new file mode 100644
index 0000000..ab1033b
--- /dev/null
+++ b/poetry.toml
@@ -0,0 +1,2 @@
+[virtualenvs]
+in-project = true
diff --git a/pyproject.toml b/pyproject.toml
index 3c9cf0b..2d26bbe 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -18,10 +18,10 @@ homepage = "https://fasttrackiverse.github.io/fasttrackpy/"
repository = "https://github.com/FastTrackiverse/fasttrackpy"
[tool.poetry.dependencies]
-python = ">=3.10,<3.13"
+python = ">=3.10,<3.12"
praat-parselmouth = "^0.4.3"
-scipy = {version = "^1.11.3", python = ">=3.10,<3.13"}
-numpy = {version = "^1.26.1", python = ">=3.10,<3.13"}
+scipy = {version = "^1.11.3", python = ">=3.10,<3.12"}
+numpy = {version = "^1.26.1", python = ">=3.10,<3.12"}
polars = "^0.19.16"
pytest-cov = "^4.1.0"
pytest = "^7.4.3"
@@ -59,7 +59,8 @@ addopts = [
"--import-mode=importlib",
"--cov-config=tests/.coveragerc",
"--cov-report=xml",
- "--cov"
+ "--cov",
+ "--log-cli-level=INFO"
]
filterwarnings =[
"ignore::UserWarning"
diff --git a/src/fasttrackpy/cli.py b/src/fasttrackpy/cli.py
index 92a5c67..4050e17 100644
--- a/src/fasttrackpy/cli.py
+++ b/src/fasttrackpy/cli.py
@@ -251,7 +251,8 @@ def audio(
n_formants: int = 4,
window_length: float = 0.025,
time_step: float = 0.002,
- pre_emphasis_from: float = 50
+ pre_emphasis_from: float = 50,
+ **kwargs
):
"""Run fasttrack.
@@ -392,7 +393,8 @@ def audio_textgrid(
n_formants: int = 4,
window_length: float = 0.025,
time_step: float = 0.002,
- pre_emphasis_from: float = 50
+ pre_emphasis_from: float = 50,
+ **kwargs
):
"""Run fasttrack.
diff --git a/tests/test_cli.py b/tests/test_cli.py
index a151fe8..f235bc2 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -3,6 +3,7 @@
from click.testing import CliRunner
import pytest
import yaml
+import logging
class TestCLI:
sound_path = Path("tests", "test_data", "ay.wav")
@@ -16,17 +17,21 @@ def test_file_usage(self):
out_dir.mkdir()
runner = CliRunner()
- runner.invoke(
+ result = runner.invoke(
fasttrack,
- f"audio --file {str(self.sound_path)} --dest {str(out_dir)}"
+ ["audio",
+ "--file", self.sound_path,
+ "--dest", out_dir]
)
+
+ assert result.exit_code == 0, result.output
out_files = list(out_dir.glob("*"))
- assert all([x.is_file() for x in out_files])
[x.unlink() for x in out_files]
out_dir.rmdir()
def test_config_file(self):
- with open("tests/test_data/config.yml") as file:
+ config_path = Path("tests", "test_data", "config.yml")
+ with config_path.open() as file:
params = yaml.safe_load(file)
sound_path = Path(params["file"])
@@ -35,12 +40,14 @@ def test_config_file(self):
dest.mkdir()
runner = CliRunner()
- runner.invoke(
+ result = runner.invoke(
fasttrack,
- f"audio --config tests/test_data/config.yml"
+ ["audio",
+ "--config", config_path]
)
+
+ assert result.exit_code == 0, result.output
out_files = list(dest.glob("*"))
- assert all([x.is_file() for x in out_files])
[x.unlink() for x in out_files]
dest.rmdir()
@@ -51,14 +58,15 @@ def test_dir_usage(self):
out_dir.mkdir()
runner = CliRunner()
- runner.invoke(
+ result = runner.invoke(
fasttrack,
- f"audio --dir {str(self.sound_path.parent)} --dest {str(out_dir)}"
+ ["audio",
+ "--dir", self.sound_path.parent,
+ "--dest", out_dir]
)
- out_files = list(out_dir.glob("*"))
- assert all([x.is_file() for x in out_files])
-
+ assert result.exit_code == 0, result.output
+ out_files = out_dir.glob("*")
[x.unlink() for x in out_files]
out_dir.rmdir()
@@ -67,13 +75,18 @@ def test_audio_tg(self):
if not out_dir.is_dir():
out_dir.mkdir()
runner = CliRunner()
- runner.invoke(
+ result = runner.invoke(
fasttrack,
- f"audio-textgrid --audio {str(self.audio_path)} --textgrid {str(self.tg_path)} --target-tier Phone --target-labels AY --dest {str(out_dir)}"
+ ["audio-textgrid",
+ "--audio", self.audio_path,
+ "--textgrid", self.tg_path,
+ "--target-tier", "Phone",
+ "--target-labels", "AY",
+ "--dest", out_dir]
)
+ assert result.exit_code == 0, result.output
out_files = list(out_dir.glob("*"))
- assert all([x.is_file() for x in out_files])
[x.unlink() for x in out_files]
out_dir.rmdir()
@@ -83,14 +96,18 @@ def test_corpus(self):
if not out_dir.is_dir():
out_dir.mkdir()
runner = CliRunner()
- runner.invoke(
+ result = runner.invoke(
fasttrack,
- f"corpus --corpus {str(self.corpus_path)} --target-labels AY --dest {str(out_dir)} --separate-output"
+ ["corpus",
+ "--corpus", self.corpus_path,
+ "--target-labels", "AY",
+ "--dest", out_dir,
+ "--separate-output"]
)
+ assert result.exit_code == 0, result.output
out_files = list(out_dir.iterdir())
- assert all([x.is_file() for x in out_files])
- #assert len(out_files) > 1
+ assert len(out_files) > 1
[x.unlink() for x in out_files]
out_dir.rmdir()