The DIRSIG4 Interactive Mode provides a highly configurable interface for querying simulations. Users supply arbitrary rays to be traced and then extract the result. The output can be set to human-friendly plaintext, parser-friendly XML, or high-performance binary. During the interactive simulation, the specific information to be pulled is specified through a configuration file. This is a simple XML file for which a a Document Type Definition (DTD) is available.

The purpose of Interactive Mode is to abstract DIRSIG down to a scene radiometry prediction model that can be queried by external tools. The most common application is where a user develops their own sensor model rather than using the built-in platform and sensor model. To compute the flux onto each pixel in their model, they can ask DIRSIG for the radiances along various rays that sample the pixel.

Although the tutorial at the end of this guide describes reading a fixed set of queries from an input file and writing the results of those queries to an output, the point of interactive mode is to be interactive. Hence, the expected usage is to start the DIRSIG model in this mode and have an external piece of software send queries to the model and receive the results as part of a continuous, interactive exchange.

Collector File

This file defines how the interactive session will operate by defining what data will be generated and the format of this data (ASCII/Text, XML or binary). An example of the collector XML is provided below and is then followed by a description:

<xml version="1.0" standalone="no"?>
<!DOCTYPE interactive SYSTEM "http://www.dirsig.org/dtds/interactive.dtd">
<interactive format="plain" pausepolicy="never">
  <simulationcollectors>
    <simscenefilename/>
    <simbandpasses/>
    <simscenebbox/>
  </simulationcollectors>
  <solutioncollectors>
    <pathviewray/>
    <pathsolidangle/>
    <pathsurfacecount/>
  </solutioncollectors>
  <surfacecollectors>
    <surfacematid/>
    <surfacetemperature/>
    <surfaceentrypoint/>
    <surfaceexitpoint/>
    <surfacepathlength/>
    <surfacenormal/>
    <surfacetransmission/>
    <surfaceradiance/>
  </surfacecollectors>
</interactive>

The interactive section has four attributes which may be set:

  1. The format attribute may be set to plain, xml, or binary. It controls the output formatting of the Interactive Session.

  2. The pausepolicy is an experimental feature which may be set to never, percollector, or persurface. Rather than immediately output all the results, the interactive session will halt at the specified points, waiting for the user to type an arbitrary character (or characters) followed by a new line.

  3. The startupoutputredirect may specify a filename to which all the DIRSIG startup text gets redirected. This does not include the output portion of the interactive session. If this attribute is not specified, then all output will go to either stdout or stderr, as in a normal DIRSIG simulation. Note that input must still be provided via stdin.

  4. The interactiveoutputredirect may specify a filename to which all the DIRSIG interactive results are redirected. If this attribute is not specified, then all output will go to stdout. Note that input must still be provided via stdin.

In the collector configuration file, the <simulationcollectors> corresponds to the Simulation Level Queries. Likewise, <solutioncollectors> go with Solutions and <surfacecollectors> are applied to each surface in a given solution. A list of the available collectors are provided in the following tables. The Document Type Definition (DTD) associated with this input file also lists the available options and provides a means for syntax validation using external tools.

Simulation Collectors

The following table lists the available collectors to gather simulation level information.

Name Description

simatmmodelname

String describing atmospheric model being used.

simscenefilename

Name of the top-level ODB filename for the simulation.

simmatfilename

Name of the simulation material filename.

simbandpasses

Outputs the simulation bandpass list. This is indicates the discretization of electromagnetic spectrum which DIRSIG is using in its radiometric calculations.

simscenebbox

Provides extent points of an axis-aligned bounding box encapsulating all the non-moving geometry in the scene.

Solution Collectors

The following table lists the available collectors to gather solution level information.

Collector Tag Description

pathviewray

Origin and direction of the ray used to intersect geometry. (Matches what is supplied by user).

pathsolidangle

Solid angle used for radiometric calculations with view ray. (Matches what is supplied by user).

pathsurfacecount

Number of surfaces intersected by the ray before the path transmission fell below DIRSIG’s internal threshold. (Normally the maximum value in the transmission spectral vector is no higher than 0.5%).

pathradiance

The sensor reaching radiance.

pathtransmission

Transmission along the entire path. Note that this will be zero if the ray strikes any opaque surfaces.

Surface Collectors

The following table lists the available collectors to gather surface level information.

Collector Tag Description

surfacetransmission

A spectral vector of Mueller matrices indicating the surface transmission.

surfaceradiance

A spectral vector of stokes vector indicating the surface radiance in W/(cm^2 * omega * micron).

surfaceirradiance

A spectral vector of stokes vectors indicating the surface irradiance in W/(cm^2).

surfacetemperature

The temperature of the surface in Kelvin.

surfaceentrypoint

World space coordinate (in meters) where the view ray hit the surface.

surfaceexitpoint

World space coordinate (in meters) where the view ray left the surface. Relevant for volume geometry.

surfaceentrydistance

Distance along ray to surface entry.

surfaceexitdistance

Distance along ray to surface exit.

surfaceentryangle

Entry angle of the ray relative to the surface normal. Given in radians.

surfaceexitangle

Exit angle of the ray relative to the surface normal. Given in radians.

surfacepathlength

Length of the ray segment passing through the surface. Relevant for volume geometry and equals the Euclidean distance between the entry and exit point.

surfacenormal

A normalized vector describing the surface normal.

surfacematid

The Material Id associated with the surface. This corresponds to an entry in the materials database (.mat file).

surfacethermalthickness

Non-volume geometry can be given a thermal thickness for the purposes of running DIRSIG’s temperature (Therm) model. This value is normally specified in the materials database (.mat file), but can be overridden on a per facet basis in a GDB file.

surfacegasconcentration

Volume geometry may be used to represent a gas, in which case this value represents the gas concentration of the associated material in PPM.

Note Polarized Mueller Matrices are stored in row major order.
Note Surfaces are output in ascending order sorted by entry distance.

Bandpass File

DIRSIG defines spectral regions using a minimum, maximum, and a uniform delta. These spectral regions are termed a "bandpass". Multiple bandpasses can be assembled in to a "bandpass list". A bandpass with a minimum wavelength of 0.3 microns, a maximum wavelength of 0.5 microns, and a sampling delta of 0.1 microns tells DIRSIG to simulate for the wavelengths 0.3, 0.4, and 0.5 microns. This means that internally, all the radiances, transmissions, irradiances, etc are computed for these three wavelengths. An example of the bandpass XML follows:

<bandpasslist>
  <bandpass spectralunits="microns">
    <minimum>0.3</minimum>
    <maximum>0.5</maximum>
    <delta>0.1</delta>
  </bandpass>
</bandpasslist>

Spectral units of "microns", "nanometers", and "wavenumbers" are currently supported. An example of a bandpass XML specifying two bandpasses follows. This example will cause DIRSIG to simulate at 0.3, 0.31, 0.32, 0.33, 0.4, and 0.5 microns.

<bandpasslist>
  <bandpass spectralunits="microns">
    <minimum>0.3</minimum>
    <maximum>0.5</maximum>
    <delta>0.1</delta>
  </bandpass>

  <bandpass spectralunits="nanometers">
    <minimum>310</minimum>
    <maximum>330</maximum>
    <delta>10</delta>
  </bandpass>
</bandpasslist>

Input Description

With a collector and bandpass configuration file in place, DIRSIG4 can be started in Interactive Mode as follows:

$ dirsig --mode=interactive --scene_filename=example.scene \
    --atm_filename=example.atm --collector_filename=collectors.xml \
    --bandpass_filename=bandpass.xml --datetime=2008-04-01T14:00:00.0000-05:00

In this case, collector.xml is the name of the collector file and bandpass.xml is the name of the bandpass file. When DIRSIG has finished loading the inputs, the following prompt will appear:

Interactive Mode Ready
<!-- [time] [omega] [orX] [orY] [orZ] [dirX] [dirY] [dirZ] -->

The XML style comment indicates the format for an input query that Interactive Mode expects (summarized below).

Note This informational prompt does not appear when operating in "binary" output mode.
Parameter Description

time

Offset in seconds from reference simulation time (fractional and negative values allowed).

omega

The solid angle represented by the ray.

orX, orY, orZ

Ray origin: X, Y, and Z coordinates.

dirX, dirY, dirZ

Ray direction vector: X, Y, and Z values.

Note Both ray origin and ray direction components are specified in the Scene ENU coordinate system.
Important The ray direction vector cannot be zero length, but it does not need to be unit length.
Important The solid angle (omega) must be greater than zero. The solid angle is utilized by only a handful of radiometry solvers and optical properties in DIRSIG. For example, the Fresnel radiometry solver uses a "solid angle in equals solid angle out" assumption when determining if the Sun overlaps the delta function ray reflected by a surface.

Output Description

Interactive Mode is capable of outputting plain text, XML, or binary. This is controlled by setting the format attribute in the collector file.

ASCII/Text Output

The ASCII/Text output format is intended to be human friendly. The following example contains the verbatim results of an interactive session.

Interactive Mode Ready

# Simulation Parameters #
Scene Bounding Box:
    minimum: (-521.713,-543.484,-953.792)
    maximum: (1654.42,1632.64,1222.34)

# Solution Results #
View Ray:
    origin: (800,800,1000)
    direction: (0,0,-1)
Solid Angle: 1
Surface Count: 1
Path Radiance:
    [0.47 microns] 0.00279327
    [0.48 microns] 0.00281209
    [0.49 microns] 0.00275102
    [0.5 microns] 0.0028744

# Surface 1 #
Entry Distance: 859.254
Entry Angle: 0.485803
Material ID: 25

Interactive Mode Finished

XML Output

The XML output format allows users to easily parse interactive mode output using a DOM or SAX parser. The output is a completely valid XML document, including a reference to a DTD which can be used for basic syntax validation. Note that the spacing in the XML demonstration has been modified to make it more human-friendly. Likewise, some XML-style comments have been omitted for brevity.

<?xml version="1.0" standalone="no"?>
<!DOCTYPE interactivesession
  SYSTEM "http://www.dirsig.org/dtds/interactive_out.dtd">
<interactivesession>
  <simulationinfo>
    <simscenebbox>
	<box>
          <lowerextent>
            <point><x>-521.713</x><y>-543.484</y><z>-953.792</z></point>
          </lowerextent>
          <upperextent>
            <point><x>1654.42</x><y>1632.64</y><z>1222.34</z></point>
          </upperextent>
        </box>
    </simscenebbox>
  </simulationinfo>
  <solutioninfo>
    <pathviewray>
      <ray>
        <origin><point><x>800</x><y>800</y><z>1000</z></point></origin>
        <direction><vector><x>0</x><y>0</y><z>-1</z></vector></direction>
      </ray>
    </pathviewray>
    <pathsolidangle>1</pathsolidangle>
    <pathsurfacecount>1</pathsurfacecount>
    <pathradiance>
      <spectralvector>
        <stokesvector location="0.47"> 0.00279327 </stokesvector>
        <stokesvector location="0.48"> 0.00281209 </stokesvector>
        <stokesvector location="0.49"> 0.00275102 </stokesvector>
        <stokesvector location="0.5"> 0.0028744 </stokesvector>
      </spectralvector>
    </pathradiance>
    <surfaceinfo>
      <surfaceentrydistance>859.254</surfaceentrydistance>
      <surfaceentryangle>0.485803</surfaceentryangle>
      <surfacematid>25</surfacematid>
    </surfaceinfo>
  </solutioninfo>
</interactivesession>

Binary Output

Interactive Mode also supports binary output. This section describes the format for that output. The table below shows the assumptions about the size and formatting of the basic types discussed in this section.

Important All data is output as big endian, regardless of the CPU architecture on which DIRSIG is run.

Basic Data Types

Type Description

byte

8 bits, signed via two’s complement, -128 to 127

int

4 bytes, signed via two’s complement, big endian, -2,147,483,648 to 2,147,483,647

double

8 bytes, IEEE754 format, big endian, 4.94065645841246544e-324 to 1.79769313486231570e+308

DIRSIG builds on these basic types to build more complex types for things like rays, stokes vectors, strings, etc. The following collection of tables shows how these DIRSIG types are structured. They list the elements of each type, in order, and explain what that element represents.

String

A string is returned when the user requests a name (for example, the material filename used in a sim).

Type Description

int

Number of characters in string.

N bytes

All N ASCII characters in string.

Mueller Matrix

A Mueller Matrix is used to represent a polarized or unpolarized reflectance, emissivity, transmission, extinction, etc. at a given wavelength.

Type Description

byte

Polarization status. 0=unpolarized, 1=polarized.

1 or 16 doubles

Mueller matrix elements in row major order. If unpolarized, there is only a single double (M_00) otherwise the full 4x4 matrix is presented.

Stokes Vector

A Stokes Vector is used to represent a polarized or unpolarized radiance, irradiance, radiant intensity, etc. at a given wavelength.

Type Description

byte

Polarization status. 0=unpolarized, 1=polarized.

1 or 4 doubles

Stokes vector elements. If unpolarized, there is only a single double (S_0) otherwise the full 4 element vector is presented.

Spectral Vector of Mueller Matrices

A Spectral Vector is used to store a spectral reflectance, emissivity, transmission, extinction, etc. It is composed of a value indicating how many wavelengths are in the vector and then a sequence of Mueller Matrix data elements.

Type Description

int

Number of Mueller matrices in spectral vector.

N (double, Mueller Matrix)

All N matrices in the vector are printed out. Each is preceded by a double indicating the wavelength associated with the matrix in microns.

Spectral Vector of Stokes Vectors

A Spectral Vector is used to store a spectral radiance, irradiance, radiant intensity, etc. It is composed of a value indicating how many wavelengths are in the vector and then a sequence of Stokes Vector data elements.

Type Description

int

Number of stokes vectors in spectral vector.

N (double, Stokes Vector)

All N stokes vectors in the spectral vector are printed out. Each is preceded by a double indicating the wavelength associated with the stokes vector in microns.

Point

A Point is used to store a 3D point in space.

Type Description

double

X component.

double

Y component.

double

Z component.

Note The X,Y and Y components of a point are in Scene ENU coordinates.

Vector

A Vector is used to store a 3D vector in space.

Type Description

double

X component.

double

Y component.

double

Z component.

Note The X,Y and Y components of a vector are in Scene ENU coordinates.

Ray

A Ray is used to to store a direction (Vector) leaving an origin (Point).

Type Description

Point

Ray origin.

Vector

Ray direction.

Box

A Box is used to store an axis-aligned box defined by the minimum XYZ corner (Point) and maximum XYZ corner (Point).

Type Description

Point

Minimum extent of axis-aligned box.

Point

Maximum extent of axis-aligned box.

Bandpass

A Bandpass defines a spectral bandpass, including the spectral units, the miniumum, the maximum and the sampling between the extents.

Type Description

double

Minimum extent of bandpass. Units defined byte "spectral units" byte.

double

Maximum extent of bandpass. Units defined byte "spectral units" byte.

double

Sampling delta for bandpass.

byte

Spectral units. 1 = wave numbers, 2 = microns, 3 = nanometers.

int

Total number of sampling points in bandpass. Should be same as computing via min/max extents and delta.

Bandpass List

A Bandpass List is a simple list of Bandpass objects.

Type Description

int

Number of "Bandpass" items in list.

int

Total number of sampling points for all the bandpasses in list.

N Bandpass

All N bandpasses in the list, printed out sequentially. Number of bandpasses printed is given by "bandpass count" above.

With the list of basic types and DIRSIG types established above, it is now possible to parse the collector output when in binary mode.

Table 1. Collector Output Types
Collector Output Type

simatmmodelname

string

simscenefilename

string

simmatfilename

string

simbandpasses

Bandpass List

simscenebbox

Box

pathviewray

Ray

pathsolidangle

double

pathsurfacecount

int

pathtransmission

Spectral Vector of Mueller Matrices

pathradiance

Spectral Vector of Stokes Vectors

surfacetransmission

Spectral Vector of Mueller Matrices

surfaceradiance

Spectral Vector of Stokes Vectors

surfacetemperature

double

surfaceentrypoint

Point

surfaceexitpoint

Point

surfaceentrydistance

double

surfaceexitdistance

double

surfaceentryangle

double

surfaceexitangle

double

surfacepathlength

double

surfacenormal

Vector

surfacematid

int

surfacethermalthickness

double

surfacegasconcentration

double

Tutorial

This tutorial walks through the process of creating a simple parser for the binary output functionality of Interactive Mode. This tutorial includes example C++ and Matlab source code to parse the path radiance for a known number of queries. This tutorial requires some knowledge of both programming and binary data representation.

When using Interactive Mode with binary output, it is the user’s responsibility to craft a valid collector file to be parsed. For instance, the number of surfaces intersected by a ray can vary depending on the scene location. In order to know how many surfaces are in the binary output, the collector file would need to include the pathsurfacecount collector. Without this solution-level collector’s information, the parser would not know how much of the following binary data represents surface collections.

Input Collector File

This tutorial will simply ask DIRSIG for the path radiance using a fixed number of queries. The collector file looks as follows:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE interactive SYSTEM "http://www.dirsig.org/dtds/interactive.dtd">
<interactive format="binary" pausepolicy="never"
             startupoutputredirect="startup.log">

  <simulationcollectors>
  </simulationcollectors>

  <solutioncollectors>
    <pathradiance/>
  </solutioncollectors>

  <surfacecollectors>
  </surfacecollectors>
</interactive>

Note that the format has been specified as "binary". Also, the startup output from DIRSIG which gives diagnostic information as a scene loads has been redirected to a file called "startup.log". Only the "pathradiance" solution-level collector is in use.

Input Bandpass File

For the tutorial, the following simple bandpass XML file is used:

<bandpasslist>
  <bandpass spectralunits="microns">
    <minimum>0.3</minimum>
    <maximum>0.5</maximum>
    <delta>0.1</delta>
  </bandpass>
</bandpasslist>

With this bandpass, DIRSIG will compute radiance values for 0.3, 0.4, and 0.5 microns. The output from the "pathradiance" collector is a Stokes Vector (which may or may not be polarized).

Input Query

The interactive mode queries will be supplied via a text file that looks as follows:

0 1E-6 0 0 800 0 0 -1
0 1E-6 0 1 800 0 0 -1

Here we have two queries. Both have a time offset of zero relative to the simulation base time. Both specify a solid angle of 1E-6 steradians. Both queries specify a ray shooting straight down from an altitude of 800 meters. The rays are separated by 1 meter along the y-axis.

Running in Interactive Mode

Given an appropriate DIRSIG scene and atmosphere, the pieces are put together as follows:

$ dirsig --mode=interactive \
        --scene_filename=demo.scene \
        --atm_filename=uniform.atm \
        --collector_filename=collectors.xml \
        --bandpass_filename=bandpasses.xml \
        --datetime=2008-07-01T12:00:00.0000-05:00 < query_input.txt > query_output.txt

This example uses shell redirection to read the queries from query_input.txt and feed them to DIRSIG via stdin. It takes the output from DIRSIG and redirects it to "query_output.txt". The contents of this queryoutput file will be binary data. Remember, there is a "startup.log" file available with plaintext output of the startup process. The next step in the tutorial is to write a simple program to parse this binary output. First the pseudo code:

  1. For each query …​

    1. Parse the radiance spectral vector in to memory</para>

    2. Print the radiance spectral vector to the console

  2. To parse a spectral vector:

    1. Parse the number of Stokes Vectors. This is a four-byte, big-endian integer.

    2. Attempt to parse the number of specified stokes vectors. Each stokes vector is preceded by an eight-byte, big-endian double describing the spectral location in microns. After the spectral location comes the actual stokes vector.

  3. To parse a stokes vector:

    1. Parse the polarization status byte:

      • A value of 0 indicates an unpolarized stokes vector, meaning just one double of data will follow. A value of 1 indicates polarized data, meaning four doubles of data will follow.

    2. Parse either one or four eight-byte, big endian doubles, as specified by the polarization status byte.

C++ Binary Reader Example

Note that Interactive Mode will always output data in big-endian format, regardless of the native architecture’s endianness. For simplicity reasons the following example code does not perform any endian checking or conversions. This means that the as-is version of the following code will only work on big-endian processors such as SPARC. The x86 processors for Intel and AMD and little-endian, and the following code will not work as-is on these platforms. The following code also assumes that a native double is 8 bytes and a native int is 4 bytes.

#include <fstream>
#include <iostream>
#include <istream>
#include <utility>
#include <vector>

typedef std::vector<double> StokesVector;
typedef std::pair<double,StokesVector> SpectralData;
typedef std::vector<SpectralData> SpectralVector;
/* Parse a stokes vector.  */
void parseSV( std::istream& is, StokesVector& stokes ) {

    // read polarization status
    char polStatus = -1;
    is.read( &polStatus, 1 );

    // number of data elements in stokes depends on polarization state
    const int numElements = ( polStatus == 1 ) ? 4 : 1;

    // read all stokes elements
    for ( int i = 0; i < numElements; i++ ) {

        // read current stokes vector element
        double stokesData = -1.0;
        is.read( reinterpret_cast<char*>( &stokesData ), sizeof( double ) );

        // stash parsed data value
        stokes.push_back( stokesData );
    }

}
/* Parse spectral vector of stokes vectors */
void parseSpecVecSV( std::istream& is, SpectralVector& specvec ) {

    // read number of stokes vectors in spectral vector
    int vectorCount = -1;
    is.read( reinterpret_cast<char*>( &vectorCount ), sizeof( int ) );

    // read each wavelength / stokes vector pair
    for ( int i = 0; i < vectorCount; i++ ) {

        double wavelength = -1.0;
        is.read( reinterpret_cast<char*>( &wavelength ), sizeof( double ) );

        StokesVector stokes;
        parseSV( is, stokes );

        specvec.push_back( SpectralData( wavelength, stokes ) );
    }
}
int main( int argc, char* argv ) {

    // Name of query output data file
    std::string dataFilename = "queryoutput";

    // Number of queries we are parsing data for
    const int numQueries = 2;

    // Open binary data file
    std::ifstream is( dataFilename.c_str(), std::ios::in | std::ios::binary );
    if ( !is ) {
        std::cerr << "Error: unable to open query result file" << std::endl;
        return 1;
    }

    // Drive through each query result
    for ( int i = 0; i < numQueries; i++ ) {

        // Parse query info
        SpectralVector pathRadiance;
        parseSpecVecSV( is, pathRadiance );

        // Pretty print query info
        std::cout << "Query # " << (i+1) << std::endl;
        for ( int l = 0; l < pathRadiance.size(); l++ ) {
            // dump wavelength
            std::cout << "  [" << pathRadiance.at(l).first << "] ";

            // dump stokes
            for ( int stokesIdx = 0;
                  stokesIdx < pathRadiance.at(l).second.size();
                  stokesIdx++ ) {
                std::cout << pathRadiance.at(l).second.at(stokesIdx) << " ";
            }
            std::cout << std::endl;
        }
        std::cout << std::endl;
    }

    return 0;
}

Assuming that the assumptions about endianness and type sizes are correct for the platform this program is compiled on, the following output will result:

Query # 1
  [0.3] 0.0236427
  [0.4] 0.0235044
  [0.5] 0.00549655

Query # 2
  [0.3] 0.0236427
  [0.4] 0.0234982
  [0.5] 0.0051655

It is possible to verify these results by rerunning the queries using the "plain" output format in the collector configuration file.

Matlab Binary Reader Example

The following example Matlab code will read a radiance Spectral Vector. Note that the fopen() call supplies the 'ieee-be' value for the optional machinefmt parameter, which says to assume the input file is in Big Endian. This will allows the values to be automatically converted to the native endian during the read.

% open the input file as read-only and big endian order
fid = fopen(fname,'r','ieee-be');

% read the number of bands (values) in the spectral radiance vector
numBands = fread(fid,1,'int32');

% create storage for the spectral locations (wavelengths) and data values
specVec = zeros(numBands,1);
dataVec = zeros(numBands,1);

% read in each spectral value one at a time
for f = 1:numBands

    % read the spectral location (wavelength)
    specVec(f) = fread(fid,1,'double');

    % read the polarization flag
    polarInfo = fread(fid,1,'int8');

    % we are expecting unpolarized data, so make sure that is true
    if(polarInfo~=0)
        error('Polarized Vector')
    else
        % read in the spectral value
        dataVec(f) = fread(fid,1,'double');
    end
end

% close the file
fclose(fid);

This tutorial has demonstrated that it is possible to bypass much of the traditional DIRSIG "front-end" by using Interactive Mode. The binary output allows for high performance interaction with the model. For many cases the XML output of Interactive Mode is preferable because it is easier to debug and robust XML parsers are available for almost all major programming languages.