Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
## Description
Provide a brief description of the PR's purpose here.
### Summary
<!-- Provide a brief description of the PR's purpose here. -->

## Todos
Notable points that this PR has either accomplished or will accomplish.
- [ ] TODO 1
### Changes
<!-- List all the changes introduced in this PR. -->
Change 1 <!-- Rename Change 1 to reflect change title -->:
- <!-- Bullet point the changes in update 1. -->
-

## Questions
- [ ] Question1
Change 2 <!-- Rename Change 2 to reflect change title -->:
- <!-- Bullet point the changes in update 2. -->
-

## Status
- [ ] Ready to go
Change 3 <!-- Rename Change 3 to reflect change title -->:
- <!-- Bullet point the changes in update 3. -->
-

### Impact
- <!-- Bullet point the expected impact this PR will have on the codebase. -->
-
108 changes: 48 additions & 60 deletions .github/workflows/CI.yaml
Original file line number Diff line number Diff line change
@@ -1,82 +1,70 @@
name: CI
name: ci

on:
# GitHub has started calling new repo's first branch "main" https://github.com/github/renaming
# Existing codes likely still have "master" as the primary branch
# Both are tracked here to keep legacy and new codes working
push:
branches:
- "master"
- "main"
branches: [main]
pull_request:
branches:
- "master"
- "main"
schedule:
# Nightly tests run on master 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 * * *"

jobs:
test:
name: Test on ${{ matrix.os }}, Python ${{ matrix.python-version }}
runs-on: ${{ matrix.os }}
tests:
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
matrix:
os: [macOS-latest, ubuntu-latest, windows-latest]
python-version: ['3.9', '3.10']

python-version: ["3.11", "3.12", "3.13"]
name: Run tests
steps:
- uses: actions/checkout@v1

- name: Additional info about the build
shell: bash
run: |
uname -a
df -h
ulimit -a

- name: Checkout repo
uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Testing Dependencies
shell: bash
run: |
python -m pip install -U pytest pytest-cov codecov

- name: Install package

- name: Install CodeEntropy and its testing dependencies
shell: bash
run: |
python -m pip install .


- name: Run tests
run: pip install -e .[testing]

- name: Run test suite
shell: bash
run: pytest --cov CodeEntropy --cov-report term-missing --cov-append .

run: |
pytest -v --cov=CodeEntropy --cov-report=xml --color=yes CodeEntropy/tests/
- name: Coveralls GitHub Action
uses: coverallsapp/github-action@v2.3.6
with:
github-token: ${{ secrets.COVERALLS_REPO_TOKEN }}

- name: CodeCov
uses: codecov/codecov-action@v1
docs:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
file: ./coverage.xml
flags: unittests
name: codecov-${{ matrix.os }}-py${{ matrix.python-version }}

- name: Testing executable capped protein
shell: bash
if: runner.os != 'Windows'
python-version: 3.12
- name: Install python dependencies
run: |
CodeEntropyPoseidon -f "CodeEntropy/tests/data/poseidon_example.prmtop" "CodeEntropy/tests/data/poseidon_example.trr" -l "resname ARG" -b 0 -e 20 --wm --res --uatom --topog 2 --solwm --solres --soluatom --solContact
pip install --upgrade pip
pip install -e .[docs]
- name: Build docs
run: cd docs && make

- name: Testing executable lysozyme in water Multi-threading
shell: bash
if: runner.os == 'Linux'
run: |
CodeEntropyPoseidon -f "CodeEntropy/tests/data/1AKI_prod_60.tpr" "CodeEntropy/tests/data/1AKI_prod_60.trr" -l "protein" -b 2 -e 12 -d 2 -t 2 --wm --res --uatom --topog 3 --solwm --solres --soluatom --solContact
pre-commit:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install python dependencies
run: |
pip install --upgrade pip
pip install -e .[pre-commit,docs,testing]
- name: Run pre-commit
run: |
pre-commit install
pre-commit run --all-files || ( git status --short ; git diff ; exit 1 )
28 changes: 28 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
repos:
- repo: https://github.com/psf/black
rev: 25.1.0
hooks:
- id: black

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: check-added-large-files
- id: check-ast
- id: check-case-conflict
- id: check-executables-have-shebangs
- id: check-merge-conflict
- id: check-toml
- id: check-yaml

- repo: https://github.com/pycqa/flake8
rev: 7.0.0
hooks:
- id: flake8
additional_dependencies: [flake8-pyproject]

- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
args: ["--profile=black"]
57 changes: 37 additions & 20 deletions CodeEntropy/ConformationFunctions.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import numpy as nmp
from MDAnalysis.analysis.dihedrals import Dihedral
import numpy as np

def assign_conformation(data_container, dihedral, number_frames, bin_width, start, end, step):
# from MDAnalysis.analysis.dihedrals import Dihedral


def assign_conformation(
data_container, dihedral, number_frames, bin_width, start, end, step
):
"""
Create a state vector, showing the state in which the input dihedral is
as a function of time. The function creates a histogram from the timeseries of the
dihedral angle values and identifies points of dominant occupancy
as a function of time. The function creates a histogram from the timeseries of the
dihedral angle values and identifies points of dominant occupancy
(called CONVEX TURNING POINTS).
Based on the identified TPs, states are assigned to each configuration of the dihedral.

Based on the identified TPs, states are assigned to each configuration of the
dihedral.

Input
-----
dihedral_atom_group : the group of 4 atoms defining the dihedral
Expand All @@ -21,25 +26,26 @@ def assign_conformation(data_container, dihedral, number_frames, bin_width, star
Return
------
A timeseries with integer labels describing the state at each point in time.

"""
conformations = nmp.zeros(number_frames)
phi = nmp.zeros(number_frames)
conformations = np.zeros(number_frames)
phi = np.zeros(number_frames)

# get the values of the angle for the dihedral
# dihedral angle values have a range from -180 to 180
for timestep in data_container.trajectory[start:end:step]:
value = dihedral.value()
# we want postive values in range 0 to 360 to make the peak assignment work
# using the fact that dihedrals have circular symetry (i.e. -15 degrees = +345 degrees)
# using the fact that dihedrals have circular symetry
# (i.e. -15 degrees = +345 degrees)
if value < 0:
value += 360
phi[timestep.frame] = value

# create a histogram using numpy
number_bins = int(360/bin_width)
popul, bin_edges = nmp.histogram(a=phi, bins=number_bins, range=(0,360))
bin_value = [0.5 * (bin_edges[i] + bin_edges[i+1]) for i in range(0,len(popul))]
number_bins = int(360 / bin_width)
popul, bin_edges = np.histogram(a=phi, bins=number_bins, range=(0, 360))
bin_value = [0.5 * (bin_edges[i] + bin_edges[i + 1]) for i in range(0, len(popul))]

# identify "convex turning-points" and populate a list of peaks
# peak : a bin whose neighboring bins have smaller population
Expand All @@ -50,19 +56,30 @@ def assign_conformation(data_container, dihedral, number_frames, bin_width, star
# if there is no dihedrals in a bin then it cannot be a peak
if popul[bin_index] == 0:
pass
# being careful of the last bin (dihedrals have circular symmetry, the histogram does not)
elif bin_index == number_bins-1: # the -1 is because the index starts with 0 not 1
if popul[bin_index] >= popul[bin_index-1] and popul[bin_index] >= popul[0]:
# being careful of the last bin
# (dihedrals have circular symmetry, the histogram does not)
elif (
bin_index == number_bins - 1
): # the -1 is because the index starts with 0 not 1
if (
popul[bin_index] >= popul[bin_index - 1]
and popul[bin_index] >= popul[0]
):
peak_values.append(bin_value[bin_index])
else:
if popul[bin_index] >= popul[bin_index-1] and popul[bin_index] >= popul[bin_index+1]:
if (
popul[bin_index] >= popul[bin_index - 1]
and popul[bin_index] >= popul[bin_index + 1]
):
peak_values.append(bin_value[bin_index])

# go through each frame again and assign conformation state
for frame in range(number_frames):
# find the TP that the snapshot is least distant from
distances = [abs(phi[frame] - peak) for peak in peak_values]
conformations[frame] = nmp.argmin(distances)
conformations[frame] = np.argmin(distances)

return conformations
#END assign_conformation


# END assign_conformation
Loading