@@ -1377,7 +1377,7 @@ def __init__(self, multiPointController):
1377
1377
self .liveController = self .multiPointController .liveController
1378
1378
self .autofocusController = self .multiPointController .autofocusController
1379
1379
self .objectiveStore = self .multiPointController .objectiveStore
1380
- self .acquisitionConfigurationManager = self .multiPointController .acquisitionConfigurationManager
1380
+ self .channelConfigurationManager = self .multiPointController .channelConfigurationManager
1381
1381
self .NX = self .multiPointController .NX
1382
1382
self .NY = self .multiPointController .NY
1383
1383
self .NZ = self .multiPointController .NZ
@@ -1754,7 +1754,7 @@ def perform_autofocus(self, region_id, fov):
1754
1754
config_AF = next (
1755
1755
(
1756
1756
config
1757
- for config in self .acquisitionConfigurationManager .get_channel_configurations_for_objective (self .objectiveStore .current_objective )
1757
+ for config in self .channelConfigurationManager .get_channel_configurations_for_objective (self .objectiveStore .current_objective )
1758
1758
if config .name == configuration_name_AF
1759
1759
)
1760
1760
)
@@ -1776,7 +1776,7 @@ def perform_autofocus(self, region_id, fov):
1776
1776
config_AF = next (
1777
1777
(
1778
1778
config
1779
- for config in self .acquisitionConfigurationManager .get_channel_configurations_for_objective (self .objectiveStore .current_objective )
1779
+ for config in self .channelConfigurationManager .get_channel_configurations_for_objective (self .objectiveStore .current_objective )
1780
1780
if config .name == configuration_name_AF
1781
1781
)
1782
1782
)
@@ -1887,7 +1887,7 @@ def acquire_rgb_image(self, config, file_ID, current_path, current_round_images,
1887
1887
rgb_channels = ["BF LED matrix full_R" , "BF LED matrix full_G" , "BF LED matrix full_B" ]
1888
1888
images = {}
1889
1889
1890
- for config_ in self .acquisitionConfigurationManager .get_channel_configurations_for_objective (self .objectiveStore .current_objective ):
1890
+ for config_ in self .channelConfigurationManager .get_channel_configurations_for_objective (self .objectiveStore .current_objective ):
1891
1891
if config_ .name in rgb_channels :
1892
1892
# update the current configuration
1893
1893
self .signal_current_configuration .emit (config_ )
@@ -2172,7 +2172,7 @@ def __init__(
2172
2172
liveController ,
2173
2173
autofocusController ,
2174
2174
objectiveStore ,
2175
- acquisitionConfigurationManager ,
2175
+ channelConfigurationManager ,
2176
2176
usb_spectrometer = None ,
2177
2177
scanCoordinates = None ,
2178
2178
parent = None ,
@@ -2187,7 +2187,7 @@ def __init__(
2187
2187
self .liveController = liveController
2188
2188
self .autofocusController = autofocusController
2189
2189
self .objectiveStore = objectiveStore ,
2190
- self .acquisitionConfigurationManager = acquisitionConfigurationManager
2190
+ self .channelConfigurationManager = channelConfigurationManager
2191
2191
self .multiPointWorker : Optional [MultiPointWorker ] = None
2192
2192
self .thread : Optional [QThread ] = None
2193
2193
self .NX = 1
@@ -2311,7 +2311,7 @@ def start_new_experiment(self, experiment_ID): # @@@ to do: change name to prep
2311
2311
self .recording_start_time = time .time ()
2312
2312
# create a new folder
2313
2313
utils .ensure_directory_exists (os .path .join (self .base_path , self .experiment_ID ))
2314
- self .acquisitionConfigurationManager .write_configuration_selected (
2314
+ self .channelConfigurationManager .write_configuration_selected (
2315
2315
self .objectiveStore .current_objective , self .selected_configurations , os .path .join (self .base_path , self .experiment_ID ) + "/configurations.xml"
2316
2316
) # save the configuration for the experiment
2317
2317
# Prepare acquisition parameters
@@ -2356,7 +2356,7 @@ def set_selected_configurations(self, selected_configurations_name):
2356
2356
self .selected_configurations .append (
2357
2357
next (
2358
2358
(config
2359
- for config in self .acquisitionConfigurationManager .get_channel_configurations_for_objective (self .objectiveStore .current_objective )
2359
+ for config in self .channelConfigurationManager .get_channel_configurations_for_objective (self .objectiveStore .current_objective )
2360
2360
if config .name == configuration_name )
2361
2361
)
2362
2362
)
@@ -2630,7 +2630,7 @@ def __init__(
2630
2630
microcontroller : Microcontroller ,
2631
2631
stage : AbstractStage ,
2632
2632
objectiveStore ,
2633
- acquisitionConfigurationManager ,
2633
+ channelConfigurationManager ,
2634
2634
liveController : LiveController ,
2635
2635
autofocusController ,
2636
2636
imageDisplayWindow ,
@@ -2640,7 +2640,7 @@ def __init__(
2640
2640
self .microcontroller = microcontroller
2641
2641
self .stage = stage
2642
2642
self .objectiveStore = objectiveStore
2643
- self .acquisitionConfigurationManager = acquisitionConfigurationManager
2643
+ self .channelConfigurationManager = channelConfigurationManager
2644
2644
self .liveController = liveController
2645
2645
self .autofocusController = autofocusController
2646
2646
self .imageDisplayWindow = imageDisplayWindow
@@ -2746,7 +2746,8 @@ def start_new_experiment(self, experiment_ID): # @@@ to do: change name to prep
2746
2746
# create a new folder
2747
2747
try :
2748
2748
utils .ensure_directory_exists (os .path .join (self .base_path , self .experiment_ID ))
2749
- self .acquisitionConfigurationManager .write_configuration (
2749
+ self .channelConfigurationManager ._save_xml_config (
2750
+ self .objectiveStore .current_objective ,
2750
2751
os .path .join (self .base_path , self .experiment_ID ) + "/configurations.xml"
2751
2752
) # save the configuration for the experiment
2752
2753
except :
@@ -2759,7 +2760,7 @@ def set_selected_configurations(self, selected_configurations_name):
2759
2760
self .selected_configurations .append (
2760
2761
next ((
2761
2762
config
2762
- for config in self .acquisitionConfigurationManager .get_channel_configurations_for_objective (self .objectiveStore .current_objective )
2763
+ for config in self .channelConfigurationManager .get_channel_configurations_for_objective (self .objectiveStore .current_objective )
2763
2764
if config .name == configuration_name )
2764
2765
)
2765
2766
)
@@ -2860,7 +2861,7 @@ def __init__(self, trackingController: TrackingController):
2860
2861
self .microcontroller = self .trackingController .microcontroller
2861
2862
self .liveController = self .trackingController .liveController
2862
2863
self .autofocusController = self .trackingController .autofocusController
2863
- self .acquisitionConfigurationManager = self .trackingController .acquisitionConfigurationManager
2864
+ self .channelConfigurationManager = self .trackingController .channelConfigurationManager
2864
2865
self .imageDisplayWindow = self .trackingController .imageDisplayWindow
2865
2866
self .crop_width = self .trackingController .crop_width
2866
2867
self .crop_height = self .trackingController .crop_height
@@ -3714,8 +3715,11 @@ def write_configuration_selected(self, objective: str, selected_configurations:
3714
3715
self ._save_xml_config (objective , filename )
3715
3716
for conf in selected_configurations :
3716
3717
self .update_configuration (conf .id , "Selected" , 0 )
3718
+
3719
+ def get_channel_configurations_for_objective (self , objective : str ) -> List [Configuration ]:
3720
+ return self .active_channel_config .get (objective , [])
3717
3721
3718
- def toggle_spinning_disk_mode (self , confocal : bool ) -> None :
3722
+ def toggle_confocal_widefield (self , confocal : bool ) -> None :
3719
3723
"""Toggle between confocal and widefield configurations."""
3720
3724
if not ENABLE_SPINNING_DISK :
3721
3725
return
@@ -3731,7 +3735,7 @@ def toggle_spinning_disk_mode(self, confocal: bool) -> None:
3731
3735
self .active_config_xml_tree_root = self .widefield_config_xml_tree_root
3732
3736
self .active_config_flag = 2
3733
3737
3734
- class LaserAFConfigurationManager :
3738
+ class LaserAFCacheManager :
3735
3739
"""Manages JSON-based laser autofocus configurations."""
3736
3740
def __init__ (self ):
3737
3741
self .autofocus_configurations = {} # Dict[str, Dict[str, Any]]
@@ -3758,21 +3762,24 @@ def save_configurations(self, objective: str) -> None:
3758
3762
with open (config_file , 'w' ) as f :
3759
3763
json .dump (self .autofocus_configurations [objective ], f , indent = 4 )
3760
3764
3761
- def get_configurations (self , objective : str ) -> Dict [str , Any ]:
3765
+ def get_cache_for_objective (self , objective : str ) -> Dict [str , Any ]:
3762
3766
return self .autofocus_configurations .get (objective , {})
3763
-
3764
- def update_configuration (self , objective : str , updates : Dict [str , Any ]) -> None :
3767
+
3768
+ def get_laser_af_cache (self ) -> Dict [str , Any ]:
3769
+ return self .autofocus_configurations
3770
+
3771
+ def update_laser_af_cache (self , objective : str , updates : Dict [str , Any ]) -> None :
3765
3772
if objective not in self .autofocus_configurations :
3766
3773
self .autofocus_configurations [objective ] = {}
3767
3774
self .autofocus_configurations [objective ].update (updates )
3768
3775
3769
3776
class ConfigurationManager (QObject ):
3770
3777
"""Main configuration manager that coordinates channel and autofocus configurations."""
3771
3778
def __init__ (self ,
3772
- base_config_path : Path = Path ("acquisition_configurations" ),
3773
- profile : str = "default_profile" ,
3774
3779
channel_manager : ChannelConfigurationManager ,
3775
- af_manager : Optional [LaserAFCacheManager ] = None ):
3780
+ af_manager : Optional [LaserAFCacheManager ] = None ,
3781
+ base_config_path : Path = Path ("acquisition_configurations" ),
3782
+ profile : str = "default_profile" ):
3776
3783
super ().__init__ ()
3777
3784
self .base_config_path = Path (base_config_path )
3778
3785
self .current_profile = profile
@@ -4620,13 +4627,14 @@ def __init__(
4620
4627
camera ,
4621
4628
stage : AbstractStage ,
4622
4629
objectiveStore : Optional [ObjectiveStore ] = None ,
4623
- cachedLaserAFConfigurations : Optional [Dict [ str , Any ] ] = None
4630
+ laserAFCacheManager : Optional [LaserAFCacheManager ] = None
4624
4631
):
4625
4632
QObject .__init__ (self )
4626
4633
self .microcontroller = microcontroller
4627
4634
self .camera = camera
4628
4635
self .stage = stage
4629
4636
self .objectiveStore = objectiveStore
4637
+ self .laserAFCacheManager = laserAFCacheManager
4630
4638
4631
4639
self .is_initialized = False
4632
4640
self .x_reference = 0
@@ -4644,8 +4652,8 @@ def __init__(
4644
4652
self .image = None # for saving the focus camera image for debugging when centroid cannot be found
4645
4653
4646
4654
# Load configurations if provided
4647
- self .laser_af_cache = cachedLaserAFConfigurations
4648
- if self .laser_af_cache is not None :
4655
+ if self .laserAFCacheManager :
4656
+ self .laser_af_cache = self . laserAFCacheManager . get_laser_af_cache ()
4649
4657
self .load_cached_configuration ()
4650
4658
4651
4659
def initialize_manual (self , x_offset , y_offset , width , height , pixel_to_um , x_reference ,
@@ -4665,12 +4673,8 @@ def initialize_manual(self, x_offset, y_offset, width, height, pixel_to_um, x_re
4665
4673
self .is_initialized = True
4666
4674
4667
4675
# Update cache if objective store and laser_af_cache is available
4668
- if self .objectiveStore and self .laser_af_cache and self .objectiveStore .current_objective :
4669
- current_objective = self .objectiveStore .current_objective
4670
- if current_objective not in self .laser_af_cache :
4671
- self .laser_af_cache [current_objective ] = {}
4672
-
4673
- self .laser_af_cache [current_objective ].update ({
4676
+ if self .objectiveStore and self .laserAFCacheManager and self .objectiveStore .current_objective :
4677
+ self .laserAFCacheManager .update_laser_af_cache (self .objectiveStore .current_objective , {
4674
4678
'x_offset' : x_offset ,
4675
4679
'y_offset' : y_offset ,
4676
4680
'width' : width ,
@@ -4687,7 +4691,7 @@ def load_cached_configuration(self):
4687
4691
"""Load configuration from the cache if available."""
4688
4692
current_objective = self .objectiveStore .current_objective if self .objectiveStore else None
4689
4693
if current_objective and current_objective in self .laser_af_cache :
4690
- config = self .laser_af_cache [ current_objective ]
4694
+ config = self .laserAFCacheManager . get_cache_for_objective ( current_objective )
4691
4695
4692
4696
self .focus_camera_exposure_time_ms = config .get ('focus_camera_exposure_time_ms' , 2 ),
4693
4697
self .focus_camera_analog_gain = config .get ('focus_camera_analog_gain' , 0 )
@@ -4739,6 +4743,8 @@ def initialize_auto(self):
4739
4743
# Calibrate pixel to um conversion
4740
4744
self ._calibrate_pixel_to_um ()
4741
4745
4746
+ self .laserAFCacheManager .save_configurations (self .objectiveStore .current_objective )
4747
+
4742
4748
def _calibrate_pixel_to_um (self ):
4743
4749
"""Calibrate the pixel to micrometer conversion factor."""
4744
4750
self .microcontroller .turn_on_AF_laser ()
@@ -4774,11 +4780,10 @@ def _calibrate_pixel_to_um(self):
4774
4780
# set reference
4775
4781
self .x_reference = x1
4776
4782
4777
- # Update cache if objective store and laser_af_cache is available
4778
- if self .objectiveStore and self .laser_af_cache and self .objectiveStore .current_objective :
4779
- current_objective = self .objectiveStore .current_objective
4780
- if current_objective in self .laser_af_cache :
4781
- self .laser_af_cache [current_objective ]['pixel_to_um' ] = self .pixel_to_um
4783
+ # Update cache
4784
+ self .laserAFCacheManager .update_laser_af_cache (self .objectiveStore .current_objective , {
4785
+ 'pixel_to_um' : self .pixel_to_um
4786
+ })
4782
4787
4783
4788
def set_laser_af_properties (self , has_two_interfaces , use_glass_top , focus_camera_exposure_time_ms , focus_camera_analog_gain ):
4784
4789
# These properties can be set from gui
@@ -4787,6 +4792,8 @@ def set_laser_af_properties(self, has_two_interfaces, use_glass_top, focus_camer
4787
4792
self .focus_camera_exposure_time_ms = focus_camera_exposure_time_ms
4788
4793
self .focus_camera_analog_gain = focus_camera_analog_gain
4789
4794
4795
+ self .is_initialized = False
4796
+
4790
4797
def measure_displacement (self ):
4791
4798
# turn on the laser
4792
4799
self .microcontroller .turn_on_AF_laser ()
@@ -4830,11 +4837,15 @@ def set_reference(self):
4830
4837
self .x_reference = x
4831
4838
self .signal_displacement_um .emit (0 )
4832
4839
4833
- # Update cache if objective store and laser_af_cache is available
4834
- if self .objectiveStore and self .laser_af_cache and self .objectiveStore .current_objective :
4835
- current_objective = self .objectiveStore .current_objective
4836
- if current_objective in self .laser_af_cache :
4837
- self .laser_af_cache [current_objective ]['x_reference' ] = x + self .x_offset
4840
+ # Update cache
4841
+ self .laserAFCacheManager .update_laser_af_cache (self .objectiveStore .current_objective , {
4842
+ 'x_reference' : x + self .x_offset
4843
+ })
4844
+ self .laserAFCacheManager .save_configurations (self .objectiveStore .current_objective )
4845
+
4846
+ def on_objective_changed (self ):
4847
+ self .is_initialized = False
4848
+ self .load_cached_configurations ()
4838
4849
4839
4850
def _calculate_centroid (self , image ):
4840
4851
"""Calculate the centroid of the laser spot."""
0 commit comments