def shape_check(self): """Check to see if the imported hybrids have the same shape Parameters ========== self (SXDMFrameset) the sxdmframeset used Returns ======= Nothing. Prints Important Data """ try: # Return the hybrid x and y data hybrid_x = return_det(self.file, self.scan_numbers, group='hybrid_x')[0] hybrid_y = return_det(self.file, self.scan_numbers, group='hybrid_y')[0] # Determine the shape of the arrays shape_hybrid_x = np.shape(hybrid_x) shape_hybrid_y = np.shape(hybrid_y) len_x = len(shape_hybrid_x) len_y = len(shape_hybrid_y) # Make sure shapes are the same if len_x != 3 and len_y != 3: warnings.warn('Scan Shapes Are Not The Same!') self.shape_checker = False else: self.shape_checker = True print('Hybrid Scan Shapes Are Equivalent') # If you can't import throw error to User except Exception as ex: print('shape_check', ex, '\n') for i, array in enumerate(hybrid_x): print('Shapes Of All Imported Scans') print(self.scan_numbers[i], np.shape(array)) warnings.warn( 'Cannot Check Shape. Some .mda Files Might Be Missing...')
def grab_fov_dimensions(self): """Returns the image dimensions for the User Parameters ========== self (SXDMFrameset) the sxdmframeset Returns ======= the np.shape() of the fluorescence images - which are identical for the the entire field of view """ image = return_det(self.file, self.scan_numbers, group='fluor', default=True) return np.shape(image[0])
def centering_det(self, group='fluor', center_around=False, summed=False, default=False): """Return a detector that has been centered around a set value Parameters ========== self (SXDMFrameset) the sxdmframeset group (str) the group name the user would like to center to - acc_vals = fluor and roi center_around (bool) if this equals -1 then there will be no centering adjustments summed (bool) if True it will sum together all scans after centering default (bool) if True it will set the fluor image to center on or roi image to view to the first index Returns ======= an array of the fluor images or the roi images for all the SXDMFrameset scans centered around the users value """ if center_around == False: center_around = set_centering(self) else: pass # Grab the User defined detector images array = return_det(file=self.file, scan_numbers=self.scan_numbers, group=group, default=default)[0] # Center them around a User defined index if center_around != -1: ims = array_shift(self, array, center_around) else: ims = array if summed == False: return ims elif summed == True: return np.sum(ims, axis=0)
def image_numbers(self): """Grab the image numbers Parameters ========== self (SXDMFrameset) the sxdmframset Returns ======= all of the diffraction image numbers for each scan in a 3D matrix """ filenumbers = return_det(self.file, self.scan_numbers, group='filenumber')[0] int_filenumbers = {} for i, scan in enumerate(filenumbers): int_filenumbers[self.scan_numbers[i]] = np.asarray(scan).astype(int) return int_filenumbers
def max_det_val(self, detector='fluor'): """Used to determine the max values for a given detector channel Parameters ========== self (SXDMFrameset) the sxdmframeset detector (str) value to be passed into the return_det() function Returns ======= the max values for all scans for a given detector channel input """ if h5path_exists(self.file, 'detector_channels/' + detector) == True: data = return_det(self.file, self.scan_numbers, group=detector) max_array = [np.max(array) for array in data[0]] return max_array else: warnings.warng('Path Does Not Exist')
def alignment_function(self): """Allows the user to align the scans based on Fluorescence or Region Of Interest. Sets alignment variables and stores them in designated .h5 file. Easier to reload alignment data or redo alignment data Parameters ========== self: (SXDMFrameset) the sxdmframeset object Returns ======= Nothing """ # Check to see if /dxdy group exsists if not make it and set attributes if h5path_exists(file=self.file, loc=self.dataset_name + '/dxdy') == True: warnings.warn('Previous Data Found') redo_alignment = input('Previous Data Found. Redo Alignment? y/n ') # Determining if User wants to reload or redo alignment if redo_alignment == 'y': start_alignment = 'y' try: self.alignment_group = h5read_attr( file=self.file, loc=self.dataset_name + '/dxdy', attribute_name='alignment_group') self.alignment_subgroup = h5read_attr( file=self.file, loc=self.dataset_name + '/dxdy', attribute_name='alignment_subgroup') except Exception as ex: print('alignment.py/alignment_function 1', ex) # If no redo and no start, save those choices else: start_alignment = 'n' redo_alignment = 'n' else: start_alignment = 'y' redo_alignment = 'n' # Initialize the alignment process if we are starting the alignment if start_alignment == 'y': if start_alignment == 'y' and redo_alignment == 'n': init_dxdy(self) else: try: # Try to pull previous alignment data - if you can't throw error to the user print('Previous Alignment Done On - {} - {}'.format( self.alignment_group, self.alignment_subgroup)) except Exception as ex: print('alignment.py/alignment_function 2', ex) # Grabbing old alignment and setting alignment circles retrieve_old_data = array2dic(array=h5grab_data( file=self.file, data_loc=self.dataset_name + '/dxdy')) warnings.warn('Refreshing Old Alignment Data') if len(retrieve_old_data.keys()) > len(self.scan_numbers): warnings.warn( 'Saved Alignment Has More Scans Than Current Import - Please Set reset=True' ) # Create variables to store data self.clicks = {} self.correction_store = {} plt.close('all') cont = True # Ask which images the user wants to align to while cont == True: user_val = input('Would You Like To Align On fluor Or roi? ') if user_val in ['fluor', 'roi']: cont = False else: warnings.warn('Please Type In An Acceptable Values: ') # Grab data and set alignment data det_return = return_det(file=self.file, scan_numbers=self.scan_numbers, group=user_val) # Setting up figure data images = det_return[0] self.alignment_subgroup = det_return[1] self.alignment_group = user_val self.max_images = np.shape(images)[0] starting = figure_size_finder(images=images) plt.close('all') # Setting up initial figure for alignment fig, axs = plt.subplots(starting, starting, figsize=(10, 10), facecolor='w', edgecolor='k') # Try to ravel axis - if data is 1D continue to the except code try: self.loc_axs = axs.ravel() except: warnings.warn( 'Ravel Function Not Called. Possible 1D Image Trying To Load') self.loc_axs = [axs] axs_store = [] # Set up saving, and click functions into partials saving = partial(save_alignment, self=self) initiate = partial(onclick_1, self=self) click1 = partial(fig1_click, self=self, fig=fig, images=images) # Display circles for alignment for i, image in enumerate(images): self.loc_axs[i].imshow(image) axs_store.append(self.loc_axs[i].get_position()) if redo_alignment == 'y': for num, old_ax in enumerate(retrieve_old_data): old_clicks = retrieve_old_data[old_ax] circ = Circle((old_clicks[0], old_clicks[1]), 0.3, color='r') self.loc_axs[old_ax].add_patch(circ) plt.suptitle('Please Click On Any Of The Images Below') plt.show() # Based on the Users clicks display different information fig.canvas.mpl_connect('button_press_event', initiate) fig.canvas.mpl_connect('button_press_event', click1) fig.canvas.mpl_connect('button_press_event', saving) elif redo_alignment == 'n': print('Staying With Current Alignment Parameters')
def return_chi_images_loc( file, chi_figures, detector_channel_loc='detector_channels/detector_scan/Main_Scan', zfill_num=4, ): """Grabs the image location for the detector sweep scan Parameters ========== file: (str) the .h5 file associated with the dataset chi_figures: (Chi_FigureClass) the Chi_FigureClass allowing transfer of data from figure to figure detector_channel_loc: (str) the h5 group location to the detector sweep scan used for chi bounds determination zfill_num: (int) the integer value for how many digits the scan number must have Returns ======= Nothing - sets the chi_figures.scan_theta and chi_figures.images_location valuess """ # Attempt to pull chi determination scan information try: # Grab the detector channel data scan = h5grab_data(file=file, data_loc=detector_channel_loc) scan_str = str(scan).zfill(zfill_num) # Grab the scans in the images and mda group im_loc = h5grab_data(file=file, data_loc='images/{}'.format(scan_str)) mda_loc = h5grab_data(file=file, data_loc='mda/{}'.format(scan_str)) # See if the images or mda group exsists im_check = h5path_exists(file=file, loc='images/{}'.format(scan_str)) mda_check = h5path_exists(file=file, loc='mda/{}'.format(scan_str)) # Formatting the image locations images_loc = ['images/{}/{}'.format(scan_str, loc) for loc in im_loc] chi_figures.images_location = images_loc # Based on what the user rocked to get the chi scan this will pull different values if chi_figures.user_rocking == 'spl': theta = return_det(file=file, scan_numbers=[scan_str], group='sample_theta') chi_figures.scan_theta = theta[0] elif chi_figures.user_rocking == 'det': det_find = 'D' + str( h5grab_data(file=file, data_loc='detector_channels/mis/2Theta')).zfill(2) theta = h5grab_data(file=file, data_loc='/mda/{}/{}'.format( scan_str, det_find)) sh = np.shape(theta) theta = np.reshape(theta, (1, sh[0] * sh[1]))[0] chi_figures.scan_theta = theta # Throw error if the program cannot pull info except Exception as ex: print('chi_determination.py/return_chi_images_loc', ex) warnings.warn( 'You Have Failed To Load In The Correct Detector Channel. ' 'Correct The detector_channel_loc or Import Correct Data') chi_figures.images_location = None # Throw error if the images or mda group does not exist if im_check == False or mda_check == False: warnings.warn( 'You Have Failed To Load In The Correct Detector Channel. ' 'Correct The detector_channel_loc or Import Correct Data ' 'im_check: {} - mda_check: {}'.format(im_check, mda_check)) chi_figures.images_location = None
def resolution_check(self, user_resolution_um=0.0005): """Check if all X dimensions for all scans are equal to each other. Also checks in all y dimensions for all scans are equal to each other. Then checks if the x and y are equal to one another. Parameters ========== self (SXDMFramset) the sxdmframset user_resolution_um (float) the resolution in um the user would like the scan dimensions for Returns ======= Nothing - sets resolution values """ try: # Grab the hybrid x and y data hybrid_x = return_det(self.file, self.scan_numbers, group='hybrid_x', dim_correction=False)[0] hybrid_y = return_det(self.file, self.scan_numbers, group='hybrid_y', dim_correction=False)[0] self.resolution_hybrid_x = hybrid_x self.resolution_hybrid_y = hybrid_y # Get all shapes of arrays shape_hybrid_x = np.asarray([np.shape(scan) for scan in hybrid_x]) - [1, 1] shape_hybrid_y = np.asarray([np.shape(scan) for scan in hybrid_y]) - [1, 1] # Determine the max value max_x = np.asarray([np.max(scan, axis=(0, 1)) for scan in hybrid_x]) min_x = np.asarray([np.min(scan, axis=(0, 1)) for scan in hybrid_x]) # Determine the min value max_y = np.asarray([np.max(scan, axis=(0, 1)) for scan in hybrid_y]) min_y = np.asarray([np.min(scan, axis=(0, 1)) for scan in hybrid_y]) #Determine difference between min and max value dif_x = max_x - min_x dif_y = max_y - min_y res_x = [] res_y = [] # For each difference between min and max values divide them by the array dimensions for i, value in enumerate(dif_x): len_hybrid_x = shape_hybrid_x[i][1] len_hybrid_y = shape_hybrid_y[i][0] current_x = dif_x[i] current_y = dif_y[i] res_x.append(current_x / len_hybrid_x) res_y.append(current_y / len_hybrid_y) # Finding the resolutions for each scan dif_res_x = [res_x[0] - step for step in res_x] dif_res_y = [res_y[0] - step for step in res_y] # Make sure the resolutions are all all identical and within the User selected resolution validation_x = val_check(dif_res_x, user_resolution_um) validation_y = val_check(dif_res_y, user_resolution_um) print('Pixel X Dimension: {}nm\nPixel Y Dimension: {}nm'.format( np.median(res_x) * 1000, np.median(res_y) * 1000)) # Store values for testing code self.res_x = np.median(res_x) * 1000 self.res_y = np.median(res_y) * 1000 self.all_res_x = res_x self.all_res_y = res_y self.validation_x = validation_x self.validation_y = validation_y if validation_x == True and validation_y == True: print('All X and All Y Resolutions are within ' + str(user_resolution_um * 1000) + ' nanometers from each other respectivley') else: if validation_x != True and validation_y != True: warnings.warn('Resolution in X and Y Differ Between Scans') elif validation_x == True and validation_y != True: warnings.warn('Resolution in Y Differ Between Scans') elif validation_x != True and validation_y == True: warnings.warn('Resolution in X Differ Between Scans') res_difference = abs(self.res_x - self.res_y) <= (user_resolution_um * 1000) if res_difference == True: print('X And Y Resolutions Are Within {} nm Of Each Other'.format( user_resolution_um * 1000)) elif res_difference == False: warnings.warn( 'X And Y Resolutions Are NOT Within {} nm Of Each Other\n' 'Plots will need to be corrected'.format(user_resolution_um * 1000)) except Exception as ex: print('mis.py/resolution_check', ex) warnings.warn( 'Cannot Check Resolution. Some .mda Files Might Be Missing...')