Skip to content

Pins

pins

DPins

Bases: ProtoPins[float]

Source code in kfactory/pins.py
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
class DPins(ProtoPins[float]):
    yaml_tag: ClassVar[str] = "!DPins"

    def __iter__(self) -> Iterator[DPin]:
        """Iterator, that allows for loops etc to directly access the object."""
        yield from (DPin(base=b) for b in self._bases)

    def __getitem__(self, key: int | str) -> DPin:
        """Get a specific pin by name."""
        if isinstance(key, int):
            return DPin(base=self._bases[key])
        try:
            return DPin(base=next(filter(lambda base: base.name == key, self._bases)))
        except StopIteration as e:
            raise KeyError(
                f"{key=} is not a valid pin name or index. "
                f"Available pins: {[v.name for v in self._bases]}"
            ) from e

    def create_pin(
        self,
        *,
        name: str,
        ports: Iterable[ProtoPort[Any]],
        pin_type: str = "DC",
        info: dict[str, MetaData] | None = None,
    ) -> DPin:
        """Add a pin to Pins."""
        if info is None:
            info = {}
        info_ = Info(**info)
        if len(list(ports)) < 1:
            raise ValueError(
                f"At least one port must provided to create pin named {name}."
            )
        port_bases = []
        for port in ports:
            port_base = port.base
            if port.kcl != self.kcl:
                port_base.kcl = self.kcl
            port_bases.append(port_base)

        base_ = BasePin(
            name=name, kcl=self.kcl, ports=port_bases, pin_type=pin_type, info=info_
        )
        self._bases.append(base_)

        return DPin(base=base_)

    def get_all_named(self) -> Mapping[str, DPin]:
        """Get all pins in a dictionary with names as keys."""
        return {v.name: DPin(base=v) for v in self._bases if v.name is not None}

__getitem__

__getitem__(key: int | str) -> DPin

Get a specific pin by name.

Source code in kfactory/pins.py
183
184
185
186
187
188
189
190
191
192
193
def __getitem__(self, key: int | str) -> DPin:
    """Get a specific pin by name."""
    if isinstance(key, int):
        return DPin(base=self._bases[key])
    try:
        return DPin(base=next(filter(lambda base: base.name == key, self._bases)))
    except StopIteration as e:
        raise KeyError(
            f"{key=} is not a valid pin name or index. "
            f"Available pins: {[v.name for v in self._bases]}"
        ) from e

__iter__

__iter__() -> Iterator[DPin]

Iterator, that allows for loops etc to directly access the object.

Source code in kfactory/pins.py
179
180
181
def __iter__(self) -> Iterator[DPin]:
    """Iterator, that allows for loops etc to directly access the object."""
    yield from (DPin(base=b) for b in self._bases)

create_pin

create_pin(
    *,
    name: str,
    ports: Iterable[ProtoPort[Any]],
    pin_type: str = "DC",
    info: dict[str, MetaData] | None = None,
) -> DPin

Add a pin to Pins.

Source code in kfactory/pins.py
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
def create_pin(
    self,
    *,
    name: str,
    ports: Iterable[ProtoPort[Any]],
    pin_type: str = "DC",
    info: dict[str, MetaData] | None = None,
) -> DPin:
    """Add a pin to Pins."""
    if info is None:
        info = {}
    info_ = Info(**info)
    if len(list(ports)) < 1:
        raise ValueError(
            f"At least one port must provided to create pin named {name}."
        )
    port_bases = []
    for port in ports:
        port_base = port.base
        if port.kcl != self.kcl:
            port_base.kcl = self.kcl
        port_bases.append(port_base)

    base_ = BasePin(
        name=name, kcl=self.kcl, ports=port_bases, pin_type=pin_type, info=info_
    )
    self._bases.append(base_)

    return DPin(base=base_)

get_all_named

get_all_named() -> Mapping[str, DPin]

Get all pins in a dictionary with names as keys.

Source code in kfactory/pins.py
225
226
227
def get_all_named(self) -> Mapping[str, DPin]:
    """Get all pins in a dictionary with names as keys."""
    return {v.name: DPin(base=v) for v in self._bases if v.name is not None}

Pins

Bases: ProtoPins[int]

Source code in kfactory/pins.py
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
class Pins(ProtoPins[int]):
    yaml_tag: ClassVar[str] = "!Pins"

    def __iter__(self) -> Iterator[Pin]:
        """Iterator, that allows for loops etc to directly access the object."""
        yield from (Pin(base=b) for b in self._bases)

    def __getitem__(self, key: int | str | None) -> Pin:
        """Get a specific pin by name."""
        if isinstance(key, int):
            return Pin(base=self._bases[key])
        try:
            return Pin(base=next(filter(lambda base: base.name == key, self._bases)))
        except StopIteration as e:
            raise KeyError(
                f"{key=} is not a valid pin name or index. "
                f"Available pins: {[v.name for v in self._bases]}"
            ) from e

    def create_pin(
        self,
        *,
        name: str,
        ports: Iterable[ProtoPort[Any]],
        pin_type: str = "DC",
        info: dict[str, MetaData] | None = None,
    ) -> Pin:
        """Add a pin to Pins."""
        if info is None:
            info = {}
        info_ = Info(**info)
        if len(list(ports)) < 1:
            raise ValueError(
                f"At least one port must provided to create pin named {name}."
            )
        port_bases = []
        for port in ports:
            port_base = port.base
            if port.kcl != self.kcl:
                raise ValueError(
                    "Cannot add a pin which belongs to a different layout or cell to a"
                    f" cell. {port=}, {self.kcl!r}"
                )
            port_bases.append(port_base)

        base_ = BasePin(
            name=name, kcl=self.kcl, ports=port_bases, pin_type=pin_type, info=info_
        )
        self._bases.append(base_)

        return Pin(base=base_)

    def get_all_named(self) -> Mapping[str, Pin]:
        """Get all pins in a dictionary with names as keys."""
        return {v.name: Pin(base=v) for v in self._bases if v.name is not None}

    def print(self, unit: Literal["dbu", "um"] | None = None) -> None:
        """Pretty print ports."""
        config.console.print(pprint_pins(self, unit=unit))

__getitem__

__getitem__(key: int | str | None) -> Pin

Get a specific pin by name.

Source code in kfactory/pins.py
122
123
124
125
126
127
128
129
130
131
132
def __getitem__(self, key: int | str | None) -> Pin:
    """Get a specific pin by name."""
    if isinstance(key, int):
        return Pin(base=self._bases[key])
    try:
        return Pin(base=next(filter(lambda base: base.name == key, self._bases)))
    except StopIteration as e:
        raise KeyError(
            f"{key=} is not a valid pin name or index. "
            f"Available pins: {[v.name for v in self._bases]}"
        ) from e

__iter__

__iter__() -> Iterator[Pin]

Iterator, that allows for loops etc to directly access the object.

Source code in kfactory/pins.py
118
119
120
def __iter__(self) -> Iterator[Pin]:
    """Iterator, that allows for loops etc to directly access the object."""
    yield from (Pin(base=b) for b in self._bases)

create_pin

create_pin(
    *,
    name: str,
    ports: Iterable[ProtoPort[Any]],
    pin_type: str = "DC",
    info: dict[str, MetaData] | None = None,
) -> Pin

Add a pin to Pins.

Source code in kfactory/pins.py
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
def create_pin(
    self,
    *,
    name: str,
    ports: Iterable[ProtoPort[Any]],
    pin_type: str = "DC",
    info: dict[str, MetaData] | None = None,
) -> Pin:
    """Add a pin to Pins."""
    if info is None:
        info = {}
    info_ = Info(**info)
    if len(list(ports)) < 1:
        raise ValueError(
            f"At least one port must provided to create pin named {name}."
        )
    port_bases = []
    for port in ports:
        port_base = port.base
        if port.kcl != self.kcl:
            raise ValueError(
                "Cannot add a pin which belongs to a different layout or cell to a"
                f" cell. {port=}, {self.kcl!r}"
            )
        port_bases.append(port_base)

    base_ = BasePin(
        name=name, kcl=self.kcl, ports=port_bases, pin_type=pin_type, info=info_
    )
    self._bases.append(base_)

    return Pin(base=base_)

get_all_named

get_all_named() -> Mapping[str, Pin]

Get all pins in a dictionary with names as keys.

Source code in kfactory/pins.py
167
168
169
def get_all_named(self) -> Mapping[str, Pin]:
    """Get all pins in a dictionary with names as keys."""
    return {v.name: Pin(base=v) for v in self._bases if v.name is not None}

print

print(unit: Literal['dbu', 'um'] | None = None) -> None

Pretty print ports.

Source code in kfactory/pins.py
171
172
173
def print(self, unit: Literal["dbu", "um"] | None = None) -> None:
    """Pretty print ports."""
    config.console.print(pprint_pins(self, unit=unit))

ProtoPins

Bases: Protocol

Source code in kfactory/pins.py
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
class ProtoPins[T: (int, float)](Protocol):
    _kcl: KCLayout
    _bases: list[BasePin]

    def __init__(
        self,
        *,
        kcl: KCLayout,
        bases: list[BasePin],
    ) -> None:
        self._kcl = kcl
        self._bases = bases

    def __len__(self) -> int:
        """Return Pin count."""
        return len(self._bases)

    @property
    def kcl(self) -> KCLayout:
        """KCLayout associated to the pins."""
        return self._kcl

    @kcl.setter
    def kcl(self, value: KCLayout) -> None:
        self._kcl = value

    @property
    def bases(self) -> list[BasePin]:
        """Get the bases."""
        return self._bases

    def to_itype(self) -> Pins:
        """Convert to a Ports."""
        return Pins(kcl=self.kcl, bases=self._bases)

    def to_dtype(self) -> DPins:
        """Convert to a DPins."""
        return DPins(kcl=self.kcl, bases=self._bases)

    @abstractmethod
    def __iter__(self) -> Iterator[ProtoPin[T]]:
        """Iterator over the Pins."""
        ...

    @abstractmethod
    def __getitem__(self, key: int | str) -> ProtoPin[T]:
        """Get a pin by index or name."""
        ...

    def __contains__(self, pin: str | ProtoPin[Any] | BasePin) -> bool:
        """Check whether a pin is in this pin collection."""
        if isinstance(pin, ProtoPin):
            return pin.base in self._bases
        if isinstance(pin, BasePin):
            return pin in self._bases
        return any(_pin.name == pin for _pin in self._bases)

    @abstractmethod
    def create_pin(
        self,
        *,
        name: str,
        ports: Iterable[ProtoPort[Any]],
        pin_type: str = "DC",
        info: dict[str, MetaData] | None = None,
    ) -> ProtoPin[T]:
        """Add a pin."""
        ...

    @abstractmethod
    def get_all_named(self) -> Mapping[str, ProtoPin[T]]:
        """Get all pins in a dictionary with names as keys.

        This filters out Pins with `None` as name.
        """
        ...

    def filter(
        self,
        pin_type: str | None = None,
        regex: str | None = None,
    ) -> Sequence[ProtoPin[T]]:
        """Filter pins by name.

        Args:
            pin_type: Filter by pin type.
            regex: Filter by regex of the name.
        Returns:
            Filtered list of pins.
        """
        pins: Iterable[ProtoPin[T]] = list(self)
        return list(filter_type_reg(pins, pin_type=pin_type, regex=regex))

bases property

bases: list[BasePin]

Get the bases.

kcl property writable

kcl: KCLayout

KCLayout associated to the pins.

__contains__

__contains__(pin: str | ProtoPin[Any] | BasePin) -> bool

Check whether a pin is in this pin collection.

Source code in kfactory/pins.py
70
71
72
73
74
75
76
def __contains__(self, pin: str | ProtoPin[Any] | BasePin) -> bool:
    """Check whether a pin is in this pin collection."""
    if isinstance(pin, ProtoPin):
        return pin.base in self._bases
    if isinstance(pin, BasePin):
        return pin in self._bases
    return any(_pin.name == pin for _pin in self._bases)

__getitem__ abstractmethod

__getitem__(key: int | str) -> ProtoPin[T]

Get a pin by index or name.

Source code in kfactory/pins.py
65
66
67
68
@abstractmethod
def __getitem__(self, key: int | str) -> ProtoPin[T]:
    """Get a pin by index or name."""
    ...

__iter__ abstractmethod

__iter__() -> Iterator[ProtoPin[T]]

Iterator over the Pins.

Source code in kfactory/pins.py
60
61
62
63
@abstractmethod
def __iter__(self) -> Iterator[ProtoPin[T]]:
    """Iterator over the Pins."""
    ...

__len__

__len__() -> int

Return Pin count.

Source code in kfactory/pins.py
34
35
36
def __len__(self) -> int:
    """Return Pin count."""
    return len(self._bases)

create_pin abstractmethod

create_pin(
    *,
    name: str,
    ports: Iterable[ProtoPort[Any]],
    pin_type: str = "DC",
    info: dict[str, MetaData] | None = None,
) -> ProtoPin[T]

Add a pin.

Source code in kfactory/pins.py
78
79
80
81
82
83
84
85
86
87
88
@abstractmethod
def create_pin(
    self,
    *,
    name: str,
    ports: Iterable[ProtoPort[Any]],
    pin_type: str = "DC",
    info: dict[str, MetaData] | None = None,
) -> ProtoPin[T]:
    """Add a pin."""
    ...

filter

filter(
    pin_type: str | None = None, regex: str | None = None
) -> Sequence[ProtoPin[T]]

Filter pins by name.

Parameters:

Name Type Description Default
pin_type str | None

Filter by pin type.

None
regex str | None

Filter by regex of the name.

None

Returns: Filtered list of pins.

Source code in kfactory/pins.py
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
def filter(
    self,
    pin_type: str | None = None,
    regex: str | None = None,
) -> Sequence[ProtoPin[T]]:
    """Filter pins by name.

    Args:
        pin_type: Filter by pin type.
        regex: Filter by regex of the name.
    Returns:
        Filtered list of pins.
    """
    pins: Iterable[ProtoPin[T]] = list(self)
    return list(filter_type_reg(pins, pin_type=pin_type, regex=regex))

get_all_named abstractmethod

get_all_named() -> Mapping[str, ProtoPin[T]]

Get all pins in a dictionary with names as keys.

This filters out Pins with None as name.

Source code in kfactory/pins.py
90
91
92
93
94
95
96
@abstractmethod
def get_all_named(self) -> Mapping[str, ProtoPin[T]]:
    """Get all pins in a dictionary with names as keys.

    This filters out Pins with `None` as name.
    """
    ...

to_dtype

to_dtype() -> DPins

Convert to a DPins.

Source code in kfactory/pins.py
56
57
58
def to_dtype(self) -> DPins:
    """Convert to a DPins."""
    return DPins(kcl=self.kcl, bases=self._bases)

to_itype

to_itype() -> Pins

Convert to a Ports.

Source code in kfactory/pins.py
52
53
54
def to_itype(self) -> Pins:
    """Convert to a Ports."""
    return Pins(kcl=self.kcl, bases=self._bases)