Skip to main content

sim_lib_pitch_serial/
vertical.rs

1//! Verticalized views of row partitions without chord reification.
2
3use sim_lib_pitch_core::PitchClass;
4use sim_lib_pitch_set::PitchClassMask;
5
6use crate::{
7    AggregateCoverageReport, BlockOrder, RowPartition, ToneRow,
8    analyze_partition_aggregate_coverage,
9};
10
11/// One unordered vertical collection extracted from a partition block.
12#[derive(Clone, Debug, PartialEq, Eq)]
13pub struct VerticalSlice {
14    /// Source block index in the validated partition.
15    pub block_index: usize,
16    /// Row ordinals contributing to the slice.
17    pub ordinals: Vec<u8>,
18    /// Exact pitch classes contributed by those ordinals.
19    pub pitch_classes: Vec<PitchClass>,
20    /// Unordered pitch-class content of the slice.
21    pub mask: PitchClassMask,
22}
23
24/// A partition rendered as a set of vertical collections.
25#[derive(Clone, Debug, PartialEq, Eq)]
26pub struct VerticalCollection {
27    /// The partition's ordering contract.
28    pub order: BlockOrder,
29    /// One vertical slice per partition block.
30    pub slices: Vec<VerticalSlice>,
31    /// Aggregate pitch-class coverage across all slices.
32    pub aggregate_coverage: AggregateCoverageReport,
33}
34
35/// Produces vertical collection data from one validated partition.
36pub fn verticalize(row: &ToneRow, partition: &RowPartition) -> VerticalCollection {
37    let slices = partition
38        .blocks()
39        .iter()
40        .enumerate()
41        .map(|(block_index, block)| {
42            let pitch_classes = block.pitch_classes(row);
43            VerticalSlice {
44                block_index,
45                ordinals: block.ordinals().to_vec(),
46                mask: PitchClassMask::from_pitch_classes(&pitch_classes),
47                pitch_classes,
48            }
49        })
50        .collect();
51    VerticalCollection {
52        order: partition.order(),
53        slices,
54        aggregate_coverage: analyze_partition_aggregate_coverage(row, partition),
55    }
56}