/* * scanraw scans an AMANDA raw data file, determines the byte order, * analyzes the record structure, and reports common problems. * Useage: scanraw [-h] [-v] [infile [outfile]]\n * or: scanraw < infile [ > outfile]\n" * -v = verbose output option, prints record info for normal records * -h = help, prints useage * Version 19970707 * Patrick C. Mock */ #include #include #define CLOCKPROBLEM /* * Define record and event delimiters and their byte swapped versions */ #define EoR 0xffffffff /* End of Record from SaveEvent */ #define CONFIG_RECORD 0x00000101 /* 257 */ #define SWAP_CF_DELIM 0x01010000 #define LP_RECORD 0x00000001 #define SWAP_LP_DELIM 0x01000000 #define HK_RECORD 0x00000003 #define SWAP_HK_DELIM 0x03000000 #define END_HDR 0x00ffffff #define SWAP_END_DELIM 0xffffff00 #define EVTNO_HDR 0x00ffffeb /* software-inserted event number */ #define EVTNO_HDR4B 0xffffeb00 #define SWAP_EVT_DELIM 0x00ebffff #define CLK_HDR 0x00fffff2 #define TTGPS0_HDR 0x00ffff7f #define TTGPS1_HDR 0x00ffff7e #define SAVEFLAG_HDR 0x00ffff10 /* next word indicates why the event */ /* * define actions arrays */ #define HI_HDR 0x00ffffff #define LO_HDR 0x00ffff00 #define ISDELIM(x) ((LO_HDR <= (x)) && ((x) <= HI_HDR )) /* * allocate global variables */ int swapbyte; /* * Get 4-byte Word */ unsigned int getword(FILE *in) { unsigned int t1,t2,t3,t4,word; extern int swapbyte; t1 = getc(in) & 0xff; t2 = getc(in) & 0xff; t3 = getc(in) & 0xff; t4 = getc(in) & 0xff; if (feof(in) != 0) return 0xdeafdeaf; if (swapbyte > 0) word = ((t1 << 24) | (t2 << 16) | (t3 << 8) | t4); else word = ((t4 << 24) | (t3 << 16) | (t2 << 8) | t1); #ifdef DEBUG fprintf(stderr,"4-0x%8x\n",word); #endif return word; } /* * Get 3-byte Word */ unsigned int get3b(FILE *in) { unsigned int t1,t2,t3,word; t1 = getc(in) & 0xff; t2 = getc(in) & 0xff; t3 = getc(in) & 0xff; if (feof(in) != 0) return 0xdeafdeaf; word = ((t1 << 16) | (t2 << 8) | t3); #ifdef DEBUG fprintf(stderr,"3-0x%8x\n",word); #endif return word; } /* * recover 3-byte Word */ unsigned int recover3b(int t1, FILE *in) { unsigned int t2,t3; t2 = getc(in) & 0xff; t3 = getc(in) & 0xff; if (feof(in) != 0) return 0xdeafdeaf; return ((t1 << 16) | (t2 << 8) | t3); } /* * Main program */ int main(int argc, char *argv[]) { int wcnt,rcnt,ecnt,rwcnt,delta,lasteor,zcnt,lp,rec_zero_cnt,etotal; int cntab,cntupdn,cntspase,cntcascade; int startevent,event_zero_cnt,clean_cnt,endhdrcnt,errcnt,evtnocnt; int i,brief,ptr,start,version,rawsize,extracted; unsigned int word,oldword,oldwrd2,size; FILE *IN,*OUT; char rectype[] = "no"; int byte = 0 , recover3bytes = 0 , configrec = 0 , noclock = 0; extern int swapbyte; extern int isatty(int); int action_array[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,13,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,0,18,17,16,15,14,4,4,4,4,4,7,0,2,2,2,2,6,5,3,3,3,3,3,3,3,3,1,1,1, 1,9}; int *actions = (action_array - LO_HDR); static char databuf[BUFSIZ]; static int actcnt[32],unknown[256]; char *actstr[]={"None","3377","2277","7164","4300","LD_GPS","IntReg","Evt#", "TT_GPS","EndHdr","SaveFlag","7164 Block","Digital OM", "Misc HDR","3377 Config","2277 Config","7164 Config", "4300 Config","2251"}; /* * Parse command line and initialize I/O */ cntab = cntupdn = cntspase = cntcascade = 0; IN = stdin ; OUT = stdout; brief = 1 ; ptr = 1 ; extracted = 0; if (argc > 1) { if (strcmp(argv[1],"-h") == 0) { fprintf(stderr,"Useage: %s [-h] [-v] [infile [outfile]]\n",argv[0]); fprintf(stderr," or: %s < infile [ > outfile]\n",argv[0]); fprintf(stderr," -v = verbose output option, prints record info for normal records\n"); fprintf(stderr," -h = print this help message\n"); return 0; } if (strcmp(argv[1],"-x") == 0) { brief = 0; extracted = 1; ptr = 2; } if (strcmp(argv[1],"-v") == 0) { brief = 0; ptr = 2; } if (argc > ptr) { IN = fopen(argv[ptr++],"rb"); if (IN == NULL) { fprintf(stderr,"File not found: %s\n",argv[--ptr]); return 1; } setvbuf(IN,databuf,_IOFBF,BUFSIZ); } if (argc > ptr) { OUT = fopen(argv[ptr],"w"); if (OUT == NULL) { fprintf(stderr,"Error opening file: %s\n",argv[ptr]); return 1; } } } else { if (isatty(fileno(IN))) { fprintf(stderr,"Useage: %s [-h] [-v] [infile [outfile]]\n",argv[0]); fprintf(stderr," or: %s < infile [ > outfile]\n",argv[0]); fprintf(stderr," -v = verbose output option, prints record info for normal records\n"); fprintf(stderr," -h = print this help message\n"); return 0; } } /* * Initialize counters and swap status, print header */ swapbyte = 0; rec_zero_cnt = lasteor = wcnt = rcnt = ecnt = rwcnt = zcnt = lp = errcnt = 0; startevent = etotal = event_zero_cnt = clean_cnt = endhdrcnt = evtnocnt = 0; start = version = size = rawsize = 0; oldword = word = EoR; fprintf(OUT,"Record Rec # of # of Size\n"); fprintf(OUT,"Type Location Size Rec# Events Zeros Error\n"); /* * analyze raw data file structure */ while(1) { oldwrd2 = oldword; oldword = word; if (lp == 0) word = getword(IN); else { if (version < 19970225) word = getword(IN); else { if (recover3bytes == 0) word = get3b(IN); else { word = recover3b(byte,IN); recover3bytes = 0; } } } if (feof(IN) != 0) break; wcnt++ ; rwcnt++; /* * Check for blocks of zeros in the data */ if (word == 0) { if (oldword != EVTNO_HDR) zcnt++; } else { if (zcnt > 1 && lp == 1) { event_zero_cnt += zcnt; rec_zero_cnt += zcnt; } zcnt = 0; } /* * count delimiters */ if (lp == 1) { if(ISDELIM(word)) { int act; act = actions[word]; actcnt[act]++; if (act == 0) { unknown[word-LO_HDR]++; #ifdef DEBUG fprintf(OUT,"0x%06x\n0x%06x\n0x%06x\n",oldwrd2,oldword,word); for(i=0;i<20;i++) fprintf(OUT,"0x%06x\n",get3b(IN)); return 0; #endif } } } /* * Check for record delimiters and process accordingly * print record structure, record by record */ switch (word) { case SWAP_CF_DELIM: if (oldword == EoR) swapbyte += 1; case CONFIG_RECORD: if (oldword == EoR) { configrec = 1; rawsize = getword(IN); start = wcnt; version = getword(IN) ; wcnt++ ; rwcnt++; fprintf(stderr,"version = %d\n",version); size = (version > 19970224) ? (rawsize >> 2) - 3 : rawsize ; rectype[0] = 'C' ; rectype[1] = 'F' ; } break; case SWAP_LP_DELIM: if (oldword == EoR) swapbyte += 1; case LP_RECORD: if (oldword == EoR) { ecnt = 0; size = getword(IN); if (size > 0 || extracted != 0) lp = 1; size = (version > 19970224) ? size/3 : size; start = wcnt; rectype[0] = 'L' ; rectype[1] = 'P' ; } break; case SWAP_HK_DELIM: if (oldword == EoR) swapbyte += 1; case HK_RECORD: if (oldword == EoR) { size = getword(IN); start = wcnt; rectype[0] = 'H' ; rectype[1] = 'K' ; } break; #ifdef CLOCKPROBLEM case TTGPS0_HDR: case TTGPS1_HDR: case CLK_HDR: word = (version < 19970225) ? getword(IN) : get3b(IN); wcnt++ ; rwcnt++; if (word < LO_HDR) { word = (version < 19970225) ? getword(IN) : get3b(IN); wcnt++ ; rwcnt++; if (word < LO_HDR) { word = (version < 19970225) ? getword(IN) : get3b(IN); wcnt++ ; rwcnt++; if (word < LO_HDR) break; } } noclock++ ; errcnt++; if (word != END_HDR) break; #endif case END_HDR: if (oldword != END_HDR) { if (startevent == 1 && event_zero_cnt == 0) clean_cnt++; startevent = 0; ecnt++ ; endhdrcnt++; break; } else { byte = getc(IN); if (byte != 0xff) { fprintf(OUT,"\nDouble END_HDR, next byte =0x%x\n",byte); recover3bytes = 1; break; } actcnt[actions[word]]--; word = EoR; } case EoR: if (lp != 0) etotal += ecnt; rcnt++ ; delta = rwcnt - size - 2; if (rec_zero_cnt > 0 || (delta != 0 && extracted == 0)) { errcnt++; fprintf(OUT," %s %11d %7d",rectype,start,size); fprintf(OUT,"%6d %6d EoR",rcnt,ecnt); fprintf(OUT," %7d %7d %7d error",rec_zero_cnt,delta,rawsize); fprintf(OUT,"\n"); } else if (brief == 0) { fprintf(OUT," %s %11d %7d",rectype,start,size); fprintf(OUT,"%6d %6d EoR",rcnt,ecnt); fprintf(OUT,"\n"); } lp = rec_zero_cnt = ecnt = rwcnt = startevent = 0; start = size = -1; rectype[0] = 'n' ; rectype[1] = 'o' ; /* no record type */ lasteor = wcnt; break; case SWAP_EVT_DELIM: swapbyte += 1; case EVTNO_HDR4B: if (lp == 0) { recover3bytes = lp = 1 ; byte = 0; version = 19970225; } if (configrec == 0) fprintf(OUT,"No configuration record\n"); case EVTNO_HDR: evtnocnt++; startevent = 1; event_zero_cnt = 0; if (version < 19970225) {getword(IN) ; wcnt++ ; rwcnt++;} else { get3b(IN) ; get3b(IN) ; wcnt += 2 ; rwcnt += 2;} break; case SAVEFLAG_HDR: word = get3b(IN); wcnt++ ; rwcnt++; if ((word & 2) != 0) cntab++; if ((word & 4) != 0) cntupdn++; if ((word & 8) != 0) cntspase++; if ((word & 16) != 0) cntcascade++; break; default: break; } } /* * Report final results */ fprintf(OUT,"\n\n"); if (word == 0xdeafdeaf) { if (oldwrd2 != 0x00ffffff || oldword != 0xffffffff) fprintf(OUT,"Last 2 words = 0x%08x 0x%08x\n",oldwrd2,oldword); } else { fprintf(OUT,"Last 3 words = 0x%8x 0x%8x 0x%8x\n",oldwrd2,oldword,word); } fprintf(OUT,"Version = %d (from the last configuration record)\n",version); fprintf(OUT,"Words = %d, Records = %d, Lost words after last EoR = %d\n", wcnt,rcnt,wcnt-lasteor); fprintf(OUT,"END_HDR cnt = %d, LP events == %d, Clean events = %d\n", endhdrcnt,etotal,clean_cnt); fprintf(OUT,"Error count = %d Event number cnt = %d\n",errcnt,evtnocnt); if(noclock) fprintf(OUT,"Events missing GPS clock data = %d\n",noclock); if (swapbyte > 0) fprintf(OUT,"Note: The raw data is byte swapped.\n"); else fprintf(OUT,"Note: The raw data is not byte swapped.\n"); if (swapbyte > 1) fprintf(OUT,"Swapbyte cnt = %d\n",swapbyte); fprintf(OUT,"\n Header Count\n"); for(i=0;i<32;i++) { if (actcnt[i] > 0) fprintf(OUT,"%12s %9d\n",actstr[i],actcnt[i]); } for(i=0;i<255;i++) { if (unknown[i] > 0) fprintf(OUT,"%12x %9d\n",i+LO_HDR,unknown[i]); } fprintf(OUT,"\n"); if (cntab > 0) fprintf(OUT,"A/B Coincidences = %d\n",cntab); if (cntupdn > 0) fprintf(OUT,"Up Down Events = %d\n",cntupdn); if (cntspase > 0) fprintf(OUT,"SPASE Events = %d\n",cntspase); if (cntcascade > 0) fprintf(OUT,"Cascade Events = %d\n",cntcascade); return errcnt; }