CEBL  2.1
DataIO.cpp
Go to the documentation of this file.
1 
2 #include <fstream>
3 #include <ctime>
4 #include <boost/regex.hpp>
5 
6 #define BOOST_FILESYSTEM_VERSION 2
7 #include <boost/filesystem/operations.hpp>
8 #include <boost/filesystem/convenience.hpp>
9 #include <boost/filesystem/fstream.hpp>
10 #include <boost/filesystem/path.hpp>
11 #include <boost/lexical_cast.hpp>
12 
13 using namespace std;
14 namespace fs = boost::filesystem;
15 
16 #include "../Exceptions.hpp"
17 #include "DataIO.hpp"
18 #include "EEGTrainingData.hpp"
19 
20 
21 
22 namespace DataIO
23 {
24  //----------------------------------------------------------------------
25 
26  void removeTempDir(string temp_dir)
27  {
28  fs::path full_path;
29  full_path = fs::system_complete(fs::path(temp_dir,
30  fs::native));
31  try
32  {
33  if(fs::exists(full_path))
34  {
35  fs::remove_all(full_path);
36  }
37  }
38  catch(...)
39  {
40  cerr << "Could not delete temp directory...\n";
41  }
42  }
43 
44 
45 
46  //----------------------------------------------------------------------
47 
48 
49  string createTempDir()
50  {
51  //TODO: make more compatible
52  string TEMP = "/tmp";
53  char buffer[] = "/tmp/CEBL-XXXXXX";
54  mkdtemp(buffer);
55  string temp_dir = buffer;
56 
57  fs::path full_path;
58 
59  //set full path to the temp directory
60  full_path = fs::system_complete(fs::path(TEMP, fs::native));
61 
62  //see if temp directory exists
63  if(fs::exists(full_path))
64  {
65  full_path = fs::system_complete(fs::path(temp_dir.c_str(), fs::native));
66  //temp dir does not exist
67  if(!fs::exists(full_path))
68  {
69  try
70  {
71  fs::create_directory(full_path);
72  }
73  catch(...)
74  {
75  cerr << "Failed to create temporary directory.\n";
76  throw FileException("DataIO: Failed to create temp directory.");
77  }
78  }
79  return temp_dir;
80  }
81  else
82  {
83  throw FileException("DataIO: Failed to create temp directory.");
84  }
85  }
86 
87 
88 
89  //----------------------------------------------------------------------
90 
91 
92 
93 
94  void saveTrainingDataToFile(const EEGTrainingData &tdata, string filename)
95  {
96  EEGTrainingData temp;
97  int lags = 0;
98  std::vector<int> components;
99  ublas::matrix<double> filter;
100  saveTrainingSessionToFile(tdata,filename,temp,lags,components,filter);
101  }
102 
103  //----------------------------------------------------------------------
104 
106  void saveTrainingSessionToFile(const EEGTrainingData &unfiltered_data,
107  string filename,
108  const EEGTrainingData &filtered_data,
109  int filter_lags,
110  std::vector<int> filter_removed_components,
111  ublas::matrix<double> filter_matrix)
112  {
113 
114  //decide if filtered data is good
115  bool filtered = filtered_data.numClasses() == unfiltered_data.numClasses();
116 
117 
118  string current_temp_dir = createTempDir();
119 
120 
121  //now create data files
122  for(int cls = 0; cls<unfiltered_data.numClasses(); cls++)
123  {
124  for(int seq=0; seq<unfiltered_data.numSequences(cls); seq++)
125  {
126  stringstream fname;
127  fname << current_temp_dir << "/class-" << cls << "_seq-" << seq;
128  unfiltered_data.getConst(cls,seq).saveToFile(fname.str().c_str());
129  }
130  }
131 
132 
133  //now create data files for filtered data
134  string filter_matrix_filename = current_temp_dir + "/filter";
135  if(filtered)
136  {
137  for(int cls = 0; cls<filtered_data.numClasses(); cls++)
138  {
139  for(int seq=0; seq<filtered_data.numSequences(cls); seq++)
140  {
141  stringstream fname;
142  fname << current_temp_dir << "/filtered_class-"
143  << cls << "_seq-" << seq;
144  filtered_data.getConst(cls,seq).saveToFile(fname.str().c_str());
145  }
146  }
147 
148  //write filter matrix
149  EEGData filt = filter_matrix;
150  filt.saveToFile(filter_matrix_filename.c_str());
151  }
152 
153  //----------------------------------------------------------------------
154  // create data description file
155 
156  stringstream fname;
157  fname << current_temp_dir << "/Description.txt";
158  ofstream desc_file;
159  desc_file.open(fname.str().c_str());
160 
161  //save the date and time
162  time_t rawtime;
163  struct tm * current_tm;
164  time(&rawtime);
165  current_tm = localtime(&rawtime);
166  desc_file << "# Date: " << asctime(current_tm);
167 
168 
169  desc_file << "# Session\n";
170  desc_file << "num_classes = " << unfiltered_data.numClasses() << "\n";
171  desc_file << "num_sequences = " << unfiltered_data.numSequences() << "\n";
172  std::vector<int> ord = unfiltered_data.getSequenceOrder();
173  if(ord.size() > 0)
174  {
175  desc_file << "class_sequence_ordering = ";
176  for(unsigned i=0;i<ord.size();i++)
177  {
178  desc_file << ord[i];
179  if(i != ord.size()-1)
180  desc_file << ", ";
181  }
182  desc_file << "\n";
183  }
184 
185 
186  desc_file << "# Class Labels\n";
187  std::vector<string> labels = unfiltered_data.getClassLabels();
188  if(labels.size() > 0)
189  {
190  for(int i=0; i < unfiltered_data.numClasses(); i++)
191  {
192  desc_file << "class" << i << " = \"" << labels.at(i) << "\"\n";
193  }
194  }
195 
196  std::vector<string> channel_names = unfiltered_data.getChannelNames();
197  desc_file << "# Channel Names\n";
198  if(channel_names.size() > 0)
199  {
200  for(unsigned i=0; i < channel_names.size(); i++)
201  {
202  desc_file << "channel" << i << " = \""
203  << channel_names.at(i) << "\"\n";
204  }
205  }
206 
207  desc_file << "# Data Files Size - CHANNELS x SAMPLES\n";
208  for(int cls = 0; cls<unfiltered_data.numClasses(); cls++)
209  {
210  for(int seq=0; seq<unfiltered_data.numSequences(cls); seq++)
211  {
212  desc_file << "class-" << cls << "_seq-" << seq << " = "
213  << unfiltered_data.getConst(cls,seq).numChannels()
214  << "x"
215  << unfiltered_data.getConst(cls,seq).numSamples()
216  << "\n";
217  }
218  }
219 
220  desc_file << "# Filter\n";
221  desc_file << "filtered_data_included = " << filtered << "\n";
222  if(filtered)
223  {
224  desc_file << "filter_matrix_file = filter\n";
225  desc_file << "filter_matrix_size = " << filter_matrix.size1()
226  << "x" << filter_matrix.size2() << "\n";
227  desc_file << "filter_num_lags = " << filter_lags << "\n";
228  desc_file << "filter_removed_components = ";
229  for(unsigned i=0;i<filter_removed_components.size();i++)
230  {
231  desc_file << filter_removed_components[i];
232  if(i != filter_removed_components.size()-1)
233  desc_file << ", ";
234  }
235  desc_file << "\n";
236  }
237 
238  desc_file.close();
239 
240 
241  //----------------------------------------------------------------------
242 
243  //now tar files and move to specified location
244  string command = "cd " + current_temp_dir +"; tar -cjf "
245  + static_cast<string>(filename) + " ./*";
246  cout << command << endl;
247  system(command.c_str());
248 
249  //remove the temp dir
250  removeTempDir(current_temp_dir);
251  }
252 
253  //----------------------------------------------------------------------
254 
255  //load from file
257  {
258  EEGTrainingData tdata;
259 
260  string current_temp_dir = createTempDir();
261  fs::path full_path;
262  //check that we can open the file
263  string file = filename;
264  full_path = fs::system_complete(fs::path(file,fs::native));
265  if(!fs::exists(full_path))
266  {
267  cerr << "File does not exist.\n";
268  throw FileException("DataIO: File does not exist.");
269  }
270  //now tar files and move to specified location
271  string command = "cd " + current_temp_dir + "; cp "+file+" "
272  + current_temp_dir +"; tar -xjf *.bz2;rm *.bz2";
273  cout << command << endl;
274  system(command.c_str());
275 
276  //now load the data files
277  full_path = fs::system_complete(fs::path(current_temp_dir,
278  fs::native));
279  //loop through directory
280  fs::directory_iterator end_iter;
281  for (fs::directory_iterator dir_itr( full_path );
282  dir_itr != end_iter;
283  ++dir_itr )
284  {
285 
286  //cout << "----------------------------------------\n";
287  //cout << tdata << "\n";
288  try
289  {
290  //make sure file is correctly named
291  string file = dir_itr->leaf();
292 
293  boost::regex filename_regexp("^class-(\\d*)_seq-(\\d*)");
294  //check if this file is a data file
295  if(!regex_search(file,filename_regexp))
296  {
297  continue;
298  }
299 
300  cout << "reading " << file << "\n";
301  //get class and sequence number from fileename
302  boost::cmatch what;
303  regex_match(file.c_str(), what, filename_regexp);
304 
305  int c = 0;
306  int s = 0;
307  try
308  {
309  c = boost::lexical_cast<int>(what[1]);
310  s = boost::lexical_cast<int>(what[2]);
311  }
312  catch(...)
313  {
314  cerr << "failed to load class " << c << " seq " << s << "\n";
315  continue;
316  }
317  //create a new data object
318  EEGData new_data;
319  new_data.loadFromFile(current_temp_dir+"/"+file);
320  tdata.set(c,s,new_data);
321  //cout << "Loaded class " << c << ", sequence " << s << "\n";
322 
323  }
324  catch(const std::exception & ex)
325  {
326  cerr << "Exception: " << ex.what() << "\n";
327  }
328  }
329  cout << tdata << "\n";
330  return tdata;
331  }
332 }
333