Narrow engine type auxiliary stem frontier
This commit is contained in:
parent
7741dc2087
commit
a265251831
3 changed files with 112 additions and 3 deletions
|
|
@ -172,6 +172,8 @@ pub struct EngineTypesInspectionReport {
|
|||
pub car_auxiliary_stem_counts: BTreeMap<String, usize>,
|
||||
pub car_auxiliary_stem_relation_counts: BTreeMap<String, usize>,
|
||||
pub car_auxiliary_stem_distinct_pair_counts: BTreeMap<String, usize>,
|
||||
pub car_auxiliary_stem_distinct_pattern_counts: BTreeMap<String, usize>,
|
||||
pub car_auxiliary_stem_distinct_pair_family_stems: BTreeMap<String, Vec<String>>,
|
||||
pub internal_ne_profile_pk4_match_count: usize,
|
||||
pub internal_ne_profile_pk4_missing_count: usize,
|
||||
pub locomotive_pair_internal_ne_profile_pk4_match_count: usize,
|
||||
|
|
@ -439,6 +441,13 @@ pub fn inspect_engine_types_dir(
|
|||
.iter()
|
||||
.filter_map(distinct_car_auxiliary_stem_pair_label),
|
||||
);
|
||||
let car_auxiliary_stem_distinct_pattern_counts = count_owned_values(
|
||||
family_entries
|
||||
.iter()
|
||||
.filter_map(classify_distinct_car_auxiliary_stem_pattern),
|
||||
);
|
||||
let car_auxiliary_stem_distinct_pair_family_stems =
|
||||
build_distinct_car_auxiliary_stem_pair_family_stems(&family_entries);
|
||||
let lco_companion_stem_counts = count_named_values(
|
||||
family_entries
|
||||
.iter()
|
||||
|
|
@ -611,6 +620,8 @@ pub fn inspect_engine_types_dir(
|
|||
car_auxiliary_stem_counts,
|
||||
car_auxiliary_stem_relation_counts,
|
||||
car_auxiliary_stem_distinct_pair_counts,
|
||||
car_auxiliary_stem_distinct_pattern_counts,
|
||||
car_auxiliary_stem_distinct_pair_family_stems,
|
||||
internal_ne_profile_pk4_match_count,
|
||||
internal_ne_profile_pk4_missing_count,
|
||||
locomotive_pair_internal_ne_profile_pk4_match_count,
|
||||
|
|
@ -1010,6 +1021,35 @@ fn distinct_car_auxiliary_stem_pair_label(family: &EngineTypeFamilyEntry) -> Opt
|
|||
))
|
||||
}
|
||||
|
||||
fn classify_distinct_car_auxiliary_stem_pattern(family: &EngineTypeFamilyEntry) -> Option<String> {
|
||||
let pair_label = distinct_car_auxiliary_stem_pair_label(family)?;
|
||||
let internal_root = strip_terminal_role_letter(family.internal_stem.as_deref()?)?;
|
||||
let auxiliary_root = strip_terminal_role_letter(family.auxiliary_stem.as_deref()?)?;
|
||||
if internal_root.eq_ignore_ascii_case(auxiliary_root) {
|
||||
return Some("paired_opposite_role_suffix".to_string());
|
||||
}
|
||||
Some(format!("other_distinct_auxiliary_stem:{pair_label}"))
|
||||
}
|
||||
|
||||
fn build_distinct_car_auxiliary_stem_pair_family_stems(
|
||||
families: &[EngineTypeFamilyEntry],
|
||||
) -> BTreeMap<String, Vec<String>> {
|
||||
let mut grouped = BTreeMap::<String, Vec<String>>::new();
|
||||
for family in families {
|
||||
let Some(pair_label) = distinct_car_auxiliary_stem_pair_label(family) else {
|
||||
continue;
|
||||
};
|
||||
grouped
|
||||
.entry(pair_label)
|
||||
.or_default()
|
||||
.push(family.canonical_stem.clone());
|
||||
}
|
||||
for stems in grouped.values_mut() {
|
||||
stems.sort();
|
||||
}
|
||||
grouped
|
||||
}
|
||||
|
||||
fn strip_terminal_role_letter(value: &str) -> Option<&str> {
|
||||
let last = value.chars().last()?;
|
||||
matches!(last, 'L' | 'T' | 'l' | 't').then(|| {
|
||||
|
|
@ -1421,6 +1461,58 @@ mod tests {
|
|||
assert_eq!(ladders.get("55.000000 -> 85.000000"), Some(&1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_distinct_auxiliary_stem_patterns() {
|
||||
let paired = EngineTypeFamilyEntry {
|
||||
canonical_stem: "class_a1t".to_string(),
|
||||
internal_stem: Some("ClassA1T".to_string()),
|
||||
auxiliary_stem: Some("ClassA1L".to_string()),
|
||||
..minimal_family_entry()
|
||||
};
|
||||
let reordered = EngineTypeFamilyEntry {
|
||||
canonical_stem: "class_qjl".to_string(),
|
||||
internal_stem: Some("classqjl".to_string()),
|
||||
auxiliary_stem: Some("qjclassl".to_string()),
|
||||
..minimal_family_entry()
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
classify_distinct_car_auxiliary_stem_pattern(&paired),
|
||||
Some("paired_opposite_role_suffix".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
classify_distinct_car_auxiliary_stem_pattern(&reordered),
|
||||
Some("other_distinct_auxiliary_stem:classqjl -> qjclassl".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn groups_distinct_auxiliary_stem_pairs_by_family() {
|
||||
let grouped = build_distinct_car_auxiliary_stem_pair_family_stems(&[
|
||||
EngineTypeFamilyEntry {
|
||||
canonical_stem: "class_a1t".to_string(),
|
||||
internal_stem: Some("ClassA1T".to_string()),
|
||||
auxiliary_stem: Some("ClassA1L".to_string()),
|
||||
..minimal_family_entry()
|
||||
},
|
||||
EngineTypeFamilyEntry {
|
||||
canonical_stem: "class_qjt".to_string(),
|
||||
internal_stem: Some("classqjt".to_string()),
|
||||
auxiliary_stem: Some("qjclasst".to_string()),
|
||||
..minimal_family_entry()
|
||||
},
|
||||
]);
|
||||
|
||||
assert_eq!(
|
||||
grouped.get("ClassA1T -> ClassA1L"),
|
||||
Some(&vec!["class_a1t".to_string()])
|
||||
);
|
||||
assert_eq!(
|
||||
grouped.get("classqjt -> qjclasst"),
|
||||
Some(&vec!["class_qjt".to_string()])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builds_lco_low_cardinality_lane_counts() {
|
||||
let lane_counts = build_lco_low_cardinality_lane_counts(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue