2023-06-12 16:32:01 -04:00
# ifndef SPLITPOLEANLAYZER_H
# define SPLITPOLEANLAYZER_H
/*********************************************
* This is online analyzer for Split - Pole at FSU
*
* It is a template for other analyzer .
*
* Any new analyzer add to added to FSUDAQ . cpp
2023-06-12 16:41:03 -04:00
* 1 ) add include header
* 2 ) in OpenAnalyzer ( ) , change the new
2023-06-12 16:32:01 -04:00
*
2023-06-12 16:41:03 -04:00
* add the source file in FSUDAQ_Qt6 . pro then compile
2023-06-12 16:32:01 -04:00
* > qmake6 FSUDAQ_Qt6 . pro
* > make
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "Analyser.h"
class SplitPole : public Analyzer {
Q_OBJECT
public :
2023-06-12 16:41:03 -04:00
SplitPole ( Digitizer * * digi , unsigned int nDigi , QMainWindow * parent = nullptr ) : Analyzer ( digi , nDigi , parent ) {
SetUpdateTimeInSec ( 1.0 ) ;
2023-06-20 11:57:39 -04:00
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.
2023-06-14 15:41:26 -04:00
evtbder = GetEventBuilder ( ) ;
2023-06-20 11:57:39 -04:00
//========== use the influx from the Analyzer
influx = new InfluxDB ( " https://fsunuc.physics.fsu.edu/influx/ " ) ;
dataBaseName = " testing " ;
2023-06-12 16:41:03 -04:00
SetUpCanvas ( ) ;
}
/// ~SplitPole(); // comment out = defalt destructor
2023-06-12 16:32:01 -04:00
void SetUpCanvas ( ) ;
public slots :
void UpdateHistograms ( ) ;
private :
2023-06-14 15:41:26 -04:00
MultiBuilder * evtbder ;
2023-06-12 16:32:01 -04:00
2023-06-12 16:41:03 -04:00
// declaie histograms
2023-06-12 16:32:01 -04:00
Histogram2D * h2 ;
Histogram1D * h1 ;
2023-06-20 11:57:39 -04:00
int tick2ns ;
2023-06-12 16:32:01 -04:00
} ;
2023-06-12 16:41:03 -04:00
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.
2023-06-20 11:57:39 -04:00
h2 = new Histogram2D ( " Split Pole PID " , " x " , " y " , 100 , 0 , 10000 , 100 , 0 , 10000 , this ) ;
2023-06-12 16:41:03 -04:00
//layout is inheriatge from Analyzer
layout - > addWidget ( h2 , 0 , 0 ) ;
h1 = new Histogram1D ( " Spectrum " , " x " , 400 , 0 , 10000 , this ) ;
layout - > addWidget ( h1 , 0 , 1 ) ;
2023-06-20 11:57:39 -04:00
2023-06-12 16:41:03 -04:00
}
inline void SplitPole : : UpdateHistograms ( ) {
BuildEvents ( ) ; // call the event builder to build events
//============ Get events, and do analysis
2023-06-14 15:41:26 -04:00
long eventBuilt = evtbder - > eventBuilt ;
2023-06-12 16:41:03 -04:00
if ( eventBuilt = = 0 ) return ;
2023-06-20 11:57:39 -04:00
//============ 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
2023-06-14 15:41:26 -04:00
long eventIndex = evtbder - > eventIndex ;
2023-06-12 16:41:03 -04:00
long eventStart = eventIndex - eventBuilt + 1 ;
if ( eventStart < 0 ) eventStart + = MaxNEvent ;
2023-06-20 11:57:39 -04:00
2023-06-12 16:41:03 -04:00
for ( long i = eventStart ; i < = eventIndex ; i + + ) {
2023-06-20 11:57:39 -04:00
unsigned short e1 = 0 , e2 = 0 ;
unsigned long long t1 = 0 , t2 = 0 ;
2023-06-14 15:41:26 -04:00
std : : vector < EventMember > event = evtbder - > events [ i ] ;
2023-06-20 11:57:39 -04:00
//printf("-------------- %ld\n", i);
2023-06-12 16:41:03 -04:00
for ( int k = 0 ; k < ( int ) event . size ( ) ; k + + ) {
2023-06-20 11:57:39 -04:00
//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 ; }
2023-06-12 16:41:03 -04:00
}
2023-06-20 11:57:39 -04:00
if ( e1 = = 0 ) continue ;
if ( e2 = = 0 ) continue ;
2023-06-12 16:41:03 -04:00
h2 - > Fill ( e1 , e2 ) ;
h1 - > Fill ( e1 ) ;
2023-06-20 11:57:39 -04:00
//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]);
}
}
2023-06-12 16:41:03 -04:00
}
h2 - > UpdatePlot ( ) ;
h1 - > UpdatePlot ( ) ;
2023-06-20 11:57:39 -04:00
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 ( ) ;
}
2023-06-12 16:41:03 -04:00
}
2023-06-12 16:32:01 -04:00
# endif