Example #1
0
def run():
    c = gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER)
    filename = c['/filename']
    dir_path,basename = os.path.split(filename)
    basename = basename[0:-4]
    #print dir_path,base_name
    d = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD)
    data_field_id = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD_ID)
    meta_field = '/' + str(data_field_id) + '/meta'
    title = '/' + str(data_field_id) + '/data/title'
    channel = c[title]
    #print channel
    gwy.gwy_app_data_browser_select_data_field(c,data_field_id)
    #meta = c[meta_field]
    #print meta.keys_by_name()
    #bias = meta['Bias']
    #bias, bu = bias.split(' ')
    #current = meta['Z controller Setpoint']
    #current, cu = current.split(' ')
    #current = float(current) * 1e12
    #cu = 'pA'
    #current_bias = 'pm'
    #xd = d.get_xreal() * 1e9
    #yd = d.get_yreal() * 1e9
    #xyu = 'nm'
    output_path = dir_path
    output_name = basename + '.png'
    output = os.path.join(output_path,output_name)
    gwy.gwy_file_save(c, output, gwy.RUN_NONINTERACTIVE)
Example #2
0
def heightediting(data, k):
    gwy.gwy_app_data_browser_select_data_field(data, k)

    # Flatten the data
    gwy.gwy_process_func_run('flatten_base', data, gwy.RUN_IMMEDIATE)

    datafield = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD)
    mask = gwy.DataField.new_alike(datafield, False)
    datafield.grains_mark_height(mask, 30, False)

    # Re-do polynomial correction with masked height
    s["/module/polylevel/masking"] = 1
    gwy.gwy_process_func_run('polylevel', data, gwy.RUN_IMMEDIATE)

    # Re-do align rows with masked heights
    s["/module/linematch/masking"] = 1
    gwy.gwy_process_func_run('align_rows', data, gwy.RUN_IMMEDIATE)

    # # Remove scars
    # gwy.gwy_process_func_run('scars_remove', data, gwy.RUN_IMMEDIATE)

    # Gaussian filter to remove noise
    current_data = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD)

    filter_width = 5 * dx * 1e9

    current_data.filter_gaussian(filter_width)

    # Set zero to mean value
    gwy.gwy_process_func_run('zero_mean', data, gwy.RUN_IMMEDIATE)

    return data
Example #3
0
def run():
    c = gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER)
    _id = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD_ID)

    # key = "/0/select/line"
    selections = [
        key for key in c.keys_by_name() if "/{}/select".format(_id) in key
    ]
    # print(selections)

    # create new combo box
    combo = gtk.combo_box_new_text()
    # add in valid selection options
    for selection in selections:
        combo.append_text(selection)
    # set default value as first in selections list, otherwise -1: None
    combo.set_active(0 if len(selections) else -1)

    # set up generic dialogue window
    dialogue = gtk.Dialog(
        title="Choose Selection",
        flags=gtk.DIALOG_MODAL,
        buttons=(
            gtk.STOCK_CANCEL,
            gtk.RESPONSE_REJECT,
            gtk.STOCK_OK,
            gtk.RESPONSE_ACCEPT,
        ),
    )

    # add combobox widget to dialogue
    dialogue.get_content_area().pack_start(combo)

    # main loop and wait for user response
    dialogue.show_all()
    response = dialogue.run()

    # heavy lifting done below here...
    # is user pressed OK
    if response == gtk.RESPONSE_ACCEPT:
        key = selections[combo.get_active()]
        # for each datafield in container
        for _id0 in gwy.gwy_app_data_browser_get_data_ids(c):
            # copy line
            line = c[key].duplicate()
            # add to new datafield with new key
            c.set_object(
                gwy.gwy_key_from_name(key.replace(str(_id), str(_id0))), line)

    # kill dialogue
    dialogue.destroy()
Example #4
0
def get_current_datafield():
   """
   Short version of function L{gwy.gwy_app_data_browser_get_current}(gwy.APP_DATA_FIELD)

   @return: current datafield
   """
   return gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD)
Example #5
0
def get_current_container():
    """
   Short version of function L{gwy.gwy_app_data_browser_get_current}(gwy.APP_CONTAINER)

   @return: current container
   """
    return gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER)
Example #6
0
def get_current_datafield():
    """
   Short version of function L{gwy.gwy_app_data_browser_get_current}(gwy.APP_DATA_FIELD)

   @return: current datafield
   """
    return gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD)
Example #7
0
def get_current_container():
   """
   Short version of function L{gwy.gwy_app_data_browser_get_current}(gwy.APP_CONTAINER)

   @return: current container
   """
   return gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER)
Example #8
0
def editfile(data, k):
    # select each channel of the file in turn
    # this is run within the for k in chosen_ids loop so k refers to the index of each chosen channel to analyse
    # NONINTERACTIVE is only for file modules
    gwy.gwy_app_data_browser_select_data_field(data, k)

    # align rows (b)
    gwy.gwy_process_func_run("align_rows", data, gwy.RUN_IMMEDIATE)

    # flatten the data (c)
    gwy.gwy_process_func_run("level", data, gwy.RUN_IMMEDIATE)

    # align rows (d)
    gwy.gwy_process_func_run("align_rows", data, gwy.RUN_IMMEDIATE)

    datafield = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD)
    mask = gwy.DataField.new_alike(datafield, False)
    datafield.grains_mark_height(mask, 10, False)

    # Re-do polynomial correction with masked height (e)
    s["/module/polylevel/masking"] = 0
    gwy.gwy_process_func_run('polylevel', data, gwy.RUN_IMMEDIATE)

    # Re-do align rows with masked heights (f)
    s["/module/linematch/masking"] = 0
    gwy.gwy_process_func_run('align_rows', data, gwy.RUN_IMMEDIATE)

    # Re-do level with masked heights (g)
    s["/module/polylevel/masking"] = 1
    gwy.gwy_process_func_run('polylevel', data, gwy.RUN_IMMEDIATE)

    # flatten base (h)
    gwy.gwy_process_func_run('flatten_base', data, gwy.RUN_IMMEDIATE)

    # remove scars (i)
    gwy.gwy_process_func_run('scars_remove', data, gwy.RUN_IMMEDIATE)

    # Fix zero (j)
    gwy.gwy_process_func_run('zero_mean', data, gwy.RUN_IMMEDIATE)

    # Apply a 1.5 pixel gaussian filter (k)
    data_field = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD)
    data_field.filter_gaussian(1)
    # # Shift contrast - equivalent to 'fix zero'
    # datafield.add(-data_field.get_min())

    return data
Example #9
0
def run():
    # get current image data
    _id = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD_ID)
    container = gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER)

    # analyse_particles_otsu_median(container, datafield_id=datafield_id)
    
    # get datafield and compute threshold
    datafield = container.get_object_by_name(get_data_key(_id))
    threshold = threshold_otsu_median(datafield)
    # create grain mask
    grains = create_mask(datafield, threshold)
    # add mask field to container
    container.set_object_by_name(get_mask_key(_id), grains)
    
    # set mask colour and opacity
    set_mask_colour(container, _id)
Example #10
0
def run():
    # get current data and correct container for file
    _id = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD_ID)
    container = gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER)

    # create undo point
    gwy.gwy_undo_qcheckpoint(container, container.keys())

    # get datafield and compute threshold
    datafield = container.get_object(gwy.gwy_app_get_data_key_for_id(_id))
    threshold = threshold_otsu_median(datafield)
    # create grain mask
    grains = create_mask(datafield, threshold)
    # add mask field to container
    container.set_object(gwy.gwy_app_get_mask_key_for_id(_id), grains)

    # set mask colour and opacity
    set_mask_colour(container, _id)
Example #11
0
def run():
    import sys
    import os
    home = os.getenv('HOME')
    sys.path.append(home + '/.gwyddion/pygwy/')

    from SpeckView.BE.Spektrum import Spektrum
    Spektrum(home + '/.gwyddion/pygwy/SpeckView/BE/',
             gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER))
Example #12
0
def run():
    import sys
    import os
    home = os.getenv('HOME')
    sys.path.append(home + '/.gwyddion/pygwy/')

    from SpeckView.BE.Spektrum import Spektrum
    Spektrum(
        home + '/.gwyddion/pygwy/SpeckView/BE/',
        gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER)
    )
Example #13
0
def imagedetails(data):
    # select the channel file of chosen_ids
    gwy.gwy_app_data_browser_select_data_field(data, k)

    datafield = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD)

    xres = datafield.get_xres()
    yres = datafield.get_yres()
    xreal = datafield.get_xreal()
    yreal = datafield.get_yreal()
    dx = xreal / xres
    dy = yreal / yres
    return xres, yres, xreal, yreal, dx, dy
Example #14
0
def grainfinding(data, minarea, k, thresholdingcriteria, gaussian, dx):
    # Select channel 'k' of the file
    gwy.gwy_app_data_browser_select_data_field(data, k)
    datafield = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD)
    # Gaussiansize = 0.25e-9 / dx
    # datafield.filter_gaussian(Gaussiansize)

    mask = gwy.DataField.new_alike(datafield, False)

    Gaussiansize = gaussian / dx
    datafield.filter_gaussian(Gaussiansize)

    # Mask data that are above thresh*sigma from average height.
    # Sigma denotes root-mean square deviation of heights.
    # This criterion corresponds to the usual Gaussian distribution outliers detection if thresh is 3.
    datafield.mask_outliers2(mask, 5, thresholdingcriteria)

    # excluding mask, zero mean
    stats = datafield.area_get_stats_mask(mask, gwy.MASK_EXCLUDE, 0, 0,
                                          datafield.get_xres(),
                                          datafield.get_yres())
    datafield.add(-stats[0])

    # Set the image display to fixed range and the colour scale for the images
    maximum_disp_value = data.set_int32_by_name(
        "/" + str(k) + "/base/range-type", int(1))
    minimum_disp_value = data.set_double_by_name("/" + str(k) + "/base/min",
                                                 float(minheightscale))
    maximum_disp_value = data.set_double_by_name("/" + str(k) + "/base/max",
                                                 float(maxheightscale))

    ### Editing grain mask
    # Remove grains touching the edge of the mask
    mask.grains_remove_touching_border()

    # Calculate pixel width in nm
    # dx = datafield.get_dx()
    # Calculate minimum feature size in pixels (integer) from a real size specified in the main
    minsize = int(minarea / dx)
    # Remove grains smaller than the minimum size in integer pixels
    mask.grains_remove_by_size(minsize)

    # Numbering grains for grain analysis
    grains = mask.number_grains()

    # Update data to show mask, comment out to remove mask
    # data['/%d/mask' % k] = mask

    return data, mask, datafield, grains
Example #15
0
def run(container, mode):
    container = gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER)
    filename = container['/filename']
    path, _ = os.path.splitext(filename)
    output_path = path + OUTPUT_SUFFIX
    if not os.path.exists(output_path):
        os.mkdir(output_path)

    for i, id_ in enumerate(gwy.gwy_app_data_browser_get_data_ids(container)):
        title = container['/{}/data/title'.format(id_)]
        gwy.gwy_app_data_browser_select_data_field(container, id_)
        output_filename = '{:03d}_{}.{}'.format(id_, title, OUTPUT_FILESUFFIX)
        output_filename = os.path.join(output_path, output_filename)
        mode = gwy.RUN_INTERACTIVE if i == 0 else gwy.RUN_NONINTERACTIVE
        print 'Exporting {} ...'.format(output_filename)
        gwy.gwy_file_save(container, output_filename, mode)
Example #16
0
def run(container, mode):
    data_field_id = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD_ID)
    data_field = container[gwy.gwy_app_get_data_key_for_id(data_field_id)]

    new_container = gwy.Container()
    gwy.gwy_app_data_browser_add(new_container)

    # Need to populate container with dummy data, otherwise
    # gwy_app_data_browser_copy_channel crashes.
    dummy_id = gwy.gwy_app_data_browser_add_data_field(
        data_field, new_container, False
    )
    new_id = gwy.gwy_app_data_browser_copy_channel(
        container, data_field_id, new_container
    )
    gwy.gwy_app_data_browser_select_data_field(new_container, new_id)

    # Get rid of dummy reference.
    new_container.remove_by_prefix('/{}/'.format(dummy_id))
def run():
    ### Create undo point
    #key=gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD_KEY)
    #gwy.gwy_app_undo_checkpoint(gwy.data, [key])

    ### get Data Field

    originalDField = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD)
    dummyDF = originalDField.new_alike()

    sixtyDegreeField = originalDField.new_rotated(dummyDF, 60. * (PI / 180.),
                                                  gwy.INTERPOLATION_LINEAR,
                                                  gwy.ROTATE_RESIZE_SAME_SIZE)

    onetwentyDegreeField = originalDField.new_rotated(
        dummyDF, 120. * (PI / 180.), gwy.INTERPOLATION_LINEAR,
        gwy.ROTATE_RESIZE_SAME_SIZE)

    originalDField.sum_fields(originalDField, sixtyDegreeField)
    originalDField.sum_fields(originalDField, onetwentyDegreeField)
    originalDField.multiply(1. / 3.)

    originalDField.data_changed()
Example #18
0
def run():
    # get current image data
    datafield_id = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD_ID)
    container = gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER)

    laplacian_of_gaussian(container, datafield_id=datafield_id)
Example #19
0
def otsuthresholdgrainfinding(data, k):
    # 'align_rows' function
    # s["/module/linematch/direction"] = 0
    # s["/module/linematch/do_extract"] = False
    # s["/module/linematch/do_plot"] = False
    # s["/module/linematch/masking"] = 2
    # s["/module/linematch/max_degree"] = 0
    # s["/module/linematch/method"] = 0  # uses median
    # s["/module/linematch/trim_fraction"] = float(0.05)

    # Select channel 'k' of the file
    gwy.gwy_app_data_browser_select_data_field(data, k)
    datafield = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD)
    mask = gwy.DataField.new_alike(datafield, False)

    # Apply a 1.5 pixel gaussian filter
    data_field = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD)
    data_field.filter_gaussian(1.5)

    # # Mask data that are above thresh*sigma from average height.
    # # Sigma denotes root-mean square deviation of heights.
    # # This criterium corresponds to the usual Gaussian distribution outliers detection if thresh is 3.
    # datafield.mask_outliers(mask, 1)

    # # Shift contrast - equivalent to 'fix zero' - essential for next step to work
    datafield.add(-datafield.get_min())
    # Calculate min, max and range of data to allow calculation of relative value for grain thresholding
    min_datarange = datafield.get_min()
    max_datarange = datafield.get_max()
    datarange = max_datarange + min_datarange
    # Calculate Otsu threshold for data
    o_threshold = datafield.otsu_threshold()
    o_threshold = o_threshold + min_datarange
    # Calculate relative threshold for grain determination
    rel_threshold = 100 * (o_threshold / datarange)
    # Mask grains using either relative threshold of the data, i.e. a percentage
    # this can be set manually i.e. 35 or
    # as the otsu threshold expressed as a percentage which is rel_threshold
    # this will fail unless the min_datarange is negative
    datafield.grains_mark_height(mask, rel_threshold, False)

    # # Invert mask to maks things below the membrane
    mask.grains_invert()

    gwy.gwy_process_func_run("align_rows", data, gwy.RUN_IMMEDIATE)
    # # gwy.gwy_process_func_run("level", data, gwy.RUN_IMMEDIATE)
    # gwy.gwy_process_func_run('flatten_base', data, gwy.RUN_IMMEDIATE)

    # Select channel 'k' of the file
    gwy.gwy_app_data_browser_select_data_field(data, k)
    datafield = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD)
    mask = gwy.DataField.new_alike(datafield, False)
    # # Mask data that are above thresh*sigma from average height.
    # # Sigma denotes root-mean square deviation of heights.
    # # This criterium corresponds to the usual Gaussian distribution outliers detection if thresh is 3.
    # datafield.mask_outliers(mask, 1)

    # # Shift contrast - equivalent to 'fix zero' - essential for next step to work
    datafield.add(-datafield.get_min())
    # Calculate min, max and range of data to allow calculation of relative value for grain thresholding
    min_datarange = datafield.get_min()
    max_datarange = datafield.get_max()
    datarange = max_datarange + min_datarange
    # Calculate Otsu threshold for data
    o_threshold = datafield.otsu_threshold()
    o_threshold = o_threshold + min_datarange
    # Calculate relative threshold for grain determination
    rel_threshold = 100 * (o_threshold / datarange)
    # Mask grains using either relative threshold of the data, i.e. a percentage
    # this can be set manually i.e. 35 or
    # as the otsu threshold expressed as a percentage which is rel_threshold
    # this will fail unless the min_datarange is negative
    datafield.grains_mark_height(mask, rel_threshold, False)

    gwy.gwy_process_func_run('zero_mean', data, gwy.RUN_IMMEDIATE)

    # # Invert mask to make things below the membrane
    mask.grains_invert()

    # Calculate pixel width in nm
    dx = datafield.get_dx()
    # Calculate minimum feature size in pixels (integer)
    minsize = int(2000e-9 / dx)
    # Remove grains smaller than (size) in integer pixels
    mask.grains_remove_by_size(minsize)

    mask.grains_invert()
    gwy.gwy_process_func_run('zero_mean', data, gwy.RUN_IMMEDIATE)
    mask.grains_invert()

    # Numbering grains for grain analysis
    grains = mask.number_grains()
    print max(grains)

    # Update data to show mask, comment out to remove mask
    s['/module/pixmap/draw_mask'] = True
    data['/0/mask/red'] = 0.1234

    #excluding mask, zero mean
    stats = datafield.area_get_stats_mask(mask, gwy.MASK_EXCLUDE, 0, 0,
                                          datafield.get_xres(),
                                          datafield.get_yres())
    datafield.add(-stats[0])

    return data, mask, datafield, grains
Example #20
0
def run():
    # get open container
    container = gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER)
    # run algorithm
    low_signal_threshold(container)
Example #21
0
def run():
    # get current image data
    datafield_id = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD_ID)
    container = gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER)

    analyse_particles_otsu(container, datafield_id=datafield_id)
Example #22
0
import gwy
import gwyutils
import re
import os
from PIL import ImageFont
from PIL import Image
from PIL import ImageDraw

import numpy as np
from skimage import io, exposure, img_as_uint, img_as_float
# get the current container and datafield
c = gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER)
d = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD)
data_field_id = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD_ID)
gwy.gwy_app_data_browser_select_data_field(c,data_field_id)
filename = c['/filename']
basename = filename[0:-4]
print filename.split('/')[-1][:-4]

meta_field = '/' + str(data_field_id) + '/meta'
title = '/' + str(data_field_id) + '/data/title'
channel = c[title]
print channel

meta = c[meta_field]
print meta.keys_by_name()
bias = meta['Bias']
bias, bu = bias.split(' ')
current = meta['Z controller Setpoint']
current, cu = current.split(' ')
current = float(current) * 1e12
        gwy.gwy_process_func_run('level', gwy_rawdata, gwy.RUN_IMMEDIATE)

        #flatten the data
        gwy.gwy_process_func_run('flatten_base', gwy_rawdata,
                                 gwy.RUN_IMMEDIATE)

        #remove scars
        gwy.gwy_process_func_run('scars_remove', gwy_rawdata,
                                 gwy.RUN_IMMEDIATE)

        #execute 'align_rows' function
        #s["/module/linematch/method"] = 2
        #gwy.gwy_process_func_run('align_rows', gwy_rawdata, gwy.RUN_IMMEDIATE)

        #Gaussian filter to remove noise
        current_data = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD)
        current_data.filter_gaussian(0.75)
        current_data.data_changed()  #not sure this line is needed

        makeBinaryMask(gwy_rawdata, i)

        #polynomial correction with masked height
        s["/module/polylevel/masking"] = 0
        gwy.gwy_process_func_run('polylevel', gwy_rawdata, gwy.RUN_IMMEDIATE)

        #remove scars
        #gwy.gwy_process_func_run('scars_remove', gwy_rawdata, gwy.RUN_IMMEDIATE)

        #Re-do align rows with masked heights
        s["/module/linematch/masking"] = 0
        s["/module/linematch/method"] = 0
Example #24
0
def run():
    # get current data and correct container for file
    datafield_id = gwy.gwy_app_data_browser_get_current(gwy.APP_DATA_FIELD_ID)
    container = gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER)
    
    save_gwy_grain_mask_to_JSON(container, datafield_id=datafield_id)
Example #25
0
def boundbox(cropwidth, datafield, grains, dx, dy, xreal, yreal, xres, yres):
    # Function to return the coordinates of the bounding box for all grains.
    # contains 4 coordinates per image
    bbox = datafield.get_grain_bounding_boxes(grains)

    # Remove all data up to index 4 (i.e. the 0th, 1st, 2nd, 3rd).
    # These are the bboxes for grain zero which is the background and should be ignored
    del bbox[:4]

    # Find the center of each grain in x
    center_x = datafield.grains_get_values(grains, gwy.GRAIN_VALUE_CENTER_X)
    # Delete the background grain center
    del center_x[0]
    # Find the center of each grain in y
    center_y = datafield.grains_get_values(grains, gwy.GRAIN_VALUE_CENTER_Y)
    # Delete the background grain center
    del center_y[0]

    # Find the centre of the grain in pixels
    # get active container
    data = gwy.gwy_app_data_browser_get_current(gwy.APP_CONTAINER)
    # get current number of files
    orig_ids = gwy.gwy_app_data_browser_get_data_ids(data)

    # Define the width of the image to crop to
    cropwidth = int((cropwidth / xreal) * xres)

    # make 2d array for grains
    multidim_grain_array = np.reshape(np.array(grains), (xres, yres))

    for i in range(len(center_x)):
        px_center_x = int((center_x[i] / xreal) * xres)
        px_center_y = int((center_y[i] / yreal) * yres)
        # ULcol = px_center_x - cropwidth
        xmin = px_center_x - cropwidth
        # ULrow = px_center_y - cropwidth
        ymin = px_center_y - cropwidth
        # BRcol = px_center_x + cropwidth
        xmax = px_center_x + cropwidth
        # BRrow = px_center_y + cropwidth
        ymax = px_center_y + cropwidth

        # making sure cropping boxes dont run outside the image dimensions
        if xmin < 0:
            xmin = 0
            xmax = 2 * cropwidth
        if ymin < 0:
            ymin = 0
            ymax = 2 * cropwidth
        if xmax > xres:
            xmax = xres
            xmin = xres - 2 * cropwidth
        if ymax > yres:
            ymax = yres
            ymin = yres - 2 * cropwidth

        # print ULcol, ULrow, BRcol, BRrow
        # crop the data
        crop_datafield_i = datafield.duplicate()
        crop_datafield_i.resize(xmin, ymin, xmax, ymax)

        # add cropped datafield to active container
        gwy.gwy_app_data_browser_add_data_field(crop_datafield_i, data,
                                                i + (len(orig_ids)))

        # cropping the grain array:
        grain_num = i + 1
        cropped_np_grain = multidim_grain_array[ymin:ymax, xmin:xmax]
        cropped_grain = [
            1 if i == grain_num else 0 for i in cropped_np_grain.flatten()
        ]

        # make a list containing each of the cropped grains
        try:
            cropped_grains.append(cropped_grain)
        except NameError:
            cropped_grains = [cropped_grain]

    # Generate list of datafields including cropped fields
    crop_ids = gwy.gwy_app_data_browser_get_data_ids(data)

    return bbox, orig_ids, crop_ids, data, cropped_grains, cropwidth