Skip to content

geno_lewm.planning.costs

costs

Edit-sequence cost functions for RFC-0008 planning.

DEFAULT_TYPE_COSTS module-attribute

DEFAULT_TYPE_COSTS: Mapping[EditType, float] = MappingProxyType(_DEFAULT_TYPE_COSTS)

Default non-negative type costs for weighted_type_cost.

The defaults keep SNVs cheapest, assign a higher penalty to simple indels and MNVs, and make mixed indels the most expensive v1 edit class. Structural variants are outside the v1 planner surface.

count_cost

count_cost(edits: Sequence[RelEdit]) -> float

Return the number of edits in a candidate sequence.

Source code in geno_lewm/planning/costs.py
def count_cost(edits: Sequence[RelEdit]) -> float:
    """Return the number of edits in a candidate sequence."""
    return float(len(edits))

edit_bp_cost

edit_bp_cost(edit: RelEdit) -> float

Return the base-pair cost contribution of a single edit.

SNVs cost one base. Insertions and deletions cost their event length excluding the VCF anchor base. MNVs cost their substituted span. Mixed indels cost the larger touched span because both the deleted and inserted sequence are material to the action.

Source code in geno_lewm/planning/costs.py
def edit_bp_cost(edit: RelEdit) -> float:
    """Return the base-pair cost contribution of a single edit.

    SNVs cost one base. Insertions and deletions cost their event
    length excluding the VCF anchor base. MNVs cost their substituted
    span. Mixed indels cost the larger touched span because both the
    deleted and inserted sequence are material to the action.
    """
    _require_shape_consistent(edit)
    ref_len = len(edit.ref_bases)
    alt_len = len(edit.alt_bases)

    if edit.edit_type is EditType.SNV:
        return 1.0
    if edit.edit_type is EditType.INS:
        return float(alt_len - ref_len)
    if edit.edit_type is EditType.DEL:
        return float(ref_len - alt_len)
    if edit.edit_type is EditType.MNV:
        return float(ref_len)
    if edit.edit_type is EditType.INDEL:
        return float(max(ref_len, alt_len))

    raise InputError(
        "SV edits are outside the v1 planning cost surface",
        details={"edit_type": int(edit.edit_type)},
    )

bp_cost

bp_cost(edits: Sequence[RelEdit]) -> float

Return the total base-pair cost for edits.

Source code in geno_lewm/planning/costs.py
def bp_cost(edits: Sequence[RelEdit]) -> float:
    """Return the total base-pair cost for ``edits``."""
    return sum(edit_bp_cost(edit) for edit in edits)

weighted_type_cost

weighted_type_cost(edits: Sequence[RelEdit], weights: Mapping[EditType, float] = DEFAULT_TYPE_COSTS) -> float

Return the sum of per-edit-type costs for edits.

Source code in geno_lewm/planning/costs.py
def weighted_type_cost(
    edits: Sequence[RelEdit],
    weights: Mapping[EditType, float] = DEFAULT_TYPE_COSTS,
) -> float:
    """Return the sum of per-edit-type costs for ``edits``."""
    normalized = _validate_type_costs(weights)
    total = 0.0
    for edit in edits:
        _require_shape_consistent(edit)
        try:
            total += normalized[edit.edit_type]
        except KeyError as exc:
            raise InputError(
                "missing cost weight for edit type",
                details={"edit_type": int(edit.edit_type)},
                remediation="provide a non-negative finite cost for every sampled edit type",
            ) from exc
    return total

custom_cost

custom_cost(edits: Sequence[RelEdit], cost_fn: Callable[[Sequence[RelEdit]], float]) -> float

Evaluate and validate a user-provided cost function.

Source code in geno_lewm/planning/costs.py
def custom_cost(edits: Sequence[RelEdit], cost_fn: Callable[[Sequence[RelEdit]], float]) -> float:
    """Evaluate and validate a user-provided cost function."""
    value = cost_fn(tuple(edits))
    return _validate_cost_value("custom cost", value)