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()