Beispiel #1
0
def LookupChargePairs(chargebyatomid,
                      # bond_ids,
                      # bond_types,
                      # bond_pairs,
                      lines_atoms,
                      lines_bonds,
                      lines_bond_list,
                      lines_chargebybond,
                      atom_style,
                      section_name,
                      prefix='',
                      suffix=''):
                      # bond_ids_offset=0):
                      # report_progress = False):
    """
    LookupChargePairs() looks up partial-charge pair contributions from the
    types of atoms participating in a bond.

    Output:
    ...It looks up the corresponding change in the partial charges for
       each pair of atoms and stores this in the "chargebyatomid" dictionary.

    Input (continued):
       This function requires:
    ...a list of bonded pairs of atoms
        stored in the lines_bonds variable (from the "Data Bond List"
                                       or "Data Bonds AtomId AtomId" sections)
    ...and a list of atom types
        stored in the lines_atoms variable (from the "Data Atoms" section)

    ...and a list of charge-pairs-as-a-function-of-atom-types
        stored in the lines_chargebybond (from the "Data Bonds By Type" section)

    """

    column_names = AtomStyle2ColNames(atom_style)
    i_atomid, i_atomtype, i_molid = ColNames2AidAtypeMolid(column_names)

    atomids = []
    atomtypes = []
    atomids2types = {}

    for iv in range(0, len(lines_atoms)):
        line = lines_atoms[iv].strip()
        if '#' in line:
            icomment = line.find('#')
            line = (line[:icomment]).strip()
        if len(line) > 0:
            tokens = ttree_lex.SplitQuotedString(line)
            if ((len(tokens) <= i_atomid) or (len(tokens) <= i_atomtype)):
                sys.stderr.write("\"" + line + "\"\n")
                raise(ttree_lex.InputError(
                    'Error not enough columns on line ' + str(iv + 1) + ' of \"Atoms\" section.'))
            tokens = ttree_lex.SplitQuotedString(line)
            atomid = ttree_lex.EscCharStrToChar(tokens[i_atomid])
            atomids.append(atomid)
            atomtype = ttree_lex.EscCharStrToChar(tokens[i_atomtype])
            atomtypes.append(atomtype)
            atomids2types[atomid] = atomtype

    #assert(isinstance(bond_ids, list))
    #assert(isinstance(bond_types, list))
    #assert(isinstance(bond_pairs, list))
    #del bond_ids[:]
    #del bond_types[:]
    #del bond_pairs[:]
    bond_pairs = []

    for ie in range(0, len(lines_bond_list)):
        line = lines_bond_list[ie].strip()
        if '#' in line:
            icomment = line.find('#')
            line = (line[:icomment]).strip()
        if len(line) == 0:
            continue
        tokens = ttree_lex.SplitQuotedString(line)
        if len(tokens) == 3:
            # bond_ids.append(ttree_lex.EscCharStrToChar(tokens[0]))
            bond_pairs.append((ttree_lex.EscCharStrToChar(tokens[1]),
                               ttree_lex.EscCharStrToChar(tokens[2])))
        else:
            raise(ttree_lex.InputError('Incorrect number of columns on line ' +
                                       str(ie + 1) + ' of \"' + section_name + '\" section.'))

    for ie in range(0, len(lines_bonds)):
        line = lines_bonds[ie].strip()
        if '#' in line:
            icomment = line.find('#')
            line = (line[:icomment]).strip()
        if len(line) == 0:
            continue
        tokens = ttree_lex.SplitQuotedString(line)
        if len(tokens) == 4:
            # bond_ids.append(ttree_lex.EscCharStrToChar(tokens[0]))
            # bond_types.append(ttree_lex.EscCharStrToChar(tokens[1]))
            bond_pairs.append((ttree_lex.EscCharStrToChar(tokens[2]),
                               ttree_lex.EscCharStrToChar(tokens[3])))
        else:
            raise(ttree_lex.InputError('Incorrect number of columns on line ' +
                                       str(ie + 1) + ' of \"' + section_name + '\" section.'))

    # for ie in range(0, len(lines_bonds_atomid_atomid)):
    #    line = lines_bonds_atomid_atomid[ie].strip()
    #    if '#' in line:
    #        icomment = line.find('#')
    #        line = (line[:icomment]).strip()
    #    if len(line) == 0:
    #        continue
    #    tokens = ttree_lex.SplitQuotedString(line)
    #    if len(tokens) == 2:
    #        #bondid_n = bond_ids_offset + len(bond_ids) + 1
    #        #bond_ids.append(prefix+str(bondid_n)+suffix)
    #        bond_pairs.append( (ttree_lex.EscCharStrToChar(tokens[0]),
    #                            ttree_lex.EscCharStrToChar(tokens[1])) )
    #    else:
    #        raise(ttree_lex.InputError('Incorrect number of columns on line '+str(ie+1)+' of \"'+section_name+'\" section.'))

    #assert(len(bond_types) == 0)
    typepattern_to_chargepairs = []
    warning_unassigned_chargepairs = None

    for i in range(0, len(lines_chargebybond)):
        line = lines_chargebybond[i].strip()
        if '#' in line:
            icomment = line.find('#')
            line = (line[:icomment]).strip()
        if len(line) > 0:
            tokens = ttree_lex.SplitQuotedString(line)

            if (len(tokens) != 4):
                raise(ttree_lex.InputError('Error: Wrong number of columns in the \"Charge Pairs By Type\" section of data file.\n'
                                           'Offending line:\n' +
                                           '\"' + line + '\"\n'
                                           'Expected 4 columns\n'))

            chargepair = (float(tokens[2]),
                          float(tokens[3]))

            typepattern = []

            for typestr in tokens[:2]:
                if ttree_lex.HasRE(typestr):
                    regex_str = typestr[3:]
                    typepattern.append(re.compile(regex_str))
                else:
                    typepattern.append(ttree_lex.EscCharStrToChar(typestr))

            typepattern_to_chargepairs.append([typepattern, chargepair])

    for atomid1, atomid2 in bond_pairs:

        if atomid1 not in atomids2types:
            raise ttree_lex.InputError('Error: atom \"' + atomid1 + '\" not defined in \"Data Atoms\".\n'
                                       '       This usually happens when the user mistypes one of the names of the\n'
                                       '       $atoms in either a \"Data Atoms\" or \"Data Bond List\" section.\n'
                                       '       To find out where the mistake occured, search the \n'
                                       '       \"ttree_assignments.txt\" file for:\n'
                                       '       \"' + atomid1 + '\"\n')

        if atomid2 not in atomids2types:
            raise ttree_lex.InputError('Error: atom \"' + atomid2 + '\" not defined in \"Data Atoms\".\n'
                                       '       This usually happens when the user mistypes one of the names of the\n'
                                       '       $atoms in either a \"Data Atoms\" or \"Data Bond List\" section.\n'
                                       '       To find out where the mistake occured, search the \n'
                                       '       \"ttree_assignments.txt\" file for:\n'
                                       '       \"' + atomid2 + '\"\n')

        atomtype1 = atomids2types[atomid1]
        atomtype2 = atomids2types[atomid2]

        found = False
        for typepattern, chargepair in typepattern_to_chargepairs:
            # use string comparisons to check if atom types match the pattern
            if ttree_lex.MatchesAll((atomtype1, atomtype2), typepattern):
                # ("MatchesAll()" defined in "ttree_lex.py")
                chargebyatomid[atomid1] += chargepair[0]
                chargebyatomid[atomid2] += chargepair[1]
                found = True
            elif ttree_lex.MatchesAll((atomtype2, atomtype1), typepattern):
                chargebyatomid[atomid1] += chargepair[1]
                chargebyatomid[atomid2] += chargepair[0]
                found = True
        if (not found) and (not warning_unassigned_chargepairs):
            warning_unassigned_chargepairs = (atomid1, atomid2)

    if warning_unassigned_chargepairs:
        sys.stderr.write('---------------------------------------------------------------------------\n'
                         'Warning: bonds found between atoms with no partial-charge rules.\n'
                         '         This means that somewhere you are using a force-field\n'
                         '         which assigns atomic charge according to the bonds these atoms\n'
                         '         participate in, AND at least one pair of bonded atoms does NOT have\n'
                         '         a rule defined to assign charges to that pair of atoms.\n'
                         '         This can happen if there is a problem with the force-field file\n'
                         '         OR if you are defining the charges for these atoms manually\n'
                         '         In the later case, it is not a problem.\n'
                         '         The first bond with this problem is between this pair of atoms:\n'
                         '            ' +
                         str(warning_unassigned_chargepairs[0]) + '\n'
                         '            ' +
                         str(warning_unassigned_chargepairs[1]) + '\n'
                         '---------------------------------------------------------------------------\n')
Beispiel #2
0
def LookupBondTypes(bond_types,
                    bond_ids,
                    bond_pairs,
                    lines_atoms,
                    lines_bonds,
                    lines_bondsbytype,
                    atom_style,
                    section_name,
                    prefix='',
                    suffix='',
                    bond_ids_offset=0):
                    #report_progress = False):
    """
    LookupBondTypes() looks up bond types.

    Output:
    ...It looks up the corresponding type of each bond and store it in the 
       "bond_types" list.  (If the bond_ids were not specified by the user, 
       generate them and store them in the bond_ids list.)


    Input (continued):
       This function requires:
    ...a list of bonded pairs of atoms
        stored in the lines_bonds variable (from the "Data Bond List"
                                       or "Data Bonds AtomId AtomId" sections)
    ...and a list of atom types
        stored in the lines_atoms variable (from the "Data Atoms" section)
    ...and a list of bond-types-as-a-function-of-atom-types
        stored in the lines_bondsbytype (from the "Data Bonds By Type" section)

    Generated bond_ids (if applicable) are of the form 
      prefix + str(number) + suffix
        (where "number" begins at bond_ids_offset+1)

    """

    column_names = AtomStyle2ColNames(atom_style)
    i_atomid, i_atomtype, i_molid = ColNames2AidAtypeMolid(column_names)

    atomids = []
    atomtypes = []
    atomids2types = {}

    for iv in range(0, len(lines_atoms)):
        line = lines_atoms[iv].strip()
        if '#' in line:
            icomment = line.find('#')
            line = (line[:icomment]).strip()
        if len(line) > 0:
            tokens = ttree_lex.SplitQuotedString(line)
            if ((len(tokens) <= i_atomid) or (len(tokens) <= i_atomtype)):
                sys.stderr.write("\""+line+"\"\n")
                raise(ttree_lex.InputError('Error not enough columns on line '+str(iv+1)+' of \"Atoms\" section.'))
            tokens = ttree_lex.SplitQuotedString(line)
            atomid = ttree_lex.EscCharStrToChar(tokens[i_atomid])
            atomids.append(atomid)
            atomtype = ttree_lex.EscCharStrToChar(tokens[i_atomtype])
            atomtypes.append(atomtype)
            atomids2types[atomid] = atomtype


    assert(isinstance(bond_ids, list))
    assert(isinstance(bond_types, list))
    assert(isinstance(bond_pairs, list))
    del bond_ids[:]
    del bond_types[:]
    del bond_pairs[:]

    for ie in range(0, len(lines_bonds)):

        line = lines_bonds[ie].strip()
        if '#' in line:
            icomment = line.find('#')
            line = (line[:icomment]).strip()

        if len(line) == 0:
            continue

        tokens = ttree_lex.SplitQuotedString(line)

        if section_name == "Data Bonds AtomId AtomId":
            if len(tokens) == 2:
                bondid_n = bond_ids_offset + len(bond_ids) + 1
                bond_ids.append(prefix+str(bondid_n)+suffix)
                bond_pairs.append( (ttree_lex.EscCharStrToChar(tokens[0]),
                                    ttree_lex.EscCharStrToChar(tokens[1])) )
            else:
                raise(ttree_lex.InputError('Incorrect number of columns on line '+str(ie+1)+' of \"'+section_name+'\" section.'))

        elif section_name == "Data Bond List":
            if len(tokens) == 3:
                bond_ids.append(ttree_lex.EscCharStrToChar(tokens[0]))
                bond_pairs.append( (ttree_lex.EscCharStrToChar(tokens[1]),
                                    ttree_lex.EscCharStrToChar(tokens[2])) )
            else:
                raise(ttree_lex.InputError('Incorrect number of columns on line '+str(ie+1)+' of \"'+section_name+'\" section.'))

        else:
            raise(ttree_lex.InputError('Internal Error ('+g_program_name+'): Unknown section name: \"'+section_name+'\"'))


    assert(len(bond_types) == 0)
    typepattern_to_coefftypes = []

    for i in range(0, len(lines_bondsbytype)):
        line = lines_bondsbytype[i].strip()
        if '#' in line:
            icomment = line.find('#')
            line = (line[:icomment]).strip()
        if len(line) > 0:
            tokens = ttree_lex.SplitQuotedString(line)

            if (len(tokens) != 3):
                raise(ttree_lex.InputError('Error: Wrong number of columns in the \"Bonds By Type\" section of data file.\n'
                                 'Offending line:\n'+
                                 '\"'+line+'\"\n'
                                 'Expected 3 columns\n'))

            coefftype = ttree_lex.EscCharStrToChar(tokens[0])
            typepattern = []

            for typestr in tokens[1:]:
                if ((len(typestr) >= 2) and 
                    (typestr[0] == '/') and (typestr[-1] == '/')):
                    regex_str = typestr[1:-1]
                    typepattern.append( re.compile(regex_str) )
                else:
                    typepattern.append(ttree_lex.EscCharStrToChar(typestr))

            typepattern_to_coefftypes.append([typepattern, coefftype])
            


    assert(len(bond_ids) == len(bond_pairs))

    for ie in range(0,len(bond_ids)):
        bond_types.append(None)

    for ie in range(0, len(bond_ids)):
        bondid = bond_ids[ie]
        (atomid1, atomid2) = bond_pairs[ie]

        if atomid1 not in atomids2types:
            raise ttree_lex.InputError('Error: atom \"'+atomid1+'\" not defined in \"Data Atoms\".\n'
                                       '       This usually happens when the user mistypes one of the names of the\n'
                                       '       $atoms in either a \"Data Atoms\" or \"Data Bond List\" section.\n'
                                       '       To find out where the mistake occured, search the \n'
                                       '       \"ttree_assignments.txt\" file for:\n'
                                       '       \"'+atomid1+'\"\n')

        if atomid2 not in atomids2types:
            raise ttree_lex.InputError('Error: atom \"'+atomid2+'\" not defined in \"Data Atoms\".\n'
                                       '       This usually happens when the user mistypes one of the names of the\n'
                                       '       $atoms in either a \"Data Atoms\" or \"Data Bond List\" section.\n'
                                       '       To find out where the mistake occured, search the \n'
                                       '       \"ttree_assignments.txt\" file for:\n'
                                       '       \"'+atomid2+'\"\n')

        atomtype1 = atomids2types[atomid1]
        atomtype2 = atomids2types[atomid2]

        for typepattern, coefftype in typepattern_to_coefftypes:

            # use string comparisons to check if atom types match the pattern
            if (ttree_lex.MatchesAll((atomtype1, atomtype2), typepattern) or
                ttree_lex.MatchesAll((atomtype2, atomtype1), typepattern)):
                # ("MatchesAll()" defined in "ttree_lex.py")

                bond_types[ie] = coefftype

    for ie in range(0, len(bond_ids)):
        if not bond_types[ie]:
            (atomid1, atomid2) = bond_pairs[ie]
            atomtype1 = atomids2types[atomid1]
            atomtype2 = atomids2types[atomid2]
            raise ttree_lex.InputError('Error: No bond types defined for the bond between\n'
                              '       atoms '+atomid1+' (type '+atomtype1+')\n'
                              '         and '+atomid2+' (type '+atomtype2+')\n')