diff --git a/src/pipeline.rs b/src/pipeline.rs index b72ec93..17c9fc2 100644 --- a/src/pipeline.rs +++ b/src/pipeline.rs @@ -13,6 +13,7 @@ pub struct Pipeline { pub meta: HashMap, pub lexical: LexicalIndex, pub pool_size: usize, + pub valid_by_code: HashMap, } impl Pipeline { @@ -20,7 +21,17 @@ impl Pipeline { let entries = corpus::load(&cfg.alpha_id_path)?; let meta = claml::load(&cfg.claml_path)?; let lexical = LexicalIndex::build_in_ram(&entries)?; - Ok(Self { entries, meta, lexical, pool_size: cfg.pool_size }) + let valid_by_code = { + let mut m: HashMap = HashMap::new(); + for e in &entries { + if let Some(code) = corpus::primary_code(e) { + let v = m.entry(code.to_string()).or_insert(false); + *v = *v || e.valid; + } + } + m + }; + Ok(Self { entries, meta, lexical, pool_size: cfg.pool_size, valid_by_code }) } /// Look up ICD metadata: exact code first, then — only for 6-char dotted codes @@ -48,8 +59,8 @@ impl Pipeline { && bytes[1].is_ascii_digit() && bytes[2].is_ascii_digit() && bytes[3] == b'.' - && bytes[4].is_ascii_alphanumeric() - && bytes[5].is_ascii_alphanumeric() + && bytes[4].is_ascii_digit() + && bytes[5].is_ascii_digit() { if let Some(m) = self.meta.get(&code[..5]) { return Some(m); @@ -61,7 +72,7 @@ impl Pipeline { fn to_suggestion(&self, code: &str, phrase: &str, score: f32, segs: Vec, alpha_valid: bool) -> Option { - let m = self.meta_lookup(code)?; + let m = self.meta_lookup(code)?; // None ≈ 31 codes absent from ClaML entirely; accepted gap (see meta_lookup doc) Some(Suggestion { icd_code: code.to_string(), description: m.description.clone(), @@ -95,23 +106,10 @@ impl Pipeline { } } - let valid_by_code: HashMap = { - let mut m = HashMap::new(); - for c in &candidates { - m.entry(c.icd_code.clone()).or_insert(false); - } - for e in &self.entries { - if let Some(code) = corpus::primary_code(e) { - if let Some(v) = m.get_mut(code) { *v = *v || e.valid; } - } - } - m - }; - let merged = cross_segment_dedupe(candidates); let mut suggestions = Vec::new(); for (d, score) in merged { - let alpha_valid = *valid_by_code.get(&d.icd_code).unwrap_or(&false); + let alpha_valid = self.valid_by_code.get(&d.icd_code).copied().unwrap_or(false); if let Some(s) = self.to_suggestion(&d.icd_code, &d.best_phrase, score, d.source_segments.clone(), alpha_valid) { if filter.accepts(&s.tags) {