DOI-USGS / DOI-USGS/ISIS3

PSMRTS Integrating into ISIS ShapeModel System

Open
#6,089 0 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
C++
Stars
245
Forks
181
Avg merge
1d 22h
Merged PRs (30d)
15

Description

# Description
The Planetary Shape Model Ray Tracing System
([PSMRTS](https://github.com/UA-LPL/psmrts)) system introduces new capabilities
into the ISIS system. Its primary enhancement is a priority tracing system
whereby more than one shape model may be added to a list of ray tracers that is
evaluated for each trace. The initial priority is the order in which they are
specified in the ShapeModel keyword or in a *.txt or *.lis file which are all
new features supported by PSMRTS. PSMRTS currently applies ray traces on
facet-based shape models. PSMRTS can read NAIF DSK kernels (BDS), OBJ and PLY
formatted files. Users can also directly specify ellipsoids, spheroids and
spheres using 3, 2 or 1 radii, respectively. A forthcoming PR integrates PSMRTS
into the ISIS system.

PSMRTS shape models are evaluated first in the `Isis::ShapeModelFactory` as it has
certain format characteristics that are unique. This allows for implicit selection
of the PsmrtsShapeModel priority shape model. Pre-existing ISIS behavior of
instantiating shape models is preserved (confirmed via tests). The following
conditions will result in the creation of a PSMRTS priority shape model:

- More than one shape model file is contained in the ShapeModel keyword
- A file with extension of *.lis, *.txt or *.conf are contained in
the ShapeModel keyword (via the **spiceinit** MODEL parameter).
- An explicit request to use PSMRTS is specified in the RayTraceEngine
keyword either in the label or specified in the IsisPreferences file in the
ShapeModel group (*RayTraceEngine = psmrts*).
- Shape model file names with a prefix of the form "bullet::", "naifdsk::",
"ellipsoid::", "spheroid::" or "sphere::".

In addition, a reference ellipsoid is created from the radii contain in the
Target parameter and maintained separately in the PSMRTS system. In the PSMRTS
system, both a PSMRTS priority ray trace and a reference ellipsoid ray trace are
executed for every requested ISIS shape model trace to eliminate ambiguity and
provide data for both ray traces for every requested shape model intercept.

For the case of files with the extension "txt" or "lis", the contents are
expected to contain a shape model file of the supported type, one per line. They
can have a recognized PSMRTS prefix as well. These files may contain comments
in lines that start with "#" and are ignored.

A file with the extension "conf" is a PVL formatted file that contains a
`ShapeModel` keyword, with other PSMRTS based options, such as `Tolerance` and
`RayTraceEngine` and others that may vary over time. To explicitly use
PSMRTS, the *RayTraceEngine = psmrts* must exist in the CONF file. See the
PSMRTS documentation for available options. Use of PSMRTS is implied if
more than one file exists in the `ShapeModel` keyword regardless of other
parameters configurations.

Several options/formats of individual shape model file specifications is
supported. Each file can have the extended formatted form:

```
tracer::$envpath/kernels/dsk/shape.ext
```
where
- _tracer_ is one of "bullet", "naifdsk", "ellipsoid", "spheroid", or "sphere";
- _envpath_ preceded with a $ is an environment variable or parameter from the ISIS `DataDirectory` group in the `IsisPreferences` file;
- followed by the remainder of the full path and the file extension, _ext_, of "bds",
"obj" or "ply".

In the case of the ellipsoid formats, after the "::", 1, 2 or 3 double values separated
by commas are expected. This value will look like
_ellipsoid::0.283065,0.271215,0.249720_.

The **spiceinit** application is used to specify shape model configurations. The
filenames may contain environment variables and/or ISIS `DataDirectory` entries, as
contained in the `IsisPreferences` file. These entries begin with a "$", that typically
specify a file path to the root directory of a specific mission directory
structure containing SPICE kernels and calibration files.

Shape models can also be provided in the `ShapeModel` configuration group within
an `IsisPreferences` file ending in a "conf" file extension. This file format
follows a PVL structure similar to an ISIS cube label that contains a `Kernel`
group and a `ShapeModel` keyword. The main advantage of this format is
additional parameterization keywords can be included that can alter PSMRTS (and
some ISIS tracer models) behavior using configuration construction features. As
long as it follows basic PVL formatting, the content can vary. The following
keywords are relevant to files with an `IsisPreferences` ".conf" (or `-pref`
parameter) format:

- **RayTraceEngine** - Explicit selection of a tracer engine such as PSMRTS, bullet,
embree or naifdsk.
- **Tolerance** - A double value in units of kilometers that specify the maximum
distance between a surface ray intercept of an observer and the light source,
typically the sun, that determines if a surface intercept point is occluded by
foreground terrain. Default: 1.0e-6.
- **PsmrtsDebug** - When detected in the PsmrtsShapeModel, it will print out the
configuration of the priority tracer for each shape model in JSON format.
- **OnError** - When _OnError = Continue_, all other shape models are attempted to
instantiate if an error occurs in previous attempts, otherwise, an error
aborts the **spiceinit** application.

An `IsisPreferences` file with just _PsmrtsDebug = true_ can be useful show the full
PSMRTS tracer configuration and show that the PSMRTS tracer was actually
created.

## PSMRTS Resource Use
Note that PSMRTS will reuse existing shapes and tracers if configurations (or
file name specifications in the ISIS environment) are compatible with
previously used files in the process. **NOTE:** The ISIS Bullet and NAIF tracers
do not reuse resources and will read and create new instances of these tracers.
This behavior will use significant resources and require very long runtimes if
you do not run out of memory first, particularly using the ISIS Bullet tracer.
PSMRTS prevents these issues.

PSMRTS was carefully designed with threading in mind. Many of the operations
including traces are thread-safe.

At any point during a processing run, you can manage resources using
[PsmrtsFactory](https://github.com/UA-LPL/psmrts/blob/main/psmrts/core/PsmrtsFactory.hpp).

Removing existing tracers will result in a new version being created and cached
in the factory.

**NOTE:** If PSMRTS is selected but does not contain a specific tracer prefix,
the PSMRTS::Bullet tracer is selected since it will accept all file formats.

Also, be cautious when using PLY formatted files, as they tend to be
created/stored in single precision floating point format. NAIF DSKs and OBJ
files all default to double precision XYZ values when read from the file.

# Examples

The follow provides examples of how to use the PSMRTS/ISIS system when running
**spiceinit**, which writes the shape model configuration to the ISIS label.
When PSMRTS is selected during **spiceinit**, the keyword/value of
_RayTraceEngine = psmrts_ will be present in the `Kernels` group of the labels.
This will ensure that all subsequent runs of ISIS applications will use the
PSMRTS shape model for instrument to ground, and vice versa, ISIS ray trace
intercept requests.

For these examples, the "${base}" parameter is set to an OREX image cube,
20190328T200344S309_pol_iofL2pan.cub.

### Example: ISIS/NAIF DSK tracer
Default behavior selects the ISIS DskShapeModel and needs no preferences file.
Its "bds" file extension will always use the ISIS NAIF DSK ray tracer by default.
```
spiceinit from="${base}.cub" \
shape=user \
model='$osirisrex/kernels/dsk/bennu_g_00880mm_alt_obj_0000n00000_v021a.bds'

Group = Kernels
NaifFrameCode = -64360
LeapSecond = $base/kernels/lsk/naif0012.tls
TargetAttitudeShape = $osirisrex/kernels/pck/bennu_v17.tpc
TargetPosition = ($osirisrex/kernels/tspk/de424.bsp,
$osirisrex/kernels/tspk/bennu_refdrmc_v1.bsp,
$osirisrex/kernels/tspk/sb-101955-76.bsp,
$osirisrex/kernels/pck/pck00010.tpc)
InstrumentPointing = ($osirisrex/kernels/ck/orx_sc_rel_190325_190331-
_v02.bc, $osirisrex/kernels/fk/orx_v14.tf)
Instrument = ($osirisrex/kernels/ik/orx_ocams_v07.ti,
$osirisrex/kernels/fk/orx_struct_polycam_v01.bc)
SpacecraftClock = $osirisrex/kernels/sclk/orx_sclkscet_00093.tsc
InstrumentPosition = $osirisrex/kernels/spk/orx_190301_190424_190412-
_od125_v1.bsp
InstrumentAddendum = $osirisrex/kernels/iak/orex_ocams_addendum_v12.-
ti
ShapeModel = $osirisrex/kernels/dsk/bennu_g_00880mm_alt_obj_-
0000n00000_v021a.bds
InstrumentPositionQuality = Reconstructed
InstrumentPointingQuality = Reconstructed
CameraVersion = 2
Source = isis
End_Group

```

### Example: ISIS/Bullet tracer
To use the ISIS Bullet ray tracer, you must provide an ISIS preferences file
that has _RayTraceEngine = bullet_. Here is the contents of the
BulletEngineSelect.pref file used in the **spiceinit** command.

#### File: BulletEngineSelect.pref
```
Group = ShapeModel
RayTraceEngine = bullet
OnError = Continue
EndGroup

End
```

To select the ISIS Bullet tracer:
```
spiceinit from="${base}.cub" \
shape=user \
model='$osirisrex/kernels/dsk/bennu_g_00880mm_alt_obj_0000n00000_v021a.bds' \
-pref=BulletEngineSelect.pref

Group = Kernels
NaifFrameCode = -64360
LeapSecond = $base/kernels/lsk/naif0012.tls
TargetAttitudeShape = $osirisrex/kernels/pck/bennu_v17.tpc
TargetPosition = ($osirisrex/kernels/tspk/de424.bsp,
$osirisrex/kernels/tspk/bennu_refdrmc_v1.bsp,
$osirisrex/kernels/tspk/sb-101955-76.bsp,
$osirisrex/kernels/pck/pck00010.tpc)
InstrumentPointing = ($osirisrex/kernels/ck/orx_sc_rel_190325_190331-
_v02.bc, $osirisrex/kernels/fk/orx_v14.tf)
Instrument = ($osirisrex/kernels/ik/orx_ocams_v07.ti,
$osirisrex/kernels/fk/orx_struct_polycam_v01.bc)
SpacecraftClock = $osirisrex/kernels/sclk/orx_sclkscet_00093.tsc
InstrumentPosition = $osirisrex/kernels/spk/orx_190301_190424_190412-
_od125_v1.bsp
InstrumentAddendum = $osirisrex/kernels/iak/orex_ocams_addendum_v12.-
ti
ShapeModel = $osirisrex/kernels/dsk/bennu_g_00880mm_alt_obj_-
0000n00000_v021a.bds
InstrumentPositionQuality = Reconstructed
InstrumentPointingQuality = Reconstructed
CameraVersion = 2
RayTraceEngine = bullet
OnError = continue
Tolerance = 1.79769313486232e+308
Source = isis
End_Group

```

### Example: PSMRTS/Bullet tracer
Note the only requirement is use of a special prefix **bullet::** in the file
name specified in the **spiceinit** _MODEL_ parameter. You can also specify an
ISIS preferences file with the following contents to ensure PSMRTS is selected:

#### File: PsmrtsEngineSelect.pref
```
Group = ShapeModel
RayTraceEngine = psmrts
OnError = Continue
EndGroup

End
```

Selects PSMRTS Bullet ray trace engine without need for preferences file.
```
spiceinit from="${base}.cub" \
shape=user \
model='bullet::$osirisrex/kernels/dsk/bennu_g_00880mm_alt_obj_0000n00000_v021a.bds'

Group = Kernels
NaifFrameCode = -64360
LeapSecond = $base/kernels/lsk/naif0012.tls
TargetAttitudeShape = $osirisrex/kernels/pck/bennu_v17.tpc
TargetPosition = ($osirisrex/kernels/tspk/de424.bsp,
$osirisrex/kernels/tspk/bennu_refdrmc_v1.bsp,
$osirisrex/kernels/tspk/sb-101955-76.bsp,
$osirisrex/kernels/pck/pck00010.tpc)
InstrumentPointing = ($osirisrex/kernels/ck/orx_sc_rel_190325_190331-
_v02.bc, $osirisrex/kernels/fk/orx_v14.tf)
Instrument = ($osirisrex/kernels/ik/orx_ocams_v07.ti,
$osirisrex/kernels/fk/orx_struct_polycam_v01.bc)
SpacecraftClock = $osirisrex/kernels/sclk/orx_sclkscet_00093.tsc
InstrumentPosition = $osirisrex/kernels/spk/orx_190301_190424_190412-
_od125_v1.bsp
InstrumentAddendum = $osirisrex/kernels/iak/orex_ocams_addendum_v12.-
ti
ShapeModel = bullet::$osirisrex/kernels/dsk/bennu_g_00880mm_-
alt_obj_0000n00000_v021a.bds
InstrumentPositionQuality = Reconstructed
InstrumentPointingQuality = Reconstructed
CameraVersion = 2
RayTraceEngine = psmrts
Source = isis
End_Group

```

### Example: ISIS/NAIF DSK tracer
This example selects the PSMRTS NaifDsk ray tracer. It does not need an ISIS
preferences file but you can provide the same _PsmrtsEngineSelect.pref_ used in
the PSMRTS Bullet example above.
```
spiceinit from="${base}.cub" \
shape=user \
model='naifdsk::$osirisrex/kernels/dsk/bennu_g_00880mm_alt_obj_0000n00000_v021a.bds'

Group = Kernels
NaifFrameCode = -64360
LeapSecond = $base/kernels/lsk/naif0012.tls
TargetAttitudeShape = $osirisrex/kernels/pck/bennu_v17.tpc
TargetPosition = ($osirisrex/kernels/tspk/de424.bsp,
$osirisrex/kernels/tspk/bennu_refdrmc_v1.bsp,
$osirisrex/kernels/tspk/sb-101955-76.bsp,
$osirisrex/kernels/pck/pck00010.tpc)
InstrumentPointing = ($osirisrex/kernels/ck/orx_sc_rel_190325_190331-
_v02.bc, $osirisrex/kernels/fk/orx_v14.tf)
Instrument = ($osirisrex/kernels/ik/orx_ocams_v07.ti,
$osirisrex/kernels/fk/orx_struct_polycam_v01.bc)
SpacecraftClock = $osirisrex/kernels/sclk/orx_sclkscet_00093.tsc
InstrumentPosition = $osirisrex/kernels/spk/orx_190301_190424_190412-
_od125_v1.bsp
InstrumentAddendum = $osirisrex/kernels/iak/orex_ocams_addendum_v12.-
ti
ShapeModel = naifdsk::$osirisrex/kernels/dsk/bennu_g_00880mm-
_alt_obj_0000n00000_v021a.bds
InstrumentPositionQuality = Reconstructed
InstrumentPointingQuality = Reconstructed
CameraVersion = 2
RayTraceEngine = psmrts
Source = isis
End_Group
```

## PSMRTS Support for Regional Shape Models
A PSMRTS design goal was to provide use of more that one shape model for a given
image ray tracer instance. This feature is implemented using the
[PsmrtsTracerSystem](https://github.com/UA-LPL/psmrts/blob/main/psmrts/tracers/PsmrtsTracerSystem.hpp).
This class was designed for use in ISIS and directly emulates and addresses ISIS
processing requirements. It is the main PSMRTS class used to implement the ISIS
**PsmrtsShapeModel** class that inherits Isis::ShapeModel.

### Why ISIS Requires Global Shape Model Coverage
The main reason ISIS requires global shape model coverage is because traces of
_special_ target body locations are commonly run during ISIS geometric
operations. Examples of these locations are north and south poles, sub-solar
and sub-spacecraft latitude/longitudes, and 0 and, 180 and 360 longitude
boundaries. In regional shape model cases, an additional shape model is required
to accomdate these operations or odd and unpredictable failures occur.

ISIS does not function properly when using regional shape models. We discovered
this issue when using high resolution shape models for OSIRIS-REx Touch-And-Go
(TAG) observations. These models have an average ground sampling distance (GSD)
of 5cm per facet. One shape model of the TAG are is about 3.5 million facets -
nearly equivalent to one 88cm GSD model. To use the global 5cm GSD shape model
data set would require multiple shape models, some up to 8 or more different
models from 1km observation distances.

### Example: Multiple Tracers in Regional DEMs
In cases like this, we recommend predetermined shape model lists where the
priority is set to use hires 5cm models with PSMRTS::Bullet and then use
PSMRTS::NaifDsk with a global model, such as the 88cm GSD. Here is the format
for the TAG site PSMRTS shape model configuration:

#### File: nightingale_regional_dems.lis
```
bullet::$osirisrex/kernels/dsk/bennu_l_00050mm_alt_dtm_5094s33170_v020.bds
naifdsk::$osirisrex/kernels/dsk/bennu_g_00880mm_alt_obj_0000n00000_v020.bds
```
This strategy considers the best use of system resources, particularly during
mapping operations as most of the intercepts will occur in the high resolution
5cm shape model.

**NOTE:** You could also choose to use the Bennu's PCK ellipsoid definition
rather than the global 88cm by **replacing** the NAIF DSK shape model with this
definition in the last line of `nightingale_regional_dems.lis`:
```
ellipsoid::0.283065,0.271215,0.249720
```

We will use a special ISIS preferences file to enable PSMRTS debugging
information. The contents of this file is:
#### File: PsmrtsDebug.pref
```
Group = ShapeModel
PsmrtsDebug = True
EndGroup
End
```

Run **spiceint** command to using this configuraton:
```
spiceinit from=20201020T212808S335_sam_iofL2pan5.cub \
shape=user \
model=nightingale_regional_dems.lis \
-pref=PsmrtsDebug.pref

ISIS/PSMRTS Constructor running...
PsmrtsShapeModel constructor done!
PsmrtsShapeModel::create() done!
FactoryShapeCount: 1
FactoryTracerCount: 2
TracerIds: 77 102
TracerUid: 77
Name: bullet::$osirisrex/kernels/dsk/bennu_l_00050mm_alt_dtm_5094s33170_v020.bds
Type: tracer
Model: bullet
Config: {"options":{"tracer":"bullet","file":"$osirisrex/kernels/dsk/bennu_l_00050mm_alt_dtm_5094s33170_v020.bds"},"metadata":{"file_expanded":"/opt/isis4/data/osirisrex/kernels/dsk/bennu_l_00050mm_alt_dtm_5094s33170_v020.bds","shape_uid":"71","tracer_uid":"77"}}
Tracer: bullet::$osirisrex/kernels/dsk/bennu_l_00050mm_alt_dtm_5094s33170_v020.bds
TracerUid: 102
Name: $osirisrex/kernels/dsk/bennu_g_00880mm_alt_obj_0000n00000_v020.bds
Type: tracer
Model: naifdsk
Config: {"options":{"dsk_file":"$osirisrex/kernels/dsk/bennu_g_00880mm_alt_obj_0000n00000_v020.bds","tracer":"naifdsk"},"metadata":{"dsk_data_type":"double","dsk_segments":1,"dsk_segment_number":0,"dsk_segment_id":300880020,"n_vertices":1579014,"n_facets":3145728,"dsk_reference_id":2101955,"dsk_body_id":2101955,"dsk_surface_id":300880020,"dsk_frame_id":10106,"dsk_type":2,"dsk_class":2,"minimum_radius":0.21367820541135105,"maximum_radius":0.29146620522863514,"dsk_file_expanded":"/opt/isis4/data/osirisrex/kernels/dsk/bennu_g_00880mm_alt_obj_0000n00000_v020.bds","total_verticies":1579014,"total_facets":3145728,"shape_uid":"104","tracer_uid":"102"}}
Tracer: $osirisrex/kernels/dsk/bennu_g_00880mm_alt_obj_0000n00000_v020.bds
Group = Kernels
NaifFrameCode = -64362
LeapSecond = $base/kernels/lsk/naif0012.tls
TargetAttitudeShape = $osirisrex/kernels/pck/bennu_v17.tpc
TargetPosition = ($osirisrex/kernels/tspk/de424.bsp,
$osirisrex/kernels/tspk/bennu_refdrmc_v1.bsp,
$osirisrex/kernels/tspk/sb-101955-76.bsp,
$osirisrex/kernels/pck/pck00010.tpc)
InstrumentPointing = ($osirisrex/kernels/ck/orx_sc_rel_201019_201025-
_v01.bc, $osirisrex/kernels/fk/orx_v14.tf)
Instrument = $osirisrex/kernels/ik/orx_ocams_v07.ti
SpacecraftClock = $osirisrex/kernels/sclk/orx_sclkscet_00093.tsc
InstrumentPosition = $osirisrex/kernels/spk/orx_200827_201020_201020-
_od294_v1.bsp
InstrumentAddendum = $osirisrex/kernels/iak/orex_ocams_addendum_v12.-
ti
ShapeModel = (bullet::$osirisrex/kernels/dsk/bennu_l_00050mm-
_alt_dtm_5094s33170_v020.bds,
naifdsk::$osirisrex/kernels/dsk/bennu_g_00880mm-
_alt_obj_0000n00000_v020.bds)
InstrumentPositionQuality = Reconstructed
InstrumentPointingQuality = Reconstructed
CameraVersion = 2
RayTraceEngine = psmrts
Source = isis
End_Group
```

Note the use of the **PsmrtsDebug.pref**. This can be used for any command and
will result in additional information provided about the PSMRTS system resulting
from the shape model configuration. Also, the contents of the
`nightingale_regional_dems.lis` file are read and recorded directly in the
ShapeModel keyword. This, will ensure that any subsequent ISIS application will
load the same configuration. While the _PSMRTS::NaifDsk_ tracer shows a shape
UID, it is not stored in the factory for future reuse since its contents is not
loaded in memory - NAIF DSK toolkit is disk-bound I/O for ray tracing. However,
when _PSMRTS::Bullet_ uses a DSK, it has a separate UID and is stored for reuse
(independent of current tracers) in the PSMRTS system factory.

We further recommend that when using multiple shape models, they be prioritized
(in the text/list/ShapeModel keyword) by highest to lowest surface area coverage
of the shape models in the image field-of-view. This ensures the least number of
ray traces as PSMRTS applies a linear algorithm to find the tracer intercept
(using threads would require all tracers to be run to completion).

Contributor guide

Open the contributing guide

Research direction

Start at Isis::ShapeModelFactory and the spiceinit MODEL and RayTraceEngine entry points, then review PsmrtsShapeModel and PsmrtsFactory. Compare existing shape-model instantiation tests with the listed PSMRTS selection conditions; done means the described formats, priorities, reference ellipsoid, and resource reuse integrate without changing pre-existing behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
computer-graphics
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.