Coherence Estimates#

[4]:
import scqubits as scq
import matplotlib.pyplot as plt
import numpy as np

Circuits defined through the Circuit objects have the ablity to provide estimates for coherence times. scqubits does this by generating methods associated with various, potentially relevant noise channels (similiariy to what is done for other pre-defined qubits and circuits - see here for details). These methods depend on the topology of the circuit and specific branch types (e.g., capacitive, indcutive or one containing a Josephson junction), as well as flux-loops that the circuit contains.

Let us considder an example “Snail” circuit configuration

[5]:
snail_yaml = """
branches:
- [JJ, 0, 1, 90, EC1=0.2]
- [JJ, 1, 2, 90, EC3=0.2]
- [JJ, 2, 3, 90, 0.2]
- [JJ, 3, 0, 15, 0.2]
- [C, 3, 0, 0.3]
"""

which we can realize with

[6]:
circ = scq.Circuit(snail_yaml, from_file=False, use_dynamic_flux_grouping=True, generate_noise_methods=True)

There two important arguments that are passed to Circuit constructor which determine if and how noise can calculated:

generate_noise_methods: A boolean argument that determines whether methods for estimating coherences are generated for this object.

use_dynamic_flux_grouping: A boolean argument that determines if a flux-grouping based on this You at al. PRB(2019) (or arXiv) paper is generated. This grouping approach is recemmendd any time flux is assumed to have time-dependence (due to noise, or otherwise) as it aims to group flux among different branches in a way that would not require a term proportional to the flux-derviative.

Warning

If generate_noise_methods is not set to True when building a Circuit object, none of the cohernece methods will be generated. Users can however, choose to genrate them at a later time by executing circ.configure(generate_noise_methods=True).

Warning

If use_dynamic_flux_grouping is not set to True when estimating coherence times, to obtain results related to flux noise, scqubits will utilize a more arbitrary grouping, and not the one proposed by You at al. PRB(2019).

Auto-generated supported channels#

The circ object now contains a variety of supported_noise_methods wich can be explictiy listed with:

[29]:
circ.supported_noise_channels()
[29]:
['tphi_1_over_f_flux1',
 'tphi_1_over_f_ng1',
 'tphi_1_over_f_ng2',
 'tphi_1_over_f_ng3',
 'tphi_1_over_f_cc0',
 'tphi_1_over_f_cc1',
 'tphi_1_over_f_cc2',
 'tphi_1_over_f_cc3',
 't1_flux_bias_line1',
 't1_capacitive0',
 't1_capacitive1',
 't1_capacitive2',
 't1_capacitive3',
 't1_capacitive4',
 'tphi_1_over_f_cc',
 'tphi_1_over_f_flux',
 'tphi_1_over_f_ng',
 't1_capacitive',
 't1_flux_bias_line']

In the above we see that scqubits generates relevant methods for each branch or flux-loop (those are indexed with a branch or loop number at the end of method’s name) but also adds a collective method, one for earch noise type. For example, as there are four Joesphosn junctions in our circuit, we have tphi_1_over_f_ccX, with X=0,1,2,3 representing branch indices (that can be listed with circ.branches), as well as tphi_1_over_f_cc, which combines the effects of the critical current \(1/f\) noise from all four junctions (through addition of the rates correspoding to each).

The types of methods that are currently included are: tphi_1_over_f_cc, tphi_1_over_f_flux, tphi_1_over_f_ng, t1_capacitive, t1_flux_bias_line - see the scqubits noise documentation for the description and details of the noise channel that each corresponds to.

Note

Quasiparticle noise, captured by the method t1_quasiparticle_tunneling (see here) has not yet been implemented, but will be at a later date.

Calculating and plotting coherence effects from different noise channels#

Calculating coherence times due to specific noise channels acting on particular branches or loops is done calling the corresponding methods.

Note

Coherence methods implemented by the Circuit class behave the same way as those implemented by other predefind qubits and circuits (e.g, Transmon, Fluxonium, etc.), and retain the same flexibility (i.e., their default parameters can be be easily modified)

Let us remember what the indices of each of the branches are

[30]:
circ.branches
[30]:
[Branch(JJ, 0, 1, id_str: 0),
 Branch(JJ, 1, 2, id_str: 1),
 Branch(JJ, 2, 3, id_str: 2),
 Branch(JJ, 3, 0, id_str: 3),
 Branch(C, 3, 0, id_str: 4)]

and look at the depolarizaion \(T_1\) time, at temperature of 0.1 mK, due to the capacitor between nodes 0 and 3 (i.e., of branch 4), but only including contributions from the downward rate between levels 2 and 1:

[31]:
circ.t1_capacitive(2,1, total=False, T=0.100, Q_cap=1e6)
[31]:
17778.29790642468

By defeault scqubits creates capactive based loss methods for all the Josephson junctions, with the same default parameters that for the stand-alone capacitors. Those however can be easily modified. For example, one can define a custom frequency-dependent quality factor, as in the following

[32]:
def custom_q_cap_fun(omega, T):
    return 1e6 * (2 * np.pi * 6e9 / np.abs(scq.to_standard_units(omega))) ** 0.85

circ.t1_capacitive2(Q_cap = custom_q_cap_fun)
[32]:
199703.34548851577

Alternatively we can look at the dephasing time, due to the \(1/f\) critical current noise in all the junctions (note there is no branch index at the end of the methode name, hence the contributions from all the rates corresponding to this type of noise are included), here with all the default parameters

[8]:
circ.tphi_1_over_f_cc()
[8]:
2308488.4887882355

Plotting is also done in the same way as in for the predefind qubits or circuits. For example let us consider a couple of noise channels, but add some custom scaling, and figure title

[34]:
fig, ax = circ.plot_coherence_vs_paramvals(
    param_name="Φ1",
    param_vals=np.linspace(-0.5, 0.5, 51),
    noise_channels=['tphi_1_over_f_flux', 't1_capacitive1'],
    scale=1e-3,
    ylabel=r"$\mu s$",
    color='black',
    ylim=(None, 1e3)
)
fig.suptitle("Important noise channels");
../../../_images/guide_circuit_ipynb_custom_circuit_coherence_estimates_20_1.svg

Calculating and plotting the “effective” noise effects#

By default when plotting the “effective” coherence times, the noise contributions from all branches and loops are included

[35]:
circ.t1_effective()
[35]:
27824.791750682736

However, if desidred, only subsets of channels can be included (each with their own non-default parameters - see here for more details)

[36]:
circ.t2_effective(noise_channels=['t1_flux_bias_line','t1_capacitive', ('tphi_1_over_f_flux', dict(A_noise=3e-6))], common_noise_options=dict(T=0.050))
[36]:
55586.75401900446

Plotting the effective noise contributions is done in a similar way, and various non-default noise channels, and/or their parameters can be readily specified

[37]:
circ.plot_t2_effective_vs_paramvals(param_name='Φ1',
                            param_vals=np.linspace(-0.5, 0.5, 51),
                            noise_channels=['t1_capacitive', 't1_flux_bias_line',
                                            ('tphi_1_over_f_flux', dict(A_flux=3e-6))],
                            common_noise_options=dict(T=0.050),
                            xlabel=r"$\Phi_x/\Phi_0$",
                            grid='red' # custom grid
                            );
../../../_images/guide_circuit_ipynb_custom_circuit_coherence_estimates_26_1.svg