Skip to content

Commit 9d08ebc

Browse files
Carole SudreCarole Sudre
authored andcommitted
Update docs for utils
1 parent e549ee0 commit 9d08ebc

1 file changed

Lines changed: 93 additions & 6 deletions

File tree

MetricsReloaded/utility/utils.py

Lines changed: 93 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,11 @@ def list_foreground_component(self):
148148

149149
def intersection_boxes(box1, box2):
150150
"""
151-
Intersection between two boxes given the corners
151+
Intersection area/volume between two boxes given their extreme corners
152152
153-
:return: intersection
153+
:param: box1 - first box to consider for intersection
154+
:param: box2 - second box to consider for intersection
155+
:return: intersection -value of the intersected volume / area as number of pixels / voxels
154156
"""
155157
min_values = np.minimum(box1, box2)
156158
max_values = np.maximum(box1, box2)
@@ -167,6 +169,9 @@ def guess_input_style(a):
167169
"""
168170
Given an array a, guess whether it represents a mask, a box or a centre of mass
169171
172+
:param: a - input array to check
173+
:return: string from either mask, box or com
174+
170175
"""
171176
if a.ndim > 1:
172177
return 'mask'
@@ -177,13 +182,26 @@ def guess_input_style(a):
177182
return 'com'
178183

179184
def com_from_box(box):
185+
"""
186+
Identifies the centre of mass of a box from its extreme coordinates
187+
188+
:param: box: box identified as a vector of size 2xndim with first the ndim minimum values and then the ndim maximum values
189+
:return: Centre of mass of the box as a vector of size ndim
190+
"""
180191
min_corner = box[:box.shape[0]//2]
181192
max_corner = box[box.shape[0]//2:]
182193
aggregate = np.vstack([min_corner,max_corner])
183194
com = np.mean(aggregate, 0)
184195
return com
185196

186197
def point_in_box(point, box):
198+
"""
199+
Indicates whether a point is contained in an axis-aligned box specified by min and maximum corners
200+
201+
:param: point: coordinates of the point to assess
202+
:param: box: vector of size 2 x ndim (2 or 3), the first ndim values corresponding to the minimum corner and the last ndim to the maximum corner
203+
:return: 1 if the point is in the box 0 otherwise
204+
"""
187205
min_corner = box[:box.shape[0]//2]
188206
max_corner = box[box.shape[0]//2:]
189207
diff_min = point - min_corner
@@ -196,6 +214,13 @@ def point_in_box(point, box):
196214
return 1
197215

198216
def point_in_mask(point, mask):
217+
"""
218+
Indicates whether a point (given by coordinates 2D or 3D) is in a mask
219+
220+
:param: point - coordinates of the point to check (list or np-array)
221+
:param: mask - nd array for a segmentation mask
222+
:return: 1 if the point is in the mask, 0 otherwise
223+
"""
199224
new_mask = np.zeros_like(mask)
200225
if new_mask.ndim == 2:
201226
new_mask[point[0],point[1]] = 1
@@ -262,10 +287,19 @@ def median_heuristic(matrix_proba):
262287
def compute_skeleton(img):
263288
"""
264289
Computes skeleton using skimage.morphology.skeletonize
290+
291+
:param: img - array with the binary mask of the element to skeletonise
292+
:return: nd array with the mask of the skeleton of the element considered in img
265293
"""
266294
return skeletonize(img)
267295

268296
def compute_box(img):
297+
"""
298+
Computes the coordinates of the bounding box based on a mask (in img)
299+
300+
:param: img: mask of the element for which to compute bounding box
301+
:return: indices of the bottom left and top right corners of the bounding box axis aligned.
302+
"""
269303
indices = np.asarray(np.where(img>0)).T
270304
min_corner = np.min(indices,0)
271305
max_corner = np.max(indices, 0)
@@ -278,6 +312,7 @@ def compute_center_of_mass(img):
278312
Computes center of mass using scipy.ndimage
279313
280314
:param: img as multidimensional array
315+
:return: Returns the centre
281316
"""
282317
return ndimage.center_of_mass(img)
283318

@@ -291,7 +326,13 @@ def distance_transform_edt(img, sampling=None):
291326

292327
def max_x_at_y_more(x, y, cut_off):
293328
"""Gets max of elements in x where elements
294-
in y are geq to a cut off value
329+
in y are geq to a cut off value - used in the metrics based on probability thresholds
330+
331+
:param: x: array of values
332+
:param: y: array of values similar length to x
333+
:param: cutoff - value at which to consider the cut-offon y
334+
:param
335+
:return: return the maximum of x for all corresponding values of y greater than or equal to the cut-off
295336
"""
296337
x = np.asarray(x)
297338
y = np.asarray(y)
@@ -301,6 +342,12 @@ def max_x_at_y_more(x, y, cut_off):
301342
def max_x_at_y_less(x, y, cut_off):
302343
"""Gets max of elements in x where elements
303344
in y are leq to a cut off value
345+
346+
:param: x: array of values
347+
:param: y: array of values similar length to x
348+
:param: cutoff - value at which to consider the cut-offon y
349+
:param
350+
:return: return the maximum of x for all corresponding values of y less than the cut-off
304351
"""
305352
x = np.asarray(x)
306353
y = np.asarray(y)
@@ -311,8 +358,11 @@ def min_x_at_y_less(x, y, cut_off):
311358
"""Gets min of elements in x where elements
312359
in y are leq to a cut off value
313360
314-
:param:
315-
:return: minimum of x such as y is <= cutoff
361+
:param: x: array of values
362+
:param: y: array of values similar length to x
363+
:param: cutoff - value at which to consider the cut-offon y
364+
:param
365+
:return: return the maximum of x for all corresponding values of y less than the cut-off
316366
"""
317367
x = np.asarray(x)
318368
y = np.asarray(y)
@@ -323,7 +373,9 @@ def min_x_at_y_more(x,y,cut_off):
323373
"""Gets min of elements in x where elements in
324374
y are greater than cutoff value
325375
326-
:param: x, y, cutoff
376+
:param: x, vector of values
377+
:param: y, vector of values same size of x
378+
:param: cutoff cutoff value for y
327379
:return: min of x where y >= cut_off
328380
"""
329381
x = np.asarray(x)
@@ -333,6 +385,10 @@ def min_x_at_y_more(x,y,cut_off):
333385

334386
def one_hot_encode(img, n_classes):
335387
"""One-hot encodes categorical image
388+
389+
:param: img: labelled nd-array to encode
390+
:param: n_classes: number of classes to consider when encoding - this is specified to avoid "forgetting one class"
391+
:return: one hot encoded version of the input labelled image given the number of classes specified
336392
"""
337393
return np.eye(n_classes)[img]
338394

@@ -354,6 +410,14 @@ def to_string_count(measures_count, counting_dict, fmt="{:.4f}"):
354410

355411

356412
def to_string_dist(measures_dist, distance_dict, fmt="{:.4f}"):
413+
"""
414+
Transform to a comma separated string the content of results from the dictionary with all the distance based metrics
415+
416+
:param: measures_dist: list of distance metrics
417+
:param: distance_dict: dictionary with the results of the distance metrics
418+
:param: fmt: format in which the outputs should be written (default 4 decimal points)
419+
:return: complete comma-separated string of results in the order of keys specifid by measures_dist
420+
"""
357421
result_str = ""
358422
# list_space = ['com_ref', 'com_pred', 'list_labels']
359423
for key in measures_dist:
@@ -371,6 +435,14 @@ def to_string_dist(measures_dist, distance_dict, fmt="{:.4f}"):
371435

372436

373437
def to_string_mt(measures_mthresh, multi_thresholds_dict, fmt="{:.4f}"):
438+
"""
439+
Transform to a comma separated string the content of results from the dictionary with all the multi-threshold metric
440+
441+
:param: measures_mthresh: list of multi threshold metrics
442+
:param: multi_thresholds_dict: dictionary with the results of the multi-threshold metrics
443+
:param: fmt: format in which the outputs should be written (default 4 decimal points)
444+
:return: complete comma-separated string of results in the order of keys specifid by measures_mthresh
445+
"""
374446
result_str = ""
375447
# list_space = ['com_ref', 'com_pred', 'list_labels']
376448
for key in measures_mthresh:
@@ -403,6 +475,13 @@ def to_dict_meas_(measures, measures_dict, fmt="{:.4f}"):
403475
return result_dict # trim the last comma
404476

405477
def combine_df(df1,df2):
478+
"""
479+
Perform the concatenation of two dataframes - is used in the overall process when combining dataframe from existing and missing/failed prediction
480+
481+
:param: df1 First dataframe to concatenate
482+
:param: df2 Second dataframe to concatenate
483+
:return: concatenated dataframe of df1 and df2
484+
"""
406485
if df1 is None or df1.shape[0]==0:
407486
print('Nothing in first')
408487
if df2 is None:
@@ -418,6 +497,14 @@ def combine_df(df1,df2):
418497
return pd.concat([df1, df2])
419498

420499
def merge_list_df(list_df, on=['label','case']):
500+
"""
501+
Performs the merging of different dataframes of results given the label and cases values
502+
503+
:param: list_df: list of dataframes to merge together
504+
:param: on list of columns on which to perform the merging operation
505+
:return: df_fin: final merged dataframe
506+
"""
507+
421508
list_fin = []
422509
for k in list_df:
423510
if k is not None and k.shape[0] > 0:

0 commit comments

Comments
 (0)