# -*- coding: utf-8 -*-
# This code is part of Qiskit.
#
# (C) Copyright IBM 2017, 2021.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
import numpy as np
from qiskit_metal import Dict, draw
from qiskit_metal.qlibrary.core import BaseQubit
[docs]
class TransmonClaw(BaseQubit): # pylint: disable=invalid-name
"""The base `TransmonClaw` class.
Inherits `BaseQubit` class.
'claw_width' and 'claw_gap' define the width/gap of the CPW line that
makes up the connector. Note, DC SQUID currently represented by single
inductance sheet
Add connectors to it using the `connection_pads` dictionary. See BaseQubit for more
information.
Sketch:
Below is a sketch of the claw
::
claw_length
Claw: _________ Gap:
| ________________ _________ ____________
______| | _________| |____________
| |________________
|_________
BaseQubit Default Options:
* connection_pads: Empty Dict -- The dictionary which contains all active connection lines for the qubit.
* _default_connection_pads: empty Dict -- The default values for the (if any) connection lines of the qubit.
Default Options:
* cross_width: '20um' -- Width of the CPW center trace making up the Crossmon
* cross_length: '200um' -- Length of one Crossmon arm (from center)
* cross_gap: '20um' -- Width of the CPW gap making up the Crossmon
* _default_connection_pads: Dict
* connector_type: '0' -- 0 = Claw type, 1 = gap type
* claw_length: '30um' -- Length of the claw 'arms', measured from the connector center trace
* ground_spacing: '5um' -- Amount of ground plane between the connector and Crossmon arm (minimum should be based on fabrication capabilities)
* claw_width: '10um' -- The width of the CPW center trace making up the claw/gap connector
* claw_gap: '6um' -- The gap of the CPW center trace making up the claw/gap connector
* connector_location: '0' -- 0 => 'west' arm, 90 => 'north' arm, 180 => 'east' arm
"""
default_options = Dict(
cross_width='20um',
cross_length='200um',
cross_gap='20um',
chip='main',
_default_connection_pads=Dict(
connector_type='0', # 0 = Claw type, 1 = gap type
claw_length='30um',
ground_spacing='5um',
claw_width='10um',
claw_gap='6um',
claw_cpw_length='40um',
claw_cpw_width='10um',
connector_location=
'0' # 0 => 'west' arm, 90 => 'north' arm, 180 => 'east' arm
))
"""Default options."""
component_metadata = Dict(short_name='Cross',
_qgeometry_table_poly='True',
_qgeometry_table_junction='True')
"""Component metadata"""
TOOLTIP = """Simple Metal Transmon Cross."""
##############################################MAKE######################################################
[docs]
def make(self):
"""This is executed by the GUI/user to generate the qgeometry for the
component."""
self.make_connection_pads()
###################################TRANSMON#############################################################
[docs]
def make_pocket(self):
"""
Creates a pocket for the claw coupler.
This method uses the parsed values from the user options to determine the dimensions of the pocket.
The pocket is created based on the cross width, cross length, cross gap, and chip name.
Args:
None
Returns:
None
"""
# self.p allows us to directly access parsed values (string -> numbers) form the user option
p = self.p
cross_width = p.cross_width
cross_length = p.cross_length
cross_gap = p.cross_gap
# access to chip name
chip = p.chip
############################CONNECTORS##################################################################################################
[docs]
def make_connection_pads(self):
"""Goes through connector pads and makes each one."""
for name in self.options.connection_pads:
self.make_connection_pad(name)
[docs]
def make_connection_pad(self, name: str):
"""Makes individual connector pad.
Args:
name (str) : Name of the connector pad
"""
# self.p allows us to directly access parsed values (string -> numbers) form the user option
p = self.p
cross_width = p.cross_width
cross_length = p.cross_length
cross_gap = p.cross_gap
# access to chip name
chip = p.chip
pc = self.p.connection_pads[name] # parser on connector options
c_g = pc.claw_gap
c_l = pc.claw_length
c_w = pc.claw_width
c_c_w = pc.claw_cpw_width
c_c_l = pc.claw_cpw_length
g_s = pc.ground_spacing
con_loc = pc.connector_location
claw_cpw = draw.box(-c_w, -c_c_w / 2, -c_c_l - c_w, c_c_w / 2)
if pc.connector_type == 0: # Claw connector
t_claw_height = 2*c_g + 2 * c_w + 2*g_s + \
2*cross_gap + cross_width # temp value
claw_base = draw.box(-c_w, -(t_claw_height) / 2, c_l,
t_claw_height / 2)
claw_subtract = draw.box(0, -t_claw_height / 2 + c_w, c_l,
t_claw_height / 2 - c_w)
claw_base = claw_base.difference(claw_subtract)
connector_arm = draw.shapely.ops.unary_union([claw_base, claw_cpw])
connector_etcher = draw.buffer(connector_arm, c_g)
else:
connector_arm = draw.box(0, -c_w / 2, -4 * c_w, c_w / 2)
connector_etcher = draw.buffer(connector_arm, c_g)
# Making the pin for tracking (for easy connect functions).
# Done here so as to have the same translations and rotations as the connector. Could
# extract from the connector later, but since allowing different connector types,
# this seems more straightforward.
port_line = draw.LineString([(-c_c_l - c_w, -c_c_w / 2),
(-c_c_l - c_w, c_c_w / 2)])
claw_rotate = 0
if con_loc > 135:
claw_rotate = 180
elif con_loc > 45:
claw_rotate = -90
# Rotates and translates the connector polygons (and temporary port_line)
polys = [connector_arm, connector_etcher, port_line]
polys = draw.translate(polys, -(cross_length + cross_gap + g_s + c_g),
0)
polys = draw.rotate(polys, claw_rotate, origin=(0, 0))
polys = draw.rotate(polys, p.orientation, origin=(0, 0))
polys = draw.translate(polys, p.pos_x, p.pos_y)
[connector_arm, connector_etcher, port_line] = polys
# Generates qgeometry for the connector pads
self.add_qgeometry('poly', {f'{name}_connector_arm': connector_arm},
chip=chip)
self.add_qgeometry('poly',
{f'{name}_connector_etcher': connector_etcher},
subtract=True,
chip=chip)
self.add_pin(name, port_line.coords, c_c_w)