dsc: only use low temperature to baseline correct calibration without enthalpy
This commit is contained in:
		| @@ -5,6 +5,8 @@ import re | ||||
| from collections import namedtuple | ||||
|  | ||||
| import numpy as np | ||||
| from matplotlib import pyplot as plt | ||||
| from scipy.stats import linregress | ||||
|  | ||||
| try: | ||||
|     from scipy.integrate import simpson | ||||
| @@ -200,35 +202,24 @@ class DSCCalibrator: | ||||
|                 high_border = np.argmin(np.abs(measurement[0] - t_high_lim)) | ||||
|                 ref_zoom = measurement[:, low_border:high_border] | ||||
|  | ||||
|                 x_val = np.array([[ref_zoom[0, 0], 1], [ref_zoom[0, -1], 1]]) | ||||
|                 y_val = np.array([ref_zoom[1, 0], ref_zoom[1, -1]]) | ||||
|  | ||||
|                 sol = np.linalg.solve(x_val, y_val) | ||||
|                 ref_zoom[1] -= (ref_zoom[0] * sol[0] + sol[1]) | ||||
|  | ||||
|                 ref_grad = np.gradient(ref_zoom[1]) | ||||
|                 crossing = np.where(np.diff(np.sign(np.abs(ref_grad)-0.001)))[0] | ||||
|  | ||||
|                 almost_flat = np.sort(crossing-np.argmax(ref_zoom[1])) | ||||
|                 integ_limit = (almost_flat[np.where((almost_flat < -20))[0][-1]]+np.argmax(ref_zoom[1]), | ||||
|                                almost_flat[np.where((almost_flat > 20))[0][0]]+np.argmax(ref_zoom[1])) | ||||
|  | ||||
|                 # subtract baseline around reference peak | ||||
|                 sol = self.solve_linear_eq(integ_limit, ref_zoom) | ||||
|                 ref_zoom[1] -= (ref_zoom[0] * sol[0] + sol[1]) | ||||
|  | ||||
|                 # calculate onset slope (use points at position of maximum gradient - 100/rate (+50/rate)) | ||||
|                 ref_grad = np.gradient(ref_zoom[1]) | ||||
|                 max_grad = np.argmax(ref_grad) | ||||
|  | ||||
|                 grad_pos = max_grad-max(1, int(160 / rate)), max_grad | ||||
|  | ||||
|                 sol = self.solve_linear_eq(grad_pos, ref_zoom) | ||||
|                 onset = sol[0] * ref_zoom[0] + sol[1] | ||||
|  | ||||
|                 melts.append(-sol[1] / sol[0]) | ||||
|  | ||||
|                 if enthalpy is not None: | ||||
|                     x_val = np.array([[ref_zoom[0, 0], 1], [ref_zoom[0, -1], 1]]) | ||||
|                     y_val = np.array([ref_zoom[1, 0], ref_zoom[1, -1]]) | ||||
|  | ||||
|                     sol = np.linalg.solve(x_val, y_val) | ||||
|                     ref_zoom[1] -= (ref_zoom[0] * sol[0] + sol[1]) | ||||
|  | ||||
|                     ref_grad = np.gradient(ref_zoom[1]) | ||||
|                     crossing = np.where(np.diff(np.sign(np.abs(ref_grad)-0.001)))[0] | ||||
|  | ||||
|                     almost_flat = np.sort(crossing-np.argmax(ref_zoom[1])) | ||||
|                     integ_limit = (almost_flat[np.where((almost_flat < -40))[0][-1]]+np.argmax(ref_zoom[1]), | ||||
|                                    almost_flat[np.where((almost_flat > 40))[0][0]]+np.argmax(ref_zoom[1])) | ||||
|  | ||||
|                     # subtract baseline around reference peak | ||||
|                     sol = self.solve_linear_eq(integ_limit, ref_zoom) | ||||
|                     ref_zoom[1] -= (ref_zoom[0] * sol[0] + sol[1]) | ||||
|  | ||||
|                     # integrate over peak to calibrate y axis | ||||
|                     # delta H in J/g: Integrate Peak over time and divide by weight | ||||
|                     area = simpson(ref_zoom[1, integ_limit[0]:integ_limit[1]], | ||||
| @@ -236,6 +227,23 @@ class DSCCalibrator: | ||||
|                                    even='avg') * 1e-3 | ||||
|                     calib_y.append(enthalpy / (area / data.weight)) | ||||
|  | ||||
|                 else: | ||||
|                     ref_grad = np.gradient(ref_zoom[1]) | ||||
|                     res = linregress(ref_zoom[0, :len(ref_grad)//5], ref_zoom[1, :len(ref_grad)//5]) | ||||
|  | ||||
|                     ref_zoom[1] -= (res.slope*ref_zoom[0] + res.intercept) | ||||
|  | ||||
|                 # calculate onset slope (use points at position of maximum gradient - 100/rate (+50/rate)) | ||||
|                 ref_grad = np.gradient(ref_zoom[1]) | ||||
|                 max_grad = np.argmax(ref_grad) | ||||
|  | ||||
|                 grad_pos = max_grad - max(1, int(160 / rate)), max_grad | ||||
|  | ||||
|                 sol = self.solve_linear_eq(grad_pos, ref_zoom) | ||||
|                 onset = sol[0] * ref_zoom[0] + sol[1] | ||||
|  | ||||
|                 melts.append(-sol[1] / sol[0]) | ||||
|  | ||||
|                 results.append([ref_zoom, onset, ref_zoom[:, grad_pos]]) | ||||
|  | ||||
|         if len(melts) > 1: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user