16 #include "graphwidget.h"
17 #include "xwavengraph.h"
20 #include "interface.h"
22 #include "xnodeconnector.h"
23 #include "signalgenerator.h"
25 #include "ui_dsoform.h"
27 const char *XDSO::s_trace_names[] = {
28 "Time [sec]",
"Trace1 [V]",
"Trace2 [V]",
"Trace3 [V]",
"Trace4 [V]"
30 const unsigned int XDSO::s_trace_colors[] = {
31 clRed, clGreen, clLime, clAqua
34 XDSO::XDSO(
const char *name,
bool runtime,
35 Transaction &tr_meas,
const shared_ptr<XMeasure> &meas) :
37 m_average(create<
XUIntNode>(
"Average", false)),
38 m_singleSequence(create<
XBoolNode>(
"SingleSequence", false)),
39 m_trigSource(create<
XComboNode>(
"TrigSource", false)),
40 m_trigFalling(create<
XBoolNode>(
"TrigFalling", false)),
42 m_trigLevel(create<
XDoubleNode>(
"TrigLevel", false)),
43 m_timeWidth(create<
XDoubleNode>(
"TimeWidth", false)),
44 m_vFullScale1(create<
XComboNode>(
"VFullScale1", false, true)),
45 m_vFullScale2(create<
XComboNode>(
"VFullScale2", false, true)),
46 m_vFullScale3(create<
XComboNode>(
"VFullScale3", false, true)),
47 m_vFullScale4(create<
XComboNode>(
"VFullScale4", false, true)),
52 m_recordLength(create<
XUIntNode>(
"RecordLength", false)),
59 m_fetchMode(create<
XComboNode>(
"FetchMode", false, true)),
60 m_firEnabled(create<
XBoolNode>(
"FIREnabled", false)),
61 m_firBandWidth(create<
XDoubleNode>(
"FIRBandWidth", false)),
62 m_firCenterFreq(create<
XDoubleNode>(
"FIRCenterFreq", false)),
63 m_firSharpness(create<
XDoubleNode>(
"FIRSharpness", false)),
64 m_dRFMode(create<
XComboNode>(
"RFMode", false)),
69 m_form->m_graphwidget, m_form->m_edDump, m_form->m_tlDump, m_form->m_btnDump)),
71 m_form->m_btnForceTrigger->setIcon(QApplication::style()->standardIcon(QStyle::SP_BrowserReload));
72 m_form->m_dblTrigPos->setRange(0.0, 100.0);
73 m_form->m_dblTrigPos->setSingleStep(1.0);
74 m_form->tabifyDockWidget(m_form->m_dockTrace1, m_form->m_dockTrace2);
75 m_form->tabifyDockWidget(m_form->m_dockTrace2, m_form->m_dockTrace3);
76 m_form->tabifyDockWidget(m_form->m_dockTrace3, m_form->m_dockTrace4);
77 m_form->m_dockTrace1->showNormal();
78 m_form->m_dockTrace1->raise();
79 m_form->tabifyDockWidget(m_form->m_dockTrigger, m_form->m_dockRF);
80 m_form->m_dockTrigger->showNormal();
81 m_form->m_dockTrigger->raise();
82 m_form->resize( QSize(m_form->width(), 400) );
85 xqcon_create<XQDoubleSpinBoxConnector>(m_trigPos, m_form->m_dblTrigPos, m_form->m_slTrigPos),
86 xqcon_create<XQLineEditConnector>(m_average, m_form->m_edAverage),
87 xqcon_create<XQToggleButtonConnector>(m_singleSequence, m_form->m_ckbSingleSeq),
88 xqcon_create<XQComboBoxConnector>(m_trace1, m_form->m_cmbTrace1,
Snapshot( *m_trace1)),
89 xqcon_create<XQComboBoxConnector>(m_trace2, m_form->m_cmbTrace2,
Snapshot( *m_trace2)),
90 xqcon_create<XQComboBoxConnector>(m_trace3, m_form->m_cmbTrace3,
Snapshot( *m_trace3)),
91 xqcon_create<XQComboBoxConnector>(m_trace4, m_form->m_cmbTrace4,
Snapshot( *m_trace4)),
92 xqcon_create<XQComboBoxConnector>(m_fetchMode, m_form->m_cmbFetchMode,
Snapshot( *m_fetchMode)),
93 xqcon_create<XQLineEditConnector>(m_timeWidth, m_form->m_edTimeWidth),
94 xqcon_create<XQComboBoxConnector>(m_vFullScale1, m_form->m_cmbVFS1,
Snapshot( *m_vFullScale1)),
95 xqcon_create<XQComboBoxConnector>(m_vFullScale2, m_form->m_cmbVFS2,
Snapshot( *m_vFullScale2)),
96 xqcon_create<XQComboBoxConnector>(m_vFullScale3, m_form->m_cmbVFS3,
Snapshot( *m_vFullScale3)),
97 xqcon_create<XQComboBoxConnector>(m_vFullScale4, m_form->m_cmbVFS4,
Snapshot( *m_vFullScale4)),
98 xqcon_create<XQComboBoxConnector>(m_trigSource, m_form->m_cmbTrigSource,
Snapshot( *m_trigSource)),
99 xqcon_create<XQLineEditConnector>(m_trigLevel, m_form->m_edTrigLevel),
100 xqcon_create<XQToggleButtonConnector>(m_trigFalling, m_form->m_ckbTrigFalling),
101 xqcon_create<XQLineEditConnector>(m_vOffset1, m_form->m_edVOffset1),
102 xqcon_create<XQLineEditConnector>(m_vOffset2, m_form->m_edVOffset2),
103 xqcon_create<XQLineEditConnector>(m_vOffset3, m_form->m_edVOffset3),
104 xqcon_create<XQLineEditConnector>(m_vOffset4, m_form->m_edVOffset4),
105 xqcon_create<XQButtonConnector>(m_forceTrigger, m_form->m_btnForceTrigger),
106 xqcon_create<XQLineEditConnector>(m_recordLength, m_form->m_edRecordLength),
107 xqcon_create<XQToggleButtonConnector>(m_firEnabled, m_form->m_ckbFIREnabled),
108 xqcon_create<XQLineEditConnector>(m_firBandWidth, m_form->m_edFIRBandWidth),
109 xqcon_create<XQLineEditConnector>(m_firSharpness, m_form->m_edFIRSharpness),
110 xqcon_create<XQLineEditConnector>(m_firCenterFreq, m_form->m_edFIRCenterFreq),
111 xqcon_create<XQComboBoxConnector>(m_dRFMode, m_form->m_cmbRFMode,
Snapshot( *m_dRFMode)),
112 xqcon_create<XQComboBoxConnector>(m_dRFSG, m_form->m_cmbRFSG, ref(tr_meas)),
113 xqcon_create<XQLineEditConnector>(m_dRFFreq, m_form->m_edRFFreq)
117 tr[ *singleSequence()] =
true;
118 tr[ *firBandWidth()] = 1000.0;
119 tr[ *firCenterFreq()] = .0;
120 tr[ *firSharpness()] = 4.5;
122 m_lsnOnCondChanged = tr[ *firEnabled()].onValueChanged().connectWeakly(
123 shared_from_this(), &XDSO::onCondChanged);
124 tr[ *firBandWidth()].onValueChanged().connect(m_lsnOnCondChanged);
125 tr[ *firCenterFreq()].onValueChanged().connect(m_lsnOnCondChanged);
126 tr[ *firSharpness()].onValueChanged().connect(m_lsnOnCondChanged);
127 tr[ *fetchMode()].add({
"Never",
"Averaging",
"Sequence"});
128 tr[ *fetchMode()] = FETCHMODE_SEQ;
130 tr[ *dRFMode()].add({
"OFF",
"By Given Freq.",
"By SG Freq.",
"With Coherent SG"});
132 m_lsnOnDRFCondChanged = tr[ *dRFMode()].onValueChanged().connectWeakly(
133 shared_from_this(), &XDSO::onDRFCondChanged);
134 tr[ *dRFSG()].onValueChanged().connect(m_lsnOnDRFCondChanged);
135 tr[ *dRFFreq()].onValueChanged().connect(m_lsnOnDRFCondChanged);
138 std::vector<shared_ptr<XNode>> runtime_ui{
139 average(), singleSequence(),
140 timeWidth(), trigSource(), trigPos(), trigLevel(), trigFalling(),
141 vFullScale1(), vFullScale2(), vFullScale3(), vFullScale4(),
142 vOffset1(), vOffset2(), vOffset3(), vOffset4(),
143 forceTrigger(), recordLength()
147 for(
auto &&x: runtime_ui)
152 tr[ *m_waveForm].setColCount(5, s_trace_names);
153 tr[ *m_waveForm->graph()->persistence()] = 0;
154 tr[ *m_waveForm].clearPoints();
160 m_form->showNormal();
166 return m_waves.size() / numChannels();
169 XDSO::Payload::wave(
unsigned int ch)
const {
170 return &m_waves[length() * ch];
174 return m_wavesDisp.size() / numChannelsDisp();
177 XDSO::Payload::waveDisp(
unsigned int ch) {
178 return &m_wavesDisp[lengthDisp() * ch];
181 XDSO::Payload::waveDisp(
unsigned int ch)
const {
182 return &m_wavesDisp[lengthDisp() * ch];
186 m_statusPrinter->clear();
192 const unsigned int num_channels = shot[ *
this].numChannelsDisp();
195 tr[ *m_waveForm].clearPoints();
199 const unsigned int length = shot[ *
this].lengthDisp();
201 tr[ *m_waveForm].setColCount(num_channels + 1, s_trace_names);
202 if(tr[ *m_waveForm].numPlots() != num_channels) {
203 tr[ *m_waveForm].clearPlots();
204 for(
unsigned int i = 0; i < num_channels; i++) {
205 tr[ *m_waveForm].insertPlot(s_trace_names[i + 1], 0, i + 1);
207 tr[ *tr[ *m_waveForm].axisy()->label()] = i18n(
"Traces [V]");
209 for(
unsigned int i = 0; i < num_channels; i++) {
210 tr[ *tr[ *m_waveForm].plot(i)->drawPoints()] =
false;
211 tr[ *tr[ *m_waveForm].plot(i)->lineColor()] = s_trace_colors[i];
212 tr[ *tr[ *m_waveForm].plot(i)->pointColor()] = s_trace_colors[i];
213 tr[ *tr[ *m_waveForm].plot(i)->barColor()] = s_trace_colors[i];
216 tr[ *m_waveForm].setRowCount(length);
218 double *times = tr[ *m_waveForm].cols(0);
219 double tint = shot[ *
this].timeIntervalDisp();
220 double t = -shot[ *
this].trigPosDisp() * tint;
221 for(
unsigned int i = 0; i < length; i++) {
226 for(
unsigned int i = 0; i < num_channels; i++) {
227 memcpy(tr[ *m_waveForm].cols(i + 1), shot[ *
this].waveDisp(i), length *
sizeof(
double));
229 m_waveForm->drawGraph(tr);
234 m_timeSequenceStarted = XTime::now();
239 m_timeSequenceStarted = XTime::now();
246 std::vector<shared_ptr<XNode>> runtime_ui{
248 timeWidth(), trigSource(), trigPos(), trigLevel(), trigFalling(),
249 vFullScale1(), vFullScale2(), vFullScale3(), vFullScale4(),
250 vOffset1(), vOffset2(), vOffset3(), vOffset4(),
251 forceTrigger(), recordLength(),
254 for(
auto &&x: runtime_ui)
259 m_lsnOnAverageChanged = tr[ *
average()].onValueChanged().connectWeakly(
260 shared_from_this(), &XDSO::onAverageChanged);
261 m_lsnOnSingleChanged = tr[ *
singleSequence()].onValueChanged().connectWeakly(
262 shared_from_this(), &XDSO::onSingleChanged);
263 m_lsnOnTimeWidthChanged = tr[ *timeWidth()].onValueChanged().connectWeakly(
264 shared_from_this(), &XDSO::onTimeWidthChanged);
265 m_lsnOnTrigSourceChanged = tr[ *trigSource()].onValueChanged().connectWeakly(
266 shared_from_this(), &XDSO::onTrigSourceChanged);
267 m_lsnOnTrigPosChanged = tr[ *trigPos()].onValueChanged().connectWeakly(
268 shared_from_this(), &XDSO::onTrigPosChanged);
269 m_lsnOnTrigLevelChanged = tr[ *trigLevel()].onValueChanged().connectWeakly(
270 shared_from_this(), &XDSO::onTrigLevelChanged);
271 m_lsnOnTrigFallingChanged = tr[ *trigFalling()].onValueChanged().connectWeakly(
272 shared_from_this(), &XDSO::onTrigFallingChanged);
273 m_lsnOnTrace1Changed = tr[ *trace1()].onValueChanged().connectWeakly(
274 shared_from_this(), &XDSO::onTrace1Changed);
275 m_lsnOnTrace2Changed = tr[ *trace2()].onValueChanged().connectWeakly(
276 shared_from_this(), &XDSO::onTrace2Changed);
277 m_lsnOnTrace3Changed = tr[ *trace3()].onValueChanged().connectWeakly(
278 shared_from_this(), &XDSO::onTrace3Changed);
279 m_lsnOnTrace4Changed = tr[ *trace4()].onValueChanged().connectWeakly(
280 shared_from_this(), &XDSO::onTrace4Changed);
281 m_lsnOnVFullScale1Changed = tr[ *vFullScale1()].onValueChanged().connectWeakly(
282 shared_from_this(), &XDSO::onVFullScale1Changed);
283 m_lsnOnVFullScale2Changed = tr[ *vFullScale2()].onValueChanged().connectWeakly(
284 shared_from_this(), &XDSO::onVFullScale2Changed);
285 m_lsnOnVFullScale3Changed = tr[ *vFullScale3()].onValueChanged().connectWeakly(
286 shared_from_this(), &XDSO::onVFullScale3Changed);
287 m_lsnOnVFullScale4Changed = tr[ *vFullScale4()].onValueChanged().connectWeakly(
288 shared_from_this(), &XDSO::onVFullScale4Changed);
289 m_lsnOnVOffset1Changed = tr[ *vOffset1()].onValueChanged().connectWeakly(
290 shared_from_this(), &XDSO::onVOffset1Changed);
291 m_lsnOnVOffset2Changed = tr[ *vOffset2()].onValueChanged().connectWeakly(
292 shared_from_this(), &XDSO::onVOffset2Changed);
293 m_lsnOnVOffset3Changed = tr[ *vOffset3()].onValueChanged().connectWeakly(
294 shared_from_this(), &XDSO::onVOffset3Changed);
295 m_lsnOnVOffset4Changed = tr[ *vOffset4()].onValueChanged().connectWeakly(
296 shared_from_this(), &XDSO::onVOffset4Changed);
297 m_lsnOnRecordLengthChanged = tr[ *recordLength()].onValueChanged().connectWeakly(
298 shared_from_this(), &XDSO::onRecordLengthChanged);
299 m_lsnOnForceTriggerTouched = tr[ *forceTrigger()].onTouch().connectWeakly(
300 shared_from_this(), &XDSO::onForceTriggerTouched);
301 m_lsnOnRestartTouched = tr[ *restart()].onTouch().connectWeakly(
302 shared_from_this(), &XDSO::onRestartTouched);
305 while( !terminated) {
307 const int fetch_mode = shot[ *fetchMode()];
308 if( !fetch_mode || (fetch_mode == FETCHMODE_NEVER)) {
312 std::deque<XString> channels;
314 XString chstr = shot[ *trace1()].to_str();
316 channels.push_back(chstr);
317 chstr = shot[ *trace2()].to_str();
319 channels.push_back(chstr);
320 chstr = shot[ *trace3()].to_str();
322 channels.push_back(chstr);
323 chstr = shot[ *trace4()].to_str();
325 channels.push_back(chstr);
327 if( !channels.size()) {
328 statusPrinter()->printMessage(
getLabel() +
" " + i18n(
"Select traces!."));
333 bool seq_busy =
false;
342 if(count == last_count) {
347 if(fetch_mode == FETCHMODE_SEQ) {
359 auto writer = std::make_shared<RawData>();
372 trans( *this).m_rawDisplayOnly = (shot[ *
singleSequence()] && seq_busy);
380 m_timeSequenceStarted = XTime::now();
391 trans( *this).m_rawDisplayOnly =
false;
396 for(
auto &&x: runtime_ui)
400 m_lsnOnAverageChanged.reset();
401 m_lsnOnSingleChanged.reset();
402 m_lsnOnTimeWidthChanged.reset();
403 m_lsnOnTrigSourceChanged.reset();
404 m_lsnOnTrigPosChanged.reset();
405 m_lsnOnTrigLevelChanged.reset();
406 m_lsnOnTrigFallingChanged.reset();
407 m_lsnOnVFullScale1Changed.reset();
408 m_lsnOnVFullScale2Changed.reset();
409 m_lsnOnVFullScale3Changed.reset();
410 m_lsnOnVFullScale4Changed.reset();
411 m_lsnOnTrace1Changed.reset();
412 m_lsnOnTrace2Changed.reset();
413 m_lsnOnTrace3Changed.reset();
414 m_lsnOnTrace4Changed.reset();
415 m_lsnOnVOffset1Changed.reset();
416 m_lsnOnVOffset2Changed.reset();
417 m_lsnOnVOffset3Changed.reset();
418 m_lsnOnVOffset4Changed.reset();
419 m_lsnOnForceTriggerTouched.reset();
420 m_lsnOnRestartTouched.reset();
421 m_lsnOnRecordLengthChanged.reset();
435 tr[ *
this].m_dRFRefWave.reset();
436 tr[ *restart()].touch();
442 switch (shot_of_this[ *dRFMode()]) {
445 case DRFMODE_GIVEN_FREQ:
446 freq = shot_of_this[ *dRFFreq()] * 1e6;
448 case DRFMODE_COHERENT_SG:
449 case DRFMODE_FREQ_BY_SG:
450 shared_ptr<XSG> sg = shot_of_this[ *dRFSG()];
453 freq = ***sg->freq() * 1e6;
456 const uint64_t tens = 10000000000uLL;
457 uint64_t a = llrint(freq * interval * tens);
459 count = count % tens;
460 double x = ((
long double)a * count) / tens;
461 return 2.0 * M_PI * x;
464 XDSO::Payload::setParameters(
unsigned int channels,
double startpos,
double interval,
unsigned int length) {
465 m_numChannelsDisp = channels;
466 m_wavesDisp.resize(channels * length, 0.0);
467 m_trigPosDisp = -startpos / interval;
468 m_timeIntervalDisp = interval;
473 unsigned int num_channels = shot[ *
this].numChannelsDisp();
474 unsigned int length = shot[ *
this].lengthDisp();
475 if( !shot[ *
this].m_dRFRefWave) {
476 tr[ *
this].m_dRFRefWave.reset(
new std::vector<std::complex<double> >(length));
477 auto *vec = &shot[ *
this].m_dRFRefWave->at(0);
478 double omega =
phaseOfRF(shot, 1, shot[ *
this].timeIntervalDisp());
479 double trigpos = shot[ *
this].trigPosDisp();
480 for(
int i = 0; i < length; ++i) {
481 vec[i] = std::polar(1.0, - omega * (i - trigpos));
485 auto *wave_ref = &shot[ *
this].m_dRFRefWave->at(0);
486 switch(shot[ *dRFMode()]) {
487 case DRFMODE_COHERENT_SG:
489 if( !isDRFCoherentSGSupported())
490 throw XSkippedRecordError(i18n(
"RF with coherent SG is not supported."), __FILE__, __LINE__);
491 if(num_channels % 2 == 1)
493 for(
unsigned int i = 0; i < num_channels; i += 2) {
494 double *wave_re = tr[ *
this].waveDisp(i);
495 double *wave_im = tr[ *
this].waveDisp(i + 1);
496 for(
int i = 0; i < length; ++i) {
497 auto z = wave_ref[i] * std::complex<double>(wave_re[i], wave_im[i]);
498 wave_re[i] = std::real(z);
499 wave_im[i] = std::imag(z);
506 for(
unsigned int i = 0; i < num_channels; ++i) {
507 double *wave_re = tr[ *
this].waveDisp(i);
508 for(
int i = 0; i < length; ++i) {
509 wave_re[i] = std::real(wave_ref[i] * wave_re[i]);
521 unsigned int num_channels = shot[ *
this].numChannelsDisp();
525 if(shot[ *dRFMode()] > DRFMODE_OFF) {
528 if(shot[ *firEnabled()]) {
529 double bandwidth = shot[ *
firBandWidth()] * 1000.0 * shot[ *
this].timeIntervalDisp();
530 double fir_sharpness = shot[ *firSharpness()];
531 if(fir_sharpness < 4.0)
532 m_statusPrinter->printWarning(i18n(
"Too small number of taps for FIR filter."));
533 int taps = std::min((
int)lrint(2 * fir_sharpness / bandwidth), 5000);
534 double center = shot[ *
firCenterFreq()] * 1000.0 * shot[ *
this].timeIntervalDisp();
535 if( !shot[ *
this].m_fir || (taps != shot[ *
this].m_fir->taps()) ||
536 (bandwidth != shot[ *
this].m_fir->bandWidth()) || (center != shot[ *
this].m_fir->centerFreq()))
537 tr[ *
this].m_fir.reset(
new FIR(taps, bandwidth, center));
538 unsigned int length = shot[ *
this].lengthDisp();
539 std::vector<double> buf(length);
540 for(
unsigned int i = 0; i < num_channels; i++) {
541 shot[ *
this].m_fir->exec(tr[ *
this].waveDisp(i), &buf[0], length);
542 memcpy(tr[ *
this].waveDisp(i), &buf[0], length *
sizeof(
double));
550 if(tr[ *
this].m_rawDisplayOnly) {
554 tr[ *
this].m_numChannels = tr[ *
this].m_numChannelsDisp;
555 tr[ *
this].m_waves.resize(tr[ *
this].m_wavesDisp.size());
556 tr[ *
this].m_trigPos = tr[ *
this].m_trigPosDisp;
557 tr[ *
this].m_timeInterval = tr[ *
this].m_timeIntervalDisp;
558 memcpy( &tr[ *
this].m_waves[0], &tr[ *
this].m_wavesDisp[0], tr[ *
this].m_wavesDisp.size() *
sizeof(double));