FSUDAQ/DigitizerPHA.cpp
2022-08-23 13:43:05 -04:00

235 lines
16 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "DigitizerPHA.h"
DigitizerPHA::DigitizerPHA(){
DPPType = V1730_DPP_PHA_CODE;
}
DigitizerPHA::DigitizerPHA(int boardID, int portID){
OpenDigitizer(boardID, portID);
}
DigitizerPHA::~DigitizerPHA(){
}
int DigitizerPHA::ProgramBoard(){
ret = CAEN_DGTZ_Reset(handle);
printf("======== program board\n");
ret = CAEN_DGTZ_WriteRegister(handle, Register::DPP::RecordLength_G + 0x7000, 625);
ret = CAEN_DGTZ_WriteRegister(handle, Register::DPP::BoardConfiguration, 0x4E8115);
//TODO change to write register
ret = CAEN_DGTZ_SetAcquisitionMode(handle, CAEN_DGTZ_SW_CONTROLLED); /// software command
ret |= CAEN_DGTZ_SetIOLevel(handle, CAEN_DGTZ_IOLevel_NIM);
ret |= CAEN_DGTZ_SetExtTriggerInputMode(handle, CAEN_DGTZ_TRGMODE_ACQ_ONLY);
ret = CAEN_DGTZ_SetChannelEnableMask(handle, 0xFFFF);
//ret = CAEN_DGTZ_SetNumEventsPerAggregate(handle, 0);
ret = CAEN_DGTZ_SetRunSynchronizationMode(handle, CAEN_DGTZ_RUN_SYNC_Disabled);
if( ret != 0 ) { printf("==== set board error.\n"); return 0;}
printf("======== program Channels\n");
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::DecayTime + 0x7000 , 5000 );
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::TrapezoidFlatTop + 0x7000 , 62 );
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::TrapezoidRiseTime + 0x7000 , 6 );
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::PeakingTime + 0x7000 , 6 );
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::RCCR2SmoothingFactor + 0x7000 , 4 );
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::InputRiseTime + 0x7000 , 6 );
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::TriggerThreshold + 0x7000 , 64 );
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::PeakHoldOff + 0x7000 , 0x3E );
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::TriggerHoldOffWidth + 0x7000 , 0x3E );
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::RiseTimeValidationWindow + 0x7000 , 0x0 );
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::ChannelDCOffset + 0x7000 , 0xEEEE );
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PreTrigger + 0x7000 , 124 );
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::InputDynamicRange + 0x7000 , 0x0 );
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::NumberEventsPerAggregate_G + 0x7000, 5);
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::AggregateOrganization, 0);
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::MaxNumberOfAggregatePerBlockTransfer, 40);
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::DPPAlgorithmControl + 0x7000, 0xe30200f);
if( ret != 0 ) { printf("==== set channels error.\n"); return 0;}
printf("End of program board and channels\n");
return ret;
}
void DigitizerPHA::AutoSetTrapezoidRescalingAndFindGate(double gain, int ch){
int startCh = 0;
int endCh = MaxNChannels;
if( ch >= 0 ){
startCh = ch;
endCh = ch;
}
for( int i = startCh ; i <= endCh; i++){
double riseTime = ReadRegister(Register::DPP::PHA::TrapezoidRiseTime, i) * 4 * ch2ns;
double flatTop = ReadRegister(Register::DPP::PHA::TrapezoidFlatTop, i) * 4 * ch2ns;
unsigned int shift = (unsigned int ) ( log(riseTime * flatTop ) / log(2.0)) ;
SetTrapezoidRescaling(shift, i);
double haha = 0xFFFF * gain * (pow(2, shift) / riseTime / flatTop);
unsigned int fineGain = (unsigned int) (haha);
if( fineGain > 0xFFFF ){
SetEnergyFineGain(0xFFFF, i);
}else{
SetEnergyFineGain(fineGain, i);
}
}
ErrorMsg("PHA-AutoSetTrapezoidRescalingAndFindGate");
}
void DigitizerPHA::PrintBoardConfiguration(){
if( !isConnected ) return;
printf("\e[33m================================================\n");
printf("================ Setting for Board \n");
printf("================================================\e[0m\n");
uint32_t * value = new uint32_t[1];
CAEN_DGTZ_ReadRegister(handle, (uint32_t) Register::BoardConfiguration, value);
printf(" 32 28 24 20 16 12 8 4 0\n");
printf(" | | | | | | | | |\n");
cout <<" Board Configuration : 0b" << bitset<32>(value[0]) << endl;
printf(" : 0x%x\n", value[0]);
printf(" Bit[ 0] = %d = Auto Data Flush \n", value[0] & 0x1);
printf(" Bit[ 1] = %d = Decimated waveform \n", (value[0] >> 1) & 0x1 );
printf(" Bit[ 2] = %d = Trigger propagation \n", (value[0] >> 2) & 0x1 );
printf(" Bit[ 3:10] = %d = must be 001 0001 0 = 22 \n", (value[0] >> 3) & 0xFF );
printf(" Bit[ 11] = %d = Dual Trace \n", (value[0] >> 11) & 0x1 );
printf(" Bit[12:13] = %d = Analog probe 1 : ",((value[0] >> 12) & 0x3 ));
switch ( ((value[0] >> 12) & 0x3 ) ){
case 0 : printf("input\n"); break;
case 1 : printf("RC-CR (1st derivative)\n");break;
case 2 : printf("RC-CR2 (2nd derivative)\n"); break;
case 3 : printf("Trapezoid \n"); break;
}
printf(" Bit[14:15] = %d = Analog probe 2 : ", ((value[0] >> 14) & 0x3 ));
switch ( ((value[0] >> 14) & 0x3 ) ){
case 0 : printf("input\n"); break;
case 1 : printf("Threshold\n"); break;
case 2 : printf("Trapezoid - Baseline\n"); break;
case 3 : printf("baseline.\n"); break;
}
printf(" Bit[ 16] = %d = WaveForm Recording \n",((value[0] >> 16) & 0x1 ) );
printf(" Bit[ 17] = %d = Extras 2 word enable \n", ((value[0] >> 17) & 0x1 ));
printf(" Bit[ 18] = %d = Record Time Stamp \n", ((value[0] >> 18) & 0x1 ));
printf(" Bit[ 19] = %d = Record Energy \n", ((value[0] >> 19) & 0x1 ));
printf(" Bit[20:23] = %d = Digital Virtual probe 1 : ", ((value[0] >> 20) & 0x7 ));
switch (((value[0] >> 20) & 0xF )) {
case 0: printf("Peaking, shows where the energy is calculated; \n"); break;
case 1: printf("”Armed”, digital input showing where the RCCR2 crosses the Threshold\n");
case 2: printf("”Peak Run”, starts with the trigger and last for the whole event\n");
case 3: printf("”Pileup”, shows where a pileup event occurred\n");
case 4: printf("”Peaking”, shows where the energy is calculated\n");
case 5: printf("”TRG Validation Win”, digital input showing the trigger validation acceptance window TVAW\n");
case 6: printf("”Baseline freeze”, shows where the algorithm stops calculating the baseline and its value is frozen\n");
case 7: printf("”TRG Holdoff”, shows the trigger holdoff parameter\n");
case 8: printf("”TRG Validation”, shows the trigger validation signal TRG_VAL \n");
case 9: printf("”Acq Busy”, this is 1 when the board is busy (saturated input signal or full memory board) or there is a veto\n");
case 10: printf("”Zero Cross. Win.”, shows the RT Discrimination Width\n");
case 11: printf("”Ext TRG”, shows the external trigger, when available\n");
case 12: printf("”Busy”, shows when the memory board is full.\n");
}
printf(" Bit[26:28] = %d = Digital Virtual probe 2 : ", ((value[0] >> 26) & 0x7 ));
if( ((value[0] >> 26) & 0x7 ) == 0 ) {
printf("Trigger\n");
}else{
printf("Reserved\n");
}
}
void DigitizerPHA::PrintChannelSettingFromDigitizer(int ch){
if( !isConnected ) return;
printf("\e[33m================================================\n");
printf("================ Setting for channel %d \n", ch);
printf("================================================\e[0m\n");
///DPP algorithm Control
uint32_t * value = new uint32_t[NChannel];
CAEN_DGTZ_ReadRegister(handle, Register::DPP::DPPAlgorithmControl + (ch << 8), value);
printf(" 32 28 24 20 16 12 8 4 0\n");
printf(" | | | | | | | | |\n");
cout <<" DPP algorithm Control : 0b" << bitset<32>(value[0]);
printf(" = 0x%x\n", value[0]);
int trapRescaling = int(value[0]) & 0x1f ;
int polarity = int(value[0] >> 16) & 0x1; /// in bit[16]
int baseline = int(value[0] >> 20) & 0x7; /// in bit[22:20]
int NsPeak = int(value[0] >> 12) & 0x3; /// in bit[13:12]
int rollOver = int(value[0] >> 26) & 0x1;
int pileUp = int(value[0] >> 27) & 0x1;
///DPP algorithm Control 2
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PHA::DPPAlgorithmControl2_G + (ch << 8), value);
cout <<" DPP algorithm Control 2: 0b" << bitset<32>(value[0]) ;
printf(" = 0x%x\n", value[0]);
int extras2WordOption = int(value[0] >> 8) & 0x3;
string extra2WordOptStr = "";
switch (extras2WordOption){
case 0 : extra2WordOptStr = "[0:15] Baseline *4 [16:31] Extended Time Stamp"; break;
case 2 : extra2WordOptStr = "[0:9] Fine Time Stamp [10:15] Reserved [16:31] Extended Time Stamp"; break;
case 4 : extra2WordOptStr = "[0:15] Total Trigger Counter [16:31] Lost Trigger Counter"; break;
case 5 : extra2WordOptStr = "[0:15] Event After the Zero Crossing [16:31] Event Before the Zero Crossing"; break;
default: extra2WordOptStr = "Reserved"; break;
}
printf(" ch2ns : %.0f ns\n", ch2ns);
printf("==========----- input \n");
CAEN_DGTZ_ReadRegister(handle, Register::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, Register::DPP::PreTrigger + (ch << 8), value); printf("%24s %5d samples = %5.0f ns \n", "Pre-tigger", value[0] * 4, value[0] * 4 * ch2ns); ///Pre-trigger
printf("%24s %5.0f samples, DPP-[20:22]\n", "baseline mean", pow(4, 1 + baseline)); ///Ns baseline
CAEN_DGTZ_ReadRegister(handle, Register::DPP::ChannelDCOffset + (ch << 8), value); printf("%24s %.2f %% \n", "DC offset", 100.0 - value[0] * 100./ 0xFFFF); ///DC offset
CAEN_DGTZ_ReadRegister(handle, Register::DPP::InputDynamicRange + (ch << 8), value); printf("%24s %.1f Vpp \n", "input Dynamic", value[0] == 0 ? 2 : 0.5); ///InputDynamic
printf("%24s %s, DPP-[16]\n", "polarity", polarity == 0 ? "Positive" : "negative"); ///Polarity
printf("==========----- discriminator \n");
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PHA::TriggerThreshold + (ch << 8), value); printf("%24s %4d LSB\n", "Threshold", value[0]); ///Threshold
CAEN_DGTZ_ReadRegister(handle, Register::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, Register::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, Register::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, Register::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
printf("==========----- Trapezoid \n");
CAEN_DGTZ_ReadRegister(handle, Register::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, Register::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;
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, Register::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, Register::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, Register::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
printf("%24s %4.0f samples, DPP-[12:13]\n", "Peak mean", pow(4, NsPeak)); ///Ns peak
printf("==========----- Other \n");
CAEN_DGTZ_ReadRegister(handle, Register::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, Register::DPP::ChannelADCTemperature + (ch << 8), value); printf("%24s %d C\n", "Temperature", value[0]); ///Temperature
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PHA::RiseTimeValidationWindow + (ch << 8), value); printf("%24s %.0f ns \n", "RiseTime Vaild Win.", value[0] * ch2ns);
CAEN_DGTZ_ReadRegister(handle, Register::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, Register::DPP::ChannelStatus + (ch << 8), value); printf("%24s 0x%x \n", "Status bit", (value[0] & 0xff) );
CAEN_DGTZ_ReadRegister(handle, Register::DPP::AMCFirmwareRevision + (ch << 8), value); printf("%24s 0x%x \n", "AMC firmware rev.", value[0] );
CAEN_DGTZ_ReadRegister(handle, Register::DPP::VetoWidth + (ch << 8), value); printf("%24s 0x%x \n", "VetoWidth bit", value[0] );
printf("%24s %d = %s\n", "RollOverFlag, DPP-[26]", rollOver, rollOver ? "enable" : "disable" );
printf("%24s %d = %s\n", "Pile-upFlag, DPP-[27]", pileUp, pileUp ? "enable" : "disable" );
printf("%24s %d, %s \n", "Extra2 opt, DPP2-[8:10]", extras2WordOption, extra2WordOptStr.c_str());
printf("========= events storage and transfer\n");
CAEN_DGTZ_ReadRegister(handle, Register::DPP::NumberEventsPerAggregate_G + (ch << 8), value); printf("%24s %d \n", "Event Aggregate", value[0] & 0x3FF);
CAEN_DGTZ_ReadRegister(handle, Register::DPP::AggregateOrganization, value); printf("%24s %d \n", "Buffer Division", ((value[0] & 0x007) < 2 ? 0 : (int)pow(2, value[0] & 7)));
CAEN_DGTZ_ReadRegister(handle, Register::DPP::MaxNumberOfAggregatePerBlockTransfer , value); printf("%24s %d \n", "Num of Agg. / ReadData", value[0] & 0x1FF);
printf("========================================= end of ch-%d\n", ch);
}