#include "ClassDigitizer2Gen.h" Digitizer2Gen::Digitizer2Gen(){ printf("======== %s \n",__func__); Initialization(); } Digitizer2Gen::~Digitizer2Gen(){ printf("======== %s \n",__func__); if(isConnected ) CloseDigitizer(); } void Digitizer2Gen::Initialization(){ printf("======== %s \n",__func__); handle = 0; ret = 0; isConnected = false; modelName = ""; cupVersion = ""; DPPVersion = ""; DPPType = ""; serialNumber = 0; adcBits = 0; nChannels = 0; adcRate = 0; ch2ns = 0; IPAddress = ""; netMask = ""; gateway = ""; outFileIndex = 0; dataStartIndetifier = 0xA345; outFile = NULL; outFileSize = 0; } //########################################### Handles functions uint64_t Digitizer2Gen::GetHandle(const char * parameter){ uint64_t par_handle; ret = CAEN_FELib_GetHandle(handle, parameter, &par_handle); if(ret != CAEN_FELib_Success) { ErrorMsg(__func__); return 0; } return par_handle; } uint64_t Digitizer2Gen::GetParentHandle(uint64_t handle){ uint64_t par_handle; ret = CAEN_FELib_GetParentHandle(handle, NULL, &par_handle); if(ret != CAEN_FELib_Success) { ErrorMsg(__func__); return 0; } return par_handle; } std::string Digitizer2Gen::GetPath(uint64_t handle){ char path[256]; ret = CAEN_FELib_GetPath(handle, path); if(ret != CAEN_FELib_Success) { ErrorMsg(__func__); return "Error"; } return path; } //########################################### Read Write std::string Digitizer2Gen::ReadValue(const char * parameter){ if( !isConnected ) return "not connected"; //printf(" %s|%s \n", __func__, parameter); ret = CAEN_FELib_GetValue(handle, parameter, retValue); if (ret != CAEN_FELib_Success) return ErrorMsg(__func__); return retValue; } void Digitizer2Gen::WriteValue(const char * parameter, std::string value){ if( !isConnected ); printf(" %s| %-45s : %s\n", __func__, parameter, value.c_str()); ret = CAEN_FELib_SetValue(handle, parameter, value.c_str()); if (ret != CAEN_FELib_Success) { ErrorMsg(__func__); return; } } void Digitizer2Gen::SendCommand(const char * parameter){ if( !isConnected ); printf("Send Command : %s \n", parameter); ret = CAEN_FELib_SendCommand(handle, parameter); if (ret != CAEN_FELib_Success) { ErrorMsg(__func__); return; } } //########################################### Open digitizer int Digitizer2Gen::OpenDigitizer(const char * url){ printf("======== %s \n",__func__); ret = CAEN_FELib_Open(url, &handle); printf("=== ret : %d | %d \n", ret, CAEN_FELib_Success); if (ret != CAEN_FELib_Success) { ErrorMsg(__func__); return -1; } isConnected = true; modelName = ReadValue("/par/ModelName"); cupVersion = ReadValue("/par/cupver"); DPPVersion = ReadValue("/par/FPGA_FwVer"); DPPType = ReadValue("/par/FwType"); serialNumber = atoi(ReadValue("/par/SerialNum").c_str()); nChannels = atoi(ReadValue("/par/NumCh").c_str()); adcBits = atoi(ReadValue("/par/ADC_Nbit").c_str()); adcRate = atoi(ReadValue("/par/ADC_SamplRate").c_str()); ch2ns = 1000/adcRate; IPAddress = ReadValue("/par/IPAddress"); netMask = ReadValue("/par/Netmask"); gateway = ReadValue("/par/Gateway"); printf(" IP address : %s\n", IPAddress.c_str()); printf(" Net Mask : %s\n", netMask.c_str()); printf(" Gateway : %s\n", gateway.c_str()); printf(" Model name : %s\n", modelName.c_str()); printf(" CUP version : %s\n", cupVersion.c_str()); printf(" DPP Type : %s\n", DPPType.c_str()); printf(" DPP Version : %s\n", DPPVersion.c_str()); printf("Serial number : %d\n", serialNumber); printf(" ADC bits : %d\n", adcBits); printf(" ADC rate : %d Msps, ch2ns : %d ns\n", adcRate, ch2ns); printf(" Channels : %d\n", nChannels); ///========== get endpoint and endpoint folder handle ret = CAEN_FELib_GetHandle(handle, "/endpoint/dpppha", &ep_handle); if (ret != CAEN_FELib_Success) { ErrorMsg("Get Handle"); return -2; } ret = CAEN_FELib_GetParentHandle(ep_handle, NULL, &ep_folder_handle); if (ret != CAEN_FELib_Success) { ErrorMsg("GetParentHandle"); return -3; } ///SendCommand("/cmd/reset"); return 0; } int Digitizer2Gen::CloseDigitizer(){ printf("======== %s \n",__func__); ret = CAEN_FELib_Close(handle); if (ret != CAEN_FELib_Success) { ErrorMsg(__func__); return 0; } isConnected = false; return 0; } //########################################### DAQ void Digitizer2Gen::StartACQ(){ SendCommand("/cmd/armacquisition"); SendCommand("/cmd/swstartacquisition"); } void Digitizer2Gen::StopACQ(){ SendCommand("/cmd/disarmacquisition"); } void Digitizer2Gen::SetPHADataFormat(unsigned dataFormat){ ret = CAEN_FELib_SetValue(ep_folder_handle, "/par/activeendpoint", "dpppha"); if (ret != CAEN_FELib_Success) { ErrorMsg("Set active endpoint"); return; } dataFormatID = dataFormat; if( dataFormatID == 0 ){ ret = CAEN_FELib_SetReadDataFormat(ep_handle, " \ [ \ { \"name\" : \"CHANNEL\", \"type\" : \"U8\" }, \ { \"name\" : \"TIMESTAMP\", \"type\" : \"U64\" }, \ { \"name\" : \"FINE_TIMESTAMP\", \"type\" : \"U16\" }, \ { \"name\" : \"TIMESTAMP_NS\", \"type\" : \"U64\" }, \ { \"name\" : \"ENERGY\", \"type\" : \"U16\" }, \ { \"name\" : \"ANALOG_PROBE_1\", \"type\" : \"I32\", \"dim\" : 1 }, \ { \"name\" : \"ANALOG_PROBE_2\", \"type\" : \"I32\", \"dim\" : 1 }, \ { \"name\" : \"DIGITAL_PROBE_1\", \"type\" : \"U8\", \"dim\" : 1 }, \ { \"name\" : \"DIGITAL_PROBE_2\", \"type\" : \"U8\", \"dim\" : 1 }, \ { \"name\" : \"DIGITAL_PROBE_3\", \"type\" : \"U8\", \"dim\" : 1 }, \ { \"name\" : \"DIGITAL_PROBE_4\", \"type\" : \"U8\", \"dim\" : 1 }, \ { \"name\" : \"ANALOG_PROBE_1_TYPE\", \"type\" : \"U8\" }, \ { \"name\" : \"ANALOG_PROBE_2_TYPE\", \"type\" : \"U8\" }, \ { \"name\" : \"DIGITAL_PROBE_1_TYPE\", \"type\" : \"U8\" }, \ { \"name\" : \"DIGITAL_PROBE_2_TYPE\", \"type\" : \"U8\" }, \ { \"name\" : \"DIGITAL_PROBE_3_TYPE\", \"type\" : \"U8\" }, \ { \"name\" : \"DIGITAL_PROBE_4_TYPE\", \"type\" : \"U8\" }, \ { \"name\" : \"WAVEFORM_SIZE\", \"type\" : \"SIZE_T\" }, \ { \"name\" : \"FLAGS_LOW_PRIORITY\", \"type\" : \"U16\"}, \ { \"name\" : \"FLAGS_HIGH_PRIORITY\", \"type\" : \"U16\" }, \ { \"name\" : \"TRIGGER_THR\", \"type\" : \"U16\" }, \ { \"name\" : \"TIME_RESOLUTION\", \"type\" : \"U8\" }, \ { \"name\" : \"BOARD_FAIL\", \"type\" : \"BOOL\" }, \ { \"name\" : \"FLUSH\", \"type\" : \"BOOL\" }, \ { \"name\" : \"AGGREGATE_COUNTER\", \"type\" : \"U32\" }, \ { \"name\" : \"EVENT_SIZE\", \"type\" : \"SIZE_T\" } \ ] \ "); } if( dataFormatID == 1 ){ ret = CAEN_FELib_SetReadDataFormat(ep_handle, " \ [ \ { \"name\" : \"CHANNEL\", \"type\" : \"U8\" }, \ { \"name\" : \"TIMESTAMP\", \"type\" : \"U64\" }, \ { \"name\" : \"FINE_TIMESTAMP\", \"type\" : \"U16\" }, \ { \"name\" : \"ENERGY\", \"type\" : \"U16\" }, \ { \"name\" : \"ANALOG_PROBE_1\", \"type\" : \"I32\", \"dim\" : 1 }, \ { \"name\" : \"ANALOG_PROBE_1_TYPE\", \"type\" : \"U8\" }, \ { \"name\" : \"WAVEFORM_SIZE\", \"type\" : \"SIZE_T\" }, \ { \"name\" : \"FLAGS_LOW_PRIORITY\", \"type\" : \"U16\"}, \ { \"name\" : \"FLAGS_HIGH_PRIORITY\", \"type\" : \"U16\" }, \ { \"name\" : \"TRIGGER_THR\", \"type\" : \"U16\" }, \ { \"name\" : \"TIME_RESOLUTION\", \"type\" : \"U8\" }, \ { \"name\" : \"BOARD_FAIL\", \"type\" : \"BOOL\" }, \ { \"name\" : \"FLUSH\", \"type\" : \"BOOL\" }, \ { \"name\" : \"AGGREGATE_COUNTER\", \"type\" : \"U32\" }, \ { \"name\" : \"EVENT_SIZE\", \"type\" : \"SIZE_T\" } \ ] \ "); } if( dataFormatID == 2 ){ ret = CAEN_FELib_SetReadDataFormat(ep_handle, " \ [ \ { \"name\" : \"CHANNEL\", \"type\" : \"U8\" }, \ { \"name\" : \"TIMESTAMP\", \"type\" : \"U64\" }, \ { \"name\" : \"FINE_TIMESTAMP\", \"type\" : \"U16\" }, \ { \"name\" : \"ENERGY\", \"type\" : \"U16\" }, \ { \"name\" : \"FLAGS_LOW_PRIORITY\", \"type\" : \"U16\"}, \ { \"name\" : \"FLAGS_HIGH_PRIORITY\", \"type\" : \"U16\" }, \ { \"name\" : \"TRIGGER_THR\", \"type\" : \"U16\" }, \ { \"name\" : \"TIME_RESOLUTION\", \"type\" : \"U8\" }, \ { \"name\" : \"BOARD_FAIL\", \"type\" : \"BOOL\" }, \ { \"name\" : \"FLUSH\", \"type\" : \"BOOL\" }, \ { \"name\" : \"AGGREGATE_COUNTER\", \"type\" : \"U32\" }, \ { \"name\" : \"EVENT_SIZE\", \"type\" : \"SIZE_T\" } \ ] \ "); } if( dataFormatID == 3 ){ ret = CAEN_FELib_SetReadDataFormat(ep_handle, " \ [ \ { \"name\" : \"CHANNEL\", \"type\" : \"U8\" }, \ { \"name\" : \"TIMESTAMP\", \"type\" : \"U64\" }, \ { \"name\" : \"ENERGY\", \"type\" : \"U16\" } \ ] \ "); } if (ret != CAEN_FELib_Success) { ErrorMsg("Set Read Data Format"); return; } } int Digitizer2Gen::ReadData(){ //printf("========= %s \n", __func__); if( dataFormatID == 0){ ret = CAEN_FELib_ReadData(ep_handle, 100, &evt.channel, &evt.timestamp, &evt.fine_timestamp, &evt.timestamp_ns, &evt.energy, &evt.analog_probes0, &evt.analog_probes1, &evt.digital_probes0, &evt.digital_probes1, &evt.digital_probes2, &evt.digital_probes3, &evt.analog_probes_type[0], &evt.analog_probes_type[1], &evt.digital_probes_type[0], &evt.digital_probes_type[1], &evt.digital_probes_type[2], &evt.digital_probes_type[3], &evt.traceLenght, &evt.flags_low_priority, &evt.flags_high_priority, &evt.trigger_threashold, &evt.downSampling, &evt.board_fail, &evt.flush, &evt.aggCounter, &evt.event_size ); evt.timestamp_us = (evt.timestamp*8 + evt.fine_timestamp*0.0078125)/1000.; }else if( dataFormatID == 1){ ret = CAEN_FELib_ReadData(ep_handle, 100, &evt.channel, &evt.timestamp, &evt.fine_timestamp, &evt.energy, &evt.analog_probes0, &evt.analog_probes_type[0], &evt.traceLenght, &evt.flags_low_priority, &evt.flags_high_priority, &evt.trigger_threashold, &evt.downSampling, &evt.board_fail, &evt.flush, &evt.aggCounter, &evt.event_size ); }else if( dataFormatID == 2){ ret = CAEN_FELib_ReadData(ep_handle, 100, &evt.channel, &evt.timestamp, &evt.fine_timestamp, &evt.energy, &evt.flags_low_priority, &evt.flags_high_priority, &evt.trigger_threashold, &evt.downSampling, &evt.board_fail, &evt.flush, &evt.aggCounter, &evt.event_size ); }else if( dataFormatID == 3){ ret = CAEN_FELib_ReadData(ep_handle, 100, &evt.channel, &evt.timestamp, &evt.energy ); }else{ return CAEN_FELib_UNKNOWN; } return ret; if( ret != CAEN_FELib_Success) { ErrorMsg("Set Read Data"); return ret; } } void Digitizer2Gen::ReadDataRaw(){ } //########################################### void Digitizer2Gen::OpenOutFile(std::string fileName){ outFileNameBase = fileName; sprintf(outFileName, "%s_%03d.sol", fileName.c_str(), outFileIndex); outFile = fopen(outFileName, "a+"); fseek(outFile, 0L, SEEK_END); outFileSize = ftell(outFile); // unsigned int = Max ~4GB } void Digitizer2Gen::CloseOutFile(){ fclose(outFile); } void Digitizer2Gen::SaveDataToFile(){ if( outFileSize > (unsigned int) MaxOutFileSize){ fclose(outFile); outFileIndex ++; sprintf(outFileName, "%s_%03d.sol", outFileNameBase.c_str(), outFileIndex); outFile = fopen(outFileName, "a+"); } if( dataFormatID == 0){ fwrite(&dataStartIndetifier, 2, 1, outFile); fwrite(&evt.channel, 1, 1, outFile); fwrite(&evt.energy, 2, 1, outFile); fwrite(&evt.timestamp, 6, 1, outFile); fwrite(&evt.fine_timestamp, 2, 1, outFile); fwrite(&evt.flags_high_priority, 1, 1, outFile); fwrite(&evt.flags_low_priority, 2, 1, outFile); fwrite(&evt.traceLenght, 8, 1, outFile); fwrite(&evt.analog_probes_type[0], 1, 1, outFile); fwrite(evt.analog_probes0, evt.traceLenght*4, 1, outFile); }else if( dataFormatID == 1){ fwrite(&dataStartIndetifier, 2, 1, outFile); fwrite(&evt.channel, 1, 1, outFile); fwrite(&evt.energy, 2, 1, outFile); fwrite(&evt.timestamp, 6, 1, outFile); fwrite(&evt.fine_timestamp, 2, 1, outFile); fwrite(&evt.flags_high_priority, 1, 1, outFile); fwrite(&evt.flags_low_priority, 2, 1, outFile); fwrite(&evt.traceLenght, 8, 1, outFile); fwrite(&evt.analog_probes_type[0], 1, 1, outFile); fwrite(evt.analog_probes0, evt.traceLenght*4, 1, outFile); }else if( dataFormatID == 2){ fwrite(&dataStartIndetifier, 2, 1, outFile); fwrite(&evt.channel, 1, 1, outFile); fwrite(&evt.energy, 2, 1, outFile); fwrite(&evt.timestamp, 6, 1, outFile); fwrite(&evt.fine_timestamp, 2, 1, outFile); fwrite(&evt.flags_high_priority, 1, 1, outFile); fwrite(&evt.flags_low_priority, 2, 1, outFile); }else if( dataFormatID == 3){ //fwrite(&dataStartIndetifier, 2, 1, outFile); fwrite(&evt.channel, 1, 1, outFile); fwrite(&evt.energy, 2, 1, outFile); fwrite(&evt.timestamp, 6, 1, outFile); } // tested speed, 64 readout and save cost ~ 200 us. ~ 5 kHz; //fwrite(evt.digital_probes_type, sizeof(evt.digital_probes_type), 1, outFile); //fwrite(evt.analog_probes1, evt.traceLenght*4, 1, outFile); //fwrite(evt.digital_probes0, evt.traceLenght, 1, outFile); //fwrite(evt.digital_probes1, evt.traceLenght, 1, outFile); //fwrite(evt.digital_probes2, evt.traceLenght, 1, outFile); //fwrite(evt.digital_probes3, evt.traceLenght, 1, outFile); //fwrite(evt.GetWord1(), 8, 1, outFile); //fwrite(evt.GetWord2(), 8, 1, outFile); //fwrite(evt.GetWord3(), 8, 1, outFile); //fwrite(evt.GetWord4(), 8, 1, outFile); //for(int i = 0; i < evt.traceLenght; i++){ // fwrite(evt.GetWordTrace(i), 8, 1, outFile); //} outFileSize = ftell(outFile); // unsigned int = Max ~4GB } //########################################### void Digitizer2Gen::ProgramPHA(bool testPulse){ if( !isConnected ) return ; // Channel enable WriteValue("/ch/0..63/par/ChEnable" , "true"); // Global trigger configuration if( testPulse ) { WriteValue("/par/GlobalTriggerSource", "SwTrg | TestPulse"); }else{ WriteValue("/par/GlobalTriggerSource", "SwTrg"); } WriteValue("/par/TestPulsePeriod" , "25000"); // 0.05 msec = 20kHz WriteValue("/par/TestPulseWidth" , "16"); // Wave configuration WriteValue("/ch/0..63/par/WaveTriggerSource" , "GlobalTriggerSource"); WriteValue("/ch/0..63/par/ChRecordLengthS" , "512"); WriteValue("/ch/0..63/par/ChPreTriggerS" , "100"); WriteValue("/ch/0..63/par/WaveResolution" , "RES8"); /// 8 ns WriteValue("/ch/0..63/par/WaveAnalogProbe0" , "ADCInput"); WriteValue("/ch/0..63/par/WaveAnalogProbe1" , "TimeFilter"); WriteValue("/ch/0..63/par/WaveDigitalProbe0" , "Trigger"); WriteValue("/ch/0..63/par/WaveDigitalProbe1" , "TimeFilterArmed"); WriteValue("/ch/0..63/par/WaveDigitalProbe2" , "EnergyFilterBaselineFreeze"); WriteValue("/ch/0..63/par/WaveDigitalProbe3" , "EnergyFilterPeakReady"); // Event configuration WriteValue("/ch/0..63/par/EventTriggerSource", "GlobalTriggerSource"); // Filter parameters WriteValue("/ch/0..63/par/TimeFilterRiseTimeS" , "10"); WriteValue("/ch/0..63/par/TriggerThr" , "3"); WriteValue("/ch/0..63/par/PulsePolarity" , "Positive"); WriteValue("/ch/0..63/par/EnergyFilterBaselineAvg" , "Medium"); WriteValue("/ch/0..63/par/EnergyFilterFineGain" , "1.0"); WriteValue("/ch/0..63/par/EnergyFilterRiseTimeS" , "100"); WriteValue("/ch/0..63/par/EnergyFilterFlatTopS" , "100"); WriteValue("/ch/0..63/par/EnergyFilterPoleZeroS" , "1000"); WriteValue("/ch/0..63/par/EnergyFilterPeakingPosition" , "80"); WriteValue("/ch/0..63/par/TimeFilterRetriggerGuardS" , "10"); WriteValue("/ch/0..63/par/EnergyFilterPileupGuardT" , "10"); WriteValue("/ch/0..63/par/EnergyFilterBaselineGuardS" , "100"); WriteValue("/ch/0..63/par/EnergyFilterLFLimitation" , "Off"); } std::string Digitizer2Gen::ErrorMsg(const char * funcName){ printf("======== %s | %s\n",__func__, funcName); char msg[1024]; int ec = CAEN_FELib_GetLastError(msg); if (ec != CAEN_FELib_Success) { std::string errMsg = __func__; errMsg += " failed"; printf("%s failed\n", __func__); return errMsg; } printf("last error: %s\n", msg); return msg; }