В прошлый раз было описано, какие базовые сущности используются для хранения медицинских данных в МИС Нумеди. Сегодня же предлагаем окунуться в мир шаблонов для протоколов исследований.
Протокол исследования – документ, выдаваемый пациенту на руки. Что же представляет собой шаблон? Красивые картинки и цветные буквы – лишь фасад, а фундамент – структура, хранящаяся в базе данных. По большому счету можно выбрать любой формат описания абстрактных данных, который бы позволил сохранить иерархическую структуру. Мы же остановились на XML.
Шаблоны – это не статические данные, которые заносятся в поле таблицы один раз и забываются. Со временем структура шаблона может измениться. Например, не хватает каких-то измерений, или они, наоборот, лишние, и врач их не заполняет, ставя прочерки или оставляя пустые места. Ещё один случай изменения структуры – расширение функциональных возможностей системы шаблонов или переосмысление старых. Независимо от причины изменений для старой версии шаблона указывается время, до которого он действует, а для нового, в свою очередь, – с какого времени он вступает в силу. Таким образом, все старые протоколы не теряют и не приобретают какие-либо части, и остаются в том виде, в котором были отданы пациенту.
В целом, в системе используется более 15 тегов, и у каждого имеется свой набор атрибутов. С помощью основных тегов, описанных ниже, можно создать шаблон для любого протокола исследования.
Template
Корневой элемент, внутри которого располагаются остальные теги. С помощью двух атрибутов в нём указывается наличие и расположение основного изображения в шаблоне:
- image-id – идентификатор изображения, лежащего в хранилище;
- image-position – расположение изображения. Варианты: none, top, left-top-corner, left-bottom-corner, left-top-corner-high. По умолчанию – none.
Anatomy
Используется для отображения сущности анатомия. Атрибуты:
- id – номер анатомии в БД;
- font-size, font-bold, font-underline – настройки шрифта;
- anatomy-name – позволяет переопределить название анатомии. По умолчанию название берется из БД.
Anatomy-comment
Используется для отображения сущности комментарий. Атрибуты:
- comment-id – номер комментария в БД;
- use-default – флаг, указывающий на необходимость в автоматическом заполнении поля комментария стандартной фразой-шаблоном, помеченной как «по умолчанию». Варианты: true и false. По умолчанию – false;
- comment-type – указывает на тип комментария. Варианты: comment (комментарий), conclusion (заключение), complaint (жалоба). По умолчанию – comment.
Measurement
Используется для отображения сущности измерение. Атрибуты:
- id – номер измерения в БД;
- max-width – общая ширина элемента;
- value-width – ширина выпадающего списка для перечислимых измерений;
- unit-width – ширина единиц измерения для числовых измерений;
- measurement-name – позволяет переопределить название измерения, которое по умолчанию берётся из БД;
- need-points-to-end – показывает нужны ли точки после значения перечислимого измерения. Варианты: true и false. По умолчанию – false;
- empty-name – флаг, позволяющий не отображать название измерения. Варианты: true и false. По умолчанию – false;
- show-referent-interval – флаг для отображения референсного интервала. Варианты: true и false. По умолчанию – true.
Conclusion-label
Используется в конце шаблона. В результате добавляется зеленая линия на всю ширину строки и слово «Заключение», отображаемое под ней.
Все эти теги можно встретить, к примеру, в шаблоне УЗИ мочевого пузыря:
<template>
<anatomy id="119" font-size="10" font-bold="true" font-underline="false" comment="Мочевой пузырь" />
<measurement id="663" comment="Толщина стенки мочевого пузыря" />
<measurement id="664" comment="Объем мочевого пузыря на начало исследования" />
<measurement id="665" comment="Объем мочевого пузыря после опорожнения(объем остаточной мочи)" />
<anatomy-comment comment-id="94" comment-type="comment" />
<conclusion-label spacing-before="HALF"/>
<anatomy-comment comment-id="4" comment-type="conclusion" />
</template>
Text
Предназначен для отображения простого текста. Атрибуты:
- text-label – отображаемый текст;
- max-width – ширина элемента;
- font-size, font-bold, font-underline – настройки шрифта;
- is-color-selection – выделение зеленым цветом. Варианты: true и false. По умолчанию – false.
Measurement-group
Используется для отображения сущности группа измерений. Внутрь этого тега можно поместить теги measurement и text. Атрибуты:
- id – номер группы измерений в БД;
- is-color-selection – выделение зеленым цветом. Варианты: true и false. По умолчанию – false;
- multi-interval – используется для отображения референсных интервалов, когда в одной линии расположено 2 измерения с ними. Варианты: true и false. По умолчанию – false;
- show-through-slash – показать измерения через /. Возможные варианты: true и false. По умолчанию – false.
Тег можно использовать двумя способами. Первый способ: указать только тег measurement-group с нужными атрибутами. Система, со своей стороны, автоматически добавит все измерения, которые входят в эту группу измерений. Например, в шаблоне УЗИ печени и желчного пузыря для желчного пузыря указано:
<anatomy id="84" font-size="10" font-bold="true" font-underline="false" comment="Желчный пузырь"/>
<measurement-group id="7"/>
<measurement id="429" comment="Толщина стенки"/>
<measurement id="430" comment="Диаметр общего желчного протока"/>
<anatomy-comment comment-id="171" comment-type="comment" comment="Комментарий желчный"/>
Второй способ: указать тег measurement-group с нужными атрибутами и внутри уточнить некоторые атрибуты тегов измерений или добавить тег с текстом. Например, в шаблоне УЗИ БЦА для отображения информации для общей сонной артерии используется следующий код:
Часть шаблона УЗИ БЦА
<line comment="Правый-левый">
<text text-label=" " />
<text text-label="справа" max-width="197" is-color-selection="true" />
<text text-label="слева" max-width="197" is-color-selection="true" />
</line>
<anatomy id="261" font-size="10" font-bold="true" font-underline="false" comment="Общая сонная артерия" />
<measurement-group id="11" multi-interval="true" comment="Общая сонная артерия: Скорость кровотока">
<measurement id="609" unit-width="19" max-width="295" measurement-name="Скорость кровотока (Vps)" comment="справа" />
<measurement id="606" unit-width="19" empty-name="true" comment="слева" />
</measurement-group>
<measurement-group id="12" multi-interval="true" comment="Общая сонная артерия: Диаметр артерии">
<measurement id="610" unit-width="19" max-width="295" measurement-name="Диаметр артерии" comment="справа" />
<measurement id="607" unit-width="19" empty-name="true" comment="слева" />
</measurement-group>
Для визуализации надписи «справа-слева» задействован уже знакомый тег text и новый line, который будет расшифрован ниже.
В любом правиле всегда можно найти исключение. Так же и получилось с артериальным давлением. Это именно та группа измерений, которая определила новый способ отображения групп: величины измерений пишутся через слеш, а референсные интервалы расположены рядом друг с другом:
<measurement id="1577" max-width="247" need-points-to-end="false" measurement-name="Тоны сердца" />
<measurement-group id="81" show-through-slash="true" multi-interval="true">
<measurement id="1581" unit-width="27" measurement-name="Артериальное давление" comment="Систолическое артериальное давление" />
<measurement id="1582" unit-width="27" max-width="190" empty-name="true" comment="Диастолическое артериальное давление" />
</measurement-group>
<measurement id="1621" comment="Частота пульса" />
Line
Все элементы внутри этого тега расположены в одну линию. Основное отличие тега line от measurement-group состоит в том, что line визуально объединяет никак не связанные друг с другом данные. Внутри могут находиться теги anatomy, measurement и text. Тег использует атрибуты is-color-selection и multi-interval, поведение которых соответствует аналогичным атрибутам в measurement-group.
Например, в шаблоне КТ головного мозга можно встретить следующие измерения:
Часть шаблона КТ головного мозга
<line>
<measurement id="2801" measurement-name="Боковой желудочек правый" />
<measurement id="2782" measurement-name="Боковой желудочек левый" />
<measurement id="2781" max-width="145" measurement-name="Расположение" comment="Расположение боковых желудочков"/>
</line>
<line>
<measurement id="2762" measurement-name="Третий желудочек" />
<measurement id="2763" measurement-name="Четвертый желудочек" />
<measurement id="2764" max-width="145" measurement-name="Турецкое седло" />
</line>
<line>
<measurement id="2743" measurement-name="Супраселлярная цистерна" />
<text max-width="247" text-label=" " />
</line>
<line>
<measurement id="2803" max-width="169" measurement-name="Мозжечок" />
<measurement id="2767" value-width="148" comment="Расположение миндалин мозжечка"/>
</line>
<line>
<measurement id="2821" measurement-name="Придаточные пазухи носа" />
<measurement id="2841" measurement-name="Пирамиды височных костей" />
</line>
Что ж осталось еще несколько тегов, но давайте перейдём к лирике, а после к сухому описанию оставшегося «добра».
Каждый шаблон привязан к определенному прайсу (услуге). Все прайсы, в свою очередь, распределены между прайс-группами. Последние уже входят в какие-либо модальности. Например:
- шейный отдел позвоночника (услуга) – шея (прайс-группа) – магнитно-резонансная томография [МРТ] (модальность);
- шейный отдел позвоночника (услуга) – шея (прайс-группа) – компьютерная томография [КТ] (модальность);
- консультация врача-терапевта (услуга) – терапия (прайс-группа) – консультации и манипуляции [КМ] (модальность);
- почки и надпочечники (услуга) – брюшная полость (прайс-группа) – ультразвуковое исследование [УЗИ] (модальность).
Если рассматривать прайс подробнее, то для него можно выделить следующие типы:
- основной;
- дополнительный;
- анализ.
Дополнительные услуги и анализы всегда связаны с основными и не могут быть оплачены и выполнены отдельно от них. В целом, введение дополнительных услуг в рамках основной услуги не только увеличивает количество получаемой во время обследования информации (актуально для исследований, проводимых на различном оборудовании), но и позволяет легко ввести в МИС понятие первичных и повторных приёмов врача-специалиста.
Рассмотрим приём к терапевту. Если перевести идею первичного приёма на язык прайсов, получим, что этот приём состоит из прайсов консультации врача-терапевта (основной прайс) и осмотра врача-терапевта (доп. прайс). Тем временем повторный приём представляет собой только прайс консультации. Аналогично для остальных специалистов. Такой подход разделения приёма на два отдельных прайса позволяет выдавать пациенту заключение только с необходимой информацией.
При генерации протокола исследования учитывается актуальная версия шаблона, которая привязана к текущему основному прайсу. Если пациент оплачивает, к примеру, услугу «УЗИ поджелудочная железа» или «консультация врача-терапевта», то вопросы при его отображении врачу не возникают. Но что делать, если оплачена не только консультация врача-терапевта, но и осмотр? Каким же образом добавить шаблон, привязанный к осмотру врача?
Не менее интересным занятием оказывается и отображение протокола исследования для лабораторной диагностики (ЛД), где используется отличный от дополнительных прайсов подход. Именно поэтому для анализов был выделен отдельный тип прайсов. Каждый основной прайс ЛД (исследование мазка/соскоба, исследование мочи и т. п.) в данном случае служит для объединения нескольких прайсов с типом «анализ», относящихся к разными прайс-группами, в единое целое. В результате для каждого основного прайса выдается только один протокол исследования независимо от количества оплаченных анализов. Если было заказано, к примеру, несколько анализов крови (основной прайс – исследование крови) и урологический мазок (основной прайс – исследование мазка/соскоба), то будет выдано два заключения.
Нельзя забывать и о том, что некоторые места в разных шаблонах могут дублироваться, или шаблон банально очень большой, и в нём трудно ориентироваться. Например, набор измерений для правой и левой миндалин встречаются в осмотрах врача-терапевта, врача-эндокринолога, врача-пульмонолога и т. п.
Таким образом, возникает необходимость, во-первых, в выделении фрагмента XML кода в отдельный шаблон и его последующем добавлении в специальное место, и, во-вторых, в присоединении к основному шаблону шаблонов оплаченных дополнительных прайсов или анализов. Для этих задач нам понадобятся оставшиеся три тега.
Наверняка возник вопрос: зачем использовать какие-то специальные теги, когда можно просто добавить один шаблон в конец другого, получив при этом своеобразный локомотив с вагонами? Да, существует и такой путь. Однако, система шаблонов должна быть гибкой и иметь возможность для вставки разных шаблонов в то место, которое нам нужно, соблюдая при этом определённый порядок.
Template-builder
Используется в качестве ссылки на другой шаблон. В атрибуте id указывается номер вставляемого шаблона.
В качестве примера приведем шаблоны правой и левой миндалин, которые используются в шаблоне осмотра специалистов.
Шаблон правой миндалины
<template>
<line>
<anatomy id="524" font-size="10" font-bold="true" font-underline="false" comment="Правая миндалина" />
<measurement id="1542" max-width="112" empty-name="true" comment="окраска Правая миндалина" />
<measurement id="1543" max-width="161" empty-name="true" comment="размеры Правая миндалина" />
</line>
<line>
<measurement id="1550" measurement-name="Структура" comment="структура правой миндалины" />
<measurement id="1551" measurement-name="Поверхность" comment="поверхность правой миндалины" />
<measurement id="1552" measurement-name="Лакуны" comment="лакуны правой миндалины" />
</line>
</template>
Шаблон левой миндалины
<template>
<line>
<anatomy id="525" font-size="10" font-bold="true" font-underline="false" comment="левая миндалина" />
<measurement id="1554" max-width="112" empty-name="true" comment="окраска левой миндалины" />
<measurement id="1555" max-width="161" empty-name="true" comment="размеры левой миндалины" />
</line>
<line>
<measurement id="1556" measurement-name="Структура" comment="структура левой миндалины" />
<measurement id="1557" measurement-name="Поверхность" comment="поверхность левой миндалины" />
<measurement id="1558" measurement-name="Лакуны" comment="лакуны левой миндалины" />
</line>
</template>
Часть шаблона осмотра специалиста, где шаблон с номером 516 – для правой миндалины, а 517 – для левой миндалины:
<template-builder id="516"/>
<anatomy-comment comment-id="372" comment-type="comment" comment="Комментарий к правой миндалине" />
<template-builder id="517"/>
<anatomy-comment comment-id="373" comment-type="comment" comment="Комментарий к левой миндалине" />
Price-template-builder
Обозначает вставку шаблона, наличие которого зависит от оплаты. Например, осмотр врача, различные анализы. Содержит только один атрибут id, где прописывается номер шаблона.
Шаблон консультации врача-терапевта:
<template>
<price-template-builder id="336"/>
<anatomy-comment comment-id="370" comment-type="comment" comment="Комментарий для тела" />
<conclusion-label spacing-before="HALF"/>
<anatomy-comment comment-id="371" comment-type="conclusion" comment="Заключение для тела" />
</template>
Шаблон осмотра врача-терапевта
<template>
<anatomy-comment comment-id="358" comment-type="complaint" comment="Комментарий жалобы" />
<measurement id="8541" comment="Температура тела" />
<line>
<measurement id="1521" measurement-name="Зев" comment="состояние Зева" />
<measurement id="1559" measurement-name="Язык" comment="состояние языка" />
<measurement id="1560" empty-name="true" comment="влажность языка" />
</line>
<template-builder id="516"/>
<anatomy-comment comment-id="372" comment-type="comment" comment="Комментарий к правой миндалине" />
<template-builder id="517"/>
<anatomy-comment comment-id="373" comment-type="comment" comment="Комментарий к левой миндалине" />
<line>
<measurement id="1181" comment="Кожные покровы" />
<measurement id="1182" measurement-name="Живот" comment="состояние живота" />
<measurement id="1183" empty-name="true" comment="болезненность живота" />
</line>
<line>
<measurement id="1561" max-width="247" measurement-name="Печень" comment="пальпация печени" />
<measurement id="1562" measurement-name="Край печени" comment="пальпация края печени" />
<measurement id="1563" max-width="70" empty-name="true" comment="болезненность края печени" />
</line>
<line>
<measurement id="1564" measurement-name="Правая почка" comment="пальпация правой почки" />
<measurement id="1565" empty-name="true" comment="болезненность правой почки" />
<measurement id="1566" empty-name="true" comment="симптом Пастернацкого правой почки" />
</line>
<line>
<measurement id="1567" measurement-name="Левая почка" comment="пальпация левой почки" />
<measurement id="1568" empty-name="true" comment="болезненность левой почки" />
<measurement id="1569" empty-name="true" comment="симптом Пастернацкого левой почки" />
</line>
<line>
<measurement id="1570" measurement-name="Лимфатические узлы" comment="состояние Лимфатические узлы" />
<measurement id="1571" empty-name="true" comment="болезненность Лимфатические узлы" />
<measurement id="1572" comment="Суставы"/>
</line>
<measurement id="1153" max-width="247" need-points-to-end="false" comment="Расположение молочных желез"/>
<line>
<measurement id="1573" measurement-name="Дыхание в легких" />
<measurement id="1574" comment="Перкуторный звук в легких" />
</line>
<measurement id="1575" comment="Частота дыхания" />
<measurement id="1576" comment="Скорость выдыхаемого воздуха" />
<measurement id="1577" max-width="247" need-points-to-end="false" measurement-name="Тоны сердца" />
<measurement-group id="81" show-through-slash="true" multi-interval="true" is-color-selection="false">
<measurement id="1581" unit-width="27" measurement-name="Артериальное давление" comment="Систолическое артериальное давление" />
<measurement id="1582" unit-width="27" max-width="190" empty-name="true" comment="Диастолическое артериальное давление" />
</measurement-group>
<line>
<measurement id="1578" measurement-name="Пульс" comment="ритмичность пульса" />
<measurement id="1579" empty-name="true" comment="наполнение пульса" />
<measurement id="1580" empty-name="true" comment="напряжение пульса" />
</line>
<measurement id="1621" comment="Частота пульса" />
<measurement id="1583" comment="Степень насыщения крови кислородом" />
<measurement id="1587" comment="Глюкоза (глюкометрия)" />
<line>
<measurement id="1584" max-width="247" comment="Характер стула" />
<measurement id="1585" comment="Характер мочеиспускания" />
<measurement id="1586" max-width="70" empty-name="true" comment="болезненность мочеиспускания" />
</line>
</template>
Price-group
Используется для отображения прайс-группы в шаблонах анализов. Может содержать тег price-template-builder. Атрибуты:
- id – номер прайс-группы из БД;
- bgcolor – цвет фона;
- fgcolor – цвет текста.
Рассмотрим протокол исследования крови для оплаченных прайсов липидный статус, аспартатаминотрансфераза (АсАТ), аланинаминотрансфераза (АлАТ), тестостерон общий, эстрадиол, пролактин, соматотропный гормон (СТГ).
Часть шаблона исследования крови
<template>
<price-group id="9" bgcolor="#E18C8E" fgcolor="#FFFFFF">
<price-template-builder id="368"/>
<price-template-builder id="369"/>
<price-template-builder id="370"/>
<price-template-builder id="371"/>
<price-template-builder id="372"/>
<price-template-builder id="373"/>
<price-template-builder id="374"/>
<price-template-builder id="375"/>
<price-template-builder id="379"/>
</price-group>
<price-group id="10" bgcolor="#E18C8E" fgcolor="#FFFFFF">
<price-template-builder id="380"/>
<price-template-builder id="381"/>
<price-template-builder id="382"/>
<price-template-builder id="383"/>
<price-template-builder id="384"/>
<price-template-builder id="385"/>
<price-template-builder id="716"/>
<price-template-builder id="717"/>
</price-group>
<price-group id="17" bgcolor="#E18C8E" fgcolor="#FFFFFF">
<price-template-builder id="425"/>
<price-template-builder id="426"/>
<price-template-builder id="427"/>
<price-template-builder id="428"/>
<price-template-builder id="429"/>
<price-template-builder id="430"/>
<price-template-builder id="431"/>
<price-template-builder id="432"/>
</price-group>
<price-group id="31" bgcolor="#E18C8E" fgcolor="#FFFFFF">
<price-template-builder id="445"/>
<price-template-builder id="446"/>
</price-group>
<anatomy-comment comment-id="6"/>
</template>
Шаблон для липидного статуса (номер в базе – 379):
<template>
<measurement id="36" comment="Триглицериды"/>
<measurement id="37" comment="Холестерин общий"/>
<measurement id="38" comment="Холестерин липопротеинов высокой плотности (ЛПВП)"/>
<measurement id="39" comment="Холестерин липопротеинов низкой плотности (ЛПНП)"/>
<measurement id="40" comment="Холестерин липопротеинов очень низкой плотности (ЛПО"/>
<measurement id="41" comment="Индекс атерогенности"/>
</template>
Шаблон для аланинаминотрансфераза (АлАТ) (номер в базе – 381):
<template>
<measurement id="43" comment="Аланинаминотрансфераза (АлАТ)"/>
</template>
В системе присутствует пара атрибутов, которые можно встретить во всех тегах:
- comment – игнорируется системой и выступает в качестве пометки для разработчика;
- spacing-before – дополнительное расстояние между строками. Возможные варианты: NONE, HALF, FULL. По умолчанию – NONE;
- is-short – указывает на тип строки: обычная (false) или короткая (true). По умолчанию стоит false.
При помощи атрибута is-short можно сделать протокол исследования, где основная картинка расположена слева, а различные измерения и группы измерений – справа. Одним из таких заключений является УЗИ щитовидной железы, шаблон которой приведен ниже:
Шаблон УЗИ щитовидной железы
<template image-id="5" need-warning="true" image-position="left-top-corner">
<anatomy id="22" font-size="10" font-bold="true" font-underline="false" is-short="true" comment="Щитовидная железа"/>
<line is-short="true" spacing-before="HALF">
<measurement id="310" max-width="156" comment="Эхоструктура"/>
<measurement id="341" max-width="156" comment="Эхогенность"/>
</line>
<line is-short="true">
<measurement id="308" max-width="156" comment="Расположение"/>
<measurement id="342" max-width="156" comment="Контуры"/>
</line>
<template-builder id="253" is-short="true"/>
<template-builder id="254" is-short="true"/>
<measurement id="307" is-short="true" measurement-name="Толщина перешейка" spacing-before="HALF" />
<measurement id="309" measurement-name="Объем долей щитовидной железы" />
<anatomy-comment comment-id="9" comment-type="comment" spacing-before="HALF" />
<conclusion-label spacing-before="HALF"/>
<anatomy-comment comment-id="8" comment-type="conclusion" />
</template>
Шаблон правой доли:
<template>
<anatomy id="24" font-size="10" font-bold="true" font-underline="false" spacing-before="HALF" is-short="true" comment="Правая доля"/>
<measurement-group id="2" is-color-selection="true" is-short="true"/>
</template>
Шаблон левой доли:
<template>
<anatomy id="23" font-size="10" font-bold="true" font-underline="false" spacing-before="HALF" is-short="true" comment="Левая доля"/>
<measurement-group id="1" is-color-selection="true" is-short="true"/>
</template>
Мы уже упоминали, что с человеком с течение жизни происходят различные метаморфозы. Оставшиеся теги как раз предназначены для их описания, и они будут рассмотрены в следующий раз.