FRIB_e21062/nscl2pixie.c
2022-05-24 18:21:12 -04:00

289 lines
9.3 KiB
C

#include <stdio.h>
#include <stdlib.h>
/*
Ring Item structure
NSCLDAQ >= 11.0
Ring Item Header
Size (4)
Type (4) (physics item, type=30)
Ring Item Body
Ring Item Body Header
Size (4)
Timestamp (8)
Source ID (4)
Barrier Type (4)
Body (for physics event)
Size (4)
Fragment #0
Fragment Header (20)
Timestamp (8)
Source ID (4)
Payload size in bytes (4)
Barrier Type (4)
Fragment Payload
Ring Item Header (8)
Size (4)
Type (4) (physics item, type=30)
Ring Item Body Header (20)
Size (4)
Timestamp (8)
Source ID (4)
Barrier Type (4)
Ring Item Body (>8)
Body Size (4) - THIS IS IN 16-bit WORDS, NOT BYTES
Device Info (4)
Raw Data (XIA format)
Fragement #1
Fragement Header (20)
Ring Item Header (8)
Ring Item Body Header (20)
Ring Item Body
.
.
.
*/
bool debug = false;
int readRingItemHeader(FILE *file, unsigned int *ri_size) {
unsigned int ri_type;
if (fread(ri_size, (size_t)sizeof(int), 1, file) != 1) {
return -1;
}
if (fread(&ri_type, (size_t)sizeof(int), 1, file) != 1) {
return -1;
}
if (ri_type != 30 ) {
//non-physics item
if (ri_type == 1) {
if( debug) printf("\n============== BEGIN RUN ===============\n");
}
else if (ri_type == 2) {
if( debug) printf("\n============== END RUN ===============\n");
}
else if (ri_type == 3) {
if( debug) printf("\n============== PAUSE RUN ===============\n");
}
else if (ri_type == 4) {
if( debug) printf("\n============== RESUME RUN ===============\n");
}
else if (ri_type == 20) {
if( debug) printf("\nSCALERS FOUND...");
}
else {
if( debug) printf("\nUntreated Ring item: %i %i\n", *ri_size, ri_type);
}
}
return ri_type;
}
int readRingItemBodyHeader(FILE *file) {
unsigned int ribh_size;
unsigned long long int ribh_ts;
unsigned int ribh_sid;
unsigned int ribh_bt;
if (fread(&ribh_size, (size_t)sizeof(int), 1, file) != 1) {
return -1;
}
if (fread(&ribh_ts, (size_t)sizeof(unsigned long long int), 1, file) != 1) {
return -1;
}
if (fread(&ribh_sid, (size_t)sizeof(int), 1, file) != 1) {
return -1;
}
if (fread(&ribh_bt, (size_t)sizeof(int), 1, file) != 1) {
return -1;
}
/*
std::cout << "Ring Item Body Header: " << std::endl;
std::cout << " size : " << ribh_size << std::endl;
std::cout << " timestamp : " << ribh_ts << std::endl;
std::cout << " source ID : " << ribh_sid << std::endl;
std::cout << " barrier type : " << ribh_bt << std::endl;
*/
return ribh_size;
}
int readRingItemBody(FILE *file, unsigned int *rib_size) {
if (fread(rib_size, (size_t)sizeof(int), 1, file) != 1) {
return -1;
}
//std::cout << "Reading ring item body size = " << rib_size << std::endl;
*rib_size -= 4;
return *rib_size;
}
int readNextFragment(FILE *file, unsigned int *rib_size) {
//this skips over the fragment header, the ring item header, and the ring item body header associated with the fragment
//reads the first 2 words of the ring item body (body size + device info)
//leaves the pointer right at the beginning of the actual PIXIE fragment
if (*rib_size > 48) {
//std::cout << "rib_size = " << rib_size << std::endl;
unsigned long long int frag_ts;
unsigned int frag_sid;
unsigned int frag_paysize;
unsigned int frag_bt;
unsigned int frag_rih_size;
unsigned int frag_rih_type;
unsigned int frag_ribh_size;
unsigned long long int frag_ribh_ts;
unsigned int frag_ribh_sid;
unsigned int frag_ribh_bt;
if (fread(&frag_ts, (size_t)sizeof(unsigned long long int), 1, file) != 1) { return -1; }
if (fread(&frag_sid, (size_t)sizeof(int), 1, file) != 1) { return -1; }
if (fread(&frag_paysize, (size_t)sizeof(int), 1, file) != 1) { return -1; }
if (fread(&frag_bt, (size_t)sizeof(int), 1, file) != 1) { return -1; }
if (fread(&frag_rih_size, (size_t)sizeof(int), 1, file) != 1) { return -1; }
if (fread(&frag_rih_type, (size_t)sizeof(int), 1, file) != 1) { return -1; }
if (fread(&frag_ribh_size, (size_t)sizeof(int), 1, file) != 1) { return -1; }
if (fread(&frag_ribh_ts, (size_t)sizeof(unsigned long long int), 1, file) != 1) { return -1; }
if (fread(&frag_ribh_sid, (size_t)sizeof(int), 1, file) != 1) { return -1; }
if (fread(&frag_ribh_bt, (size_t)sizeof(int), 1, file) != 1) { return -1; }
/*
std::cout << "Fragment Header: " << std::endl;
std::cout << " Timestamp: " << frag_ts << std::endl;
std::cout << " Source ID: " << frag_sid << std::endl;
std::cout << " Payload Size: " << frag_paysize << std::endl;
std::cout << " Barrier Type: " << frag_bt << std::endl;
std::cout << "Fragment RIH: " << std::endl;
std::cout << " Size: " << frag_rih_size << std::endl;
std::cout << " Type: " << frag_rih_type << std::endl;
std::cout << "Fragment RIBH: " << std::endl;
std::cout << " Size: " << frag_ribh_size << std::endl;
std::cout << " Timestamp: " << frag_ribh_ts << std::endl;
std::cout << " Source ID: " << frag_ribh_sid << std::endl;
std::cout << " Barrier Type: " << frag_ribh_bt << std::endl;
*/
unsigned int frag_size; //in 16 bit words not 32 bit words
unsigned int dev_info;
if (fread(&frag_size, (size_t)sizeof(int), 1, file) != 1) {
return -1;
}
if (fread(&dev_info, (size_t)sizeof(int), 1, file) != 1) {
return -1;
}
/*
unsigned int ADC_freq = (dev_info & 0x0000ffff);
unsigned int ADC_res = (dev_info & 0xff0000) >> 16;
unsigned int mod_rev = (dev_info & 0xff000000) >> 24;
std::cout << "dev_info = " << ADC_freq << " " << ADC_res << " " << mod_rev << std::endl;
std::cout << "frag_size = " << frag_size << std::endl;
*/
*rib_size -= (48 + frag_size*2);
if (*rib_size < 0 ) {
if( debug) printf("\nSEVERE ERROR, NAVIGATION THROUGH RING BUFFER BROKEN\n");
return -1;
}
}
else if (*rib_size < 48) {
if( debug) printf("\nREMAINING DATA: \n");
int rib_tmp = *rib_size;
int data;
while (rib_tmp > 0) {
fread(&data, (size_t)sizeof(int), 1, file);
if( debug) printf("%i\n", data);
rib_tmp -= 4;
}
}
else {
if( debug) printf("\nWarning! readNextFragment called when rib_size == 0\n");
}
//std::cout << "readNextFragment returning " << rib_size << std::endl;
return *rib_size;
}
int findNextFragment(FILE *file, unsigned int *rib_size) {
if (*rib_size > 0) {
return readNextFragment(file, rib_size);
}
while (1) {
unsigned int ri_size;
int type = readRingItemHeader(file, &ri_size);
if (type == -1) { return -1; }
if (type != 30) {
fseek(file, ri_size-8, SEEK_CUR); //skip the rest of the non-physics event
continue;
}
int ribh_size = readRingItemBodyHeader(file);
if (ribh_size < 0) { return ribh_size; }
readRingItemBody(file, rib_size);
if (*rib_size < 0) { return *rib_size; }
return readNextFragment(file, rib_size);
}
}
int copyPixieSubEvent(FILE *infile, FILE *outfile) {
unsigned int firstWords[4];
if (fread(&firstWords, (size_t) sizeof(int)*4, (size_t) 1, infile) != 1) {
return -1;
}
fwrite(&firstWords, (size_t) sizeof(int)*4, (size_t) 1, outfile);
int headerLength = (firstWords[0] & 0x1F000) >> 12;
int traceLength= (firstWords[3] & 0x7FFF0000) >> 16;
if (headerLength > 4) {
unsigned int otherWords[headerLength-4];
if (fread(&otherWords, (size_t) 4, (size_t) headerLength-4, infile) != (size_t) headerLength-4) {
return -1;
}
fwrite(&otherWords, (size_t) 4, (size_t) headerLength-4, outfile);
}
if (traceLength > 0) {
unsigned short int trace[traceLength]; // = {0};
if (fread(&trace[0], (size_t) 2, (size_t) traceLength, infile) != (size_t) traceLength) {
return -1;
}
fwrite(&trace[0], (size_t) 2, (size_t) traceLength, outfile);
}
return 1;
}
int main(int argc, const char **argv) {
if (argc < 3) {
printf("usage: ./nscl2pixie [infile] [outfile] [debug=0]\n");
return -1;
}
FILE *infile = fopen(argv[1], "rb");
FILE *outfile = fopen(argv[2], "wb");
if( argc == 4 ) debug = atoi(argv[3]);
unsigned int rib_size = 0;
long long unsigned int evts = 0;
int retval = 1;
while (1) {
retval = findNextFragment(infile, &rib_size);
if (retval < 0 ) { break; }
retval = copyPixieSubEvent(infile, outfile);
if (retval < 0 ) { break; }
++evts;
}
printf("%llu subevents copied\n", evts);
fclose(infile);
fclose(outfile);
}