Codebase list libgdf / 892b314
Merge branch 'debian', remote branch 'trunk' into debian-release * debian: deprecating patches -- absorbed upstream adjusting debian/changelog -- I guess upstream is getting closer to release now, so ~ ;-) do use RPATH while building with cmake -- needed for tests adjusting changelog enable testing while building libgdf adding patches submitted upstream + inverting for known to fail testRWConsistency until it is fixed deprecate patch versioned_dynlib -- upstreamed changelog mv neuroscience-electrophysiology electrophysiology added basic debian/blends * trunk: (26 commits) changed cmake version requirement to 2.8 (that's the version i'm working and testing with) Consistency test works now. (shoulda have closed the file before comparing...) throwing exception if version is not equal to "GDF 2.10" applied Yaroslav's patches to the testing framework. Wether to build and use tests is now a cmake option. Testfail now fails correctly. removed test tests from tests :) throwing general exception in reader if gdf version is smaller than 2 added EventConverter files.. ;) added EventConverter function to convert mode 1 events into mode 3 events fixed header_issues::what( ) returning the reference to a temporary string. Now the record cache should be correctly emptied upon destruction of the Reader instance. added test for file consistency (which keeps failing...) probably fixed linker issues with gdf_merger and boost on windows added sample gdf file improved matlab examples the temporary .events file now gets deleted when the events were successfully written to the .gdf added README added test framework added members to check for the number of warnings and errors in a header issues exception. fixed default value for sampling rate added Makefile to build Matlab routines ... Yaroslav Halchenko 13 years ago
32 changed file(s) with 793 addition(s) and 50 deletion(s). Raw diff Collapse all Expand all
00 cmake_minimum_required( VERSION 2.8 )
1 project( GDF )
1 #project( GDF )
2
3 option( BUILD_TESTING "Build tests" OFF )
24
35 set( BUILD_SHARED_LIBS true CACHE BOOL "Wether we shall build shared or dynamic libraries." )
6
7 set( GDF_SOURCE_ROOT ${Project_SOURCE_DIR} )
48
59 add_subdirectory( libgdf )
610 add_subdirectory( tools )
711
12 # shared library API versioning (soversion) -- NOT the same as the release version
13 # it follows first number
14 set(GDF_VERSION "0.1.1")
15 string( REGEX MATCH "^[0-9]+" GDF_SHAREDLIB_SOVERSION ${GDF_VERSION})
16
17 set_target_properties(GDF PROPERTIES
18 VERSION ${GDF_VERSION}
19 SOVERSION ${GDF_SHAREDLIB_SOVERSION})
20
21 if (BUILD_TESTING)
22 include( CTest )
23 enable_testing( )
24 add_subdirectory( test )
25 endif()
0 #
1 # This file is part of libGDF.
2 #
3 # libGDF is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Lesser General Public License as
5 # published by the Free Software Foundation, either version 3 of
6 # the License, or (at your option) any later version.
7 #
8 # libGDF is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU Lesser General Public License for more details.
12 #
13 # You should have received a copy of the GNU Lesser General Public License
14 # along with libGDF. If not, see <http://www.gnu.org/licenses/>.
15 #
16 # Copyright 2010 Martin Billinger
17
18
19 A. Build Instructions (out of source build)
20
21 replace $GDF_ROOT with the (relative or absolute) path to the source
22 tree (e.g. ~/SVN/GDF/trunk).
23
24 > mkdir build
25 > cd build
26 > cmake $GDF_ROOT
27 > make
28 > make check
0 Format: extended
1 Tasks: debian-science/electrophysiology,
2 debian-med/imaging-dev
3 Depends: libgdf-dev
4 Pkg-URL: http://neuro.debian.net/pkgs/%(Pkg-Name)s.html
5 Language: C++, Octave/Matlab
6
0 libgdf (0.1.1~svn62-1) UNRELEASED; urgency=low
1
2 * Fresh upstream snapshot (needed for sigviewer 0.5.0)
3 * Patches submitted and adopted upstream:
4 - 0001-make-explicit-option-either-to-build-include-tests
5 - 0002-testfail-must-fail-so-lets-state-that
6
7 -- Yaroslav Halchenko <debian@onerussian.com> Wed, 22 Dec 2010 12:23:40 -0500
8
09 libgdf (0.1.0~svn31-1) UNRELEASED; urgency=low
110
211 * Initial release (Closes: #601707)
0 versioned_dynlib
+0
-25
debian/patches/versioned_dynlib less more
0 From: Yaroslav Halchenko <debian@onerussian.com>
1 Subject: Versioned (0.1.0 ATM) GDF target and corresponding dynamic library
2
3 Add later on separate SOVERSION if it needs to diverge.
4
5 ---
6 The information above should follow the Patch Tagging Guidelines, please
7 checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
8 are templates for supplementary fields that you might want to add:
9
10 --- a/CMakeLists.txt
11 +++ b/CMakeLists.txt
12 @@ -6,3 +6,12 @@ set( BUILD_SHARED_LIBS true CACHE BOOL "
13 add_subdirectory( libgdf )
14 add_subdirectory( tools )
15
16 +# shared library API versioning (soversion) -- NOT the same as the release version
17 +# it follows first number
18 +SET(GDF_VERSION "0.1.0")
19 +STRING( REGEX MATCH "^[0-9]+" GDF_SHAREDLIB_SOVERSION ${GDF_VERSION})
20 +
21 +SET_TARGET_PROPERTIES(GDF PROPERTIES
22 + VERSION ${GDF_VERSION}
23 + SOVERSION ${GDF_SHAREDLIB_SOVERSION})
24 +
1313 UVER = $(shell LC_ALL=C dpkg-parsechangelog | grep '^Version:' | cut -d ' ' -f 2,2 | cut -d '-' -f 1,1)
1414
1515 DEB_CMAKE_EXTRA_FLAGS = \
16 -DCMAKE_SKIP_RPATH:BOOL=ON \
17 -DBUILD_SHARED_LIBS:BOOL=ON
16 -DBUILD_SHARED_LIBS:BOOL=ON \
17 -DBUILD_TESTING:BOOL=ON
1818
1919 # OCTDIR=$(shell octave-config --oct-site-dir)
2020 # get octave paths (have to build-depend on octave-headers)
589589 # directories like "/usr/src/myproject". Separate the files or directories
590590 # with spaces.
591591
592 INPUT = ../libgdf
592 INPUT = ../../libgdf
593593
594594 # This tag can be used to specify the character encoding of the source files
595595 # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
0 cmake_minimum_required( VERSION 2.6 )
0 cmake_minimum_required( VERSION 2.8 )
11 project( GDF )
22
33 if( UNIX )
4 add_definitions( -Wall -Wextra -pedantic -Werror -fPIC)
4 add_definitions( -Wall -Wextra -pedantic -Werror -fPIC -O2 )
55 elseif( MINGW )
6 add_definitions( -Wall -Wextra -pedantic -Werror )
6 add_definitions( -Wall -Wextra -pedantic -Werror -O2 )
77 elseif( WIN32 )
8 add_definitions( -W3 )
8 add_definitions( -W3 -O2 )
99 endif( UNIX )
1010
1111 #set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${GDF_SOURCE_DIR}/lib )
3838 include/GDF/tools.h
3939 include/GDF/Types.h
4040 include/GDF/Writer.h
41 include/GDF/EventConverter.h
4142 )
4243
4344 set( SOURCES
5253 src/SignalHeader.cpp
5354 src/Types.cpp
5455 src/Writer.cpp
56 src/EventConverter.cpp
5557 )
5658
5759 add_library( GDF ${HEADERS} ${SOURCES} ${Boost_LIBRARIES} )
0 //
1 // This file is part of libGDF.
2 //
3 // libGDF is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU Lesser General Public License as
5 // published by the Free Software Foundation, either version 3 of
6 // the License, or (at your option) any later version.
7 //
8 // libGDF is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public License
14 // along with libGDF. If not, see <http://www.gnu.org/licenses/>.
15 //
16 // Copyright 2010 Christoph Eibel
17
18 #ifndef __EVENTCONVERTER_H_INCLUDED__
19 #define __EVENTCONVERTER_H_INCLUDED__
20
21 #include "EventHeader.h"
22 #include "Exceptions.h"
23
24 #include <vector>
25
26 namespace gdf
27 {
28 //-------------------------------------------------------------------------
29 /// @brief converts a vector of mode 1 events into mode 3 events
30 /// using the flag 0x8000 which marks the type of mode 1 stop events
31 /// @throws general if events could not be converted
32 std::vector<Mode3Event> convertMode1EventsIntoMode3Events (std::vector<Mode1Event>
33 const& mode_1_events)
34 throw (exception::general);
35 }
36
37 #endif
1313 // You should have received a copy of the GNU Lesser General Public License
1414 // along with libGDF. If not, see <http://www.gnu.org/licenses/>.
1515 //
16 // Copyright 2010 Martin Billinger
16 // Copyright 2010 Martin Billinger, Christoph Eibel
1717
1818 #ifndef __EVENTHEADER_H_INCLUDED__
1919 #define __EVENTHEADER_H_INCLUDED__
8585 /// Returns a Mode 1 Event
8686 void getEvent( uint32 index, Mode1Event &ev );
8787
88 /// Returns all Mode 1 Events
89 std::vector<Mode1Event> getMode1Events () const;
90
91 /// Returns all Mode 3 Events
92 std::vector<Mode3Event> getMode3Events () const;
93
8894 /// Returns a Mode 3 Event
8995 void getEvent( uint32 index, Mode3Event &ev );
9096
179179 wrong_eventmode( std::string str ) : domain_error("Wrong event mode: "+str) { }
180180 };
181181
182 ///
183 class incompatible_gdf_version : public general
184 {
185 public:
186 incompatible_gdf_version (std::string version_of_file) :
187 general ("Version \""+version_of_file+"\" not supported!"),
188 version_of_file_ (version_of_file) {}
189
190 virtual ~incompatible_gdf_version () throw () {}
191
192 std::string getVersionOfFile () {return version_of_file_;}
193 private:
194 std::string version_of_file_;
195 };
196
182197 /// Header Issues
183198 class header_issues : public std::exception
184199 {
195210
196211 virtual ~header_issues( ) throw() { }
197212
198 const char *what( ) const throw()
213 void generate_message( )
199214 {
200215 std::stringstream ss;
201216 std::list< std::string >::const_iterator it;
202217 if( warnings.size( ) > 0 )
203 ss << "Warnings: " << std::endl;
218 ss << std::string("Warnings: ") << std::endl;
204219 for( it=warnings.begin(); it!=warnings.end(); it++ )
205220 ss << " -> " << *it << std::endl;
206221
210225 for( it=errors.begin(); it!=errors.end(); it++ )
211226 ss << " -> " << *it << std::endl;
212227 }
213 return ss.str( ).c_str( );
228
229 std::string str = ss.str( );
214230 }
231
232 const char *what( ) const throw()
233 {
234 return str.c_str( );
235 }
236
237 size_t num_warnings( ) { return warnings.size(); }
238 size_t num_errors( ) { return errors.size(); }
239
240 private:
241 std::string str;
215242 };
216243 }
217244 }
0 //
1 // This file is part of libGDF.
2 //
3 // libGDF is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU Lesser General Public License as
5 // published by the Free Software Foundation, either version 3 of
6 // the License, or (at your option) any later version.
7 //
8 // libGDF is distributed in the hope that it will be useful,
9 // but WITHout ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public License
14 // along with libGDF. If not, see <http://www.gnu.org/licenses/>.
15 //
16 // Copyright 2010 Christoph Eibel
17
18 #include "GDF/EventConverter.h"
19 #include "GDF/Types.h"
20
21 #include <map>
22 #include <vector>
23 #include <algorithm>
24
25 using namespace std;
26
27 namespace gdf
28 {
29 typedef map<uint16, vector<Mode1Event> > TypeEventMap;
30
31 uint16 const STOP_FLAG = 0x8000;
32 uint16 const NOT_STOP_FLAG = 0x7FFF;
33
34 //-------------------------------------------------------------------------
35 vector<Mode3Event> convertMode1EventsIntoMode3Events (vector<Mode1Event> const& mode_1_events)
36 throw (exception::general)
37 {
38 vector<Mode3Event> mode_3_events;
39
40 TypeEventMap type_event_map;
41
42 for (size_t index = 0; index < mode_1_events.size (); index++)
43 {
44 Mode1Event const& event_1 = mode_1_events[index];
45 type_event_map[event_1.type & NOT_STOP_FLAG].push_back (event_1);
46 }
47
48 for (TypeEventMap::iterator iter = type_event_map.begin ();
49 iter != type_event_map.end (); ++iter)
50 {
51 sort (iter->second.begin (), iter->second.end ());
52 for (unsigned index = 0; index < iter->second.size (); index++)
53 {
54 if (iter->second[index].type & STOP_FLAG)
55 throw exception::general ("events could not be converted from mode 1 to mode 3");
56 // throw exception::general ("events of same type are overlapping, not supported for mode 1 events");
57
58 Mode3Event event_3;
59 event_3.channel = 0; // ALL CHANNELS
60 event_3.type = iter->first;
61 event_3.position = iter->second[index].position;
62 mode_3_events.push_back (event_3);
63
64 if (iter->second[index+1].type == (iter->first | STOP_FLAG))
65 {
66 event_3.duration = iter->second[index + 1].position - event_3.position;
67 index++;
68 }
69 else
70 event_3.duration = 0;
71 }
72 }
73
74 return mode_3_events;
75 }
76 }
1313 // You should have received a copy of the GNU Lesser General Public License
1414 // along with libGDF. If not, see <http://www.gnu.org/licenses/>.
1515 //
16 // Copyright 2010 Martin Billinger
16 // Copyright 2010 Martin Billinger, Christoph Eibel
1717
1818 #include "GDF/EventHeader.h"
1919 #include "GDF/Exceptions.h"
161161 }
162162 }
163163
164 //-------------------------------------------------------------------------
165 std::vector<Mode1Event> EventHeader::getMode1Events () const
166 {
167 return m_mode1;
168 }
169
170 //-------------------------------------------------------------------------
171 std::vector<Mode3Event> EventHeader::getMode3Events () const
172 {
173 return m_mode3;
174 }
175
176 //-------------------------------------------------------------------------
164177 void EventHeader::getEvent( uint32 index, Mode1Event &ev )
165178 {
166179 if( m_mode != 1 )
378378
379379 MainHeader *mh = &hdr.m_mainhdr;
380380 mh->version_id.fromstream( in );
381 if (mh->get_version_id() != "GDF 2.10")
382 throw exception::incompatible_gdf_version (mh->get_version_id ());
381383 mh->patient_id.fromstream( in );
382384 mh->reserved_1.fromstream( in );
383385 mh->patient_drugs.fromstream( in );
1818 #include "GDF/Reader.h"
1919 #include "GDF/tools.h"
2020 #include <boost/numeric/conversion/cast.hpp>
21 #include <boost/lexical_cast.hpp>
2122 //#include <iostream>
2223
2324 namespace gdf
3536
3637 Reader::~Reader( )
3738 {
39 resetCache( );
3840 if( m_record_nocache ) delete m_record_nocache;
3941 if( m_events ) delete m_events;
4042 }
99101 {
100102 resetCache( );
101103 m_record_cache.clear( );
102 size_t num_records = boost::numeric_cast<size_t>( m_header.getMainHeader_readonly().get_num_datarecords() );
104 size_t num_records = boost::numeric_cast<size_t>( m_header.getMainHeader_readonly().get_num_datarecords() );
103105 m_record_cache.resize( num_records, NULL );
104106 }
105107
5959 sensor_pos[2] = 0;
6060 set_sensor_info( 0 );
6161 memset( reserved_2.item, 0, reserved_2.len );
62
63 samplerate = 0;
6264 }
6365
6466 //===================================================================================================
7575 }
7676 }
7777
78 m_file.clear( );
79
7880 m_file.open( m_filename.c_str(), std::ios_base::out | std::ios_base::binary | std::ios_base::trunc );
81
82 if( m_file.fail() )
83 {
84 throw std::invalid_argument( "Error opening file for writing." );
85 }
7986
8087 m_eventbuffermemory = flags & writer_ev_memory;
8188 if( m_eventbuffermemory )
133140 writeEvents( );
134141
135142 if( !m_eventbuffermemory )
143 {
136144 m_evbuf_file.close( );
145 remove( (m_filename+".events").c_str() );
146 }
137147
138148 m_header.setLock( false );
139149
0 #
1 # build matlab functions using matlab's mex tool
2 #
3 # issues:
4 # * MEX automatically appends the arch dependent suffix (.mexglx, .mexa64, etc.)
5 # How can we make the Makefile aware of the correct suffix? (Hardcoded for now)
6 #
7 # * The libGDF binaries are put where the user chooses to build the library with cmake.
8 # Putting the binaries into a specific location inside the source tree would probably
9 # be the easiest solution, but is not pretty. (For now the search path is hardcoded to
10 # ../build)
11 #
12 # * Location of matlab installation: How can this be determined?
13 #
14
15
16 SOURCEDIR = .
17 OUTDIR = .
18 OBJDIR = build
19
20 MEXSUFFIX = mexa64
21
22 GDF_INCLUDE_DIR = -I../libgdf/include
23 GDF_LIB_DIR = -L../build/libgdf
24 GDF_LIBS = -lGDF
25
26 MATLABROOT = /opt/matlab/R2010b
27 MATLAB_INCLUDE_DIR = -I$(MATLABROOT)/extern/include
28
29 MEXTOOL = $(MATLABROOT)/bin/mex
30
31 CXXFLAGS = -c -cxx -O -DNDEBUG
32 LDFLAGS =
33
34 all: $(OUTDIR)/gdf_reader.$(MEXSUFFIX) $(OUTDIR)/gdf_writer.$(MEXSUFFIX)
35
36 clean:
37 rm -rf $(OBJDIR) $(OUTDIR)/gdf_reader.$(MEXSUFFIX) $(OUTDIR)/gdf_writer.$(MEXSUFFIX)
38
39 buildclean:
40 rm -rf $(OBJDIR)
41
42 $(OUTDIR)/gdf_reader.$(MEXSUFFIX): $(OBJDIR)/gdf_reader.o
43 $(MEXTOOL) -cxx $(LDFLAGS) $(GDF_LIB_DIR) $(GDF_LIBS) -outdir $(OUTDIR) -output $@ $^
44
45 $(OUTDIR)/gdf_writer.$(MEXSUFFIX): $(OBJDIR)/gdf_writer.o
46 $(MEXTOOL) -cxx $(LDFLAGS) $(GDF_LIB_DIR) $(GDF_LIBS) -outdir $(OUTDIR) -output $@ $^
47
48 $(OBJDIR)/gdf_reader.o: $(SOURCEDIR)/gdf_reader.cpp
49 $(MEXTOOL) $(CXXFLAGS) $(MATLAB_INCLUDE_DIR) $(GDF_INCLUDE_DIR) -outdir $(OBJDIR) $^
50
51 $(OBJDIR)/gdf_writer.o: $(SOURCEDIR)/gdf_writer.cpp
52 $(MEXTOOL) $(CXXFLAGS) $(MATLAB_INCLUDE_DIR) $(GDF_INCLUDE_DIR) -outdir $(OBJDIR) $^
0 function gdf_resample( fs_new, inputfile, outputfile )
0 function gdf_resample( fs_new, inputfile, outputfile, datatype )
11
22 % 1. load gdf file
33
1717
1818 signals{c} = resample( signals{c}, P, Q );
1919
20 header.signals(c).sampling_rate = fs_new;
20 header.signals(c).sampling_rate = fs_new;
21
22 % better adjust physmin and physmax, as the signal may locally
23 % increase in amplitude due to the anti aliasing filter.
24 header.signals(c).physmin = min(signals{c});
25 header.signals(c).physmax = max(signals{c});
26
27 if exist( 'datatype', 'var' )
28 header.signals(c).datatype = datatype;
29 switch datatype
30 case 1, header.signals(c).digmin=-128; header.signals(c).digmax=127;
31 case 2, header.signals(c).digmin=0; header.signals(c).digmax=256;
32 case 3, header.signals(c).digmin=-32768; header.signals(c).digmax=32767;
33 case 4, header.signals(c).digmin=0; header.signals(c).digmax=65536;
34 case 5, header.signals(c).digmin=-2147483648; header.signals(c).digmax=2147483647;
35 case 6, header.signals(c).digmin=0; header.signals(c).digmax=4294967295;
36 case 7, header.signals(c).digmin=-9223372036854775808; header.signals(c).digmax=9223372036854775807;
37 case 8, header.signals(c).digmin=0; header.signals(c).digmax=18446744073709551615;
38 case 16, header.signals(c).digmin=-1; header.signals(c).digmax=1;
39 case 17, header.signals(c).digmin=-1; header.signals(c).digmax=1;
40 end
41 end
2142 end
2243
2344 % 3. fix event positions
4162
4263 gdf_writer( 'open', handle, outputfile );
4364
44 for c = 1 : num_channels
45 gdf_writer( 'blitsamples', handle, c, signals{c} );
65 % for c = 1 : num_channels
66 % gdf_writer( 'blitsamples', handle, c, signals{c} );
67 % end
68
69 chunksize = 512;
70 num_chunks = ceil(size(signals{1},2) / chunksize);
71
72 for d = 1 : num_chunks
73 for c = 1 : num_channels
74 start = (d-1)*chunksize + 1;
75 ende = min( d*chunksize, size(signals{1},2) );
76 gdf_writer( 'blitsamples', handle, c, signals{c}(start:ende) );
77 end
4678 end
4779
4880 if events.mode == 1
5183 end
5284 elseif events.mode == 3
5385 for e = 1 : length( events.position )
54 gdf_writer( 'mode1ev', handle, events.position(e), events.event_code(e), events.channel(e), events.duration(e) );
86 gdf_writer( 'mode3ev', handle, events.position(e), events.event_code(e), events.channel(e), events.duration(e) );
5587 end
5688 end
5789
0 function gdf_spatial( filtermatrix, inputfile, outputfile, labels )
1
2 % apply spatial filter matrix to a gdf
3
4 % load gdf file
5
6 [signals, header, events] = gdf_reader( inputfile, 'dataformat', 'matrix' );
7
8 num_channels = size( filtermatrix, 1 );
9
10 % apply filter
11
12 signals = filtermatrix * signals;
13
14 header.signals( num_channels+1 : end ) = [];
15
16 for c = 1 : num_channels
17 header.signals( c ).label = labels{c};
18 end
19
20 % 4. save new gdf
21
22 handle = gdf_writer( 'init' );
23
24 for c = 1 : num_channels
25 gdf_writer( 'createsignal', handle, c );
26 end
27
28 gdf_writer( 'setheader', handle, header );
29
30 gdf_writer( 'recordduration', handle, 0 ); % automatic record duration
31
32 gdf_writer( 'eventconfig', handle, events.mode, events.sample_rate );
33
34 gdf_writer( 'open', handle, outputfile );
35
36
37
38 chunksize = 512;
39 num_chunks = ceil(size(signals,2) / chunksize);
40
41 for d = 1 : num_chunks
42 for c = 1 : num_channels
43 start = (d-1)*chunksize + 1;
44 ende = min( d*chunksize, size(signals,2) );
45 gdf_writer( 'blitsamples', handle, c, signals(c,start:ende) );
46 end
47 end
48
49 if events.mode == 1
50 for e = 1 : length( events.position )
51 gdf_writer( 'mode1ev', handle, events.position(e), events.event_code(e) );
52 end
53 elseif events.mode == 3
54 for e = 1 : length( events.position )
55 gdf_writer( 'mode3ev', handle, events.position(e), events.event_code(e), events.channel(e), events.duration(e) );
56 end
57 end
58
59 gdf_writer( 'close', handle );
60
61 gdf_writer( 'clear', handle );
62
63 end
2121 #include "matlab_tools/mxStructAccess.h"
2222 #include <GDF/Writer.h>
2323 #include <mex.h>
24 #include "math.h"
2425
2526 using namespace std;
27
28 #ifndef trunc
29 inline double trunc( const double a ) { return floor( a ); }
30 #endif
31
32 #ifdef _WIN32
33 inline bool isfinite( const double a ) { return _finite( a ); }
34 #endif
2635
2736 // ===================================================================================================
2837 // Object Interface to mex
5665 class CMD_getheader : public Command { void execute( mxArray *plhs[], const mxArray *prhs[] ); };
5766 class CMD_setheader : public Command { void execute( mxArray *plhs[], const mxArray *prhs[] ); };
5867 class CMD_createsignal : public Command { void execute( mxArray *plhs[], const mxArray *prhs[] ); };
68 class CMD_newsignal : public Command { void execute( mxArray *plhs[], const mxArray *prhs[] ); };
5969 class CMD_recduration : public Command { void execute( mxArray *plhs[], const mxArray *prhs[] ); };
6070 class CMD_eventconfig : public Command { void execute( mxArray *plhs[], const mxArray *prhs[] ); };
6171 class CMD_addsample : public Command { void execute( mxArray *plhs[], const mxArray *prhs[] ); };
90100 commands.registerCommand( "Clear", new CMD_clear( ), 0, 1 );
91101 commands.registerCommand( "Clear All", new CMD_clearall( ), 0, 0 );
92102 commands.registerCommand( "CreateSignal", new CMD_createsignal( ), 0, 2 );
103 commands.registerCommand( "NewSignal", new CMD_newsignal( ), 1, 3 );
93104 commands.registerCommand( "Open", new CMD_open( ), 0, 2 );
94105 commands.registerCommand( "Close", new CMD_close( ), 0, 1 );
95106 commands.registerCommand( "GetHeader", new CMD_getheader( ), 1, 1 );
173184 w->createSignal( channel - 1, true );
174185 }
175186
176 void CMD_recduration::execute( mxArray ** /*plhs*/, const mxArray *prhs[] )
187 void CMD_newsignal::execute( mxArray *plhs[], const mxArray *prhs[] )
188 {
189 size_t handle = mx::getNumeric<size_t>( prhs[0] );
190 gdf::uint32 type = mx::getNumeric<gdf::uint32>( prhs[1] );
191 gdf::uint32 fs = mx::getNumeric<gdf::uint32>( prhs[2] );
192 gdf::Writer *w = CmexObject::getInstance().writers.get( handle );
193 size_t channel = w->getFirstFreeSignalIndex( );
194 w->createSignal( channel, true );
195 plhs[0] = mxCreateNumericMatrix( 1, 1, mxUINT64_CLASS, mxREAL );
196 *reinterpret_cast<size_t*>(mxGetData( plhs[0] )) = channel + 1;
197
198 w->getSignalHeader(channel).set_datatype( type );
199 w->getSignalHeader(channel).set_samplerate( fs );
200 }
201
202 void CMD_recduration::execute( mxArray ** /*plhs[]*/, const mxArray *prhs[] )
177203 {
178204 size_t handle = mx::getNumeric<size_t>( prhs[0] );
179205 gdf::Writer *w = CmexObject::getInstance().writers.get( handle );
2525 % SETHEADER: set header struct
2626 % gdf_writer( 'SetHeader', handle, header );
2727 %
28 % CREATESIGNAL: create a new signal
28 % CREATESIGNAL: create a new signal (with specified index)
2929 % gdf_writer( 'CreateSignal', handle, index );
30 %
31 % NEWSIGNAL: create a new signal (with first free index, which is returned)
32 % index = gdf_writer( 'NewSignal', handle, datatype, samplerate );
3033 %
3134 % RECORDDURATION: set record duration
3235 % gdf_writer( 'RecordDuration', handle, seconds );
Binary diff not shown
0 cmake_minimum_required( VERSION 2.8 )
1 project( gdf_tests )
2
3 if( UNIX )
4 add_definitions( -Wall -Wextra -pedantic -Werror -fPIC)
5 elseif( MINGW )
6 add_definitions( -Wall -Wextra -pedantic -Werror )
7 elseif( WIN32 )
8 add_definitions( -W3 )
9 endif( UNIX )
10
11 configure_file( config-tests.h.in config-tests.h )
12
13 find_package( Boost 1.36.0 COMPONENTS date_time filesystem system program_options )
14
15 include_directories(
16 ../libgdf/include
17 ${Boost_INCLUDE_DIR}
18 ${gdf_tests_BINARY_DIR}
19 )
20
21 add_executable( testok testOK.cpp )
22 target_link_libraries( testok ${Boost_LIBRARIES} GDF )
23 add_test( NAME testok COMMAND testok )
24
25 add_executable( testfail testFail.cpp )
26 target_link_libraries( testfail ${Boost_LIBRARIES} GDF )
27 add_test( NAME testfail COMMAND testfail )
28 set_tests_properties( testfail PROPERTIES WILL_FAIL TRUE )
29
30 add_executable( testCreateGDF testCreateGDF.cpp )
31 target_link_libraries( testCreateGDF ${Boost_LIBRARIES} GDF )
32 add_test( NAME testCreateGDF COMMAND testCreateGDF )
33
34 add_executable( testRWConsistency testRWConsistency.cpp )
35 target_link_libraries( testRWConsistency ${Boost_LIBRARIES} GDF )
36 add_test( NAME testRWConsistency COMMAND testRWConsistency )
37
38
39 #add_custom_target( buildtests DEPENDS testCreateGDF testRWConsistency )
40 #add_custom_target( check COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS buildtests )
0 #ifndef __CONFIG_TESTS_H_INCLUDED__
1 #define __CONFIG_TESTS_H_INCLUDED__
2
3 #cmakedefine GDF_SOURCE_ROOT "@GDF_SOURCE_ROOT@"
4
5 #endif
6
0 //
1 // This file is part of libGDF.
2 //
3 // libGDF is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU Lesser General Public License as
5 // published by the Free Software Foundation, either version 3 of
6 // the License, or (at your option) any later version.
7 //
8 // libGDF is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public License
14 // along with libGDF. If not, see <http://www.gnu.org/licenses/>.
15 //
16 // Copyright 2010 Martin Billinger
17
18 #include <GDF/Writer.h>
19
20 #include <iostream>
21 #include <stdio.h>
22 #include <sys/stat.h>
23
24 using namespace std;
25
26 const string testfile = "test.gdf.tmp";
27 const size_t gdf_emptysize = 264; // 256 bytes main header, 8 bytes event header
28
29 bool fexist( std::string filename )
30 {
31 std::ifstream f( filename.c_str(), std::ios_base::in );
32 if( f.fail() )
33 return false;
34 f.close( );
35 return true;
36 }
37
38 size_t fsize( std::string filename )
39 {
40 struct stat filestatus;
41 stat( filename.c_str(), &filestatus );
42 return filestatus.st_size;
43 }
44
45 int main( )
46 {
47 try
48 {
49 if( fexist( testfile ) )
50 {
51 cout << "Removing existing " << testfile << endl;
52 remove( testfile.c_str() );
53 }
54
55 cout << "Creating Writer instance." << endl;
56 gdf::Writer w;
57
58 w.setEventSamplingRate( 100 );
59
60 cout << "Opening file for writing." << endl;
61 try {
62 w.open( testfile );
63 } catch( gdf::exception::header_issues &e )
64 {
65 if( e.num_errors() > 0 ) throw;
66 cout << "Header Issues: " << endl << e.what( ) << endl;
67 }
68
69 cout << "Closing file." << endl;
70 w.close( );
71
72 cout << "Checking if " << testfile << " exists .... ";
73 if( !fexist( testfile ) )
74 {
75 cout << "Failed." << endl;
76 return 1;
77 }
78 cout << "OK" << endl;
79
80 cout << "Checking file size .... ";
81 if( fsize( testfile ) != gdf_emptysize )
82 {
83 cout << "Failed." << endl;
84 return 1;
85 }
86 cout << "OK" << endl;
87
88 cout << "Removing " << testfile << endl;
89 remove( testfile.c_str() );
90
91 return 0; // test succeeded
92 }
93 catch( std::exception &e )
94 {
95 std::cout << "Caught Exception: " << e.what( ) << endl;
96 }
97 catch( ... )
98 {
99 std::cout << "Caught Unknown Exception." << endl;
100 }
101
102 return 1; // test failed
103 }
0 #include <iostream>
1
2 int main( )
3 {
4 std::cout << "Fail" << std::endl;
5 return 1;
6 }
7
0 #include <iostream>
1
2 int main( )
3 {
4 std::cout << "OK" << std::endl;
5 return 0;
6 }
7
0 //
1 // This file is part of libGDF.
2 //
3 // libGDF is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU Lesser General Public License as
5 // published by the Free Software Foundation, either version 3 of
6 // the License, or (at your option) any later version.
7 //
8 // libGDF is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public License
14 // along with libGDF. If not, see <http://www.gnu.org/licenses/>.
15 //
16 // Copyright 2010 Martin Billinger
17
18 #include "config-tests.h"
19
20 #include <GDF/Writer.h>
21 #include <GDF/Reader.h>
22
23 #include <iostream>
24 #include <stdio.h>
25 #include <sys/stat.h>
26
27 using namespace std;
28
29 const string testfile = "test.gdf.tmp";
30 const string reffile = string(GDF_SOURCE_ROOT)+"/sampledata/MI128.gdf";
31
32 bool fexist( std::string filename )
33 {
34 std::ifstream f( filename.c_str(), std::ios_base::in );
35 if( f.fail() )
36 return false;
37 f.close( );
38 return true;
39 }
40
41 size_t fsize( std::string filename )
42 {
43 struct stat filestatus;
44 stat( filename.c_str(), &filestatus );
45 return filestatus.st_size;
46 }
47
48 bool fcompare( std::string fileA, std::string fileB )
49 {
50 std::ifstream f1( fileA.c_str(), std::ios_base::in | std::ios_base::binary );
51 std::ifstream f2( fileB.c_str(), std::ios_base::in | std::ios_base::binary );
52
53 bool state = true;
54
55 size_t ofs = 0;
56 while( !( f1.eof() || f2.eof() ) )
57 {
58 unsigned char a, b;
59 f1 >> a;
60 f2 >> b;
61
62
63 if( a != b )
64 {
65 cout << ofs << " : " << (int)a << " ... " << (int)b << endl;
66 state = false;
67 }
68
69 ofs++;
70
71 }
72 return state;
73 }
74
75 int main( )
76 {
77 try
78 {
79 cout << "Creating Writer instance." << endl;
80 gdf::Writer w;
81
82 cout << "Creating Reader instance." << endl;
83 gdf::Reader r;
84
85 r.enableCache( false );
86
87 cout << "Opening '" << reffile << "' for reading." << endl;
88 r.open( reffile );
89
90 cout << "Copying Header information." << endl;
91 w.getMainHeader( ).copyFrom( r.getMainHeader_readonly() );
92 w.getHeaderAccess().setRecordDuration( r.getMainHeader_readonly().get_datarecord_duration( 0 ), r.getMainHeader_readonly().get_datarecord_duration( 1 ) );
93 for( size_t m=0; m<w.getMainHeader_readonly().get_num_signals(); m++ )
94 {
95 w.createSignal( m, true );
96 w.getSignalHeader( m ).copyFrom( r.getSignalHeader_readonly( m ) );
97 }
98
99 w.setEventMode( r.getEventHeader()->getMode() );
100 w.setEventSamplingRate( r.getEventHeader()->getSamplingRate() );
101
102 cout << "Opening '" << testfile << "' for writing." << endl;
103 w.open( testfile, gdf::writer_ev_memory | gdf::writer_overwrite );
104
105 cout << "Copying data .... ";
106 size_t num_recs = boost::numeric_cast<size_t>( r.getMainHeader_readonly( ).get_num_datarecords( ) );
107
108 for( size_t n=0; n<num_recs; n++ )
109 {
110 gdf::Record *rec = w.acquireRecord( );
111 r.readRecord( n, rec );
112 w.addRecord( rec );
113 }
114 cout << "OK" << endl;
115
116 cout << "Copying events .... ";
117 gdf::EventHeader* ev_header = r.getEventHeader();
118 unsigned int num_events = ev_header->getNumEvents();switch( ev_header->getMode() )
119 {
120 default: throw(std::runtime_error("ERROR -- Invalid event mode!"));
121 case 1: {
122 gdf::Mode1Event ev;
123 for(unsigned int m = 0; m < num_events; m++)
124 {
125 ev_header->getEvent(m, ev);
126 w.addEvent(ev);
127 }
128 } break;
129 case 3: {
130 gdf::Mode3Event ev;
131 for(unsigned int m = 0; m < num_events; m++)
132 {
133 ev_header->getEvent(m, ev);
134 w.addEvent(ev);
135 }
136 } break;
137 }
138 cout << "OK" << endl;
139
140 w.close( );
141
142 cout << "Comparing files .... ";
143 if( !fcompare( reffile, testfile ) )
144 {
145 cout << "Failed." << endl;
146 return 1;
147 }
148 cout << "OK" << endl;
149
150 cout << "Removing " << testfile << endl;
151 remove( testfile.c_str() );
152
153 return 0; // test succeeded
154 }
155 catch( std::exception &e )
156 {
157 std::cout << "Caught Exception: " << e.what( ) << endl;
158 }
159 catch( ... )
160 {
161 std::cout << "Caught Unknown Exception." << endl;
162 }
163
164 return 1; // test failed
165 }
0 cmake_minimum_required( VERSION 2.6 )
0 cmake_minimum_required( VERSION 2.8 )
11 project( gdf_merger )
22
33 if( UNIX )
88 add_definitions( -W3 )
99 endif( UNIX )
1010
11 find_package( Boost 1.36.0 COMPONENTS date_time filesystem system program_options )
11 find_package( Boost 1.36.0 COMPONENTS filesystem program_options )
1212
1313 include_directories(
1414 ../../libgdf/include
5353 reader_.open(input_files_[0]);
5454
5555 writer_.getMainHeader( ).copyFrom( reader_.getMainHeader_readonly() );
56 writer_.getHeaderAccess().setRecordDuration( reader_.getMainHeader_readonly().get_datarecord_duration( 0 ), reader_.getMainHeader_readonly().get_datarecord_duration( 1 ) );
5657 for( size_t m = 0; m < writer_.getMainHeader_readonly().get_num_signals(); m++ )
5758 {
5859 writer_.createSignal( m, true );
5960 writer_.getSignalHeader( m ).copyFrom( reader_.getSignalHeader_readonly( m ) );
61 //writer_.getSignalHeader( m ).set_samplerate( reader_.getSignalHeader_readonly( m ).get_samplerate() );
6062 }
6163
6264 gdf::EventHeader* ev_header = reader_.getEventHeader();
7072 writer_.setMaxFullRecords( 0 );
7173 writer_.open( output_file_, gdf::writer_ev_memory | gdf::writer_overwrite );
7274
75 std::cout << "Record Duration : " << writer_.getMainHeader_readonly( ).get_datarecord_duration(0) << " : " << writer_.getMainHeader_readonly( ).get_datarecord_duration(1) << std::endl;
76 std::cout << "Sampling Rate : " << writer_.getSignalHeader_readonly( 1 ).get_samplerate() << std::endl;
77 std::cout << "Samples per Record: " << writer_.getSignalHeader_readonly( 1 ).get_samples_per_record() << std::endl;
78
7379 for(unsigned int n = 0; n < input_files_.size(); n++)
7480 {
7581 reader_.enableCache( false );
7884 cout << " -- merging: " << input_files_[n];
7985 cout << " Warning: No header checks performed yet!" << endl;
8086
81 size_t num_recs = boost::numeric_cast<size_t>( reader_.getMainHeader_readonly( ).get_num_datarecords( ) );
87 size_t num_recs = boost::numeric_cast<size_t>( reader_.getMainHeader_readonly( ).get_num_datarecords( ) );
88
89 std::cout << " Number of records: " << num_recs << std::endl;
8290
8391 for( size_t r = 0; r< num_recs; r++ )
8492 //for( size_t r = 0; r< 1; r++ )
9098 gdf::Record *rec = writer_.acquireRecord( );
9199 reader_.readRecord( r, rec );
92100 writer_.addRecord( rec );
101
102 /*for( size_t i=0; i< rec->getNumChannels( ); i++ )
103 {
104 gdf::Channel *ch = rec->getChannel( i );
105 std::cout << ch->getSize( ) << " ";
106 }
107 std::cout << std::endl;*/
93108
94109 /*for( size_t c = 0; c < reader_.getMainHeader_readonly().get_num_signals(); c++ )
95110 {