[med-svn] [SCM] aghermann branch, master, updated. 551e213a23b59b71cba6a9c3a282d1b60e21b854

Andrei Zavada johnhommer at gmail.com
Sun Apr 21 23:18:02 UTC 2013


The following commit has been merged in the master branch:
commit 37b6bb69e5fe50218c9558b0341e254c8e000b77
Author: Andrei Zavada <johnhommer at gmail.com>
Date:   Wed Apr 17 19:36:38 2013 +0300

    initial support for EDF annotations

diff --git a/src/libsigfile/edf.cc b/src/libsigfile/edf.cc
index efcdd4e..d3ee19f 100644
--- a/src/libsigfile/edf.cc
+++ b/src/libsigfile/edf.cc
@@ -111,6 +111,9 @@ const char version_string[8]  = {'0',' ',' ',' ', ' ',' ',' ',' '};
 
 }
 
+const char* sigfile::CEDFFile::SSignal::edf_annotations_label = "EDF Annotations";
+
+
 sigfile::CEDFFile::
 CEDFFile (const string& fname_, int flags_)
       : CSource (fname_, flags_)
@@ -676,6 +679,8 @@ _parse_header()
 
 			for ( auto &H : channels ) {
 				_get_next_field( H.header.physical_min, 8);
+				if ( H.label == SSignal::edf_annotations_label )
+					continue;
 				if ( sscanf( H.header.physical_min, "%8lg",
 					     &H.physical_min) != 1 ) {
 					_status |= bad_numfld;
@@ -685,6 +690,8 @@ _parse_header()
 			}
 			for ( auto &H : channels ) {
 				_get_next_field( H.header.physical_max, 8);
+				if ( H.label == SSignal::edf_annotations_label )
+					continue;
 				if ( sscanf( H.header.physical_max, "%8lg",
 					     &H.physical_max) != 1 ) {
 					_status |= bad_numfld;
@@ -695,6 +702,8 @@ _parse_header()
 
 			for ( auto &H : channels ) {
 				_get_next_field( H.header.digital_min, 8);
+				if ( H.label == SSignal::edf_annotations_label )
+					continue;
 				if ( sscanf( H.header.digital_min, "%8d",
 					     &H.digital_min) != 1 ) {
 					_status |= bad_numfld;
@@ -704,6 +713,8 @@ _parse_header()
 			}
 			for ( auto &H : channels ) {
 				_get_next_field( H.header.digital_max, 8);
+				if ( H.label == SSignal::edf_annotations_label )
+					continue;
 				if ( sscanf( H.header.digital_max, "%8d",
 					     &H.digital_max) != 1 ) {
 					_status |= bad_numfld;
@@ -712,9 +723,12 @@ _parse_header()
 				}
 			}
 
-			for ( auto &H : channels )
+			for ( auto &H : channels ) {
+				if ( H.label == SSignal::edf_annotations_label )
+					continue;
 				H.filtering_info.assign(
 					agh::str::trim( string (_get_next_field( H.header.filtering_info, 80), 80)));
+			}
 
 			for ( auto &H : channels ) {
 				char *tail;
@@ -742,42 +756,49 @@ _parse_header()
 
       // calculate gain
 	for ( auto &H : channels )
-		if ( H.physical_max <= H.physical_min ||
-		     H.digital_max  <= H.digital_min  ) {
-			_status |= nogain;
-			if ( not (flags() & no_field_consistency_check) )
-				return -2;
-		} else
-			H.scale =
-				(H.physical_max - H.physical_min) /
-				(H.digital_max  - H.digital_min );
+		if ( H.label == SSignal::edf_annotations_label )
+			;
+		else
+			if ( H.physical_max <= H.physical_min ||
+			     H.digital_max  <= H.digital_min  ) {
+				_status |= nogain;
+				if ( not (flags() & no_field_consistency_check) )
+					return -2;
+			} else
+				H.scale =
+					(H.physical_max - H.physical_min) /
+					(H.digital_max  - H.digital_min );
 
 
-      // determine signal type
+      // determine & validate signal types
 	i = 0;
 	for ( auto &H : channels ) {
-	      // try parsing as "type channel" first
-		string parsable (H.label);
-		char	*_1 = strtok( &parsable[0], " :,./"),
-			*_2 = strtok( NULL, " :,./");
-		if ( _2 ) {
-			H.signal_type_s = _1;
-			H.signal_type = SChannel::figure_signal_type(_1);
-			H.label.assign( _2);  // .channel overwritten
-	      // it only has a channel name
-		} else {
-			H.signal_type_s = SChannel::kemp_signal_types[
-				H.signal_type = SChannel::signal_type_of_channel( H.label) ];
-
-			if ( not H.label.follows_system1020() ) {  // in case there are duplicate labels, rewrite
-				DEF_UNIQUE_CHARP (_);
-				if ( asprintf( &_, "%zu:<%s>", i, H.label.c_str()) ) {}
-				H.label.assign( _);
-				_status |= non1020_channel;
+		if ( H.label == SSignal::edf_annotations_label )
+			;
+		else {
+		      // try parsing as "type channel" first
+			string parsable (H.label);
+			char	*_1 = strtok( &parsable[0], " :,./"),
+				*_2 = strtok( NULL, " :,./");
+			if ( _2 ) {
+				H.signal_type_s = _1;
+				H.signal_type = SChannel::figure_signal_type(_1);
+				H.label.assign( _2);  // .channel overwritten
+		      // it only has a channel name
+			} else {
+				H.signal_type_s = SChannel::kemp_signal_types[
+					H.signal_type = SChannel::signal_type_of_channel( H.label) ];
+
+				if ( not H.label.follows_system1020() ) {  // in case there are duplicate labels, rewrite
+					DEF_UNIQUE_CHARP (_);
+					if ( asprintf( &_, "%zu:<%s>", i, H.label.c_str()) ) {}
+					H.label.assign( _);
+					_status |= non1020_channel;
+				}
 			}
+			if ( H.signal_type == SChannel::TType::other )
+				_status |= nonkemp_signaltype;
 		}
-		if ( H.signal_type == SChannel::TType::other )
-			_status |= nonkemp_signaltype;
 		++i;
 	}
 
@@ -804,6 +825,50 @@ _parse_header()
 
 
 
+
+int
+sigfile::CEDFFile::
+_extract_embedded_annotations()
+{
+	auto S = find( channels.begin(), channels.end(), SSignal::edf_annotations_label);
+	if ( S == channels.end() )
+		return 0;
+	auto& AH = *S;
+
+	// hand-picked from get_signal_original
+	size_t	r_cnt = n_data_records * AH.data_record_size * 2;
+
+	size_t alen = r_cnt * AH.samples_per_record * 2;
+	char* abuf = (char*)malloc( alen);
+	while ( r_cnt-- )
+		memcpy( &abuf[ r_cnt * H.samples_per_record ],
+
+			(char*)_mmapping + header_length
+			+ r_cnt * _total_samples_per_record * 2	// full records before
+			+ H._at,				// offset to our samples
+
+			H.samples_per_record * 2);	// our precious ones
+
+	// walk it and pick up annotations
+	size_t ai = 0;
+//	while ( index( abuf+ai, 20) )
+	// for ( size_t i = 0; i < alen; ++i )
+	// 	for ( size_t k = i; k < alen-1; ++k )
+	// 		if ( abuf[k  ] == (char)21 &&
+	// 		     abuf[i+1] == (char)20 )
+	// 			;
+
+	free(tmp);
+
+	return 0;
+}
+
+
+
+
+
+
+
 string
 sigfile::CEDFFile::details( bool channels_too) const
 {
diff --git a/src/libsigfile/edf.hh b/src/libsigfile/edf.hh
index c80e5f2..9943fd1 100644
--- a/src/libsigfile/edf.hh
+++ b/src/libsigfile/edf.hh
@@ -406,6 +406,7 @@ class CEDFFile
 
       // channels
 	struct SSignal {
+		static const char* edf_annotations_label;
 		struct SEDFSignalHeader {
 			char	*label             ,//  [16],
 				*transducer_type   ,//  [80],
@@ -534,6 +535,7 @@ class CEDFFile
 
 	void _lay_out_header();
 	int _parse_header();
+	int _extract_embedded_annotations();
 
 	size_t	header_length,
 		_fsize,

-- 
Sleep experiment manager



More information about the debian-med-commit mailing list