DiadFit 0.0.78__py3-none-any.whl → 0.0.80__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
DiadFit/diads.py CHANGED
@@ -3,7 +3,7 @@ import numpy as np
3
3
  import matplotlib.pyplot as plt
4
4
  from matplotlib import patches
5
5
  import lmfit
6
- from lmfit.models import GaussianModel, VoigtModel, LinearModel, ConstantModel, PseudoVoigtModel
6
+ from lmfit.models import GaussianModel, VoigtModel, LinearModel, ConstantModel, PseudoVoigtModel, Pearson4Model
7
7
  from scipy.signal import find_peaks, gaussian
8
8
  import os
9
9
  import re
@@ -28,7 +28,7 @@ encode="ISO-8859-1"
28
28
  ## Ratio of different peaks
29
29
 
30
30
  def calculate_mole_fraction_2comp(peak_area_a, peak_area_b, cross_section_a, cross_section_b, instrument_eff_a, instrument_eff_b):
31
- """ This function calculates the molar ration of 2 components a and b based on peak areas,
31
+ """ This function calculates the molar ration of 2 components a and b based on peak areas,
32
32
  cross section and instrument efficiency
33
33
 
34
34
  Parameters
@@ -83,6 +83,9 @@ def plot_diad(*,path=None, filename=None, filetype='Witec_ASCII', Spectra_x=None
83
83
 
84
84
 
85
85
  """
86
+ if 'CRR' in filename:
87
+ filetype='headless_txt'
88
+
86
89
  if Spectra_x is None:
87
90
  Spectra_df=get_data(path=path, filename=filename, filetype=filetype)
88
91
 
@@ -141,7 +144,7 @@ class diad_id_config:
141
144
 
142
145
  Diad_window_width=30
143
146
 
144
- Diad2_window: Tuple[float, float]=(approx_diad2_pos[0], approx_diad2_pos[1]+Diad_window_width)
147
+ Diad2_window: Tuple[float, float]=(approx_diad2_pos[0]-Diad_window_width, approx_diad2_pos[1]+Diad_window_width)
145
148
  Diad1_window: Tuple[float, float]=(approx_diad1_pos[0]-Diad_window_width, approx_diad1_pos[1])
146
149
 
147
150
  approx_diad2_pos_3peaks: Tuple[float, float]=(1379, 1395, 1379-17)
@@ -154,16 +157,16 @@ class diad_id_config:
154
157
  def identify_diad_peaks(*, config: diad_id_config=diad_id_config(), path=None, filename,
155
158
  filetype='Witec_ASCII', plot_figure=True):
156
159
 
157
- """ This function fits a spline to the spectral data. It then uses Scipy find peaks to identify the diad,
158
- HB and C13 peaks. It outputs parameters such as peak positions, peak prominences,
160
+ """ This function fits a spline to the spectral data. It then uses Scipy find peaks to identify the diad,
161
+ HB and C13 peaks. It outputs parameters such as peak positions, peak prominences,
159
162
  and peak height ratios that can be very useful when splitting data into groups.
160
163
  It uses information stored in diad_id_config for most parameters
161
164
 
162
165
  Parameters
163
166
  -------------
164
167
  config: dataclass
165
- This is diad_id_config, which you should edit before you feed into the function to adjust peak finding
166
- parameters. E.g. to change prominence of peaks found by scipy, do config=pf.diad_id_config(prominence=12),
168
+ This is diad_id_config, which you should edit before you feed into the function to adjust peak finding
169
+ parameters. E.g. to change prominence of peaks found by scipy, do config=pf.diad_id_config(prominence=12),
167
170
  then input into this function
168
171
 
169
172
  Things that can be adjusted in this config file
@@ -977,7 +980,7 @@ def plot_diad_groups(*, x_cord, Weak_np=None, Medium_np=None, Strong_np=None, y
977
980
 
978
981
  Returns
979
982
  -------------
980
- figure showing 3 diad groups.
983
+ figure showing 3 diad groups.
981
984
 
982
985
 
983
986
 
@@ -1268,8 +1271,10 @@ min_cent=None, max_cent=None, min_sigma=None, max_sigma=None, amplitude=100, min
1268
1271
  Model_combo=VoigtModel(prefix=prefix)#+ConstantModel(prefix=prefix) #Stops getting results
1269
1272
 
1270
1273
  if model_name == "PseudoVoigtModel":
1271
-
1272
1274
  Model_combo=PseudoVoigtModel(prefix=prefix)#+ConstantModel(prefix=prefix) #Stops getting results
1275
+
1276
+ if model_name== "Pearson4Model":
1277
+ Model_combo=Pearson4Model(prefix=prefix)#+ConstantModel(prefix=prefix) #Stops getting results
1273
1278
  peak = Model_combo
1274
1279
  pars = peak.make_params()
1275
1280
 
@@ -1344,6 +1349,8 @@ class diad1_fit_config:
1344
1349
  # Do you want to return other parameters?
1345
1350
  return_other_params: bool =False
1346
1351
 
1352
+
1353
+
1347
1354
  @dataclass
1348
1355
  class diad2_fit_config:
1349
1356
  # Do you need a gaussian? Set position here if so
@@ -1399,7 +1406,7 @@ class diad2_fit_config:
1399
1406
  def fit_gaussian_voigt_generic_diad(config1, *, diad1=False, diad2=False, path=None, filename=None, xdat=None, ydat=None, span=None, plot_figure=True, dpi=200, Diad_pos=None, HB_pos=None, C13_pos=None, fit_peaks=None, block_print=True):
1400
1407
 
1401
1408
 
1402
- """ This function fits a voigt/Pseudovoigt curves to background subtracted data for your diads
1409
+ """ This function fits a voigt/Pseudovoigt curves to background subtracted data for your diads
1403
1410
  +- HBs+-C13 peaks. It can also fit a second Gaussian background iteratively with these peaks
1404
1411
 
1405
1412
 
@@ -1468,6 +1475,7 @@ def fit_gaussian_voigt_generic_diad(config1, *, diad1=False, diad2=False, path=N
1468
1475
 
1469
1476
 
1470
1477
 
1478
+
1471
1479
  # Calculate the amplitude from the sigma and the prominence
1472
1480
  calc_diad_amplitude=((config1.diad_sigma)*(config1.diad_prom))/0.3939
1473
1481
  calc_HB_amplitude=((config1.diad_sigma)*(config1.HB_prom))/0.3939
@@ -1498,8 +1506,12 @@ def fit_gaussian_voigt_generic_diad(config1, *, diad1=False, diad2=False, path=N
1498
1506
 
1499
1507
  if config1.model_name=="VoigtModel":
1500
1508
  model_ini = VoigtModel()#+ ConstantModel()
1501
- if config1.model_name=="PseudoVoigtModel":
1509
+ elif config1.model_name=="PseudoVoigtModel":
1502
1510
  model_ini = PseudoVoigtModel()#+ ConstantModel()
1511
+ elif config1.model_name=='Pearson4Model':
1512
+ model_ini = Pearson4Model()#+ ConstantModel()
1513
+ else:
1514
+ TypeError('Choice of model not yet supported - select VoigtModel, PseudoVoigtModel or Pearson4Model')
1503
1515
 
1504
1516
  # Create initial peak params
1505
1517
  # Set peak position to 2 spectral res units either side of the initial guess made above
@@ -1531,6 +1543,8 @@ def fit_gaussian_voigt_generic_diad(config1, *, diad1=False, diad2=False, path=N
1531
1543
  model_F = VoigtModel(prefix='lz1_') #+ ConstantModel(prefix='c1')
1532
1544
  if config1.model_name=='PseudoVoigtModel':
1533
1545
  model_F = PseudoVoigtModel(prefix='lz1_') + ConstantModel(prefix='c1')
1546
+ if config1.model_name=='Pearson4Model':
1547
+ model_F = Pearson4Model(prefix='lz1_') + ConstantModel(prefix='c1')
1534
1548
 
1535
1549
  pars1 = model_F.make_params()
1536
1550
  pars1['lz1_'+ 'amplitude'].set(calc_diad_amplitude, min=0, max=calc_diad_amplitude*10)
@@ -1547,7 +1561,8 @@ def fit_gaussian_voigt_generic_diad(config1, *, diad1=False, diad2=False, path=N
1547
1561
  model1 = VoigtModel(prefix='lz1_')# + ConstantModel(prefix='c1')
1548
1562
  if config1.model_name=='PseudoVoigtModel':
1549
1563
  model1 = PseudoVoigtModel(prefix='lz1_') #+ ConstantModel(prefix='c1')
1550
-
1564
+ if config1.model_name=='Pearson4Model':
1565
+ model1 = Pearson4Model(prefix='lz1_') #+ ConstantModel(prefix='c1')
1551
1566
  pars1 = model1.make_params()
1552
1567
  pars1['lz1_'+ 'amplitude'].set(calc_diad_amplitude, min=0, max=calc_diad_amplitude*10)
1553
1568
 
@@ -1571,6 +1586,9 @@ def fit_gaussian_voigt_generic_diad(config1, *, diad1=False, diad2=False, path=N
1571
1586
  peak = VoigtModel(prefix='lz2_')# + ConstantModel(prefix='c1')
1572
1587
  if config1.model_name=='PseudoVoigtModel':
1573
1588
  peak = PseudoVoigtModel(prefix='lz2_')# + ConstantModel(prefix='c1')
1589
+ if config1.model_name=='Pearson4Model':
1590
+ peak = Pearson4Model(prefix='lz2_')# + ConstantModel(prefix='c1')
1591
+
1574
1592
 
1575
1593
  pars = peak.make_params()
1576
1594
 
@@ -2264,9 +2282,9 @@ def fit_gaussian_voigt_generic_diad(config1, *, diad1=False, diad2=False, path=N
2264
2282
  def fit_diad_2_w_bck(*, config1: diad2_fit_config=diad2_fit_config(), config2: diad_id_config=diad_id_config(),
2265
2283
  path=None, filename=None, peak_pos_voigt=None,filetype=None,
2266
2284
  plot_figure=True, close_figure=False, Diad_pos=None, HB_pos=None, C13_pos=None):
2267
- """ This function fits the background (using the function remove_diad_baseline) and then
2285
+ """ This function fits the background (using the function remove_diad_baseline) and then
2268
2286
  fits the peaks using fit_gaussian_voigt_generic_diad()
2269
- It then checks if any parameters are right at the permitted edge (meaning fitting didnt converge),
2287
+ It then checks if any parameters are right at the permitted edge (meaning fitting didnt converge),
2270
2288
  and tries fitting if so. Then it makes a plot
2271
2289
  of the various parts of the fitting procedure, and returns a dataframe of the fit parameters.
2272
2290
 
@@ -2367,6 +2385,8 @@ def fit_diad_2_w_bck(*, config1: diad2_fit_config=diad2_fit_config(), config2: d
2367
2385
 
2368
2386
 
2369
2387
  """
2388
+ if 'CRR' in filename:
2389
+ filetype='headless_txt'
2370
2390
 
2371
2391
  # Check number of peaks makes sense
2372
2392
  fit_peaks=config1.fit_peaks
@@ -2727,6 +2747,15 @@ def fit_diad_2_w_bck(*, config1: diad2_fit_config=diad2_fit_config(), config2: d
2727
2747
  if close_figure is True:
2728
2748
  plt.close(fig)
2729
2749
 
2750
+ # Lets calculate peak skewness here.
2751
+ Skew50=assess_diad2_skewness(config1=diad2_fit_config(), int_cut_off=0.5, path=path, filename=filename, filetype=filetype,
2752
+ skewness='abs', height=1, prominence=5, width=0.5, plot_figure=False)
2753
+ Skew80=assess_diad2_skewness(config1=diad2_fit_config(), int_cut_off=0.3, path=path, filename=filename, filetype=filetype,
2754
+ skewness='abs', height=1, prominence=5, width=0.5, plot_figure=False)
2755
+ df_out['Diad2_Asym50']=Skew50['Skewness_diad2']
2756
+ df_out['Diad2_Asym70']=Skew80['Skewness_diad2']
2757
+ df_out['Diad2_Yuan2017_sym_factor']=(df_out['Diad2_fwhm'])*(df_out['Diad2_Asym50']-1)
2758
+ df_out['Diad2_Remigi2021_BSF']=df_out['Diad2_fwhm']/df_out['Diad2_Combofit_Height']
2730
2759
 
2731
2760
 
2732
2761
  if config1.return_other_params is False:
@@ -2739,9 +2768,9 @@ def fit_diad_2_w_bck(*, config1: diad2_fit_config=diad2_fit_config(), config2: d
2739
2768
 
2740
2769
  def fit_diad_1_w_bck(*, config1: diad1_fit_config=diad1_fit_config(), config2: diad_id_config=diad_id_config(),
2741
2770
  path=None, filename=None, filetype=None, plot_figure=True, close_figure=True, Diad_pos=None, HB_pos=None):
2742
- """ This function fits the background (using the function remove_diad_baseline) and then fits the peaks
2771
+ """ This function fits the background (using the function remove_diad_baseline) and then fits the peaks
2743
2772
  using fit_gaussian_voigt_generic_diad()
2744
- It then checks if any parameters are right at the permitted edge (meaning fitting didnt converge),
2773
+ It then checks if any parameters are right at the permitted edge (meaning fitting didnt converge),
2745
2774
  and tries fitting if so. Then it makes a plot
2746
2775
  of the various parts of the fitting procedure, and returns a dataframe of the fit parameters.
2747
2776
 
@@ -2836,6 +2865,8 @@ def fit_diad_1_w_bck(*, config1: diad1_fit_config=diad1_fit_config(), config2: d
2836
2865
 
2837
2866
 
2838
2867
  """
2868
+ if 'CRR' in filename:
2869
+ filetype='headless_txt'
2839
2870
 
2840
2871
  fit_peaks=config1.fit_peaks
2841
2872
 
@@ -3160,6 +3191,20 @@ def fit_diad_1_w_bck(*, config1: diad1_fit_config=diad1_fit_config(), config2: d
3160
3191
  if close_figure is True:
3161
3192
  plt.close(fig)
3162
3193
 
3194
+ # Lets calculate peak skewness here.
3195
+ Skew50=assess_diad1_skewness(config1=diad1_fit_config(), int_cut_off=0.5, path=path, filename=filename, filetype=filetype,
3196
+ skewness='abs', height=1, prominence=5, width=0.5, plot_figure=False)
3197
+ Skew80=assess_diad1_skewness(config1=diad1_fit_config(), int_cut_off=0.3, path=path, filename=filename, filetype=filetype,
3198
+ skewness='abs', height=1, prominence=5, width=0.5, plot_figure=False)
3199
+
3200
+ df_out['Diad1_Asym50']=Skew50['Skewness_diad1']
3201
+ df_out['Diad1_Asym70']=Skew80['Skewness_diad1']
3202
+ df_out['Diad1_Yuan2017_sym_factor']=(df_out['Diad1_fwhm'])*(df_out['Diad1_Asym50']-1)
3203
+ df_out['Diad1_Remigi2021_BSF']=df_out['Diad1_fwhm']/df_out['Diad1_Combofit_Height']
3204
+
3205
+
3206
+
3207
+
3163
3208
  if config1.return_other_params is False:
3164
3209
  return df_out
3165
3210
  else:
@@ -3169,7 +3214,7 @@ def fit_diad_1_w_bck(*, config1: diad1_fit_config=diad1_fit_config(), config2: d
3169
3214
  def combine_diad_outputs(*, filename=None, prefix=True,
3170
3215
  Diad1_fit=None, Diad2_fit=None, to_csv=False,
3171
3216
  to_clipboard=False, path=None):
3172
- """ This function combines the dataframes from fit_diad_2_w_bck and fit_diad_1_w_bck into a
3217
+ """ This function combines the dataframes from fit_diad_2_w_bck and fit_diad_1_w_bck into a
3173
3218
  single dataframe
3174
3219
 
3175
3220
  Parameters
@@ -3226,12 +3271,19 @@ to_clipboard=False, path=None):
3226
3271
  combo['Diad2_Gauss_Area']=np.nan
3227
3272
  combo['Diad2_Gauss_Sigma']=np.nan
3228
3273
 
3274
+
3229
3275
  combo['Splitting']=combo['Diad2_Voigt_Cent']-combo['Diad1_Voigt_Cent']
3230
3276
  #combo['Split_err_abs']=combo['Diad1_cent_err']+combo['Diad2_cent_err']
3231
3277
  combo['Split_σ']=(combo['Diad1_cent_err']**2+combo['Diad2_cent_err']**2)**0.5
3232
3278
  cols_to_move = ['Splitting', 'Split_σ', 'Diad1_Combofit_Cent', 'Diad1_cent_err', 'Diad1_Combofit_Height', 'Diad1_Voigt_Cent', 'Diad1_Voigt_Area', 'Diad1_Voigt_Sigma', 'Diad1_Residual', 'Diad1_Prop_Lor', 'Diad1_fwhm', 'Diad1_refit','Diad2_Combofit_Cent', 'Diad2_cent_err', 'Diad2_Combofit_Height', 'Diad2_Voigt_Cent', 'Diad2_Voigt_Area', 'Diad2_Voigt_Sigma', 'Diad2_Voigt_Gamma', 'Diad2_Residual', 'Diad2_Prop_Lor', 'Diad2_fwhm', 'Diad2_refit',
3233
3279
  'HB1_Cent', 'HB1_Area', 'HB1_Sigma', 'HB2_Cent', 'HB2_Area', 'HB2_Sigma', 'C13_Cent', 'C13_Area', 'C13_Sigma',
3234
- 'Diad2_Gauss_Cent', 'Diad2_Gauss_Area','Diad2_Gauss_Sigma', 'Diad1_Gauss_Cent', 'Diad1_Gauss_Area','Diad1_Gauss_Sigma',]
3280
+ 'Diad2_Gauss_Cent', 'Diad2_Gauss_Area','Diad2_Gauss_Sigma', 'Diad1_Gauss_Cent', 'Diad1_Gauss_Area','Diad1_Gauss_Sigma', 'Diad1_Asym50', 'Diad1_Asym70', 'Diad1_Yuan2017_sym_factor',
3281
+ 'Diad1_Remigi2021_BSF','Diad2_Asym50', 'Diad2_Asym70', 'Diad2_Yuan2017_sym_factor',
3282
+ 'Diad2_Remigi2021_BSF']
3283
+
3284
+
3285
+
3286
+
3235
3287
  combo_f = combo[cols_to_move + [
3236
3288
  col for col in combo.columns if col not in cols_to_move]]
3237
3289
  combo_f=combo_f.iloc[:, 0:len(cols_to_move)]
@@ -3274,6 +3326,13 @@ to_clipboard=False, path=None):
3274
3326
 
3275
3327
 
3276
3328
 
3329
+ def calculate_HB_Diad_area_ratio(df):
3330
+ """" Calculates two area ratios of hotbands and diads"""
3331
+ df_c=df.copy()
3332
+ df_c['HB_Diad_Ratio']=(df_c['HB1_Area']+df_c['HB2_Area'])/(df_c['Diad1_Voigt_Area']+df_c['Diad2_Voigt_Area'])
3333
+ df_c['HB_Total_Ratio']=(df_c['HB1_Area']+df_c['HB2_Area'])/(df_c['Diad1_Voigt_Area']+df_c['Diad2_Voigt_Area']+df_c['HB1_Area']+df_c['HB2_Area'])
3334
+ return df_c
3335
+
3277
3336
 
3278
3337
 
3279
3338
 
@@ -3757,9 +3816,9 @@ path=None, filename=None, filetype=None,
3757
3816
  return df
3758
3817
 
3759
3818
  def peak_prominence(x, y, peak_position):
3760
- """ This function calculates the approximate prominence of a peak,
3819
+ """ This function calculates the approximate prominence of a peak,
3761
3820
  by finding the local minimum either side of the peak
3762
-
3821
+
3763
3822
  Parameters
3764
3823
  ----------
3765
3824
  x: np.array
@@ -3772,7 +3831,7 @@ def peak_prominence(x, y, peak_position):
3772
3831
 
3773
3832
  Returns
3774
3833
  --------
3775
- float: prominence of peak in y coordinates.
3834
+ float: prominence of peak in y coordinates.
3776
3835
 
3777
3836
  """
3778
3837
  # Find the index of the peak position
@@ -3807,11 +3866,11 @@ from scipy.signal import find_peaks
3807
3866
  def plot_secondary_peaks(*, Diad_Files, path, filetype,
3808
3867
  xlim_plot=[1040, 1200], xlim_peaks=[1060, 1100],
3809
3868
  height=100, threshold=0.1, distance=10, prominence=5, width=6,
3810
- prominence_filter=False, sigma=3, sigma_window=30, find_peaks_filter=False,
3869
+ prominence_filter=False, sigma=3, sigma_window=30, find_peaks_filter=False,
3811
3870
  just_plot=False, yscale=0.2, gaussian_smooth=False, smoothing_window=5, smooth_std=3):
3812
3871
 
3813
3872
  """ This function plots spectra stacked vertically ontop of each other, in a specific region.
3814
- It also has two options to identify peak positions.
3873
+ It also has two options to identify peak positions.
3815
3874
 
3816
3875
  Parameters
3817
3876
  ---------------
@@ -3842,8 +3901,9 @@ def plot_secondary_peaks(*, Diad_Files, path, filetype,
3842
3901
  prominence_filter: bool
3843
3902
  if True, finds max y coordinate in the window xlim_peaks. It then calculates the prominence by
3844
3903
  comparing this peak height to the average of the median of the 3 datapoints at the left and right of the window.
3845
- If the peak is more than 'prominence' units above the average of these two end point medians, it
3904
+ If the peak is more than 'prominence' units above the average of these two end point medians, it
3846
3905
  is classified as a peak.
3906
+ Also need to specify prominence: float
3847
3907
 
3848
3908
  find_peaks_filter: bool
3849
3909
 
@@ -3973,7 +4033,7 @@ def plot_secondary_peaks(*, Diad_Files, path, filetype,
3973
4033
  i=i+1
3974
4034
 
3975
4035
 
3976
- elif sigma_filter is True:
4036
+ elif prominence_filter is True:
3977
4037
  # Find max value in region
3978
4038
 
3979
4039
  maxy=np.max(y_trim)
@@ -4121,7 +4181,7 @@ encode="ISO-8859-1"
4121
4181
 
4122
4182
 
4123
4183
  def assess_diad1_skewness(*, config1: diad1_fit_config=diad1_fit_config(), int_cut_off=0.3, path=None, filename=None, filetype=None,
4124
- skewness='abs', height=1, prominence=5, width=0.5, plot_figure=True, dpi=200):
4184
+ skewness='abs', height=1, prominence=5, width=0.5, plot_figure=True, peak_fit_routine=False, peak_pos=None, peak_height=None, dpi=200):
4125
4185
  """ Assesses Skewness of Diad peaks. Useful for identifying mixed L + V phases
4126
4186
  (see DeVitre et al. in review)
4127
4187
 
@@ -4168,6 +4228,9 @@ skewness='abs', height=1, prominence=5, width=0.5, plot_figure=True, dpi=200):
4168
4228
  dpi: int
4169
4229
  dpi to save image at
4170
4230
 
4231
+ peak_fit_routine: bool (default False) -
4232
+ if True, doesnt find max of spline, but uses the peak position you have found from the diad fitting functions.
4233
+ Also needs peak_pos (peak center in cm-1) and peak_height
4171
4234
 
4172
4235
 
4173
4236
  Returns
@@ -4202,20 +4265,28 @@ skewness='abs', height=1, prominence=5, width=0.5, plot_figure=True, dpi=200):
4202
4265
 
4203
4266
 
4204
4267
  # Use Scipy find peaks to get the biggest peak
4205
- height=height
4206
- peaks = find_peaks(y_cub, height=height, prominence=prominence, width=width)
4207
- peak_height=peaks[1]['peak_heights']
4208
- peak_pos = x_new[peaks[0]]
4268
+ if peak_fit_routine is False:
4269
+ height=height
4270
+ peaks = find_peaks(y_cub, height=height, prominence=prominence, width=width)
4271
+ peak_height=peaks[1]['peak_heights']
4272
+ peak_pos = x_new[peaks[0]]
4209
4273
 
4210
- # find max peak. put into df because i'm lazy
4211
- peak_df=pd.DataFrame(data={'pos': peak_pos,
4212
- 'height': peak_height})
4213
4274
 
4214
- # Find bigest peaks,
4215
- df_peak_sort=peak_df.sort_values('height', axis=0, ascending=False)
4216
- df_peak_sort_trim=df_peak_sort[0:1]
4217
- Peak_Center=df_peak_sort_trim['pos']
4218
- Peak_Height=df_peak_sort_trim['height']
4275
+ # find max peak. put into df because i'm lazy
4276
+ peak_df=pd.DataFrame(data={'pos': peak_pos,
4277
+ 'height': peak_height})
4278
+
4279
+ # Find bigest peaks,
4280
+ df_peak_sort=peak_df.sort_values('height', axis=0, ascending=False)
4281
+ df_peak_sort_trim=df_peak_sort[0:1]
4282
+ Peak_Center=df_peak_sort_trim['pos']
4283
+ Peak_Height=df_peak_sort_trim['height']
4284
+
4285
+ # now we are using peak parameters we got from Voigt/Pseudovoigt etc.
4286
+ if peak_fit_routine is True:
4287
+ Peak_Height=peak_height
4288
+ Peak_Center=peak_pos
4289
+
4219
4290
 
4220
4291
 
4221
4292
  # Find intensity cut off
@@ -4362,9 +4433,8 @@ skewness='abs', height=1, prominence=5, width=0.5, plot_figure=True, dpi=200):
4362
4433
 
4363
4434
 
4364
4435
 
4365
-
4366
4436
  def assess_diad2_skewness(*, config1: diad2_fit_config=diad1_fit_config(), int_cut_off=0.3, path=None, filename=None, filetype=None,
4367
- skewness='abs', height=1, prominence=5, width=0.5, plot_figure=True, dpi=200):
4437
+ skewness='abs', height=1, prominence=5, width=0.5, plot_figure=True, dpi=200, peak_fit_routine=False, peak_pos=None, peak_height=None):
4368
4438
 
4369
4439
  """ Assesses Skewness of Diad peaks. Useful for identifying mixed L + V phases
4370
4440
  (see DeVitre et al. in review)
@@ -4412,6 +4482,10 @@ skewness='abs', height=1, prominence=5, width=0.5, plot_figure=True, dpi=200):
4412
4482
  dpi: int
4413
4483
  dpi to save image at
4414
4484
 
4485
+ peak_fit_routine: bool (default False) -
4486
+ if True, doesnt find max of spline, but uses the peak position you have found from the diad fitting functions.
4487
+ Also needs peak_pos (peak center in cm-1) and peak_height
4488
+
4415
4489
 
4416
4490
 
4417
4491
  Returns
@@ -4444,21 +4518,24 @@ skewness='abs', height=1, prominence=5, width=0.5, plot_figure=True, dpi=200):
4444
4518
  y_cub=f2(x_new)
4445
4519
 
4446
4520
 
4447
-
4521
+ if peak_fit_routine is False:
4448
4522
  # Use Scipy find peaks to get that cubic peak
4449
- peaks = find_peaks(y_cub, height=height, prominence=prominence, width=width)
4450
- peak_height=peaks[1]['peak_heights']
4451
- peak_pos = x_new[peaks[0]]
4523
+ peaks = find_peaks(y_cub, height=height, prominence=prominence, width=width)
4524
+ peak_height=peaks[1]['peak_heights']
4525
+ peak_pos = x_new[peaks[0]]
4452
4526
 
4453
- # find max peak. put into df because i'm lazy
4454
- peak_df=pd.DataFrame(data={'pos': peak_pos,
4455
- 'height': peak_height})
4527
+ # find max peak. put into df because i'm lazy
4528
+ peak_df=pd.DataFrame(data={'pos': peak_pos,
4529
+ 'height': peak_height})
4456
4530
 
4457
- df_peak_sort=peak_df.sort_values('height', axis=0, ascending=False)
4458
- df_peak_sort_trim=df_peak_sort[0:1]
4459
- Peak_Center=df_peak_sort_trim['pos'].iloc[0]
4460
- Peak_Height=df_peak_sort_trim['height'].iloc[0]
4531
+ df_peak_sort=peak_df.sort_values('height', axis=0, ascending=False)
4532
+ df_peak_sort_trim=df_peak_sort[0:1]
4533
+ Peak_Center=df_peak_sort_trim['pos'].iloc[0]
4534
+ Peak_Height=df_peak_sort_trim['height'].iloc[0]
4461
4535
 
4536
+ if peak_fit_routine is True:
4537
+ Peak_Height=peak_height[0]
4538
+ Peak_Center=peak_pos[0]
4462
4539
 
4463
4540
 
4464
4541
 
@@ -4600,7 +4677,7 @@ skewness='abs', height=1, prominence=5, width=0.5, plot_figure=True, dpi=200):
4600
4677
 
4601
4678
  def loop_diad_skewness(*, Diad_files, path=None, filetype=None, skewness='abs', sort=False, int_cut_off=0.15,
4602
4679
  config_diad1: diad1_fit_config=diad1_fit_config(), config_diad2: diad2_fit_config=diad2_fit_config(), prominence=10, width=1, height=1):
4603
- """ Loops over all supplied files to calculate skewness for multiple spectra using the functions
4680
+ """ Loops over all supplied files to calculate skewness for multiple spectra using the functions
4604
4681
  assess_diad1_skewness() and assess_diad2_skewness()
4605
4682
 
4606
4683
 
@@ -59,14 +59,16 @@ def make_error_dist_microthermometry_1sam(*, T_h_C, sample_i=0, error_T_h_C=0.3,
59
59
  if error_dist_T_h_C=='uniform':
60
60
  Noise_to_add_T_h_C = np.random.uniform(- error_T_h_C, +
61
61
  error_T_h_C, N_dup)
62
-
63
- T_h_C_with_noise=Noise_to_add_T_h_C+df_c['T_h_C'].iloc[sample_i]
62
+
63
+ T_h_C_with_noise=Noise_to_add_T_h_C+df_c['T_h_C'].iloc[0]
64
+
65
+
64
66
 
65
67
  return T_h_C_with_noise
66
68
 
67
69
 
68
70
  def propagate_microthermometry_uncertainty(T_h_C, Sample_ID=None, error_T_h_C=0.3, N_dup=1000,
69
- error_dist_T_h_C='uniform', error_type_T_h_C='Abs', EOS='SW96', homog_to=None):
71
+ error_dist_T_h_C='uniform', error_type_T_h_C='Abs', EOS='SW96', homog_to=None, set_to_critical=False):
70
72
 
71
73
  """
72
74
  This function propagates the uncertainty in measured temperature values to calculate the density of gas and
@@ -108,6 +110,10 @@ def propagate_microthermometry_uncertainty(T_h_C, Sample_ID=None, error_T_h_C=0
108
110
 
109
111
  homog_to : str, optional
110
112
  The phase to which the CO2 density is homogenized. Can be either 'Gas' or 'Liq'. Default is None.
113
+
114
+ set_to_critical: bool
115
+ Default False. If true, if you enter T_h_C which exceeds 30.9782 (the critical point of CO2) it replaces your entered Temp with that temp.
116
+
111
117
 
112
118
  Returns
113
119
  -------
@@ -135,6 +141,7 @@ def propagate_microthermometry_uncertainty(T_h_C, Sample_ID=None, error_T_h_C=0
135
141
  Mean_density_gas=np.empty(len_loop)
136
142
  Mean_density_liq=np.empty(len_loop)
137
143
  Std_density_gas_IQR=np.empty(len_loop)
144
+ Std_density_Liq_IQR=np.empty(len_loop)
138
145
  Sample=np.empty(len_loop, dtype=np.dtype('U100') )
139
146
 
140
147
  for i in range(0, len_loop):
@@ -166,6 +173,7 @@ def propagate_microthermometry_uncertainty(T_h_C, Sample_ID=None, error_T_h_C=0
166
173
  Sample2=Sample[i]
167
174
  MC_T=calculate_CO2_density_homog_T(T_h_C=Temp_MC, Sample_ID=Sample2, EOS=EOS, homog_to=homog_to)
168
175
 
176
+ # Replace critical with NaN
169
177
 
170
178
 
171
179
 
@@ -179,15 +187,22 @@ def propagate_microthermometry_uncertainty(T_h_C, Sample_ID=None, error_T_h_C=0
179
187
  Mean_density_liq[i]=np.nanmean(MC_T['Liq_gcm3'])
180
188
  var=MC_T['Gas_gcm3']
181
189
  Std_density_gas_IQR[i]=0.5*np.abs((np.percentile(var, 84) -np.percentile(var, 16)))
190
+ varL=MC_T['Liq_gcm3']
191
+ Std_density_Liq_IQR[i]=0.5*np.abs((np.percentile(varL, 84) -np.percentile(varL, 16)))
182
192
 
183
-
193
+ # Preferred density no MC
194
+ Density_pref=calculate_CO2_density_homog_T(T_h_C=T_h_C, Sample_ID=Sample_ID, EOS=EOS, homog_to=homog_to, set_to_critical=set_to_critical)
184
195
 
185
196
  Av_outputs=pd.DataFrame(data={'Sample_ID': Sample,
197
+ 'Density_Gas_noMC': Density_pref['Gas_gcm3'],
198
+ 'Density_Liq_noMC': Density_pref['Liq_gcm3'],
186
199
  'Mean_density_Gas_gcm3': Mean_density_gas,
187
200
  'Std_density_Gas_gcm3': Std_density_gas,
188
201
  'Std_density_Gas_gcm3_from_percentiles': Std_density_gas_IQR,
202
+ 'Std_density_Liq_gcm3_from_percentiles': Std_density_Liq_IQR,
189
203
  'Mean_density_Liq_gcm3': Mean_density_liq,
190
204
  'Std_density_Liq_gcm3': Std_density_liq,
205
+ 'Input_temp': T_h_C,
191
206
  'error_T_h_C': error_T_h_C})
192
207
 
193
208
 
@@ -195,7 +195,7 @@ def get_data(*, path=None, filename=None, Diad_files=None, filetype='Witec_ASCII
195
195
 
196
196
 
197
197
  if np.all(np.diff(x_values) < 0):
198
- print('I flipped')
198
+ #print('I flipped')
199
199
  np_in = np.flipud(np_in)
200
200
  # print(df_in)
201
201
  # print('finish this bit')
@@ -1194,6 +1194,42 @@ def stitch_loop_individual_fits(*, fit_individually=True,
1194
1194
 
1195
1195
  ## Save settings files
1196
1196
  def save_settings(meta_path, spectra_path, filetype, prefix, prefix_str, file_ext, TruPower):
1197
+ """ This function saves settings so you can load them across multiple notebooks without repition
1198
+
1199
+ Parameters
1200
+ -------------------
1201
+ meta_path: str
1202
+ Path where your metadata is stored
1203
+ spectra_path: str
1204
+ path where your spectra is stored
1205
+ filetype: str
1206
+ Choose from 'Witec_ASCII', 'headless_txt', 'headless_csv', 'head_csv', 'Witec_ASCII', 'HORIBA_txt', 'Renishaw_txt'
1207
+ prefix: bool
1208
+ If True, removes 01, 02, from filename (WITEC problem)
1209
+ Also need to state prefix_str: prefix separating string (in this case, 01 Ne would be ' '
1210
+
1211
+ file_ext: str
1212
+ Extension of file. e.g. txt
1213
+
1214
+ TruPower: bool
1215
+ If WITEC instrument and you have TruPower, set as True
1216
+
1217
+ Returns
1218
+ --------------
1219
+ file called settings.txt with these saved.
1220
+
1221
+
1222
+ """
1223
+ filetype_opts = ['Witec_ASCII', 'headless_txt', 'headless_csv', 'head_csv', 'Witec_ASCII', 'HORIBA_txt', 'Renishaw_txt']
1224
+
1225
+
1226
+ if filetype in filetype_opts:
1227
+ # Proceed with your logic here
1228
+ print(f"Filetype {filetype} is valid.")
1229
+ # You can add more logic here if needed
1230
+ else:
1231
+ raise TypeError(f"Invalid filetype: {filetype}. Supported filetypes are {filetype_opts}")
1232
+
1197
1233
  # Get the current folder
1198
1234
  folder = os.getcwd()
1199
1235