[med-svn] [SCM] aghermann branch, master, updated. 99b1d5a023eee9df74b0e0d6f894516fc79435ad

Andrei Zavada johnhommer at gmail.com
Sun Jul 7 23:03:58 UTC 2013


The following commit has been merged in the master branch:
commit 6e987581691c0dff84595e31aaf8a928a1ff13b9
Author: Andrei Zavada <johnhommer at gmail.com>
Date:   Wed Jun 19 20:10:03 2013 +0300

    agh-profile-gen first submission

diff --git a/ChangeLog b/ChangeLog
index 011a946..2a2df4a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,7 @@ v.1.0 (2013-xx-xx)
 	* Properly use libsigfile.so.
 	* Plug a memory leak after early unique_ptr acquisition.
 	* SF: Move selection on montage (with Alt).
+	* New tool agh-profile-gen, a standalone profile generator.
 
 v.0.9.0.4 (2013-05-18)
 	* Remove stray AC_CHECK_FUNC(mremap).
diff --git a/configure.ac b/configure.ac
index 04ac619..e2cce79 100644
--- a/configure.ac
+++ b/configure.ac
@@ -222,6 +222,7 @@ AC_OUTPUT([
 	man/edfhed-gtk.1
 	man/edfhed.1
 	man/edfcat.1
+	man/agh-profile-gen.1
 ])
 
 AC_MSG_RESULT([
diff --git a/man/agh-profile-gen.1.in b/man/agh-profile-gen.1.in
new file mode 100644
index 0000000..e20c889
--- /dev/null
+++ b/man/agh-profile-gen.1.in
@@ -0,0 +1,51 @@
+.TH edfcat 1 "@build_date@" @VERSION@ "Aghermann"
+.SH NAME
+	agh-profile-gen -- Sleep profile generator using various metrics.
+.SH SYNOPSIS
+	edfcat \fIOPTIONS\fR \fIFILE\fR
+.B
+.PP
+.SH DESCRIPTION
+.PP
+\fBagh-profile-gen\fR produces PSD, MC or SWU profiles of an EEG recording.
+.TP
+\fB\-h\fR, \fB\-\-channel\fR=\fICHANNEL\fR
+use this channel (0\-based)
+.TP
+\fB\-i\fR, \fB\-\-step\fR=\fISTEP\fR
+step (sec)
+.TP
+\fB\-M\fR, \fB\-\-mc\-params\fR=\fISCOPE\fR:F0FC:BANDWIDTH:IIR_BACKPOLATE:GAIN:SMOOTH
+MC parameters
+.TP
+\fB\-p\fR, \fB\-\-page\fR=\fIPAGESIZE\fR
+page size (sec)
+.TP
+\fB\-P\fR, \fB\-\-psd\-params\fR=\fIBINSIZE\fR
+PSD: binsize (sec, one of .1, .25, .5)
+.TP
+\fB\-s\fR, \fB\-\-samplerate\fR=\fISAMPLERATE\fR
+samplerate (1/sec)
+.TP
+\fB\-S\fR, \fB\-\-swu\-params\fR=\fIMIN_UPSWING_LEN\fR
+SWU parameters
+.TP
+\fB\-t\fR, \fB\-\-profile\fR=\fIpms\fR
+profile(s) to generate (p=PSD, m=MC, s=SWU)
+.TP
+\-?, \fB\-\-help\fR
+Give this help list
+.TP
+\fB\-\-usage\fR
+Give a short usage message
+.TP
+\fB\-V\fR, \fB\-\-version\fR
+Print program version
+
+.TP
+
+.SH SEE ALSO
+aghermann(1).
+.SH AUTHOR
+agh-profile-gen is written by Andrei Zavada <johnhommer at gmail.com> as part
+of the Aghermann project.
diff --git a/src/libsigfile/source.hh b/src/libsigfile/source.hh
index 98aed9d..4bd2cfa 100644
--- a/src/libsigfile/source.hh
+++ b/src/libsigfile/source.hh
@@ -9,8 +9,8 @@
  *         License:  GPL
  */
 
-#ifndef _SIGFILE_SOURCE_H
-#define _SIGFILE_SOURCE_H
+#ifndef AGH_SIGFILE_SOURCE_H_
+#define AGH_SIGFILE_SOURCE_H_
 
 #include "source-base.hh"
 #include "edf.hh"
@@ -89,7 +89,7 @@ struct SNamedChannel {
 
 } // namespace sigfile
 
-#endif // _AGH_SOURCE_H
+#endif // AGH_SIGFILE_SOURCE_H_
 
 // Local Variables:
 // Mode: c++
diff --git a/src/tools/.gitignore b/src/tools/.gitignore
index 813cdc3..a18e5f1 100644
--- a/src/tools/.gitignore
+++ b/src/tools/.gitignore
@@ -1,3 +1,4 @@
 edfcat
 edfhed
 edfhed-gtk
+agh-profile-gen
diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am
index ddd41dd..982be97 100644
--- a/src/tools/Makefile.am
+++ b/src/tools/Makefile.am
@@ -5,8 +5,8 @@ AM_CXXFLAGS := \
 bin_PROGRAMS := \
 	edfcat \
 	edfhed \
-	edfhed-gtk
-#	agh-profile-gen
+	edfhed-gtk \
+	agh-profile-gen
 
 edfcat_SOURCES := \
 	edfcat.cc
@@ -38,3 +38,14 @@ edfhed_gtk_LDADD := \
 	$(GTK_LIBS) \
 	$(OPENMP_LDADD) $(LIBFFTW3_LDADD)
 
+
+agh_profile_gen_SOURCES := \
+	agh-profile-gen.cc
+agh_profile_gen_LDADD := \
+	../libsigfile/libsigfile.la \
+	../common/liba.a \
+	../libsigproc/libsigproc.la \
+	../libmetrics/libmetrics.la \
+	$(FFTW3_LIBS) $(ITPP_LIBS) $(SAMPLERATE_LIBS) $(GSL_LIBS) \
+	$(OPENMP_LDADD) $(LIBFFTW3_LDADD)
+
diff --git a/src/tools/agh-profile-gen.cc b/src/tools/agh-profile-gen.cc
new file mode 100644
index 0000000..b7425e2
--- /dev/null
+++ b/src/tools/agh-profile-gen.cc
@@ -0,0 +1,237 @@
+/*
+ *       File name:  tools/agh-profile-gen.cc
+ *         Project:  Aghermann
+ *          Author:  Andrei Zavada <johnhommer at gmail.com>
+ * Initial version:  2013-06-18
+ *
+ *         Purpose:  Standalone profile generator
+ *
+ *         License:  GPL
+ */
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <utime.h>
+#include <stdlib.h>
+
+#include <stdexcept>
+#include <set>
+
+#include "common/alg.hh"
+#include "common/fs.hh"
+#include "common/string.hh"
+#include "libsigfile/edf.hh"
+#include "libsigfile/source.hh"
+#include "libmetrics/all.hh"
+
+#if HAVE_CONFIG_H && !defined(VERSION)
+#  include "config.h"
+#endif
+
+#include <argp.h>
+
+
+using namespace std;
+
+#define ARGV0 "agh-profile-gen"
+
+const char
+	*argp_program_version = ARGV0 " " VERSION,
+	*argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";
+
+static char doc[] =
+       ARGV0 " -- sleep profile (PSD, MC, SWU) generator";
+
+enum TOptChar : char {
+	o_profile    = 't',
+	o_page       = 'p',
+	o_step       = 'i',
+	o_samplearte = 's',
+	o_psd_params = 'P',
+	o_mc_params  = 'M',
+	o_swu_params = 'S',
+	o_channel    = 'h',
+};
+
+static struct argp_option options[] = {
+       {"channel",		o_channel,    "CHANNEL",		0, "use this channel (0-based)"			},
+       {"profile",		o_profile,    "pms",			0, "profile(s) to generate (p=PSD, m=MC, s=SWU)"},
+       {"page",			o_page,       "PAGESIZE",		0, "page size (sec)"				},
+       {"step",			o_step,       "STEP",			0, "step (sec)"					},
+       {"samplerate",		o_samplearte, "SAMPLERATE",		0, "samplerate (1/sec)"				},
+       {"psd-params",		o_psd_params, "BINSIZE",		0, "PSD: binsize (sec, one of .1, .25, .5)"	},
+       {"mc-params",		o_mc_params,  "SCOPE:F0FC:BANDWIDTH:IIR_BACKPOLATE:GAIN:SMOOTH",
+									0, "MC parameters"				},
+       {"swu-params",		o_swu_params, "MIN_UPSWING_LEN",	0, "SWU parameters"				},
+       { 0 }
+     };
+
+static char args_doc[] = "FILE";
+
+static error_t parse_opt( int, char*, struct argp_state*);
+
+static struct argp argp = {
+	options,
+	parse_opt,
+	args_doc,
+	doc
+};
+
+
+struct SArguments {
+	string	file;
+	int	h;
+
+	double	pagesize, // will propagate to any *_pp
+		step;
+
+	set<metrics::TType>
+		types;
+
+	metrics::psd::SPPack psd_pp;
+	metrics::mc ::SPPack mc_pp;
+	metrics::swu::SPPack swu_pp;
+
+	size_t	samplerate;
+
+	SArguments()
+	      : h (-1),
+		pagesize (NAN),
+		step (NAN)
+		{}
+};
+
+
+static error_t
+parse_opt( int key, char *arg, struct argp_state *state)
+{
+	auto& Q = *(SArguments*)state->input;
+
+	switch ( key ) {
+	case TOptChar::o_profile:
+		if ( strchr( arg, 'p') )
+			Q.types.insert(metrics::TType::psd);
+		if ( strchr( arg, 'm') )
+			Q.types.insert(metrics::TType::mc);
+		if ( strchr( arg, 's') )
+			Q.types.insert(metrics::TType::swu);
+		break;
+
+	case TOptChar::o_page:
+		Q.pagesize = atof( arg);
+		break;
+
+	case TOptChar::o_step:
+		Q.step = atof( arg);
+		break;
+
+	case TOptChar::o_samplearte:
+		Q.samplerate = atof( arg);
+		break;
+
+	case TOptChar::o_channel:
+		Q.h = atoi( arg);
+		break;
+
+	case TOptChar::o_psd_params:
+		sscanf( arg, "%lg",
+			&Q.psd_pp.binsize);
+		break;
+
+	case TOptChar::o_mc_params:
+		sscanf( arg, "%lg:%lg:%lg:%lg:%lg",
+			&Q.mc_pp.scope, &Q.mc_pp.f0fc, &Q.mc_pp.bandwidth, &Q.mc_pp.iir_backpolate, &Q.mc_pp.mc_gain);
+		break;
+
+	case TOptChar::o_swu_params:
+		sscanf( arg, "%lg",
+			&Q.swu_pp.min_upswing_duration);
+		break;
+
+	case ARGP_KEY_ARG:
+		if ( Q.file.empty() )
+			Q.file = arg;
+		else
+			throw invalid_argument ("Can only process one file/channel at a time");
+		break;
+
+	case ARGP_KEY_END:
+		if ( state->arg_num < 1 )
+			argp_usage( state);
+		break;
+	default:
+		return (error_t)ARGP_ERR_UNKNOWN;
+	}
+	return (error_t)0;
+}
+
+
+
+
+int
+main( int argc, char **argv)
+{
+	SArguments A;
+	try {
+		argp_parse( &argp, argc, argv, 0, NULL, (void*)&A);
+
+		if ( A.h == -1 )
+			throw invalid_argument ("Invalid or missing channel");
+
+		if ( A.types.empty() )
+			throw invalid_argument ("Which profiles do you want?");
+
+		if ( !isfinite(A.pagesize) || !isfinite(A.step) )
+			throw invalid_argument ("Missing or invalid pagesize or step");
+
+		bool	do_psd = A.types.find( metrics::TType::psd) != A.types.end(),
+			do_mc  = A.types.find( metrics::TType:: mc) != A.types.end(),
+			do_swu = A.types.find( metrics::TType::swu) != A.types.end();
+
+		if ( do_psd )
+			A.psd_pp.pagesize = A.pagesize, A.psd_pp.check();
+		if ( do_mc )
+			A.mc_pp.pagesize = A.pagesize, A.mc_pp.check();
+		if ( do_swu )
+			A.swu_pp.pagesize = A.pagesize, A.swu_pp.check();
+
+		if ( A.file.empty() )
+			throw invalid_argument ("Missing file name");
+
+		sigfile::CTypedSource F (A.file, A.pagesize, 0|sigfile::CTypedSource::no_ancillary_files);
+		if ( do_psd ) {
+			metrics::psd::CProfile P (F, A.h, A.psd_pp);
+			if ( P.go_compute() )
+				throw runtime_error ("Failed to compute PSD");
+			P.export_tsv( A.file + ".psd");
+		}
+		if ( do_mc ) {
+			metrics::mc::CProfile P (F, A.h, A.mc_pp);
+			if ( P.go_compute() )
+				throw runtime_error ("Failed to compute MC");
+			P.export_tsv( A.file + ".mc");
+		}
+		if ( do_swu ) {
+			metrics::swu::CProfile P (F, A.h, A.swu_pp);
+			if ( P.go_compute() )
+				throw runtime_error ("Failed to compute SWU");
+			P.export_tsv( A.file + ".swu");
+		}
+
+		return 0;
+
+	} catch ( exception& ex ) {
+		fprintf( stderr, "Error: %s\n", ex.what());
+		return 1;
+	}
+}
+
+
+
+// Local Variables:
+// Mode: c++
+// indent-tabs-mode: 8
+// End:

-- 
Sleep experiment manager



More information about the debian-med-commit mailing list