/*
   Name- captureAirsGDDF.c

   Language- C     Type- MAIN

   Version- 1.0    Date-  2/18/2007   Programmer- Mike Pettey (IMSG)

   Function- This program extracts selected data from an RRODF
             and writes the data to an EDGE file.  The selected
             data is defined in the run script.  Also in the run
             script are the starting date (YYYYMMDD) and hour and
             the ending date and hour.
*/


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#define  MYTRUE      0
#define  MYFALSE     1

#define  SWAP_IN   MYTRUE
#define  SWAP_OUT  MYFALSE

#define  EIDF_RECORD_LENGTH  2000
#define  EIDF_HEADER_VALUES  EIDF_RECORD_LENGTH / 4
#define  EIDF_DATA_VALUES    EIDF_RECORD_LENGTH / 2

int    scanline, output_record;
int    num_temp_levels, num_moisture_levels, num_ozone_levels;
int    num_emiss_wavelengths;
int    num_temp_pcs, num_moisture_pcs, num_ozone_pcs;
int    num_co_layers, num_hno3_layers, num_o3_layers, num_so2_altitudes; 
int    data_frame_record, data_frame_line_number, data_frame_count, data_frame_number;
int    data_frame_lats[4], data_frame_lons[4];
/*float  temp_pressures[90], moisture_pressures[90], ozone_pressures[10][2];*/
float  temp_pressures[101], moisture_pressures[101], ozone_pressures[101];
float  emiss_wavelengths[12];
float  co_heights[19], hno3_heights[19], o3_heights[40];
float  so2_altitudes[5];


main(int argc, char *argv[])
  {
  int    record_class, instr_group, rec_subclass, subclass_ver, record_length;
  int    start_date, start_time, end_date, end_time;
  int    i, n, i4val;
  int    input_file_number;
  int    output_header[EIDF_DATA_VALUES];
  short  i2val;
  char   c;
  char   input_file_name[500];
  long   offset; 
  FILE   *in, *out;

	time_t 		date_time;
	struct		tm *ts;
	int     	year0,month0,day0,yyyymmdd0;
	char * file_name = 0;


  /* Print an initial message */

/*  printf("\nCopying the IASI files to an EIDF\n\n"); */

	/* obtain the current time */
        time(&date_time);
        ts = localtime(&date_time);
        month0 = ts->tm_mon + 1;
        day0 = ts->tm_mday;
        year0 = ts->tm_year + 1900;
        yyyymmdd0 = year0 * 10000 + month0 * 100 +day0;


  /* Initialize some of the variables */
/*
  input_file_number = 1;
  output_record = 2;
*/
  scanline = 0;
/*
  data_frame_number = 0;
*/




	 /* if the output file does not exist, a new header wil be created
 *            containing defalut values. If teh file exists, the header record
 *                       is read out */

        if ( (out=fopen("out.file","r"))==NULL)
          {
                for (i=0; i<EIDF_HEADER_VALUES; i++)
                        output_header[i]= -32768;
                output_header[0]=65686870;
                output_header[1]=10;
                output_header[2]=1;
                output_header[3]=EIDF_RECORD_LENGTH;
                output_header[4]=EIDF_RECORD_LENGTH;
                output_header[6]=0;

		 if(SWAP_OUT ==MYTRUE)
                  {
                        for(i=0;i<EIDF_HEADER_VALUES;i++)
                        output_header[i]= htonl(output_header[i]);
                  }

        /* chech to see if the file can be open for output */
                if ((out=fopen("out.file", "w")) == NULL)
                {
                printf("\n the output file can not be opened for output.\n");
                exit(1);
                 }

	         fseek(out, 0, SEEK_SET);
                fwrite(&output_header, EIDF_RECORD_LENGTH, 1, out);
                fclose(out);
          }


        /* link to the subroutine       */
        file_name=argv[1];

/*  sprintf(input_file_name, "in.file%d", input_file_number);*/
  if ((in=fopen(file_name, "r")) == NULL)
    {
    printf("\n\nThe input file could not be opened .\n");
    printf("Execution ending.\n\n");
    exit(1);
    }

    printf("Processing Input File:  %s\n", file_name); 




  /* Open the output file */
  if ((out=fopen("out.file", "r+")) == NULL)
    {
    printf("\n\nThe output file could not be opened for output.\n");
    printf("Execution ending.\n\n");
    exit(1);
    }

	
	/* read the output file header */
        fread(&output_header, EIDF_RECORD_LENGTH, 1, out);

        /* initilize some para */
        output_record=output_header[2];
        printf("output record from header[2]: %d\n", output_record);

        /*data frame record */
        output_record++;
        data_frame_record = output_record;
        input_file_number = output_header[6] + 1;
	data_frame_number = input_file_number;


  /* Initialize the header of the output file */
/*
  for (i=0; i<EIDF_HEADER_VALUES; i++)
    output_header[i] = -32768;

  output_header[0] = 73686870;
  output_header[1] = 10;
  output_header[3] = EIDF_RECORD_LENGTH;
  output_header[4] = EIDF_RECORD_LENGTH;
  output_header[5] = yyyymmdd0;
*/

  /* Loop through the input files */



/*  while ((in=fopen(input_file_name, "r")) != NULL) */

/*    {*/

   /* data_frame_number      = 0; */
/*    data_frame_number      = data_frame_number; 
    data_frame_record      = output_record;*/

    data_frame_line_number = 0;
    data_frame_count       = 0;

    for (i=0; i<4; i++)
      {
      data_frame_lats[i] = -32768;
      data_frame_lons[i] = -32768;
      }


    /* Loop through each of the record types in the file */

    offset = 0;

    while (! feof(in))
      {
      fseek(in, offset, SEEK_SET);

      fread(&c, 1, 1, in);
      record_class = c;
      /*printf("record_class= %d\n",record_class); */

      fread(&c, 1, 1, in);
      instr_group = n;

      fread(&c, 1, 1, in);
      rec_subclass = n;

      fread(&c, 1, 1, in);
      subclass_ver = n;

      fread(&i4val, 4, 1, in);
      if (SWAP_IN == MYTRUE)
        record_length = ntohl(i4val);

      /*printf ("record_length= %d\n",record_length);*/


      fread(&i2val, 2, 1, in);
      fread(&i4val, 4, 1, in);

      if (SWAP_IN == MYTRUE)
        {
        i2val = ntohs(i2val);
        i4val = ntohl(i4val);
        }

      start_date = i2val;
      start_time = i4val;

      fread(&i2val, 2, 1, in);
      fread(&i4val, 4, 1, in);

      if (SWAP_IN == MYTRUE)
        {
        i2val = ntohs(i2val);
        i4val = ntohl(i4val);
        }

      end_date = i2val;
      end_time = i4val;

      if (record_class == 1)
	{
        readMainProductHeaderRecord(in,offset);
	}

      else if (record_class == 5)
	{
        readGlobalInternalAuxiliaryDataRecord(in,offset);
	}
	

      else if (record_class == 8)
	{

        readMeasurementDataRecord(in,out,offset);
        /*printf("scanline: %d\n", scanline);*/

	}


      offset = offset + record_length;

	/*printf("offset= %d\n\n",offset); */
      }


    /* Process the last data frame header */

	printf("data_frame_count= %d\n",data_frame_count); 
    if (data_frame_count != 0)
      addDataFrameHeader(out);

    /*output_record--;*/

    fclose(in);

    /* Build the next input file name */

/*    input_file_number++;
    sprintf(input_file_name, "in.file%d", input_file_number);*/

/*  }  */


  /* Update the output file header */

/*  output_header[2] = output_record - 1;*/
  output_header[2] = output_record;
  output_header[6] = input_file_number;

/*  output_header[2] = output_record - 1;*/

  if (SWAP_OUT == MYTRUE)
    {
    for (i=0; i<EIDF_HEADER_VALUES; i++)
      output_header[i] = htonl(output_header[i]);
    }

        printf("output record: %d\n\n", output_record);
  fseek(out, 0, SEEK_SET);
  fwrite(&output_header, EIDF_RECORD_LENGTH, 1, out);

  fclose(out);

/*  printf("\nThe file has been read\n\n");*/
  }


/* ===============================================================================*/
readMainProductHeaderRecord(FILE *in, long offset)
  {
  int    record_class, instr_group, rec_subclass, subclass_ver, record_length;
  int    i, n, i4val;
  short  i2val;
  char   c;

  fseek(in, offset, SEEK_SET);

	/*printf ("offset MPHR= %d\n",offset);*/
  fread(&c, 1, 1, in);
  record_class = n;

  fread(&c, 1, 1, in);
  instr_group = n;

  fread(&c, 1, 1, in);
  rec_subclass = n;

  fread(&c, 1, 1, in);
  subclass_ver = n;

  fread(&i4val, 4, 1, in);
  if (SWAP_IN == MYTRUE)
    record_length = ntohl(i4val);
	/*printf ("record_length MPHR= %d\n",record_length);*/

  fread(&i2val, 2, 1, in);
  fread(&i4val, 4, 1, in);

  fread(&i2val, 2, 1, in);
  fread(&i4val, 4, 1, in);

  /*printf("Main Product Header Record\n\n");*/

  for (i=offset; i<(record_length-20); i++)
    {
    fread(&c, 1, 1, in);
    /*printf("%c", c);*/
    }

/*  printf("\n\n");*/
  }



/* ===============================================================================*/
readGlobalInternalAuxiliaryDataRecord(FILE *in, long offset)
  {
  int    record_class, instr_group, rec_subclass, subclass_ver, record_length;
  int    i, n, i4val;
  short  i2val;
  unsigned char c;
  unsigned long int ipressure;
  unsigned short int iheight;


  fseek(in, offset, SEEK_SET);
	/*printf ("offset GIADR= %d\n",offset);*/

  fread(&c, 1, 1, in);
  record_class = n;

  fread(&c, 1, 1, in);
  instr_group = n;

  fread(&c, 1, 1, in);
  rec_subclass = n;

  fread(&c, 1, 1, in);
  subclass_ver = n;

  fread(&i4val, 4, 1, in);
  if (SWAP_IN == MYTRUE)
    record_length = ntohl(i4val);
	/*printf ("record_length GIADR= %d\n",record_length);*/

  fread(&i2val, 2, 1, in);
  fread(&i4val, 4, 1, in);

  fread(&i2val, 2, 1, in);
  fread(&i4val, 4, 1, in);

/*  printf("Global Internal Auxiliary Data Record\n\n");*/


  /* Read the temperature pressures */

  fread(&c, 1, 1, in);
  num_temp_levels = c;
  /*printf("Number of temp pressure levels:  %d\n", num_temp_levels);*/


  for (i=0; i<num_temp_levels; i++)
    {
    fread(&ipressure, 4, 1, in);

    if (SWAP_IN == MYTRUE)
      ipressure = ntohl(ipressure);
    temp_pressures[i] = ipressure / 10000.0;

    if (i >= num_temp_levels)
      temp_pressures[i] = -32768.0;
    /*printf("temp pressures:   %d   %d    %f\n", i, ipressure, temp_pressures[i]);	*/
    }
/*	exit(1);  */


  /* Read the moisture pressures */

  fread(&c, 1, 1, in);
  num_moisture_levels = c;

  /*printf("Number of moisture pressure levels:  %d\n", num_moisture_levels);*/

  for (i=0; i<num_moisture_levels; i++)
    {
    fread(&ipressure, 4, 1, in);

    if (SWAP_IN == MYTRUE)
      ipressure = ntohl(ipressure);

    moisture_pressures[i] = ipressure / 10000.0;

    if (i >= num_moisture_levels)
      moisture_pressures[i] = -32768.0;
    /*printf("wvap pressures:   %d   %d    %f\n", i, ipressure, moisture_pressures[i]);*/
    }
/*	exit(1); */

/*     skip the rest of some para */
/*
  for (i=offset+829; i<offset+1456; i++)
    {
    fread(&c, 1, 1, in);
    }
*/

  /* Read the ozone pressures */

  fread(&c, 1, 1, in);
  num_ozone_levels = c;

  /*printf("Number of ozone pressure levels:  %d\n", num_ozone_levels);*/

  /* Read the ozone pressures */
  for (i=0; i<num_ozone_levels; i++)
    {
      fread(&ipressure, 4, 1, in);

      if (SWAP_IN == MYTRUE)
        ipressure = ntohl(ipressure);

      ozone_pressures[i] = ipressure / 10000.0;

      if (i >= num_ozone_levels)
        ozone_pressures[i] = -32768.0;

    /*printf("ozone pressures:   %d   %d    %f   %f\n", i, ipressure, 
             ozone_pressures[i], ozone_pressures[i]);*/

    }
/*	exit(1);*/


/* read surface emissivity info */
  fread(&c, 1, 1, in);
  num_emiss_wavelengths = c;
  /*printf("Number of emissivity wavelengths:  %d\n", num_emiss_wavelengths);*/

  for (i=0; i<num_emiss_wavelengths; i++)
    {
      fread(&ipressure, 4, 1, in);

      if (SWAP_IN == MYTRUE)
        ipressure = ntohl(ipressure);

      emiss_wavelengths[i] = ipressure / 10000.0;

      if (i >= num_emiss_wavelengths)
        emiss_wavelengths[i] = -32768.0;
/*
    printf("emiss lengths:   %d   %d    %f   %f\n", i, ipressure, 
             emiss_wavelengths[i], emiss_wavelengths[i]);
*/

    }



/* ERROR DATA */
  fread(&c, 1, 1, in);
  num_temp_pcs = c;
  /*printf("Number of temp PCs:  %d\n", num_temp_pcs);*/

  fread(&c, 1, 1, in);
  num_moisture_pcs = c;
  /*printf("Number of moisture PCs:  %d\n", num_moisture_pcs);*/

  fread(&c, 1, 1, in);
  num_ozone_pcs = c;
  /*printf("Number of ozone PCs:  %d\n", num_ozone_pcs);*/


  /* Read partial layer for CO */

  /* co */
  fread(&c, 1, 1, in);
  num_co_layers = c;
  /*printf("Number of co layers:  %d\n", num_co_layers);*/

  for (i=0; i<num_co_layers; i++)
    {
    fread(&iheight, 2, 1, in);

    if (SWAP_IN == MYTRUE)
      iheight = ntohl(iheight);

    co_heights[i] = iheight / 10000.0;

    if (i >= num_co_layers)
      co_heights[i] = -32768.0;
/*
    printf("co heights:   %d   %d    %f\n", i, ipressure, co_heights[i]);
*/
    }

  /* hno3 */
  fread(&c, 1, 1, in);
  num_hno3_layers = c;
  /*printf("Number of hno3 layers:  %d\n", num_hno3_layers);*/

  for (i=0; i<num_hno3_layers; i++)
    {
    fread(&iheight, 2, 1, in);

    if (SWAP_IN == MYTRUE)
      iheight = ntohl(iheight);

    hno3_heights[i] = iheight / 10000.0;

    if (i >= num_hno3_layers)
      hno3_heights[i] = -32768.0;
/*
    printf("hno3 heights:   %d   %d    %f\n", i, ipressure, hno3_heights[i]);
*/
    }

  /* o3 */
  fread(&c, 1, 1, in);
  num_o3_layers = c;
  /*printf("Number of o3 layers:  %d\n", num_o3_layers);*/

  for (i=0; i<num_o3_layers; i++)
    {
    fread(&iheight, 2, 1, in);

    if (SWAP_IN == MYTRUE)
      iheight = ntohl(iheight);

    o3_heights[i] = iheight / 10000.0;

    if (i >= num_o3_layers)
      o3_heights[i] = -32768.0;
/*
    printf("o3 heights:   %d   %d    %f\n", i, ipressure, o3_heights[i]);
*/
    }

  /* so2 */
  fread(&c, 1, 1, in);
  num_so2_altitudes = c;
  /*printf("Number of so2 altitudes:  %d\n", num_so2_altitudes);*/

  for (i=0; i<num_so2_altitudes; i++)
    {
    fread(&iheight, 2, 1, in);

    if (SWAP_IN == MYTRUE)
      iheight = ntohl(iheight);

    so2_altitudes[i] = iheight / 10000.0;

    if (i >= num_so2_altitudes)
      so2_altitudes[i] = -32768.0;
/*
    printf("so2 altitudes:   %d   %d    %f\n", i, ipressure, so2_altitudes[i]);
*/

    }

/*  printf("\n\n");*/
  }



/* ===============================================================================*/
readMeasurementDataRecord(FILE *in, FILE *out, long rec_offset)
  {
  int    i, n, i4val, fov, level;
  int    year[120], mmdd[120], hour[120], mmss[120];
  int    start_date, start_time, end_date, end_time;
  float  time_interval, ftime;
  int    fov_date, fov_time, yyyymmdd, hhmmss;
  long   offset, time1, time2;
  short  i2val;
  short  buffer[EIDF_DATA_VALUES];

/*  int    altitude, instrument_flag, processing_flag; */
  int    instrument_flag, processing_flag;

  float  fg_temps[120][101], fg_wvapor[120][101];
  float  fg_ozone[120][101], fg_surface_temps[120];
  int    fg_temps_quality[120], fg_wvapor_quality[120], fg_ozone_quality[120];
  int    fg_surface_temps_quality[120];

  float  temps[120][101], wvapor[120][101];
  float  ozone[120][101], surface_temps[120];

  float  i_wvapor[120], i_ozone[120], n2o[120], co[120], ch4[120], co2[120];
  float  emissivity[120][12];

  float  cloud_fraction[120][3], ctt[120][3], ctp[120][3];
  int    num_clouds[120], cloud_phase[120][3];
  float  surface_pressure[120];

/*  int    num_surf_temps[120], num_clouds[120], cloud_phase[120][3];*/
/*  int    instr_mode, time_attitude, nav_status; */

  int    instr_mode, sat_altitude; 
  float  sol_zenith[120], sol_azimuth[120], sat_zenith[120], sat_azimuth[120];
  float  lat[120], lon[120];

  int	 flg_amsubad[120], flg_avhrrbad[120], flg_cldfrm[120], flg_cldnes[120];
  int    flg_cldtst[120], flg_daynit[120], flg_dustcld[120], flg_fgcheck[120];
  int    flg_iasibad[120], flg_initia[120], flg_itconv[120], flg_lansea[120];
  int    flg_mhsbad[120], flg_numit[120], flg_nwpbad[120], flg_physcheck[120];
  int    flg_retcheck[120], flg_satman[120], flg_sunglnt[120], flg_thicir[120];


  int    num_error_data, error_data_index[120], temp_error, wvapor_error;
  int    ozone_error; 

  int    surface_z[120], co_qflag[120], co_bdiv[120], co_npca[120];
  int    co_nfitlayers[120], co_nbr, co_cp_air, co_cp_co_a;

  int    hno3_qflag[120], hno3_bdiv[120], hno3_npca[120];
  int    hno3_nfitlayers[120], hno3_nbr;

  int    o3_qflag[120], o3_bdiv[120], o3_npca[120];
  int    o3_nfitlayers[120], o3_nbr;

  int    so2_qflag[120], so2_col_at_alt, so2_alt[120];
  int    so2_col[120], so2_bt_dif[120];


  unsigned char ch;
  unsigned short int uint2;
  unsigned long int uint4;


  /* If enough scan lines have been read to fill a data frame, then
     create and write a data frame record */
      /*printf("scanline: %d\n", scanline);*/

/*  if (data_frame_line_number > 34)
    addDataFrameHeader(out);
  else*/
    data_frame_line_number++;


  /* Increment the scan line */

  scanline++;
      /*printf("scanline: %d\n", scanline);*/


  /* Read the scan line start and end dates/times */

  offset = rec_offset + 8;
    /*printf("rec_offset MDR:    %d\n", rec_offset);	*/
  fseek(in, offset, SEEK_SET);

  fread(&uint2, 2, 1, in);
  fread(&uint4, 4, 1, in);

  if (SWAP_IN == MYTRUE)
    {
    uint2 = ntohs(uint2);
    uint4 = ntohl(uint4);
    }

  start_date = uint2;
  start_time = uint4;

  fread(&uint2, 2, 1, in);
  fread(&uint4, 4, 1, in);

  if (SWAP_IN == MYTRUE)
    {
    uint2 = ntohs(uint2);
    uint4 = ntohl(uint4);
    }

  end_date = uint2;
  end_time = uint4;


  /* Calculate the date/time of each FOV */

  time1 = start_time;

  if (end_date == start_date)
    time2 = end_time;
  else
    time2 = 86400000 + end_time;

  time_interval = (time2 - time1) / 120.0;

  fov_date = start_date;
  ftime = start_time;


  for (fov=0; fov<120; fov++)
    {
    fov_time = ftime;

    yyyymmdd = convertEpochToYYYYMMDD(fov_date);
    hhmmss = convertMillisToHHMMSS(fov_time);

    year[fov] = yyyymmdd / 10000;
    mmdd[fov] = yyyymmdd % 10000;
    hour[fov] = hhmmss / 10000;
    mmss[fov] = hhmmss % 10000;

    ftime = ftime + time_interval;

    if (ftime > 86400000.0)
      {
      fov_date++;
      ftime = ftime - 86400000.0;
      }
    }


  /* Read in the IASI data */


  /* Instrument and processing flags */

  offset = rec_offset + 20;
    /*printf("rec_offset MDR:    %d\n", rec_offset);	*/
  fseek(in, offset, SEEK_SET);

  fread(&ch, 1, 1, in);
  instrument_flag = ch;

  fread(&ch, 1, 1, in);
  processing_flag = ch;

/*      printf("flags:   %d    %c     %c\n", scanline, instrument_flag, processing_flag);*/

/* FIRST-GUESS */
  /* Atmospheric temperatures */
  for (fov=0; fov<120; fov++) 
    {
    for (level=0; level<num_temp_levels; level++)
      {
      fread(&uint2, 2, 1, in);
      
      if (SWAP_IN == MYTRUE)
        uint2 = ntohs(uint2);

      if ((uint2 != 65535) && (uint2 != 0))
        fg_temps[fov][level] = uint2 / 100.0;
      else
        fg_temps[fov][level] = -32768.0;

      /*printf("fg_temps:   %d    %d    %d   %d  %f\n", scanline, fov, level, uint2, fg_temps[fov][level]);*/
      }
	/*exit (1);*/ 
    }


  /* Atmospheric water vapor */
  for (fov=0; fov<120; fov++)
    {
    for (level=0; level<num_moisture_levels; level++)
      {
      fread(&uint4, 4, 1, in);
      
      if (SWAP_IN == MYTRUE)
        uint4 = ntohl(uint4);

      if (uint4 != -1)
/*        fg_wvapor[fov][level] = uint4 / 1000.0; */
        fg_wvapor[fov][level] = uint4 / 10000.0; 
      else
        fg_wvapor[fov][level] = -32768.0;

      /*printf("fg_wvapor:  %d   %d   %d   %d  %f\n", scanline, fov, level, uint4, fg_wvapor[fov][level]);*/
      }
	/*exit (1);*/
    }


  /* Atmospheric ozone */

  for (fov=0; fov<120; fov++)
    {
    for (level=0; level<num_ozone_levels; level++)
      {
      fread(&uint2, 2, 1, in);
      
      if (SWAP_IN == MYTRUE)
        uint2 = ntohs(uint2);

      if (uint2 != 65535)
        fg_ozone[fov][level] = uint2 / 100.0;
      else
        fg_ozone[fov][level] = -32768.0;

      /*printf("fg_ozone:   %d    %d    %d    %f\n", scanline, fov, level, uint2, fg_ozone[fov][level]);*/
      }
	/*exit(1);*/
    }

  /* Surface temps */
  for (fov=0; fov<120; fov++)
    {
      fread(&uint2, 2, 1, in);
      
      if (SWAP_IN == MYTRUE)
        uint2 = ntohs(uint2);

      if ((uint2 != 65535) && (uint2 != 0))
        fg_surface_temps[fov] = uint2 / 100.0;
      else
        fg_surface_temps[fov] = -32768.0;

      /*printf("fg_surf temps:   %d    %d    %d    %f\n", scanline, fov, uint2, fg_surface_temps[fov]);*/
      }
	/*exit(1);*/

  /* first-guess  quality */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    fg_temps_quality[fov] = ch;

    /*printf("fg_temp quality:  %d   %d    %d\n", scanline, fov, fg_temps_quality[fov]);*/
    }
	/*exit(1);*/


  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    fg_wvapor_quality[fov] = ch;

    /*printf("fg_wvapor quality:  %d   %d    %d\n", scanline, fov, fg_wvapor_quality[fov]);*/
    }
	/*exit(1);*/

  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    fg_ozone_quality[fov] = ch;

    /*printf("fg_ozone quality:  %d   %d    %d\n", scanline, fov, fg_ozone_quality[fov]);*/
    }
	/*exit(1);*/

  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    fg_surface_temps_quality[fov] = ch;

    /*printf("fg_surf_temps quality:  %d   %d    %d\n", scanline, fov, fg_surface_temps_quality[fov]);*/
    }
	/*exit(1);*/




/* RETRIEVAL */

  /* Atmospheric temperatures */
  for (fov=0; fov<120; fov++) 
    {
    for (level=0; level<num_temp_levels; level++)
      {
      fread(&uint2, 2, 1, in);
      
      if (SWAP_IN == MYTRUE)
        uint2 = ntohs(uint2);

      if ((uint2 != 65535) && (uint2 != 0))
        temps[fov][level] = uint2 / 100.0;
      else
        temps[fov][level] = -32768.0;

      /*printf("temps:   %d    %d    %d   %d %f\n", scanline, fov, level, uint2,temps[fov][level]);*/
      }
/*	exit(1);*/
    }


  /* Atmospheric water vapor */
  for (fov=0; fov<120; fov++)
    {
    for (level=0; level<num_moisture_levels; level++)
      {
      fread(&uint4, 4, 1, in);
      
      if (SWAP_IN == MYTRUE)
        uint4 = ntohl(uint4);

      if (uint4 != -1)
/*        wvapor[fov][level] = uint4 / 1000.0;*/
        wvapor[fov][level] = uint4 / 10000.0;
      else
        wvapor[fov][level] = -32768.0;

      /*printf("wvapor:  %d   %d   %d   %d %f\n", scanline, fov, level, uint4,wvapor[fov][level]);*/
      }
	/*exit(1);*/
    }


  /* Atmospheric ozone */
  for (fov=0; fov<120; fov++)
    {
    for (level=0; level<num_ozone_levels; level++)
      {
      fread(&uint2, 2, 1, in);
      
      if (SWAP_IN == MYTRUE)
        uint2 = ntohs(uint2);

      if (uint2 != 65535)
        ozone[fov][level] = uint2 / 100.0;
      else
        ozone[fov][level] = -32768.0;

      /*printf("ozone:   %d    %d    %d   %d\n", scanline, fov, level, uint2);*/
      }
    }

  /* Surface temps */
  for (fov=0; fov<120; fov++)
    {
      fread(&uint2, 2, 1, in);
      
      if (SWAP_IN == MYTRUE)
        uint2 = ntohs(uint2);

      if ((uint2 != 65535) && (uint2 != 0))
        surface_temps[fov] = uint2 / 100.0;
      else
        surface_temps[fov] = -32768.0;

      /*printf("surf temps:   %d    %d    %d   %d %f\n", scanline, fov, uint2,surface_temps[fov]);*/
      }
	/*exit(1);*/



  /* Integrated water vapor */
  for (fov=0; fov<120; fov++)
    {
    fread(&uint2, 2, 1, in);
      
    if (SWAP_IN == MYTRUE)
      uint2 = ntohs(uint2);

    if (uint2 != 65535)
      i_wvapor[fov] = uint2 / 100.0;
    else
      i_wvapor[fov] = -32768.0;

    /*printf("i_wvapor:   %d    %d    %d   %d\n", scanline, fov, level, uint2);*/
    }

  /* Integrated ozone */

  for (fov=0; fov<120; fov++)
    {
    fread(&uint2, 2, 1, in);
      
    if (SWAP_IN == MYTRUE)
      uint2 = ntohs(uint2);

    if (uint2 != 65535)
      i_ozone[fov] = uint2 / 100.0;
    else
      i_ozone[fov] = -32768.0;

    /*printf("i_ozone:   %d    %d    %d   %d\n", scanline, fov, level, uint2);*/
    }


  /* N2O */
  for (fov=0; fov<120; fov++)
    {
    fread(&uint2, 2, 1, in);
      
    if (SWAP_IN == MYTRUE)
      uint2 = ntohs(uint2);

    if (uint2 != 65535)
      n2o[fov] = uint2 / 100.0;
    else
      n2o[fov] = -32768.0;

    /*printf("N2O:   %d    %d    %d   %d\n", scanline, fov, level, uint2);*/
    }


  /* CO */
  for (fov=0; fov<120; fov++)
    {
    fread(&uint2, 2, 1, in);
      
    if (SWAP_IN == MYTRUE)
      uint2 = ntohs(uint2);

    if (uint2 != 65535)
      co[fov] = uint2 / 100.0;
    else
      co[fov] = -32768.0;

    /*printf("CO:   %d    %d    %d   %d\n", scanline, fov, level, uint2);*/
    }


  /* CH4 */
  for (fov=0; fov<120; fov++)
    {
    fread(&uint2, 2, 1, in);
      
    if (SWAP_IN == MYTRUE)
      uint2 = ntohs(uint2);

    if (uint2 != 65535)
      ch4[fov] = uint2 / 100.0;
    else
      ch4[fov] = -32768.0;

    /*printf("CH4:   %d    %d    %d   %d\n", scanline, fov, level, uint2);*/
    }


  /* CO2 */
  for (fov=0; fov<120; fov++)
    {
    fread(&uint2, 2, 1, in);
      
    if (SWAP_IN == MYTRUE)
      uint2 = ntohs(uint2);

    if (uint2 != 65535)
      co2[fov] = uint2 / 100.0;
    else
      co2[fov] = -32768.0;

    /*printf("CO2:   %d    %d    %d\n", scanline, fov, uint2);*/
    }


  /* Surface emissivity */
  for (fov=0; fov<120; fov++)
    {
/*    for (level=0; level<num_emiss_wavelengths; level++) */
    for (level=0; level<12; level++) 
      {
      fread(&uint2, 2, 1, in);
      
      if (SWAP_IN == MYTRUE)
        uint2 = ntohs(uint2);

      if (uint2 != 65535)
        emissivity[fov][level] = uint2 / 100.0;
      else
        emissivity[fov][level] = -32768.0;

      /*printf("emissivity:   %d    %d    %d   %d\n", scanline, fov, level, uint2);*/
      }
    }


  /* Number of cloud formations */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    num_clouds[fov] = ch;

    /*printf("num clouds:  %d   %d   %d\n", scanline, fov, num_clouds[fov]);*/
    }
	/*exit(1);*/


  /* Cloud fraction */
  for (fov=0; fov<120; fov++)
    {
    for (level=0; level<3; level++)
      {
      fread(&uint2, 2, 1, in);
      
      if (SWAP_IN == MYTRUE)
        uint2 = ntohs(uint2);

      if (uint2 != 65535)
        cloud_fraction[fov][level] = uint2 / 100.0;
      else
        cloud_fraction[fov][level] = -32768.0;
      }

    /*printf("Cloud Fraction:  %d   %d    %f   %f   %f\n", scanline, fov,
           cloud_fraction[fov][0], cloud_fraction[fov][1], cloud_fraction[fov][2]);*/
    }
	/*exit(1);*/


  /* Cloud top temperature */
  for (fov=0; fov<120; fov++)
    {
    for (level=0; level<3; level++)
      {
      fread(&uint2, 2, 1, in);
      
      if (SWAP_IN == MYTRUE)
        uint2 = ntohs(uint2);

      if (uint2 != 65535)
        ctt[fov][level] = uint2 / 100.0;
      else
        ctt[fov][level] = -32768.0;
      }

    /*printf("ctt:  %d  %d   %f   %f   %f\n", scanline, fov, ctt[fov][0], ctt[fov][1], ctt[fov][2]);*/
    }


  /* Cloud top pressure */
  for (fov=0; fov<120; fov++)
    {
    for (level=0; level<3; level++)
      {
      fread(&uint4, 4, 1, in);
      
      if (SWAP_IN == MYTRUE)
        uint4 = ntohl(uint4);

      if (uint4 != -1)
        ctp[fov][level] = uint4 / 100.0;
        /*ctp[fov][level] = uint4 / 1000.0;*/
      else
        ctp[fov][level] = -32768.0;
      }

    /*printf("Cloud Top Pressure:  %d   %d    %f   %f   %f\n", scanline, fov,
           ctp[fov][0], ctp[fov][1], ctp[fov][2]);*/
    }


  /* Cloud phase */
  for (fov=0; fov<120; fov++)
    {
    for (level=0; level<3; level++)
      {
      fread(&ch, 1, 1, in);
      cloud_phase[fov][level] = ch;
      }

    /*printf("Cloud Phase:  %d   %d    %d   %d   %d\n", scanline, fov,
           cloud_phase[fov][0], cloud_phase[fov][1], cloud_phase[fov][2]);*/
    }


  /* Surface pressure */
  for (fov=0; fov<120; fov++)
    {
    fread(&uint4, 4, 1, in);

    if (SWAP_IN == MYTRUE)
      uint4 = ntohl(uint4);

    if (uint4 != -1)
      surface_pressure[fov] = uint4 / 100.0;
    else
      surface_pressure[fov] = -32768.0;

    /*printf("surf press:  %d   %d   %d   %f\n", scanline, fov, uint4, surface_pressure[fov]);*/
    }

	/*exit (1);*/



  /* Instrument mode */
  fread(&ch, 1, 1, in);
  instr_mode = ch;


  /* Navigation status */
  /* sat attitude */
  fread(&uint4, 4, 1, in);

  if (SWAP_IN == MYTRUE)
    uint4 = ntohl(uint4);

  sat_altitude = uint4;

  /*printf("Time Attitude:  %d\n", time_attitude);*/


  /* Zenith and azimuth angles */

  for (fov=0; fov<120; fov++)
    {
    fread(&i2val, 2, 1, in);

    if (SWAP_IN == MYTRUE)
      i2val = ntohs(i2val);

    sol_zenith[fov] = i2val / 100.0;

    fread(&i2val, 2, 1, in);

    if (SWAP_IN == MYTRUE)
      i2val = ntohs(i2val);

    sat_zenith[fov] = i2val / 100.0;

    fread(&i2val, 2, 1, in);

    if (SWAP_IN == MYTRUE)
      i2val = ntohs(i2val);

    sol_azimuth[fov] = i2val / 100.0;

    fread(&i2val, 2, 1, in);

    if (SWAP_IN == MYTRUE)
      i2val = ntohs(i2val);

    sat_azimuth[fov] = i2val / 100.0;

    /*printf("Zenith/Azimuth:  %d  %d   %f   %f   %f   %f\n", scanline, fov,
           sol_zenith[fov], sat_zenith[fov], sol_azimuth[fov], sat_azimuth[fov]);*/
    }


  /* Latitudes and longitudes */

  for (fov=0; fov<120; fov++)
    {
    fread(&i4val, 4, 1, in);

    if (SWAP_IN == MYTRUE)
      i4val = ntohl(i4val);

    lat[fov] = i4val / 10000.0;


    fread(&i4val, 4, 1, in);

    if (SWAP_IN == MYTRUE)
      i4val = ntohl(i4val);

    lon[fov] = i4val / 10000.0;

    /*printf("Lat/Lon:  %d   %d     %f   %f\n", scanline, fov, lat[fov], lon[fov]);*/
    }
	/*exit(1);*/

  /* Store the lat/lon of the endpoints for use in the data frame */

  if (data_frame_line_number == 1)
    {
    data_frame_lats[0] = lat[0] * 128+0.5;
    data_frame_lons[0] = lon[0] * 128+0.5;
    data_frame_lats[1] = lat[119] * 128+0.5;
    data_frame_lons[1] = lon[119] * 128+0.5;
    }

  data_frame_lats[2] = lat[119] * 128+0.5;
  data_frame_lons[2] = lon[119] * 128+0.5;
  data_frame_lats[3] = lat[0] * 128+0.5;
  data_frame_lons[3] = lon[0] * 128+0.5;


/* Processing and quality flags */

  /* FLG_AMSUBAD */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    flg_amsubad[fov] = ch;

    /*printf("flg_masubad:  %d   %d    %d\n", scanline, fov, flg_amsubad[fov]);*/
    }



  /* validation flag for avhrr product */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    flg_avhrrbad[fov] = ch;

    /*printf("flg_avhrrbad:  %d   %d    %d\n", scanline, fov, flg_avhrrbad[fov]);*/
    }


  /* number of cloud formation and origin of height assignment */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    flg_cldfrm[fov] = ch;

    }


  /* flg_cldnes */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    flg_cldnes[fov] = ch;

    }


  /* cloud tests that are executed */
  for (fov=0; fov<120; fov++)
    {
    fread(&uint2, 2, 1, in);
    flg_cldtst[fov] = uint2;

    }


  /* discrimation between day and night */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    flg_daynit[fov] = ch;
    /*printf("flg_daynit:  %d   %d    %d\n", scanline, fov, flg_daynit[fov]);*/
    }
	/*exit(1);*/


  /* flg_dustcld */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    flg_dustcld[fov] = ch;

    }

  /* check weather first-guess retrievals passed to iterative retrieval */
  for (fov=0; fov<120; fov++)
    {
    fread(&uint2, 2, 1, in);
    flg_fgcheck[fov] = uint2;

    }


  /* validating flag for iasi level 1 product */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    flg_iasibad[fov] = ch;

    }


  /* retrieval initilization */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    flg_initia[fov] = ch;

    }


  /* congergence of the iterative retrieval */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    flg_itconv[fov] = ch;

    }


  /* surface type */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    flg_lansea[fov] = ch;
    /*printf("flg_landsea:  %d   %d    %d\n", scanline, fov, flg_lansea[fov]);*/
    }
	/*exit(1);*/


  /* flg_mhsbad */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    flg_mhsbad[fov] = ch;

    }


 
 
  /* unmber o fiterations used for retrieval */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    flg_numit[fov] = ch;

    }

  /* validation flag of nwp forecast */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    flg_nwpbad[fov] = ch;

    }

  /* flg_physcheck */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    flg_physcheck[fov] = ch;

    }

  /* choise of combined or iasi stand alone */
  for (fov=0; fov<120; fov++)
    {
    fread(&uint2, 2, 1, in);
    flg_retcheck[fov] = uint2;

    }


  /* indication of satellite manouevre */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    flg_satman[fov] = ch;

    }


  /* identification of sun glint */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    flg_sunglnt[fov] = ch;

    }


  /* thin cirrus cloud test */
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    flg_thicir[fov] = ch;

    }



/* ERROR DATA */

  /* number of errro data for current scan line */

  fread(&ch, 1, 1, in);
  num_error_data = ch;


  /* index of error data record */	
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    error_data_index[fov] = ch;
    }


  /* temperature error */
  for (fov=0; fov<12180; fov++)
    {
    fread(&uint4, 4, 1, in);
    temp_error = uint4;
    }

  /* moisture error */
  for (fov=0; fov<5130; fov++)
    {
    fread(&uint4, 4, 1, in);
    wvapor_error = uint4;
    }

  /* ozone error */
  for (fov=0; fov<1650; fov++)
    {
    fread(&uint4, 4, 1, in);
    ozone_error = uint4;
    }


   /* FORLI GENERAL */

  /* altitde of surface */
  for (fov=0; fov<120; fov++)
    {
    fread(&uint2, 2, 1, in);
    surface_z[fov] = uint2;
    }



   /* FORLI CO */

  /* general retrieval quality flag  */	
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    co_qflag[fov] = ch;
    }

  /* retrieval flags  */	
  for (fov=0; fov<120; fov++)
    {
    fread(&uint4, 4, 1, in);
    co_bdiv[fov] = uint4;
    }

  /* number of vectors describing the characterization matrices  */	
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    co_npca[fov] = ch;
    }


  /* number of layers actually retrieved  */	
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    co_nfitlayers[fov] = ch;
    }


  /* number of co profiles retrievd in scanlie  */	
    fread(&ch, 1, 1, in);
    co_nbr = ch;

  /* air parcel column on each retrieval layer  */	
  for (fov=0; fov<950; fov++)
    {
    fread(&uint2, 2, 1, in);
    co_cp_air = uint2;
    }

  /* a priori air parcel column on each retrieval layer  */	
  for (fov=0; fov<950; fov++)
    {
    fread(&uint2, 2, 1, in);
    co_cp_co_a = uint2;
    }

  /* scaling factor   */	
  for (fov=0; fov<950; fov++)
    {
    fread(&ch, 1, 1, in);
    fread(&ch, 1, 1, in);
    fread(&ch, 1, 1, in);
    }

  /* main eigenvalues of the sensitivity miatrix   */	
  for (fov=0; fov<500; fov++)
    {
    fread(&ch, 1, 1, in);
    fread(&ch, 1, 1, in);
    fread(&ch, 1, 1, in);
    fread(&ch, 1, 1, in);
    fread(&ch, 1, 1, in);
    }

  /* main eigenvector of the sensitivity miatrix   */	
  for (fov=0; fov<9500; fov++)
    {
    fread(&ch, 1, 1, in);
    fread(&ch, 1, 1, in);
    fread(&ch, 1, 1, in);
    fread(&ch, 1, 1, in);
    fread(&ch, 1, 1, in);
    }



   /* FORLI HNO3 */

  /* general retrieval quality flag  */	
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    hno3_qflag[fov] = ch;
    }

  /* retrieval flags  */	
  for (fov=0; fov<120; fov++)
    {
    fread(&uint4, 4, 1, in);
    hno3_bdiv[fov] = uint4;
    }

  /* number of vectors describing the characterization matrices  */	
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    hno3_npca[fov] = ch;
    }


  /* number of layers actually retrieved  */	
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    hno3_nfitlayers[fov] = ch;
    }


  /* number of co profiles retrievd in scanlie  */	
    fread(&ch, 1, 1, in);
    hno3_nbr = ch;


   /* FORLI O3 */

  /* general retrieval quality flag  */	
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    o3_qflag[fov] = ch;
    }

  /* retrieval flags  */	
  for (fov=0; fov<120; fov++)
    {
    fread(&uint4, 4, 1, in);
    o3_bdiv[fov] = uint4;
    }

  /* number of vectors describing the characterization matrices  */	
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    o3_npca[fov] = ch;
    }


  /* number of layers actually retrieved  */	
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    o3_nfitlayers[fov] = ch;
    }


  /* number of co profiles retrievd in scanlie  */	
    fread(&ch, 1, 1, in);
    o3_nbr = ch;




   /* BRESCIA_SO2 */

  /* general retrieval quality flag  */	
  for (fov=0; fov<120; fov++)
    {
    fread(&ch, 1, 1, in);
    so2_qflag[fov] = ch;
    }

  /* so2 column for a plume at different estimated alt  */	
  for (fov=0; fov<600; fov++)
    {
    fread(&uint2, 2, 1, in);
    so2_col_at_alt = uint2;
    }


  /* retrieval plume alt  */	
  for (fov=0; fov<120; fov++)
    {
    fread(&uint2, 2, 1, in);
    so2_alt[fov] = uint2;
    }

  /* so2 column at theretrieval plume alt  */	
  for (fov=0; fov<120; fov++)
    {
    fread(&uint2, 2, 1, in);
    so2_col[fov] = uint2;
    }

  /* indicative brightness T dif  */	
  for (fov=0; fov<120; fov++)
    {
    fread(&uint2, 2, 1, in);
    so2_bt_dif[fov] = uint2;
    }



  /* Copy the data to the output buffer for each FOV */

/*  for (fov=1; fov<120; fov++) */
  for (fov=0; fov<120; fov++) 
    {
    for (i=0; i<EIDF_DATA_VALUES; i++)
      buffer[i] = -32768;


    /* Fill the output buffer with the IASI values that have been read in */

    buffer[0] = 0;

    buffer[3] = lat[fov] * 128+0.5;
    buffer[4] = lon[fov] * 128+0.5;

    buffer[5] = year[fov];
    buffer[6] = mmdd[fov];
/*    buffer[6] = 605; */
    buffer[7] = hour[fov];
    buffer[8] = mmss[fov];

    buffer[12] = scanline;
/*    buffer[13] = fov; */
    buffer[13] = fov+1; 

/*

/*    buffer[14] = ispv   */	
/*    buffer[15] = ispv */

/*    First-guess profiles */
    for (level=0; level<num_temp_levels; level++)
      {
      if (level < 20)
        buffer[16+level] = temp_pressures[level] * 1000+0.5;
      else
        buffer[16+level] = temp_pressures[level] * 10+0.5;

      if (fg_temps[fov][level] != -32768)
        buffer[117+level] = fg_temps[fov][level] * 64+0.5;
      }

    for (level=0; level<num_moisture_levels; level++)
      {
      if (level < 20)
        buffer[218+level] = moisture_pressures[level] * 1000+0.5;
      else
        buffer[218+level] = moisture_pressures[level] * 10+0.5;

      if (fg_wvapor[fov][level] != -32768)
        buffer[319+level] = log(fg_wvapor[fov][level]) * 1024+0.5;
      }


    for (level=0; level<num_ozone_levels; level++)
      {
      if (level < 20)
        buffer[420+level] = ozone_pressures[level] * 1000+0.5;
      else
        buffer[420+level] = ozone_pressures[level] * 10+0.5;

      if (fg_ozone[fov][level] != -32768)
        buffer[521+level] = log(fg_ozone[fov][level]) * 1024+0.5;
      }

    if (fg_surface_temps[fov] != -32768)
      buffer[622] = fg_surface_temps[fov] * 64+0.5;

      buffer[623] = fg_temps_quality[fov];
      buffer[624] = fg_wvapor_quality[fov];
      buffer[625] = fg_ozone_quality[fov];
      buffer[626] = fg_surface_temps_quality[fov];


/*    buffer[627] = ispv */

/*    measurement data */
    for (level=0; level<num_temp_levels; level++)
      {
      if (temps[fov][level] != -32768)
        buffer[628+level] = temps[fov][level] * 64+0.5;
      }

    for (level=0; level<num_moisture_levels; level++)
      {
      if (wvapor[fov][level] != -32768)
        buffer[729+level] = log(wvapor[fov][level]) * 1024+0.5;
      }

/*
    for (level=0; level<num_ozone_levels; level++)
      {
      if (ozone[fov][level] != -32768)
        buffer[830+level] = log(ozone[fov][level]) * 1024+0.5;
      }
*/
/*    buffer[830] = ispv */

    if (surface_temps[fov] != -32768)
      buffer[831] = surface_temps[fov] * 64+0.5;

    if (i_wvapor[fov] != -32768)
      buffer[832] = i_wvapor[fov] * 100 +0.5;

    if (i_ozone[fov] != -32768)
      buffer[833] = i_ozone[fov] * 100 +0.5;

    if (n2o[fov] != -32768)
      buffer[834] = n2o[fov] * 100 +0.5;

    if (co[fov] != -32768)
      buffer[835] = co[fov] * 100 +0.5;

    if (ch4[fov] != -32768)
      buffer[836] = ch4[fov] * 100 +0.5;

    if (co2[fov] != -32768)
      buffer[837] = co2[fov] * 100 +0.5;

    for (level=0; level<num_emiss_wavelengths; level++)
      {
      if (emissivity[fov][level] != -32768)
        buffer[838+level] = emissivity[fov][level] * 100+0.5;
      }

    buffer[850] = num_clouds[fov];

    for (level=0; level<3; level++)
      {
      if (cloud_fraction[fov][level] != -32768)
        buffer[851+level] = cloud_fraction[fov][level] * 100+0.5;

      if (ctt[fov][level] != -32768)
        buffer[854+level] = ctt[fov][level] * 64+0.5;

      if (ctp[fov][level] != -32768)
        buffer[857+level] = ctp[fov][level] * 10+0.5;

      if (cloud_phase[fov][level] != -32768)
      buffer[860+level] = cloud_phase[fov][level];
      }

    if (surface_pressure[fov] != -32768)
      buffer[863] = surface_pressure[fov] * 10+0.5;


/*    buffer[864] = ispv   */	
/*    buffer[865] = ispv */

/*    navigation data */
    buffer[866] = sat_altitude+0.5;
    buffer[867] = sol_zenith[fov]+0.5;
    buffer[868] = sat_zenith[fov]+0.5;
    buffer[869] = sol_azimuth[fov]+0.5;
    buffer[870] = sat_azimuth[fov]+0.5;

/*    buffer[871] = ispv   */	
/*    buffer[872] = ispv */

/*    processing and quality flags */
    buffer[873] = flg_amsubad[fov];
    buffer[874] = flg_avhrrbad[fov];
    buffer[875] = flg_cldfrm[fov];
    buffer[876] = flg_cldnes[fov];
    buffer[877] = flg_cldtst[fov];
/*    buffer[878] = channel_selection[fov];*/
    buffer[878] = -32768;
    buffer[879] = flg_daynit[fov];
    buffer[880] = flg_dustcld[fov];
    buffer[881] = flg_fgcheck[fov];
    buffer[882] = flg_iasibad[fov];
    buffer[883] = flg_initia[fov];
    buffer[884] = flg_itconv[fov];
    buffer[885] = flg_lansea[fov];
    buffer[886] = flg_mhsbad[fov];
    buffer[887] = flg_numit[fov];
    buffer[888] = flg_nwpbad[fov];
    buffer[889] = flg_physcheck[fov];
    buffer[890] = flg_retcheck[fov];
    buffer[891] = flg_satman[fov];
    buffer[892] = flg_sunglnt[fov];
    buffer[893] = flg_thicir[fov];

/*    buffer[894] = ispv   */	
    for (level=0; level<num_ozone_levels; level++)
      {
      if (ozone[fov][level] != -32768)
        buffer[895+level] = log(ozone[fov][level]) * 1024+0.5;
      }

/*    buffer[895] = ispv */

/*    error data */
/*    buffer[896] = num_error_data;
    buffer[897] = error_data_index[fov];

    for (level=0; level<12180; level++)
      {
      if (temp_error != -32768)
        buffer[898+level] = temp_error;
      }


    for (level=0; level<5130; level++)
      {
      if (wvapor_error != -32768)
        buffer[13078+level] = wvapor_error;
      }

    for (level=0; level<1650; level++)
      {
      if (ozone_error != -32768)
        buffer[18208+level] = ozone_error;
      }*/


/*    buffer[19858] = ispv   */	
/*    buffer[19859] = ispv */

/*    FORLI general */
       /* buffer[19860] = surface_z[fov];

	buffer[19861]= co_qflag[fov];
	buffer[19862]= co_bdiv[fov];
	buffer[19863]= co_npca[fov];
	buffer[19864]= co_nfitlayers[fov];
	buffer[19865]= co_nbr;
    for (level=0; level<950; level++)
      {
      if (co_cp_air != -32768)
        buffer[19866+level] = co_cp_air;
      }

    for (level=0; level<950; level++)
      {
      if (co_cp_co_a != -32768)
        buffer[20816+level] = co_cp_co_a;
      }*/
	
	/*	buffer[21766-22715]= -32768; */
	/*	buffer[22716-23215]= -32768;	*/
	/*	buffer[23216-118116] = -32768; */

/*    buffer[118117] = -32768   */	
/*    buffer[118118] = -32768 */

/*    FORLI HNO3 */
/*    buffer[118119] = hno3_qflag[fov];
    buffer[118120] = hno3_bdiv[fov];
    buffer[118121] = hno3_npca[fov];
    buffer[118121] = hno3_nfitlayers[fov];
    buffer[118122] = hno3_nbr;*/

/*    buffer[118123] = -32768   */	
/*    buffer[118124] = -32768 */

/*    FORLI O3 */
/*    buffer[118125] = o3_qflag[fov];
    buffer[118126] = o3_bdiv[fov];
    buffer[118127] = o3_npca[fov];
    buffer[118128] = o3_nfitlayers[fov];
    buffer[118129] = o3_nbr;*/

/*    buffer[118130] = -32768   */	
/*    buffer[118131] = -32768 */

/*    FORLI so2 */
/*    buffer[118132] = so2_qflag[fov];*/
    /* buffer[118133-118732] = -32867; */
/*    buffer[118733] = so2_alt[fov];
    buffer[118734] = so2_col[fov];
    buffer[118735] = so2_bt_dif[fov];*/
	


    /* Swap the bytes if necessary */

    if (SWAP_OUT == MYTRUE)
      {
      for (i=0; i<EIDF_DATA_VALUES; i++)
        buffer[i] = ntohs(buffer[i]);
      }


    /* Write the output buffer to the output file */

    output_record++;

    offset = (output_record - 1) * EIDF_RECORD_LENGTH;
    fseek(out, offset, SEEK_SET);
    fwrite(&buffer, EIDF_RECORD_LENGTH, 1, out);

    data_frame_count++;
    }

  }



addDataFrameHeader(FILE *out)
  {
  long  offset;
  short buffer[EIDF_DATA_VALUES];
  int   i;

/*  data_frame_number++;*/

  /* Fill the buffer */

  for (i=0; i<EIDF_DATA_VALUES; i++)
    buffer[i] = -32768;

  buffer[0] = 3;
  buffer[1] = data_frame_number;
  buffer[2] = data_frame_count;

  for (i=0; i<4; i++)
    {
    buffer[i+4] = data_frame_lats[i];
    buffer[i+8] = data_frame_lons[i];
    }

  /* Write the buffer to the output file */

  if (SWAP_OUT == MYTRUE)
    {
    for (i=0; i<EIDF_DATA_VALUES; i++)
      buffer[i] = ntohs(buffer[i]);
    }
        printf("data frame record in SUB: %d\n", data_frame_record);
  
  offset = (data_frame_record - 1) * EIDF_RECORD_LENGTH;
  fseek(out, offset, SEEK_SET);
  fwrite(&buffer, EIDF_RECORD_LENGTH, 1, out);

  /* Prepare for the next data frame */

/*  output_record++;*/
  data_frame_record = output_record;

  data_frame_line_number = 0;
  data_frame_count = 0;

  data_frame_number = data_frame_number;

  for (i=0; i<4; i++)
    {
    data_frame_lats[i] = -32768;
    data_frame_lons[i] = -32768;
    }
  }



int convertEpochToYYYYMMDD(fov_date)
  {
  int yyyymmdd;
  int epoch_day, year, month, day, julday;
  int days_in_year;

  epoch_day = fov_date + 1;

  year = 2000;
  days_in_year = 366;

  while (epoch_day > days_in_year)
    {
    epoch_day = epoch_day - days_in_year;
    year++;

    if (isLeapYear(year) == MYFALSE)
      days_in_year = 365;
    else
      days_in_year = 366;
    }

  julianToDate(epoch_day, year, &month, &day);

  yyyymmdd = (year * 10000) + (month * 100) + day;

  return yyyymmdd;
  }



int convertMillisToHHMMSS(int millis)
  {
  int hhmmss, hours, minutes, seconds;

  seconds = millis / 1000;

  hours = seconds / 3600;
  seconds = seconds - (hours * 3600);

  minutes = seconds / 60;
  seconds = seconds - (minutes * 60);

  hhmmss = (hours * 10000) + (minutes * 100) + seconds;

  return hhmmss;
  }



int isLeapYear(int year)
  {
  int leap_year = MYFALSE;

  if ((year % 4) == 0)
    {
    if ((year % 100) == 0)
      {
      if ((year % 400) == 0)
        leap_year = MYTRUE;
      }
    else
      {
      leap_year = MYTRUE;
      }
    }

  return leap_year;
  }



julianToDate(int julday, int year, int* month, int* day)
  {
  int imonth, iday;

  int  days_in_month[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};

  if (isLeapYear(year) == MYTRUE)
    days_in_month[2] = 29;

  imonth = 0;
  iday   = julday;

  while ((imonth < 12) && (iday > days_in_month[imonth+1]))
    {
    imonth++;
    iday = iday - days_in_month[imonth];
    }

  imonth++;

  *month = imonth;
  *day   = iday;
  }

/* end of file */
