Source code for qiskit_metal.qlibrary.tlines.mixed_path
# -*- 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.importnumpyasnpfromqiskit_metalimportDictfromqiskit_metal.qlibrary.coreimportQRoutePointfromcollectionsimportOrderedDictfrom.meanderedimportRouteMeanderfrom.pathfinderimportRoutePathfinder# class RouteMixed(RouteFramed, RoutePathfinder, RouteMeander):
[docs]classRouteMixed(RoutePathfinder,RouteMeander):"""Implements fully featured Routing, allowing different type of connections between anchors. The comprehensive Routing class. Inherits `RoutePathfinder, RouteMeander` class, thus also QRoute and RouteAnchors. .. meta:: :description: Route Mixed Default Options: * between_anchors: Empty OrderedDict -- Intermediate anchors only; doesn't include endpoints QRoute Default Options: * pin_inputs: Dict * start_pin: Dict -- Component and pin string pair. Define which pin to start from * component: '' -- Name of component to start from, which has a pin * pin: '' -- Name of pin used for pin_start * end_pin=Dict -- Component and pin string pair. Define which pin to start from * component: '' -- Name of component to end on, which has a pin * pin: '' -- Name of pin used for pin_end * lead: Dict * start_straight: '0mm' -- Lead-in, defined as the straight segment extension from start_pin. Defaults to 0.1um. * end_straight: '0mm' -- Lead-out, defined as the straight segment extension from end_pin. Defaults to 0.1um. * start_jogged_extension: '' -- Lead-in, jogged extension of lead-in. Described as list of tuples * end_jogged_extension: '' -- Lead-out, jogged extension of lead-out. Described as list of tuples * fillet: '0' * total_length: '7mm' * trace_width: 'cpw_width' -- Defines the width of the line RouteAnchors Default Options: * anchors: OrderedDict -- Intermediate anchors only; doesn't include endpoints RoutePathfinder Default Options: * step_size: '0.25mm' -- Length of the step for the A* pathfinding algorithm * advanced: Dict * avoid_collision: 'true' -- true/false, defines if the route needs to avoid collisions. Defaults to 'true'. RouteMeander Default Options: * meander: Dict * spacing: '200um' -- Minimum spacing between adjacent meander curves * asymmetry='0um' -- Offset between the center-line of the meander and the center-line that stretches from the tip of lead-in to the x (or y) coordinate of the tip of the lead-out. Defaults to '0um'. * snap: 'true' * prevent_short_edges: 'true' How to specify between_anchors for the RouteMixed `between_anchors` have to be specified in an OrderedDict with incremental keys. the value of each key specifies the type of routing algorythm to run between each anchors and between the pins and the first and last anchors. For example, for a RouteMixed with 4 anchors: .. code-block:: python :linenos: between_anchors = OrderedDict() between_anchors[0] = "S" between_anchors[1] = "M" between_anchors[2] = "S" between_anchors[3] = "M" between_anchors[4] = "PF" * "S" = Utilizes the RouteStraight methods * "M" = Utilizes the RouteMeander methods * "PF" = Utilizes the RoutePathfinder methods """default_options=Dict(between_anchors=OrderedDict(),# Intermediate anchors only; doesn't include endpoints# Example: {1: "M", 2: "S", 3: "PF"}# startpin -> startpin + leadin -> anchors -> endpin + leadout -> endpin)"""Default options"""TOOLTIP="""Implements fully featured Routing, allowing different type of connections between anchors."""
[docs]defmake(self):"""Generates path from start pin to end pin."""p=self.parse_options()anchors=p.anchorsbetween_anchors=p.between_anchors# Set the CPW pins and add the points/directions to the lead-in/out arraysself.set_pin("start")self.set_pin("end")# Align the lead-in/out to the input options set from the userstart_point=self.set_lead("start")end_point=self.set_lead("end")# approximate length needed for individual meanders# the meander algorithm directly reads from self._length_segmentcount_meanders_list=[1ifx=="M"else0forxinlist(between_anchors.values())]self._length_segment=Noneifany(count_meanders_list):self._length_segment=((self.p.total_length-(self.head.length+self.tail.length) \
-self.free_manhattan_length_anchors())/sum(count_meanders_list)) \
+(self.free_manhattan_length_anchors()/len(count_meanders_list))# find the points to connect between each pair of anchors, or between anchors and leads# at first, store points "per segment" in a dictionary, so it is easier to apply length requirementsself.intermediate_pts=OrderedDict()meanders=set()forarc_num,coordinanchors.items():# determine what is the connection strategy for this pair, based on user inputsconnect_method=self.select_connect_method(arc_num)ifconnect_method==self.connect_meandered:meanders.add(arc_num)# compute points connecting the anchors, all but the lastarc_pts=connect_method(self.get_tip(),QRoutePoint(coord))ifarc_ptsisNone:self.intermediate_pts[arc_num]=[coord]else:self.intermediate_pts[arc_num]=np.concatenate([arc_pts,[coord]],axis=0)# compute last connection point to the output QRouteLeadconnect_method=self.select_connect_method(len(anchors))ifconnect_method==self.connect_meandered:meanders.add(len(anchors))arc_pts=connect_method(self.get_tip(),end_point)ifarc_ptsisnotNone:self.intermediate_pts[len(anchors)]=np.array(arc_pts)# concatenate all points, transforming the dictionary into a single numpy arrayself.trim_pts()dictionary_intermediate_pts=self.intermediate_ptsself.intermediate_pts=np.concatenate(list(self.intermediate_pts.values()),axis=0)ifany(count_meanders_list):# refine length of meanderstotal_delta_length=self.p.total_length-self.lengthindividual_delta_length=total_delta_length/len(meanders)forminmeanders:arc_pts=dictionary_intermediate_pts[m][:-1]ifm==0:meander_start_point=start_pointelse:meander_start_point=QRoutePoint(anchors[m-1])ifm==len(anchors):meander_end_point=end_pointelse:meander_end_point=QRoutePoint(anchors[m])dictionary_intermediate_pts[m]=self.adjust_length(individual_delta_length,arc_pts,meander_start_point,meander_end_point)dictionary_intermediate_pts[m]=np.concatenate([dictionary_intermediate_pts[m],[anchors[m]]],axis=0)self.intermediate_pts=np.concatenate(list(dictionary_intermediate_pts.values()),axis=0)# Make points into elementsself.make_elements(self.get_points())
[docs]defselect_connect_method(self,segment_num):"""Translates the user-selected connection method into the right method to execute. Args: segment_num (int): Segment ID. Counts 0 as the first segment after the lead-in. Return: object: selected method """between_anchors=self.parse_options().between_anchorsifsegment_numinbetween_anchors:type_connect=between_anchors[segment_num]else:type_connect="S"# print(type_connect)iftype_connect=="S":returnself.connect_simpleiftype_connect=="PF":returnself.connect_astar_or_simpleiftype_connect=="M":returnself.connect_meandered