CEBL  2.1
TabFeatures.cpp
Go to the documentation of this file.
1 
7 #include "TabFeatures.hpp"
8 #include "EEGMonitor.hpp"
9 #include "WidgetUtils.hpp"
10 #include "DataSourceCombo.hpp"
11 
12 //----------------------------------------------------------------------
13 // Constructors / Destructor
14 
16 {
17  if(plot!=NULL)
18  delete plot;
19 }
20 
21 
22 //----------------------------------------------------------------------
23 // Create the GUI
24 
26 {
27  //add title
28  GtkWidget *title = gtk_label_new("");
29  gtk_label_set_markup(GTK_LABEL(title),"<big>Features</big>");
30  TabAdd(title);
31  TabAdd(gtk_hseparator_new());
32 
33 
34 
35  this->continue_plotting = false;
36 
37  //-------------------------------------------------
38  //Feature Selection
39 
40  GtkWidget *hbox_features = gtk_hbox_new(false, 0);
41 
42  this->updating_view = false;
43  this->num_features = 0;
44  this->selected_feature = "";
45  combo_features = gtk_combo_box_new_text();
46 
47 
48  //configure the combo box and add callback
49  gtk_combo_box_set_active(GTK_COMBO_BOX(combo_features),0);
50  g_signal_connect(G_OBJECT(combo_features),
51  "changed",
52  G_CALLBACK(CB_changeFeature),
53  (gpointer) this);
54 
55  gtk_box_pack_start(GTK_BOX(hbox_features), combo_features, false, false, 0);
56 
57  //is_made check box
58  check_feature_trained = gtk_check_button_new_with_label("Feature Trained");
59  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_feature_trained),false);
60  gtk_widget_set_sensitive(check_feature_trained,false);
61 
62  gtk_box_pack_end(GTK_BOX(hbox_features),check_feature_trained,false, false, 0);
63 
64  gtk_widget_show_all(hbox_features);
65  TabAdd(hbox_features);
66 
67  //----------------------------------------
68  //create buttons
69 
70  GtkWidget * btn_box1 = gtk_hbutton_box_new();
71  gtk_button_box_set_layout(GTK_BUTTON_BOX(btn_box1),GTK_BUTTONBOX_START);
72 
73  btn_start = gtk_button_new_with_label("Start Monitoring");
74  // gtk_widget_set_size_request(btn_start,30,20);
75  g_signal_connect(G_OBJECT(btn_start),
76  "clicked",
77  G_CALLBACK(CB_startPlot),
78  (gpointer) this);
79 
80  btn_stop = gtk_button_new_with_label("Stop");
81  gtk_widget_set_sensitive(btn_stop,false);
82  // gtk_widget_set_size_request(btn_stop,30,2);
83  g_signal_connect(G_OBJECT(btn_stop),
84  "clicked",
85  G_CALLBACK(CB_stopPlot),
86  (gpointer) this);
87 
88  gtk_box_pack_start(GTK_BOX(btn_box1),btn_start,false,false,2);
89  gtk_box_pack_start(GTK_BOX(btn_box1),btn_stop,false,false,2);
90  gtk_box_pack_start(GTK_BOX(btn_box1),gtk_label_new("Data Source: "), false, false, 2);
91  gtk_box_pack_start(GTK_BOX(btn_box1),getView()->getDataSource()->getCombo(),false,false,2);
92 
93 
94  //create space for widget panel
95  panel_box = gtk_vbox_new(false, 0);
96  panel = NULL;
97  //pack everything into frame
98  GtkWidget *features_box = gtk_vbox_new(false,0);
99  gtk_box_pack_start(GTK_BOX(features_box),panel_box,false,false,2);
100  gtk_box_pack_start(GTK_BOX(features_box),btn_box1,false,false,2);
101  TabFrameAdd(features_box,"Feature Configuration");
102 
103  //plot
104  plot = NULL;
105 
106 
107 
108  updateView();
109 
110  //by default set first feature in combo box active if it has not been set
111  if(gtk_combo_box_get_active(GTK_COMBO_BOX(combo_features))==-1)
112  gtk_combo_box_set_active(GTK_COMBO_BOX(combo_features),0);
113 
114 
115 }
116 
117 
118 //update view from model
119 
121 {
122  //set flag to indicate process of updating view
123  //in order to stop callbacks from triggering
124  this->updating_view = true;
125 
126  //get information from model about features
127  CEBLModel * model = getView()->getModel();
128  std::vector<string> names = model->featuresGetNameList();
129  std::vector<string> paths = model->featuresGetPathList();
130  string model_selected_feature = model->featuresGetSelected();
131 
132  {
133  this->selected_feature = model_selected_feature;
134  this->feature_names = names;
135  for(int i = this->num_features-1; i >= 0; i--)
136  {
137  gtk_combo_box_remove_text(GTK_COMBO_BOX(combo_features),i);
138  }
139  this->num_features = names.size();
140 
141  // add in all features
142  for(unsigned int i=0;i<names.size();i++)
143  {
144  gtk_combo_box_append_text(GTK_COMBO_BOX(combo_features),names[i].c_str());
145  if(names[i]==model_selected_feature)
146  {
147  gtk_combo_box_set_active(GTK_COMBO_BOX(combo_features),i);
148  }
149  }
150  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_feature_trained),
151  model->featureIsTrained());
152  // create panel
153  if (this->panel != NULL)
154  {
155  gtk_container_remove(GTK_CONTAINER(this->panel_box),this->panel->getContainer());
156  delete this->panel;
157  this->panel = NULL;
158  }
159 
160  //update panel
161  if(model_selected_feature != "")
162  {
163  try
164  {
165  std::map<std::string, CEBL::Param> params = model->featureGetParams(model_selected_feature);
166  this->panel = new WidgetPanel(params);
167  }
168  catch(...)
169  {
170  this->panel = NULL;
171  cerr << "ERROR: exception occured when trying to get parameters for feature.\n";
172  }
173  }
174  if (this->panel != NULL)
175  {
176  gtk_container_add(GTK_CONTAINER(this->panel_box),this->panel->getContainer());
177  gtk_widget_show_all(this->panel_box);
178 
179  }
180  }//end of conditional concerning whether update should occur
181 
182  //update button sensitivity
183  // change button sensitivity based on stat of collection
184  if(getView()->getModel()->dataIsStarted())
185  {
186  gtk_widget_set_sensitive(combo_features,false);
187  gtk_widget_set_sensitive(btn_start,false);
188  gtk_widget_set_sensitive(panel_box,false);
189  gtk_widget_set_sensitive(btn_stop,true);
190  }
191  else
192  {
193  gtk_widget_set_sensitive(combo_features,true);
194  gtk_widget_set_sensitive(panel_box,true);
195  gtk_widget_set_sensitive(btn_start,true);
196  gtk_widget_set_sensitive(btn_stop,false);
197  }
198  this->updating_view = false;
199 }
200 
201 //update the model from the widgets
203 {
204  // set the selected feature's params
205  if(this->panel != NULL){
206  this->getView()->getModel()->featureSetParams(this->panel->getParams());
207  }
208 }
209 
212 {
213  updateModel();
214  getView()->updateInfoBar();
215  this->stopPlotting();
216 
217  /* lags is currently unused by the classifier
218  * uncomment this section when lags is once again used
219  CEBL::Params params = getView()->getModel()->featureGetParams();
220  int lags = (params["lags"]).getInt();
221 
222  if(lags>=0){
223  getView()->getModel()->classifierReset(params);
224  }
225  */
226 
227 }
228 
229 //----------------------------------------------------------------------
230 // PLOTTING
231 
232 
234 void TabFeatures::createPlot()
235 {
236  plot_size = this->getView()->getModel()->channelsGetNumEnabledChannels();
237  if(plot==NULL)
238  {
239  plot = new EEGMonitor(this,plot_size);
240  plot->reInitPlot(plot_size);
241  TabAdd(*plot, true, true, 0);
242  }
243  else
244  {
245  plot->reInitPlot(plot_size);
246  }
247 }
248 
249 
251 void TabFeatures::startPlotting()
252 {
253  if(this->panel != NULL){
254  this->getView()->getModel()->featureSetParams(this->panel->getParams());
255  }
256 
257  try
258  {
259  getView()->getModel()->dataStart();
260  }
261  catch(exception &e)
262  {
263  WidgetUtils::AlertError("Error Starting Data Source", "There was an error starting the data source. \n("+string(e.what())+")");
264  return;
265  }
266  if(!getView()->getModel()->dataIsStarted())
267  {
268  WidgetUtils::AlertError("Error Starting Data Source", "There was an error starting the data source. Check device configuration.");
269  }
270  else
271  {
272  this->continue_plotting = true;
273  this->createPlot();
274  g_timeout_add(100, timedPlot, this);
275  }
276  this->updateView();
277 }
278 
279 
281 gint TabFeatures::timedPlot(gpointer parent)
282 {
283  TabFeatures * tab = (TabFeatures*)parent;
284  if(!tab->getView()->getModel()->dataIsStarted())
285  {
286  tab->stopPlotting();
287  }
288  if(!tab->getView()->getModel()->featureIsTrained())
289  {
290  tab->stopPlotting();
291  }
292  if(!tab->continuePlotting())
293  {
294  return false;
295  }
296  try
297  {
298  EEGData data = tab->getView()->getModel()->dataReadAll();
299  data = tab->getView()->getModel()->featuresExtract(data);
300  //upate plot if number of channels is different
301 
302  if(min(data.size1(),72) != tab->plot_size)
303  {
304  tab->plot_size = min(data.size1(),72);
305  tab->plot->reInitPlot(tab->plot_size);
306  }
307 
308  ublas::matrix<double> d = (data.getMatrix());
309 
310  if(tab->plot!=NULL)
311  {
312  tab->plot->Plot(data);
313  }
314  else
315  {
316  tab->stopPlotting();
317  }
318  }
319  catch(DataExceptionUnderflow& e)
320  {
321  cout << e.what() << "\n";
322  }
323  catch(exception& e)
324  {
325  string msg = "Failed to process data. \n(" + string(e.what()) + ")";
326  WidgetUtils::AlertError("Error Processing Data",msg);
327  tab->stopPlotting();
328  }
329  return true;
330 }
331 
333 void TabFeatures::stopPlotting()
334 {
335  this->continue_plotting = false;
336  getView()->getModel()->dataStop();
337  updateView();
338 }
339 
340 
341 //----------------------------------------------------------------------
342 // CALLBACKS
343 
344 
345 void TabFeatures::CB_startPlot(GtkWidget *w, gpointer data)
346 {
347  TabFeatures * tab = (TabFeatures*)data;
348  tab->startPlotting();
349 }
350 void TabFeatures::CB_stopPlot(GtkWidget *w, gpointer data)
351 {
352  TabFeatures * tab = (TabFeatures*)data;
353  tab->stopPlotting();
354 }
355 
356 
357 void TabFeatures::CB_changeFeature(GtkWidget *w, gpointer data)
358 {
359  TabFeatures* tab = (TabFeatures*)data;
360 
361  //as long as the update view is not currently running,
362  //set the model's selected feature to the selected feature
363  //in combo box
364  if(tab->num_features > 0 && !tab->updating_view)
365  {
366  string feature = gtk_combo_box_get_active_text(GTK_COMBO_BOX(tab->combo_features));
367  try
368  {
369  if(feature != tab->selected_feature)
370  {
371  // set the previously selected feature's params
372  if(tab->panel != NULL){
373  tab->getView()->getModel()->featureSetParams(tab->panel->getParams());
374  }
375  // now tell model what feature is selected
376  tab->getView()->getModel()->featuresSetSelected(feature);
377 
378  }
379  }
380  catch(...)
381  {
382  cerr << "Error selecting feature.\n";
383  }
384  tab->updateView();
385  }
386 
387 }
388 
389 
390