16#include <boost/core/ignore_unused.hpp>
19#include "IException.h"
57 string msg =
"Labels do not appear contain a valid MOC instrument";
69 p_instrumentId = (QString) inst[
"InstrumentId"];
70 p_startingSample = inst[
"FirstLineSample"];
71 p_crosstrackSumming = inst[
"CrosstrackSumming"];
72 p_downtrackSumming = inst[
"DowntrackSumming"];
73 p_exposureDuration = inst[
"LineExposureDuration"];
74 p_focalPlaneTemp = inst[
"FocalPlaneTemperature"];
75 p_clockCount = (QString) inst[
"SpacecraftClockCount"];
78 p_orbitNumber = inst[
"OrbitNumber"];
80 p_gainModeId = (QString) inst[
"GainModeId"];
81 p_offsetModeId = inst[
"OffsetModeId"];
82 p_startTime = (QString) inst[
"StartTime"];
85 p_dataQuality =
"Unknown";
88 p_dataQuality = (QString) arch[
"DataQualityDesc"];
93 p_filter = (QString) bandBin[
"FilterName"];
103 p_lsk =
FileName(kerns[
"LeapSecond"][0]);
104 p_sclk =
FileName(kerns[
"SpacecraftClock"][0]);
116 if(p_instrumentId ==
"MOC-NA") p_mocNA =
true;
117 if(p_instrumentId ==
"MOC-WA") {
118 if(p_filter ==
"RED") p_mocRedWA =
true;
119 if(p_filter ==
"BLUE") p_mocBlueWA =
true;
122 if(!p_mocNA && !p_mocRedWA && !p_mocBlueWA) {
123 QString msg =
"InstrumentID [" + p_instrumentId +
"] and/or FilterName ["
124 + p_filter +
"] are inappropriate for the MOC camera";
130 if((p_crosstrackSumming < 1) || (p_crosstrackSumming > 8)) {
131 string msg =
"MOC-NA keyword [CrosstrackSumming] must be between ";
132 msg +=
"1 and 8, but is [" +
IString(p_crosstrackSumming) +
"]";
136 if((p_downtrackSumming < 1) || (p_downtrackSumming > 8)) {
137 string msg =
"MOC-NA keyword [DowntrackSumming] must be between ";
138 msg +=
"1 and 8, but is [" +
IString(p_downtrackSumming) +
"]";
144 if((p_mocRedWA) || (p_mocBlueWA)) {
145 if((p_crosstrackSumming < 1) || (p_crosstrackSumming > 127)) {
146 string msg =
"MOC-WA keyword [CrosstrackSumming] must be between ";
147 msg +=
"1 and 127, but is [" +
IString(p_crosstrackSumming) +
"]";
151 if((p_downtrackSumming < 1) || (p_downtrackSumming > 127)) {
152 string msg =
"MOC-WA keyword [DowntrackSumming] must be between ";
153 msg +=
"1 and 127, but is [" +
IString(p_downtrackSumming) +
"]";
163 p_trueLineRate = p_exposureDuration * (double) p_downtrackSumming;
164 p_trueLineRate /= 1000.0;
168 p_exposureDuration *= p_downtrackSumming;
172 map<QString, double>::iterator p;
174 p = p_gainMapNA.find(p_gainModeId);
175 if(p == p_gainMapNA.end()) {
176 QString msg =
"Invalid value for PVL keyword GainModeId [" +
182 p = p_gainMapWA.find(p_gainModeId);
183 if(p == p_gainMapWA.end()) {
184 QString msg =
"Invalid value for PVL keyword GainModeId [" +
192 p_offset = p_offsetModeId * 5.0;
198 iTime currentTime(p_startTime);
199 iTime mappingPhaseBeginTime(
"1999-04-03T01:00:40.441");
200 if(currentTime < mappingPhaseBeginTime) {
201 double newGain = p_gain / (double) p_downtrackSumming;
202 double mindiff = DBL_MAX;
203 map<QString, double>::iterator p;
205 p = p_gainMapNA.begin();
206 while(p != p_gainMapNA.end()) {
207 double diff = abs(newGain - p->second);
216 p = p_gainMapNA.find(index);
217 if(p == p_gainMapNA.end()) {
218 string msg =
"Could not find new gain for pre-mapping narrow angle image";
229 QString lsk = p_lsk.expanded();
230 QString sclk = p_sclk.expanded();
231 furnsh_c(lsk.toLatin1().data());
232 furnsh_c(sclk.toLatin1().data());
235 scs2e_c(-94, p_clockCount.toLatin1().data(), &p_etStart);
239 unload_c(lsk.toLatin1().data());
240 unload_c(sclk.toLatin1().data());
248 p_gainMapNA[
"F2"] = 1.0;
249 p_gainMapNA[
"D2"] = 1.456;
250 p_gainMapNA[
"B2"] = 2.076;
251 p_gainMapNA[
"92"] = 2.935;
252 p_gainMapNA[
"72"] = 4.150;
253 p_gainMapNA[
"52"] = 5.866;
254 p_gainMapNA[
"32"] = 8.292;
255 p_gainMapNA[
"12"] = 11.73;
256 p_gainMapNA[
"EA"] = 7.968;
257 p_gainMapNA[
"CA"] = 11.673;
258 p_gainMapNA[
"AA"] = 16.542;
259 p_gainMapNA[
"8A"] = 23.386;
260 p_gainMapNA[
"6A"] = 33.067;
261 p_gainMapNA[
"4A"] = 46.740;
262 p_gainMapNA[
"2A"] = 66.071;
263 p_gainMapNA[
"0A"] = 93.465;
265 p_gainMapWA[
"9A"] = 1.0;
266 p_gainMapWA[
"8A"] = 1.412;
267 p_gainMapWA[
"7A"] = 2.002;
268 p_gainMapWA[
"6A"] = 2.832;
269 p_gainMapWA[
"5A"] = 4.006;
270 p_gainMapWA[
"4A"] = 5.666;
271 p_gainMapWA[
"3A"] = 8.014;
272 p_gainMapWA[
"2A"] = 11.34;
273 p_gainMapWA[
"1A"] = 16.03;
274 p_gainMapWA[
"0A"] = 22.67;
275 p_gainMapWA[
"96"] = 16.030;
276 p_gainMapWA[
"86"] = 22.634;
277 p_gainMapWA[
"76"] = 32.092;
278 p_gainMapWA[
"66"] = 45.397;
279 p_gainMapWA[
"56"] = 64.216;
280 p_gainMapWA[
"46"] = 90.826;
281 p_gainMapWA[
"36"] = 128.464;
282 p_gainMapWA[
"26"] = 181.780;
283 p_gainMapWA[
"16"] = 256.961;
284 p_gainMapWA[
"06"] = 363.400;
293 if((sample < 1) || (sample > p_ns)) {
294 string msg =
"Out of array bounds in MocLabels::StartDetector";
297 return p_startDetector[sample-1];
305 if((sample < 1) || (sample > p_ns)) {
306 string msg =
"Out of array bounds in MocLabels::EndDetector";
309 return p_endDetector[sample-1];
317 if((detector < 0) || (detector >=
Detectors())) {
318 string msg =
"Out of array bounds in MocLabels::Sample";
321 return p_sample[detector];
328 if(p_crosstrackSumming == 13) {
329 for(
int i = 0; i < p_ns; i++) {
330 p_startDetector[i] = mode13_table[i].starting_pixel +
331 p_startingSample - 1;
332 p_endDetector[i] = mode13_table[i].ending_pixel +
333 p_startingSample - 1;
336 else if(p_crosstrackSumming == 27) {
337 for(
int i = 0; i < p_ns; i++) {
338 p_startDetector[i] = mode27_table[i].starting_pixel +
339 p_startingSample - 1;
340 p_endDetector[i] = mode27_table[i].ending_pixel +
341 p_startingSample - 1;
345 int detector = (p_startingSample - 1);
346 for(
int i = 0; i < p_ns; i++) {
347 p_startDetector[i] = detector;
348 detector += p_crosstrackSumming - 1;
349 p_endDetector[i] = detector;
356 for(
int det = 0; det <
Detectors(); det++) {
357 p_sample[det] = -1.0;
360 for(
int samp = 1; samp <= p_ns; samp++) {
361 int sd = p_startDetector[samp-1];
362 int ed = p_endDetector[samp-1];
364 double m = ((samp + 0.5) - (samp - 0.5)) / ((ed + 0.5) - (sd - 0.5));
365 for(
int det = sd; det <= ed; det++) {
366 p_sample[det] = m * (det - (sd - 0.5)) + (samp - 0.5);
376 return p_etStart + (line - 0.5) * p_trueLineRate;
390 for(
int i = (
int)p_wagos.size() - 1; i >= 0; i--) {
391 if(etLine >= p_wagos[i].et) {
392 return p_wagos[i].gain;
408 for(
int i = (
int)p_wagos.size() - 1; i >= 0; i--) {
409 if(etLine >= p_wagos[i].et) {
410 return p_wagos[i].offset;
426 static bool firstTime =
true;
427 if(!firstTime)
return;
431 QString lskKern = p_lsk.expanded();
432 QString sclkKern = p_sclk.expanded();
433 furnsh_c(lskKern.toLatin1().data());
434 furnsh_c(sclkKern.toLatin1().data());
437 FileName wagoFile(
"$mgs/calibration/MGSC_????_wago.tab");
439 QString nameOfFile = wagoFile.
expanded();
440 ifstream temp(nameOfFile.toLatin1().data());
441 vector<int> wholeFile;
445 int nextByte = temp.get();
446 if(nextByte != 10 && nextByte != 13) {
447 wholeFile.push_back(nextByte);
454 int high = wholeFile.size() / 35;
456 IString line, filter, sclk, offsetId;
464 middle = (low + high) / 2;
465 int SclkStart = middle * 35 + 8;
466 int SclkEnd = SclkStart + 15;
470 for(
int i = SclkStart; i < SclkEnd; i++) {
471 currentSclk += (char)wholeFile[i];
477 scs2e_c(-94, currentSclk.c_str(), &et);
480 if(et < p_etEnd && et > p_etStart) {
481 int linenum = middle;
486 while(et >= p_etStart) {
488 int lineStart = (linenum * 35);
489 int lineEnd = lineStart + 35;
491 string currentLine =
"";
492 for(
int i = lineStart; i < lineEnd; i++) {
493 currentLine += (char)wholeFile[i];
498 for(
int i = 8; i < 23; ++i) {
499 currentSclk += currentLine[i];
503 scs2e_c(-94, currentSclk.c_str(), &et);
508 while(et <= p_etEnd) {
510 int lineStart = (linenum * 35);
511 int lineEnd = lineStart + 35;
513 string currentLine =
"";
514 for(
int i = lineStart; i < lineEnd; i++) {
515 currentLine += (char)wholeFile[i];
520 for(
int i = 8; i < 23; ++i) {
521 currentSclk += currentLine[i];
525 scs2e_c(-94, currentSclk.c_str(), &et);
530 for(
int i = bottom; i <= top; ++i) {
531 int lineStart = (i * 35);
532 int lineEnd = lineStart + 35;
533 string currentLine =
"";
534 for(
int j = lineStart; j < lineEnd; j++) {
535 currentLine += (char)wholeFile[j];
540 filter = line.
Token(
",");
549 sclk = line.
Token(
",");
553 scs2e_c(-94, sclk.c_str(), &et);
556 gainId = line.
Token(
",").
ToQt().remove(
"\"").trimmed();
565 map<QString, double>::iterator p;
566 p = p_gainMapWA.find(gainId);
567 if(p == p_gainMapWA.end()) {
569 unload_c(lskKern.toLatin1().data());
570 unload_c(sclkKern.toLatin1().data());
572 QString msg =
"Invalid GainModeId [" + gainId +
"] in wago table";
575 double gain = p->second;
578 double offset = offsetId.
ToDouble() * 5.0;
583 wago.offset = offset;
584 p_wagos.push_back(wago);
591 else if(et < p_etStart) {
601 sort(p_wagos.begin(), p_wagos.end());
602 boost::ignore_unused((unique(p_wagos.begin(), p_wagos.end())));
605 unload_c(lskKern.toLatin1().data());
606 unload_c(sclkKern.toLatin1().data());
This class is used to rewrite the "alpha" keywords out of the AlphaCube group or Instrument group.
int AlphaSamples() const
Returns the number of samples in the alpha cube.
int AlphaLines() const
Returns the number of lines in the alpha cube.
IO Handler for Isis Cubes.
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
File name manipulation and expansion.
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
FileName highestVersion() const
Searches the directory specified in the file name for the highest version of the file name.
@ Unknown
A type of error that cannot be classified as any of the other error types.
Adds specific functionality to C++ strings.
IString Remove(const std::string &del)
Remove all instances of any character in the string from the IString.
IString Trim(const std::string &chars)
Removes characters from the beginning and end of the IString.
IString Token(const IString &separator)
Returns the first token in the IString.
QString ToQt() const
Retuns the object string as a QString.
IString ConvertWhiteSpace()
Returns the string with all "new lines", "carriage returns", "tabs", "formfeeds", "vertical tabs" and...
double ToDouble() const
Returns the floating point value the IString represents.
void ValidateLabels()
Verifies that the labels are valid.
double Offset(int line=1)
Returns the offset at the given line.
bool WideAngleBlue() const
Indicates whether the camera was blue wide angle.
int StartDetector(int sample) const
Converts from sample to starting detector.
void ReadLabels(Cube &cube)
Reads required keywords from the labels.
double EphemerisTime(double line) const
Returns the ephemeris time at the given line.
bool NarrowAngle() const
Indicates whether the camera was narrow angle.
MocLabels(Cube &cube)
Construct MocLabels object using a Pvl object.
int Detectors() const
Returns 2048 if narrow angle and 3456 if wide angle.
double Sample(int detector) const
Converts from detector to sample.
void InitGainMaps()
Creates a lookup of gain modes to gain values.
int EndDetector(int sample) const
Converts from sample to ending detector.
void InitDetectorMaps()
Creates lookup table from sample to detectors and vice versa.
double Gain(int line=1)
Returns the true gain at a given line.
void Compute()
Computes some constants.
void InitWago()
Reads the wide-angle gain/offset table and internalizes.
void Init(Cube &cube)
General initializer.
bool WideAngleRed() const
Indicates whether the camera was red wide angle.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Contains multiple PvlContainers.
Container for cube-like labels.
@ Traverse
Search child objects.
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Parse and return pieces of a time string.
This is free and unencumbered software released into the public domain.
Namespace for the standard library.