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