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                      = "PWSCAL_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 reads the calibration tables and will      
    will apply various requested calibration operations.  In order to         
    compile this code, the PDS label must first be stripped off and the       
    file renamed to pwscal.c."                                                
END_OBJECT                      = TEXT                                        
END                                                                           
/*---------------------------------------------------------------------       
                                                                              
  pwscal.c written by L. Granroth  12-28-95                                   
  as example code for using "PWSLRCAL.TAB" to calibrate Galileo PWS LRS data. 
                                                                              
  These functions are available:                                              
                                                                              
  int pwscal_init (int type);                                                 
    reads calibration tables and initializes                                  
    returns 0 for success and errno for failure                               
    type is the requested calibration units to be returned                    
      1 is either Volts or nano-Tesla                                         
      2 is either E or B field squared (V^2/m^2 or nT^2)                      
      3 is spectral density, either V^2/m^2/Hz or nT^2/Hz                     
                                                                              
  float pwscal_SA (int dn, int chan, int antenna);                            
    calibrates spectrum analyzer data                                         
    returns float calibrated type specified in pwscal_init                    
    dn is uncalibrated 8-bit data number (0 - 255)                            
    chan is SA channel number (1 - 4)                                         
    antenna is 0 for electric and 1 for magnetic                              
                                                                              
  float pwscal_SFR (int dn, int chan, int antenna);                           
    calibrates sweep frequency receiver data                                  
    returns float calibrated type specified in pwscal_init                    
    dn is uncalibrated 8-bit data number (0 - 255)                            
    chan is SFR channel number (1 - 112)                                      
    antenna is 0 for electric and 1 for magnetic                              
                                                                              
  float pwscal_HFR (int dn, int chan);                                        
    calibrates electric high frequency receiver data                          
    returns float calibrated type specified in pwscal_init                    
    dn is uncalibrated 8-bit data number (0 - 255)                            
    chan is HFR channel number (1 - 42)                                       
                                                                              
  Note that if pwscal_init is not called successfully or if invalid           
  arguments are passed to the calibration routines, float zero is returned.   
                                                                              
  ---------------------------------------------------------------------*/     
                                                                              
#define CALIBRATED 1                                                          
#define FIELDSQUARED  2                                                       
#define SPECTRALDENSITY 3                                                     
                                                                              
#define ELECTRIC 0                                                            
#define MAGNETIC 1                                                            
                                                                              
#define CALFILE "PWSLRCAL.TAB"                                                
                                                                              
#include <errno.h>                                                            
#include <stdio.h>                                                            
                                                                              
FILE *calf;                                                                   
                                                                              
float SAcal[256];                                                             
float SFR1cal[256], SFR2cal[256], SFR3cal[256], SFR4cal[256];                 
float HFRcal[256];                                                            
                                                                              
float SAgain[2][4] = {{0.0}};                                                 
float SFRgain[2][112] = {{0.0}};                                              
float HFRgain[42] = {0.0};                                                    
                                                                              
float SAbw[4] = {1.0};                                                        
float SFRbw[4] = {1.0};                                                       
float HFRbw = 1.0;                                                            
float Elength = 1.0;                                                          
                                                                              
/*---------------------------------------------------------------------       
                                                                              
  pwscal_init - initialize Galileo PWS LRS calibrations                       
                                                                              
  ---------------------------------------------------------------------*/     
                                                                              
int                                                                           
pwscal_init (int type)                                                        
{                                                                             
  int i;                                                                      
  float bw;                                                                   
                                                                              
  if (calf) fclose (calf);                                                    
                                                                              
  if (!(calf = fopen (CALFILE, "r"))) return (errno);                         
                                                                              
  for (i = 0; i < 256; i++)                                                   
    if (!fscanf (calf, "%g", SAcal+i)) return (errno);                        
                                                                              
  for (i = 0; i < 256; i++)                                                   
    if (!fscanf (calf, "%g", SFR1cal+i)) return (errno);                      
  for (i = 0; i < 256; i++)                                                   
    if (!fscanf (calf, "%g", SFR2cal+i)) return (errno);                      
  for (i = 0; i < 256; i++)                                                   
    if (!fscanf (calf, "%g", SFR3cal+i)) return (errno);                      
  for (i = 0; i < 256; i++)                                                   
    if (!fscanf (calf, "%g", SFR4cal+i)) return (errno);                      
                                                                              
  for (i = 0; i < 256; i++)                                                   
    if (!fscanf (calf, "%g", HFRcal+i)) return (errno);                       
                                                                              
  for (i = 0; i < 8; i++)                                                     
    if (!fscanf (calf, "%g", SAgain[0]+i)) return (errno);                    
                                                                              
  for (i = 0; i < 224; i++)                                                   
    if (!fscanf (calf, "%g", SFRgain[0]+i)) return (errno);                   
                                                                              
  for (i = 0; i < 42; i++)                                                    
    if (!fscanf (calf, "%g", HFRgain+i)) return (errno);                      
                                                                              
  for (i = 0; i < 4; i++)                                                     
    if (!fscanf (calf, "%g", SAbw+i)) return (errno);                         
                                                                              
  for (i = 0; i < 4; i++)                                                     
    if (!fscanf (calf, "%g", SFRbw+i)) return (errno);                        
                                                                              
  if (!fscanf (calf, "%g", &HFRbw)) return (errno);                           
                                                                              
  if (!fscanf (calf, "%g", &Elength)) return (errno);                         
                                                                              
  fclose (calf); calf = (FILE *)0;                                            
                                                                              
  /* manipulate the calibration and gain arrays for various units */          
                                                                              
  if (type > CALIBRATED) {                                                    
                                                                              
    /* convert calibrated Volts to Volts squared (or nano-Tesla to nT^2) */   
                                                                              
    for (i = 0; i < 256; i++) {                                               
      SAcal[i]   *= SAcal[i];                                                 
      SFR1cal[i] *= SFR1cal[i];                                               
      SFR2cal[i] *= SFR2cal[i];                                               
      SFR3cal[i] *= SFR3cal[i];                                               
      SFR4cal[i] *= SFR4cal[i];                                               
      HFRcal[i]  *= HFRcal[i];                                                
    }                                                                         
                                                                              
    /* convert effective electrical length to meters squared */               
                                                                              
    Elength *= Elength;                                                       
                                                                              
    /* fold electrical length and bandwidths into squared gain multipliers */ 
                                                                              
    for (i = 0; i < 4; i++) {                                                 
      bw = type > FIELDSQUARED ? SAbw[i] : 1.0;                               
      SAgain[ELECTRIC][i] *= SAgain[ELECTRIC][i] / Elength / bw;              
      SAgain[MAGNETIC][i] *= SAgain[MAGNETIC][i] / bw;                        
    }                                                                         
                                                                              
    for (i = 0; i < 112; i++) {                                               
      bw = type > FIELDSQUARED ? SFRbw[i/28] : 1.0;                           
      SFRgain[ELECTRIC][i] *= SFRgain[ELECTRIC][i] / Elength / bw;            
      SFRgain[MAGNETIC][i] *= SFRgain[MAGNETIC][i] / bw;                      
    }                                                                         
                                                                              
    bw = type > FIELDSQUARED ? HFRbw : 1.0;                                   
    for (i = 0; i < 42; i++)                                                  
      HFRgain[i] *= HFRgain[i] / Elength / bw;                                
                                                                              
  } /* if type > CALIBRATED */                                                
                                                                              
  return (0);                                                                 
                                                                              
} /* pwscal_init - initialize Galileo PWS LRS calibrations */                 
                                                                              
/*---------------------------------------------------------------------       
                                                                              
  pwscal_SA - calibrate Galileo PWS LRS SA                                    
                                                                              
  ---------------------------------------------------------------------*/     
                                                                              
float                                                                         
pwscal_SA (int dn, int chan, int antenna)                                     
{                                                                             
                                                                              
  if ((dn < 1) || (dn > 255) || (chan < 1) || (chan > 4)) return (0.0);       
  antenna &= 1;                                                               
                                                                              
  return (SAcal[dn] * SAgain[antenna][--chan]);                               
                                                                              
} /* pwscal_SA - calibrate Galileo PWS LRS SA */                              
                                                                              
/*---------------------------------------------------------------------       
                                                                              
  pwscal_SFR - calibrate Galileo PWS LRS SFR                                  
                                                                              
  ---------------------------------------------------------------------*/     
                                                                              
float                                                                         
pwscal_SFR (int dn, int chan, int antenna)                                    
{                                                                             
                                                                              
  if ((dn < 1) || (dn > 255) || (chan < 1) || (chan > 112)) return (0.0);     
  antenna &= 1;                                                               
                                                                              
  chan--;                                                                     
                                                                              
  switch (chan / 28) {                                                        
                                                                              
    case 0: return (SFR1cal[dn] * SFRgain[antenna][chan]);                    
    case 1: return (SFR2cal[dn] * SFRgain[antenna][chan]);                    
    case 2: return (SFR3cal[dn] * SFRgain[antenna][chan]);                    
    case 3: return (SFR4cal[dn] * SFRgain[antenna][chan]);                    
                                                                              
  } /* switch */                                                              
                                                                              
  return 0.0;                                                                 
                                                                              
} /* pwscal_SFR - calibrate Galileo PWS LRS SFR */                            
                                                                              
/*---------------------------------------------------------------------       
                                                                              
  pwscal_HFR - calibrate Galileo PWS LRS HFR                                  
                                                                              
  ---------------------------------------------------------------------*/     
                                                                              
float                                                                         
pwscal_HFR (int dn, int chan)                                                 
{                                                                             
                                                                              
  if ((dn < 1) || (dn > 255) || (chan < 1) || (chan > 42)) return (0.0);      
                                                                              
  return (HFRcal[dn] * HFRgain[--chan]);                                      
                                                                              
} /* pwscal_HFR - calibrate Galileo PWS LRS HFR */