import logging
import matplotlib.pyplot as plt
import fibsem.conversions
import fibsem.data
import fibsem.display
import fibsem.orientation
import fibsem.milling
import fibsem.segmentation
import fibsem.user_input
log = logging.getLogger(__name__)
[docs]class Sample:
"""Abstract base class for FIB-SEM samples. NOT FOR DIRECT USE"""
def __init__(self):
self.image = None
self.mask = None
self.milling_rois = None
self.pixel_size = None
self.stage_position = None
[docs] def set_image(self, microscope):
microscope.imaging.set_active_view(2) # ion beam view
self.image = microscope.imaging.get_image()
try:
self.set_pixel_size()
except AttributeError:
pass
return self.image
[docs] def set_pixel_size(self):
if self.image is not None:
self.pixel_size = self.image.metadata.binary_result.pixel_size
return self.image.metadata.binary_result.pixel_size
[docs] def set_stage_position(self, microscope):
self.stage_position = microscope.specimen.stage.current_position
return self.stage_position
[docs] def set_mask(self):
while self.mask is None:
self.mask = fibsem.segmentation.manual_segmentation(self.image)
while not (self.mask == True).any(): # fixing PEP8 here causes error
print('ERROR: MUST RIGHT CLICK TO FINALIZE MASK SELECTION')
self.mask = fibsem.segmentation.manual_segmentation(self.image)
return self.mask
[docs] def move_to_stage_position(self, microscope):
target_position = self.stage_position
microscope.specimen.stage.absolute_move(target_position)
[docs] def print_vars(self):
print(vars(self))
[docs] def save_vars(self, output_filename):
with open(output_filename, 'w') as f:
f.write(str(vars(self)))
[docs]class Embryo(Sample):
"""Class for FIB-SEM embryos."""
def __init__(self, microscope=None):
super(Embryo, self).__init__()
self.major_axis = None
self.minor_axis = None
self.head_position = None
self.axes_for_milling = None
if microscope:
self.image = self.set_image(microscope)
self.pixel_size = self.set_pixel_size()
self.stage_position = self.set_stage_position(microscope)
else:
self.image = fibsem.data.embryo_adorned()
self.mask = fibsem.data.embryo_mask()
self.pixel_size = self.image.metadata.binary_result.pixel_size
[docs] def display_crosshairs(self):
if self.major_axis is None or self.minor_axis is None:
self.orientation()
fig, ax = fibsem.display.draw_crosshairs(
self.image, self.major_axis, self.minor_axis)
plt.show()
[docs] def display_milling_axes(self):
if not self.axes_for_milling:
raise ValueError('Must call set_axes_for_milling() method first!')
else:
fig, ax = fibsem.display.draw_object_axes(
self.image, self.axes_for_milling)
plt.show()
[docs] def display_milling_rois(self):
fig, ax = fibsem.display.draw_rotated_rects(
self.milling_rois, image=self.image)
plt.show()
[docs] def display_milling_rois_mask(self):
mask_adorned = fibsem.conversions._convert_to_adornedimage(
self.mask, self.pixel_size.x, self.pixel_size.y)
fig, ax = fibsem.display.draw_rotated_rects(
self.milling_rois, image=mask_adorned)
plt.show()
[docs] def set_axes_for_milling(self, settings):
head2tail, tail2head = fibsem.milling._dual_milling_directions(
self.major_axis, settings)
self.axes_for_milling = [head2tail, tail2head]
[docs] def set_head_position(self):
self.head_position = fibsem.segmentation.select_point(self.image)
return self.head_position
[docs] def set_milling_rois(self, settings):
if self.major_axis is None or self.minor_axis is None:
self.orientation()
self.milling_rois = fibsem.milling.all_roi_coordinates(self, settings)
return self.milling_rois
[docs] def orientation(self):
major_axis, minor_axis = fibsem.orientation.major_minor_axes_realspace(
self.mask, self.pixel_size, reference_coord=self.head_position)
self.major_axis = major_axis
self.minor_axis = minor_axis
return self.major_axis, self.minor_axis
[docs]def add_samples(microscope, settings, display_matplotlib=False):
"""Interactive function to add samples to list.
Parameters
----------
microscope : Autoscript microscope object.
settings : User input argument settings.
Returns
-------
samples
List of FIB-SEM sample objects.
"""
from fibsem.user_input import default_response_yes, response_no
samples = []
user_response = ''
while user_response.lower() not in response_no:
message = 'Do you want to select another sample for milling? y/[n]'
user_response = input(message)
if user_response.lower() in default_response_yes:
my_sample = Embryo(microscope)
my_sample.set_mask()
if isinstance(my_sample, Embryo):
my_sample.set_head_position()
my_sample.set_milling_rois(settings)
if display_matplotlib is True:
my_sample.display_milling_rois()
fibsem.autoscript.reset_patterning_state(microscope)
fibsem.autoscript.create_milling_patterns(microscope,
my_sample.milling_rois,
settings)
message = 'Please confirm these milling ROIs are correct. y/[n]'
user_confirmation = input(message)
if user_confirmation.lower() in default_response_yes:
samples.append(my_sample)
else:
print('Ok, skipping this sample.')
fibsem.autoscript.reset_patterning_state(microscope)
return samples