[med-svn] [SCM] aghermann branch, master, updated. 2523fe1ce5b3da7059d8e7aa2f2a4251854704cf
Andrei Zavada
johnhommer at gmail.com
Mon Jul 22 23:31:23 UTC 2013
The following commit has been merged in the master branch:
commit d21bf89fe1a1baac595e7629aa72579376f4a5b6
Author: Andrei Zavada <johnhommer at gmail.com>
Date: Mon Jul 22 01:56:20 2013 +0300
support irregular time-series TSV data
diff --git a/ChangeLog b/ChangeLog
index e56dab1..7d125f0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,7 +7,8 @@ v.0.9.1 (2013-xx-xx)
* SF: Artifact Detection dialog will now not get confused after
clicking outside it on other channels.
* New tool agh-profile-gen, a standalone profile generator.
- * ascii (tsv) format support.
+ * ascii (tsv) format support, including irregular, timestamped
+ time series data.
* Score assistant now uses delta and theta ranges as defined by user.
v.0.9.0.4 (2013-05-18)
diff --git a/src/libsigfile/tsv.cc b/src/libsigfile/tsv.cc
index 5fe877c..83f513e 100644
--- a/src/libsigfile/tsv.cc
+++ b/src/libsigfile/tsv.cc
@@ -258,34 +258,82 @@ int
CTSVFile::
_read_data()
{
- vector<vector<double>> c2 (channels.size());
-
// _line0 contains the first row of data already (it is the
// first line not beginning with a #)
+
+ vector<vector<double>> c2 (channels.size());
size_t r, ll = 0;
- do {
- for ( r = 0; r < channels.size(); ++r ) {
- double x;
- if ( 1 != sscanf( _line0, "%lg%*[,\t]", &x) )
- goto outer_break;
- c2[r].push_back( x);
+
+ if ( metadata["series"] == "irregular" ) {
+ vector<unsigned long> offsets;
+ do {
+ double ts;
+ if ( 1 != sscanf( _line0, "%lg%*[,\t]", &ts) ) {
+ fprintf( stderr, "Bad offset (at data line %zu)\n", ll);
+ _status |= bad_offset;
+ return -1;
+ }
+ if ( ll > 0 && ts * _samplerate <= offsets.back() ) {
+ fprintf( stderr, "Offsets not increasing (at data line %zu)\n", ll);
+ _status |= offsets_not_incteasing;
+ return -1;
+ }
+
+ offsets.push_back( ts * _samplerate);
+
+ for ( r = 0; r < channels.size(); ++r ) {
+ double x;
+ if ( 1 != sscanf( _line0, "%lg%*[,\t]", &x) )
+ goto outer_break1;
+ c2[r].push_back( x);
+ }
+ ++ll;
+ } while ( getline( &_line0, &_line0_mallocked_bytes, _f) > 0 );
+ outer_break1:
+
+ if ( r != 0 && r != channels.size() ) {
+ fprintf( stderr, "Number of data read (%zu) not a multiple of channel count (%zu)\n", r, channels.size());
+ _status |= bad_channel_count;
+ return -1;
}
- ++ll;
- } while ( getline( &_line0, &_line0_mallocked_bytes, _f) > 0 );
-outer_break:
+ // interpolate and resample
+ for ( size_t h = 0; h < channels.size(); ++h ) {
+ valarray<TFloat> interpolated =
+ sigproc::interpolate<TFloat>(
+ offsets,
+ _samplerate,
+ c2[h],
+ 1./_samplerate);
+ channels[h].data.resize( interpolated.size());
+ channels[h].data = interpolated;
+ }
- if ( r != 0 && r != channels.size() ) {
- fprintf( stderr, "Number of data read (%zu) not a multiple of channel count (%zu)\n", r, channels.size());
- _status |= bad_channel_count;
- return -1;
- }
- // vector -> valarray
- for ( size_t h = 0; h < channels.size(); ++h ) {
- channels[h].data.resize( ll);
- for ( size_t i = 0; i < ll; ++i )
- channels[h].data[i] = c2[h][i];
+ } else {
+ do {
+ for ( r = 0; r < channels.size(); ++r ) {
+ double x;
+ if ( 1 != sscanf( _line0, "%lg%*[,\t]", &x) )
+ goto outer_break2;
+ c2[r].push_back( x);
+ }
+ ++ll;
+ } while ( getline( &_line0, &_line0_mallocked_bytes, _f) > 0 );
+ outer_break2:
+
+ if ( r != 0 && r != channels.size() ) {
+ fprintf( stderr, "Number of data read (%zu) not a multiple of channel count (%zu)\n", r, channels.size());
+ _status |= bad_channel_count;
+ return -1;
+ }
+
+ // vector -> valarray
+ for ( size_t h = 0; h < channels.size(); ++h ) {
+ channels[h].data.resize( ll);
+ for ( size_t i = 0; i < ll; ++i )
+ channels[h].data[i] = c2[h][i];
+ }
}
@@ -377,6 +425,10 @@ explain_status( const int status)
list<string> recv;
if ( status & bad_channel_count )
recv.emplace_back( "Number of channels declared in header different from number of columns of data");
+ if ( status & bad_offset )
+ recv.emplace_back( "Bad offset");
+ if ( status & offsets_not_incteasing )
+ recv.emplace_back( "Offsets in an irregular-series data not increasing");
return CSource::explain_status(status) + (recv.empty() ? "" : (join(recv, "\n") + '\n'));
}
diff --git a/src/libsigfile/tsv.hh b/src/libsigfile/tsv.hh
index c3fea05..56e6706 100644
--- a/src/libsigfile/tsv.hh
+++ b/src/libsigfile/tsv.hh
@@ -333,12 +333,16 @@ class CTSVFile
enum TStatus : int_least32_t {
bad_channel_count = (1 << (COMMON_STATUS_BITS + 1)),
+ bad_offset = (1 << (COMMON_STATUS_BITS + 2)),
+ offsets_not_incteasing = (1 << (COMMON_STATUS_BITS + 3)),
inoperable = (bad_header
| bad_numfld
| bad_datetime
| dup_channels
| sysfail
- | too_many_channels)
+ | too_many_channels
+ | bad_offset
+ | offsets_not_incteasing)
};
static string explain_status( int);
--
Sleep experiment manager
More information about the debian-med-commit
mailing list