| 1 |  |  | from savu.data.data_structures.plugin_data import PluginData | 
            
                                                        
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 3 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 4 |  |  | def enable_iterative_loop(setup_fn): | 
            
                                                        
            
                                    
            
            
                | 5 |  |  |     ''' | 
            
                                                        
            
                                    
            
            
                | 6 |  |  |     Decorator that can be applied to a plugin's setup() method. Doing so | 
            
                                                        
            
                                    
            
            
                | 7 |  |  |     modifies the plugin's setup slightly to work correctly when at the end of an | 
            
                                                        
            
                                    
            
            
                | 8 |  |  |     iterative loop, by setting up the relevant extra output dataset. | 
            
                                                        
            
                                    
            
            
                | 9 |  |  |     ''' | 
            
                                                        
            
                                    
            
            
                | 10 |  |  |     def wrapper(*args, **kwargs): | 
            
                                                        
            
                                    
            
            
                | 11 |  |  |         # run the plugin's original setup() method | 
            
                                                        
            
                                    
            
            
                | 12 |  |  |         setup_fn(*args, **kwargs) | 
            
                                                        
            
                                    
            
            
                | 13 |  |  |         plugin = args[0] | 
            
                                                        
            
                                    
            
            
                | 14 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 15 |  |  |         if check_if_end_plugin_in_iterate_group(plugin.exp): | 
            
                                                        
            
                                    
            
            
                | 16 |  |  |             # do the other setup required for the plugin to be the end plugin of | 
            
                                                        
            
                                    
            
            
                | 17 |  |  |             # an iterative group | 
            
                                                        
            
                                    
            
            
                | 18 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 19 |  |  |             in_dataset, out_dataset = plugin.get_datasets() | 
            
                                                        
            
                                    
            
            
                | 20 |  |  |             in_pData, out_pData = plugin.get_plugin_datasets() | 
            
                                                        
            
                                    
            
            
                | 21 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 22 |  |  |             try: | 
            
                                                        
            
                                    
            
            
                | 23 |  |  |                 max_frames = plugin.get_max_frames() | 
            
                                                        
            
                                    
            
            
                | 24 |  |  |             except AttributeError: | 
            
                                                        
            
                                    
            
            
                | 25 |  |  |                 # the plugin has no get_max_frames() method, so assume it to be | 
            
                                                        
            
                                    
            
            
                | 26 |  |  |                 # 'single | 
            
                                                        
            
                                    
            
            
                | 27 |  |  |                 max_frames = 'single' | 
            
                                                        
            
                                    
            
            
                | 28 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 29 |  |  |             # create the cloned dataset | 
            
                                                        
            
                                    
            
            
                | 30 |  |  |             create_clone(out_dataset[1], out_dataset[0]) | 
            
                                                        
            
                                    
            
            
                | 31 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 32 |  |  |             # this is the pattern that was used for the "original" output data | 
            
                                                        
            
                                    
            
            
                | 33 |  |  |             # for the end plugin | 
            
                                                        
            
                                    
            
            
                | 34 |  |  |             out_pattern = out_pData[0].get_pattern_name() | 
            
                                                        
            
                                    
            
            
                | 35 |  |  |             # set the pattern for the PluginData objects associated with the | 
            
                                                        
            
                                    
            
            
                | 36 |  |  |             # newly created cloned dataset | 
            
                                                        
            
                                    
            
            
                | 37 |  |  |             out_pData[1].plugin_data_setup(out_pattern, max_frames) | 
            
                                                        
            
                                    
            
            
                | 38 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 39 |  |  |             try: | 
            
                                                        
            
                                    
            
            
                | 40 |  |  |                 iterate_plugin_group = check_if_in_iterative_loop(plugin.exp) | 
            
                                                        
            
                                    
            
            
                | 41 |  |  |                 start_plugin = iterate_plugin_group.start_plugin | 
            
                                                        
            
                                    
            
            
                | 42 |  |  |                 start_plugin_in_pData, start_plugin_out_pData = \ | 
            
                                                        
            
                                    
            
            
                | 43 |  |  |                     start_plugin.get_plugin_datasets() | 
            
                                                        
            
                                    
            
            
                | 44 |  |  |                 # this is the pattern that was used for the input data for the | 
            
                                                        
            
                                    
            
            
                | 45 |  |  |                 # start plugin | 
            
                                                        
            
                                    
            
            
                | 46 |  |  |                 in_pattern = start_plugin_in_pData[0].get_pattern_name() | 
            
                                                        
            
                                    
            
            
                | 47 |  |  |                 # this is the padding that is going to be applied to the input | 
            
                                                        
            
                                    
            
            
                | 48 |  |  |                 # data for the start plugin | 
            
                                                        
            
                                    
            
            
                | 49 |  |  |                 in_padding = start_plugin_in_pData[0].padding | 
            
                                                        
            
                                    
            
            
                | 50 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 51 |  |  |                 # create PluginData object for original and cloned Data objects, | 
            
                                                        
            
                                    
            
            
                | 52 |  |  |                 # that have the pattern of the start plugin, and append to the | 
            
                                                        
            
                                    
            
            
                | 53 |  |  |                 # start plugin's 'plugin_in_datasets' | 
            
                                                        
            
                                    
            
            
                | 54 |  |  |                 orig_start_pData = PluginData(out_dataset[0], start_plugin) | 
            
                                                        
            
                                    
            
            
                | 55 |  |  |                 orig_start_pData.padding = in_padding | 
            
                                                        
            
                                    
            
            
                | 56 |  |  |                 orig_start_pData.plugin_data_setup(in_pattern, 'single') | 
            
                                                        
            
                                    
            
            
                | 57 |  |  |                 start_plugin.parameters['plugin_in_datasets'].append(orig_start_pData) | 
            
                                                        
            
                                    
            
            
                | 58 |  |  |                 clone_start_pData = PluginData(out_dataset[1], start_plugin) | 
            
                                                        
            
                                    
            
            
                | 59 |  |  |                 clone_start_pData.padding = in_padding | 
            
                                                        
            
                                    
            
            
                | 60 |  |  |                 clone_start_pData.plugin_data_setup(in_pattern, 'single') | 
            
                                                        
            
                                    
            
            
                | 61 |  |  |                 start_plugin.parameters['plugin_in_datasets'].append(clone_start_pData) | 
            
                                                        
            
                                    
            
            
                | 62 |  |  |                 # "re-finalise" the plugin datasets for the start plugin, now | 
            
                                                        
            
                                    
            
            
                | 63 |  |  |                 # that these new PluginData obejcts have been added | 
            
                                                        
            
                                    
            
            
                | 64 |  |  |                 start_plugin._finalise_plugin_datasets() | 
            
                                                        
            
                                    
            
            
                | 65 |  |  |             except AttributeError as e: | 
            
                                                        
            
                                    
            
            
                | 66 |  |  |                 print('In plugin setup, will not create new PluginData objects') | 
            
                                                        
            
                                    
            
            
                | 67 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 68 |  |  |     return wrapper | 
            
                                                        
            
                                    
            
            
                | 69 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 70 |  |  | def setup_extra_plugin_data_padding(padding_fn): | 
            
                                                        
            
                                    
            
            
                | 71 |  |  |     """ | 
            
                                                        
            
                                    
            
            
                | 72 |  |  |     Decorator that can be applied to a filter plugin's set_filter_padding() | 
            
                                                        
            
                                    
            
            
                | 73 |  |  |     method. Doing so modifies/extends the filter plugin's padding function | 
            
                                                        
            
                                    
            
            
                | 74 |  |  |     slightly to also set the padding for the additional PluginData objects that | 
            
                                                        
            
                                    
            
            
                | 75 |  |  |     are created when an iterative loop is defined. | 
            
                                                        
            
                                    
            
            
                | 76 |  |  |     """ | 
            
                                                        
            
                                    
            
            
                | 77 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 78 |  |  |     def wrapper(*args, **kwargs): | 
            
                                                        
            
                                    
            
            
                | 79 |  |  |         # run the plugin's original set_filter_padding() method | 
            
                                                        
            
                                    
            
            
                | 80 |  |  |         padding_fn(*args, **kwargs) | 
            
                                                        
            
                                    
            
            
                | 81 |  |  |         plugin = args[0] | 
            
                                                        
            
                                    
            
            
                | 82 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 83 |  |  |         if check_if_end_plugin_in_iterate_group(plugin.exp): | 
            
                                                        
            
                                    
            
            
                | 84 |  |  |             # check for any padding on the original output data, and apply it to | 
            
                                                        
            
                                    
            
            
                | 85 |  |  |             # the cloned data | 
            
                                                        
            
                                    
            
            
                | 86 |  |  |             in_pData, out_pData = plugin.get_plugin_datasets() | 
            
                                                        
            
                                    
            
            
                | 87 |  |  |             if out_pData[0].padding is not None: | 
            
                                                        
            
                                    
            
            
                | 88 |  |  |                 out_pData[1].padding = out_pData[0].padding | 
            
                                                        
            
                                    
            
            
                | 89 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 90 |  |  |     return wrapper | 
            
                                                        
            
                                    
            
            
                | 91 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 92 |  |  | def create_clone(clone, data): | 
            
                                                        
            
                                    
            
            
                | 93 |  |  |     ''' | 
            
                                                        
            
                                    
            
            
                | 94 |  |  |     Create a clone of a Data object | 
            
                                                        
            
                                    
            
            
                | 95 |  |  |     ''' | 
            
                                                        
            
                                    
            
            
                | 96 |  |  |     clone.create_dataset(data) | 
            
                                                        
            
                                    
            
            
                | 97 |  |  |     clone.data_info.set('clone', data.get_name()) | 
            
                                                        
            
                                    
            
            
                | 98 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 99 |  |  | def check_if_in_iterative_loop(exp): | 
            
                                                        
            
                                    
            
            
                | 100 |  |  |     ''' | 
            
                                                        
            
                                    
            
            
                | 101 |  |  |     Inspect the metadata inside the Experiment object to determine if current | 
            
                                                        
            
                                    
            
            
                | 102 |  |  |     processing is inside an iterative loop | 
            
                                                        
            
                                    
            
            
                | 103 |  |  |     ''' | 
            
                                                        
            
                                    
            
            
                | 104 |  |  |     try: | 
            
                                                        
            
                                    
            
            
                | 105 |  |  |         current_plugin_index = exp.meta_data.get('nPlugin') | 
            
                                                        
            
                                    
            
            
                | 106 |  |  |         for group in exp.meta_data.get('iterate_groups'): | 
            
                                                        
            
                                    
            
            
                | 107 |  |  |             start_index = shift_plugin_index(exp, group.start_index) | 
            
                                                        
            
                                    
            
            
                | 108 |  |  |             end_index = shift_plugin_index(exp, group.end_index) | 
            
                                                        
            
                                    
            
            
                | 109 |  |  |             if start_index <= current_plugin_index and \ | 
            
                                                        
            
                                    
            
            
                | 110 |  |  |                 end_index >= current_plugin_index: | 
            
                                                        
            
                                    
            
            
                | 111 |  |  |                 return group | 
            
                                                        
            
                                    
            
            
                | 112 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 113 |  |  |         # never hit an instance of IteratePluginGroup where the current plugin | 
            
                                                        
            
                                    
            
            
                | 114 |  |  |         # index was within the start and end plugin indices, so processing is | 
            
                                                        
            
                                    
            
            
                | 115 |  |  |         # not inside an iterative loop | 
            
                                                        
            
                                    
            
            
                | 116 |  |  |         return None | 
            
                                                        
            
                                    
            
            
                | 117 |  |  |     except AttributeError as e: | 
            
                                                        
            
                                    
            
            
                | 118 |  |  |         # TODO: Currently, an AttributeError only occurs inside two framework | 
            
                                                        
            
                                    
            
            
                | 119 |  |  |         # tests: | 
            
                                                        
            
                                    
            
            
                | 120 |  |  |         # - astra_multiple_parameter_test.py | 
            
                                                        
            
                                    
            
            
                | 121 |  |  |         # - multiple_parameter_test.py | 
            
                                                        
            
                                    
            
            
                | 122 |  |  |         # due to the exp variable still being None (ie, when this check of if | 
            
                                                        
            
                                    
            
            
                | 123 |  |  |         # the processing is in an iterative loop or not occurs, the Experiment | 
            
                                                        
            
                                    
            
            
                | 124 |  |  |         # object hasn't yet been set in these tests). | 
            
                                                        
            
                                    
            
            
                | 125 |  |  |         # | 
            
                                                        
            
                                    
            
            
                | 126 |  |  |         # These framework tests should be investigated to better understand: | 
            
                                                        
            
                                    
            
            
                | 127 |  |  |         # - in what cases the Experiment object isn't yet set when running Savu | 
            
                                                        
            
                                    
            
            
                | 128 |  |  |         # - if this check can occur elsewhere, to avoid causing those framework | 
            
                                                        
            
                                    
            
            
                | 129 |  |  |         #   tests to fail | 
            
                                                        
            
                                    
            
            
                | 130 |  |  |         err_str = f"Error when checking if inside an iterative loop: {e}" | 
            
                                                        
            
                                    
            
            
                | 131 |  |  |         print(err_str) | 
            
                                                        
            
                                    
            
            
                | 132 |  |  |         return None | 
            
                                                        
            
                                    
            
            
                | 133 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 134 |  |  | def check_if_end_plugin_in_iterate_group(exp): | 
            
                                                        
            
                                    
            
            
                | 135 |  |  |     ''' | 
            
                                                        
            
                                    
            
            
                | 136 |  |  |     Determines if the current plugin is at the end of an iterative loop | 
            
                                                        
            
                                    
            
            
                | 137 |  |  |     ''' | 
            
                                                        
            
                                    
            
            
                | 138 |  |  |     iterate_plugin_group = check_if_in_iterative_loop(exp) | 
            
                                                        
            
                                    
            
            
                | 139 |  |  |     if iterate_plugin_group is None: | 
            
                                                        
            
                                    
            
            
                | 140 |  |  |         return False | 
            
                                                        
            
                                    
            
            
                | 141 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 142 |  |  |     end_index = shift_plugin_index(exp, iterate_plugin_group.end_index) | 
            
                                                        
            
                                    
            
            
                | 143 |  |  |     is_end_plugin = end_index == exp.meta_data.get('nPlugin') | 
            
                                                        
            
                                    
            
            
                | 144 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 145 |  |  |     return is_end_plugin | 
            
                                                        
            
                                    
            
            
                | 146 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 147 |  |  | def shift_plugin_index(exp, index): | 
            
                                                        
            
                                    
            
            
                | 148 |  |  |     ''' | 
            
                                                        
            
                                    
            
            
                | 149 |  |  |     The indices used for plugins when editing a process list in the | 
            
                                                        
            
                                    
            
            
                | 150 |  |  |     configurator, and the indices used by PluginRunner._run_plugin_list(), | 
            
                                                        
            
                                    
            
            
                | 151 |  |  |     differ based on a few different things, such as: | 
            
                                                        
            
                                    
            
            
                | 152 |  |  |     - zero-based indexing internally in Savu, but one-based indexing in the | 
            
                                                        
            
                                    
            
            
                | 153 |  |  |       configurator | 
            
                                                        
            
                                    
            
            
                | 154 |  |  |     - the number of loaders in the process list | 
            
                                                        
            
                                    
            
            
                | 155 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 156 |  |  |     This function is for shifting the one-based plugin index as would be seen in | 
            
                                                        
            
                                    
            
            
                | 157 |  |  |     the configurator, to the nPlugin experimental metadata value as would be | 
            
                                                        
            
                                    
            
            
                | 158 |  |  |     seen for the same plugin in the for loop in PluginRunner._run_plugin_list(). | 
            
                                                        
            
                                    
            
            
                | 159 |  |  |     ''' | 
            
                                                        
            
                                    
            
            
                | 160 |  |  |     n_loaders = exp.meta_data.plugin_list._get_n_loaders() | 
            
                                                        
            
                                    
            
            
                | 161 |  |  |     SHIFT_TO_ZERO_BASED = 1 | 
            
                                                        
            
                                    
            
            
                | 162 |  |  |     return index - SHIFT_TO_ZERO_BASED - n_loaders |