///|
/// A mathematical cleavage subset, not a kinetic/probabilistic prediction.
pub(all) struct PartialScenario {
mask : Int
active_top_cuts : Array[Int]
fragments : Array[Fragment]
} derive(Eq, Debug, ToJson)
///|
/// Prefix enumeration always advertises whether it is exhaustive.
pub(all) struct PartialReport {
candidate_cuts : Int
total_subsets : Int
truncated : Bool
scenarios : Array[PartialScenario]
} derive(Eq, Debug, ToJson)
///|
/// Enumerate subsets in ascending bitmask order, including uncut input first.
pub fn partial_digests(
dna : Dna,
enzymes : Array[Enzyme],
max_scenarios? : Int = 32,
) -> PartialReport raise RestrictError {
if max_scenarios < 1 || max_scenarios > 64 {
raise InvalidInput("PARTIAL_MAX_SCENARIOS")
}
let complete = digest_many(dna, enzymes)
if complete.cuts.length() > 12 {
raise LimitExceeded("PARTIAL_CUT_MAX_12")
}
let total = 1 << complete.cuts.length()
let count = total.min(max_scenarios)
if count * dna.length() > 2000000 {
raise LimitExceeded("PARTIAL_OUTPUT_BASES")
}
let scenarios : Array[PartialScenario] = []
for mask in 0.. s.top),
fragments: result.fragments,
})
}
{
candidate_cuts: complete.cuts.length(),
total_subsets: total,
truncated: count < total,
scenarios,
}
}