193 lines
7.9 KiB
Python
193 lines
7.9 KiB
Python
import os
|
|
import numpy as np
|
|
import datetime
|
|
#import matplotlib.pyplot as plt
|
|
from scipy.optimize import curve_fit
|
|
import csv
|
|
|
|
def calibration_function(x,a,b,c): #Calibration function for Cernox sensors
|
|
return 1/(a + b*np.log(x)+c*np.log(x)**2)
|
|
|
|
def load_AMR_params(path):#loads self.params (the fit parameters) from file and sets self.params to the new values. Is called when load button is pushed
|
|
rows = []
|
|
with open(path, 'r') as file:
|
|
csvreader = csv.reader(file,delimiter = '\t')
|
|
for row in csvreader:
|
|
rows.append(row)
|
|
|
|
#recreate arrays
|
|
coeffs = []
|
|
for r in rows[0][0:45]: #last entry is '' at index 45
|
|
r_short = r[2:-1] #get rid of "[ "at the beginning, and "]" at the end
|
|
r_split = r_short.split(' ') #split at every space
|
|
coeff_list = [x for x in r_split if x != ''] #get rid of empty entries that can occur if a double space was written in the text file
|
|
coeff_list = [float(x) for x in coeff_list] #convert str to float
|
|
coeff_array = np.array(coeff_list)
|
|
coeffs.append([coeff_array,0]) #append a list with a dummy zero, just so the data structure is as it was when self.params is created by the programm
|
|
|
|
params = coeffs
|
|
return params
|
|
|
|
def convert_AMR_Data(Vx,Vy,Vz, params):#is constantly running. If self.convert == True the voltage data is converted to B
|
|
Bx = [0 for i in range(15)] #store converted AMR data
|
|
By = [0 for i in range(15)]
|
|
Bz = [0 for i in range(15)]
|
|
|
|
#solve system of linear equation according to Felix' diss p.49 eq. 3.3.
|
|
for i,V in enumerate(zip(Vx,Vy,Vz)):
|
|
V = np.array(V) #convert tuple from zip into np.array
|
|
V0 = np.array([params[i][0][3],params[i+15][0][3],params[i+30][0][3]]) #get the offset voltages of all sensors in group number i
|
|
S = np.array([params[i][0][0:3],params[i+15][0][0:3],params[i+30][0][0:3]]) #assemble the sensitivity matrix of group number i
|
|
try:
|
|
B = np.linalg.solve(S,V-V0) #solve the linear equation
|
|
except:
|
|
B = [0,0,0]
|
|
print(i)
|
|
Bx[i] = B[0]
|
|
By[i] = B[1]
|
|
Bz[i] = B[2]
|
|
|
|
# print(B)
|
|
# print(i)
|
|
|
|
return [Bx, By, Bz]
|
|
|
|
#paths
|
|
raw_data_path = r"D:\Data\TF_CRAFT_2025-04-28\merged_data_2025_04_28.csv"
|
|
cernox_calibration_data_path = r"D:\Data\TF_CRAFT_2025-04-28\Cernox_Calibration"
|
|
AMR_calibration_folder_path = r"D:\Data\TF_CRAFT_2025-04-28\AMR_Calibration\Short"
|
|
|
|
#import files
|
|
raw_data = np.loadtxt(raw_data_path, skiprows=0)
|
|
cernox_calibration_data_U = np.loadtxt(cernox_calibration_data_path + "\\Cernox_calibration_rawdata_U.txt", skiprows=0)
|
|
cernox_calibration_data_T = np.loadtxt(cernox_calibration_data_path + "\\Cernox_calibration_rawdata_T.txt", skiprows=0)
|
|
|
|
#Import all AMR Calibration Files
|
|
AMR_Calibration_Filename_list = os.listdir(AMR_calibration_folder_path)
|
|
|
|
AMR_Params_List = [] #Parameter list with structure [time in seconds, AMR Parameters]
|
|
|
|
for Filename in AMR_Calibration_Filename_list: #Iterate through all AMR Calibration files and import parameters
|
|
|
|
file_path = AMR_calibration_folder_path +"\\" + Filename #File path of single calibration file
|
|
AMR_Params = load_AMR_params(file_path)
|
|
file_date = datetime.datetime.strptime(Filename[:-10], "%Y-%m-%d_%H-%M-%S") #Date of filename
|
|
file_date_sec = (file_date - datetime.datetime(1970,1,1)).total_seconds() #Date of filename in seconds since 1970
|
|
|
|
AMR_Params_List.append([file_date_sec, AMR_Params])
|
|
|
|
|
|
# AMR_Params = load_AMR_params(AMR_calibration_data_path)
|
|
|
|
row_count = len(raw_data[:,0])
|
|
|
|
Cernox_fit_params = []
|
|
|
|
for i in range(0,8): #Perform fit for all 8 Cernox sensors
|
|
Params, Cov = curve_fit(calibration_function, cernox_calibration_data_U[:,i], cernox_calibration_data_T[:,i])
|
|
|
|
Umin = np.min(cernox_calibration_data_U[:,i])
|
|
Umax = np.max(cernox_calibration_data_U[:,i])
|
|
|
|
#Create list of U_values and calculate T values for plotting purposes
|
|
U_values = np.linspace(Umin*0.95, Umax*1.05, 1000)
|
|
T_fit = calibration_function(U_values, *Params)
|
|
|
|
Cernox_fit_params.append([Params,Umin, Umax]) #Save fit params and Umin and Umax in Cernox_fit_params list
|
|
|
|
# plt.plot(U_values, T_fit, linestyle="--", label=f"Fit of Cernox {i}")
|
|
# plt.plot(cernox_calibration_data_U[:,i], cernox_calibration_data_T[:,i], marker="x", label=f"Data of Cernox {i}")
|
|
|
|
# plt.legend()
|
|
# plt.xlabel("Resistance (Ohm)")
|
|
# plt.ylabel("Temperature (K)")
|
|
# plt.title("Cernox calibration fits")
|
|
# plt.show()
|
|
|
|
|
|
#UNCOMMENT PART
|
|
|
|
#list of all datetime objects for every measurement point
|
|
date_list = []
|
|
calibrated_data = raw_data
|
|
|
|
#New data structure: 1. Column: Time, 2-9 Column: Cernox, 10-54 Column: AMRx, AMRy, AMRz, 3 fluxgate
|
|
new_calibrated_data = np.empty(shape=(row_count,1+8+45+3)) #timestamp + 8 cernox + 45 amr + 3 fluxgate
|
|
|
|
for i in range(0,row_count):
|
|
|
|
#Convert seconds to datetime objects, which will be stored in date_list
|
|
date_in_sec = raw_data[i,0]
|
|
date = datetime.datetime(1970,1,1) + datetime.timedelta(seconds= date_in_sec)
|
|
date_list.append(date)
|
|
|
|
new_list = [date_in_sec]
|
|
|
|
#Convert cernox voltages to temperature values
|
|
V_Cernox_List = raw_data[i,-8:] #List of Cernox voltages at measurement point i
|
|
# print(V_Cernox_List)
|
|
for i_Cernox in range(0,8):
|
|
V_Cernox = V_Cernox_List[i_Cernox]
|
|
# print(V_Cernox)
|
|
if V_Cernox >= Cernox_fit_params[i_Cernox][1] and V_Cernox <= Cernox_fit_params[i_Cernox][2]:
|
|
T_Cernox = calibration_function(V_Cernox, *Cernox_fit_params[i_Cernox][0])
|
|
else:
|
|
T_Cernox = 0
|
|
calibrated_data[i,-8+i_Cernox] = T_Cernox
|
|
new_list.append(T_Cernox)
|
|
|
|
#Perform AMR calibration
|
|
AMR_Ux = [raw_data[i][1+j] for j in [0,3,4,9,12,13,18,21,22,28,31,32,37,40,41]] #1+j since first column is time in seconds
|
|
AMR_Uy = [raw_data[i][1+j] for j in [8,7,6,17,16,15,27,26,25,36,35,34,45,44,43]] #1+j since first column is time in seconds
|
|
AMR_Uz = [raw_data[i][1+j] for j in [1,2,5,10,11,14,19,20,24,29,30,33,38,39,42]] #1+j since first column is time in seconds
|
|
|
|
#Find matching AMR Parameters (according to time of measurements and time of calibration)
|
|
for j in range(0,len(AMR_Params_List)):
|
|
Calibration_time = AMR_Params_List[j][0] #Time in seconds in which AMR calibration was performed
|
|
if j < len(AMR_Params_List)-1:
|
|
NextCalibration_time = AMR_Params_List[j+1][0]
|
|
else:
|
|
NextCalibration_time = 10e12
|
|
|
|
if date_in_sec >= Calibration_time and date_in_sec < NextCalibration_time:
|
|
AMR_Params = AMR_Params_List[j][1]
|
|
|
|
save_times = [Calibration_time, NextCalibration_time] #Save times of picked AMR Params for debugging purposes
|
|
|
|
Converted_AMR = convert_AMR_Data(AMR_Ux, AMR_Uy, AMR_Uz, AMR_Params)
|
|
for AMR_Direction in Converted_AMR:
|
|
for AMR_Sensor_B in AMR_Direction:
|
|
new_list.append(AMR_Sensor_B)
|
|
|
|
#append FluxGate data
|
|
FluxGate_B = [100*raw_data[i][1+j] for j in [46,47,48]] #fluxgate data in µT
|
|
|
|
for FluxGate_value in FluxGate_B:
|
|
new_list.append(FluxGate_value)
|
|
# print(FluxGate_value)
|
|
|
|
|
|
new_calibrated_data[i,:] = new_list
|
|
|
|
if i%1000 == 0:
|
|
print(f"Loading... {np.round(100*i/row_count,1)} % calibrated.")
|
|
|
|
# print(f"Measurement point time = {date_in_sec} s, {save_times} s")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# np.savetxt("D:\\Dokumente\\Masterarbeit\\Auswertung\\TF Analyse\\calibrated_data_test.csv", calibrated_data)
|
|
np.savetxt(r"D:\Data\TF_CRAFT_2025-04-28\calibrated_data_2025_04_28.csv", new_calibrated_data)
|
|
|
|
# for i in range(0,8):
|
|
# plt.plot(calibrated_data[:,0], calibrated_data[:,-8+i], label=f"Cernox {i}")
|
|
|
|
# plt.xlabel("time (sec)")
|
|
# plt.ylabel("Temperature (K)")
|
|
# plt.legend()
|
|
# plt.show() |