CEBL  2.1
ChannelsConfig.cpp
Go to the documentation of this file.
1 #include <fstream>
2 #include <sstream>
3 #include <boost/regex.hpp>
4 #include "../CEBLModel.hpp"
5 #include "ChannelsConfig.hpp"
6 #include "Preferences.hpp"
7 using namespace std;
8 
9 //----------------------------------------------------------------------
10 // Constructors / Destructors
11 
13 {
14  this->model = model;
15  max_num_channels = 24;
16  channels_names.resize(max_num_channels);
17  channels_enabled.resize(max_num_channels);
18  channels_reference.resize(max_num_channels);
19  config_filename = model->getPreferences()->getDefaultChannelsFilename();
20  try
21  {
22  loadFile(config_filename);
23  }
24  catch(...)
25  {
26  cerr << "Error loading default channels file. Enabling 8 channels.\n";
27  for(int i=0;i<8;i++)
28  this->setElectrodeEnabled(i,true);
29  }
30 }
31 
33 {
34 
35 }
36 
37 
38 //----------------------------------------------------------------------
39 //GETTERS
40 
41 
42 
44 {
45  return config_filename;
46 }
47 
48 string ChannelsConfig::getElectrodeName(int electrode)
49 {
50  return channels_names[electrode];
51 }
52 
54 {
55  return channels_enabled[electrode];
56 }
57 
59 {
60  return channels_reference[electrode];
61 }
62 
64 {
65  return max_num_channels;
66 }
67 
69 {
70  int count = 0;
71  for(unsigned int i = 0; i<this->channels_enabled.size();i++)
72  {
73  if(this->channels_enabled[i])
74  count++;
75  }
76  return count;
77 }
78 
79 std::vector<string> ChannelsConfig::getEnabledNames()
80 {
81  std::vector<string> ret;
82  for(unsigned int i = 0; i<this->channels_enabled.size();i++)
83  {
84  if(this->channels_enabled[i])
85  ret.push_back(getElectrodeName(i));
86  }
87  return ret;
88 }
89 
91 {
92  stringstream ss;
93  this->saveConfigToStream(ss);
94  return ss.str();
95 }
96 
97 
98 
99 
100 //----------------------------------------------------------------------
101 //SETTERS
102 
103 
104 
105 
106 void ChannelsConfig::setElectrodeName(int electrode, string name)
107 {
108  channels_names[electrode] = name;
109 }
110 
111 void ChannelsConfig::setElectrodeReference(int electrode, bool enabled)
112 {
113  channels_reference[electrode] = enabled;
114 }
115 
116 void ChannelsConfig::setElectrodeEnabled(int electrode, bool enabled)
117 {
118  channels_enabled[electrode] = enabled;
119 }
120 
122 {
123  stringstream ss;
124  ss << config;
125  this->parseConfigFromStream(ss);
126 }
127 
128 
129 
130 
131 //---------------------------------------------------
132 // LOADING
133 
134 
135 
136 
137 void ChannelsConfig::loadFile(string filename)
138 {
139 
140  //open the file
141  ifstream ifs(filename.c_str());
142  if(!ifs.is_open())
143  {
144  throw FileException("Failed to open \"" + filename + "\".");
145  }
146 
147  if(parseConfigFromStream(ifs))
148  this->config_filename = filename;
149  else
150  {
151  throw FileException("Failed to parse channels config file \""
152  + filename
153  + "\".");
154  }
155 
156 }
157 
158 bool ChannelsConfig::parseConfigFromStream(std::istream &ifs)
159 {
160  bool success = true;
161  vector<string> new_names;
162  vector<bool> new_enabled;
163  vector<bool> new_reference;
164  new_names.resize(channels_names.size());
165  new_enabled.resize(channels_enabled.size());
166  new_reference.resize(channels_reference.size());
167 
168  boost::regex comment_regexp("^[[:space:]]*#.*");
169  boost::regex valid_line_regexp("^[[:space:]]*\\d+[[:space:]]+[\\w|-]+");
170  char buffer[256];
171  string line;
172  int jack = 0;
173  string name("");
174  char ref;
175  char enable;
176  int valid_line_count = 0;
177 
178  try
179  {
180  while(!ifs.eof())
181  {
182  //get next line
183  ifs.getline(buffer,256);
184  line = buffer;
185  //check if this line is a comment
186  if(regex_search(line,comment_regexp))
187  {
188  continue;
189  }
190  if(!regex_search(line,valid_line_regexp))
191  {
192  continue;
193  }
194  else
195  valid_line_count++;
196  stringstream ss_parser(line);
197  //enable exceptions for failure
198  ss_parser.exceptions(ifstream::failbit);
199  //-------------------------
200  try{
201  ss_parser >> jack;
202  }catch(ifstream::failure e){
203  continue;
204  }
205  //-------------------------
206  try{
207  ss_parser >> name;
208  }catch(ifstream::failure e){
209  continue;
210  }
211  //-------------------------
212  try{
213  ss_parser >> ref;
214  }catch(ifstream::failure e){
215  continue;
216  }
217  //-------------------------
218  try{
219  ss_parser >> enable;
220  }catch(ifstream::failure e){
221  continue;
222  }
223  //-------------------------
224  //now we have a whole line
225  if(jack >0 && jack <= max_num_channels)
226  {
227  new_enabled[jack-1] = enable=='y';
228  new_reference[jack-1] = ref=='y' || ref=='r';
229  if(name!="-")
230  new_names[jack-1] = string(name);
231  else
232  new_names[jack-1] = "";
233  }
234 
235  }
236  } catch(...)
237  {
238  success = false;
239  }
240  if(valid_line_count == 0)
241  success = false;
242 
243  //set new values if successful
244  if(success)
245  {
246  channels_names = new_names;
247  channels_enabled = new_enabled;
248  channels_reference = new_reference;
249  }
250  return success;
251 }
252 
253 
254 
255 
256 //--------------------------------------------------
257 // SAVING
258 
259 
260 
261 
262 void ChannelsConfig::saveFile(string filename)
263 {
264  string message;
265  ofstream ofs(filename.c_str());
266  if(!ofs.is_open())
267  {
268  throw FileException("Cannot open file for reading.");
269  }
270 
271  if(!saveConfigToStream(ofs))
272  {
273  throw FileException("Failed to write file.");
274  }
275 }
276 
277 //------------------------------------------------------------------------------
278 bool ChannelsConfig::saveConfigToStream(std::ostream &ofs)
279 {
280  bool success = true;
281  try
282  {
283  ofs << "#\tname\tref\tenable" << endl;
284  for(int i=0; i < max_num_channels; i++)
285  {
286  ofs << i+1 << '\t'
287  << (channels_names[i] == "" ? "-" : channels_names[i]) << '\t'
288  << (channels_reference[i] ? 'y' : '-') << '\t'
289  << (channels_enabled[i] ? 'y' : 'n') << endl;
290  }
291  }
292  catch(...)
293  {
294  success = false;
295  }
296  return success;
297 }