2023-06-02 15:41:26 -04:00
# include "SingleSpectra.h"
2023-05-17 17:40:32 -04:00
# include <QValueAxis>
# include <QGroupBox>
# include <QStandardItemModel>
# include <QLabel>
2024-08-01 17:03:50 -04:00
// #include <QScreen>
2023-05-17 17:40:32 -04:00
2023-06-02 15:41:26 -04:00
SingleSpectra : : SingleSpectra ( Digitizer * * digi , unsigned int nDigi , QString rawDataPath , QMainWindow * parent ) : QMainWindow ( parent ) {
2024-03-22 16:47:33 -04:00
DebugPrint ( " %s " , " SingleSpectra " ) ;
2023-05-17 17:40:32 -04:00
this - > digi = digi ;
this - > nDigi = nDigi ;
2024-06-17 17:44:31 -04:00
this - > settingPath = rawDataPath + " /HistogramSettings.txt " ;
2023-05-17 17:40:32 -04:00
2024-04-05 22:33:05 -04:00
maxFillTimeinMilliSec = 1000 ;
maxFillTimePerDigi = maxFillTimeinMilliSec / nDigi ;
2024-03-22 12:43:17 -04:00
2023-10-26 17:57:06 -04:00
isSignalSlotActive = true ;
2024-04-25 18:24:05 -04:00
setWindowTitle ( " Single Histograms " ) ;
2023-05-17 17:40:32 -04:00
2024-07-26 15:21:16 -04:00
//====== resize window if screen too small
QScreen * screen = QGuiApplication : : primaryScreen ( ) ;
QRect screenGeo = screen - > geometry ( ) ;
2024-07-26 15:48:20 -04:00
if ( screenGeo . width ( ) < 1000 | | screenGeo . height ( ) < 800 ) {
setGeometry ( 0 , 0 , screenGeo . width ( ) - 100 , screenGeo . height ( ) - 100 ) ;
} else {
setGeometry ( 0 , 0 , 1000 , 800 ) ;
}
2024-07-26 15:21:16 -04:00
2023-05-18 17:14:24 -04:00
QWidget * layoutWidget = new QWidget ( this ) ;
setCentralWidget ( layoutWidget ) ;
QVBoxLayout * layout = new QVBoxLayout ( layoutWidget ) ;
layoutWidget - > setLayout ( layout ) ;
2023-06-01 17:51:00 -04:00
{ //^========================
QGroupBox * controlBox = new QGroupBox ( " Control " , this ) ;
layout - > addWidget ( controlBox ) ;
QGridLayout * ctrlLayout = new QGridLayout ( controlBox ) ;
controlBox - > setLayout ( ctrlLayout ) ;
cbDigi = new RComboBox ( this ) ;
for ( unsigned int i = 0 ; i < nDigi ; i + + ) cbDigi - > addItem ( " Digi- " + QString : : number ( digi [ i ] - > GetSerialNumber ( ) ) , i ) ;
ctrlLayout - > addWidget ( cbDigi , 0 , 0 , 1 , 2 ) ;
2023-10-26 17:57:06 -04:00
connect ( cbDigi , & RComboBox : : currentIndexChanged , this , [ = ] ( int index ) {
isSignalSlotActive = false ;
cbCh - > clear ( ) ;
2023-11-06 17:46:43 -05:00
cbCh - > addItem ( " All Ch " , digi [ index ] - > GetNumInputCh ( ) ) ;
2023-10-26 17:57:06 -04:00
for ( int i = 0 ; i < digi [ index ] - > GetNumInputCh ( ) ; i + + ) cbCh - > addItem ( " ch- " + QString : : number ( i ) , i ) ;
isSignalSlotActive = true ;
2023-12-12 18:09:43 -05:00
//printf("oldCh = %d \n", oldCh);
if ( oldCh > = digi [ index ] - > GetNumInputCh ( ) ) {
2023-10-26 17:57:06 -04:00
cbCh - > setCurrentIndex ( 0 ) ;
} else {
if ( oldCh > = 0 ) {
cbCh - > setCurrentIndex ( oldCh ) ;
} else {
cbCh - > setCurrentIndex ( 0 ) ;
}
}
ChangeHistView ( ) ;
} ) ;
2023-06-01 17:51:00 -04:00
cbCh = new RComboBox ( this ) ;
2023-11-06 17:46:43 -05:00
cbCh - > addItem ( " All Ch " , digi [ 0 ] - > GetNumInputCh ( ) ) ;
2023-10-26 17:57:06 -04:00
for ( int i = 0 ; i < digi [ 0 ] - > GetNumInputCh ( ) ; i + + ) cbCh - > addItem ( " ch- " + QString : : number ( i ) , i ) ;
2023-06-01 17:51:00 -04:00
ctrlLayout - > addWidget ( cbCh , 0 , 2 , 1 , 2 ) ;
2023-06-02 15:41:26 -04:00
connect ( cbCh , & RComboBox : : currentIndexChanged , this , & SingleSpectra : : ChangeHistView ) ;
2023-06-01 17:51:00 -04:00
2023-07-11 18:29:38 -04:00
QPushButton * bnClearHist = new QPushButton ( " Clear All Hist. " , this ) ;
2023-06-01 17:51:00 -04:00
ctrlLayout - > addWidget ( bnClearHist , 0 , 4 , 1 , 2 ) ;
connect ( bnClearHist , & QPushButton : : clicked , this , [ = ] ( ) {
for ( unsigned int i = 0 ; i < nDigi ; i + + ) {
2023-10-26 17:57:06 -04:00
for ( int j = 0 ; j < digi [ i ] - > GetNumInputCh ( ) ; j + + ) {
2023-06-01 17:51:00 -04:00
if ( hist [ i ] [ j ] ) hist [ i ] [ j ] - > Clear ( ) ;
}
2023-11-06 17:46:43 -05:00
if ( hist2D [ i ] ) hist2D [ i ] - > Clear ( ) ;
2023-05-19 16:23:04 -04:00
}
2023-06-01 17:51:00 -04:00
} ) ;
2024-08-28 16:45:23 -04:00
chkIsFillHistogram = new QCheckBox ( " Fill Histograms " , this ) ;
2024-08-28 16:53:25 -04:00
ctrlLayout - > addWidget ( chkIsFillHistogram , 0 , 6 , 1 , 2 ) ;
2023-06-02 15:41:26 -04:00
chkIsFillHistogram - > setChecked ( false ) ;
2024-08-28 16:45:23 -04:00
isFillingHistograms = false ;
2023-06-02 15:41:26 -04:00
2024-06-17 17:44:31 -04:00
QLabel * lbSettingPath = new QLabel ( settingPath , this ) ;
2024-08-19 18:53:59 -04:00
ctrlLayout - > addWidget ( lbSettingPath , 1 , 0 , 1 , 6 ) ;
QPushButton * bnSaveButton = new QPushButton ( " Save Hist. Settings " , this ) ;
ctrlLayout - > addWidget ( bnSaveButton , 1 , 6 , 1 , 2 ) ;
2024-08-20 11:20:12 -04:00
connect ( bnSaveButton , & QPushButton : : clicked , this , & SingleSpectra : : SaveSetting ) ;
2024-06-17 17:44:31 -04:00
2023-06-01 17:51:00 -04:00
}
{ //^========================
2023-11-06 17:46:43 -05:00
for ( unsigned int i = 0 ; i < nDigi ; i + + ) {
hist2DVisibility [ i ] = false ;
for ( int j = 0 ; j < digi [ i ] - > GetNumInputCh ( ) ; j + + ) {
histVisibility [ i ] [ j ] = false ;
}
}
2023-06-01 17:51:00 -04:00
histBox = new QGroupBox ( " Histgrams " , this ) ;
layout - > addWidget ( histBox ) ;
histLayout = new QGridLayout ( histBox ) ;
histBox - > setLayout ( histLayout ) ;
2023-11-06 17:46:43 -05:00
double eMax = 5000 ;
double eMin = 0 ;
2023-06-02 15:41:26 -04:00
double nBin = 200 ;
2023-06-01 17:51:00 -04:00
for ( unsigned int i = 0 ; i < MaxNDigitizer ; i + + ) {
if ( i > = nDigi ) continue ;
2023-10-09 17:46:32 -04:00
for ( int j = 0 ; j < digi [ i ] - > GetNumInputCh ( ) ; j + + ) {
2023-06-01 17:51:00 -04:00
if ( i < nDigi ) {
2023-11-06 17:46:43 -05:00
hist [ i ] [ j ] = new Histogram1D ( " Digi- " + QString : : number ( digi [ i ] - > GetSerialNumber ( ) ) + " , Ch- " + QString : : number ( j ) , " Raw Energy [ch] " , nBin , eMin , eMax ) ;
2024-08-19 18:53:59 -04:00
if ( digi [ i ] - > GetDPPType ( ) = = DPPTypeCode : : DPP_PSD_CODE ) {
2024-08-20 12:22:26 -04:00
hist [ i ] [ j ] - > AddDataList ( " Short Energy " , Qt : : green ) ;
2024-08-19 18:53:59 -04:00
}
2023-06-01 17:51:00 -04:00
} else {
hist [ i ] [ j ] = nullptr ;
}
2023-05-19 16:23:04 -04:00
}
2023-11-06 17:46:43 -05:00
hist2D [ i ] = new Histogram2D ( " Digi- " + QString : : number ( digi [ i ] - > GetSerialNumber ( ) ) , " Channel " , " Raw Energy [ch] " , digi [ i ] - > GetNumInputCh ( ) , 0 , digi [ i ] - > GetNumInputCh ( ) , nBin , eMin , eMax ) ;
2023-11-21 15:34:29 -05:00
hist2D [ i ] - > SetChannelMap ( true , digi [ i ] - > GetNumInputCh ( ) < 20 ? 1 : 4 ) ;
hist2D [ i ] - > Rebin ( digi [ i ] - > GetNumInputCh ( ) , - 0.5 , digi [ i ] - > GetNumInputCh ( ) + 0.5 , nBin , eMin , eMax ) ;
2023-05-19 16:23:04 -04:00
}
2023-06-01 17:51:00 -04:00
2023-06-02 15:41:26 -04:00
LoadSetting ( ) ;
2023-11-06 17:46:43 -05:00
histLayout - > addWidget ( hist2D [ 0 ] , 0 , 0 ) ;
hist2DVisibility [ 0 ] = true ;
oldBd = 0 ;
oldCh = digi [ 0 ] - > GetNumInputCh ( ) ;
2023-05-19 16:23:04 -04:00
}
2023-05-18 17:14:24 -04:00
2023-06-01 17:51:00 -04:00
layout - > setStretch ( 0 , 1 ) ;
layout - > setStretch ( 1 , 6 ) ;
2023-08-16 17:54:35 -04:00
ClearInternalDataCount ( ) ;
2023-06-01 17:51:00 -04:00
2023-05-17 17:40:32 -04:00
2024-08-28 16:45:23 -04:00
workerThread = new QThread ( this ) ;
histWorker = new HistWorker ( this ) ;
timer = new QTimer ( this ) ;
histWorker - > moveToThread ( workerThread ) ;
// Setup the timer to trigger every second
connect ( timer , & QTimer : : timeout , histWorker , & HistWorker : : FillHistograms ) ;
workerThread - > start ( ) ;
2023-05-17 17:40:32 -04:00
}
2023-06-02 15:41:26 -04:00
SingleSpectra : : ~ SingleSpectra ( ) {
2024-03-22 16:47:33 -04:00
DebugPrint ( " %s " , " SingleSpectra " ) ;
2024-08-28 16:45:23 -04:00
timer - > stop ( ) ;
if ( workerThread - > isRunning ( ) ) {
workerThread - > quit ( ) ;
workerThread - > wait ( ) ;
}
2023-06-02 15:41:26 -04:00
SaveSetting ( ) ;
2023-05-31 17:30:46 -04:00
for ( unsigned int i = 0 ; i < nDigi ; i + + ) {
2023-10-09 17:46:32 -04:00
for ( int ch = 0 ; ch < digi [ i ] - > GetNumInputCh ( ) ; ch + + ) {
2023-05-31 17:30:46 -04:00
delete hist [ i ] [ ch ] ;
2023-05-19 16:23:04 -04:00
}
2023-11-06 17:46:43 -05:00
delete hist2D [ i ] ;
2023-05-19 16:23:04 -04:00
}
}
2023-08-16 17:54:35 -04:00
void SingleSpectra : : ClearInternalDataCount ( ) {
2024-03-22 16:47:33 -04:00
DebugPrint ( " %s " , " SingleSpectra " ) ;
2023-08-16 17:54:35 -04:00
for ( unsigned int i = 0 ; i < nDigi ; i + + ) {
2023-10-06 16:50:28 -04:00
for ( int ch = 0 ; ch < MaxRegChannel ; ch + + ) {
2023-08-16 17:54:35 -04:00
lastFilledIndex [ i ] [ ch ] = - 1 ;
loopFilledIndex [ i ] [ ch ] = 0 ;
}
}
}
2023-06-02 15:41:26 -04:00
void SingleSpectra : : ChangeHistView ( ) {
2024-03-22 16:47:33 -04:00
DebugPrint ( " %s " , " SingleSpectra " ) ;
2023-10-26 17:57:06 -04:00
if ( ! isSignalSlotActive ) return ;
2023-11-06 17:46:43 -05:00
int bd = cbDigi - > currentIndex ( ) ;
int ch = cbCh - > currentData ( ) . toInt ( ) ;
2023-12-12 18:09:43 -05:00
//printf("bd : %d, ch : %d \n", bd, ch);
2023-11-06 17:46:43 -05:00
// Remove oldCh
if ( oldCh > = 0 & & oldCh < digi [ oldBd ] - > GetNumInputCh ( ) ) {
2023-05-31 17:30:46 -04:00
histLayout - > removeWidget ( hist [ oldBd ] [ oldCh ] ) ;
hist [ oldBd ] [ oldCh ] - > setParent ( nullptr ) ;
2023-11-06 17:46:43 -05:00
histVisibility [ oldBd ] [ oldCh ] = false ;
}
if ( oldCh = = digi [ oldBd ] - > GetNumInputCh ( ) ) {
histLayout - > removeWidget ( hist2D [ oldBd ] ) ;
hist2D [ oldBd ] - > setParent ( nullptr ) ;
hist2DVisibility [ oldBd ] = false ;
}
// Add ch
if ( ch > = 0 & & ch < digi [ bd ] - > GetNumInputCh ( ) ) {
histLayout - > addWidget ( hist [ bd ] [ ch ] , 0 , 0 ) ;
histVisibility [ bd ] [ ch ] = true ;
2023-12-12 18:09:43 -05:00
hist [ bd ] [ ch ] - > UpdatePlot ( ) ;
2023-05-19 16:23:04 -04:00
}
2023-11-06 17:46:43 -05:00
if ( ch = = digi [ bd ] - > GetNumInputCh ( ) ) {
histLayout - > addWidget ( hist2D [ bd ] , 0 , 0 ) ;
hist2DVisibility [ bd ] = true ;
2023-12-12 18:09:43 -05:00
hist2D [ bd ] - > UpdatePlot ( ) ;
2023-11-06 17:46:43 -05:00
}
2023-05-19 16:23:04 -04:00
oldBd = bd ;
oldCh = ch ;
2023-11-06 17:46:43 -05:00
// for( unsigned int i = 0; i < nDigi; i++ ){
// if( hist2DVisibility[i] ) printf(" hist2D-%d is visible\n", i);
// for( int j = 0; j < digi[i]->GetNumInputCh(); j++){
// if( histVisibility[i][j] ) printf(" hist-%d-%d is visible\n", i, j);
// }
// }
2023-05-18 17:14:24 -04:00
}
2023-06-02 15:41:26 -04:00
void SingleSpectra : : SaveSetting ( ) {
2024-03-22 16:47:33 -04:00
DebugPrint ( " %s " , " SingleSpectra " ) ;
2023-06-02 15:41:26 -04:00
2024-06-17 17:44:31 -04:00
QFile file ( settingPath ) ;
2023-06-02 15:41:26 -04:00
2024-06-17 17:44:31 -04:00
if ( ! file . exists ( ) ) {
// If the file does not exist, create it
if ( ! file . open ( QIODevice : : WriteOnly ) ) {
qWarning ( ) < < " Could not create file " < < settingPath ;
} else {
qDebug ( ) < < " File " < < settingPath < < " created successfully " ;
file . close ( ) ;
2023-06-02 15:41:26 -04:00
}
}
2024-06-17 17:44:31 -04:00
if ( file . open ( QIODevice : : Text | QIODevice : : WriteOnly ) ) {
for ( unsigned int i = 0 ; i < nDigi ; i + + ) {
file . write ( ( " ======= " + QString : : number ( digi [ i ] - > GetSerialNumber ( ) ) + " \n " ) . toStdString ( ) . c_str ( ) ) ;
for ( int ch = 0 ; ch < digi [ i ] - > GetNumInputCh ( ) ; ch + + ) {
QString a = QString : : number ( ch ) . rightJustified ( 2 , ' ' ) ;
QString b = QString : : number ( hist [ i ] [ ch ] - > GetNBin ( ) ) . rightJustified ( 6 , ' ' ) ;
QString c = QString : : number ( hist [ i ] [ ch ] - > GetXMin ( ) ) . rightJustified ( 6 , ' ' ) ;
QString d = QString : : number ( hist [ i ] [ ch ] - > GetXMax ( ) ) . rightJustified ( 6 , ' ' ) ;
file . write ( QString ( " %1 %2 %3 %4 \n " ) . arg ( a ) . arg ( b ) . arg ( c ) . arg ( d ) . toStdString ( ) . c_str ( ) ) ;
}
QString a = QString : : number ( digi [ i ] - > GetNumInputCh ( ) ) . rightJustified ( 2 , ' ' ) ;
QString b = QString : : number ( hist2D [ i ] - > GetXNBin ( ) - 2 ) . rightJustified ( 6 , ' ' ) ;
QString c = QString : : number ( hist2D [ i ] - > GetXMin ( ) ) . rightJustified ( 6 , ' ' ) ;
QString d = QString : : number ( hist2D [ i ] - > GetXMax ( ) ) . rightJustified ( 6 , ' ' ) ;
QString e = QString : : number ( hist2D [ i ] - > GetYNBin ( ) - 2 ) . rightJustified ( 6 , ' ' ) ;
QString f = QString : : number ( hist2D [ i ] - > GetYMin ( ) ) . rightJustified ( 6 , ' ' ) ;
QString g = QString : : number ( hist2D [ i ] - > GetYMax ( ) ) . rightJustified ( 6 , ' ' ) ;
file . write ( QString ( " %1 %2 %3 %4 %5 %6 %7 \n " ) . arg ( a ) . arg ( b ) . arg ( c ) . arg ( d ) . arg ( e ) . arg ( f ) . arg ( g ) . toStdString ( ) . c_str ( ) ) ;
}
file . write ( " ##========== End of file \n " ) ;
file . close ( ) ;
2024-08-20 11:20:12 -04:00
printf ( " Saved Histogram Settings to %s \n " , settingPath . toStdString ( ) . c_str ( ) ) ;
2024-06-17 17:44:31 -04:00
} else {
printf ( " %s|cannot open HistogramSettings.txt \n " , __func__ ) ;
}
2024-08-20 11:20:12 -04:00
2023-06-02 15:41:26 -04:00
}
void SingleSpectra : : LoadSetting ( ) {
2024-03-22 16:47:33 -04:00
DebugPrint ( " %s " , " SingleSpectra " ) ;
2024-06-17 17:44:31 -04:00
QFile file ( settingPath ) ;
2023-06-02 15:41:26 -04:00
if ( file . open ( QIODevice : : Text | QIODevice : : ReadOnly ) ) {
QTextStream in ( & file ) ;
QString line = in . readLine ( ) ;
int digiSN = 0 ;
int digiID = - 1 ;
while ( ! line . isNull ( ) ) {
2024-06-17 17:44:31 -04:00
if ( line . contains ( " ##========== " ) ) break ;
2023-06-02 15:41:26 -04:00
if ( line . contains ( " // " ) ) continue ;
if ( line . contains ( " ======= " ) ) {
digiSN = line . mid ( 7 ) . toInt ( ) ;
digiID = - 1 ;
for ( unsigned int i = 0 ; i < nDigi ; i + + ) {
if ( digiSN = = digi [ i ] - > GetSerialNumber ( ) ) {
digiID = i ;
break ;
}
}
line = in . readLine ( ) ;
continue ;
}
if ( digiID > = 0 ) {
QStringList list = line . split ( QRegularExpression ( " \\ s+ " ) ) ;
list . removeAll ( " " ) ;
2024-06-17 17:44:31 -04:00
// if( list.count() != 4 ) {
// line = in.readLine();
// continue;
// }
QVector < float > data ;
2023-06-02 15:41:26 -04:00
for ( int i = 0 ; i < list . count ( ) ; i + + ) {
2024-06-17 17:44:31 -04:00
data . push_back ( list [ i ] . toFloat ( ) ) ;
2023-06-02 15:41:26 -04:00
}
2023-11-21 15:34:29 -05:00
if ( 0 < = data [ 0 ] & & data [ 0 ] < digi [ digiID ] - > GetNumInputCh ( ) ) {
2024-06-17 17:44:31 -04:00
hist [ digiID ] [ int ( data [ 0 ] ) ] - > Rebin ( data [ 1 ] , data [ 2 ] , data [ 3 ] ) ;
2023-11-21 15:34:29 -05:00
}
2024-06-17 17:44:31 -04:00
if ( int ( data [ 0 ] ) = = digi [ digiID ] - > GetNumInputCh ( ) & & data . size ( ) = = 7 ) {
hist2D [ digiID ] - > Rebin ( int ( data [ 1 ] ) , data [ 2 ] , data [ 3 ] , int ( data [ 4 ] ) , data [ 5 ] , data [ 6 ] ) ;
2023-11-21 15:34:29 -05:00
}
2023-06-02 15:41:26 -04:00
}
line = in . readLine ( ) ;
}
} else {
2024-06-17 17:44:31 -04:00
printf ( " %s|cannot open HistogramSettings.txt \n " , __func__ ) ;
2023-06-02 15:41:26 -04:00
}
2024-04-05 22:33:05 -04:00
}
QVector < int > SingleSpectra : : generateNonRepeatedCombination ( int size ) {
QVector < int > combination ;
for ( int i = 0 ; i < size ; + + i ) combination . append ( i ) ;
for ( int i = 0 ; i < size - 1 ; + + i ) {
int j = QRandomGenerator : : global ( ) - > bounded ( i , size ) ;
combination . swapItemsAt ( i , j ) ;
}
return combination ;
2023-05-17 17:40:32 -04:00
}