v2.0.0
Loading...
Searching...
No Matches
rt_detect_trigger.cpp
Go to the documentation of this file.
1//=============================================================================================================
12
13//=============================================================================================================
14// INCLUDES
15//=============================================================================================================
16
17#include "rt_detect_trigger.h"
18
19//=============================================================================================================
20// QT INCLUDES
21//=============================================================================================================
22
23#include <QMapIterator>
24
25//=============================================================================================================
26// USED NAMESPACES
27//=============================================================================================================
28
29using namespace Eigen;
30using namespace RTPROCESSINGLIB;
31
32//=============================================================================================================
33// DEFINE RTPROCESSINGLIB GLOBAL METHODS
34//=============================================================================================================
35
36QList<MatrixXi> RTPROCESSINGLIB::toEventMatrix(QMap<int,QList<QPair<int,double> > > mapTriggers)
37{
38 QList<MatrixXi> lMatDetectedTrigger;
39
40 QMapIterator<int,QList<QPair<int,double> > > idx(mapTriggers);
41
42 while (idx.hasNext()) {
43 idx.next();
44 MatrixXi matDetectedTrigger(idx.value().size(),3);
45
46 for(int i = 0; i < idx.value().size(); ++i) {
47 matDetectedTrigger(i,0) = idx.value().at(i).first;
48 matDetectedTrigger(i,1) = 0;
49 matDetectedTrigger(i,2) = idx.value().at(i).second;
50 }
51
52 lMatDetectedTrigger << matDetectedTrigger;
53 }
54
55 return lMatDetectedTrigger;
56}
57
58//=============================================================================================================
59
60QMap<int,QList<QPair<int,double> > > RTPROCESSINGLIB::detectTriggerFlanksMax(const MatrixXd &data,
61 const QList<int>& lTriggerChannels,
62 int iOffsetIndex,
63 double dThreshold,
64 bool bRemoveOffset,
65 int iBurstLengthSamp)
66{
67 QMap<int,QList<QPair<int,double> > > qMapDetectedTrigger;
68
69 //Find all triggers above threshold in the data block
70 for(int i = 0; i < lTriggerChannels.size(); ++i) {
71 int iChIdx = lTriggerChannels.at(i);
72
73 //Add empty list to map
74 QList<QPair<int,double> > temp;
75 qMapDetectedTrigger.insert(iChIdx, temp);
76
77 //detect the actual triggers in the current data matrix
78 if(iChIdx > data.rows() || iChIdx < 0) {
79 return qMapDetectedTrigger;
80 }
81
82 //Find positive maximum in data vector.
83 for(int j = 0; j < data.cols(); ++j) {
84 double dMatVal = bRemoveOffset ? data(iChIdx,j) - data(iChIdx,0) : data(iChIdx,j);
85
86 if(dMatVal >= dThreshold) {
87 QPair<int,double> pair;
88 pair.first = iOffsetIndex+j;
89 pair.second = data(iChIdx,j);
90
91 qMapDetectedTrigger[iChIdx].append(pair);
92
93 j += iBurstLengthSamp;
94 }
95 }
96 }
97
98 return qMapDetectedTrigger;
99}
100
101//=============================================================================================================
102
103QList<QPair<int,double> > RTPROCESSINGLIB::detectTriggerFlanksMax(const MatrixXd &data,
104 int iTriggerChannelIdx,
105 int iOffsetIndex,
106 double dThreshold,
107 bool bRemoveOffset,
108 int iBurstLengthSamp)
109{
110 QList<QPair<int,double> > lDetectedTriggers;
111
112 //Find all triggers above threshold in the data block
113 //detect the actual triggers in the current data matrix
114 if(iTriggerChannelIdx > data.rows() || iTriggerChannelIdx < 0) {
115 return lDetectedTriggers;
116 }
117
118 //Find positive maximum in data vector.
119 for(int j = 0; j < data.cols(); ++j) {
120 double dMatVal = bRemoveOffset ? data(iTriggerChannelIdx,j) - data(iTriggerChannelIdx,0) : data(iTriggerChannelIdx,j);
121
122 if(dMatVal >= dThreshold) {
123 QPair<int,double> pair;
124 pair.first = iOffsetIndex+j;
125 pair.second = data(iTriggerChannelIdx,j);
126
127 lDetectedTriggers.append(pair);
128
129 j += iBurstLengthSamp;
130 }
131 }
132
133 return lDetectedTriggers;
134}
135
136//=============================================================================================================
137
138QMap<int,QList<QPair<int,double> > > RTPROCESSINGLIB::detectTriggerFlanksGrad(const MatrixXd& data,
139 const QList<int>& lTriggerChannels,
140 int iOffsetIndex,
141 double dThreshold,
142 bool bRemoveOffset,
143 const QString& type,
144 int iBurstLengthSamp)
145{
146 QMap<int,QList<QPair<int,double> > > qMapDetectedTrigger;
147 RowVectorXd tGradient = RowVectorXd::Zero(data.cols());
148
149 //Find all triggers above threshold in the data block
150 for(int i = 0; i < lTriggerChannels.size(); ++i) {
151 int iChIdx = lTriggerChannels.at(i);
152
153 //Add empty list to map
154 QList<QPair<int,double> > temp;
155 qMapDetectedTrigger.insert(iChIdx, temp);
156
157 //detect the actual triggers in the current data matrix
158 if(iChIdx > data.rows() || iChIdx < 0) {
159 return qMapDetectedTrigger;
160 }
161
162 //Compute gradient
163 for(int t = 1; t<tGradient.cols(); t++) {
164 tGradient(t) = data(iChIdx,t)-data(iChIdx,t-1);
165 }
166
167 // If falling flanks are to be detected flip the gradient's sign
168 if(type == "Falling") {
169 tGradient = tGradient * -1;
170 }
171
172 //Find positive maximum in gradient vector. This position is equal to the rising trigger flank.
173 for(int j = 0; j < tGradient.cols(); ++j) {
174 double dMatVal = bRemoveOffset ? tGradient(j) - data(iChIdx,0) : tGradient(j);
175
176 if(dMatVal >= dThreshold) {
177 QPair<int,double> pair;
178 pair.first = iOffsetIndex+j;
179 pair.second = tGradient(j);
180
181 qMapDetectedTrigger[iChIdx].append(pair);
182
183 j += iBurstLengthSamp;
184 }
185 }
186 }
187
188 return qMapDetectedTrigger;
189}
190
191//=============================================================================================================
192
193QList<QPair<int,double> > RTPROCESSINGLIB::detectTriggerFlanksGrad(const MatrixXd &data,
194 int iTriggerChannelIdx,
195 int iOffsetIndex,
196 double dThreshold,
197 bool bRemoveOffset,
198 const QString& type,
199 int iBurstLengthSamp)
200{
201 QList<QPair<int,double> > lDetectedTriggers;
202
203 RowVectorXd tGradient = RowVectorXd::Zero(data.cols());
204
205 //detect the actual triggers in the current data matrix
206 if(iTriggerChannelIdx > data.rows() || iTriggerChannelIdx < 0) {
207 return lDetectedTriggers;
208 }
209
210 //Compute gradient
211 for(int t = 1; t < tGradient.cols(); ++t) {
212 tGradient(t) = data(iTriggerChannelIdx,t) - data(iTriggerChannelIdx,t-1);
213 }
214
215 //If falling flanks are to be detected flip the gradient's sign
216 if(type == "Falling") {
217 tGradient = tGradient * -1;
218 }
219
220 //Find all triggers above threshold in the data block
221 for(int j = 0; j < tGradient.cols(); ++j) {
222 double dMatVal = bRemoveOffset ? tGradient(j) - data(iTriggerChannelIdx,0) : tGradient(j);
223
224 if(dMatVal >= dThreshold) {
225 QPair<int,double> pair;
226 pair.first = iOffsetIndex+j;
227 pair.second = tGradient(j);
228
229 lDetectedTriggers.append(pair);
230
231 j += iBurstLengthSamp;
232 }
233 }
234
235 return lDetectedTriggers;
236}
Threshold and edge-based trigger detection on streaming stim channels.
DSPSHARED_EXPORT QMap< int, QList< QPair< int, double > > > detectTriggerFlanksGrad(const Eigen::MatrixXd &data, const QList< int > &lTriggerChannels, int iOffsetIndex, double dThreshold, bool bRemoveOffset, const QString &type, int iBurstLengthSamp=100)
DSPSHARED_EXPORT QMap< int, QList< QPair< int, double > > > detectTriggerFlanksMax(const Eigen::MatrixXd &data, const QList< int > &lTriggerChannels, int iOffsetIndex, double dThreshold, bool bRemoveOffset, int iBurstLengthSamp=100)
DSPSHARED_EXPORT QList< Eigen::MatrixXi > toEventMatrix(QMap< int, QList< QPair< int, double > > > mapTriggers)