tg evaluation in dsc

This commit is contained in:
Dominik Demuth 2023-05-22 18:49:49 +02:00
parent 8d55430246
commit b91fbf7621

View File

@ -4,6 +4,7 @@ from typing import Optional
import numpy as np import numpy as np
from scipy.optimize import fsolve from scipy.optimize import fsolve
from scipy.signal import savgol_filter
try: try:
from scipy.integrate import cumulative_trapezoid from scipy.integrate import cumulative_trapezoid
@ -23,6 +24,11 @@ class DSC(Points):
x, unique = np.unique(x, return_index=True) x, unique = np.unique(x, return_index=True)
if 'y_err' in kwargs:
_yerr = kwargs['y_err']
_yerr = np.asarray(_yerr).reshape(np.asarray(x).shape)
kwargs['y_err'] = _yerr[unique]
super().__init__(x, y[unique], **kwargs) super().__init__(x, y[unique], **kwargs)
def get_fictive_cp(self, glass: tuple[float, float], liquid: tuple[float, float]) -> ('DSC', float): def get_fictive_cp(self, glass: tuple[float, float], liquid: tuple[float, float]) -> ('DSC', float):
@ -54,7 +60,8 @@ class DSC(Points):
def equiv_prime(_x, _i): def equiv_prime(_x, _i):
return m * _x + t return m * _x + t
fictive_temperature = np.array([fsolve(equiv, region.x[i], fprime=equiv_prime, args=(i,))[0] for i in range(len(region.x))]) fictive_temperature = np.array(
[fsolve(equiv, region.x[i], fprime=equiv_prime, args=(i,))[0] for i in range(len(region.x))])
t_g_fictive = fictive_temperature[:20].mean() t_g_fictive = fictive_temperature[:20].mean()
region.y = np.gradient(fictive_temperature, region.x) region.y = np.gradient(fictive_temperature, region.x)
@ -62,7 +69,8 @@ class DSC(Points):
return region, t_g_fictive return region, t_g_fictive
def calculate_tnmh(self, p0: list, glass: tuple[float, float], liquid: tuple[float, float], def calculate_tnmh(self, p0: list, glass: tuple[float, float], liquid: tuple[float, float],
tg: float = None, num_points: int = 200, return_fictive: bool = True) -> ('FitResult', Optional[float], Optional[DSC]): tg: float = None, num_points: int = 200, return_fictive: bool = True) \
-> ('FitResult', Optional[float], Optional[DSC]):
dtf_dt, fictive_tg = self.get_fictive_cp(glass, liquid) dtf_dt, fictive_tg = self.get_fictive_cp(glass, liquid)
if tg is None: if tg is None:
@ -83,3 +91,41 @@ class DSC(Points):
return res, tg, dtf_dt return res, tg, dtf_dt
else: else:
return res return res
def glass_transition(self, glass, liquid):
low_idx = tuple(np.argmin(np.abs(self.x - g)) for g in glass)
high_idx = tuple(np.argmin(np.abs(self.x - l)) for l in liquid)
x = self.x[low_idx[0]:high_idx[1]]
y = self.y[low_idx[0]:high_idx[1]]
yy = savgol_filter(y, window_length=min(len(x) // 20, 50), polyorder=1, deriv=1) / np.mean(np.diff(x))
high_idx = (high_idx[0] - low_idx[0], high_idx[1] - low_idx[0])
low_idx = (0, low_idx[1] - low_idx[0])
inflection = np.argmax(yy)
p1 = linregress(x[low_idx[0]:low_idx[1]], y[low_idx[0]:low_idx[1]])
glass_baseline = p1.slope * x + p1.intercept
p2 = linregress(x[high_idx[0]:high_idx[1]], y[high_idx[0]:high_idx[1]])
liquid_baseline = p2.slope * x + p2.intercept
tangent_line = yy[inflection] * (x - x[inflection]) + y[inflection]
onset = np.argmin(np.abs(tangent_line - glass_baseline))
end = np.argmin(np.abs(tangent_line - liquid_baseline))
midpoint = np.argmin(np.abs(y - 0.5 * (liquid_baseline[end] - glass_baseline[onset])))
cut_tangent = np.where((tangent_line > y.min() - 1) & (tangent_line < y.max() + 1))
return {
'onset': (x[onset], glass_baseline[onset]),
'mid': (x[midpoint], y[midpoint]),
'end': (x[end], liquid_baseline[end]),
'inflection': (x[inflection], y[inflection]),
'glass_baseline': np.c_[x, glass_baseline],
'liquid_baseline': np.c_[x, liquid_baseline],
'tangent_line': np.c_[x[cut_tangent], tangent_line[cut_tangent]],
}