OMS Data Receipt (ODR) Pipeline CVTFOF Process Design Document


Contents


CVTFOF Process Overview

The CVTFOF process is a new OMS Data Receipt (ODR) Pipeline process responsible
for producing HST Telemetry Subset Files when AEDP HST Subset processing is 
termimated in the fall of 1998.  CVTFOF produces subsets by converting CCS FOF 
All-Points Merged Engineering Telemetry into Change-Only Engineering Telemetry.
For the most part, CVTFOF Subsets and current AEDP Subsets will contain the 
same information and be in the same format.  The major difference being that 
CVTFOF subsets do not contain S/C Clock to UT conversion data.  This difference
in content will have to be accounted for by processes reading the subset files; 
namely the OMSANAL process.  Modifications made to OMSANAL will be made in such
a way that either CVTFOF or AEDP subsets can be processed; thus maintaining the
capability to perform re-processing of old AEDP subsets.  OPR 36121 was filed 
to address OMSANAL process modifications.  

A second responsibility of the CVTFOF process is to produce the Telemetry Error Files 
currently produced by the PREPROC process. In the CVTFOF Process Files section
of this document, telemetry error files are referred to as "Telemetry Gap 
Files."  The PREPROC process will become inactive when CCS FOF generation 
comes on-line however the process will be retained for re-processing of old 
AEDP subsets.  Like PREPROC, CVTFOF will produce a Telemetry Error File for 
every Engineering Subset file produced.  The CVTFOF error files and PREPROC 
error files will be in the same format and provide the same information with 
the exception of drop messages; CVTFOF produced error files will not contain 
drop messages.  As with content differences with subset files, the OMSANAL 
process will account for the abscence of dop messages in CVTFOF produced error
files.
           
In producing Engineering Subset and Telemetry Error Files, the CVTFOF 
process will work in conjunction with other processes in the new ODR
pipeline.  The other processes in the ODR pipeline assume the responsibility
of and replace the current AEDPSUB process.  These other processes will   
transfer Merged All-Points FOF files from the CCS system to the ODR pipeline,
unzip the FOF files, trigger the CVTFOF process to convert the file, and then
delete no longer needed files when the conversion is done.  OPR 36120 was 
written to develop the ODR Pipeline. 

To examine details of the CVTFOF Process requirements, reference the ODR Pipeline Requirements Document.

OMS Pipeline Processing Modifications

As discussed previously, current OMS AEDPSUB and PREPROC processing will be 
replaced by ODR Pipeline processing and the OMSANAL process will be modified 
to accept either AEDP or CVTFOF generated subsets.  In addition, the current 
OMS OMSUPD process will be modified to no longer request archiving of 
Engineering Telemetry Subset Files.  To show where the new ODR Pipeline
processes fit into current OMS processing, a sequence of the main processing
steps is provided below:                         

                1. Weekly SMS Generation

                2. Mission Schedule Parsing (YECMSC)
              
                3. Select Mission Schedule Events of Interest (OMSEVT)
 replacement->  4. Transfer FOF Files from CCS to STScI OMS 
                   -- New ODR Pipeline processes are a replacement for the 
                      current AEDPSUB process--

 replacement->  5. Convert FOF files to Subset and TLM Error Files (CVTFOF) 
                   -- New ODR Pipeline CVTFOF process is a replacement for the
                      current PREPROC process --

                6. Process Telemetry Error Files produced by CVTFOF (OMSTLM)

                7. Generate Scheduling Units (OMSCHD)

 modification-> 8. Process Engineering Telemetry Subset Files (OMSANAL)
                   -- enable processing of AEDP or CVTFOF produced subsets --

 modification-> 9. Update OMS_SCHED_TABLE and delete processed files (OMSUPD)
                    -- Subset Files no longer requested to be archived --

                10. Generate Archive requests (GENREQ)   

                11. Process Archive responses (INGRSP)

                12. delete files (ARCCLN)


CVTFOF Process Call Tree and Hierarchy Table

  
  CVTFOF_main                        !main driver to control CVTFOF processing
    CVTFOF_init                      !initialize CVTFOF process
      CVTFOF_format_subset_hdr       !format 180 byte default subset file header
    CVTFOF_convert_fof_file          !convert fof file to subset/error files
      CVTFOF_get_non_gap_pkt         !get next fof packet that is not a gap pkt
        CVTFOF_read_fof_hdr          !read header portion of fof packet
          CVTFOF_extract_ui2         !extract/swap unsigned i*2 value from hdr
        CVTFOF_read_fof_elem         !read data element portion of fof packet
      CVTFOF_get_non_cde_tlm_pkt     !get next packet not having C/DE format tlm
        CVTFOF_read_fof_hdr          !read header portion of fof packet
          CVTFOF_extract_ui2         !extract/swap unsigned i*2 value from hdr
        CVTFOF_read_fof_elem         !read data element portion of fof packet
      CVTFOF_extract_r8              !extract/swap r*8 value from fof hdr
      CVTFOF_process_fof_elements    !diver module to process fof data elements
        CVTFOF_read_fof_elem         !read data element portion of fof packet
        CVTFOF_validate_fof_elem     !check if to output non-supercomm element
          CVTFOF_extract_ui2         !extract/swap unsigned i*2 value from hdr
          CVTFOF_extract_i4          !extract & swap I*4 value from fof elem
          CVTFOF_extract_r4          !extract & swap r*4 value from fof elem
          CVTFOF_extract_r8          !extract & swap r*8 value from fof elem
          CVTFOF_special_telem       !indicates if fof element has "special" tlm
        CVTFOF_process_supercomm_elem!handle supercommutated elements
        CVTFOF_validate_fof_packet   !check if to output whole fof packet
      CVTFOF_gap_begin_end           !determines if start or end of tlm gap
      CVTFOF_write_gap_file          !write BGAP/EGAP records to tlm gap file
      CVTFOF_write_subset_file       !controls writing to telemetry subset file
        VRSF_open                    !open new subset file
        CVTFOF_write_subset_hdr      !write header to the tlm subset file
        CVTFOF_write_subset_elem     !write element to the telemetry subset file
          VRSF_write                 !write record to subset file
        CVTFOF_write_subset_flush    !write final record to the tlm subset file
          VRSF_write                 !write record to subset file
          VRSF_rewrite_header        !rewrite parts of subset file header record
          VRFS_close                 !close subset file 
          CVTFOF_convert_tlm_format  !convert tlm format from integer to char
      CVTFOF_new_subset_file         !prepare for new subset file
        CVTFOF_write_subset_file     !controls writing to telemetry subset file
          VRFS_open                  !open new subset file
          CVTFOF_write_subset_hdr    !write header to the tlm subset file
          CVTFOF_write_subset_elem   !write element to the telemetry subset file
            VRSF_write               !write record to subset file
          CVTFOF_write_subset_flush  !write final record to the tlm subset file
            VRSF_write               !write record to subset file
            VRSF_rewrite_header      !rewrite parts of subset file header record
            VRFS_close               !close subset file 
            CVTFOF_convert_tlm_format!convert tlm format from integer to char
    CVTFOF_rename_files              !rename produced files to correct format
    CVTFOF_insert_fofsub_table       !driver to insert records into fofsub table
      DBMS_insert_fofsub_table       !insert records into fofsub table


CVTFOF Process Required_packages

        OPUSBB (OPUS BlackBoard Package)
        MSGRPT (Message Reporting Package)
        OSF (Observation Status File Package)
        OSFILE (Operating System File Package)
        SYS (System File Package)
        VRSF (OMS Variable Record Size File Package)
        STDB (ST Database Package)


CVTFOF Process Individual Routine Descriptions


  ============================================================================
  ! CVTFOF_main
  !
  ! This is the main module for the CVTFOF process.  It calls a subordinate
  ! routine to initialize the process then enters an infinite loop to look for
  ! FOF files in an input directory.  When a FOF file is found, other 
  ! subordinate routines are called to process the file.  After processing a 
  ! FOF file, a success or failure status is indicated and a new FOF file is 
  ! looked for.
  !
  int main (
      int  argc,                        /* I: command line argument count */
      char *argv[]                      /* I: command line arguments */
           )  

  call CVTFOF_init to perform CVTFOF process initialization
  if (process initialized OK) 
     do (forever)
        call OPUSBB_poll to poll for input
        if (input = convert fof files)
           get fof filename from "ROOTNAME" and store in process structure
           call CVTFOF_convert_fof_file to convert fof file to subset files
           if (pipeline mode)
              if (success)
                 call CVTFOF_rename_files to name files to correct convention
                 call DBMS_insert_fofsub_table to insert info into database
                 if (renames or db updates failed) 
                    set status = failure
                 endif
              endif
              if (status still success) 
                 set fof file osf to complete
              else 
                 if (info put in databse and files were renamed) 
                   back info out of databse and un-rename files
                 endif
                 set fof file osf to failure
              endif 
           elseif (success)
              exit (SUCCESS)
           else
              exit (FAILURE)
           endif
        elseif (input = re-init)
           call CVTFOF_init to perform CVTFOF process initialization
        elseif (input = halt)
           exit (SUCCESS)
        endif
     enddo
  else
     exit (FAILURE)
  end
  ============================================================================


  ============================================================================
  ! CVTFOF_init
  !
  !This is the initialization routine for the CVTFOF process.  It initializes
  !the OPUS Blackboard, gets needed values from the process resource file, 
  !determine if the process is being executed in a Pipeline or Interactive mode,
  !and calls a routine to format a default Subset File Header
  !
  int CVTFOF_init (
       int argc,                       /* I: argument count from cmd line */  
       char *argv[],                   /* I: arguments from cmd line */  
       CVTFOF_STRUCT *cvtfof,          /* IO: ptr to process structure */
       SUB_HDR_STRUCT *subset_hdr,     /* I: ptr to subset file header */
       int *command,                   /* O: poll command */
       char *fof_filespec              /* O: FOF Filespec */
                  )		

  call OPUSBB_init to initialize the OPUS Blackboard
  if (Blackboard initialized)
     status = CVTFOF_OK
     clear out the CVTFOF process structure
     call OPUSBB_get_value to get needed values from process resource file
     store values from resource file into CVTFOF process structure
     call OPUSBB_interactive to determine if interactive or pipeline mode
     if (interactive mode )
        set mode to interactive
     else
        set mode to pipeline
     endif     
     call CVTFOF_format_subset_hdr to format the default subset file header
  else
     status = CVTFOF_NOTOK
  endif
  return (status)
  ============================================================================


  ============================================================================
  ! CVTFOF_format_subset_hdr
  !
  ! This routine formats a 180 byte subset file header with constant default 
  ! values. 
  ! 
  void CVTFOF_format_subset_hdr (
             SUB_HDR_STRUCT *subset_hdr,   /* I: ptr to subset file header */
                                )
        
  determine if executing on a BIG or Little Endian system
  insert appropriate default values into header fields having constant values
  return ()
  ============================================================================


  ============================================================================
  ! CVTFOF_convert_fof_file
  !
  ! This routine is the driver module for converting all-points telemetry fof
  ! files into change-only telemetry subset files.  It reads headers and
  ! elements from fof file packets and calls subordinate routines to determine
  ! when and if the headers and elements should be output to telemetry subset 
  ! files.
  !
  int CVTFOF_convert_fof_file (
                 CVTFOF_STRUCT *cvtfof,     /* IO: process structure */
            SUB_HDR_STRUCT *subset_hdr,     /* IO: ptr to subset file header */
     SUB_NAMES_STRUCT *sub_names_array,     /* IO: ptr to subset names array */
                    char *fof_filename      /*I: filename for fof file */
                              )          

  FILE *fof_file_ptr

  FOF_ELEM_STRUCT fof_elem_array[4000]
  FOF_ELEM_STRUCT supercomm_array[150]
  FOF_ELEM_STRUCT required_elem_array[3]
  FOF_ELEM_STRUCT fof_elem
  TLM_PARAM_STRUCT tlm_param_array[65536]
  char fof_elem_char[17]
  char fof_hdr_char[28]

  construct file specification for and open fof file
  call routine to read and discard any gap packets at the start of the fof file
  do (while not end of fof file)
    call CVTFOF_get_non_cde_tlm_pkt to get a fof packet with non C/DE TLM format
    if (entire fof file contains only C/DE format telemetry)
      set flag indicating fof file contains only C and/or DE format tlm
      break out of loop
    elseif (rest of fof file contains only C/DE format telemetry)
      break out of loop
    endif 
    call CVTFOF_process_fof_elements to process the elements in the packet
    if (the packet is to be discarded)
       continue with next iteration of loop
    endif
    call CVTFOF_gap_begin_end to see if a gap is starting or ending
    if (packet is a gap packet) 
       continue with next iteration of loop
    endif
    if (not first subset file for the current fof file)
       if (tlm format change)
          call CVTFOF_write_gap_file to close out current gap file
          call CVTFOF_write_subset_file to close out current subset file
       endif
    else
       initialaize variables
       if (minor frame counter not in this first packet)
          discard the packet by continuing with the next iteration of the loop
       endif
    endif
    if (new subset file) 
       call CVTFOF_new_subset_file to prepare new subset file
       call CVTFOF_write_gap_file to prepare new gap file
    endif
    if (minor frame counter in packet)
       call CVTFOF_write_subset_file to write required elements to subset file
    endif   
    call CVTFOF_write_subset_file to write all saved elements to subset file
  enddo
  if (there is supercommutated data that still needs to be written out)
    call CVTFOF_write_subset_file to write supercomm elements to subset file
  endif
  call CVTFOF_write_gap_file to close out current gap file
  call CVTFOF_write_subset_file to close out current subset file
  close fof file 
  return
  ============================================================================


  ============================================================================
  ! CVTFOF_get_non_gap_pkt
  !
  ! This routine reads from the start of a fof file discarding the data 
  ! until a non-gap packet is found.  A flag is set indicating if any non-gap 
  ! packets are found in the fof file.  
  ! 
  int CVTFOF_get_non_gap_pkt (
              char *fof_filespec,    /* I: file spec for FOF file */
              FILE *fof_file_ptr,    /* I: pointer to fof file */
              char *fof_hdr_char,    /* O: ptr to fof header array */
              int  *gap_pkts_only,   /* O: set if file contains gap pkts only */
  unsigned short int *num_fof_elem,  /* O: number elements in fof packet */
                         int *eof    /* O: indicates if end of file */
                             )

  call CVTFOF_read_fof_hdr to read the fof header
  if (packet is a gap packet)
     do (while not end of file and packet is a gap packet)
        call CVTFOF_read_fof_elem to read and discard the gap element
        call CVTFOF_read_fof_hdr to read the next fof header
        if (end of file is encountered)
           set flag indicating fof file contains only gap packets
        endif
     enddo
  endif
  return
  ============================================================================


  ============================================================================
  ! CVTFOF_read_fof_hdr
  !
  ! This routine reads a fof header from a fof file and checks if any errors
  ! or end of file is encountered.
  !
  int CVTFOF_read_fof_hdr (
               char *fof_filespec,    /* I: file spec for FOF file */
               FILE *fof_file_ptr,    /* I: pointer to fof file */
               char *fof_hdr_char,    /* I: ptr to fof header array */
               int  *eof,             /* O: end of file indicator */
   unsigned short int *num_fof_elem   /* O: number of elements in fof packet */
                          )
        
  read of fof header (28 bytes) from the fof file 
  if (any errors occur)
     print error messages
  endif
  return
  ============================================================================


  ============================================================================
  ! CVTFOF_extract_ui2
  !
  ! This routine extracts and returns a 2-byte unsigned short integer value 
  ! from the location specified by the input argument.  The two bytes are 
  ! extracted either in a forward or reverse order dependent upon if the host 
  ! machine uses a big or little endian format.
  ! 
  unsigned short int cvtfof_extract_ui2 (
                           char *byte_ptr    /* I: ptr to bytes to extract */
                                        )		

  determine if need to byte swap data when extracting it
  if (swap data) 
     extract 2 data bytes in reverse order
  else
     extract 2 bytes in forward order
  endif
  return (unsigned short int variable)
  ============================================================================


  ============================================================================
  ! CVTFOF_read_fof_elem
  !
  ! This routine reads a fof element from a fof file and checks if any errors
  ! or end of file is encountered.
  !
  int CVTFOF_read_fof_elem (
               char *fof_filespec,    /* I: file spec for FOF file */
               FILE *fof_file_ptr,    /* I: pointer to fof file */
               char *fof_elem_char    /* I: ptr to fof element array */
                           )
        
  read of fof element (17 bytes) from the fof file 
  if (any errors occur)
     print error messages
  endif
  return
  ============================================================================


  ============================================================================
  ! CVTFOF_get_non_cde_tlm_pkt
  !
  ! This routine reads through the fof file discarding the data until a packet 
  ! containing telemetry data in a format other than the "C" or "DE" formats is
  ! found.  A flag is set indicating if any non C/DE format telemetry is left in
  ! the fof file.  This routine also checks for telemetry fomat changes from one
  ! FOF packet to the next.  If a format change occurs, the array used to hold
  ! the last value for every telemetry parameter is reinitialized in preparation
  ! for the new Subset file to be created for the new telemetry format.
  ! 
  int CVTFOF_get_non_cde_tlm_pkt (
              char *fof_filespec,     /* I: file spec for FOF file */
              FILE *fof_file_ptr,     /* I: pointer to fof file */
              char *fof_hdr_char,     /* I: ptr to fof header array */
              int  first_fof_hdr,     /* I: indicates if 1st fof hdr */
  TLM_PARAM_STRUCT *tlm_param_array,  /* I: ptr to tlm_param_array */
              int  *cde_tlm_only,     /* O: set if file contains cde tlm only */
  unsigned short int *num_fof_elem,   /* O: number elements in fof packet */
                         int *eof     /* O: indicates if end of file */
                                 )

  if (not first time being called for current fof file)
     call CVTFOF_read_fof_hdr to read a fof header
  endif
  if (packet contains C/DE telemetry) 
     if (start of fof file) 
        do (while not end of file and packet contains C/DE format telemetry)
           do (while more elements in packet)
              call CVTFOF_read_fof_elem to read and discard the element
           enddo
           call CVTFOF_read_fof_hdr to read the next fof header
           if (end of file is encountered)
              set flag indicating fof file contains only C/DE format telemetry
           endif
        enddo
     else
        set flag indicating rest of fof file contains only C/DE format tlm   
     endif
  else
    check if tlm format has changed since last packet
    if (tlm format change)
       re-initialize the array of previous telemetry parameters
    endif
  endif
  return
  ============================================================================


  ============================================================================
  ! CVTFOF_extract_r8
  !
  ! This routine extracts and returns an 8 byte double floating point value from
  ! the location specified by the input argument.  The eight bytes are extraced 
  ! either in a forward or reverse order dependent upon if the host machine uses
  ! a big or little endian format.  Also the eight bytes are assumed to be and 
  ! will remain in IEEE floating point format.  
  !
  ! NOTE:  This routine is not to execute on VAX machines.  If it is desired to 
  !        use this routine on vax machines, the 8 bytes that are extracted need
  !        to be converted from IEEE to VAX floating point representation.
  ! 
  double cvtfof_extract_r8 (
               char *byte_ptr     /* I: ptr to bytes to extract */
                           )		

  determine if need to byte swap data when extracting it
  if (swap data) 
     extract 8 data bytes in reverse order
  else
     extract 8 bytes in forward order
  endif
  return (double variable)
  ============================================================================


  ============================================================================
  ! CVTFOF_process_fof_elements
  !
  ! Description:
  !       This module calls subordinate modules to processes each fof element.  
  !       This processing includes the following:
  !           read and validate each element
  !           handling supercommutated elements
  !           handling required elements (sc hi and low time and mf counter)
  !           handling non-required/non-supercommutated elements
  !           determining the validity of all the packet elements as a whole
  !
  int CVTFOF_process_fof_elements (
      CVTFOF_STRUCT *cvtfof,               /* I/O: process structure */
               FILE *fof_file_ptr,         /* I: pointer to fof file */
               char *fof_filespec,         /* I: filespec for fof file */
                int *mf_cntr_in_pkt,       /* I: is mf counter in packet */
 unsigned short int *num_fof_elem,         /* I: num of elements in fof pkt */
               char *fof_elem_char,        /* O: char array to hold fof elem */
   TLM_PARAM_STRUCT *tlm_param_array,      /* I/O: tlm parameter array */
    FOF_ELEM_STRUCT *fof_elem,             /* O: 1 fof element */
    FOF_ELEM_STRUCT *fof_elem_array,       /* O: multiple fof elements */
                int *num_elem_in_array,    /* O: num elem in fof elem array */
    FOF_ELEM_STRUCT *supercomm_array,      /* O: array for supercomm elements */
                int *eof,                  /* O: indicates if end of file */
                int *discard_pkt,          /* O: indicates to discard packet */
                int *supercomm_index,      /* O: index into supercomm array */
                int *pkt_mf_cntr_bad,      /* O: mf cntr bad for current pkt */
                int *mf_cntr_in_prev_pkt,  /* O: is mf counter in prev packet */
                int *prev_pkt_mf_cntr,     /* I/O: mf cntr for prev pkt */
                int *prev_pkt_mf_cntr_bad, /* I/O: mf cntr bad for prev pkt */
                int *special_tlm,          /* O: indicates if special tlm */
    FOF_ELEM_STRUCT *required_elem_array   /* O: array for required elem */
                                )          

  do (for each element in the current fof packet)
     call CVTFOF_read_fof_elem
     if (read status is bad or packet is a gap packet)
        return
     endif
     if (packet minor frame counter is bad)
        read/discard packet elements by continuing with next iteration of loop
        continue
     endif
     call CVTFOF_validate_fof_element to validate the element
     if (element is not valid)
        discard element by continuing with next iteration of loop
        continue
     else
        if (element is a supercommutated parameter)
           call CVTFOF_supercomm_elem to process element
        else if (element is "special" telemetry)
           save element in required element array
        else (regular element)
           save element in fof element array
        endif
     endif
  enddo
  call CVTFOF_validate_fof_packet to see if to output element to subset file
  if (valid packet)
     if (minor frame counter is not in the packet)
        reinitialize the supercommutated array
     endif
  endif
  return
  ============================================================================


  ============================================================================
  ! CVTFOF_validate_fof_element
  !
  ! This routine determines if the current fof element is a valid candidate
  ! to be output to the subset file.  An element is valid for output if it is a
  ! "special" telemetry item (s/c hitime, s/c lotime, minor frame counter, or
  ! supercommutated parameter) or if it is none of the above but its raw value 
  ! is different from the last saved value of the element.  If a fof element is
  ! of bad quality or had an EU conversion error, the element will be discarded.
  ! If the element is valid to be output, it will be stored into a fof_element
  ! structure and its raw value will also be stored into a tlm parameter array
  ! for comparison in the next iteration
  ! 
  int CVTFOF_validate_fof_element (
     CVTFOF_STRUCT *cvtfof,             /* I: ptr to process structure */
     char *fof_elem_char,               /* I: 17 byte element from fof file */
     TLM_PARAM_STRUCT *tlm_param_array, /* IO: pointer to tlm parameter array */
     int *mf_cntr_in_pkt,               /* IO: indicates if mf counter found */
     int *pkt_mf_cntr_bad,              /* I: indicates if mf counter bad */
     FOF_ELEM_STRUCT *fof_elem,         /* O: pointer to fof element */
     int *supercomm_index,              /* O: indicates if supercomm element, */
                                        /* if so,is index into supercomm array*/
     int *special_tlm                   /* O: indicates if special tlm */
                                  )

  call CVTFOF_extract_ui2 to get fof element flags field and numeric id
  if (elemnt is bad)
     return (discard element)
  endif
  call CVTFOF_extract_i4 to get the element raw value
  call CVTFOF_special_telem to get the element telemetry code
  if (element = sc_hitime) 
  else if (element is spacecraft high or low time) 
  elseif (element is minor frame counter) 
     store the minor frame counter
  elseif (element is supercommutated element)  
     store its index into the supercomm array
  elseif (element raw value changed)
     store new raw value in tlm param array
     store current mf count in tlm param array
  else 
     return (discard element)
  endif

  get eu type field from character fof element
  if (EU value is character)
     store character value in fof element structure
  else if (EU value is double)
     call CVTFOF_extract_r8 to get fof element EU double field
     store double value in fof element structure
  elseif (EU value is float)
     call CVTFOF_extract_r4 to get fof element EU float field
     store float value in fof element structure   
  elseif (no EU conversion)
     store 0 value in fof element structure    
  endif
  store other element values in fof element structure    
  store element raw value into telemetry parameter array for future comparison
  if (element is "special")
     set "special" telemetry  flag
  endif
  return (keep element)
  ============================================================================


  ============================================================================
  ! CVTFOF_extract_i4
  !
  ! This routine extracts and returns a 4 byte signed integer value from
  ! the location specified by the input argument.  The 4 bytes are extraced 
  ! either in a forward or reverse order dependent upon if the host machine 
  ! uses a big or little endian format. 
  !
  int cvtfof_extract_i4 (
              char *byte_ptr    /* I: ptr to bytes to extract */
                        )		

  determine if need to byte swap data when extracting it
  if (swap data) 
     extract 4 data bytes in reverse order
  else
     extract 4 bytes in forward order
  endif
  return (integer variable)
  ============================================================================


  ============================================================================
  ! CVTFOF_extract_r4
  !
  ! This routine extracts and returns a 4 byte floating point value from
  ! the location specified by the input argument.  The four bytes are extraced 
  ! either in a forward or reverse order dependent upon if the host machine 
  ! uses a big or little endian format.  Also the four bytes are assumed to be
  ! and will remain in IEEE floating point format.  
  ! 
  ! NOTE:  This routine is not to execute on VAX machines.  If it is desired to 
  !        use this routine on vax machines, the 4 bytes that are extracted need
  !        to be converted from IEEE to VAX floating point representation.
  ! 
  float cvtfof_extract_r4 (
               char *byte_ptr     /*I: ptr to bytes to extract */
                          )		

  determine if need to byte swap data when extracting it
  if (swap data) 
     extract 4 data bytes in reverse order
  else
     extract 4 bytes in forward order
  endif
  return (float variable)
  ============================================================================


  ============================================================================
  ! CVTFOF_special_telem
  ! 
  !   This function returns a non-negative integer code to indicate that a 
  !   special engineering telemetry item is associated with the given FOF 
  !   telemetry numeric id. The special items are the time and frame count and
  !   the supercommutated items for one of six telemetry formats (HN,HF,FN,FF,
  !   PN, or PF)
  ! 
  ! Return value:
  !     CVTFOF_STC_NOTHING -- not a special telemetry item 
  !     CVTFOF_STC_HI_TIME -- telemetry item having the mnemonic DVEHTIMH
  !     CVTFOF_STC_LO_TIME -- telemetry item having the mnemonic DVEHTIML
  !     CVTFOF_STC_MFR_CNT -- minor frame count (DTMMNTC or DACMFCNT)
  !     
  !     All positive return values between CVTFOF_STC_MFR_CNT and 
  !     CVTFOF_STC_MAX_VAL are unique indices for each supercommutated telemetry
  !     id. 
  ! 
  int 	cvtfof_special_telem (    	/* determine special telemetry */
	int 	numeric_id,             /* I: fof numeric id of telemetry */
	int 	telem_format_code       /* I: fof code for telemetry format */
                             )

  set up hash table to indicate what elements contain "special" telemetry
  return (special tlm indicator from location of numeric id)
  ============================================================================


  ============================================================================
  ! CVTFOF_process_supercomm_elem
  ! 
  ! This routine determines if both or neither values of a supercommutated
  ! telemetry parameter for the current minor frame should be output to a
  ! telemetry subset file.  If they are to be output, they are stored into
  ! a fof element array that subsequently gets output to the subset file
  !   
  void CVTFOF_process_supercomm_elem (
    int *num_elem_in_array,             /* I: # valid fof elements in array */
    int supercomm_index,                /* I: index into supercomm array */
    FOF_ELEM_STRUCT *fof_elem,          /* I: pointer to fof element */   
    FOF_ELEM_STRUCT *fof_elem_array,    /* IO: pointer to fof element array */
    TLM_PARAM_STRUCT *tlm_param_array,  /* IO: pointer to tlm parameter array*/
     FOF_ELEM_STRUCT *supercomm_array    /* IO: ptr to supercomm param array */
                                     )

  if (second value of element is in packet)
     if ((second value != first value) or 
         (second value != saved value in tlm parameter array))
        save first value of element in fof element array
        increment number of valid fof elements in buffer
        save second value of element in fof element array
        increment number of valid fof elements in buffer
     endif
     save second value in tlm param array
  else
     store fof element into supercomm array
  endif   
  return
  ============================================================================


  ============================================================================
  ! CVTFOF_validate_fof_packet
  ! 
  ! This module determines the validity of the current fof packet based on 
  ! the quality of the minor frame counter.  If the mf counter is in the
  ! current fof packet and its quality is bad, the fof packet is bad.  If
  ! the mf counter is not in the current fof packet but was in the previous
  ! fof packet and its quality was bad, the fof packet is bad.
  ! 
  int cvtfof_validate_fof_packet (
      CVTFOF_STRUCT *cvtfof,               /* I/O: process structure */
                int *mf_cntr_in_pkt,       /* I: is mf counter in packet */
                int *pkt_mf_cntr_bad,      /* I: mf cntr bad for current pkt */
                int *mf_cntr_in_prev_pkt,  /* I/O: is mf counter in prev pkt */
                int *prev_pkt_mf_cntr_bad, /* I/O: mf cntr bad for prev pkt */
                int *num_elem_in_array,    /* I: number of elements saved */
                int *prev_pkt_mf_cntr,     /* O: prev pkt mf counter */
                int *discard_pkt           /* O: indicates to discard packet */
                                 )          

  if (minor frame counter in packet)    
     if (mf counter bad)
        set flags
        set status to invalid packet
     else 
        save minor frame counter
     endif
  else 
     if (minor frame counter in previous packet)    
       if (mf counter bad)
          set flags
          set status to invalid packet
       endif
     else
        print error message, two consecutive frames without mf counter
        set status to invalid packet
     endif
  endif
  return status
  ============================================================================


  ============================================================================
  ! CVTFOF_gap_begin_end   
  !
  ! This routine determines if the current fof packet is a gap packet and
  ! if a gap is starting or ending.  If so, various variables and flags 
  ! are set accordingly.
  ! 
  void CVTFOF_gap_begin_end (
       int                *write_gap_records, /* O: if need to write gap recs */
       unsigned short int num_fof_elem,       /* I: num fof elem in pkt */
       int                *prev_pkt_was_gap,  /* IO: was prev pkt a gap pkt */
       double             *gap_start_time,    /* IO: gap start time */
       double             prev_pkt_sc_time,   /* I: time of previous pkt */
       int                *gap_start_mf_cntr, /* O: mf cntr at start of gap */
       int                prev_pkt_mf_cntr,   /* I: mf cntr of previous pkt */
       CVTFOF_STRUCT      *cvtfof             /* I: ptr to process structure */
                            )
        
  if (fof packet is "DATA_GAP" packet, i.e. num of elements = 1)
     if (previous packet not a gap packet)
        save previous packet time as start of gap
        save previous mf counter as mf counter at start of gap
     endif
  else
     if (packet is not a gap packet but previous packet was)
        if (gap is longer than allowable tolerance)
           set flag to write out gap records
        endif
     endif
  endif
  return (status)
  ============================================================================


  ============================================================================
  ! CVTFOF_write_gap_file
  !
  ! This routine writes records to an ascii telemetry gap file.  These records
  ! indicate the begining and end of a telemetry subset file and the begining 
  ! and end of gaps within the file.  The records are as follows:
  !   
  !       Header Records  - column headers 
  !       BOF Records - begining of subset file
  !       BGAP Records - begining of telemetry gap within subset file  
  !       EGAP Records - end of of telemetry gap within subset file   
  !       EOF Records - end of subset file 
  !   
  ! 
  int CVTFOF_write_gap_file (
          CVTFOF_STRUCT *cvtfof,   /* I: process structure */
            int gap_record_type,   /* I: indicates what type record to write */
         int gap_record_mf_cntr,   /* I: mf counter for gap record */
         double gap_record_time    /* I: time stamp for gap record */
                            )

  convert input mjd spacecraft time to calender character format
  if (gap record type == beginning of file record "BOF")
     format name for new gap file
     open new gap file
     write column header records
     write BOF record 
  elseif (gap record type == beginning of gap record "BGAP")
     write BGAP record 
  elseif (gap record type == end of gap record "EGAP")
     write EGAP record 
  else (gap record type == end of file record "EOF")
     write EOF record 
     close gap file
  endif
  return (status)
  =============================================================================


  ============================================================================
  ! CVTFOF_write_subset_file
  !
  ! This routine controls the writing of data to a telemetry subset file by
  ! calling subordinate routines to write the various parts of the file; i.e.,
  ! a subset file header and subset file elements 
  !
  int CVTFOF_write_subset_file (
     CVTFOF_STRUCT *cvtfof,          /* IO: process structure */
     SUB_HDR_STRUCT *subset_hdr,     /* I: ptr to subset file header to write */
     FOF_ELEM_STRUCT *fof_element,   /* I: pointer to fof element to write */ 
     int data_type,                  /* I: indicates what type data to write */
  SUB_NAMES_STRUCT *sub_names_array, /* IO: array of subset file names */
     int num_mf_in_subset            /* I: number of mf in the subset file */
                               )

  char        subset_file_record[8702]
  FILE        *subset_file_ptr
  static int  subset_file_size
  static char subset_file_record_ptr
  static int  subset_file_record_size

  if (write subset file header)
     reset subset file variables
     format subset file name
     call CVTFOF_write_subset_hdr to write a subset file header to buffer
     call VRSF_open to open a new subset file
  elseif (write subset file element)
     call CVTFOF_write_subset_elem to write subset file element
  elseif (subset record flush)
     call CVTFOF_write_subset_flush to write final file record & close file
  endif
  return (status)
 ==============================================================================


 ==============================================================================
  ! VRSF_open
  !
  ! This routine provides the C-language interface using null delimited
  ! character arrays to open a file using the Variable Record Size File
  ! access methods. There are two types of input files: RMS record_type=VAR
  ! files are created by VMS services to have hidden record-size control
  ! words and must be accessed as input_file_type of VAR when running on
  ! VMS system, otherwise the control word is accessible in the STREAM file.
  !
  int VRSF_open ( 	      
    int	  *VRSF_unit_number,       /* O:  1 to VRSF_MAX_OPEN_FILES */
    char  *file_name,              /* I:  name of file to open */
    char  *file_access             /* I: "Read","Write","Append" */
                )

 get unit number to use to open file
 open file using unit number
 if (file read only)
    open file as read only
 else if (file write only)
    open file as write only
 else if (append to end of file)
    open file to append 
 endif
 set up file record size
 return
 ==============================================================================


 ==============================================================================
  ! CVTFOF_write_subset_hdr
  !
  ! This routine writes a 180 byte subset file header to a 8702 byte subset 
  ! file record.  Most of the fields in the header are constant values and have
  ! already been set by the CVTFOF_format_subset_hdr routine.  The header fields
  ! that are not constants and that are known at the time are inserted into the 
  ! header prior to its writing to the subset file record.  This module also
  ! keeps a count of the number of subset files that have been created from a
  ! specific fof file.  
  !
  int  CVTFOF_write_subset_hdr (
      CVTFOF_STRUCT *cvtfof,         /* I: process structure */
      SUB_HDR_STRUCT *subset_hdr,    /* I: ptr to subset file header to write */
      char **subset_file_record_ptr, /* IO: ptr to 8702 byte subset file rec */
      SUB_NAMES_STRUCT *sub_names_array,    /* IO: array of subset file names */
      char *subset_filename                 /* I: name of subset file */
                               )

  insert subset filename into 180 byte header
  insert subset name into subset names array
  increment number of subset names in subset name array
  get current system time and insert into sub names array
  convert current time into appropriate format and insert into subset header
  call CVTFOF_convert_tlm_fortmat to convert numeric tlm format to character
  insert character telemetry format into 180 byte header
  convert subset mjd spacecraft time to character format
  insert spacecraft time into 180 byte header
  insert 180 byte header into 8702 byte subset file record
  return (status)
 ==============================================================================


 ==============================================================================
  ! CVTFOF_write_subset_elem
  !
  ! This routine writes either a 7 or 11 byte subset file element to a 8702
  ! byte subset file record.  If the element will not fit in the current 
  ! subset file record, the current record is written to the subset file, 
  ! the subset file record is reset to its begining, and the element is then
  ! written to the begining of the subset file record.  This routine calls
  ! a "Variable Record Size File (VRSF) routine to write subset file records
  ! to subset files.  
  !
  int CVTFOF_write_subset_elem (
      FOF_ELEM_STRUCT *fof_element,   /* I: pointer to fof element to write */
      int *subset_file_unit_num,      /* I: pointer to subset file */  
      char *subset_filespec,          /* I: subset file name */
      int *subset_file_size,          /* IO: ptr to subset file size */
      char *subset_file_record,       /* IO: ptr to start of subset file rec */
      char **subset_file_record_ptr,  /* IO: ptr into subset file record */
      int *subset_file_record_size    /* IO: ptr to subset file record size */
                               )

  determine and save size of subset file element
  determine fornmat of element data
  if (subset file element size causes subset file record size to be exceeded)
    call VRSF_write to write current subset file record to subset file
    increment subset file size
    reset subset file record pointer
    reset subset file record size
  endif

  insert fof element numeric id into subset file record
  increment subset file record pointer by 2
  construct subset element attribute byte from fof element eu_type and flags
  insert attribute into subset file record
  increment subset file record pointer by 1
  if (element size is 11)
    insert 8 bytes of fof element eu_val into subset file record
    increment subset file record pointer by 8
  else  
    insert 4 bytes of fof element eu_val into subset file record
    increment subset file record pointer by 4
  endif
  increment subset file record size by size of element
  return (status)
  =============================================================================


  =============================================================================
  ! VRSF_write
  !
  ! This routines writes a binary record at the end of the file. After
  ! header operations (if allowed), the output position is automatically
  ! reset to the end of the file. To rewrite any part of a header, the
  ! function VRSF_write_header must be used (if allowed).
  !
  int VRSF_write (              
    int		*VRSF_unit_number,   /* I: ptr to value assigned by VRSF_open */
    void        *data_record,        /* I: record as typeless data */
    int         *data_rec_bytes      /* I: byte size of record */
                 )

  make sure unit number is valid
  make sure file is open and allows writing to 
  set the record size word
  swap data bytes if necessary
  write the record size word to the file
  write the data to the file
  return
  =============================================================================


  =============================================================================
  ! CVTFOF_write_subset_flush
  !
  ! This routine writes subset elements remaining in the current subset file
  ! record to a subset file.  It also computes and writes subset file header
  ! values that need to be re-written to the subset file header record.
  ! This routine calls "Variable Record Size File (VRSF) routines to write 
  ! and re-write the last subset file record and subset file header record
  ! repsectively.  After writing to the subset file is complete, the file is
  ! closed.  
  !
  int CVTFOF_write_subset_flush (
      CVTFOF_STRUCT *cvtfof,            /* I: ptr to process structure */
      FOF_ELEM_STRUCT *fof_element,     /* I: pointer to fof element */ 
      int *subset_file_unit_num,        /* I: unit number for subset file */
      char *subset_filespec,            /* I: subset file name */
      int *subset_file_size,            /* IO: ptr to subset file size */
      char *subset_file_record,         /* IO: subset file record */
      int *subset_file_record_size,     /* IO: ptr to subset file record size */
      int num_mf_in_subset,             /* I: num of minor frames in subset */
      SUB_NAMES_STRUCT *sub_names_array /* I: array of subset file info */
                                )

  if (subset file record has data remaining)
     call VRSF_write to write subset file record to subset file
     increment subset file size
  endif
  compute values to be re-written to the subset file header record
            /* file data size, 
              sc time for last minor frame
              number of subset minor frames
              number minor frames expected
              number minor frames received
              number minor frames bad */
   call VRSF_rewrite_header to rewrite header record values
   call VRSF_close to close subset file
  return (status)
  =============================================================================


  =============================================================================
  ! VRSF_rewrite_header
  !
  ! Rewrite any part of existing binary header. This routine may be called
  ! multiple times for the same header record to write individual fields.
  ! The offset data is relative to the first data byte. The order of rewrites
  ! has no significance.  None of the updates will count as records written to
  ! the file, even if the entire header is rewritten.  This routine my only be
  ! used for files opened as file access method "Write" or "Append".
  !
  int VRSF_rewrite_header (   
    int		*VRSF_unit_number,   /* I: ptr to value assigned by VRSF_open */
    int		*byte_offset,        /* I: offset 0 is first header byte */
    int         *header_data_bytes,  /* I: byte size of data to rewrite */
    void        *header_data         /* I: typeless data */
                          )

  make sure unit number is valid
  make sure file is open and allows writing to 
  re-write the data to the file
  return
  =============================================================================


  =============================================================================
  ! VRSF_close
  !
  ! Close file and release unit number
  !
  int VRSF_close (               
    int	  *VRSF_unit_number         /* I: ptr to value assigned by VRSF_open */
                 )

  make sure unit number is valid
  make sure file is open
  close file
  return
  =============================================================================


  =============================================================================
  ! CVTFOF_convert_tlm_format
  !
  ! This routine converts a FOF Numeric TLM Format ID (0-255) into its 
  ! corresponding two character identifier by simply using a lookup table.  Be 
  !  advised that if new telemetry formats are added, they must be inserted into
  ! the correct locations in the the tlm_fmt_array defined in this function. At 
  ! the writing of this module, the FOF Numeric TLM Format IDs and their 
  ! corresponding character tlm formats that are currently supported are as 
  ! follows:
  ! 
  ! 0,5,6,24,25,36,37,40,41,48,64,65,80,81,82,138,145,146,163,186,187,192,193
  ! 
  ! OFF,XN,XF,TN,TF,HN,HF,FN,FF,C,YN,YF,PN,PF,DUMP,M,S,DE,U,ZN,ZF,AN,AF
  ! 
  char *CVTFOF_convert_tlm_format (
                 unsigned char tlm_fmt_int          /* I: integer tlm format */
                               )		

  set up lookup table
  use lookup table to determine character tlm format from numeric tlm format
  return (character tlm format)
 ==============================================================================


 ==============================================================================
  ! CVTFOF_new_subset_file
  !
  ! This routine does things that are necessary when a new subset file is to be
  ! created.  This includes the following:
  !
  ! This routine does things that are necessary when a new subset file is to be
  ! created.  This includes the following:
  ! 
  ! formatting filenames for the new subset file and corresponding gap file
  ! and calling a routine to open a new subset file and write a header record
  ! 
  int CVTFOF_new_subset_file (
        CVTFOF_STRUCT *cvtfof,             /* IO: process structure */
       SUB_HDR_STRUCT *subset_hdr,         /* I: ptr to subset file header */
        SUB_NAMES_STRUCT *sub_names_array  /* IO: array of subset file names */
                             )                    

  format subset file and gap file filenames
  call CVTFOF_write_subset_file to write subset file header to subset file
  return (status)
  ============================================================================


 ==============================================================================
  ! CVTFOF_rename_files
  !
  ! This module either renames with an "_FOF" or un-renames with an "_FOF" 
  ! all Telemetry Subset and Error files produced from a specific FOF file.
  ! The "_FOF" in the naming convention is what is required for the OMS 
  ! SUBPOL process to find and initiate processing of the Subset and Error
  ! files.  When Subset and Error files are initially created, they are 
  ! named with an "_NEW" extension to keep the PREPRC process from
  ! recognizing them.  After a FOF file is successfully processed, all of 
  ! the Subset and Error files generated from the FOF file will have their 
  ! "_NEW" extension replaced with an "_FOF" extension.  If this renaming
  ! is performed but errors occur in later processing, this module will be
  ! called again to un-rename the files that were renamed; i.e., the "_FOF"
  ! extension will be replace by the original "_NEW" extension.  Example
  ! file names are as follows:
  !    at file creation - SI3P2119w.VC0_NEW 
  !                       SI3P2119w.ER0_NEW 
  !                       
  !    after fof file is successfully processed  - SI3P2119w.VC0_FOF 
  !                                                SI3P2119w.ER0_FOF 
  ! 
  int cvtfof_rename_files (
              CVTFOF_STRUCT *cvtfof,               /* I: cvtfof info */
              SUB_NAMES_STRUCT *sub_names_array,   /* I: subset info */
              int rename_type                      /* I: 0=rename,1=un-rename */
                        )		

 for (each subset file produced)
    build filespec to rename or un-rename the file
    if (rename the file)
       rename file to appropriate convention 
    else if (un-rename the file)
       rename file back to its original name
    endif
 end for
 return
 ==============================================================================


 ==============================================================================
  ! CVTFOF_insert_fofsub_table
        
  ! This module calls a subordinate database module to insert telemetry
  ! subset information into the database "fofsub_table" relation.  This
  ! information is as follows:
  !   fof file name, subset file name, subset file start time,
  !   subset file stop time, and subset file create time
  !
  int cvtfof_insert_fofsub_table (
              CVTFOF_STRUCT *cvtfof,
              SUB_NAMES_STRUCT *sub_names_array
                                 )		

 for (each subset file produced from fof file)
    call DBMS_insert_fofsub_table to insert subset file info into database
 end for
 return
 ==============================================================================


 ==============================================================================
  ! DBMS_insert_fofsub_table
  !
  ! This module inserts into the database FOFSUB_TABLE relation, 
  ! information pertaining to the creation time,the start and stop times,
  ! and the names of subset files that were produced from a specific fof
  ! file.  A transaction is used to make sure that either all or none 
  ! of the information is inserted to the database
  !
  int DBMS_insert_fofsub_table (
                      char *foffile,              /* I: fof file name */ 
                      char *subfile,              /* I: subset file name */ 
                      char *start_time,           /* I: subset start time */  
                      char *stop_time,            /* I: subset stop time */  
                      char *create_time,          /* I: subset create time */
                      int  transaction_status     /* I: 1=start, -1=end */
                               ) 

  if (start of db insertion) 
     set up to begin a transaction
  endif
  perform database set-up to perform query
  set up arguments to pass into query
  format query to insert info into database
  execute query 
  clean up after query execution
  if (final status is good)
     end transaction
  else
     abort transaction
  endif
  return (status)
  ============================================================================


CVTFOF Process Data Structures



  CVTFOF Process Structure
  ------------------------
  this structure is used to hold various information as the CVTFOF process 
  executes
                                    
  typedef struct CVTFOF_PROCESS_STRUCT {
      double subset_sc_time;      /* spacecraft start time for subset file */
      double pkt_sc_time;         /* spacecraft time for current fof packet */
      double prev_pkt_sc_time;    /* spacecraft time for previous fof packet */
      double mf_sc_time;          /* spacecraft time for current minor frame */
      double gap_tolerance;       /* gaps less then this wont have bgap/egap */
      unsigned char subset_tlm_fmt;  /* tlm format for subset file */
      int pkt_mf_cntr;               /* minor frame counter for current pkt */
      unsigned char pkt_tlm_fmt;  /* tlm format for current fof packet */
      unsigned char prev_pkt_tlm_fmt;/* tlm format for previous fof packet */
      int mode;                   /* process mode; 0=interactive,1 =pipeline */
      int num_subset_files;       /* number of subset files for FOF file */
      char in_data_dir[CVTFOF_MAX_FILESPEC_LEN];      /* dir for Input files */
      char out_data_dir[CVTFOF_MAX_FILESPEC_LEN];     /* dir for Output files */
      char fof_rootname[CVTFOF_FOF_ROOTNAME_LEN];     /* fof file rootname */
      char sub_rootname[CVTFOF_SUB_ROOTNAME_LEN];     /* subset file rootname */
      char sub_extension[CVTFOF_SUB_EXTENSION_LEN];   /* subset file extension*/
      char gap_extension[CVTFOF_GAP_EXTENSION_LEN];   /* gap file extension */
  } CVTFOF_STRUCT;




  FOF Element Structure 
  ---------------------
  this 17 byte structure is used to hold fof elements read from fof files.  The
  structure will actually be allocated 24 bytes because of natural allignment

  typedef struct FOF_ELEMENT_STRUCT {
      union {
        double dbl_val;               /* double eu value */
        float  flt_val;               /* float eu value */   
        int    int_val;               /* integer eu value */   
        char   chr_val[8];            /* character eu value */
      } eu_val;                       /* tlm parameter eu value */
      int raw_value;                  /* tlm parameter raw value */
      unsigned short int numeric_id;  /* tlm parameter numeric id*/
      unsigned short int flags;       /* tlm parameter flags */
      char eu_type;                   /* format of eu_val field */
  } FOF_ELEM_STRUCT;

  A single one of these structures will be used to hold a single fof element

  An array of 4000 of these structures will be used to hold the fof elements to
  be output to a telemetry subset file for each fof packet.  FOF packets can
  contain a maximum of 4000 elements.

  An array of 75 of these structures will be used to hold the first value of a 
  supercommutated element in an fof packet of HST HN, HF, FN, FF, PN, or
  PF format telemetry                           




  Telemetry Parameter Structure
  -----------------------------
  this structure is used to hold the raw values of telemetry parameters read 
  from fof files and to keep tract of the minor frame counter when the parameter
  last changed value

  typedef struct TLM_PARAMETER_STRUCT {
      int raw_value;               /* previous tlm parameter raw value */
      int mf_of_last_change;       /* minor frame count for last value change */
  } TLM_PARAM_STRUCT;

  An array of 65536 of these structures will used to hold the raw values for 
  each of the maximum number of telemetry parameters




  Telemetry Subset File Header Structure
  --------------------------------------
  this structure is the header structure for a telemetry subset file.  A
  structure of this type appears at the beginning of every telemetry subset
  file

  typedef struct SUBSET_HDR_STRUCT {
      char product_type;           /* 'S' = Engineering Subset */
      char input_source;           /* 'M' = Merged Engineering Telemetry */
      short int header_size;       /* num bytes in subset file header (180) */
      int file_data_size;          /* num of bytes in subset file */
      char file_name[CVTFOF_SUBSET_FILE_NAME_LEN];   /* Subset File name */
      char format_id[CVTFOF_FORMAT_ID_LEN];          /* tlm format id */
      char sc_start_time[CVTFOF_TIME_GENERATED_LEN]; /*time 1st mf in sub file*/
      char sc_stop_time[CVTFOF_TIME_GENERATED_LEN];  /* time last mf in sub file */
      char zero_fill[CVTFOF_ZERO_FILL_LEN];   /* zero fill for utc time items */
      int mf_expected;             /* num of FOF minor frames */
      int mf_received;             /* number of subset minor frames */
      int mf_bad;                  /* number of bad minor frames */
      short int data_quality;      /* zeroed */
      char time_generated[CVTFOF_TIME_GENERATED_LEN];/* sub file generate time*/
      char pdb_tape_id[CVTFOF_PDB_TAPE_ID_LEN];     
                                   /* "CCS", no PDB version for FOF data */
      char blank1_fill[CVTFOF_BLANK1_FILL_LEN];              /* blank */
      char source_pref[CVTFOF_SOURCE_PREF_LEN];              /* zeroed */
      char subset_definition[CVTFOF_SUBSET_DEFINITION_LEN];  /* FOF/BE,FOF/LE */
      char subset_origin[CVTFOF_SUBSET_ORIGIN_LEN];          /* blank */
      char compress_flag;          /* 'C', always change-only telemetry */
      char convert_flag;           /* 'V', always EU converted telemetry */
      char blank2_fill[CVTFOF_BLANK2_FILL_LEN];              /* blank */
  } SUB_HDR_STRUCT;




  Subset File Names Structure
  ---------------------------
  this structure is used to hold a rootname and creation time of a subset
  file generated from a particular fof file.  

  typedef struct SUBSET_NAMES_STRUCT {
      char filename[CVTFOF_SUBSET_FILE_NAME_LEN];     /* name of subset file */
      char start_time[CVTFOF_FOFSUB_TBL_TIME_LEN];    /* sub file start time */ 
      char stop_time[CVTFOF_FOFSUB_TBL_TIME_LEN];     /* sub file end time */ 
      char create_time[CVTFOF_FOFSUB_TBL_TIME_LEN];   /* sub file create time*/
  } SUB_NAMES_STRUCT;

  There will be an array of 10 of these structures to hold info for all the 
  subset files generated by a particular fof file.  When a fof file is 
  processed, the name/time of each subset file generated and which an OSF was 
  created for is stored in the array.  When the particular fof file is finished
  being processed, all the subset OSFs produced from the fof file are either 
  set to success or failure dependent upon the outcome of the processing.  If
  the outcome of the processing is "success", the name of each subset file,
  the name of the fof file the subset file was produced from, and the subset
  file creation time are inserted into the OMS_FOF_TABLE databse relation.
               



  FOF Header Input Array
  -----------------------
  this array is used to hold 28 byte FOF Headers read from FOF files.  The
  individual fields from the headers will be extracted from this array and
  byte-swapped if necessary before they are used.                      

  char [28];




  FOF Element Input Array
  -----------------------
  this array is used to hold 17 byte FOF elements read from FOF files.  The
  individual fields from the elements will be extracted from this array and
  byte-swapped if necessary before they are used.                      

  char [17];




  Telemetry Subset File 8702 Byte Record Array
  --------------------------------------------
  this array contains a subset header and/or subset elements to be written to a
  telemetry subset file

  char subset_file_record[8702];


CVTFOF Process Files



  FOF Files
  ---------
  FOF files are IEEE standard Unix-format binary files generated by the CCS 
  system.  The files contain All-Points, Merged Engineering Telemetry in FOF 
  format (Front-End-Processor Output Format).  This format is described in 
  detail in appendix B of CCS HST_ICD_T2 however a reference diagram is
  provided below:

   +====================================================================+
   |                        FOF Packet Header                           |
   |====================================================================|
   | Name       | Bytes | Type | Description                            |
   |------------|-------|------|----------------------------------------|
   | Spacecraft |  8    |IEEE  | Time defined by the vehicle clock      |
   | Time       |       |Float | converted to modified Julian Day (MJD) |
   |------------|-------|------|----------------------------------------|
   | NGT Receipt|  8    |IEEE  | UTC ot time of NGT Transmission (MJD)  |
   | Time       |       |Float |                                        |
   |------------|-------|------|----------------------------------------|
   | CCS Receipt|  8    |IEEE  | UTC of time of CCS receipt (MJD)       |
   | Time       |       |Float |                                        |
   |------------|-------|------|----------------------------------------|
   | Number of  |  2    |unsign| Number of FOF Elements in the packet   |
   | Elements   |       |int   |                                        |
   |------------|-------|------|----------------------------------------|
   | Data       |  1    |bits  | See "Data Source Flags"                |
   | Source     |       |      |                                        |
   |------------|-------|------|----------------------------------------|
   | Telemetry  |  1    |unsign| See "Telemetry Format Code Translation"|
   | Format Code|       |int   |                                        |
   +====================================================================+
     

   +====================================================================+
   |                       Data Source Flags                            |
   |====================================================================|
   | Name          | Bit | Description                                  |
   |---------------|-----|----------------------------------------------|
   |S/C Data Mode  |  0  | set if real-time, else ETR/SSR playback      |
   |---------------|-----|----------------------------------------------|
   |Ground Sta Mode|  1  | set if replay of ground station recording    |
   |---------------|-----|----------------------------------------------|
   |CCS Mode       |  2  | set if test data                             |
   |---------------|-----|----------------------------------------------|
   |FEP Mode       |  3  | set if replaying test data                   |
   |---------------|-----|----------------------------------------------|
   |FEP Replay     |  4  | set if FEP replay request                    |
   |---------------|-----|----------------------------------------------|
   |Era            |  5  | Set if converted AEDP data, else CCS         |
   |---------------|-----|----------------------------------------------|
   |Recorder       |  6  | set if SSR dump, else ETR dump               |
   |---------------|-----|----------------------------------------------|
   |Data Warehouse |  7  | set if retrieved from data warehouse         |
   +====================================================================+


   +====================================================================+
   |                  Telemetry Format Code Translation                 |
   |====================================================================|
   | Code |  Format || Code | Format || Code | Format || Code | Format  |
   |------|---------||------|--------||------|--------||------|---------|
   |  0   |   off   ||  37  |   HF   ||  80  |   PN   || 163  |   U     |
   |  5   |   XN    ||  40  |   FN   ||  81  |   PF   || 186  |   ZN    |
   |  6   |   XF    ||  41  |   FF   ||  82  |  Dump  || 187  |   ZF    |
   | 24   |   TN    ||  48  |   C    || 138  |   M    || 192  |   AN    |
   | 25   |   TF    ||  64  |   YN   || 145  |   S    || 193  |   AF    |
   | 36   |   HN    ||  65  |   YF   || 146  |   DE   ||other | spare   |
   +====================================================================+
            

   +====================================================================+
   |                        FOF Element                                 |
   |====================================================================|
   | Name       | Bytes | Type | Description                            |
   |------------|-------|------|----------------------------------------|
   | Engineering|  8    |IEEE  | Value converted to engineering units   |
   | Value      |       |Float/| either 8-byets ASCCI or 4-byte float   |
   |            |       |ASCII | depending on EU type (see below)       |
   |------------|-------|------|----------------------------------------|
   | Raw Value  |  4    |int   | bits as stored by the spacecraft       |
   |------------|-------|------|----------------------------------------|
   | Numeric ID |  2    |int   | unique CCS identifier for parameter    |
   |------------|-------|------|----------------------------------------|
   | flags      |  2    |int   | see "FOF Element Flags"                |
   |------------|-------|------|----------------------------------------|
   | EU type    |  1    |char  | 'C'=8-byte ASCII, 'D'=IEEE double      |
   |            |       |      | precision, 'F'=IEEE single precision,  |
   |            |       |      | 'N'= not converted                     |
   +====================================================================+


   +====================================================================+
   |                        FOF Element Flags                           |
   |====================================================================|
   | Name          | Bit | Description                                  |
   |---------------|-----|----------------------------------------------|
   |Corrected Clock|  0  | set if S/C time was repaired or for DE format|
   |---------------|-----|----------------------------------------------|
   |Quality        |  1  | set if data quality is questionable          |
   |---------------|-----|----------------------------------------------|
   |Limit Low      |  2  | set if out of limits low                     |
   |---------------|-----|----------------------------------------------|
   |Limit High     |  3  | set if out of limits high                    |
   |---------------|-----|----------------------------------------------|
   |Limit Level    |  4  | set if beyond red limits                     |
   |---------------|-----|----------------------------------------------|
   |Spare          |  5  | unused                                       |
   |---------------|-----|----------------------------------------------|
   |Alternate Limit|  6  | set if alternate limit was in use            |
   |---------------|-----|----------------------------------------------|
   |EU Convert Err |  7  | set if conversion error occurred             |
   |---------------|-----|----------------------------------------------|
   |No EU Convert  |  8  | set if no conversion is defined              |
   |---------------|-----|----------------------------------------------|
   |Initial Point  |  9  | set if first point after gap                 |
   |---------------|-----|----------------------------------------------|
   |Final Point    | 10  | set if last point before gap                 |
   |---------------|-----|----------------------------------------------|
   |Derived Param  | 11  | set if this point is a derived parameter     |
   +====================================================================+


  The naming convention for FOF files is as follows:

           +=====================================+
           |FOF Naming Format: iyyyydddhhmmss.xxx|
           |-------------------------------------| 
           | i = product code (TBD)              |
           | yyyy = year                         |
           | ddd = day of year (001 - 366)       |
           | hh = hour (00 - 23)                 |
           | mm = minute (00 - 59)               |
           | ss = second (00 - 59)               |
           | xxx = data type (TBD)               |
           +=====================================+ 



  Telemetry Subset Files
  ----------------------

  Telemetry Subset Files are produced by the CVTFOF process in a simulated RMS
  Variable Record Size format having the byte ordering of the host machine. 
  These files contain Change-Only telemetry values extracted from FOF files. 
  The files are composed of variables size records (maximum size 8702 bytes)
  containing a subset header and subset elements.  The first record in a subset
  file conatains a subset header and as many subset elements that will fit
  without exceeding the maximum record size.  The remaining records contain  
  only subset elements.  Each Subset Element contains a value for a single 
  telemetry parameter and is either 7 or 11 bytes long; dependent upon its 
  contents.  The structure of Subset Headers and Subset Elements was provided 
  in the previous section however a Subset Element diagram is provided below:

      +=============================================+
      |  SUB file telemetry packet                  |
      |---------------------------------------------|
      | PDB tag id | (I*2) FOF numneric id          |
      | Attribute  | (I*1) (see below)              |
      | Value      | (I4,R4,R8,or C8) see attribute |
      +=============================================+
      

 +======================================================================+
 |          Revised Measurement Attribute Format for SUB data           |
 |======================================================================|
 | Bit |Name       |Description                                         |
 |-----|-----------|----------------------------------------------------|
 |  7  |Measurement| 0 is 4-byte value, 1 is 8-byte value               |
 |     |  Length   |                                                    |
 |  6  |Conversion | 0 is no error or no conversion, 1 is failure and   |
 |     |  Error    |   raw value is present                             |
 |     |           | (new) 0 for FOF data always - bad data not present |
 |  5  |Measurement| for 4-byte values, 0 is integer, 1 is IEEE real;   |
 |     |  Format   | (new) for 8-byte values, 0 is char, 1 is IEEE DP   |
 |  4  |Limit Low  | (new) 1 if out of limits low                       |
 |  3  |Limit High | (new) 1 if out of limits high                      |
 |  2  |Limit Level| (new) 0 if first level, 1 if high or severe level  |
 |  1  |Alternate  | (new) 1 if alternate limits are in use for level   |
 |     |  Limits   |                                                    |
 |  0  |Initial    | (new) 1 if first data point after gap              |
 |     |  Point    |                                                    |
 +======================================================================+


  The naming convention for Telemetry Subset files is as follows:

           +================================+
           |SUB Naming Format: SymdhhmmW.VC0|
           |--------------------------------| 
           | y = year from 1980 (1 - Z)     |
           | m = month (1 - C)              |
           | d = day of month (1 - V)       |
           | hh = hour (00 - 23)            |
           | mm = minute (00 - 59)          |
           +================================+ 



  Telemetry Gap Files (Formerly Telemetry Error (.ERR) File) 
  ----------------------------------------------------------

  Telemetry Gap Files are ascii format files providing the same information as
  and replacing the current Telemetry Error Files produced by the PREPROC 
  process.  The information provided by these files includes the spacecraft 
  time for the beginning and end of Telemetry Subset Files and the beginning 
  and end of telemetry gaps within the files.  Every Telemetry Subset File has
  a corresponding Telemetry Gap file.  Each gap file consists of three header 
  lines followed by a variable number of fixed-format lines of mixed data type.
  The header lines are composed of a title line and two lines used to label 
  columns in the the fixed-formatted lines.  An example of the header lines and
  a fixed-format line is as follows:  

                         OMS CVTFOF SUBSET DESCRIPTION 

     calendar_time         julian_time      mnfr                   action
  1997.245:21:13:38.306  50702.88447114116   813     0     0     0   BOF     0



  The fields in each fixed-format line are composed of the following:

      +-----------------+--------+------------------------------------------+
      |  field          | format | description                              |
      +-----------------+--------+------------------------------------------+
      |calendar time    | a21    | yyyy.ddd:hh:mm:ss.mmm                    |
      |space            | a2     | "  "                                     |
      |julian time      | F17.11 | modified julian day in double precision  |
      |space            | a2	 | "  "                                     |
      |minor frame cnt  | i4     | minor frame counter of recent record     |
      |default          | a20    | "     0     0     0  "                   |
      |record type      | a4     | "BOF ", "EOF", "BGAP" or "EGAP"          |
      |default          | a13    | "   0         "                          |
      +-----------------+--------+------------------------------------------+


  The naming convention for a Gap file is the same as its corresponding 
  Telemetry Subset file with the .VC0 extension replace with .ER0.

           +================================+
           |GAP Naming Format: SymdhhmmW.ER0|
           |--------------------------------| 
           | y = year from 1980 (1 - Z)     |
           | m = month (1 - C)              |
           | d = day of month (1 - V)       |
           | hh = hour (00 - 23)            |
           | mm = minute (00 - 59)          |
           +================================+