QA计划整理工具,
用于将Elekta Monaco导出的Patient QA计划,按照不同患者整理到各自文件夹里面。
可以尝试使用auto-py-to-exe打包,注意在advance选项里面添加submodule:pydicom。
import os
import shutil
import pydicom
import tkinter as tk
from tkinter import filedialog, messagebox
def create_patient_folder(rt_plan_file, rt_dose_file, base_folder, patient_folders):
ds_plan = pydicom.dcmread(rt_plan_file, force=True)
# ds_dose = pydicom.dcmread(rt_dose_file, force=True)
patient_id = ds_plan.PatientID
patient_name = ds_plan.PatientName
rt_plan_description = ds_plan.RTPlanDescription
total_mu = round(sum(beam.BeamMeterset for beam in ds_plan.FractionGroupSequence[0].ReferencedBeamSequence))
folder_name = f"{rt_plan_description}_{patient_id}_{patient_name}_MU_{total_mu}"
patient_folder = os.path.join(base_folder, folder_name)
if not os.path.exists(patient_folder):
os.makedirs(patient_folder)
shutil.move(rt_plan_file, os.path.join(patient_folder, os.path.basename(rt_plan_file)))
shutil.move(rt_dose_file, os.path.join(patient_folder, os.path.basename(rt_dose_file)))
patient_folders.append(folder_name)
def organize_files(base_folder):
rt_plan_files = []
rt_dose_files = []
patient_folders = []
for file in os.listdir(base_folder):
file_path = os.path.join(base_folder, file)
if file_path.endswith('.dcm'):
ds = pydicom.dcmread(file_path, force=True)
if ds.Modality == 'RTPLAN':
rt_plan_files.append(file_path)
elif ds.Modality == 'RTDOSE':
rt_dose_files.append(file_path)
for rt_plan_file in rt_plan_files:
ds_plan = pydicom.dcmread(rt_plan_file, force=True)
corresponding_dose_file = None
for rt_dose_file in rt_dose_files:
ds_dose = pydicom.dcmread(rt_dose_file, force=True)
if ds_plan.PatientID == ds_dose.PatientID:
corresponding_dose_file = rt_dose_file
break
if corresponding_dose_file:
create_patient_folder(rt_plan_file, corresponding_dose_file, base_folder, patient_folders)
rt_dose_files.remove(corresponding_dose_file)
messagebox.showinfo("完成", "文件处理完成。")
def select_folder():
folder_selected = filedialog.askdirectory()
if folder_selected:
folder_path.set(folder_selected)
def start_processing():
base_folder = folder_path.get()
if os.path.exists(base_folder):
organize_files(base_folder)
else:
messagebox.showerror("错误", "请选择一个有效的文件夹路径")
# 创建图形界面
root = tk.Tk()
root.title("DCM 文件整理工具")
folder_path = tk.StringVar()
frame = tk.Frame(root)
frame.pack(pady=10)
folder_label = tk.Label(frame, text="文件夹路径:")
folder_label.grid(row=0, column=0, padx=5, pady=5)
folder_entry = tk.Entry(frame, textvariable=folder_path, width=50)
folder_entry.grid(row=0, column=1, padx=5, pady=5)
select_button = tk.Button(frame, text="选择文件夹", command=select_folder)
select_button.grid(row=0, column=2, padx=5, pady=5)
start_button = tk.Button(root, text="开始处理", command=start_processing)
start_button.pack(pady=10)
close_button = tk.Button(root, text="关闭", command=root.quit)
close_button.pack(pady=10)
root.mainloop()