-
Notifications
You must be signed in to change notification settings - Fork 0
/
shawn_mce_freeze_servo
executable file
·373 lines (314 loc) · 15.1 KB
/
shawn_mce_freeze_servo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
#!/usr/bin/env python
import numpy as np
from mce_control import mce_control
import time
# for checking if we're mux11d (from mce_configure)
import auto_setup as ast
mas_path = ast.util.mas_path()
exp_file = mas_path.experiment_file()
cfg = ast.config.configFile(exp_file)
USAGE="""
%prog [options] stage
Configure the MCE for open loop noise measurements. Basically:
- turns off a bunch of biases
- disables the servo
- disables muxing
- for SQ1 measurements, sets a fixed feedback at the current lock point.
The "stage" argument indicates the highest stage you want to leave
biased. I.e.:
preamp - turn off sa biases and sa offsets.
sa - turn off sq2 biases.
sq2 - turn off muxing, sq1 biases.
sq1 - turn off muxing, tes biases. Requires a --row argument.
tes - turn off muxing. Requires a --row argument.
This program is not good at turning things on carefully. It is mostly
for turning things off. So you probably want to run mce_reconfig
before you run this, or pass "--reconfig" to have the program pre-run
it for you.
"""
from optparse import OptionParser
o = OptionParser(usage=USAGE)
o.add_option('--row', default=None, type=int,
help="specify row to lock (for sq1 and tes stages).")
o.add_option('--reconfig', action='store_true',
help="run mce_reconfig before setting up open loop.")
o.add_option('--frames', default=30, type=int)
o.add_option('--no-reinit', action='store_true',
help="for tes and sq1 stages, do not re-init the servo before "
"measuring the locking feedback.")
o.add_option('--sq1tune', default=None, type="string",
help="(optional) specify tune to pull locking SQ1FB from, instead of doing it on the fly.")
o.add_option('--sq1lock', default='up', type="choice",
choices=('up','dn'),
help="(optional) if specified --sq1tune, which lock point to pull from the tune, up or dn. Default is up.")
opts, args = o.parse_args()
STAGES = ['preamp', 'sa', 'sq2', 'sq1', 'tes']
# load mux11d/hybrid cfg from experiment.cfg
# keeping these integers in case wanted for
# flags later
hybrid_dict=dict()
(ismux11d,ishybrid)=(0,0)
if 'hardware_mux11d' in cfg.keys():
ismux11d=int(cfg['hardware_mux11d'])
if 'mux11d_hybrid_row_select' in cfg.keys():
ishybrid=int(cfg['mux11d_hybrid_row_select'])
# If we're hybrid MUXing, gonna need some more stuff from the config file
if ishybrid==1:
if len(set(['mux11d_row_select_cards','mux11d_row_select_cards_row0','mux11d_mux_order']).intersection(cfg.keys()))==3:
hybrid_dict['mux11d_row_select_cards']=cfg['mux11d_row_select_cards']
hybrid_dict['mux11d_row_select_cards_row0']=cfg['mux11d_row_select_cards_row0']
hybrid_dict['mux11d_mux_order']=cfg['mux11d_mux_order']
else:
o.error("""It looks like you're trying to hybrid MUX, but at least one of ['mux11d_row_select_cards','mux11d_row_select_cards_row0','mux11d_mux_order'] is not defined in experiment.cfg""")
if len(args) != 1 or args[0] not in STAGES:
o.error("Provide a single stage argument (%s)." % ','.join(STAGES))
# If on a mux11d system, there is no SQ2
if ismux11d==True:
if args[0]=='sq2':
o.error("On a mux11d system - there is no sq2!")
stage = args[0]
if stage in ['sq1','tes'] and opts.row == None:
o.error("The %s stage requires a --row argument." % stage)
# A useful function...
def read_and_zero(mce, card, param):
"""
Read values from card,param. Set them to zero in the MCE. Return
the read values.
"""
vals = mce.read(card, param)
mce.write(card, param, np.zeros(len(vals), 'int'))
return vals
# Reconfigure?
if opts.reconfig:
import os
os.system('mce_reconfig')
# Get MCE
mce = mce_control()
if stage == 'sq1':
read_and_zero(mce, 'tes', 'bias')
if stage in ['sq1', 'tes']:
# Re-lock
if not opts.no_reinit:
mce.init_servo()
time.sleep(0.1)
# Check lock:
print 'Columns that appear locked:'
mce.data_mode(0)
data = mce.read_data(opts.frames, row_col=True).data[opts.row,:,:]
err, derr = data.mean(axis=-1), data.std(axis=-1)
locked=(abs(err) < derr*2).astype('int')
print locked
# Get SQ1 locking fb
fb=None
if stage=='sq1' and opts.sq1tune!=None: # pull locking sq1 fb from provided tune
import os
if os.path.isdir(opts.sq1tune):
print 'Pulling locking SQ1 feedbacks from tune=',opts.sq1tune
# Load tune
fs = ast.util.FileSet(opts.sq1tune)
tuning = ast.util.tuningData(exp_file=fs.get('cfg_file'), data_dir='')
sq = ast.SQ1Ramp.join([ast.SQ1Ramp(f) for f in fs.stage_all('sq1_ramp_check')])
sq.tuning = tuning
# Compute locking feedbacks from tune (and other useful info)
sq.reduce()
# Get data shape
n_row, n_col, n_fb = sq.data_shape[-3:]
# Generate a view of the locking feedbacks by row,col
lock_up_x=sq.analysis['lock_%s_x'%opts.sq1lock].reshape(n_row, n_col)
# Print locking feedbacks for desired row
fb=lock_up_x[opts.row].astype('int')
else:
o.error("Asked to pull locking SQ1 feedback from tune=%s but that tune directory doesn\'t seem to exist ...." % opts.sq1tune)
else:
# Measure the feedback.
mce.data_mode(1)
data = mce.read_data(opts.frames, row_col=True).extract('fb')[opts.row,:,:]
fb, dfb = data.mean(axis=-1), data.std(axis=-1)
print 'Locking feedback:'
# There may be a good reason the column is in columns_off ; ie we might
# never want voltage down these SQ1FB lines. Send 0V, for the SQ1FB
# is -8192 DAC.
#fb[np.where(locked==0)]=-8192 # zero for the sq1 fb lines is -8192
columns_off=np.array(cfg['columns_off'][:len(fb)])
fb[np.where(columns_off==1)]=-8192
print fb.astype('int')
# Set fb_const (kill the servo below)
mce.fb_const(fb.astype('int'))
# Only if not MUX11d (otherwise there's no SQ2!)
if not ismux11d:
# There can be only one. One row.
sq1_bias = np.array(mce.read('ac', 'on_bias'))
my_bias = sq1_bias[opts.row]
sq1_bias[:] = 0
sq1_bias[opts.row] = my_bias
mce.write('ac', 'on_bias', sq1_bias)
mce.write('ac', 'off_bias', sq1_bias)
# Sleep for a bit to let those biases get written, then disable mux.
time.sleep(.1)
# Reports from users indicate that setting enbl_mux=0 does not
# work... so we set it to 1.
##mce.write('ac', 'enbl_mux', [0])
mce.write('ac', 'enbl_mux', [0])
# If fast-switching, set up the SQ2 FB to match the chosen row.
# Also disable SQ2 muxing. Hope you chose a good sq2 fb.
sq2_mux = mce.read('sq2', 'enbl_mux')
if np.any(sq2_mux):
sq2_fb = []
for c in range(len(sq2_mux)):
sq2_fb.append(mce.read('sq2', 'fb_col%i'%c)[opts.row])
# It is necessary to disable muxing before writing the new
# (non fast-switching) SQ2 feedback, otherwise it does not get
# applied.
mce.write('sq2', 'enbl_mux', np.zeros(len(sq2_mux)))
time.sleep(.1)
mce.write('sq2', 'fb', sq2_fb)
else:
# Must pick the right SQ1 bias and stop MUXing (if MUXing)
# over SQ1 bias, must pick the right SA FB and stop MUXING
# (if MUXing) over SA FB and must fix the row of interest
# on select, and all other rows on deselect for all row
# visits.
# Fix the row select/deselects first.
ac_select=np.array(mce.read('ac', 'on_bias'))
ac_deselect=np.array(mce.read('ac', 'off_bias'))
ac_row_order=np.array(mce.read('ac','row_order'))
for (ac_idx,(ac_sel,ac_desel)) in enumerate(zip(ac_select,ac_deselect)):
if ac_idx==opts.row:
ac_deselect[int(ac_row_order[ac_idx])]=ac_select[int(ac_row_order[ac_idx])]
else:
ac_select[int(ac_row_order[ac_idx])]=ac_deselect[int(ac_row_order[ac_idx])]
mce.write('ac', 'on_bias', ac_select)
mce.write('ac', 'off_bias', ac_deselect)
# Sleep for a bit to let those biases get written, then disable mux.
time.sleep(.1)
# Reports from users indicate that setting enbl_mux=0 does not
# work... so we set it to 1.
##mce.write('ac', 'enbl_mux', [0])
mce.write('ac', 'enbl_mux', [1])
# If hybrid MUXing, must disable unrequested BC RSes
if ishybrid==1:
row_selects=cfg['row_select']
row_deselects=cfg['row_deselect']
for (r0,card) in zip(hybrid_dict['mux11d_row_select_cards_row0'],hybrid_dict['mux11d_row_select_cards']):
if 'bc' in card:
bc_dacs_used_as_hybrid_row_selects=[0]*32 #32 possible RS DACs per BC
bc_fb_const=[0]*32 # constant value to apply to bc DACs being used as hybrid DACs
for rs_idx,rs in enumerate(hybrid_dict['mux11d_mux_order']):
if rs in range(r0,r0+32):
bc_fb_col=np.array(mce.read(card, 'fb_col%d'%(rs-r0)))
if rs_idx==opts.row:
bc_fb_col.fill(row_selects[rs_idx])
bc_fb_const[(rs-r0)]=row_selects[rs_idx]
else:
bc_fb_col.fill(row_deselects[rs_idx])
bc_fb_const[(rs-r0)]=row_deselects[rs_idx]
# Write this value for every row visit of this BC RS
mce.write(card, 'fb_col%d'%(rs-r0), bc_fb_col)
# Remember this DAC is being used as a hybrid RS so we can turn off MUXing on it
bc_dacs_used_as_hybrid_row_selects[(rs-r0)]=1
# Wait a little bit for those values to get picked up before disabling MUXing
time.sleep(.1)
# Disable muxing on hybrid BC RS DACs
bc_mux = np.array(mce.read(card, 'enbl_mux'))
if np.any(bc_mux):
bc_mux[np.where(np.array(bc_dacs_used_as_hybrid_row_selects)==1)]=0
mce.write(card,'enbl_mux', bc_mux)
# It is necessary to disable muxing before writing the new
# (non fast-switching) BC RS bias, otherwise it won't
# get applied
time.sleep(.1)
# Write constant BC RS fluxes
mce.write(card, 'flux_fb', np.array(bc_fb_const,dtype='int'))
# If fast-switching the SQ1 bias, set it to match the chosen row.
# Also disable the SQ1 muxing. Already chose SQ1 fb above.
sq1_mux = mce.read('sq1', 'enbl_mux')
if np.any(sq1_mux):
sq1_bias=[]
for c in range(len(sq1_mux)):
sq1_bias.append(mce.read('sq1', 'bias_col%i'%c)[opts.row])
# It is necessary to disable muxing before writing the new
# (non fast-switching) SQ1 bias, otherwise it does not get
# applied.
mce.write('sq1', 'enbl_mux', np.zeros(len(sq1_mux)))
time.sleep(.1)
mce.write('sq1', 'bias', sq1_bias)
# If fast-switching the SA fb, set it to match the chosen row.
# Also disable the SA fb muxing.
sa_mux = mce.read('sa', 'enbl_mux')
if np.any(sa_mux):
sa_fb=[]
for c in range(len(sa_mux)):
sa_fb.append(mce.read('sa', 'fb_col%i'%c)[opts.row])
# It is necessary to disable muxing before writing the new
# (non fast-switching) SA fb, otherwise it does not get
# applied.
mce.write('sa', 'enbl_mux', np.zeros(len(sa_mux)))
time.sleep(.1)
mce.write('sa', 'fb', sa_fb)
if stage in ['sq2', 'sa']:
# Kill the SQ1 bias and disable mux.
# (N.B. if we're on a mux11d system,
# these are the AC row select fluxes,
# not the SQ1 biases; but it shouldn't
# hurt to turn them off anyway.
read_and_zero(mce, 'ac', 'on_bias')
read_and_zero(mce, 'ac', 'off_bias')
time.sleep(.1)
mce.write('ac', 'enbl_mux', [0])
# Hybrid MUXing? If yes, must disable BC-driven RSes
if ismux11d==1 and ishybrid==1:
# Hybrid MUX'ing; must also disable BC-driven rows
# ...could probably get away with just blanket disabling
# all bcs w/ hybrid RSes on them, oh well.
for (r0,card) in zip(hybrid_dict['mux11d_row_select_cards_row0'],hybrid_dict['mux11d_row_select_cards']):
if 'bc' in card:
bc_dacs_used_as_hybrid_row_selects=[0]*32 #32 possible RS DACs per BC
for rs in hybrid_dict['mux11d_mux_order']:
if rs in range(r0,r0+32):
# Zero this DAC for every row visit
read_and_zero(mce,card,'fb_col%d'%(rs-r0))
# Remember this DAC is being used as a hybrid RS so we can turn off MUXing on it
bc_dacs_used_as_hybrid_row_selects[(rs-r0)]=1
# Wait a little bit for those values to get picked up before disabling MUXing
time.sleep(.1)
# Disable muxing on hybrid BC RS DACs
bc_mux = np.array(mce.read(card, 'enbl_mux'))
if np.any(bc_mux):
bc_mux[np.where(np.array(bc_dacs_used_as_hybrid_row_selects)==1)]=0
mce.write(card,'enbl_mux', bc_mux)
# Only if not MUX11d (otherwise there's no SQ2!)
if not ismux11d:
# Also disable SQ2 muxing. Hope you chose a good sq2 fb.
sq2_mux = mce.read('sq2', 'enbl_mux')
if np.any(sq2_mux):
mce.write('sq2', 'enbl_mux', np.zeros(len(sq2_mux)))
else:
# Disable SQ1 biases and bias muxing.
sq1_mux = mce.read('sq1', 'enbl_mux')
if np.any(sq1_mux):
mce.write('sq1','enbl_mux', np.zeros(len(sq1_mux)))
time.sleep(.1)
if stage == 'sa':
# Only if not MUX11d (otherwise there's no SQ2!)
if not ismux11d:
# Kill the SQ2 bias
read_and_zero(mce, 'sq2', 'bias')
else:
# Kill the SQ1 bas
read_and_zero(mce, 'sq1', 'bias')
# Disable SA fb muxing
sa_mux = mce.read('sa', 'enbl_mux')
if np.any(sa_mux):
mce.write('sa','enbl_mux', np.zeros(len(sa_mux)))
time.sleep(.1)
# It is necessary to disable muxing before writing the new
# (non fast-switching) SA feedback, otherwise it does not get
# applied.
sa_fb = mce.read('sa', 'fb')
mce.write('sa','fb',sa_fb)
if stage == 'preamp':
read_and_zero(mce, 'sa', 'bias')
read_and_zero(mce, 'sa', 'offset')
# You will probably want error mode data, with the servo off.
mce.servo_mode(1)
mce.data_mode(0)