File failed to load: https://isis.astrogeology.usgs.gov/9.0.0/Object/assets/jax/output/NativeMML/config.js
Isis 3 Programmer Reference
MdisCamera.cpp
1
6
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include <cmath>
10
11#include <QString>
12#include <QVariant>
13
14#include "MdisCamera.h"
15#include "TaylorCameraDistortionMap.h"
16
17#include "CameraDetectorMap.h"
18#include "CameraDistortionMap.h"
19#include "CameraFocalPlaneMap.h"
20#include "CameraGroundMap.h"
21#include "CameraSkyMap.h"
22#include "IException.h"
23#include "IString.h"
24#include "iTime.h"
25#include "NaifStatus.h"
26
27using namespace std;
28
29namespace Isis {
51 m_spacecraftNameLong = "Messenger";
52 m_spacecraftNameShort = "Messenger";
53
55
56 // Set up detector constants
57 // Note that Wac has filters, -236800 through -236812
58 // http://naif.jpl.nasa.gov/pub/naif/pds/data/mess-e_v_h-spice-6-v1.0/messsp_1000/data/ik/msgr_mdis_v160.ti
59 const int MdisWac(-236800);
60 const int MdisNac(-236820);
61
62 if (naifIkCode() == MdisNac) {
63 m_instrumentNameLong = "Mercury Dual Imaging System Narrow Angle Camera";
64 m_instrumentNameShort = "MDIS-NAC";
65 }
66 else if (naifIkCode() <= MdisWac && naifIkCode() >= -236812) {
67 m_instrumentNameLong = "Mercury Dual Imaging System Wide Angle Camera";
68 m_instrumentNameShort = "MDIS-WAC";
69 }
70 else {
71 QString msg = QString::number(naifIkCode());
72 msg += " is not a supported instrument kernel code for Messenger.";
73 throw IException(IException::Programmer, msg, _FILEINFO_);
74 }
75
76 Pvl &lab = *cube.label();
77 PvlGroup &inst = lab.findGroup("Instrument", Pvl::Traverse);
78
79 // Clarification on MDIS subframe image mode provides us the ability to
80 // support this mode now. The entire MDIS frame is geometrically valid
81 // but only portions of the full frame actually contain image data. The
82 // portions outside subframes should be NULL and not interfere in
83 // downstream processing, such as mosaics.
84#if defined(MDIS_SUBFRAMES_UNSUPPORTED)
85 int subFrameMode = inst["SubFrameMode"];
86 if(subFrameMode != 0) {
87 string msg = "Subframe imaging mode is not supported!";
88 throw iException::Message(iException::User, msg, _FILEINFO_);
89 }
90#endif
91
92 // According to the MDIS team, this is nothing to be concerned with and
93 // should be treated as other normal observations. So the test to
94 // disallow it has been effectively removed 2007-09-05 (KJB).
95#if defined(MDIS_JAILBARS_UNSUPPORTED)
96 int jailBars = inst["JailBars"];
97 if(jailBars != 0) {
98 string msg = "Jail bar observations are not currently supported!";
99 throw iException::Message(iException::Programmer, msg, _FILEINFO_);
100 }
101#endif
102
103 // Determine filter number. Only conditional code required for
104 // NAC and WAC support!
105 int filterNumber(0); // Default appropriate for MDIS-NAC
106 if(naifIkCode() == MdisWac) {
107 PvlGroup &bandBin = lab.findGroup("BandBin", Pvl::Traverse);
108 filterNumber = bandBin["Number"];
109 }
110
111 // Set up instrument and filter code strings
112 QString ikCode = toString(naifIkCode());
113 int fnCode(naifIkCode() - filterNumber);
114 QString filterCode = toString(fnCode);
115 QString ikernKey;
116
117 // Fetch the frame translations from the instrument kernels
118 ikernKey = "INS" + ikCode + "_REFERENCE_FRAME";
119 QString baseFrame = getString(ikernKey);
120
121 ikernKey = "INS" + filterCode + "_FRAME";
122 QString ikFrame = getString(ikernKey);
123
124 // Set up the camera info from ik/iak kernels
125
126 // Turns out (2008-01-17) the WAC has different focal lengths for
127 // each filter. Added to the instrument kernel (IAK) on this date.
128 // Add temperature dependant focal length
129 SetFocalLength(computeFocalLength(filterCode, lab));
130
132
133 // Removed by Jeff Anderson. The refactor of the SPICE class
134 // uses frames always so this is no longer needed
135 // LoadFrameMounting(baseFrame, ikFrame, false);
136
137 // Get the start time from labels as the starting image time plus half
138 // the exposure duration (in <MS>) to get pointing attitude.
139 // !!NOTE: The ephemeris time MUST be set prior to creating the
140 // cache (CreateCache) because the kernels are all unloaded
141 // after the cache is done and this operation will fail!!
142 QString stime = inst["SpacecraftClockCount"];
143 double exposureDuration = ((double) inst["ExposureDuration"]) / 1000.0;// divide by 1000 to convert to seconds
144
145 iTime etStart = getClockTime(stime);
146
147 // Setup camera detector map
148 CameraDetectorMap *detMap = new CameraDetectorMap(this);
149
150 // Setup focal plane map, and detector origin for the instrument that
151 // may have a filter (WAC only!).
152 CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this, fnCode);
153
154 // Retrieve boresight location from instrument kernel (IK) (addendum?)
155 ikernKey = "INS" + ikCode + "_BORESIGHT_SAMPLE";
156 double sampleBoreSight = getDouble(ikernKey);
157
158 ikernKey = "INS" + ikCode + "_BORESIGHT_LINE";
159 double lineBoreSight = getDouble(ikernKey);
160
161 // Apply the boresight
162 focalMap->SetDetectorOrigin(sampleBoreSight, lineBoreSight);
163
164 // Determine summing. MDIS has two sources of summing or binning.
165 // One is performed in the FPU and the in the MP, post-observation,
166 // on-board after coming out of the FPGAs, where the FPU binning is
167 // performed. The FPU binning was programmed incorrectly and the
168 // actual pixels from the detector are peculiar. Hence, I have
169 // designed this camera model such that the offsets can be managed
170 // external to the code. See the MDIS instrument kernel addendum
171 // in $ISISDATA/messenger/kernels/iak/mdisAddendum???.ti for the
172 // offsets for *each* detector. Note that an offset is only applied
173 // when FPU binning is performed.
174 int fpuBinMode = inst["FpuBinningMode"];
175 int pixelBinMode = inst["PixelBinningMode"];
176
177 int summing = ((pixelBinMode == 0) ? 1 : pixelBinMode);
178 // FPU binning was performed, retrieve the FPU binning offsets and
179 // apply them to the focal plane mapping.
180 if(fpuBinMode == 1) {
181#if defined(USE_FPU_BINNING_OFFSETS)
182 ikernKey = "INS" + ikCode + "_FPUBIN_START_SAMPLE";
183 double fpuStartingSample = getDouble(ikernKey);
184 detMap->SetStartingDetectorSample(fpuStartingSample);
185
186 ikernKey = "INS" + ikCode + "_FPUBIN_START_LINE";
187 double fpuStartingLine = getDouble(ikernKey);
188 detMap->SetStartingDetectorLine(fpuStartingLine);
189#endif
190 summing *= 2;
191 }
192
193 // Set summing/binning modes as an accumulation of FPU and MP binning.
194 detMap->SetDetectorLineSumming(summing);
195 detMap->SetDetectorSampleSumming(summing);
196
197 // Setup distortion map. As of 2007/12/06, we now have an actual model.
198 // Note that this model supports distinct distortion for each WAC filter.
199 // See $ISISDATA/messenger/kernels/iak/mdisAddendumXXX.ti or possibly
200 // $ISISDATA/messenger/kernels/ik/msgr_mdis_vXXX.ti for the *_OD_K
201 // parameters.
202 // NAC has a new implementation of its distortion contributed by
203 // Scott Turner and Lillian Nguyen at JHUAPL.
204 // (2010/10/06) The WAC now uses the same disortion model implementation.
205 // Valid Taylor Series parameters are in versions msgr_mdis_v120.ti IK
206 // and above. Note fnCode works for NAC as well as long as
207 // filterNumber stays at 0 for the NAC only!
208 try {
209 TaylorCameraDistortionMap *distortionMap = new TaylorCameraDistortionMap(this);
210 distortionMap->SetDistortion(fnCode);
211 }
212 catch(IException &ie) {
213 string msg = "New MDIS NAC/WAC distortion models will invalidate previous "
214 "SPICE - you may need to rerun spiceinit to get new kernels";
215 throw IException(ie, IException::User, msg, _FILEINFO_);
216 }
217
218 // Setup the ground and sky map
219 new CameraGroundMap(this);
220 new CameraSkyMap(this);
221
222 // Create a cache and grab spice info since it does not change for
223 // a framing camera (fixed spacecraft position and pointing) after,
224 // of course applying the gimble offset which is handled in the SPICE
225 // kernels (thank you!). Note this was done automagically in the
226 // SetEpheremisTime call above. IMPORTANT that it be done prior to
227 // creating the cache since all kernels are unloaded, essentially
228 // clearing the pool and whacking the frames definitions, required to
229 iTime centerTime = etStart + (exposureDuration / 2.0);
230 setTime(centerTime);
231 LoadCache();
233 }
234
235
261
262
292 double MdisCamera::computeFocalLength(const QString &filterCode,
293 Pvl &label) {
294
295 double focalLength(0.0);
296 QString tdflKey("TempDependentFocalLength");
297
298 // Determine if the desired value is already computed. We are interested
299 // in the temperature dependent value firstly. Backward compatibility is
300 // considered below.
301 QVariant my_tdfl = readStoredValue(tdflKey, SpiceStringType, 0);
302 if (my_tdfl.isValid()) {
303 focalLength = IString(my_tdfl.toString()).ToDouble();
304 }
305 else {
306 // Hasn't been computed yet (in spiceinit now - maybe) or the proper
307 // IK containing polynomial parameters is not in use.
308
309 // Original Code ensures backward compatibility
310 focalLength = getDouble("INS" + filterCode + "_FOCAL_LENGTH");
311
312 // Check for disabling of temperature dependent focal length
313 bool tdfl_disabled(false);
314#ifndef DISABLE_TDFL_DISABLING
315 try {
316 IString tdfl_state = getString("DISABLE_MDIS_TD_FOCAL_LENGTH");
317 tdfl_disabled = ( "TRUE" == tdfl_state.UpCase() );
318 }
319 catch (IException &ie) {
320 tdfl_disabled = false;
321 }
322#endif
323
324 // Attempt to retrieve parameters necessary for temperature-dependent focal
325 // length and computed it
326 if ( !tdfl_disabled ) {
327 // Wrap a try clause all around this so that if it fails, will return
328 // default
329 try {
330 PvlGroup &inst = label.findGroup("Instrument", Pvl::Traverse);
331 double fpTemp = inst["FocalPlaneTemperature"];
332 double fl(0.0);
333 QString fptCoeffs = "INS" + filterCode + "_FL_TEMP_COEFFS";
334 // Compute 5th order polynomial
335 for (int i = 0 ; i < 6 ; i++) {
336 fl += getDouble(fptCoeffs, i) * pow(fpTemp, (double) i);
337 }
338
339 // Store computed focal length
340 focalLength = fl;
341 storeValue(tdflKey, 0, SpiceStringType, QVariant(focalLength));
342 }
343 catch (IException &ie) {
344 // Noop when supporting old IKs
346 "Failed to compute temperature-dependent focal length",
347 _FILEINFO_);
348 }
349 }
350 }
351 return (focalLength);
352 }
353}
354
363extern "C" Isis::Camera *MdisCameraPlugin(Isis::Cube &cube) {
364 return new Isis::MdisCamera(cube);
365}
Convert between parent image coordinates and detector coordinates.
void SetDetectorLineSumming(const double summing)
Set line summing mode.
void SetStartingDetectorSample(const double sample)
Set the starting detector sample.
void SetStartingDetectorLine(const double line)
Set the starting detector line.
void SetDetectorSampleSumming(const double summing)
Set sample summing mode.
Convert between distorted focal plane and detector coordinates.
void SetDetectorOrigin(const double sample, const double line)
Set the detector origin.
Convert between undistorted focal plane and ground coordinates.
QString m_spacecraftNameLong
Full spacecraft name.
Definition Camera.h:499
virtual double exposureDuration() const
Return the exposure duration for the pixel that the camera is set to.
Definition Camera.cpp:3093
void SetFocalLength()
Reads the focal length from the instrument kernel.
Definition Camera.cpp:1422
void SetPixelPitch()
Reads the Pixel Pitch from the instrument kernel.
Definition Camera.cpp:1429
void LoadCache()
This loads the spice cache big enough for this image.
Definition Camera.cpp:2450
QString m_instrumentNameShort
Shortened instrument name.
Definition Camera.h:498
QString m_spacecraftNameShort
Shortened spacecraft name.
Definition Camera.h:500
QString m_instrumentNameLong
Full instrument name.
Definition Camera.h:497
Convert between undistorted focal plane and ra/dec coordinates.
IO Handler for Isis Cubes.
Definition Cube.h:168
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition Cube.cpp:1734
FramingCamera(Cube &cube)
Constructs the FramingCamera object.
virtual std::pair< iTime, iTime > ShutterOpenCloseTimes(double time, double exposureDuration)=0
Returns the shutter open and close times.
Isis exception class.
Definition IException.h:91
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
Adds specific functionality to C++ strings.
Definition IString.h:165
IString UpCase()
Converst any lower case characters in the object IString with uppercase characters.
Definition IString.cpp:617
double ToDouble() const
Returns the floating point value the IString represents.
Definition IString.cpp:799
MESSENGER MDIS NAC and WAC Camera Model.
Definition MdisCamera.h:97
virtual std::pair< iTime, iTime > ShutterOpenCloseTimes(double time, double exposureDuration)
Returns the shutter open and close times.
MdisCamera(Cube &cube)
Initialize the MDIS camera model for NAC and WAC.
double computeFocalLength(const QString &filterCode, Pvl &label)
Computes temperature-dependent focal length.
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
Contains multiple PvlContainers.
Definition PvlGroup.h:41
Container for cube-like labels.
Definition Pvl.h:119
@ Traverse
Search child objects.
Definition PvlObject.h:158
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition PvlObject.h:129
void setTime(const iTime &time)
By setting the time you essential set the position of the spacecraft and body as indicated in the cla...
Definition Sensor.cpp:99
QString getString(const QString &key, int index=0)
This returns a value from the NAIF text pool.
Definition Spice.cpp:1273
virtual iTime getClockTime(QString clockValue, int sclkCode=-1, bool clockTicks=false)
This converts the spacecraft clock ticks value (clockValue) to an iTime.
Definition Spice.cpp:1060
@ SpiceStringType
SpiceString type.
Definition Spice.h:350
virtual iTime time() const
Returns the ephemeris time in seconds which was used to obtain the spacecraft and sun positions.
Definition Spice.cpp:891
SpiceInt naifIkCode() const
This returns the NAIF IK code to use when reading from instrument kernels.
Definition Spice.cpp:975
SpiceDouble getDouble(const QString &key, int index=0)
This returns a value from the NAIF text pool.
Definition Spice.cpp:1046
Distort/undistort focal plane coordinates.
void SetDistortion(const int naifIkCode)
Load distortion coefficients.
Parse and return pieces of a time string.
Definition iTime.h:65
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
Namespace for the standard library.