def test_ante_error():
    ethane = pmd.load_file(get_fn("ethane.mol2"), structure=True)
    with temporary_directory() as tmpdir:
        with temporary_cd(tmpdir):
            with pytest.raises(RuntimeError, match=r"Antechamber failed"):
                charges = ante_charges(ethane, "bcc", net_charge=-1)
            assert isfile("ante_errorlog.txt")
Exemple #2
0
def ante_atomtyping(molecule, atype_style):
    """Perform atomtyping by calling antechamber

    Parameters
    ----------
    molecule : parmed.Structure or mbuild.Compound
        Molecular structure to perform atomtyping on
    atype_style : str
        Style of atomtyping. Options include 'gaff', 'gaff2',
        'amber', 'bcc', 'sybyl'.

    Returns
    -------
    typed_molecule : parmed.Structure
        The molecule with antechamber atomtyping applied
    """
    _check_antechamber(ANTECHAMBER)

    # Check valid atomtype name
    supported_atomtypes = ['gaff', 'gaff2', 'amber', 'bcc', 'sybyl' ]
    if atype_style not in supported_atomtypes:
        raise FoyerError( 'Unsupported atomtyping style requested. '
            'Please select from {}'.format(supported_atomtypes))

    # Check for parmed.Structure. Convert from mbuild.Compound if possible
    molecule = _check_structure(molecule)
    # Confirm single connected molecule
    _check_single_molecule(molecule)

    # Get current directory to write any error logs
    workdir = os.getcwd()
    # Work within a temporary directory
    # to clean up after antechamber
    with temporary_directory() as tmpdir:
        with temporary_cd(tmpdir):
            # Save the existing molecule to file
            _write_pdb(molecule,'ante_in.pdb')
            # Call antechamber
            command = ( 'antechamber -i ante_in.pdb -fi pdb '
                         '-o ante_out.mol2 -fo mol2 ' +
                         '-at ' + atype_style + ' ' +
                         '-s 2' )

            proc = Popen(command, stdout=PIPE, stderr=PIPE,
                         universal_newlines=True, shell=True)

            out, err = proc.communicate()

            # Error handling here
            if 'Fatal Error' in err or proc.returncode != 0:
                _antechamber_error(out,err,workdir)

            # Now read in the mol2 file with atomtyping
            typed_molecule = pmd.load_file('ante_out.mol2',structure=True)

    # And return it
    return typed_molecule
Exemple #3
0
def ante_charges(
    molecule, charge_style, net_charge=0.0, multiplicity=1, charge_tol=0.005
):
    """Calculates partial charges by calling antechamber

    Parameters
    ----------
    molecule : parmed.Structure or mbuild.Compound
        Molecular structure to perform atomtyping on
    charge_style : str
        Style of partial charges calculation. Options include
        'bcc', 'gas', and 'mul'. See antechamber documentation
        by running 'antechamber -L' for details.
    net_charge : float, optional, default=0.0
        Net charge of the molecule
    multiplicity : int, optional, default=1
        Spin multiplicity, 2S + 1

    Returns
    -------
    molecule : parmed.Structure
        The molecule with charges applied
    """
    _check_antechamber(ANTECHAMBER)

    # Check valid atomtype name
    supported_chargetypes = ["bcc", "gas", "mul"]
    if charge_style not in supported_chargetypes:
        raise FoyerError(
            "Unsupported charge style requested. "
            "Please select from {}".format(supported_chargetypes)
        )

    # Check for parmed.Structure. Convert from mbuild.Compound if possible
    molecule = _check_structure(molecule)
    # Confirm single connected molecule
    _check_single_molecule(molecule)

    # Get current directory to write any error logs
    workdir = os.getcwd()
    # Work within a temporary directory
    # to clean up after antechamber
    with temporary_directory() as tmpdir:
        with temporary_cd(tmpdir):
            # Save the existing molecule to file
            _write_pdb(molecule, "ante_in.pdb")
            # Call antechamber
            command = (
                "antechamber -i ante_in.pdb -fi pdb "
                "-o ante_out.mol2 -fo mol2 "
                + "-c "
                + charge_style
                + " "
                + "-nc "
                + str(net_charge)
                + " "
                + "-m "
                + str(multiplicity)
                + " "
                + "-s 2"
            )

            proc = Popen(
                command, stdout=PIPE, stderr=PIPE, universal_newlines=True, shell=True
            )

            out, err = proc.communicate()

            # Error handling here
            if "Fatal Error" in err or proc.returncode != 0:
                _antechamber_error(out, err, workdir)

            # Now read in the mol2 file with atomtyping
            charges = pmd.load_file("ante_out.mol2", structure=True)

            charge_list = [atom.charge for atom in charges]
            if abs(net_charge - sum(charge_list)) > charge_tol:
                raise ValueError(
                    "The sum of charges defined by antechamber"
                    " is {}, which differs from the desired net charge"
                    " of {} by a value greater than {}".format(
                        sum(charge_list), net_charge, charge_tol
                    )
                )
            elif abs(net_charge - sum(charge_list)) < charge_tol:
                charge_delta = (net_charge - sum(charge_list)) / len(charge_list)
                for atom in charges:
                    atom.charge += charge_delta

    # Combine charge information with existing molecule structure
    assert len(molecule.atoms) == len(charges.atoms)
    for atom_idx in range(len(molecule.atoms)):
        assert molecule.atoms[atom_idx].element == charges.atoms[atom_idx].element
        molecule.atoms[atom_idx].charge = charges.atoms[atom_idx].charge
    return molecule
Exemple #4
0
def ante_charges(molecule, charge_style, net_charge=0.0,
                           multiplicity=1):
    """Calculates partial charges by calling antechamber

    Parameters
    ----------
    molecule : parmed.Structure or mbuild.Compound
        Molecular structure to perform atomtyping on
    charge_style : str
        Style of partial charges calculation. Options include
        'bcc', 'gas', and 'mul'. See antechamber documentation
        by running 'antechamber -L' for details.
    net_charge : float, optional, default=0.0
        Net charge of the molecule
    multiplicity : int, optional, default=1
        Spin multiplicity, 2S + 1

    Returns
    -------
    molecule : parmed.Structure
        The molecule with charges applied
    """
    _check_antechamber(ANTECHAMBER)

    # Check valid atomtype name
    supported_chargetypes = ['bcc', 'gas', 'mul']
    if charge_style not in supported_chargetypes:
        raise FoyerError( 'Unsupported charge style requested. '
            'Please select from {}'.format(supported_chargetypes))

    # Check for parmed.Structure. Convert from mbuild.Compound if possible
    molecule = _check_structure(molecule)
    # Confirm single connected molecule
    _check_single_molecule(molecule)

    # Get current directory to write any error logs
    workdir = os.getcwd()
    # Work within a temporary directory
    # to clean up after antechamber
    with temporary_directory() as tmpdir:
        with temporary_cd(tmpdir):
            # Save the existing molecule to file
            _write_pdb(molecule,'ante_in.pdb')
            # Call antechamber
            command = ( 'antechamber -i ante_in.pdb -fi pdb '
                         '-o ante_out.mol2 -fo mol2 ' +
                         '-c ' + charge_style + ' ' +
                         '-nc ' + str(net_charge) + ' ' +
                         '-m ' + str(multiplicity) +  ' ' +
                         '-s 2' )

            proc = Popen(command, stdout=PIPE, stderr=PIPE,
                         universal_newlines=True, shell=True)

            out, err = proc.communicate()

            # Error handling here
            if 'Fatal Error' in err or proc.returncode != 0:
                _antechamber_error(out,err,workdir)

            # Now read in the mol2 file with atomtyping
            charges = pmd.load_file('ante_out.mol2',structure=True)

    # Combine charge information with existing molecule structure
    assert len(molecule.atoms) == len(charges.atoms)
    for atom_idx in range(len(molecule.atoms)):
        assert molecule.atoms[atom_idx].element == \
                charges.atoms[atom_idx].element
        molecule.atoms[atom_idx].charge = charges.atoms[atom_idx].charge
    return molecule