295 lines
9.1 KiB
C
295 lines
9.1 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.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;
|
|
|
|
unsigned long long words = 0;
|
|
|
|
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;
|
|
}
|
|
|
|
/*
|
|
printf("Ring Item Body Header: \n" );
|
|
printf(" size : %u\n" , ribh_size);
|
|
printf(" timestamp : %llu\n" , ribh_ts );
|
|
printf(" source ID : %u\n" , ribh_sid );
|
|
printf(" barrier type : %u\n" , ribh_bt );
|
|
*/
|
|
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; }
|
|
|
|
/*
|
|
printf("Fragment Header: \n");
|
|
printf(" Timestamp: %llu\n", frag_ts );
|
|
printf(" Source ID: %u\n", frag_sid );
|
|
printf(" Payload Size: %u\n", frag_paysize);
|
|
printf(" Barrier Type: %u\n", frag_bt );
|
|
printf("Fragment RIH: \n");
|
|
printf(" Size: %u\n", frag_rih_size);
|
|
printf(" Type: %u\n", frag_rih_type);
|
|
printf("Fragment RIBH: \n");
|
|
printf(" Size: %u\n", frag_ribh_size);
|
|
printf(" Timestamp: %llu\n", frag_ribh_ts );
|
|
printf(" Source ID: %u\n", frag_ribh_sid );
|
|
printf(" Barrier Type: %u\n", frag_ribh_bt );
|
|
*/
|
|
|
|
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;
|
|
|
|
sleep(2);
|
|
|
|
}
|
|
|
|
printf("%llu subevents copied\n", evts);
|
|
fclose(infile);
|
|
fclose(outfile);
|
|
|
|
}
|