Source code for pygromos.files.blocks.mtb_blocks

from pygromos.files.blocks.topology_blocks import TITLE as generic_TITLE
from pygromos.files.blocks.topology_blocks import FORCEFIELD as generic_FORCEFIELD
from pygromos.files.blocks.topology_blocks import MAKETOPVERSION as generic_MAKETOPVERSION
from pygromos.files.blocks._general_blocks import _generic_gromos_block, _generic_field
from pygromos.utils.typing import List


TITLE: generic_TITLE = generic_TITLE
FORCEFIELD: generic_FORCEFIELD = generic_FORCEFIELD
MAKETOPVERSION: generic_MAKETOPVERSION = generic_MAKETOPVERSION


[docs]class mtb_blocks(_generic_gromos_block): def __init__(self, name: str = None, used: bool = None, content: str = None): super().__init__(name, used, content) self.field_separator = " " self.line_separator = " \n" self.field_continue_next_line = "\n\t\t\t\t\t\t\t\t\t\t"
[docs]class mtb_fields(_generic_field): fieldseperator = " " lineseperator = " \n" field_continue_next_line = "\n\t\t\t\t\t\t\t\t\t\t"
[docs]class mtb_atoms_field(mtb_fields): def __init__( self, ATOM: int, ANM: str, IACM: int, MASS: int, CGMI: float, CGM: int, MAE: int, MSAE: List[int] ) -> None: self.ATOM = int(ATOM) self.ANM = ANM self.IACM = int(IACM) self.MASS = int(MASS) self.CGMI = float(CGMI) self.CGM = int(CGM) self.MAE = int(MAE) self.MSAE = [int(x) for x in MSAE]
[docs] def to_string(self) -> str: return_str = "" return_str += str(self.ATOM).rjust(6) + " " return_str += self.ANM.rjust(6) + " " return_str += str(self.IACM).rjust(6) + " " return_str += str(self.MASS).rjust(6) + " " # return_str += self.fieldseperator + str(self.CGMI) return_str += "{:.5f}".format(self.CGMI).rjust(10) + " " return_str += str(self.CGM).rjust(4) + " " return_str += str(self.MAE).rjust(4) + " " lcounter = 0 temp_MSAE = len(self.MSAE) for iter in self.MSAE: return_str += self.fieldseperator + str(iter).strip() lcounter += 1 if (lcounter % 6) == 0 and temp_MSAE > 6: return_str += self.lineseperator return_str += 49 * " " temp_MSAE -= 6 return_str += self.lineseperator return return_str
[docs]class mtb_preceding_exclusions_field(mtb_fields): def __init__(self, ATOM: int, MAE: int, MSAE: List[int]) -> None: self.ATOM = int(ATOM) self.MAE = int(MAE) self.MSAE = [int(x) for x in MSAE]
[docs] def to_string(self) -> str: return_str = "" return_str += self.fieldseperator + str(self.ATOM) return_str += self.fieldseperator + str(self.MAE) lcounter = 0 temp_MSAE = len(self.MSAE) for iter in self.MSAE: return_str += self.fieldseperator + str(iter).strip() lcounter += 1 if (lcounter % 6) == 0 and temp_MSAE > 6: return_str += self.field_continue_next_line temp_MSAE -= 6 return_str += self.lineseperator return return_str
[docs]class mtb_trailing_atoms_field(mtb_fields): def __init__(self, ATOM: int, ANM: str, IACM: int, MASS: int, CGMI: float, CGM: int) -> None: self.ATOM = int(ATOM) self.ANM = ANM self.IACM = int(IACM) self.MASS = int(MASS) self.CGMI = float(CGMI) self.CGM = int(CGM)
[docs] def to_string(self) -> str: return_str = "" return_str += self.fieldseperator + str(self.ATOM) return_str += self.fieldseperator + self.ANM return_str += self.fieldseperator + str(self.IACM) return_str += self.fieldseperator + str(self.MASS) # return_str += self.fieldseperator + str(self.CGMI) return_str += self.fieldseperator + "{:.5f}".format(self.CGMI) return_str += self.fieldseperator + str(self.CGM) return_str += self.lineseperator return return_str
[docs]class mtb_atoms_solvent_field(mtb_fields): def __init__(self, ATOM: int, ANM: str, IACM: int, MASS: int, CG: float) -> None: self.ATOM = int(ATOM) self.ANM = ANM self.IACM = int(IACM) self.MASS = int(MASS) self.CG = float(CG)
[docs] def to_string(self) -> str: return_str = "" return_str += self.fieldseperator + str(self.ATOM) return_str += self.fieldseperator + self.ANM return_str += self.fieldseperator + str(self.IACM) return_str += self.fieldseperator + str(self.MASS) return_str += self.fieldseperator + "{:.5f}".format(self.CG) # return_str += self.fieldseperator + str(self.CG) return_str += self.lineseperator return return_str
[docs]class mtb_bonds_field(mtb_fields): def __init__(self, IB: int, JB: int, MCB: int) -> None: self.IB = int(IB) self.JB = int(JB) self.MCB = int(MCB)
[docs] def to_string(self) -> str: return_str = "" return_str += self.fieldseperator + str(self.IB) return_str += self.fieldseperator + str(self.JB) return_str += self.fieldseperator + str(self.MCB) return_str += self.lineseperator return return_str
[docs]class mtb_angles_field(mtb_fields): def __init__(self, IB: int, JB: int, KB: int, MCB: int) -> None: self.IB = int(IB) self.JB = int(JB) self.KB = int(KB) self.MCB = int(MCB)
[docs] def to_string(self) -> str: return_str = "" return_str += self.fieldseperator + str(self.IB) return_str += self.fieldseperator + str(self.JB) return_str += self.fieldseperator + str(self.KB) return_str += self.fieldseperator + str(self.MCB) return_str += self.lineseperator return return_str
[docs]class mtb_dihedral_field(mtb_fields): def __init__(self, IB: int, JB: int, KB: int, LB: int, MCB: int) -> None: self.IB = int(IB) self.JB = int(JB) self.KB = int(KB) self.LB = int(LB) self.MCB = int(MCB)
[docs] def to_string(self) -> str: return_str = "" return_str += self.fieldseperator + str(self.IB) return_str += self.fieldseperator + str(self.JB) return_str += self.fieldseperator + str(self.KB) return_str += self.fieldseperator + str(self.LB) return_str += self.fieldseperator + str(self.MCB) return_str += self.lineseperator return return_str
[docs]class mtb_lj_exceptions_field(mtb_fields): def __init__(self, iac: int, jac: int, mcb: int): self.iac = int(iac) self.jac = int(jac) self.mcb = int(mcb)
[docs] def to_string(self) -> str: return_str = "" return_str += self.fieldseperator + str(self.iac) return_str += self.fieldseperator + str(self.jac) return_str += self.fieldseperator + str(self.mcb) return_str += self.lineseperator return return_str
[docs]class mtb_constraints_field(mtb_fields): def __init__(self, IB: int, JB: int, LENGTH: float) -> None: self.IB = int(IB) self.JB = int(JB) self.LENGTH = float(LENGTH)
[docs] def to_string(self) -> str: return_str = "" return_str += self.fieldseperator + str(self.IB) return_str += self.fieldseperator + str(self.JB) return_str += self.fieldseperator + str(self.LENGTH) return_str += self.lineseperator return return_str
[docs]class MTBUILDBLSOLUTE(mtb_blocks): FORCEFIELD: FORCEFIELD MAKETOPVERSION: MAKETOPVERSION atoms: List[mtb_atoms_field] preceding_exclusions: List[mtb_preceding_exclusions_field] trailing_atoms: List[mtb_trailing_atoms_field] bonds: List[mtb_bonds_field] angles: List[mtb_angles_field] improper_dihedrals: List[mtb_dihedral_field] dihedrals: List[mtb_dihedral_field] lj_exceptions: List[mtb_lj_exceptions_field] skip_lines: int = 2 def __init__(self, FORCEFIELD: FORCEFIELD = None, MAKETOPVERSION: MAKETOPVERSION = None, content=None): super().__init__(name=self.__class__.__name__, used=True, content=content) self.FORCEFIELD = FORCEFIELD self.MAKETOPVERSION = MAKETOPVERSION
[docs] def read_content_from_str(self, content: str): # reset all storage self.atoms = [] self.trailing_atoms = [] self.preceding_exclusions = [] self.bonds = [] self.angles = [] self.improper_dihedrals = [] self.dihedrals = [] self.lj_exceptions = [] # first line, check if information on solute type is available if "@BLOCKTYPE" in content[0]: first_line = content[0].split() self.filename = first_line[1] self.residuecode = first_line[3] self.function = first_line[4] self.type = first_line[6] self.fullname = first_line[8] else: self.filename = None self.residuecode = None self.function = None self.type = None self.fullname = None itr = 1 while itr < len(content): if content[itr].startswith("#"): itr += 1 continue else: break self.RNME = content[itr].strip() itr += 1 while itr < len(content): if content[itr].startswith("#"): itr += 1 continue else: break self.NMAT = int(content[itr].split()[0]) self.NLIN = int(content[itr].split()[1]) itr += 1 if self.NLIN != 0: nlin_found = 0 while nlin_found < self.NLIN and itr < len(content): if content[itr].startswith("#"): itr += 1 continue else: dump1 = content[itr].strip().split() if len(dump1) >= 2: atom, mae = dump1[0:2] else: raise Exception( "Error in ATOM block: \n" + content[itr - 1] + "\n" + content[itr] + "\n" + content[itr + 1] + "\n" + content[itr + 2] + "\n" ) if 1 <= int(mae): msae_values = [int(i) for i in dump1[2:]] # keep reading in lines until we have all the data needed. while int(mae) > len(msae_values): itr += 1 try: if any(i in content[itr] for i in ["\t\t\t\t\t", " "]): msae_values.extend([int(i) for i in content[itr].strip().split()]) except IOError: raise IOError("Problem reading MSAE for anm=" + str(atom) + " mae=" + str(mae)) else: msae_values = [] self.preceding_exclusions.append(mtb_preceding_exclusions_field(atom, mae, msae_values)) itr += 1 nlin_found += 1 nmat_found = 0 # try to find all atoms in the ATOM subblock and hope the while does not go to far... while nmat_found < (self.NMAT - self.NLIN) and itr < (len(content) - 10): if content[itr].startswith("#"): itr += 1 continue else: dump1 = content[itr].strip().split() if len(dump1) >= 7: atom, anm, iacm, mass, cgm, icgm, mae = dump1[0:7] else: raise Exception( "Error in ATOM block: \n" + content[itr - 1] + "\n" + content[itr] + "\n" + content[itr + 1] + "\n" + content[itr + 2] + "\n" ) if 1 <= int(mae): msae_values = [int(i) for i in dump1[7:]] # keep reading in lines until we have all the data needed. while int(mae) > len(msae_values): itr += 1 try: if any(i in content[itr] for i in ["\t\t\t\t\t", " "]): msae_values.extend([int(i) for i in content[itr].strip().split()]) except IOError: raise IOError("Problem reading MSAE for anm=" + str(anm) + " mae=" + str(mae)) else: msae_values = [] self.atoms.append(mtb_atoms_field(atom, anm, iacm, mass, cgm, icgm, mae, msae_values)) itr += 1 nmat_found += 1 if self.NMAT == 0: itr += self.skip_lines # trailing atoms trailing_atoms_found = 0 while trailing_atoms_found < self.NLIN and itr < (len(content) - 10): if content[itr].startswith("#"): itr += 1 continue else: dump1 = content[itr].strip().split() if len(dump1) >= 6: atom, anm, iacm, mass, cgm, icgm = dump1[0:6] else: raise Exception( "Error in ATOM block: \n" + content[itr - 1] + "\n" + content[itr] + "\n" + content[itr + 1] + "\n" + content[itr + 2] + "\n" ) self.trailing_atoms.append(mtb_trailing_atoms_field(atom, anm, iacm, mass, cgm, icgm)) itr += 1 trailing_atoms_found += 1 else: nmat_found = 0 # try to find all atoms in the ATOM subblock and hope the while does not go to far... while nmat_found < self.NMAT and itr < (len(content) - 10): if content[itr].startswith("#"): itr += 1 continue else: dump1 = content[itr].strip().split() if len(dump1) >= 7: atom, anm, iacm, mass, cgm, icgm, mae = dump1[0:7] else: raise Exception( "Error in ATOM block: \n" + content[itr - 1] + "\n" + content[itr] + "\n" + content[itr + 1] + "\n" + content[itr + 2] + "\n" ) if 1 <= int(mae): msae_values = [int(i) for i in dump1[7:]] # keep reading in lines until we have all the data needed. while int(mae) > len(msae_values): itr += 1 try: if any(i in content[itr] for i in ["\t\t\t\t\t", " "]): msae_values.extend([int(i) for i in content[itr].strip().split()]) except IOError: raise IOError("Problem reading MSAE for anm=" + str(anm) + " mae=" + str(mae)) else: msae_values = [] self.atoms.append(mtb_atoms_field(atom, anm, iacm, mass, cgm, icgm, mae, msae_values)) itr += 1 nmat_found += 1 if self.NMAT == 0: itr += self.skip_lines # all atoms from ATOM subblock should be found and parsed at this point # read bonds while itr < len(content): if content[itr].startswith("#"): itr += 1 continue else: try: self.NB = int(content[itr].strip()) itr += 1 break except IOError: raise IOError("Problem reading number of bonds") bonds_found = 0 while itr < len(content) and bonds_found < self.NB: if content[itr].startswith("#"): itr += 1 continue else: dump1 = content[itr].strip().split() ib, jb, mcb = dump1[0:3] self.bonds.append(mtb_bonds_field(ib, jb, mcb)) bonds_found += 1 itr += 1 if self.NB == 0: itr += self.skip_lines # read angles while itr < len(content): if content[itr].startswith("#"): itr += 1 continue else: try: self.NBA = int(content[itr].strip()) itr += 1 break except IOError: raise IOError("Problem reading number of angles") angles_found = 0 while itr < len(content) and angles_found < self.NBA: if content[itr].startswith("#"): itr += 1 continue else: dump1 = content[itr].strip().split() ib, jb, kb, mcb = dump1[0:4] self.angles.append(mtb_angles_field(ib, jb, kb, mcb)) angles_found += 1 itr += 1 if self.NBA == 0: itr += self.skip_lines # read improper dihedrals while itr < len(content): if content[itr].startswith("#"): itr += 1 continue else: try: self.NIDA = int(content[itr].strip()) itr += 1 break except IOError: raise IOError("Problem reading number of improper dihedrals") improper_dihedrals_found = 0 while itr < len(content) and improper_dihedrals_found < self.NIDA: if content[itr].startswith("#"): itr += 1 continue else: dump1 = content[itr].strip().split() ib, jb, kb, lb, mcb = dump1[0:5] self.improper_dihedrals.append(mtb_dihedral_field(ib, jb, kb, lb, mcb)) improper_dihedrals_found += 1 itr += 1 if self.NIDA == 0: itr += self.skip_lines # read dihedrals while itr < len(content): if content[itr].startswith("#"): itr += 1 continue else: try: self.NDA = int(content[itr].strip()) itr += 1 break except IOError: raise IOError("Problem reading number of dihedrals") dihedrals_found = 0 while itr < len(content) and dihedrals_found < self.NDA: if content[itr].startswith("#"): itr += 1 continue else: dump1 = content[itr].strip().split() ib, jb, kb, lb, mcb = dump1[0:5] self.dihedrals.append(mtb_dihedral_field(ib, jb, kb, lb, mcb)) dihedrals_found += 1 itr += 1 if self.NDA == 0: itr += self.skip_lines # read LJ exceptions while itr < len(content): if content[itr].startswith("#"): itr += 1 continue else: try: self.NEX = int(content[itr].strip()) itr += 1 break except IOError: raise IOError("Problem reading number of LJ exceptions") lj_exceptions_found = 0 while itr < len(content) and lj_exceptions_found < self.NEX: if content[itr].startswith("#"): itr += 1 continue else: dump1 = content[itr].strip().split() iac, jac, mcb = dump1[0:3] self.lj_exceptions.append(mtb_lj_exceptions_field(iac, jac, mcb)) lj_exceptions_found += 1 itr += 1
[docs] def block_to_string(self) -> str: result = "MTBUILDBLSOLUTE" + self.line_separator if not [x for x in (self.filename, self.residuecode, self.function, self.type, self.fullname) if x is None]: result += ( "# @BLOCKTYPE " + self.filename + " BLK " + self.residuecode + " " + self.function + " TYPE " + self.type + " NAME " + self.fullname + self.line_separator ) result += "# building block" + self.line_separator atom_s = "ATOM".rjust(4) anm_s = "ANM".rjust(6) iacm_s = "IACM".rjust(6) mass_s = "MASS".rjust(6) cgm_s = "CGM".ljust(7) icgm_s = "ICGM".rjust(4) mae_s = "MAE".rjust(4) msae_s = "MSAE" result += "# RNME" + self.line_separator result += self.RNME + self.line_separator result += "# number of atoms, number of preceding exclusions" + self.line_separator result += "# NMAT NLIN" + self.line_separator result += str(self.NMAT) + self.field_separator + str(self.NLIN) + self.line_separator result += "# preceding exclusions" + self.line_separator result += "# ATOM MAE MSAE" + self.line_separator for pre in self.preceding_exclusions: result += pre.to_string() result += "# atoms" + self.line_separator result += f"# {atom_s} {anm_s} {iacm_s} {mass_s} {cgm_s} {icgm_s} {mae_s} {msae_s}" + self.line_separator for atom in self.atoms: result += atom.to_string() result += "# trailing atoms" + self.line_separator result += "# ATOM ANM IACM MASS CGM ICGM" + self.line_separator for trailing_atom in self.trailing_atoms: result += trailing_atom.to_string() result += "# bonds" + self.line_separator result += "# NB" + self.line_separator result += str(self.NB) + self.line_separator result += "# IB JB MCB" + self.line_separator for bond in self.bonds: result += bond.to_string() result += "# angles" + self.line_separator result += "# NBA" + self.line_separator result += str(self.NBA) + self.line_separator result += "# IB JB KB MCB" + self.line_separator for angle in self.angles: result += angle.to_string() result += "# improper dihedrals" + self.line_separator result += "# NIDA" + self.line_separator result += str(self.NIDA) + self.line_separator result += "# IB JB KB LB MCB" + self.line_separator for dihedral in self.improper_dihedrals: result += dihedral.to_string() result += "# dihedrals" + self.line_separator result += "# NDA" + self.line_separator result += str(self.NDA) + self.line_separator result += "# IB JB KB LB MCB" + self.line_separator for dihedral in self.dihedrals: result += dihedral.to_string() result += "# LJ exceptions" + self.line_separator result += "# NEX" + self.line_separator result += str(self.NEX) + self.line_separator result += "# IAC JAC MCB" + self.line_separator for lj_exception in self.lj_exceptions: result += lj_exception.to_string() result += "# @FREELINE" + self.line_separator result += "END" + self.line_separator return result
[docs]class LINKEXCLUSIONS(mtb_blocks): FORCEFIELD: FORCEFIELD MAKETOPVERSION: MAKETOPVERSION NRNE: int def __init__(self, FORCEFIELD: FORCEFIELD = None, MAKETOPVERSION: MAKETOPVERSION = None, content=None): self.NRNE = 0 super().__init__(name=self.__class__.__name__, used=True, content=content) self.FORCEFIELD = FORCEFIELD self.MAKETOPVERSION = MAKETOPVERSION
[docs] def read_content_from_str(self, content: str): while content[0].startswith("#"): content = content[1:] self.NRNE = int(content[0].strip())
[docs] def block_to_string(self) -> str: result = "LINKEXCLUSIONS" + self.line_separator result += "# nearest neighbour exclusions when linking" + self.line_separator result += "# NRNE" + self.line_separator result += str(self.NRNE) + self.line_separator result += "# @FREELINE" + self.line_separator result += "END" + self.line_separator return result
[docs]class MTBUILDBLSOLVENT(mtb_blocks): FORCEFIELD: FORCEFIELD MAKETOPVERSION: MAKETOPVERSION atoms: List[mtb_atoms_field] constraints: List[mtb_constraints_field] def __init__(self, FORCEFIELD: FORCEFIELD = None, MAKETOPVERSION: MAKETOPVERSION = None, content=None): super().__init__(name=self.__class__.__name__, used=True, content=content) self.FORCEFIELD = FORCEFIELD self.MAKETOPVERSION = MAKETOPVERSION
[docs] def read_content_from_str(self, content: str): self.atoms = [] self.constraints = [] # first line, check if information on solute type is available if "@BLOCKTYPE" in content[0]: first_line = content[0].split() self.filename = first_line[1] self.residuecode = first_line[3] self.function = first_line[4] self.type = first_line[6] self.fullname = first_line[8] else: self.filename = None self.residuecode = None self.function = None self.type = None self.fullname = None while content[0].startswith("#"): content = content[1:] self.RNMES = content[0].strip() content = content[1:] while content[0].startswith("#"): content = content[1:] self.number_of_atoms = int(content[0].strip()) content = content[1:] found_atoms = 0 while found_atoms < self.number_of_atoms: if content[0].startswith("#"): content = content[1:] else: atom, anm, iac, mass, cg = content[0].split() self.atoms.append(mtb_atoms_solvent_field(atom, anm, iac, mass, cg)) found_atoms += 1 content = content[1:] while content[0].startswith("#"): content = content[1:] self.number_of_constraints = int(content[0].strip()) content = content[1:] found_constraints = 0 while found_constraints < self.number_of_constraints: if content[0].startswith("#"): content = content[1:] else: ib, jb, mcb = content[0].split() self.constraints.append(mtb_constraints_field(ib, jb, mcb)) found_constraints += 1 content = content[1:]
[docs] def block_to_string(self) -> str: result = "MTBUILDBLSOLVENT" + self.line_separator if not [x for x in (self.filename, self.residuecode, self.function, self.type, self.fullname) if x is None]: result += ( "# @BLOCKTYPE " + self.filename + " BLK " + self.residuecode + " " + self.function + " TYPE " + self.type + " NAME " + self.fullname + self.line_separator ) result += "# solvent name" + self.line_separator result += "# RNMES" + self.line_separator result += str(self.RNMES) + self.line_separator result += "# number of atoms" + self.line_separator result += str(self.number_of_atoms) + self.line_separator result += "# atoms" + self.line_separator result += "# ATOM ANM IACM MASS CG" + self.line_separator for atom in self.atoms: result += atom.to_string() result += "# number of constraints" + self.line_separator result += "# constraints" + self.line_separator result += str(self.number_of_constraints) + self.line_separator result += "# IB JB LENGTH" + self.line_separator for constraint in self.constraints: result += constraint.to_string() result += "# @FREELINE" + self.line_separator result += "END" + self.line_separator return result
[docs]class MTBUILDBLEND(mtb_blocks): FORCEFIELD: FORCEFIELD MAKETOPVERSION: MAKETOPVERSION atoms: List[mtb_atoms_field] replacing_atoms: List[mtb_trailing_atoms_field] bonds: List[mtb_bonds_field] angles: List[mtb_angles_field] improper_dihedrals: List[mtb_dihedral_field] dihedrals: List[mtb_dihedral_field] lj_exceptions: List[mtb_lj_exceptions_field] skip_lines: int = 2 def __init__(self, FORCEFIELD: FORCEFIELD = None, MAKETOPVERSION: MAKETOPVERSION = None, content=None): super().__init__(name=self.__class__.__name__, used=True, content=content) self.FORCEFIELD = FORCEFIELD self.MAKETOPVERSION = MAKETOPVERSION
[docs] def read_content_from_str(self, content: str): # reset all storage self.atoms = [] self.replacing_atoms = [] self.bonds = [] self.angles = [] self.improper_dihedrals = [] self.dihedrals = [] self.lj_exceptions = [] # first line, check if information on solute type is available if "@BLOCKTYPE" in content[0]: first_line = content[0].split() self.filename = first_line[1] self.residuecode = first_line[3] self.function = first_line[4] self.type = first_line[6] self.fullname = first_line[8] else: self.filename = None self.residuecode = None self.function = None self.type = None self.fullname = None itr = 1 while itr < len(content): if content[itr].startswith("#"): itr += 1 continue else: break self.RNME = content[itr].strip() itr += 1 while itr < len(content): if content[itr].startswith("#"): itr += 1 continue else: break self.NMAT = int(content[itr].split()[0]) self.NREP = int(content[itr].split()[1]) itr += 1 if self.NREP >= 0: nmat_found = 0 # try to find all atoms in the ATOM subblock and hope the while does not go to far... while nmat_found < (self.NMAT - self.NREP) and itr < (len(content) - 10): if content[itr].startswith("#"): itr += 1 continue else: dump1 = content[itr].strip().split() if len(dump1) >= 7: atom, anm, iacm, mass, cgm, icgm, mae = dump1[0:7] else: raise Exception( "Error in ATOM block: \n" + content[itr - 1] + "\n" + content[itr] + "\n" + content[itr + 1] + "\n" + content[itr + 2] + "\n" ) if 1 <= int(mae): msae_values = [int(i) for i in dump1[7:]] # keep reading in lines until we have all the data needed. while int(mae) > len(msae_values): itr += 1 try: if any(i in content[itr] for i in ["\t\t\t\t\t", " "]): msae_values.extend([int(i) for i in content[itr].strip().split()]) except IOError: raise IOError("Problem reading MSAE for anm=" + str(anm) + " mae=" + str(mae)) else: msae_values = [] self.atoms.append(mtb_atoms_field(atom, anm, iacm, mass, cgm, icgm, mae, msae_values)) itr += 1 nmat_found += 1 if self.NMAT == 0: itr += self.skip_lines # replacing atoms replacing_atoms_found = 0 while replacing_atoms_found < self.NREP and itr < (len(content) - 10): if content[itr].startswith("#"): itr += 1 continue else: dump1 = content[itr].strip().split() if len(dump1) >= 6: atom, anm, iacm, mass, cgm, icgm = dump1[0:6] else: raise Exception( "Error in ATOM block: \n" + content[itr - 1] + "\n" + content[itr] + "\n" + content[itr + 1] + "\n" + content[itr + 2] + "\n" ) self.replacing_atoms.append(mtb_trailing_atoms_field(atom, anm, iacm, mass, cgm, icgm)) itr += 1 replacing_atoms_found += 1 # no NREP or negative NREP else: nmat_found = 0 # try to find all atoms in the ATOM subblock and hope the while does not go to far... while nmat_found < self.NMAT and itr < (len(content) - 10): if content[itr].startswith("#"): itr += 1 continue else: dump1 = content[itr].strip().split() if len(dump1) >= 7: atom, anm, iacm, mass, cgm, icgm, mae = dump1[0:7] else: raise Exception( "Error in ATOM block: \n" + content[itr - 1] + "\n" + content[itr] + "\n" + content[itr + 1] + "\n" + content[itr + 2] + "\n" ) if 1 <= int(mae): msae_values = [int(i) for i in dump1[7:]] # keep reading in lines until we have all the data needed. while int(mae) > len(msae_values): itr += 1 try: if any(i in content[itr] for i in ["\t\t\t\t\t", " "]): msae_values.extend([int(i) for i in content[itr].strip().split()]) except IOError: raise IOError("Problem reading MSAE for anm=" + str(anm) + " mae=" + str(mae)) else: msae_values = [] self.atoms.append(mtb_atoms_field(atom, anm, iacm, mass, cgm, icgm, mae, msae_values)) itr += 1 nmat_found += 1 if self.NMAT == 0: itr += self.skip_lines # all atoms from ATOM subblock should be found and parsed at this point # read bonds while itr < len(content): if content[itr].startswith("#"): itr += 1 continue else: try: self.NB = int(content[itr].strip()) itr += 1 break except IOError: raise IOError("Problem reading number of bonds") bonds_found = 0 while itr < len(content) and bonds_found < self.NB: if content[itr].startswith("#"): itr += 1 continue else: dump1 = content[itr].strip().split() ib, jb, mcb = dump1[0:3] self.bonds.append(mtb_bonds_field(ib, jb, mcb)) bonds_found += 1 itr += 1 if self.NB == 0: itr += self.skip_lines # read angles while itr < len(content): if content[itr].startswith("#"): itr += 1 continue else: try: self.NBA = int(content[itr].strip()) itr += 1 break except IOError: raise IOError("Problem reading number of angles") angles_found = 0 while itr < len(content) and angles_found < self.NBA: if content[itr].startswith("#"): itr += 1 continue else: dump1 = content[itr].strip().split() ib, jb, kb, mcb = dump1[0:4] self.angles.append(mtb_angles_field(ib, jb, kb, mcb)) angles_found += 1 itr += 1 if self.NBA == 0: itr += self.skip_lines # read improper dihedrals while itr < len(content): if content[itr].startswith("#"): itr += 1 continue else: try: self.NIDA = int(content[itr].strip()) itr += 1 break except IOError: raise IOError("Problem reading number of improper dihedrals") improper_dihedrals_found = 0 while itr < len(content) and improper_dihedrals_found < self.NIDA: if content[itr].startswith("#"): itr += 1 continue else: dump1 = content[itr].strip().split() ib, jb, kb, lb, mcb = dump1[0:5] self.improper_dihedrals.append(mtb_dihedral_field(ib, jb, kb, lb, mcb)) improper_dihedrals_found += 1 itr += 1 if self.NIDA == 0: itr += self.skip_lines # read dihedrals while itr < len(content): if content[itr].startswith("#"): itr += 1 continue else: try: self.NDA = int(content[itr].strip()) itr += 1 break except IOError: raise IOError("Problem reading number of dihedrals") dihedrals_found = 0 while itr < len(content) and dihedrals_found < self.NDA: if content[itr].startswith("#"): itr += 1 continue else: dump1 = content[itr].strip().split() ib, jb, kb, lb, mcb = dump1[0:5] self.dihedrals.append(mtb_dihedral_field(ib, jb, kb, lb, mcb)) dihedrals_found += 1 itr += 1 if self.NDA == 0: itr += self.skip_lines # read LJ exceptions while itr < len(content): if content[itr].startswith("#"): itr += 1 continue else: try: self.NEX = int(content[itr].strip()) itr += 1 break except IOError: raise IOError("Problem reading number of LJ exceptions") lj_exceptions_found = 0 while itr < len(content) and lj_exceptions_found < self.NEX: if content[itr].startswith("#"): itr += 1 continue else: dump1 = content[itr].strip().split() iac, jac, mcb = dump1[0:3] self.lj_exceptions.append(mtb_lj_exceptions_field(iac, jac, mcb)) lj_exceptions_found += 1 itr += 1
[docs] def block_to_string(self) -> str: result = "MTBUILDBLSOLUTE" + self.line_separator if not [x for x in (self.filename, self.residuecode, self.function, self.type, self.fullname) if x is None]: result += ( "# @BLOCKTYPE " + self.filename + " BLK " + self.residuecode + " " + self.function + " TYPE " + self.type + " NAME " + self.fullname + self.line_separator ) result += "# building block" + self.line_separator result += "# RNME" + self.line_separator result += self.RNME + self.line_separator result += "# number of atoms, number of preceding exclusions" + self.line_separator result += "# NMAT NREP" + self.line_separator result += str(self.NMAT) + self.field_separator + str(self.NREP) + self.line_separator result += "# ATOM MAE MSAE" + self.line_separator result += "# atoms" + self.line_separator result += "# ATOM ANM IACM MASS CGMICGM MAE MSAE" + self.line_separator for atom in self.atoms: result += atom.to_string() result += "# replacing atoms" + self.line_separator result += "# ATOM ANM IACM MASS CGMICGM" + self.line_separator for atom in self.replacing_atoms: result += atom.to_string() result += "# bonds" + self.line_separator result += "# NB" + self.line_separator result += str(self.NB) + self.line_separator result += "# IB JB MCB" + self.line_separator for bond in self.bonds: result += bond.to_string() result += "# angles" + self.line_separator result += "# NBA" + self.line_separator result += str(self.NBA) + self.line_separator result += "# IB JB KB MCB" + self.line_separator for angle in self.angles: result += angle.to_string() result += "# improper dihedrals" + self.line_separator result += "# NIDA" + self.line_separator result += str(self.NIDA) + self.line_separator result += "# IB JB KB LB MCB" + self.line_separator for dihedral in self.improper_dihedrals: result += dihedral.to_string() result += "# dihedrals" + self.line_separator result += "# NDA" + self.line_separator result += str(self.NDA) + self.line_separator result += "# IB JB KB LB MCB" + self.line_separator for dihedral in self.dihedrals: result += dihedral.to_string() result += "# LJ exceptions" + self.line_separator result += "# NEX" + self.line_separator result += str(self.NEX) + self.line_separator result += "# IAC JAC MCB" + self.line_separator for lj_exception in self.lj_exceptions: result += lj_exception.to_string() result += "# @FREELINE" + self.line_separator result += "END" + self.line_separator return result