diff --git a/src/experiments/Experiment.py b/src/experiments/Experiment.py index 106b8eb..b27de58 100644 --- a/src/experiments/Experiment.py +++ b/src/experiments/Experiment.py @@ -1,4 +1,4 @@ -# -*- coding: iso-8859-1 -*- +# -*- coding: utf-8 -*- import types import numpy @@ -69,6 +69,10 @@ class StateLoop(StateList): import dac class Experiment: + """ + Class holding the complete state tree for a single experiment. This state tree represents one + program on the pulse card. It is written in a single file and picked up by the backend. + """ ## Experiment class holding the state tree job_id = 0 @@ -83,17 +87,6 @@ class Experiment: # Commands ------------------------------------------------------------------------------------- - ## Deprecated - def rf_pulse(self, value, length = None): - """ - deprecated: use ttl_pulse - """ - s_content = '' % value - - if length is None: - self.state_list.append(s_content) - else: - self.state_list.append(StateSimple(length, s_content)) ## Creates a state with ttl signals of duration *length*. # @@ -105,11 +98,13 @@ class Experiment: # @param value select the channels via decimal representation (2**0 + 2**1 ...) def ttl_pulse(self, length, channel = None, value = None): """ - Creates a state with length *length* and switches - some bits of the pulse programmer to HIGH: - * channel: this selects a single channel (No. 1 - 24) - * value: this is the integer representation of the 24bit word, - as an example value=3 selects channels 1 and 2 (2**1 + 2**2) + Creates a state with length **length** and switches + requested bits of the pulse programmer to HIGH: + + :param float length: pulse length in seconds + :param int channel: selects a single channel (No. 1 - 24) + :param int value: lines to set (integer) for example value=3 selects channels 1 and 2 (2**1 + 2**2) + """ the_value=0 if value is not None: @@ -122,7 +117,11 @@ class Experiment: ## Same as ttl_pulse, but no *channel* keyword def ttls(self, length = None, value = None): """ - same as ttl_pulse, but no *channel* keyword + Same as ttl_pulse, but no *channel* keyword + + :param float length: + :param int value: lines to set (integer) + :return: """ the_value=int(value) s_content = '' % the_value @@ -133,15 +132,15 @@ class Experiment: ## Beginning of a new state def state_start(self, time): """ - starts a state in the pulse programs with duration *time*. - This must be closed with state_end + Starts a state in the pulse programs with duration *time*. + This must be closed with state_end() """ self.state_list.append('\n' % repr(time)) ## End of *state_start* def state_end(self): """ - closes a state after start_state + Closes a previous start_state() """ self.state_list.append('\n') @@ -149,6 +148,13 @@ class Experiment: # @param time Duration of this state # @param ttls Additinional ttl channels def wait(self, time, ttls=None): + """ + Wait specified **time** doing nothing. + + :param float time: seconds to wait + :param int ttls: lines to set (integer) + :return: + """ if ttls is not None: s_content = '' % ttls self.state_list.append(StateSimple(time,s_content)) @@ -162,6 +168,16 @@ class Experiment: # @param sensitivity Sensitivity in Umax/V # @param ttls Additional ttl channels def record(self, samples, frequency, timelength=None, sensitivity = None, ttls=None, channels = 3, offset = None, impedance = None): + """ + Records data with given number of samples, sampling frequency and sensitivity + + :param int samples: Number of samples to record + :param float frequency: Sampling frequency + :param float timelength: Length of this state, per default calculated automatically + :param float sensitivity: Sensitivity in Umax/V + :param int ttls: lines to set (integer) + :param int channels: default=3, Number of channels counting from 0 + """ attributes='s="%d" f="%d"'%(samples,frequency)#%g if channels != 1 and channels != 3 and channels != 5 and channels != 15: raise ValueError, "Channel definition is illegal" @@ -209,10 +225,14 @@ class Experiment: ## Create a loop on the pulse programmer. Loop contents can not change inside the loop. # @params iterations Number of loop iterations def loop_start(self, iterations): - """creates a loop of given number of iterations and has to be closed by loop_end(). + """ + creates a loop of given number of iterations and has to be closed by loop_end(). Commands inside the loop can not change, i.e. the parameters are the same for each loop run. This loop is created on the pulse programmer, thus saving commands. - One must close the loop with loop_end (see below)""" + One must close the loop with loop_end (see below)! + + :param int iterations: iterations to loop + """ l = StateLoop(iterations) self.state_list.append(l) # (These two lines could probably be guarded by a mutex) @@ -221,6 +241,9 @@ class Experiment: ## End loop state def loop_end(self): + """ + Closes a loop_start() statement. + """ # (This line could probably be guarded by a mutex) self.state_list = self.list_stack.pop(-1) @@ -231,12 +254,13 @@ class Experiment: # @param ttls Additional ttl channels def set_frequency(self, frequency, phase, ttls=0): """ - Sets the frequency and phase of the frequency source and optionally further channels. - The time needed to set the frequency is 2 us. - Switch pulse programmer line with *ttls* . + Sets the frequency and phase of the frequency source and optionally further channels. + The state length is 2 µs. Stabilisation time depends on RF source. + :param float frequency: frequency to set in Hz + :param float phase: phase to set + :param int ttls: default=0, lines to set (integer) """ - "Sets the frequency generator to a desired frequency (Hz)" s_content = '' % (frequency, phase) if ttls != 0: s_content += '' % ttls @@ -254,6 +278,11 @@ class Experiment: If you wnat to set a trigger, set trigger (default=4, i.e. channel 2) If you want shaped gradients: shape=(ashape, resolution), ashape can be rec, sin2, sin + :param int dac_value: DAC value to set + :param float length: Duration of the state, minimum length is 42*90ns=3.78us (default) + :param str shape: Tuple of (shape, resolution/seconds), shape can be one of: rec (default), sin2, sin + :param bool is_seq: If set to *True*, do NOT set DAC to zero after this state + :param int trigger: default=4, lines to set (integer) """ try: form, resolution = shape @@ -298,35 +327,9 @@ class Experiment: # set it back to zero s_content = '' % (trigger) self.state_list.append(StateSimple(resolution, s_content)) - else: # don't know what to do raise SyntaxError , "form is unknown: %s"%form - ## Deprecated, use set_pfg instead - def set_pfg_wt(self, I_out=None, dac_value=None, length=None, is_seq=0, trigger=4): - """ - This sets the value for the PFG (plus trigger, default=2**2), it also sets it back automatically. - If you don't whish to do so (i.e. line shapes) set is_seq=1 - """ -# raise DeprecationWarning, "to be removed in future, use set_pfg instead" - if I_out == None and dac_value == None: - dac_value=0 - if I_out != None and dac_value == None: - dac_value=dac.conv(I_out) - if I_out == None and dac_value != None: - dac_value=dac_value - if I_out !=None and dac_value != None: - dac_value = 0 - print "WARNING: You can't set both, I_out and dac_value! dac_value set to 0" - if length==None: - length=42*9e-8 - s_content = '' \ - % (dac_value, trigger) - self.state_list.append(StateSimple(length, s_content)) - if is_seq == 0: - s_content = '' \ - % trigger - self.state_list.append(StateSimple(42*9e-8, s_content)) ## sets the value of a DAC # @param dac_value DAC value to set @@ -336,9 +339,18 @@ class Experiment: # @param ttls Additional ttl channels def set_dac(self, dac_value, dac_id=1, length=None, is_seq=False, ttls=0): """ - This sets the value for the DAC and possibly some TTLs. - It also sets it back automatically. - If you don't whish to do so (i.e. line shapes) set is_seq=True + This sets the value for the DAC and if given the TTLs. + It also sets it back to zero automatically. + If you don't whish to set the value back to zero (i.e. line shapes) set is_seq=True + + The state length is at least 3.78 µs (is_seq=1) or 7.28µs (is_seq=0). + + :param int dac_value: dac value, between -2**19-1 and +2**19 + :param int dac_id: default=1, which dac to control + :param float length: default=None, length of this state in seconds. If *None* length=42*90ns=3.78µs + :param bool is_seq: default=False, do not reset DAC to 0 (zero) if True + :param int ttls: default=0, lines to set (integer) + """ if length==None: length=42*9e-8 @@ -355,6 +367,15 @@ class Experiment: # @param phase New phase to set # @param ttls Additional ttl channels def set_phase(self, phase, ttls=0): + """ + Sets the phase of the RF source to this value. + Note: This is relative to the phase at the beginnig of the experiment. + The state length is 0.5 µs, but the stabilisation time is RF source dependent. Typical + values for PTS310 is 2 µs. + + :param float phase: phase to set + :param int ttls: default=0, lines to set (integer) + """ s_content = '' % (phase) if ttls!=0: s_content += '' % ttls @@ -377,7 +398,8 @@ class Experiment: ## set the PTS310/PTS500 frequency source to local mode def set_pts_local(self): """ - this will set the PTS310/PTS500 frequency source to local mode + Sets the PTS310/PTS500 frequency source to local mode. + State length is 2 µs. """ self.state_list.append(StateSimple(1e-6, '')) self.state_list.append(StateSimple(1e-6, '')) @@ -388,12 +410,20 @@ class Experiment: # Public Methods ------------------------------------------------------------------------------- def get_job_id(self): - "Returns the current job-id the experiment got" + """ + Returns the job-id of the current experiment + + :returns: job_id + """ return self.job_id def write_xml_string(self): - "Returns the current program as a string" + """ + Returns the current program as a string + + :returns: XML string + """ # Standart XML-Kopf xml_string = '\n' @@ -442,7 +472,10 @@ class Experiment: return xml_string def write_quit_job(self): - "Returns a xml quit-job" + """ + Returns a xml quit-job + :returns: XML quit-job + """ return '\n'