PDS_VERSION_ID = PDS3 DATA_SET_ID = {"GO-J-PWS-2-REDR-RTS-SA-FULL-V1.0", "GO-J-PWS-2-REDR-LPW-SA-FULL-V1.0"} PRODUCT_ID = "PWSLIST_C_CODE.TXT" PRODUCT_TYPE = "SOFTWARE" PRODUCT_CREATION_TIME = 1998-02-07 OBJECT = TEXT PUBLICATION_DATE = 1998-02-07 NOTE = " This file contains C code that will produce a calibrated ASCII data file from an uncalibrated binary PWS spectrum analyzer data file. In order to compile this code, the PDS label must first be stripped off and the file should be renamed pwslist.c." END_OBJECT = TEXT END /*--------------------------------------------------------------------- pwslist.c written by L. Granroth 1998-02-07 as an example program for reading Galileo PWS LRS archive data (from "safull" datasets) and using the functions in "pwscal.c" (q.v.) to produce an ASCII text listing of calibrated spectra. Typical compilation and usage: cc -O -o pwslist -I. pwslist.c pwscal.c pwslist < infile > outfile where "infile" is a binary Galileo PWS full-resolution archive file. The files "pwscal.h" and "pwslrcal.tab" are assumed to be in the current working directory. The best examples are simple. This program simply reads from standard input and writes to standard output, processing all available data. No i/o error checking is done. See file "safull.txt" for a description of the input format. See file "pwslist.txt" for a description of the output format, including a description of the frequency coordinates for each column. Note, however, that both electric and magnetic spectra are processed but the highest frequencies (from the HFR portion of the instrument) are always electric. This example selects "spectral density" output units, although other possibilities are available with the "pwscal.c" code. It should also be noted that the output of this program is in no way a substitute for the original input which contains much additional status, timing, and waveform data. This code assumes the int type is at least 32-bits long, but should work with either "big-endian" or "little-endian" byte order. The most complicated part of this code involves checking validity bits derived from parity bits in the original minor frames. These are dummy values for "phase 2" mode, but the checking is included for best results with pre-Jupiter data. ---------------------------------------------------------------------*/ #include #include #include "pwscal.h" /* utility macros to get byte order right for non-negative multi-byte items */ #define bigendian4(p) ( (int)((unsigned char *)(p))[0] << 24 \ | (int)((unsigned char *)(p))[1] << 16 \ | (int)((unsigned char *)(p))[2] << 8 \ | (int)((unsigned char *)(p))[3] ) #define bigendian3(p) ( (int)((unsigned char *)(p))[0] << 16 \ | (int)((unsigned char *)(p))[1] << 8 \ | (int)((unsigned char *)(p))[2] ) char *myname; /*---------------------------------------------------------------------*/ int main (int argc, char *argv[]) { unsigned char inbuf[600]; /* "safull" input record */ int rim, mod91; /* SCLK */ int iant; /* 0 = electric, 1 = magnetic */ char antenna; /* 'E' or 'B' */ int vflag; /* validity flag bits */ int index, ichan; float sum, count; int i, j, sample, section; unsigned char *p; myname = argv[0]; /* initialize for spectral density calibrations (V^2/m^2/Hz and nT^2/Hz) */ if (pwscal_init (SPECTRALDENSITY)) { fprintf (stderr, "%s: ERROR initializing calibrations.\n", myname); exit (-1); } /* loop while data are available from standard input */ while (fread (inbuf, sizeof(inbuf), 1, stdin)) { /* simple check for PWS LRS archive record */ if (strncmp ((char *)inbuf, "GO PWS ", 7)) { fprintf (stderr, "%s: ERROR: invalid input data\n", myname); exit (-1); } /* print leading time string and SCLK value */ fprintf (stdout, "%s", inbuf+7); rim = bigendian3(inbuf+32); mod91 = inbuf[35]; fprintf (stdout, " %08d:%02d", rim, mod91); /* antenna switch position for SA and SFR channels */ iant = bigendian4(inbuf+48) ? 1 : 0; antenna = iant ? 'B' : 'E'; fprintf (stdout, " %c", antenna); /*------------------------------------------------------------------- There are 4 SA channels which may be on either the electric or magnetic antenna and range in frequency from about 5.6 Hz to 31 Hz. Although not available in "phase 2" mode, multiple samples may be available and will be averaged here. -------------------------------------------------------------------*/ index = 124 - 1; /* index of first SA sample */ /* there are four SA channels */ for (ichan = 1; ichan < 5; ichan++) { vflag = inbuf[95+ichan]; /* 7 validity bits */ sum = count = 0.0; /* loop through 7 possible SA samples for this channel */ for (i = 0; i < 7; i++) { index++; /* check validity bit plus verify data is non-zero */ if ((vflag & (1 << i)) && (sample = (int)inbuf[index])) { count++; sum += pwscal_SA (sample, ichan, iant); } } if (count > 0.0) sum /= count; fprintf (stdout, "%10.3e", sum); } /* for all SA channels */ /*------------------------------------------------------------------- There are 112 SFR channels which may be on either the electric or magnetic antenna and range in frequency from about 42 Hz to 161 kHz. Since the uppermost channels overlap with the HFR and since these are omitted in "phase 2" mode, they are not processed here. The last channel returned is number 106 at about 103 kHz. -------------------------------------------------------------------*/ index = 152 - 1; /* index of first SFR sample */ ichan = 0; /* there are four SFR sections */ for (section = 0; section < 4; section++) { p = inbuf + 100 + section * 4; /* pointer to validity word */ vflag = bigendian4(p); /* 28 validity bits */ /* there are 28 channels per section */ for (i = 0; i < 28; i++) { index++; ichan++; /* check validity bit */ if (vflag & (1 << i)) sum = pwscal_SFR ((int)inbuf[index], ichan, iant); else sum = 0.0; fprintf (stdout, "%10.3e", sum); if (ichan >= 106) break; /* skip the last 6 channels */ } } /* for all SFR sections */ /*------------------------------------------------------------------- There are 42 HFR channels which are always on the electric antenna and range in frequency from about 100 kHz to 5.6 MHz. The lower 14 channels may be sampled twice. -------------------------------------------------------------------*/ index = 264 - 1; /* index of first HFR sample */ vflag = bigendian4(inbuf+116); /* 28 validity bits */ i = 0 - 1; /* validity bit position */ /* process the 14 lower channels */ for (ichan = 1; ichan < 15; ichan++) { sum = count = 0.0; /* handle two possible samples per channel */ for (j = 0; j < 2; j++) { index++; i++; if ((vflag & (1 << i)) && (sample = (int)inbuf[index])) { count++; sum += pwscal_HFR (sample, ichan); } } if (count > 0.0) sum /= count; fprintf (stdout, "%10.3e", sum); } /* for each of the lower 14 HFR channels */ vflag = bigendian4(inbuf+120); /* another 28 validity bits */ /* process the 28 upper channels */ for (i = 0; i < 28; i++) { index++; if (vflag & (1 << i)) sum = pwscal_HFR ((int)inbuf[index], 15 + i); else sum = 0.0; fprintf (stdout, "%10.3e", sum); } /* terminate the line */ fprintf (stdout, "\n"); } /* while input is available */ exit (0); } /* pwslist - read PWS LRS "safull" data and print calibrated spectra */