Sorce Coding to the C Program: polish.c:
Source Code for the C program polish.c
Polish.c takes fixed HIC packets and decompresses the rate data, as well as verifying the checksums. The output of polish.c can be variable depending on what mode it is compiled in. Going between versions simply involves changing commented out lines in the definitions. The three versions are:
GNLV: General version, which gives both rate and event data.
RATV: Only outputs rate data.
VNTV: Only outputs event data (pulse heights and tag word).
The header file polish.h, which defines entries in the record structure is also available.
/* rexpand.c - checks checksums and decompresses rates fpr GALILEO *
* HIC data. For use in the ratedecomp script only. *
* *
* cc -o polish polish.c -lm *
* *
* Input data must be on stdin, output goes to stdout. *
* *
* Usage: polish < infile > outfile *
* *
* Andrew Davis, Caltech, 7-96 *
* and tlg 8-96 */
/************************************************************************/
/* compiler control of 3 versions -- comment out 2 lines */
#define GNLV 1
/*#define RATV 1*/
/*#define VNTV 1 */ /* inactive line */
#define OK 0
#define SKIP 1
#include
#include "polish.h"
RECORD in ; /* ooh, a nasty global variable... */
int oldcolno = -99 ;
int c6 = 0 ;
int c8 = 0 ;
int cc = 0 ;
int oldc6 = -99 ;
int oldc8 = -99 ;
int oldcc = -99 ;
char bdat[11], junk[200]; /* byte data for cksm, fgets */
long skoffset, skm; /* not used yet */
double frat[8]; /* floating point rates */
/*:::::: collected print statements to improve readability (??) ::::::::*/
#define PRINTTIME \
fprintf (stdout, "%2d %10.6lf %9ld S ", in.yr,in.fldoy,in.sk); \
fprintf (stdout, "%03o %2d %03o" , acstat,colno, cdbits);
#define PRINTRATE \
fprintf (stdout, \
" %3.0lf %3.0lf %3.0lf %2.0lf %4.0lf %4.0lf %5.0lf %5.0lf", \
frat[0],frat[1],frat[2],frat[3],frat[4],frat[5],frat[6],frat[7]);
#define PRINTGPHA(TN) \
fprintf (stdout, \
" T %03x %3x %3x %3x\n", \
in.data[TN],in.data[TN+1],in.data[TN+2],in.data[TN+3]);
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/***************************** a short MAIN routine *********************/
main() { /*** start of MAIN *****/
int rtnval, flag;
while ((rtnval=read_input()) != EOF)
if (rtnval==SKIP) continue;
else {
flag=dochksum();
decompress();
print_out(flag);
}
} /* end main */
/********************* READ a record from stdin **********************/
read_input() { /* start of new function */
int i;
if (fscanf (stdin, "%d", &in.yr)==EOF) return(EOF);
if (in.yr>88) { /* "real" data */
fscanf (stdin, "%lf %ld", &in.fldoy,&in.sk);
for(i=0;i 3 bytes, for chksum */
/* 7 ints -> 11 bytes in bdat[] */
bsquez(ip) int *ip; {
char *p, *op;
unsigned short s[8];
int i;
for (i=0;i<7;i++) s[i] = ip[i]; /* stuff ints into shorts */
p = (char*)s;
op = bdat;
for (i=0;i<3;i++) {
*op++ = (( (*p)&0xff )<<4)|(( (*(p+1))&0xff )>>4);
p ++ ;
*op++ = (( (*p)&0xff )<<4)|( (*(p+1))&0xff );
p += 2;
*op++ = *p++;
}
*op++ = (( (*p)&0xff )<<4)|(( (*(p+1))&0xff )>>4);
p ++ ;
*op = ((*p)&0xff)<<4;
}
/************************************************************************/
int calcrc() { /* calc the crc */
int i,n;
unsigned short x,b;
x = 0;
for(i=0;i<84;i++) {
b = (x^(bdat[i/8]<<(i%8)))&0x80;
x = x<<1;
x = ( (x^b)^(b>>1) )^(b>>7);
}
n= (x&0xff)<<4; /* return 8-bits worth, shifted */
return(n); }
/******* Calculate checksums and compare with the checksums in the *****
* input file. There are three checksums, in.data[CRC1], in.data[CRC2], *
***** in.data[CRC3]. See polish.h for more info **********************/
int dochksum() {
int flag;
flag = OK;
bsquez(&(in.data[0]));
if (calcrc()!=in.data[CRC1]) {
flag += -1;
in.data[RA] = -2;
in.data[RB] = -2;
in.data[RC] = -2;
in.data[T1] = 0; }
bsquez(&(in.data[8]));
if (calcrc()!=in.data[CRC2]) {
flag += -1;
in.data[RD] = -2;
in.data[RE] = -2;
in.data[RG] = -2;
in.data[T5] = 0; }
bsquez(&(in.data[16]));
if (calcrc()!=in.data[CRC3]) {
flag += -1;
in.data[RF] = -2;
in.data[RH] = -2;
in.data[T9] = 0; }
return(flag); }
/******************* DECOMPRESS the eight rates ***********************/
decompress() { /* start of new function */
int mantissa, exponent;
int k;
for (k=RA;k<=RC;k++) {
if (in.data[k]<0) {
frat[k-RA] = -2.;}
if (in.data[k]==0x000) {
frat[k-RA] = 0;}
if (in.data[k]==0x07f) {
in.data[k] = 0 ;
frat[k-RA] = 0.;}
if (in.data[k]==0xf80) {
in.data[k] = 1;}
if (in.data[k]>1) {
mantissa = in.data[k] & 0x07f ;
exponent = (in.data[k] & 0xf80)>>7;
in.data[k] = 1+(((128+mantissa)<<16)>>exponent);
}
if (in.data[k]>0) {
frat[k-RA] = in.data[k];}
if (in.data[k]>256) {
frat[k-RA] = 1.+
((128.5+(double)mantissa)*(double)(1<<(16-exponent)));
in.data[k] = frat[k-RA];
}
/* end of for k */ }
for (k=RD;k<=RG;k++) {
if (in.data[k]<0) {
frat[k-RA] = -2.;}
if (in.data[k]==0x000) {
frat[k-RD+3] = 0;}
if (in.data[k]==0x07f) {
in.data[k] = 0 ;
frat[k-RD+3]= 0.;}
if (in.data[k]==0xf80) {
in.data[k] = 1;}
if (in.data[k]>1) {
mantissa = in.data[k] & 0x07f ;
exponent = (in.data[k] & 0xf80)>>7;
in.data[k] = 1+(((128+mantissa)<<16)>>exponent);
}
if (in.data[k]>0 ) {
frat[k-RD+3] = in.data[k];}
if (in.data[k]>256) {
frat[k-RD+3] = 1.+
((128.5+(double)mantissa)*(double)(1<<(16-exponent)));
in.data[k] = frat[k-RD+3];
}
/* end of for k */ }
for (k=RF;k<=RH;k++) {
if (in.data[k]<0) {
frat[k-RA] = -2.;}
if (in.data[k]==0x000) {
frat[k-RF+6] = 0;}
if (in.data[k]==0x07f) {
in.data[k] = 0 ;
frat[k-RF+6] = 0.;}
if (in.data[k]==0xf80) {
in.data[k] = 1;}
if (in.data[k]>1) {
mantissa = in.data[k] & 0x07f ;
exponent = (in.data[k] & 0xf80)>>7;
in.data[k] = 1+(((128+mantissa)<<16)>>exponent);
}
if (in.data[k]>0 ) {
frat[k-RF+6] = in.data[k];}
if (in.data[k]>256) {
frat[k-RF+6] = 1.+
((128.5+(double)mantissa)*(double)(1<<(16-exponent)));
in.data[k] = frat[k-RF+6];
}
/* end of for k */ }
} /* end of function decompress */
/***************** calc and format the output: PRINT_OUT **************/
print_out (flag) int flag; { /* start of new function */
int colno, cdbits, dcn ;
int dc6, dc8, dcc ;
int acstat, accqual ;
/* ======================================== status calculations ====*****/
colno = in.data[STAT]>>8;
if (colno>0) dcn = colno -1 - oldcolno;
else dcn = 15 - oldcolno;
if (dcn!=0) dcn = 1;
oldcolno=colno;
cdbits = in.data[STAT]&0xff;
if (colno==6) { c6 = cdbits>>1 ;
dc6 = (c6!=oldc6) ;
oldc6 = c6 ; }
if (colno==8) { c8 = cdbits>>6 ;
dc8 = (c8!=oldc8) ;
oldc8 = c8 ; }
if (colno==0xc) { cc = cdbits>>3 ;
dcc = (cc!=oldcc) ;
oldcc = cc ; }
if ((dcc+dc8+dc6)==0) accqual = 0;
if ((oldcc+oldc8+oldc6)<0) accqual = 1;
accqual = dcn;
if ((dc8+dc6)>0) accqual = 2;
if (dcc) accqual = 3;
acstat = cc + 2*c8 + 8*c6 + 64*accqual;
/* ================================== end of status calculations ====****/
/* ****** start the actual printing ugliness **************************/
/* mark the record as bad if there was a bad checksum */
if (flag!=OK) fprintf (stdout, "BAD: flag = %d \n", flag);
#ifndef VNTV
PRINTTIME
PRINTRATE
#ifdef RATV
fprintf (stdout, "\n");
#endif
#endif
#ifdef GNLV
PRINTGPHA(T1)
#endif
#ifdef VNTV
if (in.data[T1]!=0) { /* PRINT non-null events */
PRINTTIME
PRINTGPHA(T1) }
#endif
/* from here down, PRINT 2nd, 3rd lines for VNTV, GNLV only, not RATV ***/
#ifndef RATV
in.sk ++ ;
in.fldoy += 2./(3.*86400.);
if (in.data[T5]!=0) { /* PRINT non-null events */
PRINTTIME
#ifdef GNLV
PRINTRATE
#endif
PRINTGPHA(T5) }
/**** third line **************/
in.sk ++ ;
in.fldoy += 2./(3.*86400.);
if (in.data[T9]!=0) { /* PRINT non-null events*/
PRINTTIME
#ifdef GNLV
PRINTRATE
#endif
PRINTGPHA(T9) }
#endif /* end of ifndef RATV */
} /* end of print_out function */
Back to Galileo HIC Homepage
Last Revised: Saturday May 10, 1997