pyEPR.core_quantum_analysis module#

Main interface module to use pyEPR.

Contains code that works on the analysis after hfss, ansys, etc. These can now be closed.

Copyright Zlatko Minev, Zaki Leghtas, and the pyEPR team 2015, 2016, 2017, 2018, 2019, 2020

class pyEPR.core_quantum_analysis.HamiltonianResultsContainer(dict_file=None, data_dir=None)[source]#

Bases: OrderedDict

The user should only use the QuantumAnalysis class interface.

This class is largely for internal use.

It is a dictionary based class to contain the results stored.

clear() None.  Remove all items from od.#
copy() a shallow copy of od#
file_name_extra = ' HamiltonianResultsContainer.npz'#
classmethod fromkeys(iterable, value=None)#

Create a new ordered dictionary with keys from iterable and values set to value.

get(key, default=None, /)#

Return the value for key if key is in the dictionary, else default.

get_chi_ND(variations: list = None, vs='variation')[source]#
get_chi_O1(variations: list = None, vs='variation')[source]#
get_frequencies_HFSS(variations: list = None, vs='variation')[source]#

See help for vs_variations

get_frequencies_ND(variations: list = None, vs='variation')[source]#

See help for vs_variations

get_frequencies_O1(variations: list = None, vs='variation')[source]#

See help for vs_variations

items() a set-like object providing a view on D's items#
keys() a set-like object providing a view on D's keys#
load(filename=None)[source]#

Uses numpy npz file.

move_to_end(key, last=True)#

Move an existing element to the end (or beginning if last is false).

Raise KeyError if the element does not exist.

pop(key[, default]) v, remove specified key and return the corresponding value.#

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem(last=True)#

Remove and return a (key, value) pair from the dictionary.

Pairs are returned in LIFO order if last is true or FIFO order if false.

save(filename: str = None)[source]#

Uses numpy npz file.

setdefault(key, default=None)#

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

update([E, ]**F) None.  Update D from mapping/iterable E and F.#

If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values() an object providing a view on D's values#
vs_variations(quantity: str, variations: list = None, vs='variation', to_dataframe=False)[source]#
QUANTITIES:

f_0 : HFSS Frequencies f_1 : Analytical first order PT on the p=4 term of the cosine f_ND : Numerically diagonalized chi_O1: chi matrix from 1st order PT

Parameters:

[description] (quantity {[type]} --)

Keyword Arguments:
  • (default (vs {str} -- Swept against) – {None} – means all)

  • (default – {‘variation’})

  • dataframe. (to_dataframe {bool} -- convert or not the result to) – Make sure to call only if it can be converted to a DataFrame or can be concatenated into a multi-index DataFrame

Returns:

[type] – [description]

class pyEPR.core_quantum_analysis.QuantumAnalysis(data_filename, variations: list = None, do_print_info=True, Res_hamil_filename=None)[source]#

Bases: object

Quantum Hamiltonian analysis from saved EPR data.

Loads the HDF5/pickle data file written by do_EPR_analysis(), computes dressed eigenmode frequencies, anharmonicities, and cross-Kerr couplings using first-order perturbation theory and/or numerical diagonalization (via QuTiP).

Typical workflow#

epra = epr.QuantumAnalysis(eprd.data_filename)
epra.analyze_all_variations(cos_trunc=8, fock_trunc=7)
epra.plot_hamiltonian_results()
param data_filename:

Path to the .hdf5 data file produced by DistributedAnalysis.

type data_filename:

str or Path

param variations:

Subset of variation labels to load (e.g. ['0', '2']). Defaults to all variations present in the file.

type variations:

list of str, optional

param do_print_info:

Print a summary of loaded data on construction. Defaults to True.

type do_print_info:

bool, optional

param Res_hamil_filename:

Path to a previously saved HamiltonianResultsContainer .npz file. Allows resuming a partially completed analysis.

type Res_hamil_filename:

str or Path, optional

analyze_all_variations(variations: List[str] = None, analyze_previous: bool = False, **kwargs)[source]#

Run analyze_variation() for every variation and save results.

Parameters:
  • variations (list of str, optional) – Variation labels to analyse (e.g. ['0', '1', '3']). Defaults to all variations loaded from the data file.

  • analyze_previous (bool, optional) – If False (default), skip variations whose results are already stored in self.results. Set to True to recompute everything.

  • **kwargs – Forwarded directly to analyze_variation() — e.g. cos_trunc, fock_trunc, modes, junctions, use_full_cos.

Returns:

Mapping of variation label → result dict (same structure as the return value of analyze_variation()).

Return type:

OrderedDict

Note

Results are automatically saved to disk after all variations are processed via HamiltonianResultsContainer.save().

analyze_variation(variation: str, cos_trunc: int = None, fock_trunc: int = None, print_result: bool = True, junctions: List = None, modes: List = None, use_full_cos: bool = False)[source]#

Compute the quantum Hamiltonian parameters for a single variation.

This is the core analysis method. It extracts EPR participation matrices from the stored data, applies perturbation theory, and optionally performs numerical diagonalization via QuTiP.

Parameters:
  • variation (str) – Variation label (e.g. '0', '3').

  • cos_trunc (int, optional) – Cosine Taylor expansion order for the Josephson nonlinearity. Typical values: 4–8. Must be set together with fock_trunc to enable numerical diagonalization; if either is None, only perturbation-theory results are computed. Ignored when use_full_cos=True.

  • fock_trunc (int, optional) – Fock space truncation (number of levels per mode). Typical values: 5–10. Memory scales as fock_trunc ** n_modes.

  • print_result (bool, optional) – Print a formatted summary table of results. Defaults to True.

  • junctions (list, optional) – Subset of junction indices or labels to include. Defaults to all junctions.

  • modes (list, optional) – Subset of mode indices to include (e.g. [0, 4] for modes 0 and 4 of a 5-mode simulation). Must match the indices used in do_EPR_analysis — the DataFrame index retains the original mode numbers, not a zero-based re-index. Defaults to all modes.

  • use_full_cos (bool, optional) – If True, use the exact matrix-exponential cosine cos(φ) = (e^{iφ} + e^{-iφ}) / 2 instead of the truncated Taylor series. Recommended for strongly anharmonic circuits such as fluxonium, where large zero-point phase fluctuations (φ_zpf ≳ 1) make the low-order expansion inaccurate. Default False.

Returns:

Contains at minimum:

  • f_0 — HFSS bare eigenmode frequencies [GHz].

  • f_1 — First-order PT dressed frequencies [MHz].

  • f_ND — Numerically diagonalized dressed frequencies [MHz]; None if cos_trunc/fock_trunc not provided.

  • chi_O1 — Analytic χ matrix [MHz] (diagonal = anharmonicity, off-diagonal = cross-Kerr).

  • chi_ND — Numerically diagonalized χ matrix [MHz]; None if numerical diagonalization was not requested.

Return type:

dict

full_report_variations(var_list: list = None)[source]#

see full_variation_report

full_variation_report(variation)[source]#

prints the results and parameters of a specific variation

Parameters:

variation (int or str) – the variation to be printed .

Return type:

None.

get_Ecs(variation)[source]#

ECs in GHz Returns as pandas series

get_Ejs(variation)[source]#

EJs in GHz See calcs.convert

get_ansys_energies(swp_var='variation')[source]#

Return a multi-index dataframe of ansys energies vs swep_variable

Parameters:

swp_var (str)

get_chis(swp_variable='variation', numeric=True, variations: list = None, m=None, n=None)[source]#

Return the chi (Kerr / cross-Kerr) matrix as a multi-index DataFrame.

The diagonal entries are anharmonicities (self-Kerr); the off-diagonal entries are cross-Kerr couplings between mode pairs.

Parameters:
  • swp_variable (str, optional) – Sweep variable for the outer index (default: "variation").

  • numeric (bool, optional) – If True (default) use numerically diagonalized chi (chi_ND); if False use first-order perturbation theory (chi_O1).

  • variations (list of str, optional) – Subset of variation keys. None returns all.

  • m (int or str, optional) – Row mode label. If both m and n are given, return only the chi element between modes m and n as a Series vs sweep variable.

  • n (int or str, optional) – Column mode label. See m.

Returns:

Multi-index DataFrame (swp_variable, mode_row) × mode_col when m and n are None; a 1-D Series vs sweep variable when both are specified.

Return type:

pandas.DataFrame or pandas.Series

Examples

>>> chi = epra.get_chis()                     # full matrix, all variations
>>> chi_01 = epra.get_chis(m=0, n=1)          # mode-0 / mode-1 cross-Kerr
>>> chi_Lj = epra.get_chis(swp_variable='Lj') # sweep over Lj
get_convergences_max_delta_freq_vs_pass(as_dataframe=True)[source]#

Index([u’Pass Number’, u’Solved Elements’, u’Max Delta Freq. %’ ])

get_convergences_max_tets()[source]#

Index([u’Pass Number’, u’Solved Elements’, u’Max Delta Freq. %’ ])

get_convergences_tets_vs_pass(as_dataframe=True)[source]#

Index([u’Pass Number’, u’Solved Elements’, u’Max Delta Freq. %’ ])

get_epr_base_matrices(variation, _renorm_pj=None, print_=False)[source]#

Return the key matrices used in the EPR method for analytic calculations.

All as matrices
PJ:

Participation matrix, p_mj

SJ:

Sign matrix, s_mj

Om:

Omega_mm matrix (in GHz) (hbar = 1) Not radians.

EJ:

E_jj matrix of Josephson energies (in same units as hbar omega matrix)

PHI_zpf:

ZPFs in units of phi_0 reduced flux quantum

PJ_cap:

capacitive participation matrix

Return all as np.array

PM, SIGN, Om, EJ, Phi_ZPF

get_frequencies(swp_variable='variation', numeric=True, variations: list = None)[source]#

Return mode frequencies as a DataFrame indexed by mode, columns by sweep variable.

Parameters:
  • swp_variable (str, optional) – Name of the sweep variable to use as column labels. "variation" (default) uses the integer variation index; any HFSS variable name (e.g. "Lj") converts the index to that variable’s magnitude.

  • numeric (bool, optional) – If True (default) return numerically diagonalized frequencies (f_ND); if False return first-order perturbation theory frequencies (f_1).

  • variations (list of str, optional) – Subset of variation keys to include. None returns all variations.

Returns:

Rows are eigenmode labels, columns are sweep-variable values.

Return type:

pandas.DataFrame

get_mesh_tot()[source]#
get_participations(swp_variable='variation', variations: list = None, inductive=True, _normed=True)[source]#

Return energy participation ratios (EPR) as a multi-index DataFrame.

Parameters:
  • swp_variable (str, optional) – Sweep variable for the outermost index level (default: "variation").

  • variations (list of str, optional) – Subset of variation keys. None returns all.

  • inductive (bool, optional) – If True (default) return inductive (junction) participation ratios; if False return capacitive participation ratios.

  • _normed (bool, optional) – Return normalised participation ratios (default True). Setting False returns raw un-normalised values. Only valid when inductive is True; inductive=False, _normed=False raises NotImplementedError.

Returns:

Multi-index DataFrame with levels [swp_variable, mode] as the index and junction index as columns.

Return type:

pandas.DataFrame

Examples

Plot junction-0 participation for mode 0 vs a sweep of Lj:

df = epra.get_participations(swp_variable='Lj')
df.loc[pd.IndexSlice[:, 0], 0].unstack(1).plot(marker='o')
get_quality_factors(swp_variable='variation', variations: list = None)[source]#

Return mode quality factors as a DataFrame indexed by mode, columns by sweep variable.

Parameters:
  • swp_variable (str, optional) – Sweep variable for column labels (default: "variation").

  • variations (list of str, optional) – Subset of variation keys to include. None returns all.

Returns:

Rows are eigenmode labels, columns are sweep-variable values. Infinite Q is stored as np.inf for lossless modes.

Return type:

pandas.DataFrame

get_variable_value(swpvar, lv=None)[source]#
get_variable_vs(swpvar, lv=None)[source]#

lv is list of variations (example [‘0’, ‘1’]), if None it takes all variations swpvar is the variable by which to organize

return: ordered dictionary of key which is the variation number and the magnitude of swaver as the item

get_variation_of_multiple_variables_value(Var_dic, lv=None)[source]#

Filter variations by multiple variable values.

See also get_variations_of_variable_value.

Parameters:
  • Var_dic (dict) – variable name → value to filter on.

  • lv (list, optional) – list of variations to search; defaults to all.

Returns:

(filtered_variations, description_string)

Return type:

tuple

get_variations_of_variable_value(swpvar, value, lv=None)[source]#

A function to return all the variations in which one of the variables has a specific value lv is list of variations (example [‘0’, ‘1’]), if None it takes all variations swpvar is a string and the name of the variable we wish to filter value is the value of swapvr in which we are interested

returns lv - a list of the variations for which swavr==value

get_vs_variable(swp_var, attr: str)[source]#

Convert the index of a dictionary that is stored here from variation number to variable value.

Parameters:
  • swp_var (str) – name of sweep variable in ansys

  • attr – name of local attribute, eg.., ‘ansys_energies’

plot_hamiltonian_results(swp_variable: str = 'variation', variations: list = None, fig=None, x_label: str = None)[source]#

Plot Hamiltonian parameters (frequencies, anharmonicities, χ) versus a sweep variable.

Produces a 2×2 grid of subplots: bare and dressed frequencies, χ matrix, and participation ratios.

Parameters:
  • swp_variable (str, optional) – Name of the HFSS variable swept (e.g. 'Lj_alice'). Use 'variation' (default) to plot against the variation index.

  • variations (list of str, optional) – Subset of variations to include. Defaults to all analyzed variations.

  • fig (matplotlib.figure.Figure, optional) – Existing figure to draw into. If None, a new figure is created.

  • x_label (str, optional) – X-axis label. Defaults to swp_variable.

Returns:

(fig, axs) — the matplotlib Figure and 2×2 array of Axes.

Return type:

tuple

plot_results(result, Y_label, variable, X_label, variations: list = None)[source]#
plotting_dic_x(Var_dic, var_name)[source]#
print_info()[source]#
print_result(result)[source]#

Utility reporting function

print_variation(variation)[source]#

Utility reporting function

property project_info#
quick_plot_chi_alpha(mode1, mode2, swp_variable='variation', ax=None, kw=None, numeric=False)[source]#

Quick plot chi between mode 1 and mode 2.

If you select mode1=mode2, then you will plot the alpha

kw : extra plot arguments

quick_plot_convergence(ax=None)[source]#

Plot a report of the Ansys convergence vs pass number ona twin axis for the number of tets and the max delta frequency of the eignemode.

quick_plot_frequencies(mode, swp_variable='variation', ax=None, kw=None, numeric=False)[source]#

Quick plot freq for one mode

kw : extra plot arguments

quick_plot_mode(mode, junction, mode1=None, swp_variable='variation', numeric=False, sharex=True)[source]#

Create a quick report to see mode parameters for only a single mode and a cross-kerr coupling to another mode. Plots the participation and cross participation Plots the frequencie plots the anharmonicity

The values are either for the numeric or the non-numeric results, set by numeric

quick_plot_participation(mode, junction, swp_variable='variation', ax=None, kw=None)[source]#

Quick plot participation for one mode

kw : extra plot arguments

report_results(swp_variable='variation', numeric=True)[source]#

Report in table form the results in a markdown friendly way in Jupyter notebook using the pandas interface.

pyEPR.core_quantum_analysis.extract_dic(name=None, file_name=None)[source]#

#name is the name of the dictionary as saved in the npz file if it is None, the function will return a list of all dictionaries in the npz file file name is the name of the npz file