def _readDihedralParameters(self, file):
     format = FortranFormat('A2,1X,A2,1X,A2,1X,A2,I4,3F15.2')
     append = None
     while 1:
         l = FortranLine(file.readline()[:-1], format)
         if l.isBlank(): break
         name1 = _normalizeName(l[0])
         name2 = _normalizeName(l[1])
         name3 = _normalizeName(l[2])
         name4 = _normalizeName(l[3])
         name1, name2, name3, name4 = _sort4(name1, name2, name3, name4)
         if append is not None:
             append.addTerm(l[4], l[5], l[6], l[7])
             if l[7] >= 0: append = None
         else:
             p = AmberDihedralParameters(self.atom_types[name1],
                                         self.atom_types[name2],
                                         self.atom_types[name3],
                                         self.atom_types[name4], l[4], l[5],
                                         l[6], l[7])
             if name1 == 'X' and name4 == 'X':
                 self.dihedrals_2[(name2, name3)] = p
             else:
                 self.dihedrals[(name1, name2, name3, name4)] = p
             if l[7] < 0: append = p
 def _readAtomTypes(self, file):
     format = FortranFormat('A2,1X,F10.2')
     while 1:
         l = FortranLine(file.readline()[:-1], format)
         if l.isBlank(): break
         name = _normalizeName(l[0])
         self.atom_types[name] = AmberAtomType(name, l[1])
Пример #3
0
 def _readAtomTypes(self, file):
     format = FortranFormat('A2,1X,F10.2')
     while True:
         l = FortranLine(file.readline()[:-1], format)
         if l.isBlank(): break
         name = _normalizeName(l[0])
         self.atom_types[name] = AmberAtomType(name, l[1])
 def _readLJParameters(self, file, ljpar_set):
     format = FortranFormat('2X,A2,6X,3F10.6')
     while 1:
         l = FortranLine(file.readline()[:-1], format)
         if l.isBlank(): break
         name = _normalizeName(l[0])
         ljpar_set.addEntry(name, l[1], l[2], l[3])
Пример #5
0
 def _readImproperParameters(self, file):
     format = FortranFormat('A2,1X,A2,1X,A2,1X,A2,I4,3F15.2')
     while True:
         l = FortranLine(file.readline()[:-1], format)
         if l.isBlank(): break
         name1 = _normalizeName(l[0])
         name2 = _normalizeName(l[1])
         name3 = _normalizeName(l[2])
         name4 = _normalizeName(l[3])
         if name1 == 'X':
             if name2 == 'X':
                 name1 = name3
                 name2 = name4
                 name3 = 'X'
                 name4 = 'X'
             else:
                 name1 = name3
                 name2, name3 = _sort(name2, name4)
                 name4 = 'X'
         else:
             name1, name2, name3, name4 = \
                    (name3, ) + _sort3(name1, name2, name4)
         p = AmberImproperParameters(self.atom_types[name1],
                                     self.atom_types[name2],
                                     self.atom_types[name3],
                                     self.atom_types[name4],
                                     l[4], l[5], l[6], l[7])
         if name4 == 'X':
             if name3 == 'X':
                 self.impropers_2[(name1, name2)] = p
             else:
                 self.impropers_1[(name1, name2, name3)] = p
         else:
             self.impropers[(name1, name2, name3, name4)] = p
Пример #6
0
 def _readLJParameters(self, file, ljpar_set):
     format = FortranFormat('2X,A2,6X,3F10.6')
     while True:
         l = FortranLine(file.readline()[:-1], format)
         if l.isBlank(): break
         name = _normalizeName(l[0])
         ljpar_set.addEntry(name, l[1], l[2], l[3])
 def _readImproperParameters(self, file):
     format = FortranFormat('A2,1X,A2,1X,A2,1X,A2,I4,3F15.2')
     while 1:
         l = FortranLine(file.readline()[:-1], format)
         if l.isBlank(): break
         name1 = _normalizeName(l[0])
         name2 = _normalizeName(l[1])
         name3 = _normalizeName(l[2])
         name4 = _normalizeName(l[3])
         if name1 == 'X':
             if name2 == 'X':
                 name1 = name3
                 name2 = name4
                 name3 = 'X'
                 name4 = 'X'
             else:
                 name1 = name3
                 name2, name3 = _sort(name2, name4)
                 name4 = 'X'
         else:
             name1, name2, name3, name4 = \
                    (name3, ) + _sort3(name1, name2, name4)
         p = AmberImproperParameters(self.atom_types[name1],
                                     self.atom_types[name2],
                                     self.atom_types[name3],
                                     self.atom_types[name4], l[4], l[5],
                                     l[6], l[7])
         if name4 == 'X':
             if name3 == 'X':
                 self.impropers_2[(name1, name2)] = p
             else:
                 self.impropers_1[(name1, name2, name3)] = p
         else:
             self.impropers[(name1, name2, name3, name4)] = p
Пример #8
0
    def writeTrajectory(self, trajectory_name, block_size=1):
        trajectory = Trajectory(self.universe, trajectory_name, 'w',
                                self.title, block_size=block_size)
        actions = [TrajectoryOutput(trajectory, ["all"], 0, None, 1)]
        snapshot = SnapshotGenerator(self.universe, actions=actions)
        conf = self.universe.configuration()
        vel = self.universe.velocities()
        grad = ParticleVector(self.universe)
        try:
            while 1:
                line = self.history.readline()
                if not line:
                    break
                data = FortranLine(line, history_timestep_line)
                step = data[1]
                natoms = data[2]
                nvectors = data[3]+1
                pbc = data[4]
                dt = data[5]
                step_data = {'time': step*dt}
                if nvectors > 2:
                    step_data['gradients'] = grad
                if pbc:
                    data = FortranLine(self.history.readline(), history_pbc_line)
                    box_x = data[0]*Units.Ang
                    #if data[1] != 0. or data[2] != 0.:
                    #    raise ValueError, "box shape not supported"
                    data = FortranLine(self.history.readline(), history_pbc_line)
                    box_y = data[1]*Units.Ang
                    #if data[0] != 0. or data[2] != 0.:
                    #    raise ValueError, "box shape not supported"
                    data = FortranLine(self.history.readline(), history_pbc_line)
                    box_z = data[2]*Units.Ang
                    #if data[0] != 0. or data[1] != 0.:
                    #    raise ValueError, "box shape not supported"
                    self.universe.setSize((box_x, box_y, box_z))
                for i in range(natoms):
                    self.history.readline()
                    conf.array[i] = map(float,
                                        string.split(self.history.readline()))
                    if nvectors > 1:
                        vel.array[i] = map(float,
                                           string.split(self.history.readline()))
                        if nvectors > 2:
                            grad.array[i] = map(float,
                                             string.split(self.history.readline()))
                Numeric.multiply(conf.array, Units.Ang, conf.array)
                if nvectors > 1:
                    Numeric.multiply(vel.array, Units.Ang/Units.ps, vel.array)
                if nvectors > 2:
                    Numeric.multiply(grad.array, -Units.amu*Units.Ang/Units.ps**2,
                                     grad.array)

                snapshot(data=step_data)
        finally:
            trajectory.close()
Пример #9
0
 def _readHbondParameters(self, file):
     format = FortranFormat('2X,A2,2X,A2,2X,2F10.2')
     while True:
         l = FortranLine(file.readline()[:-1], format)
         if l.isBlank(): break
         name1 = _normalizeName(l[0])
         name2 = _normalizeName(l[1])
         name1, name2 = _sort(name1, name2)
         self.hbonds[(name1, name2)] = \
                             AmberHbondParameters(self.atom_types[name1],
                                                  self.atom_types[name2],
                                                  l[2], l[3])
 def _readHbondParameters(self, file):
     format = FortranFormat('2X,A2,2X,A2,2X,2F10.2')
     while 1:
         l = FortranLine(file.readline()[:-1], format)
         if l.isBlank(): break
         name1 = _normalizeName(l[0])
         name2 = _normalizeName(l[1])
         name1, name2 = _sort(name1, name2)
         self.hbonds[(name1, name2)] = \
                             AmberHbondParameters(self.atom_types[name1],
                                                  self.atom_types[name2],
                                                  l[2], l[3])
 def _readAngleParameters(self, file):
     format = FortranFormat('A2,1X,A2,1X,A2,2F10.2')
     while 1:
         l = FortranLine(file.readline()[:-1], format)
         if l.isBlank(): break
         name1 = _normalizeName(l[0])
         name2 = _normalizeName(l[1])
         name3 = _normalizeName(l[2])
         name1, name3 = _sort(name1, name3)
         self.bond_angles[(name1, name2, name3)] = \
                AmberBondAngleParameters(self.atom_types[name1],
                                         self.atom_types[name2],
                                         self.atom_types[name3],
                                         l[3], l[4])
Пример #12
0
 def _readAngleParameters(self, file):
     format = FortranFormat('A2,1X,A2,1X,A2,2F10.2')
     while True:
         l = FortranLine(file.readline()[:-1], format)
         if l.isBlank(): break
         name1 = _normalizeName(l[0])
         name2 = _normalizeName(l[1])
         name3 = _normalizeName(l[2])
         name1, name3 = _sort(name1, name3)
         self.bond_angles[(name1, name2, name3)] = \
                AmberBondAngleParameters(self.atom_types[name1],
                                         self.atom_types[name2],
                                         self.atom_types[name3],
                                         l[3], l[4])
Пример #13
0
def write_bgf(atoms,description=None):

    uc = atoms.get_cell()
    a,b,c = [Vector(x) for x in uc]
    A = a.length()
    B = b.length()
    C = c.length()

    rad2deg = 360./(2*math.pi)
    alpha = b.angle(c)*rad2deg
    beta  = a.angle(c)*rad2deg
    gamma = a.angle(b)*rad2deg

    crstx = str(FortranLine(('CRYSTX',
                             A,
                             B,
                             C,
                             alpha,
                             beta,
                             gamma),
                             FortranFormat('a6,1x,6f11.5')))

    atom_lines = []
    fmt = FortranFormat('a6,1x,i5,1x,a5,1x,a3,1x,a1,1x,a5,3f10.5,1x,a5,i3,i2,1x,f8.5')
    for i,atom in enumerate(atoms):
        
        line = str(FortranLine(('HETATM',
                               i,
                               atom.symbol,
                               '',
                               '',
                               '',
                               atom.x,
                               atom.y,
                               atom.z,
                               atom.symbol,
                               1,
                               1,
                               0.0),
                               fmt))
        atom_lines.append(line)

    # energy in kcal
    energy = atoms.get_potential_energy()*23.061


    bgf = Template(bgf_template, searchList=[locals()])

    return bgf.respond()
 def readCAlphaPositions(filename):
     positions = []
     chains = [positions]
     for line in TextFile(filename):
         record_type = FortranLine(line, generic_format)[0]
         if record_type == 'ATOM  ' or record_type == 'HETATM':
             data = FortranLine(line, atom_format)
             atom_name = string.strip(data[2])
             position = N.array(data[8:11])
             if atom_name == 'CA':
                 positions.append(position)
             elif atom_name == 'OXT':
                 positions = []
                 chains.append(positions)
     if len(chains[-1]) == 0:
         del chains[-1]
     return chains
Пример #15
0
 def __init__(self, directory):
     self.directory = directory
     self.history = open(os.path.join(self.directory, 'HISTORY'))
     self.title = string.strip(self.history.readline())
     info = FortranLine(self.history.readline(), '2I10')
     if info[1] > 3:
         raise ValueError, "box shape not implemented"
     nvectors = info[0] + 1
     self.makeUniverse(info[1], self.readField())
     if nvectors > 1:
         self.universe.initializeVelocitiesToTemperature(0.)
Пример #16
0
 def __init__(self,species,historyFile):
     #self.directory = directory
     self.history = open(historyFile)
     self.title = string.strip(self.history.readline())
     info = FortranLine(self.history.readline(), '2I10')
     if info[1] > 3:
         raise ValueError, "box shape not implemented"
     nvectors = info[0]+1
     self.makeUniverse(info[1], species)
     if nvectors > 1:
         self.universe.initializeVelocitiesToTemperature(0.)
Пример #17
0
 def writeXPlor(self, filename):
     from Scientific.IO.FortranFormat import FortranFormat, FortranLine
     file = open(filename, 'w')
     file.write('\n       1 !NTITLE\n')
     file.write('REMARKS Electronic density map\n')
     data = [
         self.data.shape[0], 1, self.data.shape[0], self.data.shape[1], 1,
         self.data.shape[1], self.data.shape[2], 1, self.data.shape[2]
     ]
     file.write(str(FortranLine(data, '9I8')) + '\n')
     x = (self.x_axis[-1] - self.x_axis[0]) / Units.Ang
     y = (self.y_axis[-1] - self.y_axis[0]) / Units.Ang
     z = (self.z_axis[-1] - self.z_axis[0]) / Units.Ang
     data = [x, y, z] + 3 * [90.]
     file.write(str(FortranLine(data, '6E12.5')) + '\n')
     file.write('ZYX\n')
     map_data = N.ravel(self.data)
     map_data = map_data / N.maximum.reduce(map_data)
     average = N.sum(map_data) / len(map_data)
     sd = N.sqrt(N.sum((map_data - average)**2) / len(map_data))
     map_data.shape = self.data.shape
     for i in range(self.data.shape[2]):
         file.write(str(FortranLine([i], 'I8')) + '\n')
         data = list(N.ravel(N.transpose(map_data[:, :, i])))
         while data:
             file.write(str(FortranLine(data[:6],
                                        '%dE12.5' % min(6, len(data)))) \
                        + '\n')
             data = data[6:]
     file.write(str(FortranLine([-9999], 'I8')) + '\n')
     file.write(str(FortranLine([average, sd], '2(E12.4,1X)')) + '\n')
     file.close()
Пример #18
0
 def readField(self):
     filename = os.path.join(self.directory, 'FIELD')
     lines = open(filename).readlines()
     while 1:
         if self.checkDirective(lines[0], 'MOLECULES'):
             nspecies = string.atoi(string.split(lines[0])[1])
             break
         if self.checkDirective(lines[0], 'MOLECULAR TYPES'):
             nspecies = string.atoi(string.split(lines[0])[2])
             break
         lines = lines[1:]
     lines = lines[1:]
     species = []
     for i in range(nspecies):
         name = string.strip(lines[0])
         n = string.atoi(string.split(lines[1])[1])
         natoms = string.atoi(string.split(lines[2])[1])
         lines = lines[3:]
         atoms = []
         while natoms > 0:
             data = FortranLine(lines[0], field_atom_line)
             lines = lines[1:]
             atom_name = string.strip(data[0])
             element = string.lower(atom_name[:2])
             if element not in _elements2:
                 element = element[0]
             nrepeat = max(data[3], 1)
             for j in range(nrepeat):
                 atoms.append((element, atom_name))
             natoms = natoms - nrepeat
         while (not self.checkDirective(lines[0], 'FINISH')) \
               and (not self.checkDirective(lines[0], 'CONSTRAINTS')):
             lines = lines[1:]
         constraints = []
         if self.checkDirective(lines[0], 'CONSTRAINTS'):
             nc = string.atoi(string.split(lines[0])[1])
             lines = lines[1:]
             while nc > 0:
                 l = string.split(lines[0])
                 i1 = int(l[0]) - 1
                 i2 = int(l[1]) - 1
                 d = float(l[2]) * Units.Ang
                 constraints.append((i1, i2, d))
                 lines = lines[1:]
                 nc = nc - 1
             while not self.checkDirective(lines[0], 'FINISH'):
                 lines = lines[1:]
         lines = lines[1:]
         species.append([name, n, atoms, constraints])
     return species
Пример #19
0
    def __init__(self,atoms,outfile=None):

        unitcell = atoms.get_cell()
        A = Vector(unitcell[0])
        B = Vector(unitcell[1])
        C = Vector(unitcell[2])

        # lengths of the vectors
        a = A.length()#*angstroms2bohr
        b = B.length()#*angstroms2bohr
        c = C.length()#*angstroms2bohr

        # angles between the vectors
        rad2deg = 360./(2.*math.pi)
        alpha = B.angle(C)*rad2deg
        beta = A.angle(C)*rad2deg
        gamma = A.angle(B)*rad2deg

        # scaledpositions = atoms.get_scaled_positions()
        # chemicalsymbols = [atom.get_symbol() for atom in atoms]

        input = ''
        input += '%1.3f %1.3f %1.3f %1.3f %1.3f %1.3f\n' % (a,b,c,
                                                            alpha,beta,gamma)
        input += '1 1 0.1 0.1\n'

        for atom in atoms:
            sym = atom.get_symbol()
            group = 1
            x,y,z = atom.get_position()
            #format(a6,i2,6f9.5)
            input += str(FortranLine((sym,
                                      group,
                                      x,y,z),
                                     FortranFormat('a6,i2,3f9.5')))+'\n'

        pin,pout = os.popen2('symmol')
        pin.writelines(input)
        pin.close()
        self.output = pout.readlines()
        pout.close()

        if outfile:
            f = open(outfile,'w')
            f.writelines(self.output)
            f.close()

        if os.path.exists('symmol.log'):
            os.remove('symmol.log')
    def apply(self):

        try:
            # pid = the pid number for the job
            pid = os.getpid()
            suffix = '.'.join(['', str(pid), 'pdb', 'nmoldyn'])

            # This just creates a unique temporary directory.
            dirName = mkdtemp(suffix)

            outputFile = open(self.pdbFile, 'w')

            for f in self.selectedFrames:

                pdbFrame = os.path.join(dirName,
                                        ''.join(['Frame',
                                                 str(f), '.pdb']))

                if self.outputStyle.getValue().lower() == "mmtk":
                    # This MMTK function write a PDB file given a trajectory and a selected frame index.
                    PDBOutputFile(pdbFrame).write(
                        self.trajectory.universe,
                        self.trajectory.configuration[f - 1])

                else:

                    pdbFile = open(pdbFrame, 'w')

                    resNum = 0
                    atNum = 0

                    for obj in self.trajectory.universe.objectList():

                        resNum += 1

                        data = {}

                        for at in obj.atomList():

                            atNum += 1

                            try:
                                occ = at.occupancy
                            except AttributeError:
                                occ = 0.0

                            try:
                                temp = at.temperature_factor
                            except AttributeError:
                                temp = 0.0

                            type = 'ATOM'

                            data['name'] = at.name.upper()
                            p = at.position(
                                self.trajectory.configuration[f -
                                                              1]) / Units.Ang
                            data['serial_number'] = atNum % 100000
                            data['residue_number'] = resNum
                            data['residue_name'] = at.topLevelChemicalObject(
                            ).name
                            data['alternate'] = ""
                            data['occupancy'] = occ
                            data['temperature_factor'] = temp
                            data['element'] = at.type.symbol

                            line = [type]

                            line = line + [
                                data.get('serial_number', 1),
                                data.get('name'),
                                data.get('alternate', ''),
                                data.get('residue_name', '').rjust(3),
                                data.get('chain_id', ''),
                                data.get('residue_number', 1),
                                data.get('insertion_code', ''), p[0], p[1],
                                p[2],
                                data.get('occupancy', 0.),
                                data.get('temperature_factor', 0.),
                                data.get('segment_id', ''),
                                data.get('element', '').rjust(2),
                                data.get('charge', '')
                            ]

                            pdbFile.write(
                                str(FortranLine(line, atom_format)) + '\n')

                    pdbFile.close()

                pdbFile = open(pdbFrame, 'r')
                data = pdbFile.read()
                pdbFile.close()
                os.unlink(pdbFrame)
                outputFile.write('REMARK Frame %d\n' % (f, ))
                outputFile.write(data)

            outputFile.close()

            LogMessage('info', 'Frame extraction successful', ['gui'])

        except:
            raise Error('Error when extracting PDB frame.')
Пример #21
0
    def __init__(self, file, modifications=[]):
        if isinstance(file, basestring):
            file = TextFile(file)
        title = file.readline()[:-1]

        self.atom_types = DictWithDefault(None)
        self._readAtomTypes(file)

        format = FortranFormat('20(A2,2X)')
        done = False
        while not done:
            l = FortranLine(file.readline()[:-1], format)
            for entry in l:
                name = _normalizeName(entry)
                if len(name) == 0:
                    done = True
                    break
                try: # ignore errors for now
                    self.atom_types[name].hydrophylic = True
                except: pass

        self.bonds = {}
        self._readBondParameters(file)

        self.bond_angles = {}
        self._readAngleParameters(file)

        self.dihedrals = {}
        self.dihedrals_2 = {}
        self._readDihedralParameters(file)

        self.impropers = {}
        self.impropers_1 = {}
        self.impropers_2 = {}
        self._readImproperParameters(file)

        self.hbonds = {}
        self._readHbondParameters(file)

        self.lj_equivalent = {}
        format = FortranFormat('20(A2,2X)')
        while True:
            l = FortranLine(file.readline()[:-1], format)
            if l.isBlank(): break
            name1 = _normalizeName(l[0])
            for s in l[1:]:
                name2 = _normalizeName(s)
                self.lj_equivalent[name2] = name1

        self.ljpar_sets = {}
        while True:
            l = FortranLine(file.readline()[:-1], 'A4,6X,A2')
            if l[0] == 'END ': break
            set_name = _normalizeName(l[0])
            ljpar_set = AmberLJParameterSet(set_name, l[1])
            self.ljpar_sets[set_name] = ljpar_set
            self._readLJParameters(file, ljpar_set)

        file.close()

        for mod, ljname in modifications:
            if isinstance(mod, basestring):
                file = TextFile(mod)
            else:
                file = mod
            title = file.readline()[:-1]
            blank = file.readline()[:-1]
            while True:
                keyword = file.readline()
                if not keyword: break
                keyword = keyword.strip()[:4]
                if keyword == 'MASS':
                    self._readAtomTypes(file)
                elif keyword == 'BOND':
                    self._readBondParameters(file)
                elif keyword == 'ANGL':
                    self._readAngleParameters(file)
                elif keyword == 'DIHE':
                    self._readDihedralParameters(file)
                elif keyword == 'IMPR':
                    self._readImproperParameters(file)
                elif keyword == 'HBON':
                    self._readHbondParameters(file)
                elif keyword == 'NONB':
                    self._readLJParameters(file, self.ljpar_sets[ljname])
Пример #22
0
def write_bgf(atoms, geofile=None):
    '''
	prepares a bgf entry from an atoms object and writes it to the geofile
	'''
    if geofile is None:
        geofile = 'geo'

    # create the geofile if it does not already exist
    if not os.path.exists(geofile):
        f = open(geofile, 'w')
        f.close()

    # get descriptions to make sure they are all unique.
    f = open(geofile, 'r')
    DESCRIPTIONS = []
    for line in f.readlines():
        if line.startswith('DESCRP'):
            DESCRIPTIONS.append(line[6:].strip())
    f.close()

    # we need a hash of something to check for uniqueness of the atoms.
    description = reax_hash(atoms)

    if description in DESCRIPTIONS:
        raise Exception, 'Non-unique description "%s" in geofile' % description

    # now prepare the unit cell information for the CRYSTX line
    uc = atoms.get_cell()
    a, b, c = [Vector(x) for x in uc]
    A = a.length()
    B = b.length()
    C = c.length()

    rad2deg = 360. / (2 * math.pi)
    alpha = b.angle(c) * rad2deg
    beta = a.angle(c) * rad2deg
    gamma = a.angle(b) * rad2deg

    crstx = str(
        FortranLine(('CRYSTX', A, B, C, alpha, beta, gamma),
                    FortranFormat('a6,1x,6f11.5')))

    # now we prepare each atom line. These are printed in the template.
    atom_lines = []
    reax_coords = reax_coordinates(atoms)
    fmt = FortranFormat(
        'a6,1x,i5,1x,a5,1x,a3,1x,a1,1x,a5,3f10.5,1x,a5,i3,i2,1x,f8.5')
    for i, atom in enumerate(atoms):
        x, y, z = reax_coords[i]
        line = FortranLine(('HETATM', i, atom.symbol, '', '', '', x, y, z,
                            atom.symbol, 1, 1, 0.0), fmt)
        atom_lines.append(line)

    # energy in kcal
    calc = atoms.get_calculator()
    if calc is not None:
        directory = os.path.abspath(calc.vaspdir)
        energy = atoms.get_potential_energy() * 23.061
    else:
        directory = 'None'
        energy = 'None'

    bgf = Template(bgf_template, searchList=[locals()])

    entry = bgf.respond()

    if geofile is None:
        geofile = 'geo'

    f = open(geofile, 'a')
    f.write(entry)
    f.close()
 def writeLine(self, type, data):
     """Writes a line using record type and data dictionary in the
     same format as returned by readLine(). Default values are
     provided for non-essential information, so the data dictionary
     need not contain all entries.
     """
     if self.export_filter is not None:
         type, data = self.export_filter.processLine(type, data)
         if type is None:
             return
     line = [type]
     if type == 'ATOM' or type == 'HETATM':
         format = atom_format
         position = data['position']
         line = line + [
             data.get('serial_number', 1),
             data.get('name'),
             data.get('alternate', ''),
             string.rjust(data.get('residue_name', ''), 3),
             data.get('chain_id', ''),
             data.get('residue_number', 1),
             data.get('insertion_code', ''), position[0], position[1],
             position[2],
             data.get('occupancy', 0.),
             data.get('temperature_factor', 0.),
             data.get('segment_id', ''),
             string.rjust(data.get('element', ''), 2),
             data.get('charge', '')
         ]
     elif type == 'ANISOU':
         format = anisou_format
         u = 1.e4 * data['u']
         u = [
             int(u[0, 0]),
             int(u[1, 1]),
             int(u[2, 2]),
             int(u[0, 1]),
             int(u[0, 2]),
             int(u[1, 2])
         ]
         line = line + [data.get('serial_number', 1),
                        data.get('name'),
                        data.get('alternate', ''),
                        string.rjust(data.get('residue_name'), 3),
                        data.get('chain_id', ''),
                        data.get('residue_number', 1),
                        data.get('insertion_code', '')] \
                     + u \
                     + [data.get('segment_id', ''),
                        string.rjust(data.get('element', ''), 2),
                        data.get('charge', '')]
     elif type == 'TER':
         format = ter_format
         line = line + [
             data.get('serial_number', 1),
             string.rjust(data.get('residue_name'), 3),
             data.get('chain_id', ''),
             data.get('residue_number', 1),
             data.get('insertion_code', '')
         ]
     elif type == 'CONECT':
         format = conect_format
         line = line + [data.get('serial_number')]
         line = line + (data.get('bonded', []) + 4 * [None])[:4]
         line = line + (data.get('hydrogen_bonded', []) + 4 * [None])[:4]
         line = line + (data.get('salt_bridged', []) + 2 * [None])[:2]
     elif type == 'MODEL':
         format = model_format
         line = line + [data.get('serial_number')]
     elif type == 'HEADER':
         format = header_format
         line = line + [
             data.get('compound', ''),
             data.get('date', ''),
             data.get('pdb_code')
         ]
     else:
         format = generic_format
         line = line + [data]
     self.file.write(str(FortranLine(line, format)) + '\n')
 def readLine(self):
     """Returns the contents of the next non-blank line (= record).
     The return value is a tuple whose first element (a string)
     contains the record type. For supported record types (HEADER,
     ATOM, HETATM, ANISOU, TERM, MODEL, CONECT), the items from the
     remaining fields are put into a dictionary which is returned
     as the second tuple element. Most dictionary elements are
     strings or numbers; atom positions are returned as a vector,
     and anisotropic temperature factors are returned as a rank-2
     tensor, already multiplied by 1.e-4. White space is stripped
     from all strings except for atom names, whose correct
     interpretation can depend on an initial space. For unsupported
     record types, the second tuple element is a string containing
     the remaining part of the record.
     """
     while 1:
         line = self.file.readline()
         if not line: return ('END', '')
         if line[-1] == '\n': line = line[:-1]
         line = string.strip(line)
         if line: break
     line = string.ljust(line, 80)
     type = string.strip(line[:6])
     if type == 'ATOM' or type == 'HETATM':
         line = FortranLine(line, atom_format)
         data = {
             'serial_number': line[1],
             'name': line[2],
             'alternate': string.strip(line[3]),
             'residue_name': string.strip(line[4]),
             'chain_id': string.strip(line[5]),
             'residue_number': line[6],
             'insertion_code': string.strip(line[7]),
             'position': Vector(line[8:11]),
             'occupancy': line[11],
             'temperature_factor': line[12],
             'segment_id': string.strip(line[13]),
             'element': string.strip(line[14]),
             'charge': string.strip(line[15])
         }
         return type, data
     elif type == 'ANISOU':
         line = FortranLine(line, anisou_format)
         data = {
             'serial_number':
             line[1],
             'name':
             line[2],
             'alternate':
             string.strip(line[3]),
             'residue_name':
             string.strip(line[4]),
             'chain_id':
             string.strip(line[5]),
             'residue_number':
             line[6],
             'insertion_code':
             string.strip(line[7]),
             'u':
             1.e-4 * Tensor([[line[8], line[11], line[12]],
                             [line[11], line[9], line[13]],
                             [line[12], line[13], line[10]]]),
             'segment_id':
             string.strip(line[14]),
             'element':
             string.strip(line[15]),
             'charge':
             string.strip(line[16])
         }
         return type, data
     elif type == 'TER':
         line = FortranLine(line, ter_format)
         data = {
             'serial_number': line[1],
             'residue_name': string.strip(line[2]),
             'chain_id': string.strip(line[3]),
             'residue_number': line[4],
             'insertion_code': string.strip(line[5])
         }
         return type, data
     elif type == 'CONECT':
         line = FortranLine(line, conect_format)
         data = {
             'serial_number': line[1],
             'bonded': filter(lambda i: i > 0, line[2:6]),
             'hydrogen_bonded': filter(lambda i: i > 0, line[6:10]),
             'salt_bridged': filter(lambda i: i > 0, line[10:12])
         }
         return type, data
     elif type == 'MODEL':
         line = FortranLine(line, model_format)
         data = {'serial_number': line[1]}
         return type, data
     elif type == 'HEADER':
         line = FortranLine(line, header_format)
         data = {'compound': line[1], 'date': line[2], 'pdb_code': line[3]}
         return type, data
     else:
         return type, line[6:]
    def __init__(self, file, modifications=[]):
        if isinstance(file, str):
            file = TextFile(file)
        title = file.readline()[:-1]

        self.atom_types = DictWithDefault(None)
        self._readAtomTypes(file)

        format = FortranFormat('20(A2,2X)')
        done = 0
        while not done:
            l = FortranLine(file.readline()[:-1], format)
            for entry in l:
                name = _normalizeName(entry)
                if len(name) == 0:
                    done = 1
                    break
                try:  # ignore errors for now
                    self.atom_types[name].hydrophylic = 1
                except:
                    pass

        self.bonds = {}
        self._readBondParameters(file)

        self.bond_angles = {}
        self._readAngleParameters(file)

        self.dihedrals = {}
        self.dihedrals_2 = {}
        self._readDihedralParameters(file)

        self.impropers = {}
        self.impropers_1 = {}
        self.impropers_2 = {}
        self._readImproperParameters(file)

        self.hbonds = {}
        self._readHbondParameters(file)

        self.lj_equivalent = {}
        format = FortranFormat('20(A2,2X)')
        while 1:
            l = FortranLine(file.readline()[:-1], format)
            if l.isBlank(): break
            name1 = _normalizeName(l[0])
            for s in l[1:]:
                name2 = _normalizeName(s)
                self.lj_equivalent[name2] = name1

        self.ljpar_sets = {}
        while 1:
            l = FortranLine(file.readline()[:-1], 'A4,6X,A2')
            if l[0] == 'END ': break
            set_name = _normalizeName(l[0])
            ljpar_set = AmberLJParameterSet(set_name, l[1])
            self.ljpar_sets[set_name] = ljpar_set
            self._readLJParameters(file, ljpar_set)

        file.close()

        for mod, ljname in modifications:
            if isinstance(mod, str):
                file = TextFile(mod)
            else:
                file = mod
            title = file.readline()[:-1]
            blank = file.readline()[:-1]
            while 1:
                keyword = file.readline()
                if not keyword: break
                keyword = string.strip(keyword)[:4]
                if keyword == 'MASS':
                    self._readAtomTypes(file)
                elif keyword == 'BOND':
                    self._readBondParameters(file)
                elif keyword == 'ANGL':
                    self._readAngleParameters(file)
                elif keyword == 'DIHE':
                    self._readDihedralParameters(file)
                elif keyword == 'IMPR':
                    self._readImproperParameters(file)
                elif keyword == 'HBON':
                    self._readHbondParameters(file)
                elif keyword == 'NONB':
                    self._readLJParameters(file, self.ljpar_sets[ljname])