OpenWalnut  1.5.0dev
WPagerEEGLibeep.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 <clocale>
33 #include <cstddef>
34 #include <cstdio>
35 #include <iostream>
36 #include <memory>
37 #include <sstream>
38 #include <string>
39 #include <vector>
40 
41 
42 #include "WPagerEEGLibeep.h"
43 #include "core/common/exceptions/WOutOfBounds.h"
44 #include "core/dataHandler/WEEGValueMatrix.h"
45 #include "core/dataHandler/exceptions/WDHIOFailure.h"
46 #include "core/dataHandler/exceptions/WDHNoSuchFile.h"
47 
48 
49 WPagerEEGLibeep::WPagerEEGLibeep( std::string fileName )
50  : WPagerEEG( fileName )
51 {
52  // libeep needs the standard C locale to load float values from ASCII
53  std::setlocale( LC_NUMERIC, "C" );
54 
55  // initialize
56  std::FILE* file = std::fopen( getFilename().c_str(), "rb" );
57  if( !file )
58  {
59  throw WDHNoSuchFile( getFilename() + " could not be opened" );
60  }
61 
62  int status;
63  m_eeg = eep_init_from_file( getFilename().c_str(), file, &status );
64  if( status != CNTERR_NONE || !m_eeg )
65  {
66  std::ostringstream stream;
67  stream << getFilename() << " could not be initialized. Libeep status code: " << status;
68  throw WDHIOFailure( stream.str() );
69  }
70 
71  m_nbChannels = eep_get_chanc( m_eeg );
72  m_nbSamples = eep_get_samplec( m_eeg );
73 
74  m_scales = std::vector< double >( m_nbChannels );
75  for( size_t channelID = 0; channelID < m_nbChannels; ++channelID )
76  {
77  m_scales[channelID] = eep_get_chan_scale( m_eeg, channelID );
78  }
79 }
80 
81 WPagerEEGLibeep::~WPagerEEGLibeep()
82 {
83  // cleanup
84  int status = eep_fclose( m_eeg );
85  if( status != CNTERR_NONE )
86  {
87  std::cout << getFilename() << " could not be closed. Libeep status code: " << status << std::endl;
88  }
89 }
90 
91 std::size_t WPagerEEGLibeep::getNumberOfSegments() const
92 {
93  return 1;
94 }
95 
96 std::size_t WPagerEEGLibeep::getNumberOfChannels() const
97 {
98  return m_nbChannels;
99 }
100 
101 std::size_t WPagerEEGLibeep::getNumberOfSamples( std::size_t segmentID ) const
102 {
103  if( segmentID != 0 )
104  {
105  std::ostringstream stream;
106  stream << getFilename() << " has no segment number " << segmentID;
107  throw WOutOfBounds( stream.str() );
108  }
109 
110  return m_nbSamples;
111 }
112 
113 std::shared_ptr< WEEGValueMatrix > WPagerEEGLibeep::getValues( std::size_t segmentID, std::size_t start, std::size_t length ) const
114 {
115  if( segmentID != 0 )
116  {
117  std::ostringstream stream;
118  stream << getFilename() << " has no segment number " << segmentID;
119  throw WOutOfBounds( stream.str() );
120  }
121 
122  if( start + length > m_nbSamples )
123  {
124  std::ostringstream stream;
125  stream << "Could not read sample number " << start + length - 1 << " of file " << getFilename()
126  << ", it only has " << m_nbSamples << " samples";
127  throw WOutOfBounds( stream.str() );
128  }
129 
130  int status = eep_seek( m_eeg, DATATYPE_EEG, start, 0 );
131  if( status != CNTERR_NONE )
132  {
133  std::ostringstream stream;
134  stream << "Seek error on " << getFilename() << ". Libeep status code: " << status;
135  throw WDHIOFailure( stream.str() );
136  }
137 
138  sraw_t* buffer = new sraw_t[CNTBUF_ARRAYSIZE( m_eeg, length )];
139  status = eep_read_sraw( m_eeg, DATATYPE_EEG, buffer, length );
140  if( status != CNTERR_NONE )
141  {
142  std::ostringstream stream;
143  stream << "Read error on " << getFilename() << ". Libeep status code: " << status;
144  throw WDHIOFailure( stream.str() );
145  }
146 
147  std::shared_ptr< WEEGValueMatrix > values( new WEEGValueMatrix( m_nbChannels, std::vector< double >( length ) ) );
148  for( size_t channelID = 0; channelID < m_nbChannels; ++channelID )
149  {
150  for( size_t sampleID = 0; sampleID < length; ++sampleID )
151  {
152  (*values)[channelID][sampleID] = buffer[sampleID * m_nbChannels + channelID] * m_scales[channelID];
153  }
154  }
155  delete[] buffer;
156 
157  return values;
158 }
159 
160 double WPagerEEGLibeep::getSamplingRate() const
161 {
162  return eep_get_rate( m_eeg );
163 }
164 
165 std::string WPagerEEGLibeep::getChannelUnit( std::size_t channelID ) const
166 {
167  if( channelID >= m_nbChannels )
168  {
169  std::ostringstream stream;
170  stream << getFilename() << " has no channel number " << channelID;
171  throw WOutOfBounds( stream.str() );
172  }
173 
174  return eep_get_chan_unit( m_eeg, channelID );
175 }
176 
177 std::string WPagerEEGLibeep::getChannelLabel( std::size_t channelID ) const
178 {
179  if( channelID >= m_nbChannels )
180  {
181  std::ostringstream stream;
182  stream << getFilename() << " has no channel number " << channelID;
183  throw WOutOfBounds( stream.str() );
184  }
185 
186  return eep_get_chan_label( m_eeg, channelID );
187 }
188 
189 #endif // WEEP_ENABLED
Use this for IO error handling.
Definition: WDHIOFailure.h:38
File not found exception.
Definition: WDHNoSuchFile.h:38
Indicates invalid element access of a container.
Definition: WOutOfBounds.h:37
Abstract class to load an EEG file and keep it open to support paging.
Definition: WPagerEEG.h:41
std::vector< std::vector< double > > WEEGValueMatrix
Values of an EEG.