Live data acquisition over SECoP
This commit is contained in:
@@ -27,7 +27,7 @@ import time
|
||||
import os
|
||||
import traceback
|
||||
|
||||
class ProgrammedSequence(fc.Readable):
|
||||
class ProgrammedSequence(fc.Drivable): # Drivable only for kill() funcitonality
|
||||
"""An NMR device being driven by an instance of TNMR. Requires that an instance of TNMR is opened before creation.
|
||||
|
||||
Use
|
||||
@@ -72,7 +72,12 @@ class ProgrammedSequence(fc.Readable):
|
||||
imags=fc.ArrayOf(fc.FloatRange(), maxlen=4096), # imag values
|
||||
t =fc.ArrayOf(fc.FloatRange(), maxlen=4096)), # times (starting from zero)
|
||||
default={ 'reals': [], 'imags': [], 't': [] })
|
||||
status = fc.Parameter(datatype=frappy.datatypes.StatusType(fc.Readable, "DISABLED", 'PREPARED', 'BUSY'), default=('IDLE', 'ok - uncompiled'))
|
||||
target = fc.Parameter('dummy', fc.StructOf(reals=fc.ArrayOf(fc.FloatRange(), maxlen=4096), # real values
|
||||
imags=fc.ArrayOf(fc.FloatRange(), maxlen=4096), # imag values
|
||||
t =fc.ArrayOf(fc.FloatRange(), maxlen=4096)), # times (starting from zero)
|
||||
default={ 'reals': [], 'imags': [], 't': [] }, readonly=True, visibility='w--')
|
||||
|
||||
status = fc.Parameter(datatype=frappy.datatypes.StatusType(fc.Drivable, "DISABLED", 'PREPARED', 'BUSY'), default=('IDLE', 'ok - uncompiled'))
|
||||
pollinterval = fc.Parameter(default=1)
|
||||
|
||||
# basic
|
||||
@@ -99,6 +104,7 @@ class ProgrammedSequence(fc.Readable):
|
||||
|
||||
compiled_parameters = {} # so that we can store the values of parameters only when compiling, effectively giving us an instance of each parameter loaded into TNMR, as well as "targets" (those above)
|
||||
inited = False
|
||||
starting = False
|
||||
approx_sequence_length = 0
|
||||
|
||||
### SETUP
|
||||
@@ -150,6 +156,20 @@ class ProgrammedSequence(fc.Readable):
|
||||
|
||||
### READ/WRITE
|
||||
|
||||
def read_status(self):
|
||||
if not(self.inited):
|
||||
self.status = ('ERROR', 'TNMR disconnected!')
|
||||
else:
|
||||
if(self.starting):
|
||||
self.status = ('BUSY', 'starting')
|
||||
else:
|
||||
if(self.tnmr().acquisition_running()):
|
||||
self.status = ('BUSY', 'acquiring')
|
||||
elif(self.status[1] == 'acquiring'):
|
||||
# we've just finished acquiring, in frappy's perspective
|
||||
self.status = ('PREPARED', 'compiled')
|
||||
return self.status
|
||||
|
||||
def write_title(self, t):
|
||||
self.title = t
|
||||
self.status = ('IDLE', 'ok - uncompiled')
|
||||
@@ -196,7 +216,7 @@ class ProgrammedSequence(fc.Readable):
|
||||
return self.read_acq_phase_cycle()
|
||||
|
||||
def read_num_acqs(self):
|
||||
return self.tnmr().get_nmrparameter('Scans 1D')
|
||||
return int(self.tnmr().get_nmrparameter('Scans 1D'))
|
||||
|
||||
def write_num_acqs(self, t):
|
||||
if(self.status[0] != 'BUSY'):
|
||||
@@ -223,31 +243,23 @@ class ProgrammedSequence(fc.Readable):
|
||||
|
||||
return self.read_sequence_data()
|
||||
|
||||
def read_status(self):
|
||||
if(self.tnmr().acquisition_running()):
|
||||
self.status = ('BUSY', 'acquiring')
|
||||
elif(self.status[1] == 'acquiring'):
|
||||
# we've just finished acquiring, in frappy's perspective
|
||||
self.status = ('PREPARED', 'compiled')
|
||||
return self.status
|
||||
|
||||
def read_value(self):
|
||||
newvals = {}
|
||||
try:
|
||||
d = self.tnmr().get_data()
|
||||
newvals['reals'] = d[0]
|
||||
newvals['imags'] = d[1]
|
||||
newvals['t'] = [ self.compiled_parameters['acquisition_time'] * i/len(d[0]) for i in range(0, len(d[0])) ]
|
||||
except:
|
||||
newvals['reals'] = []
|
||||
newvals['imags'] = []
|
||||
newvals['t'] = []
|
||||
#try:
|
||||
d = self.tnmr().get_data()
|
||||
newvals['reals'] = d[0]
|
||||
newvals['imags'] = d[1]
|
||||
newvals['t'] = [ self.compiled_parameters['acquisition_time'] * i/len(d[0]) for i in range(0, len(d[0])) ]
|
||||
#except:
|
||||
# newvals['reals'] = []
|
||||
# newvals['imags'] = []
|
||||
# newvals['t'] = []
|
||||
return newvals
|
||||
|
||||
def read_num_acqs_actual(self):
|
||||
try:
|
||||
n = self.tnmr().get_nmrparameter('Actual Scans 1D')
|
||||
return n
|
||||
return int(n)
|
||||
except:
|
||||
return 0
|
||||
|
||||
@@ -330,9 +342,8 @@ class ProgrammedSequence(fc.Readable):
|
||||
|
||||
def __zero_go(self):
|
||||
'''Tells TNMR to acquire data. Only call after __compile_sequence().'''
|
||||
if(self.status[0] != 'BUSY'):
|
||||
self.status = ('BUSY', 'acquiring')
|
||||
self.tnmr().ZeroGo(lock=False, check_time=max(self.approx_sequence_length*5, 5))
|
||||
if(self.status[0] != 'BUSY' or self.starting):
|
||||
self.tnmr().ZeroGo(lock=False, check_time=max(int(self.approx_sequence_length*1.5), 5))
|
||||
|
||||
def __compile_and_run(self, thread=True):
|
||||
'''Compiles and runs the currently-loaded sequence
|
||||
@@ -341,9 +352,11 @@ class ProgrammedSequence(fc.Readable):
|
||||
----------
|
||||
thread: bool, determines if this should open a child thread and detach the process
|
||||
'''
|
||||
self.starting = True
|
||||
self.__compile_sequence()
|
||||
time.sleep(1.0)
|
||||
self.__zero_go()
|
||||
self.starting = False
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -41,6 +41,9 @@ def get_single_pulse_block(name, pulse_width, pulse_height, delay_time, phase_cy
|
||||
delay_time = float(delay_time.strip()[:-1]) / 1e6
|
||||
else:
|
||||
delay_time = float(delay_time.strip()) # assume in us
|
||||
|
||||
delay_time_rounded = int(delay_time*10) / 10 # nearest 10ns
|
||||
delay_time = delay_time_rounded
|
||||
|
||||
ph = name + '_phase'
|
||||
rl = name + '_delay'
|
||||
|
||||
@@ -155,8 +155,8 @@ class TNMR:
|
||||
print('Zero-going...')
|
||||
ntnmr = self.get_instance()
|
||||
if not(self.acquisition_running()):
|
||||
print('Reset')
|
||||
ntnmr.Reset() # to avoid hardware issues? EDIT: Doesn't seem to do much...
|
||||
#print('Reset')
|
||||
#ntnmr.Reset() # to avoid hardware issues? EDIT: Doesn't seem to do much...
|
||||
if(CHECK_MODE == 'data'):
|
||||
print('Artificially setting the zeroth point to NULL for error detection.')
|
||||
ntnmr.SetDataPoint(1, [0,0])
|
||||
@@ -258,7 +258,7 @@ class TNMR:
|
||||
"""
|
||||
print('I: Saving')
|
||||
if filepath == '':
|
||||
self.get_instance().Save
|
||||
self.get_instance().Save()
|
||||
else:
|
||||
self.get_instance().SaveAs(filepath)
|
||||
print(f'I: Saved to file {filepath}')
|
||||
@@ -378,6 +378,11 @@ class TNMR:
|
||||
"""
|
||||
|
||||
ntnmr = self.get_instance()
|
||||
|
||||
if (self.acquisition_running()):
|
||||
ntnmr.Abort()
|
||||
print('W: Aborting currently running acquisition!')
|
||||
|
||||
print(f'Loading sequence at {filename}')
|
||||
ntnmr.CloseActiveFile()
|
||||
success = ntnmr.OpenFile(TEMPLATE_FILE_PATH + 'tmp.tnt')
|
||||
|
||||
Reference in New Issue
Block a user