CEBL  2.1
TabRealTimeClassification.cpp
Go to the documentation of this file.
1 
10 #include "InterfaceCombo.hpp"
13 #include "interfaces/RobotPie.hpp"
14 #include "DataSourceCombo.hpp"
15 #include "cppR.hpp"
16 
17 //----------------------------------------------------------------------
18 // Constructors / Destructor
19 
21 {
22  delete this->interface_config;
23 }
24 
25 
26 //----------------------------------------------------------------------
27 // Create the GUI
28 
29 
31 {
32  //add title
33  GtkWidget *title = gtk_label_new("");
34  gtk_label_set_markup(GTK_LABEL(title),"<big>Real Time Classification</big>");
35  TabAdd(title);
36  TabAdd(gtk_hseparator_new());
37 
38 
39 
40  //-------------------------------------------------
41 
42  this->interface_box = gtk_vbox_new(false, 0);
43  this->updating_view = false;
44  this->interface_config = new InterfaceConfigurationWindow(this->view);
45 
46  //----------------------------------------
47  //create buttons
48 
49  btn_train_classifier = gtk_button_new_with_label("Train Classifier");
50  g_signal_connect(G_OBJECT(btn_train_classifier),
51  "clicked",
52  G_CALLBACK(CB_trainClassifier),
53  (gpointer) this);
54 
55  btn_start = gtk_button_new_with_label("Start Classifying");
56  g_signal_connect(G_OBJECT(btn_start),
57  "clicked",
58  G_CALLBACK(CB_start),
59  (gpointer) this);
60 
61  btn_stop = gtk_button_new_with_label("Stop Classifying");
62  gtk_widget_set_sensitive(btn_stop,false);
63  g_signal_connect(G_OBJECT(btn_stop),
64  "clicked",
65  G_CALLBACK(CB_stop),
66  (gpointer) this);
67 
68  //----------------------------------------
69  //create boxes
70  GtkWidget * controls_hbox1 = gtk_hbox_new(false,0);
71  GtkWidget * controls_hbox2 = gtk_hbox_new(false,0);
72  GtkWidget * btn_box1 = gtk_hbutton_box_new();
73  GtkWidget * btn_box2 = gtk_hbutton_box_new();
74  gtk_button_box_set_layout(GTK_BUTTON_BOX(btn_box1),GTK_BUTTONBOX_START);
75  gtk_button_box_set_layout(GTK_BUTTON_BOX(btn_box2),GTK_BUTTONBOX_START);
76 
77 
78  //----------------------------------------
79  //pack everything into boxes
80  gtk_box_pack_start(GTK_BOX(btn_box1),btn_train_classifier,false,false,2);
81  gtk_box_pack_start(GTK_BOX(controls_hbox1),btn_box1,false,false,2);
82  source_combo = getView()->getDataSource()->getCombo();
83  gtk_box_pack_end(GTK_BOX(controls_hbox1),source_combo,false,true,2);
84  gtk_box_pack_end(GTK_BOX(controls_hbox1),gtk_label_new("Data Source: "),false,false,2);
85 
86  gtk_box_pack_start(GTK_BOX(btn_box2),btn_start,false,false,2);
87  gtk_box_pack_start(GTK_BOX(btn_box2),btn_stop,false,false,2);
88  gtk_box_pack_start(GTK_BOX(controls_hbox2),btn_box2,false,false,2);
89  //----------------------------------------
90  //add everything to tab
91  controls_box = gtk_vbox_new(false,0);
92  gtk_box_pack_start(GTK_BOX(controls_box), controls_hbox1, true, true, 2);
93  gtk_box_pack_start(GTK_BOX(controls_box), controls_hbox2, true, true, 2);
94 
95 
96  // Training/Using Interfaces
97 
98  //interface combo box
99  this->interface_combo = this->view->getInterfaceCombo()->getCombo();
100  gtk_box_pack_end(GTK_BOX(controls_hbox2),this->interface_combo,false,false,0);
101  this->btn_interface_cfg = this->interface_config->getButton();
102  gtk_box_pack_end(GTK_BOX(controls_hbox2),btn_interface_cfg,false,false,0);
103  gtk_widget_show_all(controls_hbox2);
104 
105  this->interface = NULL;
106 
107  gtk_widget_set_size_request(controls_box,700,-1);
108  TabFrameAdd(controls_box, "Classification Config");
109  TabAdd(interface_box,true,true,0);
110 }
111 
112 
113 
114 //update view from model
116 {
117  this->updating_view = true;
118 
119 
120  //----------------------------------------
121  //update interface
122  //get a pointer to the selected interface
123  EEGInterface* new_interface = this->view->getInterfaceCombo()->getInterface();
124 
125  //if the interface has changed, remove old interface and pack in new one
126  if(new_interface != this->interface)
127  {
128  if(this->interface != NULL)
129  {
130  this->interface->hide();
131  gtk_container_remove(GTK_CONTAINER(this->interface_box),this->interface->getContainer());
132  }
133 
134  this->interface = new_interface;
135  if(this->interface != NULL)
136  {
137  gtk_box_pack_start(GTK_BOX(this->interface_box),this->interface->getContainer(),true,true,0);
138  interface->setBGColor(this->getView()->getBGRED(),
139  this->getView()->getBGGREEN(),
140  this->getView()->getBGBLUE());
141  this->interface->show();
142  this->interface->setUseMode();
143  }
144  }
145 
146  this->updating_view = false;
147  updateInterface();
148 }
149 //----------------------------------------
150 //update the model from the widgets
152 {
153 
154 }
155 
156 //----------------------------------------
157 
158 void TabRealTimeClassification::updateInterface()
159 {
160  if(!updating_view)
161  {
162  int n = this->getView()->getModel()->trainingGetNumClasses();
163  interface->setNumClasses(n);
164  }
165 }
166 
167 //----------------------------------------
168 
169 gint TabRealTimeClassification::timedUpdateInterface(gpointer parent)
170 {
172  CEBLModel * model = tab->getView()->getModel();
173 
174  //ERROR CHECKING
175  bool stopped = !model->realtimeIsClassifying();
176  if(stopped)
177  {
178  tab->CB_stop(NULL,tab);
179  tab->getView()->updateInfoBar();
180  return false;
181  }
182  else //classifying not stopped
183  {
184  if(tab->interface==NULL)
185  {
186  tab->CB_stop(NULL,tab);
187  tab->getView()->updateInfoBar();
188  return false;
189  }
190  else
191  {
192  int selected_class = model->realtimeGetSelectedClass();
193  if(selected_class >= 0)
194  {
195  tab->interface->selectClass(selected_class);
197  }
198  else
199  {
200  std::vector<double> std_props =
202 
203  //nan entries, set to even split
204  if(!(std_props[0] >= 0 || std_props[0] < 0)){
205  for(unsigned int i = 0; i<std_props.size();i++){
206  std_props[i]=1.0/std_props.size();
207  }
208  }
209 
210  ublas::vector<double> proportions =
211  cppR::asUblasVector(std_props);
212  if(proportions.size() > 0)
213  {
214  tab->interface->setClassProportions(std_props);
215  }
216  }
217  }
218  }
219  tab->getView()->updateInfoBar();
220  return true;
221 }
222 //----------------------------------------
223 // Enable and disable controls
224 void TabRealTimeClassification::disableControls()
225 {
226  gtk_widget_set_sensitive(btn_train_classifier,false);
227  gtk_widget_set_sensitive(btn_stop,true);
228  gtk_widget_set_sensitive(btn_start,false);
229  gtk_widget_set_sensitive(interface_combo,false);
230  gtk_widget_set_sensitive(source_combo,false);
231  gtk_widget_set_sensitive(btn_interface_cfg,false);
232 }
233 
234 void TabRealTimeClassification::enableControls()
235 {
236  gtk_widget_set_sensitive(btn_train_classifier,true);
237  gtk_widget_set_sensitive(btn_stop,false);
238  gtk_widget_set_sensitive(btn_start,true);
239  gtk_widget_set_sensitive(interface_combo,true);
240  gtk_widget_set_sensitive(source_combo,true);
241  gtk_widget_set_sensitive(btn_interface_cfg,true);
242 }
243 
244 //----------------------------------------
245 // when the tab becomes hidden, this function is run
246 
248 {
249  this->CB_stop(NULL,this);
250  if(this->interface != NULL)
251  {
252  this->interface->hide();
253  gtk_container_remove(GTK_CONTAINER(this->interface_box),this->interface->getContainer());
254  }
255  this->interface = NULL;
256  this->enableControls();
257  this->view->updateInfoBar();
258 }
259 
260 
261 //----------------------------------------------------------------------
262 // CALLBACKS
263 
264 void TabRealTimeClassification::CB_trainClassifier(GtkWidget *w, gpointer data)
265 {
267  CEBLModel * model = tab->view->getModel();
268  if(!model->trainingDataIsLoaded())
269  {
270  WidgetUtils::AlertError("No Training Data", "There is no training data available. Either load data in training tab or perform a training session.");
271  }
272  //otherwise data is loaded so we can train the classifier
273  else
274  {
275  WidgetUtils::waitBoxShow("Training classifier");
278  while(model->realtimeIsTrainingClassifier())
279  {
280  gtk_main_iteration();
282  {
283  WidgetUtils::waitBoxSetText("Attempting to stop training.\n(This may take awhile.)");
285  gtk_main_iteration();
287  }
288  }
290  }
291  tab->getView()->updateInfoBar();
292 }
293 
294 
295 void TabRealTimeClassification::CB_start(GtkWidget *w, gpointer data)
296 {
298  CEBLModel * model = tab->view->getModel();
299 
300  int nClasses = model->trainingGetNumClasses();
301  int tClasses = model->classifierGetTrainedClasses();
302 
303  /* lags not currently implemented
304  int nLags = model->featureGetParams()["lags"].getInt();
305  int tLags = model->classifierGetTrainedLags();
306  */
307  if(!model->realtimeIsReady())
308  {
309  WidgetUtils::AlertError("Cannot Start Classifciation", "Real-time classification not ready. Make sure you have trained the selected classifier.");
310  }
311  else if(nClasses > tClasses)
312  {
313  std::ostringstream warning;
314  warning << "Real-time classification not ready. Classifier is trained for " << tClasses<< " classes, " << nClasses << " classes selected.";
315  WidgetUtils::AlertError("Cannot Start Classifciation", warning.str() );
316  }
317  /* lags not currently implemented
318  else if (nLags != tLags)
319  {
320  std::ostringstream warning;
321  warning << "Real-time classification not ready. Classifier is trained for " << tLags << " lags, " << nLags << " lags selected.";
322  WidgetUtils::AlertError("Cannot Start Classifciation", warning.str());
323  }
324  */
325  //otherwise classifier is trained on current settings
326  else
327  {
328  if(nClasses<tClasses)
329  {
330  cout<<"Classifier trained for " << tClasses << ". Only the first " << nClasses <<" will be used in classification."<<endl;
331  }
332 
333  try
334  {
335  model->realtimeStartClassifying();
336  }
337  catch(exception & e)
338  {
339  string msg = "There was an error starting the classification process.\n(" + string(e.what()) + "). Make sure you have installed the most recent classifier plugins.";
340  WidgetUtils::AlertError("Error Starting Classification Process", msg);
341  return;
342  }
343  tab->disableControls();
344  g_timeout_add(150, timedUpdateInterface, tab);
345  }
346 }
347 
348 void TabRealTimeClassification::CB_stop(GtkWidget *w, gpointer data)
349 {
351  tab->enableControls();
353  if(tab->interface != NULL)
354  tab->interface->selectTrainingClass(-1);
355 
356 }
357 
358