Complex Impedance
The complex impedance measurement is a simple measurement that gives us access to many electrothermal properties of the TES.
Following the theory presented in Irwin and Hilton, the complex impedance is given by:
where \(\beta_I = \left.\frac{d \log R}{d\log I}\right|_{T_\mathrm{bath}}\) is the current sensitivity at constant temp, \(\mathscr{L}_I\) the loop-gain, and \(\tau_I\) the thermal time-constant at constant current. We are able to fit these parameters to our complex impedance measurement, and obtain derived parameters such as the effective thermal time-constant:
Measurement
The complex impedance can be measured via the complex transfer functions of the TES as a function of frequency. To do this we play a sine-wave on the bias line over a large frequency range, and measure the amplitude and phase (with respect to the commanded bias) as a function of frequency.
In order to remove parasitic contamination from the bias circuitry, we use measurements of the TES response while the detectors are in their superconducting and normal states to obtain the Thevenin equivalent voltage and impedance of the bias circuit (see Lindeman et al.). The equivalent voltage and impedance are given by:
and the TES impedance given by
Where \(V_\mathrm{th}\), \(I_\mathrm{ob}\), \(I_\mathrm{sc}\), \(I\) and \(Z_\mathrm{eq}\) are all complex phasors that are functions of frequency.
Operation
The complex impedance measurement consists of two parts. First, measuring the superconducting and overbiased transfer functions. This only needs to be done once per cooldown, and then the results can be used for any Ztes measurement. Then we measure the transfer functions while the detectors are in transition.
These measurements all use the same base function, take_complex_impedance
which streams data for each bias-group while playing sine waves at different
frequencies.
The function take_complex_impedance_ob_sc function will take CI data in the
overbiased and superconducting states, and save their paths in the device
config for later use.
For example, the following code will take SC, OB, and in-transition datasets:
import sodetlib.operations.complex_impedance as ci
from sodetlib.operations import bias_dets
freqs = np.logspace(0, np.log10(2e3), 80)
bgs = np.arange(12)
ci.take_complex_impedance_ob_sc(S, cfg, bgs, freqs=freqs, run_analysis=True)
bias_dets.bias_to_rfrac_range(S, cfg, (0.3, 0.6))
time.sleep(60)
ds = ci.take_complex_impedance(S, cfg, bgs, freqs=freqs, run_analysis=True)
The output ds (for dataset) is an AxisManager containing a bunch of fields
including the complex-impedance for each detector. See the docstring for the
analysis functions analyze_tods, get_ztes, fit_det_params to see
what fields it contains.
On creation, the ds AxisManager is automatically loaded with
superconducting and overbiased data from the files that are set in the device
cfg. This means that the saved hdf5 file contains all the info needed for
analysis, and there is no need to manually add sc and ob data on load. For
instance, to load and plot data from a file, one can simply run:
from sotodlib.core import AxisManager
import sodetlib.operations.complex_impedance as ci
ds = AxisManager.load('/path/to/trans.h5')
# Plot transfer functions for channel with index 0.
ci.plot_transfers(ds, 0)
Note
The complex impedance dataset can only measure frequencies up to half the
sampling rate. It can be very beneficial to measure out to higher
frequencies to better constrain detector parameters, so if you are measuring
high frqeuencies it is recommended to set a flux-ramp rate of 10 kHz or more
before taking data. This can be done easily using the
relock_tracking_setup function.
However, if you are running at high sample rates, analysis may take upwards of 20 min or so to run per dataset (for a ufm with 12 biasgroups). This time is dominated by the time it takes to load datafiles with high sample rates from G3.
API
- sodetlib.operations.complex_impedance.analyze_seg(ds, tod, bg, i)
Analyze segment of CI data. The main goal of this is to calculate the Ites phasor, containing the amplitude (A) and phase (relative tot he commanded) of the TES response to an incoming sine wave. This performs the following steps:
Restrict full TOD to a single excitation frequency. This will put everything units of A, correct for channel polarity. This will also correct timestamps based on the FrameCounter.
Takes PSD of the bias data to obtain the reference freq. Filters signal using gaussian filter around reference freq.
Use lock-in amplification with bias as reference to extract amplitude and phase of the filtered signal with respect to the commanded bias.
- Parameters:
ds (AxisManager) – CI Dataset
tod (AxisManger) – axis-manager containing tod for a given bias group
bg (int) – Bias group that is being analyzed
i (int) – Freq index. 0 will analyze the first freq segment taken.
- Returns:
am – Returns an souped-up tod axis-manager corresponding to this freq with the following fields:
timestmaps, biases, signal, ch_info. Standard tod axismanager stuff but with units converted into A, timestamps fixed, and offsets subtracted out.
sample_rate, cmd_freq: Floats with the sample rate and commanded freq
filt_sig: Filtered signal (using gaussian filter around commanded freq)
lockin_x, lockin_y: Lockin x and y signals, used to calc amp and phase across the tod
Ites: Phasor for Ites. Amplitude is the amp of the sine wave response, and angle is the phase relative to the commanded bias.
- Return type:
AxisManager
- sodetlib.operations.complex_impedance.analyze_tods(ds, bgs=None, tod=None, arc=None, show_pb=True)
Analyzes TODS for a CIData set. This will add the following fields to the dataset:
Ites(dets, steps): Ites phasor for each detector / frequency combination. Amplitude is the amp of the current response (A), and angle is the phase relative to commanded bias.
Ibias(biaslines): Amplitude (A) of the sinewave used for each biasline.
Ibias_dc(biaslines): DC bias current (A) for each biasline
res_freqs(dets): Resonance frequency of each channel detectors.
- sodetlib.operations.complex_impedance.fit_det_params(ds, pb=False, fmax=None)
Fits detector params for a sweep.
- Parameters:
ds (AxisManager) – CIData
pb (bool) – If True, wil display progressbar.
fmax (optional, float) – If set, will only fit using freq values less than fmax.
- sodetlib.operations.complex_impedance.get_ztes(ds)
Calculates Ztes for in-transition CIData. Adds the following fields to the CI dataset:
Rn (dets): Normal resistances based off of low-f overbiased data points.
Rtes (dets): TES Resistance, based off of low-f in-transition segment
Vth (dets): Thevenin equiv voltage (V)
Zeq (dets): Equiv impedance
Ztes (dets): TES complex impedance
- sodetlib.operations.complex_impedance.take_complex_impedance(S, cfg, bgs, freqs=None, state='transition', nperiods=500, max_meas_time=20.0, tickle_voltage=0.005, run_analysis=False)
Takes a complex impedance sweep. This will play sine waves on specified bias-groups over the current DC bias voltage. This returns a CISweep object.
- Parameters:
S (SmurfControl) – Pysmurf Instance
cfg (DetConfig) – Det config instance
bgs (array, int) – List of bias groups to run on
freqs (array, optional) – List of frequencies to sweep over.
state (str) – Current detector state. Must be ‘ob’, ‘sc’, or ‘transition’
nperiods (float) – Number of periods to measure for at each frequency. If the meas_time ends up larger than
max_meas_time,max_meas_timewill be used instead. This makes it so we don’t spend unreasonably long amounts of time at higher freqs.max_meas_time (float) – Maximum amount of time to wait at any given frequency
tickle_voltage (float) – Tickle amplitude in low-current-mode volts.
run_analysis (bool) – Perform the full CI analysis and save the results.
- sodetlib.operations.complex_impedance.take_complex_impedance_ob_sc(S, cfg, bgs, overbias_voltage=19.9, tes_bias=15.0, overbias_wait=5.0, cool_wait=30.0, run_analysis=True, **ci_kwargs)
Takes overbiased and superconducting complex impedance sweeps. These are required to analyze any in-transition sweeps.
- Parameters:
S (SmurfControl) – Pysmurf Instance
cfg (DetConfig) – Det config instance
bgs (array, int) – List of bias groups to run on
overbias_voltage (float) – Voltage to use to overbias detectors
tes_bias (float) – Voltage to set detectors to after overbiasing
overbias_wait (float) – Time to wait at the overbias_voltage
cool_wait (float) – Time to wait at the tes_bias after overbiasing
run_analysis (bool) – Perform the full CI analysis and save the results.
**ci_kwargs – Any additional kwargs will be passed directly to the
take_complex_impedancefunction.