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:
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user