MNE-CPP  beta 1.0
ecgsimulator.cpp
Go to the documentation of this file.
1 //=============================================================================================================
36 //*************************************************************************************************************
37 //=============================================================================================================
38 // INCLUDES
39 //=============================================================================================================
40 
41 #include "ecgsimulator.h"
42 #include "ecgproducer.h"
43 
45 
46 #include <iostream>
47 
48 
49 //*************************************************************************************************************
50 //=============================================================================================================
51 // QT INCLUDES
52 //=============================================================================================================
53 
54 #include <QtCore/QtPlugin>
55 #include <QtCore/QTextStream>
56 #include <QtCore/QFile>
57 
58 #include <QDebug>
59 
60 
61 //*************************************************************************************************************
62 //=============================================================================================================
63 // USED NAMESPACES
64 //=============================================================================================================
65 
66 using namespace ECGSimulatorPlugin;
67 using namespace XMEASLIB;
68 
69 
70 //*************************************************************************************************************
71 //=============================================================================================================
72 // DEFINE MEMBER METHODS
73 //=============================================================================================================
74 
76 : m_pRTSA_ECG_I_new(0)
77 , m_fSamplingRate(250.0)
78 , m_iDownsamplingFactor(1)
79 , m_pInBuffer_I(new dBuffer(1024))
80 , m_pInBuffer_II(new dBuffer(1024))
81 , m_pInBuffer_III(new dBuffer(1024))
82 , m_pECGProducer(new ECGProducer(this, m_pInBuffer_I, m_pInBuffer_II, m_pInBuffer_III))
83 , m_qStringResourcePath(qApp->applicationDirPath()+"/mne_x_plugins/resources/ECGSimulator/")
84 , m_pECGChannel_ECG_I(new ECGSimChannel(m_qStringResourcePath+"data/", QString("ECG_I_256_s30661.txt")))
85 , m_pECGChannel_ECG_II(new ECGSimChannel(m_qStringResourcePath+"data/", QString("ECG_II_256_s30661.txt")))
86 , m_pECGChannel_ECG_III(new ECGSimChannel(m_qStringResourcePath+"data/", QString("ECG_III_256_s30661.txt")))
87 , m_bIsRunning(false)
88 {
89 }
90 
91 
92 //*************************************************************************************************************
93 
95 {
96  //If the program is closed while the sampling is in process
97  if(this->isRunning())
98  this->stop();
99 }
100 
101 
102 //*************************************************************************************************************
103 
104 QSharedPointer<IPlugin> ECGSimulator::clone() const
105 {
106  QSharedPointer<ECGSimulator> pECGSimulatorClone(new ECGSimulator());
107  return pECGSimulatorClone;
108 }
109 
110 
111 //*************************************************************************************************************
112 //=============================================================================================================
113 // Create measurement instances and config them
114 //=============================================================================================================
115 
117 {
118  if(m_pECGChannel_ECG_I->isEnabled())
119  {
120  m_pRTSA_ECG_I_new = PluginOutputData<NewRealTimeSampleArray>::create(this, "ECG I", "ECG I output data");
121  m_outputConnectors.append(m_pRTSA_ECG_I_new);
122  }
123 
124  if(m_pECGChannel_ECG_II->isEnabled())
125  {
126  m_pRTSA_ECG_II_new = PluginOutputData<NewRealTimeSampleArray>::create(this, "ECG II", "ECG II output data");
127  m_outputConnectors.append(m_pRTSA_ECG_II_new);
128  }
129 
130  if(m_pECGChannel_ECG_III->isEnabled())
131  {
132  m_pRTSA_ECG_III_new = PluginOutputData<NewRealTimeSampleArray>::create(this, "ECG III", "ECG III output data");
133  m_outputConnectors.append(m_pRTSA_ECG_III_new);
134  }
135 }
136 
137 
138 //*************************************************************************************************************
139 
141 {
142 
143 }
144 
145 
146 //*************************************************************************************************************
147 
149 {
150  m_pECGChannel_ECG_I->initChannel();
151  m_pECGChannel_ECG_II->initChannel();
152  m_pECGChannel_ECG_III->initChannel();
153 
154  if(m_pECGChannel_ECG_I->isEnabled())
155  {
156  double diff = m_pECGChannel_ECG_I->getMaximum() - m_pECGChannel_ECG_I->getMinimum();
157 
158  m_pRTSA_ECG_I_new->data()->setName("ECG I");
159  m_pRTSA_ECG_I_new->data()->setUnit("mV");
160 
161  m_pRTSA_ECG_I_new->data()->setMinValue(m_pECGChannel_ECG_I->getMinimum()-diff/10);
162  m_pRTSA_ECG_I_new->data()->setMaxValue(m_pECGChannel_ECG_I->getMaximum()+diff/10);
163  m_pRTSA_ECG_I_new->data()->setArraySize(10);
164  m_pRTSA_ECG_I_new->data()->setSamplingRate(m_fSamplingRate/m_iDownsamplingFactor);
165  m_pRTSA_ECG_I_new->data()->setVisibility(m_pECGChannel_ECG_I->isVisible());
166  }
167 
168  if(m_pECGChannel_ECG_II->isEnabled())
169  {
170  double diff = m_pECGChannel_ECG_II->getMaximum() - m_pECGChannel_ECG_II->getMinimum();
171 
172  m_pRTSA_ECG_II_new->data()->setName("ECG II");
173  m_pRTSA_ECG_II_new->data()->setUnit("mV");
174 
175  m_pRTSA_ECG_II_new->data()->setMinValue(m_pECGChannel_ECG_II->getMinimum()-diff/10);
176  m_pRTSA_ECG_II_new->data()->setMaxValue(m_pECGChannel_ECG_II->getMaximum()+diff/10);
177  m_pRTSA_ECG_II_new->data()->setArraySize(10);
178  m_pRTSA_ECG_II_new->data()->setSamplingRate(m_fSamplingRate/m_iDownsamplingFactor);
179  m_pRTSA_ECG_II_new->data()->setVisibility(m_pECGChannel_ECG_II->isVisible());
180  }
181 
182  if(m_pECGChannel_ECG_III->isEnabled())
183  {
184  double diff = m_pECGChannel_ECG_III->getMaximum() - m_pECGChannel_ECG_III->getMinimum();
185 
186  m_pRTSA_ECG_III_new->data()->setName("ECG III");
187  m_pRTSA_ECG_III_new->data()->setUnit("mV");
188 
189  m_pRTSA_ECG_III_new->data()->setMinValue(m_pECGChannel_ECG_III->getMinimum()-diff/10);
190  m_pRTSA_ECG_III_new->data()->setMaxValue(m_pECGChannel_ECG_III->getMaximum()+diff/10);
191  m_pRTSA_ECG_III_new->data()->setArraySize(10);
192  m_pRTSA_ECG_III_new->data()->setSamplingRate(m_fSamplingRate/m_iDownsamplingFactor);
193  m_pRTSA_ECG_III_new->data()->setVisibility(m_pECGChannel_ECG_III->isVisible());
194  }
195 }
196 
197 
198 //*************************************************************************************************************
199 
201 {
202  //Check if the thread is already or still running. This can happen if the start button is pressed immediately after the stop button was pressed. In this case the stopping process is not finished yet but the start process is initiated.
203  if(this->isRunning())
204  QThread::wait();
205 
206  initChannels();
207 
208  // Start threads
209  m_pECGProducer->start();
210 
211  if(m_pECGProducer->isRunning())
212  {
213  m_bIsRunning = true;
214  QThread::start();
215  return true;
216  }
217  else
218  {
219  qWarning() << "Plugin TMSI - ERROR - TMSIProducer thread could not be started - Either the device is turned off (check your OS device manager) or the driver DLL (TMSiSDK.dll / TMSiSDK32bit.dll) is not installed in the system32 / SysWOW64 directory" << endl;
220  return false;
221  }
222 }
223 
224 
225 //*************************************************************************************************************
226 
228 {
229  // Stop threads
230  m_pECGProducer->stop();
231 
232  //Wait until this thread (TMSI) is stopped
233  m_bIsRunning = false;
234 
235 
236  //In case the semaphore blocks the thread -> Release the QSemaphore and let it exit from the pop function (acquire statement)
237  m_pInBuffer_I->releaseFromPop();
238  m_pInBuffer_I->clear();
239  m_pInBuffer_II->releaseFromPop();
240  m_pInBuffer_II->clear();
241  m_pInBuffer_III->releaseFromPop();
242  m_pInBuffer_III->clear();
243 
244 
245  //Clear Buffers
246  m_pECGChannel_ECG_I->clear();
247  m_pECGChannel_ECG_II->clear();
248  m_pECGChannel_ECG_III->clear();
249 
250  m_pInBuffer_I->clear();
251  m_pInBuffer_II->clear();
252  m_pInBuffer_III->clear();
253 
254  return true;
255 }
256 
257 
258 //*************************************************************************************************************
259 
261 {
262  return _ISensor;
263 }
264 
265 
266 //*************************************************************************************************************
267 
268 QString ECGSimulator::getName() const
269 {
270  return "ECG Simulator";
271 }
272 
273 
274 //*************************************************************************************************************
275 
277 {
278  ECGSetupWidget* widget = new ECGSetupWidget(this);//widget is later distroyed by CentralWidget - so it has to be created everytime new
279 
280  //init dialog
281  widget->initSamplingFactors();
282  widget->initSelectedChannelFile();
283  widget->initChannelStates();
284 
285  return widget;
286 }
287 
288 
289 //*************************************************************************************************************
290 
292 {
293  double dValue_I = 0;
294  double dValue_II = 0;
295  double dValue_III = 0;
296 
297  while(m_bIsRunning)
298  {
299  //pop matrix only if the producer thread is running
300  if(m_pECGProducer->isRunning())
301  {
302  if(m_pECGChannel_ECG_I->isEnabled())
303  {
304  dValue_I = m_pInBuffer_I->pop();
305  m_pRTSA_ECG_I_new->data()->setValue(dValue_I);
306  }
307  if(m_pECGChannel_ECG_II->isEnabled())
308  {
309  dValue_II = m_pInBuffer_II->pop();
310  m_pRTSA_ECG_II_new->data()->setValue(dValue_II);
311  }
312  if(m_pECGChannel_ECG_III->isEnabled())
313  {
314  dValue_III = m_pInBuffer_III->pop();
315  m_pRTSA_ECG_III_new->data()->setValue(dValue_III);
316  }
317  }
318  }
319 }
Contains the declaration of the ECGProducer class.
OutputConnectorList m_outputConnectors
Definition: IPlugin.h:222
The ECGChannel class provides a ECG channel.
Definition: ecgsimchannel.h:84
Contains the declaration of the ECGSetupWidget class.
virtual IPlugin::PluginType getType() const
Contains the declaration of the ECGSimulator class.
The ECGProducer class provides a ECG data producer for a given sampling rate.
Definition: ecgproducer.h:87
virtual QSharedPointer< IPlugin > clone() const
static QSharedPointer< PluginOutputData< T > > create(IPlugin *parent, const QString &name, const QString &descr)
virtual QString getName() const
The ECGSetupWidget class provides the ECG configuration window.