Skip to content

Commit

Permalink
Merge branch 'stage-0.1' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
aradi committed Nov 10, 2021
2 parents cf02c39 + 1b7774a commit 70419ea
Show file tree
Hide file tree
Showing 30 changed files with 2,435 additions and 217 deletions.
14 changes: 14 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -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
36 changes: 36 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: CI
on: [push, pull_request]

env:
HSD_PYTHON_VERSION: '0.1'

jobs:
test:

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2

- uses: actions/setup-python@v1
with:
python-version: '3.x'

- name: Install requirements (PIP)
run: pip3 install pytest sphinx numpy build

- name: Setup up root directory
run: echo "PACKAGE_ROOT=${PWD}/src" >> $GITHUB_ENV

- name: Build and install package
run: |
python -m build
pip install dist/hsd_python*.whl
python -c "import hsd; assert hsd.__version__ == '${HSD_PYTHON_VERSION}'"
- name: Run test pytest
run: python3 -m pytest

- name: Run doctest
run: cd docs; make doctest
12 changes: 12 additions & 0 deletions .lgtm.yml
Original file line number Diff line number Diff line change
@@ -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:
- src/versioneer.py # Set Versioneer.py to an external "library" (3rd party code)
- devtools/*
generated:
- src/hsd/_version.py
48 changes: 48 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
language: python

# Run jobs on container-based infrastructure, can be overridden per job

matrix:
include:
# Extra includes for OSX since python language is not available by default on OSX
- os: osx
language: generic
env: PYTHON_VER=3.6
- os: osx
language: generic
env: PYTHON_VER=3.7


# Pip can use Travis build-in Python
- os: linux
python: 3.6
- os: linux
dist: xenial # Travis Trusty image does not have Python 3.7, Xenial does
python: 3.7


before_install:
# Additional info about the build
- uname -a
- df -h
- ulimit -a

# Install the Python environment
- source devtools/travis-ci/before_install.sh
- python -V

install:

# Install the package locally
- pip install -U pytest pytest-cov codecov
- pip install -e src/


script:
- pytest -v --cov=hsd test/

notifications:
email: false

after_success:
- codecov
14 changes: 14 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
==========
Change Log
==========


0.1
===

Added
-----

* Basic functionality to manipulate HSD-data in Python.

* Pip installation
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2020 Bálint Aradi, Universität Bremen
Copyright (c) 2011-2021 DFTB+ developers group

All rights reserved.

Expand Down
114 changes: 90 additions & 24 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,23 +1,43 @@
************************************
HSD — Human-friendly Structured Data
************************************
**********************************************
HSD — Make your structured data human friendly
**********************************************

This Python package contains utilities to write (and soon also to read) files in
the Human-friendly Structured Data (HSD) format.
Utilities to read and write files in the Human-friendly Structured Data (HSD)
format.

It is licensed under the *BSD 2-clause license*.
The HSD-format is very similar to both JSON and YAML, but tries to minimize the
effort for **humans** to read and write it. It ommits special characters as much
as possible (in contrast to JSON) and is not indentation dependent (in contrast
to YAML). It was developed originally as the input format for the scientific
simulation tool (`DFTB+ <https://github.com/dftbplus/dftbplus>`_), but is
of general purpose. Data stored in HSD can be easily mapped to a subset of JSON
or XML and vica versa.

Detailed `documentation <https://hsd-python.readthedocs.io/>`_ can be found on
`Read the Docs <https://hsd-python.readthedocs.io/>`_.

The HSD format
==============

The HSD-format is very similar to both JSON and XML, but tries to minimize the
effort for humans to read and write it. It ommits special characters as much as
possible but (in contrast to YAML for example) is not indentation dependent.
Installation
============

The package can be installed via conda-forge::

conda install --channel "conda-forge" hsd-python

Alternatively, the package can be downloaded and installed via pip into the
active Python interpreter (preferably using a virtual python environment) by ::

pip install hsd

or into the user space issueing ::

It was developed originally developed as the input format for a scientific
simulation tool (DFTB+), but is absolutely general. A typical input written in
HSD would look like ::
pip install --user hsd


Quick tutorial
==============

A typical, self-explaining input written in HSD looks like ::

driver {
conjugate_gradients {
Expand All @@ -35,11 +55,13 @@ HSD would look like ::
}
filling {
fermi {
temperature [kelvin] = 1e-8
# This is comment which will be ignored
# Note the attribute (unit) of the field below
temperature [kelvin] = 100
}
}
k_points_and_weights {
supercell_folding = {
supercell_folding {
2 0 0
0 2 0
0 0 2
Expand All @@ -49,12 +71,56 @@ HSD would look like ::
}
}

Content in HSD format can be represented as JSON. Content in JSON format can be
represented as HSD, provided it satisfies a restriction for arrays: Either all
elements of an array must be objects or none of them. (This allows for a clear
separation of structure and data and allows for the very simple input format.)
The above input can be parsed into a Python dictionary with::

import hsd
hsdinput = hsd.load("test.hsd")

The dictionary ``hsdinput`` will then look as::

{
"driver": {
"conjugate_gradients" {
"moved_atoms": [1, 2, "7:19"],
"max_steps": 100
}
},
"hamiltonian": {
"dftb": {
"scc": True,
"scc_tolerance": 1e-10,
"mixer": {
"broyden": {}
},
"filling": {
"fermi": {
"temperature": 100,
"temperature.attrib": "kelvin"
}
}
"k_points_and_weights": {
"supercell_folding": [
[2, 0, 0],
[0, 2, 0],
[0, 0, 2],
[0.5, 0.5, 0.5]
]
}
}
}
}

Being a simple Python dictionary, it can be easily queried and manipulated in
Python ::

hsdinput["driver"]["conjugate_gradients"]["max_steps"] = 200

and then stored again in HSD format ::

hsd.dump(hsdinput, "test2.hsd")


License
========

Content in HSD format can be represented as XML (DOM-tree). Content in XML can
be converted to HSD, provided it satisfies the restriction that every child has
either data (text) or further children, but never both of them. (Again, this
ensures the simplicity of the input format.)
The hsd-python package is licensed under the `BSD 2-clause license <LICENSE>`_.
93 changes: 93 additions & 0 deletions devtools/set_version
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/usr/bin/env python3

"""Sets a version number in all relevant project files"""

import sys
import re
import os

# The pattern the version number must satisfy
VERSION_PATTERN = r'\d+\.\d+(?:\.\d+)?(?:-\w+)?'

# List of (file name, search pattern, replacement pattern) tuples for all
# the occurancies to be replaced.
FILES_PATTERNS = [('src/hsd/__init__.py',
r'^__version__\s*=\s*([\'"]){}\1'.format(VERSION_PATTERN),
"__version__ = '{version}'"),
('docs/introduction.rst',
r'hsd-python version[ ]*{}.'.format(VERSION_PATTERN),
'hsd-python version {shortversion}.'),
('setup.cfg',
r'version\s*=\s*{}'.format(VERSION_PATTERN),
"version = {version}"),
('docs/conf.py',
r'release\s*=\s*([\'"]){}\1'.format(VERSION_PATTERN),
"release = '{version}'"),
('.github/workflows/ci.yml',
r'HSD_PYTHON_VERSION:\s*([\'"]){}\1'.format(VERSION_PATTERN),
"HSD_PYTHON_VERSION: '{version}'"),
]


def main():
"""Main script."""

if len(sys.argv) < 2:
sys.stderr.write("Missing version string\n")
sys.exit(1)

version, shortversion = _get_version_strings(sys.argv[1])
rootdir = os.path.join(os.path.dirname(sys.argv[0]), '..')
_replace_version_in_files(FILES_PATTERNS, rootdir, version, shortversion)
_replace_version_in_changelog(rootdir, version)


def _get_version_strings(version):
"""Returns version and the short version as string"""

match = re.match(VERSION_PATTERN, version)
if match is None:
print("Invalid version string")
sys.exit(1)

shortversion = '.'.join(version.split('.')[0:2])
return version, shortversion


def _replace_version_in_files(files_patterns, rootdir, version, shortversion):
"""Replaces version number in given files with given search/replacement patterns"""

for fname, regexp, repl in files_patterns:
fname = os.path.join(rootdir, fname)
print("Replacments in '{}': ".format(os.path.relpath(fname, rootdir)), end='')
fp = open(fname, 'r')
txt = fp.read()
fp.close()
replacement = repl.format(version=version, shortversion=shortversion)
newtxt, nsub = re.subn(regexp, replacement, txt, flags=re.MULTILINE)
print(nsub)
fp = open(fname, 'w')
fp.write(newtxt)
fp.close()


def _replace_version_in_changelog(rootdir, version):
"""Replaces the unreleased section in CHANGELOG.rst"""

fname = os.path.join(rootdir, 'CHANGELOG.rst')
print("Replacments in '{}': ".format(os.path.relpath(fname, rootdir)), end='')
fp = open(fname, 'r')
txt = fp.read()
fp.close()
decoration = '=' * len(version)
newtxt, nsub = re.subn(
r'^Unreleased\s*\n=+', version + r'\n' + decoration, txt,
count=1, flags=re.MULTILINE)
print(nsub)
fp = open(fname, 'w')
fp.write(newtxt)
fp.close()


if __name__ == '__main__':
main()
21 changes: 21 additions & 0 deletions devtools/travis-ci/before_install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Temporarily change directory to $HOME to install software
pushd .
cd $HOME
# Make sure some level of pip is installed
python -m ensurepip

if [ "$TRAVIS_OS_NAME" == "osx" ]; then
HOMEBREW_NO_AUTO_UPDATE=1 brew upgrade pyenv
# Pyenv requires minor revision, get the latest
PYENV_VERSION=$(pyenv install --list |grep $PYTHON_VER | sed -n "s/^[ \t]*\(${PYTHON_VER}\.*[0-9]*\).*/\1/p" | tail -n 1)
# Install version
pyenv install $PYENV_VERSION
# Use version for this
pyenv global $PYENV_VERSION
# Setup up path shims
eval "$(pyenv init -)"
fi
pip install --upgrade pip setuptools

# Restore original directory
popd
Loading

0 comments on commit 70419ea

Please sign in to comment.