Reference profile implemented (no editing, or clearing except when data is cleared). Added an example reference profile
This commit is contained in:
parent
5ff70ebd24
commit
c7264ded31
|
@ -0,0 +1,5 @@
|
||||||
|
0,25
|
||||||
|
120,67
|
||||||
|
3720,67
|
||||||
|
3840,76.67
|
||||||
|
4740,76.66
|
|
71
main.kv
71
main.kv
|
@ -63,6 +63,26 @@
|
||||||
text: 'Set Output File'
|
text: 'Set Output File'
|
||||||
on_press: root.set_output(filechooser.path, text_input.text)
|
on_press: root.set_output(filechooser.path, text_input.text)
|
||||||
|
|
||||||
|
<SelectReferenceProfileDialog>:
|
||||||
|
BoxLayout:
|
||||||
|
orientation: 'vertical'
|
||||||
|
Label:
|
||||||
|
text: 'Select a reference temperature profile (csv)'
|
||||||
|
size_hint_y: 0.1
|
||||||
|
FileChooserListView:
|
||||||
|
size_hint_y: 0.8
|
||||||
|
id: filechooser
|
||||||
|
filters: ['*.csv']
|
||||||
|
BoxLayout:
|
||||||
|
size_hiny_y: 0.1
|
||||||
|
orientation: 'horizontal'
|
||||||
|
Button:
|
||||||
|
text: 'Cancel'
|
||||||
|
on_press: root.cancel()
|
||||||
|
Button:
|
||||||
|
text: 'Set reference profile'
|
||||||
|
on_press: root.set_output(file = filechooser.selection)
|
||||||
|
|
||||||
<MainWindow>:
|
<MainWindow>:
|
||||||
label_wid: "Temperature Monitor"
|
label_wid: "Temperature Monitor"
|
||||||
current_temperature: current_temperature
|
current_temperature: current_temperature
|
||||||
|
@ -76,6 +96,8 @@
|
||||||
image_output_file: ''
|
image_output_file: ''
|
||||||
on_raw_data_output_file: mainplot.raw_data_output_file = self.raw_data_output_file
|
on_raw_data_output_file: mainplot.raw_data_output_file = self.raw_data_output_file
|
||||||
on_image_output_file: mainplot.image_output_file = self.image_output_file
|
on_image_output_file: mainplot.image_output_file = self.image_output_file
|
||||||
|
reference_profile_file: ''
|
||||||
|
on_reference_profile_file: mainplot.reference_profile_file = self.reference_profile_file
|
||||||
BoxLayout:
|
BoxLayout:
|
||||||
orientation: 'vertical'
|
orientation: 'vertical'
|
||||||
BoxLayout:
|
BoxLayout:
|
||||||
|
@ -93,23 +115,60 @@
|
||||||
on_state: root.set_state(self.state)
|
on_state: root.set_state(self.state)
|
||||||
Button:
|
Button:
|
||||||
id: startstop_button
|
id: startstop_button
|
||||||
text: 'Pause'
|
text: 'Pause Data'
|
||||||
on_press: startstop_widget.change_state()
|
on_press: startstop_widget.change_state()
|
||||||
Button:
|
Button:
|
||||||
id: clear_button
|
id: clear_button
|
||||||
text: 'Clear'
|
text: 'Clear Graph'
|
||||||
on_press: root.initiate_clear_dialog()
|
on_press: root.initiate_clear_dialog()
|
||||||
Button:
|
|
||||||
id: output_button
|
|
||||||
text: 'No File Chosen'
|
|
||||||
on_press: root.choose_output_file()
|
|
||||||
SerialPortButton:
|
SerialPortButton:
|
||||||
id: serial_chooser_button
|
id: serial_chooser_button
|
||||||
on_serial_port_changed: root.serial_port_changed(self.text)
|
on_serial_port_changed: root.serial_port_changed(self.text)
|
||||||
|
BoxLayout:
|
||||||
|
orientation: 'horizontal'
|
||||||
|
size_hint_y: 0.1
|
||||||
|
BoxLayout:
|
||||||
|
orientation: 'vertical'
|
||||||
|
BoxLayout:
|
||||||
|
orientation: 'horizontal'
|
||||||
|
Label:
|
||||||
|
text: 'Output file'
|
||||||
|
size_hint_x: 0.3
|
||||||
|
Button:
|
||||||
|
id: output_button
|
||||||
|
text: 'Choose output file'
|
||||||
|
on_press: root.choose_output_file()
|
||||||
|
Label:
|
||||||
|
id: output_file_selected
|
||||||
|
text: 'No file chosen'
|
||||||
|
BoxLayout:
|
||||||
|
orientation: 'vertical'
|
||||||
|
BoxLayout:
|
||||||
|
orientation: 'horizontal'
|
||||||
|
Label:
|
||||||
|
text: 'Reference Profile'
|
||||||
|
Button:
|
||||||
|
id: reference_profile_select
|
||||||
|
text: 'Choose Profile'
|
||||||
|
on_press: root.select_reference_profile()
|
||||||
|
size_hint_x: 0.5
|
||||||
|
Button:
|
||||||
|
id: reference_profile_edit
|
||||||
|
text: 'Edit'
|
||||||
|
size_hint_x: 0.2
|
||||||
|
Button:
|
||||||
|
id: reference_profile_clear
|
||||||
|
text: 'Clear'
|
||||||
|
size_hint_x: 0.2
|
||||||
|
Label:
|
||||||
|
id: reference_profile_selected
|
||||||
|
text: 'No profile selected'
|
||||||
PlotWidget:
|
PlotWidget:
|
||||||
id: mainplot
|
id: mainplot
|
||||||
|
reference_profile_file: ''
|
||||||
on_image_output_file: self.update_image_output_file()
|
on_image_output_file: self.update_image_output_file()
|
||||||
on_raw_data_output_file: self.update_raw_data_output_file()
|
on_raw_data_output_file: self.update_raw_data_output_file()
|
||||||
|
on_reference_profile_file: root.reference_profile_file = self.reference_profile_file
|
||||||
size_hint_y: 0.8
|
size_hint_y: 0.8
|
||||||
StatusBar:
|
StatusBar:
|
||||||
size_hint_y: 0.1
|
size_hint_y: 0.1
|
||||||
|
|
93
main.py
93
main.py
|
@ -67,6 +67,7 @@ class MainWindow(FloatLayout):
|
||||||
lastStatus = DictProperty({})
|
lastStatus = DictProperty({})
|
||||||
image_output_file = StringProperty('')
|
image_output_file = StringProperty('')
|
||||||
raw_data_output_file = StringProperty('')
|
raw_data_output_file = StringProperty('')
|
||||||
|
reference_profile_file = StringProperty('')
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super(MainWindow, self).__init__(**kwargs)
|
super(MainWindow, self).__init__(**kwargs)
|
||||||
|
@ -176,8 +177,7 @@ class MainWindow(FloatLayout):
|
||||||
Logger.debug('Choose Output File pressed')
|
Logger.debug('Choose Output File pressed')
|
||||||
output_file_dialog = OutputFileDialog(cancel = self.dismiss_popup,
|
output_file_dialog = OutputFileDialog(cancel = self.dismiss_popup,
|
||||||
set_output_file = self.set_output_file)
|
set_output_file = self.set_output_file)
|
||||||
self._popup = Popup(title="Choose outputfile", content = output_file_dialog)
|
self.create_popup(title="Choose outputfile", content = output_file_dialog)
|
||||||
self._popup.open()
|
|
||||||
|
|
||||||
|
|
||||||
def set_output_file(self, path, file_name, *args, **kwargs):
|
def set_output_file(self, path, file_name, *args, **kwargs):
|
||||||
|
@ -199,7 +199,7 @@ class MainWindow(FloatLayout):
|
||||||
self.image_output_file = files['image_file']
|
self.image_output_file = files['image_file']
|
||||||
self.dismiss_popup()
|
self.dismiss_popup()
|
||||||
else:
|
else:
|
||||||
# UI Feedback in the popup dialog
|
# @TODO UI Feedback in the popup dialog
|
||||||
Logger.debug('MainWindow: Set output file errors: ' + str(errors))
|
Logger.debug('MainWindow: Set output file errors: ' + str(errors))
|
||||||
|
|
||||||
|
|
||||||
|
@ -219,6 +219,11 @@ class MainWindow(FloatLayout):
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
|
||||||
|
def create_popup(self, *args, **kwargs):
|
||||||
|
self._popup = Popup(*args, **kwargs)
|
||||||
|
self._popup.open()
|
||||||
|
|
||||||
|
|
||||||
def dismiss_popup(self, *args, **kwargs):
|
def dismiss_popup(self, *args, **kwargs):
|
||||||
self._popup.dismiss()
|
self._popup.dismiss()
|
||||||
|
|
||||||
|
@ -232,9 +237,35 @@ class MainWindow(FloatLayout):
|
||||||
if self.raw_data_output_file:
|
if self.raw_data_output_file:
|
||||||
root = self.raw_data_output_file.rsplit('.', 1)
|
root = self.raw_data_output_file.rsplit('.', 1)
|
||||||
Logger.debug('MainWindow: ' + str(root))
|
Logger.debug('MainWindow: ' + str(root))
|
||||||
self.ids.output_button.text = root[0] + '[.csv|.png]'
|
self.ids.output_file_selected.text = root[0] + '[.csv|.png]'
|
||||||
else:
|
else:
|
||||||
self.ids.output_button.text = 'No File Chosen'
|
self.ids.output_file_selected.text = 'No file Chosen'
|
||||||
|
|
||||||
|
|
||||||
|
def select_reference_profile(self, *args, **kwargs):
|
||||||
|
dialog = SelectReferenceProfileDialog(output = self.set_reference_profile,
|
||||||
|
cancel = self.dismiss_popup)
|
||||||
|
self.create_popup(title='Reference Profile Selection',
|
||||||
|
content = dialog)
|
||||||
|
|
||||||
|
|
||||||
|
def set_reference_profile(self, *args, **kwargs):
|
||||||
|
Logger.debug('MainWindow: reference profile kwargs ' + str(kwargs))
|
||||||
|
ref_file = ''
|
||||||
|
if kwargs['file']:
|
||||||
|
ref_file = kwargs['file'][0]
|
||||||
|
if not os.path.isfile(ref_file):
|
||||||
|
# Not a valid path/file
|
||||||
|
return
|
||||||
|
self.reference_profile_file = ref_file
|
||||||
|
self.dismiss_popup()
|
||||||
|
|
||||||
|
|
||||||
|
def on_reference_profile_file(self, *kargs, **kwargs):
|
||||||
|
if not self.reference_profile_file:
|
||||||
|
self.ids.reference_profile_selected.text = 'No profile selected'
|
||||||
|
else:
|
||||||
|
self.ids.reference_profile_selected.text = self.reference_profile_file
|
||||||
|
|
||||||
|
|
||||||
class OutputFileDialog(FloatLayout):
|
class OutputFileDialog(FloatLayout):
|
||||||
|
@ -253,6 +284,22 @@ class OutputFileDialog(FloatLayout):
|
||||||
self.set_output(*args, **kwargs)
|
self.set_output(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class SelectReferenceProfileDialog(FloatLayout):
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(SelectReferenceProfileDialog, self).__init__(*args, **kwargs)
|
||||||
|
self.cancel = kwargs['cancel']
|
||||||
|
self.output = kwargs['output']
|
||||||
|
|
||||||
|
|
||||||
|
def cancel(self, *args, **kwargs):
|
||||||
|
self.cancel(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def set_output(self, *args, **kwargs):
|
||||||
|
self.output(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class SerialPortButton(Spinner):
|
class SerialPortButton(Spinner):
|
||||||
|
|
||||||
__events__ = ('on_serial_port_changed',)
|
__events__ = ('on_serial_port_changed',)
|
||||||
|
@ -318,6 +365,7 @@ class PlotWidget(Image):
|
||||||
|
|
||||||
image_output_file = StringProperty('')
|
image_output_file = StringProperty('')
|
||||||
raw_data_output_file = StringProperty('')
|
raw_data_output_file = StringProperty('')
|
||||||
|
reference_profile_file = StringProperty('')
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super(PlotWidget, self).__init__(**kwargs)
|
super(PlotWidget, self).__init__(**kwargs)
|
||||||
|
@ -332,11 +380,16 @@ class PlotWidget(Image):
|
||||||
self.plot_axes.set_title('Recorded Temperature')
|
self.plot_axes.set_title('Recorded Temperature')
|
||||||
self.image_data = None
|
self.image_data = None
|
||||||
self._image_raw_data = None
|
self._image_raw_data = None
|
||||||
|
self.reference_profile = None
|
||||||
|
|
||||||
|
|
||||||
def clear_data(self):
|
def clear_data(self):
|
||||||
self.data = numpy.array([], dtype=float);
|
self.data = numpy.array([], dtype=float);
|
||||||
|
self.reference_profile_file = ''
|
||||||
|
self.reference_profile = None
|
||||||
self.texture = None
|
self.texture = None
|
||||||
|
self.image_output_file = ''
|
||||||
|
self.raw_data_output_file = ''
|
||||||
|
|
||||||
|
|
||||||
def do_update(self):
|
def do_update(self):
|
||||||
|
@ -373,9 +426,21 @@ class PlotWidget(Image):
|
||||||
#Logger.debug('transpoed data: ' + str(data))
|
#Logger.debug('transpoed data: ' + str(data))
|
||||||
#Logger.debug('transposed data shape: ' + str(data.shape))
|
#Logger.debug('transposed data shape: ' + str(data.shape))
|
||||||
t, temperature = numpy.split(data, 2, axis = 0)
|
t, temperature = numpy.split(data, 2, axis = 0)
|
||||||
#Logger.debug('time: ' + str(t[0]))
|
reference_data = None
|
||||||
#Logger.debug('temperature: ' + str(temperature[0]))
|
if self.reference_profile is not None and self.reference_profile.any():
|
||||||
self.plot_axes.plot(t[0], temperature[0])
|
reference_data = numpy.copy(self.reference_profile)
|
||||||
|
reference_data = reference_data.transpose()
|
||||||
|
t2, reference_temperature = numpy.split(reference_data, 2, axis = 0)
|
||||||
|
# Add t[0] to all reference points to make it fit on the current graph
|
||||||
|
t2 = numpy.add(t2, t[0][0])
|
||||||
|
#Logger.debug('PlotWidget: reference profile t: ' + str(t2))
|
||||||
|
#Logger.debug('PlotWidget: reference profile temp: ' + str(reference_temperature))
|
||||||
|
#Logger.debug('PlotWidget: time: ' + str(t[0]))
|
||||||
|
#Logger.debug('PlotWidget: temperature: ' + str(temperature[0]))
|
||||||
|
if reference_data is not None and reference_data.any():
|
||||||
|
self.plot_axes.plot(t[0], temperature[0], 'b', t2[0], reference_temperature[0], 'r')
|
||||||
|
else:
|
||||||
|
self.plot_axes.plot(t[0], temperature[0], 'b')
|
||||||
image_data = StringIO.StringIO()
|
image_data = StringIO.StringIO()
|
||||||
self.figure.savefig(image_data, format = 'png')
|
self.figure.savefig(image_data, format = 'png')
|
||||||
image_data.seek(0)
|
image_data.seek(0)
|
||||||
|
@ -419,6 +484,18 @@ class PlotWidget(Image):
|
||||||
self.do_update()
|
self.do_update()
|
||||||
|
|
||||||
|
|
||||||
|
def on_reference_profile_file(self, *args, **kwargs):
|
||||||
|
Logger.debug('PlotWidget: on_reference_profile_file ' + str(self.reference_profile_file))
|
||||||
|
self.load_reference_profile()
|
||||||
|
|
||||||
|
|
||||||
|
def load_reference_profile(self):
|
||||||
|
if not self.reference_profile_file:
|
||||||
|
return
|
||||||
|
self.reference_profile = numpy.loadtxt(self.reference_profile_file,
|
||||||
|
delimiter=',')
|
||||||
|
Logger.debug('PlotWidget: reference_profile: ' + str(self.reference_profile))
|
||||||
|
|
||||||
class YesNoModalView(Popup):
|
class YesNoModalView(Popup):
|
||||||
|
|
||||||
def process(self, result, *args, **kwargs):
|
def process(self, result, *args, **kwargs):
|
||||||
|
|
Loading…
Reference in New Issue