USGS

Isis 3.0 Object Programmers' Reference

Home

VikingCamera.cpp
Go to the documentation of this file.
1 
23 #include "VikingCamera.h"
24 
25 #include <SpiceUsr.h>
26 #include <SpiceZfc.h>
27 #include <SpiceZmc.h>
28 
29 #include "CameraDetectorMap.h"
30 #include "CameraFocalPlaneMap.h"
31 #include "CameraGroundMap.h"
32 #include "CameraSkyMap.h"
33 #include "FileName.h"
34 #include "IString.h"
35 #include "iTime.h"
36 #include "NaifStatus.h"
37 #include "ReseauDistortionMap.h"
38 
39 using namespace std;
40 
41 namespace Isis {
56  VikingCamera::VikingCamera(Cube &cube) : FramingCamera(cube) {
58  // Set the pixel pitch
59  SetPixelPitch(1.0 / 85.0);
60 
61  // Find out what camera is being used, and set the focal length, altinstcode,
62  // raster orientation, cone, crosscone, and camera
63  Pvl &lab = *cube.label();
64  PvlGroup &inst = lab.findGroup("Instrument", Pvl::Traverse);
65  QString spacecraft = inst["SPACECRAFTNAME"];
66  QString instId = inst["INSTRUMENTID"];
67  QString cam;
68  int spn;
69  double raster, cone, crosscone;
70  int altinstcode = 0;
71  if(spacecraft == "VIKING_ORBITER_1") {
72  p_ckFrameId = -27000;
73  p_spkTargetId = -27;
74 
75  spn = 1;
76  altinstcode = -27999;
77  if(instId == "VISUAL_IMAGING_SUBSYSTEM_CAMERA_A") {
78  cam = "1a";
79  SetFocalLength(474.398);
80  crosscone = -0.707350;
81  cone = -0.007580;
82  raster = 89.735690;
83  }
84  else if(instId == "VISUAL_IMAGING_SUBSYSTEM_CAMERA_B") {
85  cam = "1b";
86  SetFocalLength(474.448);
87  crosscone = 0.681000;
88  cone = -0.032000;
89  raster = 90.022800;
90  }
91  else {
92  QString msg = "File does not appear to be a Viking image. InstrumentId ["
93  + instId + "] is invalid Viking value.";
95  }
96  }
97  else if(spacecraft == "VIKING_ORBITER_2") {
98  p_ckFrameId = -30000;
99  p_spkTargetId = -30;
100 
101  spn = 2;
102  altinstcode = -30999;
103  if(instId == "VISUAL_IMAGING_SUBSYSTEM_CAMERA_A") {
104  cam = "2a";
105  SetFocalLength(474.610);
106  crosscone = -0.679330;
107  cone = -0.023270;
108  raster = 89.880691;
109  }
110  else if(instId == "VISUAL_IMAGING_SUBSYSTEM_CAMERA_B") {
111  cam = "2b";
112  SetFocalLength(474.101);
113  crosscone = 0.663000;
114  cone = -0.044000;
115  raster = 89.663790;
116  }
117  else {
118  QString msg = "File does not appear to be a Viking image. InstrumentId ["
119  + instId + "] is invalid Viking value.";
121  }
122  }
123  else {
124  QString msg = "File does not appear to be a Viking image. SpacecraftName ["
125  + spacecraft + "] is invalid Viking value.";
127  }
128 
129  // DOCUMENTATION FROM ISIS2 lev1u_vik_vis_routines.c:
130  /*****************************************************************************
131  * Calculate the START_TIME keyword (time at middle of exposure in this case)*
132  * value from FSC to get fractional seconds (PDS START_TIME provided is only *
133  * to the nearest whole second). The algorithm below was extracted from the *
134  * NAIF document Viking Orbiter Time Tag Analysis and Restoration by Boris *
135  * Semenov and Chuck Acton. *
136  * 1. Get exposure duration from labels to center the time *
137  * 2. Get FSC from IMAGE_NUMBER on labels to use as spacecraftClock *
138  * 3. Load the appropriate FSC spacecraft clock kernel based on *
139  * the spacecraft (Viking Orbiter 1 or Viking Orbiter 2) *
140  * 4. Load a leap second kernel *
141  * 5. Convert FSC to et *
142  * 6. Add the offsets to get to midexposure *
143  * 7. Convert et to UTC calendar format and write to labels as *
144  * START_TIME *
145  *****************************************************************************/
146 
147  // Get clock count and convert it to a time
148  QString spacecraftClock = inst["SpacecraftClockCount"];
149  double etClock = getClockTime(spacecraftClock, altinstcode).Et();
150 
151  // exposure duration keyword value is measured in seconds
152  double exposureDuration = inst["ExposureDuration"];
153 
154  // Calculate and load the euler angles
155  SpiceDouble CP[3][3];
156  eul2m_c((SpiceDouble)raster * rpd_c(), (SpiceDouble)cone * rpd_c(),
157  (SpiceDouble) - crosscone * rpd_c(), 3, 2, 1, CP);
158 
159  // LoadEulerMounting(CP);
160 
161  pair<iTime, iTime> shuttertimes = ShutterOpenCloseTimes(etClock, exposureDuration);
162 
163  // find center shutter time
164  double centerTime = shuttertimes.first.Et() + exposureDuration / 2.0;
165  char timepds[25];
166  et2utc_c(centerTime, "ISOC", 3, 25, timepds);
167  utc2et_c(timepds, &centerTime);
168 
169  // Setup detector map
170  new CameraDetectorMap(this);
171 
172  // Setup focal plane map, and detector origin
173  CameraFocalPlaneMap *focalMap = new CameraFocalPlaneMap(this, naifIkCode());
174  focalMap->SetDetectorOrigin(602.0, 528.0);
175 
176  // Setup distortion map
177  QString fname = FileName("$viking" + toString(spn) + "/reseaus/vik" + cam
178  + "MasterReseaus.pvl").expanded();
179  new ReseauDistortionMap(this, lab, fname);
180 
181  // Setup the ground and sky map
182  new CameraGroundMap(this);
183  new CameraSkyMap(this);
184 
185  setTime(centerTime);
186  LoadCache();
188  }
189 
210  pair<iTime, iTime> VikingCamera::ShutterOpenCloseTimes(double time,
211  double exposureDuration) {
212  pair<iTime, iTime> shuttertimes;
213  double offset1;
214  if(exposureDuration <= .420) {
215  offset1 = 7.0 / 8.0 * 4.48; //4.48 seconds = nomtick
216  }
217  else {
218  offset1 = 3.0 / 8.0 * 4.48;
219  }
220  double offset2 = 1.0 / 64.0 * 4.48;
221 
222  // set private variables inherited from Spice class
223  shuttertimes.first = time + offset1 + offset2;
224  shuttertimes.second = shuttertimes.first.Et() + exposureDuration;
225  return shuttertimes;
226  }
227 }
228 
229 
239  return new Isis::VikingCamera(cube);
240 }