The following commit has been merged in the master branch:
commit 98b647726bda612309dea9b82d6855a4e243751b
Author: Andrei Zavada <[email protected]>
Date:   Sun Apr 21 00:29:23 2013 +0300

    CEDFFile::details takes a bitfield, reports annotations and discontinuities

diff --git a/man/edfhed.1.in b/man/edfhed.1.in
index 9779765..e14ff61 100644
--- a/man/edfhed.1.in
+++ b/man/edfhed.1.in
@@ -14,6 +14,9 @@ the header (see options \fB\-s\fR, \fB\-T\fR and \fB\-R\fR).
 \fB\-b\fR, \fB\-\-no\-channels\fR
 Only dump general header fields (no channel details).
 .TP
+\fB\-a\fR, \fB\-\-with\-annotations\fR
+List embedded annotations if any.
+.TP
 \fB\-R\fR, \fB\-\-from\-tree\fR
 Given file location \(oqSubject/Session/Episode.edf\(cq, set 
\fBrecording_id\fR to
 \(oqSession/Episode\(cq and \fBpatient_id\fR to \(oqSubject\(cq.
diff --git a/src/libsigfile/edf.cc b/src/libsigfile/edf.cc
index 3b0dd7d..6585934 100644
--- a/src/libsigfile/edf.cc
+++ b/src/libsigfile/edf.cc
@@ -911,12 +911,20 @@ _extract_embedded_annotations()
 
 string
 CEDFFile::
-details( bool channels_too) const
+details( int which) const
 {
        ostringstream recv;
        if ( _status & bad_header )
                recv << "Bad header, or no file\n";
        else {
+               size_t  n_dicontinuities = 0;
+               double  prev_offset = NAN, cur_offset;
+               for ( size_t r = 1; r < _record_offsets.size(); ++r ) {
+                       cur_offset = _record_offsets[r] - _record_offsets[r-1];
+                       if ( isfinite(prev_offset) and cur_offset != 
prev_offset )
+                               ++n_dicontinuities;
+                       prev_offset = cur_offset;
+               }
                char *outp;
                ASPRINTF( &outp,
                          "File\t: %s\n"
@@ -927,21 +935,24 @@ details( bool channels_too) const
                          " Time\t: %s\n"
                          " # of channels\t: %zu\n"
                          " # of records\t: %zu\n"
-                         " Record size\t: %g sec\n",
+                         " Record size\t: %g sec\n"
+                         " # of discontinuities\t: %zu\n"
+                         " # of embedded annotations\t: %zu\n",
                          filename(),
                          subtype_s(),
                          patient_id(),
                          trim( string (header.recording_id, 80)).c_str(),
                          trim( string (header.recording_date, 8)).c_str(),
                          trim( string (header.recording_time, 8)).c_str(),
-                         // asctime( localtime( &_start_time)),
                          channels.size(),
                          n_data_records,
-                         data_record_size);
+                         data_record_size,
+                         n_dicontinuities,
+                         common_annotations.size());
                recv << outp;
                free( outp);
 
-               if ( channels_too ) {
+               if ( which & with_channels ) {
                        size_t i = 0;
                        for ( auto &H : channels ) {
                                ASPRINTF( &outp,
@@ -973,6 +984,12 @@ details( bool channels_too) const
                                free( outp);
                        }
                }
+
+               if ( which & with_annotations ) {
+                       recv << "Embedded annotations (" << 
common_annotations.size() << "):\n";
+                       for ( auto &A : common_annotations )
+                               recv << ' ' << A.span.a << '\t' << A.span.z << 
'\t' << A.label << endl;
+               }
        }
 
        return recv.str();
diff --git a/src/libsigfile/edf.hh b/src/libsigfile/edf.hh
index 0dd69f9..49a45d6 100644
--- a/src/libsigfile/edf.hh
+++ b/src/libsigfile/edf.hh
@@ -388,7 +388,8 @@ class CEDFFile
       // reporting & misc
        void write_ancillary_files();
 
-       string details( bool channels_too = true) const;
+       enum TEdfDetails { with_channels = 1, with_annotations = 2 };
+       string details( int which) const;
 
        sigproc::TWinType af_dampen_window_type; // master copy
 
diff --git a/src/libsigfile/source-base.hh b/src/libsigfile/source-base.hh
index de990fa..4a3ce2b 100644
--- a/src/libsigfile/source-base.hh
+++ b/src/libsigfile/source-base.hh
@@ -215,8 +215,7 @@ class CSource {
        int status()    const { return _status; }
        int flags()     const { return _flags; }
        virtual string explain_status()                 const = 0;
-       virtual string details( bool channels_too = true)
-                                                       const = 0;
+       virtual string details( int which_details)      const = 0;
 
       // identification
        const char* filename() const
diff --git a/src/tools/edfcat.cc b/src/tools/edfcat.cc
index 26c4b65..45d8e1b 100644
--- a/src/tools/edfcat.cc
+++ b/src/tools/edfcat.cc
@@ -353,7 +353,7 @@ exec_convert( const SOperation::SObject& obj)
 
        printf( "Created edf:\n%s\n"
                "You may now want to fill out the header of the newly created 
EDF file.\n"
-               "Use edfhed --set ... to do so, or run edfhed-gtk.\n", 
F.details().c_str());
+               "Use edfhed --set ... to do so, or run edfhed-gtk.\n", 
F.details( 0|sigfile::CEDFFile::with_channels).c_str());
 
        return 0;
 }
@@ -396,7 +396,7 @@ exec_prune( const SOperation::SObject& obj)
        tmp = F.comment();
        G.set_comment( tmp.c_str());
        G.set_start_time( F.start_time());
-       printf( "Created edf:\n%s\n", G.details().c_str());
+       printf( "Created edf:\n%s\n", G.details( 
0|sigfile::CEDFFile::with_channels).c_str());
 
 //     F.resize( data.size() / obj.samplerate / obj.record_size);
        size_t h = 0;
diff --git a/src/tools/edfhed.cc b/src/tools/edfhed.cc
index 015d2a8..b027dd8 100644
--- a/src/tools/edfhed.cc
+++ b/src/tools/edfhed.cc
@@ -43,6 +43,7 @@ static char doc[] =
 
 static struct argp_option options[] = {
        {"no-channels",         'b', 0, 0, "Only dump general header fields (no 
channel details)"},
+       {"with-annotations",    'a', 0, 0, "List embedded annotations"},
        {"set",                 's', "[CH:]FIELD:VALUE", 0, "Set FIELD to VALUE 
(possibly in channel CH)" },
        {"id-from-tree",                'R', 0, 0, "Set 'recording_id' field to 
Subject/Session/Episode given current file location"},
        {"from-mtime",          'T', 0, 0, "Set 'recording_date' and 
'recording_time' fields to file modification date/time"},
@@ -155,11 +156,13 @@ struct SArguments {
        std::vector<SSettable>
                settables;
        bool    header_only:1,
+               with_annotations:1,
                from_tree:1,
                from_timestamp:1,
                to_timestamp:1;
        SArguments()
              : header_only (false),
+               with_annotations (false),
                from_tree (false),
                from_timestamp (false),
                to_timestamp (false)
@@ -177,6 +180,9 @@ parse_opt( int key, char *arg, struct argp_state *state)
        case 'b':
                Q.header_only = true;
                break;
+       case 'a':
+               Q.with_annotations = true;
+               break;
        case 'R':
                Q.from_tree = true;
                break;
@@ -322,7 +328,11 @@ main( int argc, char **argv)
                                                    
sigfile::CEDFFile::no_field_consistency_check);
                        if ( Opts.settables.empty() &&
                             not Opts.from_timestamp && not Opts.from_tree && 
not Opts.to_timestamp ) {
-                               cout << F.details( not Opts.header_only) << 
endl;
+                               cout << F.details(
+                                       0
+                                       | (Opts.header_only ? 0 : 
sigfile::CEDFFile::with_channels)
+                                       | (Opts.with_annotations ? 
sigfile::CEDFFile::with_annotations : 0))
+                                    << endl;
                        } else {
                                if ( Opts.to_timestamp ) {
                                        set_mtime_from_recording_datetime( F);
diff --git a/src/ui/mw/admit-one.cc b/src/ui/mw/admit-one.cc
index cebab56..1c510fe 100644
--- a/src/ui/mw/admit-one.cc
+++ b/src/ui/mw/admit-one.cc
@@ -32,7 +32,7 @@ dnd_maybe_admit_one( const char* fname)
                        pop_ok_message( wMainWindow, "Bad EDF file", "The file 
<i>%s</i> doesn't appear to be a valid EDF file", fname);
                        return 0;
                }
-               info = (*Fp)().details();
+               info = (*Fp)().details( 0|sigfile::CEDFFile::with_channels);
 
                snprintf_buf( "File: <i>%s</i>", fname);
                gtk_label_set_markup( lEdfImportCaption, __buf__);
diff --git a/src/ui/mw/measurements_cb.cc b/src/ui/mw/measurements_cb.cc
index 3af215d..91b0be2 100644
--- a/src/ui/mw/measurements_cb.cc
+++ b/src/ui/mw/measurements_cb.cc
@@ -160,7 +160,7 @@ iSubjectTimelineEDFInfo_activate_cb( GtkMenuItem*, gpointer 
userdata)
        auto J = ED.using_subject;
 
        const auto& F = J->using_episode->sources.front();
-       gtk_text_buffer_set_text( ED.tEDFFileDetailsReport, 
F().details().c_str(), -1);
+       gtk_text_buffer_set_text( ED.tEDFFileDetailsReport, F().details( 
0|sigfile::CEDFFile::with_channels).c_str(), -1);
        snprintf_buf( "%s header", F().filename());
        gtk_window_set_title( (GtkWindow*)ED.wEDFFileDetails,
                              __buf__);

-- 
Sleep experiment manager

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

Reply via email to