sodetlib 0.6.1rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sodetlib/__init__.py +22 -0
- sodetlib/_version.py +21 -0
- sodetlib/constants.py +13 -0
- sodetlib/det_config.py +709 -0
- sodetlib/noise.py +624 -0
- sodetlib/operations/__init__.py +5 -0
- sodetlib/operations/bias_dets.py +551 -0
- sodetlib/operations/bias_steps.py +1248 -0
- sodetlib/operations/bias_wave.py +688 -0
- sodetlib/operations/complex_impedance.py +651 -0
- sodetlib/operations/iv.py +716 -0
- sodetlib/operations/optimize.py +189 -0
- sodetlib/operations/squid_curves.py +641 -0
- sodetlib/operations/tracking.py +624 -0
- sodetlib/operations/uxm_relock.py +406 -0
- sodetlib/operations/uxm_setup.py +783 -0
- sodetlib/py.typed +0 -0
- sodetlib/quality_control.py +415 -0
- sodetlib/resonator_fitting.py +508 -0
- sodetlib/stream.py +291 -0
- sodetlib/tes_param_correction.py +579 -0
- sodetlib/util.py +880 -0
- sodetlib-0.6.1rc1.data/scripts/jackhammer +761 -0
- sodetlib-0.6.1rc1.dist-info/LICENSE +25 -0
- sodetlib-0.6.1rc1.dist-info/METADATA +6 -0
- sodetlib-0.6.1rc1.dist-info/RECORD +28 -0
- sodetlib-0.6.1rc1.dist-info/WHEEL +5 -0
- sodetlib-0.6.1rc1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import sodetlib as sdl
|
|
3
|
+
import time
|
|
4
|
+
import matplotlib.pyplot as plt
|
|
5
|
+
from sodetlib.operations.iv import IVAnalysis
|
|
6
|
+
from sodetlib.operations import bias_steps, iv
|
|
7
|
+
np.seterr(all="ignore")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def bias_to_volt_arr(S, cfg, biases, bias_groups=None, overbias=True):
|
|
11
|
+
"""
|
|
12
|
+
Biases detectors using an array of voltages.
|
|
13
|
+
|
|
14
|
+
Args
|
|
15
|
+
-----
|
|
16
|
+
S : SmurfControl
|
|
17
|
+
Pysmurf instance
|
|
18
|
+
cfg : DetConfig
|
|
19
|
+
det config instance
|
|
20
|
+
biases : np.ndarray
|
|
21
|
+
This must be an array of length 12, with the ith element being the
|
|
22
|
+
voltage bias of bias group i. Note that the bias of any bias group
|
|
23
|
+
that is not active, or not specified in the ``bias_groups`` parameter
|
|
24
|
+
will be ignored.
|
|
25
|
+
bias_groups : list
|
|
26
|
+
List of bias groups to bias. If None, this will default to the active
|
|
27
|
+
bgs specified in the device cfg.
|
|
28
|
+
overbias : bool
|
|
29
|
+
If true, will overbias specified bias lines. If false, will set bias
|
|
30
|
+
voltages without overbiasing detectors.
|
|
31
|
+
"""
|
|
32
|
+
if bias_groups is None:
|
|
33
|
+
bias_groups = cfg.dev.exp['active_bgs']
|
|
34
|
+
bias_groups = np.atleast_1d(bias_groups)
|
|
35
|
+
|
|
36
|
+
_biases = S.get_tes_bias_bipolar_array()
|
|
37
|
+
for bg in bias_groups:
|
|
38
|
+
_biases[bg] = biases[bg]
|
|
39
|
+
|
|
40
|
+
S.log(f"Target biases: ")
|
|
41
|
+
for bg in bias_groups:
|
|
42
|
+
S.log(f"BG {bg}: {biases[bg]:.2f}")
|
|
43
|
+
|
|
44
|
+
if overbias:
|
|
45
|
+
sdl.overbias_dets(S, cfg, bias_groups=bias_groups)
|
|
46
|
+
|
|
47
|
+
S.set_tes_bias_bipolar_array(biases)
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
sdl.set_action()
|
|
52
|
+
def bias_to_rfrac(S, cfg, rfrac=None, bias_groups=None, iva=None,
|
|
53
|
+
overbias=True, Rn_range=(5e-3, 12e-3), math_only=False):
|
|
54
|
+
"""
|
|
55
|
+
Biases detectors in their superconducting transitions to a specified fraction
|
|
56
|
+
of their normal resistance ("rfrac"). This function will choose TES bias
|
|
57
|
+
voltages for each bias-group that either (a) are the median bias voltage
|
|
58
|
+
achieving the specified rfrac value, or (b) maximizes the number of channels
|
|
59
|
+
that will be placed in the allowable rfrac range.
|
|
60
|
+
|
|
61
|
+
Args
|
|
62
|
+
----
|
|
63
|
+
S : SmurfControl
|
|
64
|
+
Pysmurf instance
|
|
65
|
+
cfg : DetConfig
|
|
66
|
+
Detconfig instance
|
|
67
|
+
rfrac : float or 2-tuple
|
|
68
|
+
If float, target rfrac value. If tuple, range of allowable rfracs.
|
|
69
|
+
bias_groups : list, optional
|
|
70
|
+
Bias groups to bias. Defaults to active bgs in device cfg.
|
|
71
|
+
iva : IVAnalysis, optional
|
|
72
|
+
IVAnalysis object. If this is passed, will use it to determine
|
|
73
|
+
bias voltages. Defaults to using value in device cfg.
|
|
74
|
+
overbias_voltage : float
|
|
75
|
+
Voltage to use to overbias detectors
|
|
76
|
+
overbias_wait : float
|
|
77
|
+
Time (sec) to wait at overbiased voltage
|
|
78
|
+
Rn_range : tuple
|
|
79
|
+
A "reasonable" range for the TES normal resistance. This will
|
|
80
|
+
be cut on when determining which IVs should be used to determine
|
|
81
|
+
the optimal bias-voltage.
|
|
82
|
+
math_only : bool
|
|
83
|
+
If this is set, will not actually over-bias voltages, and will
|
|
84
|
+
just return the target biases.
|
|
85
|
+
|
|
86
|
+
Returns
|
|
87
|
+
----------
|
|
88
|
+
biases : np.ndarray
|
|
89
|
+
Array of Smurf bias voltages. Note that this includes all smurf
|
|
90
|
+
bias lines (all 15 of them), but only voltages for the requested
|
|
91
|
+
bias-groups will have been modified.
|
|
92
|
+
"""
|
|
93
|
+
if bias_groups is None:
|
|
94
|
+
bias_groups = cfg.dev.exp['active_bgs']
|
|
95
|
+
bias_groups = np.atleast_1d(bias_groups)
|
|
96
|
+
|
|
97
|
+
if iva is None:
|
|
98
|
+
iva = IVAnalysis.load(cfg.dev.exp['iv_file'])
|
|
99
|
+
|
|
100
|
+
if rfrac is None:
|
|
101
|
+
rfrac = cfg.dev.exp['rfrac']
|
|
102
|
+
rfrac = np.atleast_1d(rfrac)
|
|
103
|
+
|
|
104
|
+
if len(rfrac) not in [1,2]:
|
|
105
|
+
raise ValueError(
|
|
106
|
+
f"`rfrac` specified as {rfrac} but must be either float or 2-tuple")
|
|
107
|
+
biases = S.get_tes_bias_bipolar_array()
|
|
108
|
+
|
|
109
|
+
Rfrac = (iva.R.T / iva.R_n).T
|
|
110
|
+
if len(rfrac) == 2:
|
|
111
|
+
in_range = (rfrac[0] < Rfrac) & (Rfrac < rfrac[1])
|
|
112
|
+
|
|
113
|
+
for bg in bias_groups:
|
|
114
|
+
m = (iva.bgmap == bg)
|
|
115
|
+
m = m & (Rn_range[0] < iva.R_n) & (iva.R_n < Rn_range[1])
|
|
116
|
+
|
|
117
|
+
if not m.any():
|
|
118
|
+
continue
|
|
119
|
+
|
|
120
|
+
if len(rfrac) == 1:
|
|
121
|
+
target_biases = []
|
|
122
|
+
for rc in np.where(m)[0]:
|
|
123
|
+
target_idx = np.nanargmin(np.abs(Rfrac[rc] - rfrac[0]))
|
|
124
|
+
target_biases.append(iva.v_bias[target_idx])
|
|
125
|
+
biases[bg] = np.median(target_biases)
|
|
126
|
+
else:
|
|
127
|
+
nchans_in_range = np.sum(in_range[m, :], axis=0)
|
|
128
|
+
target_idx = np.nanargmax(nchans_in_range)
|
|
129
|
+
biases[bg] = iva.v_bias[target_idx]
|
|
130
|
+
|
|
131
|
+
if math_only:
|
|
132
|
+
return biases
|
|
133
|
+
|
|
134
|
+
S.log(f"Target biases: ")
|
|
135
|
+
for bg in bias_groups:
|
|
136
|
+
S.log(f"BG {bg}: {biases[bg]:.2f}")
|
|
137
|
+
|
|
138
|
+
if overbias:
|
|
139
|
+
sdl.overbias_dets(S, cfg, bias_groups=bias_groups)
|
|
140
|
+
|
|
141
|
+
S.set_tes_bias_bipolar_array(biases)
|
|
142
|
+
|
|
143
|
+
return biases
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
bias_to_rfrac_range = bias_to_rfrac
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
sdl.set_action()
|
|
151
|
+
def biasstep_rebias(
|
|
152
|
+
S, cfg, target_percentage_rn=0.5, bias_groups=None,
|
|
153
|
+
show_plots=True, make_plots=True, g3_tag=None):
|
|
154
|
+
|
|
155
|
+
"""
|
|
156
|
+
re-bias detectors by taking bias_steps.
|
|
157
|
+
|
|
158
|
+
Args
|
|
159
|
+
-----
|
|
160
|
+
S : SmurfControl
|
|
161
|
+
Pysmurf instance
|
|
162
|
+
cfg : DetConfig
|
|
163
|
+
det config instance
|
|
164
|
+
target_percentage_rn : float
|
|
165
|
+
this is the target percentage rn for the script to bias to, numbers should be
|
|
166
|
+
between 0.3 and 0.7 for general usage.
|
|
167
|
+
bias_groups : list
|
|
168
|
+
List of bias groups to bias. If None, this will default to the active
|
|
169
|
+
bgs specified in the device cfg.
|
|
170
|
+
make_plots : bool
|
|
171
|
+
If this is set to False, the script will still apply the bias-voltage but will not
|
|
172
|
+
generate plots
|
|
173
|
+
show_plots : bool
|
|
174
|
+
If this is set to False, the script will not show plots
|
|
175
|
+
g3_tag : str
|
|
176
|
+
User settable tag for g3 streams
|
|
177
|
+
|
|
178
|
+
Returns
|
|
179
|
+
----------
|
|
180
|
+
bsa_final :
|
|
181
|
+
analysis result of the last biasstep taken with the re-biased bais voltage
|
|
182
|
+
vbias_estimate_final :
|
|
183
|
+
final bias_voltages calculated and applied by the script
|
|
184
|
+
"""
|
|
185
|
+
if bias_groups is None:
|
|
186
|
+
bias_groups = cfg.dev.exp['active_bgs']
|
|
187
|
+
bias_groups = np.atleast_1d(bias_groups)
|
|
188
|
+
|
|
189
|
+
bs_kwargs = dict(g3_tag=g3_tag, stream_subtype='biasstep_rebias')
|
|
190
|
+
|
|
191
|
+
## take the initial biasstep
|
|
192
|
+
S.log("taking the first biasstep")
|
|
193
|
+
S.log(f"Initial dc biases {S.get_tes_bias_bipolar_array()}")
|
|
194
|
+
bsa_0 = bias_steps.take_bias_steps(S, cfg, **bs_kwargs)
|
|
195
|
+
if make_plots:
|
|
196
|
+
fig, ax = bias_steps.plot_Rfrac(bsa_0)
|
|
197
|
+
fname = sdl.make_filename(S, 'intial_Rfrac.png', plot=True)
|
|
198
|
+
fig.savefig(fname)
|
|
199
|
+
S.pub.register_file(fname, 'biasstep_rfrac', format='png', plot=True)
|
|
200
|
+
if not show_plots:
|
|
201
|
+
plt.close(fig)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
## load IV analysis result so can use dynamic step size
|
|
205
|
+
iva = iv.IVAnalysis.load(bsa_0.meta['iv_file'])
|
|
206
|
+
|
|
207
|
+
repeat_biasstep = False
|
|
208
|
+
## check for script failue
|
|
209
|
+
for bl in bias_groups:
|
|
210
|
+
mask_bg = np.where(bsa_0.bgmap==bl)[0]
|
|
211
|
+
per_bl_R0 = bsa_0.R0[mask_bg]
|
|
212
|
+
if np.isnan(np.nanmedian(per_bl_R0)):
|
|
213
|
+
## the yield is very low, could it be the biasstep analysis script failed? repeat again
|
|
214
|
+
repeat_biasstep = True
|
|
215
|
+
S.log("the biasstep script might have failed, going to repeat the measurement")
|
|
216
|
+
|
|
217
|
+
if repeat_biasstep:
|
|
218
|
+
S.log("retaking biasstep due to failure")
|
|
219
|
+
bsa_0 = bias_steps.take_bias_steps(S, cfg, **bs_kwargs)
|
|
220
|
+
repeat_biasstep = False
|
|
221
|
+
|
|
222
|
+
percentage_rn_0 = bsa_0.R0/bsa_0.R_n_IV
|
|
223
|
+
## add in checks if detectors are SC
|
|
224
|
+
bg_overbias_needed = []
|
|
225
|
+
overbias_needed = False
|
|
226
|
+
for bl in bias_groups:
|
|
227
|
+
mask_bg = np.where(bsa_0.bgmap==bl)[0]
|
|
228
|
+
per_bl_percentage_rn_0 = percentage_rn_0[mask_bg]
|
|
229
|
+
## mask for SC
|
|
230
|
+
mask_sc = np.where((per_bl_percentage_rn_0 < 0.1) & (per_bl_percentage_rn_0 > -0.1))
|
|
231
|
+
## if more than 10 percent of the detectors are SC
|
|
232
|
+
if len(mask_sc[0]) > 0.1*len(mask_bg):
|
|
233
|
+
bg_overbias_needed.append(bl)
|
|
234
|
+
overbias_needed = True
|
|
235
|
+
|
|
236
|
+
## add in check if detectors are normal, hence we should increase the drop step
|
|
237
|
+
bg_detectors_normal = []
|
|
238
|
+
drop_from_normal = False
|
|
239
|
+
for bl in bias_groups:
|
|
240
|
+
mask_bg = np.where(bsa_0.bgmap==bl)[0]
|
|
241
|
+
per_bl_percentage_rn_0 = percentage_rn_0[mask_bg]
|
|
242
|
+
## mask for normal
|
|
243
|
+
mask_normal = np.where((per_bl_percentage_rn_0 > 0.9) | (per_bl_percentage_rn_0 < -0.9))
|
|
244
|
+
## if more than half of the detectors are normal
|
|
245
|
+
if len(mask_normal[0]) > 0.5*len(mask_bg):
|
|
246
|
+
bg_detectors_normal.append(bl)
|
|
247
|
+
drop_from_normal = True
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
if overbias_needed:
|
|
251
|
+
S.log(f"some BL: {bg_overbias_needed} are stuck in SC, going to over bias them, this takes about 5mins")
|
|
252
|
+
previous_dc_biases = S.get_tes_bias_bipolar_array()
|
|
253
|
+
|
|
254
|
+
sdl.overbias_dets(S, cfg, bias_groups=bg_overbias_needed)
|
|
255
|
+
##force wait for UFM to reach equalibrium
|
|
256
|
+
sleep_time = cfg.dev.exp["overbias_sleep_time_sec"]
|
|
257
|
+
time.sleep(sleep_time)
|
|
258
|
+
safe_dc_biases = previous_dc_biases.copy()
|
|
259
|
+
for replace_bg in bg_overbias_needed:
|
|
260
|
+
try:
|
|
261
|
+
safe_dc_biases[replace_bg] = cfg.dev.bias_groups[replace_bg]["testbed_100mK_bias_voltage"]
|
|
262
|
+
except KeyError:
|
|
263
|
+
mask_bg = np.where(bsa_0.bgmap==replace_bg)[0]
|
|
264
|
+
v_norm_bl = np.nanmedian(iva.v_bias[iva.idxs[[mask_bg], 1]])
|
|
265
|
+
safe_dc_biases[replace_bg] = v_norm_bl
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
S.set_tes_bias_bipolar_array(safe_dc_biases)
|
|
269
|
+
bsa_0 = bias_steps.take_bias_steps(S, cfg, **bs_kwargs)
|
|
270
|
+
if make_plots:
|
|
271
|
+
fig, ax = bias_steps.plot_Rfrac(bsa_0)
|
|
272
|
+
fname = sdl.make_filename(S, 'post_overbiasing_Rfrac.png', plot=True)
|
|
273
|
+
fig.savefig(fname)
|
|
274
|
+
S.pub.register_file(fname, 'biasstep_rfrac', format='png', plot=True)
|
|
275
|
+
if not show_plots:
|
|
276
|
+
plt.close(fig)
|
|
277
|
+
|
|
278
|
+
## add in check if detectors are normal now
|
|
279
|
+
percentage_rn_0 = bsa_0.R0/bsa_0.R_n_IV
|
|
280
|
+
drop_from_normal = False
|
|
281
|
+
for bl in bg_overbias_needed:
|
|
282
|
+
mask_bg = np.where(bsa_0.bgmap==bl)[0]
|
|
283
|
+
per_bl_percentage_rn_0 = percentage_rn_0[mask_bg]
|
|
284
|
+
## mask for normal
|
|
285
|
+
mask_normal = np.where((per_bl_percentage_rn_0 > 0.9) | (per_bl_percentage_rn_0 < -0.9))
|
|
286
|
+
## if more than half of the detectors are normal
|
|
287
|
+
if len(mask_normal[0]) > 0.5*len(mask_bg):
|
|
288
|
+
bg_detectors_normal.append(bl)
|
|
289
|
+
drop_from_normal = True
|
|
290
|
+
|
|
291
|
+
## drop normal detector into transition first
|
|
292
|
+
while drop_from_normal:
|
|
293
|
+
S.log(f"some biaslines are still in normal state: {bg_detectors_normal}")
|
|
294
|
+
percentage_rn_0 = bsa_0.R0/bsa_0.R_n_IV
|
|
295
|
+
S.log("droping detectors from normal to transition")
|
|
296
|
+
previous_dc_biases_dfn = S.get_tes_bias_bipolar_array()
|
|
297
|
+
|
|
298
|
+
S.log(f"current tes bias voltages are: {previous_dc_biases_dfn}")
|
|
299
|
+
for bl in bg_detectors_normal:
|
|
300
|
+
mask_bg = np.where(bsa_0.bgmap==bl)[0]
|
|
301
|
+
v_sc = iva.v_bias[iva.idxs[[mask_bg], 0]]
|
|
302
|
+
v_norm = iva.v_bias[iva.idxs[[mask_bg], 1]]
|
|
303
|
+
v_spread = np.nanmedian(v_norm) - np.nanmedian(v_sc)
|
|
304
|
+
if previous_dc_biases_dfn[bl] > v_spread:
|
|
305
|
+
previous_dc_biases_dfn[bl] = previous_dc_biases_dfn[bl] - 0.5 * v_spread
|
|
306
|
+
else:
|
|
307
|
+
previous_dc_biases_dfn[bl] = previous_dc_biases_dfn[bl] - 0.3 * v_spread
|
|
308
|
+
bg_detectors_normal.remove(bl)
|
|
309
|
+
S.log(f'biasline {bl} is approching 0 voltage, a confirmation new IV curve is recommended')
|
|
310
|
+
|
|
311
|
+
S.set_tes_bias_bipolar_array(previous_dc_biases_dfn)
|
|
312
|
+
S.log(f"applying: {previous_dc_biases_dfn}")
|
|
313
|
+
S.log(f"waiting 10s for dissipation of UFM local heating")
|
|
314
|
+
time.sleep(10)
|
|
315
|
+
bsa_0 = bias_steps.take_bias_steps(S, cfg, **bs_kwargs)
|
|
316
|
+
percentage_rn_0 = bsa_0.R0/bsa_0.R_n_IV
|
|
317
|
+
drop_from_normal = False
|
|
318
|
+
for bl in bg_detectors_normal:
|
|
319
|
+
mask_bg = np.where(bsa_0.bgmap==bl)[0]
|
|
320
|
+
per_bl_percentage_rn_0 = percentage_rn_0[mask_bg]
|
|
321
|
+
## mask for normal
|
|
322
|
+
mask_normal = np.where((per_bl_percentage_rn_0 > 0.9) | (per_bl_percentage_rn_0 < -0.9))
|
|
323
|
+
## if more than half of the detectors are normal
|
|
324
|
+
if len(mask_normal[0]) > 0.5*len(mask_bg):
|
|
325
|
+
drop_from_normal = True
|
|
326
|
+
else:
|
|
327
|
+
bg_detectors_normal.remove(bl)
|
|
328
|
+
for bl in bg_detectors_normal:
|
|
329
|
+
if previous_dc_biases_dfn[bl] < 0.5:
|
|
330
|
+
bg_detectors_normal.remove(bl)
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
##preparing for the 2nd step
|
|
336
|
+
initial_dc_biases = S.get_tes_bias_bipolar_array()
|
|
337
|
+
new_bias_voltage = initial_dc_biases.copy()
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
for bl in bias_groups:
|
|
343
|
+
mask_bg = np.where(bsa_0.bgmap==bl)[0]
|
|
344
|
+
|
|
345
|
+
per_bl_percentage_rn_0 = percentage_rn_0[mask_bg]
|
|
346
|
+
|
|
347
|
+
med_per_bl_percentage_rn = np.nanmedian(per_bl_percentage_rn_0)
|
|
348
|
+
|
|
349
|
+
## use the latest IV to decide the step size, might be tricky to get a good step size in field
|
|
350
|
+
v_sc = iva.v_bias[iva.idxs[[mask_bg], 0]]
|
|
351
|
+
v_norm = iva.v_bias[iva.idxs[[mask_bg], 1]]
|
|
352
|
+
v_spread = np.nanmedian(v_norm) - np.nanmedian(v_sc)
|
|
353
|
+
## take 15% of the spread as the step size, so the next biasstep will be taken from 0.25 ~ 0.75 percent Rn after considering the spread
|
|
354
|
+
delta_dc_bias = 0.15 * v_spread
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
## if the current bias point is below 50% Rn, increase V_biaa
|
|
358
|
+
if med_per_bl_percentage_rn < 0.5:
|
|
359
|
+
new_bias_voltage[bl] = initial_dc_biases[bl] + delta_dc_bias
|
|
360
|
+
if med_per_bl_percentage_rn >= 0.5:
|
|
361
|
+
new_bias_voltage[bl] = initial_dc_biases[bl] - delta_dc_bias
|
|
362
|
+
|
|
363
|
+
S.log(f"applying new voltage for 2nd biasstep {new_bias_voltage}")
|
|
364
|
+
S.set_tes_bias_bipolar_array(new_bias_voltage)
|
|
365
|
+
|
|
366
|
+
## taking the second bias step
|
|
367
|
+
S.log("taking the 2nd biasstep")
|
|
368
|
+
bsa_1 = bias_steps.take_bias_steps(S, cfg, **bs_kwargs)
|
|
369
|
+
if make_plots:
|
|
370
|
+
fig, ax = bias_steps.plot_Rfrac(bsa_1)
|
|
371
|
+
fname = sdl.make_filename(S, '2nd_Rfrac.png', plot=True)
|
|
372
|
+
fig.savefig(fname)
|
|
373
|
+
S.pub.register_file(fname, 'biasstep_rfrac', format='png', plot=True)
|
|
374
|
+
if not show_plots:
|
|
375
|
+
plt.close(fig)
|
|
376
|
+
|
|
377
|
+
## check for script failue
|
|
378
|
+
for bl in bias_groups:
|
|
379
|
+
mask_bg = np.where(bsa_1.bgmap==bl)[0]
|
|
380
|
+
per_bl_R0 = bsa_1.R0[mask_bg]
|
|
381
|
+
if np.isnan(np.nanmedian(per_bl_R0)):
|
|
382
|
+
## the yield is very low, could it be the biasstep analysis script failed? repeat again
|
|
383
|
+
repeat_biasstep = True
|
|
384
|
+
S.log("the biasstep script might have failed, going to repeat the measurement")
|
|
385
|
+
|
|
386
|
+
if repeat_biasstep:
|
|
387
|
+
bsa_1 = bias_steps.take_bias_steps(S, cfg, **bs_kwargs)
|
|
388
|
+
repeat_biasstep = False
|
|
389
|
+
|
|
390
|
+
percentage_rn_1 = bsa_1.R0/bsa_1.R_n_IV
|
|
391
|
+
|
|
392
|
+
target_percentage_rn_array = target_percentage_rn * np.ones(len(percentage_rn_0))
|
|
393
|
+
## getting result from the previous 2
|
|
394
|
+
v0 = np.zeros(bsa_0.bgmap.shape[0])
|
|
395
|
+
for bl in range(12):
|
|
396
|
+
mask_bl = np.where(bsa_0.bgmap==bl)[0]
|
|
397
|
+
v0[mask_bl] = initial_dc_biases[bl]
|
|
398
|
+
|
|
399
|
+
v1 = np.zeros(bsa_1.bgmap.shape[0])
|
|
400
|
+
for bl in range(12):
|
|
401
|
+
mask_bl = np.where(bsa_1.bgmap==bl)[0]
|
|
402
|
+
v1[mask_bl] = new_bias_voltage[bl]
|
|
403
|
+
## deciding the new bias point
|
|
404
|
+
vbias_estimate_array = (v0*(target_percentage_rn_array-percentage_rn_1) + v1*(percentage_rn_0 - target_percentage_rn_array)) / (percentage_rn_0 - percentage_rn_1)
|
|
405
|
+
|
|
406
|
+
vbias_estimate = initial_dc_biases.copy()
|
|
407
|
+
for bl in bias_groups:
|
|
408
|
+
mask_bg = np.where(bsa_0.bgmap==bl)[0]
|
|
409
|
+
|
|
410
|
+
per_bl_vbias_estimate = vbias_estimate_array[mask_bg]
|
|
411
|
+
med_per_bl_vbias_estimate = np.nanmedian(per_bl_vbias_estimate)
|
|
412
|
+
if np.isnan(med_per_bl_vbias_estimate):
|
|
413
|
+
med_per_bl_vbias_estimate = (np.nanmedian(v1[mask_bg]) + np.nanmedian(v0[mask_bg]))/2
|
|
414
|
+
vbias_estimate[bl] = med_per_bl_vbias_estimate
|
|
415
|
+
|
|
416
|
+
S.log("applying the new bias voltages")
|
|
417
|
+
S.set_tes_bias_bipolar_array(vbias_estimate)
|
|
418
|
+
S.log(f"applying {vbias_estimate}")
|
|
419
|
+
S.log("taking the final biasstep")
|
|
420
|
+
bsa_2 = bias_steps.take_bias_steps(S, cfg, **bs_kwargs)
|
|
421
|
+
|
|
422
|
+
## check for script failue
|
|
423
|
+
for bl in bias_groups:
|
|
424
|
+
mask_bg = np.where(bsa_2.bgmap==bl)[0]
|
|
425
|
+
per_bl_R0 = bsa_2.R0[mask_bg]
|
|
426
|
+
if np.isnan(np.nanmedian(per_bl_R0)):
|
|
427
|
+
## the yield is very low, could it be the biasstep analysis script failed? repeat again
|
|
428
|
+
repeat_biasstep = True
|
|
429
|
+
S.log("the biasstep script might have failed, going to repeat the measurement")
|
|
430
|
+
|
|
431
|
+
if repeat_biasstep:
|
|
432
|
+
bsa_2 = bias_steps.take_bias_steps(S, cfg, **bs_kwargs)
|
|
433
|
+
repeat_biasstep = False
|
|
434
|
+
|
|
435
|
+
if make_plots:
|
|
436
|
+
fig, ax = bias_steps.plot_Rfrac(bsa_2)
|
|
437
|
+
fname = sdl.make_filename(S, 'rebiased_Rfrac.png', plot=True)
|
|
438
|
+
fig.savefig(fname)
|
|
439
|
+
S.pub.register_file(fname, 'biasstep_rfrac', format='png', plot=True)
|
|
440
|
+
if not show_plots:
|
|
441
|
+
plt.close(fig)
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
S.log("confirming if the current result is close to the target")
|
|
445
|
+
percentage_rn_confirm = bsa_2.R0/bsa_2.R_n_IV
|
|
446
|
+
succeeded_bl = []
|
|
447
|
+
un_succeeded_bl = []
|
|
448
|
+
for bl in bias_groups:
|
|
449
|
+
mask_bg = np.where(bsa_2.bgmap==bl)[0]
|
|
450
|
+
per_bl_percentage_rn_confirm = np.nanmedian(percentage_rn_confirm[mask_bg])
|
|
451
|
+
if per_bl_percentage_rn_confirm > target_percentage_rn - 0.05 and per_bl_percentage_rn_confirm < target_percentage_rn + 0.05:
|
|
452
|
+
succeeded_bl.append(bl)
|
|
453
|
+
else:
|
|
454
|
+
un_succeeded_bl.append(bl)
|
|
455
|
+
S.log(f"succeeded bl: {succeeded_bl}")
|
|
456
|
+
S.log(f"unsucceeded bl: {un_succeeded_bl}")
|
|
457
|
+
|
|
458
|
+
if len(un_succeeded_bl)==0:
|
|
459
|
+
bsa_final = bsa_2
|
|
460
|
+
vbias_estimate_final = vbias_estimate
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
if len(un_succeeded_bl)!=0:
|
|
464
|
+
extra_step_bias_voltage = vbias_estimate.copy()
|
|
465
|
+
S.log("fine tunning unsucceeded bl")
|
|
466
|
+
for bl in un_succeeded_bl:
|
|
467
|
+
mask_bg = np.where(bsa_2.bgmap==bl)[0]
|
|
468
|
+
per_bl_percentage_rn_confirm = percentage_rn_confirm[mask_bg]
|
|
469
|
+
med_per_bl_percentage_confirm = np.nanmedian(per_bl_percentage_rn_confirm)
|
|
470
|
+
|
|
471
|
+
## use the latest IV to decide the step size, might be tricky to get a good step size in field
|
|
472
|
+
v_sc = iva.v_bias[iva.idxs[[mask_bg], 0]]
|
|
473
|
+
v_norm = iva.v_bias[iva.idxs[[mask_bg], 1]]
|
|
474
|
+
v_spread = np.nanmedian(v_norm) - np.nanmedian(v_sc)
|
|
475
|
+
## take 15% of the spread as the step size, so the next biasstep will be taken from 0.25 ~ 0.75 percent Rn after considering the spread
|
|
476
|
+
delta_dc_bias = 0.15 * v_spread
|
|
477
|
+
## if the current bias point is below 50% Rn, increase V_biaa
|
|
478
|
+
if med_per_bl_percentage_confirm < 0.5:
|
|
479
|
+
extra_step_bias_voltage[bl] = vbias_estimate[bl] + delta_dc_bias
|
|
480
|
+
if med_per_bl_percentage_confirm >= 0.5:
|
|
481
|
+
extra_step_bias_voltage[bl] = vbias_estimate[bl] - delta_dc_bias
|
|
482
|
+
|
|
483
|
+
S.log(f"applying new voltage for extra step biasstep {extra_step_bias_voltage}")
|
|
484
|
+
S.set_tes_bias_bipolar_array(extra_step_bias_voltage)
|
|
485
|
+
|
|
486
|
+
## taking the extra bias step
|
|
487
|
+
S.log("taking the extra biasstep")
|
|
488
|
+
bsa_extra = bias_steps.take_bias_steps(S, cfg, **bs_kwargs)
|
|
489
|
+
|
|
490
|
+
## check for script failue
|
|
491
|
+
for bl in bias_groups:
|
|
492
|
+
mask_bg = np.where(bsa_extra.bgmap==bl)[0]
|
|
493
|
+
per_bl_R0 = bsa_extra.R0[mask_bg]
|
|
494
|
+
if np.isnan(np.nanmedian(per_bl_R0)):
|
|
495
|
+
## the yield is very low, could it be the biasstep analysis script failed? repeat again
|
|
496
|
+
repeat_biasstep = True
|
|
497
|
+
S.log("the biasstep script might have failed, going to repeat the measurement")
|
|
498
|
+
|
|
499
|
+
if repeat_biasstep:
|
|
500
|
+
bsa_extra = bias_steps.take_bias_steps(S, cfg, **bs_kwargs)
|
|
501
|
+
repeat_biasstep = False
|
|
502
|
+
|
|
503
|
+
if make_plots:
|
|
504
|
+
fig, ax = bias_steps.plot_Rfrac(bsa_extra)
|
|
505
|
+
fname = sdl.make_filename(S, '3rd_Rfrac.png', plot=True)
|
|
506
|
+
fig.savefig(fname)
|
|
507
|
+
S.pub.register_file(fname, 'biasstep_rfrac', format='png', plot=True)
|
|
508
|
+
if not show_plots:
|
|
509
|
+
plt.close(fig)
|
|
510
|
+
|
|
511
|
+
percentage_rn_extra = bsa_extra.R0/bsa_extra.R_n_IV
|
|
512
|
+
|
|
513
|
+
## getting result from the previous 2
|
|
514
|
+
v0 = np.zeros(bsa_2.bgmap.shape[0])
|
|
515
|
+
for bl in range(12):
|
|
516
|
+
mask_bl = np.where(bsa_2.bgmap==bl)[0]
|
|
517
|
+
v0[mask_bl] = vbias_estimate[bl]
|
|
518
|
+
|
|
519
|
+
v1 = np.zeros(bsa_extra.bgmap.shape[0])
|
|
520
|
+
for bl in range(12):
|
|
521
|
+
mask_bl = np.where(bsa_extra.bgmap==bl)[0]
|
|
522
|
+
v1[mask_bl] = extra_step_bias_voltage[bl]
|
|
523
|
+
## deciding the new bias point
|
|
524
|
+
vbias_estimate_array_extra = (v0*(target_percentage_rn_array-percentage_rn_extra) + v1*(percentage_rn_confirm - target_percentage_rn_array)) / (percentage_rn_confirm - percentage_rn_extra)
|
|
525
|
+
|
|
526
|
+
vbias_estimate_final = initial_dc_biases.copy()
|
|
527
|
+
for bl in bias_groups:
|
|
528
|
+
mask_bg = np.where(bsa_2.bgmap==bl)[0]
|
|
529
|
+
|
|
530
|
+
per_bl_vbias_estimate = vbias_estimate_array_extra[mask_bg]
|
|
531
|
+
med_per_bl_vbias_estimate = np.nanmedian(per_bl_vbias_estimate)
|
|
532
|
+
if np.isnan(med_per_bl_vbias_estimate):
|
|
533
|
+
med_per_bl_vbias_estimate = (np.nanmedian(v1[mask_bg]) + np.nanmedian(v0[mask_bg]))/2
|
|
534
|
+
vbias_estimate_final[bl] = med_per_bl_vbias_estimate
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
S.log("applying the new bias voltages")
|
|
538
|
+
S.set_tes_bias_bipolar_array(vbias_estimate_final)
|
|
539
|
+
S.log(f"applying {vbias_estimate_final}")
|
|
540
|
+
S.log("taking the final biasstep")
|
|
541
|
+
bsa_final = bias_steps.take_bias_steps(S, cfg, **bs_kwargs)
|
|
542
|
+
if make_plots:
|
|
543
|
+
fig, ax = bias_steps.plot_Rfrac(bsa_final)
|
|
544
|
+
fname = sdl.make_filename(S, 'rebiased_Rfrac_2.png', plot=True)
|
|
545
|
+
fig.savefig(fname)
|
|
546
|
+
S.pub.register_file(fname, 'biasstep_rfrac', format='png', plot=True)
|
|
547
|
+
if not show_plots:
|
|
548
|
+
plt.close(fig)
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
return bsa_final,vbias_estimate_final
|