import __main__
import numpy as np
from collections import namedtuple
from pygromos.files.blocks._general_blocks import _generic_gromos_block, _generic_field
from pygromos.files.blocks._general_blocks import TITLE as generic_TITLE
from pygromos.utils.typing import Union, List, Tuple, Dict, Number
TITLE: generic_TITLE = generic_TITLE
"""
FIELDS
"""
pertubation_eds_state = namedtuple("pertubationEdsState", ["IAC", "CHARGE"])
pertubation_lam_state_nonbonded = namedtuple("pertubationLamState", ["IAC", "MASS", "CHARGE"])
setattr(__main__, pertubation_eds_state.__name__, pertubation_eds_state)
pertubation_eds_state.__module__ = "__main__"
setattr(__main__, pertubation_lam_state_nonbonded.__name__, pertubation_lam_state_nonbonded)
pertubation_lam_state_nonbonded.__module__ = "__main__"
[docs]class atom_mass_type(_generic_field):
def __init__(self, N: int, ATMAS: float, ATMASN: str, comment: str = ""):
self.N = N
self.ATMAS = ATMAS
self.ATMASN = ATMASN
self.comment = comment
[docs] def to_string(self) -> str:
return self.comment + "{:<8} {:<3.4f} {:<5}\n".format(self.N, self.ATMAS, self.ATMASN)
[docs]class atom_eds_pertubation_state(_generic_field):
state_format_pattern = " {:>3} {:>10.5f}"
def __init__(
self, NR: int, NAME: str, STATES: Dict[int, pertubation_eds_state], ALPHLJ: float = 1.0, ALPHCRF: float = 1.0
):
self.NR = int(NR)
self.NAME = NAME
self.STATES = STATES
self.ALPHLJ = float(ALPHLJ)
self.ALPHCRF = float(ALPHCRF)
[docs] def to_string(self) -> str:
state_str = "".join(
[
self.state_format_pattern.format(int(self.STATES[x].IAC), float(self.STATES[x].CHARGE))
for x in sorted(self.STATES)
]
)
format_str = "{:>5} {:>5}" + state_str + " {:10.5f} {:10.5f}\n"
return format_str.format(self.NR, self.NAME, self.ALPHLJ, self.ALPHCRF)
[docs]class atom_lam_pertubation_state(_generic_field):
state_format_pattern = " {:>5} {:>5} {:>10.5f}"
def __init__(
self,
NR: int,
RES: int,
NAME: str,
STATES: Dict[int, pertubation_lam_state_nonbonded],
ALPHLJ: float = 1.0,
ALPHCRF: float = 1.0,
):
self.NR = int(NR)
self.RES = int(RES)
self.NAME = NAME
self.STATES = STATES
self.ALPHLJ = float(ALPHLJ)
self.ALPHCRF = float(ALPHCRF)
[docs] def to_string(self) -> str:
state_str = "".join(
[
self.state_format_pattern.format(
int(self.STATES[x].IAC), float(self.STATES[x].MASS), float(self.STATES[x].CHARGE)
)
for x in sorted(self.STATES)
]
)
format_str = "{:>5} {:>5} {:>5}" + state_str + " {:10.5f} {:10.5f}\n"
return format_str.format(self.NR, self.RES, self.NAME, self.ALPHLJ, self.ALPHCRF)
[docs]class atom_lam_pertubation_state_bond(_generic_field):
state_format_pattern = " {:>5}"
def __init__(self, NR: int, atomI: int, atomJ: int, STATES: Dict[int, int]):
self.NR = int(NR)
self.atomI = atomI
self.atomJ = atomJ
self.STATES = STATES
[docs] def to_string(self) -> str:
state_str = "".join([self.state_format_pattern.format(int(self.STATES[x])) for x in sorted(self.STATES)])
format_str = "{:>5} {:>5}" + state_str + "\n"
return format_str.format(self.atomI, self.atomJ)
[docs]class atom_lam_pertubation_state_angle(_generic_field):
state_format_pattern = " {:>5}"
def __init__(self, NR: int, atomI: int, atomJ: int, atomK: int, STATES: Dict[int, int]):
self.NR = int(NR)
self.atomI = atomI
self.atomJ = atomJ
self.atomK = atomK
self.STATES = STATES
[docs] def to_string(self) -> str:
state_str = "".join([self.state_format_pattern.format(int(self.STATES[x])) for x in sorted(self.STATES)])
format_str = "{:>5} {:>5} {:>5}" + state_str + "\n"
return format_str.format(self.atomI, self.atomJ, self.atomK)
[docs]class atom_lam_pertubation_state_dihedral(_generic_field):
state_format_pattern = " {:>5}"
def __init__(self, NR: int, atomI: int, atomJ: int, atomK: int, atomL: int, STATES: Dict[int, int]):
self.NR = int(NR)
self.atomI = atomI
self.atomJ = atomJ
self.atomK = atomK
self.atomL = atomL
self.STATES = STATES
[docs] def to_string(self) -> str:
state_str = "".join([self.state_format_pattern.format(int(self.STATES[x])) for x in sorted(self.STATES)])
format_str = "{:>5} {:>5} {:>5} {:>5}" + state_str + "\n"
return format_str.format(self.atomI, self.atomJ, self.atomK, self.atomL)
"""
BLOCKS
"""
# NONBONDED
[docs]class MPERTATOM(_generic_gromos_block):
[docs] def __init__(
self,
NJLA: int = None,
NPTB: int = None,
STATEIDENTIFIERS: List[str] = [],
STATEATOMHEADER: Tuple[str] = ["NR", "NAME", "ALPHLJ", "ALPHCRF"],
STATEATOMS: List[atom_eds_pertubation_state] = [],
dummy_IAC: int = 22,
dummy_CHARGE: float = 0.0,
content: List[str] = None,
):
"""
This block is used for lambda sampling to define the different states.
Parameters
----------
NJLA : int
number of perturbed atoms
NPTB : int
number of pertubation states
STATEIDENTIFIERS : List[str]
string names for states
STATEATOMHEADER
header for the atom description table
STATEATOMS
list of atoms, that shall be perturbed
dummy_IAC
dummy atom VdW type for perturbed atoms
dummy_CHARGE
dummy atom charge type for perturbed atoms
"""
if content is None:
super().__init__(used=True, name=__class__.__name__)
self.NJLA = NJLA
self.NPTB = NPTB
self.STATEIDENTIFIERS = STATEIDENTIFIERS
self.STATEATOMHEADER = STATEATOMHEADER
self.STATEATOMS = STATEATOMS
else:
super().__init__(used=True, name=__class__.__name__, content=content)
self.dummy_IAC = dummy_IAC
self.dummy_CHARGE = dummy_CHARGE
[docs] def read_content_from_str(self, content: List[str]):
field = 0
NJLA = None
STATEIDENTIFIERS = []
STATEATOMS = []
first = True
for line in content:
# print(line)
if "#" in line:
pass
else:
if field > 3:
if first:
STATEATOMHEADER = [
"NR",
"NAME",
]
[STATEATOMHEADER.extend(["IAC" + str(x), "CHARGE" + str(x)]) for x in range(1, self.NPTB + 1)]
STATEATOMHEADER += ["ALPHLJ", "ALPHCRF"]
self.STATEATOMHEADER = STATEATOMHEADER
first = False
state_line = {key: value for key, value in zip(self.STATEATOMHEADER, line.split())}
final_state_line = {
key: state_line[key] for key in state_line if ("IAC" not in key and "CHARGE" not in key)
}
states = {
x: pertubation_eds_state(
IAC=int(state_line["IAC" + str(x)]), CHARGE=float(state_line["CHARGE" + str(x)])
)
for x in range(1, 1 + self.NPTB)
}
final_state_line.update({"STATES": states})
STATEATOMS.append(atom_eds_pertubation_state(**final_state_line))
elif field == 0:
NJLA, NPTB = tuple(map(int, line.split()))
self.NJLA = NJLA
self.NPTB = NPTB
elif field == 1:
STATEIDENTIFIERS = line.split()
self.STATEIDENTIFIERS = STATEIDENTIFIERS
field += 1
self.STATEATOMS = STATEATOMS
@property
def nStates(self) -> int:
return self.NPTB
@property
def nTotalStateAtoms(self) -> int:
return self.NJLA
@property
def states(self) -> dict:
return {
self.STATEIDENTIFIERS[state - 1]: {
atom.NR: atom.STATES[state] for atom in sorted(self.STATEATOMS, key=lambda x: x.NR)
}
for state in range(1, self.NPTB + 1)
}
"""
ADD FUNCTIONS
"""
[docs] def add_state_atoms(self, state_atoms: List[atom_eds_pertubation_state]):
"""
This function can add states and atoms, but also overwrite state values of existing atoms.
If a new state is defined only for a subset of atoms, all other atoms are set to the default dummy.
If a new atom misses a state definition, this state will be set to dummy.
Parameters
----------
state_atoms: List[atom_eds_pertubation_state]
"""
# some preperations:
dummy_state = pertubation_eds_state(IAC=self.dummy_IAC, CHARGE=self.dummy_CHARGE)
insert_id = self.STATEATOMHEADER.index("ALPHLJ")
# find all new states
unique_stateIDs = np.unique(np.concatenate([list(natom.STATES.keys()) for natom in state_atoms]))
# TODO: not urgent; state number adaptation ( present states 1,2,3,4 new state 8 - id should be 5 not 8)
unique_states = list(map(str, ["state" + str(x) if isinstance(x, Number) else x for x in unique_stateIDs]))
# insert new state IDs
off = 0
for unique_state in unique_stateIDs:
self.STATEATOMHEADER.insert(insert_id + off, "IAC" + str(unique_state))
self.STATEATOMHEADER.insert(insert_id + off + 1, "CHARGE" + str(unique_state))
off += 2
# add new state names
self.STATEIDENTIFIERS.extend(unique_states)
# increase the number of new states
self.NPTB += len(unique_states)
# 1. Update already present atoms:
atomIDs = [atom.NR for atom in state_atoms]
for atom in self.STATEATOMS:
if atom.NR in atomIDs:
new_atom = state_atoms[atomIDs.index(atom.NR)]
atom.NAME = new_atom.NAME
atom.STATES.update({key: val for key, val in new_atom.STATES.items()})
# add missing dummies
# print(unique_stateIDs)
atom.STATES.update({key: dummy_state for key in unique_stateIDs if key not in atom.STATES})
# remove present atom
del atomIDs[atomIDs.index(atom.NR)]
else:
# add missing dummies
atom.STATES.update({key: dummy_state for key in unique_stateIDs if key not in atom.STATES})
# 2. add new atoms
new_atoms = [atom for atom in state_atoms if (atom.NR in atomIDs)]
for atom in new_atoms:
atom.STATES.update({key: dummy_state for key in range(1, self.NPTB + 1) if (key not in atom.STATES)})
self.STATEATOMS.append(atom)
self.NJLA += 1
"""
DELETING FUNCTIONS
"""
[docs] def delete_state(self, stateIDs: Union[int, List[int]] = None, stateNames: Union[str, List[str]] = None):
"""
This function deletes an state column.
Parameters
----------
stateIDs: int
number of the state
Returns
-------
"""
if stateIDs is not None:
if isinstance(stateIDs, int):
stateIDs = [stateIDs]
for state in stateIDs:
for atom in self.STATEATOMS:
if state in atom.STATES:
del atom.STATES[state]
del self.STATEIDENTIFIERS[state - 1]
self.STATEATOMHEADER = [
x for x in self.STATEATOMHEADER if (not x == "IAC" + str(state) and not "CHARGE" + str(state) == x)
]
self.NPTB -= len(set(stateIDs))
elif stateNames is not None:
if isinstance(stateNames, str):
stateNames = [stateNames]
for stateN in stateNames:
# print(stateN)
stateID = self.STATEIDENTIFIERS.index(stateN) + 1
for atom in self.STATEATOMS:
if stateID in atom.STATES:
del atom.STATES[stateID]
del self.STATEIDENTIFIERS[stateID - 1]
self.STATEATOMHEADER = [
x
for x in self.STATEATOMHEADER
if (not x == "IAC" + str(stateID) and not "CHARGE" + str(stateID) == x)
]
self.NPTB -= len(set(stateNames))
elif stateNames is None and stateIDs is None:
raise Exception("Please give either stateNames or stateIDs")
[docs] def delete_atom(self, atomNR: Union[int, List[int]]):
"""
This function removes atom lines from the ptp file.
Parameters
----------
atomNR: int
atom to be removed.
"""
if isinstance(atomNR, int):
atomNR = [atomNR]
# ind_offset = 0
new_STATEATOMS = []
for ind, atom in enumerate(self.STATEATOMS):
if atom.NR in atomNR:
continue
else:
new_STATEATOMS.append(atom)
self.STATEATOMS = new_STATEATOMS
self.NJLA -= len(atomNR)
"""
STR FUNCTIONS
"""
def _state_STATEATOMHEADER_str(self):
state_format_pattern = "{:>3} {:>5}" + "".join([" {:>3}{:>10}" for x in range(self.NPTB)]) + " {:10} {:10}"
if len(self.STATEATOMHEADER) != self.NPTB * 2 + 4:
tmp_list = " ".join(["CHARGE" + str(x) + " " + "IAC" + str(x) for x in range(self.NPTB)])
self.STATEATOMHEADER = self.STATEATOMHEADER[:2] + tmp_list.split(" ") + self.STATEATOMHEADER[-2:]
return state_format_pattern.format(*self.STATEATOMHEADER)
[docs] def block_to_string(self) -> str:
result = self.name + self.line_seperator
result += "# NJLA " + self.field_seperator + "NPTB" + self.line_seperator
result += self.field_seperator + str(self.NJLA) + self.field_seperator + str(self.NPTB) + self.line_seperator
result += "# state_identifiers" + self.line_seperator
result += (
self.field_seperator + self.field_seperator.join(map(str, self.STATEIDENTIFIERS)) + self.line_seperator
)
result += "# " + self._state_STATEATOMHEADER_str() + self.line_seperator
result += "".join(map(str, sorted(self.STATEATOMS, key=lambda x: x.NR)))
result += "END" + self.line_seperator
return result
[docs]class PERTATOMPARAM(_generic_gromos_block):
def __init__(
self,
STATEATOMS: List[atom_lam_pertubation_state] = None,
STATEATOMHEADER: Tuple[str] = None,
NJLA: int = None,
STATEIDENTIFIERS=None,
dummy_IAC=22,
dummy_CHARGE=0.0,
content: List[str] = None,
):
self.NPTB = 2
self.dummy_IAC = dummy_IAC
self.dummy_CHARGE = dummy_CHARGE
if content is None:
if STATEATOMHEADER is None:
self.STATEATOMHEADER = [
"NR",
"RES",
"NAME",
]
for s in range(self.NPTB):
self.STATEATOMHEADER += [
"IAC",
"MASS",
"CHARGE",
]
self.STATEATOMHEADER += ["ALPHLJ", "ALPHCRF"]
else:
self.STATEATOMHEADER = STATEATOMHEADER
if STATEATOMS is None:
self.STATEATOMS = []
else:
self.STATEATOMS = []
self.NJLA = 0
self.add_state_atoms(STATEATOMS)
super().__init__(used=True, name=__class__.__name__)
else:
super().__init__(used=True, name=__class__.__name__, content=content)
# You can check yourself :)
if NJLA is not None and len(STATEATOMS) != NJLA:
raise ValueError(
"NJLA must be equal to the length of STATEATOMS! NJLA="
+ str(NJLA)
+ "\t stateatoms"
+ str(len(STATEATOMS))
+ "\n\n"
+ str(self)
)
[docs] def read_content_from_str(self, content: List[str]):
field = 0
NJLA = None
STATEIDENTIFIERS = None
STATEATOMHEADER = None
STATEATOMS = []
first = True
stdid = False
for line in content:
if "#" in line:
# comment = line
if "state_identifiers" in line:
stdid = True
elif stdid:
STATEIDENTIFIERS = line.replace("#", "").split()
stdid = False
continue
else:
if field > 0:
if first:
STATEATOMHEADER = [
"NR",
"RES",
"NAME",
]
[
STATEATOMHEADER.extend(["IAC" + str(x), "MASS" + str(x), "CHARGE" + str(x)])
for x in range(1, 3)
]
STATEATOMHEADER += ["ALPHLJ", "ALPHCRF"]
first = False
state_line = {key: value for key, value in zip(STATEATOMHEADER, line.split())}
final_state_line = {
key: state_line[key]
for key in state_line
if ("IAC" not in key and "CHARGE" not in key and "MASS" not in key)
}
states = {
x: pertubation_lam_state_nonbonded(
IAC=int(round(float(state_line["IAC" + str(x)]))),
MASS=float(state_line["MASS" + str(x)]),
CHARGE=float(state_line["CHARGE" + str(x)]),
)
for x in range(1, 3)
}
final_state_line.update({"STATES": states})
STATEATOMS.append(atom_lam_pertubation_state(**final_state_line))
elif field == 0:
NJLA = int(line.strip())
field += 1
self.NJLA = NJLA
self.STATEIDENTIFIERS = STATEIDENTIFIERS
self.STATEATOMHEADER = STATEATOMHEADER
self.STATEATOMS = STATEATOMS
@property
def nStates(self) -> int:
return self.NPTB
@property
def nTotalStateAtoms(self) -> int:
return self.NJLA
@property
def states(self) -> Dict:
return {
self.STATEIDENTIFIERS[state - 1]: {
atom.NR: atom.STATES[state] for atom in sorted(self.STATEATOMS, key=lambda x: x.NR)
}
for state in range(1, self.NPTB + 1)
}
"""
ADD FUNCTIONS
"""
[docs] def add_state_atoms(self, state_atoms: List[atom_lam_pertubation_state]):
"""
This function can add states and atoms, but also overwrite state values of existing atoms.
If a new state is defined only for a subset of atoms, all other atoms are set to the default dummy.
If a new atom misses a state definition, this state will be set to dummy.
Parameters
----------
state_atoms: List[atom_eds_pertubation_state]
"""
# some preperations:
pre_dummy_state = lambda atomMass: pertubation_lam_state_nonbonded( # noqa: E731
IAC=self.dummy_IAC, MASS=atomMass, CHARGE=self.dummy_CHARGE
)
insert_id = self.STATEATOMHEADER.index("ALPHLJ")
# find all new states
keys = np.array([list(natom.STATES.keys()) for natom in state_atoms], ndmin=1)
unique_stateIDs = np.unique(np.concatenate(keys))
# TODO: not urgent; state number adaptation ( present states 1,2,3,4 new state 8 - id should be 5 not 8)
unique_states = list(map(str, ["state" + str(x) if isinstance(x, Number) else x for x in unique_stateIDs]))
# insert new state IDs
off = 0
for unique_state in unique_stateIDs:
self.STATEATOMHEADER.insert(insert_id + off, "IAC" + str(unique_state))
self.STATEATOMHEADER.insert(insert_id + off + 1, "mass" + str(unique_state))
self.STATEATOMHEADER.insert(insert_id + off + 2, "CHARGE" + str(unique_state))
off += 3
# add new state names
if hasattr(self, "STATEIDENTIFIERS"):
self.STATEIDENTIFIERS.extend(unique_states)
self.NPTB += len(unique_states)
else:
self.STATEIDENTIFIERS = unique_states
self.NPTB = len(unique_states)
# increase the number of new states
# 1. Update already present atoms:
atomIDs = [atom.NR for atom in state_atoms]
for atom in self.STATEATOMS:
atom.STATES.update({key: val for key, val in atom.STATES.items()})
possible_masses = [val.MASS for key, val in atom.STATES.items() if (val.MASS > 0)]
dummy_state = pre_dummy_state(atomMass=possible_masses[0])
if atom.NR in atomIDs:
new_atom = state_atoms[atomIDs.index(atom.NR)]
atom.NAME = new_atom.NAME
atom.STATES.update({key: val for key, val in new_atom.STATES.items()})
possible_masses = [val.MASS for key, val in new_atom.STATES.items() if (val.MASS > 0)]
# add missing dummies
# print(unique_stateIDs)
atom.STATES.update({key: dummy_state for key in unique_stateIDs if key not in atom.STATES})
# remove present atom
del atomIDs[atomIDs.index(atom.NR)]
else:
# add missing dummies
atom.STATES.update({key: dummy_state for key in unique_stateIDs if key not in atom.STATES})
# 2. add new atoms
new_atoms = [atom for atom in state_atoms if (atom.NR in atomIDs)]
for atom in new_atoms:
atom.STATES.update({key: val for key, val in atom.STATES.items()})
possible_masses = [val.MASS for key, val in atom.STATES.items() if (val.MASS > 0)]
dummy_state = pre_dummy_state(atomMass=possible_masses[0])
atom.STATES.update({key: dummy_state for key in range(1, self.NPTB + 1) if (key not in atom.STATES)})
self.STATEATOMS.append(atom)
self.NJLA += 1
"""
DELETING FUNCTIONS
"""
[docs] def delete_state(self, stateIDs: Union[int, List[int]] = None, stateNames: Union[str, List[str]] = None):
"""
This function deletes an state column.
Parameters
----------
stateIDs: int
number of the state
Returns
-------
"""
if stateIDs is not None:
if isinstance(stateIDs, int):
stateIDs = [stateIDs]
for state in stateIDs:
for atom in self.STATEATOMS:
if state in atom.STATES:
del atom.STATES[state]
del self.STATEIDENTIFIERS[state - 1]
self.STATEATOMHEADER = [
x for x in self.STATEATOMHEADER if (not x == "IAC" + str(state) and not "CHARGE" + str(state) == x)
]
self.NPTB -= len(set(stateIDs))
elif stateNames is not None:
if isinstance(stateNames, str):
stateNames = [stateNames]
for stateN in stateNames:
# print(stateN)
stateID = self.STATEIDENTIFIERS.index(stateN) + 1
for atom in self.STATEATOMS:
if stateID in atom.STATES:
del atom.STATES[stateID]
del self.STATEIDENTIFIERS[stateID - 1]
self.STATEATOMHEADER = [
x
for x in self.STATEATOMHEADER
if (not x == "IAC" + str(stateID) and not "CHARGE" + str(stateID) == x)
]
self.NPTB -= len(set(stateNames))
elif stateNames is None and stateIDs is None:
raise Exception("Please give either stateNames or stateIDs")
[docs] def delete_atom(self, atomNR: Union[int, List[int]]):
"""
This function removes atom lines from the ptp file.
Parameters
----------
atomNR: int
atom to be removed.
"""
if isinstance(atomNR, int):
atomNR = [atomNR]
# ind_offset = 0
new_STATEATOMS = []
for ind, atom in enumerate(self.STATEATOMS):
if atom.NR in atomNR:
continue
else:
new_STATEATOMS.append(atom)
self.STATEATOMS = new_STATEATOMS
self.NJLA -= len(atomNR)
"""
STR FUNCTIONS
"""
def _state_STATEATOMHEADER_str(self):
state_format_pattern = (
"{:>5} {:>5} {:>5}" + "".join([" {:>5}{:>5}{:>10}" for x in range(self.NPTB)]) + " {:10} {:10}"
)
return state_format_pattern.format(*self.STATEATOMHEADER)
[docs] def block_to_string(self) -> str:
result = self.name + self.line_seperator
result += (
"# NJLA "
+ self.field_seperator
+ "NPTB = "
+ self.field_seperator
+ str(self.NPTB)
+ self.field_seperator
+ self.line_seperator
)
result += self.field_seperator + str(self.NJLA) + self.line_seperator
result += "# state_identifiers" + self.line_seperator
result += (
"# "
+ self.field_seperator
+ self.field_seperator.join(map(str, self.STATEIDENTIFIERS))
+ self.line_seperator
)
result += "# " + self._state_STATEATOMHEADER_str() + self.line_seperator
result += "".join(map(str, sorted(self.STATEATOMS, key=lambda x: x.NR)))
result += "END" + self.line_seperator
return result
# BONDED
[docs]class PERTBONDSTRETCH(_generic_gromos_block):
def __init__(
self,
STATEATOMS: List[atom_lam_pertubation_state_bond] = None,
STATEATOMHEADER: Tuple[str] = None,
NPB: int = None,
dummy_BOND=22,
content: List[str] = None,
):
self.NPTB = 2
self.dummy_BOND = dummy_BOND
if content is None:
if STATEATOMHEADER is None:
self.STATEATOMHEADER = ["atomI", "atomJ", "type1", "type2"]
else:
self.STATEATOMHEADER = STATEATOMHEADER
if STATEATOMS is None:
self.STATEATOMS = []
else:
self.STATEATOMS = []
self.NPB = 0
# self.add_state_atoms(STATEATOMS)
super().__init__(used=True, name=__class__.__name__)
else:
super().__init__(used=True, name=__class__.__name__, content=content)
# You can check yourself :)
if NPB is not None and len(STATEATOMS) != NPB:
raise ValueError(
"NJLA must be equal to the length of STATEATOMS! NJLA="
+ str(NPB)
+ "\t stateatoms"
+ str(len(STATEATOMS))
+ "\n\n"
+ str(self)
)
@property
def nStates(self) -> int:
return self.NPTB
@property
def nTotalStateAtoms(self) -> int:
return self.NPB
@property
def states(self) -> dict:
return {
self.STATEIDENTIFIERS[state - 1]: {
atom.NR: atom.STATES[state] for atom in sorted(self.STATEATOMS, key=lambda x: x.NR)
}
for state in range(1, self.NPTB + 1)
}
[docs] def read_content_from_str(self, content: List[str]):
field = 0
NPB = None
STATEIDENTIFIERS = None
STATEATOMHEADER = None
STATEATOMS = []
first = True
stdid = False
for line in content:
if "#" in line:
if "state_identifiers" in line:
stdid = True
elif stdid:
STATEIDENTIFIERS = line.replace("#", "").split()
stdid = False
continue
else:
if field > 0:
if first:
STATEATOMHEADER = ["atomI", "atomJ", "type1", "type2"]
first = False
state_line = {key: value for key, value in zip(STATEATOMHEADER, line.split())}
state_line.update({"NR": len(STATEATOMS) + 1})
final_state_line = {key: state_line[key] for key in state_line if ("type" not in key)}
states = {1: state_line["type1"], 2: state_line["type2"]}
final_state_line.update({"STATES": states})
STATEATOMS.append(atom_lam_pertubation_state_bond(**final_state_line))
elif field == 0:
NPB = int(line.strip())
field += 1
self.NPB = NPB
self.STATEIDENTIFIERS = STATEIDENTIFIERS
self.STATEATOMHEADER = STATEATOMHEADER
self.STATEATOMS = STATEATOMS
"""
STR FUNCTIONS
"""
def _state_STATEATOMHEADER_str(self):
state_format_pattern = "{:>5} {:>5}" + "".join([" {:>5} " for x in range(self.NPTB)]) + ""
return state_format_pattern.format(*self.STATEATOMHEADER)
[docs] def block_to_string(self) -> str:
result = self.name + self.line_seperator
result += (
"# NPB "
+ self.field_seperator
+ "NPTB = "
+ self.field_seperator
+ str(self.NPTB)
+ self.field_seperator
+ self.line_seperator
)
result += self.field_seperator + str(self.NPB) + self.line_seperator
result += "# " + self._state_STATEATOMHEADER_str() + self.line_seperator
result += "".join(map(str, sorted(self.STATEATOMS, key=lambda x: x.NR)))
result += "END" + self.line_seperator
return result
[docs]class PERTBONDSTRETCHH(_generic_gromos_block):
def __init__(
self,
STATEATOMS: List[atom_lam_pertubation_state_bond] = None,
STATEATOMHEADER: Tuple[str] = None,
NPB: int = None,
dummy_BOND=22,
content: List[str] = None,
):
self.NPTB = 2
self.dummy_BOND = dummy_BOND
if content is None:
if STATEATOMHEADER is None:
self.STATEATOMHEADER = ["atomI", "atomJ", "type1", "type2"]
else:
self.STATEATOMHEADER = STATEATOMHEADER
if STATEATOMS is None:
self.STATEATOMS = []
else:
self.STATEATOMS = []
self.NPB = 0
# self.add_state_atoms(STATEATOMS)
super().__init__(used=True, name=__class__.__name__)
else:
super().__init__(used=True, name=__class__.__name__, content=content)
# You can check yourself :)
if NPB is not None and len(STATEATOMS) != NPB:
raise ValueError(
"NJLA must be equal to the length of STATEATOMS! NJLA="
+ str(NPB)
+ "\t stateatoms"
+ str(len(STATEATOMS))
+ "\n\n"
+ str(self)
)
@property
def nStates(self) -> int:
return self.NPTB
@property
def nTotalStateAtoms(self) -> int:
return self.NPB
@property
def states(self) -> dict:
return {
self.STATEIDENTIFIERS[state - 1]: {
atom.NR: atom.STATES[state] for atom in sorted(self.STATEATOMS, key=lambda x: x.NR)
}
for state in range(1, self.NPTB + 1)
}
[docs] def read_content_from_str(self, content: List[str]):
field = 0
NPB = None
STATEIDENTIFIERS = None
STATEATOMHEADER = None
STATEATOMS = []
first = True
stdid = False
for line in content:
if "#" in line:
if "state_identifiers" in line:
stdid = True
elif stdid:
STATEIDENTIFIERS = line.replace("#", "").split()
stdid = False
continue
else:
if field > 0:
if first:
STATEATOMHEADER = ["atomI", "atomJ", "type1", "type2"]
first = False
state_line = {key: value for key, value in zip(STATEATOMHEADER, line.split())}
state_line.update({"NR": len(STATEATOMS) + 1})
final_state_line = {key: state_line[key] for key in state_line if ("type" not in key)}
states = {1: state_line["type1"], 2: state_line["type2"]}
final_state_line.update({"STATES": states})
STATEATOMS.append(atom_lam_pertubation_state_bond(**final_state_line))
elif field == 0:
NPB = int(line.strip())
field += 1
self.NPB = NPB
self.STATEIDENTIFIERS = STATEIDENTIFIERS
self.STATEATOMHEADER = STATEATOMHEADER
self.STATEATOMS = STATEATOMS
"""
STR FUNCTIONS
"""
def _state_STATEATOMHEADER_str(self):
state_format_pattern = "{:>5} {:>5}" + "".join([" {:>5} " for x in range(self.NPTB)]) + ""
return state_format_pattern.format(*self.STATEATOMHEADER)
[docs] def block_to_string(self) -> str:
result = self.name + self.line_seperator
result += (
"# NPB "
+ self.field_seperator
+ "NPTB = "
+ self.field_seperator
+ str(self.NPTB)
+ self.field_seperator
+ self.line_seperator
)
result += self.field_seperator + str(self.NPB) + self.line_seperator
result += "# " + self._state_STATEATOMHEADER_str() + self.line_seperator
result += "".join(map(str, sorted(self.STATEATOMS, key=lambda x: x.NR)))
result += "END" + self.line_seperator
return result
# ANGLE
[docs]class PERTBONDANGLE(_generic_gromos_block):
def __init__(
self,
STATEATOMS: List[atom_lam_pertubation_state_angle] = None,
STATEATOMHEADER: Tuple[str] = None,
NPA: int = None,
dummy_ANGLE=22,
content: List[str] = None,
):
self.NPTB = 2
self.dummy_ANGLE = dummy_ANGLE
if content is None:
if STATEATOMHEADER is None:
self.STATEATOMHEADER = ["atomI", "atomJ", "atomK", "type1", "type2"]
else:
self.STATEATOMHEADER = STATEATOMHEADER
if STATEATOMS is None:
self.STATEATOMS = []
else:
self.STATEATOMS = []
self.NPA = 0
# self.add_state_atoms(STATEATOMS)
super().__init__(used=True, name=__class__.__name__)
else:
super().__init__(used=True, name=__class__.__name__, content=content)
# You can check yourself :)
if NPA is not None and len(STATEATOMS) != NPA:
raise ValueError(
"NJLA must be equal to the length of STATEATOMS! NJLA="
+ str(NPA)
+ "\t stateatoms"
+ str(len(STATEATOMS))
+ "\n\n"
+ str(self)
)
@property
def nStates(self) -> int:
return self.NPTB
@property
def nTotalStateAtoms(self) -> int:
return self.NPA
@property
def states(self) -> dict:
return {
self.STATEIDENTIFIERS[state - 1]: {
atom.NR: atom.STATES[state] for atom in sorted(self.STATEATOMS, key=lambda x: x.NR)
}
for state in range(1, self.NPTB + 1)
}
[docs] def read_content_from_str(self, content: List[str]):
field = 0
NPA = None
STATEIDENTIFIERS = None
STATEATOMHEADER = None
STATEATOMS = []
first = True
stdid = False
for line in content:
if "#" in line:
if "state_identifiers" in line:
stdid = True
elif stdid:
STATEIDENTIFIERS = line.replace("#", "").split()
stdid = False
continue
else:
if field > 0:
if first:
STATEATOMHEADER = ["atomI", "atomJ", "atomK", "type1", "type2"]
first = False
state_line = {key: value for key, value in zip(STATEATOMHEADER, line.split())}
state_line.update({"NR": len(STATEATOMS) + 1})
final_state_line = {key: state_line[key] for key in state_line if ("type" not in key)}
states = {1: state_line["type1"], 2: state_line["type2"]}
final_state_line.update({"STATES": states})
STATEATOMS.append(atom_lam_pertubation_state_angle(**final_state_line))
elif field == 0:
NPA = int(line.strip())
field += 1
self.NPA = NPA
self.STATEIDENTIFIERS = STATEIDENTIFIERS
self.STATEATOMHEADER = STATEATOMHEADER
self.STATEATOMS = STATEATOMS
"""
STR FUNCTIONS
"""
def _state_STATEATOMHEADER_str(self):
state_format_pattern = "{:>5} {:>5} {:>5}" + "".join([" {:>5} " for x in range(self.NPTB)]) + ""
return state_format_pattern.format(*self.STATEATOMHEADER)
[docs] def block_to_string(self) -> str:
result = self.name + self.line_seperator
result += (
"# NPA "
+ self.field_seperator
+ "NPTB = "
+ self.field_seperator
+ str(self.NPTB)
+ self.field_seperator
+ self.line_seperator
)
result += self.field_seperator + str(self.NPA) + self.line_seperator
result += "# " + self._state_STATEATOMHEADER_str() + self.line_seperator
result += "".join(map(str, sorted(self.STATEATOMS, key=lambda x: x.NR)))
result += "END" + self.line_seperator
return result
[docs]class PERTBONDANGLEH(_generic_gromos_block):
def __init__(
self,
STATEATOMS: List[atom_lam_pertubation_state_angle] = None,
STATEATOMHEADER: Tuple[str] = None,
NPA: int = None,
dummy_ANGLE=22,
content: List[str] = None,
):
self.NPTB = 2
self.dummy_ANGLE = dummy_ANGLE
if content is None:
if STATEATOMHEADER is None:
self.STATEATOMHEADER = ["atomI", "atomJ", "atomK", "type1", "type2"]
else:
self.STATEATOMHEADER = STATEATOMHEADER
if STATEATOMS is None:
self.STATEATOMS = []
else:
self.STATEATOMS = []
self.NPA = 0
# self.add_state_atoms(STATEATOMS)
super().__init__(used=True, name=__class__.__name__)
else:
super().__init__(used=True, name=__class__.__name__, content=content)
# You can check yourself :)
if NPA is not None and not len(STATEATOMS) == NPA:
raise ValueError(
"NJLA must be equal to the length of STATEATOMS! NJLA="
+ str(NPA)
+ "\t stateatoms"
+ str(len(STATEATOMS))
+ "\n\n"
+ str(self)
)
@property
def nStates(self) -> int:
return self.NPTB
@property
def nTotalStateAtoms(self) -> int:
return self.NPA
@property
def states(self) -> dict:
return {
self.STATEIDENTIFIERS[state - 1]: {
atom.NR: atom.STATES[state] for atom in sorted(self.STATEATOMS, key=lambda x: x.NR)
}
for state in range(1, self.NPTB + 1)
}
[docs] def read_content_from_str(self, content: List[str]):
field = 0
NPA = None
STATEIDENTIFIERS = None
STATEATOMHEADER = None
STATEATOMS = []
first = True
stdid = False
for line in content:
if "#" in line:
if "state_identifiers" in line:
stdid = True
elif stdid:
STATEIDENTIFIERS = line.replace("#", "").split()
stdid = False
continue
else:
if field > 0:
if first:
STATEATOMHEADER = ["atomI", "atomJ", "atomK", "type1", "type2"]
first = False
state_line = {key: value for key, value in zip(STATEATOMHEADER, line.split())}
state_line.update({"NR": len(STATEATOMS) + 1})
final_state_line = {key: state_line[key] for key in state_line if ("type" not in key)}
states = {1: state_line["type1"], 2: state_line["type2"]}
final_state_line.update({"STATES": states})
STATEATOMS.append(atom_lam_pertubation_state_angle(**final_state_line))
elif field == 0:
NPA = int(line.strip())
field += 1
self.NPA = NPA
self.STATEIDENTIFIERS = STATEIDENTIFIERS
self.STATEATOMHEADER = STATEATOMHEADER
self.STATEATOMS = STATEATOMS
"""
STR FUNCTIONS
"""
def _state_STATEATOMHEADER_str(self):
state_format_pattern = "{:>5} {:>5} {:>5}" + "".join([" {:>5} " for x in range(self.NPTB)]) + ""
return state_format_pattern.format(*self.STATEATOMHEADER)
[docs] def block_to_string(self) -> str:
result = self.name + self.line_seperator
result += (
"# NPA "
+ self.field_seperator
+ "NPTB = "
+ self.field_seperator
+ str(self.NPTB)
+ self.field_seperator
+ self.line_seperator
)
result += self.field_seperator + str(self.NPA) + self.line_seperator
result += "# " + self._state_STATEATOMHEADER_str() + self.line_seperator
result += "".join(map(str, sorted(self.STATEATOMS, key=lambda x: x.NR)))
result += "END" + self.line_seperator
return result
# DIHEDRAL
[docs]class PERTPROPERDIH(_generic_gromos_block):
def __init__(
self,
STATEATOMS: List[atom_lam_pertubation_state_dihedral] = None,
STATEATOMHEADER: Tuple[str] = None,
NPD: int = None,
dummy_DIH=22,
content: List[str] = None,
):
self.NPTB = 2
self.dummy_DIH = dummy_DIH
if content is None:
if STATEATOMHEADER is None:
self.STATEATOMHEADER = ["atomI", "atomJ", "atomK", "atomL", "type1", "type2"]
else:
self.STATEATOMHEADER = STATEATOMHEADER
if STATEATOMS is None:
self.STATEATOMS = []
else:
self.STATEATOMS = []
self.NPD = 0
# self.add_state_atoms(STATEATOMS)
super().__init__(used=True, name=__class__.__name__)
else:
super().__init__(used=True, name=__class__.__name__, content=content)
# You can check yourself :)
if NPD is not None and len(STATEATOMS) != NPD:
raise ValueError(
"NJLA must be equal to the length of STATEATOMS! NJLA="
+ str(NPD)
+ "\t stateatoms"
+ str(len(STATEATOMS))
+ "\n\n"
+ str(self)
)
@property
def nStates(self) -> int:
return self.NPTB
@property
def nTotalStateAtoms(self) -> int:
return self.NPD
@property
def states(self) -> dict:
return {
self.STATEIDENTIFIERS[state - 1]: {
atom.NR: atom.STATES[state] for atom in sorted(self.STATEATOMS, key=lambda x: x.NR)
}
for state in range(1, self.NPTB + 1)
}
[docs] def read_content_from_str(self, content: List[str]):
field = 0
NPD = None
STATEIDENTIFIERS = None
STATEATOMHEADER = None
STATEATOMS = []
first = True
stdid = False
for line in content:
if "#" in line:
if "state_identifiers" in line:
stdid = True
elif stdid:
STATEIDENTIFIERS = line.replace("#", "").split()
stdid = False
continue
else:
if field > 0:
if first:
STATEATOMHEADER = ["atomI", "atomJ", "atomK", "atomL", "type1", "type2"]
first = False
state_line = {key: value for key, value in zip(STATEATOMHEADER, line.split())}
state_line.update({"NR": len(STATEATOMS) + 1})
final_state_line = {key: state_line[key] for key in state_line if ("type" not in key)}
states = {1: state_line["type1"], 2: state_line["type2"]}
final_state_line.update({"STATES": states})
STATEATOMS.append(atom_lam_pertubation_state_dihedral(**final_state_line))
elif field == 0:
NPD = int(line.strip())
field += 1
self.NPD = NPD
self.STATEIDENTIFIERS = STATEIDENTIFIERS
self.STATEATOMHEADER = STATEATOMHEADER
self.STATEATOMS = STATEATOMS
"""
STR FUNCTIONS
"""
def _state_STATEATOMHEADER_str(self):
state_format_pattern = "{:>5} {:>5} {:>5} {:>5}" + "".join([" {:>5} " for x in range(self.NPTB)]) + ""
return state_format_pattern.format(*self.STATEATOMHEADER)
[docs] def block_to_string(self) -> str:
result = self.name + self.line_seperator
result += (
"# NPD "
+ self.field_seperator
+ "NPTB = "
+ self.field_seperator
+ str(self.NPTB)
+ self.field_seperator
+ self.line_seperator
)
result += self.field_seperator + str(self.NPD) + self.line_seperator
result += "# " + self._state_STATEATOMHEADER_str() + self.line_seperator
result += "".join(map(str, sorted(self.STATEATOMS, key=lambda x: x.NR)))
result += "END" + self.line_seperator
return result
[docs]class PERTPROPERDIHH(_generic_gromos_block):
def __init__(
self,
STATEATOMS: List[atom_lam_pertubation_state_dihedral] = None,
STATEATOMHEADER: Tuple[str] = None,
NPD: int = None,
dummy_DIH=22,
content: List[str] = None,
):
self.NPTB = 2
self.dummy_DIH = dummy_DIH
if content is None:
if STATEATOMHEADER is None:
self.STATEATOMHEADER = ["atomI", "atomJ", "atomK", "atomL", "type1", "type2"]
else:
self.STATEATOMHEADER = STATEATOMHEADER
if STATEATOMS is None:
self.STATEATOMS = []
else:
self.STATEATOMS = []
self.NPD = 0
# self.add_state_atoms(STATEATOMS)
super().__init__(used=True, name=__class__.__name__)
else:
super().__init__(used=True, name=__class__.__name__, content=content)
# You can check yourself :)
if NPD is not None and len(STATEATOMS) != NPD:
raise ValueError(
"NJLA must be equal to the length of STATEATOMS! NJLA="
+ str(NPD)
+ "\t stateatoms"
+ str(len(STATEATOMS))
+ "\n\n"
+ str(self)
)
@property
def nStates(self) -> int:
return self.NPTB
@property
def nTotalStateAtoms(self) -> int:
return self.NPD
@property
def states(self) -> dict:
return {
self.STATEIDENTIFIERS[state - 1]: {
atom.NR: atom.STATES[state] for atom in sorted(self.STATEATOMS, key=lambda x: x.NR)
}
for state in range(1, self.NPTB + 1)
}
[docs] def read_content_from_str(self, content: List[str]):
field = 0
NPD = None
STATEIDENTIFIERS = None
STATEATOMHEADER = None
STATEATOMS = []
first = True
stdid = False
for line in content:
if "#" in line:
if "state_identifiers" in line:
stdid = True
elif stdid:
STATEIDENTIFIERS = line.replace("#", "").split()
stdid = False
continue
else:
if field > 0:
if first:
STATEATOMHEADER = ["atomI", "atomJ", "atomK", "atomL", "type1", "type2"]
first = False
state_line = {key: value for key, value in zip(STATEATOMHEADER, line.split())}
state_line.update({"NR": len(STATEATOMS) + 1})
final_state_line = {key: state_line[key] for key in state_line if ("type" not in key)}
states = {1: state_line["type1"], 2: state_line["type2"]}
final_state_line.update({"STATES": states})
STATEATOMS.append(atom_lam_pertubation_state_dihedral(**final_state_line))
elif field == 0:
NPD = int(line.strip())
field += 1
self.NPD = NPD
self.STATEIDENTIFIERS = STATEIDENTIFIERS
self.STATEATOMHEADER = STATEATOMHEADER
self.STATEATOMS = STATEATOMS
"""
STR FUNCTIONS
"""
def _state_STATEATOMHEADER_str(self):
state_format_pattern = "{:>5} {:>5} {:>5} {:>5}" + "".join([" {:>5} " for x in range(self.NPTB)]) + ""
return state_format_pattern.format(*self.STATEATOMHEADER)
[docs] def block_to_string(self) -> str:
result = self.name + self.line_seperator
result += (
"# NPD "
+ self.field_seperator
+ "NPTB = "
+ self.field_seperator
+ str(self.NPTB)
+ self.field_seperator
+ self.line_seperator
)
result += self.field_seperator + str(self.NPD) + self.line_seperator
result += "# " + self._state_STATEATOMHEADER_str() + self.line_seperator
result += "".join(map(str, sorted(self.STATEATOMS, key=lambda x: x.NR)))
result += "END" + self.line_seperator
return result
[docs] class PERTPROPERDIH(_generic_gromos_block):
def __init__(
self,
STATEATOMS: List[atom_lam_pertubation_state_dihedral] = None,
STATEATOMHEADER: Tuple[str] = None,
NPD: int = None,
dummy_DIH=22,
content: List[str] = None,
):
self.NPTB = 2
self.dummy_DIH = dummy_DIH
if content is None:
if STATEATOMHEADER is None:
self.STATEATOMHEADER = ["atomI", "atomJ", "atomK", "atomL", "type1", "type2"]
else:
self.STATEATOMHEADER = STATEATOMHEADER
if STATEATOMS is None:
self.STATEATOMS = []
else:
self.STATEATOMS = []
self.NPD = 0
# self.add_state_atoms(STATEATOMS)
super().__init__(used=True, name=__class__.__name__)
else:
super().__init__(used=True, name=__class__.__name__, content=content)
# You can check yourself :)
if NPD is not None and len(STATEATOMS) != NPD:
raise ValueError(
"NJLA must be equal to the length of STATEATOMS! NJLA="
+ str(NPD)
+ "\t stateatoms"
+ str(len(STATEATOMS))
+ "\n\n"
+ str(self)
)
@property
def nStates(self) -> int:
return self.NPTB
@property
def nTotalStateAtoms(self) -> int:
return self.NPD
@property
def states(self) -> dict:
return {
self.STATEIDENTIFIERS[state - 1]: {
atom.NR: atom.STATES[state] for atom in sorted(self.STATEATOMS, key=lambda x: x.NR)
}
for state in range(1, self.NPTB + 1)
}
[docs] def read_content_from_str(self, content: List[str]):
field = 0
NPD = None
STATEIDENTIFIERS = None
STATEATOMHEADER = None
STATEATOMS = []
first = True
stdid = False
for line in content:
if "#" in line:
if "state_identifiers" in line:
stdid = True
elif stdid:
STATEIDENTIFIERS = line.replace("#", "").split()
stdid = False
continue
else:
if field > 0:
if first:
STATEATOMHEADER = ["atomI", "atomJ", "atomK", "atomL", "type1", "type2"]
first = False
state_line = {key: value for key, value in zip(STATEATOMHEADER, line.split())}
state_line.update({"NR": len(STATEATOMS) + 1})
final_state_line = {key: state_line[key] for key in state_line if ("type" not in key)}
states = {1: state_line["type1"], 2: state_line["type2"]}
final_state_line.update({"STATES": states})
STATEATOMS.append(atom_lam_pertubation_state_dihedral(**final_state_line))
elif field == 0:
NPD = int(line.strip())
field += 1
self.NPD = NPD
self.STATEIDENTIFIERS = STATEIDENTIFIERS
self.STATEATOMHEADER = STATEATOMHEADER
self.STATEATOMS = STATEATOMS
"""
STR FUNCTIONS
"""
def _state_STATEATOMHEADER_str(self):
state_format_pattern = "{:>5} {:>5} {:>5} {:>5}" + "".join([" {:>5} " for x in range(self.NPTB)]) + ""
return state_format_pattern.format(*self.STATEATOMHEADER)
[docs] def block_to_string(self) -> str:
result = self.name + self.line_seperator
result += (
"# NPD "
+ self.field_seperator
+ "NPTB = "
+ self.field_seperator
+ str(self.NPTB)
+ self.field_seperator
+ self.line_seperator
)
result += self.field_seperator + str(self.NPD) + self.line_seperator
result += "# " + self._state_STATEATOMHEADER_str() + self.line_seperator
result += "".join(map(str, sorted(self.STATEATOMS, key=lambda x: x.NR)))
result += "END" + self.line_seperator
return result
# IMPROPER
[docs]class PERTIMROPERDIH(_generic_gromos_block):
def __init__(
self,
STATEATOMS: List[atom_lam_pertubation_state_dihedral] = None,
STATEATOMHEADER: Tuple[str] = None,
NPD: int = None,
dummy_IMP=22,
content: List[str] = None,
):
self.NPTB = 2
self.dummy_DIH = dummy_IMP
if content is None:
if STATEATOMHEADER is None:
self.STATEATOMHEADER = ["atomI", "atomJ", "atomK", "atomL", "type1", "type2"]
else:
self.STATEATOMHEADER = STATEATOMHEADER
if STATEATOMS is None:
self.STATEATOMS = []
else:
self.STATEATOMS = []
self.NPD = 0
# self.add_state_atoms(STATEATOMS)
super().__init__(used=True, name=__class__.__name__)
else:
super().__init__(used=True, name=__class__.__name__, content=content)
# You can check yourself :)
if NPD is not None and len(STATEATOMS) != NPD:
raise ValueError(
"NPD must be equal to the length of STATEATOMS! NPD="
+ str(NPD)
+ "\t stateatoms"
+ str(len(STATEATOMS))
+ "\n\n"
+ str(self)
)
@property
def nStates(self) -> int:
return self.NPTB
@property
def nTotalStateAtoms(self) -> int:
return self.NPD
@property
def states(self) -> dict:
return {
self.STATEIDENTIFIERS[state - 1]: {
atom.NR: atom.STATES[state] for atom in sorted(self.STATEATOMS, key=lambda x: x.NR)
}
for state in range(1, self.NPTB + 1)
}
[docs] def read_content_from_str(self, content: List[str]):
field = 0
NPD = None
STATEIDENTIFIERS = None
STATEATOMHEADER = None
STATEATOMS = []
first = True
stdid = False
for line in content:
if "#" in line:
if "state_identifiers" in line:
stdid = True
elif stdid:
STATEIDENTIFIERS = line.replace("#", "").split()
stdid = False
continue
else:
if field > 0:
if first:
STATEATOMHEADER = ["atomI", "atomJ", "atomK", "atomL", "type1", "type2"]
first = False
state_line = {key: value for key, value in zip(STATEATOMHEADER, line.split())}
state_line.update({"NR": len(STATEATOMS) + 1})
final_state_line = {key: state_line[key] for key in state_line if ("type" not in key)}
states = {1: state_line["type1"], 2: state_line["type2"]}
final_state_line.update({"STATES": states})
STATEATOMS.append(atom_lam_pertubation_state_dihedral(**final_state_line))
elif field == 0:
NPD = int(line.strip())
field += 1
self.NPD = NPD
self.STATEIDENTIFIERS = STATEIDENTIFIERS
self.STATEATOMHEADER = STATEATOMHEADER
self.STATEATOMS = STATEATOMS
"""
STR FUNCTIONS
"""
def _state_STATEATOMHEADER_str(self):
state_format_pattern = "{:>5} {:>5} {:>5} {:>5}" + "".join([" {:>5} " for x in range(self.NPTB)]) + ""
return state_format_pattern.format(*self.STATEATOMHEADER)
[docs] def block_to_string(self) -> str:
result = self.name + self.line_seperator
result += (
"# NPD "
+ self.field_seperator
+ "NPTB = "
+ self.field_seperator
+ str(self.NPTB)
+ self.field_seperator
+ self.line_seperator
)
result += self.field_seperator + str(self.NPD) + self.line_seperator
result += "# " + self._state_STATEATOMHEADER_str() + self.line_seperator
result += "".join(map(str, sorted(self.STATEATOMS, key=lambda x: x.NR)))
result += "END" + self.line_seperator
return result
[docs]class PERTIMROPERDIHH(_generic_gromos_block):
def __init__(
self,
STATEATOMS: List[atom_lam_pertubation_state_dihedral] = None,
STATEATOMHEADER: Tuple[str] = None,
NPD: int = None,
dummy_IMP=22,
content: List[str] = None,
):
self.NPTB = 2
self.dummy_DIH = dummy_IMP
if content is None:
if STATEATOMHEADER is None:
self.STATEATOMHEADER = ["atomI", "atomJ", "atomK", "atomL", "type1", "type2"]
else:
self.STATEATOMHEADER = STATEATOMHEADER
if STATEATOMS is None:
self.STATEATOMS = []
else:
self.STATEATOMS = []
self.NPD = 0
# self.add_state_atoms(STATEATOMS)
super().__init__(used=True, name=__class__.__name__)
else:
super().__init__(used=True, name=__class__.__name__, content=content)
# You can check yourself :)
if NPD is not None and len(STATEATOMS) != NPD:
raise ValueError(
"NPD must be equal to the length of STATEATOMS! NPD="
+ str(NPD)
+ "\t stateatoms"
+ str(len(STATEATOMS))
+ "\n\n"
+ str(self)
)
@property
def nStates(self) -> int:
return self.NPTB
@property
def nTotalStateAtoms(self) -> int:
return self.NPD
@property
def states(self) -> dict:
return {
self.STATEIDENTIFIERS[state - 1]: {
atom.NR: atom.STATES[state] for atom in sorted(self.STATEATOMS, key=lambda x: x.NR)
}
for state in range(1, self.NPTB + 1)
}
[docs] def read_content_from_str(self, content: List[str]):
field = 0
NPD = None
STATEIDENTIFIERS = None
STATEATOMHEADER = None
STATEATOMS = []
first = True
stdid = False
for line in content:
if "#" in line:
if "state_identifiers" in line:
stdid = True
elif stdid:
STATEIDENTIFIERS = line.replace("#", "").split()
stdid = False
continue
else:
if field > 0:
if first:
STATEATOMHEADER = ["atomI", "atomJ", "atomK", "atomL", "type1", "type2"]
first = False
state_line = {key: value for key, value in zip(STATEATOMHEADER, line.split())}
state_line.update({"NR": len(STATEATOMS) + 1})
final_state_line = {key: state_line[key] for key in state_line if ("type" not in key)}
states = {1: state_line["type1"], 2: state_line["type2"]}
final_state_line.update({"STATES": states})
STATEATOMS.append(atom_lam_pertubation_state_dihedral(**final_state_line))
elif field == 0:
NPD = int(line.strip())
field += 1
self.NPD = NPD
self.STATEIDENTIFIERS = STATEIDENTIFIERS
self.STATEATOMHEADER = STATEATOMHEADER
self.STATEATOMS = STATEATOMS
"""
STR FUNCTIONS
"""
def _state_STATEATOMHEADER_str(self):
state_format_pattern = "{:>5} {:>5} {:>5} {:>5}" + "".join([" {:>5} " for x in range(self.NPTB)]) + ""
return state_format_pattern.format(*self.STATEATOMHEADER)
[docs] def block_to_string(self) -> str:
result = self.name + self.line_seperator
result += (
"# NPD "
+ self.field_seperator
+ "NPTB = "
+ self.field_seperator
+ str(self.NPTB)
+ self.field_seperator
+ self.line_seperator
)
result += self.field_seperator + str(self.NPD) + self.line_seperator
result += "# " + self._state_STATEATOMHEADER_str() + self.line_seperator
result += "".join(map(str, sorted(self.STATEATOMS, key=lambda x: x.NR)))
result += "END" + self.line_seperator
return result