9 #include "DawnVirCamera.h"
19 #include "NumericalApproximation.h"
22 #include "tnt/tnt_array2d_utils.h"
29 DawnVirCamera::DawnVirCamera(Cube &cube) : LineScanCamera(cube) {
33 Pvl &lab = *cube.label();
35 int procLevel = archive[
"ProcessingLevelId"];
36 m_is1BCalibrated = (procLevel > 2) ?
true :
false;
40 QString channelId = inst[
"ChannelId"];
42 QString instMode = inst[
"InstrumentModeId"];
43 m_slitMode = instMode[14].toAscii();
46 bool hasArtCK = hasArticulationKernel(lab);
50 if (channelId ==
"VIS") {
52 virFrame = (hasArtCK) ? -203211 : -203221;
56 virFrame = (hasArtCK) ? -203213 : -203223;
59 instrumentRotation()->SetFrame(virFrame);
62 instrumentRotation()->MinimizeCache(SpiceRotation::No);
69 PvlKeyword &frameParam = inst[
"FrameParameter"];
70 m_exposureTime =
toDouble(frameParam[0]);
72 m_scanRate =
toDouble(frameParam[2]);
76 readHouseKeeping(lab.fileName(), m_scanRate);
77 new VariableLineScanCameraDetectorMap(
this, m_lineRates);
78 DetectorMap()->SetDetectorSampleSumming(m_summing);
81 new CameraFocalPlaneMap(
this, naifIkCode());
84 QString ikernKey =
"INS" +
toString(naifIkCode()) +
"_BORESIGHT_SAMPLE";
85 double sampleBoreSight = getDouble(ikernKey);
87 ikernKey =
"INS" +
toString(naifIkCode()) +
"_BORESIGHT_LINE";
88 double lineBoreSight = getDouble(ikernKey);
90 FocalPlaneMap()->SetDetectorOrigin(sampleBoreSight, lineBoreSight);
96 new LineScanCameraGroundMap(
this);
97 new LineScanCameraSkyMap(
this);
100 setTime(iTime(startTime()));
106 if (!instrumentRotation()->IsCached() && !hasArtCK) {
109 Table quats = getPointingTable(channelId, virFrame);
113 instrumentRotation()->LoadCache(quats);
119 #if defined(DUMP_INFO)
120 Table cache = instrumentRotation()->Cache(
"Loaded");
121 cout <<
"Total Records: " << cache.Records() <<
"\n";
123 for (
int i = 0 ; i < cache.Records() ; i++) {
124 TableRecord rec = cache[i];
125 string separator(
"");
126 for (
int f = 0 ; f < rec.Fields() ; f++) {
127 cout << separator << (double) rec[f];
158 for (
int i = 0 ; i < text.size() ; i++) {
159 if ((text[i] >
' ') && (text[i] <=
'z')) ostr += text[i];
203 return (m_mirrorData.size());
220 Table hktable(
"VIRHouseKeeping", filename);
225 for (
int i = 0; i < hktable.
Records(); i++) {
227 QString scet =
scrub(trec[
"ScetTimeClock"]);
228 QString shutterMode =
scrub(trec[
"ShutterStatus"]);
231 double mirrorSin = trec[
"MirrorSin"];
232 double mirrorCos = trec[
"MirrorCos"];
233 double scanElecDeg = atan(mirrorSin/mirrorCos) * dpr_c();
234 double optAng = ((scanElecDeg - 3.7996979) * 0.25/0.257812);
242 bool isDark = shutterMode.toLower() ==
"closed";
245 if ( ! isDark ) { angFit.
AddData(lineno, optAng); }
247 #if defined(DUMP_INFO)
248 cout <<
"Line(" << ((isDark) ?
"C): " :
"O): ") << i
249 <<
", OptAng(D): " << setprecision(12) << optAng * dpr_c()
250 <<
", MidExpTime(ET): " << lineMidTime
255 smInfo.m_lineNum = lineno;
256 smInfo.m_scanLineEt = lineMidTime;
257 smInfo.m_mirrorSin = mirrorSin;
258 smInfo.m_mirrorCos = mirrorCos;
259 smInfo.m_opticalAngle = optAng;
260 smInfo.m_isDarkCurrent = isDark;
262 if ((!m_is1BCalibrated) || (!(m_is1BCalibrated && isDark))) {
266 m_mirrorData.push_back(smInfo);
280 for (
unsigned int a = 0 ; a < m_mirrorData.size() ; a++) {
281 if (m_mirrorData[a].m_isDarkCurrent) {
282 m_mirrorData[a].m_opticalAngle = angFit.
Evaluate(a+1,
290 mess <<
"Number housekeeping lines determined (" <<
m_lineRates.size()
291 <<
") is not equal to image lines(" <<
Lines() <<
")";
306 const int zeroFrame) {
329 Table quats(
"SpiceRotation", record);
330 int nfields = record.
Fields();
332 QString virId =
"DAWN_VIR_" + virChannel;
333 QString virZero = virId +
"_ZERO";
336 int nvals = nfields - 1;
339 SpiceDouble eulang[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
340 SpiceDouble xform[6][6], xform2[6][6];
342 SpiceDouble q_av[7], *av(&q_av[4]);
344 for (
int i = 0 ; i < nlines ; i++) {
345 int index = min(i, nlines-1);
346 double etTime = m_mirrorData[index].m_scanLineEt;
347 double optAng = m_mirrorData[index].m_opticalAngle;
354 eul2xf_c(eulang, 1, 2, 3, xform);
355 mxmg_c(xform, &state[0][0], 6, 6, 6, xform2);
358 xf2rav_c(xform2, m, av);
362 for (
int k = 0 ; k < nvals ; k++) {
367 record[nvals] = etTime;
372 mess <<
"Failed to get point state for line " << i+1;
383 int virZeroId =
getInteger(
"FRAME_" + virZero);
388 quats.
Label() += tdf;
395 SpiceDouble identity[3][3];
400 for (
int i = 0 ; i < 3 ; i++) {
401 for (
int j = 0 ; j < 3 ; j++) {
406 quats.
Label() += crot;
428 const QString &frame2,
429 const double &etTime)
435 sxform_c(frame1.toAscii().data(), frame2.toAscii().data(), etTime,
436 (SpiceDouble (*)[6]) state[0]);
442 pxform_c(frame1.toAscii().data(), frame2.toAscii().data(), etTime,
443 (SpiceDouble (*)[3]) rot[0]);
445 SpiceDouble av[3] = {0.0, 0.0, 0.0 };
446 rav2xf_c((SpiceDouble (*)[3]) rot[0], av,
447 (SpiceDouble (*)[6]) state[0]);
451 mess <<
"Could not get state rotation for Frame1 (" << frame1
452 <<
") to Frame2 (" << frame2 <<
") at time " << etTime;
476 QRegExp virCk(
"*dawn_vir_?????????_?.bc");
477 virCk.setPatternSyntax(QRegExp::Wildcard);
478 for (
int i = 0 ; i < cks.size() ; i++) {
479 if ( virCk.exactMatch(cks[i]) )
return (
true);