Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trajectory tab and 3D view updates. #346

Merged
merged 7 commits into from
Mar 8, 2024
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
16 changes: 11 additions & 5 deletions MDANSE/Src/MDANSE/Chemistry/ChemicalEntity.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,10 @@ def center_of_mass(self, configuration: _Configuration) -> NDArray[np.float64]:
:rtype: numpy.ndarray
"""
coords = configuration["coordinates"]
masses = [ATOMS_DATABASE[at.symbol]["atomic_weight"] for at in self.atom_list]
masses = [
ATOMS_DATABASE.get_atom_property(at.symbol, "atomic_weight")
for at in self.atom_list
]

return center_of_mass(coords, masses)

Expand All @@ -198,7 +201,10 @@ def mass(self) -> float:
@property
def masses(self) -> list[float]:
"""A list of masses of all non-ghost atoms within this chemical entity."""
return [ATOMS_DATABASE[at.symbol]["atomic_weight"] for at in self.atom_list]
return [
ATOMS_DATABASE.get_atom_property(at.symbol, "atomic_weight")
for at in self.atom_list
]

def find_transformation_as_quaternion(
self, conf1: _Configuration, conf2: Union[_Configuration, None] = None
Expand Down Expand Up @@ -320,7 +326,7 @@ def center_and_moment_of_inertia(
mr = Vector(0.0, 0.0, 0.0)
t = Tensor(3 * [3 * [0.0]])
for atom in self.atom_list:
ma = ATOMS_DATABASE[atom.symbol]["atomic_weight"]
ma = ATOMS_DATABASE.get_atom_property(atom.symbol, "atomic_weight")
r = Vector(configuration["coordinates"][atom.index, :])
m += ma
mr += ma * r
Expand Down Expand Up @@ -473,7 +479,7 @@ def __init__(

self._parent = None

self.element = ATOMS_DATABASE[self._symbol]["element"]
self.element = ATOMS_DATABASE.get_atom_property(self._symbol, "element")

for k, v in kwargs.items():
try:
Expand Down Expand Up @@ -2460,7 +2466,7 @@ def add_chemical_entity(self, chemical_entity: _ChemicalEntity) -> None:

# add the atoms to the rdkit molecule, ghost atoms are
# never added to the rdkit molecule object
atm_num = ATOMS_DATABASE[at.symbol]["atomic_number"]
atm_num = ATOMS_DATABASE.get_atom_property(at.symbol, "atomic_number")
rdkit_atm = Chem.Atom(atm_num)

# makes sure that rdkit doesn't add extra hydrogens
Expand Down
18 changes: 18 additions & 0 deletions MDANSE/Src/MDANSE/Chemistry/Databases.py
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,24 @@ def save(self) -> None:
with open(AtomsDatabase._USER_DATABASE, "w") as fout:
json.dump(d, fout)

def get_atom_property(self, symbol: str, property: str) -> Union[int, float, str]:
"""Faster access to the atom property as it avoids the deepcopy
in __getitem__.

Parameters
----------
symbol : str
Symbol of the atom.
property : str
Property of the atoms to get.

Returns
-------
Union[int, float, str]
The atom property.
"""
return self._data[symbol][property]


class MoleculesDatabaseError(Error):
"""This class handles the exceptions related to MoleculesDatabase"""
Expand Down
4 changes: 2 additions & 2 deletions MDANSE/Src/MDANSE/Framework/AtomMapping/atom_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ def guess_element(atm_label: str, mass: Union[float, int, None] = None) -> str:
if guess in ATOMS_DATABASE:
if mass is None:
return guess
num = ATOMS_DATABASE[guess]["proton"]
num = ATOMS_DATABASE.get_atom_property(guess, "proton")
atms = ATOMS_DATABASE.match_numeric_property("proton", num)
for atm in atms:
atm_mass = ATOMS_DATABASE[atm]["atomic_weight"]
atm_mass = ATOMS_DATABASE.get_atom_property(atm, "atomic_weight")
diff = abs(mass - atm_mass)
if diff < best_diff:
best_match = atm
Expand Down
4 changes: 2 additions & 2 deletions MDANSE/Src/MDANSE/Framework/AtomSelector/atom_selectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def select_element(
Union[set[int], bool]
The atom indices of the matched atoms.
"""
pattern = f"[#{ATOMS_DATABASE[symbol]['atomic_number']}]"
pattern = f"[#{ATOMS_DATABASE.get_atom_property(symbol, 'atomic_number')}]"
if check_exists:
return system.has_substructure_match(pattern)
else:
Expand All @@ -56,7 +56,7 @@ def select_hs_on_element(
Union[set[int], bool]
The atom indices of the matched atoms.
"""
num = ATOMS_DATABASE[symbol]["atomic_number"]
num = ATOMS_DATABASE.get_atom_property(symbol, "atomic_number")
if check_exists:
return system.has_substructure_match(f"[#{num}]~[H]")
else:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,10 @@ def configure(self, value):
self["elements"] = [[at.symbol] for at in selectedAtoms]
self["names"] = [at.symbol for at in selectedAtoms]
self["unique_names"] = sorted(set(self["names"]))
self["masses"] = [[ATOMS_DATABASE[n]["atomic_weight"]] for n in self["names"]]
self["masses"] = [
[ATOMS_DATABASE.get_atom_property(n, "atomic_weight")]
for n in self["names"]
]
self.error_status = "OK"

def get_natoms(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ def transmutate(self, selection, element):

atomSelConfigurator["unique_names"] = sorted(set(atomSelConfigurator["names"]))
atomSelConfigurator["masses"] = [
[ATOMS_DATABASE[n]["atomic_weight"]] for n in atomSelConfigurator["names"]
[ATOMS_DATABASE.get_atom_property(n, "atomic_weight")]
for n in atomSelConfigurator["names"]
]
self.error_status = "OK"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def get_weights(self):
for i in range(ascfg["selection_length"]):
name = ascfg["names"][i]
for el in ascfg["elements"][i]:
p = ATOMS_DATABASE[el][self["property"]]
p = ATOMS_DATABASE.get_atom_property(el, self["property"])
if name in weights:
weights[name] += p
else:
Expand Down
7 changes: 6 additions & 1 deletion MDANSE/Src/MDANSE/Framework/Jobs/Density.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,12 @@ def run_step(self, index):
atomic_density = self._n_atoms / cell_volume

mass_density = (
sum([ATOMS_DATABASE[s]["atomic_weight"] for s in self._symbols])
sum(
[
ATOMS_DATABASE.get_atom_property(s, "atomic_weight")
for s in self._symbols
]
)
/ NAVOGADRO
/ cell_volume
)
Expand Down
6 changes: 4 additions & 2 deletions MDANSE/Src/MDANSE/Framework/Jobs/Eccentricity.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def initialize(self):
self._selectionTotalMass = np.sum(self._selectionMasses)

self._comMasses = [
ATOMS_DATABASE[self._atoms[idx].symbol]["atomic_weight"]
ATOMS_DATABASE.get_atom_property(self._atoms[idx].symbol, "atomic_weight")
for idx in self._comIndexes
]

Expand Down Expand Up @@ -196,7 +196,9 @@ def run_step(self, index):
atomsCoordinates = series[idxs, :]
difference = atomsCoordinates - com

w = ATOMS_DATABASE[name][self.configuration["weights"]["property"]]
w = ATOMS_DATABASE.get_atom_property(
name, self.configuration["weights"]["property"]
)

xx += np.add.reduce(
w
Expand Down
8 changes: 4 additions & 4 deletions MDANSE/Src/MDANSE/Framework/Jobs/McStasVirtualInstrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,18 +125,18 @@ def initialize(self):
# Compute some parameters used for a proper McStas run
self._mcStasPhysicalParameters = {"density": 0.0}
self._mcStasPhysicalParameters["weight"] = sum(
[ATOMS_DATABASE[s]["atomic_weight"] for s in symbols]
[ATOMS_DATABASE.get_atom_property(s, "atomic_weight") for s in symbols]
)
self._mcStasPhysicalParameters["sigma_abs"] = (
sum([ATOMS_DATABASE[s]["xs_absorption"] for s in symbols])
sum([ATOMS_DATABASE.get_atom_property(s, "xs_absorption") for s in symbols])
* MCSTAS_UNITS_LUT["nm2"]
)
self._mcStasPhysicalParameters["sigma_coh"] = (
sum([ATOMS_DATABASE[s]["xs_coherent"] for s in symbols])
sum([ATOMS_DATABASE.get_atom_property(s, "xs_coherent") for s in symbols])
* MCSTAS_UNITS_LUT["nm2"]
)
self._mcStasPhysicalParameters["sigma_inc"] = (
sum([ATOMS_DATABASE[s]["xs_incoherent"] for s in symbols])
sum([ATOMS_DATABASE.get_atom_property(s, "xs_incoherent") for s in symbols])
* MCSTAS_UNITS_LUT["nm2"]
)
for frameIndex in self.configuration["frames"]["value"]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -447,8 +447,8 @@ def finalize(self):

# Compute coherent functions and structure factor
for pair in self._elementsPairs:
bi = ATOMS_DATABASE[pair[0]]["b_coherent"]
bj = ATOMS_DATABASE[pair[1]]["b_coherent"]
bi = ATOMS_DATABASE.get_atom_property(pair[0], "b_coherent")
bj = ATOMS_DATABASE.get_atom_property(pair[1], "b_coherent")
ni = nAtomsPerElement[pair[0]]
nj = nAtomsPerElement[pair[1]]
ci = ni / nTotalAtoms
Expand Down Expand Up @@ -483,7 +483,7 @@ def finalize(self):

# Compute incoherent functions and structure factor
for element, ni in nAtomsPerElement.items():
bi = ATOMS_DATABASE[element]["b_incoherent2"]
bi = ATOMS_DATABASE.get_atom_property(element, "b_incoherent2")
ni = nAtomsPerElement[element]
ci = ni / nTotalAtoms

Expand Down
5 changes: 4 additions & 1 deletion MDANSE/Src/MDANSE/Framework/Jobs/SolventAccessibleSurface.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,10 @@ def initialize(self):
# A mapping between the atom indexes and covalent_radius radius for the whole universe.
self.vdwRadii = dict(
[
(at.index, ATOMS_DATABASE[at.symbol]["covalent_radius"])
(
at.index,
ATOMS_DATABASE.get_atom_property(at.symbol, "covalent_radius"),
)
for at in self.configuration["trajectory"][
"instance"
].chemical_system.atom_list
Expand Down
2 changes: 1 addition & 1 deletion MDANSE/Src/MDANSE/Framework/Jobs/Temperature.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def run_step(self, index):

symbol = atom.symbol

mass = ATOMS_DATABASE[symbol]["atomic_weight"]
mass = ATOMS_DATABASE.get_atom_property(symbol, "atomic_weight")

trajectory = self.configuration["trajectory"]["instance"]

Expand Down
18 changes: 9 additions & 9 deletions MDANSE/Src/MDANSE/Framework/Jobs/XRayStaticStructureFactor.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,18 @@

def atomic_scattering_factor(element, qvalues):
a = np.empty((4,), dtype=np.float64)
a[0] = ATOMS_DATABASE[element]["xray_asf_a1"]
a[1] = ATOMS_DATABASE[element]["xray_asf_a2"]
a[2] = ATOMS_DATABASE[element]["xray_asf_a3"]
a[3] = ATOMS_DATABASE[element]["xray_asf_a4"]
a[0] = ATOMS_DATABASE.get_atom_property(element, "xray_asf_a1")
a[1] = ATOMS_DATABASE.get_atom_property(element, "xray_asf_a2")
a[2] = ATOMS_DATABASE.get_atom_property(element, "xray_asf_a3")
a[3] = ATOMS_DATABASE.get_atom_property(element, "xray_asf_a4")

b = np.empty((4,), dtype=np.float64)
b[0] = ATOMS_DATABASE[element]["xray_asf_b1"]
b[1] = ATOMS_DATABASE[element]["xray_asf_b2"]
b[2] = ATOMS_DATABASE[element]["xray_asf_b3"]
b[3] = ATOMS_DATABASE[element]["xray_asf_b4"]
b[0] = ATOMS_DATABASE.get_atom_property(element, "xray_asf_b1")
b[1] = ATOMS_DATABASE.get_atom_property(element, "xray_asf_b2")
b[2] = ATOMS_DATABASE.get_atom_property(element, "xray_asf_b3")
b[3] = ATOMS_DATABASE.get_atom_property(element, "xray_asf_b4")

c = ATOMS_DATABASE[element]["xray_asf_c"]
c = ATOMS_DATABASE.get_atom_property(element, "xray_asf_c")

return c + np.sum(
a[:, np.newaxis]
Expand Down
3 changes: 2 additions & 1 deletion MDANSE/Src/MDANSE/Mathematics/Graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,12 @@ def build_connected_components(self):

# Make a copy of the set, so we can modify it.
nodes = [self._nodes[k] for k in sorted(self._nodes.keys())]
nodes.reverse()

# Iterate while we still have nodes to process.
while nodes:
# Get a random node and remove it from the global set.
n = nodes.pop(0)
n = nodes.pop()

# This set will contain the next group of nodes connected to each other.
group = set([n])
Expand Down
2 changes: 1 addition & 1 deletion MDANSE/Src/MDANSE/MolecularDynamics/Connectivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def check_composition(self, chemical: ChemicalSystem):
atom_elements = [atom.symbol for atom in chemical.atoms]
unique_elements = np.unique(atom_elements)
radii = {
element: ATOMS_DATABASE[element]["covalent_radius"]
element: ATOMS_DATABASE.get_atom_property(element, "covalent_radius")
for element in unique_elements
}
self._elements = atom_elements
Expand Down
7 changes: 6 additions & 1 deletion MDANSE/Src/MDANSE/MolecularDynamics/MockTrajectory.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,12 @@ def read_com_trajectory(
last = len(self)

indexes = [at.index for at in atoms]
masses = np.array([ATOMS_DATABASE[at.symbol]["atomic_weight"] for at in atoms])
masses = np.array(
[
ATOMS_DATABASE.get_atom_property(at.symbol, "atomic_weight")
for at in atoms
]
)

frames = np.array([self.coordinates(fnum) for fnum in range(first, last, step)])
coords = frames[:, indexes, :].astype(np.float64)
Expand Down
13 changes: 9 additions & 4 deletions MDANSE/Src/MDANSE/MolecularDynamics/Trajectory.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,6 @@ def __init__(self, h5_filename):
# Define a default name for all chemical entities which have no name
resolve_undefined_molecules_name(self._chemical_system)

# Retrieve the connectivity
build_connectivity(self._chemical_system)
ic("Trajectory.__init__ ended")

def close(self):
Expand Down Expand Up @@ -231,7 +229,12 @@ def read_com_trajectory(
last = len(self)

indexes = [at.index for at in atoms]
masses = np.array([ATOMS_DATABASE[at.symbol]["atomic_weight"] for at in atoms])
masses = np.array(
[
ATOMS_DATABASE.get_atom_property(at.symbol, "atomic_weight")
for at in atoms
]
)
grp = self._h5_file["/configuration"]

coords = grp["coordinates"][first:last:step, :, :].astype(np.float64)
Expand Down Expand Up @@ -615,7 +618,9 @@ def __init__(

atoms = chemical_entity.atom_list

masses = [ATOMS_DATABASE[at.symbol]["atomic_weight"] for at in atoms]
masses = [
ATOMS_DATABASE.get_atom_property(at.symbol, "atomic_weight") for at in atoms
]

mass = sum(masses)

Expand Down
4 changes: 3 additions & 1 deletion MDANSE/Src/MDANSE/MolecularDynamics/TrajectoryUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,9 @@ def build_connectivity(
coords = conf.to_real_coordinates()[indexes, :]
cov_radii = np.zeros((n_atoms,), dtype=np.float64)
for i, at in enumerate(atoms):
cov_radii[i] = ATOMS_DATABASE[at.symbol.capitalize()]["covalent_radius"]
cov_radii[i] = ATOMS_DATABASE.get_atom_property(
at.symbol.capitalize(), "covalent_radius"
)

bonds = fast_calculation.cpt_cluster_connectivity_nopbc(
coords, cov_radii, tolerance
Expand Down
Loading
Loading