Skip to content

Commit

Permalink
Improve masking
Browse files Browse the repository at this point in the history
Masking is now performed on accessing data in the datastore
  • Loading branch information
rhysgt committed Apr 15, 2024
1 parent 0496217 commit 3cb1161
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 41 deletions.
2 changes: 1 addition & 1 deletion defdap/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def __init__(self, file_name, data_type=None, experiment=None,
"""

self.data = Datastore(crop_func=self.crop)
self.data = Datastore(crop_func=self.crop, mask_func=self.mask)
self.frame = frame if frame is not None else Frame()
if increment is not None:
self.increment = increment
Expand Down
7 changes: 4 additions & 3 deletions defdap/ebsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ class Map(base.Map):
Nye_tensor : numpy.ndarray
3x3 Nye tensor at each point.
Derived data:
Grain list data to map data from all grains
grain_data_to_map : numpy.ndarray
Grain list data to map data from all grains
"""
MAPNAME = 'ebsd'
Expand Down Expand Up @@ -1156,9 +1157,9 @@ class Grain(base.Grain):
(x, y)
Generated data:
GROD : numpy.ndarray
Grain reference orientation distribution magnitude
GROD_axis : numpy.ndarray
Grain reference orientation distribution direction
Derived data:
Map data to list data from the map the grain is part of
Expand Down
53 changes: 17 additions & 36 deletions defdap/hrdic.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ def __init__(self, *args, **kwargs):
self.bse_scale = None # size of pixels in pattern images
self.bse_scale = None # size of pixels in pattern images
self.crop_dists = np.array(((0, 0), (0, 0)), dtype=int)
self.mask = None

## TODO: cropping, have metadata to state if saved data is cropped, if
## not cropped then crop on accesss. Maybe mark cropped data as invalid
Expand Down Expand Up @@ -444,11 +445,9 @@ def warp_to_dic_frame(self, map_data, **kwargs):
**kwargs
)

# TODO: fix component stuff
def generate_threshold_mask(self, mask, dilation=0, preview=True):
def set_mask(self, mask, dilation=0):
"""
Generate a dilated mask, based on a boolean array and previews the appication of
this mask to the max shear map.
Generate a dilated mask, based on a boolean array.
Parameters
----------
Expand All @@ -457,8 +456,6 @@ def generate_threshold_mask(self, mask, dilation=0, preview=True):
dilation: int, optional
Number of pixels to dilate the mask by. Useful to remove anomalous points
around masked values. No dilation applied if not specified.
preview: bool
If true, show the mask and preview the masked effective shear strain map.
Examples
----------
Expand All @@ -484,40 +481,24 @@ def generate_threshold_mask(self, mask, dilation=0, preview=True):
self.mask = binary_dilation(self.mask, iterations=dilation)

num_removed = np.sum(self.mask)
num_total = self.xdim * self.ydim
num_removed_crop = np.sum(self.crop(self.mask))
num_total_crop = self.x_dim * self.y_dim
num_total = self.x_dim * self.y_dim

print('Filtering will remove {0} \ {1} ({2:.3f} %) datapoints in map'
.format(num_removed, num_total, (num_removed / num_total) * 100))
print(
'Filtering will remove {0} \ {1} ({2:.3f} %) datapoints in cropped map'
.format(num_removed_crop, num_total_crop,
(num_removed_crop / num_total_crop * 100)))

if preview == True:
plot1 = MapPlot.create(self, self.crop(self.mask), cmap='binary')
plot1.set_title('Removed datapoints in black')
plot2 = MapPlot.create(self,
self.crop(
np.where(self.mask == True, np.nan,
self.data.max_shear)),
plot_colour_bar='True',
clabel="Effective shear strain")
plot2.set_title('Effective shear strain preview')
print(
'Use apply_threshold_mask function to apply this filtering to data')

def apply_threshold_mask(self):
""" Apply mask to all DIC map data by setting masked values to nan.
'Masking will remove {0} \ {1} ({2:.3f} %) datapoints in cropped map'
.format(num_removed, num_total, (num_removed / num_total * 100)))

def mask(self, map_data):
""" Values set to False in mask will be set to nan in map.
"""
for comp in ('max_shear',
'e11', 'e12', 'e22',
'f11', 'f12', 'f21', 'e22',
'x_map', 'y_map'):
# self.data[comp] = np.where(self.mask == True, np.nan, self.data[comp])
self.data[comp][self.mask] = np.nan

if self.mask is not None:
if np.shape(self.mask) == self.shape:
map_data[..., self.mask] = np.nan
return map_data
else:
raise Exception("Mask must be the same shape as cropped data.")
else:
return map_data

def set_pattern(self, img_path, window_size):
"""Set the path to the image of the pattern.
Expand Down
6 changes: 5 additions & 1 deletion defdap/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,19 +99,21 @@ class Datastore(object):
'_derivatives',
'_group_id',
'_crop_func',
'_mask_func'
]
_been_to = None

@staticmethod
def generate_id():
return uuid4()

def __init__(self, group_id=None, crop_func=None):
def __init__(self, group_id=None, crop_func=None, mask_func=None):
self._store = {}
self._generators = {}
self._derivatives = []
self._group_id = self.generate_id() if group_id is None else group_id
self._crop_func = (lambda x, **kwargs: x) if crop_func is None else crop_func
self._mask_func = (lambda x, **kwargs: x) if mask_func is None else mask_func

def __len__(self):
"""Number of data in the store, including data not yet generated."""
Expand Down Expand Up @@ -175,6 +177,8 @@ def __getitem__(self, key):
not self.get_metadata(key, 'cropped', False)):
binning = self.get_metadata(key, 'binning', 1)
val = self._crop_func(val, binning=binning)

val = self._mask_func(val)

return val

Expand Down

0 comments on commit 3cb1161

Please sign in to comment.