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 <stdio.h>                                                            
#include <string.h>                                                           
                                                                              
#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 */