craft-software/Legacy/TF_Control/scripts/Analyze_cooldowns_CRAFT.py
2025-07-04 15:52:40 +02:00

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='')