2024-07-12

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()

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 打卡每日提升流程进度: 1000-359 1.睡前安宁/午间静谧/清晨唤醒(理想方向3+2)U辅助系统 2.二十年...
    番茄打卡阅读 41评论 0 1
  • 《绿茵梦想》 第一章:初次登场 在城市的边缘,有一片不起眼的足球场,那里是年轻人们挥洒汗水和梦想的地方。每到周末,...
    少年_66a9阅读 55评论 0 0
  • 《绿茵梦想》 第一章:初次登场 在城市的边缘,有一片不起眼的足球场,那里是年轻人们挥洒汗水和梦想的地方。每到周末,...
    少年_66a9阅读 61评论 0 0
  • 昨天孩子放暑假了,我不用再每天监督孩子的作业,现在应该又要把日程中每天的事项优化一下,一些没有完成的课程和笔记在这...
    桂亘阅读 67评论 0 1
  • 请大家继续按第二周共修主题梳理自己过往的人生!感受自己生活的平衡轮 1、请描述你平衡轮的状况,如果以前没有画过,就...
    薛小丫520阅读 28评论 0 0