Skip to content

Commit

Permalink
Merge branch 'develop' into fmt-coordinates
Browse files Browse the repository at this point in the history
  • Loading branch information
RMeli authored Dec 24, 2024
2 parents 8922ee1 + 29deccc commit c141360
Show file tree
Hide file tree
Showing 27 changed files with 1,151 additions and 929 deletions.
3 changes: 2 additions & 1 deletion benchmarks/benchmarks/GRO.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import MDAnalysis as mda
import numpy as np
from MDAnalysis.coordinates.GRO import GROReader
from MDAnalysis.topology.GROParser import GROParser
from MDAnalysisTests.datafiles import GRO
import MDAnalysis as mda


class GROReadBench(object):
def time_read_GRO_coordinates(self):
Expand Down
128 changes: 61 additions & 67 deletions benchmarks/benchmarks/ag_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,31 @@
import numpy as np

try:
from MDAnalysisTests.datafiles import (GRO, TPR, XTC,
PSF, DCD,
TRZ_psf, TRZ)
from MDAnalysis.exceptions import NoDataError
from MDAnalysisTests.datafiles import DCD, GRO, PSF, TPR, TRZ, XTC, TRZ_psf
except:
pass


class AtomGroupMethodsBench(object):
"""Benchmarks for the various MDAnalysis
atomgroup methods.
"""

# NOTE: the write() method has been
# excluded as file writing is considered
# a separate benchmarking category

params = (10, 100, 1000, 10000)
param_names = ['num_atoms']
param_names = ["num_atoms"]

def setup(self, num_atoms):
self.u = MDAnalysis.Universe(GRO)
self.ag = self.u.atoms[:num_atoms]
self.weights = np.ones(num_atoms)
self.vdwradii = {'H':1.0,
'C':1.0,
'N':1.0,
'O':1.0,
'DUMMY':1.0}
self.rot_matrix = np.ones((3,3))
self.trans = np.ones((4,4))
self.vdwradii = {"H": 1.0, "C": 1.0, "N": 1.0, "O": 1.0, "DUMMY": 1.0}
self.rot_matrix = np.ones((3, 3))
self.trans = np.ones((4, 4))

def time_bbox_pbc(self, num_atoms):
"""Benchmark bounding box calculation
Expand Down Expand Up @@ -60,15 +56,13 @@ def time_center_pbc(self, num_atoms):
"""Benchmark center calculation with
pbc active.
"""
self.ag.center(weights=self.weights,
pbc=True)
self.ag.center(weights=self.weights, pbc=True)

def time_center_no_pbc(self, num_atoms):
"""Benchmark center calculation with
pbc inactive.
"""
self.ag.center(weights=self.weights,
pbc=False)
self.ag.center(weights=self.weights, pbc=False)

def time_centroid_pbc(self, num_atoms):
"""Benchmark centroid calculation with
Expand All @@ -83,8 +77,7 @@ def time_centroid_no_pbc(self, num_atoms):
self.ag.centroid(pbc=False)

def time_concatenate(self, num_atoms):
"""Benchmark atomgroup concatenation.
"""
"""Benchmark atomgroup concatenation."""
self.ag.concatenate(self.ag)

def time_difference(self, num_atoms):
Expand All @@ -97,7 +90,7 @@ def time_groupby(self, num_atoms):
"""Benchmark atomgroup groupby
operation.
"""
self.ag.groupby('resnames')
self.ag.groupby("resnames")

def time_guess_bonds(self, num_atoms):
"""Benchmark atomgroup bond guessing
Expand All @@ -106,18 +99,15 @@ def time_guess_bonds(self, num_atoms):
self.ag.guess_bonds(self.vdwradii)

def time_intersection(self, num_atoms):
"""Benchmark ag intersection.
"""
"""Benchmark ag intersection."""
self.ag.intersection(self.ag)

def time_is_strict_subset(self, num_atoms):
"""Benchmark ag strict subset operation.
"""
"""Benchmark ag strict subset operation."""
self.ag.is_strict_subset(self.ag)

def time_is_strict_superset(self, num_atoms):
"""Benchmark ag strict superset operation.
"""
"""Benchmark ag strict superset operation."""
self.ag.is_strict_superset(self.ag)

def time_isdisjoint(self, num_atoms):
Expand Down Expand Up @@ -155,19 +145,17 @@ def time_rotateby(self, num_atoms):
"""Benchmark rotation by an angle
of the ag coordinates.
"""
self.ag.rotateby(angle=45,
axis=[1,0,0])
self.ag.rotateby(angle=45, axis=[1, 0, 0])

def time_split(self, num_atoms):
"""Benchmark ag splitting into
multiple ags based on a simple
criterion.
"""
self.ag.split('residue')
self.ag.split("residue")

def time_subtract(self, num_atoms):
"""Benchmark ag subtraction.
"""
"""Benchmark ag subtraction."""
self.ag.subtract(self.ag)

def time_symmetric_difference(self, num_atoms):
Expand All @@ -187,7 +175,7 @@ def time_translate(self, num_atoms):
translation vector to the ag
coordinates.
"""
self.ag.translate([0,0.5,1])
self.ag.translate([0, 0.5, 1])

def time_union(self, num_atoms):
"""Benchmark union operation
Expand All @@ -202,14 +190,13 @@ def time_wrap(self, num_atoms):
self.ag.wrap()



class AtomGroupAttrsBench(object):
"""Benchmarks for the various MDAnalysis
atomgroup attributes.
"""

params = (10, 100, 1000, 10000)
param_names = ['num_atoms']
param_names = ["num_atoms"]

def setup(self, num_atoms):
self.u = MDAnalysis.Universe(GRO)
Expand All @@ -235,7 +222,7 @@ def time_dihedral(self, num_atoms):
"""
self.ag[:4].dihedral

#TODO: use universe / ag that
# TODO: use universe / ag that
# is suitable for force calc
def time_forces(self, num_atoms):
"""Benchmark atomgroup force
Expand All @@ -246,7 +233,7 @@ def time_forces(self, num_atoms):
except NoDataError:
pass

#TODO: use universe / ag that
# TODO: use universe / ag that
# is suitable for velocity extraction
def time_velocity(self, num_atoms):
"""Benchmark atomgroup velocity
Expand All @@ -265,8 +252,7 @@ def time_improper(self, num_atoms):
self.ag[:4].improper

def time_indices(self, num_atoms):
"""Benchmark atom index calculation.
"""
"""Benchmark atom index calculation."""
self.ag.ix

def time_atomcount(self, num_atoms):
Expand Down Expand Up @@ -326,15 +312,17 @@ def time_bond(self, num_atoms):

class CompoundSplitting(object):
"""Test how fast can we split compounds into masks and apply them
The benchmark used in Issue #3000. Parameterizes multiple compound number
and size combinations.
"""

params = [(100, 10000, 1000000), # n_atoms
(1, 10, 100), # n_compounds
(True, False), # homogeneous
(True, False)] # contiguous

params = [
(100, 10000, 1000000), # n_atoms
(1, 10, 100), # n_compounds
(True, False), # homogeneous
(True, False),
] # contiguous

def setup(self, n_atoms, n_compounds, homogeneous, contiguous):
rg = np.random.Generator(np.random.MT19937(3000))
Expand All @@ -345,7 +333,7 @@ def setup(self, n_atoms, n_compounds, homogeneous, contiguous):

if n_compounds == 1 and not (homogeneous and contiguous):
raise NotImplementedError

if n_compounds == n_atoms:
if not (homogeneous and contiguous):
raise NotImplementedError
Expand All @@ -354,51 +342,56 @@ def setup(self, n_atoms, n_compounds, homogeneous, contiguous):
ats_per_compound, remainder = divmod(n_atoms, n_compounds)
if remainder:
raise NotImplementedError
compound_indices = np.tile(np.arange(n_compounds),
(ats_per_compound, 1)).T.ravel()
compound_indices = np.tile(
np.arange(n_compounds), (ats_per_compound, 1)
).T.ravel()
else:
compound_indices = np.sort(np.floor(rg.random(n_atoms)
* n_compounds).astype(np.int))

compound_indices = np.sort(
np.floor(rg.random(n_atoms) * n_compounds).astype(np.int)
)

unique_indices = np.unique(compound_indices)
if len(unique_indices) != n_compounds:
raise RuntimeError

if not contiguous:
rg.shuffle(compound_indices)

self.u = MDAnalysis.Universe.empty(n_atoms,
n_residues=n_compounds,
n_segments=1,
atom_resindex=compound_indices,
trajectory=True)
self.u.atoms.positions = rg.random((n_atoms, 3),
dtype=np.float32) * 100

self.u = MDAnalysis.Universe.empty(
n_atoms,
n_residues=n_compounds,
n_segments=1,
atom_resindex=compound_indices,
trajectory=True,
)
self.u.atoms.positions = rg.random((n_atoms, 3), dtype=np.float32) * 100
self.u.dimensions = [50, 50, 50, 90, 90, 90]

def time_center_compounds(self, *args):
self.u.atoms.center(None, compound='residues')
self.u.atoms.center(None, compound="residues")


class FragmentFinding(object):
"""Test how quickly we find fragments (distinct molecules from bonds)"""

# if we try to parametrize over topology &
# trajectory formats asv will use all
# possible combinations, so instead handle
# this in setup()
params = ('large_fragment_small_solvents',
'large_fragment',
'polymer_chains', # 20ish polymer chains
)
param_names = ['universe_type']
params = (
"large_fragment_small_solvents",
"large_fragment",
"polymer_chains", # 20ish polymer chains
)
param_names = ["universe_type"]

def setup(self, universe_type):
if universe_type == 'large_fragment_small_solvents':
univ = (TPR, XTC)
elif universe_type == 'large_fragment':
if universe_type == "large_fragment_small_solvents":
univ = (TPR, XTC)
elif universe_type == "large_fragment":
univ = (PSF, DCD)
else:
univ = (TRZ_psf, TRZ)
univ = (TRZ_psf, TRZ)
self.u = MDAnalysis.Universe(*univ)

def time_find_fragments(self, universe_type):
Expand All @@ -407,6 +400,7 @@ def time_find_fragments(self, universe_type):

class FragmentCaching(FragmentFinding):
"""Test how quickly we find cached fragments"""

def setup(self, universe_type):
super(FragmentCaching, self).setup(universe_type)
frags = self.u.atoms.fragments # Priming the cache
Expand Down
34 changes: 9 additions & 25 deletions benchmarks/benchmarks/analysis/distances.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,20 @@ class DistancesBench(object):

def setup(self, num_atoms):
np.random.seed(17809)
self.coords_1 = np.random.random_sample((num_atoms, 3)).astype(
np.float32
)
self.coords_1 = np.random.random_sample((num_atoms, 3)).astype(np.float32)
np.random.seed(9008716)
self.coords_2 = np.random.random_sample((num_atoms, 3)).astype(
np.float32
)
self.coords_2 = np.random.random_sample((num_atoms, 3)).astype(np.float32)
np.random.seed(15809)
self.coords_3 = np.random.random_sample((num_atoms, 3)).astype(
np.float32
)
self.coords_3 = np.random.random_sample((num_atoms, 3)).astype(np.float32)
np.random.seed(871600)
self.coords_4 = np.random.random_sample((num_atoms, 3)).astype(
np.float32
)
self.coords_4 = np.random.random_sample((num_atoms, 3)).astype(np.float32)

self.allocated_array_2D = np.empty(
(num_atoms, num_atoms), dtype=np.float64
)
self.allocated_array_2D = np.empty((num_atoms, num_atoms), dtype=np.float64)
self.array_shape_1D = int(num_atoms * (num_atoms - 1) / 2.0)
self.allocated_array_1D = np.empty(
self.array_shape_1D, dtype=np.float64
)
self.allocated_array_1D = np.empty(self.array_shape_1D, dtype=np.float64)
self.u = mda.Universe(GRO)
self.ag1 = self.u.atoms[:num_atoms]
self.ag2 = self.u.atoms[num_atoms: 2 * num_atoms]
self.ag2 = self.u.atoms[num_atoms : 2 * num_atoms]
self.ag3 = self.u.atoms[-num_atoms:]

def time_distance_array(self, num_atoms):
Expand Down Expand Up @@ -139,9 +127,7 @@ def time_between(self, num_atoms):
of atomgroup that is within a specific
distance of two other atomgroups.
"""
distances.between(
group=self.ag3, A=self.ag1, B=self.ag2, distance=15.0
)
distances.between(group=self.ag3, A=self.ag1, B=self.ag2, distance=15.0)

def time_calc_bonds(self, num_atoms):
"""Benchmark calculation of bonds between
Expand All @@ -153,9 +139,7 @@ def time_calc_angles(self, num_atoms):
"""Benchmark calculation of angles between
atoms in three atomgroups.
"""
mda.lib.distances.calc_angles(
self.coords_1, self.coords_2, self.coords_3
)
mda.lib.distances.calc_angles(self.coords_1, self.coords_2, self.coords_3)

def time_calc_dihedrals(self, num_atoms):
"""Benchmark calculation of dihedrals between
Expand Down
Loading

0 comments on commit c141360

Please sign in to comment.