13 #include "mocxtrack.h"
22 MocLabels::MocLabels(
const QString &file) {
30 MocLabels::MocLabels(
Cube &cube) {
38 void MocLabels::Init(
Cube &cube) {
48 string msg =
"Labels do not appear contain a valid MOC instrument";
56 void MocLabels::ReadLabels(
Cube &cube) {
60 p_instrumentId = (QString) inst[
"InstrumentId"];
61 p_startingSample = inst[
"FirstLineSample"];
62 p_crosstrackSumming = inst[
"CrosstrackSumming"];
63 p_downtrackSumming = inst[
"DowntrackSumming"];
64 p_exposureDuration = inst[
"LineExposureDuration"];
65 p_focalPlaneTemp = inst[
"FocalPlaneTemperature"];
66 p_clockCount = (QString) inst[
"SpacecraftClockCount"];
69 p_orbitNumber = inst[
"OrbitNumber"];
71 p_gainModeId = (QString) inst[
"GainModeId"];
72 p_offsetModeId = inst[
"OffsetModeId"];
73 p_startTime = (QString) inst[
"StartTime"];
76 p_dataQuality =
"Unknown";
79 p_dataQuality = (QString) arch[
"DataQualityDesc"];
84 p_filter = (QString) bandBin[
"FilterName"];
94 p_lsk =
FileName(kerns[
"LeapSecond"][0]);
95 p_sclk =
FileName(kerns[
"SpacecraftClock"][0]);
101 void MocLabels::ValidateLabels() {
107 if(p_instrumentId ==
"MOC-NA") p_mocNA =
true;
108 if(p_instrumentId ==
"MOC-WA") {
109 if(p_filter ==
"RED") p_mocRedWA =
true;
110 if(p_filter ==
"BLUE") p_mocBlueWA =
true;
113 if(!p_mocNA && !p_mocRedWA && !p_mocBlueWA) {
114 QString msg =
"InstrumentID [" + p_instrumentId +
"] and/or FilterName ["
115 + p_filter +
"] are inappropriate for the MOC camera";
121 if((p_crosstrackSumming < 1) || (p_crosstrackSumming > 8)) {
122 string msg =
"MOC-NA keyword [CrosstrackSumming] must be between ";
123 msg +=
"1 and 8, but is [" +
IString(p_crosstrackSumming) +
"]";
127 if((p_downtrackSumming < 1) || (p_downtrackSumming > 8)) {
128 string msg =
"MOC-NA keyword [DowntrackSumming] must be between ";
129 msg +=
"1 and 8, but is [" +
IString(p_downtrackSumming) +
"]";
135 if((p_mocRedWA) || (p_mocBlueWA)) {
136 if((p_crosstrackSumming < 1) || (p_crosstrackSumming > 127)) {
137 string msg =
"MOC-WA keyword [CrosstrackSumming] must be between ";
138 msg +=
"1 and 127, but is [" +
IString(p_crosstrackSumming) +
"]";
142 if((p_downtrackSumming < 1) || (p_downtrackSumming > 127)) {
143 string msg =
"MOC-WA keyword [DowntrackSumming] must be between ";
144 msg +=
"1 and 127, but is [" +
IString(p_downtrackSumming) +
"]";
152 void MocLabels::Compute() {
154 p_trueLineRate = p_exposureDuration * (double) p_downtrackSumming;
155 p_trueLineRate /= 1000.0;
158 if(NarrowAngle() && (p_downtrackSumming != 1)) {
159 p_exposureDuration *= p_downtrackSumming;
163 map<QString, double>::iterator p;
165 p = p_gainMapNA.find(p_gainModeId);
166 if(p == p_gainMapNA.end()) {
167 QString msg =
"Invalid value for PVL keyword GainModeId [" +
173 p = p_gainMapWA.find(p_gainModeId);
174 if(p == p_gainMapWA.end()) {
175 QString msg =
"Invalid value for PVL keyword GainModeId [" +
183 p_offset = p_offsetModeId * 5.0;
188 if(NarrowAngle() && (p_downtrackSumming != 1)) {
189 iTime currentTime(p_startTime);
190 iTime mappingPhaseBeginTime(
"1999-04-03T01:00:40.441");
191 if(currentTime < mappingPhaseBeginTime) {
192 double newGain = p_gain / (double) p_downtrackSumming;
193 double mindiff = DBL_MAX;
194 map<QString, double>::iterator p;
196 p = p_gainMapNA.begin();
197 while(p != p_gainMapNA.end()) {
198 double diff = abs(newGain - p->second);
207 p = p_gainMapNA.find(index);
208 if(p == p_gainMapNA.end()) {
209 string msg =
"Could not find new gain for pre-mapping narrow angle image";
220 QString lsk = p_lsk.expanded();
221 QString sclk = p_sclk.expanded();
222 furnsh_c(lsk.toLatin1().data());
223 furnsh_c(sclk.toLatin1().data());
226 scs2e_c(-94, p_clockCount.toLatin1().data(), &p_etStart);
227 p_etEnd = EphemerisTime((
double)p_nl);
230 unload_c(lsk.toLatin1().data());
231 unload_c(sclk.toLatin1().data());
238 void MocLabels::InitGainMaps() {
239 p_gainMapNA[
"F2"] = 1.0;
240 p_gainMapNA[
"D2"] = 1.456;
241 p_gainMapNA[
"B2"] = 2.076;
242 p_gainMapNA[
"92"] = 2.935;
243 p_gainMapNA[
"72"] = 4.150;
244 p_gainMapNA[
"52"] = 5.866;
245 p_gainMapNA[
"32"] = 8.292;
246 p_gainMapNA[
"12"] = 11.73;
247 p_gainMapNA[
"EA"] = 7.968;
248 p_gainMapNA[
"CA"] = 11.673;
249 p_gainMapNA[
"AA"] = 16.542;
250 p_gainMapNA[
"8A"] = 23.386;
251 p_gainMapNA[
"6A"] = 33.067;
252 p_gainMapNA[
"4A"] = 46.740;
253 p_gainMapNA[
"2A"] = 66.071;
254 p_gainMapNA[
"0A"] = 93.465;
256 p_gainMapWA[
"9A"] = 1.0;
257 p_gainMapWA[
"8A"] = 1.412;
258 p_gainMapWA[
"7A"] = 2.002;
259 p_gainMapWA[
"6A"] = 2.832;
260 p_gainMapWA[
"5A"] = 4.006;
261 p_gainMapWA[
"4A"] = 5.666;
262 p_gainMapWA[
"3A"] = 8.014;
263 p_gainMapWA[
"2A"] = 11.34;
264 p_gainMapWA[
"1A"] = 16.03;
265 p_gainMapWA[
"0A"] = 22.67;
266 p_gainMapWA[
"96"] = 16.030;
267 p_gainMapWA[
"86"] = 22.634;
268 p_gainMapWA[
"76"] = 32.092;
269 p_gainMapWA[
"66"] = 45.397;
270 p_gainMapWA[
"56"] = 64.216;
271 p_gainMapWA[
"46"] = 90.826;
272 p_gainMapWA[
"36"] = 128.464;
273 p_gainMapWA[
"26"] = 181.780;
274 p_gainMapWA[
"16"] = 256.961;
275 p_gainMapWA[
"06"] = 363.400;
283 int MocLabels::StartDetector(
int sample)
const {
284 if((sample < 1) || (sample > p_ns)) {
285 string msg =
"Out of array bounds in MocLabels::StartDetector";
288 return p_startDetector[sample-1];
295 int MocLabels::EndDetector(
int sample)
const {
296 if((sample < 1) || (sample > p_ns)) {
297 string msg =
"Out of array bounds in MocLabels::EndDetector";
300 return p_endDetector[sample-1];
307 double MocLabels::Sample(
int detector)
const {
308 if((detector < 0) || (detector >= Detectors())) {
309 string msg =
"Out of array bounds in MocLabels::Sample";
312 return p_sample[detector];
317 void MocLabels::InitDetectorMaps() {
319 if(p_crosstrackSumming == 13) {
320 for(
int i = 0; i < p_ns; i++) {
321 p_startDetector[i] = mode13_table[i].starting_pixel +
322 p_startingSample - 1;
323 p_endDetector[i] = mode13_table[i].ending_pixel +
324 p_startingSample - 1;
327 else if(p_crosstrackSumming == 27) {
328 for(
int i = 0; i < p_ns; i++) {
329 p_startDetector[i] = mode27_table[i].starting_pixel +
330 p_startingSample - 1;
331 p_endDetector[i] = mode27_table[i].ending_pixel +
332 p_startingSample - 1;
336 int detector = (p_startingSample - 1);
337 for(
int i = 0; i < p_ns; i++) {
338 p_startDetector[i] = detector;
339 detector += p_crosstrackSumming - 1;
340 p_endDetector[i] = detector;
347 for(
int det = 0; det < Detectors(); det++) {
348 p_sample[det] = -1.0;
351 for(
int samp = 1; samp <= p_ns; samp++) {
352 int sd = p_startDetector[samp-1];
353 int ed = p_endDetector[samp-1];
355 double m = ((samp + 0.5) - (samp - 0.5)) / ((ed + 0.5) - (sd - 0.5));
356 for(
int det = sd; det <= ed; det++) {
357 p_sample[det] = m * (det - (sd - 0.5)) + (samp - 0.5);
366 double MocLabels::EphemerisTime(
double line)
const {
367 return p_etStart + (line - 0.5) * p_trueLineRate;
375 double MocLabels::Gain(
int line) {
376 if(NarrowAngle())
return p_gain;
380 double etLine = EphemerisTime((
double)line);
381 for(
int i = (
int)p_wagos.size() - 1; i >= 0; i--) {
382 if(etLine >= p_wagos[i].et) {
383 return p_wagos[i].gain;
394 double MocLabels::Offset(
int line) {
395 if(NarrowAngle())
return p_offset;
398 double etLine = EphemerisTime((
double)line);
399 for(
int i = (
int)p_wagos.size() - 1; i >= 0; i--) {
400 if(etLine >= p_wagos[i].et) {
401 return p_wagos[i].offset;
415 void MocLabels::InitWago() {
417 static bool firstTime =
true;
418 if(!firstTime)
return;
422 QString lskKern = p_lsk.expanded();
423 QString sclkKern = p_sclk.expanded();
424 furnsh_c(lskKern.toLatin1().data());
425 furnsh_c(sclkKern.toLatin1().data());
428 FileName wagoFile(
"$mgs/calibration/MGSC_????_wago.tab");
429 wagoFile = wagoFile.highestVersion();
430 QString nameOfFile = wagoFile.expanded();
431 ifstream temp(nameOfFile.toLatin1().data());
432 vector<int> wholeFile;
436 int nextByte = temp.get();
437 if(nextByte != 10 && nextByte != 13) {
438 wholeFile.push_back(nextByte);
445 int high = wholeFile.size() / 35;
447 IString line, filter, sclk, offsetId;
455 middle = (low + high) / 2;
456 int SclkStart = middle * 35 + 8;
457 int SclkEnd = SclkStart + 15;
461 for(
int i = SclkStart; i < SclkEnd; i++) {
462 currentSclk += (char)wholeFile[i];
468 scs2e_c(-94, currentSclk.c_str(), &et);
471 if(et < p_etEnd && et > p_etStart) {
472 int linenum = middle;
477 while(et >= p_etStart) {
479 int lineStart = (linenum * 35);
480 int lineEnd = lineStart + 35;
482 string currentLine =
"";
483 for(
int i = lineStart; i < lineEnd; i++) {
484 currentLine += (char)wholeFile[i];
489 for(
int i = 8; i < 23; ++i) {
490 currentSclk += currentLine[i];
494 scs2e_c(-94, currentSclk.c_str(), &et);
499 while(et <= p_etEnd) {
501 int lineStart = (linenum * 35);
502 int lineEnd = lineStart + 35;
504 string currentLine =
"";
505 for(
int i = lineStart; i < lineEnd; i++) {
506 currentLine += (char)wholeFile[i];
511 for(
int i = 8; i < 23; ++i) {
512 currentSclk += currentLine[i];
516 scs2e_c(-94, currentSclk.c_str(), &et);
521 for(
int i = bottom; i <= top; ++i) {
522 int lineStart = (i * 35);
523 int lineEnd = lineStart + 35;
524 string currentLine =
"";
525 for(
int j = lineStart; j < lineEnd; j++) {
526 currentLine += (char)wholeFile[j];
531 filter = line.
Token(
",");
536 if((filter ==
"RED") && (WideAngleBlue()))
continue;
537 if((filter ==
"BLUE") && (WideAngleRed()))
continue;
540 sclk = line.
Token(
",");
544 scs2e_c(-94, sclk.c_str(), &et);
547 gainId = line.
Token(
",").
ToQt().remove(
"\"").trimmed();
556 map<QString, double>::iterator p;
557 p = p_gainMapWA.find(gainId);
558 if(p == p_gainMapWA.end()) {
560 unload_c(lskKern.toLatin1().data());
561 unload_c(sclkKern.toLatin1().data());
563 QString msg =
"Invalid GainModeId [" + gainId +
"] in wago table";
566 double gain = p->second;
569 double offset = offsetId.
ToDouble() * 5.0;
574 wago.offset = offset;
575 p_wagos.push_back(wago);
582 else if(et < p_etStart) {
592 sort(p_wagos.begin(), p_wagos.end());
593 unique(p_wagos.begin(), p_wagos.end());
596 unload_c(lskKern.toLatin1().data());
597 unload_c(sclkKern.toLatin1().data());
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
QString ToQt() const
Retuns the object string as a QString.
File name manipulation and expansion.
Parse and return pieces of a time string.
int AlphaLines() const
Returns the number of lines in the alpha cube.
double ToDouble() const
Returns the floating point value the IString represents.
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
This class is used to rewrite the "alpha" keywords out of the AlphaCube group or Instrument group...
IString Token(const IString &separator)
Returns the first token in the IString.
Contains multiple PvlContainers.
#define _FILEINFO_
Macro for the filename and line number.
IString Remove(const std::string &del)
Remove all instances of any character in the string from the IString.
Container for cube-like labels.
Adds specific functionality to C++ strings.
IString ConvertWhiteSpace()
Returns the string with all "new lines", "carriage returns", "tabs", "form feeds", "vertical tabs" and "back spaces" converted to single spaces.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
int AlphaSamples() const
Returns the number of samples in the alpha cube.
IString Trim(const std::string &chars)
Removes characters from the beginning and end of the IString.
IO Handler for Isis Cubes.