From 3dc98f0970bfcea73fdbcb86cf1aa91f8355b97f Mon Sep 17 00:00:00 2001 From: Joachim Beerwerth Date: Thu, 5 Apr 2018 16:46:23 +0200 Subject: [PATCH] Add get_length() function to the Experiment class which returns the estimated time the experiment will take. --- src/experiments/Experiment.py | 59 +++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/src/experiments/Experiment.py b/src/experiments/Experiment.py index 5ef264c..41e84aa 100644 --- a/src/experiments/Experiment.py +++ b/src/experiments/Experiment.py @@ -90,6 +90,15 @@ class Experiment: assert len(rf_gates) == len(rf_sources), "rf_sources and rf_gates must have equal number of entries" self.rf_sources = rf_sources 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 ------------------------------------------------------------------------------------- @@ -118,6 +127,8 @@ class Experiment: the_value=1<' % the_value)) + + self.total_time[-1] += length ## Same as ttl_pulse, but no *channel* keyword def ttls(self, length = None, value = None): @@ -132,8 +143,10 @@ class Experiment: s_content = '' % the_value if length is not None: self.state_list.append(StateSimple(length, s_content)) + self.total_time[-1] += length else: self.state_list.append(s_content) + def rf_pulse(self, length=None, phase=0, source=0): """ @@ -157,6 +170,7 @@ class Experiment: This must be closed with state_end() """ self.state_list.append('\n' % repr(time)) + self.total_time[-1] += time ## End of *state_start* def state_end(self): @@ -184,6 +198,8 @@ class Experiment: self.state_list.append(StateSimple(time,s_content)) else: self.state_list.append(StateSimple(time)) + + self.total_time[-1] += time ## Records data with given number of samples, sampling-frequency frequency and sensitivity # @param samples Number of samples to record @@ -247,6 +263,7 @@ class Experiment: if timelength is None: timelength = samples / float(frequency)#*1.01 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. # @params iterations Number of loop iterations @@ -264,6 +281,9 @@ class Experiment: # (These two lines could probably be guarded by a mutex) self.list_stack.append(self.state_list) self.state_list = l + + self.total_time.append(0.0) + self.loop_iterations.append(iterations) ## End loop state def loop_end(self): @@ -272,6 +292,10 @@ class Experiment: """ # (This line could probably be guarded by a mutex) 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. ## This state needs 2us. @@ -291,6 +315,8 @@ class Experiment: if ttls != 0: s_content += '' % ttls self.state_list.append(StateSimple(2e-6, s_content)) + + self.total_time[-1] += 2e-6 ## Creates a, possibly shaped, pulsed gradient. # @param dac_value DAC value to set @@ -331,10 +357,13 @@ class Experiment: if form == 'rec': # shape==None --> rectangular gradients s_content = '' % (trigger, dac_value) self.state_list.append(StateSimple(length, s_content)) + self.total_time[-1] += length if not is_seq: s_content = '' self.state_list.append(StateSimple(42*9e-8, s_content)) + + self.total_time[-1] += 42*9e-8 elif form == 'sin2': # sin**2 shape @@ -342,9 +371,12 @@ class Experiment: dac = int (dac_value*numpy.sin(numpy.pi/length*t)**2) s_content = '' % (trigger, dac) self.state_list.append(StateSimple(resolution, s_content)) + # set it back to zero s_content = '' % (trigger) self.state_list.append(StateSimple(resolution, s_content)) + + self.total_time[-1] += resolution*(len(t_steps)+1) elif form == 'sin': # sin shape @@ -355,6 +387,8 @@ class Experiment: # set it back to zero s_content = '' % (trigger) self.state_list.append(StateSimple(resolution, s_content)) + + self.total_time[-1] += resolution*(len(t_steps)+1) else: # don't know what to do raise SyntaxError , "form is unknown: %s"%form @@ -385,10 +419,15 @@ class Experiment: s_content = '' \ % (dac_id, dac_value, ttls) self.state_list.append(StateSimple(length, s_content)) + + self.total_time[-1] += length + if not is_seq: s_content = '' \ % (dac_id, ttls) self.state_list.append(StateSimple(42*9e-8, s_content)) + + self.total_time[-1] += 42*9e-8 ## sets the phase of the frequency source. ## This state needs 0.5us, though the phase switching time is dependent on the frequency source @@ -408,6 +447,8 @@ class Experiment: if ttls!=0: s_content += '' % ttls 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 ## file to the result script in the front end. In the result script @@ -434,6 +475,8 @@ class Experiment: """ self.state_list.append(StateSimple(1e-6, '')) self.state_list.append(StateSimple(1e-6, '')) + + self.total_time[-1] += 2e-6 # / Commands ----------------------------------------------------------------------------------- @@ -508,7 +551,16 @@ class Experiment: :returns: XML quit-job """ return '\n' - + + 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): def write_xml_string(self): @@ -529,8 +581,7 @@ def self_test(): e.ttl_pulse(1e-6/3, None, 7) # val = 7 if True: e.loop_start(30) - e.set_pfg(dac_value=1024, is_seq = True) - e.set_pfg_wt(dac_value=2048) + e.set_pfg(dac_value=1024, length=5e-6, is_seq = True, shape=('rec', 42*9e-8)) e.loop_start(400) e.set_phase(270, ttls = 32) e.loop_end() @@ -550,6 +601,8 @@ def self_test(): raise AssertionError("An exception should happen") e.set_pts_local() print e.write_xml_string() + + print e.get_timelength() if __name__ == '__main__': self_test()