18 #include "IException.h"
21 #include "mocxtrack.h"
23 #include "AlphaCube.h"
30 MocLabels::MocLabels(
const QString &file) {
38 MocLabels::MocLabels(
Cube &cube) {
46 void MocLabels::Init(
Cube &cube) {
56 string msg =
"Labels do not appear contain a valid MOC instrument";
57 throw IException(IException::Unknown, msg, _FILEINFO_);
64 void MocLabels::ReadLabels(
Cube &cube) {
68 p_instrumentId = (QString) inst[
"InstrumentId"];
69 p_startingSample = inst[
"FirstLineSample"];
70 p_crosstrackSumming = inst[
"CrosstrackSumming"];
71 p_downtrackSumming = inst[
"DowntrackSumming"];
72 p_exposureDuration = inst[
"LineExposureDuration"];
73 p_focalPlaneTemp = inst[
"FocalPlaneTemperature"];
74 p_clockCount = (QString) inst[
"SpacecraftClockCount"];
77 p_orbitNumber = inst[
"OrbitNumber"];
79 p_gainModeId = (QString) inst[
"GainModeId"];
80 p_offsetModeId = inst[
"OffsetModeId"];
81 p_startTime = (QString) inst[
"StartTime"];
84 p_dataQuality =
"Unknown";
87 p_dataQuality = (QString) arch[
"DataQualityDesc"];
92 p_filter = (QString) bandBin[
"FilterName"];
102 p_lsk =
FileName(kerns[
"LeapSecond"][0]);
103 p_sclk =
FileName(kerns[
"SpacecraftClock"][0]);
109 void MocLabels::ValidateLabels() {
115 if(p_instrumentId ==
"MOC-NA") p_mocNA =
true;
116 if(p_instrumentId ==
"MOC-WA") {
117 if(p_filter ==
"RED") p_mocRedWA =
true;
118 if(p_filter ==
"BLUE") p_mocBlueWA =
true;
121 if(!p_mocNA && !p_mocRedWA && !p_mocBlueWA) {
122 QString msg =
"InstrumentID [" + p_instrumentId +
"] and/or FilterName ["
123 + p_filter +
"] are inappropriate for the MOC camera";
124 throw IException(IException::Unknown, msg, _FILEINFO_);
129 if((p_crosstrackSumming < 1) || (p_crosstrackSumming > 8)) {
130 string msg =
"MOC-NA keyword [CrosstrackSumming] must be between ";
131 msg +=
"1 and 8, but is [" +
IString(p_crosstrackSumming) +
"]";
132 throw IException(IException::Unknown, msg, _FILEINFO_);
135 if((p_downtrackSumming < 1) || (p_downtrackSumming > 8)) {
136 string msg =
"MOC-NA keyword [DowntrackSumming] must be between ";
137 msg +=
"1 and 8, but is [" +
IString(p_downtrackSumming) +
"]";
138 throw IException(IException::Unknown, msg, _FILEINFO_);
143 if((p_mocRedWA) || (p_mocBlueWA)) {
144 if((p_crosstrackSumming < 1) || (p_crosstrackSumming > 127)) {
145 string msg =
"MOC-WA keyword [CrosstrackSumming] must be between ";
146 msg +=
"1 and 127, but is [" +
IString(p_crosstrackSumming) +
"]";
147 throw IException(IException::Unknown, msg, _FILEINFO_);
150 if((p_downtrackSumming < 1) || (p_downtrackSumming > 127)) {
151 string msg =
"MOC-WA keyword [DowntrackSumming] must be between ";
152 msg +=
"1 and 127, but is [" +
IString(p_downtrackSumming) +
"]";
153 throw IException(IException::Unknown, msg, _FILEINFO_);
160 void MocLabels::Compute() {
162 p_trueLineRate = p_exposureDuration * (double) p_downtrackSumming;
163 p_trueLineRate /= 1000.0;
166 if(NarrowAngle() && (p_downtrackSumming != 1)) {
167 p_exposureDuration *= p_downtrackSumming;
171 map<QString, double>::iterator p;
173 p = p_gainMapNA.find(p_gainModeId);
174 if(p == p_gainMapNA.end()) {
175 QString msg =
"Invalid value for PVL keyword GainModeId [" +
177 throw IException(IException::Unknown, msg, _FILEINFO_);
181 p = p_gainMapWA.find(p_gainModeId);
182 if(p == p_gainMapWA.end()) {
183 QString msg =
"Invalid value for PVL keyword GainModeId [" +
185 throw IException(IException::Unknown, msg, _FILEINFO_);
191 p_offset = p_offsetModeId * 5.0;
196 if(NarrowAngle() && (p_downtrackSumming != 1)) {
197 iTime currentTime(p_startTime);
198 iTime mappingPhaseBeginTime(
"1999-04-03T01:00:40.441");
199 if(currentTime < mappingPhaseBeginTime) {
200 double newGain = p_gain / (double) p_downtrackSumming;
201 double mindiff = DBL_MAX;
202 map<QString, double>::iterator p;
204 p = p_gainMapNA.begin();
205 while(p != p_gainMapNA.end()) {
206 double diff = abs(newGain - p->second);
215 p = p_gainMapNA.find(index);
216 if(p == p_gainMapNA.end()) {
217 string msg =
"Could not find new gain for pre-mapping narrow angle image";
218 throw IException(IException::Unknown, msg, _FILEINFO_);
228 QString lsk = p_lsk.expanded();
229 QString sclk = p_sclk.expanded();
230 furnsh_c(lsk.toLatin1().data());
231 furnsh_c(sclk.toLatin1().data());
234 scs2e_c(-94, p_clockCount.toLatin1().data(), &p_etStart);
235 p_etEnd = EphemerisTime((
double)p_nl);
238 unload_c(lsk.toLatin1().data());
239 unload_c(sclk.toLatin1().data());
246 void MocLabels::InitGainMaps() {
247 p_gainMapNA[
"F2"] = 1.0;
248 p_gainMapNA[
"D2"] = 1.456;
249 p_gainMapNA[
"B2"] = 2.076;
250 p_gainMapNA[
"92"] = 2.935;
251 p_gainMapNA[
"72"] = 4.150;
252 p_gainMapNA[
"52"] = 5.866;
253 p_gainMapNA[
"32"] = 8.292;
254 p_gainMapNA[
"12"] = 11.73;
255 p_gainMapNA[
"EA"] = 7.968;
256 p_gainMapNA[
"CA"] = 11.673;
257 p_gainMapNA[
"AA"] = 16.542;
258 p_gainMapNA[
"8A"] = 23.386;
259 p_gainMapNA[
"6A"] = 33.067;
260 p_gainMapNA[
"4A"] = 46.740;
261 p_gainMapNA[
"2A"] = 66.071;
262 p_gainMapNA[
"0A"] = 93.465;
264 p_gainMapWA[
"9A"] = 1.0;
265 p_gainMapWA[
"8A"] = 1.412;
266 p_gainMapWA[
"7A"] = 2.002;
267 p_gainMapWA[
"6A"] = 2.832;
268 p_gainMapWA[
"5A"] = 4.006;
269 p_gainMapWA[
"4A"] = 5.666;
270 p_gainMapWA[
"3A"] = 8.014;
271 p_gainMapWA[
"2A"] = 11.34;
272 p_gainMapWA[
"1A"] = 16.03;
273 p_gainMapWA[
"0A"] = 22.67;
274 p_gainMapWA[
"96"] = 16.030;
275 p_gainMapWA[
"86"] = 22.634;
276 p_gainMapWA[
"76"] = 32.092;
277 p_gainMapWA[
"66"] = 45.397;
278 p_gainMapWA[
"56"] = 64.216;
279 p_gainMapWA[
"46"] = 90.826;
280 p_gainMapWA[
"36"] = 128.464;
281 p_gainMapWA[
"26"] = 181.780;
282 p_gainMapWA[
"16"] = 256.961;
283 p_gainMapWA[
"06"] = 363.400;
291 int MocLabels::StartDetector(
int sample)
const {
292 if((sample < 1) || (sample > p_ns)) {
293 string msg =
"Out of array bounds in MocLabels::StartDetector";
294 throw IException(IException::Unknown, msg, _FILEINFO_);
296 return p_startDetector[sample-1];
303 int MocLabels::EndDetector(
int sample)
const {
304 if((sample < 1) || (sample > p_ns)) {
305 string msg =
"Out of array bounds in MocLabels::EndDetector";
306 throw IException(IException::Unknown, msg, _FILEINFO_);
308 return p_endDetector[sample-1];
315 double MocLabels::Sample(
int detector)
const {
316 if((detector < 0) || (detector >= Detectors())) {
317 string msg =
"Out of array bounds in MocLabels::Sample";
318 throw IException(IException::Unknown, msg, _FILEINFO_);
320 return p_sample[detector];
325 void MocLabels::InitDetectorMaps() {
327 if(p_crosstrackSumming == 13) {
328 for(
int i = 0; i < p_ns; i++) {
329 p_startDetector[i] = mode13_table[i].starting_pixel +
330 p_startingSample - 1;
331 p_endDetector[i] = mode13_table[i].ending_pixel +
332 p_startingSample - 1;
335 else if(p_crosstrackSumming == 27) {
336 for(
int i = 0; i < p_ns; i++) {
337 p_startDetector[i] = mode27_table[i].starting_pixel +
338 p_startingSample - 1;
339 p_endDetector[i] = mode27_table[i].ending_pixel +
340 p_startingSample - 1;
344 int detector = (p_startingSample - 1);
345 for(
int i = 0; i < p_ns; i++) {
346 p_startDetector[i] = detector;
347 detector += p_crosstrackSumming - 1;
348 p_endDetector[i] = detector;
355 for(
int det = 0; det < Detectors(); det++) {
356 p_sample[det] = -1.0;
359 for(
int samp = 1; samp <= p_ns; samp++) {
360 int sd = p_startDetector[samp-1];
361 int ed = p_endDetector[samp-1];
363 double m = ((samp + 0.5) - (samp - 0.5)) / ((ed + 0.5) - (sd - 0.5));
364 for(
int det = sd; det <= ed; det++) {
365 p_sample[det] = m * (det - (sd - 0.5)) + (samp - 0.5);
374 double MocLabels::EphemerisTime(
double line)
const {
375 return p_etStart + (line - 0.5) * p_trueLineRate;
383 double MocLabels::Gain(
int line) {
384 if(NarrowAngle())
return p_gain;
388 double etLine = EphemerisTime((
double)line);
389 for(
int i = (
int)p_wagos.size() - 1; i >= 0; i--) {
390 if(etLine >= p_wagos[i].et) {
391 return p_wagos[i].gain;
402 double MocLabels::Offset(
int line) {
403 if(NarrowAngle())
return p_offset;
406 double etLine = EphemerisTime((
double)line);
407 for(
int i = (
int)p_wagos.size() - 1; i >= 0; i--) {
408 if(etLine >= p_wagos[i].et) {
409 return p_wagos[i].offset;
423 void MocLabels::InitWago() {
425 static bool firstTime =
true;
426 if(!firstTime)
return;
430 QString lskKern = p_lsk.expanded();
431 QString sclkKern = p_sclk.expanded();
432 furnsh_c(lskKern.toLatin1().data());
433 furnsh_c(sclkKern.toLatin1().data());
436 FileName wagoFile(
"$mgs/calibration/MGSC_????_wago.tab");
438 QString nameOfFile = wagoFile.
expanded();
439 ifstream temp(nameOfFile.toLatin1().data());
440 vector<int> wholeFile;
444 int nextByte = temp.get();
445 if(nextByte != 10 && nextByte != 13) {
446 wholeFile.push_back(nextByte);
453 int high = wholeFile.size() / 35;
455 IString line, filter, sclk, offsetId;
463 middle = (low + high) / 2;
464 int SclkStart = middle * 35 + 8;
465 int SclkEnd = SclkStart + 15;
469 for(
int i = SclkStart; i < SclkEnd; i++) {
470 currentSclk += (char)wholeFile[i];
476 scs2e_c(-94, currentSclk.c_str(), &et);
479 if(et < p_etEnd && et > p_etStart) {
480 int linenum = middle;
485 while(et >= p_etStart) {
487 int lineStart = (linenum * 35);
488 int lineEnd = lineStart + 35;
490 string currentLine =
"";
491 for(
int i = lineStart; i < lineEnd; i++) {
492 currentLine += (char)wholeFile[i];
497 for(
int i = 8; i < 23; ++i) {
498 currentSclk += currentLine[i];
502 scs2e_c(-94, currentSclk.c_str(), &et);
507 while(et <= p_etEnd) {
509 int lineStart = (linenum * 35);
510 int lineEnd = lineStart + 35;
512 string currentLine =
"";
513 for(
int i = lineStart; i < lineEnd; i++) {
514 currentLine += (char)wholeFile[i];
519 for(
int i = 8; i < 23; ++i) {
520 currentSclk += currentLine[i];
524 scs2e_c(-94, currentSclk.c_str(), &et);
529 for(
int i = bottom; i <= top; ++i) {
530 int lineStart = (i * 35);
531 int lineEnd = lineStart + 35;
532 string currentLine =
"";
533 for(
int j = lineStart; j < lineEnd; j++) {
534 currentLine += (char)wholeFile[j];
539 filter = line.
Token(
",");
544 if((filter ==
"RED") && (WideAngleBlue()))
continue;
545 if((filter ==
"BLUE") && (WideAngleRed()))
continue;
548 sclk = line.
Token(
",");
552 scs2e_c(-94, sclk.c_str(), &et);
555 gainId = line.
Token(
",").
ToQt().remove(
"\"").trimmed();
564 map<QString, double>::iterator p;
565 p = p_gainMapWA.find(gainId);
566 if(p == p_gainMapWA.end()) {
568 unload_c(lskKern.toLatin1().data());
569 unload_c(sclkKern.toLatin1().data());
571 QString msg =
"Invalid GainModeId [" + gainId +
"] in wago table";
572 throw IException(IException::Unknown, msg, _FILEINFO_);
574 double gain = p->second;
577 double offset = offsetId.
ToDouble() * 5.0;
582 wago.offset = offset;
583 p_wagos.push_back(wago);
590 else if(et < p_etStart) {
600 sort(p_wagos.begin(), p_wagos.end());
601 unique(p_wagos.begin(), p_wagos.end());
604 unload_c(lskKern.toLatin1().data());
605 unload_c(sclkKern.toLatin1().data());