Source Code to the C program ipftoascii.c
Source Code to the C program ipftoascii.c
The following is the source code for the C program ipftoascii.c, written by Andrew Davis. It is used to take raw Galileo HIC data in IPF (instrument packet file) format and output rate and event data in a readable ASCII format.
Note:This piece of code is currently undergoing a review. Anyone who chooses to use this source code should contact Heavy Ion Counter personnel at Caltech before using it. The best persons to ask for would beTom Garrard or Andrew Davis.
Also availble is the associated header file ipfindex.h.
/* ipftoascii - takes Galileo HIC IPF format data files *
* and outputs rates and event data in ASCII format. *
* Input is stdin. *
* Output is to stdout. *
* Andrew J. Davis, 6-96 *
* bwg 8-96 *
* *
* cc -o ipftoa ipftoascii.c *
* *
* Usage: ipftoa < infile > outfile */
#define TRUE 1
#define FALSE 0
#define PHASE 1 /* io */
/* #define PHASE 2 /* G1 */
/* #define PHASE 0 /* all that's left */
#define OFFSET 0
#include
#include
#include "ipfindex.h"
struct time t; /* structure "time" defined in ipfindex.h */
struct sclk s; /* structure "sclk" defined in ipfindex.h */
void time_data(unsigned short *pointer, int place);
void time_sclk(unsigned char *pointer, int place);
main()
{
int i,j, ret, found_label, it1[12],it2[12];
int ratestat; /* 3-nibble (12-bit) hic word *
* that may be rate or status */
int rsptr; /* state of hic mux, see below */
int datalen; /* assume length of SFDU can be *
* contained in a 4-byte int, tho it *
* is 8 bytes in the data stream */
int sclen; /* length of s/c header */
int readouts; /* number of HIC readouts in a SFDU */
long oldsk,usk;
unsigned char *buf,*datap,*malloc();
unsigned char label[4],junk[20],ref_label[4];
unsigned short *datawp,prflg;
/* set the file pointer of stdin */
ret = lseek(0,0L,0);
if(ret == -1) {
perror("ipf2ascii: lseek");
exit(3); }
/* should not need more than 1024 byte buffer per SFDU */
buf = malloc(1024);
if(buf == NULL) {
perror("ipf2ascii: malloc");
exit(4); }
rsptr = 9; /* Arbitrary initialization to indicate that rsptr could point to anywhere in SFDU */
s.sk = 0; /* total elapsed minor frames */
prflg = TRUE;
ref_label[0] = 'N'; /* start of SPDU label */
ref_label[1] = 'J';
ref_label[2] = 'P';
ref_label[3] = 'L';
while(1) {
for(i=0;i<4;i++) label[i] = 'X'; /* initialize */
/* scan for SFDU label, assume nothing about it starting on a *
* nice word boundary... */
if ((ret = read(0,label,1))!=1) exit(0);
if (label[0]==ref_label[0]) { /*possibly found it, check for JPL*/
found_label = TRUE;
for (i=1;i<4;i++) {
/* label is a pointer to start of label array */
if ((ret = read(0,label+i,1))!=1) exit(0);
if (label[i] != ref_label[i]) {
found_label = FALSE; break; }}}
else continue; /* back to top of while loop */
if (found_label==FALSE) continue;
/* OK, found the first 4 bytes of the label, assume we've
* got it right. Suck in eight more bytes of label, then
* 4 unused bytes in the datalength field, then 4
* bytes of datalength */
if((ret = read(0, junk, 12))!=12) exit(0);
if((ret = read(0, &datalen, 4))!=4) exit(0);
/* now we know the length of the rest of the SFDU, read it *
* all into a buffer */
if ((ret = read(0, buf, datalen))!=datalen) exit(0);
/* set a unsigned char/short pointer to start of 3iary header */
datap = buf + 72; /* scet and SK */
datawp = (unsigned short*) datap;
oldsk = s.sk;
time_data(datawp,19);
time_sclk(datap,32); /* new s.sk from 3iary header - compare to *
old one which is presumably from incrementing *
after printing. */
if (s.sk!=oldsk) {
printf ("\n??sk??\n");
rsptr = 9;
}
if (prflg) {
prflg = FALSE; /* normal */
/*prflg = TRUE; printf("\n"); special */
printf("start sk = %7ld.%02d = %9ld scet = 95-%03d-%010.6f\n",
s.rim,s.m91,s.sk,t.doy,t.flsod);
if (rsptr==1){
printf ("E=%02d%010.6fK=%9ld ",t.doy,t.flsod,s.sk);
printf (" "); /*39sp*/
}
if (rsptr==2){
printf ("E=%02d%010.6fK=%9ld ",t.doy,t.flsod,s.sk);
printf (" "); /*39sp*/
printf (" "); /*39sp*/
}}
/* the s/c header comes after 122 bytes of assorted GDS headers. *
* If the first byte of the s/c header is 2, the s/c header *
* is 3bytes long. Otherwise it is 7 bytes long. (not!!) */
if (buf[122]==2)
sclen = 3;
else {
sclen = 7;
datap = buf + 122;
datawp = (unsigned short*) datap;
s.rim = (long) datap[3];
s.rim = (s.rim<<16)+datawp[2];
s.m91 = datap[6];
usk = 91*s.rim+s.m91; /* occasional sk from s/c pkt */
if (s.sk != usk) {
printf ("\n!=sk??\n");
rsptr = 9;
}
if (s.sk < usk) printf ("\n<s.sk/2) {
t.flsod += 2.*((float)(s.sk-oldsk))/3.;
t.fldoy += 2.*((float)(s.sk-oldsk))/(3.*86400.);
}
/* else oldsk was probably zero or nonsense */
}
/* now we can find out how many HIC readouts there are in *
* this SFDU. Each readout is 12 bytes, there may be a pad *
* byte at the end which we can forget about. */
readouts = (datalen - 122 - sclen)/12;
/* set a unsigned char pointer to start of HIC readouts */
datap = buf + 122 + sclen;
for (i=0; i (less than)readouts; i++) { /* NOTE: C syntax for "less than" aliased in English here because HTML is stupid */
for (j=0;j<12; j++) { /* and thinks its a tag */
it2[j] = datap[j] & 0x000f ;
it1[j] = (datap[j] >> 4) & 0x00f ;} /* end for loop j */
/* it1[j] is first 4 bits of byte j */
/* it2[j] is second 4 bits of byte j */
/* CALCULATE RATESTAT */
ratestat = datap[3]; /* two nibbles */
ratestat = (ratestat<<4)+it1[4]; /* third*/
/* GET RSPTR, RANGE 0,1,2 OR greater than 6 FOR UNKNOWN */
rsptr += 1;
if ( rsptr> 3) rsptr = (s.sk-PHASE)%3;
/***** if ((rsptr> 3)&&(ratestat==0x07f)) rsptr = 1; **********
if ((rsptr> 3)&&(ratestat==0x300)) rsptr = 2;
if ((rsptr> 3)&&(ratestat==0x400)) rsptr = 2;
if ((rsptr> 3)&&(ratestat==0x500)) rsptr = 2;
if ((rsptr> 3)&&(ratestat==0x700)) rsptr = 2;
if ((rsptr> 3)&&(ratestat==0x880)) rsptr = 2;
if ((rsptr> 3)&&(ratestat==0x900)) rsptr = 2;
***** if ((rsptr> 3)&&(ratestat==0xf80)) rsptr = 1; *********/
if ((rsptr==2)&&(ratestat==0xf80)) rsptr = 9;
if ((rsptr==2)&&(ratestat==0xb80)) rsptr = 9;
if ((rsptr==2)&&(ratestat==0xb40)) rsptr = 9;
if ((rsptr==2)&&(ratestat==0xa80)) rsptr = 9;
if ((rsptr==2)&&(ratestat==0xaa0)) rsptr = 9;
if ((rsptr==2)&&(ratestat==0xac0)) rsptr = 9;
if ((rsptr==2)&&(ratestat==0x07f)) rsptr = 9;
if (ratestat==0x023) rsptr=2; /* Synchronism checks */
if (ratestat==0x100) rsptr=2; /* If ratestat = these status words, then we know */
if (ratestat==0x200) rsptr=2; /* where rsptr is in the sequence of rate, rate, status*/
if (ratestat==0xc00) rsptr=2;
if (ratestat==0xc0f) rsptr=2;
if (ratestat==0xd00) rsptr=2;
if (ratestat==0xe00) rsptr=2;
if (ratestat==0xf00) rsptr=2;
if (rsptr==3) {
rsptr=0;
printf ("%02d %10.6f %9ld ",t.yr,t.fldoy,s.sk-OFFSET);
}
/* IF RSPTR = 2, END LINE WITH \N */
if (rsptr==2) {
printf ("R_%x%x%x %x%x%x S_%x%x%x ",
it1[0],it2[0],it1[1], it2[1],it1[2],it2[2],
it1[3],it2[3],it1[4]);
printf ("T_%x%x%x %x%x%x %x%x%x %x%x%x U%x%x%x\n",
it2[4],it1[5],it2[5],it1[6],it2[6],it1[7],
it2[7],it1[8],it2[8], it1[9],it2[9],it1[10],
it2[10],it1[11],it2[11]);
}
else {
printf ("R_%x%x%x %x%x%x X_%x%x%x ",
it1[0],it2[0],it1[1], it2[1],it1[2],it2[2],
it1[3],it2[3],it1[4]);
printf ("T_%x%x%x %x%x%x %x%x%x %x%x%x U%x%x%x ",
it2[4],it1[5],it2[5], it1[6],it2[6],it1[7],
it2[7],it1[8],it2[8], it1[9],it2[9],it1[10],
it2[10],it1[11],it2[11]);
}
s.m91 ++;
s.sk ++;
t.flsod += 2./3.;
t.fldoy += 2./(3.*86400.);
datap += 12;
} /* for i */
} /* end while(1) */
} /* end main */
/*** time_data - compute the time quantities ***
*** time_sclk - get s/c clock quantities ***
*** pointer - points to start of header ***
*** place - position in header ***/
void time_data(unsigned short *pointer, int place) {
int i;
/* The doy58's start from 0; they should have started from 1. */
t.doy58 = pointer[place]+1;
if (t.doy58<(31*365+ 8)) exit(5);
if (t.doy58>(43*365+11)) exit(5);
/* Quits working after last day of year 2000. */
for (i=32;i<43;i++) {
if (t.doy58<(i*365+((i+1)/4))) break;
}
i--;
t.yr = 58+i;
t.doy = t.doy58-i*365-((int)(i+1)/4);
t.inmsod = (long) pointer[place+1];
t.inmsod = ((t.inmsod<<16)+pointer[place+2]);
t.flmsod = t.inmsod;
t.flsod = t.flmsod/1000.;
t.fldoy = ((double) t.doy) + t.flsod/86400.;
t.insod = t.flsod;
t.inhod = t.flsod/3600.;
t.inmoh = (t.flsod-3600.*((float)t.inhod))/60.;
t.flsom = t.flsod-3600.*((float)t.inhod)-60.*((float)t.inmoh);
t.insom = t.flsom;
}
void time_sclk(unsigned char *pointer, int place) {
s.rim = (long) pointer[place+0];
s.rim = (long) pointer[place+1] + (s.rim<<8);
s.rim = (long) pointer[place+2] + (s.rim<<8);
s.m91 = (int) pointer[place+3];
s.sk = 91*s.rim + s.m91;
}
Last Revision: Friday 18 April, 1997