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

# VISIBILITY CALCUTALTION

The Earth Observation CFI Visibility library contains a set of classes and methods to compute the time intervals in which a satellite instrument has visiblity of:

- an Earth zone
- a ground station
- a data relay satellite (DRS)
- a star

The visibility is computed for an orbit interval requested by the user.

The following list details the possibilities to follow for computing the visibility segments:

1. For one Earth Zone:

   - First Method:

     - Intialise the Swath object
     - Get the visibility for a zone defined in a file with Swath::zoneVisTime

   - Second Method:

     - Intialise the Swath object
     - Create a ZoneRec object. This object can be created manually or it could be read from a zone station file (see [D_H_SUM])
     - Get the visibility with Swath::zoneVisTime using as input parameter the ZoneRec object.

   - Third Method:

     - Intialise the Swath object
     - Create a ZoneRec object with the zone to be computed. This object can be created manually or it could be read from a zone database file (see [D_H_SUM])
     - Create a StfFile object and call its method read (see [D_H_SUM]).
     - Get the visibility with Swath::zoneVisTime using as input parameter the ZoneRec and the StfFile objects.

   Note that:

   - For methods 1 and 2, the swath files used for computation has to be read from the swath filenames in the Swath object.
   - In method 3, the swath file is already read and sent as a parameter to the the method, so that computation time is saved.

2. For several Earth Zones:

   - Intialise the Swath object

   - Create a ZoneRec vector with the zones to be observed. (see [D_H_SUM])

   - Get the visibility segments with Swath::multiZoneVisTime. The method computes the visibility for the previous ZoneRec vector plus a list of zones defined in an input file.

3. For a Ground Station:

   - First Method:

     - Intialise the Swath object
     - Get the visibility for a station defined in a file with Swath::stationVisTime

   - Second Method:
     - Intialise the Swath object
     - Create a StationRec object with the station to be observed. This object can be created manually or it could be read from a station database file (see [D_H_SUM])
     - Create a StfFile object and call its method read (see [D_H_SUM]).
     - Get the visibility with Swath::stationVisTime using as input parameter the StationRec and the StfFile objects.
     Note that:
     - For method 1, the swath files used for computation has to be read from the swath filenames in the Swath object.
     - In method 2, the swath file is already read and sent as a parameter to the the method, so that computation time is saved.

4. For several Ground Stations:

   - Intialise the Swath object
   - Get the visibility segments with Swath::multiStationVisTime. The method computes the visibility for the a list of zones defined in an input file.

5. DRS:

   - Construct an object of the DRS class defined in the CFI Visibility library. The object can be created with the empty constructor and then call the set method or it can be directly created using the constructor with the parameters. The DRS needs as inputs the OrbitId with the orbital information and the attitude frames objects (SatNomTransId, SatTransId and InstrTransId)

   - Get the visibility for the DRS with the method drsVisTime.

6. Star Visibility:

   - Construct an object of the SwathStar class defined in the CFI Visibility library. The object can be created with the empty constructor and then call the set method or it can be directly created using the constructor with the parameters. The SwathStar needs as inputs the OrbitId and the upper and the lower swath file names.

   - Get the visibility with one of the method starVisTime. One method takes the star from the input star database file and the star name. The second method takes the star data directly from the input parameters.

Finally, the visibility segments are returned in a VisibilityList object that is is a list of VisibilitySegment. A VisibilitySegment is a TimeSegment plus an extra information about the segment. That information depends on the way in which the segment was computed. To retrieve the extra information, it has to be called to the suitable method of VisibilitySegment. The following table shows the type of extra information that can be retrieved:

Visibility method | Extra Info Class | VisibilitySegment method to retrieve the info
zoneVisTime | ZoneExtraInfo | getZoneExtraInfo
stationVisTime | StationExtraInfo | getStationExtraInfo
multiZoneVisTime | MultiZonesExtraInfo | getMultiZonesExtraInfo
multiStationVisTime | MultiStationsExtraInfo | getMultiStationsExtraInfo
mapping | MappingExtraInfo | getMappingExtraInfo
starVisTime | StarExtraInfo | getStarExtraInfo

## Example

The followin example shows how to get the zone visibility segments and how to retrieve the info from the segment list. Note that other visibility functions work in a similar way ( the example provided with the installation packages provides a more complete example). Note the following steps in the computation:

- TimeCorrelation, Model initialisation...
- Orbit Initialisation
- Swath constructor
- Visibility computation
- Getting extra info from the time segments

    // ------------------------------------------------------------------------
    //
    //                           C++ Example Program.
    //                           VISIBILITY CALCULATIONS
    //
    // ------------------------------------------------------------------------

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

    // EOCFI includes
    #include "DataHandlingData.h"
    #include "TimeCorrelation.h"
    #include "ModelId.h"
    #include "VisibilityData.h"
    #include "AtmosId.h"
    #include "Swath.h"
    #include "OrbitId.h"
    #include "VisibilityList.h"
    #include "VisibilitySegment.h"
    #include "SatId.h"
    #include "StfFile.h"
    #include "SdfFile.h"
    #include "ZoneFile.h"

    // Namespaces
    using namespace EECFI;
    using namespace std;

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

      //-------------------------------------------------
      // Put all the code inside try-catch statements
      //  so, if something fails, an exception is thrown
      //-------------------------------------------------
      try
      {

        // ------------------------------------------------------------------------
        // Satellite Id, ModelId and TimeCorrelatins initialization
        // ------------------------------------------------------------------------

        SatId satId(XPCFI_SAT_ENVISAT);

        ModelId          modelId; //Do nothing: using default models.

        double initTime[4];

        initTime[0]   = -245.1000000000000000;   // TAI time [days]
        initTime[1]   = -245.0995949074074074;   // UTC time [days] (= TAI - 35.0 s)
        initTime[2]   = -245.0995879629629630;   // UT1 time [days] (= TAI - 35.6 s)
        initTime[3]   = -245.0997800925925926;   // GPS time [days] (= TAI - 19.0 s)

        TimeCorrelation  timeId( initTime );

        // ------------------------------------------------------------------------
        // Initialise orbit Id
        // ------------------------------------------------------------------------

        double time0, time1;
        long orbit0, orbit1;

        vector<string> inputFiles;

        long orbitMode    = XOCFI_ORBIT_INIT_OSF_MODE;
        long timeInitMode = XOCFI_SEL_FILE;
        long timeRef      = XOCFI_TIME_UTC;

        inputFiles.push_back( "./data/OSF.EEF" );

        OrbitId orbitId( satId, modelId, timeId, timeRef, orbitMode,
                         inputFiles, timeInitMode, time0, time1, orbit0, orbit1 );

        // ------------------------------------------------------------------------
        // Initialization of Swath object (With Swath Definition file)
        // ------------------------------------------------------------------------
        string swathTempFile = "./RA_2___501_.N1";

        Swath swathTemp( orbitId, swathTempFile );

        // ------------------------------------------------------------------------
        // Obtain zone visibility segments
        // ------------------------------------------------------------------------
        VisibilityList visList;

        string zoneDBFile  = "./ZONE_DB";
        string zoneId      = "ZANA____";
        long   projection  = XDCFI_GNOMONIC;
        long   startOrbit  = 1800;
        long   stopOrbit   = 2300;
        double minDuration = 0.;

        visList = swathTemp.zoneVisTime( startOrbit, stopOrbit,
                                         zoneId, zoneDBFile,
                                         projection, minDuration );

        // Show the last segment
        VisibilitySegment  lastSegment = visList[visList.size()-1];
        cout << "\tNumber of segments found for zone "
             << zoneId << " = "
             << visList.size() << endl;
        cout << "\tSegment " << visList.size() << ": ( "
             << lastSegment.start.orbit        << ", "
             << lastSegment.start.seconds      << ", "
             << lastSegment.start.microseconds << " ) -> ( "
             << lastSegment.stop.orbit         << ", "
             << lastSegment.stop.seconds       << ", "
             << lastSegment.stop.microseconds << " )" << endl;

        // ------------------------------------------------------------------------
        // Obtain zone visibility segments extra information, coverage for zoneVisTime
        // ------------------------------------------------------------------------
        ZoneExtraInfo zoneExtra;
        vector<long> covVec;

        for (long i = 0 ; i < visList.size(); i++ )
        {
          zoneExtra = visList[i].getZoneExtraInfo();
          covVec.push_back( zoneExtra.coverage );
        }

        cout << "\tCoverage for segment " << visList.size()
             << " = " << covVec[covVec.size()-1] << endl;

        // Empty list
        visList.clear();

      }
      //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;

    }