diff --git a/Data/Calibration.py b/Data/Calibration.py new file mode 100644 index 0000000..d14a1c2 --- /dev/null +++ b/Data/Calibration.py @@ -0,0 +1,81 @@ +class CalCurve(): + + def __init__(self): + self.name = "None" + self.formula = "y=x" + + def __call__(self, x): + return x + + def __str__(self): + return self.name + + +class AlSi7Mg(CalCurve): + + def __init__(self): + self.name = "AlSi7Mg" + self.formula = "N/A" + + def __call__(self, x): + return x + + +class Al6061(CalCurve): + + def __init__(self): + self.name = "Al6061" + self.formula = "T=(V+84.66)/1.45" + + def __call__(self, x): + return (x + 84.661) / 1.4516 + + +class _15_5PH(CalCurve): + + def __init__(self): + self.name = "15-5PH Stainless Steel" + self.formula = "N/A" + + def __call__(self, x): + return x + + +class H13(CalCurve): + + def __init__(self): + self.name = "H13 Tool Steel" + self.formula = "N/A" + + def __call__(self, x): + return x + + +class Inconel625(CalCurve): + + def __init__(self): + self.name = "Inconel 625" + self.formula = "N/A" + + def __call__(self, x): + return x + + +class Inconel718(CalCurve): + + def __init__(self): + self.name = "Inconel 718" + self.formula = "N/A" + + def __call__(self, x): + return x + + +class Custom(CalCurve): + + def __init__(self): + self.name = "Custom" + self.formula = "y=mx+c" + + def __call__(self, x): + return x diff --git a/Data/ThresholdFunctions.py b/Data/ThresholdFunctions.py new file mode 100644 index 0000000..5cf91be --- /dev/null +++ b/Data/ThresholdFunctions.py @@ -0,0 +1,64 @@ +import operator as __op + + +class __Base(): + + def __init__(self): + self.name = "None" + + def __str__(self): + return self.name + + +class Greater(__Base): + + def __init__(self): + self.name = ">" + + def __call__(self, *args): + return __op.gt(*args) + + +class GreaterOrEqual(__Base): + + def __init__(self): + self.name = "≥" + + def __call__(self, *args): + return __op.ge(*args) + + +class Equal(__Base): + + def __init__(self): + self.name = "=" + + def __call__(self, *args): + return __op.eq(*args) + + +class NotEqual(__Base): + + def __init__(self): + self.name = "≠" + + def __call__(self, *args): + return __op.ne(*args) + + +class LessOrEqual(__Base): + + def __init__(self): + self.name = "≤" + + def __call__(self, *args): + return __op.le(*args) + + +class Less(__Base): + + def __init__(self): + self.name = "<" + + def __call__(self, *args): + return __op.lt(*args) diff --git a/Main/Main_Desktop.py b/Main/Main_Desktop.py index b8d5ee2..86f0ff2 100644 --- a/Main/Main_Desktop.py +++ b/Main/Main_Desktop.py @@ -8,9 +8,9 @@ from kivy.uix.screenmanager import Screen # Other python module imports from Common.MTPy_Modified import MT_Modded as MeltpoolTomography from Common.threading_decorators import run_in_thread +from Data import Calibration, ThresholdFunctions from pathlib import Path -from types import SimpleNamespace -import operator as op +from types import SimpleNamespace, FunctionType from ast import literal_eval from contextlib import redirect_stdout @@ -32,7 +32,8 @@ class Main(Screen): shared_io_choosers = ["io_chooser_dataloading", "io_chooser_buildplate", "io_chooser_sampledetection", - "io_chooser_persample"] + "io_chooser_persample", + "io_chooser_datasheet"] shared_io_choosers = [self.ids[x] for x in shared_io_choosers] # Link progress bars in document to their associated functions self.mtpy.progress_bars["read_layers"] = self.ids.read_layers_progbar @@ -48,24 +49,21 @@ class Main(Screen): # self.mtpy.progress_bars["threshold_all_layers"] = self.ids.avgtemp_threshold_progbar # noqa self.mtpy.progress_bars["temp_data_to_csv"] = self.ids.kmeans_separate_samples_progbar # noqa # Starting items in cache - starting_cache = {"shared_io_choosers": shared_io_choosers, - "in_path": str(Path("~").expanduser()), # path to input data - "out_path": str(Path("~").expanduser()), # path to output data - "last_loaded_path": False, # path to last loaded - "calibration_curve": False, # last cal curve used - "static_fileformats": # Allowed static formats - ("png", "pdf", "ps", "eps", "svg"), - "thresh_functions": # Threshold functions available - { - ">": op.gt, - "≥": op.ge, - "=": op.eq, - "≠": op.ne, - "≤": op.le, - "<": op.lt, - }, - "progress_bars": self.mtpy.progress_bars} - + starting_cache = { + # Shared variables + "shared_io_choosers": shared_io_choosers, + "in_path": str(Path("~").expanduser()), # path to input data + "out_path": str(Path("~").expanduser()), # path to output data + "last_loaded_path": False, # path to last loaded + "calibration_curve": False, # last cal curve used + # Dropdown population lists + "printer_types": ("None", "3D Systems", "Aconity", "GE Additive", "Renishaw", "Stratasys"), + "calibration_curves": [v() for k, v in Calibration.__dict__.items() if "__" not in k], + "static_fileformats": ("png", "pdf", "ps", "eps", "svg"), # Allowed static formats + "thresh_functions": [v() for k, v in ThresholdFunctions.__dict__.items() if "__" not in k], + # Progress Bars + "progress_bars": self.mtpy.progress_bars + } self.cache = SimpleNamespace(**starting_cache) # Make sure each shared io chooser is aware of others and parent app for chooser in self.cache.shared_io_choosers: @@ -73,11 +71,21 @@ class Main(Screen): [x for x in self.cache.shared_io_choosers if x != chooser] chooser.cache.parent_app = self # Next, populate dropdowns - # First, the dropdowns for matplotlib filetype options - self.ids.layers_to_figures_filetype_dropdown.populate_dropdown( - self.cache.static_fileformats) - self.ids.avgtemp_thresh_function_dropdown.populate_dropdown( - self.cache.thresh_functions.keys()) + # The dropdown for selecting the printer type + self.ids.printer_type_dropdown.populate_dropdown(self.cache.printer_types) + # The dropdown for calibration curves + self.ids.calibration_curve_dropdown.populate_dropdown(self.cache.calibration_curves) + # The dropdowns for matplotlib filetype options + static_filetype_dropdowns = ( + self.ids.layers_to_figures_filetype_dropdown, + self.ids.layers_to_3dplot_filetype_dropdown, + self.ids.samples_to_figures_filetype_dropdown, + self.ids.samples_to_3dplot_filetype_dropdown, + ) + for dropdown in static_filetype_dropdowns: + dropdown.populate_dropdown(self.cache.static_fileformats) + # The dropdowns for the thresholding functions + self.ids.avgtemp_thresh_function_dropdown.populate_dropdown(self.cache.thresh_functions) # Property returns a string summarising the status of data processing @property @@ -149,9 +157,9 @@ class Main(Screen): elif c in ("(", "{", "["): neststring += c elif c in (")", "}", "]"): - if (c == ")" and neststring[-1] == "(" or - c == "}" and neststring[-1] == "{" or - c == "]" and neststring[-1] == "["): + if (c == ")" and neststring[-1] == "(" + or c == "}" and neststring[-1] == "{" + or c == "]" and neststring[-1] == "["): neststring = neststring[:-1] parsed.append(paramstring[prev_split:]) @@ -164,6 +172,18 @@ class Main(Screen): return parsed + # Parses layer selection into a layer filter + def parse_filter(self, filterstring: str) -> FunctionType: + filterstring = filterstring.strip() + if filterstring.isdigit(): + return lambda x: x == int(filterstring) + elif ":" in filterstring: + return lambda x: x in range(*(int(y) for y in filterstring.split(":"))) + elif "," in filterstring: + return lambda x: x in (int(y) for y in filterstring.split(",")) + else: + return lambda x: True + # This function loads input data only if not already loaded @run_in_thread def load_data(self): @@ -177,16 +197,23 @@ class Main(Screen): # NOTE: relies on eval! Function may be dangerous @run_in_thread def apply_calibration_curve(self): - equation = self.ids.calibration_curve.text - equation = equation.replace(" ", "") - if ((equation != self.cache.calibration_curve) and - (equation != "y=x") and - (equation[:2] == "y=")): - def func(x): - return eval(equation[2:]) - self.mtpy.apply_calibration_curve(func) - self.cache.calibration_curve = equation - self.update_data_status() + cal_curve_selection = self.ids.calibration_curve_dropdown.current_selection + if (cal_curve_selection.name == "Custom"): + equation = self.ids.calibration_curve.text + equation = equation.replace(" ", "") + if ((equation != self.cache.calibration_curve) + and (equation != "y=x") + and (equation[:2] == "y=")): + def func(x): + return eval(equation[2:]) + self.mtpy.apply_calibration_curve(func) + self.cache.calibration_curve = equation + self.update_data_status() + else: + if cal_curve_selection is not self.cache.calibration_curve: + self.mtpy.apply_calibration_curve(cal_curve_selection) + self.cache.calibration_curve = cal_curve_selection + self.update_data_status() # A wrapper function translating application state into a call to the # mtpy function layers_to_figures @@ -200,10 +227,8 @@ class Main(Screen): plot_w = self.ids.layers_to_figures_plot_w.active colorbar = self.ids.layers_to_figures_colorbar.active # then parse kwarg params - figureparams = self.parse_kwargs( - self.ids.layers_to_figures_figureparams.text) - scatterparams = self.parse_kwargs( - self.ids.layers_to_figures_plotparams.text) + figureparams = self.parse_kwargs(self.ids.layers_to_figures_figureparams.text) + scatterparams = self.parse_kwargs(self.ids.layers_to_figures_plotparams.text) self.mtpy.layers_to_figures(self.cache.out_path, filetype=filetype, plot_w=plot_w, @@ -224,9 +249,9 @@ class Main(Screen): colorbar = self.ids.layers_to_3dplot_colorbar.active # then parse kwarg params figureparams = self.parse_kwargs( - self.ids.layers_to_3dplot_figureparams.text) + self.ids.layers_to_3dplot_figureparams.text) plotparams = self.parse_kwargs( - self.ids.layers_to_3dplot_plotparams.text) + self.ids.layers_to_3dplot_plotparams.text) self.mtpy.layers_to_3dplot(self.cache.out_path, filetype=filetype, plot_w=plot_w, @@ -267,9 +292,9 @@ class Main(Screen): colorbar = self.ids.samples_to_figures_colorbar.active # then parse kwarg params figureparams = self.parse_kwargs( - self.ids.samples_to_figures_figureparams.text) + self.ids.samples_to_figures_figureparams.text) scatterparams = self.parse_kwargs( - self.ids.samples_to_figures_plotparams.text) + self.ids.samples_to_figures_plotparams.text) self.mtpy.samples_to_figures(self.cache.out_path, filetype=filetype, plot_w=plot_w, @@ -290,9 +315,9 @@ class Main(Screen): colorbar = self.ids.samples_to_3dplot_colorbar.active # then parse kwarg params figureparams = self.parse_kwargs( - self.ids.samples_to_3dplot_figureparams.text) + self.ids.samples_to_3dplot_figureparams.text) plotparams = self.parse_kwargs( - self.ids.samples_to_3dplot_plotparams.text) + self.ids.samples_to_3dplot_plotparams.text) self.mtpy.samples_to_3dplot(self.cache.out_path, filetype=filetype, plot_w=plot_w, @@ -382,4 +407,13 @@ class Main(Screen): # This function generates datasheets @run_in_thread def temp_data_to_csv(self): - self.mtpy.temp_data_to_csv(f"{self.cache.out_path}") + confidence_interval = self.ids.temp_data_to_csv_confinterval + confidence_interval = confidence_interval.strip() + if confidence_interval.isdigit(): + confidence_interval = float(confidence_interval) + else: + confidence_interval = 0.95 + self.mtpy.temp_data_to_csv(f"{self.cache.out_path}", + layers=self.ids.temp_data_to_csv_layers, + samples=self.ids.temp_data_to_csv_samples, + confidence_interval=confidence_interval) diff --git a/Templates/dropdown_button.py b/Templates/dropdown_button.py index c9e7951..0d2652a 100644 --- a/Templates/dropdown_button.py +++ b/Templates/dropdown_button.py @@ -7,30 +7,41 @@ from kivy.uix.dropdown import DropDown class DropdownButton(Button): - def __init__(self, option_list=None, **kwargs): - # ensure "text" kwarg isnt present + + def __init__(self, + option_list=None, + default_selection=None, + bound_textfields={}, + **kwargs): + # ensure "test" kwarg isnt present if "test" in kwargs: kwargs.pop("test") # Add default args if they're not specifically assigned self.defaultkwargs = \ - {"background_color": [x*0.75 for x in self.background_color], + {"background_color": [x * 0.75 for x in self.background_color], } for keyword, arg in self.defaultkwargs.items(): if keyword not in kwargs: kwargs[keyword] = arg + # self.bound_textfields is a dict of objects as keys, + # values are either the name of textfield to update or tuple containing + # the textfield name AND a function that maps the selection to a new string + self.bound_textfields = bound_textfields self.kwargs = kwargs super(DropdownButton, self).__init__(**self.kwargs) - # Create lambdas for callbacks - self.__bind_button = lambda btn: self.dropdown_list.select(btn.text) - self.__update_label = lambda instance, x: setattr(self, "text", x) - if option_list is not None: self.populate_dropdown(option_list) + if type(default_selection) == str: + self.current_selection = self.objects_dict[default_selection] + else: + self.current_selection = default_selection + + # Populates dropdown with contents of list given def populate_dropdown(self, option_list): kwargs = self.kwargs.copy() kwargs["size_hint_y"] = None @@ -42,11 +53,32 @@ class DropdownButton(Button): self.dropdown_list = None self.dropdown_list = DropDown() - for x in option_list: + self.objects_dict = {str(x): x for x in option_list} + + for x in self.objects_dict.keys(): button = Button(text=x, **kwargs) - # button = Button(text=x, size_hint_y=None, height=50) - button.bind(on_release=self.__bind_button) + button.bind(on_release=self._bind_button) self.dropdown_list.add_widget(button) self.bind(on_release=self.dropdown_list.open) - self.dropdown_list.bind(on_select=self.__update_label) + self.dropdown_list.bind(on_select=self._select_item) + + # Function to bind button to dropdown + def _bind_button(self, btn): + self.dropdown_list.select(btn.text) + + def _update_label(self, instance, x): + setattr(self, "text", x) + + # This function runs whenever an item from the dropdown is selected + def _select_item(self, instance, selection): + self.current_selection = self.objects_dict[selection] + self._update_label(instance, selection) + self.update_bound_textfields(selection) + + def update_bound_textfields(self, text): + for object, field in self.bound_textfields.items(): + if type(field) == str: + setattr(object, field, text) + elif type(field) == tuple: + setattr(object, field[0], field[1](text)) diff --git a/Templates/melter_desktop.kv b/Templates/melter_desktop.kv index 609ec1e..23d13c4 100644 --- a/Templates/melter_desktop.kv +++ b/Templates/melter_desktop.kv @@ -42,33 +42,40 @@ size_hint_x: 0.25 text: "Load Pyrometry Data" on_press: root.load_data() + # A dropdown for selecting printer type + # TODO: make this actually do something + DropdownButton: + text: "None" + size_hint_x: 0.25 + id: printer_type_dropdown ProgressBar: id: read_layers_progbar - size_hint_x: 0.75 + size_hint_x: 0.5 value: 0 # A button that applies the calibration curve Button: text: "Apply Calibration Curve" size_hint_x: 0.25 - width: 120 + width: 60 on_press: root.apply_calibration_curve() StackLayout: size_hint_x: 0.25 size_hint_y: 0.5 cols: 1 rows: 2 - # Containing a description of what the field points to - Label: - halign: "right" - text: "Calibration Curve" - width: 160 + # A dropdown for selecting preprogrammed/custom calibrations + DropdownButton: + text: "None" + id: calibration_curve_dropdown + width: 80 + bound_textfields: {calibration_curve: ("hint_text", lambda _: getattr(self.current_selection, "formula"))} # A textbox for cal curve equation entry TextInput: halign: "center" valign: "center" id: calibration_curve readonly: False - hint_text: "y = x" + hint_text: "y=x" ProgressBar: id: cal_curve_progbar size_hint_x: 0.5 @@ -319,43 +326,58 @@ #:set num_functions 3 #:set spacer_y_hint ((1-(row_y_hint*num_functions*2))/(num_functions-1)) - # First function on this panel (layers_to_figures) begins here - # This button will be a dropdown - DropdownButton: - id: layers_to_figures_filetype_dropdown - text: "select file type\n(png)" - size_hint_x: 0.25 - size_hint_y: row_y_hint - # Right of the dropdown will be a suite of options + # Panel of options for static 2d figures StackLayout: orientation: "tb-lr" - size_hint_x: 0.75 + size_hint_x: 1. size_hint_y: row_y_hint - # Checkboxes for toggling plot colouring and colourbars - CheckBox: - id: layers_to_figures_plot_w - active: True - size_hint_x: 0.1 + # First function on this panel (layers_to_figures) begins here + # This button will be a dropdown + DropdownButton: + id: layers_to_figures_filetype_dropdown + text: "select file type (png)" + size_hint_x: 0.25 size_hint_y: 0.5 - CheckBox: - id: layers_to_figures_colorbar - active: True - size_hint_x: 0.1 + GridLayout: + rows: 1 + size_hint_x: 0.25 size_hint_y: 0.5 - Label: - text: "Colour by temperature" - size_hint_x: 0.4 + # Checkboxes for toggling plot colouring and colourbars + CheckBox: + id: layers_to_figures_plot_w + active: True + size_hint_x: 0.1 + size_hint_y: 0.5 + Label: + text: "Heatmap" + size_hint_x: 0.4 + size_hint_y: 0.5 + text_size: self.size + halign: "left" + valign: "middle" + CheckBox: + id: layers_to_figures_colorbar + active: True + size_hint_x: 0.1 + size_hint_y: 0.5 + Label: + text: "Colourbar" + size_hint_x: 0.4 + size_hint_y: 0.5 + text_size: self.size + halign: "left" + valign: "middle" + # Text input for layer/sample filters + TextInput: + id: layers_to_figures_layerfilter + size_hint_x: 0.25 size_hint_y: 0.5 - text_size: self.size - halign: "left" - valign: "middle" - Label: - text: "Display colourbar" - size_hint_x: 0.4 + hint_text: "Layer filter..." + TextInput: + id: layers_to_figures_samplefilter + size_hint_x: 0.25 size_hint_y: 0.5 - text_size: self.size - halign: "left" - valign: "middle" + hint_text: "Sample filter..." # And text input for other figure parameters TextInput: id: layers_to_figures_figureparams @@ -386,42 +408,56 @@ size_hint_y: spacer_y_hint # Second function on this panel (layers_to_3dplot) begins here - # This button will be a dropdown - DropdownButton: - id: layers_to_3dplot_filetype_dropdown - text: "select file type\n(png)" - size_hint_x: 0.25 - size_hint_y: row_y_hint - # Right of the dropdown will be a suite of options StackLayout: orientation: "tb-lr" - size_hint_x: 0.75 + size_hint_x: 1. size_hint_y: row_y_hint - # Checboxes for toggling plot colouring and colourbars - CheckBox: - id: layers_to_3dplot_plot_w - active: True - size_hint_x: 0.1 + # This button will be a dropdown + DropdownButton: + id: layers_to_3dplot_filetype_dropdown + text: "select file type (png)" + size_hint_x: 0.25 size_hint_y: 0.5 - CheckBox: - id: layers_to_3dplot_colorbar - active: True - size_hint_x: 0.1 + # Checkboxes for toggling plot colouring and colourbars + GridLayout: + rows: 1 + size_hint_x: 0.25 size_hint_y: 0.5 - Label: - text: "Colour by temperature" - size_hint_x: 0.4 + CheckBox: + id: layers_to_3dplot_plot_w + active: True + size_hint_x: 0.1 + size_hint_y: 0.5 + Label: + text: "Heatmap" + size_hint_x: 0.4 + size_hint_y: 0.5 + text_size: self.size + halign: "left" + valign: "middle" + CheckBox: + id: layers_to_3dplot_colorbar + active: True + size_hint_x: 0.1 + size_hint_y: 0.5 + Label: + text: "Colourbar" + size_hint_x: 0.4 + size_hint_y: 0.5 + text_size: self.size + halign: "left" + valign: "middle" + # Text input for layer/sample filters + TextInput: + id: layers_to_3dplot_layerfilter + size_hint_x: 0.25 size_hint_y: 0.5 - text_size: self.size - halign: "left" - valign: "middle" - Label: - text: "Display colourbar" - size_hint_x: 0.4 + hint_text: "Layer filter..." + TextInput: + id: layers_to_3dplot_samplefilter + size_hint_x: 0.25 size_hint_y: 0.5 - text_size: self.size - halign: "left" - valign: "middle" + hint_text: "Sample filter..." # And text input for other figure parameters TextInput: id: layers_to_3dplot_figureparams @@ -451,7 +487,7 @@ size_hint_x: 1.0 size_hint_y: spacer_y_hint - # Second function on this panel (layers_to_3dplot) begins here + # Third function on this panel (layers_to_3dplot_interactive) begins here # First part of this panel will be a suite of options StackLayout: orientation: "lr-tb" @@ -459,10 +495,9 @@ size_hint_y: row_y_hint # Checkboxes for toggling plot colouring and colourbars # and downsampling factor input - #:set one_third 1/3 Label: - text: "Downsampling: " - size_hint_x: 0.75 * one_third + text: "Downsampling:" + size_hint_x: 0.167 size_hint_y: 0.5 text_size: self.size halign: "right" @@ -470,16 +505,26 @@ TextInput: id: layers_to_3dplot_interactive_downsampling hint_text: "1" - size_hint_x: 0.25 * one_third + size_hint_x: 0.083 size_hint_y: 0.5 + TextInput: + id: layers_to_3dplot_interactive_layerfilter + size_hint_x: 0.375 + size_hint_y: 0.5 + hint_text: "Layer Filter..." + TextInput: + id: layers_to_3dplot_interactive_samplefilter + size_hint_x: 0.375 + size_hint_y: 0.5 + hint_text: "Sample Filter..." CheckBox: id: layers_to_3dplot_interactive_plot_w active: True - size_hint_x: 0.25 * one_third + size_hint_x: 0.025 size_hint_y: 0.5 Label: - text: "Colour by temperature" - size_hint_x: 0.75 * one_third + text: "Heatmap" + size_hint_x: 0.1 size_hint_y: 0.5 text_size: self.size halign: "left" @@ -487,18 +532,18 @@ CheckBox: id: layers_to_3dplot_interactive_sliceable active: True - size_hint_x: 0.25 * one_third + size_hint_x: 0.025 size_hint_y: 0.5 Label: - text: "Sliceable model" - size_hint_x: 0.75 * one_third + text: "Sliceable" + size_hint_x: 0.1 size_hint_y: 0.5 text_size: self.size halign: "left" valign: "middle" TextInput: id: layers_to_3dplot_interactive_plotparams - size_hint_x: 1. + size_hint_x: 0.75 size_hint_y: 0.5 hint_text: "Plot parameters..." # This button is a progress bar trigger that tracks the @@ -539,43 +584,58 @@ #:set num_functions 3 #:set spacer_y_hint ((1-(row_y_hint*num_functions*2))/(num_functions-1)) - # First function on this panel (layers_to_figures) begins here - # This button will be a dropdown - DropdownButton: - id: samples_to_figures_filetype_dropdown - text: "select file type\n(png)" - size_hint_x: 0.25 - size_hint_y: row_y_hint - # Right of the dropdown will be a suite of options + # Panel of options for static 2d figures StackLayout: orientation: "tb-lr" - size_hint_x: 0.75 + size_hint_x: 1. size_hint_y: row_y_hint - # Checkboxes for toggling plot colouring and colourbars - CheckBox: - id: samples_to_figures_plot_w - active: True - size_hint_x: 0.1 + # First function on this panel (layers_to_figures) begins here + # This button will be a dropdown + DropdownButton: + id: samples_to_figures_filetype_dropdown + text: "select file type (png)" + size_hint_x: 0.25 size_hint_y: 0.5 - CheckBox: - id: samples_to_figures_colorbar - active: True - size_hint_x: 0.1 + GridLayout: + rows: 1 + size_hint_x: 0.25 size_hint_y: 0.5 - Label: - text: "Colour by temperature" - size_hint_x: 0.4 + # Checkboxes for toggling plot colouring and colourbars + CheckBox: + id: samples_to_figures_plot_w + active: True + size_hint_x: 0.1 + size_hint_y: 0.5 + Label: + text: "Heatmap" + size_hint_x: 0.4 + size_hint_y: 0.5 + text_size: self.size + halign: "left" + valign: "middle" + CheckBox: + id: samples_to_figures_colorbar + active: True + size_hint_x: 0.1 + size_hint_y: 0.5 + Label: + text: "Colourbar" + size_hint_x: 0.4 + size_hint_y: 0.5 + text_size: self.size + halign: "left" + valign: "middle" + # Text input for layer/sample filters + TextInput: + id: samples_to_figures_layerfilter + size_hint_x: 0.25 size_hint_y: 0.5 - text_size: self.size - halign: "left" - valign: "middle" - Label: - text: "Display colourbar" - size_hint_x: 0.4 + hint_text: "Layer filter..." + TextInput: + id: samples_to_figures_samplefilter + size_hint_x: 0.25 size_hint_y: 0.5 - text_size: self.size - halign: "left" - valign: "middle" + hint_text: "Sample filter..." # And text input for other figure parameters TextInput: id: samples_to_figures_figureparams @@ -606,42 +666,56 @@ size_hint_y: spacer_y_hint # Second function on this panel (layers_to_3dplot) begins here - # This button will be a dropdown - DropdownButton: - id: samples_to_3dplot_filetype_dropdown - text: "select file type\n(png)" - size_hint_x: 0.25 - size_hint_y: row_y_hint - # Right of the dropdown will be a suite of options StackLayout: orientation: "tb-lr" - size_hint_x: 0.75 + size_hint_x: 1. size_hint_y: row_y_hint - # Checboxes for toggling plot colouring and colourbars - CheckBox: - id: samples_to_3dplot_plot_w - active: True - size_hint_x: 0.1 + # This button will be a dropdown + DropdownButton: + id: samples_to_3dplot_filetype_dropdown + text: "select file type (png)" + size_hint_x: 0.25 size_hint_y: 0.5 - CheckBox: - id: samples_to_3dplot_colorbar - active: True - size_hint_x: 0.1 + GridLayout: + rows: 1 + size_hint_x: 0.25 size_hint_y: 0.5 - Label: - text: "Colour by temperature" - size_hint_x: 0.4 + # Checkboxes for toggling plot colouring and colourbars + CheckBox: + id: samples_to_3dplot_plot_w + active: True + size_hint_x: 0.1 + size_hint_y: 0.5 + Label: + text: "Heatmap" + size_hint_x: 0.4 + size_hint_y: 0.5 + text_size: self.size + halign: "left" + valign: "middle" + CheckBox: + id: samples_to_3dplot_colorbar + active: True + size_hint_x: 0.1 + size_hint_y: 0.5 + Label: + text: "Colourbar" + size_hint_x: 0.4 + size_hint_y: 0.5 + text_size: self.size + halign: "left" + valign: "middle" + # Text input for layer/sample filters + TextInput: + id: samples_to_3dplot_layerfilter + size_hint_x: 0.25 size_hint_y: 0.5 - text_size: self.size - halign: "left" - valign: "middle" - Label: - text: "Display colourbar" - size_hint_x: 0.4 + hint_text: "Layer filter..." + TextInput: + id: samples_to_3dplot_samplefilter + size_hint_x: 0.25 size_hint_y: 0.5 - text_size: self.size - halign: "left" - valign: "middle" + hint_text: "Sample filter..." # And text input for other figure parameters TextInput: id: samples_to_3dplot_figureparams @@ -671,7 +745,7 @@ size_hint_x: 1.0 size_hint_y: spacer_y_hint - # Second function on this panel (layers_to_3dplot) begins here + # Third function on this panel (layers_to_3dplot_interactive) begins here # First part of this panel will be a suite of options StackLayout: orientation: "lr-tb" @@ -679,10 +753,9 @@ size_hint_y: row_y_hint # Checkboxes for toggling plot colouring and colourbars # and downsampling factor input - #:set one_third 1/3 Label: - text: "Downsampling: " - size_hint_x: 0.75 * one_third + text: "Downsampling:" + size_hint_x: 0.167 size_hint_y: 0.5 text_size: self.size halign: "right" @@ -690,16 +763,26 @@ TextInput: id: samples_to_3dplot_interactive_downsampling hint_text: "1" - size_hint_x: 0.25 * one_third + size_hint_x: 0.083 size_hint_y: 0.5 + TextInput: + id: samples_to_3dplot_interactive_layerfilter + size_hint_x: 0.375 + size_hint_y: 0.5 + hint_text: "Layer Filter..." + TextInput: + id: samples_to_3dplot_interactive_samplefilter + size_hint_x: 0.375 + size_hint_y: 0.5 + hint_text: "Sample Filter..." CheckBox: id: samples_to_3dplot_interactive_plot_w active: True - size_hint_x: 0.25 * one_third + size_hint_x: 0.025 size_hint_y: 0.5 Label: - text: "Colour by temperature" - size_hint_x: 0.75 * one_third + text: "Heatmap" + size_hint_x: 0.1 size_hint_y: 0.5 text_size: self.size halign: "left" @@ -707,18 +790,18 @@ CheckBox: id: samples_to_3dplot_interactive_sliceable active: True - size_hint_x: 0.25 * one_third + size_hint_x: 0.025 size_hint_y: 0.5 Label: - text: "Sliceable model" - size_hint_x: 0.75 * one_third + text: "Sliceable" + size_hint_x: 0.1 size_hint_y: 0.5 text_size: self.size halign: "left" valign: "middle" TextInput: id: samples_to_3dplot_interactive_plotparams - size_hint_x: 1. + size_hint_x: 0.75 size_hint_y: 0.5 hint_text: "Plot parameters..." # This button is a progress bar trigger that tracks the @@ -744,25 +827,75 @@ # First item is an InputOutputChooser InputOutputChooser: - id: io_chooser_persample + id: io_chooser_datasheet size_hint_x: 1.0 pos_hint: {"x": 0., "y": 0.875} # Button, below, is in a simple grid layout - GridLayout: + StackLayout: + orientation: "lr-tb" size_hint_x: 0.9 - size_hint_y: 0.15 - pos_hint: {"x": 0.05, "y": 0.6} - rows: 1 + size_hint_y: 0.1875 + pos_hint: {"x": 0.05, "y": 0.5} + # rows: 2 + # Checkboxes to turn on/off layer-by-layer and sample-by-sample stats + CheckBox: + id: temp_data_to_csv_layers + active: True + size_hint_x: 0.025 + size_hint_y: 0.33 + Label: + text: "Layers" + size_hint_x: 0.1 + size_hint_y: 0.33 + text_size: self.size + halign: "left" + valign: "middle" + CheckBox: + id: temp_data_to_csv_samples + active: True + size_hint_x: 0.025 + size_hint_y: 0.33 + Label: + text: "Samples" + size_hint_x: 0.1 + size_hint_y: 0.33 + text_size: self.size + halign: "left" + valign: "middle" + # Text input for setting confidence interval + Label: + text: "Confidence Interval" + size_hint_x: 0.125 + size_hint_y: 0.33 + text_size: self.size + halign: "right" + valign: "middle" + TextInput: + id: temp_data_to_csv_confinterval + size_hint_x: 0.075 + size_hint_y: 0.33 + hint_text: "0.95" + # Text input for layer/sample filters + TextInput: + id: temp_data_to_csv_layerfilter + size_hint_x: 0.25 + size_hint_y: 0.33 + hint_text: "Layer filter..." + TextInput: + id: temp_data_to_csv_samplefilter + size_hint_x: 0.25 + size_hint_y: 0.33 + hint_text: "Sample filter..." # This button is a progress bar trigger that tracks the # generation of datasheets Button: text: "Generate\nDatasheets" size_hint_x: 0.25 - size_hint_y: 1 + size_hint_y: 0.67 on_press: root.temp_data_to_csv() ProgressBar: id: temp_data_to_csv_progbar size_hint_x: 0.75 - size_hint_y: 1 + size_hint_y: 0.67 value: 0