padne.kicad =========== .. py:module:: padne.kicad Attributes ---------- .. autoapisummary:: padne.kicad.log padne.kicad.pcbnew padne.kicad.COPPER_CONDUCTIVITY Classes ------- .. autoapisummary:: padne.kicad.StackupItem padne.kicad.Stackup padne.kicad.Directive padne.kicad.Endpoint padne.kicad.LayerPoint padne.kicad.PadIndex padne.kicad.BaseLumpedSpec padne.kicad.ResistorSpec padne.kicad.VoltageSourceSpec padne.kicad.CurrentSourceSpec padne.kicad.RegulatorSpec padne.kicad.CopperSpec padne.kicad.ViaSpec padne.kicad.KiCadProject padne.kicad.Directives padne.kicad.SchemaInstance padne.kicad.PlottedGerberLayer Functions --------- .. autoapisummary:: padne.kicad.find_pcbnew_module padne.kicad.is_kicad_version_at_least padne.kicad.nm_to_mm padne.kicad.ensure_geometry_is_multipolygon padne.kicad.copper_layers padne.kicad.extract_stackup_from_kicad_pcb padne.kicad.extract_via_specs_from_pcb padne.kicad.extract_tht_pad_specs_from_pcb padne.kicad.parse_endpoint padne.kicad.process_directives padne.kicad.build_schema_hierarchy padne.kicad.flatten_schema_hierarchy padne.kicad.extract_directives_from_text padne.kicad.extract_directives_from_schema padne.kicad.extract_directives_from_hierarchy padne.kicad.render_gerbers_from_kicad padne.kicad.plot_board_layer_to_gerber padne.kicad.render_with_shapely padne.kicad.gerber_file_to_shapely padne.kicad.extract_layers_from_gerbers padne.kicad.extract_board_outline padne.kicad.process_via_spec padne.kicad.punch_via_holes padne.kicad.verify_stackup_contains_all_layers padne.kicad.construct_layer_dict padne.kicad.clip_layer_with_outline padne.kicad.load_kicad_project Module Contents --------------- .. py:data:: log .. py:function:: find_pcbnew_module() -> Any Find and return the pcbnew module using multiple strategies. Strategy order: 1. Try direct import of pcbnew (works when running inside KiCad or with system Python) 2. Try using kigadgets.get_pcbnew_module() (works in virtual environments) Returns: The pcbnew module Raises: ImportError: If pcbnew cannot be found via any method .. py:data:: pcbnew .. py:data:: COPPER_CONDUCTIVITY :value: 59500.0 .. py:function:: is_kicad_version_at_least(major: int, minor: int) -> bool .. py:function:: nm_to_mm(f: float) -> float .. py:function:: ensure_geometry_is_multipolygon(geometry: Union[shapely.geometry.Polygon, shapely.geometry.MultiPolygon]) -> shapely.geometry.MultiPolygon Convert Polygon to MultiPolygon if needed, ensuring consistent interface. .. py:class:: StackupItem .. py:class:: Type(*args, **kwds) Bases: :py:obj:`enum.Enum` Create a collection of name/value pairs. Example enumeration: >>> class Color(Enum): ... RED = 1 ... BLUE = 2 ... GREEN = 3 Access them by: - attribute access: >>> Color.RED - value lookup: >>> Color(1) - name lookup: >>> Color['RED'] Enumerations can be iterated over, and know how many members they have: >>> len(Color) 3 >>> list(Color) [, , ] Methods can be added to enumerations, and members can have their own attributes -- see the documentation for details. .. py:attribute:: DIELECTRIC :value: 'DIELECTRIC' .. py:attribute:: COPPER :value: 'COPPER' .. py:attribute:: name :type: str .. py:attribute:: thickness :type: float .. py:attribute:: conductivity :type: Optional[float] :value: None .. py:property:: conductance .. py:class:: Stackup .. py:attribute:: items :type: list[StackupItem] .. py:method:: index_by_name(name: str) -> int .. py:function:: copper_layers(board: pcbnew) -> Iterator[int] Iterate over layer IDs of copper layers in the given KiCad board. .. py:function:: extract_stackup_from_kicad_pcb(board: pcbnew, copper_conductivity: float = COPPER_CONDUCTIVITY) -> Stackup Extract the stackup from a KiCad PCB file. Args: board: KiCad board object copper_conductivity: Optional custom copper conductivity in S/mm. If None, uses COPPER_CONDUCTIVITY constant. .. py:class:: Directive Represents a single directive in the schematic. .. py:attribute:: name :type: str .. py:attribute:: params :type: dict[str, str] .. py:method:: parse(directive: str) -> Directive :classmethod: Parse a directive string with key-value pairs into a Directive object. Format: !padne DIRECTIVE_NAME key1=value1 key2=value2 ... Args: directive: The directive string to parse Returns: A Directive object with the parsed name and parameters Raises: ValueError: If the directive format is invalid .. py:class:: Endpoint .. py:attribute:: designator :type: str .. py:attribute:: pad :type: str .. py:class:: LayerPoint .. py:attribute:: layer :type: str .. py:attribute:: point :type: shapely.geometry.Point .. py:class:: PadIndex This class effectively serves as a mapper from Endpoint to a bunch of LayerPoints that can then be used to construct a problem.Connection object. .. py:attribute:: mapping :type: dict[Endpoint, list[LayerPoint]] .. py:method:: find_by_endpoint(ep: Endpoint) -> list[LayerPoint] .. py:method:: load_smd_pads(board: pcbnew, layer_dict: dict[str, padne.problem.Layer]) -> None Load all SMD pads from the given PCB board into the mapping. Validates that connection points fall within the final layer geometry. Args: board: The PCB board to extract SMD pads from layer_dict: Dictionary of final layer geometries for validation .. py:method:: insert_via_specs(via_specs: list[ViaSpec], layer_dict: dict[str, padne.problem.Layer]) -> None Insert via specifications into the mapping. Uses all boundary points of the via shape for all layers it connects. Args: via_specs: List of via specifications to insert layer_dict: Dictionary of final layer geometries for validation .. py:class:: BaseLumpedSpec Represents a base class that specifies a _single_ lumped element being wired to a bunch of pads on the PCB. .. py:attribute:: endpoints :type: dict[str, list[Endpoint]] .. py:attribute:: values :type: dict[str, float] .. py:attribute:: coupling :type: float :value: 0.001 .. py:attribute:: endpoint_names :type: ClassVar[dict[str, str]] .. py:attribute:: value_names :type: ClassVar[dict[str, str]] .. py:attribute:: lumped_type :type: ClassVar[type] :value: None .. py:attribute:: default_values :type: ClassVar[dict[str, float]] .. py:method:: from_directive(directive: Directive) -> BaseLumpedSpec :classmethod: Parse a directive into a BaseLumpedSpec object. Args: directive: The directive to parse Returns: A BaseLumpedSpec object with parsed endpoints and values .. py:method:: construct(pad_index: PadIndex, layer_dict: dict[str, padne.problem.Layer]) -> padne.problem.BaseLumped Constructs a problem.BaseLumped element from the current specification. This method should be implemented in subclasses to create the specific type of lumped element. .. py:class:: ResistorSpec Bases: :py:obj:`BaseLumpedSpec` Represents a base class that specifies a _single_ lumped element being wired to a bunch of pads on the PCB. .. py:attribute:: endpoint_names .. py:attribute:: value_names .. py:attribute:: lumped_type .. py:class:: VoltageSourceSpec Bases: :py:obj:`BaseLumpedSpec` Represents a base class that specifies a _single_ lumped element being wired to a bunch of pads on the PCB. .. py:attribute:: endpoint_names .. py:attribute:: value_names .. py:attribute:: default_values .. py:attribute:: lumped_type .. py:method:: construct(pad_index: PadIndex, layer_dict: dict[str, padne.problem.Layer]) -> padne.problem.Network Custom construct method for voltage sources that properly handles multiple endpoints without introducing coupling resistance. Strategy: 1. Create main voltage source between first positive and first negative endpoints 2. Create 0V voltage sources to connect additional endpoints to the first ones .. py:class:: CurrentSourceSpec Bases: :py:obj:`BaseLumpedSpec` Represents a base class that specifies a _single_ lumped element being wired to a bunch of pads on the PCB. .. py:attribute:: endpoint_names .. py:attribute:: value_names .. py:attribute:: lumped_type .. py:class:: RegulatorSpec Bases: :py:obj:`BaseLumpedSpec` Represents a base class that specifies a _single_ lumped element being wired to a bunch of pads on the PCB. .. py:attribute:: endpoint_names :type: ClassVar[dict[str, str]] .. py:attribute:: value_names :type: ClassVar[dict[str, str]] .. py:attribute:: lumped_type :type: ClassVar[type] .. py:class:: CopperSpec Specifies custom copper conductivity for the project. .. py:attribute:: conductivity :type: float .. py:method:: from_directive(directive: Directive) -> CopperSpec :classmethod: Parse a COPPER directive into a CopperSpec object. Args: directive: The directive to parse Returns: A CopperSpec object with parsed conductivity Raises: ValueError: If conductivity parameter is missing or invalid .. py:class:: ViaSpec Specifies a via in the PCB. .. py:attribute:: point :type: shapely.geometry.Point .. py:attribute:: drill_diameter :type: float .. py:attribute:: layer_names :type: list[str] .. py:attribute:: endpoint :type: Optional[Endpoint] :value: None .. py:attribute:: shape :type: shapely.geometry.Polygon .. py:method:: compute_resistance(length: float, plating_thickness: float, conductivity: float) -> float Compute via resistance using hollow cylinder model. Args: length: Via length in mm plating_thickness: Copper plating thickness in mm conductivity: Copper conductivity in S/mm Returns: Resistance in ohms .. py:class:: KiCadProject Represents a KiCad project with paths to its component files. .. py:attribute:: pro_path :type: pathlib.Path .. py:attribute:: pcb_path :type: pathlib.Path .. py:attribute:: sch_path :type: pathlib.Path .. py:property:: name :type: str Get the project name (stem of the project file). .. py:method:: from_pro_file(pro_file_path: pathlib.Path) -> KiCadProject :classmethod: Create a KiCadProject from a .kicad_pro file path. Args: pro_file_path: Path to the KiCad project file (*.kicad_pro) Returns: A KiCadProject instance with validated file paths Raises: FileNotFoundError: If any required files are missing .. py:function:: extract_via_specs_from_pcb(board: pcbnew) -> list[ViaSpec] Extract via specifications from a KiCad PCB. Args: board: The KiCad board object Returns: A list of ViaSpec objects containing information about vias in the PCB .. py:function:: extract_tht_pad_specs_from_pcb(board: pcbnew) -> list[ViaSpec] Extract through-hole pad specifications from a KiCad PCB. Args: board: The KiCad board object Returns: A list of ViaSpec objects representing through-hole pads in the PCB .. py:class:: Directives Accumulates different directive types that can be present in the schematic. .. py:attribute:: lumped_specs :type: list[BaseLumpedSpec] .. py:attribute:: copper_spec :type: Optional[CopperSpec] :value: None .. py:class:: SchemaInstance Represents a schematic instance in the hierarchy. .. py:attribute:: file_path :type: pathlib.Path .. py:attribute:: sheet_name :type: str .. py:attribute:: parsed_sexp :type: Any .. py:attribute:: child_instances :type: list[SchemaInstance] :value: [] .. py:function:: parse_endpoint(token: str) -> Endpoint Parse an endpoint in the format DESIGNATOR.PAD. For example, "R1.1" will become Endpoint(designator="R1", pad="1"). .. py:function:: process_directives(directives: list[Directive]) -> Directives .. py:function:: build_schema_hierarchy(sch_file_path: pathlib.Path, sheet_name: str = 'Root') -> SchemaInstance Build the complete schematic hierarchy starting from a root schematic. .. py:function:: flatten_schema_hierarchy(schema_instance: SchemaInstance) -> list[SchemaInstance] Flatten a schema hierarchy into a list of all instances. Args: schema_instance: Root schema instance Returns: List of all schema instances in the hierarchy (root first, then children) .. py:function:: extract_directives_from_text(text: str) -> list[Directive] Extract directives from a text string that may contain multiple lines. Each line is stripped of whitespace and checked if it starts with '!padne'. Lines that don't start with '!padne' are ignored. Note: KiCad standardizes newlines to ' ' in .kicad_sch files regardless of the platform, so we can safely use splitlines() without worrying about mixed endings. Args: text: The text string to parse for directives Returns: List of Directive objects found in the text .. py:function:: extract_directives_from_schema(instance: SchemaInstance) -> list[Directive] .. py:function:: extract_directives_from_hierarchy(schema_instance: SchemaInstance) -> list[Directive] Extract all directives from a schematic hierarchy. Args: schema_instance: Root of the schematic hierarchy Returns: List of all directives found in the hierarchy (deduplicated by file path) .. py:class:: PlottedGerberLayer .. py:attribute:: name :type: str .. py:attribute:: layer_id :type: int .. py:attribute:: geometry :type: shapely.geometry.MultiPolygon .. py:function:: render_gerbers_from_kicad(board: pcbnew, layer_ids: Iterable[int]) -> list[PlottedGerberLayer] Generate Gerber files from a KiCad PCB file and convert them to PlottedGerberLayer objects. Args: pcb_file_path: Path to the KiCad PCB file Returns: List of PlottedGerberLayer objects containing layer geometries .. py:function:: plot_board_layer_to_gerber(board: pcbnew, layer_id: int, output_path: pathlib.Path) Plot copper layers of a KiCad board to Gerber files. Args: board: KiCad board object output_dir: Directory where Gerber files will be saved Returns: Dictionary mapping layer IDs to paths of generated Gerber files .. py:function:: render_with_shapely(gerber_data: pygerber.gerber.api.GerberFile) -> shapely.geometry.MultiPolygon .. py:function:: gerber_file_to_shapely(gerber_path: pathlib.Path) -> Optional[shapely.geometry.MultiPolygon] Loads data from a Gerber file and converts it to a Shapely geometry. .. py:function:: extract_layers_from_gerbers(board, gerber_layers: dict[int, pathlib.Path]) -> list[PlottedGerberLayer] Extract geometry from Gerber files and create PlottedGerberLayer objects. Args: board: KiCad board object (for layer names) gerber_layers: Dictionary mapping layer IDs to paths of Gerber files Returns: List of PlottedGerberLayer objects .. py:function:: extract_board_outline(board: pcbnew) -> Optional[shapely.geometry.MultiPolygon] Extract board outline from a KiCad PCB. This uses the internal KiCad outline processing. .. py:function:: process_via_spec(via_spec: ViaSpec, layer_dict: dict[str, padne.problem.Layer], stackup: Stackup) -> list[padne.problem.Network] .. py:function:: punch_via_holes(plotted_layers: list[PlottedGerberLayer], via_specs: list[ViaSpec]) -> list[PlottedGerberLayer] .. py:function:: verify_stackup_contains_all_layers(stackup: Stackup, plotted_layers: list[PlottedGerberLayer]) -> bool Verify that all plotted layers are contained within the stackup. Args: stackup: Stackup object containing layers plotted_layers: List of PlottedGerberLayer objects Raises: ValueError: If any plotted layer is not found in the stackup .. py:function:: construct_layer_dict(plotted_layers: list[PlottedGerberLayer], stackup: Stackup) -> dict[str, padne.problem.Layer] Construct a dictionary mapping layer names to Layer objects. Args: plotted_layers: List of PlottedGerberLayer objects Returns: Dictionary mapping layer names to Layer objects .. py:function:: clip_layer_with_outline(plotted_layer: PlottedGerberLayer, outline: shapely.geometry.MultiPolygon) -> PlottedGerberLayer Clip a plotted layer's geometry with the board outline. .. py:function:: load_kicad_project(pro_file_path: pathlib.Path) -> padne.problem.Problem Load a KiCad project and create a Problem object for PDN simulation. Args: project: Either a path to the KiCad project file (*.kicad_pro) or a KiCadProject instance Returns: A Problem object containing layers and lumped elements Raises: FileNotFoundError: If required files are missing ValueError: If the project contains invalid data