OpenWalnut  1.5.0dev
WReaderLibeep.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifdef WEEP_ENABLED
26 
27 extern "C"
28 {
29  #include <libeep/cnt/cnt.h>
30 }
31 
32 #include <locale.h>
33 #include <memory>
34 #include <string>
35 
36 #include "WReaderLibeep.h"
37 #include "core/common/WLogger.h"
38 #include "core/dataHandler/WEEG.h"
39 #include "core/dataHandler/exceptions/WDHNoSuchFile.h"
40 
41 WReaderLibeep::WReaderLibeep( std::string fileName )
42  : WReaderEEG( fileName )
43 {
44 }
45 
46 std::shared_ptr< WDataSet > WReaderLibeep::load()
47 {
48  wlog::debug( "Libeep Reader" ) << "Opening " << m_fname;
49 
50  // libeep needs the standard C locale to load float values from ASCII
51  setlocale( LC_NUMERIC, "C" );
52 
53  // initialize
54  FILE* file = fopen( m_fname.c_str(), "rb" );
55  if( !file )
56  {
57  throw WDHNoSuchFile( m_fname + " could not be opened" );
58  }
59  int status;
60  eeg_t* eeg = eep_init_from_file( m_fname.c_str(), file, &status );
61  if( status != CNTERR_NONE || !eeg )
62  {
63  std::ostringstream stream;
64  stream << m_fname << " could not be initialized. Libeep status code: " << status;
65  throw WDHIOFailure( stream.str() );
66  }
67 
68  // read data
69  unsigned int numberOfChannels = eep_get_chanc( eeg );
70  slen_t numberOfSamples = eep_get_samplec( eeg );
71 
72  if( numberOfSamples > 8192 )
73  {
74  // limit maximum size of the dataset
75  // TODO(cornimueller): Don't load EEG data as a whole, use blocks instead
76  // TODO(wiebel): Don't load EEG data as a whole, use blocks instead
77  numberOfSamples = 8192;
78  }
79 
80  sraw_t* buffer = new sraw_t[CNTBUF_ARRAYSIZE( eeg, numberOfSamples )];
81  eep_read_sraw( eeg, DATATYPE_EEG, buffer, numberOfSamples );
82 
83  WEEGChannelLabels channelLabels( numberOfChannels );
84  WEEGSegment segment( numberOfChannels );
85  for( unsigned int channel = 0; channel < numberOfChannels; ++channel )
86  {
87  channelLabels[channel].first = eep_get_chan_label( eeg, channel );
88 
89  double scale = eep_get_chan_scale( eeg, channel );
90  WEEGElectrode electrode( numberOfSamples );
91  for( slen_t sample = 0; sample < numberOfSamples; ++sample )
92  {
93  electrode[sample] = buffer[sample * numberOfChannels + channel] * scale;
94  }
95  segment[channel] = electrode;
96  }
97 
98  // cleanup
99  delete[] buffer;
100  eep_fclose( eeg );
101 
102  WEEGElectrodeLibrary electrodeLibrary = extractElectrodePositions();
103 
104  if( electrodeLibrary.size() != numberOfChannels )
105  {
106  std::ostringstream stream;
107  stream << "Contents of cnt and elc files are not compatible: The cnt has " << numberOfChannels
108  << " channels, but the elc has " << electrodeLibrary.size() << " channels.";
109  throw WDHException( stream.str() );
110  }
111 
112  // construct WEEG object and return it
113  std::shared_ptr< WEEG > out( new WEEG(
114  WEEGSegmentArray( 1, segment ),
115  electrodeLibrary,
116  channelLabels
117  ) );
118  out->setFilename( m_fname );
119  return out;
120 }
121 
122 #endif // WEEP_ENABLED
123 
General purpose exception and therefore base class for all DataHandler related exceptions.
Definition: WDHException.h:40
Use this for IO error handling.
Definition: WDHIOFailure.h:38
File not found exception.
Definition: WDHNoSuchFile.h:38
Contains EEG recording data.
Definition: WEEG.h:71
Abstract base class for all Readers who handle with EEG data.
Definition: WReaderEEG.h:39
WStreamedLogger debug(const std::string &source)
Logging a debug message.
Definition: WLogger.h:331