diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 0000000..a3ed7f4 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,14 @@ +# Codecov configuration to make it a bit less noisy +coverage: + status: + patch: false + project: + default: + threshold: 50% +comment: + layout: "header" + require_changes: false + branches: null + behavior: default + flags: null + paths: null \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fcc2c33 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +optimization_correction_rbfe/_version.py export-subst diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..82ed790 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,42 @@ +# How to contribute + +We welcome contributions from external contributors, and this document +describes how to merge code changes into this optimization_correction_rbfe. + +## Getting Started + +* Make sure you have a [GitHub account](https://github.com/signup/free). +* [Fork](https://help.github.com/articles/fork-a-repo/) this repository on GitHub. +* On your local machine, + [clone](https://help.github.com/articles/cloning-a-repository/) your fork of + the repository. + +## Making Changes + +* Add some really awesome code to your local fork. It's usually a [good + idea](http://blog.jasonmeridth.com/posts/do-not-issue-pull-requests-from-your-master-branch/) + to make changes on a + [branch](https://help.github.com/articles/creating-and-deleting-branches-within-your-repository/) + with the branch name relating to the feature you are going to add. +* When you are ready for others to examine and comment on your new feature, + navigate to your fork of optimization_correction_rbfe on GitHub and open a [pull + request](https://help.github.com/articles/using-pull-requests/) (PR). Note that + after you launch a PR from one of your fork's branches, all + subsequent commits to that branch will be added to the open pull request + automatically. Each commit added to the PR will be validated for + mergability, compilation and test suite compliance; the results of these tests + will be visible on the PR page. +* If you're providing a new feature, you must add test cases and documentation. +* When the code is ready to go, make sure you run the test suite using pytest. +* When you're ready to be considered for merging, check the "Ready to go" + box on the PR page to let the optimization_correction_rbfe devs know that the changes are complete. + The code will not be merged until this box is checked, the continuous + integration returns checkmarks, + and multiple core developers give "Approved" reviews. + +# Additional Resources + +* [General GitHub documentation](https://help.github.com/) +* [PR best practices](http://codeinthehole.com/writing/pull-requests-and-other-good-practices-for-teams-using-github/) +* [A guide to contributing to software packages](http://www.contribution-guide.org) +* [Thinkful PR example](http://www.thinkful.com/learn/github-pull-request-tutorial/#Time-to-Submit-Your-First-PR) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..c772b96 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,12 @@ +## Description +Provide a brief description of the PR's purpose here. + +## Todos +Notable points that this PR has either accomplished or will accomplish. + - [ ] TODO 1 + +## Questions +- [ ] Question1 + +## Status +- [ ] Ready to go \ No newline at end of file diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml new file mode 100644 index 0000000..fc4fbe0 --- /dev/null +++ b/.github/workflows/CI.yaml @@ -0,0 +1,66 @@ +name: CI + +on: + # GitHub has started calling new repo's first branch "main" https://github.com/github/renaming + # The cookiecutter uses the "--initial-branch" flag when it runs git-init + push: + branches: + - "main" + pull_request: + branches: + - "main" + schedule: + # Weekly tests run on main by default: + # Scheduled workflows run on the latest commit on the default or base branch. + # (from https://help.github.com/en/actions/reference/events-that-trigger-workflows#scheduled-events-schedule) + - cron: "0 0 * * 0" + +jobs: + test: + name: Test on ${{ matrix.os }}, Python ${{ matrix.python-version }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macOS-latest, ubuntu-latest, windows-latest] + python-version: [3.9, "3.10", "3.11"] + + steps: + - uses: actions/checkout@v4 + + - name: Additional info about the build + shell: bash + run: | + uname -a + df -h + ulimit -a + + # More info on options: https://github.com/marketplace/actions/setup-micromamba + - uses: mamba-org/setup-micromamba@v1 + with: + environment-file: devtools/conda-envs/test_env.yaml + environment-name: test + condarc: | + channels: + - conda-forge + create-args: >- + python=${{ matrix.python-version }} + + - name: Install package + # conda setup requires this special shell + shell: bash -l {0} + run: | + python -m pip install . --no-deps + micromamba list + + - name: Run tests + # conda setup requires this special shell + shell: bash -l {0} + run: | + pytest -v --cov=optimization_correction_rbfe --cov-report=xml --color=yes optimization_correction_rbfe/tests/ + + - name: CodeCov + uses: codecov/codecov-action@v1 + with: + file: ./coverage.xml + flags: unittests + name: codecov-${{ matrix.os }}-py${{ matrix.python-version }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..792a01a --- /dev/null +++ b/.gitignore @@ -0,0 +1,124 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# 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 + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +.pytest_cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# dotenv +.env + +# virtualenv +.venv +venv/ +ENV/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# Pycharm settings +.idea +*.iml +*.iws +*.ipr + +# Ignore Sublime Text settings +*.sublime-workspace +*.sublime-project + +# vim swap +*.swp + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# profraw files from LLVM? Unclear exactly what triggers this +# There are reports this comes from LLVM profiling, but also Xcode 9. +*profraw + +# In-tree generated files +*/_version.py +# Cookiecutter-CMS Test Artifacts +/tests/CI_files diff --git a/.lgtm.yml b/.lgtm.yml new file mode 100644 index 0000000..5e940b4 --- /dev/null +++ b/.lgtm.yml @@ -0,0 +1,12 @@ +# Configure LGTM for this package + +extraction: + python: # Configure Python + python_setup: # Configure the setup + version: 3 # Specify Version 3 +path_classifiers: + library: + - versioneer.py # Set Versioneer.py to an external "library" (3rd party code) + - devtools/* + generated: + - optimization_correction_rbfe/_version.py diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..5b2ac3e --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,77 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, +body size, disability, ethnicity, gender identity and expression, level of +experience, nationality, personal appearance, race, religion, or sexual +identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +Moreover, project maintainers will strive to offer feedback and advice to +ensure quality and consistency of contributions to the code. Contributions +from outside the group of project maintainers are strongly welcomed but the +final decision as to whether commits are merged into the codebase rests with +the team of project maintainers. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an +appointed representative at an online or offline event. Representation of a +project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at 'anandkeo@uci.edu'. The project team will +review and investigate all complaints, and will respond in a way that it deems +appropriate to the circumstances. The project team is obligated to maintain +confidentiality with regard to the reporter of an incident. Further details of +specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 1.4, available at +[http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8237eb2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ + +MIT License + +Copyright (c) 2024 Aakankschit Nandkeolyar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..e0267af --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,3 @@ +include CODE_OF_CONDUCT.md + +global-exclude *.py[cod] __pycache__ *.so diff --git a/README.md b/README.md new file mode 100644 index 0000000..8281471 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +optimization_correction_rbfe +============================== +[//]: # (Badges) +[![GitHub Actions Build Status](https://github.com/REPLACE_WITH_OWNER_ACCOUNT/optimization_correction_rbfe/workflows/CI/badge.svg)](https://github.com/REPLACE_WITH_OWNER_ACCOUNT/optimization_correction_rbfe/actions?query=workflow%3ACI) +[![codecov](https://codecov.io/gh/REPLACE_WITH_OWNER_ACCOUNT/optimization_correction_rbfe/branch/main/graph/badge.svg)](https://codecov.io/gh/REPLACE_WITH_OWNER_ACCOUNT/optimization_correction_rbfe/branch/main) + + +An workflow that utilizes constrianed optimization to estimate corrected absolute free energies from relative free energies. + +### Copyright + +Copyright (c) 2024, Aakankschit Nandkeolyar + + +#### Acknowledgements + +Project based on the +[Computational Molecular Science Python Cookiecutter](https://github.com/molssi/cookiecutter-cms) version 1.1. diff --git a/devtools/README.md b/devtools/README.md new file mode 100644 index 0000000..924a8ff --- /dev/null +++ b/devtools/README.md @@ -0,0 +1,56 @@ +# Development, testing, and deployment tools + +This directory contains a collection of tools for running Continuous Integration (CI) tests, +conda installation, and other development tools not directly related to the coding process. + + +## Manifest + +### Continuous Integration + +You should test your code, but do not feel compelled to use these specific programs. You also may not need Unix and +Windows testing if you only plan to deploy on specific platforms. These are just to help you get started. + +### Conda Environment: + +This directory contains the files to setup the Conda environment for testing purposes + +* `conda-envs`: directory containing the YAML file(s) which fully describe Conda Environments, their dependencies, and those dependency provenance's + * `test_env.yaml`: Simple test environment file with base dependencies. Channels are not specified here and therefore respect global Conda configuration + +### Additional Scripts: + +This directory contains OS agnostic helper scripts which don't fall in any of the previous categories +* `scripts` + * `create_conda_env.py`: Helper program for spinning up new conda environments based on a starter file with Python Version and Env. Name command-line options + + +## How to contribute changes +- Clone the repository if you have write access to the main repo, fork the repository if you are a collaborator. +- Make a new branch with `git checkout -b {your branch name}` +- Make changes and test your code +- Ensure that the test environment dependencies (`conda-envs`) line up with the build and deploy dependencies (`conda-recipe/meta.yaml`) +- Push the branch to the repo (either the main or your fork) with `git push -u origin {your branch name}` + * Note that `origin` is the default name assigned to the remote, yours may be different +- Make a PR on GitHub with your changes +- We'll review the changes and get your code into the repo after lively discussion! + + +## Checklist for updates +- [ ] Make sure there is an/are issue(s) opened for your specific update +- [ ] Create the PR, referencing the issue +- [ ] Debug the PR as needed until tests pass +- [ ] Tag the final, debugged version + * `git tag -a X.Y.Z [latest pushed commit] && git push --follow-tags` +- [ ] Get the PR merged in + +## Versioneer Auto-version +[Versioneer](https://github.com/warner/python-versioneer) will automatically infer what version +is installed by looking at the `git` tags and how many commits ahead this version is. The format follows +[PEP 440](https://www.python.org/dev/peps/pep-0440/) and has the regular expression of: +```regexp +\d+.\d+.\d+(?\+\d+-[a-z0-9]+) +``` +If the version of this commit is the same as a `git` tag, the installed version is the same as the tag, +e.g. `optimization_correction_rbfe-0.1.2`, otherwise it will be appended with `+X` where `X` is the number of commits +ahead from the last tag, and then `-YYYYYY` where the `Y`'s are replaced with the `git` commit hash. diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml new file mode 100644 index 0000000..006aecb --- /dev/null +++ b/devtools/conda-envs/test_env.yaml @@ -0,0 +1,18 @@ +name: test +channels: + + - defaults +dependencies: + # Base depends + - python + - pip + + # Testing + - pytest + - pytest-cov + - codecov + + # Pip-only installs + #- pip: + # - codecov + diff --git a/devtools/scripts/create_conda_env.py b/devtools/scripts/create_conda_env.py new file mode 100644 index 0000000..9ece84a --- /dev/null +++ b/devtools/scripts/create_conda_env.py @@ -0,0 +1,95 @@ +import argparse +import os +import re +import glob +import shutil +import subprocess as sp +from tempfile import TemporaryDirectory +from contextlib import contextmanager +# YAML imports +try: + import yaml # PyYAML + loader = yaml.safe_load +except ImportError: + try: + import ruamel_yaml as yaml # Ruamel YAML + except ImportError: + try: + # Load Ruamel YAML from the base conda environment + from importlib import util as import_util + CONDA_BIN = os.path.dirname(os.environ['CONDA_EXE']) + ruamel_yaml_path = glob.glob(os.path.join(CONDA_BIN, '..', + 'lib', 'python*.*', 'site-packages', + 'ruamel_yaml', '__init__.py'))[0] + # Based on importlib example, but only needs to load_module since its the whole package, not just + # a module + spec = import_util.spec_from_file_location('ruamel_yaml', ruamel_yaml_path) + yaml = spec.loader.load_module() + except (KeyError, ImportError, IndexError): + raise ImportError("No YAML parser could be found in this or the conda environment. " + "Could not find PyYAML or Ruamel YAML in the current environment, " + "AND could not find Ruamel YAML in the base conda environment through CONDA_EXE path. " + "Environment not created!") + loader = yaml.YAML(typ="safe").load # typ="safe" avoids odd typing on output + + +@contextmanager +def temp_cd(): + """Temporary CD Helper""" + cwd = os.getcwd() + with TemporaryDirectory() as td: + try: + os.chdir(td) + yield + finally: + os.chdir(cwd) + + +# Args +parser = argparse.ArgumentParser(description='Creates a conda environment from file for a given Python version.') +parser.add_argument('-n', '--name', type=str, + help='The name of the created Python environment') +parser.add_argument('-p', '--python', type=str, + help='The version of the created Python environment') +parser.add_argument('conda_file', + help='The file for the created Python environment') + +args = parser.parse_args() + +# Open the base file +with open(args.conda_file, "r") as handle: + yaml_script = loader(handle.read()) + +python_replacement_string = "python {}*".format(args.python) + +try: + for dep_index, dep_value in enumerate(yaml_script['dependencies']): + if re.match('python([ ><=*]+[0-9.*]*)?$', dep_value): # Match explicitly 'python' and its formats + yaml_script['dependencies'].pop(dep_index) + break # Making the assumption there is only one Python entry, also avoids need to enumerate in reverse +except (KeyError, TypeError): + # Case of no dependencies key, or dependencies: None + yaml_script['dependencies'] = [] +finally: + # Ensure the python version is added in. Even if the code does not need it, we assume the env does + yaml_script['dependencies'].insert(0, python_replacement_string) + +# Figure out conda path +if "CONDA_EXE" in os.environ: + conda_path = os.environ["CONDA_EXE"] +else: + conda_path = shutil.which("conda") +if conda_path is None: + raise RuntimeError("Could not find a conda binary in CONDA_EXE variable or in executable search path") + +print("CONDA ENV NAME {}".format(args.name)) +print("PYTHON VERSION {}".format(args.python)) +print("CONDA FILE NAME {}".format(args.conda_file)) +print("CONDA PATH {}".format(conda_path)) + +# Write to a temp directory which will always be cleaned up +with temp_cd(): + temp_file_name = "temp_script.yaml" + with open(temp_file_name, 'w') as f: + f.write(yaml.dump(yaml_script)) + sp.call("{} env create -n {} -f {}".format(conda_path, args.name, temp_file_name), shell=True) diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..b2bd7d2 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = optimization_correction_rbfe +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..f0b6570 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,23 @@ +# Compiling optimization_correction_rbfe's Documentation + +The docs for this project are built with [Sphinx](http://www.sphinx-doc.org/en/master/). +To compile the docs, first ensure that the necessary dependencies are installed. + + + +Once installed, you can use the `Makefile` in this directory to compile static HTML pages by +```bash +make html +``` + +The documentation contains default pages for "Getting Started", "User Guide", "Developer Guide" and API reference. +We recommend adopting these sections of documentation for your project to ensure comprehensive documentation for all aspects of your project. + +The compiled docs will be in the `_build` directory and can be viewed by opening `index.html` (which may itself +be inside a directory called `html/` depending on what version of Sphinx is installed). + + +A configuration file for [Read The Docs](https://readthedocs.org/) (readthedocs.yaml) is included in the top level of the repository. To use Read the Docs to host your documentation, go to https://readthedocs.org/ and connect this repository. You may need to change your default branch to `main` under Advanced Settings for the project. + +If you would like to use Read The Docs with `autodoc` (included automatically) and your package has dependencies, you will need to include those dependencies in your documentation yaml file (`docs/requirements.yaml`). + diff --git a/docs/_static/README.md b/docs/_static/README.md new file mode 100644 index 0000000..2f0cf84 --- /dev/null +++ b/docs/_static/README.md @@ -0,0 +1,16 @@ +# Static Doc Directory + +Add any paths that contain custom static files (such as style sheets) here, +relative to the `conf.py` file's directory. +They are copied after the builtin static files, +so a file named "default.css" will overwrite the builtin "default.css". + +The path to this folder is set in the Sphinx `conf.py` file in the line: +```python +templates_path = ['_static'] +``` + +## Examples of file to add to this directory +* Custom Cascading Style Sheets +* Custom JavaScript code +* Static logo images diff --git a/docs/_templates/README.md b/docs/_templates/README.md new file mode 100644 index 0000000..3f4f804 --- /dev/null +++ b/docs/_templates/README.md @@ -0,0 +1,14 @@ +# Templates Doc Directory + +Add any paths that contain templates here, relative to +the `conf.py` file's directory. +They are copied after the builtin template files, +so a file named "page.html" will overwrite the builtin "page.html". + +The path to this folder is set in the Sphinx `conf.py` file in the line: +```python +html_static_path = ['_templates'] +``` + +## Examples of file to add to this directory +* HTML extensions of stock pages like `page.html` or `layout.html` diff --git a/docs/api.rst b/docs/api.rst new file mode 100644 index 0000000..8ba4332 --- /dev/null +++ b/docs/api.rst @@ -0,0 +1,7 @@ +API Documentation +================= + +.. autosummary:: + :toctree: autosummary + + optimization_correction_rbfe.canvas diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..1411326 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/stable/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. + +# Incase the project was not installed +import os +import sys +sys.path.insert(0, os.path.abspath('..')) + +import optimization_correction_rbfe + + +# -- Project information ----------------------------------------------------- + +project = 'optimization_correction_rbfe' +copyright = ("2024, Aakankschit Nandkeolyar. Project structure based on the " + "Computational Molecular Science Python Cookiecutter version 1.1") +author = 'Aakankschit Nandkeolyar' + +# The short X.Y version +version = '' +# The full version, including alpha/beta/rc tags +release = '' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autosummary', + 'sphinx.ext.autodoc', + 'sphinx.ext.mathjax', + 'sphinx.ext.viewcode', + 'sphinx.ext.napoleon', + 'sphinx.ext.intersphinx', + 'sphinx.ext.extlinks', + 'sphinx_design', + 'sphinx_copybutton', +] + + +autosummary_generate = True +napoleon_google_docstring = False +napoleon_use_param = False +napoleon_use_ivar = True + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path . +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'default' + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'pydata_sphinx_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'optimization_correction_rbfedoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'optimization_correction_rbfe.tex', 'optimization_correction_rbfe Documentation', + 'optimization_correction_rbfe', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'optimization_correction_rbfe', 'optimization_correction_rbfe Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'optimization_correction_rbfe', 'optimization_correction_rbfe Documentation', + author, 'optimization_correction_rbfe', 'An workflow that utilizes constrianed optimization to estimate corrected absolute free energies from relative free energies.', + 'Miscellaneous'), +] + + +# -- Extension configuration ------------------------------------------------- diff --git a/docs/developer_guide.rst b/docs/developer_guide.rst new file mode 100644 index 0000000..ba48bf0 --- /dev/null +++ b/docs/developer_guide.rst @@ -0,0 +1,4 @@ +Developer Guide +=============== + +This page details how to contribute to optimization_correction_rbfe. diff --git a/docs/getting_started.rst b/docs/getting_started.rst new file mode 100644 index 0000000..bd8ef62 --- /dev/null +++ b/docs/getting_started.rst @@ -0,0 +1,9 @@ +Getting Started +=============== + + +You might choose to write an overview tutorial or set of tutorials. + +.. code-block:: python + + import optimization_correction_rbfe diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..d8b0074 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,75 @@ +.. optimization_correction_rbfe documentation master file, created by + sphinx-quickstart on Thu Mar 15 13:55:56 2018. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to optimization_correction_rbfe's documentation! +========================================================= + +.. grid:: 1 1 2 2 + + .. grid-item-card:: Getting Started + :margin: 0 3 0 0 + + Learn the basics of using optimization_correction_rbfe. + + .. button-link:: ./getting_started.html + :color: primary + :outline: + :expand: + + To the Getting Started Guide + + + + .. grid-item-card:: User Guide + :margin: 0 3 0 0 + + An in-depth guide for users. + + .. button-link:: ./user_guide.html + :color: primary + :outline: + :expand: + + To the User Guide + + + + .. grid-item-card:: API Reference + :margin: 0 3 0 0 + + How to use the API of optimization_correction_rbfe. + + .. button-link:: ./api.html + :color: primary + :outline: + :expand: + + To the API Reference. + + + + .. grid-item-card:: Developer Guide + :margin: 0 3 0 0 + + How to contribute to optimization_correction_rbfe. + + .. button-link:: ./developer_guide.html + :color: primary + :outline: + :expand: + + To the Developer Guide + + +.. toctree:: + :maxdepth: 2 + :hidden: + :titlesonly: + + getting_started + user_guide + api + developer_guide + diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..e38ef58 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build +set SPHINXPROJ=optimization_correction_rbfe + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/requirements.yaml b/docs/requirements.yaml new file mode 100644 index 0000000..a745737 --- /dev/null +++ b/docs/requirements.yaml @@ -0,0 +1,16 @@ +name: docs_optimization_correction_rbfe +channels: + + - defaults +dependencies: + # Base depends + - python + - pip + + + + + # Pip-only installs + - pip: + - -e ../ + diff --git a/docs/user_guide.rst b/docs/user_guide.rst new file mode 100644 index 0000000..4cc23b6 --- /dev/null +++ b/docs/user_guide.rst @@ -0,0 +1,4 @@ +User Guide +=============== + +This page details how to use optimization_correction_rbfe. diff --git a/optimization_correction_rbfe/__init__.py b/optimization_correction_rbfe/__init__.py new file mode 100644 index 0000000..233fdb4 --- /dev/null +++ b/optimization_correction_rbfe/__init__.py @@ -0,0 +1,7 @@ +"""An workflow that utilizes constrianed optimization to estimate corrected absolute free energies from relative free energies.""" + +# Add imports here +from .node_optimization import * + + +from ._version import __version__ diff --git a/optimization_correction_rbfe/data/README.md b/optimization_correction_rbfe/data/README.md new file mode 100644 index 0000000..5301dae --- /dev/null +++ b/optimization_correction_rbfe/data/README.md @@ -0,0 +1,36 @@ +# Sample Package Data + +This directory contains sample additional data you may want to include with your package. +This is a place where non-code related additional information (such as data files, molecular structures, etc.) can +go that you want to ship alongside your code. + +Please note that it is not recommended to place large files in your git directory. If your project requires files larger +than a few megabytes in size it is recommended to host these files elsewhere. This is especially true for binary files +as the `git` structure is unable to correctly take updates to these files and will store a complete copy of every version +in your `git` history which can quickly add up. As a note most `git` hosting services like GitHub have a 1 GB per repository +cap. + +## Including package data + +Modify your package's `pyproject.toml` file. +Update the [tool.setuptools.package_data](https://setuptools.pypa.io/en/latest/userguide/datafiles.html#package-data) +and point it at the correct files. +Paths are relative to `package_dir`. + +Package data can be accessed at run time with `importlib.resources` or the `importlib_resources` back port. +See https://setuptools.pypa.io/en/latest/userguide/datafiles.html#accessing-data-files-at-runtime +for suggestions. + +If modules within your package will access internal data files using +[the recommended approach](https://setuptools.pypa.io/en/latest/userguide/datafiles.html#accessing-data-files-at-runtime), +you may need to include `importlib_resources` in your package dependencies. +In `pyproject.toml`, include the following in your `[project]` table. +``` +dependencies = [ + "importlib-resources;python_version<'3.10'", +] +``` + +## Manifest + +* `look_and_say.dat`: first entries of the "Look and Say" integer series, sequence [A005150](https://oeis.org/A005150) diff --git a/optimization_correction_rbfe/data/look_and_say.dat b/optimization_correction_rbfe/data/look_and_say.dat new file mode 100644 index 0000000..97df452 --- /dev/null +++ b/optimization_correction_rbfe/data/look_and_say.dat @@ -0,0 +1,15 @@ +1 +11 +21 +1211 +111221 +312211 +13112221 +1113213211 +31131211131221 +13211311123113112211 +11131221133112132113212221 +3113112221232112111312211312113211 +1321132132111213122112311311222113111221131221 +11131221131211131231121113112221121321132132211331222113112211 +311311222113111231131112132112311321322112111312211312111322212311322113212221 \ No newline at end of file diff --git a/optimization_correction_rbfe/node_optimization.py b/optimization_correction_rbfe/node_optimization.py new file mode 100644 index 0000000..b062e21 --- /dev/null +++ b/optimization_correction_rbfe/node_optimization.py @@ -0,0 +1,29 @@ +"""Provide the primary functions.""" + + +def canvas(with_attribution=True): + """ + Placeholder function to show example docstring (NumPy format). + + Replace this function and doc string for your own project. + + Parameters + ---------- + with_attribution : bool, Optional, default: True + Set whether or not to display who the quote is from. + + Returns + ------- + quote : str + Compiled string including quote and optional attribution. + """ + + quote = "The code is but a canvas to our imagination." + if with_attribution: + quote += "\n\t- Adapted from Henry David Thoreau" + return quote + + +if __name__ == "__main__": + # Do something if this file is invoked on its own + print(canvas()) diff --git a/optimization_correction_rbfe/py.typed b/optimization_correction_rbfe/py.typed new file mode 100644 index 0000000..6e3cdd2 --- /dev/null +++ b/optimization_correction_rbfe/py.typed @@ -0,0 +1 @@ +# PEP 561 marker file. See https://peps.python.org/pep-0561/ diff --git a/optimization_correction_rbfe/tests/__init__.py b/optimization_correction_rbfe/tests/__init__.py new file mode 100644 index 0000000..e131175 --- /dev/null +++ b/optimization_correction_rbfe/tests/__init__.py @@ -0,0 +1,3 @@ +""" +Empty init file in case you choose a package besides PyTest such as Nose which may look for such a file. +""" diff --git a/optimization_correction_rbfe/tests/test_optimization_correction_rbfe.py b/optimization_correction_rbfe/tests/test_optimization_correction_rbfe.py new file mode 100644 index 0000000..37a60d2 --- /dev/null +++ b/optimization_correction_rbfe/tests/test_optimization_correction_rbfe.py @@ -0,0 +1,15 @@ +""" +Unit and regression test for the optimization_correction_rbfe package. +""" + +# Import package, test suite, and other packages as needed +import sys + +import pytest + +import optimization_correction_rbfe + + +def test_optimization_correction_rbfe_imported(): + """Sample test, will always pass so long as import statement worked.""" + assert "optimization_correction_rbfe" in sys.modules diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..5fbb8b4 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,84 @@ +[build-system] +requires = ["setuptools>=61.0", "versioningit~=2.0"] +build-backend = "setuptools.build_meta" + +# Self-descriptive entries which should always be present +# https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ +[project] +name = "optimization_correction_rbfe" +description = "An workflow that utilizes constrianed optimization to estimate corrected absolute free energies from relative free energies." +dynamic = ["version"] +readme = "README.md" +authors = [ + { name = "Aakankschit Nandkeolyar", email = "anandkeo@uci.edu" } +] +license = { text = "MIT" } +# See https://pypi.org/classifiers/ +classifiers = [ + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", +] +requires-python = ">=3.8" +# Declare any run-time dependencies that should be installed with the package. +#dependencies = [ +# "importlib-resources;python_version<'3.10'", +#] + +# Update the urls once the hosting is set up. +#[project.urls] +#"Source" = "https://github.com//optimization_correction_rbfe/" +#"Documentation" = "https://optimization_correction_rbfe.readthedocs.io/" + +[project.optional-dependencies] +test = [ + "pytest>=6.1.2", +] + +[tool.setuptools] +# This subkey is a beta stage development and keys may change in the future, see https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html for more details +# +# As of version 0.971, mypy does not support type checking of installed zipped +# packages (because it does not actually import the Python packages). +# We declare the package not-zip-safe so that our type hints are also available +# when checking client code that uses our (installed) package. +# Ref: +# https://mypy.readthedocs.io/en/stable/installed_packages.html?highlight=zip#using-installed-packages-with-mypy-pep-561 +zip-safe = false +# Let setuptools discover the package in the current directory, +# but be explicit about non-Python files. +# See also: +# https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html#setuptools-specific-configuration +# Note that behavior is currently evolving with respect to how to interpret the +# "data" and "tests" subdirectories. As of setuptools 63, both are automatically +# included if namespaces is true (default), even if the package is named explicitly +# (instead of using 'find'). With 'find', the 'tests' subpackage is discovered +# recursively because of its __init__.py file, but the data subdirectory is excluded +# with include-package-data = false and namespaces = false. +include-package-data = false +[tool.setuptools.packages.find] +namespaces = false +where = ["."] + +# Ref https://setuptools.pypa.io/en/latest/userguide/datafiles.html#package-data +[tool.setuptools.package-data] +optimization_correction_rbfe = [ + "py.typed" +] + +[tool.versioningit] +default-version = "1+unknown" + +[tool.versioningit.format] +distance = "{base_version}+{distance}.{vcs}{rev}" +dirty = "{base_version}+{distance}.{vcs}{rev}.dirty" +distance-dirty = "{base_version}+{distance}.{vcs}{rev}.dirty" + +[tool.versioningit.vcs] +# The method key: +method = "git" # <- The method name +# Parameters to pass to the method: +match = ["*"] +default-tag = "1.0.0" + +[tool.versioningit.write] +file = "optimization_correction_rbfe/_version.py" diff --git a/readthedocs.yml b/readthedocs.yml new file mode 100644 index 0000000..69d6db5 --- /dev/null +++ b/readthedocs.yml @@ -0,0 +1,15 @@ +# readthedocs.yml + +version: 2 + +build: + image: latest + +python: + version: 3.8 + install: + - method: pip + path: . + +conda: + environment: docs/requirements.yaml \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..2e7eb32 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,22 @@ +# Helper file to handle all configs + +[coverage:run] +# .coveragerc to control coverage.py and pytest-cov +omit = + # Omit the tests + */tests/* + # Omit generated versioneer + optimization_correction_rbfe/_version.py + +[yapf] +# YAPF, in .style.yapf files this shows up as "[style]" header +COLUMN_LIMIT = 119 +INDENT_WIDTH = 4 +USE_TABS = False + +[flake8] +# Flake8, PyFlakes, etc +max-line-length = 119 + +[aliases] +test = pytest