added Scope Class. not tested
This commit is contained in:
parent
3478991fd2
commit
cd0f41841f
4
.vscode/c_cpp_properties.json
vendored
4
.vscode/c_cpp_properties.json
vendored
|
@ -18,7 +18,9 @@
|
|||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"/usr/include/x86_64-linux-gnu/qt6/**",
|
||||
"/home/splitpole/cern/root/include/**"
|
||||
"/home/splitpole/cern/root/include/**",
|
||||
"/usr/include/x86_64-linux-gnu/qt6/QtWidgets",
|
||||
"/usr/include/x86_64-linux-gnu/qt6/QtCore"
|
||||
],
|
||||
"defines": [],
|
||||
"compilerPath": "/usr/bin/gcc",
|
||||
|
|
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
|
@ -82,6 +82,8 @@
|
|||
}
|
||||
],
|
||||
"files.associations": {
|
||||
"mainWindow.C": "cpp"
|
||||
"mainWindow.C": "cpp",
|
||||
"Scope.C": "cpp",
|
||||
"new": "cpp"
|
||||
}
|
||||
}
|
104
CustomWidgets.h
104
CustomWidgets.h
|
@ -7,6 +7,12 @@
|
|||
#include <QComboBox>
|
||||
#include <QWheelEvent>
|
||||
|
||||
#include <QChart>
|
||||
#include <QChartView>
|
||||
#include <QRubberBand>
|
||||
#include <QMouseEvent>
|
||||
#include <QGestureEvent>
|
||||
|
||||
//^=======================================
|
||||
class RSpinBox : public QDoubleSpinBox{
|
||||
Q_OBJECT
|
||||
|
@ -49,5 +55,103 @@ class RComboBox : public QComboBox{
|
|||
void wheelEvent(QWheelEvent * event) override{ event->ignore(); }
|
||||
};
|
||||
|
||||
//^====================================================
|
||||
class Trace : public QChart{
|
||||
public:
|
||||
explicit Trace(QGraphicsItem *parent = nullptr, Qt::WindowFlags wFlags = {})
|
||||
: QChart(QChart::ChartTypeCartesian, parent, wFlags){
|
||||
grabGesture(Qt::PanGesture);
|
||||
grabGesture(Qt::PinchGesture);
|
||||
}
|
||||
~Trace(){}
|
||||
|
||||
protected:
|
||||
bool sceneEvent(QEvent *event){
|
||||
if (event->type() == QEvent::Gesture) return gestureEvent(static_cast<QGestureEvent *>(event));
|
||||
return QChart::event(event);
|
||||
}
|
||||
|
||||
private:
|
||||
bool gestureEvent(QGestureEvent *event){
|
||||
if (QGesture *gesture = event->gesture(Qt::PanGesture)) {
|
||||
QPanGesture *pan = static_cast<QPanGesture *>(gesture);
|
||||
QChart::scroll(-(pan->delta().x()), pan->delta().y());
|
||||
}
|
||||
|
||||
if (QGesture *gesture = event->gesture(Qt::PinchGesture)) {
|
||||
QPinchGesture *pinch = static_cast<QPinchGesture *>(gesture);
|
||||
if (pinch->changeFlags() & QPinchGesture::ScaleFactorChanged) QChart::zoom(pinch->scaleFactor());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
class TraceView : public QChartView{
|
||||
public:
|
||||
TraceView(QChart * chart, QWidget * parent = nullptr): QChartView(chart, parent){
|
||||
m_isTouching = false;
|
||||
this->setRubberBand(QChartView::RectangleRubberBand);
|
||||
|
||||
m_coordinateLabel = new QLabel(this);
|
||||
m_coordinateLabel->setStyleSheet("QLabel { color : black; }");
|
||||
m_coordinateLabel->setVisible(false);
|
||||
m_coordinateLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool viewportEvent(QEvent *event) override{
|
||||
if (event->type() == QEvent::TouchBegin) {
|
||||
m_isTouching = true;
|
||||
chart()->setAnimationOptions(QChart::NoAnimation);
|
||||
}
|
||||
return QChartView::viewportEvent(event);
|
||||
}
|
||||
void mousePressEvent(QMouseEvent *event) override{
|
||||
if (m_isTouching) return;
|
||||
QChartView::mousePressEvent(event);
|
||||
}
|
||||
void mouseMoveEvent(QMouseEvent *event) override{
|
||||
|
||||
QPointF chartPoint = this->chart()->mapToValue(event->pos());
|
||||
QString coordinateText = QString("x: %1, y: %2").arg(QString::number(chartPoint.x(), 'f', 0)).arg(QString::number(chartPoint.y(), 'f', 0));
|
||||
m_coordinateLabel->setText(coordinateText);
|
||||
m_coordinateLabel->move(event->pos() + QPoint(10, -10));
|
||||
m_coordinateLabel->setVisible(true);
|
||||
if (m_isTouching) return;
|
||||
QChartView::mouseMoveEvent(event);
|
||||
|
||||
}
|
||||
void mouseReleaseEvent(QMouseEvent *event) override{
|
||||
if (m_isTouching) m_isTouching = false;
|
||||
chart()->setAnimationOptions(QChart::SeriesAnimations);
|
||||
QChartView::mouseReleaseEvent(event);
|
||||
}
|
||||
void leaveEvent(QEvent *event) override {
|
||||
m_coordinateLabel->setVisible(false);
|
||||
QChartView::leaveEvent(event);
|
||||
}
|
||||
void keyPressEvent(QKeyEvent *event) override{
|
||||
switch (event->key()) {
|
||||
case Qt::Key_Plus: chart()->zoomIn(); break;
|
||||
case Qt::Key_Minus: chart()->zoomOut(); break;
|
||||
case Qt::Key_Left: chart()->scroll(-10, 0); break;
|
||||
case Qt::Key_Right: chart()->scroll(10, 0); break;
|
||||
case Qt::Key_Up: chart()->scroll(0, 10); break;
|
||||
case Qt::Key_Down: chart()->scroll(0, -10); break;
|
||||
case Qt::Key_R : chart()->axes(Qt::Vertical).first()->setRange(-16384, 65536); break;
|
||||
default: QGraphicsView::keyPressEvent(event); break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_isTouching;
|
||||
QLabel * m_coordinateLabel;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
#include "mainWindow.h"
|
||||
#include "FSUDAQ.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QVBoxLayout>
|
||||
|
@ -24,6 +24,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
|
|||
digi = nullptr;
|
||||
nDigi = 0;
|
||||
|
||||
scope = nullptr;
|
||||
|
||||
QWidget * mainLayoutWidget = new QWidget(this);
|
||||
setCentralWidget(mainLayoutWidget);
|
||||
QVBoxLayout * layoutMain = new QVBoxLayout(mainLayoutWidget);
|
||||
|
@ -58,6 +60,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
|
|||
QGridLayout * layout = new QGridLayout(box);
|
||||
|
||||
int rowID = 0;
|
||||
//------------------------------------------
|
||||
QLabel * lbDataPath = new QLabel("Data Path : ", this);
|
||||
lbDataPath->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||
leDataPath = new QLineEdit(this);
|
||||
|
@ -66,28 +69,45 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
|
|||
connect(bnSetDataPath, &QPushButton::clicked, this, &MainWindow::OpenDataPath);
|
||||
|
||||
layout->addWidget(lbDataPath, rowID, 0);
|
||||
layout->addWidget(leDataPath, rowID, 1, 1, 3);
|
||||
layout->addWidget(bnSetDataPath, rowID, 4);
|
||||
layout->addWidget(leDataPath, rowID, 1, 1, 6);
|
||||
layout->addWidget(bnSetDataPath, rowID, 7);
|
||||
|
||||
//------------------------------------------
|
||||
rowID ++;
|
||||
QLabel * lbPrefix = new QLabel("Prefix : ", this);
|
||||
lbPrefix->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||
lePrefix = new QLineEdit(this);
|
||||
lePrefix->setAlignment(Qt::AlignHCenter);
|
||||
|
||||
QLabel * lbRunID = new QLabel("Run No. :", this);
|
||||
lbRunID->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||
leRunID = new QLineEdit(this);
|
||||
leRunID->setReadOnly(true);
|
||||
leRunID->setAlignment(Qt::AlignHCenter);
|
||||
|
||||
bnOpenScaler = new QPushButton("Scalar", this);
|
||||
connect(bnOpenScaler, &QPushButton::clicked, this, &MainWindow::OpenScalar);
|
||||
chkSaveData = new QCheckBox("Save Data", this);
|
||||
cbAutoRun = new QComboBox(this);
|
||||
cbAutoRun->addItem("Single Infinite", 0);
|
||||
cbAutoRun->addItem("Single 30 mins", 30);
|
||||
cbAutoRun->addItem("Single 60 mins", 60);
|
||||
cbAutoRun->addItem("Repeat 60 mins", -60);
|
||||
cbAutoRun->setEnabled(false);
|
||||
|
||||
bnStartACQ = new QPushButton("Start ACQ", this);
|
||||
connect( bnStartACQ, &QPushButton::clicked, this, &MainWindow::StartACQ);
|
||||
bnStopACQ = new QPushButton("Stop ACQ", this);
|
||||
connect( bnStopACQ, &QPushButton::clicked, this, &MainWindow::StopACQ);
|
||||
|
||||
layout->addWidget(lbPrefix, rowID, 0);
|
||||
layout->addWidget(lePrefix, rowID, 1);
|
||||
layout->addWidget(lbRunID, rowID, 2);
|
||||
layout->addWidget(leRunID, rowID, 3);
|
||||
layout->addWidget(bnOpenScaler, rowID, 4);
|
||||
layout->addWidget(chkSaveData, rowID, 4);
|
||||
layout->addWidget(cbAutoRun, rowID, 5);
|
||||
layout->addWidget(bnStartACQ, rowID, 6);
|
||||
layout->addWidget(bnStopACQ, rowID, 7);
|
||||
|
||||
//------------------------------------------
|
||||
rowID ++;
|
||||
QLabel * lbComment = new QLabel("Run Comment : ", this);
|
||||
lbComment->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||
|
@ -95,21 +115,22 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
|
|||
leComment = new QLineEdit(this);
|
||||
leComment->setEnabled(false);
|
||||
|
||||
bnStartACQ = new QPushButton("Start ACQ", this);
|
||||
connect( bnStartACQ, &QPushButton::clicked, this, &MainWindow::StartACQ);
|
||||
bnStopACQ = new QPushButton("Stop ACQ", this);
|
||||
connect( bnStopACQ, &QPushButton::clicked, this, &MainWindow::StopACQ);
|
||||
bnOpenScaler = new QPushButton("Scalar", this);
|
||||
connect(bnOpenScaler, &QPushButton::clicked, this, &MainWindow::OpenScalar);
|
||||
|
||||
layout->addWidget(lbComment, rowID, 0);
|
||||
layout->addWidget(leComment, rowID, 1, 1, 2);
|
||||
layout->addWidget(bnStartACQ, rowID, 3);
|
||||
layout->addWidget(bnStopACQ, rowID, 4);
|
||||
layout->addWidget(leComment, rowID, 1, 1, 6);
|
||||
|
||||
layout->addWidget(bnOpenScaler, rowID, 7);
|
||||
|
||||
layout->setColumnStretch(0, 1);
|
||||
layout->setColumnStretch(1, 2);
|
||||
layout->setColumnStretch(2, 1);
|
||||
layout->setColumnStretch(3, 3);
|
||||
layout->setColumnStretch(4, 3);
|
||||
layout->setColumnStretch(3, 1);
|
||||
layout->setColumnStretch(4, 1);
|
||||
layout->setColumnStretch(5, 1);
|
||||
layout->setColumnStretch(6, 3);
|
||||
layout->setColumnStretch(7, 3);
|
||||
|
||||
}
|
||||
|
||||
|
@ -161,8 +182,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
|
|||
lbLastUpdateTime = nullptr;
|
||||
lbScalarACQStatus = nullptr;
|
||||
|
||||
nScalarBuilt = 0;
|
||||
|
||||
scalarThread = new ScalarThread();
|
||||
//connect(scalarThread, &ScalarThread::updataScalar, this, &MainWindow::UpdateScalar);
|
||||
|
||||
|
@ -174,6 +193,8 @@ MainWindow::~MainWindow(){
|
|||
if( digi ) CloseDigitizers();
|
||||
SaveProgramSettings();
|
||||
|
||||
if( scope ) delete scope;
|
||||
|
||||
}
|
||||
|
||||
//***************************************************************
|
||||
|
@ -216,6 +237,18 @@ void MainWindow::LoadProgramSettings(){
|
|||
|
||||
//looking for the lastRun.sh for
|
||||
leDataPath->setText(rawDataPath);
|
||||
|
||||
//check is rawDataPath exist, if not, create one
|
||||
QDir rawDataDir;
|
||||
if( !rawDataDir.exists(rawDataPath ) ) {
|
||||
if( rawDataDir.mkdir(rawDataPath) ){
|
||||
LogMsg("Created folder <b>" + rawDataPath + "</b> for storing root files.");
|
||||
}else{
|
||||
LogMsg("<font style=\"color:red;\"><b>" + rawDataPath + "</b> cannot be created. Access right problem? </font>" );
|
||||
}
|
||||
}else{
|
||||
LogMsg("<b>" + rawDataPath + "</b> already exist." );
|
||||
}
|
||||
LoadLastRunFile();
|
||||
}
|
||||
|
||||
|
@ -340,6 +373,8 @@ void MainWindow::CloseDigitizers(){
|
|||
|
||||
CleanUpScalar();
|
||||
|
||||
if( digi == nullptr ) return;
|
||||
|
||||
for(unsigned int i = 0; i < nDigi; i ++){
|
||||
digi[i]->CloseDigitizer();
|
||||
delete digi[i];
|
||||
|
@ -379,7 +414,6 @@ void MainWindow::SetupScalar(){
|
|||
scalarLayout->addWidget(lbScalarACQStatus, 1, 1, 1, 1 + nDigi);
|
||||
|
||||
int rowID = 3;
|
||||
if( nScalarBuilt == 0 ){
|
||||
///==== create the header row
|
||||
for( int ch = 0; ch < MaxNChannels; ch++){
|
||||
|
||||
|
@ -393,33 +427,30 @@ void MainWindow::SetupScalar(){
|
|||
lbCH->setAlignment(Qt::AlignCenter);
|
||||
scalarLayout->addWidget(lbCH, rowID, 0);
|
||||
}
|
||||
}
|
||||
|
||||
///===== create the trigger and accept
|
||||
leTrigger = new QLineEdit**[nDigi];
|
||||
leAccept = new QLineEdit**[nDigi];
|
||||
lbDigi = new QLabel * [nDigi];
|
||||
lbTrigger = new QLabel * [nDigi];
|
||||
lbAccept = new QLabel * [nDigi];
|
||||
for( unsigned int iDigi = 0; iDigi < nDigi; iDigi++){
|
||||
rowID = 2;
|
||||
leTrigger[iDigi] = new QLineEdit *[digi[iDigi]->GetNChannels()];
|
||||
leAccept[iDigi] = new QLineEdit *[digi[iDigi]->GetNChannels()];
|
||||
for( int ch = 0; ch < MaxNChannels; ch++){
|
||||
|
||||
lbDigi[iDigi] = new QLabel("Digi-" + QString::number(digi[iDigi]->GetSerialNumber()), scalar);
|
||||
lbDigi[iDigi]->setAlignment(Qt::AlignCenter);
|
||||
scalarLayout->addWidget(lbDigi[iDigi], rowID, 2*iDigi+1, 1, 2);
|
||||
if( ch == 0 ){
|
||||
QLabel * lbDigi = new QLabel("Digi-" + QString::number(digi[iDigi]->GetSerialNumber()), scalar);
|
||||
lbDigi->setAlignment(Qt::AlignCenter);
|
||||
scalarLayout->addWidget(lbDigi, rowID, 2*iDigi+1, 1, 2);
|
||||
|
||||
rowID ++;
|
||||
|
||||
lbTrigger[iDigi] = new QLabel("Trig. [Hz]", scalar);
|
||||
lbTrigger[iDigi]->setAlignment(Qt::AlignCenter);
|
||||
scalarLayout->addWidget(lbTrigger[iDigi], rowID, 2*iDigi+1);
|
||||
lbAccept[iDigi] = new QLabel("Accp. [Hz]", scalar);
|
||||
lbAccept[iDigi]->setAlignment(Qt::AlignCenter);
|
||||
scalarLayout->addWidget(lbAccept[iDigi], rowID, 2*iDigi+2);
|
||||
|
||||
for( int ch = 0; ch < MaxNChannels; ch++){
|
||||
QLabel * lbA = new QLabel("Trig. [Hz]", scalar);
|
||||
lbA->setAlignment(Qt::AlignCenter);
|
||||
scalarLayout->addWidget(lbA, rowID, 2*iDigi+1);
|
||||
QLabel * lbB = new QLabel("Accp. [Hz]", scalar);
|
||||
lbB->setAlignment(Qt::AlignCenter);
|
||||
scalarLayout->addWidget(lbB, rowID, 2*iDigi+2);
|
||||
}
|
||||
|
||||
rowID ++;
|
||||
|
||||
|
@ -435,7 +466,6 @@ void MainWindow::SetupScalar(){
|
|||
scalarLayout->addWidget(leAccept[iDigi][ch], rowID, 2*iDigi+2);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::CleanUpScalar(){
|
||||
|
@ -452,25 +482,14 @@ void MainWindow::CleanUpScalar(){
|
|||
delete [] leTrigger[i];
|
||||
delete [] leAccept[i];
|
||||
|
||||
delete lbDigi[i];
|
||||
delete lbTrigger[i];
|
||||
delete lbAccept[i];
|
||||
}
|
||||
delete [] leTrigger;
|
||||
delete [] lbDigi;
|
||||
delete [] lbTrigger;
|
||||
delete [] lbAccept;
|
||||
leTrigger = nullptr;
|
||||
leAccept = nullptr;
|
||||
lbDigi = nullptr;
|
||||
lbTrigger = nullptr;
|
||||
lbAccept = nullptr;
|
||||
|
||||
delete lbLastUpdateTime;
|
||||
delete lbScalarACQStatus;
|
||||
|
||||
lbLastUpdateTime = nullptr;
|
||||
lbScalarACQStatus = nullptr;
|
||||
//Clean up QLabel
|
||||
QList<QLabel *> labelChildren = scalar->findChildren<QLabel *>();
|
||||
for( int i = 0; i < labelChildren.size(); i++) delete labelChildren[i];
|
||||
|
||||
printf("---- end of %s \n", __func__);
|
||||
|
||||
|
@ -491,6 +510,8 @@ void MainWindow::UpdateScalar(){
|
|||
void MainWindow::StartACQ(){
|
||||
if( digi == nullptr ) return;
|
||||
|
||||
if( CommentDialog(true) == false) return;
|
||||
|
||||
for( unsigned int i = 0; i < nDigi ; i++){
|
||||
digi[i]->GetData()->OpenSaveFile((rawDataPath + "/" + prefix).toStdString());
|
||||
digi[i]->StartACQ();
|
||||
|
@ -505,6 +526,8 @@ void MainWindow::StartACQ(){
|
|||
void MainWindow::StopACQ(){
|
||||
if( digi == nullptr ) return;
|
||||
|
||||
if( CommentDialog(false) == false) return;
|
||||
|
||||
for( unsigned int i = 0; i < nDigi; i++){
|
||||
digi[i]->StopACQ();
|
||||
digi[i]->GetData()->CloseSaveFile();
|
||||
|
@ -517,6 +540,120 @@ void MainWindow::StopACQ(){
|
|||
|
||||
}
|
||||
|
||||
void MainWindow::AutoRun(){
|
||||
|
||||
}
|
||||
|
||||
bool MainWindow::CommentDialog(bool isStartRun){
|
||||
|
||||
if( isStartRun ) runID ++;
|
||||
QString runIDStr = QString::number(runID).rightJustified(3, '0');
|
||||
|
||||
QDialog * dOpen = new QDialog(this);
|
||||
if( isStartRun ) {
|
||||
dOpen->setWindowTitle("Start Run Comment");
|
||||
}else{
|
||||
dOpen->setWindowTitle("Stop Run Comment");
|
||||
}
|
||||
dOpen->setWindowFlags(Qt::Dialog | Qt::WindowTitleHint | Qt::CustomizeWindowHint);
|
||||
dOpen->setMinimumWidth(600);
|
||||
connect(dOpen, &QDialog::finished, dOpen, &QDialog::deleteLater);
|
||||
|
||||
QGridLayout * vlayout = new QGridLayout(dOpen);
|
||||
QLabel *label = new QLabel("Enter Run comment for <font style=\"color : red;\">Run-" + runIDStr + "</font> : ", dOpen);
|
||||
QLineEdit *lineEdit = new QLineEdit(dOpen);
|
||||
QPushButton *button1 = new QPushButton("OK", dOpen);
|
||||
QPushButton *button2 = new QPushButton("Cancel", dOpen);
|
||||
|
||||
vlayout->addWidget(label, 0, 0, 1, 2);
|
||||
vlayout->addWidget(lineEdit, 1, 0, 1, 2);
|
||||
vlayout->addWidget(button1, 2, 0);
|
||||
vlayout->addWidget(button2, 2, 1);
|
||||
|
||||
connect(button1, &QPushButton::clicked, dOpen, &QDialog::accept);
|
||||
connect(button2, &QPushButton::clicked, dOpen, &QDialog::reject);
|
||||
int result = dOpen->exec();
|
||||
|
||||
if(result == QDialog::Accepted ){
|
||||
|
||||
if( isStartRun ){
|
||||
startComment = lineEdit->text();
|
||||
if( startComment == "") startComment = "No commet was typed.";
|
||||
startComment = "Start Comment: " + startComment;
|
||||
leComment->setText(startComment);
|
||||
}else{
|
||||
stopComment = lineEdit->text();
|
||||
if( stopComment == "") stopComment = "No commet was typed.";
|
||||
stopComment = "Stop Comment: " + stopComment;
|
||||
leComment->setText(stopComment);
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
if( isStartRun ){
|
||||
LogMsg("Start Run aborted. ");
|
||||
runID --;
|
||||
leRunID->setText(QString::number(runID));
|
||||
}else{
|
||||
LogMsg("Stop Run cancelled. ");
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::WriteRunTimestamp(bool isStartRun){
|
||||
|
||||
QFile file(rawDataPath + "/RunTimeStamp.dat");
|
||||
|
||||
QString dateTime = QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss");
|
||||
if( file.open(QIODevice::Text | QIODevice::WriteOnly | QIODevice::Append) ){
|
||||
|
||||
if( isStartRun ){
|
||||
file.write(("Start Run | " + QString::number(runID) + " | " + dateTime + " | " + startComment + "\n").toStdString().c_str());
|
||||
}else{
|
||||
file.write((" Stop Run | " + QString::number(runID) + " | " + dateTime + " | " + stopComment + "\n").toStdString().c_str());
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
|
||||
QFile fileCSV(rawDataPath + "/RunTimeStamp.csv");
|
||||
|
||||
if( fileCSV.open(QIODevice::Text | QIODevice::WriteOnly | QIODevice::Append) ){
|
||||
|
||||
QTextStream out(&fileCSV);
|
||||
|
||||
if( isStartRun){
|
||||
out << QString::number(runID) + "," + dateTime + "," + startComment;
|
||||
}else{
|
||||
out << "," + dateTime + "," + stopComment + "\n";
|
||||
}
|
||||
|
||||
fileCSV.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//***************************************************************
|
||||
//***************************************************************
|
||||
void MainWindow::OpenScope(){
|
||||
|
||||
if( scope == nullptr ) {
|
||||
scope = new Scope(digi, nDigi, readDataThread);
|
||||
scope->show();
|
||||
}else{
|
||||
scope->show();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//***************************************************************
|
||||
//***************************************************************
|
||||
void MainWindow::LogMsg(QString msg){
|
|
@ -7,10 +7,13 @@
|
|||
#include <QPlainTextEdit>
|
||||
#include <QLineEdit>
|
||||
#include <QLabel>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QGridLayout>
|
||||
|
||||
#include "ClassDigitizer.h"
|
||||
#include "CustomThreads.h"
|
||||
#include "Scope.h"
|
||||
|
||||
//^#===================================================== MainWindow
|
||||
class MainWindow : public QMainWindow{
|
||||
|
@ -38,6 +41,11 @@ private slots:
|
|||
|
||||
void StartACQ();
|
||||
void StopACQ();
|
||||
void AutoRun();
|
||||
bool CommentDialog(bool isStartRun);
|
||||
void WriteRunTimestamp(bool isStartRun);
|
||||
|
||||
void OpenScope();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -70,22 +78,27 @@ private:
|
|||
QLineEdit * leComment;
|
||||
QLineEdit * leRunID;
|
||||
|
||||
QCheckBox * chkSaveData;
|
||||
QComboBox * cbAutoRun;
|
||||
|
||||
QString startComment;
|
||||
QString stopComment;
|
||||
|
||||
//@----- Scalar
|
||||
QMainWindow * scalar;
|
||||
QLineEdit *** leTrigger; // need to delete manually
|
||||
QLineEdit *** leAccept; // need to delete manually
|
||||
QLabel **lbDigi;
|
||||
QLabel ** lbTrigger;
|
||||
QLabel ** lbAccept;
|
||||
QGridLayout * scalarLayout;
|
||||
ScalarThread * scalarThread;
|
||||
QLineEdit *** leTrigger; // need to delete manually
|
||||
QLineEdit *** leAccept; // need to delete manually
|
||||
QLabel * lbLastUpdateTime;
|
||||
QLabel * lbScalarACQStatus;
|
||||
int nScalarBuilt;
|
||||
|
||||
//@----- ACQ
|
||||
ReadDataThread ** readDataThread;
|
||||
|
||||
//@----- Scope
|
||||
Scope * scope;
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -1,13 +1,11 @@
|
|||
######################################################################
|
||||
# Automatically generated by qmake (3.1) Tue Apr 11 11:05:33 2023
|
||||
# Automatically generated by qmake (3.1) Tue Apr 18 13:09:25 2023
|
||||
######################################################################
|
||||
|
||||
TEMPLATE = app
|
||||
TARGET = FSUDAQ_Qt6
|
||||
INCLUDEPATH += .
|
||||
|
||||
CONFIG += c++17
|
||||
|
||||
QT += core widgets charts
|
||||
|
||||
QMAKE_CXXFLAGS += `root-config --cflags --glibs`
|
||||
|
@ -21,7 +19,15 @@ LIBS += -lCAENDigitizer `root-config --cflags --glibs`
|
|||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
# Input
|
||||
HEADERS += ClassData.h ClassDigitizer.h macro.h mainWindow.h RegisterAddress.h CustomWidgets.h CustomThreads.h
|
||||
SOURCES += ClassDigitizer.cpp main.cpp mainWindow.C
|
||||
|
||||
|
||||
HEADERS += ClassData.h \
|
||||
ClassDigitizer.h \
|
||||
CustomThreads.h \
|
||||
CustomWidgets.h \
|
||||
FSUDAQ.h \
|
||||
macro.h \
|
||||
RegisterAddress.h \
|
||||
Scope.h
|
||||
SOURCES += ClassDigitizer.cpp \
|
||||
FSUDAQ.cpp \
|
||||
main.cpp \
|
||||
Scope.cpp
|
||||
|
|
120
Scope.cpp
Normal file
120
Scope.cpp
Normal file
|
@ -0,0 +1,120 @@
|
|||
#include "Scope.h"
|
||||
|
||||
#include <QValueAxis>
|
||||
#include <QRandomGenerator>
|
||||
#include <QGroupBox>
|
||||
#include <QStandardItemModel>
|
||||
#include <QLabel>
|
||||
|
||||
|
||||
Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataThread, QMainWindow * parent) : QMainWindow(parent){
|
||||
|
||||
this->digi = digi;
|
||||
this->nDigi = nDigi;
|
||||
this->readDataThread = readDataThread;
|
||||
|
||||
setWindowTitle("Scope");
|
||||
setGeometry(0, 0, 1000, 800);
|
||||
setWindowFlags( this->windowFlags() & ~Qt::WindowCloseButtonHint );
|
||||
|
||||
enableSignalSlot = false;
|
||||
|
||||
plot = new Trace();
|
||||
for( int i = 0; i < MaxNumberOfTrace; i++) {
|
||||
dataTrace[i] = new QLineSeries();
|
||||
dataTrace[i]->setName("Trace " + QString::number(i));
|
||||
for(int j = 0; j < 100; j ++) dataTrace[i]->append(40*j, QRandomGenerator::global()->bounded(8000) + 8000);
|
||||
plot->addSeries(dataTrace[i]);
|
||||
}
|
||||
|
||||
dataTrace[0]->setPen(QPen(Qt::red, 2));
|
||||
dataTrace[1]->setPen(QPen(Qt::blue, 2));
|
||||
dataTrace[2]->setPen(QPen(Qt::darkYellow, 1));
|
||||
dataTrace[3]->setPen(QPen(Qt::darkGreen, 1));
|
||||
|
||||
plot->setAnimationDuration(1); // msec
|
||||
plot->setAnimationOptions(QChart::NoAnimation);
|
||||
plot->createDefaultAxes(); /// this must be after addSeries();
|
||||
/// this must be after createDefaultAxes();
|
||||
QValueAxis * yaxis = qobject_cast<QValueAxis*> (plot->axes(Qt::Vertical).first());
|
||||
QValueAxis * xaxis = qobject_cast<QValueAxis*> (plot->axes(Qt::Horizontal).first());
|
||||
yaxis->setTickCount(6);
|
||||
yaxis->setTickInterval(16384);
|
||||
yaxis->setRange(-16384, 65536);
|
||||
yaxis->setLabelFormat("%.0f");
|
||||
|
||||
xaxis->setRange(0, 5000);
|
||||
xaxis->setTickCount(11);
|
||||
xaxis->setLabelFormat("%.0f");
|
||||
xaxis->setTitleText("Time [ns]");
|
||||
|
||||
updateTraceThread = new UpdateTraceThread();
|
||||
//connect(updateTraceThread, &UpdateTraceThread::updateTrace, this, &Scope::UpdateScope);
|
||||
|
||||
//*================================== UI
|
||||
int rowID = -1;
|
||||
|
||||
QWidget * layoutWidget = new QWidget(this);
|
||||
setCentralWidget(layoutWidget);
|
||||
QGridLayout * layout = new QGridLayout(layoutWidget);
|
||||
layoutWidget->setLayout(layout);
|
||||
|
||||
//--------------------
|
||||
rowID ++;
|
||||
cbScopeDigi = new RComboBox(this);
|
||||
cbScopeCh = new RComboBox(this);
|
||||
layout->addWidget(cbScopeDigi, rowID, 0);
|
||||
layout->addWidget(cbScopeCh, rowID, 1);
|
||||
|
||||
|
||||
//-------------------- Plot view
|
||||
rowID ++;
|
||||
TraceView * plotView = new TraceView(plot);
|
||||
plotView->setRenderHints(QPainter::Antialiasing);
|
||||
layout->addWidget(plotView, rowID, 0, 1, 6);
|
||||
|
||||
//------------ close button
|
||||
rowID ++;
|
||||
bnScopeStart = new QPushButton("Start", this);
|
||||
layout->addWidget(bnScopeStart, rowID, 0);
|
||||
bnScopeStart->setEnabled(false);
|
||||
connect(bnScopeStart, &QPushButton::clicked, this, [=](){this->StartScope();});
|
||||
|
||||
bnScopeStop = new QPushButton("Stop", this);
|
||||
layout->addWidget(bnScopeStop, rowID, 1);
|
||||
connect(bnScopeStop, &QPushButton::clicked, this, &Scope::StopScope);
|
||||
|
||||
QLabel * lbTriggerRate = new QLabel("Trigger Rate [Hz] : ", this);
|
||||
lbTriggerRate->setAlignment(Qt::AlignCenter | Qt::AlignRight);
|
||||
layout->addWidget(lbTriggerRate, rowID, 2);
|
||||
|
||||
leTriggerRate = new QLineEdit(this);
|
||||
leTriggerRate->setAlignment(Qt::AlignRight);
|
||||
leTriggerRate->setReadOnly(true);
|
||||
layout->addWidget(leTriggerRate, rowID, 3);
|
||||
|
||||
QPushButton * bnClose = new QPushButton("Close", this);
|
||||
layout->addWidget(bnClose, rowID, 5);
|
||||
connect(bnClose, &QPushButton::clicked, this, &Scope::close);
|
||||
|
||||
}
|
||||
|
||||
Scope::~Scope(){
|
||||
|
||||
updateTraceThread->Stop();
|
||||
updateTraceThread->quit();
|
||||
updateTraceThread->wait();
|
||||
delete updateTraceThread;
|
||||
for( int i = 0; i < MaxNumberOfTrace; i++) delete dataTrace[i];
|
||||
delete plot;
|
||||
}
|
||||
|
||||
void Scope::StartScope(){
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Scope::StopScope(){
|
||||
|
||||
}
|
||||
|
67
Scope.h
Normal file
67
Scope.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
#ifndef SCOPE_H
|
||||
#define SCOPE_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QChart>
|
||||
#include <QChartView>
|
||||
#include <QSpinBox>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QCheckBox>
|
||||
#include <QLineEdit>
|
||||
#include <QComboBox>
|
||||
#include <QGridLayout>
|
||||
#include <QLineSeries>
|
||||
#include <QRubberBand>
|
||||
#include <QMouseEvent>
|
||||
#include <QGestureEvent>
|
||||
|
||||
#include "macro.h"
|
||||
#include "ClassDigitizer.h"
|
||||
#include "CustomThreads.h"
|
||||
#include "CustomWidgets.h"
|
||||
|
||||
//^====================================================
|
||||
//^====================================================
|
||||
class Scope : public QMainWindow{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataThread, QMainWindow * parent = nullptr);
|
||||
~Scope();
|
||||
|
||||
public slots:
|
||||
|
||||
private slots:
|
||||
void StartScope();
|
||||
void StopScope();
|
||||
|
||||
signals:
|
||||
|
||||
private:
|
||||
|
||||
Digitizer ** digi;
|
||||
unsigned short nDigi;
|
||||
|
||||
ReadDataThread ** readDataThread;
|
||||
UpdateTraceThread * updateTraceThread;
|
||||
|
||||
bool enableSignalSlot;
|
||||
|
||||
Trace * plot;
|
||||
QLineSeries * dataTrace[MaxNumberOfTrace]; // 2 analog, 2 digi
|
||||
|
||||
RComboBox * cbScopeDigi;
|
||||
RComboBox * cbScopeCh;
|
||||
|
||||
|
||||
QPushButton * bnScopeStart;
|
||||
QPushButton * bnScopeStop;
|
||||
|
||||
QLineEdit * leTriggerRate;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
3
macro.h
3
macro.h
|
@ -7,6 +7,9 @@
|
|||
#define MaxRecordLength 0x3fff * 8
|
||||
#define MaxSaveFileSize 1024 * 1024 * 1024 * 2
|
||||
|
||||
#define MaxDisplayTraceDataLength 2000 //data point,
|
||||
#define MaxNumberOfTrace 4 // in an event
|
||||
|
||||
#define SETTINGSIZE 2048
|
||||
|
||||
#include <sys/time.h> /** struct timeval, select() */
|
||||
|
|
Loading…
Reference in New Issue
Block a user