Exemple #1
0
def save_final_images(microscope, settings, lamella_number):
    """Aquire and save ion beam & SEM images after complete milling stage."""
    from autoscript_sdb_microscope_client.structures import (GrabFrameSettings,
                                                             Rectangle)

    output_dir = settings["save_directory"]
    fullfield_cam_settings = GrabFrameSettings(
        reduced_area=Rectangle(0, 0, 1, 1),
        resolution=settings["fiducial"]["reduced_area_resolution"],
        dwell_time=settings["imaging"]["dwell_time"],
    )
    if settings["imaging"]["autocontrast"]:
        microscope.imaging.set_active_view(2)  # the ion beam view
        microscope.auto_functions.run_auto_cb()
    if settings["imaging"]["full_field_ib_images"]:
        original_ion_current = microscope.beams.ion_beam.beam_current.value
        microscope.beams.ion_beam.beam_current.value = 20e-12  # ion imaging
        image = grab_ion_image(microscope, fullfield_cam_settings)
        filename = os.path.join(
            output_dir,
            "IB_lamella{}-milling-complete.tif".format(lamella_number + 1))
        image.save(filename)
        microscope.beams.ion_beam.beam_current.value = original_ion_current
    sem_adorned_image = grab_sem_image(microscope, fullfield_cam_settings)
    sem_fname = "SEM_lamella{}-milling-complete.tif".format(lamella_number + 1)
    sem_filename = os.path.join(output_dir, sem_fname)
    sem_adorned_image.save(sem_filename)
Exemple #2
0
def create_camera_settings(imaging_settings, reduced_area=None):
    """Camera settings for acquiring images on the microscope.

    Parameters
    ----------
    imaging_settings : dictionary
        User input as dictionary containing keys "resolution" and "dwell_time".
    reduced_area : Rectangle, optional
        Reduced area view for image acquisition.
        By default None, which will create a Rectangle(0, 0, 1, 1),
        which means the whole field of view will be imaged.

    Returns
    -------
    GrabFrameSettings
        Camera acquisition settings
    """
    from autoscript_sdb_microscope_client.structures import (GrabFrameSettings,
                                                             Rectangle)

    if reduced_area is None:
        reduced_area = Rectangle(0, 0, 1, 1)
    camera_settings = GrabFrameSettings(
        resolution=imaging_settings["resolution"],
        dwell_time=imaging_settings["dwell_time"],
        reduced_area=reduced_area,
    )
    return camera_settings
Exemple #3
0
def fiducial_reduced_area_rect(fiducial_relative_center,
                               fiducial_relative_size):
    """Return autoscript Rectangle object describing the fiducial reduced area

    Returns
    -------
    Autoscript Rectangle
        Fiducial reduced area rectangle, in relative units.
    """
    from autoscript_sdb_microscope_client.structures import Rectangle

    width, height = fiducial_relative_size
    top_left_x = fiducial_relative_center[0] - (width / 2)
    top_left_y = fiducial_relative_center[1] - (height / 2)
    if top_left_x < 0:
        top_left_x = 0
    if top_left_x > 1:
        raise ValueError(
            "top_left_x relative coordinate cannot be larger than 1")
    if top_left_y < 0:
        top_left_y = 0
    if top_left_y > 1:
        raise ValueError(
            "top_left_y relative coordinate cannot be larger than 1")
    # create the relative rectangle
    fiducial_reduced_area = Rectangle(top_left_x, top_left_y, width, height)
    print("fiducial_reduced_area", fiducial_reduced_area)
    return fiducial_reduced_area
Exemple #4
0
def run_drift_corrected_milling(microscope,
                                correction_interval,
                                reduced_area=None):
    """
    Parameters
    ----------
    microscope : Autoscript microscope object
    correction_interval : Time in seconds between drift correction realignment
    reduced_area : Autoscript Rectangle() object
        Describes the reduced area view in relative coordinates, with the
        origin in the top left corner.
        Default value is None, which will create a Rectangle(0, 0, 1, 1),
        which means the imaging will use the whole field of view.
    """
    from autoscript_core.common import ApplicationServerException
    from autoscript_sdb_microscope_client.structures import (GrabFrameSettings,
                                                             Rectangle)

    if reduced_area is None:
        reduced_area = Rectangle(0, 0, 1, 1)
    s = GrabFrameSettings(reduced_area=reduced_area)
    reference_image = microscope.imaging.grab_frame(s)
    # start drift corrected patterning (is a blocking function, not asynchronous)
    microscope.patterning.start()
    while microscope.patterning.state == "Running":
        time.sleep(correction_interval)
        try:
            microscope.patterning.pause()
        except ApplicationServerException:
            continue
        else:
            new_image = microscope.imaging.grab_frame(s)
            realign(microscope, new_image, reference_image)
            microscope.patterning.resume()
Exemple #5
0
def test_create_camera_settings(microscope):
    from autoscript_sdb_microscope_client.structures import GrabFrameSettings

    imaging_settings = {"resolution": "1536x1024", "dwell_time": 1e-6}
    result = autolamella.acquire.create_camera_settings(imaging_settings,
                                                        reduced_area=Rectangle(
                                                            0, 0, 1, 1))
    assert isinstance(result, GrabFrameSettings)
Exemple #6
0
    def set_sem_image(self, microscope, settings):
        from autoscript_sdb_microscope_client.structures import (
            GrabFrameSettings,
            Rectangle,
        )

        microscope.imaging.set_active_view(1)  # SEM beam view
        camera_settings = GrabFrameSettings(
            reduced_area=Rectangle(0, 0, 1, 1),
            resolution=settings["imaging"]["resolution"],
        )
        self.sem_image = microscope.imaging.grab_frame(camera_settings)
        microscope.imaging.set_active_view(2)  # Restore ion beam view
        return self.sem_image
Exemple #7
0
def grab_images(microscope, settings, my_lamella, prefix="", suffix=""):
    """Aquire and save images, with optional autocontrast.

    Parameters
    ----------
    microscope : Autoscript microscope object.
    settings : dictionary
        Dictionary continaing user input parameters.
    my_lamella : Lamella object
    prefix : str, optional
        Prefix to use when saving image files, by default ""
    suffix : str, optional
        Suffix to use when saving image files, by default ""

    Returns
    -------
    AdornedImage
        The reduced area ion beam image (shows just the fiducial marker).
    """
    from autoscript_sdb_microscope_client.structures import (GrabFrameSettings,
                                                             Rectangle)

    output_dir = settings["save_directory"]
    # Reduced area images (must reset camera settings each time, because different samples have different reduced areas)
    camera_settings = GrabFrameSettings(
        reduced_area=my_lamella.fiducial_reduced_area,
        resolution=settings["fiducial"]["reduced_area_resolution"],
        dwell_time=settings["imaging"]["dwell_time"],
    )
    fullfield_cam_settings = GrabFrameSettings(
        reduced_area=Rectangle(0, 0, 1, 1),
        resolution=settings["fiducial"]["reduced_area_resolution"],
        dwell_time=settings["imaging"]["dwell_time"],
    )
    # Optional autocontrast (you cannot do autocontrast on a reduced area)
    if settings["imaging"]["autocontrast"]:
        microscope.imaging.set_active_view(2)  # the ion beam view
        autocontrast(microscope)
    image = grab_ion_image(microscope, camera_settings)
    filename = os.path.join(output_dir, prefix + "_" + suffix + ".tif")
    image.save(filename)
    # Optional full field images
    acquire_many_images = settings["imaging"]["full_field_ib_images"]
    if acquire_many_images:
        fullfield_image = grab_ion_image(microscope, fullfield_cam_settings)
        fname_fullfield = prefix + "_FullField_" + suffix + ".tif"
        filename_fullfield = os.path.join(output_dir, fname_fullfield)
        fullfield_image.save(filename_fullfield)
    return image
Exemple #8
0
def camera_settings():
    imaging_settings = {"resolution": "3072x2048", "dwell_time": 1e-6}
    camera_settings = autolamella.acquire.create_camera_settings(
        imaging_settings, reduced_area=Rectangle(0, 0, 1, 1))
    return camera_settings
def add_single_sample(microscope, settings):
    """Create a single lamella object.

    Parameters
    ----------
    microscope : Autoscript microscope object.
    settings :  Dictionary of user input argument settings.

    Returns
    -------
    my_lamella
        A single Lamella() object.
    """
    from autoscript_core.common import ApplicationServerException
    from autoscript_sdb_microscope_client.structures import (GrabFrameSettings,
                                                             Rectangle)

    autolamella.autoscript.reset_state(microscope, settings)
    demo_mode = settings["demo_mode"]
    acquire_many_images = settings["imaging"]["full_field_ib_images"]
    # Reset microscope state
    autolamella.autoscript.reset_state(microscope, settings)
    microscope.beams.ion_beam.beam_current.value = settings["lamella"][
        "milling_current"]
    # Optional autocontrast
    if settings["imaging"]["autocontrast"]:
        microscope.imaging.set_active_view(2)  # the ion beam view
        autolamella.acquire.autocontrast(microscope)
    # Take full field image
    full_field_camera_settings = autolamella.acquire.create_camera_settings(
        settings["imaging"], reduced_area=Rectangle(0, 0, 1, 1))
    original_image = grab_ion_image(microscope, full_field_camera_settings)
    # Select fiducial posiion
    print("Please select where to put a fiducial marker.")
    my_fiducial = autolamella.fiducial.fiducial(
        microscope,
        original_image,
        settings["fiducial"]["fiducial_length"],
        settings["fiducial"]["fiducial_width"],
        settings["fiducial"]["fiducial_image_size_x"],
        settings["fiducial"]["fiducial_image_size_y"],
        settings["fiducial"]["fiducial_milling_depth"],
    )
    if my_fiducial is None:
        print("No fiducial location selected, cancelling.")
        microscope.patterning.clear_patterns()
        return
    #
    fiducial_coord_realspace, fiducial_coord_relative, fiducial_coord_pixels = (
        my_fiducial)
    pixelsize_x = original_image.metadata.binary_result.pixel_size.x
    fiducial_image_relative_size = [
        settings["fiducial"]["fiducial_image_size_x"] /
        (original_image.width * pixelsize_x),
        settings["fiducial"]["fiducial_image_size_y"] /
        (original_image.height * pixelsize_x),
    ]
    reduced_area_fiducial = autolamella.fiducial.fiducial_reduced_area_rect(
        fiducial_coord_relative, fiducial_image_relative_size)
    camera_settings = autolamella.acquire.create_camera_settings(
        settings["imaging"], reduced_area=reduced_area_fiducial)
    cropped_original_image = grab_ion_image(microscope, camera_settings)
    my_lamella = Lamella(microscope)
    my_lamella.fiducial_image_relative_size = fiducial_image_relative_size
    my_fiducial = my_lamella.set_fiducial(
        cropped_original_image,
        fiducial_coord_realspace,
        fiducial_coord_relative,
        fiducial_coord_pixels,
        reduced_area_fiducial,
    )
    # Select the lamella position
    print("Please select the center point of your lamella.")
    my_lamella.original_image = original_image
    lamella_center = my_lamella.set_center(original_image, settings)
    if lamella_center == []:
        print("No lamella position selected, cancelling.")
        microscope.patterning.clear_patterns()
        return
    # Ask user for decision
    message = "Are you happy with this position? [y]/n\n"
    if ask_user(message, default="yes"):
        message = "Do you want to mill a fiducial marker here? [y]/n\n"
        if ask_user(message, default="yes"):
            print("Milling fiducial marker...")
            if not demo_mode:
                microscope.beams.ion_beam.beam_current.value = settings[
                    "fiducial"]["fiducial_milling_current"]
                microscope.imaging.set_active_view(2)  # the ion beam view
                try:
                    microscope.patterning.run()
                except ApplicationServerException:
                    logging.error(
                        "ApplicationServerException: could not mill!")
                    microscope.patterning.clear_patterns()
                    return  # returns None which gets stripped from sample list
            if acquire_many_images:
                full_field_camera_settings = GrabFrameSettings(
                    reduced_area=Rectangle(0, 0, 1, 1),
                    resolution=settings["imaging"]["resolution"],
                    dwell_time=settings["imaging"]["dwell_time"],
                )
                microscope.auto_functions.run_auto_cb()
                reference_image = grab_ion_image(microscope,
                                                 full_field_camera_settings)
                my_lamella.reference_image = reference_image
            camera_settings = GrabFrameSettings(
                reduced_area=reduced_area_fiducial,
                resolution=settings["fiducial"]["reduced_area_resolution"],
                dwell_time=settings["imaging"]["dwell_time"],
            )
            cropped_reference_image = grab_ion_image(microscope,
                                                     camera_settings)
            message = "Do you want to re-mill the fiducial marker? y/[n]\n"
            if ask_user(message, default="no"):
                print("Milling fiducial marker again...")
                if not demo_mode:
                    microscope.imaging.set_active_view(2)  # the ion beam view
                    try:
                        microscope.patterning.run()
                    except ApplicationServerException:
                        logging.error(
                            "ApplicationServerException: could not mill")
                        microscope.patterning.clear_patterns()
                        return  # returns None which gets stripped from sample list
                if acquire_many_images:
                    full_field_camera_settings = GrabFrameSettings(
                        reduced_area=Rectangle(0, 0, 1, 1),
                        resolution=settings["imaging"]["resolution"],
                        dwell_time=settings["imaging"]["dwell_time"],
                    )
                    microscope.auto_functions.run_auto_cb()
                    reference_image = grab_ion_image(
                        microscope, full_field_camera_settings)
                    my_lamella.reference_image = reference_image
                microscope.patterning.clear_patterns()
    else:
        print("Ok, deleting those milling patterns.")
        microscope.patterning.clear_patterns()
        return  # returns None, which gets stripped from sample list later
    # Continue on
    camera_settings = GrabFrameSettings(
        reduced_area=reduced_area_fiducial,
        resolution=settings["fiducial"]["reduced_area_resolution"],
        dwell_time=settings["imaging"]["dwell_time"],
    )
    cropped_reference_image = grab_ion_image(microscope, camera_settings)
    my_lamella.set_fiducial(
        cropped_reference_image,
        fiducial_coord_realspace,
        fiducial_coord_relative,
        fiducial_coord_pixels,
        reduced_area_fiducial,
    )
    if not acquire_many_images:
        my_lamella.reference_image = cropped_reference_image
    my_lamella.set_sem_image(microscope, settings)
    my_lamella.set_custom_milling_depth()
    return my_lamella