/* gcc -Wall -o sruunpack sruunpack.c g++ -Wall -o sruunpack sruunpack.c `root-config --cflags --glibs` DONE: check on packet_count and prev_packet_count Accept 258 channels (i.e. 2 FECs) Empty channels flagged by: Ett fejkat 6000_FFFF (header,fel, 0 10-bitars ord från chip FFF kanal F) */ #include #include #include #include #define __ROOT #ifdef __ROOT #include "TFile.h" #include "TMapFile.h" #include "TTree.h" #endif int getParameters(int argc, char **argv); char datafile[100]; char rootfile[100]; int firstevent = 1; int lastevent = 0; int events = 0; int dumpraw = 0; int dumpevt = 0; int mkntuples = 0; int getParameters(int argc, char **argv) { const char *short_options = "d:f:l:r"; int option_index = 0; int c; int nbarg = 0; const struct option long_options[]= { {"data",1,0,'d'}, {"dump",0,0,'D'}, {"events",1,0,'e'}, {"first",1,0,'f'}, {"raw",0,0,'r'}, {"root",0,0,'R'}, }; if (argc > 1) { while ((c = getopt_long(argc, argv, short_options, long_options, &option_index)) != EOF) { switch (c) { case 'd': nbarg++; strncpy(datafile,optarg,sizeof(datafile)); break; case 'D': nbarg++; dumpevt = 1; break; case 'f': nbarg++; sscanf(optarg,"%d",&firstevent); break; case 'e': nbarg++; sscanf(optarg,"%d",&events); break; case 'r': nbarg++; dumpraw = 1; break; case 'R': nbarg++; mkntuples = 1; break; default: printf("%s: Unknown option %s\n",__FUNCTION__,argv[optind-1]); return 1; } } if (nbarg == 0) { puts("Arguments:"); puts("--data,-d "); puts("--dump,-D event dump"); puts("--first,-f "); puts("--events,-e "); puts("--raw,-r dump raw data"); puts("--root,-R make root ntuples"); return 1; } } else { puts("Arguments:"); puts("--data,-d "); puts("--dump,-D event dump"); puts("--first,-f "); puts("--events,-e "); puts("--raw,-r dump raw data"); puts("--root,-R make root ntuples"); return 1; } lastevent = firstevent + events - 1; // Check if datafile ends with .dat and make rootfile name char *cptr; strcpy(rootfile,datafile); cptr = strstr(rootfile,".dat"); if (cptr != NULL) { *cptr = '\0'; strcat(cptr,".root"); printf("ROOTFILE: %s\n",rootfile); } else { printf("%s is not a datafile, must end with .dat\n",datafile); return 1; } return 0; } int main(int argc, char **argv) { unsigned int buffer[1000000]; unsigned int header_length; unsigned int packet_length; unsigned int packet_type; unsigned int sru_header[2]; unsigned int saltro_header; unsigned int saltro_channel; unsigned int saltro_errflag; unsigned int saltro_words; unsigned int saltro_length; unsigned int saltro_data; unsigned int saltro_cltime; unsigned int saltro_cllength; unsigned int saltro_buffer[1024]; int nbchannels; int channels_found; int channels_error; int channels_exist[256]; int errorbit_set; int type0_found; int loop = 1; unsigned int *ptr; int nbpackets = 0; int trailers_found; int nbcluster; unsigned int clindex; int sru_event_number; int first_sru_event_number; int sru_packet_count; int sru_prev_packet_count; FILE *infile; int istat; #ifdef __ROOT TFile *f; TTree* tree; unsigned int iEventNb; unsigned short iClLength; unsigned short iClTime; unsigned short iMcm; char iChan; char iChip; int iSamples[1024]; #endif if (getParameters(argc,argv) != 0) exit(1); infile = fopen(datafile,"r"); printf("DATAFILE: %s Events %d %d\n",datafile,firstevent,lastevent); if (infile == NULL) { printf("Could not open %s\n",datafile); return 2; } memset(channels_exist,0,sizeof(channels_exist)); #ifdef __ROOT if (mkntuples != 0) { f = new TFile(rootfile,"RECREATE"); tree = new TTree("tree", "SALTRO events"); tree->Branch("iEventnb",&iEventNb,"iEventNb/i"); tree->Branch("iClLength",&iClLength,"iClLength/s"); tree->Branch("iClTime",&iClTime,"iClTime/s"); tree->Branch("iChan",&iChan,"iChan/B"); tree->Branch("iChip",&iChip,"iChip/B"); tree->Branch("iMcm",&iMcm,"iMcm/s"); tree->Branch("iSamples",&iSamples,"iSamples[iClLength]/I"); } #endif // record at the beginning channels_error = 0; trailers_found = 0; first_sru_event_number = -1; sru_prev_packet_count = 0; while (!feof(infile) && loop) { istat = fread(&packet_length,4,1,infile); if (istat != 1) { printf("%s: fread packet_length returned istat %d\n",argv[0],istat); if (feof(infile)) printf("%s: EOF on %s\n",argv[0],datafile); break; } memset(buffer,0,sizeof(buffer)); istat = fread(buffer,4,packet_length,infile); if (istat != (int) packet_length) { printf("%s: fread buffer returned istat %d packet_length=%08X(%d)\n",argv[0],istat,packet_length,packet_length); if (feof(infile)) printf("%s: EOF on %s\n",argv[0],datafile); for (int j = 0; j < istat; j++) { if ( (j % 8) == 0) { printf("\n%4d:",j); } printf(" %08X",buffer[j]); } putchar('\n'); break; } printf("Packet length=%08X Next length=%08X Packet=%08X istat=%d(%08X)\n", packet_length,buffer[0],buffer[1],istat,istat); header_length = buffer[0]; packet_type = buffer[1]; if (packet_type == 0x11111111) { loop = 1; } else if (packet_type == 0x33333333) { loop = 0; } else if ((events > 0) && (nbpackets >= lastevent)) { loop = 0; } else if (packet_type == 0x22222222) { if (dumpraw != 0) { for (unsigned int j = 0; j < packet_length; j++) { printf("%4d: %08X\n",j,buffer[j]); } } nbpackets++; if (nbpackets >= firstevent) { if (header_length == 2) { printf("SRU ipnumber: %08X\n",buffer[2]); } sru_header[0] = buffer[header_length+1]; sru_header[1] = buffer[header_length+2]; printf("Packet %d: SRU words %08X %08X\n",nbpackets,sru_header[0],sru_header[1]); if ( buffer[header_length+3] & 0x80000000) { sru_header[0] = buffer[header_length+3]; sru_header[1] = buffer[header_length+4]; printf("Packet %d: SRU words %08X %08X\n",nbpackets,sru_header[0],sru_header[1]); channels_found = 0; type0_found = 0; errorbit_set = 0; ptr = &buffer[header_length+5]; } else { channels_found = 0; type0_found = 0; errorbit_set = 0; ptr = &buffer[header_length+3]; } sru_event_number = sru_header[0] & 0x7FFFFFFF; nbchannels = sru_header[1] & 0x3FF; sru_packet_count = (sru_header[1] >> 10) & 0x3FF; printf("SRU: event %d channels %d packet %d\n",sru_event_number,nbchannels,sru_packet_count); if (sru_packet_count != (sru_prev_packet_count + 1)) { printf("*ERR packet: SRU: event %d channels %d packet %d prevpacket %d\n", sru_event_number,nbchannels,sru_packet_count,sru_prev_packet_count); } sru_prev_packet_count = sru_packet_count; if (first_sru_event_number < 0) first_sru_event_number = sru_event_number; for (int k = 0; k < nbchannels; k++) { saltro_header= *ptr++; printf("SALTRO header %08X\n",saltro_header); saltro_channel = saltro_header & 0xFFFF; saltro_errflag = (saltro_header >> 29) & 1; printf("Event: %d Packet: %d Type: %02X Errflag: %X 10bitwords: %X(%d) Channel: %X(%d)\n", sru_event_number,sru_packet_count, ((saltro_header >> 30) & 3), ((saltro_header >> 29) & 1), ((saltro_header >> 16) & 0x3FF),((saltro_header >> 16) & 0x3FF), (saltro_header & 0xFFFF), (saltro_header & 0xFFFF) ); if (saltro_channel >= (128 * 40)) { channels_error++; printf("ERR* Packet %d SRU event %d channel number = %X\n",nbpackets,sru_event_number,saltro_channel); } else { channels_exist[saltro_channel & 255]++; } if (((saltro_header >> 30) & 3) == 0x01) channels_found++; if (((saltro_header >> 30) & 3) == 0x00) type0_found++; if (saltro_errflag == 1) errorbit_set++; saltro_words = (saltro_header >> 16) & 0x3FF; saltro_length = saltro_words/3; if ( (saltro_words % 3) != 0) saltro_length++; if (dumpevt != 0) printf("%4s: %8s %8s %8s %8s\n","word","hex","ADC3","ADC2","ADC1"); for (int j = 0, k=0; j < (int) saltro_length; j++) { saltro_data = *ptr++; saltro_buffer[k++] = (saltro_data >> 20) & 0x3FF; saltro_buffer[k++] = (saltro_data >> 10) & 0x3FF; saltro_buffer[k++] = saltro_data & 0x3FF; if (dumpevt != 0) { printf("%4d: %08X %08X %08X %08X", j,saltro_data,(saltro_data >> 20) & 0x3FF, (saltro_data >> 10) & 0x3FF, saltro_data & 0x3FF); printf(" (%4d %4d %4d)\n", (saltro_data >> 20) & 0x3FF, (saltro_data >> 10) & 0x3FF, saltro_data & 0x3FF); } } saltro_cltime = 0; // No cluster by default saltro_cllength = 0; nbcluster = 0; clindex = 0; // index in buffer for next cluster do { if ( saltro_words != 0) { saltro_cllength = saltro_buffer[clindex++]; // exclude length & time saltro_cltime = saltro_buffer[clindex++]; if (saltro_cllength > 0) saltro_cllength -= 2; // exclude length & time } nbcluster++; printf("Evt: %d Ch: %d Cluster: %d time %d (%08X) length %d (%08X) \n", sru_event_number,saltro_channel,nbcluster,saltro_cltime,saltro_cltime, saltro_cllength,saltro_cllength); if (dumpevt != 0) { for (int j = 0; j < (int) saltro_cllength; j++) { if ((j % 8) == 0) printf("%4d: %5d",j,saltro_buffer[clindex+j]); else if ((j % 8) == 7) printf(" %5d\n",saltro_buffer[clindex+j]); else printf(" %5d",saltro_buffer[clindex+j]); if (saltro_buffer[clindex+j] < 10) printf("*0*"); } putchar('\n'); } #ifdef __ROOT if ((mkntuples != 0) && (saltro_errflag == 0)) { // Right now we skip channels with errorbit set iEventNb = sru_event_number; iChan = saltro_channel & 0xF; iChip = (saltro_channel >> 4) & 0x7; iMcm = (saltro_channel >> 7) & 0x3F; // Find all clusters here and loop iClLength = saltro_cllength; iClTime = saltro_cltime; memcpy(iSamples,&saltro_buffer[clindex],saltro_cllength << 2); tree->Fill(); } #endif if (saltro_cllength != 0) clindex += saltro_cllength; else clindex = saltro_words; // abort if cluster length is zero } while(clindex < saltro_words); } printf("Packet %d SRU event %d: Channels found %d type0=%d errbit=%d\n",nbpackets,sru_event_number,channels_found,type0_found,errorbit_set); if (ptr[0] & 0xC0000000) { printf("Trailer words1: %08X %08X %08X %08X\n",ptr[0],ptr[1],ptr[2],ptr[3]); trailers_found++; sru_prev_packet_count = 0; } else printf("No Trailer words: %08X %08X %08X %08X\n",ptr[0],ptr[1],ptr[2],ptr[3]); ptr+=4; if (ptr[0] & 0xC0000000) printf("Trailer words2: %08X %08X %08X %08X\n",ptr[0],ptr[1],ptr[2],ptr[3]); // buffer[0] = 0; if (feof(infile)) break; } } else { printf("Unknown packet_type %08X, expected %08X\n",packet_type,0x22222222); } } fclose(infile); printf("SRU first event %d last event %d\n",first_sru_event_number,sru_event_number); printf("Packets found %d\n",nbpackets); printf("Trailers found %d\n",trailers_found); printf("Channel number errors found %d\n",channels_error); puts("Channels found"); for (int j = 0; j < 256; j+=16) { printf("%3d - %3d: ",j,j+15); for (int k = j; k < j +16; k++) { printf(" %6d",channels_exist[k]); } putchar('\n'); } #ifdef __ROOT // Save root file also if (mkntuples != 0) { f->Write(); f->Close(); } #endif }