1 // Copyright (c) 2016 The SigViewer Development Team
2 // Licensed under the GNU General Public License (GPL)
3 // https://www.gnu.org/licenses/gpl
4 
5 
6 #include "biosig_basic_header.h"
7 #include "xdf_reader.h"
8 
9 #include <ctime>
10 #include <cmath>
11 
12 namespace sigviewer
13 {
14 
15 //-----------------------------------------------------------------------------
BiosigBasicHeader(HDRTYPE * raw_header,QString const & file_path)16 BiosigBasicHeader::BiosigBasicHeader (HDRTYPE* raw_header, QString const& file_path)
17     : BasicHeader (file_path),
18       number_samples_ (raw_header->NRec * raw_header->SPR)
19 {
20     if (raw_header->EVENT.CodeDesc)
21     {
22         for (unsigned index = 0; index < raw_header->EVENT.LenCodeDesc; index++)
23         {
24             if (raw_header->EVENT.CodeDesc[index])
25                 user_defined_event_map_[index] = QString(raw_header->EVENT.CodeDesc[index]);
26         }
27     }
28 
29 
30     setFileTypeString (QString (GetFileTypeString(raw_header->TYPE)).append(" v").append(QString::number(raw_header->VERSION)));
31 
32     float64 sampling_rate = raw_header->SampleRate;
33 
34     setSampleRate (sampling_rate);
35     readChannelsInfo (raw_header);
36     readPatientInfo (raw_header);
37     readRecordingInfo (raw_header);
38 }
39 
40 //!alternative for XDF---------------------------------------------------------
BiosigBasicHeader(QString file_format,QString const & file_path)41 BiosigBasicHeader::BiosigBasicHeader (QString file_format, QString const& file_path)
42     : BasicHeader (file_path),
43       number_samples_ (XDFdata->totalLen)
44 {
45     if (XDFdata->dictionary.size())
46     {
47         for (unsigned index = 0; index < XDFdata->dictionary.size(); index++)
48         {
49             //below we use index+1 because in SigViewer, 0 is reserved for a special event type.
50             //thus we count from 1
51             user_defined_event_map_[index + 1] = QString::fromStdString(XDFdata->dictionary[index]);
52         }
53     }
54 
55     QString fileType = "XDF v" + QString::number(XDFdata->version, 'f', 1);
56     setFileTypeString (fileType);
57 
58     float64 sampling_rate = XDFdata->majSR;
59 
60     setSampleRate (sampling_rate);
61     readChannelsInfo (file_format);
62 }
63 
64 
65 //-----------------------------------------------------------------------------
getNumberOfSamples() const66 size_t BiosigBasicHeader::getNumberOfSamples () const
67 {
68     return ceil(static_cast<double>(number_samples_));
69 }
70 
71 //-----------------------------------------------------------------------------
getNamesOfUserSpecificEvents() const72 QMap<unsigned, QString> BiosigBasicHeader::getNamesOfUserSpecificEvents () const
73 {
74     return user_defined_event_map_;
75 }
76 
77 //-----------------------------------------------------------------------------
readChannelsInfo(HDRTYPE const * raw_header)78 void BiosigBasicHeader::readChannelsInfo (HDRTYPE const* raw_header)
79 {
80     unsigned ch = 0;
81     for (unsigned channel_index = 0; channel_index < raw_header->NS; channel_index++)
82         if (raw_header->CHANNEL[channel_index].OnOff)
83         {
84             QSharedPointer<SignalChannel> channel(new SignalChannel(channel_index, raw_header));
85             addChannel(ch++, channel);
86         }
87 }
88 
89 //-------------------------------------------------------------------------
readChannelsInfo(QString file_format)90 void BiosigBasicHeader::readChannelsInfo (QString file_format)
91 {
92     unsigned ch = 0;
93     for (unsigned channel_index = 0; channel_index < XDFdata->totalCh; channel_index++)
94     {
95         QSharedPointer<SignalChannel> channel(new SignalChannel(channel_index, file_format));
96         addChannel(ch++, channel);
97     }
98 }
99 
100 //-------------------------------------------------------------------------
readPatientInfo(HDRTYPE const * raw_header)101 void BiosigBasicHeader::readPatientInfo (HDRTYPE const* raw_header)
102 {
103     switch (raw_header->Patient.Handedness)
104     {
105     case 1:
106         addPatientInfo ("Handedness", "Right"); break;
107     case 2:
108         addPatientInfo ("Handedness", "Left"); break;
109     case 3:
110         addPatientInfo ("Handedness", "Equal"); break;
111     }
112 
113     switch (raw_header->Patient.Sex)
114     {
115     case 1:
116         addPatientInfo ("Sex", "Male"); break;
117     case 2:
118         addPatientInfo ("Sex", "Female"); break;
119     }
120 
121     switch (raw_header->Patient.Smoking)
122     {
123     case 1:
124         addPatientInfo ("Smoking", "No"); break;
125     case 2:
126         addPatientInfo ("Smoking", "Yes"); break;
127     }
128     switch (raw_header->Patient.Smoking)
129     {
130     case 1:
131         addPatientInfo ("Smoking", "No"); break;
132     case 2:
133         addPatientInfo ("Smoking", "Yes"); break;
134     }
135 
136     QString patient_id;
137     for (unsigned i = 0; i < MAX_LENGTH_PID && raw_header->Patient.Id[i]; i++)
138         patient_id.append (raw_header->Patient.Id[i]);
139     addPatientInfo ("Id", patient_id.trimmed());
140 
141     if (raw_header->Patient.Birthday)
142     {
143         time_t birthday_t = mktime(gdf_time2tm_time (raw_header->Patient.Birthday));
144         addPatientInfo ("Birthday", QString (ctime(&birthday_t)).trimmed());
145     }
146 
147     if (raw_header->Patient.Weight)
148         addPatientInfo ("Weight", QString::number(raw_header->Patient.Weight).append("kg"));
149     if (raw_header->Patient.Height)
150         addPatientInfo ("Height", QString::number(raw_header->Patient.Height).append("cm"));
151 }
152 
153 
154 //-------------------------------------------------------------------------
readRecordingInfo(HDRTYPE const * raw_header)155 void BiosigBasicHeader::readRecordingInfo (HDRTYPE const* raw_header)
156 {
157     if (raw_header->T0)
158     {
159         time_t recording_t = mktime(gdf_time2tm_time (raw_header->T0));
160         addRecordingInfo("Recording Time", QString (ctime(&recording_t)).trimmed());
161     }
162 }
163 
164 }
165