Source code for qiskit_metal.analyses.core.simulation
# -*- 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.fromabcimportabstractmethodfromqiskit_metal.designsimportQDesign# pylint: disable=unused-importfromqiskit_metalimportDictfromqiskit_metalimportconfigfrom.importQAnalysisimportimportlib
[docs]classQSimulation(QAnalysis):"""A subclass of `QAnalysis`, intended to standardize across all Analysis classes select and name renderers. Default Setup: * name (str): Name of simulation setup. Defaults to "Setup". Data Labels: * sim_setup_name (str): Name given to the current setup. """default_setup=Dict(name="Setup",reuse_selected_design=True,reuse_setup=True)"""Default setup"""# supported labels for data generated from the simulationdata_labels=['sim_setup_name']"""Default data labels."""def__init__(self,design:'QDesign'=None,renderer_name:str=None,*args,**kwargs):"""Variables and method needed from all those Analysis types that need a renderer. Args: design (QDesign): The Metal design you are working on. Defaults to None. renderer_name (str): Name of the renderer you intend to use. Defaults to None. """super().__init__(*args,**kwargs)# pointer to find renderersself.design=designifself.designisNone:self.logger.info("You did not specify a design, so you will need to provide manual inputs"" for the analysis.")# verify renderer existenceself.renderer_name=renderer_nameself.renderer=Noneifself.renderer_nameisNone:self.logger.info("You did not specify a renderer, so you are expected to manually provide "" the analysis input information.")else:self.renderer=self.select_renderer(renderer_name)
[docs]defselect_renderer(self,renderer_name:str):"""Makes sure the renderer exists in qiskit-metal. If yes it sets the analysis class variables to be able to reach it easily. Else it throws an error. Args: renderer_name (str): Name of the renderer you intend to use. Returns: (QRenderer): The renderer to be used in the analysis. """try:ifself.designisNone:# we want to setup a renderer from scratch# renderer_ref will be {} id renderer_name does not existrenderer_ref=config.renderers_to_load[renderer_name]ifnotrenderer_ref:raiseKeyError#needed because this is a Dict, not a dictifnot(renderer_ref.path_nameandrenderer_ref.class_name):self.logger.error(f'The renderer={renderer_name} is not properly configured in'' config.renderers_to_load. Please add the missing information'' (Tip: needs to have both a path_name and a class_name keys).')returnNone# if the path_name exists, grab the classifimportlib.util.find_spec(renderer_ref.path_name):class_renderer=getattr(importlib.import_module(renderer_ref.path_name),renderer_ref.class_name,None)# if the class_name exists, then create the renderer objectifclass_rendererisnotNone:renderer=class_renderer(None)else:self.logger.warning(f'Could not find the class={renderer_ref.class_name} 'f'in the renderer={renderer_name}')else:self.logger.warning(f'Could not find the renderer={renderer_name} 'f'at the path={renderer_ref.path_name}.')else:# the renderer would have been already registered within the design objectrenderer=self.design.renderers[renderer_name]ifnotrenderer:self.design.logger.error(f"Cannot find the renderer \"{renderer_name}\" registered with qiskit-metal")returnNoneexceptKeyError:self.design.logger.error(f"Cannot find a renderer {renderer_name} registered with qiskit-metal")returnNonereturnrenderer
[docs]defstart(self):"""Starts the renderer by executing the routine of the selected renderer. """self._initialize_renderer()
def_initialize_renderer(self):"""Starts the renderer by executing the routine of the selected renderer. """self.renderer.start()def_render(self,solution_type,vars_to_initialize,**design_selection)->str:"""Renders the design from qiskit metal into the selected renderer. First it decides the tentative name of the design. Then it runs the renderer method that executes the design rendering. It returns the final design name. Args: solution_type (str): The type of simulation solution to apply. Supported so far: eigenmode, capacitive, drivenmodal vars_to_initialize (Dict): The variables to initialize, i.e. Ljx, Cjx. Returns: (str): Final design name that the renderer used. """ifself.designisNone:returnself.renderer.get_active_design_name()# need a default renderer-design name. Use the name of the metal-design.base_name=self.design.name# if a renderer-design name was provided as input to run(), use that as a baseif"name"indesign_selection:ifdesign_selection["name"]isnotNone:base_name=design_selection["name"]deldesign_selection["name"]design_name=base_name+"_"+self.renderer_namedesign_name=self.renderer.execute_design(design_name,solution_type=solution_type,force_redraw=self.setup.reuse_selected_design,vars_to_initialize=vars_to_initialize,**design_selection)returndesign_name
[docs]defclose(self):"""Stops the renderer by executing the routine of the selected renderer. """self._close_renderer()
def_close_renderer(self):"""Stops the renderer by executing the routine of the selected renderer. """self.renderer.stop()@propertydefrenderer_initialized(self):"""Reports whether the renderer is initialized or stopped. """returnself.renderer.initialized
[docs]defsave_screenshot(self):"""Saves the screenshot. Returns: (pathlib.WindowsPath): Path to png formatted screenshot. """returnself.renderer.save_screenshot()
[docs]defrun(self,*args,**kwargs):"""Alias for run_sim() necessary to implement super-class method, while preventing method name collision when sim and non-sim QAnalysis classes are inherited. """self.run_sim(*args,**kwargs)
[docs]@abstractmethoddefrun_sim(self,*args,**kwargs):"""Abstract method. Must be implemented by the subclass. Write in here the code to launch the simulations. You will be able to execute this with the alias run(). """
@propertydefsim_setup_name(self)->str:"""Getter Returns: str: Name of the setup being executed. """returnself.get_data('sim_setup_name')@sim_setup_name.setterdefsim_setup_name(self,data:str):"""Setter Args: data (str): Name of the setup being executed. """ifnotisinstance(data,str):self.logger.warning('Unsupported type %s. Only accepts str. Please try again.',{type(data)})returnself.set_data('sim_setup_name',data)