예제 #1
0
    def setUnitCellDimensions(self, dimensions):
        """Set the dimensions of the crystallographic unit cell.

        This method is an alternative to setPeriodicBoxVectors() for the case of a rectangular box.  It sets
        the box vectors to be orthogonal to each other and to have the specified lengths."""
        if dimensions is None:
            self._periodicBoxVectors = None
        else:
            if is_quantity(dimensions):
                dimensions = dimensions.value_in_unit(nanometers)
            self._periodicBoxVectors = (Vec3(dimensions[0], 0,
                                             0), Vec3(0, dimensions[1], 0),
                                        Vec3(0, 0, dimensions[2])) * nanometers
예제 #2
0
    def prepare_pdb(self, path_pdb: Union[str, PDBFile], rm_residue=[]):
        '''
        prepare pdb file: add hydrogens, add solvent
        return:
            pdb
        '''
        from_fixer = False
        if isinstance(path_pdb, str):
            assert os.path.isfile(path_pdb)
            pdb_tmp = PDBFile(path_pdb)
        else:
            from_fixer = True
            pdb_tmp = path_pdb
        # feed it into Modeller and add missing atoms
        # quasi centering

        positions_arr = self._asarray(pdb_tmp.positions._value)
        positions_arr = positions_arr - np.mean(positions_arr, axis=0)
        shift = self._asarray(self.params.boxSize) / 2
        positions_arr += shift
        modeller = Modeller(pdb_tmp.topology, positions_arr)
        if len(rm_residue) != 0:
            modeller.delete(toDelete=rm_residue)
        if not from_fixer:
            _ = modeller.addHydrogens(self.forcefield)
        modeller.addSolvent(self.forcefield,
                            boxSize=Vec3(*self.params.boxSize) * nanometer)
        return modeller
예제 #3
0
    def getUnitCellDimensions(self):
        """Get the dimensions of the crystallographic unit cell.

        The return value may be None if this Topology does not represent a periodic structure.
        """
        if self._periodicBoxVectors is None:
            return None
        xsize = self._periodicBoxVectors[0][0].value_in_unit(nanometers)
        ysize = self._periodicBoxVectors[1][1].value_in_unit(nanometers)
        zsize = self._periodicBoxVectors[2][2].value_in_unit(nanometers)
        return Vec3(xsize, ysize, zsize) * nanometers
예제 #4
0
    def _parse(self, fname):

        with open(fname, 'r') as crdfile:
            line = crdfile.readline()

            while len(line.strip()) == 0:  # Skip whitespace, as a precaution
                line = crdfile.readline()

            intitle = True

            while intitle:
                self.title.append(line.strip())
                line = crdfile.readline()
                if len(line.strip()) == 0:
                    intitle = False
                elif line.strip()[0] != '*':
                    intitle = False
                else:
                    intitle = True

            while len(line.strip()) == 0:  # Skip whitespace
                line = crdfile.readline()

            try:
                self.natom = int(line.strip().split()[0])

                for _ in range(self.natom):
                    line = crdfile.readline().strip().split()
                    self.atomno.append(int(line[0]))
                    self.resno.append(int(line[1]))
                    self.resname.append(line[2])
                    self.attype.append(line[3])
                    pos = Vec3(float(line[4]), float(line[5]), float(line[6]))
                    self.positions.append(pos)
                    self.segid.append(line[7])
                    self.weighting.append(float(line[9]))

                if self.natom != len(self.positions):
                    raise CharmmFileError(
                        "Error parsing CHARMM .crd file: %d "
                        "atoms requires %d positions (not %d)" %
                        (self.natom, self.natom, len(self.positions)))

            except (ValueError, IndexError):
                raise CharmmFileError('Error parsing CHARMM coordinate file')

        # Apply units to the positions now. Do it this way to allow for
        # (possible) numpy functionality in the future.
        self.positions = u.Quantity(self.positions, u.angstroms)
예제 #5
0
    def _get_formatted_crds(self, crdfile, crds):
        for row in range(self.natom):
            line = crdfile.readline()

            if not line:
                raise CharmmFileError('Premature end of file')

            if len(line) < 3 * CHARMMLEN:
                raise CharmmFileError("Less than 3 coordinates present in "
                                      "coordinate row or positions may be "
                                      "truncated.")

            line = line.replace('D', 'E')  # CHARMM uses 'D' for exponentials

            # CHARMM uses fixed format (len = CHARMMLEN = 22) for crds in .rst's

            c = Vec3(float(line[0:CHARMMLEN]),
                     float(line[CHARMMLEN:2 * CHARMMLEN]),
                     float(line[2 * CHARMMLEN:3 * CHARMMLEN]))
            crds.append(c)
예제 #6
0
def addHydrogensPageCallback(parameters, handler):
    if 'addhydrogens' in parameters:
        pH = float(parameters.getfirst('ph'))
        fixer.addMissingHydrogens(pH)
    if 'addwater' in parameters:
        padding, boxSize, boxVectors = None, None, None
        if parameters.getfirst('boxType') == 'geometry':
            geompadding = float(
                parameters.getfirst('geomPadding')) * unit.nanometer
            geometry = parameters.getfirst('geometryDropdown')
            base_size = float(
                parameters.getfirst('maxMolecularAxis')) * unit.nanometer
            if geometry == 'cube':
                padding = geompadding
            elif geometry == 'truncatedOctahedron':
                vectors = Vec3(1, 0, 0), Vec3(1 / 3, 2 * sqrt(2) / 3,
                                              0), Vec3(-1 / 3,
                                                       sqrt(2) / 3,
                                                       sqrt(6) / 3)
                boxVectors = [(base_size + geompadding) * v for v in vectors]
            elif geometry == 'rhombicDodecahedron':
                vectors = Vec3(1, 0, 0), Vec3(0, 1,
                                              0), Vec3(0.5, 0.5,
                                                       sqrt(2) / 2)
                boxVectors = [(base_size + geompadding) * v for v in vectors]
        else:
            boxSize = (float(parameters.getfirst('boxx')),
                       float(parameters.getfirst('boxy')),
                       float(parameters.getfirst('boxz'))) * unit.nanometer
        ionicStrength = float(
            parameters.getfirst('ionicstrength')) * unit.molar
        positiveIon = parameters.getfirst('positiveion') + '+'
        negativeIon = parameters.getfirst('negativeion') + '-'
        fixer.addSolvent(boxSize, padding, boxVectors, positiveIon,
                         negativeIon, ionicStrength)
    if 'addmembrane' in parameters:
        lipidType = parameters.getfirst('lipidType')
        padding = float(
            parameters.getfirst('membranePadding')) * unit.nanometer
        ionicStrength = float(
            parameters.getfirst('ionicstrength')) * unit.molar
        positiveIon = parameters.getfirst('positiveion') + '+'
        negativeIon = parameters.getfirst('negativeion') + '-'
        fixer.addMembrane(lipidType, 0 * unit.nanometer, padding, positiveIon,
                          negativeIon, ionicStrength)
    displaySaveFilePage()
예제 #7
0
    def __init__(self,
                 pdb_line,
                 pdbstructure=None,
                 extraParticleIdentifier='EP'):
        """Create a new pdb.Atom from an ATOM or HETATM line.

        Example line:
        ATOM   2209  CB  TYR A 299       6.167  22.607  20.046  1.00  8.12           C
        00000000011111111112222222222333333333344444444445555555555666666666677777777778
        12345678901234567890123456789012345678901234567890123456789012345678901234567890

        ATOM line format description from
          http://deposit.rcsb.org/adit/docs/pdb_atom_format.html:

        COLUMNS        DATA TYPE       CONTENTS
        --------------------------------------------------------------------------------
         1 -  6        Record name     "ATOM  "
         7 - 11        Integer         Atom serial number.
        13 - 16        Atom            Atom name.
        17             Character       Alternate location indicator.
        18 - 20        Residue name    Residue name.
        22             Character       Chain identifier.
        23 - 26        Integer         Residue sequence number.
        27             AChar           Code for insertion of residues.
        31 - 38        Real(8.3)       Orthogonal coordinates for X in Angstroms.
        39 - 46        Real(8.3)       Orthogonal coordinates for Y in Angstroms.
        47 - 54        Real(8.3)       Orthogonal coordinates for Z in Angstroms.
        55 - 60        Real(6.2)       Occupancy (Default = 1.0).
        61 - 66        Real(6.2)       Temperature factor (Default = 0.0).
        73 - 76        LString(4)      Segment identifier, left-justified.
        77 - 78        LString(2)      Element symbol, right-justified.
        79 - 80        LString(2)      Charge on the atom.

        """
        # We might modify first/final status during _finalize() methods
        self.is_first_atom_in_chain = False
        self.is_final_atom_in_chain = False
        self.is_first_residue_in_chain = False
        self.is_final_residue_in_chain = False
        # Start parsing fields from pdb line
        self.record_name = pdb_line[0:6].strip()
        if pdbstructure is not None and pdbstructure._atom_numbers_are_hex:
            self.serial_number = int(pdb_line[6:11], 16)
        else:
            try:
                self.serial_number = int(pdb_line[6:11])
            except:
                try:
                    self.serial_number = int(pdb_line[6:11], 16)
                    pdbstructure._atom_numbers_are_hex = True
                except:
                    # Just give it the next number in sequence.
                    self.serial_number = pdbstructure._next_atom_number
        self.name_with_spaces = pdb_line[12:16]
        alternate_location_indicator = pdb_line[16]

        self.residue_name_with_spaces = pdb_line[17:20]
        # In some MD codes, notably ffamber in gromacs, residue name has a fourth character in
        # column 21
        possible_fourth_character = pdb_line[20:21]
        if possible_fourth_character != " ":
            # Fourth character should only be there if official 3 are already full
            if len(self.residue_name_with_spaces.strip()) != 3:
                raise ValueError('Misaligned residue name: %s' % pdb_line)
            self.residue_name_with_spaces += possible_fourth_character
        self.residue_name = self.residue_name_with_spaces.strip()

        self.chain_id = pdb_line[21]
        if pdbstructure is not None and pdbstructure._residue_numbers_are_hex:
            self.residue_number = int(pdb_line[22:26], 16)
        else:
            try:
                self.residue_number = int(pdb_line[22:26])
            except:
                try:
                    self.residue_number = int(pdb_line[22:26], 16)
                    pdbstructure._residue_numbers_are_hex = True
                except:
                    # When VMD runs out of hex values it starts filling the residue ID field with ****.
                    # Look at the most recent atoms to figure out whether this is a new residue or not.
                    if pdbstructure._current_model is None or pdbstructure._current_model._current_chain is None or pdbstructure._current_model._current_chain._current_residue is None:
                        # This is the first residue in the model.
                        self.residue_number = pdbstructure._next_residue_number
                    else:
                        currentRes = pdbstructure._current_model._current_chain._current_residue
                        if currentRes.name_with_spaces != self.residue_name_with_spaces:
                            # The residue name has changed.
                            self.residue_number = pdbstructure._next_residue_number
                        elif self.name_with_spaces in currentRes.atoms_by_name:
                            # There is already an atom with this name.
                            self.residue_number = pdbstructure._next_residue_number
                        else:
                            self.residue_number = currentRes.number
        self.insertion_code = pdb_line[26]
        # coordinates, occupancy, and temperature factor belong in Atom.Location object
        x = float(pdb_line[30:38])
        y = float(pdb_line[38:46])
        z = float(pdb_line[46:54])
        try:
            occupancy = float(pdb_line[54:60])
        except:
            occupancy = 1.0
        try:
            temperature_factor = unit.Quantity(float(pdb_line[60:66]),
                                               unit.angstroms**2)
        except:
            temperature_factor = unit.Quantity(0.0, unit.angstroms**2)
        self.locations = {}
        loc = Atom.Location(alternate_location_indicator,
                            unit.Quantity(Vec3(x, y, z),
                                          unit.angstroms), occupancy,
                            temperature_factor, self.residue_name_with_spaces)
        self.locations[alternate_location_indicator] = loc
        self.default_location_id = alternate_location_indicator
        # segment id, element_symbol, and formal_charge are not always present
        self.segment_id = pdb_line[72:76].strip()
        self.element_symbol = pdb_line[76:78].strip()
        try:
            self.formal_charge = int(pdb_line[78:80])
        except ValueError:
            self.formal_charge = None
        # figure out atom element
        if self.element_symbol == extraParticleIdentifier:
            self.element = 'EP'
        else:
            try:
                # Try to find a sensible element symbol from columns 76-77
                self.element = element.get_by_symbol(self.element_symbol)
            except KeyError:
                self.element = None
        if pdbstructure is not None:
            pdbstructure._next_atom_number = self.serial_number + 1
            pdbstructure._next_residue_number = self.residue_number + 1
예제 #8
0
파일: vec3.py 프로젝트: jlmaccal/ParmEd
 def __neg__(self):
     return Vec3(-self.x, -self.y, -self.z)
예제 #9
0
파일: vec3.py 프로젝트: jlmaccal/ParmEd
 def __deepcopy__(self, memo):
     return Vec3(self.x, self.y, self.z)
예제 #10
0
파일: vec3.py 프로젝트: jlmaccal/ParmEd
 def __div__(self, other):
     """Divide a Vec3 by a constant."""
     return Vec3(self.x / other, self.y / other, self.z / other)
예제 #11
0
파일: vec3.py 프로젝트: jlmaccal/ParmEd
 def __rmul__(self, other):
     """Multiply a Vec3 by a constant."""
     if unit.is_unit(other):
         return unit.Quantity(self, other)
     return Vec3(other * self.x, other * self.y, other * self.z)
예제 #12
0
파일: vec3.py 프로젝트: jlmaccal/ParmEd
 def __rsub__(self, other):
     """Add two Vec3s."""
     return Vec3(other[0] - self.x, other[1] - self.y,
                 other[2] - self.z)
예제 #13
0
파일: vec3.py 프로젝트: jlmaccal/ParmEd
 def __sub__(self, other):
     """Add two Vec3s."""
     return Vec3(self.x - other[0], self.y - other[1],
                 self.z - other[2])
예제 #14
0
파일: vec3.py 프로젝트: jlmaccal/ParmEd
 def __radd__(self, other):
     """Add two Vec3s."""
     return Vec3(self.x + other[0], self.y + other[1],
                 self.z + other[2])