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

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


The following commit has been merged in the master branch:
commit 98b647726bda612309dea9b82d6855a4e243751b
Author: Andrei Zavada <johnhommer at gmail.com>
Date:   Sun Apr 21 00:29:23 2013 +0300

    CEDFFile::details takes a bitfield, reports annotations and discontinuities

diff --git a/man/edfhed.1.in b/man/edfhed.1.in
index 9779765..e14ff61 100644
--- a/man/edfhed.1.in
+++ b/man/edfhed.1.in
@@ -14,6 +14,9 @@ the header (see options \fB\-s\fR, \fB\-T\fR and \fB\-R\fR).
 \fB\-b\fR, \fB\-\-no\-channels\fR
 Only dump general header fields (no channel details).
 .TP
+\fB\-a\fR, \fB\-\-with\-annotations\fR
+List embedded annotations if any.
+.TP
 \fB\-R\fR, \fB\-\-from\-tree\fR
 Given file location \(oqSubject/Session/Episode.edf\(cq, set \fBrecording_id\fR to
 \(oqSession/Episode\(cq and \fBpatient_id\fR to \(oqSubject\(cq.
diff --git a/src/libsigfile/edf.cc b/src/libsigfile/edf.cc
index 3b0dd7d..6585934 100644
--- a/src/libsigfile/edf.cc
+++ b/src/libsigfile/edf.cc
@@ -911,12 +911,20 @@ _extract_embedded_annotations()
 
 string
 CEDFFile::
-details( bool channels_too) const
+details( int which) const
 {
 	ostringstream recv;
 	if ( _status & bad_header )
 		recv << "Bad header, or no file\n";
 	else {
+		size_t	n_dicontinuities = 0;
+		double	prev_offset = NAN, cur_offset;
+		for ( size_t r = 1; r < _record_offsets.size(); ++r ) {
+			cur_offset = _record_offsets[r] - _record_offsets[r-1];
+			if ( isfinite(prev_offset) and cur_offset != prev_offset )
+				++n_dicontinuities;
+			prev_offset = cur_offset;
+		}
 		char *outp;
 		ASPRINTF( &outp,
 			  "File\t: %s\n"
@@ -927,21 +935,24 @@ details( bool channels_too) const
 			  " Time\t: %s\n"
 			  " # of channels\t: %zu\n"
 			  " # of records\t: %zu\n"
-			  " Record size\t: %g sec\n",
+			  " Record size\t: %g sec\n"
+			  " # of discontinuities\t: %zu\n"
+			  " # of embedded annotations\t: %zu\n",
 			  filename(),
 			  subtype_s(),
 			  patient_id(),
 			  trim( string (header.recording_id, 80)).c_str(),
 			  trim( string (header.recording_date, 8)).c_str(),
 			  trim( string (header.recording_time, 8)).c_str(),
-			  // asctime( localtime( &_start_time)),
 			  channels.size(),
 			  n_data_records,
-			  data_record_size);
+			  data_record_size,
+			  n_dicontinuities,
+			  common_annotations.size());
 		recv << outp;
 		free( outp);
 
-		if ( channels_too ) {
+		if ( which & with_channels ) {
 			size_t i = 0;
 			for ( auto &H : channels ) {
 				ASPRINTF( &outp,
@@ -973,6 +984,12 @@ details( bool channels_too) const
 				free( outp);
 			}
 		}
+
+		if ( which & with_annotations ) {
+			recv << "Embedded annotations (" << common_annotations.size() << "):\n";
+			for ( auto &A : common_annotations )
+				recv << ' ' << A.span.a << '\t' << A.span.z << '\t' << A.label << endl;
+		}
 	}
 
 	return recv.str();
diff --git a/src/libsigfile/edf.hh b/src/libsigfile/edf.hh
index 0dd69f9..49a45d6 100644
--- a/src/libsigfile/edf.hh
+++ b/src/libsigfile/edf.hh
@@ -388,7 +388,8 @@ class CEDFFile
       // reporting & misc
 	void write_ancillary_files();
 
-	string details( bool channels_too = true) const;
+	enum TEdfDetails { with_channels = 1, with_annotations = 2 };
+	string details( int which) const;
 
 	sigproc::TWinType af_dampen_window_type; // master copy
 
diff --git a/src/libsigfile/source-base.hh b/src/libsigfile/source-base.hh
index de990fa..4a3ce2b 100644
--- a/src/libsigfile/source-base.hh
+++ b/src/libsigfile/source-base.hh
@@ -215,8 +215,7 @@ class CSource {
 	int status()	const { return _status; }
 	int flags()	const { return _flags; }
 	virtual string explain_status()			const = 0;
-	virtual string details( bool channels_too = true)
-							const = 0;
+	virtual string details( int which_details)	const = 0;
 
       // identification
 	const char* filename() const
diff --git a/src/tools/edfcat.cc b/src/tools/edfcat.cc
index 26c4b65..45d8e1b 100644
--- a/src/tools/edfcat.cc
+++ b/src/tools/edfcat.cc
@@ -353,7 +353,7 @@ exec_convert( const SOperation::SObject& obj)
 
 	printf( "Created edf:\n%s\n"
 		"You may now want to fill out the header of the newly created EDF file.\n"
-		"Use edfhed --set ... to do so, or run edfhed-gtk.\n", F.details().c_str());
+		"Use edfhed --set ... to do so, or run edfhed-gtk.\n", F.details( 0|sigfile::CEDFFile::with_channels).c_str());
 
 	return 0;
 }
@@ -396,7 +396,7 @@ exec_prune( const SOperation::SObject& obj)
 	tmp = F.comment();
 	G.set_comment( tmp.c_str());
 	G.set_start_time( F.start_time());
-	printf( "Created edf:\n%s\n", G.details().c_str());
+	printf( "Created edf:\n%s\n", G.details( 0|sigfile::CEDFFile::with_channels).c_str());
 
 //	F.resize( data.size() / obj.samplerate / obj.record_size);
 	size_t h = 0;
diff --git a/src/tools/edfhed.cc b/src/tools/edfhed.cc
index 015d2a8..b027dd8 100644
--- a/src/tools/edfhed.cc
+++ b/src/tools/edfhed.cc
@@ -43,6 +43,7 @@ static char doc[] =
 
 static struct argp_option options[] = {
        {"no-channels",		'b', 0,	0, "Only dump general header fields (no channel details)"},
+       {"with-annotations",	'a', 0,	0, "List embedded annotations"},
        {"set",			's', "[CH:]FIELD:VALUE", 0, "Set FIELD to VALUE (possibly in channel CH)" },
        {"id-from-tree",		'R', 0,	0, "Set 'recording_id' field to Subject/Session/Episode given current file location"},
        {"from-mtime",		'T', 0,	0, "Set 'recording_date' and 'recording_time' fields to file modification date/time"},
@@ -155,11 +156,13 @@ struct SArguments {
 	std::vector<SSettable>
 		settables;
 	bool	header_only:1,
+		with_annotations:1,
 		from_tree:1,
 		from_timestamp:1,
 		to_timestamp:1;
 	SArguments()
 	      : header_only (false),
+		with_annotations (false),
 		from_tree (false),
 		from_timestamp (false),
 		to_timestamp (false)
@@ -177,6 +180,9 @@ parse_opt( int key, char *arg, struct argp_state *state)
 	case 'b':
 		Q.header_only = true;
 		break;
+	case 'a':
+		Q.with_annotations = true;
+		break;
 	case 'R':
 		Q.from_tree = true;
 		break;
@@ -322,7 +328,11 @@ main( int argc, char **argv)
 						    sigfile::CEDFFile::no_field_consistency_check);
 			if ( Opts.settables.empty() &&
 			     not Opts.from_timestamp && not Opts.from_tree && not Opts.to_timestamp ) {
-				cout << F.details( not Opts.header_only) << endl;
+				cout << F.details(
+					0
+					| (Opts.header_only ? 0 : sigfile::CEDFFile::with_channels)
+					| (Opts.with_annotations ? sigfile::CEDFFile::with_annotations : 0))
+				     << endl;
 			} else {
 				if ( Opts.to_timestamp ) {
 					set_mtime_from_recording_datetime( F);
diff --git a/src/ui/mw/admit-one.cc b/src/ui/mw/admit-one.cc
index cebab56..1c510fe 100644
--- a/src/ui/mw/admit-one.cc
+++ b/src/ui/mw/admit-one.cc
@@ -32,7 +32,7 @@ dnd_maybe_admit_one( const char* fname)
 			pop_ok_message( wMainWindow, "Bad EDF file", "The file <i>%s</i> doesn't appear to be a valid EDF file", fname);
 			return 0;
 		}
-		info = (*Fp)().details();
+		info = (*Fp)().details( 0|sigfile::CEDFFile::with_channels);
 
 		snprintf_buf( "File: <i>%s</i>", fname);
 		gtk_label_set_markup( lEdfImportCaption, __buf__);
diff --git a/src/ui/mw/measurements_cb.cc b/src/ui/mw/measurements_cb.cc
index 3af215d..91b0be2 100644
--- a/src/ui/mw/measurements_cb.cc
+++ b/src/ui/mw/measurements_cb.cc
@@ -160,7 +160,7 @@ iSubjectTimelineEDFInfo_activate_cb( GtkMenuItem*, gpointer userdata)
 	auto J = ED.using_subject;
 
 	const auto& F = J->using_episode->sources.front();
-	gtk_text_buffer_set_text( ED.tEDFFileDetailsReport, F().details().c_str(), -1);
+	gtk_text_buffer_set_text( ED.tEDFFileDetailsReport, F().details( 0|sigfile::CEDFFile::with_channels).c_str(), -1);
 	snprintf_buf( "%s header", F().filename());
 	gtk_window_set_title( (GtkWindow*)ED.wEDFFileDetails,
 			      __buf__);

-- 
Sleep experiment manager



More information about the debian-med-commit mailing list