Показаны различия между двумя версиями страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
converterdicom [2021/04/27 04:25] sector |
converterdicom [2023/01/29 05:35] sector |
||
---|---|---|---|
Строка 1: | Строка 1: | ||
- | ====== Меняем кодировку в DICOM и конвертируем кириллицу в латиницу. ====== | + | ====== Меняем кодировку в DICOM и конвертируем кириллицу в латиницу, пишем в базу и отправляем в ORTHANC. ====== |
Есть у нас рентген аппарат у которого в xml файле написана кодировка ISO-8859-5, а русские символы в Windows-1251. | Есть у нас рентген аппарат у которого в xml файле написана кодировка ISO-8859-5, а русские символы в Windows-1251. | ||
- | Изменим тег с кодировкой и конвертируем кириkлицу в латиницу с помощью python и отправим это все дело в ORTHANC. | + | Изменим тег с кодировкой и конвертируем кириллицу в латиницу с помощью python и отправим это все дело в ORTHANC. |
+ | |||
+ | [[https:// | ||
+ | === Создадим базу данных: | ||
- | ОСТОРОЖНО ! ГОВНОКОД ! | + | <code | INI> |
+ | -- phpMyAdmin SQL Dump | ||
+ | -- version 5.0.4deb2 | ||
+ | -- https:// | ||
+ | -- | ||
+ | -- Хост: localhost: | ||
+ | -- Время создания: | ||
+ | -- Версия сервера: | ||
+ | -- Версия PHP: 7.4.28 | ||
+ | |||
+ | SET SQL_MODE = " | ||
+ | START TRANSACTION; | ||
+ | SET time_zone = " | ||
+ | |||
+ | |||
+ | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; | ||
+ | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; | ||
+ | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; | ||
+ | /*!40101 SET NAMES utf8mb4 */; | ||
+ | |||
+ | -- | ||
+ | -- База данных: | ||
+ | -- | ||
+ | |||
+ | -- -------------------------------------------------------- | ||
+ | |||
+ | -- | ||
+ | -- Структура таблицы `DicomSend` | ||
+ | -- | ||
+ | |||
+ | CREATE TABLE `DicomSend` ( | ||
+ | `id` int(11) NOT NULL, | ||
+ | `FileName` text NOT NULL, | ||
+ | `SendDate` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), | ||
+ | `PatientName` text NOT NULL | ||
+ | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; | ||
+ | |||
+ | -- | ||
+ | -- Индексы сохранённых таблиц | ||
+ | -- | ||
+ | |||
+ | -- | ||
+ | -- Индексы таблицы `DicomSend` | ||
+ | -- | ||
+ | ALTER TABLE `DicomSend` | ||
+ | ADD PRIMARY KEY (`id`); | ||
+ | |||
+ | -- | ||
+ | -- AUTO_INCREMENT для сохранённых таблиц | ||
+ | -- | ||
+ | |||
+ | -- | ||
+ | -- AUTO_INCREMENT для таблицы `DicomSend` | ||
+ | -- | ||
+ | ALTER TABLE `DicomSend` | ||
+ | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, | ||
+ | COMMIT; | ||
+ | |||
+ | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; | ||
+ | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; | ||
+ | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; | ||
+ | |||
+ | </ | ||
+ | |||
+ | === Подключимся к базе: === | ||
<code | INI> | <code | INI> | ||
- | # -*- coding: utf-8 -*- | + | cat connector.py |
+ | |||
+ | import mysql.connector | ||
+ | cnx = mysql.connector.connect(user=' | ||
+ | host=' | ||
+ | database=' | ||
+ | use_pure=False) | ||
+ | </ | ||
+ | |||
+ | === Сам скрипт конвертации и отправки: === | ||
+ | |||
+ | <code | INI> | ||
+ | |||
+ | cat dicomSend.py | ||
import glob | import glob | ||
import subprocess | import subprocess | ||
import os | import os | ||
import signal | import signal | ||
- | import fileinput | ||
import sys | import sys | ||
import time | import time | ||
- | import | + | import |
- | reload(sys) | + | import connector |
- | sys.setdefaultencoding(' | + | import transliterate |
- | path="/ | ||
- | for filepath in glob.iglob(path+'*.[dD][cC][mM]'): | + | server = '192.168.1.43 4242' |
+ | fileList = open("/ | ||
- | a=filepath | + | from datetime import datetime |
- | b=a.split('/' | + | now= datetime.now() |
- | c=subprocess.Popen(" | + | while True: |
- | c.communicate() | + | lineFileList |
+ | if not lineFileList: | ||
+ | break | ||
+ | filePath=lineFileList.strip() | ||
+ | | ||
- | def replaceAll(file, | + | cursor = connector.cnx.cursor() |
- | | + | |
- | if searchExp in line: | + | |
- | line = line.replace(searchExp,replaceExp) | + | row = cursor.fetchone() |
- | | + | |
- | replaceAll(filepath + " | + | if row == None: |
- | fullpathxml | + | dcmToXml=subprocess.Popen(" |
+ | dcmToXml.communicate() | ||
+ | fin = open(filePath + " | ||
+ | fout = open(filePath +" | ||
+ | for line in fin: | ||
+ | fout.write( line.replace('ISO-8859-5', | ||
+ | fin.close() | ||
+ | fout.close() | ||
- | import | + | fullpathxml = filePath +'.xml.mod' |
- | tree = ET.parse(fullpathxml) | + | |
- | PatientName=tree.findall(' | + | import xml.etree.ElementTree as ET |
- | | + | |
- | if BodyPE: | + | |
- | BodyPE=BodyPE | + | |
- | else: | + | |
- | BodyPE=" | + | |
- | ViewPos=tree.findall(' | + | PatientName=tree.findall(' |
- | if ViewPos: | + | if PatientName: |
- | | + | |
- | else: | + | else: |
- | | + | |
- | PatientNameTrans= transliterate.transliterate(PatientName) | + | tree.findall(' |
- | BodyPETrans= transliterate.transliterate(BodyPE) | + | |
- | ViewPosTrans= transliterate.transliterate(ViewPos) | + | |
- | PatientNameClean=tree.findall(' | + | BodyPE=tree.findall(' |
- | | + | if BodyPE: |
- | | + | BodyPETrans=transliterate.transliterate(BodyPE) |
+ | | ||
+ | BodyPETrans=" | ||
+ | |||
+ | | ||
+ | |||
+ | try: | ||
+ | ViewPos=tree.findall(' | ||
+ | ViewPosTrans=transliterate.transliterate(ViewPos) | ||
+ | except: | ||
+ | | ||
+ | |||
+ | tree.findall(' | ||
+ | |||
+ | tree.write(fullpathxml) | ||
+ | |||
+ | xmlToDcm=subprocess.Popen(" | ||
+ | xmlToDcm.communicate() | ||
+ | |||
+ | dcmSend=subprocess.Popen(" | ||
+ | data=dcmSend.communicate() | ||
+ | for line in data: | ||
+ | if line: | ||
+ | line = line.strip() | ||
+ | line=line.split(':' | ||
+ | if line==' | ||
+ | cursor = connector.cnx.cursor() | ||
+ | insert_query=(f" | ||
+ | cursor.execute(insert_query, | ||
+ | connector.cnx.commit() | ||
+ | fullpath='/' | ||
+ | for xmlpath in glob.iglob(os.path.join(fullpath, | ||
+ | os.remove(xmlpath) | ||
+ | for modpath in glob.iglob(os.path.join(fullpath, | ||
+ | os.remove(modpath) | ||
+ | for moddcmpath in glob.iglob(os.path.join(fullpath, | ||
+ | os.remove(moddcmpath) | ||
+ | else: | ||
+ | print(' | ||
+ | else: | ||
+ | print(' | ||
+ | |||
+ | </ | ||
+ | |||
+ | === Скрипт в крон для запуска конвертера: | ||
+ | |||
+ | * Проверяем, | ||
+ | * синхронизируем хранилище сервера с рабочей станцией мед. оборудования (на рабочих станциях хранилища со снимками у меня расшарены, | ||
+ | * создаем файл со списком изображений. | ||
+ | * пишем лог. | ||
+ | |||
+ | <code | INI> | ||
+ | |||
+ | # | ||
+ | |||
+ | #!/bin/sh | ||
+ | if ps -ef | grep -v grep | grep dicomSend.py ; then | ||
+ | rsync -azvp --exclude 2020/ --exclude test.txt --exclude *.tgz / | ||
+ | rsync -azvp --exclude 2020/ --exclude test.txt --exclude *.tgz / | ||
+ | exit 0 | ||
+ | else | ||
+ | rsync -azvp --exclude 2020/ --exclude test.txt --exclude *.tgz / | ||
+ | rsync -azvp --exclude 2020/ --exclude test.txt --exclude *.tgz / | ||
+ | find / | ||
+ | python / | ||
+ | exit 0 | ||
+ | fi | ||
+ | |||
+ | </ | ||
+ | |||
+ | === Транслитерация: | ||
+ | |||
+ | <code | INI> | ||
+ | cat transliterate.py | ||
+ | |||
+ | # -*- coding: utf-8 -*- | ||
- | tree.write(fullpathxml) | + | def transliterate(name): |
+ | """ | ||
+ | | ||
+ | | ||
+ | Не претендую на " | ||
+ | вы всегда сможете добавить свои символы и даже слова. Только | ||
+ | | ||
+ | """ | ||
+ | # Слоаврь с заменами | ||
+ | | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ':':'',';':'','<':'','>':'',' | ||
+ | ' | ||
+ | ' | ||
- | d=subprocess.Popen(" | + | # Циклически заменяем все буквы в строке |
- | time.sleep(5) | + | |
- | | + | name = name.replace(key, slovar[key]) |
- | time.sleep(5) | + | return name |
- | e.communicate() | + | |
- | os.remove(filepath) | + | |
- | | + | |
- | os.remove(xmlpath) | + | |
- | for modpath in glob.iglob(os.path.join(path, | + | |
</ | </ |