OpenWalnut  1.5.0dev
WReaderBiosig.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 WBIOSIG_ENABLED
26 
27 #include <iostream>
28 #include <memory>
29 #include <string>
30 #include <vector>
31 
32 
33 #include "WReaderBiosig.h"
34 #include "core/common/WAssert.h"
35 #include "core/common/WException.h"
36 #include "core/common/WLogger.h"
37 #include "core/common/WStringUtils.h"
38 #include "core/dataHandler/WEEG.h"
39 #include "core/dataHandler/WSubject.h"
40 
41 WReaderBiosig::WReaderBiosig( std::string fileName )
42  : WReaderEEG( fileName ),
43  m_columns( 0 ),
44  m_rows( 0 )
45 {
46 }
47 
48 void WReaderBiosig::fillSegmentColumnBased( std::vector<std::vector<double> >* segment, biosig_data_type* data )
49 {
50  for( unsigned int i = 0; i < m_columns; ++i )
51  {
52  WEEGElectrode channel( 0 );
53  for( unsigned int j = 0; j < m_rows; ++j )
54  {
55  channel.push_back( data[i*m_rows+j] );
56  }
57  segment->push_back( channel );
58  }
59 }
60 
61 void WReaderBiosig::fillSegmentRowBased( std::vector<std::vector<double> >* segment, biosig_data_type* data )
62 {
63  for( unsigned int j = 0; j < m_rows; ++j )
64  {
65  WEEGElectrode channel( 0 );
66  for( unsigned int i = 0; i < m_columns; ++i )
67  {
68  channel.push_back( data[i*m_rows+j] );
69  }
70  segment->push_back( channel );
71  }
72 }
73 
74 std::shared_ptr< WDataSet > WReaderBiosig::load()
75 {
76  WAssert( m_fname.substr( m_fname.size() - 4 ) == ".edf", "We expect only EDF for the biosig loader so far." );
77 
78  hd = sopen( m_fname.c_str(), "r", 0 );
79 
80 #if( BIOSIG_VERSION >= 10400 )
81  switch( serror2( hd ) )
82 #else
83  switch( B4C_ERRNUM )
84 #endif
85  {
86  case B4C_NO_ERROR:
87  break;
88  case B4C_FORMAT_UNKNOWN:
89  throw WException( std::string( "BIOSIG: Unknown format!" ) );
90  break;
91  case B4C_FORMAT_UNSUPPORTED:
92  throw WException( std::string( "BIOSIG: Unsupported format!" ) );
93  break;
94  case B4C_UNSPECIFIC_ERROR:
95  throw WException( std::string( "BIOSIG: Unspecific error occured!" ) );
96  break;
97  default:
98  throw WException( std::string( "BIOSIG: An error occured! The type is not known to OpenWalnut biosig loader." ) );
99  }
100 
101  if( hd->NRec == -1 )
102  {
103  throw WException( std::string( "Unknown number of blocks in file loaded by biosig!" ) );
104  }
105 
106 
107  bool rowBasedChannels = hd->FLAG.ROW_BASED_CHANNELS;
108  if( rowBasedChannels )
109  {
110  wlog::info( "BIOSIG channels stored as rows." );
111  }
112  else
113  {
114  wlog::info( "BIOSIG channels stored as cols." );
115  }
116 
117  biosig_data_type* DATA = 0;
118  size_t LEN = 1;
119  size_t dummy = sread( DATA, 0, LEN, hd );
120  wlog::info( "BIOSIG" ) << " DataSize " << dummy;
121  size_t nbSamples = LEN*hd->SPR*hd->NS;
122  m_rows = hd->data.size[0];
123  m_columns = hd->data.size[1];
124  wlog::info( "BIOSIG" ) << " nbSamples " << nbSamples;
125 
126 
127  std::vector<std::vector<double> > segment;
128  if( rowBasedChannels )
129  {
130  fillSegmentRowBased( &segment, hd->data.block );
131  }
132  else
133  {
134  fillSegmentColumnBased( &segment, hd->data.block );
135  }
136 
137 
138  std::vector<std::vector<std::vector<double> > > segments( 0 );
139  segments.push_back( segment );
140 
141 
142  WEEGElectrodeLibrary lib = extractElectrodePositions();
143 
144  if( hd->NS != lib.size() )
145  throw WDHException( std::string( "Contents of edf and elc files are not compatible: Different number of channels." ) );
146 
147  WEEGChannelLabels labels( hd->NS );
148  for( unsigned int i = 0; i < hd->NS; ++i )
149  {
150 // std::cout << "BIOSIG Channel Label : " << hd->CHANNEL[i].Label << std::endl;
151  labels[i].first = hd->CHANNEL[i].Label;
152  // TODO(wiebel): set second channel
153  }
154 
155  std::shared_ptr< WEEG > eeg( new WEEG( segments, lib, labels ) );
156  eeg->setFilename( m_fname );
157 
158 
159  wlog::info( "BIOSIG loading done." );
160  return eeg;
161 }
162 
163 #endif
General purpose exception and therefore base class for all DataHandler related exceptions.
Definition: WDHException.h:40
Contains EEG recording data.
Definition: WEEG.h:71
Basic exception handler.
Definition: WException.h:39
Abstract base class for all Readers who handle with EEG data.
Definition: WReaderEEG.h:39
WStreamedLogger info(const std::string &source)
Logging an information message.
Definition: WLogger.h:320