def index_in_block(self, channel_index: int) -> int:
        """Return the index a channel has within the subblock it belongs to

        I.e., only for reducible circuits, this gives a result different from
        the argument itself.

        Args:
            channel_index (int): The index of the external channel

        Raises:
            ValueError: for an invalid `channel_index`

        """
        if channel_index < 0 or channel_index >= self.cdim:
            raise ValueError()

        struct = self.block_structure

        if len(struct) == 1:
            return channel_index, 0
        i = 1
        while sum(struct[:i]) <= channel_index and i < self.cdim:
            i += 1
        block_index = i - 1
        index_in_block = channel_index - sum(struct[:block_index])

        return index_in_block, block_index
Return the index a channel has within the subblock it belongs to

        I.e., only for reducible circuits, this gives a result different from
        the argument itself.

        Args:
            channel_index (int): The index of the external channel

        Raises:
            ValueError: for an invalid `channel_index`