diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..dec7895 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,55 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-dockerfile +{ + "name": "Existing Dockerfile", + "build": { + // Sets the run context to one level up instead of the .devcontainer folder. + "context": "..", + // Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename. + "dockerfile": "../Dockerfile", + "target": "development" + }, + "customizations": { + "vscode": { + "settings": { + "python.languageServer": "Pylance", + "python.testing.pytestEnabled": true, + "python.testing.pytestArgs": [ + "tests" + ], + "[python]": { + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.organizeImports": true + }, + "editor.defaultFormatter": "charliermarsh.ruff" + }, + "files.autoSave": "afterDelay", + "files.autoSaveDelay": 1000 + }, + "extensions": [ + "ms-python.python", + "littlefoxteam.vscode-python-test-adapter", + "ms-vsliveshare.vsliveshare", + "mhutchie.git-graph", + "ms-toolsai.jupyter", + "charliermarsh.ruff" + ] + } + } + + // 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": [], + + // Uncomment the next line to run commands after the container is created. + // "postCreateCommand": "cat /etc/os-release", + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as an existing user other than the container default. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "devcontainer" +} diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..21fbe37 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,68 @@ +name: Lint and Test + +on: + workflow_dispatch: + push: + branches: [ "mdmix3-dev" ] + + pull_request: + branches: [ "mdmix3-dev" ] + +jobs: + build-dev: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + outputs: + REPOSITORY: ${{ steps.repository_lower.outputs.REPOSITORY }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Docker buildx + uses: docker/setup-buildx-action@v3 + + - name: Log into registry ghcr.io + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: set repository lower case + id: repository_lower + run: | + echo REPOSITORY=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]') >> $GITHUB_OUTPUT + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + tags: ghcr.io/${{ steps.repository_lower.outputs.REPOSITORY }}_dev + push: true + target: development + cache-from: type=gha + cache-to: type=gha,mode=max + + test: + needs: build-dev + runs-on: ubuntu-latest + container: + image: ghcr.io/${{ needs.build-dev.outputs.REPOSITORY }}_dev + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Run ruff + run: | + ruff check . + + - name: Run mypy + run: | + mypy . + + - name: Run pytest + run: | + pytest -v . \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3747545..5b17178 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,6 @@ -*.pyc -addiwraptorepl.py -build/ -makezip.sh -nbproject/ -pyMDMix-0.1.6.zip -pyMDMix.egg-info/ -src/mdmixscore.py - -singularity - +# do not save local vscode configuration for now .vscode/** + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] @@ -39,12 +30,6 @@ share/python-wheels/ *.egg MANIFEST -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - # Installer logs pip-log.txt pip-delete-this-directory.txt @@ -63,29 +48,6 @@ coverage.xml .hypothesis/ .pytest_cache/ -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - # Jupyter Notebook .ipynb_checkpoints @@ -93,25 +55,9 @@ target/ profile_default/ ipython_config.py -# pyenv -.python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - # PEP 582; used by e.g. github.com/David-OConnor/pyflow __pypackages__/ -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py # Environments .env @@ -122,20 +68,7 @@ ENV/ env.bak/ venv.bak/ -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - # mypy .mypy_cache/ .dmypy.json dmypy.json - -# Pyre type checker -.pyre/ diff --git a/Dockerfile b/Dockerfile index 2317ef5..e362592 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,22 @@ -FROM ggutierrezbio/ambertools20 -ARG CONDA_PREFIX="/opt/SOFT/miniconda3" -ENV PATH="$CONDA_PREFIX/bin:${PATH}" -ARG PATH="$CONDA_PREFIX/bin:${PATH}" - -SHELL [ "/bin/bash", "--login", "-c" ] -RUN apt-get update && apt-get install -y wget git && rm -rf /var/lib/apt/lists/* - -RUN wget \ - https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh \ - && bash Miniconda3-latest-Linux-x86_64.sh -b -p $CONDA_PREFIX \ - && rm -f Miniconda3-latest-Linux-x86_64.sh -RUN conda --version - -COPY ./environment_p27.yml ./environment_p27.yml -RUN conda env create -f environment_p27.yml -RUN echo ". $CONDA_PREFIX/etc/profile.d/conda.sh" >> ~/.bash_profile -RUN echo "conda activate mdmix-env" >> ~/.bash_profile -WORKDIR /mnt -SHELL ["conda", "run", "-n", "mdmix-env", "/bin/bash", "-c"] -ENTRYPOINT ["conda", "run", "-n", "mdmix-env", "mdmix"] +FROM continuumio/miniconda3 AS base + +ARG PYTHON_VERSION=3.12 + +# Create environment and install ambertools +RUN conda config --add channels defaults && \ + conda config --add channels bioconda && \ + conda config --add channels conda-forge + +# RUN apt update && apt install libnetcdf-dev -y + +RUN conda install -y python=${PYTHON_VERSION} ambertools + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +CMD ["bash"] + +FROM base AS development + +COPY requirements-dev.txt . +RUN python -m pip install -r requirements-dev.txt diff --git a/Licenses/license-mdmix.txt b/Licenses/license-mdmix.txt deleted file mode 100644 index eeaef1c..0000000 --- a/Licenses/license-mdmix.txt +++ /dev/null @@ -1,33 +0,0 @@ -<#if licenseFirst??> -${licenseFirst} - -${licensePrefix} ------------------------ pyMDMix ----------------------------------- -${licensePrefix} http://mdmix.sourceforge.net -${licensePrefix} -------------------------------------------------------------------- -${licensePrefix} -${licensePrefix} Software for preparation, analysis and quality control -${licensePrefix} of solvent mixtures molecular dynamics. -${licensePrefix} -${licensePrefix} Copyright (C) ${date?date?string("yyyy")} ${user} -${licensePrefix} -${licensePrefix} This program is free software: you can redistribute it and/or modify -${licensePrefix} it under the terms of the GNU General Public License as published by -${licensePrefix} the Free Software Foundation, either version 3 of the License, or -${licensePrefix} (at your option) any later version. -${licensePrefix} -${licensePrefix} This program is distributed in the hope that it will be useful, -${licensePrefix} but WITHOUT ANY WARRANTY; without even the implied warranty of -${licensePrefix} MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -${licensePrefix} GNU General Public License for more details. -${licensePrefix} -${licensePrefix} You should have received a copy of the GNU General Public License -${licensePrefix} along with this program. If not, see . -${licensePrefix} -${licensePrefix} Please cite your use of pyMDMix in published work: -${licensePrefix} -${licensePrefix} TOBEPUBLISHED -${licensePrefix} -${licensePrefix} -------------------------------------------------------------------- -<#if licenseLast??> -${licenseLast} - diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 666b4af..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,3 +0,0 @@ -include setup.py -recursive-include doc * -recursive-include pyMDMix/data * diff --git a/README.md b/README.md index ab94462..370711a 100644 --- a/README.md +++ b/README.md @@ -1,76 +1 @@ -## pyMDMix --- http://mdmix.sourceforge.net - -The program is distributed under GNU GPLv3 license. Find the license file -under Licenses/ folder. - -DOCUMENTATION -============= -All documentation on program usage is online at -http://mdmix.sourceforge.net - -INSTALLATION -============ - -1- Dependencies ---------------- -This version of pyMDMix depends on: - - ambertools>=12 - - python>=2.7 - -make sure ambertools environment variables are set - -2 - Installation process ------------------------- -it is advised to install pyMDMix in a virtual environment - -there are three recommended ways to install pyMDMix: -1. from the repository by -`python -m pip install [insert address here]` - -2. from the project's local folder after cloning the repo by -`python -m pip install .` - -3. Use conda or mamba: we will first create the correct conda environment which will already contain ambertools. We will then set the AMBERHOME variable within the environment and finally proceed to install pymdmix from the local git cloned files. Make sure `$CONDA_PREFIX` points to the conda installation directory (it may happen when you activate the new environment this varaible is lost, in that case change the variable for the explicit path). - -```bash -git clone https://github.com/CBDD/pyMDmix.git -cd pyMDMix -conda env create -f environment_p27.yml -conda activate mdmix-env -conda env config vars set AMBERHOME=$CONDA_PREFIX/envs/mdmix-env -pip install . -``` - -3 - Testing ------------ - -You can test the package has been successfuly installed by activating -the environment and, from a folder other than the cloned repository, running -`python -m pyMDMix` -if everything went fine, you will see something like -`Welcome to MDMix 2.6` - -The main script should have been installed correclty also. check it by running -`mdmix -h` - -Test the program works correctly: - Move again to the package source directory and type: - > python pyMDMix/test.py all - This will run a series of source code checks. - No test should fail. - -4 - Using Docker ----------------- -Build and run from a docker container using the provided Dockerfile. - -- docker build -t pymdmix . -- docker run -v $PWD:/mnt pymdmix -h - -The docker run command will mount the current working directory (windows users should replace $PWD by %cd%) so the container has access to the current location. Output will be also in the current working directory. -s - -4 - Enjoy! ----------- -Read program usage at online documentation. - - +# pyMDMix diff --git a/dist/pyMDMix-0.2.6-py2.7.egg b/dist/pyMDMix-0.2.6-py2.7.egg deleted file mode 100644 index 8c8aebe..0000000 Binary files a/dist/pyMDMix-0.2.6-py2.7.egg and /dev/null differ diff --git a/environment_p27.yml b/environment_p27.yml deleted file mode 100644 index 67d4a3b..0000000 --- a/environment_p27.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: mdmix-env -channels: - - conda-forge -dependencies: - - python=2.7 - - pip=19.3.1=py27_0 - - numpy=1.16 - - matplotlib - - scipy - - cftime - - ambertools - - netCDF4==1.5.3 - - mechanize - - biopython==1.76 - - griddataformats diff --git a/mdmix/__init__.py b/mdmix/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mdmix/core/__init__.py b/mdmix/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mdmix/core/main.py b/mdmix/core/main.py new file mode 100644 index 0000000..acaba69 --- /dev/null +++ b/mdmix/core/main.py @@ -0,0 +1,2 @@ +def main() -> None: + print("mdmix 0.3.0 - to be implemented") diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..a3dddc2 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,69 @@ +[project] +name = "mdmix" +version = "0.3.0" +description = "Molecular Dynamics with organic solvent mixtures setup and analysis" +requires-python = ">=3.12.0" +dynamic = ["dependencies", "optional-dependencies"] + +[tool.setuptools.dynamic] +dependencies = {file = ["requirements.txt"]} +optional-dependencies = { dev = {file = ["requirements-dev.txt"]} } + +[project.urls] +Repository = "https://github.com/CBDD/pyMDMix" + +[project.scripts] +sdfield = "rdock_utils.sdfield:main" +sdrmsd_old = "rdock_utils.sdrmsd_original:main" +sdrmsd = "rdock_utils.sdrmsd.main:main" +sdsplit = "rdock_utils.sdsplit:main" +sdtether = "rdock_utils.sdtether.main:main" +sdtether_old = "rdock_utils.sdtether_original:main" +sdfilter = "rdock_utils.sdfilter.main:main" +sdmodify = "rdock_utils.sdmodify:main" + +[tool.ruff] +line-length = 119 +target-version = "py312" +exclude = [".git","__pycache__","pyMDMix", "src", "createSolvents.py", "doc"] + +[tool.ruff.lint] +select = ["E4", "E7", "E9", "F", "I"] +ignore = ["E231","E501","E203"] + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" +skip-magic-trailing-comma = false +line-ending = "auto" + +[tool.mypy] +python_version = "3.12" +pretty = true +show_error_context = true +show_error_codes = true + +follow_imports = "silent" +ignore_missing_imports = true + +disallow_incomplete_defs = true +disallow_any_generics = true +disallow_subclassing_any = false +disallow_untyped_calls = true +disallow_untyped_defs = true +disallow_untyped_decorators = true + +warn_unused_configs = true +warn_unreachable = true +warn_redundant_casts = true +warn_unused_ignores = true +warn_return_any = true + +check_untyped_defs = true + +no_implicit_optional = true +no_implicit_reexport = false + +strict_equality = true + +exclude = ['^doc.*', '^setup\.py\.bak$', '^pyMDMix.*', '^src.*', 'createSolvents\.py$'] \ No newline at end of file diff --git a/requirements-dev.in b/requirements-dev.in new file mode 100644 index 0000000..b9a1861 --- /dev/null +++ b/requirements-dev.in @@ -0,0 +1,5 @@ +-c requirements.txt +ruff +mypy +pip-tools +pytest \ No newline at end of file diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..8763057 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,45 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile requirements-dev.in +# +build==1.2.2.post1 + # via pip-tools +click==8.2.0 + # via + # -c /workspaces/pymdmix/requirements.txt + # pip-tools +iniconfig==2.1.0 + # via pytest +mypy==1.15.0 + # via -r requirements-dev.in +mypy-extensions==1.1.0 + # via mypy +packaging==25.0 + # via + # -c /workspaces/pymdmix/requirements.txt + # build + # pytest +pip-tools==7.4.1 + # via -r requirements-dev.in +pluggy==1.5.0 + # via pytest +pyproject-hooks==1.2.0 + # via + # build + # pip-tools +pytest==8.3.5 + # via -r requirements-dev.in +ruff==0.11.9 + # via -r requirements-dev.in +typing-extensions==4.13.2 + # via + # -c /workspaces/pymdmix/requirements.txt + # mypy +wheel==0.45.1 + # via pip-tools + +# The following packages are considered to be unsafe in a requirements file: +# pip +# setuptools diff --git a/requirements.in b/requirements.in new file mode 100644 index 0000000..37e8e4e --- /dev/null +++ b/requirements.in @@ -0,0 +1,9 @@ +numpy +scipy +Matplotlib +netCDF4 +griddataformats +platformdirs +pydantic-settings +typer[all] +semver \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 3903467..16c416a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,88 @@ -numpy==1.16 -scipy>=0.18.1 -Matplotlib -netCDF4==1.5.3 -Biskit -mechanize -biopython==1.76 -griddataformats +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile requirements.in +# +annotated-types==0.7.0 + # via pydantic +certifi==2025.4.26 + # via netcdf4 +cftime==1.6.4.post1 + # via netcdf4 +click==8.2.0 + # via typer +contourpy==1.3.2 + # via matplotlib +cycler==0.12.1 + # via matplotlib +fonttools==4.58.0 + # via matplotlib +griddataformats==1.0.2 + # via -r requirements.in +kiwisolver==1.4.8 + # via matplotlib +markdown-it-py==3.0.0 + # via rich +matplotlib==3.10.3 + # via -r requirements.in +mdurl==0.1.2 + # via markdown-it-py +mrcfile==1.5.4 + # via griddataformats +netcdf4==1.7.2 + # via -r requirements.in +numpy==2.2.5 + # via + # -r requirements.in + # cftime + # contourpy + # griddataformats + # matplotlib + # mrcfile + # netcdf4 + # scipy +packaging==25.0 + # via matplotlib +pillow==11.2.1 + # via matplotlib +platformdirs==4.3.8 + # via -r requirements.in +pydantic==2.11.4 + # via pydantic-settings +pydantic-core==2.33.2 + # via pydantic +pydantic-settings==2.9.1 + # via -r requirements.in +pygments==2.19.1 + # via rich +pyparsing==3.2.3 + # via matplotlib +python-dateutil==2.9.0.post0 + # via matplotlib +python-dotenv==1.1.0 + # via pydantic-settings +rich==14.0.0 + # via typer +scipy==1.15.3 + # via + # -r requirements.in + # griddataformats +semver==3.0.4 + # via -r requirements.in +shellingham==1.5.4 + # via typer +six==1.17.0 + # via python-dateutil +typer[all]==0.15.3 + # via -r requirements.in +typing-extensions==4.13.2 + # via + # pydantic + # pydantic-core + # typer + # typing-inspection +typing-inspection==0.4.0 + # via + # pydantic + # pydantic-settings diff --git a/setup.py b/setup.py.bak similarity index 100% rename from setup.py rename to setup.py.bak diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_dummy.py b/tests/test_dummy.py new file mode 100644 index 0000000..32dc8f7 --- /dev/null +++ b/tests/test_dummy.py @@ -0,0 +1,4 @@ +# just a dummy test + +def test_all_ok() -> None: + assert True \ No newline at end of file