Ejemplo n.º 1
0
def test_change_parameters(verbose=False):
    """Test modification of forcefield parameters."""
    from openeye import oechem
    # Load simple OEMol
    ifs = oechem.oemolistream(
        get_data_filename('molecules/AlkEthOH_c100.mol2'))
    mol = oechem.OEMol()
    flavor = oechem.OEIFlavor_Generic_Default | oechem.OEIFlavor_MOL2_Default | oechem.OEIFlavor_MOL2_Forcefield
    ifs.SetFlavor(oechem.OEFormat_MOL2, flavor)
    oechem.OEReadMolecule(ifs, mol)
    oechem.OETriposAtomNames(mol)

    # Load forcefield file
    ffxml = get_data_filename('forcefield/Frosst_AlkEtOH.ffxml')
    ff = ForceField(ffxml)

    from smarty.forcefield import generateTopologyFromOEMol
    topology = generateTopologyFromOEMol(mol)
    # Create initial system
    system = ff.createSystem(topology, [mol], verbose=verbose)
    # Get initial energy before parameter modification
    positions = positions_from_oemol(mol)
    old_energy = get_energy(system, positions)

    # Get params for an angle
    params = ff.getParameter(smirks='[a,A:1]-[#6X4:2]-[a,A:3]')
    # Modify params
    params['k'] = '0.0'
    ff.setParameter(params, smirks='[a,A:1]-[#6X4:2]-[a,A:3]')
    # Write params
    ff.writeFile(tempfile.TemporaryFile(suffix='.ffxml'))
    # Make sure params changed energy! (Test whether they get rebuilt on system creation)
    system = ff.createSystem(topology, [mol], verbose=verbose)
    energy = get_energy(system, positions)
    if verbose:
        print("New energy/old energy:", energy, old_energy)
    if np.abs(energy - old_energy) < 0.1:
        raise Exception("Error: Parameter modification did not change energy.")
Ejemplo n.º 2
0
def test_change_parameters(verbose=False):
    """Test modification of forcefield parameters."""
    from openeye import oechem
    # Load simple OEMol
    ifs = oechem.oemolistream(get_data_filename('molecules/AlkEthOH_c100.mol2'))
    mol = oechem.OEMol()
    flavor = oechem.OEIFlavor_Generic_Default | oechem.OEIFlavor_MOL2_Default | oechem.OEIFlavor_MOL2_Forcefield
    ifs.SetFlavor( oechem.OEFormat_MOL2, flavor)
    oechem.OEReadMolecule(ifs, mol )
    oechem.OETriposAtomNames(mol)

    # Load forcefield file
    ffxml = get_data_filename('forcefield/Frosst_AlkEtOH.ffxml')
    ff = ForceField(ffxml)

    from smarty.forcefield import generateTopologyFromOEMol
    topology = generateTopologyFromOEMol(mol)
    # Create initial system
    system = ff.createSystem(topology, [mol], verbose=verbose)
    # Get initial energy before parameter modification
    positions = positions_from_oemol(mol)
    old_energy=get_energy(system, positions)

    # Get params for an angle
    params = ff.getParameter(smirks='[a,A:1]-[#6X4:2]-[a,A:3]')
    # Modify params
    params['k']='0.0'
    ff.setParameter(params, smirks='[a,A:1]-[#6X4:2]-[a,A:3]')
    # Write params
    ff.writeFile( tempfile.TemporaryFile(suffix='.ffxml') )
    # Make sure params changed energy! (Test whether they get rebuilt on system creation)
    system=ff.createSystem(topology, [mol], verbose=verbose)
    energy=get_energy(system, positions)
    if verbose:
        print("New energy/old energy:", energy, old_energy)
    if np.abs(energy-old_energy)<0.1:
        raise Exception("Error: Parameter modification did not change energy.")
Ejemplo n.º 3
0
def convert_frcmod_to_ffxml( infile, inxml, outxml ):
    """Convert a modified AMBER frcmod (with SMIRKS replacing atom types) to SMIRFF ffxml format by inserting parameters into a template ffxml file.

    Parameters
    ----------
    infile : str
        File name of input SMIRKS-ified frcmod file containing parameters
    inxml : str
        File name of template SMIRFF FFXML file into which to insert these parameters.
    outxml : str
        File name of resulting output SMIRFF FFXML

    Notes:
    -------
    Input XML file will normally be the template of a SMIRFF XML file without any parameters present (but with requisite force types already specified).
    """


    # Obtain sections from target file
    file = open(infile, 'r')
    text = file.readlines()
    file.close()
    sections = {}
    # Section names from frcmod which we will parse
    secnames = ['NONBON', 'BOND', 'ANGL', 'IMPR', 'DIHE']
    # Tags that will be used in the FFXML for these (same order)
    tag = ['Atom', 'Bond', 'Angle', 'Improper', 'Proper']
    # Force names in the FFXML (same order)
    force_section = ['NonbondedForce', 'HarmonicBondForce', 'HarmonicAngleForce', 'PeriodicTorsionForce', 'PeriodicTorsionForce']
    ct = 0
    thissec = None
    # Why is this a while loop and not a for line in text loop?
    while ct < len(text):
        line = text[ct]
        tmp = line.split()

        # Skip lines starting with comment or which are blank
        if line[0]=='#' or len(tmp) < 1:
            ct+=1
            continue

        # Check first entry to see if it's a section name, if so initialize storage
        if tmp[0] in secnames:
            thissec = tmp[0]
            sections[thissec] = []
        # Otherwise store
        else:
            sections[thissec].append(line)

        ct+=1


    # Read template forcefield file
    ff = ForceField(inxml)
    # Use functions to parse sections from target file and add parameters to force field
    param_id_by_section={}
    param_prefix_by_sec = {'NONBON':'n' , 'BOND':'b', 'ANGL':'a', 'DIHE':'t', 'IMPR':'i'}
    for (idx, name) in enumerate(secnames):
        param_id_by_section[name] = 1
        for line in sections[name]:
            # Parse line for parameters
            if name=='NONBON':
                params = _parse_nonbon_line(line)
            elif name=='BOND':
                params = _parse_bond_line(line)
            elif name=='DIHE':
                params = _parse_dihe_line(line)
            elif name=='IMPR':
                params = _parse_impr_line(line)
            elif name=='ANGL':
                params = _parse_angl_line(line)

            # Add parameter ID
            params['id'] = param_prefix_by_sec[name]+str( param_id_by_section[name] )

            smirks = params['smirks']
            #Check smirks is valid for chemical enviroment parsing:
            env = environment.ChemicalEnvironment(smirks)

            # If it's not a torsion, just store in straightforward way
            if not (name=='IMPR' or name=='DIHE'):
                # Check for duplicates first
                if ff.getParameter( smirks, force_type = force_section[idx] ):
                    raise ValueError("Error: parameter for %s is already present in forcefield." % smirks )
                else:
                    ff.addParameter( params, smirks, force_section[idx], tag[idx] )

                # Increment parameter id
                param_id_by_section[name] +=1
            # If it's a torsion, check to see if there are already parameters and
            # if so, add a new term to this torsion
            else:
                # If we have parameters already
                oldparams = ff.getParameter(smirks, force_type=force_section[idx])
                if oldparams:
                    # Find what number to use
                    idnr = 1
                    paramtag = 'k%s' % idnr
                    # This was "while paramtag in params" so it was overwriting k2 etc.
                    while paramtag in oldparams:
                        idnr+=1
                        paramtag = 'k%s' % idnr
                    # Construct new param object with updated numbers
                    for paramtag in ('periodicity1', 'phase1', 'idivf1', 'k1'):
                        if paramtag in params:
                            val = params.pop(paramtag)
                            oldparams[paramtag[:-1]+str(idnr) ] = val
                    # Store
                    ff.setParameter( oldparams, smirks=smirks, force_type=force_section[idx])
                else:
                    # Otherwise, just store new parameters
                    ff.addParameter( params, smirks, force_section[idx], tag[idx])
                    # Increment parameter ID
                    param_id_by_section[name] += 1


    # Write SMIRFF XML file
    ff.writeFile(outxml)

    # Roundtrip to fix formatting (for some reason etree won't format it properly on first write after modification)
    tmp = ForceField(outxml)
    tmp.writeFile(outxml)