16
16
import numpy as np
17
17
18
18
19
- class WindfreakSynthWorker (Worker ):
19
+ class WindfreakSynthHDWorker (Worker ):
20
20
21
21
def init (self ):
22
22
# hide import of 3rd-party library in here so docs don't need it
@@ -32,12 +32,41 @@ def init(self):
32
32
# connect to synth
33
33
self .synth = windfreak .SynthHD (self .com_port )
34
34
self .valid_modes = self .synth .trigger_modes
35
+ self .valid_ref_modes = self .synth .reference_modes
36
+ # set reference mode
37
+ self .set_reference_mode (self .reference_mode , self .reference_frequency )
35
38
# set trigger mode from connection_table_properties
36
39
self .set_trigger_mode (self .trigger_mode )
37
40
38
41
# populate smart chache
39
42
self .smart_cache ['STATIC_DATA' ] = self .check_remote_values ()
40
43
44
+ def set_reference_mode (self , mode , ext_freq ):
45
+ """Sets the synth reference mode.
46
+
47
+ Provides basic error checking that setting is valid.
48
+
49
+ Args:
50
+ mode (str): Valid reference modes are `external`, `internal 27mhz`
51
+ and `internal 10mhz`. If mode is external, ext_freq must be provided.
52
+ ext_freq (float): Frequency of external reference.
53
+ If using internal reference, pass `None`.
54
+
55
+ Raises:
56
+ ValueError: if `mode` is not a valid setting or `ext_ref` not provided
57
+ when using an external reference.
58
+ """
59
+
60
+ if mode == 'external' and ext_freq is None :
61
+ raise ValueError ('Must specify external reference frequency' )
62
+
63
+ if mode in self .valid_ref_modes :
64
+ self .synth .reference_mode = mode
65
+ if mode == 'external' :
66
+ self .synth .reference_frequency = ext_freq
67
+ else :
68
+ raise ValueError (f'{ mode } not in { self .valid_ref_modes } ' )
69
+
41
70
def set_trigger_mode (self ,mode ):
42
71
"""Sets the synth trigger mode.
43
72
@@ -81,6 +110,16 @@ def program_manual(self, front_panel_values):
81
110
return self .check_remote_values ()
82
111
83
112
def check_remote_value (self ,channel ,typ ):
113
+ """Checks the remote value of a parameter for a channel.
114
+
115
+ Args:
116
+ channel (int): Which channel to check. Must be 0 or 1.
117
+ typ (str): Which parameter to get. Must be `freq`, `amp`, `phase`
118
+ or `gate`.
119
+
120
+ Raises:
121
+ ValueError: If `typ` is not a valid parameter type for the channel.
122
+ """
84
123
85
124
if typ == 'freq' :
86
125
return self .synth [channel ].frequency
@@ -91,9 +130,21 @@ def check_remote_value(self,channel,typ):
91
130
elif typ == 'gate' :
92
131
return self .synth [channel ].rf_enable and self .synth [channel ].pll_enable
93
132
else :
94
- raise ValueError (type )
133
+ raise ValueError (typ )
95
134
96
135
def program_static_value (self ,channel ,typ ,value ):
136
+ """Program a value for the specified parameter of the channel.
137
+
138
+ Args:
139
+ channel (int): Channel to program. Must be 0 or 1.
140
+ typ (str): Parameter to program. Must be `freq`, `amp`, `phase`,
141
+ or `gate`.
142
+ value (float or bool): Value to program. `gate` takes a boolean type,
143
+ all others take a float.
144
+
145
+ Raises:
146
+ ValueError: If requested parameter type is not valid.
147
+ """
97
148
98
149
if typ == 'freq' :
99
150
self .synth [channel ].frequency = value
@@ -104,11 +155,12 @@ def program_static_value(self,channel,typ,value):
104
155
elif typ == 'gate' :
105
156
# windfreak API does not like np.bool_
106
157
# convert to native python bool
107
- if isinstance (value , np .bool_ ): value = value .item ()
158
+ if isinstance (value , np .bool_ ):
159
+ value = value .item ()
108
160
self .synth [channel ].rf_enable = value
109
161
self .synth [channel ].pll_enable = value
110
162
else :
111
- raise ValueError (type )
163
+ raise ValueError (typ )
112
164
113
165
def transition_to_buffered (self , device_name , h5file , initial_values , fresh ):
114
166
@@ -122,21 +174,20 @@ def transition_to_buffered(self, device_name, h5file, initial_values, fresh):
122
174
static_data = group ['STATIC_DATA' ][:][0 ]
123
175
124
176
if static_data is not None :
125
- data = static_data
126
- if fresh or data != self .smart_cache ['STATIC_DATA' ]:
127
-
128
- # need to infer which channels are programming
129
- num_chan = len (data )// len (self .subchnls )
130
- channels = [int (name [- 1 ]) for name in data .dtype .names [0 :num_chan ]]
131
-
132
- for i in channels :
133
- for sub in self .subchnls :
134
- if initial_values [f'channel { i :d} ' ][sub ] != data [sub + str (i )]:
135
- self .program_static_value (i ,sub ,data [sub + str (i )])
136
- # update smart cache to reflect programmed values
137
- self .smart_cache ['STATIC_DATA' ][f'channel { i :d} ' ][sub ] = data [sub + str (i )]
138
- # update final values to reflect programmed values
139
- self .final_values [f'channel { i :d} ' ][sub ] = data [sub + str (i )]
177
+
178
+ # need to infer which channels are programming
179
+ num_chan = len (static_data )// len (self .subchnls )
180
+ channels = [int (name [- 1 ]) for name in static_data .dtype .names [0 :num_chan ]]
181
+
182
+ for i in channels :
183
+ for sub in self .subchnls :
184
+ desired_value = static_data [sub + str (i )]
185
+ if self .smart_cache ['STATIC_DATA' ][f'channel { i :d} ' ][sub ] != desired_value or fresh :
186
+ self .program_static_value (i ,sub ,desired_value )
187
+ # update smart cache to reflect programmed values
188
+ self .smart_cache ['STATIC_DATA' ][f'channel { i :d} ' ][sub ] = desired_value
189
+ # update final values to reflect programmed values
190
+ self .final_values [f'channel { i :d} ' ][sub ] = desired_value
140
191
141
192
return self .final_values
142
193
@@ -161,5 +212,5 @@ def transition_to_manual(self,abort = False):
161
212
# If we're aborting the run, reset to original value
162
213
self .program_manual (self .initial_values )
163
214
# If we're not aborting the run, stick with buffered value. Nothing to do really!
164
- # return the current values in the device
215
+
165
216
return True
0 commit comments