tested database

This commit is contained in:
Ryan Tang 2023-02-14 17:39:49 -05:00
parent 86dfc176af
commit 68e86fa379
9 changed files with 114 additions and 53 deletions

View File

@ -484,17 +484,17 @@ int Digitizer2Gen::ReadData(){
//########################################### //###########################################
void Digitizer2Gen::OpenOutFile(std::string fileName){ void Digitizer2Gen::OpenOutFile(std::string fileName, const char * mode){
outFileNameBase = fileName; outFileNameBase = fileName;
sprintf(outFileName, "%s_%03d.sol", fileName.c_str(), outFileIndex); sprintf(outFileName, "%s_%03d.sol", fileName.c_str(), outFileIndex);
outFile = fopen(outFileName, "a+"); outFile = fopen(outFileName, mode);
fseek(outFile, 0L, SEEK_END); fseek(outFile, 0L, SEEK_END);
outFileSize = ftell(outFile); // unsigned int = Max ~4GB outFileSize = ftell(outFile); // unsigned int = Max ~4GB
} }
void Digitizer2Gen::CloseOutFile(){ void Digitizer2Gen::CloseOutFile(){
fclose(outFile); if( outFile != NULL ) fclose(outFile);
} }
void Digitizer2Gen::SaveDataToFile(){ void Digitizer2Gen::SaveDataToFile(){

View File

@ -114,7 +114,7 @@ class Digitizer2Gen {
uint64_t GetHandle() const {return handle;} uint64_t GetHandle() const {return handle;}
Event *evt; // should be evt[MaxNumber], when full or stopACQ, save into file 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 CloseOutFile();
void SaveDataToFile(); void SaveDataToFile();
unsigned int GetFileSize() {return outFileSize;} unsigned int GetFileSize() {return outFileSize;}

View File

@ -5,27 +5,31 @@ InfluxDB::InfluxDB(std::string url, bool verbose){
curl = curl_easy_init(); curl = curl_easy_init();
if( verbose) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); if( verbose) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
this->databaseIP = url; SetURL(url);
respondCode = 0; respondCode = 0;
dataPoints = ""; dataPoints = "";
} }
InfluxDB::~InfluxDB(){ InfluxDB::~InfluxDB(){
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
} }
void InfluxDB::SetURL(std::string url){ void InfluxDB::SetURL(std::string url){
// check the last char of url is "/"
if( url.back() != '/') {
this->databaseIP = url + "/";
}else{
this->databaseIP = url; this->databaseIP = url;
}
} }
bool InfluxDB::TestingConnection(){ bool InfluxDB::TestingConnection(){
ShowDatabases(); CheckDatabases();
if( respond != CURLE_OK ) return false; if( respond != CURLE_OK ) return false;
return true; return true;
} }
std::string InfluxDB::ShowDatabases(){ std::string InfluxDB::CheckDatabases(){
curl_easy_setopt(curl, CURLOPT_POST, 1); curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_URL, (databaseIP + "/query").c_str()); curl_easy_setopt(curl, CURLOPT_URL, (databaseIP + "/query").c_str());
@ -126,7 +130,7 @@ void InfluxDB::PrintDataPoints(){
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_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<long>(dataPoints.length())); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast<long>(dataPoints.length()));
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, dataPoints.c_str()); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, dataPoints.c_str());
Execute(); Execute();

View File

@ -35,10 +35,10 @@ class InfluxDB{
bool IsURLValid() const {return isURLValid;} bool IsURLValid() const {return isURLValid;}
/// Query /// 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); 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<std::string> GetDatabaseList() {return databaseList;} std::vector<std::string> GetDatabaseList() {return databaseList;}
void CreateDatabase(std::string databaseName); void CreateDatabase(std::string databaseName);

View File

@ -145,8 +145,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
leRunID = new QLineEdit(this); leRunID = new QLineEdit(this);
leRunID->setAlignment(Qt::AlignHCenter); leRunID->setAlignment(Qt::AlignHCenter);
leRunID->setReadOnly(true); leRunID->setReadOnly(true);
leRunID->setStyleSheet("background-color: #F3F3F3;");
chkSaveRun = new QCheckBox("Save Run", this); chkSaveRun = new QCheckBox("Save Run", this);
chkSaveRun->setChecked(true);
chkSaveRun->setEnabled(false);
cbAutoRun = new QComboBox(this); cbAutoRun = new QComboBox(this);
cbAutoRun->addItem("Single Run"); cbAutoRun->addItem("Single Run");
@ -167,8 +170,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
QLabel * lbRunComment = new QLabel("Run Comment : ", this); QLabel * lbRunComment = new QLabel("Run Comment : ", this);
lbRunComment->setAlignment(Qt::AlignRight | Qt::AlignCenter); lbRunComment->setAlignment(Qt::AlignRight | Qt::AlignCenter);
QLineEdit * runComment = new QLineEdit(this); QLineEdit * leRunComment = new QLineEdit(this);
runComment->setReadOnly(true); leRunComment->setReadOnly(true);
leRunComment->setStyleSheet("background-color: #F3F3F3;");
layout2->addWidget(lbRawDataPath, 0, 0); layout2->addWidget(lbRawDataPath, 0, 0);
layout2->addWidget(leRawDataPath, 0, 1, 1, 4); layout2->addWidget(leRawDataPath, 0, 1, 1, 4);
@ -182,7 +186,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
layout2->addWidget(bnStopACQ, 1, 5); layout2->addWidget(bnStopACQ, 1, 5);
layout2->addWidget(lbRunComment, 2, 0); 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(0, 2);
layout2->setColumnStretch(1, 1); layout2->setColumnStretch(1, 1);
@ -229,6 +233,10 @@ MainWindow::~MainWindow(){
//delete logInfo; //delete logInfo;
printf("- %s\n", __func__); printf("- %s\n", __func__);
for( int i = 0; i < nDigi ; i++){
if( readDataThread[i]->isRunning()) StopACQ();
}
DeleteTriggerLineEdit(); DeleteTriggerLineEdit();
delete scalarThread; delete scalarThread;
CloseDigitizers(); CloseDigitizers();
@ -244,7 +252,18 @@ MainWindow::~MainWindow(){
//^################################################################ ACQ control //^################################################################ ACQ control
void MainWindow::StartACQ(){ void MainWindow::StartACQ(){
LogMsg("Start Run...."); if( chkSaveRun->isChecked() ){
runIDStr = QString::number(runID).rightJustified(3, '0');
LogMsg("=========================== Start <b><font style=\"color : red;\">Run-" + runIDStr + "</font></b>");
//TODO ============ start comment
//TODO ============ elog
//TODO ============ update expName.sh
}else{
LogMsg("=========================== Start no-save Run");
}
for( int i =0 ; i < nDigi; i ++){ for( int i =0 ; i < nDigi; i ++){
if( digi[i]->IsDummy () ) continue; if( digi[i]->IsDummy () ) continue;
digi[i]->Reset(); digi[i]->Reset();
@ -253,13 +272,15 @@ void MainWindow::StartACQ(){
digi[i]->WriteValue("/ch/0..63/par/WaveAnalogProbe0", "ADCInput"); digi[i]->WriteValue("/ch/0..63/par/WaveAnalogProbe0", "ADCInput");
//TODO =========================== save file if( chkSaveRun->isChecked() ){
remove("haha_000.sol"); // remove file QString outFileName = rawDataFolder + "/" + expName + "_" + runIDStr+ "_" + QString::number(digi[i]->GetSerialNumber());
digi[i]->OpenOutFile("haha");// haha_000.sol qDebug() << outFileName;
digi[i]->OpenOutFile(outFileName.toStdString());// overwrite
}
digi[i]->StartACQ(); digi[i]->StartACQ();
//TODO ========================== Sync start. //TODO ========================== Sync start.
readDataThread[i]->SetScopeRun(!chkSaveRun->isChecked ()); readDataThread[i]->SetSaveData(chkSaveRun->isChecked());
readDataThread[i]->start(); readDataThread[i]->start();
} }
@ -269,8 +290,8 @@ void MainWindow::StartACQ(){
bnStartACQ->setEnabled(false); bnStartACQ->setEnabled(false);
bnStopACQ->setEnabled(true); bnStopACQ->setEnabled(true);
bnOpenScope->setEnabled(false); bnOpenScope->setEnabled(false);
chkSaveRun->setEnabled(false);
LogMsg("end of " + QString::fromStdString(__func__));
} }
void MainWindow::StopACQ(){ void MainWindow::StopACQ(){
@ -279,22 +300,35 @@ void MainWindow::StopACQ(){
if( digi[i]->IsDummy () ) continue; if( digi[i]->IsDummy () ) continue;
digi[i]->StopACQ(); digi[i]->StopACQ();
if( readDataThread[i]->isRunning()){
readDataThread[i]->quit(); readDataThread[i]->quit();
readDataThread[i]->wait(); readDataThread[i]->wait();
digi[i]->CloseOutFile(); }
if( chkSaveRun->isChecked() ) digi[i]->CloseOutFile();
} }
if( scalarThread->isRunning()){
scalarThread->Stop(); scalarThread->Stop();
scalarThread->quit(); scalarThread->quit();
scalarThread->wait(); scalarThread->wait();
}
LogMsg("Stop Run"); if( chkSaveRun->isChecked() ){
LogMsg("=========================== <b><font style=\"color : red;\">Run-" + runIDStr + "</font></b> stopped.");
}else{
LogMsg("=========================== no-Save Run stopped.");
}
bnStartACQ->setEnabled(true); bnStartACQ->setEnabled(true);
bnStopACQ->setEnabled(false); bnStopACQ->setEnabled(false);
bnOpenScope->setEnabled(true); bnOpenScope->setEnabled(true);
chkSaveRun->setEnabled(true);
if( chkSaveRun->isChecked() ){ if( chkSaveRun->isChecked() ){
//TODO ============ stop comment
//TODO ============= elog
runID ++; runID ++;
leRunID->setText(QString::number(runID)); leRunID->setText(QString::number(runID));
} }
@ -324,10 +358,16 @@ void MainWindow::OpenDigitizers(){
bnStartACQ->setEnabled(true); bnStartACQ->setEnabled(true);
bnStopACQ->setEnabled(false); bnStopACQ->setEnabled(false);
bnOpenScope->setEnabled(true); bnOpenScope->setEnabled(true);
chkSaveRun->setEnabled(true);
bnOpenDigitizers->setEnabled(false);
bnOpenDigitizers->setStyleSheet("");
readDataThread[i] = new ReadDataThread(digi[i], this); readDataThread[i] = new ReadDataThread(digi[i], this);
connect(readDataThread[i], &ReadDataThread::sendMsg, this, &MainWindow::LogMsg); connect(readDataThread[i], &ReadDataThread::sendMsg, this, &MainWindow::LogMsg);
SetUpScalar();
bnOpenScalar->setEnabled(true);
}else{ }else{
digi[i]->SetDummy(i); digi[i]->SetDummy(i);
LogMsg("Cannot open digitizer. Use a dummy with serial number " + QString::number(i) + " and " + QString::number(digi[i]->GetNChannels()) + " ch."); 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); bnDigiSettings->setEnabled(true);
bnCloseDigitizers->setEnabled(true); bnCloseDigitizers->setEnabled(true);
bnOpenDigitizers->setEnabled(false);
bnOpenDigitizers->setStyleSheet("");
SetUpScalar();
bnOpenScalar->setEnabled(true);
} }
void MainWindow::CloseDigitizers(){ void MainWindow::CloseDigitizers(){
@ -380,6 +416,7 @@ void MainWindow::CloseDigitizers(){
bnStopACQ->setEnabled(false); bnStopACQ->setEnabled(false);
bnOpenDigitizers->setFocus(); bnOpenDigitizers->setFocus();
bnOpenScalar->setEnabled(false); bnOpenScalar->setEnabled(false);
chkSaveRun->setEnabled(false);
} }
@ -421,7 +458,7 @@ void MainWindow::OpenScaler(){
void MainWindow::SetUpScalar(){ 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 = new QLabel("Last update : ");
lbLastUpdateTime->setAlignment(Qt::AlignCenter); lbLastUpdateTime->setAlignment(Qt::AlignCenter);
@ -505,7 +542,10 @@ void MainWindow::UpdateScalar(){
lbLastUpdateTime->setText("Last update: " + QDateTime::currentDateTime().toString("MM.dd hh:mm:ss")); lbLastUpdateTime->setText("Last update: " + QDateTime::currentDateTime().toString("MM.dd hh:mm:ss"));
printf("++++++++++++++++++ influx %p\n", influx);
if( influx ) influx->ClearDataPointsBuffer(); if( influx ) influx->ClearDataPointsBuffer();
std::string haha[MaxNumberOfChannel] = {""};
double acceptRate[MaxNumberOfChannel] = {0};
///===== Get trigger for all channel ///===== Get trigger for all channel
for( int iDigi = 0; iDigi < nDigi; iDigi ++ ){ for( int iDigi = 0; iDigi < nDigi; iDigi ++ ){
@ -521,8 +561,6 @@ void MainWindow::UpdateScalar(){
//=========== another method, directly readValue //=========== another method, directly readValue
std::string haha[MaxNumberOfChannel] = {""};
double acceptRate[MaxNumberOfChannel] = {0};
digiMTX.lock(); digiMTX.lock();
for( int ch = 0; ch < digi[iDigi]->GetNChannels(); ch ++){ for( int ch = 0; ch < digi[iDigi]->GetNChannels(); ch ++){
@ -546,9 +584,11 @@ void MainWindow::UpdateScalar(){
} }
} }
if( influx ){
//influx->PrintDataPoints();
influx->WriteData(DatabaseName.toStdString()); influx->WriteData(DatabaseName.toStdString());
influx->ClearDataPointsBuffer(); influx->ClearDataPointsBuffer();
}
} }
//^###################################################################### Program Settings //^###################################################################### Program Settings
@ -778,12 +818,30 @@ void MainWindow::SetupInflux(){
influx = new InfluxDB(DatabaseIP.toStdString(), false); influx = new InfluxDB(DatabaseIP.toStdString(), false);
if( influx->TestingConnection() ){ if( influx->TestingConnection() ){
LogMsg("InfluxDB URL (<b>"+ DatabaseIP + "</b>) is Valid"); LogMsg("<font style=\"color : green;\"> InfluxDB URL (<b>"+ DatabaseIP + "</b>) is Valid </font>");
//==== chck database exist
std::vector<std::string> 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("<font style=\"color : green;\"> Database <b>" + DatabaseName + "</b> found.");
}else{
LogMsg("<font style=\"color : red;\"> Database <b>" + DatabaseName + "</b> NOT found.");
delete influx;
influx = NULL;
}
}else{ }else{
LogMsg("<font style=\"color : red;\"> InfluxDB URL (<b>"+ DatabaseIP + "</b>) is NOT Valid </font>"); LogMsg("<font style=\"color : red;\"> InfluxDB URL (<b>"+ DatabaseIP + "</b>) is NOT Valid </font>");
delete influx; delete influx;
influx = NULL; influx = NULL;
} }
}else{
LogMsg("No database is provided.");
} }
} }

View File

@ -142,6 +142,7 @@ private:
QString expName; QString expName;
QString rawDataFolder; QString rawDataFolder;
unsigned int runID; unsigned int runID;
QString runIDStr;
unsigned int elogID; unsigned int elogID;
}; };

View File

@ -15,9 +15,9 @@ class ReadDataThread : public QThread {
public: public:
ReadDataThread(Digitizer2Gen * dig, QObject * parent = 0) : QThread(parent){ ReadDataThread(Digitizer2Gen * dig, QObject * parent = 0) : QThread(parent){
this->digi = dig; this->digi = dig;
isScopeRun = false; isSaveData = false;
} }
void SetScopeRun(bool onOff) {this->isScopeRun = onOff;} void SetSaveData(bool onOff) {this->isSaveData = onOff;}
void run(){ void run(){
clock_gettime(CLOCK_REALTIME, &ta); clock_gettime(CLOCK_REALTIME, &ta);
while(true){ while(true){
@ -26,16 +26,16 @@ public:
digiMTX.unlock(); digiMTX.unlock();
if( ret == CAEN_FELib_Success){ if( ret == CAEN_FELib_Success){
if( !isScopeRun) digi->SaveDataToFile(); if( isSaveData) digi->SaveDataToFile();
}else if(ret == CAEN_FELib_Stop){ }else if(ret == CAEN_FELib_Stop){
digi->ErrorMsg("No more data"); digi->ErrorMsg("No more data");
break; break;
}else{ }else{
//digi->ErrorMsg("ReadDataLoop()"); digi->ErrorMsg("ReadDataLoop()");
digi->evt->ClearTrace(); digi->evt->ClearTrace();
} }
if( !isScopeRun ){ if( isSaveData ){
clock_gettime(CLOCK_REALTIME, &tb); clock_gettime(CLOCK_REALTIME, &tb);
if( tb.tv_sec - ta.tv_sec > 2 ) { if( tb.tv_sec - ta.tv_sec > 2 ) {
emit sendMsg("FileSize : " + QString::number(digi->GetFileSize()/1024./1024.) + " MB"); emit sendMsg("FileSize : " + QString::number(digi->GetFileSize()/1024./1024.) + " MB");
@ -52,7 +52,7 @@ signals:
private: private:
Digitizer2Gen * digi; Digitizer2Gen * digi;
timespec ta, tb; timespec ta, tb;
bool isScopeRun; bool isSaveData;
}; };
//^#===================================================== UpdateTrace Thread //^#===================================================== UpdateTrace Thread

View File

@ -428,7 +428,7 @@ void Scope::StartScope(){
digi[iDigi]->StartACQ(); digi[iDigi]->StartACQ();
readDataThread[iDigi]->SetScopeRun(true); readDataThread[iDigi]->SetSaveData(false);
readDataThread[iDigi]->start(); readDataThread[iDigi]->start();
updateTraceThread->start(); updateTraceThread->start();

View File

@ -92,7 +92,7 @@ int main(int argc, char* argv[]){
digi->Reset(); digi->Reset();
digi->ProgramPHA(false); 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/ChRealtimeMonitor").c_str());
//printf("%s \n", digi->ReadValue("/ch/0/par/Energy_Nbit").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()); printf("%s\n", digi->GetPath(parHandle).c_str());
*/ */
/*
digi->ReadDigitizerSettings(); digi->ReadDigitizerSettings();
digi->SetPHADataFormat(1); digi->SetPHADataFormat(1);
@ -131,7 +131,6 @@ int main(int argc, char* argv[]){
digi->OpenOutFile("haha"); digi->OpenOutFile("haha");
digi->StartACQ(); digi->StartACQ();
timespec t0, t1; timespec t0, t1;
@ -160,7 +159,6 @@ int main(int argc, char* argv[]){
digi->CloseOutFile(); digi->CloseOutFile();
*/
digi->CloseDigitizer(); digi->CloseDigitizer();