Isis 3 Programmer Reference
RosettaVirtisCamera.cpp
1 #include "RosettaVirtisCamera.h"
2 
3 #include <cctype>
4 #include <iostream>
5 #include <iomanip>
6 #include <sstream>
7 #include <algorithm>
8 
9 #include <QRegExp>
10 #include <QString>
11 
12 #include <tnt/tnt_array2d_utils.h>
13 
14 #include "Camera.h"
15 #include "CameraFocalPlaneMap.h"
16 #include "IException.h"
17 #include "IString.h"
18 #include "iTime.h"
19 #include "Kernels.h"
22 #include "LineScanCameraSkyMap.h"
23 #include "NaifStatus.h"
24 #include "NumericalApproximation.h"
25 
26 // #define DUMP_INFO 1
27 
28 using namespace std;
29 namespace Isis {
30  // constructors
37  RosettaVirtisCamera::RosettaVirtisCamera(Cube &cube) : LineScanCamera(cube) {
38 
39  m_instrumentNameLong = "Visual and Infrared Thermal Imaging Spectrometer";
40  m_instrumentNameShort = "VIRTIS";
41  m_spacecraftNameLong = "Rosetta";
42  m_spacecraftNameShort = "Rosetta";
43 
44  // cout << "Testing RosettaVirtisCamera...\n";
45 
46  Pvl &lab = *cube.label();
47 // PvlGroup &archive = lab.findGroup("Archive", Isis::Pvl::Traverse);
48  PvlGroup &inst = lab.findGroup("Instrument", Isis::Pvl::Traverse);
49 
50  QString instrumentId = inst["InstrumentId"];
51  if ( "virtis" != instrumentId.toLower()) {
52  QString mess = "This data is apparently not from the VIRTIS instrument but "
53  + instrumentId;
55  }
56 
57 
58  int procLevel = inst["ProcessingLevelId"];
59  m_is1BCalibrated = (procLevel > 2) ? true : false;
60 
61  // Get the start time from labels
62  QString channelId = inst["ChannelId"];
63 
64  QString instMode = inst["InstrumentModeId"];
65  m_slitMode = instMode[14].toLatin1(); // "F" for full slit, Q for quarter slit
66 
67 
68  // Check for presence of articulation kernel
69  bool hasArtCK = hasArticulationKernel(lab);
70 
71  // Set proper end frame
72  int virFrame(0);
73  QString frameId ("");
74  if (channelId == "VIRTIS_M_VIS") {
75  // Frame ROS_VIRTIS-M_VIS : ROS_VIRTIS-M_VIS_ZERO
76  virFrame = (hasArtCK) ? -226211 : -226112;
77  frameId = "ROS_VIRTIS-M_VIS";
78  }
79  else if (channelId == "VIRTIS_M_IR") {
80  // Frame ROS_VIRTIS-M_IR : ROS_VIRTIS-M_IR_ZERO
81  virFrame = (hasArtCK) ? -226213 : -226214;
82  frameId = "ROS_VIRTIS-M_IR";
83  }
84 
85  instrumentRotation()->SetFrame(virFrame);
86 
87  // We do not want to downsize the cache
89 
90  // Set up the camera info from ik/iak kernels
92  SetPixelPitch();
93 
94  // Get other info from labels
95  PvlKeyword &frameParam = inst["FrameParameter"];
96 
97  // convert milliseconds to seconds
98 
99  m_exposureTime = toDouble(frameParam[0]) * 0.001;
100  m_summing = toDouble(frameParam[1]);
101  m_scanRate = toDouble(frameParam[2]);
102 
103  // Setup detector map
104  // Get the line scan rates/times
105 
106  if (!m_is1BCalibrated) {
108  }
109  else {
110  readSCET(lab.fileName());
111  }
112 
115 
116  // Setup focal plane map
117  new CameraFocalPlaneMap(this, naifIkCode());
118  // Retrieve boresight location from instrument kernel (IK) (addendum?)
119  QString ikernKey = "INS" + toString(naifIkCode()) + "_BORESIGHT_SAMPLE";
120  double sampleBoreSight = getDouble(ikernKey);
121 
122  ikernKey = "INS" + toString(naifIkCode()) + "_BORESIGHT_LINE";
123  double lineBoreSight = getDouble(ikernKey);
124  FocalPlaneMap()->SetDetectorOrigin(sampleBoreSight, lineBoreSight);
125 
126  // Setup distortion map
127  new CameraDistortionMap(this);
128  // Setup the ground and sky map
129  new LineScanCameraGroundMap(this);
130  new LineScanCameraSkyMap(this);
131  // Set initial start time always (label start time is inaccurate)
132 
133  if (!m_is1BCalibrated){
134  setTime(iTime(startTime()));
135  }
136 
137  // Now check to determine if we have a cache already. If we have a cache
138  // table, we are beyond spiceinit and have already computed the proper
139  // point table from the housekeeping data or articulation kernel.
140  if (!instrumentRotation()->IsCached() && !hasArtCK && !m_is1BCalibrated) {
141  // Create new table here prior to creating normal caches
142  Table quats = getPointingTable(frameId, virFrame);
143 
144  // Create all system tables - all kernels closed after this
145  LoadCache();
146  instrumentRotation()->LoadCache(quats);
147  }
148  else {
149  LoadCache();
150  }
151 
152 #if defined(DUMP_INFO)
153  Table cache = instrumentRotation()->Cache("Loaded");
154  cout << "Total Records: " << cache.Records() << "\n";
155 
156  for (int i = 0 ; i < cache.Records() ; i++) {
157  TableRecord rec = cache[i];
158  string separator("");
159  for (int f = 0 ; f < rec.Fields() ; f++) {
160  cout << separator << (double) rec[f];
161  separator = ", ";
162  }
163  cout << "\n";
164  }
165 #endif
166  }
167 
172  }
173 
180  return (-226000);
181  }
182 
183 
190  return (1);
191  }
192 
193 
200  return (1);
201  }
202 
203 
210  return (m_summing);
211  }
212 
213 
220  return (m_exposureTime);
221  }
222 
223 
230  return (m_scanRate);
231  }
232 
233 
239  double RosettaVirtisCamera::lineStartTime(const double midExpTime) const {
240  return (midExpTime - (exposureTime() / 2.0));
241  }
242 
243 
249  double RosettaVirtisCamera::lineEndTime(const double midExpTime) const {
250  return (midExpTime+(exposureTime()/2.0));
251  }
252 
253 
260  return (lineStartTime(m_mirrorData[0].m_scanLineEt));
261  }
262 
263 
270  return (lineEndTime(m_mirrorData[hkLineCount()-1].m_scanLineEt));
271  }
272 
273 
280  return (m_mirrorData.size());
281  }
282 
283 
293  void RosettaVirtisCamera::readSCET(const QString &filename) {
294  // Open the ISIS table object
295  std::vector<double> cacheTime;
296  Table hktable("VIRTISHouseKeeping", filename);
297  m_lineRates.clear();
298  int lineno(1);
299  double lineEndTime = 0;
300  for (int i = 0; i < hktable.Records(); i++) {
301  TableRecord &trec = hktable[i];
302  QString scetString = trec["dataSCET"];
303  lineEndTime = getClockTime(scetString, naifSpkCode()).Et();
304  m_lineRates.push_back(LineRateChange(lineno,
306  exposureTime()));
307  cacheTime.push_back(lineEndTime-exposureTime());
308  lineno++;
309  }
310  cacheTime.push_back(lineEndTime);
311 
312  // Adjust the last time
313  LineRateChange lastR = m_lineRates.back();
314 
315  // Normally the line rate changes would store the line scan rate instead of exposure time.
316  // Storing the exposure time instead allows for better time calculations within a line.
317  // In order for the VariableLineScanCameraDetectorMap to work correctly with this change,
318  // every line in the cube must have a LineRateChange object. This is because determining
319  // the start time for one line based on another line requires the line scan rate. Having
320  // a LineRateChange for every line means never needing to calculate the start time for a line
321  // because the start time is stored in that line's LineRateChange. So, the detector map only
322  // calculates times within a given line.
323  // See VariableLineScanCameraDetectorMap::exposureDuration() for a description of the
324  // difference between exposure time and line scan rate.
325 
326  m_lineRates.back() = LineRateChange(lastR.GetStartLine(),
327  lastR.GetStartEt(),
328  exposureTime());
329 
330  instrumentRotation()->SetCacheTime(cacheTime);
331  }
332 
333 
348  void RosettaVirtisCamera::readHouseKeeping(const QString &filename,
349  double lineRate) {
350  // Open the ISIS table object
351  Table hktable("VIRTISHouseKeeping", filename);
352 
353  m_lineRates.clear();
354  int lineno(1);
355  NumericalApproximation angFit;
356  for (int i = 0; i < hktable.Records(); i++) {
357  TableRecord &trec = hktable[i];
358  double scet = (double) trec["dataSCET"];
359  int shutterMode = (int) trec["Data Type__Shutter state"];
360 
361  // Compute the optical mirror angle
362  double mirrorSin = trec["M_MIRROR_SIN_HK"];
363  double mirrorCos = trec["M_MIRROR_COS_HK"];
364  double scanElecDeg = atan(mirrorSin/mirrorCos) * dpr_c();
365  double optAng = ((scanElecDeg - 3.7996979) * 0.25/0.257812);
366  optAng /= 1000.0;
367 
368 
369  ScanMirrorInfo smInfo;
370  double lineMidTime;
371  // scs2e_c(naifSpkCode(), scet.c_str(), &lineMidTime);
372  lineMidTime = getClockTime(toString(scet), naifSpkCode()).Et();
373  bool isDark = (shutterMode == 1);
374 
375  // Add fit data for all open angles
376  if ( ! isDark ) { angFit.AddData(lineno, optAng); }
377 
378 #if defined(DUMP_INFO)
379  cout << "Line(" << ((isDark) ? "C): " : "O): ") << i
380  << ", OptAng(D): " << setprecision(12) << optAng * dpr_c()
381  << ", MidExpTime(ET): " << lineMidTime
382  << "\n";
383 #endif
384 
385  // Store line,
386  smInfo.m_lineNum = lineno;
387  smInfo.m_scanLineEt = lineMidTime;
388  smInfo.m_mirrorSin = mirrorSin;
389  smInfo.m_mirrorCos = mirrorCos;
390  smInfo.m_opticalAngle = optAng;
391  smInfo.m_isDarkCurrent = isDark;
392 
393  if ((!m_is1BCalibrated) || (!(m_is1BCalibrated && isDark))) {
394  m_lineRates.push_back(LineRateChange(lineno,
395  lineStartTime(lineMidTime),
396  exposureTime()));
397  m_mirrorData.push_back(smInfo);
398  lineno++;
399  }
400  }
401 
402  // Adjust the last time
403  LineRateChange lastR = m_lineRates.back();
404 
405  // Normally the line rate changes would store the line scan rate instead of exposure time.
406  // Storing the exposure time instead allows for better time calculations within a line.
407  // In order for the VariableLineScanCameraDetectorMap to work correctly with this change,
408  // every line in the cube must have a LineRateChange object. This is because determining
409  // the start time for one line based on another line requires the line scan rate. Having
410  // a LineRateChange for every line means never needing to calculate the start time for a line
411  // because the start time is stored in that line's LineRateChange. So, the detector map only
412  // calculates times within a given line.
413  // See VariableLineScanCameraDetectorMap::exposureDuration() for a description of the
414  // difference between exposure time and line scan rate.
415 
416  m_lineRates.back() = LineRateChange(lastR.GetStartLine(),
417  lastR.GetStartEt(),
418  exposureTime());
419 
420  // Run through replacing all closed optical angles with fitted data.
421  // These are mostly first/last lines so must set proper extrapolation
422  // option.
423  for (unsigned int a = 0 ; a < m_mirrorData.size() ; a++) {
424  if (m_mirrorData[a].m_isDarkCurrent) {
425  m_mirrorData[a].m_opticalAngle = angFit.Evaluate(a+1,
427  }
428  }
429 
430  // Gut check on housekeeping contents and cube lines
431  if ((int) m_lineRates.size() != Lines()) {
432  ostringstream mess;
433  mess << "Number housekeeping lines determined (" << m_lineRates.size()
434  << ") is not equal to image lines(" << Lines() << ")";
435  throw IException(IException::Programmer, mess.str(), _FILEINFO_);
436  }
437  }
438 
439 
450  Table RosettaVirtisCamera::getPointingTable(const QString &virChannel,
451  const int zeroFrame) {
452 
453  // Create Spice Pointing table
454  TableField q0("J2000Q0", TableField::Double);
455  TableField q1("J2000Q1", TableField::Double);
456  TableField q2("J2000Q2", TableField::Double);
457  TableField q3("J2000Q3", TableField::Double);
458  TableField av1("AV1", TableField::Double);
459  TableField av2("AV2", TableField::Double);
460  TableField av3("AV3", TableField::Double);
462 
463  TableRecord record;
464  record += q0;
465  record += q1;
466  record += q2;
467  record += q3;
468  record += av1;
469  record += av2;
470  record += av3;
471  record += t;
472 
473  // Get pointing table
474  Table quats("SpiceRotation", record);
475  int nfields = record.Fields();
476 
477  QString virZero = virChannel + "_ZERO";
478 
479  // Allocate output arrays
480  int nvals = nfields - 1;
481  int nlines = m_lineRates.size();
482 
483  SpiceDouble eulang[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
484  SpiceDouble xform[6][6], xform2[6][6];
485  SpiceDouble m[3][3];
486  SpiceDouble q_av[7], *av(&q_av[4]);
487 
488  for (int i = 0 ; i < nlines ; i++) {
489  int index = min(i, nlines-1);
490  double etTime = m_mirrorData[index].m_scanLineEt; // mid exposure ET
491  double optAng = m_mirrorData[index].m_opticalAngle;
492  try {
493  // J2000 -> ROS_VIRTIS-M_{channel}_ZERO
494  SMatrix state = getStateRotation("J2000", virZero, etTime);
495 
496  // Set rotation of optical scan mirror (in radians)
497  eulang[1] = -optAng;
498  eul2xf_c(eulang, 1, 2, 3, xform);
499  mxmg_c(xform, &state[0][0], 6, 6, 6, xform2);
500 
501  // Transform to output format
502  xf2rav_c(xform2, m, av); // Transfers AV to output q_av via pointer
503  m2q_c(m, q_av); // Transfers quaternion
504 
505  // Now populate the table record with the line pointing
506  for (int k = 0 ; k < nvals ; k++) {
507  record[k] = q_av[k];
508  }
509 
510  // Add time to record; record to table
511  record[nvals] = etTime;
512  quats += record;
513  }
514  catch (IException &ie) {
515  ostringstream mess;
516  mess << "Failed to get point state for line " << i+1;
517  throw IException(ie, IException::User, mess.str(), _FILEINFO_);
518  }
519  }
520 
521  // Add some necessary keywords
522  quats.Label() += PvlKeyword("CkTableStartTime", toString(startTime()));
523  quats.Label() += PvlKeyword("CkTableEndTime", toString(endTime()));
524  quats.Label() += PvlKeyword("CkTableOriginalSize", toString(quats.Records()));
525 
526  // Create the time dependant frames keyword
527  int virZeroId = getInteger("FRAME_" + virZero);
528  PvlKeyword tdf("TimeDependentFrames", toString(virZeroId)); // ROS_VIRTIS_M_{ID}_ZERO
529  tdf.addValue("-226200"); // ROS_VIRTIS
530  tdf.addValue("-226000"); // ROSETTA_SPACECRAFT
531  tdf.addValue("1"); // J2000
532  quats.Label() += tdf;
533 
534  // Create constant rotation frames
535  PvlKeyword cf("ConstantFrames", toString(virZeroId));
536  cf.addValue(toString(virZeroId));
537  quats.Label() += cf;
538 
539  SpiceDouble identity[3][3];
540  ident_c(identity);
541 
542  // Store DAWN_VIR_{ID}_ZERO -> DAWN_VIR_{ID}_ZERO identity rotation
543  PvlKeyword crot("ConstantRotation");
544  for (int i = 0 ; i < 3 ; i++) {
545  for (int j = 0 ; j < 3 ; j++) {
546  crot.addValue(toString(identity[i][j]));
547  }
548  }
549 
550  quats.Label() += crot;
551 
552  return (quats);
553  }
554 
555 
573  const QString &frame2,
574  const double &etTime)
575  const {
576  SMatrix state(6,6);
578  try {
579  // Get pointing w/AVs
580  sxform_c(frame1.toLatin1().data(), frame2.toLatin1().data(), etTime,
581  (SpiceDouble (*)[6]) state[0]);
583  }
584  catch (IException &) {
585  try {
586  SMatrix rot(3,3);
587  pxform_c(frame1.toLatin1().data(), frame2.toLatin1().data(), etTime,
588  (SpiceDouble (*)[3]) rot[0]);
590  SpiceDouble av[3] = {0.0, 0.0, 0.0 };
591  rav2xf_c((SpiceDouble (*)[3]) rot[0], av,
592  (SpiceDouble (*)[6]) state[0]);
593  }
594  catch (IException &ie2) {
595  ostringstream mess;
596  mess << "Could not get state rotation for Frame1 (" << frame1
597  << ") to Frame2 (" << frame2 << ") at time " << etTime;
598  throw IException(ie2, IException::User, mess.str(), _FILEINFO_);
599  }
600  }
601  return (state);
602  }
603 
604 
620  Kernels kerns(label);
621  QStringList cks = kerns.getKernelList("CK");
622  QRegExp virCk("*ROS_VIRTIS_M_????_????_V?.BC");
623  virCk.setPatternSyntax(QRegExp::Wildcard);
624  for (int i = 0 ; i < cks.size() ; i++) {
625  if ( virCk.exactMatch(cks[i]) ) return (true);
626  }
627  return (false);
628  }
629 
630 }
631 
635 extern "C" Isis::Camera *RosettaVirtisCameraPlugin(Isis::Cube &cube) {
636  return new Isis::RosettaVirtisCamera(cube);
637 }
Table Cache(const QString &tableName)
Return a table with J2000 to reference rotations.
double m_exposureTime
Line exposure time.
int Records() const
Returns the number of records.
Definition: Table.cpp:224
double startTime() const
Return start time for the entire cube.
void SetFocalLength()
Reads the focal length from the instrument kernel.
Definition: Camera.cpp:1430
double endTime() const
Return end time for the entire cube.
void MinimizeCache(DownsizeStatus status)
Set the downsize status to minimize cache.
virtual int SpkReferenceId() const
SPK Reference ID - J2000.
Camera model for both Rosetta VIRTIS-M instruments.
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
virtual int CkFrameId() const
CK Frame ID - Instrument Code from spacit run on CK.
Parse and return pieces of a time string.
Definition: iTime.h:78
QStringList getKernelList(const QString &ktype="") const
Provide a list of all the kernels found.
Definition: Kernels.cpp:689
double lineStartTime(const double midExpTime) const
Return the start time for a given line exposure time.
void readSCET(const QString &filename)
For calibrated VIRTIS-M images, read the SCET values from the cube.
SpiceInt getInteger(const QString &key, int index=0)
This returns a value from the NAIF text pool.
Definition: Spice.cpp:949
QString m_instrumentNameLong
Full instrument name.
Definition: Camera.h:507
bool m_isDarkCurrent
If the line is dark current data.
void SetDetectorSampleSumming(const double summing)
Set sample summing mode.
void LoadCache(double startTime, double endTime, int size)
Cache J2000 rotation quaternion over a time range.
double m_opticalAngle
Optical angle in degrees.
void SetPixelPitch()
Reads the Pixel Pitch from the instrument kernel.
Definition: Camera.cpp:1437
SMatrix getStateRotation(const QString &frame1, const QString &frame2, const double &et) const
Compute the state rotation at a given time for given frames.
Namespace for the standard library.
char m_slitMode
Slit mode of the instrument.
Generic class for Line Scan Cameras.
Determine SPICE kernels defined in an ISIS file.
Definition: Kernels.h:111
double lineEndTime(const double midExpTime) const
Return the end time for a given line exposure time.
Search child objects.
Definition: PvlObject.h:170
NumericalApproximation provides various numerical analysis methods of interpolation, extrapolation and approximation of a tabulated set of x, y data.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
Evaluate() returns the y-value of the nearest endpoint if a is outside of the domain.
void SetDetectorOrigin(const double sample, const double line)
Set the detector origin.
int pixelSumming() const
Return the pixel summing rate.
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition: IString.cpp:164
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:162
double m_scanLineEt
Center of line time in ET.
int hkLineCount() const
Returns number of housekeeping records found in the cube Table.
Convert between undistorted focal plane and ground coordinates.
Container class for storing timing information for a section of an image.
void SetFrame(int frameCode)
Change the frame to the given frame code.
double Evaluate(const double a, const ExtrapType &etype=ThrowError)
Calculates interpolated or extrapolated value of tabulated data set for given domain value...
double m_scanRate
Line scan rate.
double scanLineTime() const
Return the line scan rate.
Convert between distorted focal plane and detector coordinates.
std::vector< ScanMirrorInfo > m_mirrorData
vector of mirror info for each line
QString m_instrumentNameShort
Shortened instrument name.
Definition: Camera.h:508
QString instrumentId()
This method returns the InstrumentId as it appears in the cube.
Definition: Camera.cpp:2888
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
SpiceInt naifIkCode() const
This returns the NAIF IK code to use when reading from instrument kernels.
Definition: Spice.cpp:893
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:142
A single keyword-value pair.
Definition: PvlKeyword.h:98
iTime getClockTime(QString clockValue, int sclkCode=-1, bool clockTicks=false)
This converts the spacecraft clock ticks value (clockValue) to an iTime.
Definition: Spice.cpp:977
Do not downsize the cache.
Distort/undistort focal plane coordinates.
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:112
double m_mirrorCos
Raw mirror cosine value.
Convert between parent image coordinates and detector coordinates.
Container for cube-like labels.
Definition: Pvl.h:135
The values in the field are 8 byte doubles.
Definition: TableField.h:70
CameraFocalPlaneMap * FocalPlaneMap()
Returns a pointer to the CameraFocalPlaneMap object.
Definition: Camera.cpp:2848
Convert between undistorted focal plane and ra/dec coordinates.
void LoadCache()
This loads the spice cache big enough for this image.
Definition: Camera.cpp:2432
int m_lineNum
The line the info is for.
TNT::Array2D< SpiceDouble > SMatrix
2-D buffer
QString m_spacecraftNameLong
Full spacecraft name.
Definition: Camera.h:509
bool m_is1BCalibrated
is determined by Archive/ProcessingLevelId
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition: Cube.cpp:1346
Class for storing Table blobs information.
Definition: Table.h:77
LineScanCameraDetectorMap * DetectorMap()
Returns a pointer to the LineScanCameraDetectorMap object.
virtual int CkReferenceId() const
CK Reference ID - J2000.
bool hasArticulationKernel(Pvl &label) const
determine if the CK articulation kernels are present/given
void AddData(const double x, const double y)
Add a datapoint to the set.
int Lines() const
Returns the number of lines in the image.
Definition: Camera.cpp:2798
QString fileName() const
Returns the filename used to initialise the Pvl object.
Definition: PvlContainer.h:246
std::vector< LineRateChange > m_lineRates
vector of timing info for each line
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
Definition: NaifStatus.cpp:43
void readHouseKeeping(const QString &filename, double lineRate)
Read the VIRTIS houskeeping table from cube.
Isis exception class.
Definition: IException.h:107
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
int Fields() const
Returns the number of fields that are currently in the record.
Definition: TableRecord.cpp:94
SpiceRotation * instrumentRotation() const
Accessor method for the instrument rotation.
Definition: Spice.cpp:1489
QString m_spacecraftNameShort
Shortened spacecraft name.
Definition: Camera.h:510
Class for storing an Isis::Table&#39;s field information.
Definition: TableField.h:63
PvlObject & Label()
Accessor method that returns a PvlObject containing the Blob label.
Definition: Blob.cpp:167
SpiceInt naifSpkCode() const
This returns the NAIF SPK code to use when reading from SPK kernels.
Definition: Spice.cpp:875
double exposureTime() const
Return the exposure time.
double Et() const
Returns the ephemeris time (TDB) representation of the time as a double.
Definition: iTime.h:139
Table getPointingTable(const QString &channelId, const int zeroFrame)
Compute the pointing table for each line.
int m_summing
Summing/binnning mode.
SpiceDouble getDouble(const QString &key, int index=0)
This returns a value from the NAIF text pool.
Definition: Spice.cpp:963
void addValue(QString value, QString unit="")
Adds a value with units.
Definition: PvlKeyword.cpp:268
IO Handler for Isis Cubes.
Definition: Cube.h:170
double m_mirrorSin
Raw mirror sine value.