v2.0.0
Loading...
Searching...
No Matches
inv_ecd_set.cpp
Go to the documentation of this file.
1//=============================================================================================================
36
37//=============================================================================================================
38// INCLUDES
39//=============================================================================================================
40
41#include "inv_ecd_set.h"
42#include <fiff/fiff_types.h>
43
44
45
46//=============================================================================================================
47// QT INCLUDES
48//=============================================================================================================
49
50#include <QDebug>
51#include <QFile>
52#include <QString>
53#include <QRegularExpression>
54#include <QDebug>
55
56//=============================================================================================================
57// EIGEN INCLUDES
58//=============================================================================================================
59
60//=============================================================================================================
61// USED NAMESPACES
62//=============================================================================================================
63
64using namespace INVLIB;
65using namespace FIFFLIB;
66
67//=============================================================================================================
68// DEFINES
69//=============================================================================================================
70
71constexpr int X = 0;
72constexpr int Y = 1;
73constexpr int Z = 2;
74
75//=============================================================================================================
76// DEFINE STATIC METHODS
77//=============================================================================================================
78
79static fiff_int_t swap_int (fiff_int_t source)
80{
81 unsigned char *csource = (unsigned char *)(&source);
82 fiff_int_t result;
83 unsigned char *cresult = (unsigned char *)(&result);
84
85 cresult[0] = csource[3];
86 cresult[1] = csource[2];
87 cresult[2] = csource[1];
88 cresult[3] = csource[0];
89 return (result);
90}
91
92//=============================================================================================================
93
94static float swap_float (float source)
95{
96 unsigned char *csource = (unsigned char *)(&source);
97 float result;
98 unsigned char *cresult = (unsigned char *)(&result);
99
100 cresult[0] = csource[3];
101 cresult[1] = csource[2];
102 cresult[2] = csource[1];
103 cresult[3] = csource[0];
104 return result;
105}
106
107//=============================================================================================================
108
109namespace INVLIB {
110
114typedef struct {
115 int dipole; /* Which dipole in a multi-dipole set */
116 float begin,end; /* Fitting time range */
117 float r0[3]; /* Sphere model origin */
118 float rd[3]; /* Dipole location */
119 float Q[3]; /* InvDipole amplitude */
120 float goodness; /* Goodness-of-fit */
121 int errors_computed; /* Have we computed the errors */
122 float noise_level; /* Noise level used for error computations */
123 float single_errors[5]; /* Single parameter error limits */
124 float error_matrix[5][5]; /* This fully describes the conf. ellipsoid */
125 float conf_vol; /* The xyz confidence volume */
126 float khi2; /* The khi^2 value */
127 float prob; /* Probability to exceed khi^2 by chance */
128 float noise_est; /* Total noise estimate */
129} bdipEcdRec;
131
132} // Namespace
133
134//=============================================================================================================
135// DEFINE MEMBER METHODS
136//=============================================================================================================
137
141
142//=============================================================================================================
143
145: dataname(p_ECDSet.dataname)
146, m_qListDips(p_ECDSet.m_qListDips)
147{
148}
149
150//=============================================================================================================
151
155
156//=============================================================================================================
157
158void InvEcdSet::addEcd(const InvEcd& p_ecd)
159{
160 m_qListDips.append(p_ecd);
161}
162
163//=============================================================================================================
164
166{
167 InvEcdSet set;
168
169 QFile inputFile(fileName);
170 if (inputFile.open(QIODevice::ReadOnly|QIODevice::Text))
171 {
172 QTextStream in(&inputFile);
173 while (!in.atEnd())
174 {
175 QString line = in.readLine();
176 QStringList list = line.split(QRegularExpression("\\s+"));
177
178 if(list[0].contains("#") || list.size() != 11) {
179 continue;
180 }
181 else {
182 InvEcd one;
183 one.valid = true;
184 one.time = list[1].toFloat() / 1000.0f;
185 one.rd[X] = list[3].toFloat() / 1000.0f;
186 one.rd[Y] = list[4].toFloat() / 1000.0f;
187 one.rd[Z] = list[5].toFloat() / 1000.0f;
188 one.Q[X] = list[7].toFloat() / 1e9f;
189 one.Q[Y] = list[8].toFloat() / 1e9f;
190 one.Q[Z] = list[9].toFloat() / 1e9f;
191 one.good = list[10].toFloat() / 100.0f;
192 set << one;
193 }
194 }
195 inputFile.close();
196
197 qInfo("Read %d dipoles in dip format from %s\n",set.size(),fileName.toUtf8().data());
198 }
199 else {
200 qCritical("Not able to read from: %s\n", fileName.toUtf8().data());
201 }
202
203 return set;
204}
205
206//=============================================================================================================
207
208bool InvEcdSet::save_dipoles_bdip(const QString& fileName)
209/*
210 * Save dipoles in the bdip format employed by xfit
211 */
212{
213 FILE *out = nullptr;
214 bdipEcdRec one_out;
215 InvEcd one;
216 int k,p;
217 int nsave;
218
219 if (fileName.isEmpty() || this->size() == 0)
220 return true;
221
222 if ((out = fopen(fileName.toUtf8().data(),"w")) == nullptr) {
223 qInfo("%s", fileName.toUtf8().constData());
224 return false;
225 }
226
227 for (k = 0, nsave = 0; k < this->size(); k++) {
228 one = m_qListDips[k];
229 if (one.valid) {
230 one_out.dipole = swap_int(1);
231 one_out.begin = swap_float(one.time);
232 for (p = 0; p < 3; p++) {
233 one_out.r0[p] = swap_float(0.0);
234 one_out.rd[p] = swap_float(one.rd[p]);
235 one_out.Q[p] = swap_float(one.Q[p]);
236 }
237 one_out.goodness = swap_float(one.good);
238 one_out.errors_computed = swap_int(0);
239 one_out.khi2 = swap_float(one.khi2);
240 if (fwrite(&one_out,sizeof(bdipEcdRec),1,out) != 1) {
241 qCritical("Failed to write a dipole");
242 fclose(out);
243 QFile::remove(fileName);
244 return false;
245 }
246 nsave++;
247 }
248 }
249 if (fclose(out) != 0) {
250 out = nullptr;
251 qInfo("%s", fileName.toUtf8().constData());
252 return false;
253 }
254 qInfo("Save %d dipoles in bdip format to %s\n",nsave,fileName.toUtf8().data());
255 return true;
256}
257
258//=============================================================================================================
259
260bool InvEcdSet::save_dipoles_dip(const QString& fileName) const
261{
262 FILE *out = nullptr;
263 int k,nsave;
264 InvEcd one;
265
266 if (fileName.isEmpty() || this->size() == 0)
267 return true;
268 if ((out = fopen(fileName.toUtf8().data(),"w")) == nullptr) {
269 qInfo("%s", fileName.toUtf8().constData());
270 return false;
271 }
272 fprintf(out,"# CoordinateSystem \"Head\"\n");
273 fprintf (out,"# %7s %7s %8s %8s %8s %8s %8s %8s %8s %6s\n",
274 "begin","end","X (mm)","Y (mm)","Z (mm)","Q(nAm)","Qx(nAm)","Qy(nAm)","Qz(nAm)","g/%");
275 for (k = 0, nsave = 0; k < this->size(); k++) {
276 one = this->m_qListDips[k];
277 if (one.valid) {
278 fprintf(out," %7.1f %7.1f %8.2f %8.2f %8.2f %8.3f %8.3f %8.3f %8.3f %6.1f\n",
279 1000*one.time,1000*one.time,
280 1000*one.rd[X],1000*one.rd[Y],1000*one.rd[Z],
281 1e9*one.Q.norm(),1e9*one.Q[X],1e9*one.Q[Y],1e9*one.Q[Z],100.0*one.good);
282 nsave++;
283 }
284 }
285 fprintf(out,"## Name \"%s dipoles\" Style \"Dipoles\"\n","ALL");
286 if (fclose(out) != 0) {
287 out = nullptr;
288 qInfo("%s", fileName.toUtf8().constData());
289 return false;
290 }
291 qInfo("Save %d dipoles in dip format to %s\n",nsave,fileName.toUtf8().data());
292 return true;
293}
294
295//=============================================================================================================
296
297const InvEcd& InvEcdSet::operator[] (int idx) const
298{
299 if (idx>=m_qListDips.length())
300 {
301 qWarning("Warning: Required InvEcd doesn't exist! Returning InvEcd '0'.");
302 idx=0;
303 }
304 return m_qListDips[idx];
305}
306
307//=============================================================================================================
308
310{
311 if (idx >= m_qListDips.length())
312 {
313 qWarning("Warning: Required InvEcd doesn't exist! Returning InvEcd '0'.");
314 idx = 0;
315 }
316 return m_qListDips[idx];
317}
318
319//=============================================================================================================
320
322{
323 this->m_qListDips.append(p_ecd);
324 return *this;
325}
FiffDigPointSet class declaration.
constexpr int Y
constexpr int Z
constexpr int X
Old fiff_type declarations - replace them.
FIFF file I/O and data structures (raw, epochs, evoked, covariance, forward).
float swap_float(float source)
qint32 swap_int(qint32 source)
qint32 fiff_int_t
Definition fiff_types.h:89
Inverse source estimation (MNE, dSPM, sLORETA, dipole fitting).
bdipEcdRec * bdipEcd
Single equivalent current dipole with position, orientation, amplitude, and goodness-of-fit.
Definition inv_ecd.h:73
Eigen::Vector3f Q
Definition inv_ecd.h:108
Eigen::Vector3f rd
Definition inv_ecd.h:107
Binary-format dipole record for file I/O, storing fitted dipole parameters and error estimates.
float error_matrix[5][5]
qint32 size() const
InvEcdSet & operator<<(const InvEcd &p_ecd)
void addEcd(const InvEcd &p_ecd)
bool save_dipoles_dip(const QString &fileName) const
bool save_dipoles_bdip(const QString &fileName)
const InvEcd & operator[](int idx) const
static InvEcdSet read_dipoles_dip(const QString &fileName)