204 lines
11 KiB
Python
204 lines
11 KiB
Python
import numpy as np
|
|
import matplotlib.pyplot as plt
|
|
import datetime as dt
|
|
from scipy.optimize import curve_fit
|
|
|
|
# Define linear fit function:
|
|
def linear_fit(x, a, b):
|
|
return a+b*x
|
|
|
|
# Define smooth_transition function for correcting not-linear section in the beginning of the cooldown
|
|
def smooth_transition(x, a, b, c, x0):
|
|
"""
|
|
A function that is constant before t0 and transitions smoothly into a linear function after t0.
|
|
|
|
Parameters:
|
|
t : array-like, time values
|
|
t0 : float, transition point
|
|
a : float, constant value before t0
|
|
b : float, slope of the linear function after t0
|
|
c : float, controls the smoothness of the transition
|
|
|
|
Returns:
|
|
array-like, function values
|
|
"""
|
|
return a + (b * (x - x0)) / (1 + np.exp(-c * np.clip(x - x0, -100, 100)))
|
|
|
|
# Define the path to the converted CSV file
|
|
data_path = r'/Users/alexandercierpka/Documents/Eigene Dokumente/Universität/Masterarbeit/Daten/TF_CRAFT_2025-03-06/calibrated_data_2025_03_06.csv'
|
|
|
|
|
|
#Define the path to the points.txt file
|
|
good_points_path = r'/Users/alexandercierpka/Documents/Eigene Dokumente/Universität/Masterarbeit/Daten/TF_CRAFT_2025-03-06/points/good points/good_points2.txt'
|
|
|
|
|
|
# Load the CSV file as a numpy array
|
|
data = np.loadtxt(data_path, delimiter=' ', dtype=float) # Load the CSV file as a numpy array, column 0 is time, column 1-8 are the temperatures of the 8 Cernox sensors, followed by AMR, followed by FG
|
|
|
|
# Correct for imc timeshift:
|
|
data[:,0] = data[:,0] - (1737650746.34 - 1737650711) - 4 -33 # Correct the time shift of the data 2025_03_06
|
|
|
|
# Load the points.txt file as a numpy array
|
|
points = np.loadtxt(good_points_path, delimiter='\t', dtype=str, skiprows=1) # Load the points.txt file as a numpy array, column 0: t_start, column 1: t_stop, column 2: t_save, columne 3,4,5: B_start_x, y, z
|
|
|
|
# GENERAL PARAMETERS
|
|
|
|
# "Tc" measured by the two Cernox sensors (Temperature at which AMR sensors start to measure superconducting transition). This Tc is NOT the real Tc of the material
|
|
Tc_top = 9.62 #Critical temperature of the superconductor for the top sensor
|
|
Tc_bottom = 9.7 #Critical temperature of the superconductor for the bottom sensor
|
|
|
|
Distance = 9.2 #Distance between Cernox 1 and 8 in cm
|
|
Sample_length = 10 #Length of the sample in cm
|
|
|
|
# Timepoints t_Tc_start / _stop are calculated automatically by checking time when Cernox 1 and 8 transition Tc_top and Tc_bottom. Use this delta to adjust the time interval.
|
|
t_Tc_start_delta = 0
|
|
t_Tc_stop_delta = 0
|
|
|
|
#Define cooldown_array to save all cooldown parameters
|
|
cooldown_parameters = np.empty((0,15))
|
|
|
|
# Go through all points and calculate the cooldown parameters
|
|
total_points = len(points[:,0]) # Total number of points
|
|
for i in range(total_points):
|
|
t_start = points[i,0]
|
|
t_stop = points[i,1]
|
|
t_save = points[i,2]
|
|
B_start = points[i,3:6]
|
|
|
|
# Convert time strings to floats (seconds since 01.01.1970)
|
|
time_format = '%Y-%m-%d_%H-%M-%S'
|
|
t_start_sec = (dt.datetime.strptime(t_start, time_format) - dt.datetime(1970,1,1)).total_seconds()
|
|
t_stop_sec = (dt.datetime.strptime(t_stop, time_format) - dt.datetime(1970,1,1)).total_seconds()
|
|
t_save_sec = (dt.datetime.strptime(t_save, time_format) - dt.datetime(1970,1,1)).total_seconds()
|
|
|
|
# Convert B_start to floats
|
|
B_start = B_start.astype(float)
|
|
|
|
# Find the indices of the data array which are between t_start and t_save
|
|
cooldown_indices = np.where((data[:,0] >= t_start_sec) & (data[:,0] <= t_save_sec))
|
|
|
|
#Calculate t_Tc_start: Lowest timepoint where Tc is reached by Cernox 1 OR 8. "OR" is important, because CRAFT allows for negative gradients during cooldown
|
|
t_Tc_start = np.min(data[cooldown_indices,0][0][np.where((data[cooldown_indices,1][0] <= Tc_top) | (data[cooldown_indices,8][0] <= Tc_bottom))])
|
|
#Calculate t_Tc_stop: Highest timepoint where Tc is reached by Cernox 1 OR 8
|
|
t_Tc_stop = np.max(data[cooldown_indices,0][0][np.where((data[cooldown_indices,1][0] >= Tc_top) | (data[cooldown_indices,8][0] >= Tc_bottom))])
|
|
|
|
# Smooth_transition fit to the temperature data of Cernox 1 and 8, from t_Tc_start - t_Tc_start_delta until t_Tc_stop + t_Tc_stop_delta
|
|
# Often a linear fit is sufficient. But when the sc transitions starts immediately after cooldown start, the temperature data is not linear in the beginning.
|
|
|
|
fit_indices = np.where((data[cooldown_indices,0][0] >= t_Tc_start - t_Tc_start_delta) & (data[cooldown_indices,0][0] <= t_Tc_stop + t_Tc_stop_delta)) # Indices of the data array which are in the interesting time interval
|
|
t0 = data[cooldown_indices,0][0][fit_indices[0][0]] #Set t0 to the first timepoint of the fit_indices. Reduces the number of digits in the fit parameters...
|
|
t_T1 = data[cooldown_indices,0][0][fit_indices] - t0
|
|
y_T1 = data[cooldown_indices,1][0][fit_indices]
|
|
t_T8 = data[cooldown_indices,0][0][fit_indices] - t0
|
|
y_T8 = data[cooldown_indices,8][0][fit_indices]
|
|
# Fit the smooth_transition function to the data
|
|
popt_T1, pcov_T1 = curve_fit(smooth_transition, t_T1, y_T1, p0=[y_T1[0], -0.03, 0.1, 30], maxfev=10000)
|
|
popt_T8, pcov_T8 = curve_fit(smooth_transition, t_T8, y_T8, p0=[y_T8[0], -0.03, 0.1, 30], maxfev=10000)
|
|
y_T1_fit = smooth_transition(t_T1, *popt_T1)
|
|
y_T8_fit = smooth_transition(t_T8, *popt_T8)
|
|
|
|
# print(f"Fit parameters Cernox 1: {popt_T1}")
|
|
# print(f"Fit parameters Cernox 8: {popt_T8}")
|
|
|
|
# Linear fit for calculating cooldown speed
|
|
|
|
popt_T1_linear, pcov_T1_linear = curve_fit(linear_fit, t_T1, y_T1)
|
|
popt_T8_linear, pcov_T8_linear = curve_fit(linear_fit, t_T8, y_T8)
|
|
y_T1_linearfit = linear_fit(t_T1, *popt_T1_linear)
|
|
y_T8_linearfit = linear_fit(t_T8, *popt_T8_linear)
|
|
|
|
|
|
#Calculate cooldown speed using the linear fit.
|
|
cooldown_speed_T1 = popt_T1_linear[1]
|
|
cooldown_speed_T1_std = np.sqrt(np.diag(pcov_T1_linear))[1]
|
|
cooldown_speed_T8 = popt_T8_linear[1]
|
|
cooldown_speed_T8_std = np.sqrt(np.diag(pcov_T8_linear))[1]
|
|
#Calculate the mean cooldown speed
|
|
cooldown_speed = np.mean([cooldown_speed_T1, cooldown_speed_T8])
|
|
#Calculate the std of the mean cooldown speed
|
|
cooldown_speed_std = np.sqrt(cooldown_speed_T1_std**2 + cooldown_speed_T8_std**2)
|
|
|
|
#Calculate the mean and std temperature gradient by calc. difference of y_T1 and y_T8 for each x inbetween t_Tc_start and t_Tc_stop. Here, smooth_transition fit could be crucial!
|
|
Gradients = (y_T1_fit - y_T8_fit) / Distance
|
|
Gradients = Gradients[np.where((t_T1 + t0 >= t_Tc_start) & (t_T1 +t0 <= t_Tc_stop))]
|
|
mean_gradient = np.mean(Gradients)
|
|
std_gradient = np.std(Gradients)
|
|
|
|
#B0: B-field of AMR sensor 8 at t_start
|
|
B0 = [data[cooldown_indices,16][0][0], data[cooldown_indices,31][0][0], data[cooldown_indices,46][0][0]]
|
|
B0_std = 1.5 #Hardcoded error of the AMR sensor
|
|
|
|
#Trapped flux: B-field of AMR sensor 8 at t_save (B=sqrt(Bx^2+By^2+Bz^2))
|
|
TF = np.sqrt(data[cooldown_indices,16][0][-1]**2 + data[cooldown_indices,31][0][-1]**2 + data[cooldown_indices,46][0][-1]**2)
|
|
TF_std = 1.5 #Hardcoded error of the AMR sensor
|
|
|
|
#Save the cooldown parameters to the cooldown_array
|
|
cooldown_parameters = np.append(cooldown_parameters, [[t_start_sec, t_stop_sec, t_save_sec, t_Tc_start, t_Tc_stop, cooldown_speed, cooldown_speed_std, mean_gradient, std_gradient, TF, TF_std, B0[0], B0[1], B0[2], B0_std]], axis=0)
|
|
|
|
print(f"Cooldown {i+1} done.")
|
|
|
|
|
|
# Plot Cernox 1 and Cernox 8 and AMR 8y with two y-axes.
|
|
#COMMENT THE FOLLOWING LINES TO PREVENT PLOTTING EACH COOLDOWN
|
|
fig, ax1 = plt.subplots()
|
|
ax1.plot(data[cooldown_indices,0][0], data[cooldown_indices,1][0], label='Sample Cernox 1', color='tab:blue')
|
|
ax1.plot(data[cooldown_indices,0][0], data[cooldown_indices,8][0], label='Sample Cernox 8', color='tab:orange')
|
|
ax1.set_xlabel("Time (s)")
|
|
ax1.set_ylabel("Temperature (K)", color='tab:blue')
|
|
ax1.tick_params(axis='y', labelcolor='tab:blue')
|
|
ax2 = ax1.twinx()
|
|
ax2.plot(data[cooldown_indices,0][0], np.abs(data[cooldown_indices,31][0]), label='AMR Sensor 8y', color='tab:green')
|
|
ax2.plot(data[cooldown_indices,0][0], np.abs(data[cooldown_indices,25][0]), label='AMR Sensor 2y', color='tab:green')
|
|
ax2.plot(data[cooldown_indices,0][0], np.abs(data[cooldown_indices,37][0]), label='AMR Sensor 14y', color='tab:green')
|
|
ax2.set_ylabel("Absolute magnetic Field (μT)", color='tab:green')
|
|
ax2.tick_params(axis='y', labelcolor='tab:green')
|
|
plt.title(f"Cooldown {i+1}")
|
|
|
|
# Plot the linear fits
|
|
ax1.plot(t_T1+t0, smooth_transition(t_T1, *popt_T1), color='tab:red', linestyle='dashed', label='Fit Cernox 1')
|
|
ax1.plot(t_T8+t0, smooth_transition(t_T8, *popt_T8), color='tab:purple', linestyle='dashed', label='Fit Cernox 8')
|
|
|
|
# Plot t_start, t_stop, t_save as vertical dashed lines
|
|
ax1.axvline(x=t_start_sec, color='black', linestyle='dashed')
|
|
ax1.axvline(x=t_stop_sec, color='black', linestyle='dashed')
|
|
ax1.axvline(x=t_save_sec, color='black', linestyle='dashed')
|
|
|
|
plt.show()
|
|
# COMMENT END
|
|
|
|
|
|
# # Center the data by fitting a gauss + lorentz
|
|
# def gauss_lorentz(x, a, b, c, d, e):
|
|
# exponent = -b*(x-c)**2
|
|
# exponent_clip = np.clip(exponent, -100, 100)
|
|
# return a*np.exp(exponent_clip) + d/(1+e*(x-c)**2)
|
|
|
|
# # popt, pcov = curve_fit(gauss_lorentz, cooldown_parameters[:,7], cooldown_parameters[:,9], maxfev=10000)
|
|
# # print(popt[2])
|
|
|
|
#Import mVTS data
|
|
mVTS_data_path = r'/Users/alexandercierpka/Documents/Eigene Dokumente/Universität/Masterarbeit/Daten/mVTS Daten/LG-01/LG-01_TF_vs_Gradient.txt'
|
|
mVTS_data = np.loadtxt(mVTS_data_path, delimiter='\t', dtype=float, skiprows=1)
|
|
|
|
|
|
#Plot TF vs Gradient
|
|
fig, ax1 = plt.subplots()
|
|
ax1.errorbar(cooldown_parameters[:,7], cooldown_parameters[:,9], xerr=cooldown_parameters[:,8], yerr=cooldown_parameters[:,10], fmt='x', capsize= 3, label="CRAFT")
|
|
ax1.set_xlabel("Temperature Gradient (K/cm)")
|
|
ax1.set_ylabel("Trapped Flux (μT)")
|
|
|
|
#Plot mVTS data
|
|
# ax1.plot(mVTS_data[:,0], mVTS_data[:,1], 'x', label='mVTS')
|
|
ax1.errorbar(mVTS_data[:,0], mVTS_data[:,1], xerr=mVTS_data[:,2], yerr=mVTS_data[:,3], fmt='x', capsize=3, label='mVTS')
|
|
plt.title("Trapped Flux vs Temperature Gradient")
|
|
plt.grid()
|
|
plt.legend()
|
|
plt.show()
|
|
|
|
|
|
# Save the cooldown parameters to a txt file
|
|
cooldown_parameters_path = r'/Users/alexandercierpka/Documents/Eigene Dokumente/Universität/Masterarbeit/Daten/TF_CRAFT_2025-03-06/Auswertung/Cooldowns_TF_vs_Gradient_V3.txt'
|
|
|
|
|
|
|
|
# np.savetxt(cooldown_parameters_path, cooldown_parameters, delimiter='\t', header='t_start\tt_stop\tt_save\tt_Tc_start\tt_Tc_stop\tcooldown_speed\tcooldown_speed_std\tmean_gradient\tstd_gradient\tTF\tTF_std\tB0\tB0_std', comments='') |