diff --git a/fishgrid.cfg b/fishgrid.cfg index 624374b..3f8c7e9 100644 --- a/fishgrid.cfg +++ b/fishgrid.cfg @@ -5,6 +5,7 @@ RecordMode1 : standalone Columns1 : 2 Rows1 : 4 + Extra1 : 0 ColumnDistance1 : 50.0cm RowDistance1 : 50.0cm ElectrodeType1 : headstage diff --git a/rasp_grid.py b/rasp_grid.py index 2395c9e..3cf3132 100644 --- a/rasp_grid.py +++ b/rasp_grid.py @@ -1,5 +1,6 @@ from __future__ import print_function import os +import sys import glob import datetime from shutil import copyfile @@ -9,10 +10,9 @@ except: pass import subprocess import numpy as np -import matplotlib.pyplot as plt +import threading +import multiprocessing as mp from time import sleep, time -from os import system -from sys import stdout from IPython import embed from uldaq import (get_daq_device_inventory, DaqDevice, AInScanFlag, ScanStatus, @@ -56,35 +56,37 @@ def read_cfg(cfg_file, now, init_read=False): path_format = ':'.join(line.split(':')[1:]).strip().replace('"', '').replace("'", "") cfg_f.close() return path_format + else: + for line in cfg: + if 'Columns1' in line: + n_cols = int(line.split(':')[1].strip()) + elif 'Rows1' in line: + n_rows = int(line.split(':')[1].strip()) + elif 'Extra1' in line: + n_extra = int(line.split(':')[1].strip()) + elif "AISampleRate" in line: + samplerate = int(float(line.split(':')[-1].strip().replace('kHz', '')) * 1000) + elif "AIMaxVolt" in line: + max_v = float(line.split(':')[1].strip().replace('mV', '')) + elif 'Gain' in line: + gain = int(line.split(':')[1].strip()) + gain = int(line.split(':')[1].strip()) + channels = n_rows * n_cols + n_extra + + ### alter information and re-write ### + for enu, line in enumerate(cfg): + if "StartDate" in line: + cfg[enu] = (' StartDate : %s\n' % now.strftime('%Y-%m-%d')) + elif "StartTime" in line: + cfg[enu] = (' StartTime : %s\n' % (now.strftime('%H:%M:%S') + now.strftime(".%f")[:4])) + cfg_f.close() + + cfg_f = open(cfg_file, 'w+') + for line in cfg: + cfg_f.write(line) + cfg_f.close() - for line in cfg: - if 'Columns1' in line: - n_cols = int(line.split(':')[1].strip()) - elif 'Rows1' in line: - n_rows = int(line.split(':')[1].strip()) - elif "AISampleRate" in line: - samplerate = int(float(line.split(':')[-1].strip().replace('kHz', '')) * 1000) - elif "AIMaxVolt" in line: - max_v = float(line.split(':')[1].strip().replace('mV', '')) - elif 'Gain' in line: - gain = int(line.split(':')[1].strip()) - channels = n_rows * n_cols - - ### alter information and re-write ### - for enu, line in enumerate(cfg): - if "StartDate" in line: - cfg[enu] = (' StartDate : %s\n' % now.strftime('%Y-%m-%d')) - elif "StartTime" in line: - cfg[enu] = (' StartTime : %s\n' % (now.strftime('%H:%M:%S') + now.strftime(".%f")[:4])) - cfg_f.close() - - cfg_f = open(cfg_file, 'w+') - for line in cfg: - cfg_f.write(line) - cfg_f.close() - - return channels, samplerate, n_cols, n_rows, max_v, gain - + return channels, samplerate, n_cols, n_rows, max_v, gain # for line in cfg: # if 'Columns1' in line: # self.Grid.columns_val = int(line.split(':')[1].strip()) @@ -156,9 +158,165 @@ def read_cfg(cfg_file, now, init_read=False): # continue +def led_controll(pin, t0, dt, stop_flag, save_f=None): + next = t0 + + while True: + if stop_flag(): + break + if time() > next: + save_t = next + time() - next + GPIO.output(pin, GPIO.HIGH) + sleep(0.1) + GPIO.output(pin, GPIO.LOW) + + if save_f != None: + save_f.write('%.4f' % (save_t)) + save_f.flush() + next += dt + + + +def temp_rec(w1_bus_path, temp_f, t0, dt, stop_flag): + next = t0 + while True: + if stop_flag(): + break + if time() > next: + w1_f = open(w1_bus_path, 'r') + w1_file = w1_f.readlines() + for line in w1_file: + if 't=' in line: + temp = float((line.split('=')[-1].strip())) / 1000 + temp_f.write('%6.0f; %7.3f\n' % (next, temp)) + temp_f.flush() + break + w1_f.close() + next += dt + +def clock_controll(end_clock, run_led_pin, sync_led_pin, w1_bus_path, temp_f, led_f, stop_flag): + t0 = time() + sub_stop_flag = False + + run_led_interval = 2 + run_thread = threading.Thread(target=led_controll, args=(run_led_pin, t0, run_led_interval, lambda: sub_stop_flag, None)) + + sync_led_interval = 1 + sync_thread = threading.Thread(target=led_controll, args=(sync_led_pin, t0, sync_led_interval, lambda: sub_stop_flag, led_f)) + + temp_interval = 300 + temp_thread = threading.Thread(target=temp_rec, args=(w1_bus_path, temp_f, t0, temp_interval, lambda: sub_stop_flag)) + + run_thread.start() + sync_thread.start() + temp_thread.start() + + while True: + if stop_flag(): + sub_stop_flag = True + sync_thread.join() + run_thread.join() + break + if datetime.datetime.now().hour == end_clock[0] and datetime.datetime.now().minute == end_clock[1]: + break + +# def duration_control(end_clock, stop_flag): +# while True: +# if stop_flag(): +# break +# +# if datetime.datetime.now().hour == end_clock[0] and datetime.datetime.now().minute == end_clock[1]: +# break +# +# def led_controll_box(LED_t, LED1_pin, LED_out_pin, led_f, stop_flag): +# LED_t_interval = 2 +# out_LED_interval = 1 +# +# led_on_times = [] +# +# status0 = False +# status1 = False +# while True: +# if stop_flag(): +# GPIO.output(LED1_pin, GPIO.LOW) +# GPIO.output(LED_out_pin, GPIO.LOW) +# break +# +# if (time() - LED_t) % LED_t_interval < .1: +# status0 = True +# GPIO.output(LED1_pin, GPIO.HIGH) +# elif (time() - LED_t) % LED_t_interval >= .1 and status0 == True: +# status0 = False +# GPIO.output(LED1_pin, GPIO.LOW) +# else: +# pass +# +# if (time() - LED_t) % out_LED_interval < .1: +# status1 = True +# GPIO.output(LED_out_pin, GPIO.HIGH) +# +# led_on_times.append(time() - LED_t) +# led_f.write('%.4f' % (time() - LED_t)) +# led_f.flush() +# elif (time() - LED_t) % out_LED_interval >= .1 and status1 == True: +# GPIO.output(LED_out_pin, GPIO.LOW) +# status1 = False +# else: +# pass + +# def record_temperature(temp_t0, w1_bus_path, temp_f, stop_flag): +# next_temp_t = 0 +# temp_interval = 300 +# +# while True: +# if stop_flag(): +# break +# +# if time() - temp_t0 > next_temp_t: +# w1_f = open(w1_bus_path, 'r') +# w1_file = w1_f.readlines() +# for line in w1_file: +# if 't=' in line: +# temp = float((line.split('=')[-1].strip())) / 1000 +# temp_f.write('%6.0f; %7.3f\n' % (next_temp_t, temp)) +# temp_f.flush() +# break +# +# w1_f.close() +# next_temp_t += temp_interval + def main(): + LED1_pin = 11 + LED2_pin = 13 + LED_out_pin = 35 + Button1_pin = 16 + Button2_pin = 18 + power_controll_pin = 37 + + LED_status = GPIO_setup(LED1_pin, LED2_pin, LED_out_pin, Button1_pin, Button2_pin, power_controll_pin) + + # switch LEDs off + GPIO.output(LED1_pin, GPIO.LOW) + LED_status[0] = False + GPIO.output(LED2_pin, GPIO.LOW) + LED_status[1] = False + + last_button_2_t = time() + now = datetime.datetime.now() + # defined start and end time + valid = False + if len(sys.argv) == 3: + if len(sys.argv[1]) == 4 and len(sys.argv[2]) == 4: + start_clock = [int(sys.argv[1][:2]), int(sys.argv[1][2:])] + end_clock = [int(sys.argv[2][:2]), int(sys.argv[2][2:])] + valid = True + if not valid: + start_clock = [10, 00] + end_clock = [16, 00] + + # get init cfg if os.path.exists('/media/pi/data1'): init_path = '/media/pi/data1' @@ -179,38 +337,28 @@ def main(): cfgfile = os.path.join(path, 'fishgrid.cfg') # read and edit config file - channels, rate, n_cols, n_rows, max_v, gain = read_cfg(init_cfgfile, now) - + channels, rate, n_cols, n_rows, max_v, gain = read_cfg(cfgfile, now) file = os.path.join(path, 'traces-grid1.raw') temp_file = os.path.join(path, 'temperatures.csv') + led_file = os.path.join(path, 'led_times.csv') + # find w1bus for temp record_temp = False + temp_f = None w1_bus_path = glob.glob('/sys/bus/w1/devices/28*/w1_slave') if len(w1_bus_path) > 0: w1_bus_path = w1_bus_path[0] record_temp = True + temp_f = open(temp_file, 'w') + temp_f.write('%-6s; %-7s\n' % ('time/s', 'T/C')) + f = open(file, 'wb') - temp_f = open(temp_file, 'w') - temp_f.write('%-6s; %-7s\n' % ('time/s', 'T/C')) + led_f = open(led_file, 'w') # f.close() - LED1_pin = 11 - LED2_pin = 13 - LED_out_pin = 35 - Button1_pin = 16 - Button2_pin = 18 - power_controll_pin = 37 - - LED_status = GPIO_setup(LED1_pin, LED2_pin, LED_out_pin, Button1_pin, Button2_pin, power_controll_pin) - - last_button_1_t = time() - last_button_2_t = time() - # DAQ setup if True: - # channels = 16 - status = ScanStatus.IDLE descriptor_index = 0 # ToDo: ???? @@ -218,9 +366,11 @@ def main(): interface_type = InterfaceType.USB low_channel = 0 - high_channel = channels + high_channel = channels - 1 samples_per_channel = rate * 20 # * channels = Buffer size + buffer_size = samples_per_channel * channels + print('channels: %.0f' % channels) # rate = 20000 scan_options = ScanOption.CONTINUOUS flags = AInScanFlag.DEFAULT @@ -238,7 +388,7 @@ def main(): # Create the DAQ device object associated with the specified descriptor index. daq_device = None daq_device = DaqDevice(devices[descriptor_index]) - + # Get the AiDevice object and verify that it is valid. ai_device = None ai_device = daq_device.get_ai_device() @@ -279,133 +429,138 @@ def main(): break print(ranges[range_index]) - # Allocate a buffer to receive the data. - # f = open('/media/pi/data1/test_file.raw', 'wb') + GPIO.output(LED1_pin, GPIO.HIGH) + LED_status[0] = True + GPIO.output(LED2_pin, GPIO.HIGH) + LED_status[0] = True + sleep(.5) + + GPIO.output(LED1_pin, GPIO.LOW) + LED_status[0] = False + GPIO.output(LED2_pin, GPIO.LOW) + LED_status[0] = False + sleep(.5) - # LED on when here ... wait for switch to start data aquisition GPIO.output(LED1_pin, GPIO.HIGH) LED_status[0] = True - while GPIO.input(Button1_pin) == GPIO.LOW: - sleep(.1) + GPIO.output(LED2_pin, GPIO.HIGH) + LED_status[0] = True + sleep(.5) + GPIO.output(LED1_pin, GPIO.LOW) LED_status[0] = False - sleep(2.) + + disp_eth_power = True + stop_flag = False + + while True: + if datetime.datetime.now().hour == start_clock[0] and datetime.datetime.now().minute == start_clock[1]: + break + elif datetime.datetime.now().hour > start_clock[0] or datetime.datetime.now().minute > start_clock[1]: + h = datetime.datetime.now().hour + m = datetime.datetime.now().minute + start_clock = [h, m] + end_clock = [h + 6, m] + + clock_thread = threading.Thread(target=clock_controll, args=(end_clock, LED1_pin, LED_out_pin, w1_bus_path, temp_f, led_f, lambda: stop_flag)) + clock_thread.start() + + print('go') data = create_float_buffer(channel_count, samples_per_channel) - # system('clear') + print('----') + print(len(data)) + print(samples_per_channel) + print(channel_count) + print('----') - # Start the acquisition. rate = ai_device.a_in_scan(low_channel, high_channel, input_mode, ranges[range_index], samples_per_channel, - rate, scan_options, flags, data) - last_idx = 0 - - + rate, scan_options, flags, data) - emergency_LED_t = time() - emergency_LED_interval = 0.5 + status, transfer_status = ai_device.get_scan_status() - LED_t = time() - LED_t_interval = 2 + save_ranges = np.array([[int(buffer_size / 2), len(data)], [0, int(buffer_size / 2)]]) + save_range = save_ranges[0] - out_LED_t = time() - out_LED_interval = 1 - - temp_t0 = time() - next_temp_t = 0 - temp_interval = 300 # sec --> 5 min - disp_eth_power = True - #while True: - while GPIO.input(Button1_pin) == GPIO.LOW: - if record_temp == True: - if time() - temp_t0 > next_temp_t: - w1_f = open(w1_bus_path, 'r') - w1_file = w1_f.readlines() - for line in w1_file: - if 't=' in line: - temp = float((line.split('=')[-1].strip())) / 1000 - temp_f.write('%6.0f; %7.3f\n' % (next_temp_t, temp)) - temp_f.flush() - break - - w1_f.close() - next_temp_t += temp_interval - - # blinking LED for rec - if time() - LED_t < .1 and LED_status[0] == False: - LED_status[0] = True - GPIO.output(LED1_pin, GPIO.HIGH) - if time() - LED_t >= .1 and LED_status[0] == True: - LED_status[0] = False - GPIO.output(LED1_pin, GPIO.LOW) - if time() - LED_t >= LED_t_interval: - LED_t = time() - (time() - LED_t - LED_t_interval) - - if len(LED_status) == 3: - if time() - out_LED_t < .1 and LED_status[2] == False: - LED_status[2] = True - GPIO.output(LED_out_pin, GPIO.HIGH) - elif time() - out_LED_t >= .1 and LED_status[2] == True: - LED_status[2] = False - GPIO.output(LED_out_pin, GPIO.LOW) - else: - pass - - if time() - out_LED_t >= out_LED_interval: - out_LED_t = time() - (time() - out_LED_t - out_LED_interval ) - - - # dist & eth0 controll - if GPIO.input(Button2_pin) == GPIO.HIGH and (time() - last_button_2_t) > 5: - if disp_eth_power == True: - subprocess.run(['tvservice', '-o']) - subprocess.run(['vcgencmd', 'display_power', '0'])# - - subprocess.run(['sudo', 'ip', 'link', 'set', 'eth0', 'down']) - GPIO.output(LED2_pin, GPIO.LOW) - disp_eth_power = False - last_button_2_t = time() - - elif disp_eth_power == False: - subprocess.run(['tvservice', '-p']) - subprocess.run(['vcgencmd', 'display_power', '1']) - subprocess.run(['sudo', '/bin/chvt', '6']) - subprocess.run(['sudo', '/bin/chvt', '7'])# - - subprocess.run(['sudo', 'ip', 'link', 'set', 'eth0', 'up']) - GPIO.output(LED2_pin, GPIO.HIGH) - disp_eth_power = True - last_button_2_t = time() + cont_t = time() + while GPIO.input(Button1_pin) == GPIO.LOW and clock_thread.is_alive(): + + if GPIO.input(Button2_pin) == GPIO.HIGH: + if (time() - last_button_2_t) > 5: + if disp_eth_power == True: + subprocess.run(['tvservice', '-o']) + subprocess.run(['vcgencmd', 'display_power', '0'])# + + subprocess.run(['sudo', 'ip', 'link', 'set', 'eth0', 'down']) + GPIO.output(LED2_pin, GPIO.LOW) + disp_eth_power = False + last_button_2_t = time() + + elif disp_eth_power == False: + subprocess.run(['tvservice', '-p']) + subprocess.run(['vcgencmd', 'display_power', '1']) + subprocess.run(['sudo', '/bin/chvt', '6']) + subprocess.run(['sudo', '/bin/chvt', '7'])# + + subprocess.run(['sudo', 'ip', 'link', 'set', 'eth0', 'up']) + GPIO.output(LED2_pin, GPIO.HIGH) + disp_eth_power = True + last_button_2_t = time() # Get the status of the background operation status, transfer_status = ai_device.get_scan_status() index = transfer_status.current_index - #print(last_idx - index) - #embed() - #quit() - if index < 0 or index == last_idx: - continue - - if index > last_idx: - (np.array(data[last_idx:index], dtype=np.float32) / gain).tofile(f) - else: - (np.array(data[last_idx:], dtype=np.float32) / gain).tofile(f) - (np.array(data[:index], dtype=np.float32) / gain).tofile(f) - f.flush() + # print(index) + + if index >= save_range[0] and index < save_range[1]: + dt = time() - cont_t + cont_t = time() - last_idx = index + print("dt = %.3f sec" % (dt)) + print('samples = %.0f' % (len(data[save_range[0]:save_range[1]]) / 15)) + print('rate = %.2f Hz\n' % (len(data[save_range[0]:save_range[1]]) / 15 /dt)) + + (np.array(data[save_range[0]:save_range[1]], dtype=np.float32) / gain).tofile(f) + f.flush() + save_ranges = np.roll(save_ranges, 1, axis=0) + save_range = save_ranges[0] + + # if index < 0 or index == last_idx: + # continue + # + # if index > last_idx: + # + # if index-last_idx > buffer_size / 5: + # (np.array(data[last_idx:index], dtype=np.float32) / gain).tofile(f) + # last_idx = index + # print('save') + # else: + # buffer_size = samples_per_channel * channels + # if buffer_size - last_idx + index > buffer_size / 5: + # (np.array(data[last_idx:], dtype=np.float32) / gain).tofile(f) + # (np.array(data[:index], dtype=np.float32) / gain).tofile(f) + # f.flush() + # print('save n flush') + # last_idx = index + + stop_flag = True + clock_thread.join() + print('end') f.close() temp_f.close() + led_f.close() - if LED_status[0] == False: - GPIO.output(LED1_pin, GPIO.HIGH) - if LED_status[1] == False: - GPIO.output(LED2_pin, GPIO.HIGH) + GPIO.output(LED1_pin, GPIO.HIGH) + GPIO.output(LED2_pin, GPIO.HIGH) sleep(2) + GPIO.output(LED1_pin, GPIO.LOW) + GPIO.output(LED2_pin, GPIO.LOW) + if daq_device: # Stop the acquisition if it is still running. if status == ScanStatus.RUNNING: diff --git a/rasp_grid_cfg.py b/rasp_grid_cfg.py index 8806726..7f5e4d7 100644 --- a/rasp_grid_cfg.py +++ b/rasp_grid_cfg.py @@ -14,6 +14,7 @@ class Grid_tab(QWidget): self.rec_mode_val = 'standalone' self.columns_val = 8 self.rows_val = 8 + self.extra_val = 0 self.col_dist_val = 50 self.row_dist_val = 50 self.channel_offset_val = 0 @@ -57,53 +58,60 @@ class Grid_tab(QWidget): self.gridlayout.addWidget(self.row_elecs, 3, 1) self.gridlayout.addWidget(row_elecsU, 3, 2) + ext_elecsU = QLabel('n', self) + ext_elecsL = QLabel('Extra electrodes:', self) + self.extra_elecs = QLineEdit(str(self.extra_val), self) + self.gridlayout.addWidget(ext_elecsL, 4, 0) + self.gridlayout.addWidget(self.extra_elecs, 4, 1) + self.gridlayout.addWidget(ext_elecsU, 4, 2) + col_spaceU = QLabel('cm', self) col_spaceL = QLabel('Column spacing:', self) self.col_space = QLineEdit(str(self.col_dist_val), self) - self.gridlayout.addWidget(col_spaceL, 4, 0) - self.gridlayout.addWidget(self.col_space, 4, 1) - self.gridlayout.addWidget(col_spaceU, 4, 2) + self.gridlayout.addWidget(col_spaceL, 5, 0) + self.gridlayout.addWidget(self.col_space, 5, 1) + self.gridlayout.addWidget(col_spaceU, 5, 2) row_spaceU = QLabel('cm', self) row_spaceL = QLabel('Row spacing:', self) self.row_space = QLineEdit(str(self.row_dist_val), self) - self.gridlayout.addWidget(row_spaceL, 5, 0) - self.gridlayout.addWidget(self.row_space, 5, 1) - self.gridlayout.addWidget(row_spaceU, 5, 2) + self.gridlayout.addWidget(row_spaceL, 6, 0) + self.gridlayout.addWidget(self.row_space, 6, 1) + self.gridlayout.addWidget(row_spaceU, 6, 2) elec_typeL = QLabel('Electrode Type:', self) self.elec_type = QLineEdit(self.elec_type_val, self) - self.gridlayout.addWidget(elec_typeL, 6, 0) - self.gridlayout.addWidget(self.elec_type, 6, 1) + self.gridlayout.addWidget(elec_typeL, 7, 0) + self.gridlayout.addWidget(self.elec_type, 7, 1) ref_elec_typeL = QLabel('Ref. Electrode Type:', self) self.ref_elec_type = QLineEdit(self.ref_elec_type_val, self) - self.gridlayout.addWidget(ref_elec_typeL, 7, 0) - self.gridlayout.addWidget(self.ref_elec_type, 7, 1) + self.gridlayout.addWidget(ref_elec_typeL, 8, 0) + self.gridlayout.addWidget(self.ref_elec_type, 8, 1) ref_elec_xU = QLabel('m', self) ref_elec_xL = QLabel('Ref. Electrode Pos-x:', self) self.ref_elec_x = QLineEdit('%.2f' % self.ref_elec_posx_val, self) - self.gridlayout.addWidget(ref_elec_xL, 8, 0) - self.gridlayout.addWidget(self.ref_elec_x, 8, 1) - self.gridlayout.addWidget(ref_elec_xU, 8, 2) + self.gridlayout.addWidget(ref_elec_xL, 9, 0) + self.gridlayout.addWidget(self.ref_elec_x, 9, 1) + self.gridlayout.addWidget(ref_elec_xU, 9, 2) ref_elec_yU = QLabel('m', self) ref_elec_yL = QLabel('Ref. Electrode Pos-y:', self) self.ref_elec_y = QLineEdit('%.2f' % self.ref_elec_posy_val, self) - self.gridlayout.addWidget(ref_elec_yL, 9, 0) - self.gridlayout.addWidget(self.ref_elec_y, 9, 1) - self.gridlayout.addWidget(ref_elec_yU, 9, 2) + self.gridlayout.addWidget(ref_elec_yL, 10, 0) + self.gridlayout.addWidget(self.ref_elec_y, 10, 1) + self.gridlayout.addWidget(ref_elec_yU, 10, 2) water_depthU = QLabel('cm', self) water_depthL = QLabel('Water depth:', self) self.water_depth = QLineEdit('%.2f' % self.water_depth_val, self) - self.gridlayout.addWidget(water_depthL, 10, 0) - self.gridlayout.addWidget(self.water_depth, 10, 1) - self.gridlayout.addWidget(water_depthU, 10, 2) + self.gridlayout.addWidget(water_depthL, 11, 0) + self.gridlayout.addWidget(self.water_depth, 11, 1) + self.gridlayout.addWidget(water_depthU, 11, 2) space = QLabel('', self) - self.gridlayout.addWidget(space, 11, 0) + self.gridlayout.addWidget(space, 12, 0) class Hardware_settings_tab(QWidget): def __init__(self): @@ -381,6 +389,8 @@ class MainWindow(QTabWidget): self.Grid.columns_val = int(line.split(':')[1].strip()) elif 'Rows1' in line: self.Grid.rows_val = int(line.split(':')[1].strip()) + elif 'Extra1' in line: + self.Grid.extra_val = int(line.split(':')[1].strip()) elif "ColumnDistance1" in line: self.Grid.col_dist_val = float(line.split(':')[-1].strip().replace('cm', '')) elif "RowDistance1" in line: @@ -459,6 +469,7 @@ class MainWindow(QTabWidget): f.write(' RecordMode1 : %s\n' % self.Grid.rec_mode.text()) f.write(' Columns1 : %.0f\n' % int(self.Grid.col_elecs.text())) f.write(' Rows1 : %.0f\n' % int(self.Grid.row_elecs.text())) + f.write(' Extra1 : %.0f\n' % int(self.Grid.extra_elecs.text())) f.write(' ColumnDistance1 : %.1fcm\n' % float(self.Grid.col_space.text())) f.write(' RowDistance1 : %.1fcm\n' % float(self.Grid.row_space.text())) # f.write(' ChannelOffset1 : %.0f\n' % int(self.Grid.channel_offset.text()))