[med-svn] [aghermann] 17/34: profile parameters diamond problem and related work

andrei zavada hmmr-guest at moszumanska.debian.org
Sat Nov 23 00:46:48 UTC 2013


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

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

commit 8ce07df79468c97b10d700dc94261a38a4d7743e
Author: Andrei Zavada <hmmr at ra>
Date:   Fri Nov 15 14:26:41 2013 +0200

    profile parameters diamond problem and related work
---
 upstream/src/aghermann/expdesign/expdesign.cc    |  13 ++-
 upstream/src/aghermann/expdesign/expdesign.hh    |   2 +-
 upstream/src/aghermann/expdesign/loadsave.cc     |  21 ++--
 upstream/src/aghermann/expdesign/recording.cc    |  14 +--
 upstream/src/aghermann/expdesign/recording.hh    |   2 +-
 upstream/src/aghermann/expdesign/tree-scanner.cc |   5 +-
 upstream/src/aghermann/ui/mw/admit-one.cc        |   2 +-
 upstream/src/aghermann/ui/mw/mw.cc               |  20 ++--
 upstream/src/aghermann/ui/mw/mw.hh               |  10 +-
 upstream/src/aghermann/ui/mw/populate.cc         |   8 +-
 upstream/src/aghermann/ui/mw/settings_cb.cc      |  45 ++++----
 upstream/src/aghermann/ui/sf/channel.cc          |   2 +-
 upstream/src/aghermann/ui/sf/montage-overlays.cc |   4 +-
 upstream/src/aghermann/ui/sf/montage_cb.cc       |   2 +-
 upstream/src/libmetrics/mc.cc                    |  87 ++++++++++------
 upstream/src/libmetrics/mc.hh                    | 126 ++++++++++++++---------
 upstream/src/libmetrics/page-metrics-base.cc     |  45 +++++---
 upstream/src/libmetrics/page-metrics-base.hh     |  45 +++++---
 upstream/src/libmetrics/psd.cc                   |  66 ++++++++----
 upstream/src/libmetrics/psd.hh                   |  99 +++++++++---------
 upstream/src/libmetrics/swu.cc                   |  65 +++++++-----
 upstream/src/libmetrics/swu.hh                   |  48 ++++++---
 upstream/src/libsigfile/typed-source.cc          |   2 +-
 23 files changed, 439 insertions(+), 294 deletions(-)

diff --git a/upstream/src/aghermann/expdesign/expdesign.cc b/upstream/src/aghermann/expdesign/expdesign.cc
index 880aeb3..4ed6d89 100644
--- a/upstream/src/aghermann/expdesign/expdesign.cc
+++ b/upstream/src/aghermann/expdesign/expdesign.cc
@@ -47,6 +47,9 @@ agh::CExpDesign::
 CExpDesign (const string& session_dir_,
             TMsmtCollectProgressIndicatorFun progress_fun)
       : num_threads              (0),
+        // fft_params ({30., 30,}, .25, sigproc::TWinType::hanning, metrics::psd::TFFTWPlanType::estimate),
+        // swu_params ({30., 30,}, 1.),
+        // mc_params  ({30., 30,}, 30 / 6., .8, 1.5, 0.5, 0.0, 0, .5, .5, 5),
         af_dampen_window_type    (sigproc::TWinType::welch),
         af_dampen_factor         (.95),
         tunables0                (tstep, tlo, thi), // only references here, don't worry
@@ -60,16 +63,16 @@ CExpDesign (const string& session_dir_,
                 ("ctl_param.damping_mu",                 &ctl_params0.siman_params.mu_t,                       SValidator<double>::SVFRangeEx( DBL_MIN, 1e9))
                 ("ctl_param.t_min",                      &ctl_params0.siman_params.t_min,                      SValidator<double>::SVFRangeEx( DBL_MIN, 1e9))
                 ("profile.req_scored_pc",                &profile_common_params0.req_percent_scored,           SValidator<double>::SVFRangeIn( 80., 100.))
-                ("fft_param.pagesize",                   &fft_params.pagesize,                                 SValidator<double>::SVFRangeIn( 4., 120.))
-                ("fft_param.binsize",                    &fft_params.binsize,                                  SValidator<double>::SVFRangeIn( .125, 1.))
+                ("psd_param.pagesize",                   &psd_params.pagesize,                                 SValidator<double>::SVFRangeIn( 4., 120.))
+                ("psd_param.binsize",                    &psd_params.binsize,                                  SValidator<double>::SVFRangeIn( .125, 1.))
                 ("artifacts.dampen_factor",              &af_dampen_factor,                                    SValidator<double>::SVFRangeIn( 0., 1.))
                 ("mc_param.mc_gain",                     &mc_params.mc_gain,                                   SValidator<double>::SVFRangeIn( 0., 100.))
                 ("mc_param.f0fc",                        &mc_params.f0fc,                                      SValidator<double>::SVFRangeEx( 0., 80.))
                 ("mc_param.bandwidth",                   &mc_params.bandwidth,                                 SValidator<double>::SVFRangeIn( 0.125, 2.))
                 ("mc_param.iir_backpolate",              &mc_params.iir_backpolate,                            SValidator<double>::SVFRangeIn( 0., 1.))
                 ("swu_param.min_upswing_duration",       &swu_params.min_upswing_duration,                     SValidator<double>::SVFRangeIn( 0.01, 1.))
-                ("fft_param.welch_window_type",  (int*)  &fft_params.welch_window_type,                        SValidator<int>::SVFRangeIn( 0, (int)sigproc::TWinType_total - 1))
-                ("fft_param.plan_type",          (int*)  &fft_params.plan_type,                                SValidator<int>::SVFRangeIn( 0, (int)metrics::psd::TFFTWPlanType_total - 1))
+                ("psd_param.welch_window_type",  (int*)  &psd_params.welch_window_type,                        SValidator<int>::SVFRangeIn( 0, (int)sigproc::TWinType_total - 1))
+                ("psd_param.plan_type",          (int*)  &psd_params.plan_type,                                SValidator<int>::SVFRangeIn( 0, (int)metrics::psd::TFFTWPlanType_total - 1))
                 ("artifacts.dampen_window_type", (int*)  &af_dampen_window_type,                               SValidator<int>::SVFRangeIn( 0, (int)sigproc::TWinType_total - 1))
                 ("ctl_param.iters_fixed_t",              &ctl_params0.siman_params.iters_fixed_T,              SValidator<int>::SVFRangeIn( 1, 1000000))
                 ("ctl_param.n_tries",                    &ctl_params0.siman_params.n_tries,                    SValidator<int>::SVFRangeIn( 1, 10000))
@@ -108,7 +111,7 @@ CExpDesign (const string& session_dir_,
         load_settings();
 
         // that's pretty important: scope is not itself exposed to the user
-        mc_params.scope = fft_params.pagesize;
+        mc_params.scope = psd_params.pagesize;
 
 #ifdef _OPENMP
         omp_set_num_threads( (num_threads == 0) ? global::num_procs : num_threads);
diff --git a/upstream/src/aghermann/expdesign/expdesign.hh b/upstream/src/aghermann/expdesign/expdesign.hh
index 3699950..f8d9828 100644
--- a/upstream/src/aghermann/expdesign/expdesign.hh
+++ b/upstream/src/aghermann/expdesign/expdesign.hh
@@ -211,7 +211,7 @@ class CExpDesign {
       // inventory
         size_t  num_threads;
         metrics::psd::SPPack
-                fft_params;
+                psd_params;
         metrics::swu::SPPack
                 swu_params;
         metrics::mc::SPPack
diff --git a/upstream/src/aghermann/expdesign/loadsave.cc b/upstream/src/aghermann/expdesign/loadsave.cc
index e7e7d90..2e42b7f 100644
--- a/upstream/src/aghermann/expdesign/loadsave.cc
+++ b/upstream/src/aghermann/expdesign/loadsave.cc
@@ -45,8 +45,9 @@ load_settings()
 
                 ctl_params0.reset();
                 tunables0.set_defaults();
-                fft_params.reset();
-                mc_params.reset();
+                psd_params.sane_defaults();
+                swu_params.sane_defaults();
+                mc_params.sane_defaults();
 
                 return -1;
         }
@@ -54,7 +55,7 @@ load_settings()
         try {
                 for ( size_t i = metrics::TBand::delta; i < metrics::TBand::TBand_total; ++i ) {
                         auto& A = conf.lookup(string("Band.")+FreqBandNames[i]);
-                        float        f0 = A[0],
+                        float   f0 = A[0],
                                 f1 = A[1];
                         if ( f0 < f1 ) {
                                 freq_bands[i][0] = f0;
@@ -77,15 +78,21 @@ load_settings()
                 APPLOG_WARN ("load_settings(\"%s\"): Invalid tunables", EXPD_FILE);
         }
 
-        try { fft_params.check(); }
+        try { psd_params.check(); }
         catch (invalid_argument ex) {
-                fft_params.reset();
-                APPLOG_WARN ("load_settings(\"%s\"): Invalid FFT params (%s)", EXPD_FILE, ex.what());
+                psd_params.sane_defaults();
+                APPLOG_WARN ("load_settings(\"%s\"): Invalid PSD params (%s)", EXPD_FILE, ex.what());
+        }
+
+        try { swu_params.check(); }
+        catch (invalid_argument ex) {
+                swu_params.sane_defaults();
+                APPLOG_WARN ("load_settings(\"%s\"): Invalid SWU params (%s)", EXPD_FILE, ex.what());
         }
 
         try { mc_params.check(); }
         catch (invalid_argument ex) {
-                mc_params.reset();
+                mc_params.sane_defaults();
                 APPLOG_WARN ("load_settings(\"%s\"): Invalid MC params (%s)", EXPD_FILE, ex.what());
         }
 
diff --git a/upstream/src/aghermann/expdesign/recording.cc b/upstream/src/aghermann/expdesign/recording.cc
index e68f4d2..ab0bbcf 100644
--- a/upstream/src/aghermann/expdesign/recording.cc
+++ b/upstream/src/aghermann/expdesign/recording.cc
@@ -113,7 +113,8 @@ CProfile (CSubject& J, const string& d, const sigfile::SChannel& h,
 
                 if ( Mi == _mm_list.begin() ) {
                         _0at = F.start_time();
-                        _pagesize = M.psd_profile.Pp.pagesize;
+                        _pagesize = M.pagesize();
+                        printf( "constructing profile ps %d\n", _pagesize);
                         _pages_in_bed = 0;
                 } else
                         if ( _pagesize != M.pagesize() ) {
@@ -126,9 +127,9 @@ CProfile (CSubject& J, const string& d, const sigfile::SChannel& h,
                         pz = pa + M.hypnogram().n_pages();
               // anchor zero page, get pagesize from edf^W CBinnedPower^W either goes
                 time_t dima = F.start_time();
-                APPLOG_INFO ("adding %s of [%s, %s, %s] %zu full pages (%zu total, %zu in hypnogram) recorded %s",
+                APPLOG_INFO ("adding %s of [%s, %s, %s] %zu full pages (%zu total, %zu in hypnogram @%zu) recorded %s",
                              metrics::name(params.metric), F.subject().id.c_str(), F.session(), F.episode(),
-                             M.full_pages(), M.total_pages(), M.hypnogram().n_pages(), ctime( &dima));
+                             M.full_pages(), M.total_pages(), M.hypnogram().n_pages(), _pagesize, ctime( &dima));
 
                 if ( pz - pa != (int)M.total_pages() ) {
                         APPLOG_WARN ("correcting end page to match total page count in EDF: %d->%zu",
@@ -175,15 +176,15 @@ CProfile (CRecording& M,
         _mm_list.push_back( &M);
 
         _0at = M.F().start_time();
-        _pagesize = M.psd_profile.Pp.pagesize;
+        _pagesize = M.pagesize();
         _pages_in_bed = 0;
 
         int     pa = (size_t)difftime( M.F().start_time(), _0at) / _pagesize,
                 pz = (size_t)difftime( M.F().end_time(), _0at) / _pagesize;
         time_t  dima = M.F().start_time();
-        APPLOG_INFO ("adding single recording %s of [%s, %s, %s] %zu full pages (%zu total, %zu in hypnogram) recorded %s",
+        APPLOG_INFO ("adding single recording %s of [%s, %s, %s] %zu full pages (%zu total, %zu in hypnogram; pagesize %zu) recorded %s",
                      metrics::name(params.metric), M.F().subject().id.c_str(), M.F().session(), M.F().episode(),
-                     M.full_pages(), M.total_pages(), M.hypnogram().n_pages(), ctime( &dima));
+                     M.full_pages(), M.total_pages(), M.hypnogram().n_pages(), _pagesize, ctime( &dima));
 
         if ( pz - pa != (int)M.total_pages() ) {
                 APPLOG_WARN ("correcting end page to match total page count in EDF: %d->%zu",
@@ -193,6 +194,7 @@ CProfile (CRecording& M,
         _pages_in_bed += (pz-pa);
 
         if ( pa < 0 ) {
+                APPLOG_WARN ("negative starting page %d", pa);
                 _status |= TFlags::enegoffset;
                 return;
         }
diff --git a/upstream/src/aghermann/expdesign/recording.hh b/upstream/src/aghermann/expdesign/recording.hh
index a0a86c2..99e201c 100644
--- a/upstream/src/aghermann/expdesign/recording.hh
+++ b/upstream/src/aghermann/expdesign/recording.hh
@@ -180,7 +180,7 @@ class CRecording {
         // this one damn identical in all bases
         size_t
         pagesize() const
-                { return ((metrics::psd::CProfile*)this) -> Pp.pagesize; }
+                { return psd_profile.pagesize; }
 
         // actual page counts based on actual edf samples
         size_t
diff --git a/upstream/src/aghermann/expdesign/tree-scanner.cc b/upstream/src/aghermann/expdesign/tree-scanner.cc
index 2363f59..5b7cefb 100644
--- a/upstream/src/aghermann/expdesign/tree-scanner.cc
+++ b/upstream/src/aghermann/expdesign/tree-scanner.cc
@@ -69,6 +69,7 @@ add_one( sigfile::CTypedSource&& Fmc,
                         return AGH_EPSEQADD_TOOFAR;
 
                 episodes.emplace_back( move(Fmc), fft_params, swu_params, mc_params);
+                printf( "ps %zu; %zu\n", Fmc.pagesize(), episodes.back().sources.back().pagesize());
                 episodes.sort();
 
         } else { // same as SEpisode() but done on an existing one
@@ -210,7 +211,7 @@ register_intree_source( sigfile::CTypedSource&& F,
                 APPLOG_INFO( "register_intree_source( file: \"%s\", J: %s (\"%s\"), E: \"%s\", D: \"%s\")",
                              F().filename(), F().subject().id.c_str(), F().subject().name.c_str(), F().episode(), F().session());
                 switch ( J->measurements[F().session()].add_one(
-                                 move(F), fft_params, swu_params, mc_params) ) {  // this will do it
+                                 move(F), psd_params, swu_params, mc_params) ) {  // this will do it
                 case AGH_EPSEQADD_OVERLAP:
                         log_message( TLogEntryStyle::plain, "%s: not added as it overlaps with existing episodes", F().filename());
                         APPLOG_WARN ("%s: not added as it overlaps with existing episodes", F().filename());
@@ -265,7 +266,7 @@ supported_sigfile_processor( const char *fname, const struct stat*, int flag, st
                         try {
                                 using namespace sigfile;
                                 CTypedSource F {fname,
-                                                (size_t)roundf(only_expdesign->fft_params.pagesize),
+                                                (size_t)roundf(only_expdesign->psd_params.pagesize),
                                                 0,
                                                 agh::global::default_log_facility};
                                 string st = F().explain_status();
diff --git a/upstream/src/aghermann/ui/mw/admit-one.cc b/upstream/src/aghermann/ui/mw/admit-one.cc
index c5055b2..3852f75 100644
--- a/upstream/src/aghermann/ui/mw/admit-one.cc
+++ b/upstream/src/aghermann/ui/mw/admit-one.cc
@@ -25,7 +25,7 @@ dnd_maybe_admit_one( const char* fname)
 {
         try {
                 string info;
-                sigfile::CTypedSource F_ (fname, ED->fft_params.pagesize, 0, agh::global::default_log_facility);
+                sigfile::CTypedSource F_ (fname, ED->psd_params.pagesize, 0, agh::global::default_log_facility);
                 switch ( F_.type() ) {
                 case sigfile::CTypedSource::TType::edf:
                 {
diff --git a/upstream/src/aghermann/ui/mw/mw.cc b/upstream/src/aghermann/ui/mw/mw.cc
index 8f39009..d679500 100644
--- a/upstream/src/aghermann/ui/mw/mw.cc
+++ b/upstream/src/aghermann/ui/mw/mw.cc
@@ -221,7 +221,7 @@ SExpDesignUI (SSessionChooser *parent,
         W_V1.reg( eScanTreeStrict,              &ED->strict_subject_id_checks);
         W_V1.reg( eArtifDampenWindowType, (int*)&ED->af_dampen_window_type);
         W_V1.reg( eArtifDampenFactor,           &ED->af_dampen_factor);
-        W_V1.reg( eFFTParamsWindowType,   (int*)&ED->fft_params.welch_window_type);
+        W_V1.reg( eFFTParamsWindowType,   (int*)&ED->psd_params.welch_window_type);
         W_V1.reg( eMCParamIIRBackpolate,        &ED->mc_params.iir_backpolate);
         W_V1.reg( eMCParamMCGain,               &ED->mc_params.mc_gain);
         W_V1.reg( eMCParamBandWidth,            &ED->mc_params.bandwidth);
@@ -232,7 +232,7 @@ SExpDesignUI (SSessionChooser *parent,
         W_V1.reg( eScanTreeSuppressReport,          &suppress_scan_report);
         W_V1.reg( eFFTParamsPageSize,               &pagesize_item);
         W_V1.reg( eFFTParamsBinSize,                &binsize_item);
-        W_V1.reg( eFFTParamsPlanType,         (int*)&ED->fft_params.plan_type);
+        W_V1.reg( eFFTParamsPlanType,         (int*)&ED->psd_params.plan_type);
         W_V1.reg( eUltradianCycleDetectionAccuracy, &uc_accuracy_factor);
         for ( size_t i = 0; i < sigfile::SPage::TScore::TScore_total; ++i )
                 W_V1.reg( eScoreCode[i], &ext_score_codes[i]);
@@ -249,11 +249,11 @@ SExpDesignUI (SSessionChooser *parent,
         W_V1.reg( eScrollSpeedFactor,       &scroll_factor);
 
         // set _saved, too
-        fft_params_welch_window_type_saved  = ED->fft_params.welch_window_type;
-        fft_params_plan_type_saved          = ED->fft_params.plan_type;
         af_dampen_window_type_saved         = ED->af_dampen_window_type;
         af_dampen_factor_saved              = ED->af_dampen_factor;
-        mc_params_saved                     = ED->mc_params;
+        psd_params_saved.make_same( ED->psd_params);
+         mc_params_saved.make_same( ED-> mc_params);
+        swu_params_saved.make_same( ED->swu_params);
         pagesize_item_saved = pagesize_item = figure_pagesize_item();
         binsize_item_saved = binsize_item   = figure_binsize_item();
 
@@ -312,7 +312,7 @@ SExpDesignUI::
 figure_pagesize_item()
 {
         size_t i = 0;
-        while ( FFTPageSizeValues[i] < ED->fft_params.pagesize )
+        while ( FFTPageSizeValues[i] < ED->psd_params.pagesize )
                 ++i;
         return i;
 }
@@ -322,7 +322,7 @@ SExpDesignUI::
 figure_binsize_item()
 {
         size_t i = 0;
-        while ( FFTBinSizeValues[i] < ED->fft_params.binsize )
+        while ( FFTBinSizeValues[i] < ED->psd_params.binsize )
                 ++i;
         return i;
 }
@@ -413,12 +413,12 @@ adjust_op_freq_spinbuttons()
 {
         suppress_redraw = true;
 
-        gtk_adjustment_set_step_increment( jMsmtProfileParamsPSDFreqFrom,  ED->fft_params.binsize);
-        gtk_adjustment_set_step_increment( jMsmtProfileParamsPSDFreqWidth, ED->fft_params.binsize);
+        gtk_adjustment_set_step_increment( jMsmtProfileParamsPSDFreqFrom,  ED->psd_params.binsize);
+        gtk_adjustment_set_step_increment( jMsmtProfileParamsPSDFreqWidth, ED->psd_params.binsize);
         if ( not used_eeg_samplerates.empty() )
                 gtk_adjustment_set_upper(
                         jMsmtProfileParamsPSDFreqFrom,
-                        ED->fft_params.binsize * (ED->fft_params.compute_n_bins( used_eeg_samplerates.back()) - 1));
+                        ED->psd_params.binsize * (ED->psd_params.compute_n_bins( used_eeg_samplerates.back()) - 1));
 
         gtk_adjustment_set_step_increment( jMsmtProfileParamsMCF0,
                                            ED->mc_params.freq_inc); // matches the default in metrics/mc.cc
diff --git a/upstream/src/aghermann/ui/mw/mw.hh b/upstream/src/aghermann/ui/mw/mw.hh
index 7ed9c0f..4827111 100644
--- a/upstream/src/aghermann/ui/mw/mw.hh
+++ b/upstream/src/aghermann/ui/mw/mw.hh
@@ -296,19 +296,19 @@ class SExpDesignUI
         // _saved items
         size_t  tl_pph_saved,
                 tl_height_saved;
+
         int     pagesize_item_saved,
                 binsize_item_saved;
         sigproc::TWinType
-                fft_params_welch_window_type_saved,
                 af_dampen_window_type_saved;
-        metrics::psd::TFFTWPlanType
-                fft_params_plan_type_saved;
         double  af_dampen_factor_saved;
 
-        // sigfile::SFFTParamSet
-        //         fft_params_saved; // members not represented in widgets as is
+        metrics::psd::SPPack
+                psd_params_saved;
         metrics::mc::SPPack
                 mc_params_saved;
+        metrics::swu::SPPack
+                swu_params_saved;
 
         // bind fields to widgets
         SUIVarCollection
diff --git a/upstream/src/aghermann/ui/mw/populate.cc b/upstream/src/aghermann/ui/mw/populate.cc
index d7638aa..b211316 100644
--- a/upstream/src/aghermann/ui/mw/populate.cc
+++ b/upstream/src/aghermann/ui/mw/populate.cc
@@ -446,7 +446,7 @@ populate_1()
         timeline_start = earliest_start;
         timeline_end   = latest_end;
         tl_width = (timeline_end - timeline_start) / 3600 * tl_pph;
-        tl_pages = (timeline_end - timeline_start) / ED->fft_params.pagesize;
+        tl_pages = (timeline_end - timeline_start) / ED->psd_params.pagesize;
 
         APPLOG_INFO ("populate_1(): common timeline:");
         {
@@ -576,9 +576,9 @@ populate_1()
         gtk_label_set_markup(
                 lMsmtProfilePSDExtra,
                 snprintf_buf( "<small>%gsec/%gHz/%s</small>",
-                              ED->fft_params.pagesize,
-                              ED->fft_params.binsize,
-                              sigproc::welch_window_type_names[ED->fft_params.welch_window_type]));
+                              ED->psd_params.pagesize,
+                              ED->psd_params.binsize,
+                              sigproc::welch_window_type_names[ED->psd_params.welch_window_type]));
 
         gtk_label_set_markup(
                 lMsmtProfileMCExtra,
diff --git a/upstream/src/aghermann/ui/mw/settings_cb.cc b/upstream/src/aghermann/ui/mw/settings_cb.cc
index 2df3ea7..aaf5ee5 100644
--- a/upstream/src/aghermann/ui/mw/settings_cb.cc
+++ b/upstream/src/aghermann/ui/mw/settings_cb.cc
@@ -42,25 +42,20 @@ tDesign_switch_page_cb(
               // collect values from widgets
                 ED.W_V1.down();
 
-                ED.ED->fft_params.pagesize = ED.FFTPageSizeValues[ED.pagesize_item];
-                ED.ED->fft_params.binsize =  ED.FFTBinSizeValues [ED.binsize_item];
-
-                try { ED.ED->fft_params.check(); }
-                catch (invalid_argument ex) {
-                        pop_ok_message(
-                                ED.wMainWindow,
-                                "Invalid FFT parameters", "Resetting to defaults.");
-                        ED.ED->fft_params.reset();
-                }
-
-                try {
-                        ED.ED->mc_params.check();
-                } catch (invalid_argument ex) {
-                        pop_ok_message(
-                                ED.wMainWindow,
-                                "Invalid uC parameters", "Resetting to defaults.");
-                        ED.ED->mc_params.reset();
-                }
+                ED.ED->psd_params.pagesize = ED.ED->mc_params.pagesize = ED.ED->swu_params.pagesize =
+                        ED.FFTPageSizeValues[ED.pagesize_item];
+                ED.ED->psd_params.binsize  = ED.FFTBinSizeValues [ED.binsize_item];
+
+                for ( auto& P : {reinterpret_cast<metrics::SPPack*>(&ED.ED->psd_params),
+                                 reinterpret_cast<metrics::SPPack*>(&ED.ED->mc_params),
+                                 reinterpret_cast<metrics::SPPack*>(&ED.ED->swu_params)} )
+                        try { P->check(); }
+                        catch (invalid_argument ex) {
+                                pop_ok_message(
+                                        ED.wMainWindow,
+                                        "Invalid parameters", "Resetting %s parameters to defaults.", P->metric_name());
+                                P->sane_defaults();
+                        }
 
                 ED.adjust_op_freq_spinbuttons();
 
@@ -73,11 +68,11 @@ tDesign_switch_page_cb(
               // scan as necessary
                 if ( ED.pagesize_item_saved                != ED.pagesize_item ||
                      ED.binsize_item_saved                 != ED.binsize_item ||
-                     ED.fft_params_plan_type_saved         != ED.ED->fft_params.plan_type ||
-                     ED.fft_params_welch_window_type_saved != ED.ED->fft_params.welch_window_type ||
                      ED.af_dampen_window_type_saved        != ED.ED->af_dampen_window_type ||
                      ED.af_dampen_factor_saved             != ED.ED->af_dampen_factor ||
-                     !ED.ED->mc_params.same_as( ED.mc_params_saved) ) {
+                     !ED.ED->psd_params.same_as( ED.psd_params_saved) ||
+                     !ED.ED-> mc_params.same_as( ED. mc_params_saved) ||
+                     !ED.ED->swu_params.same_as( ED.swu_params_saved) ) {
                       // rescan tree
                         ED.do_rescan_tree(); // with populate
                 } else if ( ED.tl_height_saved != ED.tl_height ||
@@ -90,11 +85,11 @@ tDesign_switch_page_cb(
                 ED.tl_height_saved                    = ED.tl_height;
                 ED.pagesize_item_saved                = ED.pagesize_item;
                 ED.binsize_item_saved                 = ED.binsize_item;
-                ED.fft_params_welch_window_type_saved = ED.ED->fft_params.welch_window_type;
-                ED.fft_params_plan_type_saved         = ED.ED->fft_params.plan_type;
                 ED.af_dampen_window_type_saved        = ED.ED->af_dampen_window_type;
                 ED.af_dampen_factor_saved             = ED.ED->af_dampen_factor;
-                ED.mc_params_saved                    = ED.ED->mc_params;
+                ED.psd_params_saved.make_same( ED.ED->psd_params);
+                ED. mc_params_saved.make_same( ED.ED-> mc_params);
+                ED.swu_params_saved.make_same( ED.ED->swu_params);
 
                 ED.pagesize_item                      = ED.figure_pagesize_item();
                 ED.binsize_item                       = ED.figure_binsize_item();
diff --git a/upstream/src/aghermann/ui/sf/channel.cc b/upstream/src/aghermann/ui/sf/channel.cc
index fb4b789..04bb7f8 100644
--- a/upstream/src/aghermann/ui/sf/channel.cc
+++ b/upstream/src/aghermann/ui/sf/channel.cc
@@ -123,7 +123,7 @@ SChannel (agh::CRecording& r,
                 spectrum_bins = last_spectrum_bin = crecording.psd_profile.bins();
                 get_spectrum( 0);
                 // will be reassigned in REDRAW_ALL
-                spectrum_upper_freq = spectrum_bins * crecording.psd_profile.Pp.binsize;
+                spectrum_upper_freq = spectrum_bins * crecording.psd_profile.binsize;
 
               // power in bands
                 size_t n_bands = 0;
diff --git a/upstream/src/aghermann/ui/sf/montage-overlays.cc b/upstream/src/aghermann/ui/sf/montage-overlays.cc
index bfbdd89..18cfb39 100644
--- a/upstream/src/aghermann/ui/sf/montage-overlays.cc
+++ b/upstream/src/aghermann/ui/sf/montage-overlays.cc
@@ -138,7 +138,7 @@ draw_overlays( cairo_t* cr,
                         // spectrum
                         _p._p.CwB[SExpDesignUI::TColour::sf_ticks].set_source_rgba( cr, .8);
                         cairo_set_line_width( cr, 2);
-                        float factor = psd.display_scale / crecording.psd_profile.Pp.binsize;
+                        float factor = psd.display_scale / crecording.psd_profile.binsize;
                         cairo_move_to( cr,
                                        gx, gy + gh - (2 + spectrum[0] * factor));
                         for ( m = 1; m < last_spectrum_bin; ++m ) {
@@ -170,7 +170,7 @@ draw_overlays( cairo_t* cr,
 
                         snprintf_buf(
                                 "%g Hz",
-                                last_spectrum_bin * crecording.psd_profile.Pp.binsize);
+                                last_spectrum_bin * crecording.psd_profile.binsize);
 //                                draw_spectrum_absolute ? 'A' : 'R');
                         cairo_text_extents( cr, global::buf, &extents);
                         cairo_move_to( cr,
diff --git a/upstream/src/aghermann/ui/sf/montage_cb.cc b/upstream/src/aghermann/ui/sf/montage_cb.cc
index b061ecf..91fdd73 100644
--- a/upstream/src/aghermann/ui/sf/montage_cb.cc
+++ b/upstream/src/aghermann/ui/sf/montage_cb.cc
@@ -445,7 +445,7 @@ daSFMontage_scroll_event_cb(
                                         }
                                 } else {
                                         auto& R = Ch->crecording;
-                                        if ( Ch->psd.upto < R.psd_profile.Pp.binsize * R.psd_profile.bins() ) {
+                                        if ( Ch->psd.upto < R.psd_profile.binsize * R.psd_profile.bins() ) {
                                                 Ch->psd.from += .5;
                                                 Ch->psd.upto += .5;
                                                 Ch->get_psd_course();
diff --git a/upstream/src/libmetrics/mc.cc b/upstream/src/libmetrics/mc.cc
index ffb7336..05c4351 100644
--- a/upstream/src/libmetrics/mc.cc
+++ b/upstream/src/libmetrics/mc.cc
@@ -21,36 +21,55 @@
 using namespace std;
 
 
+void
+metrics::mc::SPPack::
+check() const
+{
+        metrics::SPPack::check();
+#ifdef _OPENMP
+#pragma omp single
+#endif
+        {
+                if ( mc_gain < 1.0 )
+                        throw invalid_argument ("mc_gain must be >= 1.0");
+                // if ( (int)(pagesize/scope) != (double)pagesize / (double)scope )
+                //         throw invalid_argument ("Page size not a multiple of MC scope");
+        }
+}
+
+
 
 metrics::mc::CProfile::
 CProfile (const sigfile::CTypedSource& F, const int sig_no,
           const SPPack &params)
-      : metrics::CProfile (F, sig_no,
+      : metrics::SPPack (params),
+        SPPack (params),
+        metrics::CProfile (F, sig_no,
                            params.pagesize, params.step,
-                           params.compute_n_bins(F().samplerate(sig_no))),
-        Pp (params)
+                           params.compute_n_bins(F().samplerate(sig_no)))
         // *_filter's initialized at compute time
 {
-        Pp.check(); // throw if not ok
+        check(); // throw if not ok
 }
 
 
 
 
+
 string
 metrics::mc::CProfile::
 fname_base() const
 {
         return move(
-		agh::str::sasprintf(
-			"%s.%s-%lu"
-			":%g+%g-%g_%g" "_%g" "_%g_%g",
-			_using_F().filename(), _using_F().channel_by_id(_using_sig_no).name(),
-			_using_F().dirty_signature( _using_sig_no),
-			Pp.pagesize, Pp.step,
-			Pp.scope, Pp.iir_backpolate,
-			Pp.mc_gain,
-			Pp.f0fc, Pp.bandwidth));
+                agh::str::sasprintf(
+                        "%s.%s-%lu"
+                        ":%g+%g-%g_%g" "_%g" "_%g_%g",
+                        _using_F().filename(), _using_F().channel_by_id(_using_sig_no).name(),
+                        _using_F().dirty_signature( _using_sig_no),
+                        pagesize, step,
+                        scope, iir_backpolate,
+                        mc_gain,
+                        f0fc, bandwidth));
 }
 
 string
@@ -58,19 +77,19 @@ metrics::mc::CProfile::
 mirror_fname() const
 {
         return move(
-		agh::str::sasprintf(
-			"%s-%s-%lu"
-			":%g+%g-%g_%g" "_%g" "_%g_%g" "_%g_%g@%zu"
-			".mc",
-			agh::fs::make_fname_base (_using_F().filename(), "", agh::fs::TMakeFnameOption::hidden).c_str(),
-			_using_F().channel_by_id(_using_sig_no).name(),
-			_using_F().dirty_signature( _using_sig_no),
-			Pp.pagesize, Pp.step,
-			Pp.scope, Pp.iir_backpolate,
-			Pp.mc_gain,
-			Pp.f0fc, Pp.bandwidth,
-			Pp.freq_from, Pp.freq_inc,
-			sizeof(TFloat)));
+                agh::str::sasprintf(
+                        "%s-%s-%lu"
+                        ":%g+%g-%g_%g" "_%g" "_%g_%g" "_%g_%g@%zu"
+                        ".mc",
+                        agh::fs::make_fname_base (_using_F().filename(), "", agh::fs::TMakeFnameOption::hidden).c_str(),
+                        _using_F().channel_by_id(_using_sig_no).name(),
+                        _using_F().dirty_signature( _using_sig_no),
+                        pagesize, step,
+                        scope, iir_backpolate,
+                        mc_gain,
+                        f0fc, bandwidth,
+                        freq_from, freq_inc,
+                        sizeof(TFloat)));
 }
 
 int
@@ -82,11 +101,11 @@ go_compute()
         for ( size_t b = 0; b < bins(); ++b ) {
                 auto su_ss = metrics::mc::do_sssu_reduction(
                         S, samplerate(),
-                        Pp.scope, Pp.step,
-                        Pp.mc_gain, Pp.iir_backpolate,
-                        Pp.freq_from + b * Pp.freq_inc,
-                        Pp.freq_from + b * Pp.freq_inc + Pp.f0fc,
-                        Pp.bandwidth);
+                        scope, step,
+                        mc_gain, iir_backpolate,
+                        freq_from + b * freq_inc,
+                        freq_from + b * freq_inc + f0fc,
+                        bandwidth);
                 auto suss = su_ss.first - su_ss.second;  // make it positive
 
                 for ( size_t p = 0; p < steps(); ++p )
@@ -126,9 +145,9 @@ export_tsv( const string& fname) const
                  _using_F().subject().name.c_str(), _using_F().session(), _using_F().episode(),
                  (int)strlen(asctime_)-1, asctime_,
                  _using_F().channel_by_id(_using_sig_no).name(),
-                 steps(), Pp.pagesize, Pp.step, Pp.freq_from, Pp.freq_from + Pp.bandwidth * bins(), Pp.bandwidth);
+                 steps(), pagesize, step, freq_from, freq_from + bandwidth * bins(), bandwidth);
 
-        for ( bin = 0; bin < _bins; ++bin, bum += Pp.bandwidth )
+        for ( bin = 0; bin < _bins; ++bin, bum += bandwidth )
                 fprintf( f, "%g%c", bum, bin+1 == _bins ? '\n' : '\t');
 
         for ( p = 0; p < steps(); ++p ) {
@@ -160,7 +179,7 @@ export_tsv( size_t bin,
                  _using_F().subject().name.c_str(), _using_F().session(), _using_F().episode(),
                  (int)strlen(asctime_)-1, asctime_,
                  _using_F().channel_by_id(_using_sig_no).name(),
-                 steps(), Pp.pagesize, Pp.step, Pp.freq_from, Pp.freq_from + (bin+1) * Pp.bandwidth);
+                 steps(), pagesize, step, freq_from, freq_from + (bin+1) * bandwidth);
 
         for ( size_t p = 0; p < steps(); ++p )
                 fprintf( f, "%zu\t%g\n", p, nmth_bin(p, bin));
diff --git a/upstream/src/libmetrics/mc.hh b/upstream/src/libmetrics/mc.hh
index ec6b23a..5af7d54 100644
--- a/upstream/src/libmetrics/mc.hh
+++ b/upstream/src/libmetrics/mc.hh
@@ -28,7 +28,7 @@ namespace metrics {
 namespace mc {
 
 struct SPPack
-  : public metrics::SPPack {
+  : virtual public metrics::SPPack {
         double	scope,
                 f0fc,
                 //f0, // = 1.,
@@ -41,52 +41,82 @@ struct SPPack
                 freq_inc;
         size_t	n_bins;
 
-        SPPack (const SPPack&) = default;
         SPPack ()
-                { reset(); }
+                {
+                        sane_defaults();
+                }
+        SPPack (const SPPack& rv)
+              : metrics::SPPack (rv),
+                scope           (rv.scope),
+                f0fc            (rv.f0fc),
+                bandwidth       (rv.bandwidth),
+                iir_backpolate  (rv.iir_backpolate),
+                mc_gain         (rv.mc_gain),
+                smooth_side     (rv.smooth_side),
+                freq_from       (rv.freq_from),
+                freq_inc        (rv.freq_inc),
+                n_bins          (rv.n_bins)
+                {}
+
+        SPPack (const metrics::SPPack& base,
+                const double scope_,
+                const double f0fc_,
+                const double bandwidth_,
+                const double iir_backpolate_,
+                const double mc_gain_,
+                const size_t smooth_side_,
+                const double freq_from_,
+                const double freq_inc_,
+                const size_t n_bins_)
+              : metrics::SPPack (base),
+                scope           (scope_),
+                f0fc            (f0fc_),
+                bandwidth       (bandwidth_),
+                iir_backpolate  (iir_backpolate_),
+                mc_gain         (mc_gain_),
+                smooth_side     (smooth_side_),
+                freq_from       (freq_from_),
+                freq_inc        (freq_inc_),
+                n_bins          (n_bins_)
+                {}
+
 
-        bool same_as( const SPPack& rv) const
+        bool
+        same_as( const SPPack& rv) const
                 {
                         return	metrics::SPPack::same_as(rv) &&
-                                scope == rv.scope &&
+                                scope          == rv.scope &&
                                 iir_backpolate == rv.iir_backpolate &&
-                                mc_gain == rv.mc_gain &&
-                                f0fc == rv.f0fc &&
-                                bandwidth == rv.bandwidth &&
-                                smooth_side == rv.smooth_side &&
-                                freq_from == rv.freq_from &&
-                                freq_inc == rv.freq_inc &&
-                                n_bins == rv.n_bins;
+                                mc_gain        == rv.mc_gain &&
+                                f0fc           == rv.f0fc &&
+                                bandwidth      == rv.bandwidth &&
+                                smooth_side    == rv.smooth_side &&
+                                freq_from      == rv.freq_from &&
+                                freq_inc       == rv.freq_inc &&
+                                n_bins         == rv.n_bins;
                 }
-        void make_same( const SPPack& rv)
+        void
+        make_same( const SPPack& rv)
                 {
                         metrics::SPPack::make_same(rv);
-                        scope = rv.scope;
+                        scope          = rv.scope;
                         iir_backpolate = rv.iir_backpolate;
-                        mc_gain = rv.mc_gain;
-                        f0fc = rv.f0fc;
-                        bandwidth = rv.bandwidth;
-                        smooth_side = rv.smooth_side;
-                        freq_from = rv.freq_from;
-                        freq_inc = rv.freq_inc;
-                        n_bins = rv.n_bins;
+                        mc_gain        = rv.mc_gain;
+                        f0fc           = rv.f0fc;
+                        bandwidth      = rv.bandwidth;
+                        smooth_side    = rv.smooth_side;
+                        freq_from      = rv.freq_from;
+                        freq_inc       = rv.freq_inc;
+                        n_bins         = rv.n_bins;
                 }
 
-        void check() const // throws
-                {
-#ifdef _OPENMP
-#pragma omp single
-#endif
-                        {
-                                if ( mc_gain < 1.0 )
-                                        throw invalid_argument ("mc_gain must be >= 1.0");
-                                // if ( (int)(pagesize/scope) != (double)pagesize / (double)scope )
-                                //         throw invalid_argument ("Page size not a multiple of MC scope");
-                        }
-                }
+        void
+        check() const; // throws
 
-        void reset()
+        void
+        sane_defaults()
                 {
+                        metrics::SPPack::sane_defaults();
                         scope           =     30 / 6.;  // 5 sec is close to 4 sec ('recommended')
                         f0fc            =      .8;
                         bandwidth       =     1.5;
@@ -98,6 +128,10 @@ struct SPPack
                         n_bins          =     5;
                 }
 
+        const char*
+        metric_name() const
+                { return metrics::name( TType::mc); }
+
         size_t
         compute_n_bins( size_t) const // to match psd::SPPack::compute_n_bins
                 { return n_bins; }
@@ -107,23 +141,20 @@ struct SPPack
 
 
 class CProfile
-  : public metrics::CProfile {
+  : virtual public SPPack,
+    virtual public metrics::CProfile {
 
     public:
         CProfile (const sigfile::CTypedSource&, int sig_no,
                   const SPPack&);
 
-        SPPack Pp;
-
-        const char* metric_name() const
-                { return metrics::name( TType::mc); }
-
-        valarray<TFloat> course( double binf) const
+        valarray<TFloat>
+        course( double binf) const
                 {
                         size_t	bin = agh::alg::value_within(
-                                (int)((binf - Pp.freq_from) / Pp.freq_inc),
+                                (int)((binf - freq_from) / freq_inc),
                                 0, (int)bins()-1);
-                        return metrics::CProfile::course(bin);
+                        return move(metrics::CProfile::course(bin));
                 }
 
         int go_compute();
@@ -134,10 +165,11 @@ class CProfile
         int export_tsv( size_t bin,
                         const string& fname) const;
 
-        // to enable use as mapped type
-        CProfile (const CProfile& rv)
-	      : metrics::CProfile (rv)
-                {}
+        // // to enable use as mapped type
+        // CProfile (const CProfile& rv)
+        //       : SPPack (rv),
+        //         metrics::CProfile (rv)
+        //         {}
 };
 
 
diff --git a/upstream/src/libmetrics/page-metrics-base.cc b/upstream/src/libmetrics/page-metrics-base.cc
index fb3d7d3..85760e4 100644
--- a/upstream/src/libmetrics/page-metrics-base.cc
+++ b/upstream/src/libmetrics/page-metrics-base.cc
@@ -31,14 +31,36 @@ using namespace std;
 metrics::CProfile::
 CProfile (const sigfile::CTypedSource& F, int sig_no,
           double pagesize, double step, size_t bins)
-      : _status (0),
+      : SPPack (pagesize, step),
+        _status (0),
         _bins (bins),
         _signature_when_mirrored (0),
         _using_F (F),
         _using_sig_no (sig_no)
+{}
+
+metrics::CProfile::
+CProfile (const metrics::CProfile& rv)
+      : SPPack (rv),
+        _status (rv._status),
+        _data (rv._data),
+        _bins (rv._bins),
+        _signature_when_mirrored (rv._signature_when_mirrored),
+        _using_F (rv._using_F),
+        _using_sig_no (rv._using_sig_no)
+{}
+
+metrics::CProfile::
+CProfile (metrics::CProfile&& rv)
+      : SPPack (rv),
+        _status (rv._status),
+        _bins (rv._bins),
+        _signature_when_mirrored (rv._signature_when_mirrored),
+        _using_F (rv._using_F),
+        _using_sig_no (rv._using_sig_no)
 {
-        Pp.pagesize = pagesize;
-        Pp.step = step;
+        _data.swap(rv._data);
+
 }
 
 size_t
@@ -52,7 +74,7 @@ size_t
 metrics::CProfile::
 steps() const
 {
-        return (_using_F().recording_time() - Pp.pagesize) / Pp.step;
+        return (_using_F().recording_time() - pagesize) / step;
 }
 
 
@@ -76,12 +98,7 @@ check() const
         throw invalid_argument (string ("step > pagesize: ") + to_string(step) + " > "+ to_string(pagesize));
 }
 
-void
-metrics::SPPack::
-reset()
-{
-        pagesize = step = 30.;
-}
+
 
 
 list<agh::alg::SSpan<size_t>>
@@ -112,11 +129,11 @@ compute( const SPPack& req_params)
         auto req_signature = _using_F().dirty_signature( _using_sig_no);
         if ( have_data()
              and req_signature == _signature_when_mirrored
-             and Pp.same_as(req_params) )
+             and same_as(req_params) )
                 return 0;
 
         auto old_mirror = mirror_fname();
-        Pp.make_same( req_params);
+        make_same( req_params);
         _signature_when_mirrored = req_signature;
         auto new_mirror = mirror_fname();
 
@@ -157,11 +174,11 @@ need_compute( const SPPack& req_params)
         auto req_signature = _using_F().dirty_signature( _using_sig_no);
         if ( have_data()
              and req_signature == _signature_when_mirrored
-             and Pp.same_as(req_params) )
+             and same_as(req_params) )
                 return false;
 
         auto old_mirror = mirror_fname();
-        Pp.make_same( req_params);
+        make_same( req_params);
         _signature_when_mirrored = req_signature;
         auto new_mirror = mirror_fname();
 
diff --git a/upstream/src/libmetrics/page-metrics-base.hh b/upstream/src/libmetrics/page-metrics-base.hh
index 42ddb88..279a81b 100644
--- a/upstream/src/libmetrics/page-metrics-base.hh
+++ b/upstream/src/libmetrics/page-metrics-base.hh
@@ -57,21 +57,41 @@ struct SPPack {
 
         SPPack ()
                 {
-                        reset();
+                        sane_defaults();
                 }
 
+        SPPack (const SPPack& rv)
+              : pagesize (rv.pagesize),
+                step     (rv.step)
+                {}
+        SPPack (const double pagesize_, const double step_)
+              : pagesize (pagesize_),
+                step (step_)
+                {}
+
         virtual bool same_as( const SPPack& rv) const
                 {
-                        return pagesize == rv.pagesize && step == rv.step;
+                        return  agh::dbl_cmp(pagesize, rv.pagesize) == 0 &&
+                                agh::dbl_cmp( step, rv.step) == 0;
                 }
         virtual void make_same( const SPPack& rv)
                 {
                         pagesize = rv.pagesize;
-                        step = rv.step;
+                        step     = rv.step;
+                }
+
+        virtual void
+        check() const; // throws
+
+        virtual void
+        sane_defaults()
+                {
+                        pagesize = step = 30.;
                 }
 
-        void check() const; // throws
-        void reset();
+        virtual const char*
+        metric_name() const
+                { return "(base metrics ppack)"; }
 };
 
 
@@ -79,17 +99,16 @@ struct SPPack {
 // We better keep the internal storage as valarray<double> regardless
 // of what TFloat today is, because the computed data are written/read
 // to files (else, we'd need to mark files as holding double data, not float).
-class CProfile {
+class CProfile
+  : virtual public SPPack {
 
     protected:
         CProfile (const sigfile::CTypedSource&, int sig_no,
                   double pagesize, double step, size_t bins);
-        CProfile (const CProfile&) = default;
-    public:
-        SPPack  Pp;
-
-        virtual const char* metric_name() const = 0;
+        CProfile (const CProfile&);
+        CProfile (CProfile&&);
 
+    public:
         const sigfile::CSource&
         source() const
                 { return _using_F(); }
@@ -150,11 +169,11 @@ class CProfile {
 
         int compute( const SPPack&);
         int compute()
-                { return compute( Pp); }
+                { return compute( *this); }
 
         bool need_compute( const SPPack&);  // not const because it does mirror_back
         bool need_compute()
-                { return need_compute( Pp); }
+                { return need_compute( *this); }
 
 
     protected:
diff --git a/upstream/src/libmetrics/psd.cc b/upstream/src/libmetrics/psd.cc
index f6e1849..3445085 100644
--- a/upstream/src/libmetrics/psd.cc
+++ b/upstream/src/libmetrics/psd.cc
@@ -31,12 +31,34 @@
 using namespace std;
 
 
+void
+metrics::psd::SPPack::
+check() const
+{
+        metrics::SPPack::check();
 
-sigproc::TWinType
-        metrics::psd::SPPack::welch_window_type = sigproc::TWinType::hanning;
-metrics::psd::TFFTWPlanType
-        metrics::psd::SPPack::plan_type = metrics::psd::TFFTWPlanType::estimate;
+        if ( welch_window_type > sigproc::TWinType::TWinType_total )
+#ifdef _OPENMP
+#pragma omp single
+#endif
+                throw invalid_argument ("Invalid window type");
 
+        if ( plan_type != metrics::psd::TFFTWPlanType::estimate &&
+             plan_type != metrics::psd::TFFTWPlanType::measure )
+#ifdef _OPENMP
+#pragma omp single
+#endif
+                throw invalid_argument ("Invalid FFTW plan type");
+
+        for ( auto c : {.1, .25, .5} )
+                if ( binsize == c )
+                        return;
+
+#ifdef _OPENMP
+#pragma omp single
+#endif
+        throw invalid_argument ("Invalid binsize");
+}
 
 
 
@@ -44,16 +66,18 @@ metrics::psd::TFFTWPlanType
 metrics::psd::CProfile::
 CProfile (const sigfile::CTypedSource& F, const int sig_no,
           const SPPack &params)
-      : metrics::CProfile (F, sig_no,
+      : metrics::SPPack (params),
+        SPPack (params),
+        metrics::CProfile (F, sig_no,
                            params.pagesize, params.step,
-                           params.compute_n_bins( F().samplerate(sig_no))),
-        Pp (params)
+                           params.compute_n_bins( F().samplerate(sig_no)))
 {
-        Pp.check();
+        check();
 }
 
 
 
+
 string
 metrics::psd::CProfile::
 fname_base() const
@@ -64,8 +88,8 @@ fname_base() const
                         ":%g+%g-%g-%c%c",
                         _using_F().filename(), _using_F().channel_by_id(_using_sig_no).name(),
                         _using_F().dirty_signature( _using_sig_no),
-                        Pp.pagesize, Pp.step, Pp.binsize,
-                        'a'+(char)Pp.welch_window_type, 'a'+(char)Pp.plan_type)
+                        pagesize, step, binsize,
+                        'a'+(char)welch_window_type, 'a'+(char)plan_type)
                 );
 }
 
@@ -83,8 +107,8 @@ mirror_fname() const
                         agh::fs::make_fname_base (_using_F().filename(), "", agh::fs::TMakeFnameOption::hidden).c_str(),
                         _using_F().channel_by_id(_using_sig_no).name(),
                         _using_F().dirty_signature( _using_sig_no),
-                        Pp.pagesize, Pp.step, Pp.binsize,
-                        'a'+(char)Pp.welch_window_type, 'a'+(char)Pp.plan_type,
+                        pagesize, step, binsize,
+                        'a'+(char)welch_window_type, 'a'+(char)plan_type,
                         sizeof(double))
                 );
 }
@@ -99,8 +123,8 @@ go_compute()
         _data.resize( steps() * _bins);
 
         size_t	sr = samplerate();
-        size_t	spp = sr * Pp.pagesize,
-                sps = sr * Pp.step;
+        size_t	spp = sr * pagesize,
+                sps = sr * step;
 //        double freq_max = (spp+1)/2 / sr;
 
       // 0. get signal sample; always use double not TFloat
@@ -144,7 +168,7 @@ go_compute()
                         //memcpy( fft_Ti, &S[0], spp * sizeof(double));  // not necessary?
                         plannen[spp] = fftw_plan_dft_r2c_1d(
                                 spp, fft_Ti, (fftw_complex*)fft_To,
-                                plan_flags(Pp.plan_type));
+                                plan_flags(plan_type));
                         printf( "done\n");
                 }
         }
@@ -159,7 +183,7 @@ go_compute()
         {
                 size_t	t9 = spp - window,   // start of the last window but one
                         t;
-                auto wfun = sigproc::winf[Pp.welch_window_type];
+                auto wfun = sigproc::winf[welch_window_type];
                 for ( t = 0; t < window/2; ++t )
                         W[t] = wfun( t, window);
                 for ( t = window/2; t < window; ++t )
@@ -188,11 +212,11 @@ go_compute()
                 // the frequency resolution in P is (1/samplerate) Hz, right?
                 ////memcpy( &_data[p*bins], &P[ThId][0], bins * sizeof(TFloat));
                 ///printf( "n_bins = %zu, max_freq = %g\n", n_bins(), max_freq);
-                for ( f = 0., b = 0; b < _bins; (f += Pp.binsize), ++b ) {
+                for ( f = 0., b = 0; b < _bins; (f += binsize), ++b ) {
                         //printf( "b = %zu, f = %g\n", b, f);
                         nmth_bin(p, b) = (TFloat) // brilliant!
                                 valarray<double>
-                                (P[ slice( f*sr, (f + Pp.binsize)*sr, 1) ]) . sum();
+                                (P[ slice( f*sr, (f + binsize)*sr, 1) ]) . sum();
                 }
                 /// / (bin_size * sr) // don't; power is cumulative
         }
@@ -230,9 +254,9 @@ export_tsv( const string& fname) const
                  _using_F().subject().name.c_str(), _using_F().session(), _using_F().episode(),
                  (int)strlen(asctime_)-1, asctime_,
                  _using_F().channel_by_id(_using_sig_no).name(),
-                 steps(), Pp.pagesize, Pp.step, _bins*Pp.binsize, Pp.binsize);
+                 steps(), pagesize, step, _bins*binsize, binsize);
 
-        for ( bin = 0; bin < _bins; ++bin, bum += Pp.binsize )
+        for ( bin = 0; bin < _bins; ++bin, bum += binsize )
                 fprintf( f, "%g%c", bum, bin+1 == _bins ? '\n' : '\t');
 
         for ( p = 0; p < steps(); ++p ) {
@@ -266,7 +290,7 @@ export_tsv( float from, float upto,
                  _using_F().subject().name.c_str(), _using_F().session(), _using_F().episode(),
                  (int)strlen(asctime_)-1, asctime_,
                  _using_F().channel_by_id(_using_sig_no).name(),
-                 steps(), Pp.pagesize, Pp.step, from, upto);
+                 steps(), pagesize, step, from, upto);
 
         valarray<TFloat> crs = course( from, upto);
         for ( size_t p = 0; p < steps(); ++p )
diff --git a/upstream/src/libmetrics/psd.hh b/upstream/src/libmetrics/psd.hh
index c6c58c9..ff3febd 100644
--- a/upstream/src/libmetrics/psd.hh
+++ b/upstream/src/libmetrics/psd.hh
@@ -19,6 +19,7 @@
 
 #include <fftw3.h>
 
+#include "common/lang.hh"
 #include "libsigproc/winfun.hh"
 #include "forward-decls.hh"
 #include "page-metrics-base.hh"
@@ -64,61 +65,67 @@ plan_type( int f)
 }
 
 struct SPPack
-  : public metrics::SPPack {
+  : virtual public metrics::SPPack {
         double  binsize;
-        static sigproc::TWinType
+        sigproc::TWinType
                 welch_window_type;
-        static TFFTWPlanType
+        TFFTWPlanType
                 plan_type;
 
         SPPack ()
-                { reset(); }
+                {
+                        sane_defaults();
+                }
+
+        SPPack (const SPPack& rv)
+              : metrics::SPPack   (rv),
+                binsize           (rv.binsize),
+                welch_window_type (rv.welch_window_type),
+                plan_type         (rv.plan_type)
+                {}
+
+        SPPack (const metrics::SPPack& base,
+                const double binsize_,
+                const sigproc::TWinType welch_window_type_, const TFFTWPlanType plan_type_)
+              : metrics::SPPack   (base),
+                binsize           (binsize_),
+                welch_window_type (welch_window_type_),
+                plan_type         (plan_type_)
+                {}
 
         bool
         same_as( const SPPack& rv) const
-                { return metrics::SPPack::same_as(rv); }
+                {
+                        return  metrics::SPPack::same_as(rv) &&
+                                agh::dbl_cmp( binsize, rv.binsize) == 0 &&
+                                welch_window_type == rv.welch_window_type &&
+                                plan_type         == rv.plan_type;
+                }
         void
         make_same( const SPPack& rv)
                 { metrics::SPPack::make_same(rv); }
 
         size_t
         compute_n_bins( size_t samplerate) const
-                { return (samplerate * pagesize + 1) / 2 / samplerate / binsize; }
-
-        void
-        check() const
                 {
-                        metrics::SPPack::check();
-
-                        if ( welch_window_type > sigproc::TWinType::TWinType_total )
-#ifdef _OPENMP
-#pragma omp single
-#endif
-                                throw invalid_argument ("Invalid window type");
-
-                        if ( plan_type != metrics::psd::TFFTWPlanType::estimate &&
-                             plan_type != metrics::psd::TFFTWPlanType::measure )
-#ifdef _OPENMP
-#pragma omp single
-#endif
-                                throw invalid_argument ("Invalid FFTW plan type");
-
-                        for ( auto c : {.1, .25, .5} )
-                                if ( binsize == c )
-                                        return;
-
-#ifdef _OPENMP
-#pragma omp single
-#endif
-                        throw invalid_argument ("Invalid binsize");
+                        return (samplerate * pagesize + 1) / 2 / samplerate / binsize;
                 }
 
         void
-        reset()
+        check() const;
+
+        void
+        sane_defaults()
                 {
-                        metrics::SPPack::reset();
+                        metrics::SPPack::sane_defaults();
                         binsize = .25;
+                        welch_window_type = sigproc::TWinType::hanning;
+                        plan_type = TFFTWPlanType::measure;
                 }
+
+        const char*
+        metric_name() const
+                { return metrics::name( TType::psd); }
 };
 
 
@@ -126,25 +133,20 @@ struct SPPack
 
 
 class CProfile
-  : public metrics::CProfile {
+  : virtual public SPPack,
+    virtual public metrics::CProfile {
 
     public:
         CProfile (const sigfile::CTypedSource&, int sig_no,
                   const SPPack&);
 
-        SPPack  Pp;
-
-        const char*
-        metric_name() const
-                { return metrics::name( TType::psd); }
-
         // in a frequency range
         valarray<TFloat>
-        course( double from, double upto) const
+        course( const double from, const double upto) const
                 {
                         valarray<TFloat> acc (0., steps());
-                        size_t  bin_a = min( (size_t)(from / Pp.binsize), _bins),
-                                bin_z = min( (size_t)(upto / Pp.binsize), _bins);
+                        size_t  bin_a = min( (size_t)(from / binsize), _bins),
+                                bin_z = min( (size_t)(upto / binsize), _bins);
                         for ( size_t b = bin_a; b < bin_z; ++b )
                                 acc += metrics::CProfile::course(b);
                         return move(acc);
@@ -159,10 +161,11 @@ class CProfile
         int export_tsv( float, float,
                         const string&) const;
 
-        // to enable use as mapped type
-        CProfile (const CProfile& rv)
-              : metrics::CProfile (rv)
-                {}
+        // // to enable use as mapped type
+        // CProfile (const CProfile& rv)
+        //       : SPPack (rv),
+        //         metrics::CProfile (rv)
+        //         {}
 };
 
 } // namespace psd
diff --git a/upstream/src/libmetrics/swu.cc b/upstream/src/libmetrics/swu.cc
index 7f898d8..63e40fe 100644
--- a/upstream/src/libmetrics/swu.cc
+++ b/upstream/src/libmetrics/swu.cc
@@ -23,16 +23,25 @@ using namespace std;
 using namespace metrics;
 
 
+void
+metrics::swu::SPPack::
+check() const  // throws if not ok
+{
+        metrics::SPPack::check();
+}
+
+
 swu::CProfile::
 CProfile (const sigfile::CTypedSource& F, const int sig_no,
           const SPPack &params)
-      : metrics::CProfile (
-	      F, sig_no,
-	      params.pagesize, params.step,
-	      params.compute_n_bins(F().samplerate(sig_no))),
-        Pp (params)
+      : metrics::SPPack (params),
+        SPPack (params),
+        metrics::CProfile (
+              F, sig_no,
+              params.pagesize, params.step,
+              params.compute_n_bins(F().samplerate(sig_no)))
 {
-        Pp.check();
+        check();
 }
 
 
@@ -42,12 +51,12 @@ swu::CProfile::
 fname_base() const
 {
         return move(
-		agh::str::sasprintf(
-			"%s.%s-%lu"
-			":%g+%g-%g",
-			_using_F().filename(), _using_F().channel_by_id(_using_sig_no).name(),
-			_using_F().dirty_signature( _using_sig_no),
-			Pp.pagesize, Pp.step, Pp.min_upswing_duration));
+                agh::str::sasprintf(
+                        "%s.%s-%lu"
+                        ":%g+%g-%g",
+                        _using_F().filename(), _using_F().channel_by_id(_using_sig_no).name(),
+                        _using_F().dirty_signature( _using_sig_no),
+                        pagesize, step, min_upswing_duration));
 }
 
 
@@ -56,15 +65,15 @@ swu::CProfile::
 mirror_fname() const
 {
         return move(
-		agh::str::sasprintf(
-			"%s.%s-%lu"
-			":%g+%g-%g@%zu"
-			".swu",
-			agh::fs::make_fname_base (_using_F().filename(), "", agh::fs::TMakeFnameOption::hidden).c_str(),
-			_using_F().channel_by_id(_using_sig_no).name(),
-			_using_F().dirty_signature( _using_sig_no),
-			Pp.pagesize, Pp.step, Pp.min_upswing_duration,
-			sizeof(TFloat)));
+                agh::str::sasprintf(
+                        "%s.%s-%lu"
+                        ":%g+%g-%g@%zu"
+                        ".swu",
+                        agh::fs::make_fname_base (_using_F().filename(), "", agh::fs::TMakeFnameOption::hidden).c_str(),
+                        _using_F().channel_by_id(_using_sig_no).name(),
+                        _using_F().dirty_signature( _using_sig_no),
+                        pagesize, step, min_upswing_duration,
+                        sizeof(TFloat)));
 }
 
 
@@ -78,10 +87,10 @@ go_compute()
                 _using_F().get_signal_filtered( _using_sig_no));
 
         for ( size_t p = 0; p < steps(); ++p ) {
-                auto	a = p * (samplerate() * Pp.step),
-                        z = a + (samplerate() * Pp.pagesize);
-                auto	la = a, lz = a;
-                double	Q = 0.;
+                auto    a = p * (samplerate() * step),
+                        z = a + (samplerate() * pagesize);
+                auto    la = a, lz = a;
+                double  Q = 0.;
 
               // 1. upswing proper
                 // find a stretch of uninterrupted positive values
@@ -96,14 +105,14 @@ go_compute()
                         }
                         la = i; lz = j;
                         double upswing_duration = (lz - la) * samplerate();
-                        if ( upswing_duration > Pp.min_upswing_duration )
+                        if ( upswing_duration > min_upswing_duration )
                                 Q += q;
                 }
               // 2. clean peaks
                 
 
                 nmth_bin(p, 0) =
-                        Q / Pp.pagesize;
+                        Q / pagesize;
         }
 
 
@@ -134,7 +143,7 @@ export_tsv( const string& fname) const
                  _using_F().subject().name.c_str(), _using_F().session(), _using_F().episode(),
                  (int)strlen(asctime_)-1, asctime_,
                  _using_F().channel_by_id(_using_sig_no).name(),
-                 steps(), Pp.pagesize, Pp.step);
+                 steps(), pagesize, step);
 
         for ( size_t p = 0; p < steps(); ++p )
                 fprintf( f, "%zu\t%g\n", p, nmth_bin( p, 0));
diff --git a/upstream/src/libmetrics/swu.hh b/upstream/src/libmetrics/swu.hh
index 15645a1..2528f20 100644
--- a/upstream/src/libmetrics/swu.hh
+++ b/upstream/src/libmetrics/swu.hh
@@ -31,42 +31,55 @@ namespace swu {
 
 
 struct SPPack
-  : public metrics::SPPack {
+  : virtual public metrics::SPPack {
 
         double	min_upswing_duration;
 
         SPPack ()
-                { reset(); }
+                {
+                        sane_defaults();
+                }
+
+        SPPack (const SPPack& rv)
+              : metrics::SPPack      (rv),
+                min_upswing_duration (rv.min_upswing_duration)
+                {}
+
+        SPPack (const metrics::SPPack& base,
+                const double min_upswing_duration_)
+              : metrics::SPPack      (base),
+                min_upswing_duration (min_upswing_duration_)
+                {}
+
         size_t
         compute_n_bins( size_t) const
                 { return 1; }
 
         void
-	check() const  // throws if not ok
-                { metrics::SPPack::check(); }
+        check() const;
 
         void
-	reset()
+        sane_defaults()
                 {
-                        metrics::SPPack::reset();
-                        min_upswing_duration = .3;
+                        metrics::SPPack::sane_defaults();
+                        min_upswing_duration = 1.;
                 }
+
+        const char*
+        metric_name() const
+                { return metrics::name( TType::swu); }
 };
 
 
 
 class CProfile
-  : public metrics::CProfile {
+  : virtual public SPPack,
+    virtual public metrics::CProfile {
 
     public:
         CProfile (const sigfile::CTypedSource&, int sig_no,
                   const SPPack&);
 
-        SPPack Pp;
-
-        const char* metric_name() const
-                { return metrics::name( TType::swu); }
-
         valarray<TFloat> course( double) const
                 {
                         size_t	bin = 0; // (size_t)(binf - freq_from / Pp.freq_inc);
@@ -82,10 +95,11 @@ class CProfile
         int export_tsv( float, float,
                         const string&) const;
 
-        // to enable use as mapped type
-        CProfile (const CProfile& rv)
-              : metrics::CProfile (rv)
-                {}
+        // // to enable use as mapped type
+        // CProfile (const CProfile& rv)
+        //       : SPPack (rv),
+        //         metrics::CProfile (rv)
+        //         {}
 };
 
 } // namespace swu
diff --git a/upstream/src/libsigfile/typed-source.cc b/upstream/src/libsigfile/typed-source.cc
index 43c6883..9dd3b9f 100644
--- a/upstream/src/libsigfile/typed-source.cc
+++ b/upstream/src/libsigfile/typed-source.cc
@@ -62,7 +62,7 @@ CTypedSource (const string& fname,
 
         case TType::bin:
                 throw invalid_argument ("Source type 'bin' not supported");
-        case TType::unrecognised:
+        default:
                 throw invalid_argument ("Unrecognised source type");
         }
 

-- 
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