Source code for squadds.interpolations.physics

import pandas as pd
from pyEPR.calcs import Convert

from squadds import Analyzer
from squadds.core.utils import *
from squadds.interpolations.interpolator import Interpolator


[docs] class ScalingInterpolator(Interpolator): """Class for scaling-based interpolation.""" def __init__(self, analyzer: Analyzer, target_params: dict): super().__init__(analyzer, target_params)
[docs] def get_design(self) -> pd.DataFrame: """ Retrieves the design options for qubit and cavity based on target parameters. Returns: pd.DataFrame: A DataFrame containing the design options for qubit and cavity. """ # Extract target parameters f_q_target = self.target_params["qubit_frequency_GHz"] g_target = self.target_params["g_MHz"] alpha_target = self.target_params["anharmonicity_MHz"] f_res_target = self.target_params["cavity_frequency_GHz"] kappa_target = self.target_params["kappa_kHz"] try: res_type = self.target_params["resonator_type"] except: res_type = self.analyzer.selected_resonator_type self.df = self.analyzer.df # Find the closest qubit-claw design if self.analyzer.selected_resonator_type == "half": closest_qubit_claw_design = self.analyzer.find_closest( {"qubit_frequency_GHz": f_q_target, "anharmonicity_MHz": alpha_target, "g_MHz": g_target}, parallel=True, num_cpu="auto", num_top=1, ) else: closest_qubit_claw_design = self.analyzer.find_closest( {"qubit_frequency_GHz": f_q_target, "anharmonicity_MHz": alpha_target, "g_MHz": g_target}, num_top=1 ) # Scale values alpha_scaling = closest_qubit_claw_design["anharmonicity_MHz"] / alpha_target g_scaling = g_target / closest_qubit_claw_design["g_MHz"] # Scale qubit and claw dimensions updated_cross_length = ( string_to_float(closest_qubit_claw_design["design_options_qubit"].iloc[0]["cross_length"]) * alpha_scaling.values[0] ) updated_claw_length = ( string_to_float( closest_qubit_claw_design["design_options_qubit"].iloc[0]["connection_pads"]["readout"]["claw_length"] ) * g_scaling.values[0] * alpha_scaling.values[0] ) # Scaling logic for cavity-coupler designs # Filter DataFrame based on qubit coupling claw capacitance try: cross_to_claw_cap_chosen = closest_qubit_claw_design["cross_to_claw"].iloc[0] except: cross_to_claw_cap_chosen = closest_qubit_claw_design["cross_to_claw_closest"].iloc[0] threshold = 0.3 # 30% threshold try: filtered_df = self.df[ (self.df["cross_to_claw"] >= (1 - threshold) * cross_to_claw_cap_chosen) & (self.df["cross_to_claw"] <= (1 + threshold) * cross_to_claw_cap_chosen) ] except: filtered_df = self.df[ (self.df["cross_to_claw_closest"] >= (1 - threshold) * cross_to_claw_cap_chosen) & (self.df["cross_to_claw_closest"] <= (1 + threshold) * cross_to_claw_cap_chosen) ] # Find the closest cavity-coupler design merged_df = self.analyzer.df.copy() system_chosen = self.analyzer.selected_system H_params_chosen = self.analyzer.H_param_keys self.analyzer.df = filtered_df self.analyzer.selected_system = "cavity_claw" self.analyzer.H_param_keys = ["resonator_type", "cavity_frequency_GHz", "kappa_kHz"] self.analyzer.target_params = { "cavity_frequency_GHz": f_res_target, "kappa_kHz": kappa_target, "resonator_type": res_type, } target_params_cavity = { "cavity_frequency_GHz": f_res_target, "kappa_kHz": kappa_target, "resonator_type": res_type, } if self.analyzer.selected_resonator_type == "half": closest_cavity_cpw_design = self.analyzer.find_closest( target_params_cavity, parallel=True, num_cpu="auto", num_top=1 ) else: closest_cavity_cpw_design = self.analyzer.find_closest(target_params_cavity, num_top=1) closest_kappa = closest_cavity_cpw_design["kappa_kHz"].values[0] closest_f_cavity = closest_cavity_cpw_design["cavity_frequency_GHz"].values[0] if self.analyzer.selected_resonator_type == "half": closest_coupler_length = string_to_float( closest_cavity_cpw_design["design_options_cavity_claw"].iloc[0]["cplr_opts"]["finger_length"] ) else: closest_coupler_length = string_to_float( closest_cavity_cpw_design["design_options_cavity_claw"].iloc[0]["cplr_opts"]["coupling_length"] ) # Scale resonator and coupling element dimensions updated_resonator_length = ( string_to_float(closest_cavity_cpw_design["design_options_cavity_claw"].iloc[0]["cpw_opts"]["total_length"]) * (closest_cavity_cpw_design["cavity_frequency_GHz"] / f_res_target).values[0] ) updated_resonator_length = round(updated_resonator_length) res_scaling = closest_f_cavity / f_res_target res_scaling = closest_f_cavity / f_res_target kappa_scaling = np.sqrt(kappa_target / closest_kappa) print("=" * 50) print(f"Kappa scaling: {kappa_scaling}") print(f"g scaling: {g_scaling.values[0]}") print(f"alpha scaling: {alpha_scaling.values[0]}") print(f"resonator scaling: {res_scaling}") print("=" * 50) updated_coupling_length = closest_coupler_length * kappa_scaling # round updated_coupling_length to nearest integer updated_coupling_length = round(updated_coupling_length) # Reset the analyzer's DataFrame self.analyzer.df = merged_df self.analyzer.selected_system = system_chosen self.analyzer.H_param_keys = H_params_chosen # a dataframe with three empty colums interpolated_designs_df = pd.DataFrame( columns=["design_options_qubit", "design_options_cavity_claw", "design_options"] ) # Update the qubit and cavity design options qubit_design_options = closest_qubit_claw_design["design_options_qubit"].iloc[0] qubit_design_options["cross_length"] = f"{updated_cross_length}um" qubit_design_options["connection_pads"]["readout"]["claw_length"] = f"{updated_claw_length}um" required_Lj = Convert.Lj_from_Ej(closest_qubit_claw_design["EJ"].iloc[0], units_in="GHz", units_out="nH") qubit_design_options["aedt_hfss_inductance"] = required_Lj * 1e-9 qubit_design_options["aedt_q3d_inductance"] = required_Lj * 1e-9 qubit_design_options["q3d_inductance"] = required_Lj * 1e-9 qubit_design_options["hfss_inductance"] = required_Lj * 1e-9 qubit_design_options["connection_pads"]["readout"]["Lj"] = f"{required_Lj}nH" # setting the `claw_cpw_length` params to zero qubit_design_options["connection_pads"]["readout"]["claw_cpw_length"] = "0um" cavity_design_options = closest_cavity_cpw_design["design_options_cavity_claw"].iloc[0] cavity_design_options["cpw_opts"]["total_length"] = f"{updated_resonator_length}um" if self.analyzer.selected_resonator_type == "half": cavity_design_options["cplr_opts"]["finger_length"] = f"{updated_coupling_length}um" else: cavity_design_options["cplr_opts"]["coupling_length"] = f"{updated_coupling_length}um" # update the claw of the cavity based on the one from the qubit cavity_design_options["claw_opts"]["connection_pads"] = qubit_design_options["connection_pads"] interpolated_designs_df = pd.DataFrame( { "coupler_type": self.analyzer.selected_coupler, "design_options_qubit": [qubit_design_options], "design_options_cavity_claw": [cavity_design_options], "setup_qubit": [closest_qubit_claw_design["setup_qubit"].iloc[0]], "setup_cavity_claw": [closest_cavity_cpw_design["setup_cavity_claw"].iloc[0]], } ) device_design_options = create_unified_design_options(interpolated_designs_df.iloc[0]) # add the device design options to the dataframe interpolated_designs_df["design_options"] = [device_design_options] interpolated_designs_df.iloc[0]["design_options"]["qubit_options"]["connection_pads"]["readout"][ "claw_cpw_length" ] = "0um" return interpolated_designs_df