[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