File size: 7,634 Bytes
e275025
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
"""
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': [],    # Т1-ВИ, Т2-ВИ, FLAIR
            '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()
            }
        }