diff --git a/hit2023v2/datareceiver.cpp b/hit2023v2/datareceiver.cpp index 59ead57..578552b 100644 --- a/hit2023v2/datareceiver.cpp +++ b/hit2023v2/datareceiver.cpp @@ -4,9 +4,9 @@ DataReceiver::DataReceiver(QObject *parent) : QObject(parent), dataBuffer(RECEIVER_BUFFER_SIZE) { - connect(this, DataReceiver::sigInit, this, DataReceiver::onInit); - connect(this, DataReceiver::sigDeinit, this, DataReceiver::onDeinit); - connect(this, DataReceiver::sigConfigureEthSettings, this, DataReceiver::onConfigureEthSettings); + connect(this, &DataReceiver::sigInit, this, &DataReceiver::onInit); + connect(this, &DataReceiver::sigDeinit, this, &DataReceiver::onDeinit); + connect(this, &DataReceiver::sigConfigureEthSettings, this, &DataReceiver::onConfigureEthSettings); moveToThread(&thread); thread.start(); @@ -97,13 +97,13 @@ void DataReceiver::onInit() if (dataSocket == NULL) { dataSocket = new QUdpSocket(this); - connect(dataSocket, QUdpSocket::readyRead, this, DataReceiver::readData); + connect(dataSocket, &QUdpSocket::readyRead, this, &DataReceiver::readData); } if (timer == NULL) { timer = new QTimer(this); - connect(timer, QTimer::timeout, this, onTimer); + connect(timer, &QTimer::timeout, this, &DataReceiver::onTimer); timer->start(RECEIVER_TIMER_PERIOD_MS); } diff --git a/hit2023v2/dialogbeta.cpp b/hit2023v2/dialogbeta.cpp index 6391aa7..480503d 100644 --- a/hit2023v2/dialogbeta.cpp +++ b/hit2023v2/dialogbeta.cpp @@ -22,7 +22,7 @@ DialogBeta::DialogBeta(QWidget *parent) : DialogBeta::~DialogBeta() { timer.stop(); - disconnect(&timer, QTimer::timeout, this, &DialogBeta::onTimer); + disconnect(&timer, &QTimer::timeout, this, &DialogBeta::onTimer); delete ui; } @@ -35,9 +35,9 @@ void DialogBeta::showEvent(QShowEvent * event) ui->lineRunsDone->setText(QString("%1").arg(nrRunsDone)); //data logging possible only if global data logging is switched off if (theHW->eventBuilder.isLogging()) - ui->checkSaveRawData->setEnabled(FALSE); + ui->checkSaveRawData->setEnabled(false); - connect(&timer, QTimer::timeout, this, &DialogBeta::onTimer); + connect(&timer, &QTimer::timeout, this, &DialogBeta::onTimer); timer.start(250); } } diff --git a/hit2023v2/dialoglinearity.cpp b/hit2023v2/dialoglinearity.cpp index e6ea70d..78af262 100644 --- a/hit2023v2/dialoglinearity.cpp +++ b/hit2023v2/dialoglinearity.cpp @@ -80,14 +80,14 @@ void DialogLinearity::run() //Collect sensor data histoReady = 0; - connect(&(theHW->eventBuilder), EventBuilder::sigHistoCompleted, this, DialogLinearity::onHistogramCompleted); + connect(&(theHW->eventBuilder), &EventBuilder::sigHistoCompleted, this, &DialogLinearity::onHistogramCompleted); theHW->eventBuilder.startTakingHistos(nacqs); while (!histoReady) { QCoreApplication::processEvents(); QThread::msleep(10); } - disconnect(&(theHW->eventBuilder), EventBuilder::sigHistoCompleted, this, DialogLinearity::onHistogramCompleted); + disconnect(&(theHW->eventBuilder), &EventBuilder::sigHistoCompleted, this, &DialogLinearity::onHistogramCompleted); QVector histos = theHW->eventBuilder.getHistos(); result.mean.fill(0, nr_devices*128); diff --git a/hit2023v2/dialoglogsettings.ui b/hit2023v2/dialoglogsettings.ui index 568c05f..29a09fc 100644 --- a/hit2023v2/dialoglogsettings.ui +++ b/hit2023v2/dialoglogsettings.ui @@ -99,7 +99,7 @@ - Display + BPMDisplay diff --git a/hit2023v2/dialogprofiler.cpp b/hit2023v2/dialogprofiler.cpp index 310ccd9..93a4d3d 100644 --- a/hit2023v2/dialogprofiler.cpp +++ b/hit2023v2/dialogprofiler.cpp @@ -57,14 +57,14 @@ void DialogProfiler::run(int nr_loops) //Collect sensor data histoReady = 0; - connect(&(theHW->eventBuilder), EventBuilder::sigHistoCompleted, this, DialogProfiler::onHistogramCompleted); + connect(&(theHW->eventBuilder), &EventBuilder::sigHistoCompleted, this, &DialogProfiler::onHistogramCompleted); theHW->eventBuilder.startTakingHistos(nacqs); while (!histoReady) { QCoreApplication::processEvents(); QThread::msleep(10); } - disconnect(&(theHW->eventBuilder), EventBuilder::sigHistoCompleted, this, DialogProfiler::onHistogramCompleted); + disconnect(&(theHW->eventBuilder), &EventBuilder::sigHistoCompleted, this, &DialogProfiler::onHistogramCompleted); QVector histos = theHW->eventBuilder.getHistos(); result.mean.fill(0, nr_devices*128); diff --git a/hit2023v2/dialogtiscan.cpp b/hit2023v2/dialogtiscan.cpp index 5c0277a..81c47bd 100644 --- a/hit2023v2/dialogtiscan.cpp +++ b/hit2023v2/dialogtiscan.cpp @@ -106,14 +106,14 @@ void DialogTiScan::run() //Collect sensor data histoReady = 0; - connect(&(theHW->eventBuilder), EventBuilder::sigHistoCompleted, this, DialogTiScan::onHistogramCompleted); + connect(&(theHW->eventBuilder), &EventBuilder::sigHistoCompleted, this, &DialogTiScan::onHistogramCompleted); theHW->eventBuilder.startTakingHistos(nacqs); while (!histoReady) { QCoreApplication::processEvents(); QThread::msleep(10); } - disconnect(&(theHW->eventBuilder), EventBuilder::sigHistoCompleted, this, DialogTiScan::onHistogramCompleted); + disconnect(&(theHW->eventBuilder), &EventBuilder::sigHistoCompleted, this, &DialogTiScan::onHistogramCompleted); QVector histos = theHW->eventBuilder.getHistos(); result.mean.fill(0, nr_devices*128); diff --git a/hit2023v2/display.cpp b/hit2023v2/display.cpp index e871eac..fc38aa5 100644 --- a/hit2023v2/display.cpp +++ b/hit2023v2/display.cpp @@ -4,7 +4,7 @@ #include #include -Display::Display(QWidget *parent) : +BPMDisplay::BPMDisplay(QWidget *parent) : QDialog(parent), ui(new Ui::display) { @@ -27,12 +27,12 @@ Display::Display(QWidget *parent) : // Connect the buttonClicked signal of the button group connect(buttonGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(onButtonClicked(QAbstractButton*))); - connect(ui->pushButton_savebkg, &QPushButton::clicked, this, &Display::onSaveBackgroundClicked); - connect(ui->pushButton_loadbkg, &QPushButton::clicked, this, &Display::onLoadBackgroundClicked); - connect(ui->checkBox_subbkg, &QCheckBox::stateChanged, this, &Display::onCheckBoxStateChanged); - connect(ui->pushButton_savecalib, &QPushButton::clicked, this, &Display::onSaveCalibrationClicked); - connect(ui->pushButton_loadcalib, &QPushButton::clicked, this, &Display::onLoadCalibrationClicked); - connect(ui->checkBox_expertmode, &QCheckBox::stateChanged, this, &Display::onExpertModeStateChanged); + connect(ui->pushButton_savebkg, &QPushButton::clicked, this, &BPMDisplay::onSaveBackgroundClicked); + connect(ui->pushButton_loadbkg, &QPushButton::clicked, this, &BPMDisplay::onLoadBackgroundClicked); + connect(ui->checkBox_subbkg, &QCheckBox::stateChanged, this, &BPMDisplay::onCheckBoxStateChanged); + connect(ui->pushButton_savecalib, &QPushButton::clicked, this, &BPMDisplay::onSaveCalibrationClicked); + connect(ui->pushButton_loadcalib, &QPushButton::clicked, this, &BPMDisplay::onLoadCalibrationClicked); + connect(ui->checkBox_expertmode, &QCheckBox::stateChanged, this, &BPMDisplay::onExpertModeStateChanged); // Enable or disable the "Save Background" and "Save Calib" buttons accordingly ui->pushButton_savebkg->setEnabled(expertModeEnabled); @@ -45,12 +45,12 @@ Display::Display(QWidget *parent) : } -Display::~Display() +BPMDisplay::~BPMDisplay() { delete ui; } -void Display::showEvent(QShowEvent * event) +void BPMDisplay::showEvent(QShowEvent * event) { if (!event->spontaneous()) { @@ -62,7 +62,7 @@ void Display::showEvent(QShowEvent * event) //*********************************************** -void Display::plot(const QVector &data) +void BPMDisplay::plot(const QVector &data) { //resize data vectors and fill X values - only if needed if (data.length() != nrPoints) @@ -138,18 +138,18 @@ void Display::plot(const QVector &data) ui->plot->replot(); } -void Display::plot() +void BPMDisplay::plot() { plot(buffer); } -void Display::setTitle(QString title) +void BPMDisplay::setTitle(QString title) { ui->lineTitle->setText(title); } // Slot to handle button clicks -void Display::onButtonClicked(QAbstractButton *button) +void BPMDisplay::onButtonClicked(QAbstractButton *button) { // Handle button clicks here if (button == radioButtonFixedScale) @@ -170,7 +170,7 @@ void Display::onButtonClicked(QAbstractButton *button) } } -void Display::onSaveBackgroundClicked() +void BPMDisplay::onSaveBackgroundClicked() { // Check if there is data to save if (buffer.isEmpty()) { @@ -208,7 +208,7 @@ void Display::onSaveBackgroundClicked() } } -void Display::onLoadBackgroundClicked() +void BPMDisplay::onLoadBackgroundClicked() { // Get the plane's name (you might need to adjust how you retrieve it) QString planeName = ui->lineTitle->text(); @@ -246,13 +246,13 @@ void Display::onLoadBackgroundClicked() } } -void Display::onCheckBoxStateChanged(int state) +void BPMDisplay::onCheckBoxStateChanged(int state) { // The state argument will be Qt::Unchecked (0) or Qt::Checked (2) subtractBackground = (state == Qt::Checked); } -void Display::onSaveCalibrationClicked() +void BPMDisplay::onSaveCalibrationClicked() { // Check if there is data to save @@ -291,7 +291,7 @@ void Display::onSaveCalibrationClicked() } } -void Display::onLoadCalibrationClicked() +void BPMDisplay::onLoadCalibrationClicked() { // Get the plane's name (you might need to adjust how you retrieve it) QString planeName = ui->lineTitle->text(); @@ -361,14 +361,14 @@ void Display::onLoadCalibrationClicked() } } -void Display::onCalibrationCheckBoxChanged(int state) { +void BPMDisplay::onCalibrationCheckBoxChanged(int state) { // Check the state and update the subtractCalibration flag accordingly applyCalibration = (state == Qt::Checked); } // Slot to handle the state change of the "Expert Mode" checkbox -void Display::onExpertModeStateChanged(int state) +void BPMDisplay::onExpertModeStateChanged(int state) { // Check if the checkbox is checked (Expert Mode enabled) expertModeEnabled = (state == Qt::Checked); diff --git a/hit2023v2/display.h b/hit2023v2/display.h index 68548f8..c34f4a2 100644 --- a/hit2023v2/display.h +++ b/hit2023v2/display.h @@ -13,13 +13,13 @@ namespace Ui { class display; } -class Display : public QDialog +class BPMDisplay : public QDialog { Q_OBJECT public: - explicit Display(QWidget *parent = 0); - ~Display(); + explicit BPMDisplay(QWidget *parent = 0); + ~BPMDisplay(); void plot(const QVector &data); diff --git a/hit2023v2/display.ui b/hit2023v2/display.ui index b0e7302..4c7a43d 100644 --- a/hit2023v2/display.ui +++ b/hit2023v2/display.ui @@ -17,7 +17,7 @@ - Online Display + Online BPMDisplay diff --git a/hit2023v2/displayserver.cpp b/hit2023v2/displayserver.cpp index 7948b17..2d5f9a2 100644 --- a/hit2023v2/displayserver.cpp +++ b/hit2023v2/displayserver.cpp @@ -66,7 +66,7 @@ void DisplayServer::show() displays.clear(); for (int plane = 0; plane < planeConfig.length(); plane++) { - Display* newDisplay = new Display; + BPMDisplay* newDisplay = new BPMDisplay; newDisplay->setTitle(planeConfig[plane]->name); newDisplay->show(); displays.append(newDisplay); diff --git a/hit2023v2/displayserver.h b/hit2023v2/displayserver.h index 41091b1..68d7a98 100644 --- a/hit2023v2/displayserver.h +++ b/hit2023v2/displayserver.h @@ -38,7 +38,7 @@ protected: int active = 0; HW* theHW; QVector planeConfig; - QVector displays; + QVector displays; PlaneConfig *findPlane(int plane_nr); }; diff --git a/hit2023v2/eventbuilder.cpp b/hit2023v2/eventbuilder.cpp index 999da26..1232799 100644 --- a/hit2023v2/eventbuilder.cpp +++ b/hit2023v2/eventbuilder.cpp @@ -1,20 +1,19 @@ #include "eventbuilder.h" -#include "udpserver.h" #include "hit_analyse_v2.h" - -EventBuilder::EventBuilder(QObject *parent) : QObject(parent) +#include +EventBuilder::EventBuilder( QObject *parent) : QObject(parent) { - connect(this, EventBuilder::sigInit, this, EventBuilder::onInit); - connect(this, EventBuilder::sigDeinit, this, EventBuilder::onDeinit); - connect(this, EventBuilder::sigStartLogging, this, EventBuilder::onStartLogging); - connect(this, EventBuilder::sigStopLogging, this, EventBuilder::onStopLogging); - connect(this, EventBuilder::sigStartTakingHistos, this, EventBuilder::onStartTakingHistos); - connect(this, EventBuilder::sigStopTakingHistos, this, EventBuilder::onStopTakingHistos); - + connect(this, &EventBuilder::sigInit, this, &EventBuilder::onInit); + connect(this, &EventBuilder::sigDeinit, this, &EventBuilder::onDeinit); + connect(this, &EventBuilder::sigStartLogging, this, &EventBuilder::onStartLogging); + connect(this, &EventBuilder::sigStopLogging, this, &EventBuilder::onStopLogging); + connect(this, &EventBuilder::sigStartTakingHistos, this, &EventBuilder::onStartTakingHistos); + connect(this, &EventBuilder::sigStopTakingHistos, this, &EventBuilder::onStopTakingHistos); moveToThread(&thread); thread.start(); init(); + //get the network thread } EventBuilder::~EventBuilder() @@ -23,6 +22,8 @@ EventBuilder::~EventBuilder() thread.quit(); thread.wait(); + // networkThread.stopThread(); + // networkThread.wait(); // Wait for the network thread to finish gracefully } @@ -64,7 +65,7 @@ void EventBuilder::onNewData(DataReceiver* receiver) //1. Background subtraction. frame_counter++; - +/* while (frame_counter<10000){ for (unsigned int dev_nr = 0; dev_nr < nrReceivers; dev_nr++){ for (unsigned int ch = 0; ch < channelCounts[dev_nr]; ch++) @@ -84,7 +85,7 @@ void EventBuilder::onNewData(DataReceiver* receiver) currentFrame[dev_nr].sensor_data[ch]-=backgroundFrame[dev_nr].sensor_data[ch] ; } } - +*/ lastFrameMutex.lock(); @@ -92,7 +93,7 @@ void EventBuilder::onNewData(DataReceiver* receiver) newDataSemaphore.release(1); lastFrame = currentFrame; lastFrameMutex.unlock(); - +/* //histogram stuff if (histogramSamplesToTake) { @@ -105,16 +106,25 @@ void EventBuilder::onNewData(DataReceiver* receiver) if (histogramSamplesToTake == 0) emit sigHistoCompleted(); } - +*/ //log data if (loggingData) logDataToFile(); - //HIT_ANALYSE_V2 hit_analyse_v2;//create the object - // QString dataString = hit_analyse_v2.analyseBeamData(currentFrame); - + HIT_ANALYSE_V2 hit_analyse_v2;//create the object + QString dataString; + for (unsigned int dev_nr = 0; dev_nr < nrReceivers; dev_nr++){ + dataString += hit_analyse_v2.analyseBeamData(currentFrame); + dataString +=','; + } + QTime currentTime = QTime::currentTime(); + //Calculate the time since midnight in milliseconds + int millisecondsSinceMidnight = currentTime.msecsSinceStartOfDay(); + dataString += QString::number(millisecondsSinceMidnight); + receiveData(dataString.toUtf8()); + // std::cerr << dataString.toStdString() << std::endl; // Call sendData method of the UDP server - QString dataString = QString::number(intensity) + ',' + QString::number(position) + ',' + QString::number(focus); - QByteArray data = dataString.toUtf8(); - udpServer.sendData(data); + // QString dataString = QString::number(intensity) + ',' + QString::number(position) + ',' + QString::number(focus); + + } @@ -282,13 +292,13 @@ void EventBuilder::addSource(DataReceiver* source) nrReceivers = receivers.length(); currentFrame.resize(nrReceivers); backgroundFrame.resize(nrReceivers); - connect(source, DataReceiver::sigDataReady, this, EventBuilder::onNewData); + connect(source, &DataReceiver::sigDataReady, this, &EventBuilder::onNewData); } void EventBuilder::deleteSources() { for (int i = 0; i < receivers.length(); i++) - disconnect(receivers[i], DataReceiver::sigDataReady, this, EventBuilder::onNewData); + disconnect(receivers[i], &DataReceiver::sigDataReady, this, &EventBuilder::onNewData); receivers.clear(); nrReceivers = receivers.length(); @@ -342,3 +352,21 @@ QVector EventBuilder::getNewFrame() //and return it return getLastFrame(); } + +void EventBuilder::receiveData(const QByteArray &data) +{ + QMutexLocker locker(&mutex); + dataQueue.enqueue(data); + QString dataString = QString(data); + // std::cerr << dataString.toStdString() << std::endl; + + dataAvailable.wakeOne(); +} + +QByteArray EventBuilder::getNextData() +{ + QMutexLocker locker(&mutex); + if (dataQueue.isEmpty()) + return QByteArray(); // Return an empty QByteArray if no data is available + return dataQueue.dequeue(); +} diff --git a/hit2023v2/eventbuilder.h b/hit2023v2/eventbuilder.h index 17b378d..a5467ab 100644 --- a/hit2023v2/eventbuilder.h +++ b/hit2023v2/eventbuilder.h @@ -8,8 +8,8 @@ #include #include #include -#include "udpserver.h" // Include the UDP server header - +#include +#include //#include "hw.h" #include "datareceiver.h" #include "histogram.h" @@ -24,7 +24,7 @@ class EventBuilder : public QObject { Q_OBJECT public: - explicit EventBuilder(QObject *parent = 0); + explicit EventBuilder( QObject *parent = 0); ~EventBuilder(); void addSource(DataReceiver *source); @@ -48,9 +48,18 @@ signals: void sigStopTakingHistos(); void sigHistoCompleted(); //this is a public signal which can be used to notify user that the histo is ready - + // Define a signal to notify when postdata is updated + void dataReady(const QByteArray& data); // Define a signal for data readiness public slots: void onNewData(DataReceiver *receiver); + // Add a public slot to receive and store data + void receiveData(const QByteArray &data); + + + // Add a method to get data from the queue + QByteArray getNextData(); + + protected: int checkBufferOccupancies(); int findLowestId(); @@ -94,6 +103,9 @@ private: double intensity = 0.0; double position = 0.0; double focus = 0.0; + QQueue dataQueue; + QMutex mutex; + QWaitCondition dataAvailable; }; diff --git a/hit2023v2/hit2023v2.pro b/hit2023v2/hit2023v2.pro index d2c4a5c..1722868 100644 --- a/hit2023v2/hit2023v2.pro +++ b/hit2023v2/hit2023v2.pro @@ -5,8 +5,14 @@ #------------------------------------------------- QT += core gui network serialport -QMAKE_CXXFLAGS += -Wa,-mbig-obj +unix { + QMAKE_CXXFLAGS += -W -std=c++17 +} + +win32 { + QMAKE_CXXFLAGS += -Wa,-mbig-obj -std=c++17 +} greaterThan(QT_MAJOR_VERSION, 5): QT += widgets printsupport @@ -37,8 +43,7 @@ SOURCES += main.cpp\ dialogtiscan.cpp \ dialogprofiler.cpp \ stepper.cpp \ - dialogbeta.cpp \ - udpserver.cpp + dialogbeta.cpp HEADERS += mainwindow.h \ Q_DebugStream.h \ @@ -54,6 +59,7 @@ HEADERS += mainwindow.h \ helpers.h \ cbuffer.h \ eventbuilder.h \ + networkthread.h \ qcustomplot.h \ display.h \ displayserver.h \ @@ -65,7 +71,6 @@ HEADERS += mainwindow.h \ dialogprofiler.h \ stepper.h \ dialogbeta.h \ - udpserver.h \ hitreader.h FORMS += mainwindow.ui \ diff --git a/hit2023v2/hit_analyse_v2.cpp b/hit2023v2/hit_analyse_v2.cpp index 6a096f4..d223d82 100644 --- a/hit2023v2/hit_analyse_v2.cpp +++ b/hit2023v2/hit_analyse_v2.cpp @@ -8,11 +8,37 @@ HIT_ANALYSE_V2::HIT_ANALYSE_V2(QObject *parent) : QObject(parent) } +// Define your own functions for matrix operations +struct Matrix2x2 { + double data[2][2]; +}; + +Matrix2x2 InvertMatrix2x2(const Matrix2x2& mat) { + Matrix2x2 result; + double det = mat.data[0][0] * mat.data[1][1] - mat.data[0][1] * mat.data[1][0]; + if (det != 0.0) { + double invDet = 1.0 / det; + result.data[0][0] = mat.data[1][1] * invDet; + result.data[0][1] = -mat.data[0][1] * invDet; + result.data[1][0] = -mat.data[1][0] * invDet; + result.data[1][1] = mat.data[0][0] * invDet; + } else { + // Handle the case when the matrix is not invertible + // You might want to implement error handling here. + std::cerr << "Matrix not invertible! " << std::endl; + } + return result; +} + +struct Vector2 { + double data[2]; +}; + QString HIT_ANALYSE_V2::analyseBeamData(QVector dataframe){ double position=0.1; double focus=8; - double intensity=10000.0; + double intensity=1000.0; QString dataString; @@ -20,7 +46,8 @@ QString HIT_ANALYSE_V2::analyseBeamData(QVector dataframe){ std::vector signal_list(vector_length); std::vector channel_list(vector_length); - + std::vector short_signal_list; + std::vector short_channel_list; // Create a random number generator with a Gaussian distribution std::random_device rd; @@ -30,21 +57,29 @@ QString HIT_ANALYSE_V2::analyseBeamData(QVector dataframe){ // Create a vector to store the generated values std::vector result(vector_length); - // Fill the vector with random values - for (int i = 0; i < vector_length; ++i) { - result[i] = static_cast(dist(gen)); - signal_list.push_back(result[i]); - channel_list.push_back(i); - } + // Fill the vector with random noise values //add a gaussian profile, focus is FWHM, position is random between 50 and 250 + bool fixeddata = true; + if (!fixeddata){ position = 50 + (rand() % (int)(250 - 50 + 1)); - for (int i = 0; i < vector_length; ++i) { - signal_list[i] += intensity*exp(-4*log(2)*pow((channel_list[i]-position)/focus,2)); + + for (int i = 0; i < vector_length; i++) { + double randomValue = dist(gen); + signal_list[i] = static_cast(std::round(randomValue)); + channel_list[i] = i; + signal_list[i] += static_cast(std::round(intensity*exp(-4*log(2)*pow((channel_list[i]-position)/focus,2)))); + + // std::cerr << channel_list[i] << ", "; } + // std::cerr < dataframe){ //sigma = sqrt(1.0 / (2.0 * ABC_0)); focus = 2.3548/sqrt(2*p); intensity = b; +*/ + double SumArea = 0.0, SumY2 = 0.0, SumXY2 = 0.0, SumX2Y2 = 0.0, SumX3Y2 = 0.0; + double SumY2LnY = 0.0, SumXY2LnY = 0.0, Ymax = 0.0, Pomax = 0.0; + double fac_c = 0.0, Yn = 0.0, sigma = 0.0, amp = 0.0; + double SumYYP = 0.0, SumYYM = 0.0, MeanY = 0.0, window_start = 0.0, window_end = 0.0; + + // ... + + Matrix2x2 M1, M1inv; + Vector2 ABC, M2; + + for (int i = 0; i < vector_length; i++) { + if (signal_list[i] > Ymax) { + Ymax = signal_list[i]; + Pomax = channel_list[i]; + } + if (i > 0 && signal_list[i] > 34) { + SumArea += signal_list[i] * (channel_list[i] - channel_list[i - 1]); + } + } + + // Estimate sigma + sigma = SumArea / Ymax / 2.5066; + + // Set a +-3 sigma window + window_start = Pomax - 3 * sigma; + window_end = Pomax + 3 * sigma; + // std::cerr<< Pomax << " " << Ymax << " " << sigma << std::endl; + + + for (int i = 0; i < vector_length; i++) { + if (signal_list[i] > 34 && channel_list[i] > window_start && channel_list[i] < window_end) { + short_signal_list.push_back(signal_list[i]); + short_channel_list.push_back(channel_list[i]); + } + } + signal_list.clear(); + channel_list.clear(); + // Recalculate SumArea using the sieved data + SumArea = 0.0; + for (int i = 1; i < short_signal_list.size(); i++) { + SumArea += short_signal_list[i] * (short_channel_list[i] - short_channel_list[i - 1]); + } + + + const int shortlist_length = short_channel_list.size(); + + if (shortlist_length <= 3) { + intensity = -1; + focus = -1; + position = -128; + dataString += QString::number(intensity) + ',' + QString::number(position) + ',' + QString::number(focus) + + ',' + QString::number(0); + + + return dataString; + } + + // Re-Estimate sigma + sigma = SumArea / Ymax / 2.5066; + fac_c = -1.0 / (2.0 * sigma * sigma); + // std::cerr << sigma << std::endl; + for(int k=0; k dataframe){ } + + HIT_ANALYSE_V2::~HIT_ANALYSE_V2() { diff --git a/hit2023v2/hit_analyse_v2.h b/hit2023v2/hit_analyse_v2.h index 4aadf1a..89fb888 100644 --- a/hit2023v2/hit_analyse_v2.h +++ b/hit2023v2/hit_analyse_v2.h @@ -54,6 +54,14 @@ private: }; + const std::vector> fixed_signal = + { + {-13, -7, -12, 22, -6, 0, 22, 5, 8, 11, 25, -10, 11, 13, 32, -4, -2, -37, -21, 23, 13, 26, 11, -24, 1, -6, -6, 1, 22, 30, -21, -3, 11, -2, -11, 5, -2, 31, 24, 4, -17, 24, -24, 20, 31, -6, -1, -4, -10, -26, -12, -19, -7, -39, 1, 19, 3, -13, 37, 2, 11, -10, -14, 20, 14, -1, -13, 13, -18, -18, -15, -25, 14, 11, -32, 50, 18, -11, 26, 4, 4, -2, -10, 34, 6, 36, -9, 19, -3, 7, -10, -15, 4, 24, -3, 2, 13, -34, -28, -25, -4, -14, -11, 23, -19, -7, -6, 6, 23, 7, -21, 18, -8, 6, 21, -4, 3, -1, -11, 7, -38, -38, -12, -11, -11, 9, -11, -7, 2, -1, 19, 12, 0, -7, 15, 3, 28, -8, 1, 8, 2, -4, 4, 23, 31, -17, 8, 11, 34, 1, 7, 14, 14, 16, -1, -30, -2, 19, -20, -4, -9, 15, -6, -4, -4, 10, -27, -18, 24, 19, 20, 22, 68, 122, 234, 371, 496, 713, 840, 967, 1026, 957, 833, 674, 485, 317, 194, 98, 70, 45, 34, -15, 3, 10, 12, -19, 11, 27, -1, 2, -9, -1, -2, -15, -22, 7, 0, -20, -1, -7, 21, -4, -21, 21, -6, 23, -4, -2, -28, -17, -13, 1, 19, 20, 6, 10, -25, -4, 5, -14, -18, -4, 12, 7, -21, 7, -10, 10, 11, -21, 7, -6, -2, -3, 1, 16, 4, -23, 2, 14, 0, -5, -7, -12, -2, -8, -20, 11, 21, -5, -5, 20, -10, 3, -18, -5, 4, 6, 4, -21, -3, -26, -15, -7, -14, -10, -14, 7, -18, -2, -14, 36, -10, 11, 9, 3, -7, -51, -12, 2, 5, 9, 15, 20, -23, -6, -14, -4, 16, 4} + ,{-9, -1, -32, 19, 12, -13, 7, 7, -18, -5, 19, 15, 5, -5, -27, 4, -7, 7, -16, -9, -4, -6, -2, 27, 23, 15, -16, -23, 25, 4, 26, -17, -9, -1, 14, -9, -15, -29, -40, 5, 22, 14, 23, -25, 9, -16, -26, -4, -31, -6, -27, 1, 23, 24, 26, 61, 133, 222, 301, 501, 690, 822, 972, 980, 966, 852, 685, 486, 333, 239, 107, 54, 29, 19, 9, 1, 1, 6, 9, 14, -8, -5, 11, 21, -6, -17, -7, 11, 30, -3, 6, -4, 2, 18, -18, 4, -2, 18, 16, 17, 5, -15, -14, 24, -36, -19, 7, -22, -3, -15, -11, -4, -11, 13, -5, -6, 12, 8, 21, -24, -10, -10, -7, 5, 30, -16, -18, -3, -23, 3, -20, -3, 24, 8, -15, -1, -6, -1, -8, -25, 6, 1, -16, -11, 29, -21, 13, 11, -2, -10, 12, -13, 24, -31, 21, -7, 6, -13, 3, -6, -9, 20, -3, 2, -16, -14, 10, 6, 20, 6, 21, 9, 7, -27, 13, -17, 19, 20, -13, -11, -17, -4, 11, -24, 17, -7, -4, 26, 5, 13, 13, 4, -3, -17, -32, -14, 40, 1, -23, -28, 16, 1, 16, -4, -8, -9, 4, 2, -7, 7, -16, -23, -9, 10, 24, 0, -5, -24, -4, -22, -10, -29, 0, 2, 2, 4, -45, 4, -2, 12, 21, -22, -31, -15, 16, 2, 11, 35, 0, 3, 15, -15, -17, 20, -27, 24, 24, -6, 8, -15, 8, 26, -6, -14, 10, -20, 33, 6, -5, 1, 0, 9, 3, -33, -10, -3, 0, 11, -33, 0, 33, 25, -5, 1, 0, -32, -24, 17, 10, -2, 12, -26, 13, 7, -3, 36, 28, 10, 17, -26, 29, -15, 3, 14, -8, -9, -7, -15, -4, 0} + ,{14, -3, 2, 20, 3, -9, 15, -3, 26, 3, 8, -1, -5, 13, -10, -18, -9, 35, 3, 29, -12, 37, 12, -12, -9, -34, 9, -3, -19, -3, -10, -9, 3, -1, 5, 22, 10, -10, -27, 30, -19, -26, -23, -25, 16, 4, 4, 9, -23, 5, 0, -35, -5, -21, 0, 22, 18, -42, -4, 16, 17, 41, -15, -12, 13, -5, 35, 5, -4, 19, -12, 4, 4, -2, 2, -12, -23, 5, -2, 4, 7, 5, -10, 41, -20, -2, 4, 5, -34, -19, -6, 6, -3, -12, 39, 38, 72, 104, 194, 347, 484, 666, 808, 946, 1018, 978, 838, 690, 511, 317, 211, 112, 51, 22, 0, -14, 21, -2, 12, -24, 1, -6, 18, 5, -12, 6, -3, -9, -6, -29, -31, -6, -15, -2, -22, 14, -33, 1, 3, -7, -13, 14, 21, -11, -17, -1, -9, -12, 7, 5, -2, -2, -4, -2, -12, -33, 2, 5, -2, -8, 10, 26, 2, -28, 3, -20, 10, -8, 22, 8, -25, 3, -18, -18, 19, 15, -8, 8, 24, -13, 0, -5, -15, 1, -24, -2, 3, -28, 8, 5, -5, 0, 12, 10, -5, 12, 0, -10, -5, -7, -23, -32, -3, 9, 17, -14, -12, -3, -35, -12, -5, 8, 15, -10, 13, 4, 9, 23, -21, -31, 32, 6, -3, -7, 10, -5, 25, -32, 16, -22, 18, 0, 1, -16, -13, -10, -13, 2, -20, -2, 15, 7, 17, -17, 0, 8, 43, -23, -34, -7, 45, 8, 16, 26, -7, -7, -5, 4, -20, -8, -21, 13, 4, -23, 9, 29, 1, 13, -3, -23, 3, 20, 23, 29, -7, -8, 37, -4, -23, 1, -14, -11, 9, -4, -13, -20, -20, 16, -12, 23, 31, 5, 0, 27, 2, 5, 30, -12, -10, 3} + ,{-9, -15, -6, 24, -10, -12, 12, -9, -13, 1, -15, -2, -2, 0, 26, -19, -22, 7, 0, 26, 28, -13, -8, -24, 20, -1, -18, -1, -23, -21, -7, -10, 25, 29, 16, 23, -36, 9, 7, -28, -7, 1, 41, -1, -2, 14, -3, 26, -26, 20, -4, 22, 8, 50, 8, 0, -22, -8, 45, 1, -22, -24, -12, 6, 8, 26, 21, 22, -5, 1, -1, -10, -4, 22, 20, 40, -9, 11, -32, 9, -12, -3, -8, 13, 3, -4, -6, 2, 18, 6, 1, -16, 0, 33, 16, -18, -7, 27, 10, -3, 11, -10, -16, -3, 24, 1, -14, -4, 12, -11, -4, 22, 22, -21, -4, 24, 3, 12, 13, 28, -3, 27, 11, -6, 19, 8, -22, -1, 5, 0, 27, 2, -2, -12, -8, 6, 6, 9, 10, -8, 4, 40, 27, 38, 111, 200, 323, 492, 667, 834, 944, 990, 945, 861, 683, 466, 337, 205, 108, 53, 22, 0, 27, 9, -3, 37, 11, -8, -15, -16, 4, 23, 25, -14, -7, -7, -18, -7, 21, 6, 19, -12, 2, -13, -9, -8, -3, -7, -20, -27, 13, 4, -11, 16, 3, -24, 4, -23, 17, 17, -18, -25, 4, 5, -21, -10, -13, 43, 4, -1, -3, -1, -4, -4, 25, 47, 18, 21, 29, 4, -22, 16, -17, -37, -1, 12, -9, -7, 5, -4, 23, 21, -14, -17, 19, 11, 22, 39, -6, 3, 19, -25, 4, 1, -15, -8, 20, 13, -31, 5, 28, 10, 27, 9, -11, 2, 0, -20, -18, -9, 14, 9, 24, -16, -10, 29, 16, 13, 13, -22, 16, 18, 22, 20, 27, -20, 23, 6, 0, 14, -6, -6, -8, 15, -11, 23, -11, 23, -16, 16, -2, 10, 4, -22, -33, -17, -4, 4, 4, -8} + }; + const std::vector fixed_channel = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299}; public slots: QString analyseBeamData(QVector dataframe); diff --git a/hit2023v2/hw.cpp b/hit2023v2/hw.cpp index 2ed6bb0..944f31c 100644 --- a/hit2023v2/hw.cpp +++ b/hit2023v2/hw.cpp @@ -1,16 +1,21 @@ #include "hw.h" - -HW::HW(QObject *parent) : QObject(parent) +HW::HW(QObject *parent) : QObject(parent), eventBuilder(), networkThread(eventBuilder) { /*eventBuilder.moveToThread(&eventBuilderThread); eventBuilderThread.start(); eventBuilder.init();*/ + // Create and start the network thread + networkThread.start(); } HW::~HW() { + if (networkThread.isRunning()){ + networkThread.stopThread(); + networkThread.wait(); // Wait for the network thread to finish gracefully + } eventBuilder.stopLogging(); removeDevices(); @@ -64,7 +69,7 @@ void HW::disconnectDevices() void HW::run() { //No need to start EVB. It's running all the time. - + // Start the UDP server when an instance of HW is created //run slave(s) for (int i = 0; i < devices.length(); i++) if (devices[i]->deviceConfig.master == 0) @@ -78,6 +83,11 @@ void HW::run() void HW::stop() { + // Application cleanup + if (networkThread.isRunning()){ + networkThread.stopThread(); + networkThread.wait(); // Wait for the network thread to finish gracefully + } //stop master(s) for (int i = 0; i < devices.length(); i++) if (devices[i]->deviceConfig.master != 0) diff --git a/hit2023v2/hw.h b/hit2023v2/hw.h index 3d5f1e8..9454a8e 100644 --- a/hit2023v2/hw.h +++ b/hit2023v2/hw.h @@ -6,17 +6,19 @@ #include #include "device.h" #include "eventbuilder.h" - +#include "networkthread.h" class HW : public QObject { Q_OBJECT +public: + public: explicit HW(QObject *parent = 0); ~HW(); QVector devices; EventBuilder eventBuilder; - + NetworkThread networkThread; Device &operator [](int nr); void addDevices(int nr_devices); @@ -33,9 +35,12 @@ signals: public slots: - protected: +private: + + + }; #endif // HW_H diff --git a/hit2023v2/keithley_thr.cpp b/hit2023v2/keithley_thr.cpp index 306c19b..c2931df 100644 --- a/hit2023v2/keithley_thr.cpp +++ b/hit2023v2/keithley_thr.cpp @@ -64,11 +64,11 @@ keithley_thr::keithley_thr() keithleyWorker *worker = new keithleyWorker; //worker->theKeithley = &theKeithley; - worker->moveToThread(&workerThread); - worker->timer.moveToThread(&workerThread); - worker->theKeithley.serialPort.moveToThread(&workerThread); + worker->moveToThread(&udpThread); + worker->timer.moveToThread(&udpThread); + worker->theKeithley.serialPort.moveToThread(&udpThread); //controller -> worker - QObject::connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); + QObject::connect(&udpThread, &QThread::finished, worker, &QObject::deleteLater); QObject::connect(this, &keithley_thr::sig_connect, worker, &keithleyWorker::connect); QObject::connect(this, &keithley_thr::sig_disconnect, worker, &keithleyWorker::disconnect); QObject::connect(this, &keithley_thr::sig_on, worker, &keithleyWorker::on); @@ -78,13 +78,13 @@ keithley_thr::keithley_thr() //worker -> controller QObject::connect(worker, &keithleyWorker::sig_currentReadout, this, &keithley_thr::on_currentReadout); QObject::connect(worker, &keithleyWorker::sig_isOpen, this, &keithley_thr::on_isOpen); - workerThread.start(); + udpThread.start(); } keithley_thr::~keithley_thr() { - workerThread.quit(); - workerThread.wait(); + udpThread.quit(); + udpThread.wait(); } @@ -92,7 +92,7 @@ keithley_thr::~keithley_thr() //************************** slots for communication with worker thread ****************** //called on each current readout -keithley_thr::on_currentReadout(const double value) +void keithley_thr::on_currentReadout(const double value) { lastCurrentReadout = value; emit esig_newCurrentReadout(lastCurrentReadout); diff --git a/hit2023v2/keithley_thr.h b/hit2023v2/keithley_thr.h index 2cac354..fe30173 100644 --- a/hit2023v2/keithley_thr.h +++ b/hit2023v2/keithley_thr.h @@ -58,14 +58,14 @@ public: double getCurrent(); void ps_flush(); - QThread workerThread; + QThread udpThread; double lastCurrentReadout; QString portName; int recognizeSpillState(double current); public slots: - on_currentReadout(const double value); + void on_currentReadout(const double value); int on_isOpen(const int state, const QString givenPortName); signals: void sig_connect(); diff --git a/hit2023v2/main.cpp b/hit2023v2/main.cpp index 9db49a4..66c046b 100644 --- a/hit2023v2/main.cpp +++ b/hit2023v2/main.cpp @@ -1,16 +1,10 @@ #include "mainwindow.h" #include -#include "udpserver.h" // Include udpserver header - -// Define the global UdpServer object -UdpServer udpServer; // This allocates memory for udpServer int main(int argc, char *argv[]) { QApplication a(argc, argv); - // Create the UdpServer object on the heap and store a pointer to it - udpServer.startServer(); // Apply the stylesheet to each display qDebug() << "App path : " << qApp->applicationDirPath(); diff --git a/hit2023v2/mainwindow.cpp b/hit2023v2/mainwindow.cpp index a5a34c1..9e07b1e 100644 --- a/hit2023v2/mainwindow.cpp +++ b/hit2023v2/mainwindow.cpp @@ -29,8 +29,13 @@ MainWindow::MainWindow(QWidget *parent) : theKeithley = new keithley_thr; theStepper = new Stepper; - connect(&timer, QTimer::timeout, this, on_timer); - connect(theKeithley, keithley_thr::esig_newCurrentReadout, this, MainWindow::on_newCurrentReadout); +// connect(&timer, QTimer::timeout, this, on_timer); + connect(&timer, &QTimer::timeout, this, &MainWindow::on_timer); + + // connect(theKeithley, keithley_thr::esig_newCurrentReadout, this, MainWindow::on_newCurrentReadout); + connect(theKeithley, &keithley_thr::esig_newCurrentReadout, this, &MainWindow::on_newCurrentReadout); + + } @@ -41,6 +46,7 @@ MainWindow::~MainWindow() delete theHW; delete theDisplay; delete theKeithley; + } //***************** Initialization ****************** @@ -479,3 +485,14 @@ void MainWindow::on_actionDisconnect_Stepper_triggered() qInfo("Stepper controller disconnected."); } + +void MainWindow::on_pushButton_exit_clicked() +{ + if(running) stop(); + theHW->stop(); + + theHW->disconnectDevices(); + + QApplication::exit(); //close the application; +} + diff --git a/hit2023v2/mainwindow.h b/hit2023v2/mainwindow.h index a3902d9..b78cb06 100644 --- a/hit2023v2/mainwindow.h +++ b/hit2023v2/mainwindow.h @@ -63,30 +63,19 @@ private slots: void on_actionDisconnect_triggered(); void on_actionHost_IP_triggered(); void on_actionTrigger_config_triggered(); - void on_actionDevices_triggered(); - void on_pushRun_pressed(); - void on_pushLogging_pressed(); - void on_pushDisplay_pressed(); - void on_actionConnect_Keithley_triggered(); - void on_actionDisconnect_Keithley_triggered(); - void on_actionLinearity_test_triggered(); - void on_actionIntegration_time_scan_triggered(); - void on_actionProfile_viewer_triggered(); - void on_actionConnect_Stepper_triggered(); - void on_actionDisconnect_Stepper_triggered(); - void on_actionBeta_Scanner_triggered(); + void on_pushButton_exit_clicked(); private: Ui::MainWindow *ui; diff --git a/hit2023v2/mainwindow.ui b/hit2023v2/mainwindow.ui index 3d36b83..4c20f10 100644 --- a/hit2023v2/mainwindow.ui +++ b/hit2023v2/mainwindow.ui @@ -80,6 +80,19 @@ + + + + 760 + 510 + 80 + 24 + + + + Quit + + diff --git a/hit2023v2/networkthread.h b/hit2023v2/networkthread.h new file mode 100644 index 0000000..e5e5dfa --- /dev/null +++ b/hit2023v2/networkthread.h @@ -0,0 +1,198 @@ +#ifndef NETWORKTHREAD_H +#define NETWORKTHREAD_H + + +#include +#include +#include "iostream" +#include +#include +#include +#include +#include +#include "eventbuilder.h" + +class NetworkThread : public QThread +{ + Q_OBJECT +private: + quint16 serverPort = 1901; // Port number for the UDP server + double intensity = 0.0, position = 0.0, focus = 0.0; + + QMutex mutex; // Mutex for data synchronization + QWaitCondition dataReady; // Condition variable to signal data readiness + +EventBuilder &eventBuilder; + +public: + NetworkThread(EventBuilder &builder, QObject *parent = nullptr) : QThread(parent), eventBuilder(builder), stopped(false) {} + + void run() override + { + QUdpSocket udpSocket; + //udpSocket.bind(QHostAddress::Any, 12345); // Set your desired port + // Bind the socket to a specific IP address and port + if ( udpSocket.bind(QHostAddress("127.0.0.1"), serverPort) ) + { + // connect(udpSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams())); + qInfo() << "UDP server started on port" << serverPort; + } + else + { + stopped = true; + qWarning() << "Failed to bind UDP socket on port" << serverPort; + } + + while (!stopped) + { + // Your data serialization and broadcasting logic here + + + QByteArray data = eventBuilder.getNextData(); // Get data from the EventBuilder + if (!data.isEmpty()) + { + QString dataString = QString(data); + udpSocket.writeDatagram(data.data(), data.size(), QHostAddress::Broadcast, serverPort); + // std::cerr << dataString.toStdString() << std::endl; + } + else + { + // std::cerr << "data is empty" << std::endl; + + } + // QByteArray data = serializeYourData(); + + + // QTime currentTime = QTime::currentTime(); + // Calculate the time since midnight in milliseconds + // int millisecondsSinceMidnight = currentTime.msecsSinceStartOfDay(); + + // QByteArray data; // Create a QByteArray for your data + // Populate data with your custom data + // data.append(QByteArray::number(millisecondsSinceMidnight)); + + // udpSocket.writeDatagram(data.data(),data.size(), QHostAddress::Broadcast, serverPort); // Broadcast to all reachable devices + // emit dataReady(data); // Emit the signal when data is ready + // std::cerr << " running" << std::endl; +// QThread::msleep(1); // Sleep for microseconds usleep / millisecond msleep //!!!!! on windows the minimum is about 15ms from OS reasons. ~ 30 microseconds between loops without thread sleep. + + } + } + + void stopThread() + { + stopped = true; + emit terminationRequested(); + } + // Add this public slot to receive data from the main thread +public slots: + +signals: + void terminationRequested(); + +private: + bool stopped; + + QByteArray serializeYourData() + { + // Implement your data serialization here + } +}; + +/* +#include +#include +#include +#include +#include + +class NetworkThread : public QThread +{ + Q_OBJECT + +private: + quint16 serverPort = 1901; // Port number for the UDP server + double intensity = 0.0, position = 0.0, focus = 0.0; + + QMutex mutex; // Mutex for data synchronization + QWaitCondition dataReady; // Condition variable to signal data readiness + +public: + NetworkThread(QObject *parent = nullptr) : QThread(parent), stopped(false) {} + + void run() override + { + QUdpSocket udpSocket; + + if (udpSocket.bind(QHostAddress("10.0.7.1"), serverPort)) + { + qInfo() << "UDP server started on port" << serverPort; + } + else + { + stopped = true; + qWarning() << "Failed to bind UDP socket on port" << serverPort; + } + + while (!stopped) + { + // Wait for data to be ready + mutex.lock(); + dataReady.wait(&mutex); + // Data is now ready, unlock the mutex + + QTime currentTime = QTime::currentTime(); + int millisecondsSinceMidnight = currentTime.msecsSinceStartOfDay(); + + QByteArray data; + data.append(QByteArray::number(millisecondsSinceMidnight)); + + // Append the updated parameters to the data + data.append(","); + data.append(QByteArray::number(intensity)); + data.append(","); + data.append(QByteArray::number(position)); + data.append(","); + data.append(QByteArray::number(focus)); + + udpSocket.writeDatagram(data.data(), data.size(), QHostAddress::Broadcast, serverPort); + mutex.unlock(); + } + } + + void stopThread() + { + stopped = true; + emit terminationRequested(); + } + +public slots: + // This slot is called from another thread to update the parameters + void updateParameters(double newIntensity, double newPosition, double newFocus) + { + // Lock the mutex before updating the parameters + mutex.lock(); + + // Update the parameters + intensity = newIntensity; + position = newPosition; + focus = newFocus; + + // Signal that data is ready to be sent + dataReady.wakeAll(); + + // Unlock the mutex + mutex.unlock(); + } + +signals: + void terminationRequested(); + +private: + bool stopped; +}; + + +*/ + +#endif // NETWORKTHREAD_H diff --git a/hit2023v2/release/hit2023v2.exe b/hit2023v2/release/hit2023v2.exe index 68d2eed..568b126 100644 Binary files a/hit2023v2/release/hit2023v2.exe and b/hit2023v2/release/hit2023v2.exe differ diff --git a/hit2023v2/udpserver.cpp b/hit2023v2/udpserver.cpp deleted file mode 100644 index bea789d..0000000 --- a/hit2023v2/udpserver.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "udpserver.h" - -UdpServer::UdpServer(QObject *parent) : QObject(parent) -{ - - // Configure the timer for data updates - // connect(&timer, &QTimer::timeout, this, &UdpServer::sendData); - // timer.setInterval(1); // 1 milliseconds (1 kHz) - startServer(); -} - -void UdpServer::startServer() -{ - // Bind the UDP socket to a specific port (replace with your desired port) -// udpSocket.bind(QHostAddress::Any, 12345); // Replace 12345 with your desired port - udpSocket.bind(QHostAddress("10.0.7.1"), 12345); // Use the desired host address and port -// udpSocket.bind(QHostAddress::LocalHost, 12345); // Use "localhost" (127.0.0.1) and port 12345 - // Start the timer for data updates - // timer.start(); -} - -void UdpServer::stopServer() -{ - // Stop the timer and close the UDP socket - // timer.stop(); - udpSocket.close(); -} - - -void UdpServer::sendData(QByteArray data) -{ - // Prepare the data to be sent - // QString dataString = QString::number(intensity) + ',' + QString::number(position) + ',' + QString::number(focus); - // QByteArray data = dataString.toUtf8(); - // Send the data to all connected clients (broadcast to all on the same network) - udpSocket.writeDatagram(data, QHostAddress::Broadcast, 12345); // Replace 12345 with your desired port -} diff --git a/hit2023v2/udpserver.h b/hit2023v2/udpserver.h deleted file mode 100644 index 16e05c0..0000000 --- a/hit2023v2/udpserver.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef UDPSERVER_H -#define UDPSERVER_H - -#include -#include -#include // Add this line to include QTimer - - - -class UdpServer : public QObject -{ - Q_OBJECT - -public: - explicit UdpServer(QObject *parent = nullptr); - -public slots: - void startServer(); - void stopServer(); - void sendData(QByteArray data); // New slot to send data with custom values - -private: - QUdpSocket udpSocket; - QTimer timer; - -}; - -// Declare the global UdpServer object as an external variable -extern UdpServer udpServer; - -#endif // UDPSERVER_H diff --git a/hit2023v2_client/udpclient.cpp b/hit2023v2_client/udpclient.cpp index f7e8623..ca37cae 100644 --- a/hit2023v2_client/udpclient.cpp +++ b/hit2023v2_client/udpclient.cpp @@ -1,20 +1,25 @@ // udpclient.cpp #include "udpclient.h" +#include + +quint16 serverPort = 1901; // Port number for the UDP server UdpClient::UdpClient(QObject *parent) : QObject(parent) { + // Create a QHostAddress for the server's IP address - QHostAddress serverAddress("10.0.7.1"); + QHostAddress serverAddress("127.0.0.1"); // Bind the UDP socket to a specific port for receiving data (replace with your desired port) - udpSocket.bind(QHostAddress::Any, 12345); // Replace 12345 with your desired port + udpSocket.bind(QHostAddress::Any, serverPort); // Replace 12345 with your desired port // Connect the UDP socket's readyRead signal to the receiveData slot connect(&udpSocket, &QUdpSocket::readyRead, this, &UdpClient::receiveData); // Set the server's address and port for sending data - udpSocket.connectToHost(serverAddress, 12345); // Replace 12345 with the server's port + udpSocket.connectToHost(serverAddress, serverPort); // Replace 12345 with the server's port + } void UdpClient::startClient() @@ -22,6 +27,7 @@ void UdpClient::startClient() // Start any client functionality here // This method can be used to initialize the client if needed. qDebug() << "UDP Client is listening for data..."; + messageCount = 0; } void UdpClient::receiveData() @@ -39,18 +45,53 @@ void UdpClient::processPendingDatagrams() datagram.resize(udpSocket.pendingDatagramSize()); QHostAddress sender; quint16 senderPort; + QTime currentTime = QTime::currentTime(); - udpSocket.readDatagram(datagram.data(), datagram.size(), &sender, &senderPort); + + if(udpSocket.readDatagram(datagram.data(), datagram.size(), &sender, &senderPort)){ + // std::cerr << "found data" << std::endl; + + } // Parse and display the received data QString receivedData = QString::fromUtf8(datagram); +// std::cout << "Received Data: " << receivedData.toStdString() << std::endl; QStringList dataList = receivedData.split(','); - if (dataList.size() == 3) { + + if (dataList.size() == 9) { + double intensity = dataList[0].toDouble(); double position = dataList[1].toDouble(); double focus = dataList[2].toDouble(); + double rSquare = dataList[3].toDouble(); + int msecTime = dataList[4].toInt(); - qDebug() << "Received data - Intensity:" << intensity << "Position:" << position << "Focus:" << focus; + // qDebug() << "Received data - Intensity: " << intensity << " Position:" << position << " Focus:" << focus << " rsquare:" << rSquare << " msec:" << msecTime ; + } + else{ + qDebug() << "Data of unexpected size" << dataList.size() ; + } + messageCount++; + if (messageCount==1) { + startTime = currentTime.msecsSinceStartOfDay(); + } + + // Check if 1000 messages have been received + if (messageCount % 1000 == 0 && messageCount >1) { + QTime currentTime = QTime::currentTime(); + elapsedTimeInmSeconds = currentTime.msecsSinceStartOfDay(); + elapsedTimeInmSeconds-= startTime; + + // Calculate the rate in messages per second +// double messageRate = static_cast(messageCount) / elapsedTimeInmSeconds; + +// qInfo() << "Messages received: " << messageCount; + qInfo() << "Message rate (msec/1k): " << elapsedTimeInmSeconds;;// << 1000/(elapsedTimeInmSeconds/1000) << "kHz" ; + + + // Reset the counters + messageCount = 0; + startTime = currentTime.msecsSinceStartOfDay(); } } } diff --git a/hit2023v2_client/udpclient.h b/hit2023v2_client/udpclient.h index ac4bca6..a0fa785 100644 --- a/hit2023v2_client/udpclient.h +++ b/hit2023v2_client/udpclient.h @@ -5,6 +5,7 @@ #include #include +#include class UdpClient : public QObject { @@ -15,7 +16,9 @@ public: private: QUdpSocket udpSocket; - + int messageCount = 0; + int startTime=0; + int elapsedTimeInmSeconds=0; public slots: void receiveData(); void processPendingDatagrams();