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
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)
def savefilesasgwy(data, filename): # Turn rulers on s["/module/pixmap/xytype"] = 1 # Get directory path and filename (including extension to avoid overwriting .000 type Bruker files) directory, filename = os.path.split(filename) # Create a saving name format/directory savedir = os.path.join(directory) # If the folder Processed doest exist make it here if not os.path.exists(savedir): os.makedirs(savedir) # Save the data for the channels found above i.e. ZSensor/Height, as chosen_ids # Data is exported to a file of extension set in the main script # Data is exported with the string '_processed' added to the end of its filename gwy.gwy_app_data_browser_select_data_field(data, k) # change the colour map for all channels (k) in the image: palette = data.set_string_by_name("/" + str(k) + "/base/palette", "Nanoscope.txt") # Determine the title of each channel # title = data["/%d/data/title" % k] # if not title: # title = 'unknown' # Generate a filename to save to by removing the extension to the file, adding the suffix '_processed' # and an extension set in the main file savename = os.path.join(savedir, filename) + str(k) + '.gwy' # Save the file gwy.gwy_file_save(data, savename, gwy.RUN_NONINTERACTIVE)
def run(): # get all containers containers = gwy.gwy_app_data_browser_get_containers() # save each container as gwy file with file name for c in containers: # get datafield 0 for each container for func to operate on gwy.gwy_app_data_browser_select_data_field(c, 0) gwy.gwy_process_func_run("arc_revolve", c, gwy.RUN_IMMEDIATE)
def save_phase_bwd_image(self, path): """Save backward phase to image file.""" gwy.gwy_app_data_browser_select_data_field(self.container, self.return_phase_bwd_ch()) self.img_phase_bwd = os.path.join( path, str(self.m_id) + "_pb." + config.img_type_out) gwyddion.save_image_file(self.container, self.img_phase_bwd)
def __init__(self, m_file, **kwargs): self.surface = None Data.__init__(self, m_file, **kwargs) self.container = gwy.gwy_file_load(self.m_file, gwy.RUN_NONINTERACTIVE) gwy.gwy_app_data_browser_add(self.container) self.channel_id = gwy.gwy_app_data_browser_find_data_by_title( self.container, "*SE*" )[0] gwy.gwy_app_data_browser_select_data_field(self.container, self.channel_id) self.extract_meta(gwyddion.get_meta_ids(self.container)[0])
def update_image(self,widget,data): #pass for container,gwydata,view in zip(self.containers,self.gwydatas,self.views): self.c = gwydata.get_container() self.load_data(0,0) gwy.gwy_app_data_browser_add(self.c) self.d_origin = self.c[self.data_id_str + 'data'] #self.d = self.d_origin.duplicate() if self.d_origin: self.c.set_object_by_name(self.data_id_str + 'data',self.d_origin) else: self.d_origin = self.c[self.data_id_str + 'data'] gwy.gwy_app_data_browser_select_data_field(self.c,0) #if self.togglebutton_level.get_active(): # gwy.gwy_app_data_browser_select_data_field(self.c, 0) # gwy.gwy_process_func_run("level", self.c, gwy.RUN_IMMEDIATE) self.d = self.c[self.data_id_str + 'data'] d_process = self.d.duplicate() #self.data_min = self.d.get_min() #self.data_max = self.d.get_max() #self. data_dif = self.data_max - self.data_min #self.scale_min_current = self.scale_min.get_value() #self.scale_max_current = self.scale_max.get_value() #bottom = self.data_min + self.scale_min_current/100*self.data_dif #top = self.data_min + self.scale_max_current/100*self.data_dif #d_process.clamp(bottom, top) #self.d.clamp(bottom, top) self.d = d_process self.d.data_changed() #print "update", self.togglebutton_level.get_active() container.set_object_by_name(self.data_id_str+"data", self.d) #if re.search(r'Z', self.channel_str): #print self.channel_str # self.gradient_key = 'Julio' self.gradient_key = 'Julio' #elif re.search(r'Frequency', self.channel_str): # self.gradient_key = 'Gray' container.set_string_by_name(self.data_id_str+"base/palette", self.gradient_key) container.set_int32_by_name(self.data_id_str+"base/range-type", 1)#gwy.LAYER_BASIC_RANGE_FIXED #self.local_c.set_double_by_name(self.data_id_str+"base/min", float(self.data_min + self.scale_min_current/100*self.data_dif)) #self.local_c.set_double_by_name(self.data_id_str+"base/max", float(self.data_min + self.scale_max_current/100*self.data_dif)) container[self.data_id_str+"data"].data_changed() #print self.local_c[self.data_id_str+"base/min"],self.data_id_str+"base/min" #print self.data_min + self.scale_min_current/100*self.data_dif,self.data_min + self.scale_max_current/100*self.data_dif layer = gwy.LayerBasic() layer.set_data_key(self.data_id_str+"data") layer.set_gradient_key(self.data_id_str+"base/palette") layer.set_range_type_key(self.data_id_str+"base") layer.set_min_max_key(self.data_id_str+"base") view.set_data_prefix(self.data_id_str+"data") view.set_base_layer(layer) #self.combobox_files.grab_focus() gwy.gwy_app_data_browser_remove(self.c)
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
def save_dfield_to_png(container, datafield_name, filename, run_type): """ Save desired datafield given by name stored in container to file. @param container: gwy.Container which has datafield of given name @param datafield_name: datafield name in string representation (like '/0/data') @param filename: expected filename @param run_type: select of interactive (RUN_INTERACTIVE) or noninteractive mode (RUN_NONINTERACTIVE) """ gwy.gwy_app_data_browser_reset_visibility(container, gwy.VISIBILITY_RESET_SHOW_ALL) datafield_num = int(datafield_name.split('/')[1]) gwy.gwy_app_data_browser_select_data_field(container, datafield_num) gwy.gwy_file_save(container, filename, run_type)
def save_dfield_to_png(container, datafield_name, filename, run_type): """ Save desired datafield given by name stored in container to file. @param container: gwy.Container which has datafield of given name @param datafield_name: datafield name in string representation (like '/0/data') @param filename: expected filename @param run_type: select of interactive (RUN_INTERACTIVE) or noninteractive mode (RUN_NONINTERACTIVE) """ gwy.gwy_app_data_browser_reset_visibility(container, gwy.VISIBILITY_RESET_SHOW_ALL) datafield_num = int(datafield_name.split('/')[1]) gwy.gwy_app_data_browser_select_data_field(container, datafield_num) gwy.gwy_file_save(container, filename, run_type)
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
def load_data(self ): self.channel_id = self.combobox_channels.get_active() model = self.combobox_channels.get_model() active = self.combobox_channels.get_active() if active >= 0: self.channel_str = model[self.channel_id][0] #print self.channel_str self.direction_id = self.combobox_directions.get_active() #if self.gwydata.param['full_path'][-6:]=='Z_mtrx': # data_id = self.channel_id #else: data_id = self.channel_id * 2 + self.direction_id #print self.channel_id,self.direction_id, data_id self.data_id_str = '/'+str(data_id)+'/' print data_id,self.data_id_str self.d_origin = self.c[self.data_id_str + 'data'] #self.d = self.d_origin.duplicate() if self.d_origin: self.c.set_object_by_name(self.data_id_str + 'data',self.d_origin) else: self.d_origin = self.c[self.data_id_str + 'data'] gwy.gwy_app_data_browser_select_data_field(self.c,data_id) self.get_active_process() print self.process_id if self.process_id == 1: gwy.gwy_app_data_browser_select_data_field(self.c, data_id) gwy.gwy_process_func_run("level", self.c, gwy.RUN_IMMEDIATE) elif self.process_id == 2: gwy.gwy_process_func_run("align_rows", self.c, gwy.RUN_IMMEDIATE) elif self.process_id == 3: gwy.gwy_process_func_run("level", self.c, gwy.RUN_IMMEDIATE) gwy.gwy_process_func_run("align_rows", self.c, gwy.RUN_IMMEDIATE) self.d = self.c[self.data_id_str + 'data'] d_process = self.d.duplicate() self.data_min = self.d.get_min() self.data_max = self.d.get_max() self.data_dif = self.data_max - self.data_min self.scale_min_current = self.scale_min.get_value() self.scale_max_current = self.scale_max.get_value() bottom = self.data_min + self.scale_min_current/100*self.data_dif top = self.data_min + self.scale_max_current/100*self.data_dif #print bottom,top if bottom <= top: d_process.clamp(bottom, top) #self.d.clamp(bottom, top) self.d = d_process else: pass
def convert_np(self, channel_id): """Converts a Gwyddion container to a Numpy array. Args: channel_id (int): ID of channel which will be converted. Returns: np_array (array): Numpy array of container channel. """ # Makes a data field (channel) current/active in the data browser. gwy.gwy_app_data_browser_select_data_field(self.container, channel_id) self.key = gwy.gwy_app_get_data_key_for_id(channel_id) self.name = gwy.gwy_name_from_key(self.key) return gwyutils.data_field_data_as_array(self.container[self.name])
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)
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
def savecroppedfiles(directory, data, filename, extension, orig_ids, crop_ids, minheightscale, maxheightscale): # Save the data for the cropped channels # Data is exported to a file of extension set in the main script # Data is exported with the string '_cropped' added to the end of its filename # Turn rulers off s["/module/pixmap/xytype"] = 0 # Get directory path and filename (including extension to avoid overwriting .000 type Bruker files) directory, filename = os.path.split(filename) # Create a saving name format/directory savedir = os.path.join(directory, 'Cropped') # If the folder Cropped doest exist make it here if not os.path.exists(savedir): os.makedirs(savedir) crop_directory = savedir # Otherwise set the existing Cropped directory as the directory to write to else: crop_directory = savedir # For each cropped file, save out the data with the suffix _Cropped_# for i in range(len(orig_ids), len(crop_ids), 1): # select each channel fo the file in turn gwy.gwy_app_data_browser_select_data_field(data, i) # change the colour map for all channels (k) in the image: palette = data.set_string_by_name("/" + str(i) + "/base/palette", "Nanoscope.txt") # Set the image display to fixed range and the colour scale for the images maximum_disp_value = data.set_int32_by_name( "/" + str(i) + "/base/range-type", int(1)) minimum_disp_value = data.set_double_by_name( "/" + str(i) + "/base/min", float(minheightscale)) maximum_disp_value = data.set_double_by_name( "/" + str(i) + "/base/max", float(maxheightscale)) # Generate a filename to save to by removing the extension to the file and a numerical identifier (the crop no) # The 'crop number' is the channel number minus the original number of channels, less one to avoid starting at 0 savenumber = i - (len(orig_ids) - 1) # adding the suffix '_cropped' and adding the extension set in the main file savename = os.path.join( crop_directory, filename) + '_cropped_' + str(savenumber) + str(extension) # Save the file gwy.gwy_file_save(data, savename, gwy.RUN_NONINTERACTIVE)
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 savefiles(data, filename, extension): # Save file scale option: 1 - ruler, 2 - inset scale bar, 0 - none s["/module/pixmap/xytype"] = savefilesScale_option # Get directory path and filename (including extension to avoid overwriting .000 type Bruker files) directory, filename = os.path.split(filename) # Create a saving name format/directory savedir = os.path.join(directory, 'Processed') # If the folder Processed doest exist make it here if not os.path.exists(savedir): os.makedirs(savedir) # Save the data for the channels found above i.e. ZSensor/Height, as chosen_ids # Data is exported to a file of extension set in the main script # Data is exported with the string '_processed' added to the end of its filename gwy.gwy_app_data_browser_select_data_field(data, k) # change the colour map for all channels (k) in the image: palette = data.set_string_by_name("/%s/base/palette" % k, savefile_zscalecolour) # Determine the title of each channel title = data["/%d/data/title" % k] # Generate a filename to save to by removing the extension to the file, adding the suffix '_processed' # and an extension set in the main file savename = os.path.join( savedir, filename) + str(k) + '_' + str(title) + '_processed' + str(extension) # Save the file gwy.gwy_file_save(data, savename, gwy.RUN_NONINTERACTIVE) # Show the mask data['/%d/mask' % k] = mask # Add the sufix _masked to the previous filename savename = os.path.join(savedir, filename) + str(k) + '_' + str( title) + '_processed_masked' + str(extension) # Save the data gwy.gwy_file_save(data, savename, gwy.RUN_NONINTERACTIVE) gwy.gwy_app_file_close()
def save_all(containers, format="svg", palette="Gray", _id=0): """ Saves all open files to PNG image files in a folder in image directory. containers is a list of open containers... ...can be obtained by gwy.gwy_app_data_browser_get_containers() """ for c in containers: # set palette of datafield c.set_string_by_name("/{}/base/palette".format(_id), "Gray") # file name fname = gwy.gwy_file_get_filename_sys(c) fpath, image_name = os.path.split(fname) # save image_name_string = "{}.{}".format( os.path.splitext(image_name)[0], format) save_string = os.path.join(fpath, image_name_string) gwy.gwy_app_data_browser_select_data_field(c, _id) gwy.gwy_file_save(c, save_string, gwy.RUN_NONINTERACTIVE)
def process_topo(self, data_ch_id): """Processes the data with Gwyddion Python module. Gwyddion topography processing functions: see config file. Before saving the image, the colorrange needs adjustment. The colorrange settings are stored in the container for each spm file. (see online gwyfile-format) Args: data_ch_id (int): Channel of the container should be processed. """ for ch in data_ch_id: gwy.gwy_app_data_browser_select_data_field(self.container, ch) self.run_gwy_func = { gwy.RUN_IMMEDIATE: config.run_gwy_immediate_func } for k, funcs in self.run_gwy_func.iteritems(): for func in funcs: gwy.gwy_process_func_run(func, self.container, k) self.match_ch_topo = "/" + str(ch) + "/base/range-type" self.container[self.match_ch_topo] = 2
ids = gwy.gwy_app_data_browser_get_data_ids(container) for i in ids: channel_folder = "%s/channel/%02d/" % (output_folder,i) os.makedirs(channel_folder) print("Created folder '%s'" % channel_folder) # Channel metadata ch_meta = {} # Get channel title title = container["/%d/data/title" % i] ch_meta["title"] = title ch_meta["index"] = i # Select the channel gwy.gwy_app_data_browser_select_data_field(container, i) # Run some functions #gwy.gwy_process_func_run('align_rows', container, gwy.RUN_NONINTERACTIVE) #gwy.gwy_process_func_run('flatten_base', container, gwy.RUN_NONINTERACTIVE) key = gwy.gwy_app_get_data_key_for_id(i) data_field = container[key] # Extract simple statistics and print them. avg, ra, rms, skew, kurtosis = data_field.get_stats() #print '%s:%s\t%g\t%g\t%g\t%g' % (path, i, ra, rms, skew, kurtosis) data = data_field.get_data() # from array import array
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
# Stupid bloody /0/data/nonsense key = "/"+str(data_set)+"/data" data = datafields[key] # Plane level a, bx, by = data.fit_plane() data.plane_level(a, bx, by) # Median line correction data = line_correct_median(data) # Fix zero data.add(-1.0 * data.get_min()) # Set colour range base = "/"+str(data_set)+"/base" container.set_int32_by_name(base+"/range-type", 1) container.set_double_by_name(base+"/min", colour_min) container.set_double_by_name(base+"/max", colour_max) container.set_string_by_name(base+"/palette", palette) # Do silly things required to save gwy.gwy_app_data_browser_reset_visibility(container, gwy.VISIBILITY_RESET_SHOW_ALL) gwy.gwy_app_data_browser_select_data_field(container, data_set) if saved_once: gwy.gwy_file_save(container, out_file, gwy.RUN_NONINTERACTIVE) else: gwy.gwy_file_save(container, out_file, gwy.RUN_INTERACTIVE) saved_once = True gwy.gwy_app_data_browser_reset_visibility(container, gwy.VISIBILITY_RESET_HIDE_ALL)
#Get the settings for each function from the saved settings file (~/.gwyddion/settings) s = gwy.gwy_app_settings_get() configureGwySettings(s) #Process both trace and retrace for i in height_ids: ### ### CORRECTING THE DATA WITH GWYDDION FUNCTIONS ### HAVE INCREDIBLY UNPLEASANT LOOKING EDITING OF SETTINGS TO DO FOR EACH FUNCTION ### PROBABLY A NEATER WAY TO DO THIS BUT CBA TO LOOK FOR IT NOW ### COPIED THE SETTINGS FROM THE ~/.gwyddion/settings file ### gwy.gwy_app_data_browser_select_data_field(gwy_rawdata, i) #level the data 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)
def gwybas(filename): #add the gwyddion folders to the path, making sure they can be found import sys sys.path.append('C:\Program Files (x86)\Gwyddion\\bin') sys.path.append('C:\Program Files (x86)\Gwyddion\share\gwyddion\pygwy') #import gwyddion import gwy import gwyutils #load the file and add to data browser c = gwy.gwy_file_load(filename, gwy.RUN_IMMEDIATE) gwy.gwy_app_data_browser_add(c) #Set the right settings for the align_rows command settings = gwy.gwy_app_settings_get() settings['/module/linematch/direction'] = int(gwy.ORIENTATION_HORIZONTAL) settings['/module/linematch/do_extract'] = False settings['/module/linematch/do_plot'] = False settings[ '/module/linematch/method'] = 0 # 0: poly, 1: median, 2: median of diff,3: modus,4: matching, 5: trimemd mean, 6: trimmed mean of diff settings['/module/linematch/masking'] = 2 settings['/module/linematch/max_degree'] = 3 #Order of polynominal settings['/module/linematch/trim_fraction'] = 0.05 #print the datafield ID's corresponding to the different channels of the AFM, such as height, phase and error, usually the first one (0) is the height # print gwy.gwy_app_data_browser_get_data_ids(c) #itterate over the different datafield ID's/AFM channels, and do processing on them for datafield_id in gwy.gwy_app_data_browser_get_data_ids(c): # datafield = c['/%d/data' % datafield_id] #set the color range to automatic with tials cut off (corresponding to number 2) c['/%d/base/range-type' % datafield_id] = 2 #select the datafield_ID/AFM channel to process gwy.gwy_app_data_browser_select_data_field(c, datafield_id) #level the plane gwy.gwy_process_func_run("level", c, gwy.RUN_IMMEDIATE) #align the rows, with settings chosen above line 19-25 gwy.gwy_process_func_run("align_rows", c, gwy.RUN_IMMEDIATE) #remove scars a couple of times (button bashing) gwy.gwy_process_func_run("scars_remove", c, gwy.RUN_IMMEDIATE) gwy.gwy_process_func_run("scars_remove", c, gwy.RUN_IMMEDIATE) gwy.gwy_process_func_run("scars_remove", c, gwy.RUN_IMMEDIATE) gwy.gwy_process_func_run("scars_remove", c, gwy.RUN_IMMEDIATE) gwy.gwy_process_func_run("scars_remove", c, gwy.RUN_IMMEDIATE) #fix lowest point to zero gwy.gwy_process_func_run('fix_zero', c, gwy.RUN_IMMEDIATE) #define new file names, I chose to simply add the wanted extention to the original filename newname = filename + '.gwy' newname2 = filename + '.jpg' #find the ID/Channel corresponding to the height, of this one a JPG will be created, .gwy will contain all channels ids = gwy.gwy_app_data_browser_find_data_by_title(c, 'Height') gwy.gwy_app_data_browser_select_data_field(c, ids[0]) gwy.gwy_file_save(c, newname, gwy.RUN_NONINTERACTIVE) gwy.gwy_file_save(c, newname2, gwy.RUN_NONINTERACTIVE) #remove the current container, makes room for the next file gwy.gwy_app_data_browser_remove(c)
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
def runbatch(root, cwd, pdr, pngexp, ratio): # Export PNG with scalebar s = gwy.gwy_app_settings_get() s['/module/pixmap/title_type'] = 0 s['/module/pixmap/ztype'] = 0 s['/module/pixmap/xytype'] = 0 s['/module/pixmap/draw_maskkey'] = False # ... (*lots* of possible settings, see ~/.gwyddion/settings) Files_To_Open = [ f for f in listdir(cwd) if isfile(join(cwd,f)) ] try: mkdir(join(cwd,'Processed')) except Exception as sym: print ('Already Exist') Tobe_Saved = join(cwd, 'Processed') filename_save = cwd.split('/')[-1] print (Files_To_Open) #Load first file to use as Merged file for filename in Files_To_Open: print(filename) try: Temp = gwy.gwy_file_load(join(cwd,filename), RUN_NONINTERACTIVE) print(type(Temp)) if type(Temp) == gwy.Container : print('right type') Cont_Dest = Temp Files_To_Open.remove(filename) break Files_To_Open.remove(filename) print('loadedbutnot') except Exception as sym: print('except') print ("not proper file"+str(sym)+"\n") continue #Add into current browser and Make Visible on display gwy.gwy_app_data_browser_add(Cont_Dest) Cont_Dest.set_boolean_by_name('/0/data/visible', 1) print (Files_To_Open) #File Merge #First Container DataFields = gwyutils.get_data_fields_dir(Cont_Dest) for key in DataFields.keys(): title = Cont_Dest.get_string_by_name(key+"/title") if (title == 'Amplitude') : Cont_Dest.remove_by_prefix('/'+key.split('/')[1]+'/') Cont_Dest.set_string_by_name(key+'/title', title+'.'+Files_To_Open[0]) #Rest of Containers for filename in Files_To_Open : #print (orgfile, join(cwd,filename)) try: Temp_Source = gwy.gwy_file_load(join(cwd,filename), RUN_NONINTERACTIVE) if type(Temp_Source) == gwy.Container: Cont_Source = Temp_Source pass else: continue except Exception as sym: print ("not proper file"+sym+"\n") continue DataFields = gwyutils.get_data_fields_dir(Cont_Source) for key in DataFields.keys(): ID = key.split('/')[1] title = Cont_Source.get_string_by_name(key+"/title") if (title == 'Height') : Cont_Source.set_string_by_name(key+'/title', title+'.'+filename) gwy.gwy_app_data_browser_copy_channel(Cont_Source, int(ID), Cont_Dest) print (key, title) gwy_app_data_browser_remove(Cont_Source) del Cont_Source print (gc.collect()) #Change Palette, Flatten, Correct line, Remove Scars, Change Scale DataFields = gwyutils.get_data_fields_dir(Cont_Dest) for key in DataFields.keys(): ID = key.split('/')[1] title = Cont_Dest.get_string_by_name(key+"/title") print (title+'\n') # Subtract polynomial background coeffs = DataFields[key].fit_polynom(3, 3) DataFields[key].subtract_polynom(3, 3, coeffs) DataFields[key].data_changed() #Get X Y scale si = {'x' : 'um' , 'y' : 'um'} size_x = DataFields[key].get_xreal()*1000000 if (size_x < 1.0): size_x = size_x * 1000 si['x'] = 'nm' size_y = DataFields[key].get_yreal()*1000000 if (size_y < 1.0): size_y = size_y * 1000 si['y'] = 'nm' scale = str(size_x)+si['x']+'by'+str(size_y)+si['y'] title = title + '_'+ scale # Line and scar correction (run module functions) gwy.gwy_app_data_browser_select_data_field(Cont_Dest, int(ID)) gwy.gwy_process_func_run("line_correct_median", Cont_Dest, gwy.RUN_IMMEDIATE) gwy.gwy_process_func_run("scars_remove", Cont_Dest, gwy.RUN_IMMEDIATE) gwy.gwy_process_func_run("fix_zero", Cont_Dest, gwy.RUN_IMMEDIATE) #Get Color Type colorr = Cont_Dest.get_int32_by_name('/'+ID+'/base/range-type') #Change_Color Palette Cont_Dest.set_string_by_name('/'+ID+'/base/palette', 'Gold') #Get Height Distribution and get Percentile color set range #Get CDH histogram = gwy.DataLine(1, 1, False) DataFields[key].cdh(histogram, 512) data = histogram.get_data() #Get Percentile Range Data_Range = DataFields[key].get_min_max() Histogram_pct = [(float(index))/512 for index, value in enumerate(data) if (data[index] >= ratio[1] and data[index-1] <= ratio[1]) or (data[index] <= ratio[0] and data[index+1] >= ratio[0])] Range = Data_Range[1]-Data_Range[0] Color_Range = {'min': Data_Range[0]+Range*Histogram_pct[0], 'max':Data_Range[0]+Range*Histogram_pct[1]} Cont_Dest.set_int32_by_name('/0/base/range-type' , 1) Cont_Dest.set_double_by_name('/0/base/min', Color_Range['min']) Cont_Dest.set_double_by_name('/0/base/max', Color_Range['max']) #Change Color Range into (Full:0, Manual:1, Auto:2, Adaptive:3) Cont_Dest.set_int32_by_name('/'+ID+'/base/range-type', 2) print (title) gwy.gwy_file_save(Cont_Dest, Tobe_Saved+'/'+str(title)+'%d.png' % int(ID), gwy.RUN_NONINTERACTIVE) Cont_Dest.set_boolean_by_name('/'+ID+'/data/visible', 0) gwy.gwy_file_save(Cont_Dest,Tobe_Saved+'/'+filename_save+'.gwy', gwy.RUN_NONINTERACTIVE) gwy_app_data_browser_remove(Cont_Dest)