def test_valence_state_not_parametrized(): """ Test case in which parameters for a certain valence state of a generally parametrized atom are not available. In our case, it is sulfur having a double bond, i. e. only one binding partner. For this purpose, a fictitious molecule consisting of a central carbon bound to two hydrogen atoms via single bonds and to one sulfur atom via a double bond is created and tested. The expectations are the following: the sulfur's partial charge to be NaN and the carbons's partial charge to be smaller than that of the two hydrogens. """ with pytest.warns(UserWarning): fictitious_molecule = array([carbon, sulfur, hydrogen, hydrogen]) fictitious_molecule.bonds = BondList( fictitious_molecule.array_length(), np.array([[0, 1], [0, 2], [0, 3]])) mol_length = fictitious_molecule.array_length() fictitious_molecule.charge = np.array([0] * mol_length) charges = partial_charges(fictitious_molecule) sulfur_part_charge = charges[1] carb_part_charge = charges[0] hyd_part_charge = charges[2] assert np.isnan(sulfur_part_charge) assert carb_part_charge < hyd_part_charge
def test_pos_formal_charge(): """ Test whether the partial charge of carbon in methane behaves as expected if it carries a formal charge of +1. To be more precise, it is expected to be smaller than 1 since this is the value which negative charge is addded to during iteration and also greater than the partial charge of carbon in methane carrying no formal charge. """ pos_methane = methane.copy() pos_methane.charge = np.array([1, 0, 0, 0, 0]) ref_carb_part_charge = partial_charges(methane, iteration_step_num=6)[0] pos_carb_part_charge = partial_charges(pos_methane, iteration_step_num=6)[0] assert pos_carb_part_charge < 1 assert pos_carb_part_charge > ref_carb_part_charge
def test_correct_output_ions(): """ Ions such as sodium or potassium are not parametrized. However, their formal charge is taken as partial charge since they are not involved in covalent bonding. Hence, it is expected that no warning is raised. The test is performed with a sodium ion. """ sodium = Atom([0, 0, 0], element="NA") sodium_array = array([sodium]) # Sodium possesses a formal charge of +1 sodium_array.charge = np.array([1]) # Sodium is not involved in covalent bonding sodium_array.bonds = BondList(sodium_array.array_length()) with pytest.warns(None) as record: partial_charges(sodium_array, iteration_step_num=1) assert len(record) == 0
def test_total_charge_zero(molecule): """ In the case of the 17 molecules given in table 3, it is verified whether the sum of all partial charges equals the sum of all formal charges (in our case zero since we are exclusively dealing with uncharged molecules). """ total_charge = np.sum(partial_charges(molecule)) assert total_charge == pytest.approx(0, abs=1e-15)
def test_partial_charges(molecule, expected_results): """ Test whether the partial charges of the carbon atoms comprised in the molecules given in table 3 of the publication computed in this implementation correspond to the values given in the publication within a certain tolerance range. """ charges = partial_charges(molecule) assert charges[molecule.element == "C"].tolist() == \ pytest.approx(expected_results, abs=1e-2)
# Get an atom array for the selected molecule molecule = info.residue(MOLECULE_NAME) # Align molecule with principal component analysis: # The component with the least variance, i.e. the axis with the lowest # number of atoms lying over each other, is aligned to the z-axis, # which points into the plane of the figure pca = PCA(n_components=3) pca.fit(molecule.coord) molecule = struc.align_vectors(molecule, pca.components_[-1], [0, 0, 1]) # Balls should be colored by partial charge charges = struc.partial_charges(molecule, ITERATION_NUMBER) # Later this variable stores values between 0 and 1 for use in color map normalized_charges = charges.copy() # Show no partial charge for atoms # that are not parametrized for the PEOE algorithm normalized_charges[np.isnan(normalized_charges)] = 0 # Norm charge values to highest absolute value max_charge = np.max(np.abs(normalized_charges)) normalized_charges /= max_charge # Transform range (-1, 1) to range (0, 1) normalized_charges = (normalized_charges + 1) / 2 # Calculate colors color_map = plt.get_cmap(CMAP_NAME) colors = color_map(normalized_charges) # Ball size should be proportional to VdW radius of the respective atom