dcm4chee の pacsdb から必要なデータだけを sqlite3 へ

自作の pacs もどきのプログラムを動かすのに、これまでは dicom ファイルのタグ情報を読み込んで mysql に記録してきましたが、dcm4chee の pacsdb というテーブルのデータを利用するのが一番簡単であると思うので、その中で必要なものだけを抽出して sqlite 3 に書き込んでみました。

必要な情報はどれか?

6年ほど前に pacsdb を分析して、いろいろなクエリを作成したことがあります。

カルテ番号で検査一覧


SELECT study.pk, study_datetime, patient.pat_id, pat_name, pat_birthdate, pat_sex, mods_in_study, study_desc
FROM study INNER JOIN patient 
ON study.patient_fk = patient.pk
WHERE pat_id = '8901573'

日付で検査一覧


SELECT study.pk, study_datetime, patient.pat_id, pat_name, pat_birthdate, pat_sex, mods_in_study, study_desc
FROM study INNER JOIN patient 
ON study.patient_fk = patient.pk
WHERE DATE_FORMAT(study_datetime, '%Y-%m-%d') = '2013-09-13'

study の pk から Dicom ファイルを抽出


SELECT filepath 
FROM files 
WHERE instance_fk IN 
    (SELECT pk FROM instance WHERE series_fk IN 
        (SELECT pk FROM series WHERE study_fk = 'study.pk')
    )

以上から必要な情報は以下のようになります。

テーブル名
filesfilepatd, instance_fk
filesystempk, dirpatd
instancepk, series_fk
patientpk, pat_id, pat_name, pat_birtddate, pat_sex
seriespk, study_fk
studypk, patient_fk, study_id, study_datetime, study_desc, mods_in_study

sqlite 3 作成

mypacs.sql3 という sqlite 3 ファイルを作成して以下の sql を実行し、各テーブルを作成します。


CREATE TABLE "files" (
	"filepath"	TEXT,
	"instance_fk"	TEXT,
	PRIMARY KEY("filepath")
);
CREATE TABLE "filesystem" (
	"pk"	INTEGER,
	"dirpath"	TEXT,
	PRIMARY KEY("pk")
);
CREATE TABLE "instance" (
	"pk"	INTEGER,
	"series_fk"	INTEGER,
	PRIMARY KEY("pk")
);
CREATE TABLE "patient" (
	"pk"	INTEGER,
	"pat_id"	TEXT,
	"pat_name"	TEXT,
	"pat_birthdate"	TEXT,
	"pat_sex"	TEXT,
	PRIMARY KEY("pk")
);
CREATE TABLE "series" (
	"pk"	INTEGER,
	"study_fk"	INTEGER,
	PRIMARY KEY("pk")
);
CREATE TABLE "study" (
	"pk"	INTEGER,
	"patient_fk"	INTEGER,
	"study_id"	TEXT,
	"study_datetime"	TEXT,
	"study_desc"	TEXT,
	"mods_in_study"	TEXT,
	PRIMARY KEY("pk")
);

必要なデータを sqlite 3 に書き込む python

msql_sqlite.py

import sqlite3
import pymysql

class MySQL_sqlite():
    
    def __init__( self ):    

        self.host = 'localhost'
        self.user = 'root'
        self.password = 'pass'
        self.db = 'pacsdb'
               
    def read_data( self, sql ):
        conn = pymysql.connect(host=self.host,
            user=self.user,
            db=self.db,
            password=self.password,
            cursorclass=pymysql.cursors.DictCursor)
        try:
            with conn.cursor() as cursor:
                cursor.execute(sql)
                res = cursor.fetchall()       
                datas = self.list_change(res)
                return datas
        finally:
            conn.close()

    def insert_data( self, sql, datas ):
        conn = sqlite3.connect('/home/user/mypacs.sql3')
        cur = conn.cursor()
        cur.executemany(sql , datas)
        conn.commit()
        conn.close()

    def list_change(self, allinfo ):
        datas = []
        for infos in allinfo:
            el = []
            for v in infos.values():
                el.append(v)
            datas.append(el)
        return datas 

if __name__ == "__main__":   
    
    readsql = []
    insertsql = []
    readsql.append("SELECT pk, pat_id, pat_name, pat_birthdate, pat_sex FROM patient;")
    readsql.append("SELECT pk, patient_fk, study_id, study_datetime, study_desc, mods_in_study FROM study;")
    readsql.append("SELECT pk, study_fk FROM series;")
    readsql.append("SELECT pk, series_fk FROM instance;")
    readsql.append("SELECT filepath, instance_fk FROM files;")
    readsql.append("SELECT pk, dirpath FROM filesystem;")
    
    insertsql.append("replace into patient ( pk, pat_id, pat_name, pat_birthdate, pat_sex ) VALUES ( ?,?,?,?,? )" )
    insertsql.append("replace into study ( pk, patient_fk, study_id, study_datetime, study_desc, mods_in_study ) VALUES ( ?, ?, ?, ?, ?, ? )")
    insertsql.append("replace into series ( pk, study_fk ) VALUES ( ?, ? )")
    insertsql.append("replace into instance ( pk, series_fk ) VALUES ( ?, ? )" )
    insertsql.append("replace into files ( filepath, instance_fk ) VALUES ( ?, ? )" )    
    insertsql.append("replace into filesystem ( pk, dirpath ) VALUES ( ?, ? )" ) 
 
    msql = MySQL_sqlite()
    for k in range(0, len(readsql)):
        infos = msql.read_data( readsql[k] )
        msql.insert_data(insertsql[k], infos)

sqlite 3 のサイズは pacsdb をエクスポートしたダンプファイルの10分の1になります。

確認

sqlite 3 上で以下のクエリを実行します。


SELECT filepath 
FROM files 
WHERE instance_fk IN 
    (SELECT pk FROM instance WHERE series_fk IN 
        (SELECT pk FROM series WHERE study_fk = 2)
    )