From a0e8bdb9fd1424db4a9e8b0afd7f9f695dda768c Mon Sep 17 00:00:00 2001 From: titusquah <46580668+titusquah@users.noreply.github.com> Date: Mon, 8 Jun 2020 11:02:04 -0600 Subject: [PATCH] Added r-squared printout to parity plot. Fixed default optimizer to detect number of dimensions and update bounds to match. --- .idea/dictionaries/Titus.xml | 2 + .idea/workspace.xml | 89 +++++++++++++++------------ README.md | 12 +++- data/xmls/twophase.xml | 2 +- docs/Examples/1_getting_started.ipynb | 28 ++++----- reeps.py | 41 ++++++++---- 6 files changed, 107 insertions(+), 67 deletions(-) diff --git a/.idea/dictionaries/Titus.xml b/.idea/dictionaries/Titus.xml index b634bf6..618a4d8 100644 --- a/.idea/dictionaries/Titus.xml +++ b/.idea/dictionaries/Titus.xml @@ -3,6 +3,7 @@ coeffs conc + csvs diluant disp dodecane @@ -18,6 +19,7 @@ scipy slsqp thermo + xmls \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 18a656d..afc0287 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,13 +1,13 @@ - + + - - - + + - + - + - - - - - + + + + + @@ -222,7 +225,14 @@ @@ -242,7 +252,8 @@ - @@ -261,10 +272,11 @@ - - + + + @@ -273,30 +285,30 @@ - + - - + + - - + + - - + + - + @@ -305,12 +317,12 @@ - + - + @@ -319,10 +331,11 @@ - - + + + diff --git a/README.md b/README.md index d3a7bb2..c83f743 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # REEPS -REEPS is a toolkit for estimating standard thermodynamic parameters for Gibbs minimization. +REEPS (Rare Earth Element Parameter Searcher) is a toolkit for estimating standard thermodynamic parameters for Gibbs minimization. Extend a methodology for estimating standard thermodynamic parameters for Gibbs minimization in multiphase, multicomponent separations systems @@ -23,4 +23,12 @@ $ pip install -e. REEPS uses packages: cantera (https://cantera.org/), pandas, numpy, scipy, xml, seaborn, and matplotlib ## Usage -Do random stuff and pray. +Check out examples in docs/examples +```python +from reeps import REEPS +searcher = REEPS(**REEPS_parameters_dictionary) +optimized_parameter_dictionary = searcher.fit() +searcher.update_xml(optimized_parameter_dictionary) +searcher.parity_plot() +print(seacher.r_squared()) +``` diff --git a/data/xmls/twophase.xml b/data/xmls/twophase.xml index ed936a8..337bd4a 100644 --- a/data/xmls/twophase.xml +++ b/data/xmls/twophase.xml @@ -50,7 +50,7 @@ 298.14999999999998 - -4704703.645715787 + -4704699.156668724 1117.965 0.0 diff --git a/docs/Examples/1_getting_started.ipynb b/docs/Examples/1_getting_started.ipynb index 6f93a81..f04f220 100644 --- a/docs/Examples/1_getting_started.ipynb +++ b/docs/Examples/1_getting_started.ipynb @@ -42,7 +42,7 @@ "from reeps import REEPS\n", "searcher_parameters = {'exp_csv_filename': '../../data/csvs/exp_data.csv',\n", " 'phases_xml_filename': '../../data/xmls/twophase.xml',\n", - " 'opt_dict': {'Nd(H(A)2)3(org)': {'h0': -4662344.64}},\n", + " 'opt_dict': {'Nd(H(A)2)3(org)': {'h0': -4.7e6}},\n", " 'phase_names': ['HCl_electrolyte', 'PC88A_liquid'],\n", " 'aq_solvent_name': 'H2O(L)',\n", " 'extractant_name': '(HA)2(org)',\n", @@ -238,7 +238,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "[, ]\n" + "[, ]\n" ] } ], @@ -297,9 +297,9 @@ "source": [ "This is a dictionary that contains the information about what species and what thermodynamic properties are to be modified.
\n", "The number after the thermodynamic property is the initial guess for the optimizer.
\n", - "In this example, we chose to optimize the standard enthalpy (h0) of the neodymium-PC88A complex ('Nd(H(A)2)3(org)') and give it an initial guess of -4662344.64. Thus,
\n", + "In this example, we chose to optimize the standard enthalpy (h0) of the neodymium-PC88A complex ('Nd(H(A)2)3(org)') and give it an initial guess of -4.7e6. Thus,
\n", "```python \n", - "opt_dict={'Nd(H(A)2)3(org)': {'h0': -4662344.64}}```" + "opt_dict={'Nd(H(A)2)3(org)': {'h0': -4.7e6}}```" ] }, { @@ -308,8 +308,8 @@ "source": [ "Say we wanted to also modify the extractant ('(HA)2(org)'), but this time change both the standard enthalpy (h0) and the molar volume (molarVolume), then the dictionary would be\n", "```python \n", - "opt_dict={'Nd(H(A)2)3(org)': {'h0': -4662344.64, 'molarVolume':1.01},\n", - " '(HA)2(org)': {'h0': -4662344.64, 'molarVolume':1.01}}```" + "opt_dict={'Nd(H(A)2)3(org)': {'h0': -4.7e6, 'molarVolume':1.01},\n", + " '(HA)2(org)': {'h0': -4.7e6, 'molarVolume':1.01}}```" ] }, { @@ -365,7 +365,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now that the thermodynamic properties have been set, we now need to set up the optimizer.
The default optimizer is from scipy.optimize.minimize with the arguments below." + "Now that the thermodynamic properties have been set, we now need to set up the optimizer.
The default optimizer is from scipy.optimize.minimize with the arguments below. The optimizer optimizes a value multiplied by the initial guess.
Say $x$ is the variable controlled by the minimizer, the value that is entering the objective function is $x\\times\\mathrm{Guess\\,value}$. So for our case, the values tested are $(4.6\\times 10^6)x$. This is more important for bounds and constraints." ] }, { @@ -400,11 +400,11 @@ "output_type": "stream", "text": [ "Optimization terminated successfully. (Exit mode 0)\n", - " Current function value: 0.025193550841886146\n", - " Iterations: 5\n", - " Function evaluations: 19\n", - " Gradient evaluations: 5\n", - "{'Nd(H(A)2)3(org)': {'h0': -4704703.645715787}}\n" + " Current function value: 0.025193288852542232\n", + " Iterations: 4\n", + " Function evaluations: 16\n", + " Gradient evaluations: 4\n", + "{'Nd(H(A)2)3(org)': {'h0': -4704699.156668724}}\n" ] } ], @@ -464,7 +464,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -493,7 +493,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "0.997071413389365\n" + "0.9970803631106648\n" ] } ], diff --git a/reeps.py b/reeps.py index 8c97159..16029a6 100644 --- a/reeps.py +++ b/reeps.py @@ -11,8 +11,9 @@ import shutil import copy from inspect import signature import os -sns.set() +sns.set() +sns.set(font_scale=1.6) class REEPS: """REEPS (Rare earth extraction parameter searcher) @@ -113,7 +114,7 @@ class REEPS: @staticmethod def log_mean_squared_error(predicted_dict, meas_df): - meas = meas_df['D(m)'].values + meas = meas_df.values[:, 2] pred = predicted_dict['re_org'] / predicted_dict['re_aq'] log_pred = np.log10(pred) log_meas = np.log10(meas) @@ -123,7 +124,7 @@ class REEPS: @staticmethod def slsqp_optimizer(objective, x_guess): optimizer_kwargs = {"method": 'SLSQP', - "bounds": [(1e-1, 1e1) * len(x_guess)], + "bounds": [(1e-1, 1e1)] * len(x_guess), "constraints": (), "options": {'disp': True, 'maxiter': 1000, 'ftol': 1e-6}} res = minimize(objective, x_guess, **optimizer_kwargs) @@ -400,7 +401,8 @@ class REEPS: for _ in opt_dict[species_name].keys(): i += 1 x = np.array(x) - if i == len(x.shape): + + if len(x.shape) == 1: xs = np.array([x]) vectorized_x = False else: @@ -449,11 +451,9 @@ class REEPS: optimizer = self._optimizer opt_dict = copy.deepcopy(self._opt_dict) - # x_guess = [] i = 0 for species_name in opt_dict.keys(): for _ in opt_dict[species_name].keys(): - # x_guess.append(opt_dict[species_name][thermo_prop]) i += 1 x_guess = np.ones(i) @@ -504,7 +504,8 @@ class REEPS: self.set_phases(self._phases_xml_filename, self._phase_names) return None - def parity_plot(self, species='re_aq'): + # noinspection PyUnusedLocal + def parity_plot(self, species='re_aq', save_path=None, print_r_squared=False): """Parity plot between measured and predicted rare earth composition""" phases_copy = self._phases.copy() mix = ct.Mixture(phases_copy) @@ -520,16 +521,32 @@ class REEPS: aq_ind, rare_earth_ion_name)] pred.append(re_aq) pred = np.array(pred) - meas = exp_df['REeq(m)'].values + meas = exp_df.values[:, 1] min_data = np.min([pred, meas]) max_data = np.max([pred, meas]) min_max_data = np.array([min_data, max_data]) fig, ax = plt.subplots() - sns.scatterplot(meas, pred, color="r", - label="Rare earth equilibrium concentration (mol/L)") - sns.lineplot(min_max_data, min_max_data, color="b", label="") + re_element = '' + n_plus = 0 + for char in self._rare_earth_ion_name: + if char.isalpha(): + re_element = '{0}{1}'.format(re_element, char) + else: + n_plus += 1 + re_ion_name = '$%s^{%d+}$' % (re_element, n_plus) + p1 = sns.scatterplot(meas, pred, color="r", + label="{0} eq. conc. (mol/L)".format(re_ion_name), + legend=False) + p2 = sns.lineplot(min_max_data, min_max_data, color="b", label="") + if print_r_squared: + p1.text(min_max_data[0], min_max_data[1]*0.9, '$R^2$={0:.2f}'.format(self.r_squared())) + plt.legend(loc='lower right') + else: + plt.legend() ax.set(xlabel='Measured', ylabel='Predicted') plt.show() + if save_path is not None: + plt.savefig(save_path, bbox_inches='tight') return None def r_squared(self): @@ -548,7 +565,7 @@ class REEPS: aq_ind, rare_earth_ion_name)] pred.append(re_aq) predicted_y = np.array(pred) - actual_y = exp_df['REeq(m)'].values + actual_y = exp_df.values[:, 1] num = sum((actual_y - predicted_y) ** 2) den = sum((actual_y - np.mean(actual_y)) ** 2) r_2 = (1 - num / den)