Skip to content

Instance pins

instance_pins

DInstancePins

Bases: ProtoTInstancePins[float]

Source code in kfactory/instance_pins.py
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
class DInstancePins(ProtoTInstancePins[float]):
    def __init__(self, instance: DInstance) -> None:
        """Creates the virtual pins object.

        Args:
            instance: The related instance
        """
        self.instance = instance

    @property
    def cell_pins(self) -> DPins:
        return DPins(kcl=self.instance.cell.kcl, bases=self.instance.cell.pins.bases)

    def filter(
        self,
        pin_type: str | None = None,
        regex: str | None = None,
    ) -> list[DPin]:
        """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[DPin] = list(self)
        return list(filter_type_reg(pins, pin_type=pin_type, regex=regex))

    def __getitem__(self, key: int | str | tuple[int | str, int, int]) -> DPin:
        return DPin(base=super().__getitem__(key).base)

    def __iter__(self) -> Iterator[DPin]:
        yield from (p.to_dtype() for p in self.each_pin())

__getitem__

__getitem__(
    key: int | str | tuple[int | str, int, int],
) -> DPin

Returns pin from instance.

The key can either be an integer, in which case the nth pin is returned, or a string in which case the first pin with a matching name is returned.

If the instance is an array, the key can also be a tuple in the form of c.pins[key_name, i_a, i_b], where i_a is the index in the instance.a direction and i_b the instance.b direction.

E.g. c.pins["a", 3, 5], accesses the pins of the instance which is 3 times in a direction (4th index in the array), and 5 times in b direction (5th index in the array).

Raises:

Type Description
IndexError

If the pin is an array pin and the index is out of range.

KeyError

If the pin name does not exist.

Returns:

Type Description
ProtoPin[T]

Pin from instance by name or name and array index.

Source code in kfactory/instance_pins.py
339
340
def __getitem__(self, key: int | str | tuple[int | str, int, int]) -> DPin:
    return DPin(base=super().__getitem__(key).base)

__init__

__init__(instance: DInstance) -> None

Creates the virtual pins object.

Parameters:

Name Type Description Default
instance DInstance

The related instance

required
Source code in kfactory/instance_pins.py
311
312
313
314
315
316
317
def __init__(self, instance: DInstance) -> None:
    """Creates the virtual pins object.

    Args:
        instance: The related instance
    """
    self.instance = instance

filter

filter(
    pin_type: str | None = None, regex: str | None = None
) -> list[DPin]

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/instance_pins.py
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
def filter(
    self,
    pin_type: str | None = None,
    regex: str | None = None,
) -> list[DPin]:
    """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[DPin] = list(self)
    return list(filter_type_reg(pins, pin_type=pin_type, regex=regex))

InstancePins

Bases: ProtoTInstancePins[int]

Source code in kfactory/instance_pins.py
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
class InstancePins(ProtoTInstancePins[int]):
    def __init__(self, instance: Instance) -> None:
        """Creates the virtual pins object.

        Args:
            instance: The related instance
        """
        self.instance = instance

    @property
    def cell_pins(self) -> Pins:
        return Pins(kcl=self.instance.cell.kcl, bases=self.instance.cell.pins.bases)

    def filter(
        self,
        pin_type: str | None = None,
        regex: str | None = None,
    ) -> list[Pin]:
        """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[Pin] = list(self)
        return list(filter_type_reg(pins, pin_type=pin_type, regex=regex))

    def __getitem__(self, key: int | str | tuple[int | str, int, int]) -> Pin:
        return Pin(base=super().__getitem__(key).base)

    def __iter__(self) -> Iterator[Pin]:
        yield from (p.to_itype() for p in self.each_pin())

__getitem__

__getitem__(
    key: int | str | tuple[int | str, int, int],
) -> Pin

Returns pin from instance.

The key can either be an integer, in which case the nth pin is returned, or a string in which case the first pin with a matching name is returned.

If the instance is an array, the key can also be a tuple in the form of c.pins[key_name, i_a, i_b], where i_a is the index in the instance.a direction and i_b the instance.b direction.

E.g. c.pins["a", 3, 5], accesses the pins of the instance which is 3 times in a direction (4th index in the array), and 5 times in b direction (5th index in the array).

Raises:

Type Description
IndexError

If the pin is an array pin and the index is out of range.

KeyError

If the pin name does not exist.

Returns:

Type Description
ProtoPin[T]

Pin from instance by name or name and array index.

Source code in kfactory/instance_pins.py
303
304
def __getitem__(self, key: int | str | tuple[int | str, int, int]) -> Pin:
    return Pin(base=super().__getitem__(key).base)

__init__

__init__(instance: Instance) -> None

Creates the virtual pins object.

Parameters:

Name Type Description Default
instance Instance

The related instance

required
Source code in kfactory/instance_pins.py
275
276
277
278
279
280
281
def __init__(self, instance: Instance) -> None:
    """Creates the virtual pins object.

    Args:
        instance: The related instance
    """
    self.instance = instance

filter

filter(
    pin_type: str | None = None, regex: str | None = None
) -> list[Pin]

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/instance_pins.py
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
def filter(
    self,
    pin_type: str | None = None,
    regex: str | None = None,
) -> list[Pin]:
    """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[Pin] = list(self)
    return list(filter_type_reg(pins, pin_type=pin_type, regex=regex))

ProtoTInstancePins

Bases: ProtoInstancePins[T, ProtoTInstance[T]], ABC

Pins of an Instance.

These act as virtual pins as the centers needs to change if the instance changes etc.

Attributes:

Name Type Description
cell_pins ProtoPins[T]

A pointer to the KCell.pins of the cell

instance ProtoTInstance[T]

A pointer to the Instance related to this. This provides a way to dynamically calculate the pins.

Source code in kfactory/instance_pins.py
 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
113
114
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
174
175
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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
class ProtoTInstancePins[T: (int, float)](ProtoInstancePins[T, ProtoTInstance[T]], ABC):
    """Pins of an Instance.

    These act as virtual pins as the centers needs to change if the
    instance changes etc.


    Attributes:
        cell_pins: A pointer to the [`KCell.pins`][kfactory.kcell.KCell.pins]
            of the cell
        instance: A pointer to the Instance related to this.
            This provides a way to dynamically calculate the pins.
    """

    instance: ProtoTInstance[T]

    def __len__(self) -> int:
        """Return Pin count."""
        if not self.instance.instance.is_regular_array():
            return len(self.cell_pins)
        return len(self.cell_pins) * self.instance.na * self.instance.nb

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

    @property
    def pins(self) -> ProtoTInstancePins[T]:
        return self.instance.pins

    @property
    def bases(self) -> list[BasePin]:
        return [p.base for p in self.instance.pins]

    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))

    def __getitem__(self, key: int | str | tuple[int | str, int, int]) -> ProtoPin[T]:
        """Returns pin from instance.

        The key can either be an integer, in which case the nth pin is
        returned, or a string in which case the first pin with a matching
        name is returned.

        If the instance is an array, the key can also be a tuple in the
        form of `c.pins[key_name, i_a, i_b]`, where `i_a` is the index in
        the `instance.a` direction and `i_b` the `instance.b` direction.

        E.g. `c.pins["a", 3, 5]`, accesses the pins of the instance which is
        3 times in `a` direction (4th index in the array), and 5 times in `b` direction
        (5th index in the array).

        Raises:
            IndexError: If the pin is an array pin and the index is out of range.
            KeyError: If the pin name does not exist.

        Returns:
            Pin from instance by name or name and array index.
        """
        if not self.instance.is_regular_array():
            try:
                p = self.cell_pins[cast("int | str", key)]
                if not self.instance.is_complex():
                    return p.copy(self.instance.trans)
                return p.copy(self.instance.dcplx_trans)
            except KeyError as e:
                raise KeyError(
                    f"{key=} is not a valid pin name or index. "
                    "Make sure the instance is an array when giving it a tuple. "
                    f"Available pins: {[v.name for v in self.cell_pins]}"
                ) from e
        else:
            if isinstance(key, tuple):
                key, i_a, i_b = key
                if i_a >= self.instance.na or i_b >= self.instance.nb:
                    raise IndexError(
                        f"The indexes {i_a=} and {i_b=} must be within the array size"
                        f" instance.na={self.instance.na} and"
                        f" instance.nb={self.instance.nb}"
                    )
            else:
                i_a = 0
                i_b = 0
            p = self.cell_pins[key]
            if not self.instance.is_complex():
                return p.copy(
                    kdb.Trans(self.instance.a * i_a + self.instance.b * i_b)
                    * self.instance.trans
                )
            return p.copy(
                kdb.DCplxTrans(self.instance.da * i_a + self.instance.db * i_b)
                * self.instance.dcplx_trans
            )

    @property
    @abstractmethod
    def cell_pins(self) -> ProtoPins[T]: ...

    def each_pin(self) -> Iterator[ProtoPin[T]]:
        """Create a copy of the pins to iterate through."""
        if not self.instance.is_regular_array():
            if not self.instance.is_complex():
                yield from (p.copy(self.instance.trans) for p in self.cell_pins)
            else:
                yield from (p.copy(self.instance.dcplx_trans) for p in self.cell_pins)
        elif not self.instance.is_complex():
            yield from (
                p.copy(
                    kdb.Trans(self.instance.a * i_a + self.instance.b * i_b)
                    * self.instance.trans
                )
                for i_a in range(self.instance.na)
                for i_b in range(self.instance.nb)
                for p in self.cell_pins
            )
        else:
            yield from (
                p.copy(
                    kdb.DCplxTrans(self.instance.da * i_a + self.instance.db * i_b)
                    * self.instance.dcplx_trans
                )
                for i_a in range(self.instance.na)
                for i_b in range(self.instance.nb)
                for p in self.cell_pins
            )

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

    def each_by_array_coord(self) -> Iterator[tuple[int, int, ProtoPin[T]]]:
        if not self.instance.is_regular_array():
            if not self.instance.is_complex():
                yield from ((0, 0, p.copy(self.instance.trans)) for p in self.cell_pins)
            else:
                yield from (
                    (0, 0, p.copy(self.instance.dcplx_trans)) for p in self.cell_pins
                )
        elif not self.instance.is_complex():
            yield from (
                (
                    i_a,
                    i_b,
                    p.copy(
                        kdb.Trans(self.instance.a * i_a + self.instance.b * i_b)
                        * self.instance.trans
                    ),
                )
                for i_a in range(self.instance.na)
                for i_b in range(self.instance.nb)
                for p in self.cell_pins
            )
        else:
            yield from (
                (
                    i_a,
                    i_b,
                    p.copy(
                        kdb.DCplxTrans(self.instance.da * i_a + self.instance.db * i_b)
                        * self.instance.dcplx_trans
                    ),
                )
                for i_a in range(self.instance.na)
                for i_b in range(self.instance.nb)
                for p in self.cell_pins
            )

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

    def copy(self, rename_function: Callable[[list[Pin]], None] | None = None) -> Pins:
        """Creates a copy in the form of [Pins][kfactory.kcell.Pins]."""
        if not self.instance.is_regular_array():
            if not self.instance.is_complex():
                return Pins(
                    kcl=self.instance.kcl,
                    bases=[
                        b.transformed(trans=self.instance.trans)
                        for b in self.cell_pins.bases
                    ],
                )
            return Pins(
                kcl=self.instance.kcl,
                bases=[
                    b.transformed(trans=self.instance.dcplx_trans)
                    for b in self.cell_pins.bases
                ],
            )
        if not self.instance.is_complex():
            return Pins(
                kcl=self.instance.kcl,
                bases=[
                    b.transformed(
                        self.instance.trans
                        * kdb.Trans(self.instance.a * i_a + self.instance.b * i_b)
                    )
                    for i_a in range(self.instance.na)
                    for i_b in range(self.instance.nb)
                    for b in self.cell_pins.bases
                ],
            )
        return Pins(
            kcl=self.instance.kcl,
            bases=[
                b.transformed(
                    self.instance.dcplx_trans
                    * kdb.DCplxTrans(self.instance.db * i_a + self.instance.db * i_b)
                )
                for i_a in range(self.instance.na)
                for i_b in range(self.instance.nb)
                for b in self.cell_pins.bases
            ],
        )

__contains__

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

Check whether a pin is in this pin collection.

Source code in kfactory/instance_pins.py
67
68
69
70
71
def __contains__(self, pin: str | ProtoPin[Any]) -> bool:
    """Check whether a pin is in this pin collection."""
    if isinstance(pin, ProtoPin):
        return pin.base in [p.base for p in self.instance.pins]
    return any(_pin.name == pin for _pin in self.instance.pins)

__getitem__

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

Returns pin from instance.

The key can either be an integer, in which case the nth pin is returned, or a string in which case the first pin with a matching name is returned.

If the instance is an array, the key can also be a tuple in the form of c.pins[key_name, i_a, i_b], where i_a is the index in the instance.a direction and i_b the instance.b direction.

E.g. c.pins["a", 3, 5], accesses the pins of the instance which is 3 times in a direction (4th index in the array), and 5 times in b direction (5th index in the array).

Raises:

Type Description
IndexError

If the pin is an array pin and the index is out of range.

KeyError

If the pin name does not exist.

Returns:

Type Description
ProtoPin[T]

Pin from instance by name or name and array index.

Source code in kfactory/instance_pins.py
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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
def __getitem__(self, key: int | str | tuple[int | str, int, int]) -> ProtoPin[T]:
    """Returns pin from instance.

    The key can either be an integer, in which case the nth pin is
    returned, or a string in which case the first pin with a matching
    name is returned.

    If the instance is an array, the key can also be a tuple in the
    form of `c.pins[key_name, i_a, i_b]`, where `i_a` is the index in
    the `instance.a` direction and `i_b` the `instance.b` direction.

    E.g. `c.pins["a", 3, 5]`, accesses the pins of the instance which is
    3 times in `a` direction (4th index in the array), and 5 times in `b` direction
    (5th index in the array).

    Raises:
        IndexError: If the pin is an array pin and the index is out of range.
        KeyError: If the pin name does not exist.

    Returns:
        Pin from instance by name or name and array index.
    """
    if not self.instance.is_regular_array():
        try:
            p = self.cell_pins[cast("int | str", key)]
            if not self.instance.is_complex():
                return p.copy(self.instance.trans)
            return p.copy(self.instance.dcplx_trans)
        except KeyError as e:
            raise KeyError(
                f"{key=} is not a valid pin name or index. "
                "Make sure the instance is an array when giving it a tuple. "
                f"Available pins: {[v.name for v in self.cell_pins]}"
            ) from e
    else:
        if isinstance(key, tuple):
            key, i_a, i_b = key
            if i_a >= self.instance.na or i_b >= self.instance.nb:
                raise IndexError(
                    f"The indexes {i_a=} and {i_b=} must be within the array size"
                    f" instance.na={self.instance.na} and"
                    f" instance.nb={self.instance.nb}"
                )
        else:
            i_a = 0
            i_b = 0
        p = self.cell_pins[key]
        if not self.instance.is_complex():
            return p.copy(
                kdb.Trans(self.instance.a * i_a + self.instance.b * i_b)
                * self.instance.trans
            )
        return p.copy(
            kdb.DCplxTrans(self.instance.da * i_a + self.instance.db * i_b)
            * self.instance.dcplx_trans
        )

__len__

__len__() -> int

Return Pin count.

Source code in kfactory/instance_pins.py
61
62
63
64
65
def __len__(self) -> int:
    """Return Pin count."""
    if not self.instance.instance.is_regular_array():
        return len(self.cell_pins)
    return len(self.cell_pins) * self.instance.na * self.instance.nb

copy

copy(
    rename_function: Callable[[list[Pin]], None]
    | None = None,
) -> Pins

Creates a copy in the form of Pins.

Source code in kfactory/instance_pins.py
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
def copy(self, rename_function: Callable[[list[Pin]], None] | None = None) -> Pins:
    """Creates a copy in the form of [Pins][kfactory.kcell.Pins]."""
    if not self.instance.is_regular_array():
        if not self.instance.is_complex():
            return Pins(
                kcl=self.instance.kcl,
                bases=[
                    b.transformed(trans=self.instance.trans)
                    for b in self.cell_pins.bases
                ],
            )
        return Pins(
            kcl=self.instance.kcl,
            bases=[
                b.transformed(trans=self.instance.dcplx_trans)
                for b in self.cell_pins.bases
            ],
        )
    if not self.instance.is_complex():
        return Pins(
            kcl=self.instance.kcl,
            bases=[
                b.transformed(
                    self.instance.trans
                    * kdb.Trans(self.instance.a * i_a + self.instance.b * i_b)
                )
                for i_a in range(self.instance.na)
                for i_b in range(self.instance.nb)
                for b in self.cell_pins.bases
            ],
        )
    return Pins(
        kcl=self.instance.kcl,
        bases=[
            b.transformed(
                self.instance.dcplx_trans
                * kdb.DCplxTrans(self.instance.db * i_a + self.instance.db * i_b)
            )
            for i_a in range(self.instance.na)
            for i_b in range(self.instance.nb)
            for b in self.cell_pins.bases
        ],
    )

each_pin

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

Create a copy of the pins to iterate through.

Source code in kfactory/instance_pins.py
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
def each_pin(self) -> Iterator[ProtoPin[T]]:
    """Create a copy of the pins to iterate through."""
    if not self.instance.is_regular_array():
        if not self.instance.is_complex():
            yield from (p.copy(self.instance.trans) for p in self.cell_pins)
        else:
            yield from (p.copy(self.instance.dcplx_trans) for p in self.cell_pins)
    elif not self.instance.is_complex():
        yield from (
            p.copy(
                kdb.Trans(self.instance.a * i_a + self.instance.b * i_b)
                * self.instance.trans
            )
            for i_a in range(self.instance.na)
            for i_b in range(self.instance.nb)
            for p in self.cell_pins
        )
    else:
        yield from (
            p.copy(
                kdb.DCplxTrans(self.instance.da * i_a + self.instance.db * i_b)
                * self.instance.dcplx_trans
            )
            for i_a in range(self.instance.na)
            for i_b in range(self.instance.nb)
            for p in self.cell_pins
        )

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/instance_pins.py
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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))

VInstancePins

Bases: ProtoInstancePins[float, VInstance]

Pins of an instance.

These act as virtual pins as the centers needs to change if the instance changes etc.

Attributes:

Name Type Description
cell_pins DPins

A pointer to the KCell.pins of the cell

instance VInstance

A pointer to the Instance related to this. This provides a way to dynamically calculate the pins.

Source code in kfactory/instance_pins.py
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
class VInstancePins(ProtoInstancePins[float, VInstance]):
    """Pins of an instance.

    These act as virtual pins as the centers needs to change if the
    instance changes etc.


    Attributes:
        cell_pins: A pointer to the [`KCell.pins`][kfactory.kcell.KCell.pins]
            of the cell
        instance: A pointer to the Instance related to this.
            This provides a way to dynamically calculate the pins.
    """

    instance: VInstance

    def __init__(self, instance: VInstance) -> None:
        """Creates the virtual pins object.

        Args:
            instance: The related instance
        """
        self.instance = instance

    @property
    def cell_pins(self) -> DPins:
        return DPins(kcl=self.instance.cell.kcl, bases=self.instance.cell.pins.bases)

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

    def __getitem__(self, key: int | str) -> DPin:
        """Get a pin by name."""
        p = self.cell_pins[key]
        return p.copy(self.instance.trans)

    def __iter__(self) -> Iterator[DPin]:
        """Create a copy of the pins to iterate through."""
        yield from (p.copy(self.instance.trans) for p in self.cell_pins)

    def __contains__(self, pin: str | ProtoPin[Any]) -> bool:
        """Check if a pin is in the instance."""
        if isinstance(pin, ProtoPin):
            return pin.base in [p.base for p in self.instance.pins]
        return any(_pin.name == pin for _pin in self.instance.pins)

    def filter(
        self,
        pin_type: str | None = None,
        regex: str | None = None,
    ) -> list[DPin]:
        """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[DPin] = list(self)
        return list(filter_type_reg(pins, pin_type=pin_type, regex=regex))

    def copy(self) -> DPins:
        """Creates a copy in the form of [Pins][kfactory.kcell.Pins]."""
        return DPins(
            kcl=self.instance.cell.kcl,
            bases=[b.transformed(self.instance.trans) for b in self.cell_pins.bases],
        )

__contains__

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

Check if a pin is in the instance.

Source code in kfactory/instance_pins.py
387
388
389
390
391
def __contains__(self, pin: str | ProtoPin[Any]) -> bool:
    """Check if a pin is in the instance."""
    if isinstance(pin, ProtoPin):
        return pin.base in [p.base for p in self.instance.pins]
    return any(_pin.name == pin for _pin in self.instance.pins)

__getitem__

__getitem__(key: int | str) -> DPin

Get a pin by name.

Source code in kfactory/instance_pins.py
378
379
380
381
def __getitem__(self, key: int | str) -> DPin:
    """Get a pin by name."""
    p = self.cell_pins[key]
    return p.copy(self.instance.trans)

__init__

__init__(instance: VInstance) -> None

Creates the virtual pins object.

Parameters:

Name Type Description Default
instance VInstance

The related instance

required
Source code in kfactory/instance_pins.py
362
363
364
365
366
367
368
def __init__(self, instance: VInstance) -> None:
    """Creates the virtual pins object.

    Args:
        instance: The related instance
    """
    self.instance = instance

__iter__

__iter__() -> Iterator[DPin]

Create a copy of the pins to iterate through.

Source code in kfactory/instance_pins.py
383
384
385
def __iter__(self) -> Iterator[DPin]:
    """Create a copy of the pins to iterate through."""
    yield from (p.copy(self.instance.trans) for p in self.cell_pins)

__len__

__len__() -> int

Return Pin count.

Source code in kfactory/instance_pins.py
374
375
376
def __len__(self) -> int:
    """Return Pin count."""
    return len(self.cell_pins)

copy

copy() -> DPins

Creates a copy in the form of Pins.

Source code in kfactory/instance_pins.py
409
410
411
412
413
414
def copy(self) -> DPins:
    """Creates a copy in the form of [Pins][kfactory.kcell.Pins]."""
    return DPins(
        kcl=self.instance.cell.kcl,
        bases=[b.transformed(self.instance.trans) for b in self.cell_pins.bases],
    )

filter

filter(
    pin_type: str | None = None, regex: str | None = None
) -> list[DPin]

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/instance_pins.py
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
def filter(
    self,
    pin_type: str | None = None,
    regex: str | None = None,
) -> list[DPin]:
    """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[DPin] = list(self)
    return list(filter_type_reg(pins, pin_type=pin_type, regex=regex))