testes many things with pulser (except backward event building). All parts looks good at 10 Hz

This commit is contained in:
splitPoleDAQ 2023-06-20 11:57:39 -04:00
parent 33e2a7ee56
commit d246bb8dcf
15 changed files with 514 additions and 442 deletions

View File

@ -11,6 +11,9 @@ Analyzer::Analyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent )
setWindowTitle("Online Analyzer");
setGeometry(0, 0, 1000, 800);
influx = nullptr;
dataBaseName = "";
mb = new MultiBuilder(digi, nDigi);
buildTimerThread = new TimingThread(this);
@ -28,7 +31,7 @@ Analyzer::Analyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent )
}
Analyzer::~Analyzer(){
delete influx;
delete mb;
}
@ -51,15 +54,15 @@ void Analyzer::StopThread(){
void Analyzer::BuildEvents(){
void Analyzer::BuildEvents(bool verbose){
unsigned int nData = mb->GetNumOfDigitizer();
std::vector<int> idList = mb->GetDigiIDList();
for( unsigned int i = 0; i < nData; i++ ) digiMTX[idList[i]].lock();
if( isBuildBackward ){
mb->BuildEventsBackWard(0);
mb->BuildEventsBackWard(maxNumEventBuilt, verbose);
}else{
mb->BuildEvents(0, 0, 0);
mb->BuildEvents(0, 0, verbose);
}
for( unsigned int i = 0; i < nData; i++ ) digiMTX[idList[i]].unlock();

View File

@ -15,8 +15,8 @@
#include "ClassDigitizer.h"
#include "CustomThreads.h"
#include "CustomWidgets.h"
//#include "OnlineEventBuilder.h"
#include "MultiBuilder.h"
#include "influxdb.h"
/**************************************
@ -46,7 +46,7 @@ public:
MultiBuilder * GetEventBuilder() { return mb;}
void RedefineEventBuilder(std::vector<int> idList);
void SetBackwardBuild(bool TF) { isBuildBackward = TF;}
void SetBackwardBuild(bool TF, int maxNumEvent = 100) { isBuildBackward = TF; maxNumEventBuilt = maxNumEvent;}
public slots:
void StartThread();
@ -58,9 +58,12 @@ private slots:
protected:
QGridLayout * layout;
void BuildEvents();
void BuildEvents(bool verbose = false);
void SetUpdateTimeInSec(double sec = 1.0) {waitTimeinSec = sec; buildTimerThread->SetWaitTimeinSec(waitTimeinSec);}
InfluxDB * influx;
std::string dataBaseName;
private:
Digitizer ** digi;
unsigned short nDigi;
@ -69,7 +72,9 @@ private:
MultiBuilder * mb;
bool isBuildBackward;
int maxNumEventBuilt;
TimingThread * buildTimerThread;
};
#endif

View File

@ -23,7 +23,7 @@ class Data{
int DPPType;
std::string DPPTypeStr;
unsigned short boardSN;
float ch2ns; /// only use in TriggerRate calculation
float tick2ns; /// only use in TriggerRate calculation
unsigned int nByte; /// number of byte from read buffer
uint32_t AllocatedSize;
@ -42,7 +42,7 @@ class Data{
int DataIndex[MaxNChannels];
unsigned long long Timestamp[MaxNChannels][MaxNData]; /// 47 bit
unsigned short fineTime[MaxNChannels][MaxNData]; /// 10 bits, in unit of ch2ns / 1000 = ps
unsigned short fineTime[MaxNChannels][MaxNData]; /// 10 bits, in unit of tick2ns / 1000 = ps
unsigned short Energy[MaxNChannels][MaxNData]; /// 15 bit
unsigned short Energy2[MaxNChannels][MaxNData]; /// 15 bit, in PSD, Energy = Qshort, Energy2 = Qlong
bool PileUp[MaxNChannels][MaxNData]; /// pile up flag
@ -113,7 +113,7 @@ class Data{
//==========================================
inline Data::Data(){
ch2ns = 2.0;
tick2ns = 2.0;
boardSN = 0;
DPPType = V1730_DPP_PHA_CODE;
DPPTypeStr = "";
@ -414,7 +414,7 @@ inline void Data::DecodeBuffer(bool fastDecode, int verbose){
//printf("%d %d| %d %d \n", DataIndex[ch], NumEventsDecoded[ch], indexStart, DataIndex[ch] );
unsigned long long dTime = Timestamp[ch][DataIndex[ch]] - Timestamp[ch][indexStart];
double sec = dTime * ch2ns / 1e9;
double sec = dTime * tick2ns / 1e9;
TriggerRate[ch] = NumEventsDecoded[ch]/sec;
NonPileUpRate[ch] = NumNonPileUpDecoded[ch]/sec;
@ -430,9 +430,9 @@ inline void Data::DecodeBuffer(bool fastDecode, int verbose){
if( calIndexes[ch][0] > -1 && calIndexes[ch][1] > -1 && nEvent > 10 ){
unsigned long long dTime = Timestamp[ch][calIndexes[ch][1]] - Timestamp[ch][calIndexes[ch][0]];
double sec = dTime * ch2ns / 1e9;
double sec = dTime * tick2ns / 1e9;
//printf(" %10llu %10llu, %f = %f sec, rate = %f \n", Timestamp[ch][calIndexes[ch][0]], Timestamp[ch][calIndexes[ch][1]], ch2ns, sec, nEvent / sec);
//printf(" %10llu %10llu, %f = %f sec, rate = %f \n", Timestamp[ch][calIndexes[ch][0]], Timestamp[ch][calIndexes[ch][1]], tick2ns, sec, nEvent / sec);
TriggerRate[ch] = nEvent / sec;

View File

@ -25,7 +25,7 @@ void Digitizer::Initalization(){
ADCbits = 1;
DPPType = 0;
ADCFullSize = 0;
ch2ns = 0;
tick2ns = 0;
BoardInfo = {};
channelMask = 0xFFFF;
@ -59,7 +59,7 @@ void Digitizer::Reset(){
void Digitizer::PrintBoard (){
printf("Connected to Model %s with handle %d using %s\n", BoardInfo.ModelName, handle, LinkType == CAEN_DGTZ_USB ? "USB" : "Optical Link");
printf("Sampling rate : %.0f MHz = %.1f ns \n", 1000/ch2ns, ch2ns);
printf("Sampling rate : %.0f MHz = %.1f ns \n", 1000/tick2ns, tick2ns);
printf("Number of Channels : %d = 0x%X\n", NChannel, channelMask);
printf("SerialNumber :\e[1m\e[33m %d\e[0m\n", BoardInfo.SerialNumber);
printf("DPPType : %d (%s)\n", DPPType, GetDPPString().c_str());
@ -103,11 +103,11 @@ int Digitizer::OpenDigitizer(int boardID, int portID, bool program, bool verbose
NChannel = BoardInfo.Channels;
channelMask = pow(2, NChannel)-1;
switch(BoardInfo.Model){
case CAEN_DGTZ_V1730: ch2ns = 2.0; break; ///ns -> 500 MSamples/s
case CAEN_DGTZ_V1725: ch2ns = 4.0; break; ///ns -> 250 MSamples/s
default : ch2ns = 4.0; break;
case CAEN_DGTZ_V1730: tick2ns = 2.0; break; ///ns -> 500 MSamples/s
case CAEN_DGTZ_V1725: tick2ns = 4.0; break; ///ns -> 250 MSamples/s
default : tick2ns = 4.0; break;
}
data->ch2ns = ch2ns;
data->tick2ns = tick2ns;
data->boardSN = BoardInfo.SerialNumber;
ADCbits = BoardInfo.ADC_NBits;
ADCFullSize = (unsigned int)( pow(2, ADCbits) -1 );
@ -739,8 +739,8 @@ int Digitizer::LoadSettingBinaryToMemory(std::string fileName){
if( dummy != 0 ) printf("reach the end of file (read %ld).\n", dummy);
uint32_t boardInfo = GetSettingFromMemory(DPP::BoardInfo_R);
if( (boardInfo & 0xFF) == 0x0E ) ch2ns = 4.0;
if( (boardInfo & 0xFF) == 0x0B ) ch2ns = 2.0;
if( (boardInfo & 0xFF) == 0x0E ) tick2ns = 4.0;
if( (boardInfo & 0xFF) == 0x0B ) tick2ns = 2.0;
///Should seperate file<->memory, memory<->board
///ProgramSettingsToBoard(); /// do nothing if not connected.

View File

@ -31,7 +31,7 @@ class Digitizer{
int ADCbits; /// ADC bit
int DPPType; /// DPP verion
unsigned int ADCFullSize; /// pow(2, ADCbits) - 1
float ch2ns; /// channel to ns
float tick2ns; /// channel to ns
CAEN_DGTZ_BoardInfo_t BoardInfo;
//^----- adjustable parameters
@ -105,7 +105,7 @@ class Digitizer{
int GetSerialNumber() const {return BoardInfo.SerialNumber;}
int GetChannelMask() { channelMask = GetSettingFromMemory(DPP::ChannelEnableMask); return channelMask;}
bool GetChannelOnOff(unsigned ch) { channelMask = GetSettingFromMemory(DPP::ChannelEnableMask); return (channelMask & ( 1 << ch) );}
float GetCh2ns() const {return ch2ns;}
float GetTick2ns() const {return tick2ns;}
int GetNChannels() const {return NChannel;}
int GetHandle() const {return handle;}
int GetDPPType() const {return DPPType;}

View File

@ -74,7 +74,7 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr
SetUpInfo( "S/N No. ", std::to_string(digi[ID]->GetSerialNumber()), infoLayout[ID], 1, 0);
SetUpInfo( "No. Ch. ", std::to_string(digi[ID]->GetNChannels()), infoLayout[ID], 1, 2);
SetUpInfo("Sampling Rate ", std::to_string((int) digi[ID]->GetCh2ns()) + " ns = " + std::to_string( (int) (1000/digi[ID]->GetCh2ns())) + " MHz" , infoLayout[ID], 1, 4);
SetUpInfo("Sampling Rate ", std::to_string((int) digi[ID]->GetTick2ns()) + " ns = " + std::to_string( (int) (1000/digi[ID]->GetTick2ns())) + " MHz" , infoLayout[ID], 1, 4);
SetUpInfo("ADC bit ", std::to_string(digi[ID]->GetADCBits()), infoLayout[ID], 2, 0);
SetUpInfo("ROC version ", digi[ID]->GetROCVersion(), infoLayout[ID], 2, 2);
@ -733,8 +733,8 @@ void DigiSettingsPanel::SetUpSpinBox(RSpinBox * &sb, QString label, QGridLayout
sb->setSingleStep(1);
sb->setMaximum(para.GetMaxBit());
}else{
sb->setMaximum(para.GetMaxBit() * para.GetPartialStep() * digi[ID]->GetCh2ns());
sb->setSingleStep(para.GetPartialStep() * digi[ID]->GetCh2ns());
sb->setMaximum(para.GetMaxBit() * para.GetPartialStep() * digi[ID]->GetTick2ns());
sb->setSingleStep(para.GetPartialStep() * digi[ID]->GetTick2ns());
}
if( para == DPP::DPPAlgorithmControl ) {
@ -770,7 +770,7 @@ void DigiSettingsPanel::SetUpSpinBox(RSpinBox * &sb, QString label, QGridLayout
}
if( para == DPP::PSD::CFDSetting ){
digi[ID]->SetBits(para, DPP::PSD::Bit_CFDSetting::CFDDealy, sb->value()/digi[ID]->GetCh2ns(), chID);
digi[ID]->SetBits(para, DPP::PSD::Bit_CFDSetting::CFDDealy, sb->value()/digi[ID]->GetTick2ns(), chID);
UpdatePanelFromMemory();
emit UpdateOtherPanels();
return;
@ -783,7 +783,7 @@ void DigiSettingsPanel::SetUpSpinBox(RSpinBox * &sb, QString label, QGridLayout
return;
}
uint32_t bit = para.GetPartialStep() == -1 ? sb->value() : sb->value() / para.GetPartialStep() / digi[ID]->GetCh2ns();
uint32_t bit = para.GetPartialStep() == -1 ? sb->value() : sb->value() / para.GetPartialStep() / digi[ID]->GetTick2ns();
digi[ID]->WriteRegister(para, bit, chID);
if( para.IsCoupled() == true && chID >= 0 ) digi[ID]->WriteRegister(para, bit, chID%2 == 0 ? chID + 1 : chID - 1);
@ -964,8 +964,8 @@ void DigiSettingsPanel::SetUpGlobalTriggerMaskAndFrontPanelMask(QGridLayout * &
sbGlbMajCoinWin[ID] = new RSpinBox(this);
sbGlbMajCoinWin[ID]->setMinimum(0);
sbGlbMajCoinWin[ID]->setMaximum(0xF * 4 * digi[ID]->GetCh2ns() );
sbGlbMajCoinWin[ID]->setSingleStep(4 * digi[ID]->GetCh2ns());
sbGlbMajCoinWin[ID]->setMaximum(0xF * 4 * digi[ID]->GetTick2ns() );
sbGlbMajCoinWin[ID]->setSingleStep(4 * digi[ID]->GetTick2ns());
maskLayout->addWidget(sbGlbMajCoinWin[ID], 1, 10);
connect(sbGlbMajCoinWin[ID], &RSpinBox::valueChanged, this, [=](){
if( !enableSignalSlot ) return;
@ -982,7 +982,7 @@ void DigiSettingsPanel::SetUpGlobalTriggerMaskAndFrontPanelMask(QGridLayout * &
}
sbGlbMajCoinWin[ID]->setStyleSheet("");
digi[ID]->SetBits(DPP::GlobalTriggerMask, DPP::Bit_GlobalTriggerMask::MajorCoinWin, sbGlbMajCoinWin[ID]->value() / 4 / digi[ID]->GetCh2ns(), -1);
digi[ID]->SetBits(DPP::GlobalTriggerMask, DPP::Bit_GlobalTriggerMask::MajorCoinWin, sbGlbMajCoinWin[ID]->value() / 4 / digi[ID]->GetTick2ns(), -1);
});
//*============================================
@ -2581,7 +2581,7 @@ void DigiSettingsPanel::UpdatePanelFromMemory(){
//&###########################################################
void DigiSettingsPanel::UpdateSpinBox(RSpinBox * &sb, Reg para, int ch){
int ch2ns = digi[ID]->GetCh2ns();
int tick2ns = digi[ID]->GetTick2ns();
int pStep = para.GetPartialStep();
uint32_t value = digi[ID]->GetSettingFromMemory(para, ch);
@ -2593,7 +2593,7 @@ void DigiSettingsPanel::UpdateSpinBox(RSpinBox * &sb, Reg para, int ch){
}
if( para == DPP::PSD::CFDSetting ){
sb->setValue( ( value & DPP::PSD::CFDSetting.GetMaxBit() ) * ch2ns );
sb->setValue( ( value & DPP::PSD::CFDSetting.GetMaxBit() ) * tick2ns );
return;
}
@ -2602,9 +2602,9 @@ void DigiSettingsPanel::UpdateSpinBox(RSpinBox * &sb, Reg para, int ch){
return;
}
sb->setValue( pStep > 0 ? value * pStep * ch2ns : value);
sb->setValue( pStep > 0 ? value * pStep * tick2ns : value);
//printf("%d, %s | %d %d %u, %f\n", para.GetNameChar(), ch, ch2ns, pStep, value, sb->value());
//printf("%d, %s | %d %d %u, %f\n", para.GetNameChar(), ch, tick2ns, pStep, value, sb->value());
}

View File

@ -136,143 +136,7 @@ public:
}
//^================= right click
if (event->button() == Qt::RightButton) {
usingMenu = true;
setSelectionRectMode(QCP::SelectionRectMode::srmNone);
QMenu *menu = new QMenu(this);
menu->setAttribute(Qt::WA_DeleteOnClose);
QAction * a1 = menu->addAction("UnZoom");
QAction * a2 = menu->addAction("Clear hist.");
QAction * a3 = menu->addAction("Toggle Stat.");
QAction * a4 = menu->addAction("Rebin (clear histogram)");
QAction * a5 = menu->addAction("Create a Cut");
if( numCut > 0 ) {
menu->addSeparator();
menu->addAction("Add/Edit names to Cuts");
menu->addAction("Clear all Cuts");
}
for( int i = 0; i < cutList.size(); i++){
if( cutList[i].isEmpty()) continue;
QString haha = "";
menu->addAction("Delete " + cutNameList[i] + " ["+ colorCycle[cutIDList[i]%colorCycle.count()].second+"]");
}
QAction *selectedAction = menu->exec(event->globalPosition().toPoint());
if( selectedAction == a1 ){
xAxis->setRangeLower(xMin);
xAxis->setRangeUpper(xMax);
yAxis->setRangeLower(yMin);
yAxis->setRangeUpper(yMax);
replot();
usingMenu = false;
return;
}
if( selectedAction == a2 ) {
Clear();
usingMenu = false;
return;
}
if( selectedAction == a3 ){
for( int i = 0; i < 3; i ++ ){
for( int j = 0; j < 3; j ++ ){
box[i][j]->setVisible( !box[i][j]->visible());
txt[i][j]->setVisible( !txt[i][j]->visible());
}
}
replot();
usingMenu = false;
return;
}
if( selectedAction == a4){
rightMouseClickRebin();
usingMenu = false;
return;
}
if( selectedAction == a5 ){
tempCut.clear();
tempCutID ++;
isDrawCut= true;
usingMenu = false;
numCut ++;
return;
}
if( selectedAction && numCut > 0 && selectedAction->text().contains("Delete ") ){
QString haha = selectedAction->text();
int index1 = haha.indexOf("-");
int index2 = haha.indexOf("[");
int cutID = haha.mid(index1+1, index2-index1-1).remove(' ').toInt();
removeItem(cutTextIDList[cutID]);
removePlottable(plottableIDList[cutID]);
replot();
numCut --;
cutList[cutID].clear();
cutIDList[cutID] = -1;
cutTextIDList[cutID] = -1;
plottableIDList[cutID] = -1;
cutNameList[cutID] = "";
cutEntryList[cutID] = -1;
for( int i = cutID + 1; i < cutTextIDList.count() ; i++){
cutTextIDList[i] --;
plottableIDList[i] --;
}
if( numCut == 0 ){
tempCutID = -1;
lastPlottableID = -1;
cutList.clear();
cutIDList.clear();
cutTextIDList.clear();
plottableIDList.clear();
cutNameList.clear();
cutEntryList.clear();
}
return;
}
if( selectedAction && numCut > 0 && selectedAction->text().contains("Clear all Cuts") ){
ClearAllCuts();
return;
}
if( selectedAction && numCut > 0 && selectedAction->text().contains("Add/Edit names to Cuts") ){
QDialog dialog(this);
dialog.setWindowTitle("Add/Edit name of cuts ");
QFormLayout layout(&dialog);
for(int i = 0; i < cutTextIDList.count(); i++){
if( cutTextIDList[i] < 0 ) continue;
QLineEdit * le = new QLineEdit(&dialog);
layout.addRow(colorCycle[i%colorCycle.count()].second, le);
le->setText( cutNameList[i] );
connect(le, &QLineEdit::textChanged, this, [=](){
le->setStyleSheet("color : blue;");
});
connect(le, &QLineEdit::returnPressed, this, [=](){
le->setStyleSheet("");
cutNameList[i] = le->text();
((QCPItemText *) this->item(cutTextIDList[i]))->setText(le->text());
replot();
});
}
dialog.exec();
return;
}
}///================= end of right click
if (event->button() == Qt::RightButton) rightMouseClickMenu(event);
});
//connect( this, &QCustomPlot::mouseDoubleClick, this, [=](QMouseEvent *event){
@ -310,134 +174,26 @@ public:
connect(this, &QCustomPlot::mouseRelease, this, [=](){
});
}
//^===================================
void Rebin(int xbin, double xmin, double xmax, int ybin, double ymin, double ymax){
xMin = xmin;
xMax = xmax;
yMin = ymin;
yMax = ymax;
xBin = xbin;
yBin = ybin;
void Rebin(int xbin, double xmin, double xmax, int ybin, double ymin, double ymax);
colorMap->data()->clear();
colorMap->data()->setSize(xBin, yBin);
colorMap->data()->setRange(QCPRange(xMin, xMax), QCPRange(yMin, yMax));
void UpdatePlot(){ colorMap->rescaleDataRange(); replot(); }
for( int i = 0; i < 3; i ++){
for( int j = 0; j < 3; j ++){
entry[i][j] = 0;
if( txt[i][j] ) txt[i][j]->setText("0");
}
}
void Clear(); // Clear Data and histrogram
}
void Fill(double x, double y);
void UpdatePlot(){
colorMap->rescaleDataRange();
//rescaleAxes();
replot();
}
void Clear(){
for( int i = 0; i < 3; i ++){
for( int j = 0; j < 3; j ++){
entry[i][j] = 0;
txt[i][j]->setText("0");
}
}
colorMap->data()->clear();
UpdatePlot();
}
void Fill(double x, double y){
if( isBusy ) return;
int xIndex, yIndex;
colorMap->data()->coordToCell(x, y, &xIndex, &yIndex);
//printf("%f, %d %d| %f, %d %d\n", x, xIndex, xBin, y, yIndex, yBin);
int xk = 1, yk = 1;
if( xIndex < 0 ) xk = 0;
if( xIndex >= xBin ) xk = 2;
if( yIndex < 0 ) yk = 0;
if( yIndex >= yBin ) yk = 2;
entry[xk][yk] ++;
txt[xk][yk]->setText(QString::number(entry[xk][yk]));
if( xk == 1 && yk == 1 ) {
double value = colorMap->data()->cell(xIndex, yIndex);
colorMap->data()->setCell(xIndex, yIndex, value + 1);
for( int i = 0; i < cutList.count(); i++){
if( cutList[i].isEmpty() ) continue;
if( cutList[i].containsPoint(QPointF(x,y), Qt::OddEvenFill) ) cutEntryList[i] ++;
}
}
}
void DrawCut(){
//The histogram is the 1st plottable.
// the lastPlottableID should be numCut+ 1
if( lastPlottableID != numCut ){
removePlottable(lastPlottableID);
}
if(tempCut.size() > 0) {
QCPCurve *polygon = new QCPCurve(xAxis, yAxis);
lastPlottableID = plottableCount() - 1;
int colorID = tempCutID% colorCycle.count();
QPen pen(colorCycle[colorID].first);
pen.setWidth(1);
polygon->setPen(pen);
QVector<QCPCurveData> dataPoints;
for (const QPointF& point : tempCut) {
dataPoints.append(QCPCurveData(dataPoints.size(), point.x(), point.y()));
}
polygon->data()->set(dataPoints, false);
}
replot();
//qDebug() << "Plottable count : " << plottableCount() << ", cutList.count :" << cutList.count() << ", cutID :" << lastPlottableID;
}
void ClearAllCuts(){
numCut = 0;
tempCutID = -1;
lastPlottableID = -1;
cutList.clear();
cutIDList.clear();
for( int i = cutTextIDList.count() - 1; i >= 0 ; i--){
if( cutTextIDList[i] < 0 ) continue;
removeItem(cutTextIDList[i]);
removePlottable(plottableIDList[i]);
}
replot();
cutTextIDList.clear();
plottableIDList.clear();
cutNameList.clear();
cutEntryList.clear();
}
void DrawCut();
void ClearAllCuts();
QList<QPolygonF> GetCutList() const{return cutList;} // this list may contain empty element
QList<int> GetCutEntryList() const{ return cutEntryList;}
void PrintCutEntry() const{
if( numCut == 0 ) return;
printf("=============== There are %d cuts.\n", numCut);
for( int i = 0; i < cutList.count(); i++){
if( cutList[i].isEmpty() ) continue;
printf("%10s | %d \n", cutNameList[i].toStdString().c_str(), cutEntryList[i]);
}
}
QList<QString> GetCutNameList() const { return cutNameList;}
void PrintCutEntry() const;
private:
double xMin, xMax, yMin, yMax;
@ -470,104 +226,367 @@ private:
bool isBusy;
//^======================== Right Mouse click action
void rightMouseClickRebin(){
QDialog dialog(this);
dialog.setWindowTitle("Rebin histogram");
QFormLayout layout(&dialog);
QLabel * info = new QLabel(&dialog);
info->setStyleSheet("color:red;");
info->setText("This will also clear histogram!!");
layout.addRow(info);
QStringList nameListX = {"Num. x-Bin", "x-Min", "x-Max"};
QLineEdit* lineEditX[3];
for (int i = 0; i < 3; ++i) {
lineEditX[i] = new QLineEdit(&dialog);
layout.addRow(nameListX[i] + " : ", lineEditX[i]);
}
lineEditX[0]->setText(QString::number(xBin));
lineEditX[1]->setText(QString::number(xMin));
lineEditX[2]->setText(QString::number(xMax));
QStringList nameListY = {"Num. y-Bin", "y-Min", "y-Max"};
QLineEdit* lineEditY[3];
for (int i = 0; i < 3; ++i) {
lineEditY[i] = new QLineEdit(&dialog);
layout.addRow(nameListY[i] + " : ", lineEditY[i]);
}
lineEditY[0]->setText(QString::number(yBin));
lineEditY[1]->setText(QString::number(yMin));
lineEditY[2]->setText(QString::number(yMax));
QLabel * msg = new QLabel(&dialog);
msg->setStyleSheet("color:red;");
layout.addRow(msg);
QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog);
layout.addRow(&buttonBox);
double number[3][2];
QObject::connect(&buttonBox, &QDialogButtonBox::accepted, [&]() {
int OKcount = 0;
bool conversionOk = true;
for( int i = 0; i < 3; i++ ){
number[i][0] = lineEditX[i]->text().toDouble(&conversionOk);
if( conversionOk ){
OKcount++;
}else{
msg->setText(nameListX[i] + " is invalid.");
return;
}
}
for( int i = 0; i < 3; i++ ){
number[i][1] = lineEditY[i]->text().toDouble(&conversionOk);
if( conversionOk ){
OKcount++;
}else{
msg->setText(nameListY[i] + " is invalid.");
return;
}
}
if( OKcount == 6 ) {
if( number[0][0] <= 0 ) {
msg->setText( nameListX[0] + " is zero or negative" );
return;
}
if( number[0][0] <= 0 ) {
msg->setText( nameListX[0] + " is zero or negative" );
return;
}
if( number[2][0] > number[1][0] && number[2][1] > number[1][1] ) {
dialog.accept();
}else{
if( number[2][0] > number[1][0] ){
msg->setText(nameListX[2] + " is smaller than " + nameListX[1]);
}
if( number[2][1] > number[1][1] ){
msg->setText(nameListY[2] + " is smaller than " + nameListY[1]);
}
}
}
});
QObject::connect(&buttonBox, &QDialogButtonBox::rejected, [&]() { dialog.reject();});
if( dialog.exec() == QDialog::Accepted ){
isBusy = true;
Rebin((int)number[0][0], number[1][0], number[2][0], (int)number[0][1], number[1][1], number[2][1]);
rescaleAxes();
UpdatePlot();
isBusy = false;
}
}
void rightMouseClickMenu(QMouseEvent * event);
void rightMouseClickRebin();
};
//^###############################################
//^###############################################
inline void Histogram2D::Fill(double x, double y){
if( isBusy ) return;
int xIndex, yIndex;
colorMap->data()->coordToCell(x, y, &xIndex, &yIndex);
//printf("%f, %d %d| %f, %d %d\n", x, xIndex, xBin, y, yIndex, yBin);
int xk = 1, yk = 1;
if( xIndex < 0 ) xk = 0;
if( xIndex >= xBin ) xk = 2;
if( yIndex < 0 ) yk = 0;
if( yIndex >= yBin ) yk = 2;
entry[xk][yk] ++;
txt[xk][yk]->setText(QString::number(entry[xk][yk]));
if( xk == 1 && yk == 1 ) {
double value = colorMap->data()->cell(xIndex, yIndex);
colorMap->data()->setCell(xIndex, yIndex, value + 1);
for( int i = 0; i < cutList.count(); i++){
if( cutList[i].isEmpty() ) continue;
if( cutList[i].containsPoint(QPointF(x,y), Qt::OddEvenFill) ) cutEntryList[i] ++;
}
}
}
inline void Histogram2D::Rebin(int xbin, double xmin, double xmax, int ybin, double ymin, double ymax){
xMin = xmin;
xMax = xmax;
yMin = ymin;
yMax = ymax;
xBin = xbin;
yBin = ybin;
colorMap->data()->clear();
colorMap->data()->setSize(xBin, yBin);
colorMap->data()->setRange(QCPRange(xMin, xMax), QCPRange(yMin, yMax));
for( int i = 0; i < 3; i ++){
for( int j = 0; j < 3; j ++){
entry[i][j] = 0;
if( txt[i][j] ) txt[i][j]->setText("0");
}
}
}
inline void Histogram2D::Clear(){
for( int i = 0; i < 3; i ++){
for( int j = 0; j < 3; j ++){
entry[i][j] = 0;
txt[i][j]->setText("0");
}
}
colorMap->data()->clear();
colorMap->data()->setSize(xBin, yBin);
colorMap->data()->setRange(QCPRange(xMin, xMax), QCPRange(yMin, yMax));
UpdatePlot();
}
inline void Histogram2D::ClearAllCuts(){
numCut = 0;
tempCutID = -1;
lastPlottableID = -1;
cutList.clear();
cutIDList.clear();
for( int i = cutTextIDList.count() - 1; i >= 0 ; i--){
if( cutTextIDList[i] < 0 ) continue;
removeItem(cutTextIDList[i]);
removePlottable(plottableIDList[i]);
}
replot();
cutTextIDList.clear();
plottableIDList.clear();
cutNameList.clear();
cutEntryList.clear();
}
inline void Histogram2D::PrintCutEntry() const{
if( numCut == 0 ) return;
printf("=============== There are %d cuts.\n", numCut);
for( int i = 0; i < cutList.count(); i++){
if( cutList[i].isEmpty() ) continue;
printf("%10s | %d \n", cutNameList[i].toStdString().c_str(), cutEntryList[i]);
}
}
inline void Histogram2D::DrawCut(){
//The histogram is the 1st plottable.
// the lastPlottableID should be numCut+ 1
if( lastPlottableID != numCut ){
removePlottable(lastPlottableID);
}
if(tempCut.size() > 0) {
QCPCurve *polygon = new QCPCurve(xAxis, yAxis);
lastPlottableID = plottableCount() - 1;
int colorID = tempCutID% colorCycle.count();
QPen pen(colorCycle[colorID].first);
pen.setWidth(1);
polygon->setPen(pen);
QVector<QCPCurveData> dataPoints;
for (const QPointF& point : tempCut) {
dataPoints.append(QCPCurveData(dataPoints.size(), point.x(), point.y()));
}
polygon->data()->set(dataPoints, false);
}
replot();
//qDebug() << "Plottable count : " << plottableCount() << ", cutList.count :" << cutList.count() << ", cutID :" << lastPlottableID;
}
inline void Histogram2D::rightMouseClickMenu(QMouseEvent * event){
usingMenu = true;
setSelectionRectMode(QCP::SelectionRectMode::srmNone);
QMenu *menu = new QMenu(this);
menu->setAttribute(Qt::WA_DeleteOnClose);
QAction * a1 = menu->addAction("UnZoom");
QAction * a2 = menu->addAction("Clear hist.");
QAction * a3 = menu->addAction("Toggle Stat.");
QAction * a4 = menu->addAction("Rebin (clear histogram)");
QAction * a5 = menu->addAction("Create a Cut");
if( numCut > 0 ) {
menu->addSeparator();
menu->addAction("Add/Edit names to Cuts");
menu->addAction("Clear all Cuts");
}
for( int i = 0; i < cutList.size(); i++){
if( cutList[i].isEmpty()) continue;
QString haha = "";
menu->addAction("Delete " + cutNameList[i] + " ["+ colorCycle[cutIDList[i]%colorCycle.count()].second+"]");
}
QAction *selectedAction = menu->exec(event->globalPosition().toPoint());
if( selectedAction == a1 ){
xAxis->setRangeLower(xMin);
xAxis->setRangeUpper(xMax);
yAxis->setRangeLower(yMin);
yAxis->setRangeUpper(yMax);
replot();
usingMenu = false;
return;
}
if( selectedAction == a2 ) {
Clear();
usingMenu = false;
return;
}
if( selectedAction == a3 ){
for( int i = 0; i < 3; i ++ ){
for( int j = 0; j < 3; j ++ ){
box[i][j]->setVisible( !box[i][j]->visible());
txt[i][j]->setVisible( !txt[i][j]->visible());
}
}
replot();
usingMenu = false;
return;
}
if( selectedAction == a4){
rightMouseClickRebin();
usingMenu = false;
return;
}
if( selectedAction == a5 ){
tempCut.clear();
tempCutID ++;
isDrawCut= true;
usingMenu = false;
numCut ++;
return;
}
if( selectedAction && numCut > 0 && selectedAction->text().contains("Delete ") ){
QString haha = selectedAction->text();
int index1 = haha.indexOf("-");
int index2 = haha.indexOf("[");
int cutID = haha.mid(index1+1, index2-index1-1).remove(' ').toInt();
removeItem(cutTextIDList[cutID]);
removePlottable(plottableIDList[cutID]);
replot();
numCut --;
cutList[cutID].clear();
cutIDList[cutID] = -1;
cutTextIDList[cutID] = -1;
plottableIDList[cutID] = -1;
cutNameList[cutID] = "";
cutEntryList[cutID] = -1;
for( int i = cutID + 1; i < cutTextIDList.count() ; i++){
cutTextIDList[i] --;
plottableIDList[i] --;
}
if( numCut == 0 ){
tempCutID = -1;
lastPlottableID = -1;
cutList.clear();
cutIDList.clear();
cutTextIDList.clear();
plottableIDList.clear();
cutNameList.clear();
cutEntryList.clear();
}
return;
}
if( selectedAction && numCut > 0 && selectedAction->text().contains("Clear all Cuts") ){
ClearAllCuts();
return;
}
if( selectedAction && numCut > 0 && selectedAction->text().contains("Add/Edit names to Cuts") ){
QDialog dialog(this);
dialog.setWindowTitle("Add/Edit name of cuts ");
QFormLayout layout(&dialog);
for(int i = 0; i < cutTextIDList.count(); i++){
if( cutTextIDList[i] < 0 ) continue;
QLineEdit * le = new QLineEdit(&dialog);
layout.addRow(colorCycle[i%colorCycle.count()].second, le);
le->setText( cutNameList[i] );
connect(le, &QLineEdit::textChanged, this, [=](){
le->setStyleSheet("color : blue;");
});
connect(le, &QLineEdit::returnPressed, this, [=](){
le->setStyleSheet("");
cutNameList[i] = le->text();
((QCPItemText *) this->item(cutTextIDList[i]))->setText(le->text());
replot();
});
}
dialog.exec();
return;
}
}
inline void Histogram2D::rightMouseClickRebin(){
QDialog dialog(this);
dialog.setWindowTitle("Rebin histogram");
QFormLayout layout(&dialog);
QLabel * info = new QLabel(&dialog);
info->setStyleSheet("color:red;");
info->setText("This will also clear histogram!!");
layout.addRow(info);
QStringList nameListX = {"Num. x-Bin", "x-Min", "x-Max"};
QLineEdit* lineEditX[3];
for (int i = 0; i < 3; ++i) {
lineEditX[i] = new QLineEdit(&dialog);
layout.addRow(nameListX[i] + " : ", lineEditX[i]);
}
lineEditX[0]->setText(QString::number(xBin));
lineEditX[1]->setText(QString::number(xMin));
lineEditX[2]->setText(QString::number(xMax));
QStringList nameListY = {"Num. y-Bin", "y-Min", "y-Max"};
QLineEdit* lineEditY[3];
for (int i = 0; i < 3; ++i) {
lineEditY[i] = new QLineEdit(&dialog);
layout.addRow(nameListY[i] + " : ", lineEditY[i]);
}
lineEditY[0]->setText(QString::number(yBin));
lineEditY[1]->setText(QString::number(yMin));
lineEditY[2]->setText(QString::number(yMax));
QLabel * msg = new QLabel(&dialog);
msg->setStyleSheet("color:red;");
layout.addRow(msg);
QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog);
layout.addRow(&buttonBox);
double number[3][2];
QObject::connect(&buttonBox, &QDialogButtonBox::accepted, [&]() {
int OKcount = 0;
bool conversionOk = true;
for( int i = 0; i < 3; i++ ){
number[i][0] = lineEditX[i]->text().toDouble(&conversionOk);
if( conversionOk ){
OKcount++;
}else{
msg->setText(nameListX[i] + " is invalid.");
return;
}
}
for( int i = 0; i < 3; i++ ){
number[i][1] = lineEditY[i]->text().toDouble(&conversionOk);
if( conversionOk ){
OKcount++;
}else{
msg->setText(nameListY[i] + " is invalid.");
return;
}
}
if( OKcount == 6 ) {
if( number[0][0] <= 0 ) {
msg->setText( nameListX[0] + " is zero or negative" );
return;
}
if( number[0][0] <= 0 ) {
msg->setText( nameListX[0] + " is zero or negative" );
return;
}
if( number[2][0] > number[1][0] && number[2][1] > number[1][1] ) {
dialog.accept();
}else{
if( number[2][0] > number[1][0] ){
msg->setText(nameListX[2] + " is smaller than " + nameListX[1]);
}
if( number[2][1] > number[1][1] ){
msg->setText(nameListY[2] + " is smaller than " + nameListY[1]);
}
}
}
});
QObject::connect(&buttonBox, &QDialogButtonBox::rejected, [&]() { dialog.reject();});
if( dialog.exec() == QDialog::Accepted ){
isBusy = true;
Rebin((int)number[0][0], number[1][0], number[2][0], (int)number[0][1], number[1][1], number[2][1]);
rescaleAxes();
UpdatePlot();
isBusy = false;
}
}
#endif

View File

@ -92,6 +92,7 @@ void MultiBuilder::ClearEvents(){
nExhaushedCh = 0;
}
}
void MultiBuilder::PrintStat(){
@ -292,7 +293,7 @@ void MultiBuilder::BuildEvents(bool isFinal, bool skipTrace, bool verbose){
}
void MultiBuilder::BuildEventsBackWard(bool verbose){
void MultiBuilder::BuildEventsBackWard(int maxNumEvent, bool verbose){
//skip trace, and only build for 100 events max
@ -375,7 +376,7 @@ void MultiBuilder::BuildEventsBackWard(bool verbose){
}
}while(nExhaushedCh < nData * MaxNChannels && eventBuilt < 100);
}while(nExhaushedCh < nData * MaxNChannels && eventBuilt <= maxNumEvent);
// // remember the end of DataIndex, prevent over build
// for( int k = 0; k < nData; k++){

View File

@ -32,10 +32,13 @@ public:
fineTime = 0;
trace.clear();
}
void Print(){
printf("(%2d, %2d)[%3d] %6d %10llu, %5ld\n", bd, ch, sn, energy, timestamp, trace.size());
}
};
class MultiBuilder {
public:
@ -56,7 +59,7 @@ public:
std::vector<int> GetDigiIDList() const {return idList;}
void BuildEvents(bool isFinal = false, bool skipTrace = false, bool verbose = false);
void BuildEventsBackWard(bool verbose = false); // always skip trace, for faster online building
void BuildEventsBackWard(int maxNumEvent = 100, bool verbose = false); // always skip trace, for faster online building
void ClearEvents();
void PrintStat();

View File

@ -63,7 +63,7 @@ class Reg{
RW GetType() const {return type;}
bool IsCoupled() const {return group;}
unsigned int GetMaxBit() const {return maxBit;}
int GetPartialStep() const {return partialStep;} /// step = partialStep * ch2ns, -1 : step = 1
int GetPartialStep() const {return partialStep;} /// step = partialStep * tick2ns, -1 : step = 1
void Print() const ;
std::vector<std::pair<std::string, unsigned int>> GetComboList() const {return comboList;}

View File

@ -101,12 +101,12 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh
ID = 0;
cbScopeDigi->setCurrentIndex(0);
for( int i = 0; i < digi[0]->GetNChannels(); i++) cbScopeCh->addItem("Ch-" + QString::number(i));
ch2ns = digi[ID]->GetCh2ns();
tick2ns = digi[ID]->GetTick2ns();
connect(cbScopeDigi, &RComboBox::currentIndexChanged, this, [=](int index){
if( !enableSignalSlot ) return;
ID = index;
ch2ns = digi[ID]->GetCh2ns();
tick2ns = digi[ID]->GetTick2ns();
//---setup cbScopeCh
cbScopeCh->clear();
for( int i = 0; i < digi[ID]->GetNChannels(); i++) cbScopeCh->addItem("Ch-" + QString::number(i));
@ -310,7 +310,7 @@ void Scope::UpdateScope(){
if( digi[ID]->GetChannelOnOff(ch) == false) return;
int ch2ns = digi[ID]->GetCh2ns();
int tick2ns = digi[ID]->GetTick2ns();
int factor = digi[ID]->IsDualTrace_PHA() ? 2 : 1;
digiMTX[ID].lock();
@ -329,19 +329,19 @@ void Scope::UpdateScope(){
QVector<QPointF> points[4];
if( digi[ID]->GetDPPType() == V1730_DPP_PHA_CODE ) {
for( int i = 0; i < (int) (data->Waveform1[ch][index]).size() ; i++ ) {
points[0].append(QPointF(ch2ns * i * factor, (data->Waveform1[ch][index])[i]));
if( i < (int) data->Waveform2[ch][index].size() ) points[1].append(QPointF(ch2ns * i * factor, (data->Waveform2[ch][index])[i]));
if( i < (int) data->DigiWaveform1[ch][index].size() ) points[2].append(QPointF(ch2ns * i * factor, (data->DigiWaveform1[ch][index])[i] * 1000));
if( i < (int) data->DigiWaveform2[ch][index].size() ) points[3].append(QPointF(ch2ns * i * factor, (data->DigiWaveform2[ch][index])[i] * 1000 + 500));
points[0].append(QPointF(tick2ns * i * factor, (data->Waveform1[ch][index])[i]));
if( i < (int) data->Waveform2[ch][index].size() ) points[1].append(QPointF(tick2ns * i * factor, (data->Waveform2[ch][index])[i]));
if( i < (int) data->DigiWaveform1[ch][index].size() ) points[2].append(QPointF(tick2ns * i * factor, (data->DigiWaveform1[ch][index])[i] * 1000));
if( i < (int) data->DigiWaveform2[ch][index].size() ) points[3].append(QPointF(tick2ns * i * factor, (data->DigiWaveform2[ch][index])[i] * 1000 + 500));
}
}
if( digi[ID]->GetDPPType() == V1730_DPP_PSD_CODE ) {
for( int i = 0; i < (int) (data->DigiWaveform1[ch][index]).size() ; i++ ) {
points[0].append(QPointF(ch2ns * i * factor, (data->Waveform1[ch][index])[i]));
if( i < (int) data->Waveform2[ch][index].size() ) points[1].append(QPointF(ch2ns * i * factor, (data->Waveform2[ch][index])[i]));
if( i < (int) data->DigiWaveform1[ch][index].size() ) points[2].append(QPointF(ch2ns * i, (data->DigiWaveform1[ch][index])[i] * 1000));
if( i < (int) data->DigiWaveform2[ch][index].size() ) points[3].append(QPointF(ch2ns * i, (data->DigiWaveform2[ch][index])[i] * 1000 + 500));
points[0].append(QPointF(tick2ns * i * factor, (data->Waveform1[ch][index])[i]));
if( i < (int) data->Waveform2[ch][index].size() ) points[1].append(QPointF(tick2ns * i * factor, (data->Waveform2[ch][index])[i]));
if( i < (int) data->DigiWaveform1[ch][index].size() ) points[2].append(QPointF(tick2ns * i, (data->DigiWaveform1[ch][index])[i] * 1000));
if( i < (int) data->DigiWaveform2[ch][index].size() ) points[3].append(QPointF(tick2ns * i, (data->DigiWaveform2[ch][index])[i] * 1000 + 500));
}
}
dataTrace[0]->replace(points[0]);
@ -351,7 +351,7 @@ void Scope::UpdateScope(){
}
digiMTX[ID].unlock();
plot->axes(Qt::Horizontal).first()->setRange(0, ch2ns * traceLength * factor);
plot->axes(Qt::Horizontal).first()->setRange(0, tick2ns * traceLength * factor);
emit UpdateScaler();
@ -412,8 +412,8 @@ void Scope::SetUpSpinBox(RSpinBox * &sb, QString str, int row, int col, const Re
sb = new RSpinBox(settingGroup);
if( para.GetPartialStep() != 0 ){
sb->setMinimum(0);
sb->setMaximum(para.GetMaxBit() * para.GetPartialStep() * ch2ns);
if( para.GetPartialStep() > 0 ) sb->setSingleStep(para.GetPartialStep() * ch2ns);
sb->setMaximum(para.GetMaxBit() * para.GetPartialStep() * tick2ns);
if( para.GetPartialStep() > 0 ) sb->setSingleStep(para.GetPartialStep() * tick2ns);
if( para.GetPartialStep() == -1 ) sb->setSingleStep(1);
}
settingLayout->addWidget(sb, row, col + 1);
@ -438,7 +438,7 @@ void Scope::SetUpSpinBox(RSpinBox * &sb, QString str, int row, int col, const Re
msg = QString::fromStdString(para.GetName()) + "|DIG:"+ QString::number(digi[ID]->GetSerialNumber()) + ",CH:" + (ch == -1 ? "All" : QString::number(ch));
msg += " = " + QString::number(sb->value());
uint32_t value = sb->value() / ch2ns / abs(para.GetPartialStep());
uint32_t value = sb->value() / tick2ns / abs(para.GetPartialStep());
if( para == DPP::RecordLength_G){
int factor = digi[ID]->IsDualTrace_PHA() ? 2 : 1;
@ -694,7 +694,7 @@ void Scope::UpdateSpinBox(RSpinBox * &sb, const Reg para){
enableSignalSlot = false;
unsigned int haha = digi[ID]->GetSettingFromMemory(para, ch);
if( para.GetPartialStep() > 0 ) sb->setValue(haha * para.GetPartialStep() * ch2ns);
if( para.GetPartialStep() > 0 ) sb->setValue(haha * para.GetPartialStep() * tick2ns);
if( para.GetPartialStep() == -1 ) sb->setValue(haha);
//enableSignalSlot = true;
}
@ -708,11 +708,11 @@ void Scope::UpdatePanelFromMomeory(){
int ch = cbScopeCh->currentIndex();
unsigned int haha = digi[ID]->GetSettingFromMemory(DPP::RecordLength_G, ch);
sbReordLength->setValue(haha * DPP::RecordLength_G.GetPartialStep() * ch2ns);
sbReordLength->setValue(haha * DPP::RecordLength_G.GetPartialStep() * tick2ns);
// if( digi[ID]->GetDPPType() == V1730_DPP_PHA_CODE ){
// int factor = digi[ID]->IsDualTrace() ? 2 : 1; // if dual trace,
// sbReordLength->setValue(haha * DPP::RecordLength_G.GetPartialStep() * ch2ns / factor);
// sbReordLength->setValue(haha * DPP::RecordLength_G.GetPartialStep() * tick2ns / factor);
// }else{
// }

View File

@ -71,7 +71,7 @@ private:
Digitizer ** digi;
unsigned short nDigi;
unsigned short ID; // the id of digi, index of cbScopeDigi
int ch2ns;
int tick2ns;
bool traceOn[MaxNDigitizer];
ReadDataThread ** readDataThread;

View File

@ -26,9 +26,15 @@ public:
SetUpdateTimeInSec(1.0);
RedefineEventBuilder({0}); // only build for the 0-th digitizer;
RedefineEventBuilder({0}); // only build for the 0-th digitizer, otherwise, it will build event accross all digitizers
tick2ns = digi[0]->GetTick2ns();
SetBackwardBuild(false, 500); // using normal building (acceding in time) or backward building, int the case of backward building, default events to be build is 100.
evtbder = GetEventBuilder();
//========== use the influx from the Analyzer
influx = new InfluxDB("https://fsunuc.physics.fsu.edu/influx/");
dataBaseName = "testing";
SetUpCanvas();
}
@ -47,6 +53,8 @@ private:
Histogram2D * h2;
Histogram1D * h1;
int tick2ns;
};
@ -55,12 +63,13 @@ inline void SplitPole::SetUpCanvas(){
setGeometry(0, 0, 1600, 800);
// the "this" make the histogram a child of the SplitPole class. When SplitPole destory, all childs destory as well.
h2 = new Histogram2D("Split Pole PID", "x", "y", 400, 0, 10000, 400, 0, 10000, this);
h2 = new Histogram2D("Split Pole PID", "x", "y", 100, 0, 10000, 100, 0, 10000, this);
//layout is inheriatge from Analyzer
layout->addWidget(h2, 0, 0);
h1 = new Histogram1D("Spectrum", "x", 400, 0, 10000, this);
layout->addWidget(h1, 0, 1);
}
@ -72,29 +81,61 @@ inline void SplitPole::UpdateHistograms(){
long eventBuilt = evtbder->eventBuilt;
if( eventBuilt == 0 ) return;
//============ Get the cut list, if any
QList<QPolygonF> cutList = h2->GetCutList();
const int nCut = cutList.count();
unsigned long long tMin[nCut] = {0xFFFFFFFFFFFFFFFF}, tMax[nCut] = {0};
unsigned int count[nCut]={0};
//============ Processing data and fill histograms
long eventIndex = evtbder->eventIndex;
long eventStart = eventIndex - eventBuilt + 1;
if(eventStart < 0 ) eventStart += MaxNEvent;
//============ Processing data and fill histograms
unsigned short e1 = 0, e2 = 0;
for( long i = eventStart ; i <= eventIndex; i ++ ){
unsigned short e1 = 0, e2 = 0;
unsigned long long t1 = 0, t2 = 0;
std::vector<EventMember> event = evtbder->events[i];
//printf("-------------- %ld\n", i);
for( int k = 0; k < (int) event.size(); k++ ){
if( event[k].ch == 9 ) e1 = event[k].energy;
if( event[k].ch == 10 ) e2 = event[k].energy;
//event[k].Print();
if( event[k].ch == 9 ) {e1 = event[k].energy; t1 = event[k].timestamp;}
if( event[k].ch == 10 ) {e2 = event[k].energy; t2 = event[k].timestamp;}
}
if( e1 == 0 ) continue;
if( e2 == 0 ) continue;
h2->Fill(e1, e2);
h1->Fill(e1);
//check events inside any Graphical cut and extract the rate, using t1 only
for(int p = 0; p < cutList.count(); p++ ){
if( cutList[p].isEmpty() ) continue;
if( cutList[p].containsPoint(QPointF(e1, e2), Qt::OddEvenFill) ){
if( t1 < tMin[p] ) tMin[p] = t1;
if( t1 > tMax[p] ) tMax[p] = t1;
count[p] ++;
//printf(".... %d \n", count[p]);
}
}
}
h2->UpdatePlot();
h1->UpdatePlot();
h2->PrintCutEntry();
QList<QString> cutNameList = h2->GetCutNameList();
for( int p = 0; p < cutList.count(); p ++){
if( cutList[p].isEmpty() ) continue;
double dT = (tMax[p]-tMin[p]) * tick2ns / 1e9; // tick to sec
double rate = count[p]*1.0/(dT);
//printf("%llu %llu, %f %d\n", tMin[p], tMax[p], dT, count[p]);
//printf("%10s | %d | %f Hz \n", cutNameList[p].toStdString().c_str(), count[p], rate);
influx->AddDataPoint("Cut,name=" + cutNameList[p].toStdString()+ " value=" + std::to_string(rate));
influx->WriteData(dataBaseName);
influx->ClearDataPointsBuffer();
}
}

View File

@ -41,7 +41,7 @@ int main(int argc, char* argv[]){
// dig[0]->ProgramBoard();
// dig[0]->ProgramPSDBoard();
// const float ch2ns = dig[0]->GetCh2ns();
// const float tick2ns = dig[0]->GetTick2ns();
Data * data = dig[0]->GetData();
data->ClearData();
@ -117,7 +117,7 @@ int main(int argc, char* argv[]){
unsigned short nData = data->DataIndex[0]; //channel-0
haha = data->Waveform1[0][nData-1];
for( int i = 0; i < waveFormLength; i++) g1->SetPoint(i, i*ch2ns, haha[i]);
for( int i = 0; i < waveFormLength; i++) g1->SetPoint(i, i*tick2ns, haha[i]);
canvas->cd(3); g1->Draw("AP");

View File

@ -13,7 +13,7 @@
using namespace std;
void PrintChannelSettingFromDigitizer(int handle, int ch, float ch2ns){
void PrintChannelSettingFromDigitizer(int handle, int ch, float tick2ns){
printf("\e[33m================================================\n");
printf("================ Setting for channel %d \n", ch);
@ -48,11 +48,11 @@ void PrintChannelSettingFromDigitizer(int handle, int ch, float ch2ns){
default: extra2WordOptStr = "Reserved"; break;
}
printf(" ch2ns : %.0f ns\n", ch2ns);
printf(" tick2ns : %.0f ns\n", tick2ns);
printf("==========----- input \n");
CAEN_DGTZ_ReadRegister(handle, DPP::RecordLength_G + (ch << 8), value); printf("%24s %5d samples = %5.0f ns \n", "Record Length", ((value[0] * 8) & MaxRecordLength), ((value[0] * 8) & MaxRecordLength) * ch2ns); ///Record length
CAEN_DGTZ_ReadRegister(handle, DPP::PreTrigger + (ch << 8), value); printf("%24s %5d samples = %5.0f ns \n", "Pre-tigger", value[0] * 4, value[0] * 4 * ch2ns); ///Pre-trigger
CAEN_DGTZ_ReadRegister(handle, DPP::RecordLength_G + (ch << 8), value); printf("%24s %5d samples = %5.0f ns \n", "Record Length", ((value[0] * 8) & MaxRecordLength), ((value[0] * 8) & MaxRecordLength) * tick2ns); ///Record length
CAEN_DGTZ_ReadRegister(handle, DPP::PreTrigger + (ch << 8), value); printf("%24s %5d samples = %5.0f ns \n", "Pre-tigger", value[0] * 4, value[0] * 4 * tick2ns); ///Pre-trigger
printf("%24s %5.0f samples, DPP-[20:22]\n", "baseline mean", pow(4, 1 + baseline)); ///Ns baseline
CAEN_DGTZ_ReadRegister(handle, DPP::ChannelDCOffset + (ch << 8), value); printf("%24s %.2f %% \n", "DC offset", 100.0 - value[0] * 100./ 0xFFFF); ///DC offset
CAEN_DGTZ_ReadRegister(handle, DPP::InputDynamicRange + (ch << 8), value); printf("%24s %.1f Vpp \n", "input Dynamic", value[0] == 0 ? 2 : 0.5); ///InputDynamic
@ -60,27 +60,27 @@ void PrintChannelSettingFromDigitizer(int handle, int ch, float ch2ns){
printf("==========----- discriminator \n");
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::TriggerThreshold + (ch << 8), value); printf("%24s %4d LSB\n", "Threshold", value[0]); ///Threshold
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::TriggerHoldOffWidth + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "trigger hold off", value[0], value[0] * 4 * ch2ns); ///Trigger Hold off
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::RCCR2SmoothingFactor + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Fast Dis. smoothing", (value[0] & 0x1f) * 2, (value[0] & 0x1f) * 2 * ch2ns ); ///Fast Discriminator smoothing
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::ShapedTriggerWidth + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Fast Dis. output width", value[0], value[0] * 4 * ch2ns); ///Fast Dis. output width
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::InputRiseTime + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Input rise time ", value[0], value[0] * 4 * ch2ns); ///Input rise time
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::TriggerHoldOffWidth + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "trigger hold off", value[0], value[0] * 4 * tick2ns); ///Trigger Hold off
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::RCCR2SmoothingFactor + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Fast Dis. smoothing", (value[0] & 0x1f) * 2, (value[0] & 0x1f) * 2 * tick2ns ); ///Fast Discriminator smoothing
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::ShapedTriggerWidth + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Fast Dis. output width", value[0], value[0] * 4 * tick2ns); ///Fast Dis. output width
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::InputRiseTime + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Input rise time ", value[0], value[0] * 4 * tick2ns); ///Input rise time
printf("==========----- Trapezoid \n");
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::TrapezoidRiseTime + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Trap. rise time", value[0], value[0] * 4 * ch2ns); ///Trap. rise time, 2 for 1 ch to 2ns
int riseTime = value[0] * 4 * ch2ns;
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::TrapezoidFlatTop + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Trap. flat time", value[0], value[0] * 4 * ch2ns); ///Trap. flat time
int flatTopTime = value[0] * 4 * ch2ns;
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::TrapezoidRiseTime + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Trap. rise time", value[0], value[0] * 4 * tick2ns); ///Trap. rise time, 2 for 1 ch to 2ns
int riseTime = value[0] * 4 * tick2ns;
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::TrapezoidFlatTop + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Trap. flat time", value[0], value[0] * 4 * tick2ns); ///Trap. flat time
int flatTopTime = value[0] * 4 * tick2ns;
double shift = log(riseTime * flatTopTime ) / log(2) - 2;
printf("%24s %4d bit =? %.1f = Ceil( Log(rise [ns] x decay [ns])/Log(2) ), DPP-[0:5]\n", "Trap. Rescaling", trapRescaling, shift ); ///Trap. Rescaling Factor
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::DecayTime + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Decay time", value[0], value[0] * 4 * ch2ns); ///Trap. pole zero
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::PeakingTime + (ch << 8), value); printf("%24s %4d samples, %5.0f ns = %.2f %% of FlatTop\n", "Peaking time", value[0], value[0] * 4 * ch2ns, value[0] * 400. * ch2ns / flatTopTime ); ///Peaking time
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::PeakHoldOff + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Peak hole off", value[0], value[0] * 4 *ch2ns ); ///Peak hold off
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::DecayTime + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Decay time", value[0], value[0] * 4 * tick2ns); ///Trap. pole zero
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::PeakingTime + (ch << 8), value); printf("%24s %4d samples, %5.0f ns = %.2f %% of FlatTop\n", "Peaking time", value[0], value[0] * 4 * tick2ns, value[0] * 400. * tick2ns / flatTopTime ); ///Peaking time
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::PeakHoldOff + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Peak hole off", value[0], value[0] * 4 *tick2ns ); ///Peak hold off
printf("%24s %4.0f samples, DPP-[12:13]\n", "Peak mean", pow(4, NsPeak)); ///Ns peak
printf("==========----- Other \n");
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::FineGain + (ch << 8), value); printf("%24s %d = 0x%x\n", "Energy fine gain", value[0], value[0]); ///Energy fine gain
CAEN_DGTZ_ReadRegister(handle, DPP::ChannelADCTemperature_R + (ch << 8), value); printf("%24s %d C\n", "Temperature", value[0]); ///Temperature
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::RiseTimeValidationWindow + (ch << 8), value); printf("%24s %.0f ns \n", "RiseTime Vaild Win.", value[0] * ch2ns);
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::RiseTimeValidationWindow + (ch << 8), value); printf("%24s %.0f ns \n", "RiseTime Vaild Win.", value[0] * tick2ns);
CAEN_DGTZ_ReadRegister(handle, DPP::PHA::ChannelStopAcquisition + (ch << 8), value); printf("%24s %d = %s \n", "Stop Acq bit", value[0] & 1 , (value[0] & 1 ) == 0 ? "Run" : "Stop");
CAEN_DGTZ_ReadRegister(handle, DPP::ChannelStatus_R + (ch << 8), value); printf("%24s 0x%x \n", "Status bit", (value[0] & 0xff) );
CAEN_DGTZ_ReadRegister(handle, DPP::AMCFirmwareRevision_R + (ch << 8), value); printf("%24s 0x%x \n", "AMC firmware rev.", value[0] );
@ -181,10 +181,10 @@ int main(int argc, char* argv[]){
ret = (int) CAEN_DGTZ_GetInfo(handle, &BoardInfo);
int NChannel = BoardInfo.Channels;
uint32_t channelMask = 0xFFFF;
float ch2ns = 4.0;
float tick2ns = 4.0;
switch(BoardInfo.Model){
case CAEN_DGTZ_V1730: ch2ns = 2.0; break; ///ns -> 500 MSamples/s
case CAEN_DGTZ_V1725: ch2ns = 4.0; break; ///ns -> 250 MSamples/s
case CAEN_DGTZ_V1730: tick2ns = 2.0; break; ///ns -> 500 MSamples/s
case CAEN_DGTZ_V1725: tick2ns = 4.0; break; ///ns -> 250 MSamples/s
}
unsigned int ADCbits = BoardInfo.ADC_NBits;
@ -309,7 +309,7 @@ int main(int argc, char* argv[]){
if( ret != 0 ) { printf("==== memory allocation error.\n"); return 0;}
PrintBoardConfiguration(handle);
PrintChannelSettingFromDigitizer(handle, 4, ch2ns);
PrintChannelSettingFromDigitizer(handle, 4, tick2ns);
printf("============ Start ACQ \n");
CAEN_DGTZ_SWStartAcquisition(handle);