@@ -768,6 +768,85 @@ def log(self, message):
768768 self .console_widget .see ('end' )
769769 self .console_widget .config (state = 'disabled' )
770770
771+ def _handle_log_message (self , message ):
772+ self .log (message )
773+
774+ def _handle_cutoff_event (self ):
775+ self .log ("!!! SAFETY CUTOFF REACHED !!!" )
776+ self .stop_measurement (False )
777+ messagebox .showwarning ("Cutoff" , "Safety cutoff temperature reached." )
778+
779+ def _handle_complete_event (self ):
780+ self .log ("Target temperature reached." )
781+ self .stop_measurement (False )
782+ messagebox .showinfo ("Finished" , "Measurement complete." )
783+
784+ def _handle_runtime_error (self , exception ):
785+ self .log (f"RUNTIME ERROR: { traceback .format_exc ()} " )
786+ self .stop_measurement (False )
787+ messagebox .showerror (
788+ "Runtime Error" , f"A critical error occurred: { exception } " )
789+
790+ def _process_measurement_data_point (self , data ):
791+ temp , htr , cur , res , elapsed = data
792+ self ._log_measurement_data (temp , htr , cur , res )
793+ self ._save_measurement_to_csv (temp , htr , cur , res , elapsed )
794+ self ._update_data_storage (temp , htr , cur , res , elapsed )
795+ self ._update_live_plots ()
796+
797+ def _log_measurement_data (self , temp , htr , cur , res ):
798+ self .log (
799+ f"T:{ temp :.3f} K | R:{ res :.3e} Ω | Htr:{ htr :.1f} % ({ self .current_heater_range } )" )
800+
801+ def _save_measurement_to_csv (self , temp , htr , cur , res , elapsed ):
802+ with open (self .data_filepath , 'a' , newline = '' ) as f :
803+ writer = csv .writer (f )
804+ writer .writerow (
805+ [
806+ datetime .now ().strftime ('%Y-%m-%d %H:%M:%S' ),
807+ f"{ elapsed :.2f} " ,
808+ f"{ temp :.4f} " ,
809+ f"{ htr :.2f} " ,
810+ f"{ self .backend .params ['source_voltage' ]:.4e} " ,
811+ f"{ cur :.4e} " ,
812+ f"{ res :.4e} " ])
813+
814+ def _update_data_storage (self , temp , htr , cur , res , elapsed ):
815+ self .data_storage ['time' ].append (elapsed )
816+ self .data_storage ['temperature' ].append (temp )
817+ self .data_storage ['current' ].append (cur )
818+ self .data_storage ['resistance' ].append (res )
819+
820+ def _update_live_plots (self ):
821+ self .line_main .set_data (
822+ self .data_storage ['temperature' ],
823+ self .data_storage ['resistance' ])
824+ self .line_sub1 .set_data (
825+ self .data_storage ['temperature' ],
826+ self .data_storage ['current' ])
827+ self .line_sub2 .set_data (
828+ self .data_storage ['time' ],
829+ self .data_storage ['temperature' ])
830+
831+ if self .plot_backgrounds :
832+ for bg in self .plot_backgrounds :
833+ self .canvas .restore_region (bg )
834+ for ax in [self .ax_main , self .ax_sub1 , self .ax_sub2 ]:
835+ ax .relim ()
836+ ax .autoscale_view ()
837+
838+ self .ax_main .draw_artist (self .line_main )
839+ self .ax_sub1 .draw_artist (self .line_sub1 )
840+ self .ax_sub2 .draw_artist (self .line_sub2 )
841+
842+ self .canvas .blit (self .figure .bbox )
843+ else :
844+ for ax in [self .ax_main , self .ax_sub1 , self .ax_sub2 ]:
845+ ax .relim ()
846+ ax .autoscale_view ()
847+ self .figure .tight_layout (pad = 3.0 )
848+ self .canvas .draw_idle ()
849+
771850 def start_measurement (self ):
772851 try :
773852 params = {
@@ -914,113 +993,24 @@ def _process_data_queue(self):
914993 while not self .data_queue .empty ():
915994 data = self .data_queue .get_nowait ()
916995 if isinstance (data , str ) and data .startswith ("LOG:" ):
917- self .log (data [4 :])
996+ self ._handle_log_message (data [4 :])
918997 elif isinstance (data , str ) and data == "CUTOFF" :
919- self .log ("!!! SAFETY CUTOFF REACHED !!!" )
920- self .stop_measurement (False )
921- messagebox .showwarning (
922- "Cutoff" , "Safety cutoff temperature reached." )
998+ self ._handle_cutoff_event ()
923999 return
9241000 elif isinstance (data , str ) and data == "COMPLETE" :
925- self .log ("Target temperature reached." )
926- self .stop_measurement (False )
927- messagebox .showinfo ("Finished" , "Measurement complete." )
1001+ self ._handle_complete_event ()
9281002 return
9291003 elif isinstance (data , Exception ):
930- self .log (f"RUNTIME ERROR: { traceback .format_exc ()} " )
931- self .stop_measurement (False )
932- messagebox .showerror (
933- "Runtime Error" , f"A critical error occurred: { data } " )
1004+ self ._handle_runtime_error (data )
9341005 return
9351006 else :
936- temp , htr , cur , res , elapsed = data
937- self .log (
938- f"T:{ temp :.3f} K | R:{ res :.3e} Ω | Htr:{ htr :.1f} % ({ self .current_heater_range } )" )
939- with open (self .data_filepath , 'a' , newline = '' ) as f :
940- writer = csv .writer (f )
941- writer .writerow (
942- [
943- datetime .now ().strftime ('%Y-%m-%d %H:%M:%S' ),
944- f"{ elapsed :.2f} " ,
945- f"{ temp :.4f} " ,
946- f"{ htr :.2f} " ,
947- f"{ self .backend .params ['source_voltage' ]:.4e} " ,
948- f"{ cur :.4e} " ,
949- f"{ res :.4e} " ])
950-
951- self .data_storage ['time' ].append (elapsed )
952- self .data_storage ['temperature' ].append (temp )
953- self .data_storage ['current' ].append (cur )
954- self .data_storage ['resistance' ].append (res )
955-
956- self .line_main .set_data (
957- self .data_storage ['temperature' ],
958- self .data_storage ['resistance' ])
959- self .line_sub1 .set_data (
960- self .data_storage ['temperature' ],
961- self .data_storage ['current' ]) # This was likely a bug, should be temp vs current
962- self .line_sub2 .set_data (
963- self .data_storage ['time' ],
964- self .data_storage ['temperature' ])
965-
966- # --- Performance Improvement: Use blitting for fast graph updates ---
967- if self .plot_backgrounds :
968- for bg in self .plot_backgrounds :
969- self .canvas .restore_region (bg )
970- for ax in [self .ax_main , self .ax_sub1 , self .ax_sub2 ]:
971- ax .relim ()
972- ax .autoscale_view ()
973-
974- self .ax_main .draw_artist (self .line_main )
975- self .ax_sub1 .draw_artist (self .line_sub1 )
976- self .ax_sub2 .draw_artist (self .line_sub2 )
977-
978- self .canvas .blit (self .figure .bbox )
979- else :
980- for ax in [self .ax_main , self .ax_sub1 , self .ax_sub2 ]:
981- ax .relim ()
982- ax .autoscale_view ()
983- self .figure .tight_layout (pad = 3.0 )
984- self .canvas .draw_idle ()
1007+ self ._process_measurement_data_point (data )
9851008 except queue .Empty :
9861009 pass
9871010
9881011 if self .is_running or self .is_stabilizing :
9891012 self .root .after (200 , self ._process_data_queue )
9901013
991- def _handle_new_data_point (self , data ):
992- """Helper to process a single data point from the queue."""
993- temp , htr , cur , res , elapsed = data
994- self .log (
995- f"T:{ temp :.3f} K | R:{ res :.3e} Ω | Htr:{ htr :.1f} % ({ self .current_heater_range } )" )
996- with open (self .data_filepath , 'a' , newline = '' ) as f :
997- writer = csv .writer (f )
998- writer .writerow (
999- [
1000- datetime .now ().strftime ('%Y-%m-%d %H:%M:%S' ),
1001- f"{ elapsed :.2f} " ,
1002- f"{ temp :.4f} " ,
1003- f"{ htr :.2f} " ,
1004- f"{ self .backend .params ['source_voltage' ]:.4e} " ,
1005- f"{ cur :.4e} " ,
1006- f"{ res :.4e} " ])
1007-
1008- self .data_storage ['time' ].append (elapsed )
1009- self .data_storage ['temperature' ].append (temp )
1010- self .data_storage ['current' ].append (cur )
1011- self .data_storage ['resistance' ].append (res )
1012-
1013- # Update plot data
1014- self .line_main .set_data (
1015- self .data_storage ['temperature' ],
1016- self .data_storage ['resistance' ])
1017- self .line_sub1 .set_data (
1018- self .data_storage ['temperature' ],
1019- self .data_storage ['current' ])
1020- self .line_sub2 .set_data (
1021- self .data_storage ['time' ],
1022- self .data_storage ['temperature' ])
1023-
10241014 def _scan_for_visa_instruments (self ):
10251015 if not pyvisa :
10261016 self .log ("ERROR: PyVISA is not installed." )
0 commit comments