Commit 106da42f authored by wiebel's avatar wiebel
Browse files

[ADD] added code of external library for loading bio signal data like EEG and MEG.

parent 169b7867
......@@ -5,7 +5,7 @@ FILE( GLOB DATAHANDLER_SRC "*.cpp" "*.hpp" )
FILE( GLOB DATAHANDLER_EXCEPTIONS_SRC "exceptions/*.cpp" )
FILE( GLOB DATAHANDLER_LOADERS_SRC "io/WLoader*.cpp" )
ADD_LIBRARY( dataHandler SHARED ${DATAHANDLER_SRC} ${DATAHANDLER_EXCEPTIONS_SRC} ${DATAHANDLER_LOADERS_SRC})
TARGET_LINK_LIBRARIES( dataHandler common math ${Boost_LIBRARIES} niftiio )
TARGET_LINK_LIBRARIES( dataHandler common math ${Boost_LIBRARIES} niftiio biosig)
# Unit tests
IF( CXXTEST_FOUND )
......
ADD_SUBDIRECTORY( test )
ADD_SUBDIRECTORY( nifti )
ADD_SUBDIRECTORY( biosig )
# Unit tests
IF( CXXTEST_FOUND )
......
SET( CMAKE_CXX_FLAGS "-pedantic -Wall -Wextra -Wno-long-long")#without "-ansi"
FILE( GLOB BIOSIG_SRC "*.c" "*.cpp" "XMLParser/*.cpp" )
ADD_LIBRARY( biosig SHARED ${BIOSIG_SRC} )
This diff is collapsed.
This file contains the original README file as distributed with "BioSig for C/C++". The contents of the original file starts at "Introduction". The license for the code in this directory can be found in the file LICENSE. The source code and documentation in this directory are adapted from "BioSig for C/C++" (http://biosig.sf.net/). See the file VERSION for more information. The changes were made by Alexander Wiebel. Parts of the text of the old README file do not apply to the changed code anymore.
Introduction:
---------------
The aim of this repository is providing a C/C++ software library for biomedical signal processing.
This library is called "BioSig for C/C++" and is complementary to "BioSig for Octave and Matlab".
BioSig4C++ provides several tools:
(1) "libbiosig.a" provides a library for accessing different dataformats.
Recommended: zlib (http://zlib.net/) and GNU Scientific Library (GSL)
The supported data formats are listed here:
http://hci.tugraz.at/schloegl/biosig/TESTED
(2) "save2gdf" is a converter between different file formats,
including but not limited to SCP-ECG(EN1064), HL7aECG (FDA-XML), GDF, EDF, BDF, CWFB.
save2gdf can be also used to upload or retrieve data from a bscs server.
(3) "mexSLOAD" is a MEX-interface for Octave and Matlab
Requirement: Matlab OR Octave (v2.9 or higher) with octave-headers
For Matlab, precompiled binaries are available in matlab/mexSLOAD.mex*
(4) "_biosig.so" is an interface to python.
Requirement: python, python-dev, python-scipy, swig (http://www.swig.org/)
(5) SigViewer
Requirement: qmake, Qt4
(6) Precompiled binaries for Win32
win32/save2gdf.exe binary converter
win32/libbiosig.a library for MinGW 4.x (might work with other compilers too)
The internal data structure resemble the header structure similar to
http://biosig.cvs.sourceforge.net/biosig/biosig/doc/header.txt
and is defined in
http://biosig.cvs.sourceforge.net/biosig/biosig4c++/biosig.h
(see HDRTYPE and CHANNEL_TYPE)
Encoding of Event/Markers/Annotations is available here:
http://hci.tugraz.at/schloegl/matlab/eeg/EventCodes.html
The latest list of supported data formats is available here:
http://hci.tugraz.at/schloegl/biosig/TESTED
File(s):
-------------
README this file
biosig.h definition of external biosig interface
biosig-dev.h definition of internal functions
biosig.c SOPEN, SREAD, SWRITE, SEOF, SCLOSE functions
save2gdf.c converter between various file formats.
physicalunit.c en-/decodes physical units according to ISO/DIS 11073-10101:2003
mexSLOAD.cpp is a MEX-File for loading data in Octave and Matab.
t210/* reading SCP,FAMOS file format
t220/* writing SCP file format
t230/* support of HL7aECG file format
test0/* scripts and functions for testing
Makefile script for compiling and testing under GNU/Linux
Makefile.win32 script for compiling and testing on win32 using mingw
win32/* executables for Windows
Compilation:
-------------
# Linux
You need g++(>4.0), make and zlib. (If you do not have zlib, do not define WITH_ZLIB).
Running make compiles the converter.
make # makes the file format converter
make save2gdf # makes the file format converter
make win32 # makes the file format converter for Win32
make physicalunits # makes the en/decoder for physical units
make libbiosig.a # makes a static library
make mex4o # makes mexSLOAD for Octave (requires Octave-headers2.9 or higher)
make mex4m # makes mexSLOAD for Matlab (path_to_mex need to be defined in Makefile)
make sigviewer # recompiles SigViewer (requires qmake and Qt, and the sources of sigviewer must be in ../sigviewer)
make biosig4python # compiles the BioSig interface for Python (requires SWIG and Python)
make all # all of the above
make testscp
make testhl7
make test # tests HL7<->SCP, SCP<->GDF, GDF<->HL7 converters
make test6 # tests bidirectional conversion between 6 differerent data formats
# MinGW Crosscompiler on Linux for Windows
Currently, only the file converter save2gdf is supported.
- install mingw32 mingw32-binutils mingw32-runtime
- run the command
make win32
# Windows + MinGW
Currently, only the file converter save2gdf is supported.
- You need MinGW with g++ and make.
- run the make command
make -f Makefile.win32
# Windows + MinGW + Matlab
do the steps in "Windows+MinGW"
install and configure gnumex (from http://gnumex.sf.net)
make libbiosig.a
start matlab
>> gnumex % configure mingw for mex
>> mex mexSLOAD.cpp libbiosig \mingw\lib\libws2_32.a
# Windows + Cygwin
Currently, only the file converter save2gdf is supported.
- install Cygwin
- within Cygwin install g++, zlib, and make
- run the make command
make save2gdf
# MSVC - Microsoft Visual C++
MSVC is currently not supported. The main incompatibility is
the use of the typeof() operator. Since typeof() is very convinient,
I'm not planning to change this. However, you can easy replace
any typeof()-operator by the appropriate type, and the code
should compile on MSVC as well.
# Other platforms (Windows+MSVC, MacOSX, Solaris, etc. )
Not tested (yet). Let me know about successful compilations,
or tell me what changes are needed.
Installation:
-------------
run as root
make
make install # installs save2gdf, save2scp, save2aecg,
make install_octave # installs mexSLOAD.mex in /usr/local/share/octave/site-m/
make install_sigviewer # installs sigviewer
Execution:
----------
# if test.gdf exists, some header information is displayed
save2gdf test.gdf
# help and usage information
save2gdf -h
# converts a data file into a GDF format (destination
save2gdf PFE103.scp t5.gdf
# converts a data file into a SCP format (destination
save2scp t5.gdf t5.scp
save2gdf -f=SCP t5.gdf t5.scp
# converts a data file into a HL7aECG format (destination
save2aecg t5.gdf t5.hl7
save2gdf -f=HL7aECG t5.gdf t5.hl7
# load matlab into octave or matlab
start octave or matlab
addpath path_to_mexSLOAD.mex
[data,HDR] = mexSLOAD(filename); % loads data and header information
Open Issue(s) of the SCP-ECG <-> HL7aECG converter:
---------------------------------------------------
The following fields of SCP-ECG are not converted to HL7.
= Mandatory fields (prEN1064:2007 p.18, chp 5.4.3.1) not propagated to HL7:
- time zone information, (tag34, section 1)
- "ID of acquiring device" (tag14, section 1)
= "Highly recommended" fields (prEN1064:2007 p.18, chp 5.4.3.1) not propagated to HL7:
- "ID of analysing device", Patient first name,
= Other fields of the SCP-ECG standard,
- section 1: blood pressure, medication, etc
- section 4 (QRS location), 7 (global measurements), 8-11 (interpretative statements)
The following fields of HL7aECG are not converted to SCP-ECG.
- study, treatment group, clinical trial, clinical trial protocol, trial sponsor, investigator etc.
Development & Testing:
----------------------
There are several testing functions included.
The following commands test the converter and should finish without errors.
make test
make testhl7
make testscp
make test6
The Octave/Matlab script
test0/test01.m
tests whether the various data formats give the same results
or whether some conversion error has been included.
More information is available at http://biosig.sf.net/
If you have any questions you can also contact the mailinglist
https://lists.sourceforge.net/lists/listinfo/biosig-general
$Id: README,v 1.26 2009/02/27 09:18:33 schloegl Exp $
Copyright (C) 2005,2006,2007,2008,2009 Alois Schloegl <a.schloegl@ieee.org>
This function is part of the "BioSig for C/C++" repository
(BioSig4C++) at http://biosig.sf.net/
Thanks to the contributors:
Thomas Brunner
Makefile, testing
Eugenio Cervesato
reading of SCP-ECG format
Franco Chiarugi
writing of SCP-ECG format
Elias Apostolopoulos
read/write support of HL7aECG format
Luca Citi
made the interface to python working
Thsi version was adapted for OpenWalnut by Alexander Wiebel. The basis for this version is the one specified below.
# BIOSIG http://biosig.sf.net/
# Version: BioSig4C++ 0.84
# Date: 2009-06-18
//---------------------------------------------------------------------------
//
// Project: OpenWalnut
//
// Copyright 2009 SomeCopyrightowner
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WLOADEREDF_TEST_H
#define WLOADEREDF_TEST_H
#include <cxxtest/TestSuite.h>
#include <boost/thread.hpp>
#include "../WLoaderEDF.h"
#include "../../../WDataHandler.h"
/**
* TODO(wiebel): Document this!
*/
class WLoaderEDFTest : public CxxTest::TestSuite
{
public:
/**
* TODO(wiebel): Document this!
*/
void testSomething( void )
{
//std::string fileName = "/dargb/bv_data/Medical/MPI-CBS/ASA/A1_alex_Segment_1.edf";
std::string fileName = "/home/wiebel/Data/EEG/A1.cnt";
std::cout << std::endl << "Test loading of " << fileName << "." << std::endl;
boost::shared_ptr< WDataHandler > dataHandler =
boost::shared_ptr< WDataHandler >( new WDataHandler() );
TS_ASSERT_EQUALS( dataHandler->getNumberOfDataSets(), 0 );
WLoaderEDF edfLoader( fileName, dataHandler );
boost::thread loaderThread( edfLoader );
sleep(1);
TS_FAIL("Try to test EDF" );
}
};
#endif // WLOADEREDF_TEST_H
#include <string>
template <typename TContainer>
void stringtokenizer(TContainer& container, const std::string& in, const char* const delimiters = " \t\n"){
const std::string::size_type len = in.length();
std::string::size_type i = 0;
while (i < len){
i = in.find_first_not_of(delimiters, i);
if (i == std::string::npos)
return;
std::string::size_type j = in.find_first_of(delimiters, i);
if (j == std::string::npos){
container.push_back(in.substr(i));
return;
}
else
container.push_back(in.substr(i, j-i));
i = j + 1;
}
}
/*
www.sourceforge.net/projects/tinyxml
Original file by Yves Berquin.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
/*
* THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005.
*/
#ifndef TIXML_USE_STL
#include "tinystr.h"
// Error value for find primitive
const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1);
// Null rep.
TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, '\0' };
void TiXmlString::reserve (size_type cap)
{
if (cap > capacity())
{
TiXmlString tmp;
tmp.init(length(), cap);
memcpy(tmp.start(), data(), length());
swap(tmp);
}
}
TiXmlString& TiXmlString::assign(const char* str, size_type len)
{
size_type cap = capacity();
if (len > cap || cap > 3*(len + 8))
{
TiXmlString tmp;
tmp.init(len);
memcpy(tmp.start(), str, len);
swap(tmp);
}
else
{
memmove(start(), str, len);
set_size(len);
}
return *this;
}
TiXmlString& TiXmlString::append(const char* str, size_type len)
{
size_type newsize = length() + len;
if (newsize > capacity())
{
reserve (newsize + capacity());
}
memmove(finish(), str, len);
set_size(newsize);
return *this;
}
TiXmlString operator + (const TiXmlString & a, const TiXmlString & b)
{
TiXmlString tmp;
tmp.reserve(a.length() + b.length());
tmp += a;
tmp += b;
return tmp;
}
TiXmlString operator + (const TiXmlString & a, const char* b)
{
TiXmlString tmp;
TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) );
tmp.reserve(a.length() + b_len);
tmp += a;
tmp.append(b, b_len);
return tmp;
}
TiXmlString operator + (const char* a, const TiXmlString & b)
{
TiXmlString tmp;
TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) );
tmp.reserve(a_len + b.length());
tmp.append(a, a_len);
tmp += b;
return tmp;
}
#endif // TIXML_USE_STL
/*
www.sourceforge.net/projects/tinyxml
Original file by Yves Berquin.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
/*
* THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005.
*
* - completely rewritten. compact, clean, and fast implementation.
* - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems)
* - fixed reserve() to work as per specification.
* - fixed buggy compares operator==(), operator<(), and operator>()
* - fixed operator+=() to take a const ref argument, following spec.
* - added "copy" constructor with length, and most compare operators.
* - added swap(), clear(), size(), capacity(), operator+().
*/
#ifndef TIXML_USE_STL
#ifndef TIXML_STRING_INCLUDED
#define TIXML_STRING_INCLUDED
#include <assert.h>
#include <string.h>
/* The support for explicit isn't that universal, and it isn't really
required - it is used to check that the TiXmlString class isn't incorrectly
used. Be nice to old compilers and macro it here:
*/
#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
// Microsoft visual studio, version 6 and higher.
#define TIXML_EXPLICIT explicit
#elif defined(__GNUC__) && (__GNUC__ >= 3 )
// GCC version 3 and higher.s
#define TIXML_EXPLICIT explicit
#else
#define TIXML_EXPLICIT
#endif
/*
TiXmlString is an emulation of a subset of the std::string template.
Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
Only the member functions relevant to the TinyXML project have been implemented.
The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
a string and there's no more room, we allocate a buffer twice as big as we need.
*/
class TiXmlString
{
public :
// The size type used
typedef size_t size_type;
// Error value for find primitive
static const size_type npos; // = -1;
// TiXmlString empty constructor
TiXmlString () : rep_(&nullrep_)
{
}
// TiXmlString copy constructor
TiXmlString ( const TiXmlString & copy) : rep_(0)
{
init(copy.length());
memcpy(start(), copy.data(), length());
}
// TiXmlString constructor, based on a string
TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0)
{
init( static_cast<size_type>( strlen(copy) ));
memcpy(start(), copy, length());
}
// TiXmlString constructor, based on a string
TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0)
{
init(len);
memcpy(start(), str, len);
}
// TiXmlString destructor
~TiXmlString ()
{
quit();
}
// = operator
TiXmlString& operator = (const char * copy)
{
return assign( copy, (size_type)strlen(copy));
}
// = operator
TiXmlString& operator = (const TiXmlString & copy)
{
return assign(copy.start(), copy.length());
}
// += operator. Maps to append
TiXmlString& operator += (const char * suffix)
{
return append(suffix, static_cast<size_type>( strlen(suffix) ));
}
// += operator. Maps to append
TiXmlString& operator += (char single)
{
return append(&single, 1);
}
// += operator. Maps to append
TiXmlString& operator += (const TiXmlString & suffix)
{
return append(suffix.data(), suffix.length());
}
// Convert a TiXmlString into a null-terminated char *
const char * c_str () const { return rep_->str; }
// Convert a TiXmlString into a char * (need not be null terminated).
const char * data () const { return rep_->str; }
// Return the length of a TiXmlString
size_type length () const { return rep_->size; }
// Alias for length()
size_type size () const { return rep_->size; }
// Checks if a TiXmlString is empty
bool empty () const { return rep_->size == 0; }
// Return capacity of string
size_type capacity () const { return rep_->capacity; }
// single char extraction
const char& at (size_type index) const
{
assert( index < length() );
return rep_->str[ index ];
}
// [] operator
char& operator [] (size_type index) const
{
assert( index < length() );
return rep_->str[ index ];
}