| Earth Observation Mission CFI Software Usage Guide for Object Oriented Software |

# WORKING EARTH OBSERVATION FILES

## Introduction

While the FileHandling CFI library provides methods for reading and writting generic XML files, the DataHandling library contains classes to handle the files for the Earth Observation missions. The Earth Observation missions work with a set of files with data for the mission planning activities. These files have a predefined format common for all missions. The supported files are:

- IERS Bulletin B files
- Orbit files
- Orbit Scenario files
- DORIS Navigator files
- Attitude files
- Star tracker files
- Digital Elevation files (ACE model)
- Digital Elevation configuration files
- Swath Definition files
- Swath Template files
- Zone Database files
- Station Database files
- Star Database files
- TLE files

The file format and versions available for these files can be found in the DataHandling SUM for the C-library. Schemas and example files can also be found in the installation package.

The following sub-sections describe the operations that can be performed with the Earth Observation Files, that is, reading, writing and validating the files.

## Classes for the Earth Observation Files

All the previous files have an associated class. These classes inherit from its parent abstract class EEFile. All the classes contain a set of public attributes that can be easily accessed to:

- File name
- File type
- Fixed header elements
- Data of the Data block of the file
- Optionally, data of the variable header

The classes allows the following methods:

- Reading the file data
- Writing the class data to a file (not for all files)
- Validate the XML file with its XML schema

Exceptions: The IERS Bulletin B file (class IersFile), the DEM files (class DemFile) and the TLE files (class TleFile) are external to the CFI and are not in XML format. They only contain methods for reading its data.

## Reading Earth Observation Files

The calling sequence for reading a file is the following:

- Create the object and set the file name in the fileName attribute:

  1. With the empty constructor and then setting the file name. For instance:
     `OsfFile myOsf;
     myOsf.fileName = "./cfi_files/osf_file";`

  2. With the constructor with the filename in it. For instance:
     `OsfFile myOsf("./cfi_files/osf_file");`

- Read the file with the read method:
  `myOsf.read()`
- Data handlig for users purposes. For instance:
  `cout << "Number of orbital changes in OSF = " << myOsf.osfRec.size();`

The user should be aware that:

- depending on the file type, there could be different methods for reading specific parts of the file.
- The reading functions for each of the file types, does not read the fixed header. The fixed header could be read independently using the method readHeader().
- When reading the fixed header with readHeader(), the schema name is not read (the "schema" attribute will be set to "_NOSCHEMA_") . If required, the schema name and version should be read with the methods for XmlFile class.

See Example

## Writting Earth Observation Files

#### Create a new Earth Observation File

The calling sequence for writing a file from scratch is the following:

- Create the object with the empty constructor:
  `OsfFile myOsf;`

- Call the write method:
  Note that the method requires as input parameters the filename to write the file in disk, and the data object(s) and/or structure to be written. For instance:
  `//Setting the Fixed Header the OsfRec values`
  `FixedHeader fhr;
  vector<OsfRec> osfList;
  fhr.filename = "my_osf";
  fhr.Mission = "CryoSat";
  [...];
  myOsf.write("./cfi_files/my_osf", fhr, osfList);
  `

Note that also it is possible to create the object with the filename:
`OsfFile myOsf("./cfi_files/my_osf");`
or
`OsfFile myOsf;
myOsf.fileName = "./cfi_files/my_osf";
` In this case, it is not neccessary the filename in the write method:
`myOsf.write(fhr, osfList);
`

#### Modify an existing Earth Observation File

The calling sequence to modify an existing file is the following:

- Create the object and set the file name in the fileName attribute:

  1. With the empty constructor and then setting the file name. For instance:
     `OsfFile myOsf;
     myOsf.fileName = "./cfi_files/osf_file";`

  2. With the constructor with the filename in it. For instance:
     `OsfFile myOsf("./cfi_files/osf_file");`

- Read the file with the read method:
  `myOsf.read()`

- Modify the data in the read object. Note that the data are stored in the public attributes. For instance:
  `//remove last element from list of orbital changes`
  `myOsf.osfRec.pop_back()`

- Write the file to disk either with a new file name:
  `myOsf.write("./cfi_files/my_new_osf", *(myOsf.fhr), myOsf.osfRec);`
  Or with the same file name (overwrite the existing file):
  `myOsf.write(*(myOsf.fhr), myOsf.osfRec);`

#### Setting the schema in an XML Earth Explorer File

The schema name and version can be written in an XML file in the following ways:

- Setting the schema name in the attribute EECFI::EEFile::fixedHeader::schema. When calling the with write method, the schema name and version will be written in the file. Note that if the schema name is set to "_NOSCHEMA_", the schema attributes will no be written in the file.
- After writing the file, by calling the method EECFI::XmlFile::setSchema (in FileHandling). Note that the method EECFI::FileInfo::selectSchema allows to get the default schema name with which the file to be written is compliant.

See Example

## Validation of Earth Observation Files

The Earth Observation files in XML can be checked to verify that they are well formed. This validation process checks the format of a file with respect to its XSD schema. (The schemas are delivered within the CFI installation package (see [GEN_SUM]))

The calling sequence to validate a file is the following:

- Create the object and set the file name in the fileName attribute:

  1. With the empty constructor and then setting the file name. For instance:
     `OsfFile myOsf;
     myOsf.fileName = "./cfi_files/osf_file";`

  2. With the constructor with the filename in it. For instance:
     `OsfFile myOsf("./cfi_files/osf_file");`

- Validate the file with one of the validate methods:
  `myOsf.validate("validation_log")`

See Example

## Example

    // ------------------------------------------------------------------------
    //
    //                           C++ Example Program.
    //                           HANDLING EARTH OBSERVATION FILES
    //
    // ------------------------------------------------------------------------

    // Non-EOCFI include files
    #include <string>
    #include <vector>
    #include <iostream>

    // EOCFI includes
    #include "EEFile.h"
    #include "OsfFile.h"
    #include "FixedHeader.h"
    #include "CfiError.h"
    #include "DataHandlingData.h"

    // Namespaces
    using namespace EECFI;
    using namespace std;

    // Main program
    int main (int argc, char *argv[])
    {
      //-------------------------------------------------
      //-------------------------------------------------

      try
      {

        OsfFile myOsf;
        OsfFile copyOsf("./copy_of_osf.xml");

        //-------------------------------
        // Reading an Orbit Scenario File
        //-------------------------------

        myOsf.fileName = "./osf.xml";
        myOsf.read();

        // From now on, the data of the file can be accessed with the public
        // attributes of the object.
        // For example, print the Absolute_Orbit number of the 2nd Orbit_Change:
        cout << "2nd. Absolute Orbit =" << myOsf.osfRec[2].absOrbit << endl;

        // Important: the Fixed header is not read with read()
        myOsf.readHeader();

        //----------------------------------
        // Writing a new Orbit Scenario File
        //----------------------------------

        copyOsf.write(*myOsf.fixedHeader, myOsf.osfRec);

        //------------------------------------
        // Modify the last Orbit Scenario File
        //------------------------------------

        // Change values in the object. For example:
        // add a comment to the "Notes" in the fixed header
        // and the Absolute_Orbit in the first Orbit_Change

        myOsf.fixedHeader->fileClass="OPER";
        myOsf.osfRec[0].absOrbit = 250;

        copyOsf.write(*(myOsf.fixedHeader), myOsf.osfRec);

        //------------------------------------
        // Validate the file
        //------------------------------------
        long validStatus;
        string schema  = "./files/schemas/EO_OPER_MPL_SWTREF_0200.XSD";
        string logfile = "validation_log.txt";

        validStatus = myOsf.validate(schema, logfile);

        cout << "Validation Status for " << myOsf.fileName << (valid_status? "OK", "FAIL") << endl;

      }//end try

      catch (CfiError cfiError)
      {
        //If an exception is thrown, there have been errors during execution
        vector<string> errorMessages;

        // Get error messages
        cfiError.getMsg(errorMessages);

        // Pring Error messages
        for (long i = 0; i < errorMessages.size(); i++)
        {
          cout << errorMessages[i] << endl;
        }
      }

      return 0;

    }