@@ -60,6 +60,8 @@ def read_parameters_from_file(param_file):
6060 ny = 0
6161 omega_sum_frames = None
6262 rmax , rmin , rbin_size = 100 , 10 , 0.1 # Defaults match integrator_stream_process_h5.py
63+ n_peaks = 0
64+ peak_fit = False
6365
6466 with open (param_file , 'r' ) as f :
6567 for line in f :
@@ -91,9 +93,16 @@ def read_parameters_from_file(param_file):
9193 rbin_size = float (val )
9294 elif key == 'PanelShiftsFile' :
9395 panel_shifts_file = val
94-
96+ elif key == 'PeakLocation' :
97+ n_peaks += 1
98+ elif key == 'DoPeakFit' :
99+ if int (val ) == 1 :
100+ peak_fit = True
101+
102+ if n_peaks > 0 :
103+ peak_fit = True # PeakLocation implies DoPeakFit
95104 n_rbins = int (math .ceil ((rmax - rmin ) / rbin_size ))
96- return nx , ny , omega_sum_frames , n_rbins , panel_shifts_file
105+ return nx , ny , omega_sum_frames , n_rbins , panel_shifts_file , n_peaks , peak_fit
97106
98107def is_port_open (host , port , timeout = 1 ):
99108 """Check if a port is open on the specified host"""
@@ -440,6 +449,10 @@ def main():
440449 help = 'Output zarr.zip filename for GSAS-II (default: auto from h5 name)' )
441450 parser .add_argument ('--no-zarr' , action = 'store_true' ,
442451 help = 'Skip creating zarr.zip output for GSAS-II' )
452+ parser .add_argument ('--live-viewer' , action = 'store_true' ,
453+ help = 'Launch real-time visualization dashboard' )
454+ parser .add_argument ('--viewer-theme' , choices = ['dark' , 'light' ], default = 'light' ,
455+ help = 'Theme for live viewer (default: light)' )
443456
444457 args = parser .parse_args ()
445458
@@ -480,7 +493,7 @@ def main():
480493 print (f"Found { expected_frames } { extension } files to process" )
481494
482495 # Read parameters from parameter file
483- nx , ny , omega_sum_frames , n_rbins , panel_shifts_file = read_parameters_from_file (param_file )
496+ nx , ny , omega_sum_frames , n_rbins , panel_shifts_file , n_peaks , peak_fit = read_parameters_from_file (param_file )
484497 if nx == 0 or ny == 0 :
485498 print ("Error: Could not determine frame size from parameter file" )
486499 sys .exit (1 )
@@ -605,6 +618,26 @@ def main():
605618
606619 print (f"Started integrator_server.py with PID { server_proc .pid } " )
607620
621+ # Launch live viewer if requested
622+ viewer_proc = None
623+ if args .live_viewer :
624+ print ("\n Launching live viewer dashboard..." )
625+ viewer_script = os .path .join (INSTALL_PATH , "utils/live_viewer.py" )
626+ viewer_cmd = [
627+ sys .executable , viewer_script ,
628+ '--lineout' , str (output_dir / 'lineout.bin' ),
629+ '--nRBins' , str (n_rbins ),
630+ '--theme' , args .viewer_theme
631+ ]
632+ if peak_fit and n_peaks > 0 :
633+ viewer_cmd .extend ([
634+ '--fit' , str (output_dir / 'fit.bin' ),
635+ '--nPeaks' , str (n_peaks )
636+ ])
637+ print (f"Viewer command: { ' ' .join (viewer_cmd )} " )
638+ viewer_proc = subprocess .Popen (viewer_cmd , env = midas_env )
639+ print (f"Started live_viewer.py with PID { viewer_proc .pid } " )
640+
608641 # Monitor processing
609642 print ("\n Monitoring processing progress..." )
610643 completed = monitor_processing (output_dir / mapping_file , expected_frames )
@@ -655,6 +688,11 @@ def main():
655688 for pid in pids :
656689 kill_process (pid )
657690
691+ # Terminate live viewer if running
692+ if viewer_proc and viewer_proc .poll () is None :
693+ print ("Terminating live viewer..." )
694+ kill_process (viewer_proc .pid )
695+
658696 # Run integrator_stream_process_h5.py
659697 print ("\n Converting binary output to HDF5..." )
660698 h5_cmd = [
0 commit comments