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")
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
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
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