diff --git a/ClassDigitizer2Gen.cpp b/ClassDigitizer2Gen.cpp index 9f374c9..68b2cd8 100644 --- a/ClassDigitizer2Gen.cpp +++ b/ClassDigitizer2Gen.cpp @@ -484,17 +484,17 @@ int Digitizer2Gen::ReadData(){ //########################################### -void Digitizer2Gen::OpenOutFile(std::string fileName){ +void Digitizer2Gen::OpenOutFile(std::string fileName, const char * mode){ outFileNameBase = fileName; sprintf(outFileName, "%s_%03d.sol", fileName.c_str(), outFileIndex); - outFile = fopen(outFileName, "a+"); + outFile = fopen(outFileName, mode); fseek(outFile, 0L, SEEK_END); outFileSize = ftell(outFile); // unsigned int = Max ~4GB } void Digitizer2Gen::CloseOutFile(){ - fclose(outFile); + if( outFile != NULL ) fclose(outFile); } void Digitizer2Gen::SaveDataToFile(){ diff --git a/ClassDigitizer2Gen.h b/ClassDigitizer2Gen.h index 0831989..50b5284 100644 --- a/ClassDigitizer2Gen.h +++ b/ClassDigitizer2Gen.h @@ -114,7 +114,7 @@ class Digitizer2Gen { uint64_t GetHandle() const {return handle;} Event *evt; // should be evt[MaxNumber], when full or stopACQ, save into file - void OpenOutFile(std::string fileName); + void OpenOutFile(std::string fileName, const char * mode = "w"); void CloseOutFile(); void SaveDataToFile(); unsigned int GetFileSize() {return outFileSize;} diff --git a/influxdb.cpp b/influxdb.cpp index 403da5f..08b484e 100644 --- a/influxdb.cpp +++ b/influxdb.cpp @@ -5,27 +5,31 @@ InfluxDB::InfluxDB(std::string url, bool verbose){ curl = curl_easy_init(); if( verbose) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); - this->databaseIP = url; + SetURL(url); respondCode = 0; dataPoints = ""; } InfluxDB::~InfluxDB(){ - curl_easy_cleanup(curl); } void InfluxDB::SetURL(std::string url){ - this->databaseIP = url; + // check the last char of url is "/" + if( url.back() != '/') { + this->databaseIP = url + "/"; + }else{ + this->databaseIP = url; + } } bool InfluxDB::TestingConnection(){ - ShowDatabases(); + CheckDatabases(); if( respond != CURLE_OK ) return false; return true; } -std::string InfluxDB::ShowDatabases(){ +std::string InfluxDB::CheckDatabases(){ curl_easy_setopt(curl, CURLOPT_POST, 1); curl_easy_setopt(curl, CURLOPT_URL, (databaseIP + "/query").c_str()); @@ -124,9 +128,9 @@ void InfluxDB::PrintDataPoints(){ printf("%s\n", dataPoints.c_str()); } -void InfluxDB::WriteData(std::string databaseName){ +void InfluxDB::WriteData(std::string databaseName){ curl_easy_setopt(curl, CURLOPT_URL, (databaseIP + "write?db=" + databaseName).c_str()); - curl_easy_setopt(curl, CURLOPT_POST, 1); + curl_easy_setopt(curl, CURLOPT_POST, 1L); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast(dataPoints.length())); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, dataPoints.c_str()); Execute(); diff --git a/influxdb.h b/influxdb.h index c59c9cd..ad98a65 100644 --- a/influxdb.h +++ b/influxdb.h @@ -35,10 +35,10 @@ class InfluxDB{ bool IsURLValid() const {return isURLValid;} /// Query - std::string ShowDatabases(); /// this save the list of database into databaseList + std::string CheckDatabases(); /// this save the list of database into databaseList std::string Query(std::string databaseName, std::string query); - /// the ShowDatabases() function must be called before + /// the CheckDatabases() function must be called before std::vector GetDatabaseList() {return databaseList;} void CreateDatabase(std::string databaseName); diff --git a/mainwindow.cpp b/mainwindow.cpp index 0ad03c9..aac3e92 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -145,8 +145,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ leRunID = new QLineEdit(this); leRunID->setAlignment(Qt::AlignHCenter); leRunID->setReadOnly(true); + leRunID->setStyleSheet("background-color: #F3F3F3;"); chkSaveRun = new QCheckBox("Save Run", this); + chkSaveRun->setChecked(true); + chkSaveRun->setEnabled(false); cbAutoRun = new QComboBox(this); cbAutoRun->addItem("Single Run"); @@ -167,8 +170,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ QLabel * lbRunComment = new QLabel("Run Comment : ", this); lbRunComment->setAlignment(Qt::AlignRight | Qt::AlignCenter); - QLineEdit * runComment = new QLineEdit(this); - runComment->setReadOnly(true); + QLineEdit * leRunComment = new QLineEdit(this); + leRunComment->setReadOnly(true); + leRunComment->setStyleSheet("background-color: #F3F3F3;"); layout2->addWidget(lbRawDataPath, 0, 0); layout2->addWidget(leRawDataPath, 0, 1, 1, 4); @@ -182,7 +186,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ layout2->addWidget(bnStopACQ, 1, 5); layout2->addWidget(lbRunComment, 2, 0); - layout2->addWidget(runComment, 2, 1, 1, 5); + layout2->addWidget(leRunComment, 2, 1, 1, 5); layout2->setColumnStretch(0, 2); layout2->setColumnStretch(1, 1); @@ -229,6 +233,10 @@ MainWindow::~MainWindow(){ //delete logInfo; printf("- %s\n", __func__); + for( int i = 0; i < nDigi ; i++){ + if( readDataThread[i]->isRunning()) StopACQ(); + } + DeleteTriggerLineEdit(); delete scalarThread; CloseDigitizers(); @@ -244,7 +252,18 @@ MainWindow::~MainWindow(){ //^################################################################ ACQ control void MainWindow::StartACQ(){ - LogMsg("Start Run...."); + if( chkSaveRun->isChecked() ){ + runIDStr = QString::number(runID).rightJustified(3, '0'); + LogMsg("=========================== Start Run-" + runIDStr + ""); + //TODO ============ start comment + + //TODO ============ elog + + //TODO ============ update expName.sh + + }else{ + LogMsg("=========================== Start no-save Run"); + } for( int i =0 ; i < nDigi; i ++){ if( digi[i]->IsDummy () ) continue; digi[i]->Reset(); @@ -253,13 +272,15 @@ void MainWindow::StartACQ(){ digi[i]->WriteValue("/ch/0..63/par/WaveAnalogProbe0", "ADCInput"); - //TODO =========================== save file - remove("haha_000.sol"); // remove file - digi[i]->OpenOutFile("haha");// haha_000.sol + if( chkSaveRun->isChecked() ){ + QString outFileName = rawDataFolder + "/" + expName + "_" + runIDStr+ "_" + QString::number(digi[i]->GetSerialNumber()); + qDebug() << outFileName; + digi[i]->OpenOutFile(outFileName.toStdString());// overwrite + } digi[i]->StartACQ(); //TODO ========================== Sync start. - readDataThread[i]->SetScopeRun(!chkSaveRun->isChecked ()); + readDataThread[i]->SetSaveData(chkSaveRun->isChecked()); readDataThread[i]->start(); } @@ -269,8 +290,8 @@ void MainWindow::StartACQ(){ bnStartACQ->setEnabled(false); bnStopACQ->setEnabled(true); bnOpenScope->setEnabled(false); + chkSaveRun->setEnabled(false); - LogMsg("end of " + QString::fromStdString(__func__)); } void MainWindow::StopACQ(){ @@ -279,22 +300,35 @@ void MainWindow::StopACQ(){ if( digi[i]->IsDummy () ) continue; digi[i]->StopACQ(); - readDataThread[i]->quit(); - readDataThread[i]->wait(); - digi[i]->CloseOutFile(); - + if( readDataThread[i]->isRunning()){ + readDataThread[i]->quit(); + readDataThread[i]->wait(); + } + if( chkSaveRun->isChecked() ) digi[i]->CloseOutFile(); } - scalarThread->Stop(); - scalarThread->quit(); - scalarThread->wait(); - - LogMsg("Stop Run"); + if( scalarThread->isRunning()){ + scalarThread->Stop(); + scalarThread->quit(); + scalarThread->wait(); + } + if( chkSaveRun->isChecked() ){ + LogMsg("=========================== Run-" + runIDStr + " stopped."); + }else{ + LogMsg("=========================== no-Save Run stopped."); + } bnStartACQ->setEnabled(true); bnStopACQ->setEnabled(false); bnOpenScope->setEnabled(true); + chkSaveRun->setEnabled(true); if( chkSaveRun->isChecked() ){ + + //TODO ============ stop comment + + + //TODO ============= elog + runID ++; leRunID->setText(QString::number(runID)); } @@ -324,10 +358,16 @@ void MainWindow::OpenDigitizers(){ bnStartACQ->setEnabled(true); bnStopACQ->setEnabled(false); bnOpenScope->setEnabled(true); + chkSaveRun->setEnabled(true); + bnOpenDigitizers->setEnabled(false); + bnOpenDigitizers->setStyleSheet(""); readDataThread[i] = new ReadDataThread(digi[i], this); connect(readDataThread[i], &ReadDataThread::sendMsg, this, &MainWindow::LogMsg); + SetUpScalar(); + bnOpenScalar->setEnabled(true); + }else{ digi[i]->SetDummy(i); LogMsg("Cannot open digitizer. Use a dummy with serial number " + QString::number(i) + " and " + QString::number(digi[i]->GetNChannels()) + " ch."); @@ -338,11 +378,7 @@ void MainWindow::OpenDigitizers(){ bnDigiSettings->setEnabled(true); bnCloseDigitizers->setEnabled(true); - bnOpenDigitizers->setEnabled(false); - bnOpenDigitizers->setStyleSheet(""); - SetUpScalar(); - bnOpenScalar->setEnabled(true); } void MainWindow::CloseDigitizers(){ @@ -380,6 +416,7 @@ void MainWindow::CloseDigitizers(){ bnStopACQ->setEnabled(false); bnOpenDigitizers->setFocus(); bnOpenScalar->setEnabled(false); + chkSaveRun->setEnabled(false); } @@ -421,7 +458,7 @@ void MainWindow::OpenScaler(){ void MainWindow::SetUpScalar(){ - scalar->setGeometry(0, 0, 10 + nDigi * 200, 800); + scalar->setGeometry(0, 0, 10 + nDigi * 230, 800); lbLastUpdateTime = new QLabel("Last update : "); lbLastUpdateTime->setAlignment(Qt::AlignCenter); @@ -505,7 +542,10 @@ void MainWindow::UpdateScalar(){ lbLastUpdateTime->setText("Last update: " + QDateTime::currentDateTime().toString("MM.dd hh:mm:ss")); + printf("++++++++++++++++++ influx %p\n", influx); if( influx ) influx->ClearDataPointsBuffer(); + std::string haha[MaxNumberOfChannel] = {""}; + double acceptRate[MaxNumberOfChannel] = {0}; ///===== Get trigger for all channel for( int iDigi = 0; iDigi < nDigi; iDigi ++ ){ @@ -521,8 +561,6 @@ void MainWindow::UpdateScalar(){ //=========== another method, directly readValue - std::string haha[MaxNumberOfChannel] = {""}; - double acceptRate[MaxNumberOfChannel] = {0}; digiMTX.lock(); for( int ch = 0; ch < digi[iDigi]->GetNChannels(); ch ++){ @@ -546,9 +584,11 @@ void MainWindow::UpdateScalar(){ } } - influx->WriteData(DatabaseName.toStdString()); - influx->ClearDataPointsBuffer(); - + if( influx ){ + //influx->PrintDataPoints(); + influx->WriteData(DatabaseName.toStdString()); + influx->ClearDataPointsBuffer(); + } } //^###################################################################### Program Settings @@ -778,12 +818,30 @@ void MainWindow::SetupInflux(){ influx = new InfluxDB(DatabaseIP.toStdString(), false); if( influx->TestingConnection() ){ - LogMsg("InfluxDB URL ("+ DatabaseIP + ") is Valid"); + LogMsg(" InfluxDB URL ("+ DatabaseIP + ") is Valid "); + + //==== chck database exist + std::vector databaseList = influx->GetDatabaseList(); + bool foundDatabase = false; + for( int i = 0; i < (int) databaseList.size(); i++){ + if( databaseList[i] == DatabaseName.toStdString() ) foundDatabase = true; + } + + if( foundDatabase ){ + LogMsg(" Database " + DatabaseName + " found."); + }else{ + LogMsg(" Database " + DatabaseName + " NOT found."); + delete influx; + influx = NULL; + } + }else{ LogMsg(" InfluxDB URL ("+ DatabaseIP + ") is NOT Valid "); delete influx; influx = NULL; } + }else{ + LogMsg("No database is provided."); } } diff --git a/mainwindow.h b/mainwindow.h index cc5efd0..29d5414 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -142,6 +142,7 @@ private: QString expName; QString rawDataFolder; unsigned int runID; + QString runIDStr; unsigned int elogID; }; diff --git a/manyThread.h b/manyThread.h index 31ada72..ac521db 100644 --- a/manyThread.h +++ b/manyThread.h @@ -15,9 +15,9 @@ class ReadDataThread : public QThread { public: ReadDataThread(Digitizer2Gen * dig, QObject * parent = 0) : QThread(parent){ this->digi = dig; - isScopeRun = false; + isSaveData = false; } - void SetScopeRun(bool onOff) {this->isScopeRun = onOff;} + void SetSaveData(bool onOff) {this->isSaveData = onOff;} void run(){ clock_gettime(CLOCK_REALTIME, &ta); while(true){ @@ -26,16 +26,16 @@ public: digiMTX.unlock(); if( ret == CAEN_FELib_Success){ - if( !isScopeRun) digi->SaveDataToFile(); + if( isSaveData) digi->SaveDataToFile(); }else if(ret == CAEN_FELib_Stop){ digi->ErrorMsg("No more data"); break; }else{ - //digi->ErrorMsg("ReadDataLoop()"); + digi->ErrorMsg("ReadDataLoop()"); digi->evt->ClearTrace(); } - if( !isScopeRun ){ + if( isSaveData ){ clock_gettime(CLOCK_REALTIME, &tb); if( tb.tv_sec - ta.tv_sec > 2 ) { emit sendMsg("FileSize : " + QString::number(digi->GetFileSize()/1024./1024.) + " MB"); @@ -52,7 +52,7 @@ signals: private: Digitizer2Gen * digi; timespec ta, tb; - bool isScopeRun; + bool isSaveData; }; //^#===================================================== UpdateTrace Thread diff --git a/scope.cpp b/scope.cpp index 7844717..8c2cef8 100644 --- a/scope.cpp +++ b/scope.cpp @@ -428,7 +428,7 @@ void Scope::StartScope(){ digi[iDigi]->StartACQ(); - readDataThread[iDigi]->SetScopeRun(true); + readDataThread[iDigi]->SetSaveData(false); readDataThread[iDigi]->start(); updateTraceThread->start(); diff --git a/test.cpp b/test.cpp index 5e71eb9..84833a6 100644 --- a/test.cpp +++ b/test.cpp @@ -92,7 +92,7 @@ int main(int argc, char* argv[]){ digi->Reset(); digi->ProgramPHA(false); - printf("--------%s \n", digi->ReadChValue(0, "WaveAnalogprobe0", true).c_str()); + printf("--------%s \n", digi->ReadChValue("0..63", "WaveAnalogprobe0", true).c_str()); //printf("%s \n", digi->ReadValue("/ch/0/par/ChRealtimeMonitor").c_str()); //printf("%s \n", digi->ReadValue("/ch/0/par/Energy_Nbit").c_str()); @@ -122,7 +122,7 @@ int main(int argc, char* argv[]){ printf("%s\n", digi->GetPath(parHandle).c_str()); */ -/* + digi->ReadDigitizerSettings(); digi->SetPHADataFormat(1); @@ -131,7 +131,6 @@ int main(int argc, char* argv[]){ digi->OpenOutFile("haha"); - digi->StartACQ(); timespec t0, t1; @@ -160,7 +159,6 @@ int main(int argc, char* argv[]){ digi->CloseOutFile(); -*/ digi->CloseDigitizer();