From 99ed9040dc4c31bb89ec1f5f6f4bc6e33eb87ae0 Mon Sep 17 00:00:00 2001 From: Matt Clifford Date: Tue, 6 Aug 2024 14:47:36 +0100 Subject: [PATCH] new docs --- docs/_build/doctrees/IQM_Vis.UI.doctree | Bin 193466 -> 205427 bytes .../doctrees/IQM_Vis.data_handlers.doctree | Bin 56936 -> 62822 bytes docs/_build/doctrees/IQM_Vis.examples.doctree | Bin 24586 -> 24586 bytes docs/_build/doctrees/IQM_Vis.utils.doctree | Bin 144369 -> 146209 bytes docs/_build/doctrees/environment.pickle | Bin 422999 -> 446617 bytes docs/_build/html/IQM_Vis.UI.html | 58 ++++++- docs/_build/html/IQM_Vis.data_handlers.html | 20 +++ docs/_build/html/IQM_Vis.examples.html | 2 +- docs/_build/html/IQM_Vis.utils.html | 7 +- .../_modules/IQM_Vis/UI/experiment_mode.html | 57 ++++--- .../html/_modules/IQM_Vis/UI/images.html | 119 +++++++++++++- .../html/_modules/IQM_Vis/UI/layout.html | 39 ++++- .../_build/html/_modules/IQM_Vis/UI/main.html | 50 +++++- .../html/_modules/IQM_Vis/UI/widgets.html | 148 ++++++++++++++++-- .../IQM_Vis/data_handlers/data_api.html | 35 ++++- .../data_handlers/data_api_abstract.html | 6 +- .../html/_modules/IQM_Vis/examples/dists.html | 49 +++--- .../html/_modules/IQM_Vis/metrics/IQMs.html | 2 +- .../IQM_Vis/transformations/transforms.html | 2 +- .../_modules/IQM_Vis/utils/gui_utils.html | 18 ++- .../_modules/IQM_Vis/utils/plot_utils.html | 4 +- .../_modules/IQM_Vis/utils/save_utils.html | 5 + docs/_build/html/genindex.html | 46 +++++- docs/_build/html/objects.inv | Bin 8494 -> 8765 bytes docs/_build/html/searchindex.js | 2 +- 25 files changed, 565 insertions(+), 104 deletions(-) diff --git a/docs/_build/doctrees/IQM_Vis.UI.doctree b/docs/_build/doctrees/IQM_Vis.UI.doctree index 2140c8b7dae3f9494a093011b4470c38ea0ffc23..a977459a00817f1cf4be1844f96dcf6b2ae68ef4 100644 GIT binary patch delta 28673 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 delta 23972 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 JG}2{|_&<>?F^>QM diff --git a/docs/_build/doctrees/IQM_Vis.data_handlers.doctree b/docs/_build/doctrees/IQM_Vis.data_handlers.doctree index 611f3538ab8108470047e2502a7292ca1c20e7d8..0f1e853f87bd6dad6a9a3302e24627dfb3c3f35a 100644 GIT binary patch delta 9082 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 c_?QY6opKUV5ajtQ1VPl?(OgDRkwdwp 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 Ce-c9g delta 56 zcmeA=z}R(wal;%rW+PLx&GY4+GlChN3e%ZDjLFK%@A-lBlnnORDH&otU`a)lm(~Cu C`Vw3K diff --git a/docs/_build/doctrees/IQM_Vis.utils.doctree b/docs/_build/doctrees/IQM_Vis.utils.doctree index 9845eb45218b828991a80de2e0d1af11411f0766..e48cfe7d3149bc9cb007d3be1b02f9abef8098b0 100644 GIT binary patch delta 22419 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 delta 21406 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 diff --git a/docs/_build/doctrees/environment.pickle b/docs/_build/doctrees/environment.pickle index 9950fbfab70066edc7692edeaac9f31fd20c3823..4b57c74b95ba34425def074a5130027496927214 100644 GIT binary patch delta 48709 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

-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

43dx7^H;rY}y?V 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 diff --git a/docs/_build/html/IQM_Vis.UI.html b/docs/_build/html/IQM_Vis.UI.html index d316f1a..9274ef9 100644 --- a/docs/_build/html/IQM_Vis.UI.html +++ b/docs/_build/html/IQM_Vis.UI.html @@ -245,11 +245,6 @@

Submodules -
-IQM_Vis.UI.experiment_mode.make_name_for_trans(trans)[source]
-
-
class IQM_Vis.UI.experiment_mode.reset_image_widget_to_black(time=0.1)[source]
@@ -290,6 +285,11 @@

Submoduleschange_data(ival, _redo_plots=True)[source]

+
+
+change_data_click_im(widget_ind, *args)[source]
+
+
change_metric_correlations_graph(add=1)[source]
@@ -300,6 +300,11 @@

Submoduleschange_metric_range_graph(add=1)[source]

+
+
+change_preview_images(ival)[source]
+
+
change_to_data_num(ind)[source]
@@ -390,11 +395,21 @@

Submodules +
+plot_metric_range_mlp(i)[source]
+

+
plot_radar_graph(results, i)[source]
+
+
+plot_radar_mlp(i)[source]
+
+
redo_plots(calc_range=False)[source]
@@ -405,6 +420,16 @@

Submodulesrequest_range_work

+
+
+set_preview_images(preview_num)[source]
+
+ +
+
+set_save_dir_mpl(i=0)[source]
+
+
stopped_range_worker(signal=False)[source]
@@ -453,7 +478,7 @@

Submodules
-class IQM_Vis.UI.main.make_app(app, data_stores: list, transformations: dict, metrics_info_format='graph', metrics_avg_graph=False, metric_range_graph=True, metric_params: dict = {}, image_display_size=300, default_save_dir='/home/matt/IQM-Vis-experiments', restrict_options=None, num_steps_range=11, num_step_experiment=6, test=False)[source]
+class IQM_Vis.UI.main.make_app(app, data_stores: list, transformations: dict, metrics_info_format='graph', metrics_avg_graph=False, metric_range_graph=True, metric_params: dict = {}, image_display_size=300, default_save_dir='/home/matt/IQM-Vis-experiments', restrict_options=None, num_steps_range=11, num_step_experiment=6, num_images_scroll_show=7, test=False)[source]

Bases: IQM_Vis.UI.widgets.widgets, IQM_Vis.UI.layout.layout, IQM_Vis.UI.images.images

@@ -461,6 +486,11 @@

Submodules +
+clear_all_cache_data()[source]
+

+
closeEvent(self, a0: Optional[QCloseEvent])[source]
@@ -658,6 +688,12 @@

Submodules +
+change_text_export_trans(trans)[source]
+

change colour of text when checkbox is pressed

+

+
colour_lineedit(widget, txt)[source]
@@ -683,6 +719,11 @@

Submodulesenable_settings_button()[source]

+
+
+export_trans_images()[source]
+
+
generic_value_change(key, param_group)[source]
@@ -704,6 +745,11 @@

Submodulesmake_slider_range(sliders_dict, key, _min, _max, num_steps=None)[source]

+
+
+open_mlp_new(mpl_canvas)[source]
+
+
reset_slider_group(param_group, redo_plots=False, display_images=True)[source]
diff --git a/docs/_build/html/IQM_Vis.data_handlers.html b/docs/_build/html/IQM_Vis.data_handlers.html index 1beb2ff..3a47871 100644 --- a/docs/_build/html/IQM_Vis.data_handlers.html +++ b/docs/_build/html/IQM_Vis.data_handlers.html @@ -108,6 +108,11 @@

Submodules +
+IQM_Vis.data_handlers.data_api.cache_tracked(func)[source]
+

+
class IQM_Vis.data_handlers.data_api.dataset_holder(image_list: list, metrics: dict = {}, metric_images: dict = {}, image_loader=<function load_image>, image_pre_processing=None, image_post_processing=None, image_list_to_transform=None, human_exp_csv=None)[source]
@@ -145,6 +150,11 @@

Submodulesadd_metric_image(key, value)[source]

+
+
+clear_all_cache()[source]
+
+
get_image_dataset_list()[source]
@@ -175,6 +185,11 @@

Submodulesget_reference_image()[source]

+
+
+get_reference_image_by_index(index)[source]
+
+
get_reference_image_name()[source]
@@ -251,6 +266,11 @@

Submodules class IQM_Vis.data_handlers.data_api_abstract.base_dataset_loader[source]

Bases: IQM_Vis.data_handlers.data_api_abstract.base_dataloader

+
+
+abstract get_reference_image_by_index(index)[source]
+
+

diff --git a/docs/_build/html/IQM_Vis.examples.html b/docs/_build/html/IQM_Vis.examples.html index 449c10c..93c1308 100644 --- a/docs/_build/html/IQM_Vis.examples.html +++ b/docs/_build/html/IQM_Vis.examples.html @@ -126,7 +126,7 @@

Submodules
-IQM_Vis.examples.dists.load_and_calibrate_image(file, max_luminance=200, size=256)[source]
+IQM_Vis.examples.dists.load_and_calibrate_image(file, max_luminance=200, size=512)[source]

diff --git a/docs/_build/html/IQM_Vis.utils.html b/docs/_build/html/IQM_Vis.utils.html index 1603416..1c4c5f4 100644 --- a/docs/_build/html/IQM_Vis.utils.html +++ b/docs/_build/html/IQM_Vis.utils.html @@ -100,7 +100,7 @@

Submodules
-IQM_Vis.utils.gui_utils.change_im(widget, im, resize=False, rgb_brightness=250, display_brightness=250)[source]
+IQM_Vis.utils.gui_utils.change_im(widget, im, resize=False, rgb_brightness=250, display_brightness=250, border=False)[source]

given a numpy image, changes the given widget Frame

@@ -493,6 +493,11 @@

Submodules +
+IQM_Vis.utils.save_utils.make_name_for_trans(trans)[source]
+
+
IQM_Vis.utils.save_utils.save_and_merge_df_as_csv(df, file)[source]
diff --git a/docs/_build/html/_modules/IQM_Vis/UI/experiment_mode.html b/docs/_build/html/_modules/IQM_Vis/UI/experiment_mode.html index c6256a9..8968b02 100644 --- a/docs/_build/html/_modules/IQM_Vis/UI/experiment_mode.html +++ b/docs/_build/html/_modules/IQM_Vis/UI/experiment_mode.html @@ -113,7 +113,7 @@

Source code for IQM_Vis.UI.experiment_mode

 import IQM_Vis
 from IQM_Vis.UI.custom_widgets import ClickLabel
 from IQM_Vis.UI import utils
-from IQM_Vis.utils import gui_utils, plot_utils, image_utils
+from IQM_Vis.utils import gui_utils, plot_utils, image_utils, save_utils
 
 
 
[docs]class make_experiment(QMainWindow): @@ -126,7 +126,7 @@

Source code for IQM_Vis.UI.experiment_mode

                  image_display_size,
                  rgb_brightness,
                  display_brightness,
-                 default_save_dir=IQM_Vis.utils.save_utils.DEFAULT_SAVE_DIR,
+                 default_save_dir=save_utils.DEFAULT_SAVE_DIR,
                  image_preprocessing='None',
                  image_postprocessing='None',
                  checked_metrics={}):
@@ -208,7 +208,7 @@ 

Source code for IQM_Vis.UI.experiment_mode

             ax.imshow(image_utils.calibrate_brightness(
                 trans['image'], self.rgb_brightness, self.display_brightness, ubyte=False))
             ax.axis('off')
-            ax.set_title(make_name_for_trans(trans), fontsize=6)
+ ax.set_title(save_utils.make_name_for_trans(trans), fontsize=6)
# self.widget_experiments[tab]['images'].figure.tight_layout() # time.sleep(5) @@ -233,7 +233,8 @@

Source code for IQM_Vis.UI.experiment_mode

             param = single_trans[trans_name]
             data = {'transform_name': trans_name,
                     'transform_value': param}
-            self.original_params_order.append(make_name_for_trans(data))
+            self.original_params_order.append(
+                save_utils.make_name_for_trans(data))
 
         # REFERENCE image
         self.ref_image = self.data_store.get_reference_image()
@@ -282,7 +283,7 @@ 

Source code for IQM_Vis.UI.experiment_mode

             for name, score in score_dict.items():
                 metrics.append(name)
                 scores.append(float(score))
-            IQM_scores[make_name_for_trans(data)] = scores
+            IQM_scores[save_utils.make_name_for_trans(data)] = scores
         IQM_scores['IQM'] = metrics
         self.IQM_scores_df = pd.DataFrame.from_dict(IQM_scores)
         self.IQM_scores_df.set_index('IQM', inplace=True)
@@ -511,16 +512,16 @@

Source code for IQM_Vis.UI.experiment_mode

             exp_save_dir = f'{self.default_save_dir}-experiment-{i}'
             if os.path.exists(exp_save_dir):
                 # get transform funcs and params
-                exp_trans_params = IQM_Vis.utils.save_utils.load_obj(
+                exp_trans_params = save_utils.load_obj(
                     os.path.join(exp_save_dir, 'transforms', 'transform_params.pkl'))
-                exp_trans_funcs = IQM_Vis.utils.save_utils.load_obj(
+                exp_trans_funcs = save_utils.load_obj(
                     os.path.join(exp_save_dir, 'transforms', 'transform_functions.pkl'))
                 
                 # get image processing saved params
-                processing_file = IQM_Vis.utils.save_utils.get_image_processing_file(exp_save_dir)
+                processing_file = save_utils.get_image_processing_file(exp_save_dir)
                 procesing_same = False
                 if os.path.exists(processing_file):
-                    processing = IQM_Vis.utils.save_utils.load_json_dict(processing_file)
+                    processing = save_utils.load_json_dict(processing_file)
                     if processing == self.processing:
                         procesing_same = True
 
@@ -540,34 +541,34 @@ 

Source code for IQM_Vis.UI.experiment_mode

         os.makedirs(os.path.join(self.default_save_dir, 'transforms'), exist_ok=True)
 
         # save experiment images
-        if not os.path.exists(IQM_Vis.utils.save_utils.get_original_image_file(self.default_save_dir)):
+        if not os.path.exists(save_utils.get_original_image_file(self.default_save_dir)):
             image_utils.save_image(self.ref_image,
-                                    IQM_Vis.utils.save_utils.get_original_image_file(self.default_save_dir))
-        if not os.path.exists(IQM_Vis.utils.save_utils.get_original_unprocessed_image_file(self.default_save_dir)):
+                                    save_utils.get_original_image_file(self.default_save_dir))
+        if not os.path.exists(save_utils.get_original_unprocessed_image_file(self.default_save_dir)):
             if hasattr(self, 'ref_image_unprocessed'):
                 image_utils.save_image(self.ref_image_unprocessed,
-                                        IQM_Vis.utils.save_utils.get_original_unprocessed_image_file(self.default_save_dir))
+                                        save_utils.get_original_unprocessed_image_file(self.default_save_dir))
         if new_dir == True:
             for trans in self.experiment_transforms:
                 image_utils.save_image(
-                    trans['image'], os.path.join(self.default_save_dir, 'images', f'{make_name_for_trans(trans)}.png'))
+                    trans['image'], os.path.join(self.default_save_dir, 'images', f'{save_utils.make_name_for_trans(trans)}.png'))
             # save the transformations
-            IQM_Vis.utils.save_utils.save_obj(
-                IQM_Vis.utils.save_utils.get_transform_params_file(self.default_save_dir),
+            save_utils.save_obj(
+                save_utils.get_transform_params_file(self.default_save_dir),
                 self.original_params_order)
-            IQM_Vis.utils.save_utils.save_obj(
-                IQM_Vis.utils.save_utils.get_transform_functions_file(self.default_save_dir),
+            save_utils.save_obj(
+                save_utils.get_transform_functions_file(self.default_save_dir),
                 dict(sorted(trans_funcs.items())))
             # save the image pre/post processing options
-            IQM_Vis.utils.save_utils.save_json_dict(
-                IQM_Vis.utils.save_utils.get_image_processing_file(self.default_save_dir),
+            save_utils.save_json_dict(
+                save_utils.get_image_processing_file(self.default_save_dir),
                 self.processing)
 
         # save the experiment results
         exp_order = []
         for trans in self.experiment_transforms:
-            exp_order.append(make_name_for_trans(trans))
-        csv_file = IQM_Vis.utils.save_utils.save_experiment_results(
+            exp_order.append(save_utils.make_name_for_trans(trans))
+        csv_file = save_utils.save_experiment_results(
             self.original_params_order,
             exp_order,
             self.default_save_dir,
@@ -645,7 +646,7 @@ 

Source code for IQM_Vis.UI.experiment_mode

         self.able_to_click = False
         # get comparison to pivot
         trans_str = image_name[len(self.image_name)+1:]
-        if trans_str != make_name_for_trans(self.pivot): # lower value
+        if trans_str != save_utils.make_name_for_trans(self.pivot): # lower value
             # If element smaller than pivot is found swap it with the greater element pointed by i
             self.less_than_pivot = True
         else:
@@ -674,10 +675,12 @@ 

Source code for IQM_Vis.UI.experiment_mode

         
         gui_utils.change_im(self.widget_experiments['exp']['A']['data'], A, resize=self.image_display_size,
                             rgb_brightness=self.rgb_brightness, display_brightness=self.display_brightness)
-        self.widget_experiments['exp']['A']['data'].setObjectName(f'{self.image_name}-{make_name_for_trans(A_trans)}')
+        self.widget_experiments['exp']['A']['data'].setObjectName(
+            f'{self.image_name}-{save_utils.make_name_for_trans(A_trans)}')
         gui_utils.change_im(self.widget_experiments['exp']['B']['data'], B, resize=self.image_display_size,
                             rgb_brightness=self.rgb_brightness, display_brightness=self.display_brightness)
-        self.widget_experiments['exp']['B']['data'].setObjectName(f'{self.image_name}-{make_name_for_trans(B_trans)}')
+ self.widget_experiments['exp']['B']['data'].setObjectName( + f'{self.image_name}-{save_utils.make_name_for_trans(B_trans)}')
''' UI '''
[docs] def init_style(self, style='light', css_file=None): @@ -748,10 +751,6 @@

Source code for IQM_Vis.UI.experiment_mode

     for i in inds:
         sorted_list1.append(list1[i])
     return sorted_list1
- -
[docs]def make_name_for_trans(trans): - splitter = '-----' - return f"{trans['transform_name']}{splitter}{trans['transform_value']}"
diff --git a/docs/_build/html/_modules/IQM_Vis/UI/images.html b/docs/_build/html/_modules/IQM_Vis/UI/images.html index e84911a..d5b680e 100644 --- a/docs/_build/html/_modules/IQM_Vis/UI/images.html +++ b/docs/_build/html/_modules/IQM_Vis/UI/images.html @@ -162,10 +162,55 @@

Source code for IQM_Vis.UI.images

     '''
     change image in dataset
     '''
-
[docs] def change_to_data_num(self, ind): - # change to an exact ind in the data list - be careful that the ind exists!!! - self.data_num = ind - self.change_data(0)
+
[docs] def change_preview_images(self, ival): + # have roll around scrolling + if self.preview_num + ival < 0: + self.preview_num = self.max_data_ind - self.num_images_scroll_show + 1 + if self.preview_num + ival < 0: # dataset is smaller than the number of images to show + self.preview_num = 0 + elif self.preview_num + ival + self.num_images_scroll_show > self.max_data_ind + 1: + self.preview_num = 0 + else: + self.preview_num += ival + self.set_preview_images(self.preview_num)
+ +
[docs] def set_preview_images(self, preview_num): + for data_store in self.data_stores: + for i in range(min(self.num_images_scroll_show, self.max_data_ind+1)): + im_preview_ind = preview_num + i + if im_preview_ind <= self.max_data_ind: + # load image + im_preview_data = data_store.get_reference_image_by_index(im_preview_ind) + self.widget_im_num_hash[i] = im_preview_ind + # set image preview size + scale = self.num_images_scroll_show - 1 + if isinstance(self.image_display_size, list) or isinstance(self.image_display_size, tuple): + preview_size = (self.image_display_size[0]//scale, self.image_display_size[1]//scale) + else: + preview_size = self.image_display_size//scale + # determine if we have the current display image + if self.data_num == im_preview_ind: + border = True + else: + border = False + gui_utils.change_im(self.widget_controls['images'][i], im_preview_data, + resize=preview_size, rgb_brightness=self.rgb_brightness, display_brightness=self.display_brightness, border=border) + self.widget_controls['label']['data_num'].setText( + f'({preview_num+1}-{im_preview_ind+1}/{self.max_data_ind+1})')
+ +
[docs] def change_data_click_im(self, widget_ind, *args): # args sent are position of mouse click on the image widget + self.change_to_data_num(self.widget_im_num_hash[widget_ind]) + self.set_preview_images(self.preview_num) # refresh boarder on image
+ +
[docs] def change_to_data_num(self, ind): # change to an exact ind in the data list + # check the num is within the data limits + if ind < 0: + return + elif ind > self.max_data_ind: + return + else: + self.data_num = ind + self.change_data(0) # 0 means dont increment data_num
[docs] def change_data(self, ival, _redo_plots=True): # reset any range/correlation data stored @@ -204,8 +249,7 @@

Source code for IQM_Vis.UI.images

                 self._load_experiment(self.human_experiment_cache[name], change_image=False)
             # otherwise from the datastore scores
             elif hasattr(data_store, 'human_scores'):
-                self.human_experiment_scores[i] = data_store.human_scores
-        self.widget_controls['label']['data_num'].setText(f'({self.data_num+1}/{self.max_data_ind+1})')
+ self.human_experiment_scores[i] = data_store.human_scores
[docs] def load_new_single_image(self): ''' change the image we are using ''' @@ -452,6 +496,28 @@

Source code for IQM_Vis.UI.images

                 axes = self.widget_row[i]['metrics']['range']['data']
                 plot = plot_utils.get_transform_range_plots(self.metric_over_range_results[i], trans_to_plot, axes, self.plot_data_lim)
                 plot.show()
+ +
[docs] def plot_metric_range_mlp(self, i): + # TODO: reduce copy of code from above function + # make sure we have somethign to plot + if not hasattr(self, 'metric_over_range_results'): + return + + # plot our data on a new axis + fig = gui_utils.plt.figure() + axes = fig.add_subplot(111) + all_trans = list(self.checked_transformations.keys()) + trans_to_plot = all_trans[self.metric_range_graph_num] + plot = plot_utils.get_transform_range_plots( + self.metric_over_range_results[i], trans_to_plot, axes, self.plot_data_lim) + plot.set_style() + fig.canvas.manager.set_window_title( + f"{self.data_stores[i].get_reference_image_name()}-{trans_to_plot}") + + self.set_save_dir_mpl(i) + + # show fig in new window + gui_utils.matplotlib.pyplot.show()
[docs] def change_metric_range_graph(self, add=1): max_graph_num = len(list(self.checked_transformations.keys())) @@ -496,6 +562,47 @@

Source code for IQM_Vis.UI.images

             axes = self.widget_row[i]['metrics']['avg']['data']
             radar_plotter = plot_utils.get_radar_plots_avg_plots(results, metrics_names, transformation_names, axes, self.plot_data_lim)
             radar_plotter.show()
+ +
[docs] def plot_radar_mlp(self, i): + # TODO: reduce copy of code from above function + # make sure we have somethign to plot + if not hasattr(self, 'metric_over_range_results'): + return + + # plot our data on a new axis + fig = gui_utils.plt.figure() + axes = fig.add_subplot(projection='polar') + all_trans = list(self.checked_transformations.keys()) + transformation_names = list(self.sliders['transforms'].keys()) + if 'avg' in self.widget_row[i]['metrics'].keys(): + # get current metrics used for this data_store + metrics_names = [] + for metric in self.data_stores[i].metrics: + if metric in self.checked_metrics: + metrics_names.append(metric) + + if len(metrics_names) == 0: + return + + plot = plot_utils.get_radar_plots_avg_plots( + self.metric_over_range_results[i], metrics_names, transformation_names, axes, self.plot_data_lim) + plot.set_style() + + fig.canvas.manager.set_window_title( + f"{self.data_stores[i].get_reference_image_name()}-radar") + + self.set_save_dir_mpl(i) + + # show fig in new window + gui_utils.matplotlib.pyplot.show()
+ +
[docs] def set_save_dir_mpl(self, i=0): + # set the default save path + image_name = f"{self.data_stores[i].get_reference_image_name()}-export" + save_path = os.path.join(self.default_save_dir, image_name) + if not os.path.exists(save_path): + os.makedirs(save_path) + gui_utils.matplotlib.rcParams['savefig.directory'] = save_path
''' metric correlation plots diff --git a/docs/_build/html/_modules/IQM_Vis/UI/layout.html b/docs/_build/html/_modules/IQM_Vis/UI/layout.html index f47a14b..a6736e1 100644 --- a/docs/_build/html/_modules/IQM_Vis/UI/layout.html +++ b/docs/_build/html/_modules/IQM_Vis/UI/layout.html @@ -165,6 +165,9 @@

Source code for IQM_Vis.UI.layout

                 graph = QGridLayout()
                 graph.addWidget(self.widget_row[i]['metrics']['avg']['data'], 0, 0, im_height, im_width)
                 avg_graph.addLayout(graph)   # need for matplotlib? - test this...   (grid)
+                graph_save = QHBoxLayout()
+                graph_save.addWidget(self.widget_row[i]['metrics']['avg']['save_button'])
+                avg_graph.addLayout(graph_save)
                 utils.add_layout_to_tab(self.tabs['graph'], avg_graph, 'Radar')
             if 'range' in self.widget_row[i]['metrics'].keys():
                 range_graph = QVBoxLayout()
@@ -177,6 +180,9 @@ 

Source code for IQM_Vis.UI.layout

                 graph_controls.addWidget(self.widget_controls['button']['prev_metric_graph'])
                 graph_controls.addWidget(self.widget_controls['button']['next_metric_graph'])
                 range_graph.addLayout(graph_controls)
+                graph_save = QHBoxLayout()
+                graph_save.addWidget(self.widget_row[i]['metrics']['range']['save_button'])
+                range_graph.addLayout(graph_save)
                 utils.add_layout_to_tab(self.tabs['graph'], range_graph, 'Range')
             if 'correlation' in self.widget_row[i]['metrics'].keys():
                 correlation_graph = QVBoxLayout()
@@ -201,6 +207,8 @@ 

Source code for IQM_Vis.UI.layout

         if self.dataset:
             dataset_layout.addWidget(self.widget_controls['label']['data'])
             dataset_layout.addWidget(self.widget_controls['button']['prev_data'])
+            for im in range(self.num_images_scroll_show):
+                dataset_layout.addWidget(self.widget_controls['images'][im])
             dataset_layout.addWidget(self.widget_controls['button']['next_data'])
             dataset_layout.addWidget(self.widget_controls['label']['data_num'])
 
@@ -264,16 +272,43 @@ 

Source code for IQM_Vis.UI.layout

                 experiment_trans.addStretch()
             experiment_controls.addLayout(experiment_trans)
         experiment_controls.addStretch()
+        # Save folder
+        save_button_exp = QHBoxLayout()
+        save_button_exp.addWidget(self.widget_controls['label']['exp_change_save'])
+        save_button_exp.addWidget(self.widget_controls['button']['exp_change_save'])
+        save_button_exp.addStretch()
+        experiment_controls.addLayout(save_button_exp)
         # run experiment button
         experiment_button = QHBoxLayout()
         experiment_button.addWidget(self.widget_controls['button']['launch_exp'])
         experiment_button.addStretch()
         experiment_controls.addLayout(experiment_button)
 
+        '''export images'''
+        export_controls = QVBoxLayout()
+        for trans_name in self.widget_export:
+            export_trans = QHBoxLayout()
+            for _, widget in self.widget_export[trans_name].items():
+                export_trans.addWidget(widget)
+                export_trans.addStretch()
+            export_controls.addLayout(export_trans)
+        export_controls.addStretch()
+        # Save folder
+        save_button_exp = QHBoxLayout()
+        save_button_exp.addWidget(self.widget_controls['label']['export_change_save'])
+        save_button_exp.addWidget(self.widget_controls['button']['export_change_save'])
+        save_button_exp.addStretch()
+        export_controls.addLayout(save_button_exp)
+        # export images button
+        export_button = QHBoxLayout()
+        export_button.addWidget(self.widget_controls['button']['export_images'])
+        export_button.addStretch()
+        export_controls.addLayout(export_button)
+
         ''' add to parameter controls tab'''
         self.tabs['slider'] = QTabWidget()
-        for tab_layout, tab_name in zip([image_controls, metric_controls, settings_controls, experiment_controls],
-                                        ['transforms', 'metric params', 'image settings', 'experiment']):
+        for tab_layout, tab_name in zip([image_controls, metric_controls, settings_controls, experiment_controls, export_controls],
+                                        ['transforms', 'metric params', 'image settings', 'experiment', 'export']):
             utils.add_layout_to_tab(self.tabs['slider'], tab_layout, tab_name)
 
         '''re calc graphs button'''
diff --git a/docs/_build/html/_modules/IQM_Vis/UI/main.html b/docs/_build/html/_modules/IQM_Vis/UI/main.html
index 1cca417..cf07b24 100644
--- a/docs/_build/html/_modules/IQM_Vis/UI/main.html
+++ b/docs/_build/html/_modules/IQM_Vis/UI/main.html
@@ -112,6 +112,7 @@ 

Source code for IQM_Vis.UI.main

                  restrict_options=None,
                  num_steps_range=11,
                  num_step_experiment=6,
+                 num_images_scroll_show=7,
                  test=False
                  ):
         super().__init__()
@@ -120,6 +121,8 @@ 

Source code for IQM_Vis.UI.main

         self.transformations = transformations
         self.num_steps_range = num_steps_range
         self.num_step_experiment = num_step_experiment
+        self.num_images_scroll_show = num_images_scroll_show
+        self.preview_num = 0
         self.test = test
 
         self.metrics_info_format = metrics_info_format
@@ -192,7 +195,12 @@ 

Source code for IQM_Vis.UI.main

 
         load_transforms.triggered.connect(self.load_all_transforms)
         load_metrics.triggered.connect(self.load_all_metrics)
-        load_metric_images.triggered.connect(self.load_all_metric_images)
+ load_metric_images.triggered.connect(self.load_all_metric_images) + + self.cache_menu = self.menu_bar.addMenu('Cache') + clear_all_cache = self.cache_menu.addAction('Clear All Cache') + + clear_all_cache.triggered.connect(self.clear_all_cache_data)
[docs] def load_all_transforms(self): @@ -221,6 +229,12 @@

Source code for IQM_Vis.UI.main

         self._remake_menu()
         self.construct_UI()
+
[docs] def clear_all_cache_data(self): + for data_store in self.data_stores: + if hasattr(data_store, 'clear_all_cache'): + data_store.clear_all_cache() + self.status_bar.showMessage('Cleared all cache data', 8000)
+
[docs] def quit(self): # QApplication.instance().quit() self.app.quit()
@@ -256,33 +270,48 @@

Source code for IQM_Vis.UI.main

 
 
[docs] def get_menu_checkboxes(self): ''' list all trans/metrics in the menu drop downs ''' - # transformations self.menu_options = {'transforms': {}, 'metrics': {}, 'metric_images': {}} + # check if we need to restore current checked + if hasattr(self, 'restore_checked_menu_items'): + restrict_options = self.restore_checked_menu_items + else: # or building for the first time + restrict_options = self.restrict_options + + # make menus set_checked_menu_from_iterable(self.menu_bar, self.transformations, 'Transforms', self.menu_options['transforms'], self.construct_UI, - self.restrict_options['transforms']) + restrict_options['transforms']) set_checked_menu_from_iterable(self.menu_bar, self.data_stores[0].metric_images, 'Metric Images', self.menu_options['metric_images'], self.construct_UI, - self.restrict_options['metric_images']) + restrict_options['metric_images']) set_checked_menu_from_iterable(self.menu_bar, self.data_stores[0].metrics, 'Metrics', self.menu_options['metrics'], self.construct_UI, - self.restrict_options['metrics'])
+ restrict_options['metrics'])
def _remake_menu(self): + self._save_checked_menu_items() self.menu_bar.clear() self.make_menu() + def _save_checked_menu_items(self): + self.restore_checked_menu_items = {} + for menu in ['transforms', 'metric_images', 'metrics']: + self.restore_checked_menu_items[menu] = {} + for item in self.menu_options[menu]: + self.restore_checked_menu_items[menu][item] = self.menu_options[menu][item].isChecked() + +
[docs] def make_status_bar(self): self.status_bar = self.statusBar() self.pbar = ProgressBar(self, minimum=0, maximum=100, textVisible=False, @@ -330,6 +359,8 @@

Source code for IQM_Vis.UI.main

         self.init_style()     # layout.py
         self.init_widgets()   # widgets.py
         self.change_data(0, _redo_plots=True)   # images.py
+        if self.dataset:
+            self.set_preview_images(self.preview_num)
         self.main = self.init_layout()    # layout.py
         self.tabs['slider'].setCurrentIndex(tabs_index['slider'])
         self.tabs['graph'].setCurrentIndex(tabs_index['graph'])
@@ -386,7 +417,9 @@ 

Source code for IQM_Vis.UI.main

             return
         
         self.default_save_dir = dir
-        self.status_bar.showMessage(f'Changed save dir to: {self.default_save_dir}', 8000)
+ self.status_bar.showMessage(f'Changed save dir to: {self.default_save_dir}', 8000) + self.widget_controls['label']['exp_change_save'].setText(f'Save Folder: {self.default_save_dir}') + self.widget_controls['label']['export_change_save'].setText(f'Save Folder: {self.default_save_dir}')
[docs]def set_checked_menu_from_iterable(main_menu, iterable, name, action_store, connect_func, restrict_options=None): @@ -400,6 +433,11 @@

Source code for IQM_Vis.UI.main

                 action_store[trans].setChecked(True)
             else:
                 action_store[trans].setChecked(False)
+        elif isinstance(restrict_options, dict):
+            if trans in restrict_options.keys():
+                action_store[trans].setChecked(restrict_options[trans])
+            else:
+                action_store[trans].setChecked(False)
         else:
             action_store[trans].setChecked(True)
diff --git a/docs/_build/html/_modules/IQM_Vis/UI/widgets.html b/docs/_build/html/_modules/IQM_Vis/UI/widgets.html index c092459..6ed73bb 100644 --- a/docs/_build/html/_modules/IQM_Vis/UI/widgets.html +++ b/docs/_build/html/_modules/IQM_Vis/UI/widgets.html @@ -91,7 +91,9 @@

Source code for IQM_Vis.UI.widgets

 # License: BSD 3-Clause License
 
 import re
+import os
 from functools import partial
+import datetime
 
 import numpy as np
 from PyQt6.QtWidgets import QPushButton, QLabel, QSlider, QCheckBox, QComboBox, QLineEdit
@@ -100,7 +102,7 @@ 

Source code for IQM_Vis.UI.widgets

 
 import IQM_Vis
 from IQM_Vis.UI.custom_widgets import ClickLabel
-from IQM_Vis.utils import gui_utils, plot_utils, image_utils
+from IQM_Vis.utils import gui_utils, plot_utils, image_utils, save_utils
 
 # sub class used by IQM_Vis.main.make_app to initialise widgets and general UI functions for widgets
 
[docs]class widgets(): @@ -116,6 +118,7 @@

Source code for IQM_Vis.UI.widgets

         '''
         create all the widgets we need and init params
         '''
+        self.tool_tip_style = """QToolTip {background-color: black; color: white; border: black solid 1px}"""
         # first setup the slider data
         self.sliders = {'transforms': {}, 'metric_params': {}}
         self._init_sliders(self.sliders['transforms'], self.checked_transformations,  param_group='transforms')
@@ -157,7 +160,7 @@ 

Source code for IQM_Vis.UI.widgets

                 self.widget_row[i]['metrics']['info']['data'] = QLabel(self)
                 self.widget_row[i]['metrics']['info']['data'].setAlignment(Qt.AlignmentFlag.AlignCenter)
                 self.widget_row[i]['metrics']['info']['data'].setText('')
-            # metrics avgerage graphs
+            # metrics average graphs
             if self.metrics_avg_graph:
                 self.widget_row[i]['metrics']['avg'] = {}
                 self.widget_row[i]['metrics']['avg']['label'] = QLabel(self)
@@ -165,33 +168,42 @@ 

Source code for IQM_Vis.UI.widgets

                 self.widget_row[i]['metrics']['avg']['label'].setText('IQM Averages')
                 self.widget_row[i]['metrics']['avg']['data'] = gui_utils.MplCanvas(size=(self.graph_size/10, self.graph_size/10), polar=True)
                 self.widget_row[i]['metrics']['avg']['data'].setToolTip('Mean metric value over the range of each transform.')
+                self.widget_row[i]['metrics']['avg']['data'].setStyleSheet(self.tool_tip_style)
+                self.widget_row[i]['metrics']['avg']['save_button'] = QPushButton('Adjust or Save', self)
+                self.widget_row[i]['metrics']['avg']['save_button'].clicked.connect(partial(self.plot_radar_mlp, i))
             if self.metric_range_graph:
                 self.widget_row[i]['metrics']['range'] = {}
                 self.widget_row[i]['metrics']['range']['label'] = QLabel(self)
                 self.widget_row[i]['metrics']['range']['label'].setAlignment(Qt.AlignmentFlag.AlignCenter)
                 self.widget_row[i]['metrics']['range']['label'].setText('Response Profiles')
                 self.widget_row[i]['metrics']['range']['data'] = gui_utils.MplCanvas(size=(self.graph_size/10, self.graph_size/10))
-                self.widget_row[i]['metrics']['range']['data'].setToolTip('Single tranformation value range for all metrics.')
+                self.widget_row[i]['metrics']['range']['data'].setToolTip('Single transformation value range for all metrics.')
+                self.widget_row[i]['metrics']['range']['data'].setStyleSheet(self.tool_tip_style)
+                self.widget_row[i]['metrics']['range']['save_button'] = QPushButton('Adjust or Save', self)
+                self.widget_row[i]['metrics']['range']['save_button'].clicked.connect(partial(self.plot_metric_range_mlp, i))
             self.widget_row[i]['metrics']['correlation'] = {}
             self.widget_row[i]['metrics']['correlation']['label'] = QLabel(self)
             self.widget_row[i]['metrics']['correlation']['label'].setAlignment(Qt.AlignmentFlag.AlignCenter)
             self.widget_row[i]['metrics']['correlation']['label'].setText('Human Correlation')
             self.widget_row[i]['metrics']['correlation']['data'] = gui_utils.MplCanvas(size=(self.graph_size/10, self.graph_size/10))
             self.widget_row[i]['metrics']['correlation']['data'].setToolTip('Human scores versus IQMs.\nMean shown with points\nStandard deviation shown with bars.\nClick points to show image.')
+            self.widget_row[i]['metrics']['correlation']['data'].setStyleSheet(self.tool_tip_style)
 
 
         '''buttons'''
-        self.widget_controls = {'button': {}, 'slider': {}, 'label': {}, 'check_box': {}}
+        self.widget_controls = {'button': {}, 'slider': {}, 'label': {}, 'check_box': {}, 'images': {}}
         
         if (self.metrics_avg_graph or self.metric_range_graph):
             # Update graphs
             self.widget_controls['button']['force_update'] = QPushButton('Update Graphs', self)
             self.widget_controls['button']['force_update'].setToolTip('Update graphs using all the current slider values.')
+            self.widget_controls['button']['force_update'].setStyleSheet(self.tool_tip_style)
             self.widget_controls['button']['force_update'].clicked.connect(self.display_images)
             self.widget_controls['button']['force_update'].clicked.connect(partial(self.redo_plots, True))
             # Change plot limits
             self.widget_controls['check_box']['graph_limits'] = QCheckBox('Squeeze plots')
             self.widget_controls['check_box']['graph_limits'].setToolTip('Set the scale of the plots to the metric data range.')
+            self.widget_controls['check_box']['graph_limits'].setStyleSheet(self.tool_tip_style)
             self.widget_controls['check_box']['graph_limits'].setCheckState(Qt.CheckState.Unchecked)
             self.widget_controls['check_box']['graph_limits'].stateChanged.connect(self.change_plot_lims)
 
@@ -210,13 +222,19 @@ 

Source code for IQM_Vis.UI.widgets

         if self.dataset:
             # control what image is used from the dataset
             self.widget_controls['button']['next_data'] = QPushButton('->', self)
-            self.widget_controls['button']['next_data'].clicked.connect(partial(self.change_data, 1, True))
+            self.widget_controls['button']['next_data'].clicked.connect(partial(self.change_preview_images, 1))
             self.widget_controls['button']['prev_data'] = QPushButton('<-', self)
-            self.widget_controls['button']['prev_data'].clicked.connect(partial(self.change_data, -1, True))
+            self.widget_controls['button']['prev_data'].clicked.connect(partial(self.change_preview_images, -1))
             self.widget_controls['label']['data'] = QLabel(self)
             self.widget_controls['label']['data'].setText('Change Image:')
             self.widget_controls['label']['data_num'] = QLabel(self)
             self.widget_controls['label']['data_num'].setText('1/1')
+            self.widget_im_num_hash = {}
+            for im in range(self.num_images_scroll_show):
+                self.widget_controls['images'][im] = QLabel( self)
+                self.widget_controls['images'][im].setAlignment(Qt.AlignmentFlag.AlignCenter)
+                self.widget_controls['images'][im].mousePressEvent = partial(self.change_data_click_im, im)
+                self.widget_im_num_hash[im] = im # store the ind number of each im widget preview
 
         # launch experiment button
         self.widget_controls['button']['launch_exp'] = QPushButton('Run Experiment', self)
@@ -224,6 +242,10 @@ 

Source code for IQM_Vis.UI.widgets

         # load experiment button
         self.widget_controls['button']['load_exp'] = QPushButton('Load Experiment', self)
         self.widget_controls['button']['load_exp'].clicked.connect(self.load_experiment_from_dir)
+        # export images button
+        self.widget_controls['button']['export_images'] = QPushButton('Export Images', self)
+        self.widget_controls['button']['export_images'].clicked.connect(self.export_trans_images)
+        
 
 
         '''sliders'''
@@ -289,6 +311,50 @@ 

Source code for IQM_Vis.UI.widgets

             self.widget_experiment_params[trans_name]['steps_edit'].setValidator(QIntValidator())
             self.widget_experiment_params[trans_name]['steps_edit'].setMaxLength(2)
             self.widget_experiment_params[trans_name]['steps_edit'].setText(f"{self.num_step_experiment}")
+        # change save folder button
+        self.widget_controls['label']['exp_change_save'] = QLabel(self)
+        self.widget_controls['label']['exp_change_save'].setText(f'Save Folder: {self.default_save_dir}')
+        self.widget_controls['button']['exp_change_save'] = QPushButton('Change', self)
+        self.widget_controls['button']['exp_change_save'].clicked.connect(self.change_save_folder)
+
+        ''' export options '''
+        self.widget_export = {}
+        
+        for trans_name, deets in self.checked_transformations.items():
+            self.widget_export[trans_name] = {}
+            self.widget_export[trans_name]['check_box'] = QCheckBox(self)
+            self.widget_export[trans_name]['check_box'].setChecked(True)
+            self.widget_export[trans_name]['check_box'].stateChanged.connect(partial(self.change_text_export_trans,
+                                                                                                  trans=trans_name))
+
+            self.widget_export[trans_name]['name'] = QLabel(self)
+            self.widget_export[trans_name]['name'].setText(trans_name)
+
+            self.widget_export[trans_name]['min'] = QLabel(self)
+            self.widget_export[trans_name]['min'].setText('min:')
+            self.widget_export[trans_name]['min_edit'] = QLineEdit()
+            self.widget_export[trans_name]['min_edit'].setValidator(get_float_validator())
+            self.widget_export[trans_name]['min_edit'].textChanged.connect(partial(self.colour_lineedit, self.widget_export[trans_name]['min_edit']))
+            self.widget_export[trans_name]['min_edit'].setText(f"{deets['min']}")
+
+            self.widget_export[trans_name]['max'] = QLabel(self)
+            self.widget_export[trans_name]['max'].setText('max:')
+            self.widget_export[trans_name]['max_edit'] = QLineEdit()
+            self.widget_export[trans_name]['max_edit'].setValidator(get_float_validator())
+            self.widget_export[trans_name]['max_edit'].textChanged.connect(partial(self.colour_lineedit, self.widget_export[trans_name]['max_edit']))
+            self.widget_export[trans_name]['max_edit'].setText(f"{deets['max']}")
+
+            self.widget_export[trans_name]['steps'] = QLabel(self)
+            self.widget_export[trans_name]['steps'].setText('steps:')
+            self.widget_export[trans_name]['steps_edit'] = QLineEdit()
+            self.widget_export[trans_name]['steps_edit'].setValidator(QIntValidator())
+            self.widget_export[trans_name]['steps_edit'].setMaxLength(2)
+            self.widget_export[trans_name]['steps_edit'].setText(f"{self.num_steps_range}")
+        # change save folder button
+        self.widget_controls['label']['export_change_save'] = QLabel(self)
+        self.widget_controls['label']['export_change_save'].setText(f'Save Folder: {self.default_save_dir}')
+        self.widget_controls['button']['export_change_save'] = QPushButton('Change', self)
+        self.widget_controls['button']['export_change_save'].clicked.connect(self.change_save_folder)
 
 
     '''
@@ -376,7 +442,7 @@ 

Source code for IQM_Vis.UI.widgets

                 if str(data_store.image_pre_processing) not in [str(f) for f in self.pre_processing_options.values()]:
                     name = f"Custom {i}"
                     self.pre_processing_options[name] = data_store.image_pre_processing
-                    init_val = name
+                    self.pre_processing_option = name
         combobox_pre = QComboBox()
         combobox_pre.addItems(list(self.pre_processing_options.keys()))
         combobox_pre.setCurrentText(self.pre_processing_option)
@@ -396,7 +462,7 @@ 

Source code for IQM_Vis.UI.widgets

                 if data_store.image_post_processing not in list(self.post_processing_options.values()):
                     name = f"Custom {i}"
                     self.post_processing_options[name] = data_store.image_post_processing
-                    init_val = name
+                    self.post_processing_option = name
         combobox_post = QComboBox()
         combobox_post.addItems(list(self.post_processing_options.keys()))
         combobox_post.setCurrentText(self.post_processing_option)
@@ -643,7 +709,71 @@ 

Source code for IQM_Vis.UI.widgets

             self.status_bar.showMessage(v, time)
''' - experimetns + export controls + ''' +
[docs] def change_text_export_trans(self, trans): + ''' change colour of text when checkbox is pressed ''' + checked = self.widget_export[trans]['check_box'].isChecked() + for widget in self.widget_export[trans]: + if widget == 'check_box': + pass + else: + self.widget_export[trans][widget].setEnabled(checked) + if checked == True: + self.widget_export[trans][widget].setStyleSheet(f"QLineEdit {{color: {self.settings_text_colour_original};}}\nQLabel {{color: {self.settings_text_colour_original};}}") + else: + self.widget_export[trans][widget].setStyleSheet(f"QLineEdit {{color: gray;}}\nQLabel {{color: gray;}}")
+ +
[docs] def export_trans_images(self): + # make save folder + image_name = f"{self.data_stores[0].get_reference_image_name()}-export" + + save_folder = os.path.join( + self.default_save_dir, image_name, f"images-{str(datetime.datetime.now()).split('.')[0]}") + if not os.path.exists(save_folder): + os.makedirs(save_folder) + + # save original image + ref_image = self.data_stores[0].get_reference_image() + image_utils.save_image(ref_image, + os.path.join(save_folder, f"reference.png")) + + # make and save transforms + checked_transforms = {} + for trans in self.widget_export: + if self.widget_export[trans]['check_box'].isChecked(): + data = {'min': make_float_from_text(self.widget_export[trans]['min_edit'].text()), + 'max': make_float_from_text(self.widget_export[trans]['max_edit'].text()), + 'num_steps': int(self.widget_export[trans]['steps_edit'].text()), + 'function': self.checked_transformations[trans]['function'] + } + name = self.widget_export[trans]['name'].text() + checked_transforms[name] = data + + export_images = plot_utils.get_all_single_transform_params( + checked_transforms, num_steps='from_dict') + + # remove any params with value 0 + export_images = [x for x in export_images if not x[list(x.keys())[0]] == 0] + + # make and save images + for single_trans in export_images: + trans_name = list(single_trans.keys())[0] + param = single_trans[trans_name] + img = image_utils.get_transform_image(self.data_stores[0], + transform_functions={trans_name: self.checked_transformations[trans_name]}, + transform_params={trans_name: param}) + trans_info = {'transform_name': trans_name, 'transform_value': param} + image_utils.save_image(img, os.path.join( + save_folder, f'{save_utils.make_name_for_trans(trans_info)}.png')) + self.status_bar.showMessage(f'Images saved to {save_folder}', 5000)
+ +
[docs] def open_mlp_new(self, mpl_canvas): + fig = gui_utils.break_out_mlp(mpl_canvas) + fig.show()
+ + ''' + experiments '''
[docs] def change_text_exp_trans(self, trans): ''' change colour of text when checkbox is pressed ''' diff --git a/docs/_build/html/_modules/IQM_Vis/data_handlers/data_api.html b/docs/_build/html/_modules/IQM_Vis/data_handlers/data_api.html index e7cd29f..2cbe3bb 100644 --- a/docs/_build/html/_modules/IQM_Vis/data_handlers/data_api.html +++ b/docs/_build/html/_modules/IQM_Vis/data_handlers/data_api.html @@ -93,7 +93,7 @@

Source code for IQM_Vis.data_handlers.data_api

import os import imghdr -from functools import cache +from functools import cache, lru_cache from collections import namedtuple import numpy as np import pandas as pd @@ -101,6 +101,15 @@

Source code for IQM_Vis.data_handlers.data_api

from IQM_Vis.data_handlers import base_dataloader, base_dataset_loader +# keep a track of all the cached functions so we can clear them easily +CACHED_FUNCTIONS = [] +# custom decorator to cache functions and store which are cached +

[docs]def cache_tracked(func): + cached_func = lru_cache(maxsize=None)(func) + CACHED_FUNCTIONS.append(cached_func) + return cached_func
+ +
[docs]class cache_metric_call: ''' cache metric fucntions that have been calculated already to do this we need to convert numpy arrays to a hashable object (since arrs are mutable) @@ -109,7 +118,7 @@

Source code for IQM_Vis.data_handlers.data_api

def __init__(self, metric): self.metric = metric -

[docs] @cache +
[docs] @cache_tracked def __call__(self, ref, trans, **kwargs): # expect a hashable bytes array tuple as input with the data type and shape # N.B. we need to copy the array since from buffer gives a read only array since @@ -206,7 +215,7 @@

Source code for IQM_Vis.data_handlers.data_api

self.image_post_processing_hash = None self.current_file = self.image_list[i] image_name_ref = get_image_name(self.current_file) - image_data_ref = self.image_loader(self.current_file) + image_data_ref = self._cached_image_loader(self.current_file) self.reference_unprocessed = image_data_ref if self.image_pre_processing is not None: image_data_ref = self.image_pre_processing(image_data_ref) @@ -219,7 +228,8 @@

Source code for IQM_Vis.data_handlers.data_api

self.image_to_transform = self.image_storer(image_name_ref, image_data_ref) else: image_name_trans = get_image_name(self.image_list_to_transform[i]) - image_data_trans = self.image_loader(self.image_list_to_transform[i]) + image_data_trans = self._cached_image_loader( + self.image_list_to_transform[i]) if self.image_pre_processing is not None: image_data_trans = self.image_pre_processing(image_data_trans) self.image_reference = self.image_storer(image_name_trans, image_data_trans) @@ -237,6 +247,17 @@

Source code for IQM_Vis.data_handlers.data_api

def __getitem__(self, i): self._load_image_data(i) + @cache_tracked + def _cached_image_loader(self, file_name): + return self.image_loader(file_name) + +

[docs] def get_reference_image_by_index(self, index): + if index >= len(self.image_list): + raise IndexError('Index out of range of the length of the image list') + file_name = self.image_list[index] + image_data = self._cached_image_loader(file_name) + return image_data
+
[docs] def get_reference_image_name(self): return self.image_reference.name
@@ -297,7 +318,11 @@

Source code for IQM_Vis.data_handlers.data_api

for item in input_types: if type(item[0]) != item[1]: var_name = f'{item[0]=}'.split('=')[0] - raise TypeError(f'holder input: {var_name} should be a {item[1]} not {type(item[0])}')

+ raise TypeError(f'holder input: {var_name} should be a {item[1]} not {type(item[0])}') + +
[docs] def clear_all_cache(self): + for cached_func in CACHED_FUNCTIONS: + cached_func.cache_clear()
[docs]def get_image_name(file_path): diff --git a/docs/_build/html/_modules/IQM_Vis/data_handlers/data_api_abstract.html b/docs/_build/html/_modules/IQM_Vis/data_handlers/data_api_abstract.html index 5760a7b..7fb6241 100644 --- a/docs/_build/html/_modules/IQM_Vis/data_handlers/data_api_abstract.html +++ b/docs/_build/html/_modules/IQM_Vis/data_handlers/data_api_abstract.html @@ -141,7 +141,11 @@

Source code for IQM_Vis.data_handlers.data_api_abstract

@abstractmethod def __getitem__(self): - pass
+ pass + +
[docs] @abstractmethod + def get_reference_image_by_index(self, index): + pass
diff --git a/docs/_build/html/_modules/IQM_Vis/examples/dists.html b/docs/_build/html/_modules/IQM_Vis/examples/dists.html index d4b3e7e..af3a40b 100644 --- a/docs/_build/html/_modules/IQM_Vis/examples/dists.html +++ b/docs/_build/html/_modules/IQM_Vis/examples/dists.html @@ -99,7 +99,7 @@

Source code for IQM_Vis.examples.dists

 
 
 '''Textures calibrated image loader'''
-
[docs]def load_and_calibrate_image(file, max_luminance=200, size=256): +
[docs]def load_and_calibrate_image(file, max_luminance=200, size=512): # Calculate max luminance value in the whole dataset img = Image.open(file) meta_dict = {TAGS[key] : img.tag[key] for key in img.tag_v2} @@ -167,48 +167,47 @@

Source code for IQM_Vis.examples.dists

 
[docs]def run(): # metrics functions must return a single value metric = {'DISTS': IQM_Vis.IQMs.DISTS(), - 'MAE': IQM_Vis.IQMs.MAE(), + 'LPIPS': IQM_Vis.IQMs.LPIPS(), '1-SSIM': IQM_Vis.IQMs.SSIM(), - '1-MS_SSIM': IQM_Vis.IQMs.MS_SSIM(), - 'NLPD': IQM_Vis.IQMs.NLPD(), - # 'LPIPS': IQM_Vis.IQMs.LPIPS(), + 'MAE': IQM_Vis.IQMs.MAE(), + # '1-MS_SSIM': IQM_Vis.IQMs.MS_SSIM(), + # 'NLPD': IQM_Vis.IQMs.NLPD(), } # metrics images return a numpy image - dont include any for this example metric_images = {} # make dataset list of images - files = sorted(glob.glob('/home/matt/datasets/Textures/*')) + files = sorted(glob.glob(os.path.join(os.path.expanduser('~'), 'datasets', 'Textures', '*'))) + if len(files) == 0: + raise ValueError('No files found in the dataset directory - please download the texture dataset') + data = IQM_Vis.dataset_holder(files, metric, metric_images, - load_and_calibrate_image, - image_post_processing=IQM_Vis.utils.image_utils.crop_centre) + image_loader=load_and_calibrate_image, + image_pre_processing=lambda x: x, # no resize at start up + image_post_processing=lambda x: IQM_Vis.utils.image_utils.crop_centre( + x, scale_factor=2, keep_size=False) + ) # define the transformations transformations = { - 'rotation':{'min':-10, 'max':10, 'function':IQM_Vis.transforms.rotation}, # normal input - 'x_shift': {'min':-0.1, 'max':0.1, 'function':IQM_Vis.transforms.x_shift, 'init_value': 0.0}, - 'y_shift': {'min':-0.1, 'max':0.1, 'function':IQM_Vis.transforms.y_shift, 'init_value': 0.0}, + 'rotation':{'min':-12, 'max':12, 'function':IQM_Vis.transforms.rotation}, # normal input + 'x_shift': {'min':-0.2, 'max':0.2, 'function':IQM_Vis.transforms.x_shift, 'init_value': 0.0}, + # 'y_shift': {'min':-0.1, 'max':0.1, 'function':IQM_Vis.transforms.y_shift, 'init_value': 0.0}, 'zoom': {'min': 0.8, 'max':1.2, 'function':IQM_Vis.transforms.zoom_image, 'init_value': 1.0}, # requires non standard slider params - 'brightness':{'min':-1.0, 'max':1.0, 'function':IQM_Vis.transforms.brightness}, # normal but with float - 'contrast': {'min': 0.5, 'max': 2.5, 'init_value': 1.0, 'function': IQM_Vis.transforms.contrast}, - 'hue': {'min': -0.5, 'max': 0.5, 'function': IQM_Vis.transforms.hue}, - 'saturation': {'min': -0.5, 'max': 0.5, 'function': IQM_Vis.transforms.saturation}, - 'jpg compr':{'init_value':101, 'min':1, 'max':101, 'function':IQM_Vis.transforms.jpeg_compression}, - 'blur':{'min':1, 'max':41, 'normalise':'odd', 'function':IQM_Vis.transforms.blur}, # only odd ints + # 'brightness':{'min':-1.0, 'max':1.0, 'function':IQM_Vis.transforms.brightness}, # normal but with float + # 'contrast': {'min': 0.5, 'max': 2.5, 'init_value': 1.0, 'function': IQM_Vis.transforms.contrast}, + # 'hue': {'min': -0.5, 'max': 0.5, 'function': IQM_Vis.transforms.hue}, + # 'saturation': {'min': -0.5, 'max': 0.5, 'function': IQM_Vis.transforms.saturation}, + # 'jpg compr':{'init_value':101, 'min':1, 'max':101, 'function':IQM_Vis.transforms.jpeg_compression}, + # 'blur':{'min':1, 'max':41, 'normalise':'odd', 'function':IQM_Vis.transforms.blur}, # only odd ints # 'threshold':{'min':-40, 'max':40, 'function':IQM_Vis.transforms.binary_threshold}, } - # define any parameters that the metrics need (names shared across both metrics and metric_images) - ssim_params = {'sigma': {'min':0.25, 'max':5.25, 'init_value': 1.5}, # for the guassian kernel - # 'kernel_size': {'min':1, 'max':41, 'normalise':'odd', 'init_value': 11}, # ignored if guassian kernel used - 'k1': {'min':0.01, 'max':0.21, 'init_value': 0.01}, - 'k2': {'min':0.01, 'max':0.21, 'init_value': 0.03}} # use the API to create the UI - IQM_Vis.make_UI(data, - transformations, - metric_params=ssim_params)
+ IQM_Vis.make_UI(data, transformations)
if __name__ == '__main__': diff --git a/docs/_build/html/_modules/IQM_Vis/metrics/IQMs.html b/docs/_build/html/_modules/IQM_Vis/metrics/IQMs.html index 20672d2..32ce6b7 100644 --- a/docs/_build/html/_modules/IQM_Vis/metrics/IQMs.html +++ b/docs/_build/html/_modules/IQM_Vis/metrics/IQMs.html @@ -277,7 +277,7 @@

Source code for IQM_Vis.metrics.IQMs

                                      K=(k1, k2),
                                      size_average=True)
                     # _score = _metric(im_ref, im_comp).cpu().detach().numpy()
-                _score = 1 - _score # get score not similarity
+                _score = 1 - _score.cpu().detach().numpy() # get score not similarity
                 success = True
             except ValueError:
                 # get an error with small images that the torchmetrics package seems to advise the wrong larger than size for
diff --git a/docs/_build/html/_modules/IQM_Vis/transformations/transforms.html b/docs/_build/html/_modules/IQM_Vis/transformations/transforms.html
index 5803265..fa8fdc2 100644
--- a/docs/_build/html/_modules/IQM_Vis/transformations/transforms.html
+++ b/docs/_build/html/_modules/IQM_Vis/transformations/transforms.html
@@ -110,7 +110,7 @@ 

Source code for IQM_Vis.transformations.transforms

''' if angle == 0: return image - return np.clip(rotate(image, angle), 0, 1)
+ return np.clip(rotate(image, angle, order=3), 0, 1)
[docs]def blur(image, kernel_size=7): '''Gaussian Blur on an image diff --git a/docs/_build/html/_modules/IQM_Vis/utils/gui_utils.html b/docs/_build/html/_modules/IQM_Vis/utils/gui_utils.html index 00eabef..29a6c3e 100644 --- a/docs/_build/html/_modules/IQM_Vis/utils/gui_utils.html +++ b/docs/_build/html/_modules/IQM_Vis/utils/gui_utils.html @@ -95,11 +95,15 @@

Source code for IQM_Vis.utils.gui_utils

     import matplotlib; matplotlib.use('Qt5Agg')
     from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
     from matplotlib.figure import Figure
+    import matplotlib.pyplot as plt
     HEADLESS = False
 except ImportError:
     import warnings
     warnings.warn('Can not load PyQt6 library - running IQM_Vis package in headless mode')
     HEADLESS = True
+import pickle
+import io
+
 import numpy as np
 from skimage.util import img_as_ubyte
 from skimage.transform import resize
@@ -113,7 +117,7 @@ 

Source code for IQM_Vis.utils.gui_utils

 #     return img_as_ubyte(down_im)
 
 
-
[docs]def change_im(widget, im, resize=False, rgb_brightness=250, display_brightness=250): +
[docs]def change_im(widget, im, resize=False, rgb_brightness=250, display_brightness=250, border=False): ''' given a numpy image, changes the given widget Frame ''' @@ -128,6 +132,12 @@

Source code for IQM_Vis.utils.gui_utils

         im = resize_to_longest_side(im, resize)
         im = img_as_ubyte(im)
     im = calibrate_brightness(im, rgb_brightness, display_brightness)
+    if border == True:
+        # add a black border to the image
+        im = np.pad(im, ((5, 5), (5, 5), (0, 0)), 'constant', constant_values=0)
+        if resize:
+            im = resize_to_longest_side(im, resize)
+            im = img_as_ubyte(im)
     qimage = QImage(im,
                     im.shape[1],
                     im.shape[0],
@@ -183,7 +193,11 @@ 

Source code for IQM_Vis.utils.gui_utils

 
 
[docs]def get_resolutions(data_store): ref = data_store.get_reference_image().shape - trans = data_store.get_image_to_transform().shape + if hasattr(data_store, 'image_post_processing'): + trans_im = data_store.get_image_to_transform() + if data_store.image_post_processing is not None: + trans_im = data_store.image_post_processing(trans_im) + trans = trans_im.shape return {'reference': f'{ref[0]}x{ref[1]}', 'transform': f'{trans[0]}x{trans[1]}'}
diff --git a/docs/_build/html/_modules/IQM_Vis/utils/plot_utils.html b/docs/_build/html/_modules/IQM_Vis/utils/plot_utils.html index 3e8c991..170ba60 100644 --- a/docs/_build/html/_modules/IQM_Vis/utils/plot_utils.html +++ b/docs/_build/html/_modules/IQM_Vis/utils/plot_utils.html @@ -258,7 +258,8 @@

Source code for IQM_Vis.utils.plot_utils

                        stop=transforms['max']*float_stabiliser, 
                        step=steps*float_stabiliser)
     values = list(values/float_stabiliser)
-    values.append(transforms['max'])
+    if transforms['max'] not in values:
+        values.append(transforms['max'])
     return values
[docs]def get_all_single_transform_params(transforms, num_steps=11): @@ -272,6 +273,7 @@

Source code for IQM_Vis.utils.plot_utils

             steps = num_steps
         for val in get_all_slider_values(trans_data, num_steps=steps):
             list_of_single_trans.append({trans_name: val})
+
     return list_of_single_trans
[docs]def compute_metric_for_human_correlation(data_store, transforms, metric_params, trans_str_values, metric): diff --git a/docs/_build/html/_modules/IQM_Vis/utils/save_utils.html b/docs/_build/html/_modules/IQM_Vis/utils/save_utils.html index 892c8ae..cb37f67 100644 --- a/docs/_build/html/_modules/IQM_Vis/utils/save_utils.html +++ b/docs/_build/html/_modules/IQM_Vis/utils/save_utils.html @@ -206,6 +206,11 @@

Source code for IQM_Vis.utils.save_utils

 
[docs]def load_json_dict(path): with open(path, 'r') as fp: return json.load(fp)
+ + +
[docs]def make_name_for_trans(trans): + splitter = '-----' + return f"{trans['transform_name']}{splitter}{trans['transform_value']}"
diff --git a/docs/_build/html/genindex.html b/docs/_build/html/genindex.html index 529bfcc..00f5d00 100644 --- a/docs/_build/html/genindex.html +++ b/docs/_build/html/genindex.html @@ -182,12 +182,16 @@

C

- +
@@ -397,10 +411,10 @@

G

  • get_IQM_file() (in module IQM_Vis.utils.save_utils)
  • - - + +
  • set_preview_images() (IQM_Vis.UI.images.images method) +
  • +
  • set_save_dir_mpl() (IQM_Vis.UI.images.images method) +
  • set_style() (IQM_Vis.utils.plot_utils.bar_plotter method)
      diff --git a/docs/_build/html/objects.inv b/docs/_build/html/objects.inv index d8c6f2442767a220708fc0fb2742fbca2d0db24c..103aa512c28b1a45575e8a7ccfd0a9ba0f493cac 100644 GIT binary patch delta 8650 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 delta 8378 zcmV;rAVuH3M6N=Rmw%B}MK_D2x%A>+|FDq+Py~TQf;x3Ikon)UIc4P~DEZ*nKX_Lu%zz7e6j|4DY=jp1MK7RA5bt!V6zL)X{W^ts5+dEcP{_V3H$ z`1pw&@{(a4OVV}84>wT082cmpnP&`(^nF_#hCavOUF)IC?|<98>pni^RnP6s`%9gH zLGRo8%y51tEx^+JrODgkN|R1$cIE;3Z6NHg9M{xq%FF- z>L3~B#J`a0tcIk;m7MdqX|PYv4Jh+ol%uH7c_v851+KdsTs&Qme%msi=zX zVidzz;Iz7>q<<_oC>;!$VztFF?T&RDAG|B7bD5`oORDZvw^wRI%p_>8(=__mGHUsw zb-ge8qOM|s{xz_Q*wt+x88s>%Edunb-PCMA*W;JMHWj5KPx*$>nSmWKS7@FL%~sSe z_47vUN7vJ;vK8%T(xgR|MJ3$VXVxA?WL%MJp3g{w8R-ec_(c#o5}*TtHZKV?ze~?8X)dvlTmDZRNc!EG(P=eYV_WUmd+D{F0G&PmX9BJ)u8Qee@Xek`-zkT=2LT!=em8Q`2D5LNfwS()2A1^tw2qg+&Ua9thq zFvG8T*D+E`>+V0KQIlS5i~~b~80G8z4;suv^m` z2Y(}c5({q~46L9fGy{W<|N3?~_NiQ04?+<=Nj0R$OMZMj)Gx3eLkHuH9_xyN2OFz+ zF_5OEE(93=!7>dAL0gc1=+Xm0lqBd1lddh-lazK1I#c0z9E6o0+KBVQ#Jl&R&s%a3 zHQc{-6C;g~8JpDPMOqu(D_x3b&38cs&wrTRzytjj<5oj#aN6^aowe`xbz(MhpD8w1 z=z4({U<3YOLtm63g^}y+NtVg3l1*ZJa)8x^@LkVw7f@~ro@o2WCjTVBPs^_*8Zn@8}KtWF7XJ&vAjh9 zRL8PNsDQa0-!GwMJS)fCHphILgmw6*OY#3mQ$z>c9|@iFO&b<;a=kQWS${|&1bUzH zKWVy{n_-FY6+&7tFVkX99P&CYp92U>Hsh|Ov9iz{C8hIJlg9|_!fNF7*aT`^y!qDY z@n&n=MBPhfk(1gukv2c&ZC)MoZ&4zR#J<7jno}GqIgYg)-;9zZU%zy0WP~Mj*1BfP zoHYnKC5MjIpkp7s>zR=E2Y;GLyd`286tNMvrm%T~1Wh?|Szk|nqejXn(QlUAW(^l8 z*>Cn)Z$2q)&FHkIf89FCtrO#8lh9Tne<5sve|Z=_Mp|2~Nk9&YaR~c%s4VTWjHh8>!Go*E;PLt0$8Z)@ISPjd42OqE9MXq} zyU!RN93Tdle}B6F5PwdDX~$rJ%Z^xi!B^2A^R~*%w9Yb1%j1VtSGhPAd!twApG_K{4sVA<`+#73&+=Y-vUrG9fm*|mr~0fTI!~B+ z&#WOuySBv%08~eHksxWyUzfu)K*NEFi=bI?l!uYKzKsORis$HfB!cCX7~9J%^C|>K zu)q~s1!F&N0yxJ%zP$Fwwr-2rW zg!{GbNP7FChBp=+z|*nA*gG(vGvc0ra=k8U67uT*bY^%HV9iAsGL><);Ku9N>S7BR zeLBrPF6(0~Oc{rUKZk15q6~_lj8|0e-c^EVtf<> z3jbM5z<3{K2^s%sZcwowN8aopRTb6=@DV6(3^_yWKYaY<-PccF(ua3{d`v&w@qJ2u zc^}M%cO5M9RFpZ+Fb<{Nj*N=g7uR@@%6%k0OIB$|gP*TB#-d%*xoJ@m=`J!ls&bk= zZVL0*WCZHsLyLiA3|u}nfBv&$9x;kz9|NpD{E39&KiNwAHE-DkoKs4=^l05f0l`KE zQyhIM4)(C9vAzcX3H};%6g=+DI2X#lCkN)_sO|cs>$A5dcQ?QLArZk$I(f%_GJqWg zP!!(qU%TS3>+Y%OZ0d%T73?q+B^9f7qn)HI`d2HeMf_(LoD@}}e+8@Q@V0YDKl(9m zn80o>0d^Z!mHx#dllv($`8Y?aDR=d$eXwoXt({yqOM zx#RyWCm_RiGRz|he^bND4!Kt()0X7xiC`$~xzTTM?!v^fsd#|iK_4Q4iQYp}11?~2Cw0qh0 z>>ht-O?5%^P6Q=1C=o##wyZRo{dV|8X=fh(HLzBR20!JLe;FxXyTWe5qVR8XVDe4| z8YxuF@w{gOH?qG?VTD1g<17e=i!d8)J4-(KmSq3WnT5%*qvZU%ueG@lb`BR?R!fTbVbf5UhzX*tp3b z$w&hgBpuBdf7N}!CU&U_geq=ft=y~I+Gd#yPCcIe7WWF<m1P% zivhBAj)>zJ-!fZ7iqVkbW{`gJdb@1V(?RNQkp;;rHwG&e{gsc$yfswBpq&y-4RY4v+VeR zdK;L!?FbQ^Y+Sf+mtQe!Ls;4yU~ZLtTZ}FtDMmxuHiN!p*2Kt^&9Y;gktr6flB?18$LP-?kx&(+F+e0DY^*2ix#$(dZ~%&o(n(Nduv~X0|*_u_)kemjqef zJNhine{it7!s19l7@660(ph?djI-|0mVSVM?_H@HR2>E}1Mde}oIj3Rz zF0*cyE;%_%tX|U0J;{Y+rp?YVZYSc_H%%9Pt+|j;G>tN3V)(N(N{tC*t&5YO``avj zloc}?b{9t~q< z^&uHf(+UZchZz$5u_tYNlrIy*Wn~B*1HuvSOKkQz8NzASwnzCg(R@yZkkJ5EV|^*9 zt|vnnsrqY?zI+r1lp%B!^_4ga8B3q(L&VZc`gM=i&f0pY$t&@_dUQz(G>2?nWJYJi ze+WV&gf$|J75G@>`CbM81jk?fMVGcO>kBT7vAY_NN9woa`_VVK>{G#|&UBZ`6H+;H(_;C~tbVQz4GI-)`RakPz$;@Dsfv~knJY*EdcPyw=NQ_lM1e}PdAG9D%bYoLu| zuiQnohynVEp}F6@r5DwZ8}tAjw29MOeo;-EPyw=NQlSvr`rGju$qwaJ$f%|$xFG3ugN&)BIV176z?g!XK-Nh% zoYX#OhO^FZ?=itqe?-iQ^pX*-iS;5&$3%N5>=WXzclsQdJ>_Z6Cx!krKOKto$*qK3 zlJ`qx{P#F?JuQ#VMMh_d^3^Yq+G@JW{|3T)hVY5&`3MDZ6F+VKsURFDB#3Yr=W9K5 zIUnidPu80YAnqLTo*{mGQg1OplmNCgZGC2X2hxU;zn2g{f0H)xl3JsuJf%RZV=fk* zT~|XEIJ$8BMGpJ&%zHos2E`3mMO!z%juY3m2{lv^XII_juvXg(@}}AL*TR^i#Fyliy^j*hs#|1? zGRDSJQ5D@~e}nE|0U4u=v2nVJ6u0d(V1qTWrpY@+^4YPN*6GL?Wvq=i@4ed2iv(J_ zgpY^7SWPRy_=I6BLlwv%EsQyIG{hb*v8`DJSTiGrC}C{*Yv4~l*KNGUQh^N8LYfoR z5U2?#^0aMX4=isopjyJlspBo(prgJ4M(AP;G~WG-e`cSF8?K7AF5Aky3}Igu%fP%J znoSHeff2eW126US7UM`0H(V8E9ecxWlh0=YBXm&)K9eRbsx0D%n-D{kFt+sdnT<6! z_*%Ef7-g`H;w|O66~kzpRR$JJ9Ku|5g2GF$Ses>T#1ADoJ_cK`h8d<7$)a(&kN)4) zWsz-Rf8k9UabTk50D4){4;>2-%igZ9n@vpRzzAK4foztv@-~TwB{PDL&>A=C*c3R9 z(6ww4-sz6DgPraVhCOx&M2YtLlUhUvg=V7w*$ zskV7mqndpMz(WQ??5}}c{}-bj*7yVyf4l(#$odmzOG3>wJrS*CAmv3UkhDMTp~={L z8?%=M*E_mS_G^eCO8&My6|~B#lN9dYqdJDR8g@LmiiZ`~yz7|Jfs;K`-6^p~Nu2H5 z15Y06TDA!9bj82}!$Cvv5dw099g(sEc*v{~yON?3+eoDGUn|$OY!Tk+j!R7Zf7AkS zpy31p$N~t%4-78=+#CwviK5S2 zasUh~e6V2RYs|$0kXYW*wql@j9w!h$7DG7TLs8%CxM8 ztps=j2I!y+8E@&vvt&XHQ9{`QI-ui+230`wZ(>&d5ime!&5)rl%5G1xe@sqQ*=BxE z4&JkJQC*_53b^41uII}++M=) z6Z2tMbaY65tvjg>Dr#Y|z=1U&CYY1O=U3mWi+Tl0Dtg~feXi9G=OcuzO@?(B7DR7<{_eW zVuripuXlD2%(es!hpE8yOl^CN=}g(m$G9yFC1k3vM0r#4e>sM8%fxo&%RgP8GljS5 z+RhRBr_1)c*DBT2jCmLAW>?1&1(k}nxV_Ghk zXlqXYmUi9hTM7$AAx3f<1A#|L-`DE(SjtZgq(*W6~E*Pg3V*1LO>5%LU2kz zh@GclMMH{~e~&GKDK23FWTCXxV}y9(w`d?~D0w=fsLNsHc?3_|DvqZdl&ZL_mla33 zdDitUit-X3P(H{6b{=wc0*Eg!7D%`X#FlGQ9!d2?!pqF(rhG3DoDvXX^qa6#5@lWm zGgBbkB5rOXgJsJ|%Hq(np|NWp(aO^a2NMVKZ|f#Kf6{Sfn`3AzC|*)9l3EF0J9g(q zb_oq64I|G_PGdPMAU;AchO_}M{?5@HH5fm!AfBw6)^s@1F{jK~1jZ&HQ~_oMze$75 zYX!td$jy*%Uy7dx=`f(rp`Eb>#78KU;og3c4@h&b-RW~m1`}qhZH^skD03YWu7a{< z<%V8}e;xXLJwNeq{?;eo!PK=U;9Zg+!s2C;?nrPoQit&qgYm4d&CpMN$C$58aRx=X zwt=AUgO1Wh7%TmctZe1LP1G<0bRwCfJ$$f*ZF&M&0Fc$=LmfA7J2a#vn8w)!9I6;* z-L&~`_16QkNrQulgZcaUXY-|R^~>fZ4JNPne_l$-(|OGch_409kZ={SEpthny`v#* zS%!qGfNZ(&b_3m+>M(v{AfD`S6@C=1p?FCJlSB^0Z=w7}!#PJ9i?3h?=-|vj4#zEc zKzW1-s1f-sl)os5^W3PS>ZcClCl<~VSw$DH0I~?$k!tB0XowQhB4kCi0YVipR-o$Y ze*zXj7DQWi!1(%V0{IGJ*dlA~A{s~ZJmbd zDBhmIn`lK1(n1&|7O%*T&k_^Eqe*q%K zf0By1Lu;9nfKy7k^w>Rx6SX3OHQbCHk>jLY1loL^5j8p)743O14 z%M2r>=vyOzl;#o^MoH1PM%XF2e{Opysar05$RD>?J;n(2l7}WfUd^zpO%juORrmR! zt{=Pa`=O^}K{^opVRt2uY*Nu*sJ+F$XkIJBd)%z`Wl>AsX-US|0rg|4kmIi|XE7+Vde!8~FRLKi{-}Gz`)9;WB8-nt)6hqjx{N zmGL_ozcX*2`%?L$zuFrEQ@Z;{irlk)Be|~&Rn=0nNI?<&3 z(|_Yx$ChY_W}p-Gz5}Ew`uiOw>CXZ}G7$fT5htL`8;g4@==g$hgE*8j7K^0X=mkO(EKkZ2N z#9pAvbdH^8t^aBFe{R%&uj}je|EIS)ndC#>lcMZGNWFozmFpDW=q;tYb##*Rtg0?r z9+lQb1zIm0ltOBVlj2yae|oD6>@rb6(4>_FwD_GYfq`Z8AG>y_D%J&SuWx!*8=JOX zY5qZnHbRWfK9i4%w=O85H_H6!R8(DYFT3gMd?K$vh;0SsDCPTq47RywJ6@=M(&|HqaF zzEF{WE|K%f1TJJVkB1bUWaY#%#Q#hGO^Qwu{^xgcfAyKeWc5*9A6FN*CpSWhceMqT zaj{vEG8Ne?Tj_;VSvh)7G%z#)9ZuIZk@FYA#@CCWW1NmRY1p7tXJ7J+ky>gBf=xnW2G$*jnc=n07PvL9yD>s2%UxB$Qr+;9=`8M5xmT}L2>c$C zdp_+*FKi(TGBa@yK+mcD2NVt_$Z3jFfE*?3B>uI(Py@6A*5#x