diff --git a/GUI/drs4scopedlg.cpp b/GUI/drs4scopedlg.cpp index 107d680..dfb06c3 100644 --- a/GUI/drs4scopedlg.cpp +++ b/GUI/drs4scopedlg.cpp @@ -51,8 +51,7 @@ DRS4ScopeDlg::DRS4ScopeDlg(const ProgramStartType &startType, bool *connectionLo m_pulseSaveRangeDlg(nullptr), m_burstModeTimer(nullptr), m_autoSaveSpectraTimer(nullptr), - m_bSwapDirection(true) -{ + m_bSwapDirection(true) { ui->setupUi(this); #ifdef __DISABLE_SCRIPT @@ -240,6 +239,12 @@ DRS4ScopeDlg::DRS4ScopeDlg(const ProgramStartType &startType, bool *connectionLo connect(ui->action_StartDAQStreaming, SIGNAL(triggered()), this, SLOT(startStreaming())); connect(ui->actionStop_Running, SIGNAL(triggered()), this, SLOT(stopStreaming())); + ui->actionStart_True_False_Pulse_Streaming->setEnabled(true); + ui->actionStop_True_False_Pulse_Streaming->setEnabled(false); + + connect(ui->actionStart_True_False_Pulse_Streaming, SIGNAL(triggered()), this, SLOT(startTrueFalsePulseStreaming())); + connect(ui->actionStop_True_False_Pulse_Streaming, SIGNAL(triggered()), this, SLOT(stopTrueFalsePulseStreaming())); + connect(ui->actionInfo, SIGNAL(triggered()), this, SLOT(showAboutBox())); connect(this, SIGNAL(signalUpdateCurrentFileLabelFromScript(QString)), this, SLOT(updateCurrentFileLabelFromScript(QString)), Qt::QueuedConnection); @@ -272,6 +277,9 @@ DRS4ScopeDlg::DRS4ScopeDlg(const ProgramStartType &startType, bool *connectionLo ui->label_88->setEnabled(false); ui->label_89->setEnabled(false); ui->label_cores->setEnabled(false); + + ui->actionStart_True_False_Pulse_Streaming->setEnabled(true); + ui->actionStop_True_False_Pulse_Streaming->setEnabled(false); } ui->widget_CFDAlgorithm->init(m_worker); @@ -382,6 +390,15 @@ DRS4ScopeDlg::DRS4ScopeDlg(const ProgramStartType &startType, bool *connectionLo ui->checkBox_hyperthreading->setChecked(DRS4ProgramSettingsManager::sharedInstance()->isMulticoreThreadingEnabled()); + if (ui->checkBox_hyperthreading->isChecked()) { + ui->actionStart_True_False_Pulse_Streaming->setEnabled(false); + ui->actionStop_True_False_Pulse_Streaming->setEnabled(false); + } + else { + ui->actionStart_True_False_Pulse_Streaming->setEnabled(true); + ui->actionStop_True_False_Pulse_Streaming->setEnabled(false); + } + if (DRS4ProgramSettingsManager::sharedInstance()->isMulticoreThreadingEnabled()) { ui->actionSave_next_N_Pulses->setEnabled(false); ui->actionSave_next_N_Pulses_in_Range->setEnabled(false); @@ -607,20 +624,20 @@ DRS4ScopeDlg::DRS4ScopeDlg(const ProgramStartType &startType, bool *connectionLo ui->spinBox_stopMinB->setValue(0); ui->spinBox_stopMaxB->setValue(1000); - ui->spinBox_chnCountAB->setRange(1, 12384); - ui->spinBox_chnCountBA->setRange(1, 12384); - ui->spinBox_chnCountCoincidence->setRange(1, 12384); - ui->spinBox_chnCountMerged->setRange(1, 12384); + ui->spinBox_chnCountAB->setRange(10, 50000); + ui->spinBox_chnCountBA->setRange(10, 50000); + ui->spinBox_chnCountCoincidence->setRange(10, 50000); + ui->spinBox_chnCountMerged->setRange(10, 50000); ui->doubleSpinBox_offsetAB->setRange(-900, 900); ui->doubleSpinBox_offsetBA->setRange(-900, 900); ui->doubleSpinBox_offsetCoincidence->setRange(-900, 900); ui->doubleSpinBox_offsetMerged->setRange(-900, 900); - ui->doubleSpinBox_scalerAB->setRange(0.010, 2000); - ui->doubleSpinBox_scalerBA->setRange(0.010, 2000); - ui->doubleSpinBox_scalerCoincidence->setRange(0.010, 2000); - ui->doubleSpinBox_scalerMerged->setRange(0.010, 2000); + ui->doubleSpinBox_scalerAB->setRange(0.010, 50000); + ui->doubleSpinBox_scalerBA->setRange(0.010, 50000); + ui->doubleSpinBox_scalerCoincidence->setRange(0.010, 50000); + ui->doubleSpinBox_scalerMerged->setRange(0.010, 50000); ui->spinBox_chnCountAB->setValue(4096); ui->spinBox_chnCountBA->setValue(4096); @@ -4196,6 +4213,8 @@ void DRS4ScopeDlg::plotPersistance() m_bSwapDirection = m_bSwapDirection?false:true; } + + m_worker->setBusy(false); ui->widget_persistanceA->replot(); @@ -6374,6 +6393,10 @@ void DRS4ScopeDlg::changeMulticoreThreadingEnabled(bool on, const FunctionSource DDELETE_SAFETY(m_pulseSaveDlg); m_pulseSaveDlg = new DRS4PulseSaveDlg(m_worker); } + + if(DRS4FalseTruePulseStreamManager::sharedInstance()->isArmed()) { + DRS4FalseTruePulseStreamManager::sharedInstance()->stopAndSave(); + } } ui->actionSave_next_N_Pulses->setEnabled(!on); @@ -6381,6 +6404,10 @@ void DRS4ScopeDlg::changeMulticoreThreadingEnabled(bool on, const FunctionSource ui->tabWidget_persistanceB->setEnabled(!on); ui->tabWidget_persistanceB->setEnabled(!on); ui->checkBox_enablePersistance->setEnabled(!on); + ui->actionStart_True_False_Pulse_Streaming->setEnabled(!on); + + if (DRS4FalseTruePulseStreamManager::sharedInstance()->isArmed()) + ui->actionStop_True_False_Pulse_Streaming->setEnabled(!on); m_worker->setBusy(false); } @@ -6567,6 +6594,87 @@ void DRS4ScopeDlg::stopStreaming() MSGBOX("OK. Finished Streaming!"); } +void DRS4ScopeDlg::startTrueFalsePulseStreaming() +{ + /*const QString fileName = QFileDialog::getSaveFileName(this, tr("Stream Data to..."), + DRS4ProgramSettingsManager::sharedInstance()->streamInputFilePath(), + QString("DRS4 Data Stream (*" + EXT_PULSE_STREAM_FILE + ")"));*/ + + QFileDialog *fd = new QFileDialog(this); + fd->setWindowTitle(tr("Stream Data to..")); + fd->setAcceptMode(QFileDialog::AcceptSave); + fd->setDirectory(DRS4ProgramSettingsManager::sharedInstance()->streamInputFilePath()); + fd->setViewMode(QFileDialog::Detail); + fd->setDefaultSuffix(EXT_PULSE_STREAM_FILE); + fd->setFileMode(QFileDialog::AnyFile); + fd->setNameFilter(QString("DRS4 Data Stream (*" + EXT_PULSE_STREAM_FILE + ")")); + + fd->setOption(QFileDialog::DontUseNativeDialog, true); + + QGridLayout *layout = static_cast(fd->layout()); + + QHBoxLayout *hboxLayout = new QHBoxLayout; + + QLabel *label = new QLabel("stream for branch A (otherwise B)?"); + QCheckBox *streamCheckBox = new QCheckBox; + streamCheckBox->setChecked(true); + + hboxLayout->addWidget(label); + hboxLayout->addWidget(streamCheckBox); + + layout->addLayout(hboxLayout, layout->rowCount()-1, layout->columnCount()); + + if (!fd->exec()) + return; + + const QString fileName = !fd->selectedFiles().isEmpty()?fd->selectedFiles().first():QString(""); + const bool bStreamForA = streamCheckBox->isChecked(); + + DDELETE_SAFETY(label); + DDELETE_SAFETY(streamCheckBox); + DDELETE_SAFETY(hboxLayout); + DDELETE_SAFETY(fd); + + + if ( fileName.isEmpty() ) + return; + + DRS4ProgramSettingsManager::sharedInstance()->setStreamInputFilePath(fileName); + + m_worker->setBusy(true); + + while(!m_worker->isBlocking()) {} + + DRS4FalseTruePulseStreamManager::sharedInstance()->init(fileName, this); + + if ( DRS4FalseTruePulseStreamManager::sharedInstance()->start(bStreamForA) ) { + m_worker->setBusy(false); + + ui->actionStart_True_False_Pulse_Streaming->setEnabled(false); + ui->actionStop_True_False_Pulse_Streaming->setEnabled(true); + } + else { + m_worker->setBusy(false); + MSGBOX("Sorry, an error occurred while starting the pulse-stream!"); + } +} + +void DRS4ScopeDlg::stopTrueFalsePulseStreaming() +{ + m_worker->setBusy(true); + + while(!m_worker->isBlocking()) {} + + DRS4FalseTruePulseStreamManager::sharedInstance()->stopAndSave(); + + ui->actionStart_True_False_Pulse_Streaming->setEnabled(true); + ui->actionStop_True_False_Pulse_Streaming->setEnabled(false); + + m_worker->setBusy(false); + + MSGBOX("OK. Finished streaming!"); +} + void DRS4ScopeDlg::saveSettings() { if ( m_currentSettingsPath == NO_SETTINGS_FILE_PLACEHOLDER @@ -8330,7 +8438,7 @@ void DRS4ScopeDlg::closeEvent(QCloseEvent *event) { const QMessageBox::StandardButton reply = QMessageBox::question(this, "Quit Program?", "Exit Program?", QMessageBox::Yes|QMessageBox::No); - if ( reply != QMessageBox::Yes ) { + if (reply != QMessageBox::Yes) { event->ignore(); return; } @@ -8354,6 +8462,9 @@ void DRS4ScopeDlg::closeEvent(QCloseEvent *event) if ( DRS4StreamManager::sharedInstance()->isArmed() ) DRS4StreamManager::sharedInstance()->stopAndSave(); + if ( DRS4FalseTruePulseStreamManager::sharedInstance()->isArmed() ) + DRS4FalseTruePulseStreamManager::sharedInstance()->stopAndSave(); + if ( DRS4StreamDataLoader::sharedInstance()->isArmed() ) DRS4StreamDataLoader::sharedInstance()->stop(); @@ -8372,6 +8483,9 @@ void DRS4ScopeDlg::arrangeIcons() ui->action_StartDAQStreaming->setIcon(QIcon(":/images/images/play_click.svg")); ui->actionStop_Running->setIcon(QIcon(":/images/images/stop_hover.svg")); + ui->actionStart_True_False_Pulse_Streaming->setIcon(QIcon(":/images/images/play_click.svg")); + ui->actionStop_True_False_Pulse_Streaming->setIcon(QIcon(":/images/images/stop_hover.svg")); + ui->actionSave_next_N_Pulses->setIcon(QIcon(":/images/images/001-heart-rate-monitor.png")); ui->actionSave_next_N_Pulses_in_Range->setIcon(QIcon(":/images/images/001-heart-rate-monitor.png")); diff --git a/GUI/drs4scopedlg.h b/GUI/drs4scopedlg.h index 23b77b4..f52d39b 100644 --- a/GUI/drs4scopedlg.h +++ b/GUI/drs4scopedlg.h @@ -83,6 +83,7 @@ class DRS4ScopeDlg : public QMainWindow, public DRSCallback friend class DRS4ScriptingEngineAccessManager; friend class DRS4StreamDataLoader; friend class DRS4StreamManager; + friend class DRS4FalseTruePulseStreamManager; public: explicit DRS4ScopeDlg(const ProgramStartType& startType, bool *connectionLost, QWidget *parent = 0); virtual ~DRS4ScopeDlg(); @@ -260,6 +261,9 @@ private slots: void startStreaming(); void stopStreaming(); + void startTrueFalsePulseStreaming(); + void stopTrueFalsePulseStreaming(); + void loadSimulationToolSettings(); void loadStreamingData(); diff --git a/GUI/drs4scopedlg.ui b/GUI/drs4scopedlg.ui index 92e2e9e..7ac2f26 100644 --- a/GUI/drs4scopedlg.ui +++ b/GUI/drs4scopedlg.ui @@ -1779,7 +1779,7 @@ 0.005000000000000 - 200.000000000000000 + 2000.000000000000000 5.000000000000000 @@ -1808,10 +1808,10 @@ - 1 + 10 - 12384 + 300000 4096 @@ -2134,7 +2134,7 @@ 0.005000000000000 - 200.000000000000000 + 2000.000000000000000 5.000000000000000 @@ -2163,10 +2163,10 @@ - 1 + 10 - 12384 + 300000 4096 @@ -2489,7 +2489,7 @@ 0.005000000000000 - 200.000000000000000 + 2000.000000000000000 5.000000000000000 @@ -2518,10 +2518,10 @@ - 1 + 10 - 12384 + 300000 4096 @@ -2878,7 +2878,7 @@ 0.005000000000000 - 200.000000000000000 + 2000.000000000000000 5.000000000000000 @@ -2907,10 +2907,10 @@ - 1 + 10 - 12384 + 300000 4096 @@ -6651,6 +6651,9 @@ + + + @@ -6886,6 +6889,16 @@ Check for Updates of DDRS4PALS... + + + Start (True/False) Pulse Streaming... + + + + + Stop (True/False) Pulse Streaming... + + diff --git a/README.md b/README.md index 080a078..a4df14a 100644 --- a/README.md +++ b/README.md @@ -13,14 +13,27 @@ Copyright (c) 2016-2019 Danny Petschke (danny.petschke@uni-wuerzburg.de) All rig ### Feb. 2019 Experimentally obtained and simulated Positron Annihilation Lifetime Spectra (PALS) acquired on pure Tin (4N) using DDRS4PALS software were published in the following [Data in Brief (Elsevier)](https://www.sciencedirect.com/science/article/pii/S2352340918315142) article.

+### Jun. 2019 +[DDRS4PALS: A software for the acquisition and simulation of lifetime spectra using the DRS4 evaluation board (SoftwareX, Elsevier)](https://www.sciencedirect.com/science/article/pii/S2352711019300676)

+ +# Documentation + +### Jun. 2019 +[DDRS4PALS: A software for the acquisition and simulation of lifetime spectra using the DRS4 evaluation board (SoftwareX, Elsevier)](https://www.sciencedirect.com/science/article/pii/S2352711019300676)

+ # How to cite this Software? -You can cite all versions by using the DOI 10.5281/zenodo.1219522. This DOI represents all versions, and will always resolve to the latest one.
+You should at least cite the following publication:

+[DDRS4PALS: A software for the acquisition and simulation of lifetime spectra using the DRS4 evaluation board](https://www.sciencedirect.com/science/article/pii/S2352711019300676)
+ +Additionally, you can cite all released software versions by using the DOI 10.5281/zenodo.1219522. This DOI represents all versions, and will always resolve to the latest one.
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.1219522.svg)](https://doi.org/10.5281/zenodo.1219522) ## v1.x +DDRS4PALS v1.09 (DLTPulseGenerator v1.3):
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.2540851.svg)](https://doi.org/10.5281/zenodo.2540851)
+ DDRS4PALS v1.08 (DLTPulseGenerator v1.3):
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.2540851.svg)](https://doi.org/10.5281/zenodo.2540851)
DDRS4PALS v1.07 (DLTPulseGenerator v1.2):
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.1495099.svg)](https://doi.org/10.5281/zenodo.1495099)
diff --git a/Stream/drs4streamdataloader.cpp b/Stream/drs4streamdataloader.cpp index fcf871b..a766bf4 100644 --- a/Stream/drs4streamdataloader.cpp +++ b/Stream/drs4streamdataloader.cpp @@ -51,35 +51,27 @@ DRS4StreamDataLoader *DRS4StreamDataLoader::sharedInstance() bool DRS4StreamDataLoader::init(const QString &fileName, DRS4ScopeDlg *guiAccess, bool accessFromScript) { - //QMutexLocker locker(&m_mutex); - m_guiAccess = guiAccess; DDELETE_SAFETY(m_file); m_file = new QFile(fileName); - if ( m_file->open(QIODevice::ReadWrite) ) - { + if ( m_file->open(QIODevice::ReadWrite) ) { QFileInfo info(*m_file); m_fileSize = info.size(); // [Byte] m_loadedSize = 0; DRS4PulseStreamHeader header; - if (m_file->read((char*)&header, sz_structDRS4PulseStreamHeader) == sz_structDRS4PulseStreamHeader) - { + if (m_file->read((char*)&header, sz_structDRS4PulseStreamHeader) == sz_structDRS4PulseStreamHeader) { m_loadedSize += sz_structDRS4PulseStreamHeader; - if ( header.version <= DATA_STREAM_VERSION ) - { - if (!accessFromScript ) - { + if ( header.version <= DATA_STREAM_VERSION ) { + if (!accessFromScript ) { if ( !qFuzzyCompare(header.sampleSpeedInGHz, DRS4SettingsManager::sharedInstance()->sampleSpeedInGHz()) - || !qFuzzyCompare(header.sweepInNanoseconds, DRS4SettingsManager::sharedInstance()->sweepInNanoseconds()) ) - { + || !qFuzzyCompare(header.sweepInNanoseconds, DRS4SettingsManager::sharedInstance()->sweepInNanoseconds()) ) { const QString text = "Stream was recorded with the following Sample-Speed: \n" + QString::number(header.sampleSpeedInGHz, 'f', 2) + "GHz [" + QString::number(header.sweepInNanoseconds, 'f', 0) + "ns].\n"\ "\nSample-Speed will be adapted to this Values!"; - //locker.unlock(); const int ret = QMessageBox::warning(NULL, "Stream was recorded with different Settings!", text, QMessageBox::Ok, QMessageBox::NoButton); DUNUSED_PARAM(ret); @@ -96,8 +88,7 @@ bool DRS4StreamDataLoader::init(const QString &fileName, DRS4ScopeDlg *guiAccess return true; } - else - { + else { m_fileSize = 0; m_loadedSize = 0; diff --git a/Stream/drs4streammanager.cpp b/Stream/drs4streammanager.cpp index 50f3aa9..6a584cb 100644 --- a/Stream/drs4streammanager.cpp +++ b/Stream/drs4streammanager.cpp @@ -153,6 +153,175 @@ qint64 DRS4StreamManager::streamedContentInBytes() const } + + + + +DRS4FalseTruePulseStreamManager *__sharedInstanceDRS4FalseTruePulseStreamManager = nullptr; + +DRS4FalseTruePulseStreamManager::DRS4FalseTruePulseStreamManager() +{ + m_fileTrue = nullptr; + m_fileFalse = nullptr; + m_guiAccess = nullptr; + m_isArmed = false; + m_contentInByte = 0; + m_nameLiteral = ""; + + m_bStreamForABranch = false; +} + +DRS4FalseTruePulseStreamManager::~DRS4FalseTruePulseStreamManager() +{ + DDELETE_SAFETY(m_fileTrue); + DDELETE_SAFETY(m_fileFalse); +} + +DRS4FalseTruePulseStreamManager *DRS4FalseTruePulseStreamManager::sharedInstance() +{ + if ( !__sharedInstanceDRS4FalseTruePulseStreamManager ) + __sharedInstanceDRS4FalseTruePulseStreamManager = new DRS4FalseTruePulseStreamManager(); + + return __sharedInstanceDRS4FalseTruePulseStreamManager; +} + +void DRS4FalseTruePulseStreamManager::init(const QString &fileName, DRS4ScopeDlg *guiAccess) +{ + QMutexLocker locker(&m_mutex); + + m_guiAccess = guiAccess; + + DDELETE_SAFETY(m_fileTrue); + DDELETE_SAFETY(m_fileFalse); + + m_nameLiteral = fileName; + + const QStringList list = fileName.split("."); + + m_fileTrue = new QFile(QString(list.at(0) + "__truePulses." + list.at(1))); + m_fileFalse = new QFile(QString(list.at(0) + "__falsePulses." + list.at(1))); + + m_contentInByte = 0; + m_isArmed = false; +} + +bool DRS4FalseTruePulseStreamManager::start(bool bA) +{ + QMutexLocker locker(&m_mutex); + + m_bStreamForABranch = bA; + + if ( m_fileTrue->open(QIODevice::ReadWrite) + && m_fileFalse->open(QIODevice::ReadWrite) ) { + m_isArmed = true; + + DRS4PulseStreamHeader header; + + header.version = DATA_STREAM_VERSION; + header.sweepInNanoseconds = DRS4SettingsManager::sharedInstance()->sweepInNanoseconds(); + header.sampleSpeedInGHz = DRS4SettingsManager::sharedInstance()->sampleSpeedInGHz(); + header.sampleDepth = kNumberOfBins; + + if (m_fileTrue->write((const char*)&header, sz_structDRS4PulseStreamHeader) != sz_structDRS4PulseStreamHeader + || m_fileFalse->write((const char*)&header, sz_structDRS4PulseStreamHeader) != sz_structDRS4PulseStreamHeader) { + m_fileTrue->close(); + m_fileFalse->close(); + + m_isArmed = false; + m_contentInByte = 0; + + return false; + } + + m_contentInByte += sz_structDRS4PulseStreamHeader; + + m_guiAccess->addSampleSpeedWarningMessage(true, DRS4ScriptManager::sharedInstance()->isArmed()); + + return true; + } + else { + m_contentInByte = 0; + m_isArmed = false; + + return false; + } + + Q_UNREACHABLE(); +} + +void DRS4FalseTruePulseStreamManager::stopAndSave() +{ + QMutexLocker locker(&m_mutex); + + m_isArmed = false; + m_contentInByte = 0; + m_nameLiteral = ""; + + if ( m_fileTrue ) + m_fileTrue->close(); + + if ( m_fileFalse ) + m_fileFalse->close(); + + m_guiAccess->addSampleSpeedWarningMessage(false, DRS4ScriptManager::sharedInstance()->isArmed()); + + DDELETE_SAFETY(m_fileTrue); + DDELETE_SAFETY(m_fileFalse); +} + +bool DRS4FalseTruePulseStreamManager::writeTruePulse(const char* data, qint64 length) +{ + QMutexLocker locker(&m_mutex); + + m_contentInByte += length; + + return (m_fileTrue->write(data, length) == length); +} + +bool DRS4FalseTruePulseStreamManager::writeFalsePulse(const char* data, qint64 length) +{ + QMutexLocker locker(&m_mutex); + + m_contentInByte += length; + + return (m_fileFalse->write(data, length) == length); +} + +bool DRS4FalseTruePulseStreamManager::isArmed() const +{ + QMutexLocker locker(&m_mutex); + + return m_isArmed; +} + +bool DRS4FalseTruePulseStreamManager::isStreamingForABranch() const +{ + QMutexLocker locker(&m_mutex); + + return m_bStreamForABranch; +} + +QString DRS4FalseTruePulseStreamManager::fileName() const +{ + QMutexLocker locker(&m_mutex); + + if (m_fileFalse && m_fileTrue) + return m_nameLiteral; + else + return ""; +} + +qint64 DRS4FalseTruePulseStreamManager::streamedContentInBytes() const +{ + return m_contentInByte; +} + + + + + + + DRS4TextFileStreamManager *__sharedInstanceTextFileStreamManager = nullptr; DRS4TextFileStreamManager::DRS4TextFileStreamManager() diff --git a/Stream/drs4streammanager.h b/Stream/drs4streammanager.h index 6930485..3ff0c57 100644 --- a/Stream/drs4streammanager.h +++ b/Stream/drs4streammanager.h @@ -42,10 +42,10 @@ typedef struct { - unsigned int version; + quint32 version; double sweepInNanoseconds; double sampleSpeedInGHz; - int sampleDepth; + qint32 sampleDepth; } DRS4PulseStreamHeader; #define sz_structDRS4PulseStreamHeader sizeof(DRS4PulseStreamHeader) @@ -83,6 +83,44 @@ class DRS4StreamManager qint64 streamedContentInBytes() const; }; +class DRS4FalseTruePulseStreamManager +{ + DRS4FalseTruePulseStreamManager(); + virtual ~DRS4FalseTruePulseStreamManager(); + + QFile *m_fileTrue; + QFile *m_fileFalse; + + QString m_nameLiteral; + + bool m_isArmed; + + qint64 m_contentInByte; + + bool m_bStreamForABranch; + + DRS4ScopeDlg *m_guiAccess; + + mutable QMutex m_mutex; + +public: + static DRS4FalseTruePulseStreamManager *sharedInstance(); + + void init(const QString& fileName, DRS4ScopeDlg *guiAccess); + + bool start(bool bA); + void stopAndSave(); + + bool writeTruePulse(const char *data, qint64 length); + bool writeFalsePulse(const char *data, qint64 length); + + bool isArmed() const; + bool isStreamingForABranch() const; + + QString fileName() const; + + qint64 streamedContentInBytes() const; +}; class DRS4TextFileStreamManager : public QObject { diff --git a/drs4settingsmanager.h b/drs4settingsmanager.h index ea85bf0..aadaac5 100644 --- a/drs4settingsmanager.h +++ b/drs4settingsmanager.h @@ -39,12 +39,12 @@ #include "alglib.h" -#define __PULSESHAPEFILTER_LEFT_MAX -30.0 /* [ns] */ -#define __PULSESHAPEFILTER_RIGHT_MAX 100.0 /* [ns] */ +#define __PULSESHAPEFILTER_LEFT_MAX -200.0 //-30.0 /* [ns] */ +#define __PULSESHAPEFILTER_RIGHT_MAX 200.0 //100.0 /* [ns] */ -#define __PULSESHAPEFILTER_REGION 130.0 /* [ns] */ +#define __PULSESHAPEFILTER_REGION 400.0 //130.0 /* [ns] */ -#define __PULSESHAPEFILTER_SPLINE_TRACE_NUMBER 1424 +#define __PULSESHAPEFILTER_SPLINE_TRACE_NUMBER 4381 //1424 struct DRS4PulseShapeFilterRecordScheme { enum Scheme : int { diff --git a/drs4worker.cpp b/drs4worker.cpp index ee2cecc..df1531a 100644 --- a/drs4worker.cpp +++ b/drs4worker.cpp @@ -292,7 +292,7 @@ QVector DRS4Worker::calculateMeanTraceB() const for (DSpline spline : m_pulseShapeDataSplineB) { for (int i = 0 ; i < __PULSESHAPEFILTER_SPLINE_TRACE_NUMBER ; ++ i) { - const double t = __PULSESHAPEFILTER_LEFT_MAX + (double)i*timeIncr; + const double t = __PULSESHAPEFILTER_LEFT_MAX + ((double)i)*timeIncr; meanVec[i] += QPointF(t, spline(t)); } } @@ -2887,8 +2887,37 @@ void DRS4Worker::runSingleThreaded() } if ((int)timeStampA == -1 - || (int)timeStampB == -1) + || (int)timeStampB == -1) { + if ((int)timeStampA == -1) { + /* stream as 'false' pulse */ + if ( DRS4FalseTruePulseStreamManager::sharedInstance()->isArmed() + && DRS4FalseTruePulseStreamManager::sharedInstance()->isStreamingForABranch()) { + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeFalsePulse((const char*)tChannel0, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteFalsePulseStream time(0): size(" + QVariant(sizeOfWave).toString() + ")")); + } + + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeFalsePulse((const char*)waveChannel0S, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteFalsePulseStream volt(0): size(" + QVariant(sizeOfWave).toString() + ")")); + } + } + } + + if ((int)timeStampB == -1) { + /* stream as 'false' pulse */ + if ( DRS4FalseTruePulseStreamManager::sharedInstance()->isArmed() + && !DRS4FalseTruePulseStreamManager::sharedInstance()->isStreamingForABranch()) { + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeFalsePulse((const char*)tChannel1, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteFalsePulseStream time(1): size(" + QVariant(sizeOfWave).toString() + ")")); + } + + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeFalsePulse((const char*)waveChannel1S, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteFalsePulseStream volt(1): size(" + QVariant(sizeOfWave).toString() + ")")); + } + } + } + continue; + } /* area-Filter */ if (!bBurstMode @@ -2978,8 +3007,37 @@ void DRS4Worker::runSingleThreaded() const bool y_BInside = (multB >= yLowerB && multB <=yUpperB); - if ( !y_AInside || !y_BInside ) + if (!y_AInside) { + /* stream as 'false' pulse */ + if ( DRS4FalseTruePulseStreamManager::sharedInstance()->isArmed() + && DRS4FalseTruePulseStreamManager::sharedInstance()->isStreamingForABranch()) { + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeFalsePulse((const char*)tChannel0, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteFalsePulseStream time(0): size(" + QVariant(sizeOfWave).toString() + ")")); + } + + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeFalsePulse((const char*)waveChannel0S, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteFalsePulseStream volt(0): size(" + QVariant(sizeOfWave).toString() + ")")); + } + } + } + + if (!y_BInside) { + /* stream as 'false' pulse */ + if ( DRS4FalseTruePulseStreamManager::sharedInstance()->isArmed() + && !DRS4FalseTruePulseStreamManager::sharedInstance()->isStreamingForABranch()) { + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeFalsePulse((const char*)tChannel1, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteFalsePulseStream time(1): size(" + QVariant(sizeOfWave).toString() + ")")); + } + + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeFalsePulse((const char*)waveChannel1S, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteFalsePulseStream volt(1): size(" + QVariant(sizeOfWave).toString() + ")")); + } + } + } + + if ( !y_AInside || !y_BInside ) { continue; + } } /* apply rise time-filter and reject pulses if one of both appears outside the windows */ @@ -2996,8 +3054,37 @@ void DRS4Worker::runSingleThreaded() if (binB >= riseTimeFilterWindowLeftB && binB <= riseTimeFilterWindowRightB) bAcceptedB = true; - if (!bAcceptedA || !bAcceptedB) + if (!bAcceptedA) { + /* stream as 'false' pulse */ + if ( DRS4FalseTruePulseStreamManager::sharedInstance()->isArmed() + && DRS4FalseTruePulseStreamManager::sharedInstance()->isStreamingForABranch()) { + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeFalsePulse((const char*)tChannel0, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteFalsePulseStream time(0): size(" + QVariant(sizeOfWave).toString() + ")")); + } + + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeFalsePulse((const char*)waveChannel0S, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteFalsePulseStream volt(0): size(" + QVariant(sizeOfWave).toString() + ")")); + } + } + } + + if (!bAcceptedB) { + /* stream as 'false' pulse */ + if ( DRS4FalseTruePulseStreamManager::sharedInstance()->isArmed() + && !DRS4FalseTruePulseStreamManager::sharedInstance()->isStreamingForABranch()) { + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeFalsePulse((const char*)tChannel1, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteFalsePulseStream time(1): size(" + QVariant(sizeOfWave).toString() + ")")); + } + + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeFalsePulse((const char*)waveChannel1S, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteFalsePulseStream volt(1): size(" + QVariant(sizeOfWave).toString() + ")")); + } + } + } + + if (!bAcceptedA || !bAcceptedB) { continue; + } } /* apply pulse-shape filter */ @@ -3061,8 +3148,37 @@ void DRS4Worker::runSingleThreaded() break; } - if (bRejectA || bRejectB) + if (bRejectA) { + /* stream as 'false' pulse */ + if ( DRS4FalseTruePulseStreamManager::sharedInstance()->isArmed() + && DRS4FalseTruePulseStreamManager::sharedInstance()->isStreamingForABranch()) { + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeFalsePulse((const char*)tChannel0, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteFalsePulseStream time(0): size(" + QVariant(sizeOfWave).toString() + ")")); + } + + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeFalsePulse((const char*)waveChannel0S, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteFalsePulseStream volt(0): size(" + QVariant(sizeOfWave).toString() + ")")); + } + } + } + + if (bRejectB) { + /* stream as 'false' pulse */ + if ( DRS4FalseTruePulseStreamManager::sharedInstance()->isArmed() + && !DRS4FalseTruePulseStreamManager::sharedInstance()->isStreamingForABranch()) { + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeFalsePulse((const char*)tChannel1, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteFalsePulseStream time(1): size(" + QVariant(sizeOfWave).toString() + ")")); + } + + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeFalsePulse((const char*)waveChannel1S, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteFalsePulseStream volt(1): size(" + QVariant(sizeOfWave).toString() + ")")); + } + } + } + + if (bRejectA || bRejectB) { continue; + } } bool bValidLifetime = false; @@ -3114,6 +3230,16 @@ void DRS4Worker::runSingleThreaded() } } + /*if ( cellPHSA < kNumberOfBins && cellPHSA >= 0 ) { + m_phsA[cellPHSA] ++; + m_phsACounts ++; + } + + if ( cellPHSB < kNumberOfBins && cellPHSB >= 0 ) { + m_phsB[cellPHSB] ++; + m_phsBCounts ++; + }*/ + /* calculate normalized persistance data */ if (bPersistance && bValidLifetime2 && !bBurstMode) { m_persistanceDataA.clear(); @@ -3138,6 +3264,30 @@ void DRS4Worker::runSingleThreaded() } } + if (bValidLifetime2) { + /* stream as 'false' pulse */ + if ( DRS4FalseTruePulseStreamManager::sharedInstance()->isArmed()) { + if (DRS4FalseTruePulseStreamManager::sharedInstance()->isStreamingForABranch() ) { + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeTruePulse((const char*)tChannel0, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteTruePulseStream time(0): size(" + QVariant(sizeOfWave).toString() + ")")); + } + + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeTruePulse((const char*)waveChannel0S, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteTruePulseStream volt(0): size(" + QVariant(sizeOfWave).toString() + ")")); + } + } + else { + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeTruePulse((const char*)tChannel1, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteTruePulseStream time(1): size(" + QVariant(sizeOfWave).toString() + ")")); + } + + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeTruePulse((const char*)waveChannel1S, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteTruePulseStream volt(1): size(" + QVariant(sizeOfWave).toString() + ")")); + } + } + } + } + /* recording pulse shape data if required */ if (!bBurstMode && bValidLifetime) recordPulseShapeData(positiveSignal, timeAForYMax, timeBForYMax, yMinA, yMaxA, yMinB, yMaxB); @@ -3234,6 +3384,39 @@ void DRS4Worker::runSingleThreaded() } } + /*if ( cellPHSA < kNumberOfBins && cellPHSA >= 0 ) { + m_phsA[cellPHSA] ++; + m_phsACounts ++; + } + + if ( cellPHSB < kNumberOfBins && cellPHSB >= 0 ) { + m_phsB[cellPHSB] ++; + m_phsBCounts ++; + }*/ + + if (bValidLifetime2) { + if ( DRS4FalseTruePulseStreamManager::sharedInstance()->isArmed()) { + if (DRS4FalseTruePulseStreamManager::sharedInstance()->isStreamingForABranch() ) { + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeTruePulse((const char*)tChannel0, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteTruePulseStream time(0): size(" + QVariant(sizeOfWave).toString() + ")")); + } + + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeTruePulse((const char*)waveChannel0S, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteTruePulseStream volt(0): size(" + QVariant(sizeOfWave).toString() + ")")); + } + } + else { + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeTruePulse((const char*)tChannel1, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteTruePulseStream time(1): size(" + QVariant(sizeOfWave).toString() + ")")); + } + + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeTruePulse((const char*)waveChannel1S, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteTruePulseStream volt(1): size(" + QVariant(sizeOfWave).toString() + ")")); + } + } + } + } + /* recording pulse shape data if required */ if (!bBurstMode && bValidLifetime) recordPulseShapeData(positiveSignal, timeAForYMax, timeBForYMax, yMinA, yMaxA, yMinB, yMaxB); @@ -3286,6 +3469,29 @@ void DRS4Worker::runSingleThreaded() if (!bBurstMode && bValidLifetime) recordPulseShapeData(positiveSignal, timeAForYMax, timeBForYMax, yMinA, yMaxA, yMinB, yMaxB); } + + if (bValidLifetime2) { + if ( DRS4FalseTruePulseStreamManager::sharedInstance()->isArmed()) { + if (DRS4FalseTruePulseStreamManager::sharedInstance()->isStreamingForABranch() ) { + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeTruePulse((const char*)tChannel0, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteTruePulseStream time(0): size(" + QVariant(sizeOfWave).toString() + ")")); + } + + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeTruePulse((const char*)waveChannel0S, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteTruePulseStream volt(0): size(" + QVariant(sizeOfWave).toString() + ")")); + } + } + else { + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeTruePulse((const char*)tChannel1, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteTruePulseStream time(1): size(" + QVariant(sizeOfWave).toString() + ")")); + } + + if (!DRS4FalseTruePulseStreamManager::sharedInstance()->writeTruePulse((const char*)waveChannel1S, sizeOfWave)) { + DRS4BoardManager::sharedInstance()->log(QString(QDateTime::currentDateTime().toString() + "\twriteTruePulseStream volt(1): size(" + QVariant(sizeOfWave).toString() + ")")); + } + } + } + } } //end prompt } } diff --git a/dversion.h b/dversion.h index 6653046..a5e2e32 100644 --- a/dversion.h +++ b/dversion.h @@ -37,9 +37,9 @@ #define NAME QString("DDRS4PALS") #define MAJOR_VERSION QString("1") -#define MINOR_VERSION QString("08") +#define MINOR_VERSION QString("09") #define VERSION_EXTENSION QString("(official)") -#define DATE_EXTENSION QString("15.01.2018") +#define DATE_EXTENSION QString("09.07.2019") #define DATA_STREAM_VERSION 1