Sample GRETINA Mode3 (Raw Data) Unpacking Code This is a sample bit of code that properly unpacks raw GRETINA data, with the format as described for GEB header type = 2 (see GEB Headers). Obviously not the only way to code this, but it does the job. #define MAX_TRACE_LENGTH 2048 struct mode3DataPacket { unsigned short aahdr[2]; unsigned short hdr[14]; unsigned short waveform[MAX_TRACE_LENGTH]; }; struct GEBHeader { int32_t type; int32_t length; /* length of payload following the header, in bytes */ int 64_t timestamp; } GEBHeader gHeader; mode3DataPacket *dp; unsigned char gBuf[32*32*1024] = {0}; unsigned char *tmp; unsigned int mode3i = 0; Included below is the code snippet using the structures/variables defined above to unpack GRETINA Mode3 data. This assumes a global header has been read into the gHeader structure, and will result in unpacking all GRETINA channel events following a single global header. int siz = fread(gBuf, gHeader.length, 1, inputFile); if (siz != 1) { cerr << "Error reading GRETINA data. Aborting now... " << endl; exit; } for (int j=0; j<gHeader.length; j++) { swap(*(gBuf + j), *(gBuf + j + 1)); } mode3i = 0; while( (int)(mode3i*2) < gHeader.length ) { tmp = (gBuf + mode3i*2); if !(dp = (mode3DataPacket*)malloc(sizeof(dp->aahdr) + sizeof(dp->hdr) + sizeof(dp->waveform))) ) { exit(-1); } memset(dp->waveform, 1, gMode3.tracelength*sizeof(unsigned short)); memmove(&dp->aahdr[0], tmp, (sizeof(dp->hdr) + sizeof(dp->aahdr))); if ((dp->aahdr[0] != 43690) || (dp->aahdr[1] != 43690)) { cerr << "Didn't find 'AAAA' header as expected!" << endl; } mode3i += (sizeof(dp->aahdr) + sizeof(dp->hdr))/2; gMode3->tracelength = (((dp->hdr[0] & 0x7ff))*2) - 14; tmp = (gBuf + mode3i*2); memmove(&dp->waveform[0], tmp, gMode3->tracelength*sizeof(unsigned short)); mode3i += (gMode3->tracelength*sizeof(unsigned short))/2; tmp = (gBuf + mode3i*2); /* Interpret the header information... */ gMode3->board_id = (dp->hdr[0] >> 11); gMode3->chan_id = (dp->hdr[1] & 0xf); gMode3->module = (dp->hdr[1] >> 4); if (gMode3->module/16 == Q1) { gMode3->id = (gMode3->module - (Q1-Q1E)*4*4)*10 + gMode3->chan_id; } else if (gMode3->module/16 == Q2) { gMode3->id = (gMode3->module - (Q2-Q2E)*4*4)*10 + gMode3->chan_id; } else if (gMode3->module/16 == Q3) { gMode3->id = (gMode3->module - (Q3-Q3E)*4*4)*10 + gMode3->chan_id; } else if (gMode3->module/16 == Q4) { gMode3->id = (gMode3->module - (Q4-Q4E)*4*4)*10 + gMode3->chan_id; } else if (gMode3->module/16 == Q5) { gMode3->id = (gMode3->module - (Q5-Q5E)*4*4)*10 + gMode3->chan_id; } else if (gMode3->module/16 == Q6) { gMode3->id = (gMode3->module - (Q6-Q6E)*4*4)*10 + gMode3->chan_id; } else if (gMode3->module/16 == Q7) { gMode3->id = (gMode3->module - (Q7-Q7E)*4*4)*10 + gMode3->chan_id; } else { gMode3->id = (gMode3->module)*10 + gMode3->chan_id; } int hienergy = 0; hienergy = (dp->hdr[7] & 0x00ff); bool sign = 0; sign = (dp->hdr[7] & 0x0100); assert( (((hienergy) << 16) & (uint)(0xff000000)) == 0); uint tmp_energy = 0; int tmp_int_energy = 0; tmp_energy = ((uint)(hienergy) << 16); tmp_energy += dp->hdr[4]; assert((tmp_energy & 0xff000000) == 0); tmp_int_energy = (int)(tmp_energy); assert((tmp_int_energy & 0xff000000) == 0); if (sign) { if ( (((int)(gMode3->id)%10) == 9) ) { /* CC */ tmp_int_energy = (int)(tmp_int_energy - (int)0x01000000); } else { tmp_int_energy = (int)(tmp_int_energy - (int)0x01000000); tmp_int_energy = -(int)(tmp_int_energy); } } else { if ( (((int)(gMode3->id)%10) == 9) ) { /* CC */ tmp_int_energy = (int)(tmp_int_energy); } else { tmp_int_energy = -(int)(tmp_int_energy); } } gMode3->mask |= 0x0001; gMode3->mask |= 0x0002; gMode3->energy = (tmp_int_energy/32); gMode3->mask |= 0x0004; gMode3->cfd_timestamp = 0; gMode3->led_timestamp = 0; gMode3->cfd_timestamp = (ULong64_t)((ULong64_t)(dp->hdr[6]) + ((ULong64_t)(dp->hdr[9]) << 16) + ((ULong64_t)(dp->hdr[8]) << 32)); gMode3->mask |= 0x0008; gMode3->led_timestamp = (ULong64_t)((ULong64_t)(dp->hdr[3]) + ((ULong64_t)(dp->hdr[2]) << 16) + ((ULong64_t)(dp->hdr[5]) << 32)); gMode3->waveform.clear(); for (int j=0; j<gMode3->tracelength; j++) { if (dp->waveform[j] & 0x8000) { if (gMode3->id%10 == 9) { gMode3->waveform.push_back(dp->waveform[j] - std::numeric_limits<unsigned int>::max()); } else { gMode3->waveform.push_back((-(dp->waveform[j] - std::numeric_limits<unsigned int>::max()))); } } else { if (gMode3->id%10 == 9) { gMode3->waveform.push_back(dp->waveform[j]); } else { gMode3->waveform.push_back((-(dp->waveform[j]))); } } } for (int j=0; j<(gMode3->tracelength+1); j+=2) { swap(gMode3->waveform[j], gMode3->waveform[j+1]); } free(dp); } /* End of while( (int)(mode3i*2) < gHeader.length ) */ |
Analysis >