289 lines
9.3 KiB
C
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);
|
||
|
|
||
|
}
|