#include #include /* 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); }