From 688bab6f5f7737be110333b7b75bb478a5e66fa1 Mon Sep 17 00:00:00 2001 From: David Beyer <57479570+davidbbeyer@users.noreply.github.com> Date: Tue, 16 Apr 2024 18:29:42 +0200 Subject: [PATCH] Add test for cpH and G-RxMC (ideal). (#33) * Add test of G-RxMC (ideal). * Adjust G-RxMC test * Add test on cpH * add test mode to speed up CI tests, get rid of numpy warnings, clean up sample scripts, change order of the CI tests * Remove plot option from samples * CI check --------- Co-authored-by: Pablo M. Blanco --- Makefile | 7 +- pyMBE.py | 5 +- samples/branched_polyampholyte.py | 117 +++++++++++++------ samples/peptide.py | 4 +- samples/peptide_mixture_grxmc_ideal.py | 149 ++++++++++++++----------- testsuite/cph_ideal_tests.py | 26 +++++ testsuite/grxmc_ideal_tests.py | 41 +++++++ testsuite/lj_tests.py | 20 ++-- 8 files changed, 253 insertions(+), 116 deletions(-) create mode 100644 testsuite/cph_ideal_tests.py create mode 100644 testsuite/grxmc_ideal_tests.py diff --git a/Makefile b/Makefile index d96f261..7f41fcd 100644 --- a/Makefile +++ b/Makefile @@ -8,15 +8,14 @@ docs: pdoc ./pyMBE.py -o ./documentation --docformat google tests: - python3 testsuite/henderson_hasselbalch_tests.py python3 testsuite/lj_tests.py python3 testsuite/generate_perpendicular_vectors_test.py python3 testsuite/read-write-df_test.py + python3 testsuite/henderson_hasselbalch_tests.py + python3 testsuite/cph_ideal_tests.py + python3 testsuite/grxmc_ideal_tests.py python3 testsuite/peptide_tests.py -sample: - python3 sample_scripts/peptide_simulation_example.py - visual: python3 handy_scripts/vmd-traj.py vmd -e visualization.tcl diff --git a/pyMBE.py b/pyMBE.py index 7ac1c7a..79f4d4c 100644 --- a/pyMBE.py +++ b/pyMBE.py @@ -486,7 +486,10 @@ def check_if_df_cell_has_a_value(self, index,key): `bool`: `True` if the cell has a value, `False` otherwise. """ idx = self.pd.IndexSlice - return not self.pd.isna(self.df.loc[index, idx[key]]) + import warnings + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + return not self.pd.isna(self.df.loc[index, idx[key]]) def check_if_name_is_defined_in_df(self, name, pmb_type_to_be_defined): """ diff --git a/samples/branched_polyampholyte.py b/samples/branched_polyampholyte.py index 58de10c..e1c0b43 100644 --- a/samples/branched_polyampholyte.py +++ b/samples/branched_polyampholyte.py @@ -1,4 +1,4 @@ -# Load espresso, sugar and other necessary libraries +# Load espresso, pyMBE and other necessary libraries import sys import os import inspect @@ -6,15 +6,25 @@ import espressomd import numpy as np import matplotlib.pyplot as plt -from tqdm import tqdm +import argparse +import pandas as pd from espressomd.io.writer import vtf from espressomd import interactions - +import pyMBE # Create an instance of pyMBE library -import pyMBE + pmb = pyMBE.pymbe_library() +# Command line arguments +parser = argparse.ArgumentParser(description='Script that runs a Monte Carlo simulation of an ideal branched polyampholyte using pyMBE and ESPResSo.') +parser.add_argument('--test', + default=False, + action='store_true', + help='to run a short simulation for testing the script') +args = parser.parse_args() + + # Load some functions from the handy_scripts library for convinience from lib.handy_functions import setup_langevin_dynamics from lib.analysis import block_analyze @@ -26,14 +36,24 @@ # Simulation parameters pmb.set_reduced_units(unit_length=0.4*pmb.units.nm) pH_range = np.linspace(2, 12, num=20) -Samples_per_pH = 100 -MD_steps_per_sample = 0 +Samples_per_pH = 1000 +MD_steps_per_sample = 1000 steps_eq = int(Samples_per_pH/3) N_samples_print = 10 # Write the trajectory every 100 samples probability_reaction =0.5 SEED = 100 dt = 0.001 solvent_permitivity = 78.3 +N_polyampholyte_chains = 5 +polyampholyte_concentration = 5.56e-4 *pmb.units.mol/pmb.units.L +volume = N_polyampholyte_chains/(pmb.N_A*polyampholyte_concentration) + +if args.test: + Samples_per_pH = 100 + probability_reaction = 1 + N_samples_print = 1000 + N_polyampholyte_chains = 1 + pH_range = np.linspace(2, 12, num=10) # Define different particles # Inert particle @@ -96,9 +116,7 @@ pmb.define_particle(name=anion_name, q=-1, sigma=0.35*pmb.units.nm, epsilon=1*pmb.units('reduced_energy')) # System parameters -N_polyampholyte_chains = 5 -polyampholyte_concentration = 5.56e-4 *pmb.units.mol/pmb.units.L -volume = N_polyampholyte_chains/(pmb.N_A*polyampholyte_concentration) + L = volume ** (1./3.) # Side of the simulation box calculated_polyampholyte_concentration = N_polyampholyte_chains/(volume*pmb.N_A) @@ -121,8 +139,8 @@ total_ionisible_groups = len (list_ionisible_groups) print("The box length of your system is", L.to('reduced_length'), L.to('nm')) -print('The polyampholyte concentration in your system is ', calculated_polyampholyte_concentration.to('mol/L') , 'with', N_polyampholyte_chains, 'peptides') -print('The ionisable groups in your peptide are ', list_ionisible_groups) +print('The polyampholyte concentration in your system is ', calculated_polyampholyte_concentration.to('mol/L') , 'with', N_polyampholyte_chains, 'molecules') +print('The ionisable groups in your polyampholyte are ', list_ionisible_groups) RE, sucessfull_reactions_labels = pmb.setup_cpH(counter_ion=cation_name, constant_pH=2, SEED=SEED) print('The acid-base reaction has been sucessfully setup for ', sucessfull_reactions_labels) @@ -148,17 +166,24 @@ N_frame=0 Z_pH=[] # List of the average global charge at each pH +err_Z_pH=[] # List of the error of the global charge at each pH + #Save the pyMBE dataframe in a CSV file pmb.write_pmb_df (filename='df.csv') # Main loop for performing simulations at different pH-values +labels_obs=["time","charge"] -for index in tqdm(range(len(pH_range))): +for index in range(len(pH_range)): pH_value=pH_range[index] - # Sample list inicialization - Z_sim=[] + + time_series={} + + for label in labels_obs: + time_series[label]=[] + RE.constant_pH = pH_value # Inner loop for sampling each pH value @@ -174,7 +199,11 @@ # Get polyampholyte net charge charge_dict=pmb.calculate_net_charge(espresso_system=espresso_system, molecule_name="polyampholyte") - Z_sim.append(charge_dict["mean"]) + if args.test: + time_series["time"].append(step) + else: + time_series["time"].append(espresso_system.time) + time_series["charge"].append(charge_dict["mean"]) if (step % N_samples_print == 0) : N_frame+=1 @@ -182,28 +211,42 @@ vtf.writevsf(espresso_system, coordinates) vtf.writevcf(espresso_system, coordinates) - Z_pH.append(Z_sim) + # Estimate the statistical error and the autocorrelation time of the data + processed_data = block_analyze(full_data=pd.DataFrame(time_series, columns=labels_obs)) + Z_pH.append(processed_data["mean", "charge"]) + err_Z_pH.append(processed_data["err_mean", "charge"]) print("pH = {:6.4g} done".format(pH_value)) -# Estimate the statistical error and the autocorrelation time of the data - -print("Net charge analysis") -av_net_charge, err_net_charge, tau_net_charge, block_size_net_charge = block_analyze(input_data=Z_pH) - -# Calculate the ideal titration curve of the polyampholyte with Henderson-Hasselbach equation (manually) -pH_range_HH = np.linspace(2, 12, num=1000) -Z_HH_manually = [10 * (1/(1+10**(pH_value-9)) - 1/(1+10**(4-pH_value))) for pH_value in pH_range_HH] - -# Calculate the ideal titration curve of the polyampholyte with Henderson-Hasselbach equation (pyMBE) -Z_HH = pmb.calculate_HH(molecule_name="polyampholyte", - pH_list=pH_range_HH) - -fig, ax = plt.subplots(figsize=(10, 7)) -plt.errorbar(pH_range, av_net_charge, yerr=err_net_charge, fmt = 'o', capsize=3, label='Simulation') -plt.plot(pH_range_HH, Z_HH_manually, label="Henderson-Hasselbalch (manually)") -ax.plot(pH_range_HH, Z_HH, "-k", label='Henderson-Hasselbach (pyMBE)', linestyle="dashed") -plt.legend() -plt.xlabel('pH') -plt.ylabel('Charge of the polyampholyte / e') -plt.show() +if args.test: + # Calculate the ideal titration curve of the polyampholyte with Henderson-Hasselbach equation (pyMBE) + Z_HH = pmb.calculate_HH(molecule_name="polyampholyte", + pH_list=pH_range) + + # Write out the data + data = {} + data["Z_sim"] = np.asarray(Z_pH) + data["Z_HH"] = np.asarray(Z_HH) + data = pd.DataFrame.from_dict(data) + + data_path = pmb.get_resource(path="samples") + data.to_csv(f"{data_path}/data_polyampholyte_cph.csv", index=False) + +else: + # Calculate the ideal titration curve of the polyampholyte with Henderson-Hasselbach equation (manually) + pH_range_HH = np.linspace(2, 12, num=1000) + Z_HH_manually = [10 * (1/(1+10**(pH_value-9)) - 1/(1+10**(4-pH_value))) for pH_value in pH_range_HH] + + # Calculate the ideal titration curve of the polyampholyte with Henderson-Hasselbach equation (pyMBE) + Z_HH = pmb.calculate_HH(molecule_name="polyampholyte", + pH_list=pH_range_HH) + + fig, ax = plt.subplots(figsize=(10, 7)) + plt.errorbar(pH_range, Z_pH, yerr=err_Z_pH, fmt = 'o', capsize=3, label='Simulation') + plt.plot(pH_range_HH, Z_HH_manually, label="Henderson-Hasselbalch (manually)") + ax.plot(pH_range_HH, Z_HH, "-k", label='Henderson-Hasselbach (pyMBE)') + plt.legend() + plt.xlabel('pH') + plt.ylabel('Charge of the polyampholyte / e') + + plt.show() diff --git a/samples/peptide.py b/samples/peptide.py index 1b5864c..4bda9d4 100644 --- a/samples/peptide.py +++ b/samples/peptide.py @@ -1,4 +1,4 @@ -# Load espresso, sugar and other necessary libraries +# Load espresso, pyMBE and other necessary libraries import sys import os import inspect @@ -10,9 +10,9 @@ from espressomd.io.writer import vtf from espressomd import interactions from espressomd import electrostatics +import pyMBE # Create an instance of pyMBE library -import pyMBE pmb = pyMBE.pymbe_library() # Load some functions from the handy_scripts library for convinience diff --git a/samples/peptide_mixture_grxmc_ideal.py b/samples/peptide_mixture_grxmc_ideal.py index 573ca38..dd1b6c4 100644 --- a/samples/peptide_mixture_grxmc_ideal.py +++ b/samples/peptide_mixture_grxmc_ideal.py @@ -1,4 +1,4 @@ -#Load espresso, sugar and other necessary libraries +#Load espresso, pyMBE and other necessary libraries import sys import os import inspect @@ -8,15 +8,18 @@ import matplotlib.pyplot as plt import pandas as pd import argparse -from tqdm import tqdm from espressomd.io.writer import vtf from espressomd import interactions from espressomd import electrostatics +import pyMBE # Create an instance of pyMBE library -import pyMBE pmb = pyMBE.pymbe_library() +import warnings + + + # Command line arguments valid_modes=["standard", "unified"] @@ -24,10 +27,16 @@ parser.add_argument('--mode', type=str, default= "standard", - help='set if the grand-reaction method is used with unified ions or not, valid modes are {valid_modes}') -args = parser.parse_args() + help='Set if the grand-reaction method is used with unified ions or not, valid modes are {valid_modes}') +parser.add_argument('--test', + default=False, + action='store_true', + help='to run a short simulation for testing the script') +args = parser.parse_args() +if args.mode not in valid_modes: + raise ValueError(f"Mode {mode} is not currently supported, valid modes are {valid_modes}") # The trajectories of the simulations will be stored using espresso built-up functions in separed files in the folder 'frames' if not os.path.exists('./frames'): @@ -50,45 +59,37 @@ solvent_permitivity = 78.3 # Peptide parameters -sequence1 = 'nGEGHc' +sequence1 = 'nEHc' model = '1beadAA' # Model with 2 beads per each aminoacid pep1_concentration = 1e-2 *pmb.units.mol/pmb.units.L N_peptide1_chains = 10 -sequence2 = 'nGEEHHc' +sequence2 = 'nEEHHc' pep2_concentration = 1e-2 *pmb.units.mol/pmb.units.L N_peptide2_chains = 10 +if args.test: + Samples_per_pH = 1000 + probability_reaction = 1 + N_samples_print = 1000 + N_peptide1_chains = 5 + N_peptide2_chains = 5 + pH_range = np.linspace(2, 12, num=10) + + # Load peptide parametrization from Lunkad, R. et al. Molecular Systems Design & Engineering (2021), 6(2), 122-131. -path_to_interactions=pmb.get_resource("parameters/peptides/Lunkad2021.txt") +# Note that this parameterization only includes some of the natural aminoacids +# For the other aminoacids the user needs to use a parametrization including all the aminoacids in the peptide sequence path_to_pka=pmb.get_resource("parameters/pka_sets/Hass2015.txt") +path_to_interactions=pmb.get_resource("parameters/peptides/Lunkad2021.txt") + + + + pmb.load_interaction_parameters(filename=path_to_interactions) -pmb.load_pka_set(path_to_pka) - -# Use a generic parametrization for the aminoacids not parametrized -not_parametrized_neutral_aminoacids = ['A','N','Q','G','I','L','M','F','P','O','S','U','T','W','V','J'] -not_parametrized_acidic_aminoacids = ['C','c'] -not_parametrized_basic_aminoacids = ['R','n'] - -already_defined_AA=[] - -for aminoacid_key in sequence1+sequence2: - if aminoacid_key in already_defined_AA: - continue - if aminoacid_key in not_parametrized_acidic_aminoacids: - pmb.define_particle(name=aminoacid_key, - acidity='acidic', - sigma=0.35*pmb.units.nm, - epsilon=1*pmb.units('reduced_energy')) - elif aminoacid_key in not_parametrized_basic_aminoacids: - pmb.define_particle(name=aminoacid_key, acidity='basic',sigma=0.35*pmb.units.nm,epsilon=1*pmb.units('reduced_energy')) - - elif aminoacid_key in not_parametrized_neutral_aminoacids: - pmb.define_particle(name=aminoacid_key, - q=0, - sigma=0.35*pmb.units.nm, - epsilon=1*pmb.units('reduced_energy')) - already_defined_AA.append(aminoacid_key) +with warnings.catch_warnings(): + warnings.simplefilter('error') + pmb.load_pka_set(path_to_pka) generic_bond_lenght=0.4 * pmb.units.nm generic_harmonic_constant = 400 * pmb.units('reduced_energy / reduced_length**2') @@ -180,9 +181,6 @@ RE.set_non_interacting_type (type=non_interacting_type) print('The non interacting type is set to ', non_interacting_type) -# Minimize the system energy to avoid huge starting force due to random inicialization of the system -minimize_espresso_system_energy (espresso_system=espresso_system) - espresso_system.time_step = dt #Save the initial state @@ -209,7 +207,7 @@ # Main loop for performing simulations at different pH-values labels_obs=["time","charge","num_plus"] -for index in tqdm(range(len(pH_range))): +for index in range(len(pH_range)): pH_value=pH_range[index] @@ -238,7 +236,10 @@ for pid in particle_id_list: z_one_object +=espresso_system.part.by_id(pid).q - time_series["time"].append(espresso_system.time) + if args.test: + time_series["time"].append(step) + else: + time_series["time"].append(espresso_system.time) time_series["charge"].append(np.mean((z_one_object))) if args.mode == 'standard': @@ -253,38 +254,56 @@ vtf.writevcf(espresso_system, coordinates) # Estimate the statistical error and the autocorrelation time of the data - print("Net charge analysis") processed_data = block_analyze(full_data=pd.DataFrame(time_series, columns=labels_obs)) Z_pH.append(processed_data["mean", "charge"]) err_Z_pH.append(processed_data["err_mean", "charge"]) concentration_plus = (processed_data["mean", "num_plus"]/(pmb.N_A * L**3)).to('mol/L') err_concentration_plus = (processed_data["err_mean", "num_plus"]/(pmb.N_A * L**3)).to('mol/L') - xi_plus.append(concentration_plus/ionic_strength_res) + xi_plus.append((concentration_plus/ionic_strength_res).magnitude) err_xi_plus.append(err_concentration_plus/ionic_strength_res) print("pH = {:6.4g} done".format(pH_value)) -# Calculate the ideal titration curve of the peptide with Henderson-Hasselbach equation -pH_range_HH = np.linspace(2, 12, num=100) -HH_charge_dict = pmb.calculate_HH_Donnan(c_macro={peptide1: pep1_concentration, peptide2: pep2_concentration}, c_salt=c_salt, pH_list=pH_range_HH) -Z_HH_Donnan = HH_charge_dict["charges_dict"] -pH_sys = HH_charge_dict["pH_system_list"] -xi = HH_charge_dict["partition_coefficients"] - -fig, ax = plt.subplots(figsize=(10, 7)) -plt.errorbar(pH_range, np.asarray(Z_pH)/N_peptide1_chains, yerr=np.asarray(err_Z_pH)/N_peptide1_chains, fmt = 'o', capsize=3, label='Simulation') -ax.plot(pH_range_HH, np.asarray(Z_HH_Donnan[peptide1])+np.asarray(Z_HH_Donnan[peptide2]), "--r", label='HH+Donnan') -plt.legend() -plt.xlabel('pH') -plt.ylabel('Charge of the peptide 1 + peptide 2 / e') -plt.show() -plt.close() - -fig, ax = plt.subplots(figsize=(10, 7)) -plt.errorbar(pH_range, xi_plus, yerr=err_xi_plus, fmt = 'o', capsize=3, label='Simulation') -ax.plot(pH_range_HH, np.asarray(xi), "-k", label='HH+Donnan') -plt.legend() -plt.xlabel('pH') -plt.ylabel(r'partition coefficient $\xi_+$') -plt.show() -plt.close() + +if args.test: + # Calculate the ideal titration curve of the peptide with Henderson-Hasselbach equation + HH_charge_dict = pmb.calculate_HH_Donnan(c_macro={peptide1: pep1_concentration, peptide2: pep2_concentration}, c_salt=c_salt, pH_list=pH_range) + Z_HH_Donnan = HH_charge_dict["charges_dict"] + xi = HH_charge_dict["partition_coefficients"] + + # Write out the data + data = {} + data["Z_sim"] = np.asarray(Z_pH)/N_peptide1_chains + data["xi_sim"] = np.asarray(xi_plus) + data["Z_HH_Donnan"] = np.asarray(Z_HH_Donnan[peptide1])+np.asarray(Z_HH_Donnan[peptide2]) + data["xi_HH_Donnan"] = np.asarray(xi) + data = pd.DataFrame.from_dict(data) + + data_path = pmb.get_resource(path="samples") + data.to_csv(f"{data_path}/data_peptide_grxmc.csv", index=False) + +else: + # Calculate the ideal titration curve of the peptide with Henderson-Hasselbach equation + pH_range_HH = np.linspace(2, 12, num=100) + HH_charge_dict = pmb.calculate_HH_Donnan(c_macro={peptide1: pep1_concentration, peptide2: pep2_concentration}, c_salt=c_salt, pH_list=pH_range_HH) + Z_HH_Donnan = HH_charge_dict["charges_dict"] + xi = HH_charge_dict["partition_coefficients"] + + # Plot the results + fig, ax = plt.subplots(figsize=(10, 7)) + plt.errorbar(pH_range, np.asarray(Z_pH)/N_peptide1_chains, yerr=np.asarray(err_Z_pH)/N_peptide1_chains, fmt = 'o', capsize=3, label='Simulation') + ax.plot(pH_range_HH, np.asarray(Z_HH_Donnan[peptide1])+np.asarray(Z_HH_Donnan[peptide2]), "--r", label='HH+Donnan') + plt.legend() + plt.xlabel('pH') + plt.ylabel('Charge of the peptide 1 + peptide 2 / e') + plt.show() + plt.close() + + fig, ax = plt.subplots(figsize=(10, 7)) + plt.errorbar(pH_range, xi_plus, yerr=err_xi_plus, fmt = 'o', capsize=3, label='Simulation') + ax.plot(pH_range_HH, np.asarray(xi), "-k", label='HH+Donnan') + plt.legend() + plt.xlabel('pH') + plt.ylabel(r'partition coefficient $\xi_+$') + plt.show() + plt.close() diff --git a/testsuite/cph_ideal_tests.py b/testsuite/cph_ideal_tests.py new file mode 100644 index 0000000..9148858 --- /dev/null +++ b/testsuite/cph_ideal_tests.py @@ -0,0 +1,26 @@ +# Import pyMBE and other libraries +import pyMBE +from lib import analysis +import os +import tempfile +import subprocess +import numpy as np +import pandas as pd + +# Create an instance of pyMBE library +pmb = pyMBE.pymbe_library() +script_path = pmb.get_resource(f"samples/branched_polyampholyte.py") +data_path = pmb.get_resource(f"samples/data_polyampholyte_cph.csv") + + +print(f"*** Constant pH (cpH) implementation tests ***\n") +print(f"*** Test that our implementation of the cpH method reproduces the Henderson Hasselbalch equation for an ideal polyampholyte ***\n") + +run_command = ["python3", script_path, "--test"] +subprocess.check_output(run_command) + +data = pd.read_csv(data_path) +# Check if charges agree +np.testing.assert_allclose(data["Z_sim"], data["Z_HH"], rtol=0.05, atol=0.1) + +print(f"*** Test passed ***\n") diff --git a/testsuite/grxmc_ideal_tests.py b/testsuite/grxmc_ideal_tests.py new file mode 100644 index 0000000..119c626 --- /dev/null +++ b/testsuite/grxmc_ideal_tests.py @@ -0,0 +1,41 @@ +# Import pyMBE and other libraries +import pyMBE +from lib import analysis +import os +import tempfile +import subprocess +import numpy as np +import pandas as pd + +# Create an instance of pyMBE library +pmb = pyMBE.pymbe_library() +script_path = pmb.get_resource(f"samples/peptide_mixture_grxmc_ideal.py") +data_path = pmb.get_resource(f"samples/data_peptide_grxmc.csv") + +print(f"*** Grand reaction (G-RxMC) implementation tests ***\n") +print(f"*** Test that our implementation of the original G-RxMC method reproduces the Henderson Hasselbalch equation corrected with the Donnan potential (HH+Don) for an ideal mixture of peptides ***") + +run_command = ["python3", script_path, "--mode", "standard", "--test"] +subprocess.check_output(run_command) + +data = pd.read_csv(data_path) +# Check if charges agree +np.testing.assert_allclose(data["Z_sim"], data["Z_HH_Donnan"], rtol=0.01, atol=0.05) +# Check if partition coefficients agree +np.testing.assert_allclose(data["xi_sim"], data["xi_HH_Donnan"], rtol=0.1, atol=0.1) + +print(f"*** Test passed ***\n") + + +print(f"*** Test that our implementation of the G-RxMC method with unified ion types reproduces HH+Don for an ideal mixture of peptides ***") + +run_command = ["python3", script_path, "--mode", "unified", "--test"] +subprocess.check_output(run_command) + +data = pd.read_csv(data_path) +# Check if charges agree +np.testing.assert_allclose(data["Z_sim"], data["Z_HH_Donnan"], rtol=0.01, atol=0.05) +# Check if partition coefficients agree +np.testing.assert_allclose(data["xi_sim"], data["xi_HH_Donnan"], rtol=0.1, atol=0.1) + +print(f"*** Test passed ***\n") diff --git a/testsuite/lj_tests.py b/testsuite/lj_tests.py index 43f9381..d5d302c 100644 --- a/testsuite/lj_tests.py +++ b/testsuite/lj_tests.py @@ -1,7 +1,8 @@ # Import pyMBE and other libraries import pyMBE import numpy as np - +import warnings + # Create an instance of pyMBE library pmb = pyMBE.pymbe_library() @@ -15,18 +16,21 @@ "offset":3*pmb.units.nm} pmb.define_particle(**input_parameters) - for parameter_key in input_parameters.keys(): - np.testing.assert_equal(actual=pmb.df[parameter_key].values[0], - desired=input_parameters[parameter_key], - verbose=True) + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + np.testing.assert_equal(actual=pmb.df[parameter_key].values[0], + desired=input_parameters[parameter_key], + verbose=True) print("*** Unit test passed ***") print(f"*** Unit test: check that `offset` defaults to 0***") # Clean pmb.df pmb.setup_df() # Define dummy particle pmb.define_particle(name="A") -np.testing.assert_equal(actual=pmb.df["offset"].values[0], +with warnings.catch_warnings(): + warnings.simplefilter("ignore") + np.testing.assert_equal(actual=pmb.df["offset"].values[0], desired=pmb.units.Quantity(0,"reduced_length"), verbose=True) print("*** Unit test passed ***") @@ -36,7 +40,9 @@ pmb.setup_df() # Define dummy particle pmb.define_particle(name="A") -np.testing.assert_equal(actual=pmb.df["cutoff"].values[0], +with warnings.catch_warnings(): + warnings.simplefilter("ignore") + np.testing.assert_equal(actual=pmb.df["cutoff"].values[0], desired=pmb.units.Quantity(2**(1./6.),"reduced_length"), verbose=True) print("*** Unit test passed ***")