Update archive_discovery.py

 New Features Included

    Live Record Count: Label shows how many studies have been written.

    Pause/Resume Button: Temporarily halt and resume querying without killing the session.

    Stop Button: Gracefully terminates the process early.

    Real-Time File Writing: Ensures each writer.writerow() call flushes immediately.

📝 Notes

    f.flush() is automatic now with buffering=1 (line-buffered mode).

    self.pause_event.wait() halts progress until "Resume" is pressed.

    self.stop_event.is_set() stops the loop immediately.
This commit is contained in:
2025-05-14 17:18:51 +00:00
parent 59823679b7
commit dcf2f54f82

View File

@@ -5,7 +5,7 @@ import os
import csv
import logging
import configparser
from threading import Thread
from threading import Thread, Event
from pydicom.dataset import Dataset
from pynetdicom import AE, evt, debug_logger
from pynetdicom.sop_class import StudyRootQueryRetrieveInformationModelFind
@@ -62,6 +62,10 @@ class ConfigDialog:
self.current_profile = tk.StringVar()
self.log_level = tk.StringVar(value="INFO")
self.status = tk.StringVar(value="Ready")
self.record_count = tk.IntVar(value=0)
self.pause_event = Event()
self.stop_event = Event()
self.pause_event.set()
self.all_profiles = load_all_profiles()
self.profile_names = self.all_profiles.sections()
@@ -89,9 +93,14 @@ class ConfigDialog:
self.status_label = tk.Label(self.top, textvariable=self.status, fg="blue")
self.status_label.grid(row=len(self.fields)+2, column=0, columnspan=2, padx=10, pady=5)
self.record_label = tk.Label(self.top, text="Records Written: 0")
self.record_label.grid(row=len(self.fields)+3, column=0, columnspan=2, padx=10, pady=5)
button_frame = tk.Frame(self.top)
button_frame.grid(row=len(self.fields)+3, column=0, columnspan=2, pady=10)
button_frame.grid(row=len(self.fields)+4, column=0, columnspan=2, pady=10)
tk.Button(button_frame, text="Run Query", command=self.on_run).pack(side=tk.LEFT, padx=5)
tk.Button(button_frame, text="Pause", command=self.on_pause).pack(side=tk.LEFT, padx=5)
tk.Button(button_frame, text="Stop", command=self.on_stop).pack(side=tk.LEFT, padx=5)
tk.Button(button_frame, text="Cancel", command=self.on_cancel).pack(side=tk.RIGHT, padx=5)
if self.profile_names:
@@ -124,9 +133,23 @@ class ConfigDialog:
logging.getLogger().setLevel(LOG_LEVELS[self.log_level.get()])
self.values['log_level'] = self.log_level.get()
self.stop_event.clear()
self.pause_event.set()
thread = Thread(target=self.run_query)
thread.start()
def on_pause(self):
if self.pause_event.is_set():
self.pause_event.clear()
self.update_status("Paused")
else:
self.pause_event.set()
self.update_status("Resumed")
def on_stop(self):
self.stop_event.set()
self.update_status("Stopping...")
def on_cancel(self):
self.top.destroy()
@@ -136,6 +159,10 @@ class ConfigDialog:
def _set_status(self, message):
self.status.set(message)
def update_record_count(self):
count = self.record_count.get()
self.record_label.config(text=f"Records Written: {count}")
def run_query(self):
config = self.values
self.update_status("Initializing DICOM query...")
@@ -172,14 +199,16 @@ class ConfigDialog:
output_path = os.path.join(os.getcwd(), generate_output_filename())
logging.info("Starting C-FIND loop from %s to %s", start_date, now)
with open(output_path, 'w', newline='') as f:
with open(output_path, 'w', newline='', buffering=1) as f:
writer = csv.writer(f, delimiter='|')
writer.writerow([
'PatientID', 'PatientName', 'AccessionNumber', 'StudyDate',
'StudyInstanceUID', 'ModalitiesInStudy', 'NumberOfStudyRelatedInstances'
])
while start_date < now:
while start_date < now and not self.stop_event.is_set():
self.pause_event.wait()
end_date = start_date + timedelta(hours=1)
ds = create_cfind_dataset(start_date, end_date)
self.update_status(f"Querying: {start_date.strftime('%Y-%m-%d %H:%M')}")
@@ -187,6 +216,9 @@ class ConfigDialog:
try:
responses = assoc.send_c_find(ds, StudyRootQueryRetrieveInformationModelFind)
for status, identifier in responses:
if self.stop_event.is_set():
break
self.pause_event.wait()
if status and status.Status in (0xFF00, 0xFF01) and identifier:
mod_raw = getattr(identifier, 'ModalitiesInStudy', '')
try:
@@ -211,11 +243,10 @@ class ConfigDialog:
mod_string,
str(getattr(identifier, 'NumberOfStudyRelatedInstances', '')).strip()
])
f.flush()
self.record_count.set(self.record_count.get() + 1)
self.update_record_count()
except Exception as e:
logging.exception("Error writing to output file.")
elif status:
logging.debug("C-FIND response: 0x%04X", status.Status)
except Exception as e:
logging.exception("Exception during C-FIND from %s to %s", start_date, end_date)