[med-svn] [aghermann] 31/60: unify the three artifact detection algorithms (part 2/3)

andrei zavada hmmr-guest at alioth.debian.org
Mon Nov 4 23:49:56 UTC 2013


This is an automated email from the git hooks/post-receive script.

hmmr-guest pushed a commit to branch WIP
in repository aghermann.

commit 3bde897e9ab3400d17f1c9fdcc5da251f2c238d6
Author: Andrei Zavada <johnhommer at gmail.com>
Date:   Fri Oct 18 00:37:51 2013 +0300

    unify the three artifact detection algorithms (part 2/3)
---
 upstream/data/sf-artifacts.glade                   |   96 ++++++++++++------
 upstream/src/aghermann/Makefile.am                 |    1 +
 upstream/src/aghermann/artifact-detection/3in1.cc  |  106 +++++++++++---------
 upstream/src/aghermann/artifact-detection/3in1.hh  |   10 +-
 .../aghermann/artifact-detection/forward-decls.hh  |   31 ++++++
 upstream/src/aghermann/expdesign/recording.cc      |   17 +---
 upstream/src/aghermann/expdesign/recording.hh      |    6 --
 upstream/src/aghermann/rk1968/rk1968.hh            |    2 +-
 .../src/aghermann/ui/dirlevel-storable-adapter.ii  |    2 +
 upstream/src/aghermann/ui/mw/mainmenu_cb.cc        |    5 +-
 upstream/src/aghermann/ui/sf/channel.cc            |   11 +-
 upstream/src/aghermann/ui/sf/channel.hh            |    2 +-
 upstream/src/aghermann/ui/sf/d/artifacts.cc        |   92 ++++++-----------
 upstream/src/common/config-validate.hh             |    2 +-
 upstream/src/libsigfile/edf.cc                     |    4 +-
 upstream/src/libsigfile/edf.hh                     |    5 +-
 upstream/src/libsigfile/forward-decls.hh           |    1 +
 upstream/src/libsigfile/source-base.hh             |   43 ++++----
 upstream/src/libsigfile/tsv.cc                     |    2 +-
 upstream/src/libsigfile/tsv.hh                     |    4 +-
 upstream/src/libsigfile/typed-source.hh            |   10 +-
 21 files changed, 248 insertions(+), 204 deletions(-)

diff --git a/upstream/data/sf-artifacts.glade b/upstream/data/sf-artifacts.glade
index 1bddef5..c75507f 100644
--- a/upstream/data/sf-artifacts.glade
+++ b/upstream/data/sf-artifacts.glade
@@ -1,6 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkAdjustment" id="jSFADBackpolate">
+    <property name="upper">1</property>
+    <property name="value">0.5</property>
+    <property name="step_increment">0.01</property>
+    <property name="page_increment">0.10000000000000001</property>
+  </object>
   <object class="GtkAdjustment" id="jSFADBandwidth">
     <property name="lower">0.5</property>
     <property name="upper">4</property>
@@ -8,6 +14,20 @@
     <property name="step_increment">0.25</property>
     <property name="page_increment">1</property>
   </object>
+  <object class="GtkAdjustment" id="jSFADEMGMinSteadyToneFactor">
+    <property name="lower">1.01</property>
+    <property name="upper">100</property>
+    <property name="value">1.2</property>
+    <property name="step_increment">0.01</property>
+    <property name="page_increment">0.10000000000000001</property>
+  </object>
+  <object class="GtkAdjustment" id="jSFADEMGMinSteadyToneRun">
+    <property name="lower">0.10000000000000001</property>
+    <property name="upper">10</property>
+    <property name="value">1</property>
+    <property name="step_increment">0.10000000000000001</property>
+    <property name="page_increment">1</property>
+  </object>
   <object class="GtkAdjustment" id="jSFADEvalue">
     <property name="lower">0.10000000000000001</property>
     <property name="upper">40</property>
@@ -29,6 +49,19 @@
     <property name="step_increment">0.25</property>
     <property name="page_increment">1</property>
   </object>
+  <object class="GtkAdjustment" id="jSFADFlatMinRegionSize">
+    <property name="lower">0.050000000000000003</property>
+    <property name="upper">120</property>
+    <property name="value">0.5</property>
+    <property name="step_increment">0.050000000000000003</property>
+    <property name="page_increment">0.5</property>
+  </object>
+  <object class="GtkAdjustment" id="jSFADFlatPad">
+    <property name="upper">10</property>
+    <property name="value">0.20000000000000001</property>
+    <property name="step_increment">0.050000000000000003</property>
+    <property name="page_increment">0.5</property>
+  </object>
   <object class="GtkAdjustment" id="jSFADHistBins">
     <property name="lower">80</property>
     <property name="upper">9000</property>
@@ -69,11 +102,6 @@
     <property name="step_increment">1</property>
     <property name="page_increment">10</property>
   </object>
-  <object class="GtkAdjustment" id="jSFADSmoothSide">
-    <property name="upper">8</property>
-    <property name="step_increment">1</property>
-    <property name="page_increment">2</property>
-  </object>
   <object class="GtkAdjustment" id="jSFADUpperThr">
     <property name="lower">1</property>
     <property name="upper">30</property>
@@ -81,11 +109,10 @@
     <property name="step_increment">0.5</property>
     <property name="page_increment">2</property>
   </object>
-  <object class="GtkAdjustment" id="jSFADBackpolate">
-    <property name="upper">1</property>
-    <property name="value">0.5</property>
-    <property name="step_increment">0.01</property>
-    <property name="page_increment">0.10000000000000001</property>
+  <object class="GtkAdjustment" id="jSFADSmoothSide">
+    <property name="upper">8</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">2</property>
   </object>
   <object class="GtkDialog" id="wSFAD">
     <property name="can_focus">False</property>
@@ -161,6 +188,7 @@
               <object class="GtkBox" id="box2">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <property name="spacing">10</property>
                 <child>
                   <object class="GtkLabel" id="lSFADInfo">
                     <property name="visible">True</property>
@@ -256,6 +284,7 @@
               <object class="GtkExpander" id="expander1">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
+                <property name="resize_toplevel">True</property>
                 <child>
                   <object class="GtkGrid" id="cSFADMicrocontinuityOptions">
                     <property name="visible">True</property>
@@ -968,21 +997,6 @@
                       </packing>
                     </child>
                     <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
                       <object class="GtkCheckButton" id="eSFADMCBasedConsider">
                         <property name="label" translatable="yes">Inspect every </property>
                         <property name="visible">True</property>
@@ -999,6 +1013,21 @@
                         <property name="height">1</property>
                       </packing>
                     </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
                   </object>
                 </child>
                 <child type="label">
@@ -1016,6 +1045,7 @@
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">True</property>
+                <property name="padding">5</property>
                 <property name="position">1</property>
               </packing>
             </child>
@@ -1024,6 +1054,7 @@
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="use_underline">True</property>
+                <property name="resize_toplevel">True</property>
                 <child>
                   <object class="GtkTable" id="table4">
                     <property name="visible">True</property>
@@ -1070,12 +1101,13 @@
                         <property name="invisible_char">•</property>
                         <property name="xalign">1</property>
                         <property name="invisible_char_set">True</property>
-                        <property name="adjustment"/>
+                        <property name="adjustment">jSFADFlatMinRegionSize</property>
                         <property name="digits">2</property>
                       </object>
                       <packing>
                         <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
                       </packing>
                     </child>
                     <child>
@@ -1099,7 +1131,7 @@
                         <property name="invisible_char">•</property>
                         <property name="xalign">1</property>
                         <property name="invisible_char_set">True</property>
-                        <property name="adjustment"/>
+                        <property name="adjustment">jSFADFlatPad</property>
                         <property name="digits">2</property>
                       </object>
                       <packing>
@@ -1107,6 +1139,7 @@
                         <property name="right_attach">2</property>
                         <property name="top_attach">1</property>
                         <property name="bottom_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
                       </packing>
                     </child>
                     <child>
@@ -1145,6 +1178,8 @@
               <object class="GtkExpander" id="expander3">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
+                <property name="use_underline">True</property>
+                <property name="resize_toplevel">True</property>
                 <child>
                   <object class="GtkTable" id="table2">
                     <property name="visible">True</property>
@@ -1170,13 +1205,14 @@
                         <property name="invisible_char">•</property>
                         <property name="xalign">1</property>
                         <property name="invisible_char_set">True</property>
-                        <property name="adjustment"/>
+                        <property name="adjustment">jSFADEMGMinSteadyToneFactor</property>
                         <property name="digits">2</property>
                         <property name="numeric">True</property>
                       </object>
                       <packing>
                         <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
                       </packing>
                     </child>
                     <child>
@@ -1215,13 +1251,15 @@
                         <property name="invisible_char">•</property>
                         <property name="xalign">1</property>
                         <property name="invisible_char_set">True</property>
-                        <property name="adjustment"/>
+                        <property name="adjustment">jSFADEMGMinSteadyToneRun</property>
+                        <property name="digits">2</property>
                       </object>
                       <packing>
                         <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
                         <property name="top_attach">1</property>
                         <property name="bottom_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
                       </packing>
                     </child>
                     <child>
diff --git a/upstream/src/aghermann/Makefile.am b/upstream/src/aghermann/Makefile.am
index 2aa3af9..3215a04 100644
--- a/upstream/src/aghermann/Makefile.am
+++ b/upstream/src/aghermann/Makefile.am
@@ -9,6 +9,7 @@ AM_CXXFLAGS := \
 bin_PROGRAMS := aghermann
 
 aghermann_SOURCES := \
+	artifact-detection/forward-decls.hh \
 	artifact-detection/3in1.cc \
 	artifact-detection/3in1.hh \
 	expdesign/forward-decls.hh \
diff --git a/upstream/src/aghermann/artifact-detection/3in1.cc b/upstream/src/aghermann/artifact-detection/3in1.cc
index d2ee889..c8a29ec 100644
--- a/upstream/src/aghermann/artifact-detection/3in1.cc
+++ b/upstream/src/aghermann/artifact-detection/3in1.cc
@@ -11,10 +11,10 @@
 
 #include "3in1.hh"
 #include "common/lang.hh"
+#include "libsigfile/source-base.hh"
+#include "libsigfile/typed-source.hh"
 #include "aghermann/globals.hh"
-#include "aghermann/expdesign/subject.hh"
-#include "aghermann/expdesign/recording.hh"
-
+#include "aghermann/rk1968/rk1968.hh"
 using namespace std;
 using namespace agh::ad;
 
@@ -60,8 +60,11 @@ serialize() const
         return move(
                 CStorablePPack::serialize() +
                 agh::str::sasprintf(
-                        "scope:%g; upper_thr:%g; lower_thr:%g; f0:%g; fc:%g; bandwidth:%g; mc_gain:%g; iir_backpolate:%g; E:%g; dmin:%g; dmax:%g; sssu_hist_size:%zu; smooth_side:%zu; estimate_E:%d;  use_range:%d;",
-                        // FIXME: mention all members please?
+                        "flat.min_size:%g; flat.pad:%g;\n"
+                        "emg.min_steadytone_factor:%g; emg.min_steadytone_run:%g;\n"
+                        "MC.scope:%g; MC.upper_thr:%g; MC.lower_thr:%g; MC.f0:%g; MC.fc:%g; MC.bandwidth:%g; MC.mc_gain:%g; MC.iir_backpolate:%g; MC.E:%g; MC.dmin:%g; MC.dmax:%g; MC.sssu_hist_size:%zu; MC.smooth_side:%zu; MC.estimate_E:%d; MC.use_range:%d;",
+                        Pp.flat_min_size, Pp.flat_pad,
+                        Pp.emg_min_steadytone_factor, Pp.emg_min_steadytone_run,
                         Pp.MC.scope, Pp.MC.upper_thr, Pp.MC.lower_thr, Pp.MC.f0, Pp.MC.fc, Pp.MC.bandwidth, Pp.MC.mc_gain, Pp.MC.iir_backpolate,
                         Pp.MC.E, Pp.MC.dmin, Pp.MC.dmax, Pp.MC.sssu_hist_size, Pp.MC.smooth_side,
                         Pp.MC.estimate_E, Pp.MC.use_range));
@@ -70,18 +73,19 @@ serialize() const
 
 
 TDetectArtifactsResult
-detect_artifacts( agh::CRecording& R,
+agh::ad::
+detect_artifacts( sigfile::SNamedChannel& N,
                   const SComprehensiveArtifactDetectionPPack& P)
 {
-        auto S = R.F().get_signal_original( R.h());
-        size_t sr = R.F().samplerate( R.h());
+        auto S = N.source.get_signal_original( N.sig_no);
+        size_t sr = N.source.samplerate( N.sig_no);
 
-        auto AF2 = R.F().artifacts( R.h());
-        auto& AF = R.F().artifacts( R.h());
+        auto AF2 = N.source.artifacts( N.sig_no);
+        auto& AF = N.source.artifacts( N.sig_no);
         bool marked_some = false;
 
         // 1. Flat regions
-        {
+        if ( P.do_flat_regions ) {
                 size_t  last_j = 0;
                 for ( size_t i = 0; i < S.size(); ++i ) {
                         if ( agh::dbl_cmp( S[i], S[last_j]) == 0 ) {
@@ -100,11 +104,42 @@ detect_artifacts( agh::CRecording& R,
                 }
         }
 
-        // 2. EMG perturbations tada, needs EMG channel: how to get it here?
-        
+      // 2. EMG perturbations
+        if ( P.do_emg_perturbations ) {
+                // which EMG channels are there?
+                list<int> emgRR;
+                for ( int h = 0; h < (int)N.source.n_channels(); ++h )
+                        if ( N.source.signal_type(h) == sigfile::SChannel::TType::emg )
+                                emgRR.push_front( h);
+
+                if ( emgRR.empty() )
+                        APPLOG_INFO ("No EMG recordings in %s:%s, skipping EMG perturbation-bound artifact detection", N.source.filename(), N.source.channel_by_id(N.sig_no).name());
+
+                for ( int h = 0; h < (int)emgRR.size(); ++h ) {
+                        sigproc::SSignalRef<TFloat> sigref {N.source.get_signal_original(h), N.source.samplerate(h)};
+                        double this_steady_tone;
+                        tie (this_steady_tone, ignore) =
+                                agh::rk1968::emg_steady_tone(
+                                        sigref,
+                                        P.emg_steady_secs,
+                                        P.emg_max_dev_factor);
+                        //APPLOG_INFO ("steady tone: %g", this_steady_tone);
+                        auto emg_raw_profile =
+                                sigproc::raw_signal_profile<TFloat>(
+                                        sigref,
+                                        1., P.emg_min_steadytone_run);
+                        for ( size_t t = 0; t < emg_raw_profile.size(); ++t )
+                                if ( emg_raw_profile[t] > this_steady_tone * P.emg_min_steadytone_factor ) {
+                                        //APPLOG_INFO ("perturbed[%zu]? %g > %g * %g", t, emg_raw_profile[t], this_steady_tone,  P.emg_min_steadytone_factor);
+                                        AF.mark_artifact(
+                                                (t+0) * P.emg_min_steadytone_run,
+                                                (t+1) * P.emg_min_steadytone_run);
+                                }
+                }
+        }
 
         // 3. MC-based
-        {
+        if ( P.do_mc_based ) {
                 auto marked =
                         metrics::mc::detect_artifacts( S, sr, P.MC);
                 for ( size_t p = 0; p < marked.size(); ++p ) {
@@ -125,44 +160,15 @@ detect_artifacts( agh::CRecording& R,
 
 // this looks appropriate if we claim to be comprehensive
 void
-detect_artifacts( agh::SEpisode& E,
+agh::ad::
+detect_artifacts( sigfile::CSource& F,
                   const SComprehensiveArtifactDetectionPPack& P)
 {
-      // 1. and 3. are simple, single-channel algorithms
-        for ( auto& HR : E.recordings )
-                agh::ad::detect_artifacts( HR.second, P);
-
-      // 2. EMG perturbations
-        // which EMG channels are there?
-        list<agh::CRecording*> emgRR;
-        for ( auto& HR : E.recordings ) {
-                const sigfile::SChannel& H = HR.first;
-                agh::CRecording& R = HR.second;
-                if ( H.type() == sigfile::SChannel::TType::emg )
-                        emgRR.push_front( &R);
-                if ( emgRR.empty() ) {
-                        APPLOG_INFO ("No EMG recordings in episode %s (%s), skipping EMG perturbation-bound artifact detection", E.name(), E.sources.front()().patient_id());
-                }
-        }
-
-        for ( auto& emgR : emgRR ) {
-                double this_steady_tone =
-                        emgR->emg_steady_tone(
-                                P.emg_steady_secs, P.emg_max_dev_factor);
-                auto emg_raw_profile =
-                        sigproc::raw_signal_profile<TFloat>(
-                                {emgR->F().get_signal_original( emgR->h()), emgR->F().samplerate( emgR->h())},
-                                1., P.emg_min_steadytone_run);
-                for ( size_t t = 0; t < emg_raw_profile.size(); ++t )
-                        if ( emg_raw_profile[t] > this_steady_tone * P.emg_min_steadytone_factor )
-                                for ( auto& HR : E.recordings ) {
-                                        // if ( &HR.second != emgR ) {  // why skip emg channels indeed?
-                                        agh::CRecording& R = HR.second;
-                                        auto& AF = R.F().artifacts( R.h());
-                                        AF.mark_artifact(
-                                                (t+0) * P.emg_min_steadytone_run,
-                                                (t+1) * P.emg_min_steadytone_run);
-                                }
+        // it may be reasonable for this function to be or do
+        // something more than just a mere channel iterator
+        for ( int h = 0; h < (int)F.n_channels(); ++h ) {
+                sigfile::SNamedChannel N {F, h};
+                agh::ad::detect_artifacts( N, P);
         }
 }
 
diff --git a/upstream/src/aghermann/artifact-detection/3in1.hh b/upstream/src/aghermann/artifact-detection/3in1.hh
index f49b1ca..8794729 100644
--- a/upstream/src/aghermann/artifact-detection/3in1.hh
+++ b/upstream/src/aghermann/artifact-detection/3in1.hh
@@ -17,8 +17,8 @@
 #include <gtk/gtk.h>
 
 #include "common/lang.hh"
+#include "libsigfile/typed-source.hh"
 #include "libmetrics/mc-artifacts.hh"
-#include "libsigfile/source-base.hh"
 #include "aghermann/expdesign/dirlevel.hh"
 #include "aghermann/expdesign/forward-decls.hh"
 
@@ -90,7 +90,9 @@ class CComprehensiveArtifactDetector
         CComprehensiveArtifactDetector (const string& name_, agh::TExpDirLevel, agh::CExpDesign&, const agh::SExpDirLevelId&);
         CComprehensiveArtifactDetector (agh::CExpDesign& ED_, const agh::SExpDirLevelId& level_id_)
               : CStorablePPack (common_subdir, "(unnamed)", agh::TExpDirLevel::transient, ED_, level_id_)
-                {}
+                {
+                        make_default_SComprehensiveArtifactDetectionPPack( Pp);
+                }
         explicit CComprehensiveArtifactDetector (const CComprehensiveArtifactDetector& rv)
               : CStorablePPack (rv),
                 Pp (rv.Pp)
@@ -130,11 +132,11 @@ enum class TDetectArtifactsResult {
 };
 
 TDetectArtifactsResult
-detect_artifacts( agh::CRecording& R,
+detect_artifacts( sigfile::SNamedChannel& R,
                   const SComprehensiveArtifactDetectionPPack& P);
 
 void
-detect_artifacts( agh::SEpisode& E,
+detect_artifacts( sigfile::CSource& E,
                   const SComprehensiveArtifactDetectionPPack& P);
 
 }}
diff --git a/upstream/src/aghermann/artifact-detection/forward-decls.hh b/upstream/src/aghermann/artifact-detection/forward-decls.hh
new file mode 100644
index 0000000..13db3e6
--- /dev/null
+++ b/upstream/src/aghermann/artifact-detection/forward-decls.hh
@@ -0,0 +1,31 @@
+/*
+ *       File name:  aghermann/artifact-detection/forward-decls.hh
+ *         Project:  Aghermann
+ *          Author:  Andrei Zavada <johnhommer at gmail.com>
+ * Initial version:  2013-10-16
+ *
+ *         Purpose:  forward declarations of ::agh::ad classes
+ *
+ *         License:  GPL
+ */
+
+
+#ifndef AGH_AGHERMANN_ARTIFACT_DETECTION_FORWARD_DECLS_H_
+#define AGH_AGHERMANN_ARTIFACT_DETECTION_FORWARD_DECLS_H_
+
+namespace agh {
+namespace ad {
+
+struct SComprehensiveArtifactDetectionPPack;
+class CComprehensiveArtifactDetector;
+
+}} // namespace agh::ad
+
+#endif
+
+// Local Variables:
+// Mode: c++
+// indent-tabs-mode: nil
+// tab-width: 8
+// c-basic-offset: 8
+// End:
diff --git a/upstream/src/aghermann/expdesign/recording.cc b/upstream/src/aghermann/expdesign/recording.cc
index 5789d73..d9703b6 100644
--- a/upstream/src/aghermann/expdesign/recording.cc
+++ b/upstream/src/aghermann/expdesign/recording.cc
@@ -33,8 +33,7 @@ CRecording (sigfile::CTypedSource& F, int sig_no,
         mc_profile  (F, sig_no, mc_params),
         uc_params (nullptr),
         _status (0), // not computed
-        _source (F), _sig_no (sig_no),
-        _cached_emg_steady_tone (NAN)
+        _source (F), _sig_no (sig_no)
 {}
 
 
@@ -47,20 +46,6 @@ agh::CRecording::
 
 
 
-double
-agh::CRecording::
-emg_steady_tone( size_t steady_secs, double max_dev_factor)
-{
-        if ( !isfinite( _cached_emg_steady_tone) ||
-             _cached_steady_secs != steady_secs ||
-             _cached_max_dev_factor != max_dev_factor )
-                tie (_cached_emg_steady_tone, ignore) =
-                        agh::rk1968::emg_steady_tone(
-                                sigproc::SSignalRef<TFloat> {_source().get_signal_original(_sig_no), _source().samplerate(_sig_no)},
-                                _cached_steady_secs = steady_secs,
-                                _cached_max_dev_factor = max_dev_factor);
-        return _cached_emg_steady_tone;
-}
 
 
 
diff --git a/upstream/src/aghermann/expdesign/recording.hh b/upstream/src/aghermann/expdesign/recording.hh
index e7e9af9..2254e93 100644
--- a/upstream/src/aghermann/expdesign/recording.hh
+++ b/upstream/src/aghermann/expdesign/recording.hh
@@ -243,18 +243,12 @@ class CRecording {
         agh::beersma::SUltradianCycle
                 *uc_params;
 
-        double  emg_steady_tone( size_t steady_secs, double max_dev_factor);
-
     protected:
         int     _status;
 
         sigfile::CTypedSource&
                 _source;
         int     _sig_no;
-
-        size_t  _cached_steady_secs;
-        double  _cached_max_dev_factor;
-        double  _cached_emg_steady_tone;
 };
 
 
diff --git a/upstream/src/aghermann/rk1968/rk1968.hh b/upstream/src/aghermann/rk1968/rk1968.hh
index 5bbd2f0..d49c030 100644
--- a/upstream/src/aghermann/rk1968/rk1968.hh
+++ b/upstream/src/aghermann/rk1968/rk1968.hh
@@ -112,7 +112,7 @@ emg_steady_tone( const sigproc::SSignalRef<T>& V, size_t steady_secs, double max
         size_t s = 1 * V.samplerate;
         for ( int sec = 0; sec < V.signal.size() / V.samplerate - steady_secs - 1; ++sec ) {
                 auto range = slice (sec * s, s, 1);
-                bench[sec % steady_secs] = V.signal[range].sum() / s;
+                bench[sec % steady_secs] = 2 * V.signal[range].apply(fabs).sum() / s;
                 if ( sec < steady_secs )
                         continue;
                 T avg = bench.sum() / steady_secs;
diff --git a/upstream/src/aghermann/ui/dirlevel-storable-adapter.ii b/upstream/src/aghermann/ui/dirlevel-storable-adapter.ii
index 44654c4..0ad7b71 100644
--- a/upstream/src/aghermann/ui/dirlevel-storable-adapter.ii
+++ b/upstream/src/aghermann/ui/dirlevel-storable-adapter.ii
@@ -220,6 +220,8 @@ bXProfileSave_clicked_cb()
                 break;
         }
 
+        check_profile_name_save_button_label();
+
         if ( GTK_RESPONSE_OK == gtk_dialog_run( wXProfileSaveName) ) {
                 using namespace agh;
 
diff --git a/upstream/src/aghermann/ui/mw/mainmenu_cb.cc b/upstream/src/aghermann/ui/mw/mainmenu_cb.cc
index 90ebbc7..2b0a51f 100644
--- a/upstream/src/aghermann/ui/mw/mainmenu_cb.cc
+++ b/upstream/src/aghermann/ui/mw/mainmenu_cb.cc
@@ -314,10 +314,11 @@ iExpGloballyDetectArtifacts_activate_cb(
                 [&]( SEpisode& E)
                 {
                         if ( not keep_existing )
-                                for ( auto& F : E.sources )
+                                for ( auto& F : E.sources ) {
                                         for ( size_t h = 0; h < F().n_channels(); ++h )
                                                 F().artifacts((int)h).clear_all();
-                        ad::detect_artifacts( E, P);
+                                        ad::detect_artifacts( F(), P);
+                                }
                         // for ( size_t p = 0; p < marked.size(); ++p )
                         //         af.mark_artifact(
                         //                 marked[p] * P.scope * sr,
diff --git a/upstream/src/aghermann/ui/sf/channel.cc b/upstream/src/aghermann/ui/sf/channel.cc
index 4aef7d1..ab0e7e7 100644
--- a/upstream/src/aghermann/ui/sf/channel.cc
+++ b/upstream/src/aghermann/ui/sf/channel.cc
@@ -15,9 +15,10 @@
 #include "common/lang.hh"
 #include "common/alg.hh"
 #include "common/config-validate.hh"
-#include "libsigproc/exstrom.hh"
+//#include "libsigproc/exstrom.hh"
 #include "libmetrics/bands.hh"
 #include "aghermann/globals.hh"
+#include "aghermann/artifact-detection/3in1.hh"
 #include "aghermann/patterns/patterns.hh"
 #include "aghermann/rk1968/rk1968.hh"
 #include "aghermann/ui/globals.hh"
@@ -401,10 +402,12 @@ calculate_dirty_percent()
 
 void
 SScoringFacility::SChannel::
-detect_artifacts( const metrics::mc::SArtifactDetectionPPack& P)
+detect_artifacts( const agh::ad::SComprehensiveArtifactDetectionPPack& P)
 {
-        
-        
+        sigfile::SNamedChannel N {crecording.F(), h()};
+        if ( agh::ad::TDetectArtifactsResult::marked_new !=
+             agh::ad::detect_artifacts( N, P) )
+                return;
 
         calculate_dirty_percent();
         get_signal_filtered();
diff --git a/upstream/src/aghermann/ui/sf/channel.hh b/upstream/src/aghermann/ui/sf/channel.hh
index 644b6df..3c4aac5 100644
--- a/upstream/src/aghermann/ui/sf/channel.hh
+++ b/upstream/src/aghermann/ui/sf/channel.hh
@@ -22,9 +22,9 @@
 #include "common/config-validate.hh"
 #include "libsigproc/forward-decls.hh"
 #include "libsigfile/forward-decls.hh"
-#include "libmetrics/mc-artifacts.hh"
 #include "libmetrics/page-metrics-base.hh"
 #include "libmetrics/bands.hh"
+#include "aghermann/artifact-detection/forward-decls.hh"
 #include "aghermann/patterns/patterns.hh"
 #include "aghermann/expdesign/forward-decls.hh"
 #include "aghermann/expdesign/recording.hh"
diff --git a/upstream/src/aghermann/ui/sf/d/artifacts.cc b/upstream/src/aghermann/ui/sf/d/artifacts.cc
index bb464ba..66c0329 100644
--- a/upstream/src/aghermann/ui/sf/d/artifacts.cc
+++ b/upstream/src/aghermann/ui/sf/d/artifacts.cc
@@ -27,7 +27,7 @@ artifacts_d()
 
 SScoringFacility::SArtifactsDialog::
 SArtifactsDialog (SScoringFacility& p_)
-      : SDirlevelStorableAdapter<agh::ad::CComprehensiveArtifactDetector>> (
+      : SDirlevelStorableAdapter<agh::ad::CComprehensiveArtifactDetector> (
               *p_._p.ED, agh::SExpDirLevelId {p_._p.ED->group_of(p_.csubject()), p_.csubject().id, p_.session()},
               mSFADProfiles, eSFADProfileList, eSFADProfileList_changed_cb_handler_id,
               bSFADProfileSave, bSFADProfileRevert, bSFADProfileDiscard,
@@ -44,6 +44,19 @@ SArtifactsDialog (SScoringFacility& p_)
         gtk_builder_connect_signals( builder, NULL);
 
         AGH_GBGETOBJ (wSFAD);
+
+        AGH_GBGETOBJ (eSFADProfileList);
+        AGH_GBGETOBJ (bSFADProfileSave);
+        AGH_GBGETOBJ (bSFADProfileRevert);
+        AGH_GBGETOBJ (bSFADProfileDiscard);
+        AGH_GBGETOBJ (wSFADProfileSave);
+        AGH_GBGETOBJ (eSFADProfileSaveName);
+        AGH_GBGETOBJ (eSFADProfileSaveOriginSubject);
+        AGH_GBGETOBJ (eSFADProfileSaveOriginExperiment);
+        AGH_GBGETOBJ (eSFADProfileSaveOriginUser);
+        AGH_GBGETOBJ (bSFADProfileSaveOK);
+
+        AGH_GBGETOBJ (eSFADMCBasedConsider);
         AGH_GBGETOBJ (eSFADScope);
         AGH_GBGETOBJ (eSFADUpperThr);
         AGH_GBGETOBJ (eSFADLowerThr);
@@ -63,23 +76,21 @@ SArtifactsDialog (SScoringFacility& p_)
         AGH_GBGETOBJ (eSFADUseComputedRange);
         AGH_GBGETOBJ (cSFADWhenEstimateEOn);
         AGH_GBGETOBJ (cSFADWhenEstimateEOff);
+
+        AGH_GBGETOBJ (eSFADFlatConsider);
+        AGH_GBGETOBJ (eSFADFlatMinRegionSize);
+        AGH_GBGETOBJ (eSFADFlatPad);
+
+        AGH_GBGETOBJ (eSFADEMGConsider);
+        AGH_GBGETOBJ (eSFADEMGMinSteadyToneFactor);
+        AGH_GBGETOBJ (eSFADEMGMinSteadyToneRun);
+
         AGH_GBGETOBJ (lSFADInfo);
         AGH_GBGETOBJ (lSFADDirtyPercent);
         AGH_GBGETOBJ (bSFADPreview);
         AGH_GBGETOBJ (bSFADApply);
         AGH_GBGETOBJ (bSFADDismiss);
 
-        AGH_GBGETOBJ (eSFADProfileList);
-        AGH_GBGETOBJ (bSFADProfileSave);
-        AGH_GBGETOBJ (bSFADProfileRevert);
-        AGH_GBGETOBJ (bSFADProfileDiscard);
-        AGH_GBGETOBJ (wSFADProfileSave);
-        AGH_GBGETOBJ (eSFADProfileSaveName);
-        AGH_GBGETOBJ (eSFADProfileSaveOriginSubject);
-        AGH_GBGETOBJ (eSFADProfileSaveOriginExperiment);
-        AGH_GBGETOBJ (eSFADProfileSaveOriginUser);
-        AGH_GBGETOBJ (bSFADProfileSaveOK);
-
         mSFADProfiles = gtk_list_store_new( 1, G_TYPE_STRING);
         // this GtkListStore is populated from the same source, but something
         // haunting GTK+ forbids reuse of _p.mGlobalArtifactDetectionProfiles
@@ -124,6 +135,7 @@ SArtifactsDialog (SScoringFacility& p_)
                         this);
       // 2. vars
         auto& P = Pp2.Pp;
+        W_V.reg( eSFADMCBasedConsider,               &P.do_mc_based);
         W_V.reg( eSFADScope,                         &P.MC.scope);
         W_V.reg( eSFADUpperThr,                      &P.MC.upper_thr);
         W_V.reg( eSFADLowerThr,                      &P.MC.lower_thr);
@@ -141,7 +153,14 @@ SArtifactsDialog (SScoringFacility& p_)
         W_V.reg( (GtkCheckButton*)eSFADUseThisRange, &P.MC.use_range);
         W_V.reg( eSFADFlatMinRegionSize,             &P.flat_min_size);
         W_V.reg( eSFADFlatPad,                       &P.flat_pad);
-        W_V.reg( eSFADEMGMinSteadyToneFactor,        &P.
+
+        W_V.reg( eSFADEMGConsider,                   &P.do_emg_perturbations);
+        W_V.reg( eSFADEMGMinSteadyToneFactor,        &P.emg_min_steadytone_factor);
+        W_V.reg( eSFADEMGMinSteadyToneRun,           &P.emg_min_steadytone_run);
+
+        W_V.reg( eSFADFlatConsider,                  &P.do_flat_regions);
+        W_V.reg( eSFADFlatMinRegionSize,             &P.flat_min_size);
+        W_V.reg( eSFADFlatPad,                       &P.flat_pad);
 
         atomic_up();
 }
@@ -157,53 +176,6 @@ SScoringFacility::SArtifactsDialog::
 }
 
 
-// a very odd one out!
-// putting these in libmetrics.so brings in a hell of dependencies
-// which are not needed for standalone operations (such as in agh-profile-gen)
-metrics::mc::CArtifactDetector::
-CArtifactDetector (const string& name_, agh::TExpDirLevel level_, agh::CExpDesign& ED_, const agh::SExpDirLevelId& level_id_)
-      : CStorablePPack (common_subdir, name_, level_, ED_, level_id_)
-{
-        using agh::confval::SValidator;
-        config
-                ("scope",          &Pp.scope,           SValidator<double>::SVFRangeIn (0.5, 60.))
-                ("upper_thr",      &Pp.upper_thr,       SValidator<double>::SVFRangeIn (0., 100.))
-                ("lower_thr",      &Pp.lower_thr,       SValidator<double>::SVFRangeIn (-100., 0.))
-                ("f0",             &Pp.f0,              SValidator<double>::SVFRangeIn (.1, 80.))
-                ("fc",             &Pp.fc,              SValidator<double>::SVFRangeIn (.1, 80.))
-                ("bandwidth",      &Pp.bandwidth,       SValidator<double>::SVFRangeIn (.1, 40.))
-                ("mc_gain",        &Pp.mc_gain,         SValidator<double>::SVFRangeIn (0., 100.))
-                ("iir_backpolate", &Pp.iir_backpolate,  SValidator<double>::SVFRangeIn (0., 1.))
-                ("E",              &Pp.E,               SValidator<double>::SVFRangeIn (.1, 100.))
-                ("dmin",           &Pp.dmin,            SValidator<double>::SVFRangeIn (-100., 100.))
-                ("dmax",           &Pp.dmax,            SValidator<double>::SVFRangeIn (-100., 100.))
-                ("sssu_hist_size", &Pp.sssu_hist_size,  SValidator<size_t>::SVFRangeIn (10, 1000))
-                ("smooth_side",    &Pp.smooth_side,     SValidator<size_t>::SVFRangeIn (0, 10))
-                ("estimate_E", &Pp.estimate_E)
-                ("use_range", &Pp.use_range);
-
-        make_default_SArtifactDetectionPPack( Pp);
-        load();
-}
-
-
-string
-metrics::mc::CArtifactDetector::
-serialize() const
-{
-        return move(
-                CStorablePPack::serialize() +
-                agh::str::sasprintf(
-                        "scope:%g; upper_thr:%g; lower_thr:%g; f0:%g; fc:%g; bandwidth:%g; mc_gain:%g; iir_backpolate:%g; E:%g; dmin:%g; dmax:%g; sssu_hist_size:%zu; smooth_side:%zu; estimate_E:%d;  use_range:%d;",
-                        Pp.scope, Pp.upper_thr, Pp.lower_thr, Pp.f0, Pp.fc, Pp.bandwidth, Pp.mc_gain, Pp.iir_backpolate,
-                        Pp.E, Pp.dmin, Pp.dmax, Pp.sssu_hist_size, Pp.smooth_side,
-                        Pp.estimate_E, Pp.use_range));
-}
-
-
-
-
-
 // Local Variables:
 // Mode: c++
 // indent-tabs-mode: nil
diff --git a/upstream/src/common/config-validate.hh b/upstream/src/common/config-validate.hh
index f2ba3e0..004d1be 100644
--- a/upstream/src/common/config-validate.hh
+++ b/upstream/src/common/config-validate.hh
@@ -189,7 +189,7 @@ get( const libconfig::Config& C,
         int tmp; // libconfig doesn't deal in unsigned values
         if ( not C.lookupValue( key, tmp) ) {
                 if (lo)
-                        lo->msg( agh::log::TLevel::warning, LOG_SOURCE_ISSUER, "Key %s not found", key.c_str());
+                        lo->msg( agh::log::TLevel::warning, LOG_SOURCE_ISSUER, "Key \"%s\" not found", key.c_str());
                 return; // leave at default
         }
         if ( tmp < 0 || not valf((size_t)tmp) ) {
diff --git a/upstream/src/libsigfile/edf.cc b/upstream/src/libsigfile/edf.cc
index 83d356d..7b85209 100644
--- a/upstream/src/libsigfile/edf.cc
+++ b/upstream/src/libsigfile/edf.cc
@@ -783,7 +783,7 @@ details( const int which) const
                         n_dicontinuities,
                         common_annotations.size());
 
-                if ( which & with_channels ) {
+                if ( which & TDetails::with_channels ) {
                         size_t i = 0;
                         for ( auto &H : channels ) {
                                 recv << agh::str::sasprintf(
@@ -814,7 +814,7 @@ details( const int which) const
                         }
                 }
 
-                if ( which & with_annotations ) {
+                if ( which & TDetails::with_annotations ) {
                         recv << "Embedded annotations (" << common_annotations.size() << "):\n";
                         for ( auto &A : common_annotations )
                                 recv << ' '
diff --git a/upstream/src/libsigfile/edf.hh b/upstream/src/libsigfile/edf.hh
index d48fd10..9b5e2a5 100644
--- a/upstream/src/libsigfile/edf.hh
+++ b/upstream/src/libsigfile/edf.hh
@@ -92,7 +92,7 @@ class CEDFFile
         // status
         string explain_status() const
                 { return move(explain_status( _status)); }
-        static string explain_status( int);
+        static string explain_status( TStatusBits);
 
         // identification
         const char* patient_id() const
@@ -352,7 +352,7 @@ class CEDFFile
                 }
 
 
-        enum TStatus : int_least32_t {
+        enum TStatus : TStatusBits {
                 bad_version               = (1 << (COMMON_STATUS_BITS + 1)),
                 file_truncated            = (1 << (COMMON_STATUS_BITS + 2)),
                 trailing_junk             = (1 << (COMMON_STATUS_BITS + 3)),
@@ -411,7 +411,6 @@ class CEDFFile
 // Local Variables:
 // Mode: c++
 // indent-tabs-mode: nil
-
 // tab-width: 8
 // c-basic-offset: 8
 // End:
diff --git a/upstream/src/libsigfile/forward-decls.hh b/upstream/src/libsigfile/forward-decls.hh
index 7c3c8dc..6a18134 100644
--- a/upstream/src/libsigfile/forward-decls.hh
+++ b/upstream/src/libsigfile/forward-decls.hh
@@ -27,6 +27,7 @@ struct SFilterPack;
 class CSource;
 class CTypedSource;
 class CHypnogram;
+struct SNamedChannel;
 
 class CTSVFile;
 class CEDFFile;
diff --git a/upstream/src/libsigfile/source-base.hh b/upstream/src/libsigfile/source-base.hh
index 5629cf6..1040087 100644
--- a/upstream/src/libsigfile/source-base.hh
+++ b/upstream/src/libsigfile/source-base.hh
@@ -50,7 +50,7 @@ make_fname_artifacts( const string& filename, const SChannel& channel)
                 filename,
                 supported_sigfile_extensions,
                 agh::fs::TMakeFnameOption::hidden)
-                + "-" + channel.name() + ".af";
+                + "-" + channel.name() + ".artifacts";
 }
 
 inline string
@@ -113,9 +113,11 @@ struct SArtifacts {
         void clear_all()
                 { obj.clear(); }
 
-        float region_dirty_fraction( double a, double z) const;
+        float
+        region_dirty_fraction( double a, double z) const;
 
-        unsigned long dirty_signature() const;
+        unsigned long
+        dirty_signature() const;
 };
 
 
@@ -125,8 +127,9 @@ struct SArtifacts {
 struct SAnnotation {
         static const char EOA = '$';
 
-        agh::alg::SSpan<double> span;
-        string label;
+        agh::alg::SSpan<double>
+                span;
+        string  label;
         enum TType {
                 plain,
                 phasic_event_spindle,
@@ -134,7 +137,7 @@ struct SAnnotation {
                 eyeblink,
                 TType_total
         };
-        TType type;
+        TType   type;
 
         SAnnotation (double aa, double az, const string& l, TType t = TType::plain)
               : span {aa, az},
@@ -229,11 +232,14 @@ class CSource
   : public agh::log::SLoggingClient {
         friend class CTypedSource;
     public:
+        typedef int_least32_t TStatusBits;
+        typedef int_least8_t TFlagBits;
+
         enum TFlags {
                 no_ancillary_files         = 1<<1,
                 no_field_consistency_check = 1<<2,
         };
-        enum TStatus : int_least32_t {
+        enum TStatus : TStatusBits {
                 ok                        = 0,
                 bad_header                = (1 <<  0),
                 bad_numfld                = (1 <<  1),
@@ -252,10 +258,10 @@ class CSource
     protected:
         string  _filename;
 
-        int_least32_t
+        TStatusBits
                 _status;
-
-        int     _flags;
+        TFlagBits
+                _flags;
 
         agh::SSubjectId
                 _subject;
@@ -280,14 +286,16 @@ class CSource
                         /// for similar reasons, some methods will revert to pure when called from CSource dtor
                 }
 
-        int status() const { return _status; }
-        int flags()  const { return _flags; }
+        TStatusBits
+        status() const { return _status; }
+        TFlagBits
+        flags()  const { return _flags; }
 
-        static string explain_status( int);
+        static string explain_status( TStatusBits);
         virtual string explain_status() const
                 { return move(explain_status( _status)); }
 
-        enum TDetails { with_channels = 1, with_annotations = 2 };
+        enum TDetails { with_channels = (1 << 0), with_annotations = (1 << 1) };
         virtual string details( int which_details) const = 0;
 
       // identification
@@ -422,10 +430,11 @@ class CSource
         virtual int
         put_region_smpl( int, const valarray<TFloat>&, size_t) = 0;
 
-        int put_region_sec( const int h, const valarray<TFloat>& src, const float offset)
+        int
+        put_region_sec( const int h, const valarray<TFloat>& src, const float offset)
                 { return put_region_smpl( h, src, offset * samplerate(h)); }
-
-        int put_signal( const int h, const valarray<TFloat>& src)
+        int
+        put_signal( const int h, const valarray<TFloat>& src)
                 { return put_region_smpl( h, src, 0); }
 
       // signal data info
diff --git a/upstream/src/libsigfile/tsv.cc b/upstream/src/libsigfile/tsv.cc
index 955b6f7..baeef74 100644
--- a/upstream/src/libsigfile/tsv.cc
+++ b/upstream/src/libsigfile/tsv.cc
@@ -401,7 +401,7 @@ details( const int which) const
                 channels.size(),
                 _samplerate);
 
-        if ( which & with_channels ) {
+        if ( which & TDetails::with_channels ) {
                 size_t i = 0;
                 for ( auto &H : channels )
                         recv << agh::str::sasprintf(
diff --git a/upstream/src/libsigfile/tsv.hh b/upstream/src/libsigfile/tsv.hh
index 87aa0da..85f8d65 100644
--- a/upstream/src/libsigfile/tsv.hh
+++ b/upstream/src/libsigfile/tsv.hh
@@ -327,7 +327,7 @@ class CTSVFile
                 }
 
 
-        enum TStatus : int_least32_t {
+        enum TStatus : TStatusBits {
                 bad_channel_count        = (1 << (COMMON_STATUS_BITS + 1)),
                 bad_offset               = (1 << (COMMON_STATUS_BITS + 2)),
                 offsets_not_incteasing   = (1 << (COMMON_STATUS_BITS + 3)),
@@ -340,7 +340,7 @@ class CTSVFile
                                            | bad_offset
                                            | offsets_not_incteasing)
         };
-        static string explain_status( int);
+        static string explain_status( TStatusBits);
 
     private:
       // header...
diff --git a/upstream/src/libsigfile/typed-source.hh b/upstream/src/libsigfile/typed-source.hh
index a7701e9..455bfc8 100644
--- a/upstream/src/libsigfile/typed-source.hh
+++ b/upstream/src/libsigfile/typed-source.hh
@@ -75,18 +75,18 @@ class CTypedSource
 };
 
 
-template <> inline         CTSVFile& CTypedSource::obj()       { return *(CTSVFile*)_obj; }
-template <> inline         CEDFFile& CTypedSource::obj()       { return *(CEDFFile*)_obj; }
+template <> inline       CTSVFile& CTypedSource::obj()       { return *(CTSVFile*)_obj; }
+template <> inline       CEDFFile& CTypedSource::obj()       { return *(CEDFFile*)_obj; }
 template <> inline const CTSVFile& CTypedSource::obj() const { return *(CTSVFile*)_obj; }
 template <> inline const CEDFFile& CTypedSource::obj() const { return *(CEDFFile*)_obj; }
 
 
 
-template <typename T = int>
+// template <typename T = int>
 struct SNamedChannel {
         CSource& source;
-        T sig_no;
-        SNamedChannel (CSource& source_, T sig_no_)
+        int sig_no;
+        SNamedChannel (CSource& source_, int sig_no_)
               : source (source_),
                 sig_no (sig_no_)
                 {}

-- 
Alioth's /git/debian-med/git-commit-notice on /srv/git.debian.org/git/debian-med/aghermann.git



More information about the debian-med-commit mailing list