| """ |
| Medical Term Manager - управление медицинской терминологией |
| """ |
|
|
| import logging |
| from pathlib import Path |
| from typing import List, Set, Dict, Optional |
| import re |
|
|
| logger = logging.getLogger(__name__) |
|
|
|
|
| class MedicalTermManager: |
| """ |
| Менеджер медицинских терминов для коррекции транскрипций. |
| |
| Функции: |
| - Загрузка терминов из файлов |
| - Поиск и валидация терминов |
| - Категоризация (анатомия, процедуры, диагнозы) |
| - Нормализация терминов |
| """ |
| |
| def __init__(self, terms_file: Optional[Path] = None): |
| """ |
| Инициализация менеджера. |
| |
| Args: |
| terms_file: Путь к файлу с медицинскими терминами |
| """ |
| self.terms: Set[str] = set() |
| self.categories: Dict[str, List[str]] = { |
| 'imaging': [], |
| 'sequences': [], |
| 'anatomy': [], |
| 'pathology': [], |
| 'modifiers': [] |
| } |
| |
| if terms_file: |
| self.load_from_file(terms_file) |
| |
| def load_from_file(self, filepath: Path) -> int: |
| """ |
| Загрузить термины из файла. |
| |
| Args: |
| filepath: Путь к файлу с терминами (разделитель: запятая) |
| |
| Returns: |
| Количество загруженных терминов |
| """ |
| try: |
| with open(filepath, 'r', encoding='utf-8') as f: |
| content = f.read().strip() |
| |
| |
| raw_terms = [term.strip() for term in content.split(',')] |
| |
| for term in raw_terms: |
| if term: |
| self.add_term(term) |
| |
| logger.info(f"Loaded {len(self.terms)} medical terms from {filepath}") |
| return len(self.terms) |
| |
| except FileNotFoundError: |
| logger.error(f"Terms file not found: {filepath}") |
| return 0 |
| except Exception as e: |
| logger.error(f"Error loading terms: {e}") |
| return 0 |
| |
| def add_term(self, term: str) -> None: |
| """ |
| Добавить термин в базу знаний. |
| |
| Args: |
| term: Медицинский термин |
| """ |
| normalized = self.normalize_term(term) |
| self.terms.add(normalized) |
| |
| |
| self._categorize_term(normalized) |
| |
| def normalize_term(self, term: str) -> str: |
| """ |
| Нормализовать термин (удалить лишние пробелы, привести к единому формату). |
| |
| Args: |
| term: Исходный термин |
| |
| Returns: |
| Нормализованный термин |
| """ |
| |
| normalized = ' '.join(term.split()) |
| return normalized |
| |
| def _categorize_term(self, term: str) -> None: |
| """ |
| Автоматическая категоризация термина. |
| |
| Args: |
| term: Термин для категоризации |
| """ |
| term_lower = term.lower() |
| |
| |
| if any(x in term_lower for x in ['мрт', 'кт', 'мскт', 'рентген', 'узи']): |
| self.categories['imaging'].append(term) |
| |
| |
| elif any(x in term_lower for x in ['т1', 'т2', 'flair', 'stir', 'dwi', 'adc']): |
| self.categories['sequences'].append(term) |
| |
| |
| elif re.search(r'[cltsl]\d+', term_lower) or any(x in term_lower for x in |
| ['позвонок', 'диск', 'желудочк', 'цистерн', 'паренхима']): |
| self.categories['anatomy'].append(term) |
| |
| |
| elif any(x in term_lower for x in ['грыжа', 'протрузия', 'стеноз', 'экструзия', 'остеофит']): |
| self.categories['pathology'].append(term) |
| |
| |
| elif any(x in term_lower for x in ['гипер', 'гипо', 'изо', 'дорзальн', 'вентральн']): |
| self.categories['modifiers'].append(term) |
| |
| def search_term(self, query: str) -> List[str]: |
| """ |
| Поиск термина в базе. |
| |
| Args: |
| query: Поисковый запрос |
| |
| Returns: |
| Список найденных терминов |
| """ |
| query_lower = query.lower() |
| matches = [ |
| term for term in self.terms |
| if query_lower in term.lower() |
| ] |
| return sorted(matches) |
| |
| def get_category_terms(self, category: str) -> List[str]: |
| """ |
| Получить термины по категории. |
| |
| Args: |
| category: Название категории |
| |
| Returns: |
| Список терминов категории |
| """ |
| return self.categories.get(category, []) |
| |
| def get_all_terms(self) -> List[str]: |
| """ |
| Получить все термины. |
| |
| Returns: |
| Список всех терминов |
| """ |
| return sorted(list(self.terms)) |
| |
| def get_terms_as_text(self, separator: str = ', ') -> str: |
| """ |
| Получить все термины в виде текста. |
| |
| Args: |
| separator: Разделитель терминов |
| |
| Returns: |
| Строка с терминами |
| """ |
| return separator.join(sorted(self.terms)) |
| |
| def validate_transcription(self, text: str) -> Dict[str, any]: |
| """ |
| Валидировать транскрипцию на наличие медицинских терминов. |
| |
| Args: |
| text: Текст транскрипции |
| |
| Returns: |
| Словарь с результатами валидации |
| """ |
| found_terms = [] |
| text_lower = text.lower() |
| |
| for term in self.terms: |
| if term.lower() in text_lower: |
| found_terms.append(term) |
| |
| return { |
| 'found_terms': found_terms, |
| 'count': len(found_terms), |
| 'coverage': len(found_terms) / len(self.terms) if self.terms else 0 |
| } |
| |
| def get_statistics(self) -> Dict[str, any]: |
| """ |
| Получить статистику по базе знаний. |
| |
| Returns: |
| Словарь со статистикой |
| """ |
| return { |
| 'total_terms': len(self.terms), |
| 'categories': { |
| cat: len(terms) |
| for cat, terms in self.categories.items() |
| } |
| } |
|
|