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