v2.0.0
Loading...
Searching...
No Matches
ieeg_reference.cpp
Go to the documentation of this file.
1//=============================================================================================================
12
13//=============================================================================================================
14// INCLUDES
15//=============================================================================================================
16
17#include "ieeg_reference.h"
18#include "ieeg_implantation.h"
19
20//=============================================================================================================
21// STL INCLUDES
22//=============================================================================================================
23
24#include <vector>
25
26//=============================================================================================================
27// USED NAMESPACES
28//=============================================================================================================
29
30using namespace IEEGLIB;
31
32//=============================================================================================================
33// DEFINE MEMBER METHODS
34//=============================================================================================================
35
36QVector<IeegBipolarPair> IeegReference::bipolarPairs(const IeegImplantation& implantation)
37{
38 const QVector<IeegContact>& contacts = implantation.contacts();
39 QVector<IeegBipolarPair> pairs;
40 auto add = [&](int anode, int cathode) {
41 const Eigen::Vector3f& a = contacts[anode].position;
42 const Eigen::Vector3f& c = contacts[cathode].position;
43 if ((a - c).norm() > kMaxNeighbourDistance)
44 return;
45 pairs.append({anode, cathode, contacts[anode].name + QLatin1Char('-') + contacts[cathode].name, (a + c) * 0.5f});
46 };
47
48 for (const IeegLead& lead : implantation.leads()) {
49 const QVector<int>& order = lead.contacts;
50 const bool grid = lead.type == IeegLeadType::Grid && qint64(lead.rows) * lead.cols == order.size() && lead.cols > 0;
51 const int cols = grid ? lead.cols : int(order.size());
52 // Along each row (the whole lead for depth leads and strips)
53 for (int k = 0; k + 1 < order.size(); ++k) {
54 if ((k + 1) % cols != 0)
55 add(order[k], order[k + 1]);
56 }
57 // Down each column of a grid
58 if (grid) {
59 for (int k = 0; k + cols < order.size(); ++k)
60 add(order[k], order[k + cols]);
61 }
62 }
63 return pairs;
64}
65
66//=============================================================================================================
67
68Eigen::SparseMatrix<double> IeegReference::bipolarMatrix(const QVector<IeegBipolarPair>& pairs, int contactCount)
69{
70 std::vector<Eigen::Triplet<double>> entries;
71 entries.reserve(size_t(pairs.size()) * 2);
72 for (int p = 0; p < pairs.size(); ++p) {
73 entries.emplace_back(p, pairs[p].anode, 1.0);
74 entries.emplace_back(p, pairs[p].cathode, -1.0);
75 }
76 Eigen::SparseMatrix<double> montage(pairs.size(), contactCount);
77 montage.setFromTriplets(entries.begin(), entries.end());
78 return montage;
79}
Bipolar re-referencing of sEEG / ECoG contacts along their leads.
sEEG / ECoG implantation: contacts grouped into depth leads, strips and grids.
Intracranial EEG (sEEG, ECoG): implantation, bipolar referencing, cortical mapping.
One lead: a depth shaft, a strip or a grid.
Contacts of an sEEG / ECoG implantation and the leads they belong to.
const QVector< IeegLead > & leads() const
const QVector< IeegContact > & contacts() const
static constexpr float kMaxNeighbourDistance
static Eigen::SparseMatrix< double > bipolarMatrix(const QVector< IeegBipolarPair > &pairs, int contactCount)
static QVector< IeegBipolarPair > bipolarPairs(const IeegImplantation &implantation)