Skip to content

Commit

Permalink
PyIRoGlass v0.2.0 released!
Browse files Browse the repository at this point in the history
  • Loading branch information
sarahshi committed Sep 24, 2023
1 parent 4213bec commit deb500e
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 50 deletions.
30 changes: 28 additions & 2 deletions UnitTests/test_concentration.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import PyIRoGlass as pig



class test_conc_outputs_h2ot(unittest.TestCase):

def setUp(self):
Expand Down Expand Up @@ -89,14 +88,41 @@ def setUp(self):
self.P_room = 1
self.decimalPlace = 5

def test_concentration(self):
def test_concentration(self): # OL53

density_epsilon, mega_spreadsheet = pig.Concentration_Output(self.PH, self.N, self.thickness, self.MI_Composition, self.T_room, self.P_room)
expected_H2O = 4.03892743514451
expected_CO2 = 713.3372363302
self.assertAlmostEqual(float(mega_spreadsheet['H2OT_MEAN']), expected_H2O, self.decimalPlace, msg="H2Ot test values from the Concentration_Output equation do not agree")
self.assertAlmostEqual(float(mega_spreadsheet['CO2_MEAN']), expected_CO2, self.decimalPlace, msg="CO2m test values from the Concentration_Output equation do not agree")

class test_conc_outputs_saturated(unittest.TestCase): # OL49

def setUp(self):

self.MI_Composition = pd.DataFrame({'SiO2': [52.34], 'TiO2': [1.04], 'Al2O3': [17.92], 'Fe2O3': [1.93], 'FeO': [7.03],
'MnO': [0.20], 'MgO': [3.63], 'CaO': [7.72], 'Na2O': [4.25], 'K2O': [0.78], 'P2O5': [0.14]},
index=['AC4_OL49_021920_30x30_H2O_a'])
self.PH = pd.DataFrame({'PH_3550_M': [2.17224950314409], 'PH_3550_STD': [0.00220916618090868], 'H2OT_3550_SAT?': ['*'], 'PH_1635_BP': [0.658349188362703],
'PH_1635_STD': [0.00307592496318145], 'PH_1515_BP': [0.106864326434928], 'PH_1515_STD': [0.0035555642315165],
'PH_1430_BP': [0.109429135799036], 'PH_1430_STD': [0.00405404583060287], 'PH_5200_M': [0.0249095178877388], 'PH_5200_STD': [0.000801149484503151],
'PH_4500_M': [0.014569658580663], 'PH_4500_STD': [0.0000638336854435091], 'S2N_P5200': [12.1959313061391], 'S2N_P4500': [8.15732983956986],
'ERR_5200': ['-'], 'ERR_4500': ['-']}, index=['AC4_OL49_021920_30x30_H2O_a'])
self.thickness = pd.DataFrame({'Thickness': [91.25], 'Sigma_Thickness': [3]}, index=['AC4_OL49_021920_30x30_H2O_a'])
self.N = 500000
self.T_room = 25
self.P_room = 1
self.decimalPlace = 5

def test_concentration(self):

density_epsilon, mega_spreadsheet = pig.Concentration_Output(self.PH, self.N, self.thickness, self.MI_Composition, self.T_room, self.P_room)
expected_H2O = 2.54389275724829
expected_CO2 = 738.262088884613
self.assertAlmostEqual(float(mega_spreadsheet['H2OT_MEAN']), expected_H2O, self.decimalPlace, msg="H2Ot test values from the saturated Concentration_Output equation do not agree")
self.assertAlmostEqual(float(mega_spreadsheet['CO2_MEAN']), expected_CO2, self.decimalPlace, msg="CO2m test values from the saturated Concentration_Output equation do not agree")



if __name__ == '__main__':
unittest.main()
18 changes: 17 additions & 1 deletion UnitTests/test_fittingfunc.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import os
import unittest
import numpy as np
import pandas as pd
import PyIRoGlass as pig



class test_fitting_functions(unittest.TestCase):

def setUp(self):
Expand Down Expand Up @@ -86,5 +86,21 @@ def test_MCMC(self):
self.assertAlmostEqual(result_CO2_1515, expected_CO2_1515, self.decimalPlace-3, msg="CO2_1515 peak height test and expected values from the Run_All_Spectra function do not agree")


def test_MCMC_exportpath(self):

temp_export_path = "temp_test_dir"
os.makedirs(temp_export_path, exist_ok=True)

Volatiles_DF, failures = pig.Run_All_Spectra(self.sample_dfs_dict, temp_export_path)
Volatiles_DF.to_csv(os.path.join(temp_export_path, "output.csv"))

# Check if the result was exported correctly
self.assertTrue(os.path.exists(os.path.join(temp_export_path, "output.csv")))

# Cleanup
os.remove(os.path.join(temp_export_path, "output.csv"))
os.rmdir(temp_export_path)


if __name__ == '__main__':
unittest.main()
63 changes: 60 additions & 3 deletions UnitTests/test_plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,35 @@
import pandas as pd
import sys
import PyIRoGlass as pig

import matplotlib.pyplot as plt


class test_plotting_trace(unittest.TestCase):

def test_trace(self):
@patch("matplotlib.pyplot.Figure.savefig")
def test_trace_savefile(self, mock_savefig):

pnames = ['B_mean',"B_PC1","B_PC2","B_PC3","B_PC4",'G1430_peak','G1430_std','G1430_amp',
'G1515_peak','G1515_std','G1515_amp','H1635_mean','H1635_PC1','H1635_PC2','m','b']

texnames = ['$\overline{B}$',"$\overline{B}_{PC1}$","$\overline{B}_{PC2}$","$\overline{B}_{PC3}$",'$\overline{B}_{PC4}$',
'$\mu_{1430}$','$\sigma_{1430}$','$a_{1430}$','$\mu_{1515}$','$\sigma_{1515}$','$a_{1515}$',
'$\overline{H_{1635}}$','$\overline{H_{1635}}_{PC1}$','$\overline{H_{1635}}_{PC2}$','$m$','$b$']

file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../docs/examples/transmission_ftir/NPZTXTFILES/RESULTS/AC4_OL53_101220_256s_30x30_a.npz')
mcmc_npz = np.load(file_path)

fig = pig.trace(mcmc_npz['posterior'], title = 'AC4_OL53_101220_256s_30x30_a', zchain=mcmc_npz['zchain'], burnin=mcmc_npz['burnin'], pnames=texnames, savefile='dummy_filename.png')

# Check if savefig was called with the correct filename
mock_savefig.assert_called_once()
args, kwargs = mock_savefig.call_args
assert 'dummy_filename.png' in args[0]
plt.close('all')


@patch("matplotlib.pyplot.Figure.savefig")
def test_trace_nosavefile(self, mock_savefig):

pnames = ['B_mean',"B_PC1","B_PC2","B_PC3","B_PC4",'G1430_peak','G1430_std','G1430_amp',
'G1515_peak','G1515_std','G1515_amp','H1635_mean','H1635_PC1','H1635_PC2','m','b']
Expand All @@ -24,6 +47,11 @@ def test_trace(self):

fig = pig.trace(mcmc_npz['posterior'], title = 'AC4_OL53_101220_256s_30x30_a', zchain=mcmc_npz['zchain'], burnin=mcmc_npz['burnin'], pnames=texnames)

# Check if savefig was never called
mock_savefig.assert_not_called()
plt.close('all')


class test_plotting_modelfit(unittest.TestCase):

def setUp(self):
Expand All @@ -37,7 +65,32 @@ def setUp(self):
self.spec_mc3 = self.df_lim['Absorbance'].to_numpy()
self.decimalPlace = 5

def test_modelfit(self):

def test_modelfit_savefile(self, mock_savefig):

file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../src/PyIRoGlass/BaselineAvgPC.npz')
wavenumber = pig.Load_Wavenumber(file_path)

pnames = ['B_mean',"B_PC1","B_PC2","B_PC3","B_PC4",'G1430_peak','G1430_std','G1430_amp',
'G1515_peak','G1515_std','G1515_amp','H1635_mean','H1635_PC1','H1635_PC2','m','b']

texnames = ['$\overline{B}$',"$\overline{B}_{PC1}$","$\overline{B}_{PC2}$","$\overline{B}_{PC3}$",'$\overline{B}_{PC4}$',
'$\mu_{1430}$','$\sigma_{1430}$','$a_{1430}$','$\mu_{1515}$','$\sigma_{1515}$','$a_{1515}$',
'$\overline{H_{1635}}$','$\overline{H_{1635}}_{PC1}$','$\overline{H_{1635}}_{PC2}$','$m$','$b$']

file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../docs/examples/transmission_ftir/NPZTXTFILES/RESULTS/AC4_OL49_021920_30x30_H2O_a.npz')
mcmc_npz = np.load(file_path)

fig = pig.modelfit(self.spec_mc3, np.ones_like(self.spec_mc3) * 0.01, wavenumber, mcmc_npz['best_model'], title = 'AC4_OL49_021920_30x30_H2O_a', savefile='dummy_filename.png')

# Check if savefig was called with the correct filename
mock_savefig.assert_called_once()
args, kwargs = mock_savefig.call_args
assert "dummy_filename.png" in args[0]
plt.close('all')


def test_modelfit_nosavefile(self, mock_savefig):

file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../src/PyIRoGlass/BaselineAvgPC.npz')
wavenumber = pig.Load_Wavenumber(file_path)
Expand All @@ -53,6 +106,10 @@ def test_modelfit(self):
mcmc_npz = np.load(file_path)

fig = pig.modelfit(self.spec_mc3, np.ones_like(self.spec_mc3) * 0.01, wavenumber, mcmc_npz['best_model'], title = 'AC4_OL49_021920_30x30_H2O_a')

# Check if savefig was called with the correct filename
mock_savefig.assert_not_called()
plt.close('all')


if __name__ == '__main__':
Expand Down
2 changes: 1 addition & 1 deletion UnitTests/test_thickness.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def test_peak_identification(self):
peak_search_width = 10
wn_high = 2700
wn_low = 2100
peaks, troughs = pig.PeakID(self.df, wn_high, wn_low, filename=self.file, plotting=False, savgol_filter_width=savgol_filter_width, smoothing_wn_width = smoothing_wn_width, remove_baseline = True, peak_heigh_min_delta = peak_heigh_min_delta, peak_search_width = peak_search_width)
peaks, troughs = pig.PeakID(self.df, wn_high, wn_low, filename=self.file, plotting=True, savgol_filter_width=savgol_filter_width, smoothing_wn_width = smoothing_wn_width, remove_baseline = True, peak_heigh_min_delta = peak_heigh_min_delta, peak_search_width = peak_search_width)
expected_peak_loc = 2138.76
self.assertAlmostEqual(float(peaks[0, 0]), expected_peak_loc, self.decimalPlace-2, msg="Peak location test and expected values from the Peak_ID function do not agree")

Expand Down
2 changes: 1 addition & 1 deletion docs/FAQs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
FAQs and Troubleshooting
========================

``PyIRoGlass`` has been tested by several users, but it is still very possible that there are errors. Please alert `Sarah Shi <sarah.shi@columbia.edu>`_ to any errors or bugs within the code and/or raise an issue on the `PyIRoGlass GitHub repository <https://github.com/sarahshi/PyIRoGlass>`_, so future users can see an approach or resolution to the same problem. Select 'new issue' and make sure you provide information to trobuleshoot the problem, either by providing your Python notebook or screenshots of the entire error message.
``PyIRoGlass`` has been tested by several users, but it is still very possible that there are errors. Please alert `Sarah Shi <mailto:sarah.shi@columbia.edu>`_ to any errors or bugs within the code and/or raise an issue on the `PyIRoGlass GitHub repository <https://github.com/sarahshi/PyIRoGlass>`_, so future users can see an approach or resolution to the same problem. Select 'new issue' and make sure you provide information to trobuleshoot the problem, either by providing your Python notebook or screenshots of the entire error message.
4 changes: 2 additions & 2 deletions docs/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Welcome to ``PyIRoGlass``: An Open-Source, Bayesian MCMC Algorithm for Fitting B

This tool is currently in progress, with submission to Volcanica in the near future. Please make sure you cite this tool if you use it. Software development takes time and and academia does not always recognize the effort taken, but it does recognize citations.

The open-source nature of the tool allows for continuous development. We welcome the submission of devolatilized FTIR spectra that can continue to shape the form of the baseline, and molar absorptivities. You can email `Sarah Shi <sarah.shi@columbia.edu>`_ or post an enhancement request or report of a bug on the issue page of the `PyIRoGlass GitHub repository <https://github.com/SarahShi/PyIRoGlass>`_.
The open-source nature of the tool allows for continuous development. We welcome the submission of devolatilized FTIR spectra that can continue to shape the form of the baseline, and molar absorptivities. You can email `Sarah Shi <mailto:sarah.shi@columbia.edu>`_ or post an enhancement request or report of a bug on the issue page of the `PyIRoGlass GitHub repository <https://github.com/SarahShi/PyIRoGlass>`_.


=============
Expand All @@ -15,7 +15,7 @@ Collaborators

These folks have been fundamental to the development of ``PyIRoGlass``:

- `Sarah Shi <https://github.com/sarahshi>`_ (LDEO) `<sarah.shi@columbia.edu>`_
- `Sarah Shi <https://github.com/sarahshi>`_ (LDEO) `sarah.shi@columbia.edu <mailto:sarah.shi@columbia.edu>`_
- `Henry Towbin <https://github.com/whtowbin>`_ (LDEO)
- `Terry Plank <https://github.com/terryplank>`_ (LDEO)
- `Anna Barth <https://github.com/barthac>`_ (LDEO, Berkeley)
Expand Down
2 changes: 1 addition & 1 deletion docs/submitting_data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
Submitting data
===============

We welcome the submission of devolatilized FTIR spectra that can continue to shape the form of the baseline, and molar absorptivities. You can email `Sarah Shi <sarah.shi@columbia.edu>`_, or post an enhancement request or report of a bug on the issue page of the `PyIRoGlass GitHub repository <https://github.com/SarahShi/PyIRoGlass>`_.
We welcome the submission of devolatilized FTIR spectra that can continue to shape the form of the baseline, and molar absorptivities. You can email `Sarah Shi <mailto:sarah.shi@columbia.edu>`_, or post an enhancement request or report of a bug on the issue page of the `PyIRoGlass GitHub repository <https://github.com/SarahShi/PyIRoGlass>`_.
39 changes: 0 additions & 39 deletions src/PyIRoGlass/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,45 +548,6 @@ def modelfit(data, uncert, indparams, model, title, nbins=75,
plt.savefig(savefile)
return ax, rax

def subplotter(rect, margin, ipan, nx, ny=None, ymargin=None):

"""
Create an axis instance for one panel (with index ipan) of a grid
of npanels, where the grid located inside rect (xleft, ybottom,
xright, ytop).
Parameters:
rect (1D np.ndarray): Rectangle with xlo, ylo, xhi, yhi positions of the grid boundaries.
margin (float): Width of margin between panels.
ipan (int): Index of panel to create (as in plt.subplots).
nx (int): Number of panels along the x axis.
ny (int): Number of panels along the y axis. If None, assume ny=nx.
ymargin (float): Width of margin between panels along y axes (if None, adopt margin).
Returns:
ax (matplotlib.axes.Axes): Axes instance at the specified position.
"""
if ny is None:
ny = nx
if ymargin is None:
ymargin = margin

# Size of a panel:
Dx = rect[2] - rect[0]
Dy = rect[3] - rect[1]
dx = Dx/nx - (nx-1.0)* margin/nx
dy = Dy/ny - (ny-1.0)*ymargin/ny
# Position of panel ipan:
# Follow plt's scheme, where panel 1 is at the top left panel,
# panel 2 is to the right of panel 1, and so on:
xloc = (ipan-1) % nx
yloc = (ny-1) - ((ipan-1) // nx)
# Bottom-left corner of panel:
xpanel = rect[0] + xloc*(dx+ margin)
ypanel = rect[1] + yloc*(dy+ymargin)

return plt.axes([xpanel, ypanel, dx, dy])


# %%

Expand Down

0 comments on commit deb500e

Please sign in to comment.