added dataFormatID, speed up data saving process

This commit is contained in:
Ryan Tang 2023-01-10 16:58:35 -05:00
parent 1fce22bd2b
commit 35f6ee70c4
3 changed files with 259 additions and 144 deletions

View File

@ -32,6 +32,9 @@ void Digitizer2Gen::Initialization(){
gateway = "";
outFileIndex = 0;
dataStartIndetifier = 0xA345;
outFile = NULL;
outFileSize = 0;
}
@ -188,7 +191,7 @@ void Digitizer2Gen::StopACQ(){
}
void Digitizer2Gen::SetPHADataFormat(){
void Digitizer2Gen::SetPHADataFormat(unsigned dataFormat){
ret = CAEN_FELib_SetValue(ep_folder_handle, "/par/activeendpoint", "dpppha");
if (ret != CAEN_FELib_Success) {
@ -196,36 +199,92 @@ void Digitizer2Gen::SetPHADataFormat(){
return;
}
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\" } \
] \
");
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;
@ -235,37 +294,79 @@ void Digitizer2Gen::SetPHADataFormat(){
int Digitizer2Gen::ReadData(){
//printf("========= %s \n", __func__);
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
);
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;
}
evt.timestamp_us = (evt.timestamp*8 + evt.fine_timestamp*0.0078125)/1000.;
return ret;
if( ret != CAEN_FELib_Success) {
@ -279,34 +380,81 @@ void Digitizer2Gen::ReadDataRaw(){
}
//###########################################
void Digitizer2Gen::SaveDataToFile(std::string fileName){
char outFileName[100];
void Digitizer2Gen::OpenOutFile(std::string fileName){
outFileNameBase = fileName;
sprintf(outFileName, "%s_%03d.sol", fileName.c_str(), outFileIndex);
FILE * outFile = fopen(outFileName, "a+");
outFile = fopen(outFileName, "a+");
fseek(outFile, 0L, SEEK_END);
unsigned int outFileSize = ftell(outFile); // unsigned int = Max ~4GB
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", fileName.c_str(), outFileIndex);
sprintf(outFileName, "%s_%03d.sol", outFileNameBase.c_str(), outFileIndex);
outFile = fopen(outFileName, "a+");
}
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);
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);
//}
fclose(outFile);
outFileSize = ftell(outFile); // unsigned int = Max ~4GB
}
@ -324,7 +472,7 @@ void Digitizer2Gen::ProgramPHA(bool testPulse){
}else{
WriteValue("/par/GlobalTriggerSource", "SwTrg");
}
WriteValue("/par/TestPulsePeriod" , "1000000"); // 1 msec = 1kHz
WriteValue("/par/TestPulsePeriod" , "25000"); // 0.05 msec = 20kHz
WriteValue("/par/TestPulseWidth" , "16");
// Wave configuration

View File

@ -8,18 +8,23 @@
//#include "Parameter.h"
#define MaxOutFileSize 2*1024*1024
#define MaxOutFileSize 2*1024*1024*1024
#define MaxTraceLenght 2048
#define DataStartIndetifier 0xA345
struct event {
uint8_t channel; // 6 bit
uint16_t energy; // 16 bit
uint64_t timestamp; // 48 bit
uint16_t fine_timestamp; // 16 bit
uint64_t timestamp_ns; // 51 bit fine_timestamp not included
double timestamp_us;
uint16_t fine_timestamp; // 16 bit
uint16_t energy; // 16 bit
uint16_t flags_low_priority; // 12 bit
uint16_t flags_high_priority; // 8 bit
size_t traceLenght; // 64 bit
uint8_t downSampling; // 8 bit
bool board_fail;
bool flush;
uint8_t analog_probes_type[2]; // 3 bit
uint8_t digital_probes_type[4]; // 4 bit
int32_t analog_probes0[MaxTraceLenght]; // 18 bit
@ -28,12 +33,8 @@ struct event {
uint8_t digital_probes1[MaxTraceLenght];
uint8_t digital_probes2[MaxTraceLenght];
uint8_t digital_probes3[MaxTraceLenght];
size_t traceLenght; // 64 bit
uint16_t trigger_threashold; // 16 bit
uint8_t downSampling; // 8 bit
bool board_fail;
size_t event_size; // 64 bit
bool flush;
uint32_t aggCounter; // 32 bit
void PrintEnergyTimeStamp(){
@ -60,58 +61,6 @@ struct event {
}
}
uint64_t word;
uint64_t* GetWord1(){
word = 0;
word += timestamp;
word += ((((uint64_t)channel & 0x3F) << 48));
word += ((((uint64_t)board_fail) << 58));
word += ((((uint64_t)flush) << 59));
word += (((uint64_t) 0xA) << 60);
return &word;
}
uint64_t* GetWord2(){
word = 0;
word += energy;
word += ((((uint64_t)fine_timestamp & 0x3FF) << 16));
word += ((((uint64_t)flags_low_priority & 0xFFF) << 26));
word += ((((uint64_t)flags_high_priority & 0xFF) << 38));
word += ((((uint64_t)traceLenght) << 46));
return &word;
}
uint64_t* GetWord3(){
word = 0;
word += trigger_threashold;
word += ((((uint64_t)aggCounter) << 16));
word += ((((uint64_t)downSampling) << 48));
return &word;
}
uint64_t* GetWord4(){
word = 0;
word += analog_probes_type[0] & 0x7 ;
word += (((uint64_t)(analog_probes_type[1] & 0x7)) << 3) ;
word += (((uint64_t)(digital_probes_type[0] & 0xF)) << 6) ;
word += (((uint64_t)(digital_probes_type[1] & 0xF)) << 10) ;
word += (((uint64_t)(digital_probes_type[2] & 0xF)) << 14) ;
word += (((uint64_t)(digital_probes_type[3] & 0xF)) << 18) ;
return &word;
}
uint64_t* GetWordTrace(int i){
word = 0;
word += analog_probes0[i] & 0x7FFFF;
word += (((uint64_t)analog_probes1[i] & 0x7FFFF) << 32) ;
word += (((uint64_t)digital_probes0[i]) << 18) ;
word += (((uint64_t)digital_probes1[i]) << 19) ;
word += (((uint64_t)digital_probes2[i]) << 50) ;
word += (((uint64_t)digital_probes3[i]) << 51) ;
return &word;
}
};
class Digitizer2Gen {
@ -142,7 +91,18 @@ class Digitizer2Gen {
std::string ErrorMsg(const char * funcName);
unsigned int dataFormatID; // 0 = all data,
// 1 = analog trace-0 only + flags
// 2 = no trace, only ch, energy, timestamp, fine_timestamp + flags
// 3 = only ch, energy, timestamp, minimum
unsigned short outFileIndex;
unsigned short dataStartIndetifier;
std::string outFileNameBase;
char outFileName[100];
FILE * outFile;
unsigned int outFileSize;
public:
@ -163,7 +123,7 @@ class Digitizer2Gen {
void StartACQ();
void StopACQ();
void SetPHADataFormat();
void SetPHADataFormat(unsigned dataFormat);
int ReadData();
void ReadDataRaw(); //not impletmented
@ -174,7 +134,9 @@ class Digitizer2Gen {
uint64_t GetHandle() {return handle;}
event evt;
void SaveDataToFile(std::string fileName);
void OpenOutFile(std::string fileName);
void CloseOutFile();
void SaveDataToFile();
};

View File

@ -49,13 +49,16 @@ int main(int argc, char* argv[]){
digi->SetPHADataFormat();
digi->SetPHADataFormat(1);
digi->OpenOutFile("haha");
digi->StartACQ();
timespec t0, t1;
clock_gettime(CLOCK_REALTIME, &t0);
for( int i = 0; i < 64*10; i++){
for( int i = 0; i < 64*20; i++){
int ret = digi->ReadData();
if( ret == CAEN_FELib_Success){
@ -68,11 +71,11 @@ int main(int argc, char* argv[]){
digi->SaveDataToFile("haha");
digi->SaveDataToFile();
if( digi->evt.channel == 63 ) {
clock_gettime(CLOCK_REALTIME, &t1);
printf("%3d | t1-t0 : %ld\n", i, t1.tv_nsec-t0.tv_nsec);
printf("%5d | t1-t0 : %10ld\n", i, t1.tv_nsec-t0.tv_nsec);
t0 = t1;
}
}
@ -80,6 +83,8 @@ int main(int argc, char* argv[]){
}
digi->StopACQ();
digi->CloseOutFile();
digi->CloseDigitizer();