The following commit has been merged in the master branch:
commit 6e987581691c0dff84595e31aaf8a928a1ff13b9
Author: Andrei Zavada <[email protected]>
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 <[email protected]> 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 <[email protected]>
+ * 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

_______________________________________________
debian-med-commit mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/debian-med-commit

Reply via email to