Source code for pyEPR.calcs.convert

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Mar 19 18:14:08 2019

Unit and variable conversions.

@author: Zlatko Minev
"""

from __future__ import (
    absolute_import,  # Python 2.7 and 3 compatibility
    division,
    print_function,
)

import numpy as np
import pandas as pd
from numpy import sqrt

from .basic import CalcsBasic
from .constants import Planck, e_el, elementary_charge, fluxQ, hbar, pi, ħ, π, ϕ0


[docs] class Convert: """ Static container class for conversions of units and variables. TEST CONVERSION: .. code-block:: python from pyEPR.toolbox.conversions import Convert Lj_nH, Cs_fF = 11, 60 Convert.transmon_print_all_params(Lj_nH, Cs_fF); """ # Known SI prefixed _prefix = { "y": -24, # yocto "z": -21, # zepto "a": -18, # atto "f": -15, # femto "p": -12, # pico "n": -9, # nano "u": -6, # micro "m": -3, # mili "c": -2, # centi "d": -1, # deci " ": 0, "k": 3, # kilo "M": 6, # mega "G": 9, # giga "T": 12, # tera "P": 15, # peta "E": 18, # exa "Z": 21, # zetta "Y": 24, # yotta } # Known SI units _SI_units = [ "H", # Henries "F", # Farads "Hz", # Hertz "Ohm", # Ohms "Ω", # Ohms "Wb" "J", # Webers # Joules "A", # Amps ]
[docs] @staticmethod def toSI(number, from_units: str): r""" Convert from SI unit prefix to regular SI units If the from_units is ' ' or not in the prefix list, then the unit is assumed to be """ if from_units in Convert._SI_units: from_units = " " # else: we assume that the first letter is a prefix return number * (10 ** Convert._prefix.get(from_units[0]))
[docs] @staticmethod def fromSI(number, from_units: str): r"""Convert a number with SI units, such as fF to F. Arguments: number {[numeric]} -- number from_units {str} -- string Returns: numeric number, with units expanded """ if from_units in Convert._SI_units: from_units = " " # else: we assume that the first letter is a prefix return number * (10 ** (-Convert._prefix.get(from_units[0])))
@staticmethod def _convert_num(out_func, in_num, in_units, out_units): in_num = 1.0 * in_num # to float # convert units of input number in_num = Convert.toSI(in_num, in_units) out_num = out_func(in_num) # Assume func processes all in SI units out_num = Convert.fromSI(out_num, out_units) return out_num
[docs] @staticmethod def Ej_from_Lj(Lj, units_in="nH", units_out="MHz"): r""" Josephson Junction energy from Josephson inductance. Returns in MHz :math:`E_j = \phi_0^2 / L_J` """ return Convert._convert_num( # Plank to go from Joules to Hz lambda _Lj: Planck**-1 * (ϕ0**2) / _Lj, Lj, units_in, units_out, )
[docs] @staticmethod def Lj_from_Ej(Ej, units_in="MHz", units_out="nH"): r""" Josephson Junction ind from Josephson energy in MHZ. Returns in units of nano Henries by default :math:`E_j = \phi_0^2 / L_J` """ return Convert._convert_num( lambda _x: (ϕ0**2.0) / (_x * Planck), # Plank to go from Joules to Hz Ej, units_in, units_out, )
[docs] @staticmethod def Ic_from_Lj(Lj, units_in="nH", units_out="nA"): r""" Josephson Junction crit. curr from Josephson inductance. :math:`E_j = \phi_0^2 / L_J = \phi_0 I_C` """ return Convert._convert_num( lambda _x: ϕ0 / _x, Lj, units_in, units_out # Plank to go from Joules to Hz )
[docs] @staticmethod def Lj_from_Ic(Lj, units_in="nA", units_out="nH"): r""" Josephson Junction crit. curr from Josephson inductance. :math:`E_j = \phi_0^2 / L_J = \phi_0 I_C` """ return Convert._convert_num( lambda _x: ϕ0 / _x, Lj, units_in, units_out # Plank to go from Joules to Hz )
[docs] @staticmethod def Ec_from_Cs(Cs, units_in="fF", units_out="MHz"): r""" Charging energy :math:`4E_c n^2`, where :math:`n=Q/2e` Returns in MHz :math:`E_{C}=\frac{e^{2}}{2C}J` """ return Convert._convert_num( # Plank to go from Joules to Hz lambda _x: Planck**-1 * (e_el**2.0) / (2.0 * _x), Cs, units_in, units_out, )
[docs] @staticmethod def Cs_from_Ec(Ec, units_in="MHz", units_out="fF"): r""" Charging energy :math:`4E_c n^2`, where :math:`n=Q/2e` Returns in SI units, in Farads. :math:`E_{C}=\frac{e^{2}}{2C}J` """ return Convert._convert_num( # Plank to go from Joules to Hz lambda _x: (e_el**2.0) / (2.0 * _x * Planck), Ec, units_in, units_out, )
[docs] @staticmethod def ZPF_from_LC(L, C): r""" Input units assumed to be identical Returns Phi ZPF in and Q_ZPF in NOT reduced units, but SI """ Z = sqrt(L / C) return (sqrt(hbar * Z / 2.0), sqrt(hbar / (2.0 * Z))) # Phi , Q
[docs] @staticmethod def ZPF_from_EPR( hfss_freqs, hfss_epr_, hfss_signs, hfss_Ljs, Lj_units_in="H", to_df=False ): r""" Parameters: Can be either Pandas or numpy arrays. hfss_freqs : HFSS Freqs. (standard units: GHz, but these will cancel with Ejs) (list/Series) hfss_epr : EPR ratio matrix, dim = M x J (2D array/DataFrame) hfss_signs : Sign matrix, dim = M x J (2D array/DataFrame) hfss_Ljs : Assumed in Henries (see Lj_units_in). (list/Series) Lj_units_in : Default 'H' for Henries. Can change here. Returns: M x J matrix of reduced ZPF; i.e., scaled by reduced flux quantum. type: np.array and a tuple of matrices. Example use: ϕzpf, (Ωm, Ej, Pmj, Smj) = Convert.ZPF_from_EPR(hfss_freqs, hfss_epr, hfss_signs, hfss_Ljs, to_df=True) """ hfss_freqs, hfss_epr, hfss_signs, hfss_Ljs = map( np.array, (hfss_freqs, hfss_epr_, hfss_signs, hfss_Ljs) ) Ωd = np.diagflat(hfss_freqs) Ej = Convert.Ej_from_Lj(hfss_Ljs, units_in=Lj_units_in, units_out="GHz") Ej = np.diagflat(Ej) ϕzpfs = CalcsBasic.epr_to_zpf(hfss_epr, hfss_signs, Ωd, Ej) if to_df: ϕzpfs = pd.DataFrame( ϕzpfs, columns="ϕ" + hfss_epr_.columns.values, index=hfss_epr_.index ) return ϕzpfs, (Ωd, Ej, hfss_epr, hfss_signs)
[docs] @staticmethod def Omega_from_LC(L, C): r""" Calculate the resonant *angular* frequency """ return sqrt(1.0 / (L * C))