Files
dicom_utilities/analyize_discovery.py
john a01fe8a35c Update analyize_discovery.py
 New Features

    Graphical file selectors for both:

        Choosing the discovery output file

        Choosing the name and location of the analysis output file

    Output saved to a text file formatted for easy copy/paste into Excel

    Tab-separated values in the summary for compatibility with Excel columns

    Modality breakdown + exam statistics in one concise report

📝 How to Use It

    Save the code below as dicom_analysis_tool.py.

    Run it (python dicom_analysis_tool.py or double-click if .py is registered).

    Click the button to:

        Select the discovery results .txt file.

        Specify the output .txt destination.

    It will create a text summary that can be easily opened in Excel (tab-delimited).
2025-05-16 13:52:44 +00:00

84 lines
3.3 KiB
Python

import tkinter as tk
from tkinter import filedialog, simpledialog
import pandas as pd
import os
def normalize_modalities(val):
if val.startswith("[") and val.endswith("]"):
try:
return ", ".join(eval(val))
except:
return val
return val
def analyze_and_save():
input_path = filedialog.askopenfilename(
title="Select DICOM Discovery Output File",
filetypes=[("Text Files", "*.txt")]
)
if not input_path:
return
output_path = filedialog.asksaveasfilename(
title="Save Analysis Output As",
defaultextension=".txt",
filetypes=[("Text Files", "*.txt")]
)
if not output_path:
return
df = pd.read_csv(input_path, delimiter='|', dtype=str).fillna('')
df['ModalitiesInStudy'] = df['ModalitiesInStudy'].apply(normalize_modalities)
stats = {
"Distinct StudyInstanceUIDs": df['StudyInstanceUID'].nunique(),
"Distinct AccessionNumbers": df['AccessionNumber'].nunique(),
"AccessionNumbers with 2 StudyInstanceUIDs": (df.groupby('AccessionNumber')['StudyInstanceUID'].nunique() == 2).sum(),
"AccessionNumbers with 3 StudyInstanceUIDs": (df.groupby('AccessionNumber')['StudyInstanceUID'].nunique() == 3).sum(),
"AccessionNumbers with >3 StudyInstanceUIDs": (df.groupby('AccessionNumber')['StudyInstanceUID'].nunique() > 3).sum(),
"Missing AccessionNumbers": (df['AccessionNumber'] == '').sum(),
"Missing StudyDescriptions": (df['StudyDescription'] == '').sum(),
"*QA* in PatientID": df['PatientID'].str.contains('QA', case=False, na=False).sum(),
"*QA* in StudyDescription": df['StudyDescription'].str.contains('QA', case=False, na=False).sum(),
"*QA* in PatientName": df['PatientName'].str.contains('QA', case=False, na=False).sum(),
"*TEST* in PatientID": df['PatientID'].str.contains('TEST', case=False, na=False).sum(),
"*TEST* in StudyDescription": df['StudyDescription'].str.contains('TEST', case=False, na=False).sum(),
"*TEST* in PatientName": df['PatientName'].str.contains('TEST', case=False, na=False).sum()
}
modality_counts = {
"CR": 0, "DX": 0, "CT": 0, "MR": 0, "NM": 0, "US": 0,
"XA": 0, "PR": 0, "SC": 0, "OT": 0, "Other": 0
}
for val in df['ModalitiesInStudy']:
for modality in [m.strip().upper() for m in val.split(',') if m.strip()]:
if modality in modality_counts:
modality_counts[modality] += 1
else:
modality_counts["Other"] += 1
with open(output_path, 'w') as f:
f.write("DICOM Discovery Analysis Summary\n")
f.write("="*40 + "\n\n")
for key, value in stats.items():
f.write(f"{key}\t{value}\n")
f.write("\nModality Breakdown\n")
f.write("-"*40 + "\n")
for modality, count in modality_counts.items():
f.write(f"{modality}\t{count}\n")
tk.messagebox.showinfo("Analysis Complete", f"Analysis saved to:\n{output_path}")
# GUI
root = tk.Tk()
root.title("DICOM Discovery Analyzer")
root.geometry("400x150")
frame = tk.Frame(root, padx=10, pady=20)
frame.pack(expand=True)
tk.Button(frame, text="Select Input File and Analyze", command=analyze_and_save, width=30).pack(pady=10)
root.mainloop()