Add get_length() function to the Experiment class which returns the estimated time the experiment will take.

This commit is contained in:
Joachim Beerwerth 2018-04-05 16:46:23 +02:00
parent c3c4839d3c
commit 3dc98f0970

View File

@ -91,6 +91,15 @@ class Experiment:
self.rf_sources = rf_sources self.rf_sources = rf_sources
self.rf_gates = rf_gates self.rf_gates = rf_gates
#for tracking the experiment length:
#because loops are possible we need to track the length for each loop level
self.total_time=[]
self.total_time.append(0.0)
#and we need to know the number of iterations of the loops to multiply the state.
self.loop_iterations=[]
self.loop_iterations.append(1)
# Commands ------------------------------------------------------------------------------------- # Commands -------------------------------------------------------------------------------------
## Creates a state with ttl signals of duration *length*. ## Creates a state with ttl signals of duration *length*.
@ -119,6 +128,8 @@ class Experiment:
self.state_list.append(StateSimple(length, \ self.state_list.append(StateSimple(length, \
'<ttlout value="0x%06x"/>' % the_value)) '<ttlout value="0x%06x"/>' % the_value))
self.total_time[-1] += length
## Same as ttl_pulse, but no *channel* keyword ## Same as ttl_pulse, but no *channel* keyword
def ttls(self, length = None, value = None): def ttls(self, length = None, value = None):
""" """
@ -132,9 +143,11 @@ class Experiment:
s_content = '<ttlout value="0x%06x"/>' % the_value s_content = '<ttlout value="0x%06x"/>' % the_value
if length is not None: if length is not None:
self.state_list.append(StateSimple(length, s_content)) self.state_list.append(StateSimple(length, s_content))
self.total_time[-1] += length
else: else:
self.state_list.append(s_content) self.state_list.append(s_content)
def rf_pulse(self, length=None, phase=0, source=0): def rf_pulse(self, length=None, phase=0, source=0):
""" """
make an rf pulse, including gating and phase switching make an rf pulse, including gating and phase switching
@ -157,6 +170,7 @@ class Experiment:
This must be closed with state_end() This must be closed with state_end()
""" """
self.state_list.append('<state time="%s">\n' % repr(time)) self.state_list.append('<state time="%s">\n' % repr(time))
self.total_time[-1] += time
## End of *state_start* ## End of *state_start*
def state_end(self): def state_end(self):
@ -185,6 +199,8 @@ class Experiment:
else: else:
self.state_list.append(StateSimple(time)) self.state_list.append(StateSimple(time))
self.total_time[-1] += time
## Records data with given number of samples, sampling-frequency frequency and sensitivity ## Records data with given number of samples, sampling-frequency frequency and sensitivity
# @param samples Number of samples to record # @param samples Number of samples to record
# @param frequency Sampling frequency # @param frequency Sampling frequency
@ -247,6 +263,7 @@ class Experiment:
if timelength is None: if timelength is None:
timelength = samples / float(frequency)#*1.01 timelength = samples / float(frequency)#*1.01
self.state_list.append(StateSimple(timelength, s_content)) self.state_list.append(StateSimple(timelength, s_content))
self.total_time[-1] += timelength
## Create a loop on the pulse programmer. Loop contents can not change inside the loop. ## Create a loop on the pulse programmer. Loop contents can not change inside the loop.
# @params iterations Number of loop iterations # @params iterations Number of loop iterations
@ -265,6 +282,9 @@ class Experiment:
self.list_stack.append(self.state_list) self.list_stack.append(self.state_list)
self.state_list = l self.state_list = l
self.total_time.append(0.0)
self.loop_iterations.append(iterations)
## End loop state ## End loop state
def loop_end(self): def loop_end(self):
""" """
@ -273,6 +293,10 @@ class Experiment:
# (This line could probably be guarded by a mutex) # (This line could probably be guarded by a mutex)
self.state_list = self.list_stack.pop(-1) self.state_list = self.list_stack.pop(-1)
looptime=self.total_time.pop(-1)
loopiterations=self.loop_iterations.pop(-1)
self.total_time[-1] += looptime*loopiterations
## Set the frequency and phase of the frequency source. ## Set the frequency and phase of the frequency source.
## This state needs 2us. ## This state needs 2us.
# @param frequency New frequency in Hz # @param frequency New frequency in Hz
@ -292,6 +316,8 @@ class Experiment:
s_content += '<ttlout value="0x%06x"/>' % ttls s_content += '<ttlout value="0x%06x"/>' % ttls
self.state_list.append(StateSimple(2e-6, s_content)) self.state_list.append(StateSimple(2e-6, s_content))
self.total_time[-1] += 2e-6
## Creates a, possibly shaped, pulsed gradient. ## Creates a, possibly shaped, pulsed gradient.
# @param dac_value DAC value to set # @param dac_value DAC value to set
# @param length Duration of the state, minimum length is 42*90ns=3.78us (default) # @param length Duration of the state, minimum length is 42*90ns=3.78us (default)
@ -331,21 +357,27 @@ class Experiment:
if form == 'rec': # shape==None --> rectangular gradients if form == 'rec': # shape==None --> rectangular gradients
s_content = '<ttlout value="%s"/><analogout id="1" dac_value="%i"/>' % (trigger, dac_value) s_content = '<ttlout value="%s"/><analogout id="1" dac_value="%i"/>' % (trigger, dac_value)
self.state_list.append(StateSimple(length, s_content)) self.state_list.append(StateSimple(length, s_content))
self.total_time[-1] += length
if not is_seq: if not is_seq:
s_content = '<analogout id="1" dac_value="0"/>' s_content = '<analogout id="1" dac_value="0"/>'
self.state_list.append(StateSimple(42*9e-8, s_content)) self.state_list.append(StateSimple(42*9e-8, s_content))
self.total_time[-1] += 42*9e-8
elif form == 'sin2': elif form == 'sin2':
# sin**2 shape # sin**2 shape
for t in t_steps: for t in t_steps:
dac = int (dac_value*numpy.sin(numpy.pi/length*t)**2) dac = int (dac_value*numpy.sin(numpy.pi/length*t)**2)
s_content = '<ttlout value="%s"/><analogout id="1" dac_value="%i"/>' % (trigger, dac) s_content = '<ttlout value="%s"/><analogout id="1" dac_value="%i"/>' % (trigger, dac)
self.state_list.append(StateSimple(resolution, s_content)) self.state_list.append(StateSimple(resolution, s_content))
# set it back to zero # set it back to zero
s_content = '<ttlout value="%s"/><analogout id="1" dac_value="0"/>' % (trigger) s_content = '<ttlout value="%s"/><analogout id="1" dac_value="0"/>' % (trigger)
self.state_list.append(StateSimple(resolution, s_content)) self.state_list.append(StateSimple(resolution, s_content))
self.total_time[-1] += resolution*(len(t_steps)+1)
elif form == 'sin': elif form == 'sin':
# sin shape # sin shape
for t in t_steps: for t in t_steps:
@ -355,6 +387,8 @@ class Experiment:
# set it back to zero # set it back to zero
s_content = '<ttlout value="%s"/><analogout id="1" dac_value="0"/>' % (trigger) s_content = '<ttlout value="%s"/><analogout id="1" dac_value="0"/>' % (trigger)
self.state_list.append(StateSimple(resolution, s_content)) self.state_list.append(StateSimple(resolution, s_content))
self.total_time[-1] += resolution*(len(t_steps)+1)
else: # don't know what to do else: # don't know what to do
raise SyntaxError , "form is unknown: %s"%form raise SyntaxError , "form is unknown: %s"%form
@ -385,11 +419,16 @@ class Experiment:
s_content = '<analogout id="%d" dac_value="%i"/><ttlout value="0x%06x"/>' \ s_content = '<analogout id="%d" dac_value="%i"/><ttlout value="0x%06x"/>' \
% (dac_id, dac_value, ttls) % (dac_id, dac_value, ttls)
self.state_list.append(StateSimple(length, s_content)) self.state_list.append(StateSimple(length, s_content))
self.total_time[-1] += length
if not is_seq: if not is_seq:
s_content = '<analogout id="%d" dac_value="0"/><ttlout value="0x%06x"/>' \ s_content = '<analogout id="%d" dac_value="0"/><ttlout value="0x%06x"/>' \
% (dac_id, ttls) % (dac_id, ttls)
self.state_list.append(StateSimple(42*9e-8, s_content)) self.state_list.append(StateSimple(42*9e-8, s_content))
self.total_time[-1] += 42*9e-8
## sets the phase of the frequency source. ## sets the phase of the frequency source.
## This state needs 0.5us, though the phase switching time is dependent on the frequency source ## This state needs 0.5us, though the phase switching time is dependent on the frequency source
# @param phase New phase to set # @param phase New phase to set
@ -409,6 +448,8 @@ class Experiment:
s_content += '<ttlout value="%d"/>' % ttls s_content += '<ttlout value="%d"/>' % ttls
self.state_list.append(StateSimple(0.5e-6, s_content)) self.state_list.append(StateSimple(0.5e-6, s_content))
self.total_time[-1] += 0.5e-6
## sets a description which is carried via the back end result ## sets a description which is carried via the back end result
## file to the result script in the front end. In the result script ## file to the result script in the front end. In the result script
## you can extract the description with get_description(key) ## you can extract the description with get_description(key)
@ -435,6 +476,8 @@ class Experiment:
self.state_list.append(StateSimple(1e-6, '<ttlout value="0xf000"/>')) self.state_list.append(StateSimple(1e-6, '<ttlout value="0xf000"/>'))
self.state_list.append(StateSimple(1e-6, '<ttlout value="0x8000"/>')) self.state_list.append(StateSimple(1e-6, '<ttlout value="0x8000"/>'))
self.total_time[-1] += 2e-6
# / Commands ----------------------------------------------------------------------------------- # / Commands -----------------------------------------------------------------------------------
@ -509,6 +552,15 @@ class Experiment:
""" """
return '<?xml version="1.0" encoding="ISO-8859-1"?>\n<quit/>' return '<?xml version="1.0" encoding="ISO-8859-1"?>\n<quit/>'
def get_length(self):
timelength = 0.0
#calculate the correct timelength also for unclosed loops, if there is no unclosed loop
#the timelength of this experiment is self.total_time[-1].
for i in range(len(self.total_time)):
timelength += self.total_time[i]*self.loop_iterations[i]
return timelength
class Quit(Experiment): class Quit(Experiment):
def write_xml_string(self): def write_xml_string(self):
@ -529,8 +581,7 @@ def self_test():
e.ttl_pulse(1e-6/3, None, 7) # val = 7 e.ttl_pulse(1e-6/3, None, 7) # val = 7
if True: if True:
e.loop_start(30) e.loop_start(30)
e.set_pfg(dac_value=1024, is_seq = True) e.set_pfg(dac_value=1024, length=5e-6, is_seq = True, shape=('rec', 42*9e-8))
e.set_pfg_wt(dac_value=2048)
e.loop_start(400) e.loop_start(400)
e.set_phase(270, ttls = 32) e.set_phase(270, ttls = 32)
e.loop_end() e.loop_end()
@ -551,5 +602,7 @@ def self_test():
e.set_pts_local() e.set_pts_local()
print e.write_xml_string() print e.write_xml_string()
print e.get_timelength()
if __name__ == '__main__': if __name__ == '__main__':
self_test() self_test()