Conditions | 12 |
Total Lines | 75 |
Code Lines | 55 |
Lines | 0 |
Ratio | 0 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like savu.plugins.reconstructions.tomobar.tomobar_recon_3D.TomobarRecon3d.process_frames() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | # Copyright 2019 Diamond Light Source Ltd. |
||
135 | def process_frames(self, data): |
||
136 | cor, angles, self.vol_shape, init = self.get_frame_params() |
||
137 | self.anglesRAD = np.deg2rad(angles.astype(np.float32)) |
||
138 | projdata3D = data[0].astype(np.float32) |
||
139 | dim_tuple = np.shape(projdata3D) |
||
140 | self.Horiz_det = dim_tuple[self.det_dimX_ind] |
||
141 | half_det_width = 0.5 * self.Horiz_det |
||
142 | projdata3D[projdata3D > 10 ** 15] = 0.0 |
||
143 | projdata3D = np.require(np.swapaxes(projdata3D, 0, 1), requirements='CA') |
||
144 | self._data_.update({'projection_norm_data': projdata3D}) |
||
145 | |||
146 | # setup the CoR and offset |
||
147 | cor_astra = half_det_width - np.mean(cor) |
||
148 | CenterOffset_scalar = cor_astra.item() - 0.5 |
||
149 | CenterOffset = np.zeros(np.shape(self.projection_shifts)) |
||
150 | CenterOffset[:, 0] = CenterOffset_scalar |
||
151 | CenterOffset[:, 1] = -0.5 # TODO: maybe needs to be tweaked? |
||
152 | |||
153 | # check if Projection2dAlignment is in the process list, and if so, |
||
154 | # fetch the value of the "registration" parameter (in order to decide |
||
155 | # whether projection shifts need to be taken into account or not) |
||
156 | registration = False |
||
157 | for plugin_dict in self.exp.meta_data.plugin_list.plugin_list: |
||
158 | if plugin_dict['name'] == 'Projection2dAlignment': |
||
159 | registration = plugin_dict['data']['registration'] |
||
160 | break |
||
161 | |||
162 | if np.sum(self.projection_shifts) != 0.0 and not registration: |
||
163 | # modify the offset to take into account the shifts |
||
164 | CenterOffset[:, 0] -= self.projection_shifts[:, 0] |
||
165 | CenterOffset[:, 1] -= self.projection_shifts[:, 1] |
||
166 | |||
167 | # set parameters and initiate a TomoBar class object for iterative reconstruction |
||
168 | RectoolsIter = RecToolsIR(DetectorsDimH=self.Horiz_det, # DetectorsDimH # detector dimension (horizontal) |
||
169 | DetectorsDimV=self.Vert_det, # DetectorsDimV # detector dimension (vertical) for 3D case only |
||
170 | CenterRotOffset=CenterOffset, # The center of rotation combined with the shift offsets |
||
171 | AnglesVec=-self.anglesRAD, # the vector of angles in radians |
||
172 | ObjSize=self.vol_shape[0], # a scalar to define the reconstructed object dimensions |
||
173 | datafidelity=self.parameters['data_fidelity'], # data fidelity, choose LS, PWLS, SWLS |
||
174 | device_projector=self.parameters['GPU_index']) |
||
175 | |||
176 | # set parameters and initiate a TomoBar class object for direct reconstruction |
||
177 | RectoolsDIR = RecToolsDIR(DetectorsDimH=self.Horiz_det, # DetectorsDimH # detector dimension (horizontal) |
||
178 | DetectorsDimV=self.Vert_det, # DetectorsDimV # detector dimension (vertical) for 3D case only |
||
179 | CenterRotOffset=CenterOffset, # The center of rotation combined with the shift offsets |
||
180 | AnglesVec=-self.anglesRAD, # the vector of angles in radians |
||
181 | ObjSize=self.vol_shape[0], # a scalar to define the reconstructed object dimensions |
||
182 | device_projector=self.parameters['GPU_index']) |
||
183 | |||
184 | if self.parameters['reconstruction_method'] == 'FBP3D': |
||
185 | recon = RectoolsDIR.FBP(projdata3D) #perform FBP3D |
||
186 | |||
187 | if self.parameters['reconstruction_method'] == 'CGLS3D': |
||
188 | # Run CGLS 3D reconstruction algorithm here |
||
189 | self._algorithm_.update({'lipschitz_const': None}) |
||
190 | recon = RectoolsIter.CGLS(self._data_, self._algorithm_) |
||
191 | |||
192 | if self.parameters['reconstruction_method'] == 'SIRT3D': |
||
193 | # Run SIRT 3D reconstruction algorithm here |
||
194 | self._algorithm_.update({'lipschitz_const': None}) |
||
195 | recon = RectoolsIter.SIRT(self._data_, self._algorithm_) |
||
196 | |||
197 | if self.parameters['reconstruction_method'] == 'FISTA3D': |
||
198 | if self.parameters['regularisation_method'] == 'PD_TV': |
||
199 | self._regularisation_.update({'device_regulariser': self.parameters['GPU_index']}) |
||
200 | # if one selects PWLS or SWLS models then raw data is also required (2 inputs) |
||
201 | if (self.parameters['data_fidelity'] == 'PWLS') or (self.parameters['data_fidelity'] == 'SWLS'): |
||
202 | rawdata3D = data[1].astype(np.float32) |
||
203 | rawdata3D[rawdata3D > 10 ** 15] = 0.0 |
||
204 | rawdata3D = np.swapaxes(rawdata3D, 0, 1) / np.max(np.float32(rawdata3D)) |
||
205 | self._data_.update({'projection_raw_data': rawdata3D}) |
||
206 | self._data_.update({'beta_SWLS': self.parameters['data_beta_SWLS'] * np.ones(self.Horiz_det)}) |
||
207 | # Run FISTA reconstruction algorithm here |
||
208 | recon = RectoolsIter.FISTA(self._data_, self._algorithm_, self._regularisation_) |
||
209 | return np.require(np.swapaxes(recon, 0, 1), requirements='CA') |
||
210 | |||
230 |