• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CCPBioSim / CodeEntropy / 14328256002

08 Apr 2025 08:00AM UTC coverage: 39.089% (-0.1%) from 39.213%
14328256002

push

github

web-flow
Merge pull request #82 from CCPBioSim/80-controlling-trajectory-size

Resolve issue #80 fixing indexing issue for start parameter affecting timesteps

0 of 5 new or added lines in 2 files covered. (0.0%)

1 existing line in 1 file now uncovered.

249 of 637 relevant lines covered (39.09%)

1.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

13.79
/CodeEntropy/calculations/ConformationFunctions.py
1
import logging
3✔
2

3
import numpy as np
3✔
4

5
logger = logging.getLogger(__name__)
3✔
6

7
# from MDAnalysis.analysis.dihedrals import Dihedral
8

9

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

21
    Input
22
    -----
23
    dihedral_atom_group : the group of 4 atoms defining the dihedral
24
    number_frames : number of frames in the trajectory
25
    bin_width : the width of the histogram bit, default 30 degrees
26
    start : int, starting frame, will default to 0
27
    end : int, ending frame, will default to -1 (last frame in trajectory)
28
    step : int, spacing between frames, will default to 1
29

30
    Return
31
    ------
32
    A timeseries with integer labels describing the state at each point in time.
33

34
    """
35
    conformations = np.zeros(number_frames)
×
36
    phi = np.zeros(number_frames)
×
37

38
    # get the values of the angle for the dihedral
39
    # dihedral angle values have a range from -180 to 180
40
    for timestep in data_container.trajectory[start:end:step]:
×
NEW
41
        timestep_index = timestep.frame - start
×
UNCOV
42
        value = dihedral.value()
×
43
        # we want postive values in range 0 to 360 to make the peak assignment work
44
        # using the fact that dihedrals have circular symetry
45
        # (i.e. -15 degrees = +345 degrees)
46
        if value < 0:
×
47
            value += 360
×
NEW
48
        phi[timestep_index] = value
×
49

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

55
    # identify "convex turning-points" and populate a list of peaks
56
    # peak : a bin whose neighboring bins have smaller population
57
    # NOTE might have problems if the peak is wide with a flat or sawtooth top
58
    peak_values = []
×
59

60
    for bin_index in range(number_bins):
×
61
        # if there is no dihedrals in a bin then it cannot be a peak
62
        if popul[bin_index] == 0:
×
63
            pass
×
64
        # being careful of the last bin
65
        # (dihedrals have circular symmetry, the histogram does not)
66
        elif (
×
67
            bin_index == number_bins - 1
68
        ):  # the -1 is because the index starts with 0 not 1
69
            if (
×
70
                popul[bin_index] >= popul[bin_index - 1]
71
                and popul[bin_index] >= popul[0]
72
            ):
73
                peak_values.append(bin_value[bin_index])
×
74
        else:
75
            if (
×
76
                popul[bin_index] >= popul[bin_index - 1]
77
                and popul[bin_index] >= popul[bin_index + 1]
78
            ):
79
                peak_values.append(bin_value[bin_index])
×
80

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

87
    logger.debug(f"Final conformations: {conformations}")
×
88

89
    return conformations
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc