diff --git a/.gitignore b/.gitignore index b6e4761..0498486 100644 --- a/.gitignore +++ b/.gitignore @@ -127,3 +127,7 @@ dmypy.json # Pyre type checker .pyre/ + +# Mac +.DS_Store +.idea/ diff --git a/notebooks/__code/__init__.py b/notebooks/__code/__init__.py new file mode 100644 index 0000000..5ac2af1 --- /dev/null +++ b/notebooks/__code/__init__.py @@ -0,0 +1,6 @@ +from qtpy.uic import loadUi + +__all__ = ['load_ui'] + +def load_ui(ui_filename, baseinstance): + return loadUi(ui_filename, baseinstance=baseinstance) diff --git a/notebooks/__code/array.py b/notebooks/__code/array.py new file mode 100644 index 0000000..941ba60 --- /dev/null +++ b/notebooks/__code/array.py @@ -0,0 +1,23 @@ +import numpy as np + + +def exclude_y_value_when_error_is_nan(axis, error_axis): + axis_cleaned = [] + error_axis_cleaned = [] + + for _x, _error in zip(axis, error_axis): + if (_x == "None") or (_error == "None") or (_x is None) or (_error is None): + axis_cleaned.append(np.NaN) + error_axis_cleaned.append(np.NaN) + else: + axis_cleaned.append(np.float(_x)) + error_axis_cleaned.append(np.float(_error)) + + return axis_cleaned, error_axis_cleaned + + +def check_size(x_axis=None, y_axis=None): + size_x = len(x_axis) + size_y = len(y_axis) + min_len = np.min([size_x, size_y]) + return x_axis[:min_len], y_axis[:min_len] diff --git a/notebooks/__code/bragg_edge.py b/notebooks/__code/bragg_edge.py new file mode 100644 index 0000000..dd7085c --- /dev/null +++ b/notebooks/__code/bragg_edge.py @@ -0,0 +1,763 @@ +from __code.ipywe import fileselector +import random +import os +import glob +from IPython.core.display import HTML +from IPython.display import display +import numpy as np +from collections import OrderedDict +from plotly.offline import iplot +import plotly.graph_objs as go +from ipywidgets import widgets +import pyqtgraph as pg +try: + from PyQt4.QtGui import QFileDialog + from PyQt4 import QtCore, QtGui + from PyQt4.QtGui import QMainWindow +except ImportError: + from PyQt5.QtWidgets import QFileDialog + from PyQt5 import QtCore, QtGui + from PyQt5.QtWidgets import QApplication, QMainWindow + +from neutronbraggedge.experiment_handler import * +from neutronbraggedge.braggedge import BraggEdge as BraggEdgeLibrary +from neutronbraggedge.material_handler.retrieve_material_metadata import RetrieveMaterialMetadata +from NeuNorm.normalization import Normalization + +from __code import file_handler +from __code.ui_roi_selection import Ui_MainWindow as UiMainWindow + + +class BraggEdge: + + list_of_elements = ['Fe'] + data = [] + spectra_file = None + + label_width = '15%' + + def __init__(self, working_dir='./'): + self.working_dir = working_dir + self.ipts_folder = working_dir + + def full_list_elements(self): + retrieve_material = RetrieveMaterialMetadata(material='all') + self.list_returned = retrieve_material.full_list_material() + + # import pprint + # pprint.pprint(list_returned) + + box4 = widgets.HBox([widgets.Label("List of elements", + layout=widgets.Layout(width=self.label_width)), + widgets.Select(options=self.list_returned, + layout=widgets.Layout(width='20%'))]) + + box5 = widgets.HBox([widgets.Label("Nbr Bragg Edges", + layout=widgets.Layout(width=self.label_width)), + widgets.IntText(8, + layout=widgets.Layout(width='20%'))]) + + vertical_box = widgets.VBox([box4, box5]) + display(vertical_box) + + self.list_elements_ui = box4.children[1] + self.nbr_bragg_edges_ui = box5.children[1] + + def list_elements(self): + retrieve_material = RetrieveMaterialMetadata(material='all') + self.list_returned = retrieve_material.full_list_material() + + # import pprint + # pprint.pprint(list_returned) + + box4 = widgets.HBox([widgets.Label("List of elements", + layout=widgets.Layout(width=self.label_width)), + widgets.Text(','.join(self.list_of_elements), + layout=widgets.Layout(width='20%'))]) + + box5 = widgets.HBox([widgets.Label("Nbr Bragg Edges", + layout=widgets.Layout(width=self.label_width)), + widgets.Text(str(8), + layout=widgets.Layout(width='20%'))]) + + vertical_box = widgets.VBox([box4, box5]) + display(vertical_box) + + self.list_elements_ui = box4.children[1] + self.nbr_bragg_edges_ui = box5.children[1] + + def exp_setup(self): + + box2 = widgets.HBox([widgets.Label("dSD (m)", + layout=widgets.Layout(width=self.label_width)), + widgets.Text(str(16.08), + layout=widgets.Layout(width='20%'))]) + + box3 = widgets.HBox([widgets.Label("detector offset (microns)", + layout=widgets.Layout(width=self.label_width)), + widgets.Text(str(3700), + layout=widgets.Layout(width='20%'))]) + + vertical_box = widgets.VBox([box2, box3]) + display(vertical_box) + + self.dSD_ui = box2.children[1] + self.detector_offset_ui = box3.children[1] + + def list_powder_bragg_edges(self): + + list_of_elements_selected = self.list_elements_ui.value + list_of_elements = list_of_elements_selected.split(',') + list_of_elements = [_element.strip() for _element in list_of_elements] + number_of_bragg_edges = np.int(self.nbr_bragg_edges_ui.value) + + _handler = BraggEdgeLibrary(material=list_of_elements, + number_of_bragg_edges=number_of_bragg_edges) + self.bragg_edges = _handler.bragg_edges + self.hkl = _handler.hkl + self.handler = _handler + + def select_working_folder(self): + select_data = fileselector.FileSelectorPanel(instruction='Select Data Folder ...', + start_dir=self.working_dir, + next=self.load_data, + type='directory', + multiple=False) + select_data.show() + + def load_data(self, folder_selected): + list_files = glob.glob(os.path.join(folder_selected, '*.fits')) + + if list_files == []: + list_files = glob.glob(os.path.join(folder_selected, '*.tif*')) + + else: #fits + # keep only files of interest + list_files = [file for file in list_files if not "_SummedImg.fits" in file] + list_files = [file for file in list_files if ".fits" in file] + + # sort list of files + list_files.sort() + + o_norm = Normalization() + o_norm.load(file=list_files, notebook=True) + + self.data = o_norm.data['sample']['data'] + self.list_files = o_norm.data['sample']['file_name'] + + display(HTML('' + str(len(list_files)) + \ + ' files have been loaded')) + + # define time spectra file + folder = os.path.dirname(self.list_files[0]) + spectra_file = glob.glob(os.path.join(folder, '*_Spectra.txt')) + if spectra_file: + self.spectra_file = spectra_file[0] + display(HTML(' Spectra File automatically located: ' + \ + self.spectra_file + '')) + + else: + #ask for spectra file + self.select_time_spectra_file() + + def load_time_spectra(self): + _tof_handler = TOF(filename=self.spectra_file) + _exp = Experiment(tof=_tof_handler.tof_array, + distance_source_detector_m=np.float(self.dSD_ui.value), + detector_offset_micros=np.float(self.detector_offset_ui.value)) + self.lambda_array = _exp.lambda_array * 1e10 # to be in Angstroms + self.tof_array = _tof_handler.tof_array + + def save_time_spectra(self, file): + self.spectra_file = file + display(HTML(' Spectra File : ' + \ + self.spectra_file + '')) + + def select_time_spectra_file(self): + self.working_dir = os.path.dirname(self.list_files[0]) + + self.time_spectra_ui = fileselector.FileSelectorPanel(instruction='Select Time Spectra File ...', + start_dir=self.working_dir, + next=self.save_time_spectra, + filters={'spectra_file': "_Spectra.txt"}, + multiple=False) + self.time_spectra_ui.show() + + def select_just_time_spectra_file(self): + self.time_spectra_ui = fileselector.FileSelectorPanel(instruction='Select Time Spectra File ...', + start_dir=self.working_dir, + filters={'spectra_file': "*_Spectra.txt"}, + multiple=False) + self.time_spectra_ui.show() + + def how_many_data_to_use_to_select_sample_roi(self): + nbr_images = len(self.data) + init_value = np.int(nbr_images/10) + if init_value == 0: + init_value = 1 + box1 = widgets.HBox([widgets.Label("Nbr of images to use:", + layout=widgets.Layout(width='15')), + widgets.IntSlider(value=init_value, + max=nbr_images, + min=1, + layout=widgets.Layout(width='50%'))]) + box2 = widgets.Label("(The more you select, the longer it will take to display the preview!)") + vbox = widgets.VBox([box1, box2]) + display(vbox) + self.number_of_data_to_use_ui = box1.children[1] + + def define_sample_roi(self): + nbr_data_to_use = np.int(self.number_of_data_to_use_ui.value) + nbr_images = len(self.data) + list_of_indexes_to_keep = random.sample(list(range(nbr_images)), nbr_data_to_use) + + final_array = [] + for _index in list_of_indexes_to_keep: + final_array.append(self.data[_index]) + final_image = np.mean(final_array, axis=0) + self.final_image = final_image + + def calculate_counts_vs_file_index_of_regions_selected(self, list_roi=[]): + + counts_vs_file_index = [] + for _data in self.data: + + _array_data = [] + + for _roi in list_roi.keys(): + + x0 = np.int(list_roi[_roi]['x0']) + y0 = np.int(list_roi[_roi]['y0']) + x1 = np.int(list_roi[_roi]['x1']) + y1 = np.int(list_roi[_roi]['y1']) + + _array_data.append(np.mean(_data[y0:y1, x0:x1])) + + counts_vs_file_index.append(np.mean(_array_data)) + + self.counts_vs_file_index = counts_vs_file_index + + def plot(self): + + bragg_edges = self.bragg_edges + hkl = self.hkl + lambda_array = self.lambda_array + sum_cropped_data = self.final_image + + # format hkl labels + _hkl_formated = {} + for _material in hkl: + _hkl_string = [] + for _hkl in hkl[_material]: + _hkl_s = ",".join(str(x) for x in _hkl) + _hkl_s = _material + "\n" + _hkl_s + _hkl_string.append(_hkl_s) + _hkl_formated[_material] = _hkl_string + + trace = go.Scatter( + x=self.lambda_array, + y=self.counts_vs_file_index, + mode='markers') + + layout = go.Layout( + width="100%", + height=500, + title="Sum Counts vs TOF", + xaxis=dict( + title="Lambda (Angstroms)" + ), + yaxis=dict( + title="Sum Counts" + ), + ) + + max_x = 6 + y_off = 1 + + for y_index, _material in enumerate(bragg_edges): + for _index, _value in enumerate(bragg_edges[_material]): + if _value > max_x: + continue + bragg_line = {"type": "line", + 'x0': _value, + 'x1': _value, + 'yref': "paper", + 'y0': 0, + 'y1': 1, + 'line': { + 'color': 'rgb(255, 0, 0)', + 'width': 1 + }} + layout.shapes.append(bragg_line) + y_off = 1 - 0.25 * y_index + + # add labels to plots + _annot = dict( + x=_value, + y=y_off, + text=_hkl_formated[_material][_index], + yref="paper", + font=dict( + family="Arial", + size=16, + color="rgb(150,50,50)" + ), + showarrow=True, + arrowhead=3, + ax=0, + ay=-25) + + layout.annotations.append(_annot) + + data = [trace] + + figure = go.Figure(data=data, layout=layout) + iplot(figure) + + def select_output_folder(self): + self.select_folder(message='output', + next_function=self.export_table) + + def export_table(self, output_folder): + material = self.handler.material[0] + lattice = self.handler.lattice[material] + crystal_structure = self.handler.crystal_structure[material] + metadata = ["# material: {}".format(material), + "# crystal structure: {}".format(crystal_structure), + "# lattice: {} Angstroms".format(lattice), + "#", + "# hkl, d(angstroms), BraggEdge"] + data = [] + bragg_edges = self.bragg_edges[material] + hkl = self.hkl[material] + for _index in np.arange(len(bragg_edges)): + _hkl_str = [str(i) for i in hkl[_index]] + _hkl = "".join(_hkl_str) + _bragg_edges = np.float(bragg_edges[_index]) + _d = _bragg_edges/2. + _row = "{}, {}, {}".format(_hkl, _d, _bragg_edges) + data.append(_row) + + output_file_name = os.path.join(output_folder, 'bragg_edges_of_{}.txt'.format(material)) + + file_handler.make_ascii_file(metadata=metadata, + data=data, + dim='1d', + output_file_name=output_file_name) + + display(HTML('File created : ' + \ + output_file_name + '')) + + def select_folder(self, message="", next_function=None): + folder_widget = fileselector.FileSelectorPanel(instruction='select {} folder'.format(message), + start_dir=self.working_dir, + next=next_function, + type='directory', + multiple=False) + folder_widget.show() + + +class Interface(QMainWindow): + + roi_width = 0.01 + roi_selected = {} #nice formatting of list_roi for outside access + + live_data = [] + o_norm = None + roi_column_width = 70 + integrated_image = None + integrated_image_size = {'width': -1, 'height': -1} + + list_roi = {} # 'row": {'x0':None, 'y0': None, 'x1': None, 'y1': None} + default_roi = {'x0': 0, 'y0': 0, 'x1': 50, 'y1': 50, 'id': None} + + def __init__(self, parent=None, data=None): + + display(HTML('Check UI that poped up \ + (maybe hidden behind this browser!)')) + + self.live_data = data + + QMainWindow.__init__(self, parent=parent) + self.ui = UiMainWindow() + self.ui.setupUi(self) + self.init_statusbar() + self.setWindowTitle("Background ROI Selection Tool") + + self.ui.image_view = pg.ImageView() + self.ui.image_view.ui.roiBtn.hide() + self.ui.image_view.ui.menuBtn.hide() + + top_layout = QtGui.QVBoxLayout() + top_layout.addWidget(self.ui.image_view) + self.ui.widget.setLayout(top_layout) + self.init_widgets() + self.integrate_images() + self.display_image() + + def init_widgets(self): + nbr_columns = self.ui.table_roi.columnCount() + for _col in range(nbr_columns): + self.ui.table_roi.setColumnWidth(_col, self.roi_column_width) + + def init_statusbar(self): + self.eventProgress = QtGui.QProgressBar(self.ui.statusbar) + self.eventProgress.setMinimumSize(20, 14) + self.eventProgress.setMaximumSize(540, 100) + self.eventProgress.setVisible(False) + self.ui.statusbar.addPermanentWidget(self.eventProgress) + + # def __get_recap(self, data_array): + # if data_array: + # [height, width] = np.shape(data_array[0]) + # nbr_sample = len(data_array) + # else: + # nbr_sample = '0' + # [height, width] = ['N/A', 'N/A'] + # + # return [nbr_sample, height, width] + + # def __built_html_table_row_3_columns(self, name, nbr, height, width): + # _html = '' + str(name) + '' + str(nbr) + '' + str(height) + \ + # '*' + str(width) + '' + # return _html + # + # def recap(self): + # """Display nbr of files loaded and size. This can be used to figure why a normalization failed""" + # [nbr_sample, height_sample, width_sample] = self.__get_recap(self.o_norm.data['sample']['data']) + # [nbr_ob, height_ob, width_ob] = self.__get_recap(self.o_norm.data['ob']['data']) + # [nbr_df, height_df, width_df] = self.__get_recap(self.o_norm.data['df']['data']) + # + # html = '' + # html += self.__built_html_table_row_3_columns('sample', nbr_sample, height_sample, width_sample) + # html += self.__built_html_table_row_3_columns('ob', nbr_ob, height_ob, width_ob) + # html += self.__built_html_table_row_3_columns('df', nbr_df, height_df, width_df) + # html += '
TypeNumber' + \ + # 'Size (height*width)
' + # display(HTML(html)) + + def integrate_images(self): + self.integrated_image = self.live_data + [_height, _width] = np.shape(self.integrated_image) + self.integrated_image_size['height'] = _height + self.integrated_image_size['width'] = _width + + def _clean_image(self, image): + _result_inf = np.where(np.isinf(image)) + image[_result_inf] = np.NaN + return image + + def display_image(self): + _image = np.transpose(self.live_data) + _image = self._clean_image(_image) + self.ui.image_view.setImage(_image) + + def remove_row_entry(self, row): + _roi_id = self.list_roi[row]['id'] + self.ui.image_view.removeItem(_roi_id) + del self.list_roi[row] + + #rename row + new_list_roi = {} + new_row_index = 0 + for _previous_row_index in self.list_roi.keys(): + new_list_roi[new_row_index] = self.list_roi[_previous_row_index] + new_row_index += 1 + self.list_roi = new_list_roi + + def remove_roi_button_clicked(self): + + self.ui.table_roi.blockSignals(True) + + _selection = self.ui.table_roi.selectedRanges() + row = _selection[0].topRow() + old_nbr_row = self.ui.table_roi.rowCount() + + # remove entry from list of roi + self.remove_row_entry(row) + + # update table of rois + self.update_table_roi_ui() + self.ui.table_roi.blockSignals(False) + self.check_add_remove_button_widgets_status() + + # update selection + new_nbr_row = self.ui.table_roi.rowCount() + if new_nbr_row == 0: + return + + if row == (old_nbr_row-1): + row = new_nbr_row - 1 + + _new_selection = QtGui.QTableWidgetSelectionRange(row, 0, row, 3) + self.ui.table_roi.setRangeSelected(_new_selection, True) + + def clear_table(self): + nbr_row = self.ui.table_roi.rowCount() + for _row in np.arange(nbr_row): + self.ui.table_roi.removeRow(0) + + def update_table_roi_ui(self): + """Using list_roi as reference, repopulate the table_roi_ui""" + + self.ui.table_roi.blockSignals(True) + list_roi = self.list_roi + + self.clear_table() + + _index_row = 0 + for _roi_key in list_roi.keys(): + _roi = list_roi[_roi_key] + + self.ui.table_roi.insertRow(_index_row) + + self._set_item_value(_index_row, 0, _roi['x0']) + # _item = QtGui.QTableWidgetItem(str(_roi['x0'])) + # self.ui.table_roi.setItem(_index_row, 0, _item) + + self._set_item_value(_index_row, 1, _roi['y0']) + # _item = QtGui.QTableWidgetItem(str(_roi['y0'])) + # self.ui.table_roi.setItem(_index_row, 1, _item) + + self._set_item_value(_index_row, 2, _roi['x1']) + # _item = QtGui.QTableWidgetItem(str(_roi['x1'])) + # self.ui.table_roi.setItem(_index_row, 2, _item) + + self._set_item_value(_index_row, 3, _roi['y1']) + # _item = QtGui.QTableWidgetItem(str(_roi['y1'])) + # self.ui.table_roi.setItem(_index_row, 3, _item) + + _index_row += 1 + + self.ui.table_roi.blockSignals(False) + #self.ui.table_roi.itemChanged['QTableWidgetItem*'].connect(self.update_table_roi) + + def _set_item_value(self, row=0, column=0, value=-1): + _item = QtGui.QTableWidgetItem(str(value)) + self.ui.table_roi.setItem(row, column, _item) + + def check_roi_validity(self, value, x_axis=True): + """Make sure the ROI selected or defined stays within the image size""" + min_value = 0 + + value = np.int(value) + + if x_axis: + max_value = self.integrated_image_size['width'] + else: + max_value = self.integrated_image_size['height'] + + if value < 0: + return min_value + + if value > max_value: + return max_value + + return value + + def update_table_roi(self, item): + """Using the table_roi_ui as reference, will update the list_roi dictionary""" + self.ui.table_roi.blockSignals(True) + + nbr_row = self.ui.table_roi.rowCount() + new_list_roi = OrderedDict() + old_list_roi = self.list_roi + for _row in np.arange(nbr_row): + _roi = {} + + # checking that x0, y0, x1 and y1 stay within the range of the image + _x0 = self.check_roi_validity(self._get_item_value(_row, 0)) + _y0 = self.check_roi_validity(self._get_item_value(_row, 1), x_axis=False) + + _x1 = self.check_roi_validity(self._get_item_value(_row, 2)) + _y1 = self.check_roi_validity(self._get_item_value(_row, 3), x_axis=False) + + # updating table content (in case some of the roi were out of scope + self._set_item_value(_row, 0, _x0) + self._set_item_value(_row, 1, _y0) + self._set_item_value(_row, 2, _x1) + self._set_item_value(_row, 3, _y1) + + _roi['x0'] = _x0 + _roi['y0'] = _y0 + _roi['x1'] = _x1 + _roi['y1'] = _y1 + _roi['id'] = old_list_roi[_row]['id'] + + new_list_roi[_row] = _roi + + self.list_roi = new_list_roi + self.update_image_view_item() + self.ui.table_roi.blockSignals(False) + + def update_image_view_item(self): + self.clear_roi_on_image_view() + + list_roi = self.list_roi + for _row in list_roi.keys(): + _roi = list_roi[_row] + + _x0 = np.int(_roi['x0']) + _y0 = np.int(_roi['y0']) + _x1 = np.int(_roi['x1']) + _y1 = np.int(_roi['y1']) + + _width = np.abs(_x1 - _x0) + _height = np.abs(_y1 - _y0) + + _roi_id = self.init_roi(x0=_x0, y0=_y0, + width=_width, height=_height) + _roi['id'] = _roi_id + + list_roi[_row] = _roi + + self.list_roi = list_roi + + def _get_item_value(self, row, column): + _item = self.ui.table_roi.item(row, column) + if _item: + return str(_item.text()) + else: + return '' + + def roi_manually_moved(self): + list_roi = self.list_roi + + for _row in list_roi.keys(): + + _roi = list_roi[_row] + + roi_id = _roi['id'] + region = roi_id.getArraySlice(self.integrated_image, self.ui.image_view.imageItem) + + x0 = region[0][0].start + x1 = region[0][0].stop + y0 = region[0][1].start + y1 = region[0][1].stop + + _roi['x0'] = x0 + _roi['x1'] = x1 + _roi['y0'] = y0 + _roi['y1'] = y1 + + list_roi[_row] = _roi + + self.list_roi = list_roi + self.update_table_roi_ui() + + def clear_roi_on_image_view(self): + list_roi = self.list_roi + + for _row in list_roi.keys(): + + _roi = list_roi[_row] + roi_id = _roi['id'] + self.ui.image_view.removeItem(roi_id) + + def add_roi_button_clicked(self): + self.clear_roi_on_image_view() + + self.ui.table_roi.blockSignals(True) + _selection = self.ui.table_roi.selectedRanges() + if _selection: + row = _selection[0].topRow() + else: + row = 0 + + # init new row with default value + self.ui.table_roi.insertRow(row) + _default_roi = self.default_roi + + _item = QtGui.QTableWidgetItem(str(_default_roi['x0'])) + self.ui.table_roi.setItem(row, 0, _item) + + _item = QtGui.QTableWidgetItem(str(_default_roi['y0'])) + self.ui.table_roi.setItem(row, 1, _item) + + _item = QtGui.QTableWidgetItem(str(_default_roi['x1'])) + self.ui.table_roi.setItem(row, 2, _item) + + _item = QtGui.QTableWidgetItem(str(_default_roi['y1'])) + self.ui.table_roi.setItem(row, 3, _item) + + # save new list_roi dictionary + nbr_row = self.ui.table_roi.rowCount() + list_roi = OrderedDict() + for _row in np.arange(nbr_row): + _roi = {} + + _x0 = self._get_item_value(_row, 0) + _roi['x0'] = np.int(_x0) + + _y0 = self._get_item_value(_row, 1) + _roi['y0'] = np.int(_y0) + + _x1 = self._get_item_value(_row, 2) + _roi['x1'] = np.int(_x1) + + _y1 = self._get_item_value(_row, 3) + _roi['y1'] = np.int(_y1) + + x0_int = int(_x0) + y0_int = int(_y0) + width_int = np.abs(x0_int - int(_x1)) + height_int = np.abs(y0_int - int(_y1)) + + _roi_id = self.init_roi(x0=x0_int, y0=y0_int, + width=width_int, height=height_int) + _roi['id'] = _roi_id + list_roi[_row] = _roi + + self.list_roi = list_roi + + self.ui.table_roi.blockSignals(False) + + self.check_add_remove_button_widgets_status() + + if not _selection: + _new_selection = QtGui.QTableWidgetSelectionRange(0, 0, 0, 3) + self.ui.table_roi.setRangeSelected(_new_selection, True) + + def init_roi(self, x0=0, y0=0, width=0, height=0): + _color = QtGui.QColor(62, 13, 244) + _pen = QtGui.QPen() + _pen.setColor(_color) + _pen.setWidthF(self.roi_width) + _roi_id = pg.ROI([x0, y0], [width, height], pen=_pen, scaleSnap=True) + _roi_id.addScaleHandle([1, 1], [0, 0]) + _roi_id.addScaleHandle([0, 0], [1, 1]) + self.ui.image_view.addItem(_roi_id) + # add connection to roi + _roi_id.sigRegionChanged.connect(self.roi_manually_moved) + return _roi_id + + def check_add_remove_button_widgets_status(self): + nbr_row = self.ui.table_roi.rowCount() + if nbr_row > 0: + self.ui.remove_roi_button.setEnabled(True) + else: + self.ui.remove_roi_button.setEnabled(False) + + def format_roi(self): + roi_selected = {} + for _key in self.list_roi.keys(): + _roi = self.list_roi[_key] + x0 = _roi['x0'] + y0 = _roi['y0'] + x1 = _roi['x1'] + y1 = _roi['y1'] + new_entry = {'x0': x0, 'y0': y0, 'x1': x1, 'y1': y1} + roi_selected[_key] = new_entry + + self.roi_selected = roi_selected + + def apply_clicked(self): + self.update_table_roi(None) #check ROI before leaving application + self.format_roi() + self.close() + + def cancel_clicked(self): + self.close() + + def closeEvent(self, eventhere=None): + print("Leaving Parameters Selection UI") diff --git a/notebooks/__code/bragg_edge_normalization.py b/notebooks/__code/bragg_edge_normalization.py new file mode 100644 index 0000000..5091bf4 --- /dev/null +++ b/notebooks/__code/bragg_edge_normalization.py @@ -0,0 +1,367 @@ +import random +import os +import glob +from pathlib import Path +from IPython.core.display import HTML +from IPython.display import display +import numpy as np +from plotly.offline import iplot +import plotly.graph_objs as go +from ipywidgets import widgets + +try: + from PyQt4.QtGui import QFileDialog + from PyQt4 import QtCore, QtGui + from PyQt4.QtGui import QMainWindow +except ImportError: + from PyQt5.QtWidgets import QFileDialog + from PyQt5 import QtCore, QtGui + from PyQt5.QtWidgets import QApplication, QMainWindow + +from neutronbraggedge.experiment_handler import * +from NeuNorm.normalization import Normalization +from NeuNorm.roi import ROI + +from __code import file_handler +from __code.bragg_edge.bragg_edge import BraggEdge as BraggEdgeParent +from __code.file_folder_browser import FileFolderBrowser +from __code import ipywe + + +class BraggEdge(BraggEdgeParent): + + def load_data(self, folder_selected): + self.o_norm = Normalization() + self.load_files(data_type='sample', folder=folder_selected) + + # define time spectra file + folder = os.path.dirname(self.o_norm.data['sample']['file_name'][0]) + self.list_files = self.o_norm.data['sample']['file_name'] + self.data_folder_name = os.path.basename(folder) + spectra_file = glob.glob(os.path.join(folder, '*_Spectra.txt')) + if spectra_file: + self.spectra_file = spectra_file[0] + display(HTML(' Spectra File automatically located: ' + \ + self.spectra_file + '')) + + else: + #ask for spectra file + self.select_time_spectra_file() + + def select_time_spectra_file(self): + self.working_dir = os.path.dirname(self.list_files[0]) + self.time_spectra_ui = ipywe.fileselector.FileSelectorPanel(instruction='Select Time Spectra File ...', + start_dir=self.working_dir, + next=self.save_time_spectra, + filters={'spectra_file': "_Spectra.txt"}, + multiple=False) + + self.time_spectra_ui.show() + self.cancel_button = widgets.Button(description="or Do Not Select any Time Spectra", + button_style="info", + layout=widgets.Layout(width='100%')) + display(self.cancel_button) + self.cancel_button.on_click(self.cancel_time_spectra_selection) + + def save_time_spectra(self, file): + BraggEdgeParent.save_time_spectra(self, file) + self.cancel_button.close() + + def cancel_time_spectra_selection(self, value): + self.time_spectra_ui.remove() + self.cancel_button.close() + display(HTML('NO Spectra File loaded! ')) + + def load_files(self, data_type='sample', folder=None): + + self.starting_dir = os.path.dirname(folder) + if data_type == 'sample': + self.data_folder_name = os.path.basename(folder) + list_files = glob.glob(os.path.join(folder, '*.fits')) + + if list_files == []: + list_files = glob.glob(os.path.join(folder, '*.tif*')) + + else: # fits + # keep only files of interest + list_files = [file for file in list_files if not "_SummedImg.fits" in file] + list_files = [file for file in list_files if ".fits" in file] + + # sort list of files + list_files.sort() + + self.o_norm.load(file=list_files, notebook=True, data_type=data_type) + + display(HTML('' + str(len(list_files)) + \ + ' files have been loaded as ' + data_type + '')) + + def select_ob_folder(self): + select_data = ipywe.fileselector.FileSelectorPanel(instruction='Select OB Folder ...', + start_dir=self.starting_dir, + next=self.load_ob, + type='directory', + multiple=False) + select_data.show() + + def load_ob(self, folder_selected): + self.load_files(data_type='ob', folder=folder_selected) + self.check_data_array_sizes() + + def check_data_array_sizes(self): + len_ob = len(self.o_norm.data['ob']['file_name']) + len_sample = len(self.o_norm.data['sample']['file_name']) + + if len_ob == len_sample: + display(HTML(' Sample and OB have the same size!')) + return + + if len_ob < len_sample: + self.o_norm.data['sample']['data'] = self.o_norm.data['sample']['data'][0:len_ob] + self.o_norm.data['sample']['file_name'] = self.o_norm.data['sample']['file_name'][0:len_ob] + display(HTML(' Truncated Sample array to match OB!')) + else: + self.o_norm.data['ob']['data'] = self.o_norm.data['ob']['data'][0:len_sample] + self.o_norm.data['ob']['file_name'] = self.o_norm.data['ob']['file_name'][0:len_sample] + display(HTML(' Truncated OB array to match Sample!')) + + def load_time_spectra(self): + _tof_handler = TOF(filename=self.spectra_file) + _exp = Experiment(tof=_tof_handler.tof_array, + distance_source_detector_m=np.float(self.dSD_ui.value), + detector_offset_micros=np.float(self.detector_offset_ui.value)) + + nbr_sample = len(self.o_norm.data['sample']['file_name']) + + self.lambda_array = _exp.lambda_array[0: nbr_sample] * 1e10 # to be in Angstroms + self.tof_array = _tof_handler.tof_array[0: nbr_sample] + + def how_many_data_to_use_to_select_sample_roi(self): + nbr_images = len(self.o_norm.data['sample']['data']) + init_value = np.int(nbr_images/10) + if init_value == 0: + init_value = 1 + box1 = widgets.HBox([widgets.Label("Nbr of images to use:", + layout=widgets.Layout(width='15')), + widgets.IntSlider(value=init_value, + max=nbr_images, + min=1)]) + # layout=widgets.Layout(width='50%'))]) + box2 = widgets.Label("(The more you select, the longer it will take to display the preview!)") + vbox = widgets.VBox([box1, box2]) + display(vbox) + self.number_of_data_to_use_ui = box1.children[1] + + def get_image_to_use_for_display(self): + nbr_data_to_use = np.int(self.number_of_data_to_use_ui.value) + _data = self.o_norm.data['sample']['data'] + + nbr_images = len(_data) + list_of_indexes_to_keep = random.sample(list(range(nbr_images)), nbr_data_to_use) + + final_array = [] + for _index in list_of_indexes_to_keep: + final_array.append(_data[_index]) + final_image = np.mean(final_array, axis=0) + self.final_image = final_image + return final_image + + def normalization(self, list_rois=None): + if list_rois is None: + self.o_norm.normalization() + else: + list_o_roi = [] + for key in list_rois.keys(): + roi = list_rois[key] + _x0 = roi['x0'] + _y0 = roi['y0'] + _x1 = roi['x1'] + _y1 = roi['y1'] + + list_o_roi.append(ROI(x0=_x0, + y0=_y0, + x1=_x1, + y1=_y1)) + + self.o_norm.normalization(roi=list_o_roi, notebook=True) + display(HTML(' Normalization DONE! ')) + + def export_normalized_data(self): + self.o_folder = FileFolderBrowser(working_dir=self.working_dir, + next_function=self.export_normalized_data_step2, + ipts_folder=self.ipts_folder) + self.o_folder.select_output_folder_with_new(instruction="Select where to create the normalized data ...") + + def export_normalized_data_step2(self, output_folder): + output_folder = os.path.abspath(output_folder) + self.o_folder.list_output_folders_ui.shortcut_buttons.close() + normalized_export_folder = str(Path(output_folder) / (self.data_folder_name + '_normalized')) + file_handler.make_or_reset_folder(normalized_export_folder) + + self.o_norm.export(folder=normalized_export_folder) + display(HTML(' Created the normalized data in the folder ' + + normalized_export_folder + '')) + if self.spectra_file: + file_handler.copy_files_to_folder(list_files=[self.spectra_file], + output_folder=normalized_export_folder) + display(HTML(' Copied time spectra file to same folder ')) + + def calculate_counts_vs_file_index_of_regions_selected(self, list_roi=None): + + self.list_roi = list_roi + data = self.o_norm.get_sample_data() + + nbr_data = len(data) + box_ui = widgets.HBox([widgets.Label("Calculate Counts vs lambda", + layout=widgets.Layout(width='20%')), + widgets.IntProgress(min=0, + max=nbr_data, + value=0, + layout=widgets.Layout(width='50%'))]) + progress_bar = box_ui.children[1] + display(box_ui) + + counts_vs_file_index = [] + for _index, _data in enumerate(data): + + if len(list_roi) == 0: + _array_data = _data + + else: + _array_data = [] + for _roi in list_roi.keys(): + + x0 = np.int(list_roi[_roi]['x0']) + y0 = np.int(list_roi[_roi]['y0']) + x1 = np.int(list_roi[_roi]['x1']) + y1 = np.int(list_roi[_roi]['y1']) + + _array_data.append(np.nanmean(_data[y0:y1, x0:x1])) + + counts_vs_file_index.append(np.nanmean(_array_data)) + + progress_bar.value = _index+1 + + self.counts_vs_file_index = counts_vs_file_index + box_ui.close() + + def plot(self): + + trace = go.Scatter( + x=self.lambda_array, + y=self.counts_vs_file_index, + mode='markers') + + layout = go.Layout( + height=500, + title="Average transmission vs TOF (of entire images, or of selected region if any)", + xaxis=dict( + title="Lambda (Angstroms)" + ), + yaxis=dict( + title="Average Transmission" + ), + ) + + data = [trace] + figure = go.Figure(data=data, layout=layout) + + iplot(figure) + + def select_output_data_folder(self): + o_folder = FileFolderBrowser(working_dir=self.working_dir, + next_function=self.export_data) + o_folder.select_output_folder(instruction="Select where to create the ascii file...") + # self.select_folder(message='Select where to output the data', + # next_function=self.export_data) + + def make_output_file_name(self, output_folder='', input_folder=''): + file_name = os.path.basename(input_folder) + "_counts_vs_lambda_tof.txt" + return os.path.join(os.path.abspath(output_folder), file_name) + + def export_data(self, output_folder): + input_folder = os.path.dirname(self.o_norm.data['sample']['file_name'][0]) + output_file_name = self.make_output_file_name(output_folder=output_folder, + input_folder=input_folder) + + lambda_array = self.lambda_array + counts_vs_file_index = self.counts_vs_file_index + tof_array = self.tof_array + + metadata = ["# input folder: {}".format(input_folder)] + + list_roi = self.list_roi + if len(list_roi) == 0: + metadata.append("# Entire sample selected") + else: + for index, key in enumerate(list_roi.keys()): + roi = list_roi[key] + _x0 = roi['x0'] + _y0 = roi['y0'] + _x1 = roi['x1'] + _y1 = roi['y1'] + metadata.append("# ROI {}: x0={}, y0={}, x1={}, y1={}".format(index, + _x0, + _y0, + _x1, + _y1)) + metadata.append("#") + metadata.append("# tof (micros), lambda (Angstroms), Average transmission") + + data = [] + for _t, _l, _c in zip(tof_array, lambda_array, counts_vs_file_index): + data.append("{}, {}, {}".format(_t, _l, _c)) + + file_handler.make_ascii_file(metadata=metadata, + data=data, + output_file_name=output_file_name, + dim='1d') + + if os.path.exists(output_file_name): + display(HTML('Ascii file ' + output_file_name + ' has been ' + + 'created ')) + else: + display(HTML('Error exporting Ascii file ' + output_file_name + + '')) + + def select_output_table_folder(self): + o_folder = FileFolderBrowser(working_dir=self.working_dir, + next_function=self.export_table) + o_folder.select_output_folder() + + def export_table(self, output_folder): + material = self.handler.material[0] + lattice = self.handler.lattice[material] + crystal_structure = self.handler.crystal_structure[material] + metadata = ["# material: {}".format(material), + "# crystal structure: {}".format(crystal_structure), + "# lattice: {} Angstroms".format(lattice), + "#", + "# hkl, d(angstroms), BraggEdge"] + data = [] + bragg_edges = self.bragg_edges[material] + hkl = self.hkl[material] + for _index in np.arange(len(bragg_edges)): + _hkl_str = [str(i) for i in hkl[_index]] + _hkl = "".join(_hkl_str) + _bragg_edges = np.float(bragg_edges[_index]) + _d = _bragg_edges/2. + _row = "{}, {}, {}".format(_hkl, _d, _bragg_edges) + data.append(_row) + + output_file_name = os.path.join(output_folder, 'bragg_edges_of_{}.txt'.format(material)) + + file_handler.make_ascii_file(metadata=metadata, + data=data, + dim='1d', + output_file_name=output_file_name) + + display(HTML('File created : ' + \ + output_file_name + '')) + + def select_folder(self, message="", next_function=None): + folder_widget = ipywe.fileselector.FileSelectorPanel(instruction='select {} folder'.format(message), + start_dir=self.working_dir, + next=next_function, + type='directory', + multiple=False) + folder_widget.show() diff --git a/notebooks/__code/bragg_edge_peak_fitting.py b/notebooks/__code/bragg_edge_peak_fitting.py new file mode 100644 index 0000000..20daad1 --- /dev/null +++ b/notebooks/__code/bragg_edge_peak_fitting.py @@ -0,0 +1,4 @@ +from __code.bragg_edge.bragg_edge_peak_fitting_evaluation import BraggEdge + +class BraggEdgePeakFitting(BraggEdge): + pass diff --git a/notebooks/__code/bragg_edge_peak_fitting_gui_utility.py b/notebooks/__code/bragg_edge_peak_fitting_gui_utility.py new file mode 100644 index 0000000..442fde6 --- /dev/null +++ b/notebooks/__code/bragg_edge_peak_fitting_gui_utility.py @@ -0,0 +1,186 @@ +import numpy as np +from qtpy.QtWidgets import QHBoxLayout, QCheckBox, QLineEdit, QVBoxLayout, QWidget, QLabel + +from __code.table_handler import TableHandler + + +class GuiUtility: + + cell_str_format = "{:.3f}" + cell_str_format_2 = "{:f}" + + def __init__(self, parent=None): + self.parent = parent + + def get_tab_selected(self, tab_ui=None): + tab_index = tab_ui.currentIndex() + return tab_ui.tabText(tab_index) + + def get_rows_of_table_selected(self, table_ui=None): + o_table = TableHandler(table_ui=table_ui) + return o_table.get_rows_of_table_selected() + + def select_rows_of_table(self, table_ui=None, list_of_rows=None): + if list_of_rows is None: + return + o_table = TableHandler(table_ui=table_ui) + o_table.select_rows(list_of_rows=list_of_rows) + + def get_toolbox_selected(self, toolbox_ui=None): + toolbox_index = toolbox_ui.currentIndex() + return toolbox_ui.itemText(toolbox_index) + + def update_kropff_high_lambda_table_ui(self, row=0, a0=None, b0=None, a0_error=None, b0_error=None): + table_ui = self.parent.ui.high_lda_tableWidget + table_ui.item(row, 1).setText(self.cell_str_format.format(a0)) + table_ui.item(row, 2).setText(self.cell_str_format.format(b0)) + table_ui.item(row, 3).setText(self.cell_str_format.format(a0_error)) + table_ui.item(row, 4).setText(self.cell_str_format.format(b0_error)) + + def update_kropff_low_lambda_table_ui(self, row=0, ahkl=None, bhkl=None, ahkl_error=None, bhkl_error=None): + table_ui = self.parent.ui.low_lda_tableWidget + table_ui.item(row, 1).setText(self.cell_str_format.format(ahkl)) + table_ui.item(row, 2).setText(self.cell_str_format.format(bhkl)) + table_ui.item(row, 3).setText(self.cell_str_format.format(ahkl_error)) + table_ui.item(row, 4).setText(self.cell_str_format.format(bhkl_error)) + + def update_kropff_bragg_edge_table_ui(self, row=0, ldahkl=None, ldahkl_error=None, + tau=None, tau_error=None, + sigma=None, sigma_error=None): + + ldahkl_error = np.NaN if ldahkl_error is None else ldahkl_error + tau_error = np.NaN if tau_error is None else tau_error + sigma_error = np.NaN if sigma_error is None else sigma_error + + table_ui = self.parent.ui.bragg_edge_tableWidget + table_ui.item(row, 1).setText(self.cell_str_format_2.format(ldahkl)) + table_ui.item(row, 2).setText(self.cell_str_format_2.format(tau)) + table_ui.item(row, 3).setText(self.cell_str_format_2.format(sigma)) + table_ui.item(row, 4).setText(self.cell_str_format_2.format(ldahkl_error)) + table_ui.item(row, 5).setText(self.cell_str_format_2.format(tau_error)) + table_ui.item(row, 6).setText(self.cell_str_format_2.format(sigma_error)) + + def check_status_of_kropff_fitting_buttons(self): + pass + # enabled_low_lambda_button = False + # enabled_bragg_peak_button = False + # + # # can we enabled the low lambda button + # if self.parent.fitting_input_dictionary['rois'][0]['fitting']['kropff']['high']['a0']: + # enabled_low_lambda_button = True + # + # if self.parent.fitting_input_dictionary['rois'][0]['fitting']['kropff']['low']['ahkl']: + # enabled_bragg_peak_button = True + + def get_kropff_fit_parameter_selected(self, fit_region='high'): + """ + return the name of the button checked in the requested tab (kropff fit) + for example: a0 if high lambda and first radioButton checked + :param fit_region: name of the region ('high', 'low' or 'bragg_peak') + :return: + """ + list_fit_parameters_radio_button = {'high': {'ui': [self.parent.ui.kropff_a0_radioButton, + self.parent.ui.kropff_b0_radioButton], + 'name': ['a0', 'b0']}, + 'low': {'ui': [self.parent.ui.kropff_ahkl_radioButton, + self.parent.ui.kropff_bhkl_radioButton], + 'name': ['ahkl', 'bhkl']}, + 'bragg_peak': {'ui': [self.parent.ui.kropff_lda_hkl_radioButton, + self.parent.ui.kropff_tau_radioButton, + self.parent.ui.kropff_sigma_radioButton], + 'name': ['ldahkl', 'tau', 'sigma'], + }, + } + + for _index, _ui in enumerate(list_fit_parameters_radio_button[fit_region]['ui']): + if _ui.isChecked(): + return list_fit_parameters_radio_button[fit_region]['name'][_index] + + return None + + def get_kropff_fit_graph_ui(self, fit_region='high'): + list_ui = {'high': self.parent.kropff_high_plot, + 'low': self.parent.kropff_low_plot, + 'bragg_peak': self.parent.kropff_bragg_peak_plot} + return list_ui[fit_region] + + def get_table_str_item(self, table_ui=None, row=0, column=0): + item = table_ui.item(row, column) + if item: + return str(item.text()) + else: + return "" + + def fill_march_dollase_table(self, list_state=None, initial_parameters=None): + + table_ui = self.parent.ui.march_dollase_user_input_table + o_table = TableHandler(table_ui=table_ui) + o_table.remove_all_rows() + + if not list_state: + return + + march_dollase_row_height = {0: 110, + 'other': 60} + + nbr_column = len(list_state[0]) + for _row in np.arange(len(list_state)): + self.parent.ui.march_dollase_user_input_table.insertRow(_row) + + row_height = march_dollase_row_height[0] if _row == 0 else march_dollase_row_height['other'] + table_ui.setRowHeight(_row, row_height) + + for _col in np.arange(nbr_column): + _state_col = list_state[_row][_col] + _widget = QWidget() + verti_layout = QVBoxLayout() + + hori_layout = QHBoxLayout() + _checkbox = QCheckBox() + _checkbox.setChecked(_state_col) + _checkbox.stateChanged.connect(lambda state=0, row=_row, column=_col: + self.parent.march_dollase_table_state_changed(state=state, + row=row, + column=column)) + hori_layout.addStretch() + hori_layout.addWidget(_checkbox) + hori_layout.addStretch() + new_widget = QWidget() + new_widget.setLayout(hori_layout) + verti_layout.addWidget(new_widget) + + if _row == 0: + parameter_key = self.parent.march_dollase_list_columns[_col] + + if (_col == 1) or (_col == 2): + _input = QLineEdit() + _input.returnPressed.connect(lambda column=_col: + self.parent.march_dollase_table_init_value_changed(column=column)) + _input.setText(str(initial_parameters[parameter_key])) + verti_layout.addWidget(_input) + _input.setVisible(not _state_col) + + elif (_col == 0): + _label = QLabel() + try: + str_format = "{:0.6f}".format(np.float(initial_parameters[parameter_key])) + except ValueError: + str_format = initial_parameters[parameter_key] + + _label.setText(str_format) + verti_layout.addWidget(_label) + _label.setVisible(not _state_col) + + else: + _label = QLabel() + _label.setText("Row dependent") + verti_layout.addWidget(_label) + _label.setVisible(not _state_col) + + + _widget.setLayout(verti_layout) + table_ui.setCellWidget(_row, _col, _widget) + + def set_columns_hidden(self, table_ui=None, list_of_columns=None, state=True): + for _col in list_of_columns: + table_ui.setColumnHidden(_col, state) diff --git a/notebooks/__code/bragg_edge_selection_tab.py b/notebooks/__code/bragg_edge_selection_tab.py new file mode 100644 index 0000000..6737c60 --- /dev/null +++ b/notebooks/__code/bragg_edge_selection_tab.py @@ -0,0 +1,255 @@ +import numpy as np +import pyqtgraph as pg +from qtpy import QtGui +from collections import OrderedDict + +from __code._utilities.array import check_size +from __code.bragg_edge.get import Get + + +class BraggEdgeSelectionTab: + + def __init__(self, parent=None): + self.parent = parent + + def update_all_size_widgets_infos(self): + + if self.parent.ui.square_roi_radiobutton.isChecked(): + return + + roi_id = self.parent.roi_id + region = roi_id.getArraySlice(self.parent.final_image, + self.parent.ui.image_view.imageItem) + x0 = region[0][0].start + x1 = region[0][0].stop + y0 = region[0][1].start + y1 = region[0][1].stop + + new_width = x1 - x0 - 1 + new_height = y1 - y0 - 1 + + # if new width and height is the same as before, just skip that step + if self.parent.new_dimensions_within_error_range(): + return + + self.parent.ui.roi_width.setText(str(new_width)) + self.parent.ui.roi_height.setText(str(new_height)) + self.parent.ui.profile_of_bin_size_width.setText(str(new_width)) + self.parent.ui.profile_of_bin_size_height.setText(str(new_height)) + + max_value = np.min([new_width, new_height]) + self.parent.ui.profile_of_bin_size_slider.setValue(max_value) + self.parent.ui.profile_of_bin_size_slider.setMaximum(max_value) + + def get_shrinking_roi_dimension(self): + coordinates = self.get_coordinates_of_new_inside_selection_box() + return [coordinates['x0'], + coordinates['y0'], + coordinates['x0'] + coordinates['width'], + coordinates['y0'] + coordinates['height']] + + def get_coordinates_of_new_inside_selection_box(self): + # get width and height defined in fitting labels (top right) + width_requested = np.int(str(self.parent.ui.profile_of_bin_size_width.text())) + height_requested = np.int(str(self.parent.ui.profile_of_bin_size_height.text())) + + # retrieve x0, y0, width and height of full selection + region = self.parent.roi_id.getArraySlice(self.parent.final_image, self.parent.ui.image_view.imageItem) + x0 = region[0][0].start + y0 = region[0][1].start + # [x0, y0] = self.parentselection_x0y0 + width_full_selection = np.int(str(self.parent.ui.roi_width.text())) + height_full_selection = np.int(str(self.parent.ui.roi_height.text())) + + delta_width = width_full_selection - width_requested + delta_height = height_full_selection - height_requested + + new_x0 = x0 + np.int(delta_width / 2) + new_y0 = y0 + np.int(delta_height / 2) + + return {'x0' : new_x0, 'y0': new_y0, + 'x1' : new_x0 + width_requested + 1, 'y1': new_y0 + height_requested + 1, + 'width': width_requested, 'height': height_requested} + + + def update_selection_profile_plot(self): + + if self.parent.is_file_imported: + self.update_selection_plot() + self.parent.update_vertical_line_in_profile_plot() + + else: + o_get = Get(parent=self.parent) + x_axis, x_axis_label = o_get.x_axis() + self.parent.ui.profile.clear() + + # large selection region + [x0, y0, x1, y1, _, _] = o_get.selection_roi_dimension() + profile = o_get.profile_of_roi(x0, y0, x1, y1) + x_axis, y_axis = check_size(x_axis=x_axis, + y_axis=profile) + self.parent.ui.profile.plot(x_axis, y_axis, pen=(self.parent.selection_roi_rgb[0], + self.parent.selection_roi_rgb[1], + self.parent.selection_roi_rgb[2])) + + # shrinkable region + shrinking_roi = self.get_coordinates_of_new_inside_selection_box() + x0 = shrinking_roi['x0'] + y0 = shrinking_roi['y0'] + x1 = shrinking_roi['x1'] + y1 = shrinking_roi['y1'] + profile = o_get.profile_of_roi(x0, y0, x1, y1) + x_axis, y_axis = check_size(x_axis=x_axis, + y_axis=profile) + self.parent.ui.profile.plot(x_axis, y_axis, pen=(self.parent.shrinking_roi_rgb[0], + self.parent.shrinking_roi_rgb[1], + self.parent.shrinking_roi_rgb[2])) + self.parent.ui.profile.setLabel("bottom", x_axis_label) + self.parent.ui.profile.setLabel("left", 'Mean transmission') + + # vertical line showing peak to fit + bragg_edge_range = [x_axis[self.parent.bragg_edge_range[0]], + x_axis[self.parent.bragg_edge_range[1]]] + + self.parent.bragg_edge_range_ui = pg.LinearRegionItem(values=bragg_edge_range, + orientation=None, + brush=None, + movable=True, + bounds=None) + self.parent.bragg_edge_range_ui.sigRegionChanged.connect(self.parent.bragg_edge_range_changed) + self.parent.bragg_edge_range_ui.setZValue(-10) + self.parent.ui.profile.addItem(self.parent.bragg_edge_range_ui) + + def update_selection(self, new_value=None, mode='square'): + if self.parent.roi_id is None: + return + + try: + region = self.parent.roi_id.getArraySlice(self.parent.final_image, + self.parent.ui.image_view.imageItem) + except TypeError: + return + + x0 = region[0][0].start + y0 = region[0][1].start + self.parent.selection_x0y0 = [x0, y0] + + # remove old one + self.parent.ui.image_view.removeItem(self.parent.roi_id) + + _pen = QtGui.QPen() + _pen.setColor(self.parent.roi_settings['color']) + _pen.setWidth(self.parent.roi_settings['width']) + self.parent.roi_id = pg.ROI([x0, y0], + [new_value, new_value], + pen=_pen, + scaleSnap=True) + + self.parent.ui.image_view.addItem(self.parent.roi_id) + self.parent.roi_id.sigRegionChanged.connect(self.parent.roi_moved) + + if mode == 'square': + self.parent.ui.roi_width.setText(str(new_value)) + self.parent.ui.roi_height.setText(str(new_value)) + self.parent.reset_profile_of_bin_size_slider() + self.parent.update_profile_of_bin_size_infos() + else: + self.parent.roi_id.addScaleHandle([1, 1], [0, 0]) + + self.update_selection_profile_plot() + self.update_roi_defined_by_profile_of_bin_size_slider() + + def update_selection_plot(self): + self.parent.ui.profile.clear() + o_get = Get(parent=self.parent) + x_axis, x_axis_label = o_get.x_axis() + max_value = self.parent.ui.profile_of_bin_size_slider.maximum() + roi_selected = max_value - self.parent.ui.profile_of_bin_size_slider.value() + + y_axis = self.parent.fitting_input_dictionary['rois'][roi_selected]['profile'] + + self.parent.ui.profile.plot(x_axis, y_axis, pen=(self.parent.shrinking_roi_rgb[0], + self.parent.shrinking_roi_rgb[1], + self.parent.shrinking_roi_rgb[2])) + self.parent.ui.profile.setLabel("bottom", x_axis_label) + self.parent.ui.profile.setLabel("left", 'Mean transmission') + + # full region + y_axis = self.parent.fitting_input_dictionary['rois'][0]['profile'] + self.parent.ui.profile.plot(x_axis, y_axis, pen=(self.parent.selection_roi_rgb[0], + self.parent.selection_roi_rgb[1], + self.parent.selection_roi_rgb[2])) + + + def profile_of_bin_size_slider_changed(self, new_value): + try: + self.parent.update_dict_profile_to_fit() + if self.parent.ui.square_roi_radiobutton.isChecked(): + new_width = new_value + new_height = new_value + else: + initial_roi_width = np.int(str(self.parent.ui.roi_width.text())) + initial_roi_height = np.int(str(self.parent.ui.roi_height.text())) + if initial_roi_width == initial_roi_height: + new_width = new_value + new_height = new_value + elif initial_roi_width < initial_roi_height: + new_width = new_value + delta = initial_roi_width - new_width + new_height = initial_roi_height - delta + else: + new_height = new_value + delta = initial_roi_height - new_height + new_width = initial_roi_width - delta + + self.parent.ui.profile_of_bin_size_width.setText(str(new_width)) + self.parent.ui.profile_of_bin_size_height.setText(str(new_height)) + self.update_roi_defined_by_profile_of_bin_size_slider() + self.update_selection_profile_plot() + except AttributeError: + pass + + def update_roi_defined_by_profile_of_bin_size_slider(self): + coordinates_new_selection = self.get_coordinates_of_new_inside_selection_box() + self.parent.shrinking_roi = coordinates_new_selection + x0 = coordinates_new_selection['x0'] + y0 = coordinates_new_selection['y0'] + width = coordinates_new_selection['width'] + height = coordinates_new_selection['height'] + + # remove old selection + if self.parent.shrinking_roi_id: + self.parent.ui.image_view.removeItem(self.parent.shrinking_roi_id) + + # plot new box + _pen = QtGui.QPen() + _pen.setDashPattern(self.parent.shrinking_roi_settings['dashes_pattern']) + _pen.setColor(self.parent.shrinking_roi_settings['color']) + _pen.setWidth(self.parent.shrinking_roi_settings['width']) + + self.parent.shrinking_roi_id = pg.ROI([x0, y0], + [width, height], + pen=_pen, + scaleSnap=True, + movable=False) + self.parent.ui.image_view.addItem(self.parent.shrinking_roi_id) + + def update_profile_of_bin_slider_widget(self): + self.parent.change_profile_of_bin_slider_signal() + fitting_input_dictionary = self.parent.fitting_input_dictionary + dict_rois_imported = OrderedDict() + nbr_key = len(fitting_input_dictionary['rois'].keys()) + for _index, _key in enumerate(fitting_input_dictionary['rois'].keys()): + dict_rois_imported[nbr_key - 1 - _index] = {'width' : fitting_input_dictionary['rois'][_key]['width'], + 'height': fitting_input_dictionary['rois'][_key]['height']} + self.parent.dict_rois_imported = dict_rois_imported + self.parent.ui.profile_of_bin_size_slider.setRange(0, len(dict_rois_imported) - 1) + # self.parent.ui.profile_of_bin_size_slider.setMinimum(0) + # self.parent.ui.profile_of_bin_size_slider.setMaximum(len(dict_rois_imported)-1) + self.parent.ui.profile_of_bin_size_slider.setSingleStep(1) + self.parent.ui.profile_of_bin_size_slider.setValue(len(dict_rois_imported) - 1) + self.parent.update_profile_of_bin_slider_labels() + + def update_selection_roi_slider_changed(self): + value = self.parent.ui.roi_size_slider.value() + self.parent.selection_roi_slider_changed(value) diff --git a/notebooks/__code/export_handler.py b/notebooks/__code/export_handler.py new file mode 100644 index 0000000..12c3840 --- /dev/null +++ b/notebooks/__code/export_handler.py @@ -0,0 +1,272 @@ +from pathlib import Path +from qtpy.QtWidgets import QFileDialog +import numpy as np +from collections import OrderedDict + +from __code.bragg_edge.get import Get +from __code.file_handler import make_ascii_file +from __code.bragg_edge.bragg_edge_peak_fitting_gui_utility import GuiUtility + + +class ExportHandler: + + def __init__(self, parent=None): + self.parent = parent + + def configuration(self): + # bring file dialog to locate where the file will be saved + base_folder = Path(self.parent.working_dir) + directory = str(base_folder.parent) + _export_folder = QFileDialog.getExistingDirectory(self.parent, + directory=directory, + caption="Select Output Folder", + options=QFileDialog.ShowDirsOnly) + + if _export_folder: + data, metadata = self.get_data_metadata_from_selection_tab() + + # collect initial selection size (x0, y0, width, height) + o_get = Get(parent=self.parent) + [x0, y0, x1, y1, width, height] = o_get.selection_roi_dimension() + + name_of_ascii_file = ExportHandler.makeup_name_of_profile_ascii_file(base_name=str(base_folder.name), + export_folder=_export_folder, + x0=x0, y0=y0, + width=width, + height=height) + + make_ascii_file(metadata=metadata, + data=data, + output_file_name=name_of_ascii_file, + dim='1d') + + self.parent.ui.statusbar.showMessage("{} has been created!".format(name_of_ascii_file), 10000) # 10s + self.parent.ui.statusbar.setStyleSheet("color: green") + + @staticmethod + def makeup_name_of_profile_ascii_file(base_name="default", + export_folder="./", + x0=None, y0=None, width=None, height=None): + """this will return the full path name of the ascii file to create that will contain all the profiles + starting with the selection box and all the way to the minimal size""" + full_base_name = "full_set_of_shrinkable_region_profiles_from_" + \ + "x{}_y{}_w{}_h{}_for_folder_{}.txt".format(x0, y0, width, height, base_name) + return str(Path(export_folder) / full_base_name) + + def get_data_metadata_from_selection_tab(self): + base_folder = Path(self.parent.working_dir) + o_get = Get(parent=self.parent) + + index_axis, _ = o_get.specified_x_axis(xaxis='index') + tof_axis, _ = o_get.specified_x_axis(xaxis='tof') + lambda_axis, _ = o_get.specified_x_axis('lambda') + fitting_peak_range = self.parent.bragg_edge_range + distance_detector_sample = str(self.parent.ui.distance_detector_sample.text()) + detector_offset = str(self.parent.ui.detector_offset.text()) + kropff_fitting_values = self.collect_all_kropff_fitting_values() + march_dollase_fitting_values = self.collect_all_march_dollase_fitting_values() + + dict_regions = o_get.all_russian_doll_region_full_infos() + metadata = ExportHandler.make_metadata(base_folder=base_folder, + fitting_peak_range=fitting_peak_range, + dict_regions=dict_regions, + distance_detector_sample=distance_detector_sample, + detector_offset=detector_offset, + kropff_fitting_values=kropff_fitting_values, + march_dollase_fitting_values=march_dollase_fitting_values) + self.add_fitting_infos_to_metadata(metadata) + + metadata.append("#") + metadata.append("#File Index, TOF(micros), lambda(Angstroms), ROIs (see above)") + data = ExportHandler.format_data(col1=index_axis, + col2=tof_axis, + col3=lambda_axis, + dict_regions=dict_regions) + + return data, metadata + + def add_fitting_infos_to_metadata(self, metadata): + o_tab = GuiUtility(parent=self.parent) + fitting_algorithm_used = o_tab.get_tab_selected(tab_ui=self.parent.ui.tab_algorithm) + # fitting_rois = self.fitting_rois + # fitting_flag = True if self.parent.fitting_peak_ui else False + metadata.append("#fitting algorithm selected: {}".format(fitting_algorithm_used)) + metadata.append("#kropff fitting procedure started: {}".format( + self.parent.fitting_procedure_started['kropff'])) + metadata.append("#Bragg peak selection range: [{}, {}]".format(self.parent.kropff_fitting_range[ + 'bragg_peak'][0], + self.parent.kropff_fitting_range['bragg_peak'][1])) + # kropff + for _key in self.parent.kropff_fitting_range.keys(): + metadata.append("#kropff {} selection range: [{}, {}]".format(_key, + self.parent.kropff_fitting_range[_key][0], + self.parent.kropff_fitting_range[_key][1])) + + # March-dollase + [left_peak, right_peak] = self.parent.march_dollase_fitting_range_selected + metadata.append("#march-dollase bragg peak selection range: [{}, {}]".format(left_peak, right_peak)) + metadata.append("#march-dollase fitting procedure started: {}".format( + self.parent.fitting_procedure_started['march-dollase'])) + for _row_index, _row_entry in enumerate(self.parent.march_dollase_fitting_history_table): + str_row_entry = [str(_value) for _value in _row_entry] + joined_str_row_entry = ", ".join(str_row_entry) + metadata.append("#march-dollase history table row {}: {}".format(_row_index, joined_str_row_entry)) + + sigma = self.parent.march_dollase_fitting_initial_parameters['sigma'] + alpha = self.parent.march_dollase_fitting_initial_parameters['alpha'] + + metadata.append("#march-dollase history init sigma: {}".format(sigma)) + metadata.append("#march-dollase history init alpha: {}".format(alpha)) + + def collect_all_march_dollase_fitting_values(self): + march_fitting_values = OrderedDict() + fitting_input_dictionary = self.parent.fitting_input_dictionary + + for _row in fitting_input_dictionary['rois'].keys(): + _entry = fitting_input_dictionary['rois'][_row]['fitting']['march_dollase'] + + march_fitting_values[_row] = {'d_spacing': _entry['d_spacing'], + 'sigma': _entry['sigma'], + 'alpha': _entry['alpha'], + 'a1': _entry['a1'], + 'a2': _entry['a2'], + 'a5': _entry['a5'], + 'a6': _entry['a6'], + 'd_spacing_error': _entry['d_spacing_error'], + 'sigma_error': _entry['sigma_error'], + 'alpha_error': _entry['alpha_error'], + 'a1_error': _entry['a1_error'], + 'a2_error': _entry['a2_error'], + 'a5_error': _entry['a5_error'], + 'a6_error': _entry['a6_error'], + } + return march_fitting_values + + def collect_all_kropff_fitting_values(self): + kropff_fitting_values = OrderedDict() + + fitting_input_dictionary = self.parent.fitting_input_dictionary + + for _row in fitting_input_dictionary['rois'].keys(): + _entry = fitting_input_dictionary['rois'][_row]['fitting']['kropff'] + + _entry_high = _entry['high'] + _entry_low = _entry['low'] + _entry_bragg_peak = _entry['bragg_peak'] + kropff_fitting_values[_row] = {'a0': _entry_high['a0'], + 'b0': _entry_high['b0'], + 'a0_error': _entry_high['a0_error'], + 'b0_error': _entry_high['b0_error'], + 'ahkl': _entry_low['ahkl'], + 'bhkl': _entry_low['bhkl'], + 'ahkl_error': _entry_low['ahkl_error'], + 'bhkl_error': _entry_low['bhkl_error'], + 'ldahkl': _entry_bragg_peak['ldahkl'], + 'tau': _entry_bragg_peak['tau'], + 'sigma': _entry_bragg_peak['sigma'], + 'ldahkl_error': _entry_bragg_peak['ldahkl_error'], + 'tau_error': _entry_bragg_peak['tau_error'], + 'sigma_error': _entry_bragg_peak['sigma_error'], + } + return kropff_fitting_values + + @staticmethod + def make_metadata(base_folder=None, + fitting_peak_range=None, + dict_regions=None, + distance_detector_sample="", + detector_offset="", + kropff_fitting_values=None, + march_dollase_fitting_values=None): + + metadata = ["#base folder: {}".format(base_folder)] + metadata.append("#fitting peak range in file index: [{}, {}]".format(fitting_peak_range[0], + fitting_peak_range[1])) + metadata.append("#distance detector-sample: {}".format(distance_detector_sample)) + metadata.append("#detector offset: {}".format(detector_offset)) + for _row, _key in enumerate(dict_regions.keys()): + _entry = dict_regions[_key] + x0 = _entry['x0'] + y0 = _entry['y0'] + width = _entry['width'] + height = _entry['height'] + + _entry_kropff = kropff_fitting_values[_row] + a0 = _entry_kropff['a0'] + b0 = _entry_kropff['b0'] + a0_error = _entry_kropff['a0_error'] + b0_error = _entry_kropff['b0_error'] + ahkl = _entry_kropff['ahkl'] + bhkl = _entry_kropff['bhkl'] + ahkl_error = _entry_kropff['ahkl_error'] + bhkl_error = _entry_kropff['bhkl_error'] + ldahkl = _entry_kropff['ldahkl'] + tau = _entry_kropff['tau'] + sigma = _entry_kropff['sigma'] + ldahkl_error = _entry_kropff['ldahkl_error'] + tau_error = _entry_kropff['tau_error'] + sigma_error = _entry_kropff['sigma_error'] + + _entry_march = march_dollase_fitting_values[_row] + d_spacing = _entry_march['d_spacing'] + sigma1 = _entry_march['sigma'] + alpha = _entry_march['alpha'] + a1 = _entry_march['a1'] + a2 = _entry_march['a2'] + a5 = _entry_march['a5'] + a6 = _entry_march['a6'] + d_spacing_error = _entry_march['d_spacing_error'] + sigma1_error = _entry_march['sigma_error'] + alpha_error = _entry_march['alpha_error'] + a1_error = _entry_march['a1_error'] + a2_error = _entry_march['a2_error'] + a5_error = _entry_march['a5_error'] + a6_error = _entry_march['a6_error'] + + metadata.append("#column {} -> x0:{}, y0:{}, width:{}, height:{}," + " kropff: a0:{}, b0:{}, a0_error:{}, b0_error:{}," + " ahkl:{}, bhkl:{}, ahkl_error:{}, bhkl_error:{}," + " ldahkl:{}, tau:{}, sigma:{}," + " ldahkl_error:{}, tau_error:{}, sigma_error:{}," + " march_dollase: d_spacing:{}, sigma:{}, alpha:{}," + " a1:{}, a2:{}, a5:{}, a6:{}," + " d_spacing_error:{}, sigma_error:{}, alpha_error:{}," + " a1_error:{}, a2_error:{}, a5_error:{}, a6_error:{}".format(_key + 3, + x0, y0, + width, height, + a0, b0, a0_error, b0_error, + ahkl, bhkl, + ahkl_error, + bhkl_error, + ldahkl, tau, sigma, + ldahkl_error, + tau_error, + sigma_error, + d_spacing, + sigma1, alpha, + a1, a2, a5, a6, + d_spacing_error, + sigma1_error, alpha_error, + a1_error, a2_error, a5_error, + a6_error)) + + return metadata + + @staticmethod + def format_data(col1=None, col2=None, col3=None, dict_regions=None): + if col1 is None: + return [] + + data = [] + profile_length = len(dict_regions[0]['profile']) + for _row_index in np.arange(profile_length): + list_profile_for_this_row = [] + for _key in dict_regions.keys(): + _profile = dict_regions[_key]['profile'] + list_profile_for_this_row.append(str(_profile[_row_index])) + _col1 = col1[_row_index] + _col2 = col2[_row_index] + _col3 = col3[_row_index] + data.append("{}, {}, {}, ".format(_col1, _col2, _col3) + ", ".join(list_profile_for_this_row)) + return data + diff --git a/notebooks/__code/get.py b/notebooks/__code/get.py new file mode 100644 index 0000000..ccc40ea --- /dev/null +++ b/notebooks/__code/get.py @@ -0,0 +1,167 @@ +import numpy as np + +from __code.bragg_edge.bragg_edge_peak_fitting_gui_utility import GuiUtility +from __code.selection_region_utilities import SelectionRegionUtilities + + +class Get: + + def __init__(self, parent=None): + self.parent = parent + + self.x_axis_choice_ui = {'selection': {'index' : self.parent.ui.selection_index_radiobutton, + 'tof' : self.parent.ui.selection_tof_radiobutton, + 'lambda': self.parent.ui.selection_lambda_radiobutton}, + 'fitting' : {'index' : self.parent.ui.fitting_index_radiobutton, + 'tof' : self.parent.ui.fitting_tof_radiobutton, + 'lambda': self.parent.ui.fitting_lambda_radiobutton}, + } + + def specified_x_axis(self, xaxis='index'): + # if self.parent.is_file_imported: + # return self.parent.fitting_input_dictionary['xaxis'][xaxis] + # else: + label = self.parent.xaxis_label[xaxis] + if xaxis == 'index': + return self.parent.index_array, label + elif xaxis == 'tof': + return self.parent.tof_array_s * 1e6, label + elif xaxis == 'lambda': + return self.parent.lambda_array, label + else: + raise NotImplementedError + + def x_axis_label(self, x_axis_selected='index'): + x_axis_dict = self.parent.fitting_input_dictionary['xaxis'] + return x_axis_dict[x_axis_selected][1] + + def x_axis_checked(self): + o_gui = GuiUtility(parent=self) + tab_selected = o_gui.get_tab_selected(tab_ui=self.parent.ui.tabWidget).lower() + + list_ui = self.x_axis_choice_ui[tab_selected] + + if list_ui['index'].isChecked(): + return 'index' + elif list_ui['tof'].isChecked(): + return 'tof' + else: + return 'lambda' + + def x_axis(self): + o_gui = GuiUtility(parent=self.parent) + tab_selected = o_gui.get_tab_selected(self.parent.ui.tabWidget).lower() + + list_ui = self.x_axis_choice_ui[tab_selected] + if list_ui['index'].isChecked(): + return self.specified_x_axis(xaxis='index') + elif list_ui['tof'].isChecked(): + return self.specified_x_axis(xaxis='tof') + else: + return self.specified_x_axis(xaxis='lambda') + + def all_x_axis(self): + all_x_axis = {'index' : self.specified_x_axis(xaxis='index'), + 'tof' : self.specified_x_axis(xaxis='tof'), + 'lambda': self.specified_x_axis(xaxis='lambda')} + return all_x_axis + + def all_russian_doll_region_full_infos(self): + if self.parent.is_file_imported: + dict_regions = self.parent.fitting_input_dictionary['rois'] + else: + # collect initial selection size (x0, y0, width, height) + [x0, y0, x1, y1, width, height] = self.selection_roi_dimension() + # create profile for all the fitting region inside that first box + o_regions = SelectionRegionUtilities(x0=x0, y0=y0, width=width, height=height) + dict_regions = o_regions.get_all_russian_doll_regions() + self.parent.add_profile_to_dict_of_all_regions(dict_regions=dict_regions) + return dict_regions + + def selection_roi_dimension(self): + roi_id = self.parent.roi_id + + x0, y0, x1, y1, width, height = None, None, None, None, None, None + + if roi_id: + region = roi_id.getArraySlice(self.parent.final_image, + self.parent.ui.image_view.imageItem) + x0 = region[0][0].start + x1 = region[0][0].stop + y0 = region[0][1].start + y1 = region[0][1].stop + width = np.int(x1 - x0) + height = np.int(y1 - y0) + + else: + x0, y0, x1, y1, width, height = self.parent.roi_dimension_from_config_file + + return [x0, y0, x1, y1, width, height] + + def profile_of_roi(self, x0=None, y0=None, x1=None, y1=None, width=None, height=None): + profile_value = [] + + if width: + x1 = x0 + width + if height: + y1 = y0 + height + + for _image in self.parent.o_norm.data['sample']['data']: + _value = np.mean(_image[y0:y1, x0:x1]) + profile_value.append(_value) + + return profile_value + + def requested_xaxis(self, xaxis_label='index'): + if xaxis_label == 'index': + return self.parent.dict_profile_to_fit['xaxis']['index'], self.parent.xaxis_label['index'] + elif xaxis_label == 'tof': + return self.parent.dict_profile_to_fit['xaxis']['tof'], self.parent.xaxis_label['tof'] + elif xaxis_label == 'lambda': + return self.parent.dict_profile_to_fit['xaxis']['lambda'], self.parent.xaxis_label['lambda'] + + def fitting_profile_xaxis(self): + if self.parent.ui.fitting_tof_radiobutton.isChecked(): + return self.requested_xaxis(xaxis_label='tof') + elif self.ui.fitting_index_radiobutton.isChecked(): + return self.requested_xaxis(xaxis_label='index') + else: + return self.requested_xaxis(xaxis_label='lambda') + + def part_of_fitting_selected(self): + """high, low or bragg_peak""" + list_pages = ["Bragg peak selection", "high", "low", "bragg_peak"] + list_table_ui = [None, + self.parent.ui.high_lda_tableWidget, + self.parent.ui.low_lda_tableWidget, + self.parent.ui.bragg_edge_tableWidget] + + page_index = self.parent.ui.kropff_toolBox.currentIndex() + + return {'name_of_page': list_pages[page_index], + 'table_ui' : list_table_ui[page_index]} + + def y_axis_data_of_selected_row(self, row_selected): + selected_roi = self.parent.fitting_input_dictionary['rois'][row_selected] + yaxis = selected_roi['profile'] + [left_xaxis_index, right_xaxis_index] = self.parent.bragg_edge_range + yaxis = yaxis[left_xaxis_index: right_xaxis_index] + return yaxis + + def x_axis_data(self, x_axis_selected='index'): + xaxis_dict = self.parent.fitting_input_dictionary['xaxis'] + xaxis_index, xaxis_label = xaxis_dict[x_axis_selected] + [left_xaxis_index, right_xaxis_index] = self.parent.bragg_edge_range + xaxis = xaxis_index[left_xaxis_index: right_xaxis_index] + return xaxis + + @staticmethod + def units(name='index'): + if name == 'index': + return 'file index' + elif name == 'tof': + return u"\u03BCs" + elif name == 'lambda': + return u"\u212B" + else: + return "" diff --git a/notebooks/__code/import_handler.py b/notebooks/__code/import_handler.py new file mode 100644 index 0000000..144b23e --- /dev/null +++ b/notebooks/__code/import_handler.py @@ -0,0 +1,298 @@ +from pathlib import Path +from qtpy.QtWidgets import QFileDialog +import numpy as np +from collections import OrderedDict + +from __code.file_handler import read_bragg_edge_fitting_ascii_format +from __code.bragg_edge.peak_fitting_initialization import PeakFittingInitialization +from __code.bragg_edge.fitting_functions import kropff_high_lambda, kropff_low_lambda, kropff_bragg_peak_tof +from __code.bragg_edge.bragg_edge_peak_fitting_gui_utility import GuiUtility +from __code.bragg_edge.bragg_edge_selection_tab import BraggEdgeSelectionTab +from __code.bragg_edge.kropff import Kropff +from __code.bragg_edge.march_dollase import MarchDollase + + +class ImportHandler: + + def __init__(self, parent=None): + self.parent = parent + + def run(self): + working_dir = str(Path(self.parent.working_dir).parent) + ascii_file = QFileDialog.getOpenFileName(self.parent, + caption="Select ASCII file", + directory=working_dir, + filter="ASCII (*.txt)") + + if ascii_file[0]: + + self.parent.full_reset_of_ui() + self.parent.block_table_ui(True) + self.parent.is_file_imported = True + result_of_import = read_bragg_edge_fitting_ascii_format(full_file_name=str(ascii_file[0])) + self.save_initial_roi_dimension_from_config_file(result_of_import['metadata']['columns']['3']) + self.save_march_dollase_parameters(result_of_import['metadata']) + self.parent.bragg_edge_range = result_of_import['metadata']['bragg_edge_range'] + self.parent.bragg_peak_selection_range = result_of_import['metadata']['bragg_peak_selection_range'] + + self.update_selection_tab(result_of_import=result_of_import) + self.update_interface(result_of_import=result_of_import) + + self.parent.ui.statusbar.showMessage("{} has been imported!".format(ascii_file[0]), 10000) # 10s + self.parent.ui.statusbar.setStyleSheet("color: green") + + o_selection = BraggEdgeSelectionTab(parent=self.parent) + o_selection.update_profile_of_bin_slider_widget() + o_selection.update_selection_plot() + + self.parent.ui.tabWidget.setTabEnabled(1, self.parent.is_fit_infos_loaded()) + self.parent.ui.tabWidget.setEnabled(True) + self.parent.ui.actionExport.setEnabled(True) + + self.parent.fitting_procedure_started['kropff'] = result_of_import.get('metadata').get('kropff fitting ' + 'procedure ' + 'started', False) + self.parent.fitting_procedure_started['march-dollase'] = result_of_import.get('metadata').get( + 'march-dollase fitting procedure started', False) + + o_kropff = Kropff(parent=self.parent) + o_kropff.reset_all_table() + + o_march = MarchDollase(parent=self.parent) + o_march.reset_table() + + if result_of_import.get('metadata').get('kropff fitting procedure started', False): + # fill tables with minimum contains + o_kropff.fill_table_with_fitting_information() + + if result_of_import.get('metadata').get('march-dollase fitting procedure started', False): + # fill tables with minimum contains + o_march.fill_tables_with_fitting_information() + o_march.fill_history_table_with_fitting_information() + + self.parent.select_first_row_of_all_fitting_table() + + # self.parent.initialize_default_peak_regions() + + self.parent.block_table_ui(False) + self.parent.update_vertical_line_in_profile_plot() + self.parent.update_fitting_plot() + self.parent.kropff_fitting_range_changed() + + o_gui = GuiUtility(parent=self.parent) + o_gui.check_status_of_kropff_fitting_buttons() + + def update_interface(self, result_of_import=None): + self.create_fitting_input_dictionary_from_imported_ascii_file(result_of_import=result_of_import) + self.parent.tof_array_s = self.parent.fitting_input_dictionary['xaxis']['tof'][0] * 1e-6 + self.parent.lambda_array = self.parent.fitting_input_dictionary['xaxis']['lambda'][0] + self.parent.index_array = self.parent.fitting_input_dictionary['xaxis']['index'][0] + + def update_selection_tab(self, result_of_import=None): + self.parent.ui.distance_detector_sample.setText(result_of_import['metadata']['distance_detector_sample']) + self.parent.ui.detector_offset.setText(result_of_import['metadata']['detector_offset']) + self.parent.disable_left_part_of_selection_tab() + self.parent.ui.info_message_about_cyan.setVisible(False) + + def save_march_dollase_parameters(self, metadata_dict): + march_dollase_history_table = metadata_dict['march-dollase history table'] + march_dollase_history_init = metadata_dict['march-dollase history init'] + + march_dollase_fitting_history_table = [] + for _row_index in march_dollase_history_table.keys(): + str_flag = march_dollase_history_table[_row_index] + list_flag = str_flag.split(",") + list_flag = [_value.strip() for _value in list_flag] + + _row_flag = [] + for _value in list_flag: + _flag = True if _value == "True" else False + _row_flag.append(_flag) + march_dollase_fitting_history_table.append(_row_flag) + + march_dollase_fitting_initial_parameters = {'sigma': march_dollase_history_init['sigma'], + 'alpha': march_dollase_history_init['alpha'], + 'd_spacing': np.NaN, + 'a1': np.NaN, + 'a2': np.NaN, + 'a5': np.NaN, + 'a6': np.NaN} + + self.parent.march_dollase_fitting_history_table = march_dollase_fitting_history_table + self.parent.march_dollase_fitting_initial_parameters = march_dollase_fitting_initial_parameters + self.parent.march_dollase_fitting_range_selected = metadata_dict['march-dollase bragg peak selection range'] + + def save_initial_roi_dimension_from_config_file(self, column_3_dict): + """column_3_dict = {'x0': value, 'y0': value, 'width': value, 'height': value}""" + self.parent.roi_dimension_from_config_file = [column_3_dict['x0'], + column_3_dict['y0'], + None, None, + column_3_dict['width'], + column_3_dict['height']] + + def create_fitting_input_dictionary_from_imported_ascii_file(self, result_of_import): + metadata = result_of_import['metadata'] + self.parent.kropff_fitting_range['high'] = metadata['kropff_high'] + self.parent.kropff_fitting_range['low'] = metadata['kropff_low'] + self.parent.kropff_fitting_range['bragg_peak'] = metadata['kropff_bragg_peak'] + + self.parent.working_dir = metadata['base_folder'] + self.parent.bragg_edge_range = metadata['bragg_edge_range'] + + columns_roi = metadata['columns'] + + o_init = PeakFittingInitialization(parent=self.parent) + self.parent.fitting_input_dictionary = o_init.fitting_input_dictionary(nbr_rois=len(columns_roi)) + self.parent.fitting_input_dictionary['bragg_edge_range'] = metadata['bragg_edge_range'] + + data = result_of_import['data'] + tof_array = np.array(data['tof']) + index_array = np.array(data['index']) + lambda_array = np.array(data['lambda']) + rois_dictionary = OrderedDict() + + lda_array_of_peak_selected = lambda_array[self.parent.bragg_edge_range[0]: + self.parent.bragg_edge_range[1]] + + for col in np.arange(3, len(columns_roi) + 3): + str_col = str(col) + col_index = col-3 + + # high lambda + self.parent.fitting_input_dictionary['rois'][col_index]['profile'] = np.array(data[str_col]) + self.parent.fitting_input_dictionary['rois'][col_index]['x0'] = columns_roi[str_col]['x0'] + self.parent.fitting_input_dictionary['rois'][col_index]['y0'] = columns_roi[str_col]['y0'] + self.parent.fitting_input_dictionary['rois'][col_index]['width'] = columns_roi[str_col]['width'] + self.parent.fitting_input_dictionary['rois'][col_index]['height'] = columns_roi[str_col]['height'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['high']['a0'] = \ + columns_roi[str_col]['kropff']['a0'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['high']['b0'] = \ + columns_roi[str_col]['kropff']['b0'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['high']['a0_error'] = \ + columns_roi[str_col]['kropff']['a0_error'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['high']['b0_error'] = \ + columns_roi[str_col]['kropff']['b0_error'] + + xaxis_to_fit = lda_array_of_peak_selected[self.parent.kropff_fitting_range['high'][0]: + self.parent.kropff_fitting_range['high'][1]] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['high']['xaxis_to_fit'] = \ + xaxis_to_fit + + kropff_a0 = np.NaN if columns_roi[str_col]['kropff']['a0'] == 'None' else np.float(columns_roi[str_col][ + 'kropff']['a0']) + kropff_b0 = np.NaN if columns_roi[str_col]['kropff']['b0'] == 'None' else np.float(columns_roi[str_col][ + 'kropff']['b0']) + yaxis_fitted = kropff_high_lambda(xaxis_to_fit, + kropff_a0, + kropff_b0) + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['high']['yaxis_fitted'] = \ + yaxis_fitted + + # low lambda + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['low']['ahkl'] = \ + columns_roi[str_col]['kropff']['ahkl'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['low']['bhkl'] = \ + columns_roi[str_col]['kropff']['bhkl'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['low']['ahkl_error'] = \ + columns_roi[str_col]['kropff']['ahkl_error'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['low']['bhkl_error'] = \ + columns_roi[str_col]['kropff']['bhkl_error'] + + xaxis_to_fit = lda_array_of_peak_selected[self.parent.kropff_fitting_range['low'][0]: + self.parent.kropff_fitting_range['low'][1]] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['low']['xaxis_to_fit'] = \ + xaxis_to_fit + + kropff_ahkl = np.NaN if columns_roi[str_col]['kropff']['ahkl'] == 'None' else np.float(columns_roi[str_col][ + 'kropff']['ahkl']) + kropff_bhkl = np.NaN if columns_roi[str_col]['kropff']['bhkl'] == 'None' else np.float(columns_roi[str_col][ + 'kropff']['bhkl']) + + yaxis_fitted = kropff_low_lambda(xaxis_to_fit, + kropff_a0, + kropff_b0, + kropff_ahkl, + kropff_bhkl) + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['low']['yaxis_fitted'] = \ + yaxis_fitted + + # Bragg peak + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['bragg_peak']['ldahkl'] = \ + columns_roi[str_col]['kropff']['ldahkl'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['bragg_peak']['tau'] = \ + columns_roi[str_col]['kropff']['tau'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['bragg_peak']['sigma'] = \ + columns_roi[str_col]['kropff']['sigma'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['bragg_peak']['ldahkl_error']\ + = columns_roi[str_col]['kropff']['ldahkl_error'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['bragg_peak']['tau_error'] = \ + columns_roi[str_col]['kropff']['tau_error'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['bragg_peak']['sigma_error']\ + = \ + columns_roi[str_col]['kropff']['sigma_error'] + + xaxis_to_fit = lda_array_of_peak_selected[self.parent.kropff_fitting_range['bragg_peak'][0]: + self.parent.kropff_fitting_range['bragg_peak'][1]] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['bragg_peak']['xaxis_to_fit']\ + = \ + xaxis_to_fit + + kropff_tau = np.NaN if columns_roi[str_col]['kropff']['tau'] == 'None' else np.float(columns_roi[ + str_col][ + 'kropff']['tau']) + kropff_ldahkl = np.NaN if columns_roi[str_col]['kropff']['ldahkl'] == 'None' else np.float(columns_roi[ + str_col][ + 'kropff'][ + 'ldahkl']) + kropff_sigma = np.NaN if columns_roi[str_col]['kropff']['sigma'] == 'None' else np.float(columns_roi[ + str_col][ + 'kropff'][ + 'sigma']) + + yaxis_fitted = kropff_bragg_peak_tof(xaxis_to_fit, + kropff_a0, + kropff_b0, + kropff_ahkl, + kropff_bhkl, + kropff_ldahkl, + kropff_sigma, + kropff_tau) + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['kropff']['bragg_peak']['yaxis_fitted']\ + = \ + yaxis_fitted + + # March_dollase + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['march_dollase']['d_spacing'] = \ + columns_roi[str_col]['march_dollase']['d_spacing'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['march_dollase']['sigma'] = \ + columns_roi[str_col]['march_dollase']['sigma'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['march_dollase']['alpha'] = \ + columns_roi[str_col]['march_dollase']['alpha'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['march_dollase']['a1'] = \ + columns_roi[str_col]['march_dollase']['a1'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['march_dollase']['a2'] = \ + columns_roi[str_col]['march_dollase']['a2'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['march_dollase']['a5'] = \ + columns_roi[str_col]['march_dollase']['a5'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['march_dollase']['a6'] = \ + columns_roi[str_col]['march_dollase']['a6'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['march_dollase']['d_spacing_error'] = \ + columns_roi[str_col]['march_dollase']['d_spacing_error'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['march_dollase']['sigma_error'] = \ + columns_roi[str_col]['march_dollase']['sigma_error'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['march_dollase']['alpha_error'] = \ + columns_roi[str_col]['march_dollase']['alpha_error'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['march_dollase']['a1_error'] = \ + columns_roi[str_col]['march_dollase']['a1_error'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['march_dollase']['a2_error'] = \ + columns_roi[str_col]['march_dollase']['a2_error'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['march_dollase']['a5_error'] = \ + columns_roi[str_col]['march_dollase']['a5_error'] + self.parent.fitting_input_dictionary['rois'][col_index]['fitting']['march_dollase']['a6_error'] = \ + columns_roi[str_col]['march_dollase']['a6_error'] + + xaxis_dictionary = {'index': (index_array, self.parent.xaxis_label['index']), + 'lambda': (lambda_array, self.parent.xaxis_label['lambda']), + 'tof': (tof_array, self.parent.xaxis_label['tof'])} + self.parent.fitting_input_dictionary['xaxis'] = xaxis_dictionary + self.parent.fitting_input_dictionary['bragg_edge_range_selected'] = result_of_import['metadata']['bragg_edge_range'] diff --git a/notebooks/__code/kropff.py b/notebooks/__code/kropff.py new file mode 100644 index 0000000..cb0321d --- /dev/null +++ b/notebooks/__code/kropff.py @@ -0,0 +1,344 @@ +import numpy as np +from qtpy import QtGui +from qtpy.QtWidgets import QFileDialog +from pathlib import Path +import pyqtgraph as pg + +from __code.table_handler import TableHandler +from __code.bragg_edge.bragg_edge_peak_fitting_gui_utility import GuiUtility +from __code.bragg_edge.kropff_fitting_job_handler import KropffFittingJobHandler +from __code.file_handler import make_ascii_file_from_2dim_array +from __code.bragg_edge.get import Get +from __code._utilities.dictionary import key_path_exists_in_dictionary +from __code.utilities import find_nearest_index + + +class Kropff: + + def __init__(self, parent=None): + self.parent = parent + + self.table_ui = {'high_lda': self.parent.ui.high_lda_tableWidget, + 'low_lda' : self.parent.ui.low_lda_tableWidget, + 'bragg_peak' : self.parent.ui.bragg_edge_tableWidget} + + def reset_all_table(self): + self.reset_high_lambda_table() + self.reset_low_lambda_table() + self.reset_bragg_peak_table() + + def reset_high_lambda_table(self): + self.clear_table(table_name='high_lda') + self.fill_table_with_minimum_contain(table_ui=self.table_ui['high_lda']) + + def reset_low_lambda_table(self): + self.clear_table(table_name='low_lda') + self.fill_table_with_minimum_contain(table_ui=self.table_ui['low_lda']) + + def reset_bragg_peak_table(self): + self.clear_table(table_name='bragg_peak') + self.fill_table_with_minimum_contain(table_ui=self.parent.ui.bragg_edge_tableWidget) + + def clear_table(self, table_name='high_lambda', is_all=False): + """remove all the rows of the table name specified, or all if is_all is True""" + if is_all: + for _key in self.table_ui.keys(): + self.clear_table(table_name=_key) + else: + o_table = TableHandler(table_ui=self.table_ui[table_name]) + o_table.remove_all_rows() + + def fill_table_with_minimum_contain(self, table_ui=None): + fitting_input_dictionary = self.parent.fitting_input_dictionary + rois = fitting_input_dictionary['rois'] + + o_table = TableHandler(table_ui=table_ui) + nbr_column = o_table.table_ui.columnCount() + other_column_name = ["N/A" for _ in np.arange(nbr_column)] + for _row, _roi in enumerate(rois.keys()): + _roi_key = rois[_roi] + list_col_name = "{}; {}; {}; {}".format(_roi_key['x0'], + _roi_key['y0'], + _roi_key['width'], + _roi_key['height']) + col_name = [list_col_name] + other_column_name + o_table.insert_row(_row, col_name) + + def fill_table_with_fitting_information(self): + fitting_input_dictionary = self.parent.fitting_input_dictionary + + o_table = TableHandler(table_ui=self.table_ui['high_lda']) + _col = 1 + for _row in fitting_input_dictionary['rois'].keys(): + _entry = fitting_input_dictionary['rois'][_row]['fitting']['kropff']['high'] + o_table.set_item_with_float(_row, _col, _entry['a0']) + o_table.set_item_with_float(_row, _col+1, _entry['b0']) + o_table.set_item_with_float(_row, _col+2, _entry['a0_error']) + o_table.set_item_with_float(_row, _col+3, _entry['b0_error']) + + o_table = TableHandler(table_ui=self.table_ui['low_lda']) + _col = 1 + for _row in fitting_input_dictionary['rois'].keys(): + _entry = fitting_input_dictionary['rois'][_row]['fitting']['kropff']['low'] + o_table.set_item_with_float(_row, _col, _entry['ahkl']) + o_table.set_item_with_float(_row, _col+1, _entry['bhkl']) + o_table.set_item_with_float(_row, _col+2, _entry['ahkl_error']) + o_table.set_item_with_float(_row, _col+3, _entry['bhkl_error']) + + o_table = TableHandler(table_ui=self.table_ui['bragg_peak']) + _col = 1 + for _row in fitting_input_dictionary['rois'].keys(): + _entry = fitting_input_dictionary['rois'][_row]['fitting']['kropff']['bragg_peak'] + o_table.set_item_with_float(_row, _col, _entry['ldahkl']) + o_table.set_item_with_float(_row, _col+1, _entry['tau']) + o_table.set_item_with_float(_row, _col+2, _entry['sigma']) + o_table.set_item_with_float(_row, _col+3, _entry['ldahkl_error']) + o_table.set_item_with_float(_row, _col+4, _entry['tau_error']) + o_table.set_item_with_float(_row, _col+5, _entry['sigma_error']) + + def bragg_peak_right_click(self, position=None): + menu = QtGui.QMenu(self.parent) + + selected_rows_submenu = QtGui.QMenu("Selected Rows") + menu.addMenu(selected_rows_submenu) + _fit = selected_rows_submenu.addAction("Fit") + _export = selected_rows_submenu.addAction("Export ...") + + advanced_selection_submenu = QtGui.QMenu("Advanced Rows Selection") + menu.addMenu(advanced_selection_submenu) + _negative_thkl = advanced_selection_submenu.addAction("Where t_hkl < 0") + + action = menu.exec_(QtGui.QCursor.pos()) + + if action == _fit: + self.fit_bragg_peak_selected_rows() + elif action == _export: + self.export_bragg_peak_profile() + elif action == _negative_thkl: + self.select_all_rows_with_negative_thkl() + + QtGui.QGuiApplication.processEvents() # to close QFileDialog + + def fit_bragg_peak_selected_rows(self): + o_gui = GuiUtility(parent=self.parent) + list_rows_selected = o_gui.get_rows_of_table_selected(table_ui=self.parent.ui.bragg_edge_tableWidget) + self.parent.kropff_fit_bragg_peak_region_of_selected_rows(list_row_to_fit=list_rows_selected) + + def export_bragg_peak_profile(self): + working_dir = str(Path(self.parent.working_dir).parent) + _export_folder = QFileDialog.getExistingDirectory(self.parent, + directory=working_dir, + caption="Select Output Folder") + + QtGui.QGuiApplication.processEvents() # to close QFileDialog + + if _export_folder: + + o_gui = GuiUtility(parent=self.parent) + list_row_selected = o_gui.get_rows_of_table_selected(table_ui=self.parent.ui.bragg_edge_tableWidget) + + for row_selected in list_row_selected: + + # make up output file name + name_of_row = o_gui.get_table_str_item(table_ui=self.parent.ui.bragg_edge_tableWidget, + row=row_selected, + column=0) + [x0, y0, width, height] = name_of_row.split("; ") + name_of_row_formatted = "x0{}_y0{}_width{}_height{}".format(x0,y0, width, height) + file_name = "kropff_bragg_peak_profile_{}.txt".format(name_of_row_formatted) + full_file_name = str(Path(_export_folder) / Path(file_name)) + + o_fit = KropffFittingJobHandler(parent=self.parent) + o_fit.prepare(kropff_tooldbox='bragg_peak') + + x_axis = o_fit.xaxis_to_fit + y_axis = o_fit.list_yaxis_to_fit[row_selected] + + a0 = self.parent.fitting_input_dictionary['rois'][row_selected]['fitting']['kropff']['high']['a0'] + b0 = self.parent.fitting_input_dictionary['rois'][row_selected]['fitting']['kropff']['high']['b0'] + ahkl = self.parent.fitting_input_dictionary['rois'][row_selected]['fitting']['kropff']['low']['ahkl'] + bhkl = self.parent.fitting_input_dictionary['rois'][row_selected]['fitting']['kropff']['low']['bhkl'] + + metadata = ["# Bragg peak fitting of row {}".format(row_selected+1)] + metadata.append("# x0: {}".format(x0)) + metadata.append("# y0: {}".format(y0)) + metadata.append("# width: {}".format(width)) + metadata.append("# height: {}".format(height)) + metadata.append("# a0: {}".format(a0)) + metadata.append("# b0: {}".format(b0)) + metadata.append("# ahkl: {}".format(ahkl)) + metadata.append("# bhkl: {}".format(bhkl)) + metadata.append("#") + metadata.append("# lambda (Angstroms), average transmission") + + make_ascii_file_from_2dim_array(metadata=metadata, + col1=x_axis, + col2=y_axis, + output_file_name=full_file_name) + + message = "Exported {} file(s) in {}".format(len(list_row_selected), _export_folder) + self.parent.ui.statusbar.showMessage(message, 15000) # 15s + self.parent.ui.statusbar.setStyleSheet("color: green") + + def select_all_rows_with_negative_thkl(self): + # activate table + self.parent.ui.bragg_edge_tableWidget.setFocus() + + # switch to multi selection mode + self.parent.ui.kropff_bragg_peak_multi_selection.setChecked(True) + self.parent.ui.bragg_edge_tableWidget.setSelectionMode(2) + + list_of_rows_to_select = [] + fitting_input_dictionary_rois = self.parent.fitting_input_dictionary['rois'] + for _row in fitting_input_dictionary_rois.keys(): + _thkl = np.float(fitting_input_dictionary_rois[_row]['fitting']['kropff']['bragg_peak']['ldahkl']) + if _thkl < 0: + list_of_rows_to_select.append(_row) + + o_gui = GuiUtility(parent=self.parent) + o_gui.select_rows_of_table(table_ui=self.parent.ui.bragg_edge_tableWidget, + list_of_rows=list_of_rows_to_select) + + def update_fitting_plot(self): + self.parent.ui.fitting.clear() + o_get = Get(parent=self.parent) + part_of_fitting_dict = o_get.part_of_fitting_selected() + name_of_page = part_of_fitting_dict['name_of_page'] + table_ui = part_of_fitting_dict['table_ui'] + + o_table = TableHandler(table_ui=table_ui) + list_row_selected = o_table.get_rows_of_table_selected() + x_axis_selected = o_get.x_axis_checked() + + if list_row_selected is None: + # first fitting tab where we only display the full data with bragg peak selection + if self.parent.fitting_peak_ui: + self.parent.ui.fitting.removeItem(self.parent.fitting_peak_ui) + xaxis_dict = self.parent.fitting_input_dictionary['xaxis'] + xaxis_index, xaxis_label = xaxis_dict[x_axis_selected] + [left_xaxis_index, right_xaxis_index] = self.parent.bragg_edge_range + xaxis = xaxis_index[left_xaxis_index: right_xaxis_index] + selected_roi = self.parent.fitting_input_dictionary['rois'][0] + yaxis = selected_roi['profile'] + yaxis = yaxis[left_xaxis_index: right_xaxis_index] + yaxis = -np.log(yaxis) + self.parent.ui.fitting.plot(xaxis, yaxis, + pen=(self.parent.selection_roi_rgb[0], + self.parent.selection_roi_rgb[1], + self.parent.selection_roi_rgb[2]), + symbol='o') + self.parent.ui.fitting.setLabel("bottom", xaxis_label) + peak_range_index = self.parent.kropff_fitting_range['bragg_peak'] + if peak_range_index[0] is None: + peak_range = self.parent.bragg_edge_range + else: + peak_range = [xaxis[peak_range_index[0]], xaxis[peak_range_index[1]]] + + if self.parent.fitting_peak_ui: + self.parent.ui.fitting.removeItem(self.parent.fitting_peak_ui) + self.parent.fitting_peak_ui = pg.LinearRegionItem(values=peak_range, + orientation=None, + brush=None, + movable=True, + bounds=None) + self.parent.fitting_peak_ui.sigRegionChanged.connect(self.parent.fitting_range_changed) + self.parent.fitting_peak_ui.setZValue(-10) + self.parent.ui.fitting.addItem(self.parent.fitting_peak_ui) + + else: + + for row_selected in list_row_selected: + + selected_roi = self.parent.fitting_input_dictionary['rois'][row_selected] + + xaxis_dict = self.parent.fitting_input_dictionary['xaxis'] + [left_xaxis_index, right_xaxis_index] = self.parent.bragg_edge_range + + yaxis = selected_roi['profile'] + xaxis_index, xaxis_label = xaxis_dict[x_axis_selected] + + xaxis = xaxis_index[left_xaxis_index: right_xaxis_index] + yaxis = yaxis[left_xaxis_index: right_xaxis_index] + + self.parent.ui.fitting.setLabel("bottom", xaxis_label) + self.parent.ui.fitting.setLabel("left", 'Cross Section (arbitrary units)') + yaxis = -np.log(yaxis) + self.parent.ui.fitting.plot(xaxis, yaxis, + pen=(self.parent.selection_roi_rgb[0], + self.parent.selection_roi_rgb[1], + self.parent.selection_roi_rgb[2]), + symbol='o') + + peak_range_index = self.parent.kropff_fitting_range[name_of_page] + if peak_range_index[0] is None: + peak_range = self.parent.bragg_edge_range + else: + peak_range = [xaxis[peak_range_index[0]], xaxis[peak_range_index[1]]] + + if self.parent.fitting_peak_ui: + self.parent.ui.fitting.removeItem(self.parent.fitting_peak_ui) + self.parent.fitting_peak_ui = pg.LinearRegionItem(values=peak_range, + orientation=None, + brush=None, + movable=False, + bounds=None) + self.parent.fitting_peak_ui.sigRegionChanged.connect(self.parent.fitting_range_changed) + self.parent.fitting_peak_ui.setZValue(-10) + self.parent.ui.fitting.addItem(self.parent.fitting_peak_ui) + + o_gui = GuiUtility(parent=self.parent) + algo_name = o_gui.get_tab_selected(self.parent.ui.tab_algorithm).lower() + + if key_path_exists_in_dictionary(dictionary=self.parent.fitting_input_dictionary, + tree_key=['rois', row_selected, 'fitting', algo_name, + name_of_page, 'xaxis_to_fit']): + + # show fit only if tof scale selected + if x_axis_selected == 'lambda': + _entry = self.parent.fitting_input_dictionary['rois'][row_selected]['fitting'][algo_name][name_of_page] + xaxis = _entry['xaxis_to_fit'] + yaxis = _entry['yaxis_fitted'] + yaxis = -np.log(yaxis) + self.parent.ui.fitting.plot(xaxis, yaxis, + pen=(self.parent.fit_rgb[0], + self.parent.fit_rgb[1], + self.parent.fit_rgb[2])) + + if peak_range_index[0] is None: + self.parent.fitting_range_changed() + + self.parent.ui.fitting.setLabel("left", "Cross Section (arbitrary Units)") + + def update_roi_labels(self): + [global_left_range, global_right_range] = self.parent.bragg_edge_range + [left_range, right_range] = list(self.parent.fitting_peak_ui.getRegion()) + + o_get = Get(parent=self.parent) + x_axis_selected = o_get.x_axis_checked() + xaxis_dict = self.parent.fitting_input_dictionary['xaxis'] + xaxis_index, _ = xaxis_dict[x_axis_selected] + [left_xaxis_index, right_xaxis_index] = [global_left_range, global_right_range] + + xaxis = xaxis_index[left_xaxis_index: right_xaxis_index] + + left_index = find_nearest_index(array=xaxis, value=left_range) + right_index = find_nearest_index(array=xaxis, value=right_range) + + xaxis_in_selected_axis = self.parent.fitting_input_dictionary['xaxis'][x_axis_selected][0][ + global_left_range: global_right_range] + real_left_value = xaxis_in_selected_axis[left_index] + real_right_value = xaxis_in_selected_axis[right_index] + if x_axis_selected == 'lambda': + str_format = "{:02f}" + elif x_axis_selected == 'tof': + str_format = "{:04.2f}" + else: + str_format = "{}" + real_left_value = str_format.format(real_left_value) + real_right_value = str_format.format(real_right_value) + + units = Get.units(name=x_axis_selected) + self.parent.ui.bragg_peak_range_from_value.setText(str(real_left_value)) + self.parent.ui.bragg_peak_range_to_value.setText(str(real_right_value)) + self.parent.ui.from_bragg_peak_range_units.setText(units) + self.parent.ui.to_bragg_peak_range_units.setText(units) \ No newline at end of file diff --git a/notebooks/__code/kropff_fitting_job_handler.py b/notebooks/__code/kropff_fitting_job_handler.py new file mode 100644 index 0000000..925b6b1 --- /dev/null +++ b/notebooks/__code/kropff_fitting_job_handler.py @@ -0,0 +1,188 @@ +from lmfit import Model, Parameter +from copy import deepcopy +import numpy as np + +from __code.bragg_edge.fitting_functions import kropff_high_lambda, kropff_low_lambda, kropff_bragg_peak_tof +from __code.bragg_edge.bragg_edge_peak_fitting_gui_utility import GuiUtility + + +class KropffFittingJobHandler: + """https://lmfit.github.io/lmfit-py/examples/example_Model_interface.html""" + + def __init__(self, parent=None): + self.parent = parent + + self.xaxis_to_fit = None + self.list_yaxis_to_fit = None + + def prepare(self, kropff_tooldbox='high'): + """ + :param kropff_tooldbox: 'high', 'low', 'bragg_peak' + """ + if kropff_tooldbox == 'bragg_peak': + fitting_range = [self.parent.kropff_fitting_range['low'][0], + self.parent.kropff_fitting_range['high'][1]] + else: + fitting_range = self.parent.kropff_fitting_range[kropff_tooldbox] + + xaxis = self.parent.fitting_input_dictionary['xaxis']['lambda'][0] + [left_xaxis_index, right_xaxis_index] = self.parent.bragg_edge_range + full_fitting_xaxis = xaxis[left_xaxis_index: right_xaxis_index] + # self.xaxis_to_fit = full_fitting_xaxis[fitting_range[0]: fitting_range[1] + 1] * 1e-6 # to convert in s + self.xaxis_to_fit = full_fitting_xaxis[fitting_range[0]: fitting_range[1] + 1] + + list_yaxis_to_fit = [] + for _key in self.parent.fitting_input_dictionary['rois'].keys(): + _yaxis = self.parent.fitting_input_dictionary['rois'][_key]['profile'] + full_fitting_yaxis = _yaxis[left_xaxis_index: right_xaxis_index] + list_yaxis_to_fit.append(full_fitting_yaxis[fitting_range[0]: fitting_range[1] + 1]) + self.list_yaxis_to_fit = list_yaxis_to_fit + + def run_kropff_high_lambda(self, update_table_ui=False): + gmodel = Model(kropff_high_lambda, missing='drop', independent_vars=['lda']) + + lda = self.xaxis_to_fit + o_gui = GuiUtility(parent=self.parent) + + a0_init = np.float(str(self.parent.kropff_high_lda_a0_init.text())) + b0_init = np.float(str(self.parent.kropff_high_lda_b0_init.text())) + for _index, yaxis in enumerate(self.list_yaxis_to_fit): + + yaxis = -np.log(yaxis) + _result = gmodel.fit(yaxis, lda=lda, a0=a0_init, b0=b0_init) + a0 = _result.params['a0'].value + a0_error = _result.params['a0'].stderr + b0 = _result.params['b0'].value + b0_error = _result.params['b0'].stderr + + yaxis_fitted = kropff_high_lambda(self.xaxis_to_fit, a0, b0) + + result_dict = {'a0': a0, + 'b0': b0, + 'a0_error': a0_error, + 'b0_error': b0_error, + 'xaxis_to_fit': lda, + 'yaxis_fitted': yaxis_fitted} + + self.parent.fitting_input_dictionary['rois'][_index]['fitting']['kropff']['high'] = deepcopy(result_dict) + + if update_table_ui: + o_gui.update_kropff_high_lambda_table_ui(row=_index, + a0=a0, + b0=b0, + a0_error=a0_error, + b0_error=b0_error) + + def run_kropff_low_lambda(self, update_table_ui=False): + gmodel = Model(kropff_low_lambda, missing='drop', independent_vars=['lda']) + + lda = self.xaxis_to_fit + o_gui = GuiUtility(parent=self.parent) + + ahkl_init = np.float(str(self.parent.kropff_low_lda_ahkl_init.text())) + bhkl_init = np.float(str(self.parent.kropff_low_lda_bhkl_init.text())) + + for _row, yaxis in enumerate(self.list_yaxis_to_fit): + + _entry = self.parent.fitting_input_dictionary['rois'][_row]['fitting']['kropff']['high'] + a0 = np.float(_entry['a0']) + b0 = np.float(_entry['b0']) + + yaxis = -np.log(yaxis) + _result = gmodel.fit(yaxis, lda=lda, + a0=Parameter('a0', value=a0, vary=False), + b0=Parameter('b0', value=b0, vary=False), + ahkl=ahkl_init, + bhkl=bhkl_init) + + ahkl = _result.params['ahkl'].value + ahkl_error = _result.params['ahkl'].stderr + bhkl = _result.params['bhkl'].value + bhkl_error = _result.params['bhkl'].stderr + + yaxis_fitted = kropff_low_lambda(lda, + a0, b0, ahkl, bhkl) + + result_dict = {'ahkl': ahkl, + 'bhkl': bhkl, + 'ahkl_error': ahkl_error, + 'bhkl_error': bhkl_error, + 'xaxis_to_fit': lda, + 'yaxis_fitted': yaxis_fitted} + + self.parent.fitting_input_dictionary['rois'][_row]['fitting']['kropff']['low'] = deepcopy(result_dict) + + if update_table_ui: + o_gui.update_kropff_low_lambda_table_ui(row=_row, + ahkl=ahkl, + bhkl=bhkl, + ahkl_error=ahkl_error, + bhkl_error=bhkl_error) + + def run_bragg_peak(self, update_table_ui=False, list_row_to_fit=None): + gmodel = Model(kropff_bragg_peak_tof, nan_policy='propagate', independent_vars=['lda']) + + lda = self.xaxis_to_fit + o_gui = GuiUtility(parent=self.parent) + + ldahkl_init = np.float(str(self.parent.ui.kropff_bragg_peak_ldahkl_init.text())) + tau_init = np.float(str(self.parent.kropff_bragg_peak_tau_init.text())) + sigma_init = np.float(self.parent.kropff_bragg_peak_sigma_comboBox.currentText()) + + for _row, yaxis in enumerate(self.list_yaxis_to_fit): + + if not list_row_to_fit is None: + if _row not in list_row_to_fit: + continue + + _entry_high = self.parent.fitting_input_dictionary['rois'][_row]['fitting']['kropff']['high'] + a0 = np.float(_entry_high['a0']) + b0 = np.float(_entry_high['b0']) + + _entry_low = self.parent.fitting_input_dictionary['rois'][_row]['fitting']['kropff']['low'] + ahkl = np.float(_entry_low['ahkl']) + bhkl = np.float(_entry_low['bhkl']) + + yaxis = -np.log(yaxis) + + _result = gmodel.fit(yaxis, + lda=lda, + a0=Parameter('a0', value=a0, vary=False), + b0=Parameter('b0', value=b0, vary=False), + ahkl=Parameter('ahkl', value=ahkl, vary=False), + bhkl=Parameter('bhkl', value=bhkl, vary=False), + ldahkl=ldahkl_init, + sigma=sigma_init, + tau=tau_init) + + ldahkl = _result.params['ldahkl'].value + ldahkl_error = _result.params['ldahkl'].stderr + sigma = _result.params['sigma'].value + sigma_error = _result.params['sigma'].stderr + tau = _result.params['tau'].value + tau_error = _result.params['tau'].stderr + + yaxis_fitted = kropff_bragg_peak_tof(self.xaxis_to_fit, + a0, b0, ahkl, bhkl, + ldahkl, sigma, tau) + + result_dict = {'ldahkl': ldahkl, + 'ldahkl_error': ldahkl_error, + 'sigma': sigma, + 'sigma_error': sigma_error, + 'tau': tau, + 'tau_error': tau_error, + 'xaxis_to_fit': lda, + 'yaxis_fitted': yaxis_fitted} + + self.parent.fitting_input_dictionary['rois'][_row]['fitting']['kropff']['bragg_peak'] = deepcopy( + result_dict) + + if update_table_ui: + o_gui.update_kropff_bragg_edge_table_ui(row=_row, + ldahkl=ldahkl, + ldahkl_error=ldahkl_error, + tau=tau, + tau_error=tau_error, + sigma=sigma, + sigma_error=sigma_error) diff --git a/notebooks/__code/peak_fitting_initialization.py b/notebooks/__code/peak_fitting_initialization.py new file mode 100644 index 0000000..3876664 --- /dev/null +++ b/notebooks/__code/peak_fitting_initialization.py @@ -0,0 +1,65 @@ +import numpy as np +from copy import deepcopy + +KROPFF_HIGH = {'a0': None, 'b0': None, + 'a0_error': None, 'b0_error': None, + 'xaxis_to_fit': None, + 'yaxis_fitted': None} +KROPFF_LOW = {'ahkl': None, 'bhkl': None, + 'ahkl_error': None, 'bhkl_error': None, + 'xaxis_to_fit': None, + 'yaxis_fitted': None} +KROPFF_BRAGG_PEAK = {'ldahkl': None, + 'ldahkl_error': None, + 'tau': None, + 'tau_error': None, + 'sigma': None, + 'sigma_error': None} +MARCHE_DOLLASE = {'d_spacing': None, + 'd_spacing_error': None, + 'alpha': None, + 'alpha_error': None, + 'sigma': None, + 'sigma_error': None, + 'a1': None, + 'a1_error': None, + 'a2': None, + 'a2_error': None, + 'a5': None, + 'a5_error': None, + 'a6': None, + 'a6_error': None, + } + + +class PeakFittingInitialization: + + def __init__(self, parent=None): + self.parent = parent + + def fitting_input_dictionary(self, nbr_rois=0): + + fitting_input_dictionary = {'xaxis': {}, + 'rois': {}, + 'fit_infos': {}} + + for _roi_index in np.arange(nbr_rois): + _roi_dict = {'x0': None, 'y0': None, + 'width': None, 'height': None, + 'profile': None, + 'bragg_edge_range': None, # bragg peak range selected in first tab + 'fitting': {'kropff': {'high': deepcopy(KROPFF_HIGH), + 'low': deepcopy(KROPFF_LOW), + 'bragg_peak': deepcopy(KROPFF_BRAGG_PEAK), + }, + 'march_dollase': deepcopy(MARCHE_DOLLASE), + }, + } + fitting_input_dictionary['rois'][_roi_index] = deepcopy(_roi_dict) + + return fitting_input_dictionary + + def set_top_keys_values(self, dictionary=None, new_keys_values=None): + for _key in new_keys_values.keys(): + _value = new_keys_values[_key] + dictionary[_key] = _value diff --git a/notebooks/__code/peak_fitting_interface_initialization.py b/notebooks/__code/peak_fitting_interface_initialization.py new file mode 100644 index 0000000..99167bc --- /dev/null +++ b/notebooks/__code/peak_fitting_interface_initialization.py @@ -0,0 +1,274 @@ +import numpy as np +import matplotlib +import os +import copy +matplotlib.use('Qt5Agg') + +from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar + +from qtpy.QtWidgets import QProgressBar, QVBoxLayout +from qtpy import QtGui +import pyqtgraph as pg + +from __code.table_handler import TableHandler +from __code.bragg_edge.mplcanvas import MplCanvas +from __code.bragg_edge.bragg_edge_peak_fitting_gui_utility import GuiUtility + + +class Initialization: + + distance_detector_sample = 1300 # m + detector_offset = 6500 # micros + + march_dollase_history_state = list() + march_dollase_history_init = [np.NaN, np.NaN] + march_dollase_history_state.append([False, False, False, True, False, False, True]) + march_dollase_history_state.append([False, False, False, False, True, True, False]) + march_dollase_history_state.append([True, True, True, False, False, False, False]) + march_dollase_history_state.append([False, False, False, True, True, True, True]) + march_dollase_history_state.append([True, True, True, False, False, False, False]) + march_dollase_history_state.append([True, True, True, True, True, True, True]) + + def __init__(self, parent=None, tab='all'): + self.parent = parent + + self.block_signals(True) + self.pyqtgraph_image_view() + self.pyqtgraph_profile() + self.matplotlib() + + if tab == 'all': + self.normalize_images_by_white_beam() + self.save_image_size() + self.roi_setup() + self.widgets() + + self.labels() + self.text_fields() + self.statusbar() + self.pyqtgraph_fitting() + self.kropff_fitting_table() + self.march_dollase() + + self.block_signals(False) + + def normalize_images_by_white_beam(self): + white_beam_ob = self.parent.o_bragg.white_beam_ob + list_data = self.parent.o_norm.data['sample']['data'] + for _index_data, _data in enumerate(list_data): + normalized_data = _data / white_beam_ob + self.parent.o_norm.data['sample']['data'][_index_data] = normalized_data + + def block_signals(self, flag): + list_ui = [self.parent.ui.profile_of_bin_size_slider] + for _ui in list_ui: + _ui.blockSignals(flag) + + def save_image_size(self): + _image = self.parent.get_live_image() + [height, width] = np.shape(_image) + self.parent.image_size['width'] = width + self.parent.image_size['height'] = height + + def statusbar(self): + self.parent.eventProgress = QProgressBar(self.parent.ui.statusbar) + self.parent.eventProgress.setMinimumSize(20, 14) + self.parent.eventProgress.setMaximumSize(540, 100) + self.parent.eventProgress.setVisible(False) + self.parent.ui.statusbar.addPermanentWidget(self.parent.eventProgress) + + def pyqtgraph_image_view(self): + # image view + self.parent.ui.image_view = pg.ImageView() + self.parent.ui.image_view.ui.roiBtn.hide() + self.parent.ui.image_view.ui.menuBtn.hide() + image_layout = QVBoxLayout() + image_layout.addWidget(self.parent.ui.image_view) + self.parent.ui.image_widget.setLayout(image_layout) + + def pyqtgraph_profile(self): + # profile view + self.parent.ui.profile = pg.PlotWidget(title="Profile of ROI selected") + profile_layout = QVBoxLayout() + profile_layout.addWidget(self.parent.ui.profile) + self.parent.ui.profile_widget.setLayout(profile_layout) + + def matplotlib(self): + + def _matplotlib(parent=None, widget=None): + sc = MplCanvas(parent, width=5, height=4, dpi=100) + # sc.axes.plot([0,1,2,3,4,5], [10, 1, 20 ,3, 40, 50]) + toolbar = NavigationToolbar(sc, parent) + layout = QVBoxLayout() + layout.addWidget(toolbar) + layout.addWidget(sc) + widget.setLayout(layout) + return sc + + self.parent.kropff_high_plot = _matplotlib(parent=self.parent, + widget=self.parent.ui.high_widget) + self.parent.kropff_low_plot = _matplotlib(parent=self.parent, + widget=self.parent.ui.low_widget) + self.parent.kropff_bragg_peak_plot = _matplotlib(parent=self.parent, + widget=self.parent.ui.bragg_peak_widget) + + self.parent.march_dollase_plot = _matplotlib(parent=self.parent, + widget=self.parent.ui.march_dollase_graph_widget) + + def pyqtgraph_fitting(self): + # fitting view + self.parent.ui.fitting = pg.PlotWidget(title="Fitting") + fitting_layout = QVBoxLayout() + fitting_layout.addWidget(self.parent.ui.fitting) + self.parent.ui.fitting_widget.setLayout(fitting_layout) + + def kropff_fitting_table(self): + ## Kropff + # high lambda + column_names = [u'x\u2080; y\u2080; width; height', u'a\u2080', u'b\u2080', u'a\u2080_error', + u'b\u2080_error'] + column_sizes = [150, 100, 100, 100, 100] + o_high = TableHandler(table_ui=self.parent.ui.high_lda_tableWidget) + for _col_index, _col_name in enumerate(column_names): + o_high.insert_column(_col_index) + o_high.set_column_names(column_names=column_names) + o_high.set_column_sizes(column_sizes=column_sizes) + + # low lambda + column_names = [u'x\u2080; y\u2080; width; height', + u'a_hkl', u'b_hkl', + u'a_hkl_error', + u'b_hkl_error'] + column_sizes = [150, 100, 100, 100, 100] + o_low = TableHandler(table_ui=self.parent.ui.low_lda_tableWidget) + for _col_index, _col_name in enumerate(column_names): + o_low.insert_column(_col_index) + o_low.set_column_names(column_names=column_names) + o_low.set_column_sizes(column_sizes=column_sizes) + + # bragg edge + column_names = ['x0; y0; width; height', 't_hkl', 'tau', 'sigma', + 't_hkl_error', 'tau_error', 'sigma_error'] + column_sizes = [150, 100, 100, 100, 100, 100, 100] + o_bragg = TableHandler(table_ui=self.parent.ui.bragg_edge_tableWidget) + for _col_index, _col_name in enumerate(column_names): + o_bragg.insert_column(_col_index) + o_bragg.set_column_names(column_names=column_names) + o_bragg.set_column_sizes(column_sizes=column_sizes) + + def march_dollase(self): + + self.parent.march_dollase_history_state_full_reset = copy.deepcopy(self.march_dollase_history_state) + + # init widgets + _file_path = os.path.dirname(__file__) + up_arrow_file = os.path.abspath(os.path.join(_file_path, '../static/up_arrow_black.png')) + self.parent.ui.march_dollase_user_input_up.setIcon(QtGui.QIcon(up_arrow_file)) + + down_arrow_file = os.path.abspath(os.path.join(_file_path, '../static/down_arrow_black.png')) + self.parent.ui.march_dollase_user_input_down.setIcon(QtGui.QIcon(down_arrow_file)) + + o_gui = GuiUtility(parent=self.parent) + o_gui.fill_march_dollase_table(list_state=self.march_dollase_history_state, + initial_parameters=self.parent.march_dollase_fitting_initial_parameters) + + self.parent.march_dollase_fitting_history_table = self.march_dollase_history_state + self.parent.march_dollase_fitting_history_table_default_new_row = copy.deepcopy( + self.march_dollase_history_state[0]) + + column_names = [u'x\u2080; y\u2080; width; height', + u'd_spacing', u'sigma', u'alpha', + u'A\u2081', u'A\u2082', + u'A\u2085', u'A\u2086', + u'd_spacing_error', u'sigma_error', u'alpha_error', + u'A\u2081_error', + u'A\u2082_error', + u'A\u2085_error', u'A\u2086_error', + ] + column_sizes = [150, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100] + o_march = TableHandler(table_ui=self.parent.ui.march_dollase_result_table) + for _col_index, _col_name in enumerate(column_names): + o_march.insert_column(_col_index) + o_march.set_column_names(column_names=column_names) + o_march.set_column_sizes(column_sizes=column_sizes) + + state_advanced_columns = not self.parent.ui.march_dollase_advanced_mode_checkBox.isChecked() + o_gui.set_columns_hidden(table_ui=self.parent.ui.march_dollase_user_input_table, + list_of_columns=[5, 6], + state=state_advanced_columns) + + # table + self.parent.ui.march_dollase_user_input_table.verticalHeader().setVisible(True) + self.parent.ui.march_dollase_result_table.verticalHeader().setVisible(True) + self.parent.ui.march_dollase_result_table.horizontalHeader().setVisible(True) + + def labels(self): + # labels + self.parent.ui.detector_offset_units.setText(u"\u03BCs") + self.parent.ui.selection_tof_radiobutton.setText(u"TOF (\u03BCs)") + self.parent.ui.fitting_tof_radiobutton.setText(u"TOF (\u03BCs)") + self.parent.ui.selection_lambda_radiobutton.setText(u"\u03BB (\u212B)") + self.parent.ui.fitting_lambda_radiobutton.setText(u"\u03BB (\u212B)") + + def text_fields(self): + self.parent.ui.distance_detector_sample.setText(str(self.distance_detector_sample)) + self.parent.ui.detector_offset.setText(str(self.detector_offset)) + + self.parent.ui.kropff_high_lda_a0_init.setText(str(self.parent.fitting_parameters_init['kropff']['a0'])) + self.parent.ui.kropff_high_lda_b0_init.setText(str(self.parent.fitting_parameters_init['kropff']['b0'])) + self.parent.ui.kropff_low_lda_ahkl_init.setText(str(self.parent.fitting_parameters_init['kropff']['ahkl'])) + self.parent.ui.kropff_low_lda_bhkl_init.setText(str(self.parent.fitting_parameters_init['kropff']['bhkl'])) + self.parent.ui.kropff_bragg_peak_ldahkl_init.setText(str(self.parent.fitting_parameters_init['kropff'][ + 'ldahkl'])) + self.parent.ui.kropff_bragg_peak_tau_init.setText(str(self.parent.fitting_parameters_init['kropff']['tau'])) + # list_sigma = self.parent.fitting_parameters_init['kropff']['sigma'] + # list_sigma = [str(_value) for _value in list_sigma] + # str_list_sigma = ", ".join(list_sigma) + # self.parent.ui.kropff_bragg_peak_sigma_init.setText(str_list_sigma) + + kropff_list_sigma = self.parent.fitting_parameters_init['kropff']['sigma'] + str_kropff_list_sigma = [str(value) for value in kropff_list_sigma] + self.parent.ui.kropff_bragg_peak_sigma_comboBox.addItems(str_kropff_list_sigma) + + def widgets(self): + self.parent.ui.splitter.setSizes([500, 400]) + + self.parent.ui.roi_size_slider.setMinimum(1) + max_value = np.min([self.parent.image_size['width'], self.parent.image_size['height']]) + self.parent.ui.roi_size_slider.setMaximum(max_value) + default_roi_size = np.int(max_value/3) + self.parent.ui.roi_size_slider.setValue(default_roi_size) + self.parent.ui.roi_width.setText(str(default_roi_size)) + self.parent.ui.roi_height.setText(str(default_roi_size)) + self.parent.ui.profile_of_bin_size_width.setText(str(default_roi_size)) + self.parent.ui.profile_of_bin_size_height.setText(str(default_roi_size)) + self.parent.ui.profile_of_bin_size_slider.setMaximum(default_roi_size) + self.parent.ui.profile_of_bin_size_slider.setValue(default_roi_size) + + def roi_setup(self): + [x0, y0] = self.parent.roi_settings['position'] + self.parent.selection_x0y0 = [x0, y0] + width = self.parent.ui.roi_size_slider.value() + self.parent.previous_roi_selection['width'] = width + self.parent.previous_roi_selection['height'] = width + _pen = QtGui.QPen() + _pen.setColor(self.parent.roi_settings['color']) + _pen.setWidth(self.parent.roi_settings['width']) + self.parent.roi_id = pg.ROI([x0, y0], + [width, width], + pen=_pen, + scaleSnap=True) + self.parent.ui.image_view.addItem(self.parent.roi_id) + self.parent.roi_id.sigRegionChanged.connect(self.parent.roi_moved) + + def display(self, image=None): + self.parent.live_image = image + _image = np.transpose(image) + _image = self._clean_image(_image) + self.parent.ui.image_view.setImage(_image) + + def _clean_image(self, image): + _result_inf = np.where(np.isinf(image)) + image[_result_inf] = np.NaN + return image diff --git a/notebooks/__code/table_handler.py b/notebooks/__code/table_handler.py new file mode 100644 index 0000000..ef5b67c --- /dev/null +++ b/notebooks/__code/table_handler.py @@ -0,0 +1,138 @@ +import numpy as np +from qtpy import QtGui + +class TableHandler: + + cell_str_format = "{:.3f}" + cell_str_format = "{}" + + def __init__(self, table_ui=None): + self.table_ui = table_ui + + def select_everything(self, state): + nbr_row = self.table_ui.rowCount() + nbr_column = self.table_ui.columnCount() + selection_range = QtGui.QTableWidgetSelectionRange(0, 0, nbr_row-1, nbr_column-1) + self.table_ui.setRangeSelected(selection_range, state) + + def select_rows(self, list_of_rows=None): + self.select_everything(False) + nbr_row = self.table_ui.rowCount() + nbr_column = self.table_ui.columnCount() + + for _row in list_of_rows: + selection_range = QtGui.QTableWidgetSelectionRange(_row, 0, _row, nbr_column - 1) + self.table_ui.setRangeSelected(selection_range, True) + + def remove_all_rows(self): + nbr_row = self.table_ui.rowCount() + for _ in np.arange(nbr_row): + self.table_ui.removeRow(0) + + def remove_all_columns(self): + nbr_column = self.table_ui.columnCount() + for _ in np.arange(nbr_column): + self.table_ui.removeColumn(0) + + def full_reset(self): + self.remove_all_rows() + self.remove_all_columns() + + def get_rows_of_table_selected(self): + if self.table_ui is None: + return None + + selected_ranges = self.table_ui.selectedRanges() + if selected_ranges == []: + return None + + list_row_selected = [] + for _selection in selected_ranges: + top_row = _selection.topRow() + bottom_row = _selection.bottomRow() + if top_row == bottom_row: + list_row_selected.append(top_row) + else: + _range = np.arange(top_row, bottom_row + 1) + for _row in _range: + list_row_selected.append(_row) + + return list_row_selected + + def get_row_selected(self): + if self.table_ui is None: + return -1 + list_selection = self.table_ui.selectedRanges() + try: + first_selection = list_selection[0] + except IndexError: + return -1 + return first_selection.topRow() + + def get_cell_selected(self): + list_selection = self.table_ui.selectedRanges() + first_selection = list_selection[0] + row = first_selection.topRow() + col = first_selection.leftColumn() + return (row, col) + + def select_cell(self, row=0, column=0): + self.select_everything(False) + range_selected = QtGui.QTableWidgetSelectionRange(row, column, row, column) + self.table_ui.setRangeSelected(range_selected, True) + + def select_row(self, row=0): + if row < 0: + row = 0 + self.table_ui.selectRow(row) + + def set_column_names(self, column_names=None): + self.table_ui.setHorizontalHeaderLabels(column_names) + + def set_row_names(self, row_names=None): + self.table_ui.setVerticalHeaderLabels(row_names) + + def set_column_sizes(self, column_sizes=None): + for _col, _size in enumerate(column_sizes): + self.table_ui.setColumnWidth(_col, _size) + + def insert_empty_row(self, row=0): + self.table_ui.insertRow(row) + + def insert_row(self, row=0, list_col_name=None): + """row is the row number + """ + self.table_ui.insertRow(row) + for column, _text in enumerate(list_col_name): + _item = QtGui.QTableWidgetItem(_text) + self.table_ui.setItem(row, column, _item) + + def insert_column(self, column): + self.table_ui.insertColumn(column) + + def insert_empty_column(self, column): + self.table_ui.insertColumn(column) + + def set_item_with_float(self, row=0, column=0, float_value=""): + if (str(float_value) == 'None') or (str(float_value) == 'N/A'): + _str_value = "N/A" + else: + _str_value = self.cell_str_format.format(np.float(float_value)) + self.table_ui.item(row, column).setText(_str_value) + + def insert_item_with_float(self, row=0, column=0, float_value="", format_str="{}"): + if (str(float_value) == 'None') or (str(float_value) == 'N/A'): + _str_value = "N/A" + else: + _str_value = format_str.format(np.float(float_value)) + _item = QtGui.QTableWidgetItem(_str_value) + self.table_ui.setItem(row, column, _item) + + def insert_item(self, row=0, column=0, value="", format_str="{}"): + _str_value = format_str.format(value) + _item = QtGui.QTableWidgetItem(_str_value) + self.table_ui.setItem(row, column, _item) + + def set_background_color(self, row=0, column=0, qcolor=QtGui.QColor(0, 255, 255)): + _item = self.table_ui.item(row, column) + _item.setBackground(qcolor) diff --git a/notebooks/__code/utilities.py b/notebooks/__code/utilities.py new file mode 100644 index 0000000..ac2be54 --- /dev/null +++ b/notebooks/__code/utilities.py @@ -0,0 +1,387 @@ +import numpy as np +import os +import re +import shutil +from configparser import RawConfigParser +#import glob +import itertools +from shutil import copyfile + +#from ipywidgets.widgets import interact +from ipywidgets import widgets +from IPython.core.display import display, HTML + + +def calculate_file_temperature(left_T=-1, right_T=-1, left_time=-1, right_time=-1, file_time = -1): + coeff = (float(right_T) - float(left_T)) / (float(right_time) - float(left_time)) + part1 = coeff * (float(file_time) - float(left_time)) + return part1 + float(left_T) + + +def get_first_temperature_and_index_value(index=-1, data_array=[], direction='left'): + if direction == 'left': + coeff = -1 + else: + coeff = 1 + + while (np.isnan(data_array[index])): + index += coeff + return [data_array[index], index] + + +def extract_temperature(index=-1, temperature_array=[], time_stamp_array=[]): + + [left_T, left_index] = get_first_temperature_and_index_value(index=index, data_array=temperature_array, direction='left') + [right_T, right_index] = get_first_temperature_and_index_value(index=index, data_array=temperature_array, direction='right') + + left_time = time_stamp_array[left_index] + right_time = time_stamp_array[right_index] + + file_time = time_stamp_array[index] + + file_temperature = calculate_file_temperature(left_T = left_T, right_T = right_T, + left_time = left_time, right_time = right_time, + file_time = file_time) + + return file_temperature + + +def retrieve_T_from_file_vs_temperature_array(file_name='', file_array=[], temperature_array=[]): + index = file_array.index(file_name) + return temperature_array[index] + + +def make_output_file_name(bin_number=-1, index=-1, algorithm='mean'): + ''' + takes the bin number and the algorithm name to create the output file name + + Paramters: + * bin_number: index of bin + * index: index of file in folder + * algorithm: (optional) default value 'mean'. Name of algorithm used to bin data + will be used in the new output file name + + Return: + * string file name of the output file + + Example: + bin_number = 3 + index = 2 + algorithm = "mean" + + will return 'bin#3_0002_mean.fits + + ''' + + ext = '.fits' + list_output_file_name = [] + _output_file_name = "bin#{:03d}_{:04d}_{}.fits".format(bin_number, index, algorithm) + return _output_file_name + + +def keep_folder_name(image): + image_array = image.split('_') + return image_array[0] + + +def is_extension(filename='', ext='.fits'): + _ext = os.path.splitext(filename)[1] + if _ext == ext: + return True + else: + return False + + +def index_first_boolean(result, boolean=True): + for _index, _value in enumerate(result): + if _value == boolean: + return _index + + +def index_last_boolean(result, boolean=True): + for _index, _value in reversed(list(enumerate(result))): + if _value == boolean: + return _index + + +def find_index_of_value_in_array(array=[], value=-1, index_type='le'): + ''' + index_type is either 'le' or 'ge' + ''' + if index_type == 'le': + result = x_axis < value + return index_first_boolean(result, False) + else: + result = x_axis > value + return index_last_boolean(result, False) + + +def make_user_friendly_list_of_bins(full_list_of_bins): + return [os.path.basename(_file) for _file in full_list_of_bins] + + +def get_ipts(): + current_folder = os.getcwd() + parent_folder = os.path.basename(current_folder) + + result = re.search('IPTS_(\d+)', parent_folder) + if result: + ipts = result.group(1) + else: + ipts = '' + + return ipts + + +def get_working_dir(ipts='', debugging=False): + ''' + if there is an ipts argument passed in, the working dir will be '/HFIR/CG1DImaging/IPTS-{}'.format(ipts) + if ipts is empty: program will look if there is a 'working_dir' argument in the 'main_session' of the config file + '~/.notebooks_config.cfg', otherwise will return the current folder location + ''' + if ipts: + if debugging: + _path = '/Volumes/my_book_thunderbolt_duo/IPTS/IPTS_{}'.format(ipts) + else: + _path = '/HFIR/CG1DImaging/IPTS-{}/'.format(ipts) + print(_path) + if os.path.exists(_path): + return _path + + config_path = os.path.join(os.path.expanduser('~/'), '.notebooks_config.cfg') + if os.path.exists(config_path): + parser = RawConfigParser() + parser.read(config_path) + try: + working_dir = parser.get('main_session', 'working_dir') + except: + working_dir = './' + else: + working_dir = './' + + return working_dir + + +def make_dir(dir='', overwrite=True): + if dir== '': + return + + if overwrite: + if os.path.exists(dir): + shutil.rmtree(dir) + os.mkdir(dir) + else: + if not (os.path.exists(dir)): + os.mkdir(dir) + + +def format_file_index(filename='', number_of_digits=4): + ''' + This function take a file name that may look like this /Users/my_user/folder/description_1.tif + and will format it to make sure the prefix has a fix number of digit. If number of digit is 4, + the file name will be now /Users/my_user/folder/description_0001.tif + + Parameters: + =========== + filename: string. name of file + number_of_digits: default is 4. int. number of digit to add to number at the end + + Returns: + ======== + new file name formatted + ''' + _basename = os.path.basename(filename) + [_base, _ext] = os.path.splitext(_basename) + _base_slitted = _base.split('_') + _number = np.int(_base_slitted[-1]) + + return '' + + +def get_n_random_element(input_list=[], n=1): + ''' + will return a list of n element taken from the input array called input_list + ''' + n_random = np.random.randint(0, len(input_list)-1, n) + new_list = [input_list[_index] for _index in n_random] + return new_list + + +def rename_files(dict_old_new_names={}, new_output_folder=''): + make_dir(dir=new_output_folder) + + nbr_files = len(dict_old_new_names.keys()) + w1 = widgets.IntProgress() + w1.max = nbr_files + display(w1) + + # create new images + for _index, _old_name in enumerate(dict_old_new_names.keys()): + _new_name = os.path.join(new_output_folder, dict_old_new_names[_old_name]) + os.rename(_old_name, _new_name) + w1.value = _index + 1 + + +def copy_files(dict_old_new_names={}, new_output_folder='', overwrite=True): + make_dir(dir=new_output_folder, overwrite=overwrite) + + nbr_files = len(dict_old_new_names.keys()) + w1 = widgets.IntProgress() + w1.max = nbr_files + display(w1) + + # create new images + for _index, _old_name in enumerate(dict_old_new_names.keys()): + _new_name = os.path.join(new_output_folder, dict_old_new_names[_old_name]) + copyfile(_old_name, _new_name) + w1.value = _index + 1 + + +def display_html_message(*, title_message='', message='', message_type='info'): + + if message_type == 'info': + line_color = 'blue' + message_color = 'black' + + elif message_type == 'error': + line_color = 'red' + message_color = 'red' + + elif message_type == 'ok': + line_color = 'green' + message_color = 'black' + + else: + line_color = 'black' + message_color = 'black' + + display(HTML('{} '.format(line_color, + title_message) + + ' '.format(message_color) + + message + '')) + +def find_nearest_index(array, value): + idx = (np.abs(np.array(array) - value)).argmin() + return idx + + +class ListRunsParser(object): + """ + will clean up the current_list_of_runs with the new added runs + ex: [1,2,3,4,7] -> 1:4,7 + if a new run is already in the list of runs, it will then be removed from the list + ex: [1,2,3,4] with new run [1] -> 2:4 + """ + + list_current_runs = [] # ['1','10','2','30','4'] + int_list_current_runs = [] # [1, 2, 4, 10, 30] + + def __init__(self, current_runs=''): + if current_runs: + self.make_discrete_list_of_runs(str_current_runs=current_runs) + + def make_discrete_list_of_runs(self, str_current_runs=''): + spans = (el.partition(':')[::2] for el in str_current_runs.split(',')) + ranges = (np.arange(int(s), int(e) + 1 if e else int(s) + 1) + for s, e in spans) + try: + all_nums = itertools.chain.from_iterable(ranges) + _all_nums = set(all_nums) + except ValueError: + raise ValueError("Check format of input") + self.list_current_runs = [str(_run) for _run in _all_nums] + + def new_runs(self, list_runs=[]): + """add new runs, remove already existing ones""" + + # find list of runs to remove + list_runs = set(list_runs) + _list_runs_to_remove = set(list_runs.intersection(self.list_current_runs)) + + # remove the runs from list_runs and list_current_runs + clean_list_runs = list(list_runs - _list_runs_to_remove) + clean_list_current_runs = list(set(self.list_current_runs) - _list_runs_to_remove) + + new_list_current_runs = clean_list_runs + clean_list_current_runs + self.list_current_runs = new_list_current_runs + + # go from string to int + int_new_list_current_runs = [np.int(_run) for _run in new_list_current_runs] + + # sort them to prepare them for output format + int_new_list_current_runs.sort() + self.int_list_current_runs = int_new_list_current_runs + + if int_new_list_current_runs == []: + self.str_list_current_runs = "" + return + + # create output string format + + # only 1 run + if len(int_new_list_current_runs) == 1: + self.str_list_current_runs = str(int_new_list_current_runs[0]) + return str(int_new_list_current_runs[0]) + + # more than 1 run + + # create full matching list + def match_list(reference_list=[], our_list=[]): + _index = 0 + _ref_list_and_our_list = zip(our_list, reference_list) + for _ref_run, _our_run in _ref_list_and_our_list: + if _ref_run == _our_run: + _index += 1 + continue + break + + return _index + + _index = 0 + _groups = [] + _our_list = self.int_list_current_runs[_index: ] + _list_full_reference = np.arange(_our_list[0], _our_list[-1]+1) + + # print("new list: {}".format(_our_list)) + + while _our_list: + + _ref_index = match_list(reference_list=_list_full_reference, + our_list=_our_list) + + _group = [_our_list[0], _our_list[_ref_index-1]] + # print("_group: {}".format(_group)) + _groups.append(_group) + + _our_list = _our_list[_ref_index:] + if len(_our_list) == 1: + _groups.append(_our_list) + break + + if len(_our_list) == 0: + break + + _list_full_reference = np.arange(_our_list[0], _our_list[-1]+1) + + # print("_groups: {}".format(_groups)) + + list_runs = [] + for _group in _groups: + + if len(_group) == 2: + [_left_value, _right_value] = _group + + if _left_value == _right_value: + list_runs.append(str(_left_value)) + elif _right_value == (_left_value + 1): + list_runs.append(str(_left_value)) + list_runs.append(str(_right_value)) + else: + list_runs.append("{}:{}".format(_left_value, _right_value)) + + else: + list_runs.append(str(_group[0])) + + str_runs = ",".join(list_runs) + # print(str_runs) + return str_runs diff --git a/notebooks/bragg_edge_peak_fitting.ipynb b/notebooks/bragg_edge_peak_fitting.ipynb new file mode 100644 index 0000000..862a303 --- /dev/null +++ b/notebooks/bragg_edge_peak_fitting.ipynb @@ -0,0 +1,288 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": false, + "read_only": false + } + }, + "source": [ + "[![Notebook Tutorial](__code/__all/notebook_tutorial.png)](https://neutronimaging.pages.ornl.gov/tutorial/notebooks/bragg_edge_peak_fitting/#activate-search)\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": false, + "read_only": false + } + }, + "source": [ + "# Select Your IPTS " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "run_control": { + "frozen": false, + "read_only": false + } + }, + "outputs": [], + "source": [ + "from __code import system\n", + "from __code.bragg_edge.bragg_edge_peak_fitting import BraggEdge, Interface\n", + "\n", + "system.System.select_working_dir(facility='SNS', instrument='VENUS')\n", + "from __code.__all import custom_style\n", + "custom_style.style()\n", + "\n", + "from plotly.offline import plot, init_notebook_mode, iplot\n", + "init_notebook_mode()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Prepare UI engine " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "run_control": { + "frozen": false, + "read_only": false + } + }, + "outputs": [], + "source": [ + "%gui qt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "run_control": { + "frozen": false, + "read_only": false + } + }, + "source": [ + "# Select Normalized Data Input Folder\n", + "\n", + "Data and time spectra files will be loaded" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "run_control": { + "frozen": false, + "read_only": false + } + }, + "outputs": [], + "source": [ + "o_bragg = BraggEdge(working_dir=system.System.get_working_dir())\n", + "o_bragg.select_working_folder()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Select Open Beam Data Input folder " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "jupyter": { + "outputs_hidden": true + } + }, + "outputs": [], + "source": [ + "o_bragg.select_ob_folder()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Select sample region and peak to fit" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Select how many random files to use to select region to fit" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "o_bragg.how_many_data_to_use_to_select_sample_roi()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### fit ui " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "o_interface = Interface(o_bragg=o_bragg, spectra_file=o_bragg.spectra_file)\n", + "o_interface.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# DEBUGGING" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from __code import system\n", + "from __code.bragg_edge.bragg_edge_peak_fitting import BraggEdge, Interface" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%gui qt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "data_path = \"/Users/j35/IPTS/VENUS/shared/testing_normalized/\"\n", + "import glob\n", + "import os\n", + "list_data = glob.glob(data_path + \"*.tif\")\n", + "spectra_file = os.path.join(data_path, \"Image019_Spectra.txt\")\n", + "assert os.path.exists(spectra_file)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "o_bragg = BraggEdge(working_dir=data_path)\n", + "o_bragg.load_data(data_path)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "o_interface = Interface(o_bragg=o_bragg,\n", + " working_dir=data_path,\n", + " spectra_file=spectra_file)\n", + "o_interface.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# DEBUGGING using import straight " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from __code import system\n", + "from __code.bragg_edge.bragg_edge_peak_fitting import BraggEdge, Interface" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%gui qt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "data_path = \"/Users/j35/IPTS/SNAP/Si_normalized\"\n", + "o_interface = Interface(working_dir=data_path)\n", + "o_interface.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}