Isis 3 Programmer Reference
HiCalConf.cpp
1
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include <iostream>
10#include <numeric>
11#include <sstream>
12#include <vector>
13
14#include <QString>
15
16#include <SpiceUsr.h>
17
18#include "Brick.h"
19#include "Camera.h"
20#include "Cube.h"
21#include "FileName.h"
22#include "HiCalConf.h"
23#include "HiCalUtil.h"
24#include "IString.h"
25#include "IException.h"
26#include "Pvl.h"
27#include "SpecialPixel.h"
28#include "NaifStatus.h"
29
30using namespace std;
31
32namespace Isis {
33
34bool HiCalConf::_naifLoaded = false;
35
39 HiCalConf::HiCalConf() : DbAccess() {
40 _profName.clear();
41 init();
42 }
43
44
49 HiCalConf::HiCalConf(Pvl &label) : DbAccess() {
50 _profName.clear();
51 init(label);
52 }
53
60 HiCalConf::HiCalConf(Pvl &label, const QString &conf) :
61 DbAccess(Pvl(filepath(conf)).findObject("Hical", PvlObject::Traverse)) {
62 _profName.clear();
63 init(label);
64 }
65
71 void HiCalConf::setLabel(Pvl &label) {
72 init(label);
73 return;
74 }
75
88 QString HiCalConf::filepath(const QString &fname) const {
89 FileName efile(fname);
90 if (efile.isVersioned()) {
91 QString path(efile.originalPath());
92 if (!path.isEmpty()) path += "/";
93
94 efile = efile.highestVersion();
95
96 return (path + efile.name());
97 }
98 return (fname);
99 }
100
101
111 void HiCalConf::setConf(const QString &conf) {
112 load(Pvl(filepath(conf)).findObject("Hical", PvlObject::Traverse));
113 }
114
124 void HiCalConf::selectProfile(const QString &profile) {
125 _profName = profile;
126 return;
127 }
128
136 QString HiCalConf::getProfileName() const {
137 return (_profName);
138 }
139
153 QString HiCalConf::getMatrixSource(const QString &name) const {
154 return (getMatrixSource(name, getMatrixProfile()));
155 }
156
171 QString HiCalConf::getMatrixSource(const QString &name,
172 const DbProfile &matconf) const {
173
174 QString mfile = parser(matconf.value(name),
175 getList(matconf,"OptionKeywords"),
176 matconf);
177
178// Translate and return
179 return (filepath(mfile));
180 }
181
182 HiVector HiCalConf::getMatrix(const QString &name,
183 int expected_size) const {
184 return (getMatrix(name,getMatrixProfile(), expected_size));
185 }
186
187
188 QString HiCalConf::resolve(const QString &composite,
189 const DbProfile &matconf) const {
190 return (parser(composite,getList(matconf,"OptionKeywords"), matconf));
191 }
192
193
194
218 HiVector HiCalConf::getMatrix(const QString &name,
219 const DbProfile &profile,
220 int expected_size) const {
221
222 QString mfile = getMatrixSource(name, profile);
223
224// Crack the file and read the appropriate band
225 Cube cube;
226 cube.open(mfile);
227
228// Check for proper size if specifeid
229 if (expected_size != 0) {
230 if (cube.sampleCount() != expected_size) {
231 ostringstream mess;
232 mess << "Specifed matrix (" << name
233 << ") from file \"" << mfile
234 << "\" does not have expected samples (" << expected_size
235 << ") but has " << cube.sampleCount();
236 cube.close();
237 throw IException(IException::User, mess.str(), _FILEINFO_);
238 }
239 }
240
241// Read the specifed region
242 Brick bandio(cube.sampleCount(), 1, 1, Real);
243 bandio.SetBasePosition(1,1,getMatrixBand(profile));
244 cube.read(bandio);
245
246// Now create the output buffer with some TNT funny business
247 HiVector temp(cube.sampleCount(), bandio.DoubleBuffer());
248 HiVector out(cube.sampleCount());
249 out.inject(temp);
250 cube.close();
251 return (out);
252 }
253
268 HiVector HiCalConf::getScalar(const QString &name,
269 const DbProfile &profile,
270 int expected_size) const {
271 int nvals = profile.count(name);
272
273 // Check for proper size if specifeid
274 if (expected_size != 0) {
275 if (nvals != expected_size) {
276 ostringstream mess;
277 mess << "Specifed scalar (" << name
278 << ") does not have expected size (" << expected_size
279 << ") but has " << nvals;
280 throw IException(IException::User, mess.str(), _FILEINFO_);
281 }
282 }
283// All is OK
284 HiVector mtx(nvals, Null);
285 for (int i = 0 ; i < nvals ; i++) {
286 mtx[i] = ToDouble(profile(name, i));
287 }
288 return (mtx);
289 }
290
299 double HiCalConf::sunDistanceAU(Cube *cube) {
300 double sunkm = 0.0;
301 try {
302 Camera *cam;
303 cam = cube->camera();
304 cam->SetImage(0.5, 0.5);
305 sunkm = cam->sunToBodyDist();
306 NaifStatus::CheckErrors();
307 }
308 catch (IException &e) {
309 try {
310 loadNaifTiming();
311
312 QString scStartTime = getKey("SpacecraftClockStartCount", "Instrument");
313 double obsStartTime;
314 NaifStatus::CheckErrors();
315 scs2e_c (-74999,scStartTime.toLatin1().data(),&obsStartTime);
316
317 QString targetName = getKey("TargetName", "Instrument");
318 if (targetName.toLower() == "sky" ||
319 targetName.toLower() == "cal" ||
320 targetName.toLower() == "phobos" ||
321 targetName.toLower() == "deimos") {
322 targetName = "Mars";
323 }
324 double sunv[3];
325 double lt;
326 (void) spkpos_c(targetName.toLatin1().data(), obsStartTime, "J2000", "LT+S", "sun",
327 sunv, &lt);
328 sunkm = vnorm_c(sunv);
329
330 NaifStatus::CheckErrors();
331 }
332 catch(IException &e) {
333 QString msg = "Unable to determine the distance from the target to the sun";
334 throw IException(e, IException::User, msg, _FILEINFO_);
335 }
336 }
337
338 // Return in AU units
339 return (sunkm/1.49597870691E8);
340 }
341
342
357 int HiCalConf::getMatrixBand() const {
358 Pvl label = _label;
359 DbProfile parms = makeParameters(label);
360 return (getMatrixBand(parms));
361 }
362
376 int HiCalConf::getMatrixBand(const DbProfile &p) const {
377 return (getChannelIndex(ToInteger(p("CCD")), ToInteger(p("CHANNEL"))));
378 }
379
392 HiCalConf::ValueList HiCalConf::getList(const DbProfile &profile,
393 const QString &key) const {
394 ValueList slist;
395
396// Get keyword parameters
397 if ( profile.exists(key) ) {
398 int nvals = profile.count(key);
399 for (int i = 0 ; i < nvals ; i++) {
400 slist.push_back(profile.value(key, i));
401 }
402 }
403 return (slist);
404 }
405
412void HiCalConf::loadNaifTiming( ) {
413 NaifStatus::CheckErrors();
414 if (!_naifLoaded) {
415// Load the NAIF kernels to determine timing data
416 Isis::FileName leapseconds("$base/kernels/lsk/naif????.tls");
417 leapseconds = leapseconds.highestVersion();
418
419 Isis::FileName sclk("$mro/kernels/sclk/MRO_SCLKSCET.?????.65536.tsc");
420 sclk = sclk.highestVersion();
421
422 Isis::FileName pck("$base/kernels/spk/de???.bsp");
423 pck = pck.highestVersion();
424
425 Isis::FileName sat("$base/kernels/spk/mar???.bsp");
426 sat = sat.highestVersion();
427
428// Load the kernels
429 QString lsk = leapseconds.expanded();
430 QString sClock = sclk.expanded();
431 QString pConstants = pck.expanded();
432 QString satConstants = sat.expanded();
433 furnsh_c(lsk.toLatin1().data());
434 furnsh_c(sClock.toLatin1().data());
435 furnsh_c(pConstants.toLatin1().data());
436 furnsh_c(satConstants.toLatin1().data());
437 NaifStatus::CheckErrors();
438
439// Ensure it is loaded only once
440 _naifLoaded = true;
441 }
442 return;
443}
444
448void HiCalConf::init() {
449 _label.clear();
450 return;
451}
452
462void HiCalConf::init(Pvl &label) {
463 init();
464 _label = label;
465 return;
466}
467
479PvlKeyword &HiCalConf::getKey(const QString &key,
480 const QString &group) {
481 if (!group.isEmpty()) {
482 PvlGroup &grp = _label.findGroup(group, Pvl::Traverse);
483 return (grp[key]);
484 }
485 else {
486 return (_label.findKeyword(key));
487 }
488}
489
508DbProfile HiCalConf::getMatrixProfile(const QString &profile) const {
509 QString myprof = (!profile.isEmpty()) ? profile : _profName;
510 DbProfile matconf = getProfile(myprof);
511 if (!matconf.isValid()) {
512 ostringstream mess;
513 mess << "Specifed matrix profile (" << matconf.Name()
514 << ") does not exist or is invalid!";
515 throw IException(IException::User, mess.str(), _FILEINFO_);
516 }
517
518 // Profile the label and merge them. Order is important.
519 matconf = DbProfile(getLabelProfile(matconf), matconf, matconf.Name());
520
521 // Add special parameters. Again, order is important.
522 matconf = DbProfile(matconf, makeParameters(matconf), matconf.Name());
523
524// Load any optional ones
525 ValueList profkeys = getList(matconf,"OptionKeywords");
526 ValueList proforder = getList(matconf,"ProfileOptions");
527 QString pName(matconf.Name());
528 for (unsigned int i = 0 ; i < proforder.size() ; i++) {
529 QString profile = parser(proforder[i], profkeys, matconf);
530 if (profileExists(profile)) {
531 pName += "+[" + profile + "]";
532 matconf = DbProfile(matconf,getProfile(profile), pName);
533 }
534 }
535 return (matconf);
536}
537
538
539DbProfile HiCalConf::getLabelProfile(const DbProfile &profile) const {
540 DbProfile lblprof("Label");
541 if ( profile.exists("LabelGroups") ) {
542 int ngroups = profile.count("LabelGroups");
543 Pvl label = _label;
544 for ( int g = 0 ; g < ngroups ; g++ ) {
545 QString group = profile("LabelGroups", g);
546 PvlGroup grp = label.findGroup(group, Pvl::Traverse);
547 lblprof = DbProfile(lblprof,DbProfile(grp));
548 }
549 }
550 return (lblprof);
551}
552
553int HiCalConf::getChannelIndex(const int &ccd, const int &channel) const {
554 return(1 + (ccd*2) + channel);
555}
556
557DbProfile HiCalConf::makeParameters(Pvl &label) const {
558 PvlGroup inst = label.findGroup("Instrument", Pvl::Traverse);
559 DbProfile parms("Parameters");
560
561 int ccd = CpmmToCcd((int) inst["CpmmNumber"]);
562 int channel = inst["ChannelNumber"];
563 parms.add("CCD",ToString(ccd));
564 parms.add("CHANNEL", ToString(channel));
565 parms.add("TDI", inst["Tdi"]);
566 parms.add("BIN", inst["Summing"]);
567 parms.add("FILTER", CcdToFilter(ccd));
568 parms.add("CCDCHANNELINDEX", ToString(getChannelIndex(ccd, channel)));
569 return (parms);
570}
571
572DbProfile HiCalConf::makeParameters(const DbProfile &profile) const {
573 DbProfile parms("Parameters");
574 int ccd = CpmmToCcd(ToInteger(profile("CpmmNumber")));
575 int channel = ToInteger(profile("ChannelNumber"));
576 parms.add("CCD",ToString(ccd));
577 parms.add("CHANNEL", ToString(channel));
578 parms.add("TDI", profile("Tdi"));
579 parms.add("BIN", profile("Summing"));
580 parms.add("FILTER", CcdToFilter(ccd));
581 parms.add("CCDCHANNELINDEX", ToString(getChannelIndex(ccd, channel)));
582 return (parms);
583}
584
585QString HiCalConf::makePattern(const QString &str) const {
586 return (QString("{" + str + "}"));
587}
588
600QString HiCalConf::parser(const QString &s, const ValueList &vlist,
601 const DbProfile &prof) const {
602 QString sout(s);
603
604 ValueList::const_iterator ciVlist;
605 for ( ciVlist = vlist.begin() ; ciVlist != vlist.end() ; ++ciVlist ) {
606 QString str(*ciVlist);
607 if ( prof.exists(str) ) {
608 sout = sout.replace(makePattern(str), prof(str));
609 }
610 }
611
612 return (sout);
613}
614
615} // namespace Isis
File name manipulation and expansion.
Definition FileName.h:100
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString CcdToFilter(int ccd)
Convert HiRISE Ccd number to string filter name.
Definition HiCalUtil.h:86
int CpmmToCcd(int cpmm)
Convert HiRISE Cpmm number to Ccd number.
Definition HiCalUtil.h:71
TNT::Array1D< double > HiVector
1-D Buffer
Definition HiCalTypes.h:27
QString ToString(const T &value)
Helper function to convert values to strings.
Definition HiCalUtil.h:246
double ToDouble(const T &value)
Helper function to convert values to doubles.
Definition HiCalUtil.h:234
int ToInteger(const T &value)
Helper function to convert values to Integers.
Definition HiCalUtil.h:222
Namespace for the standard library.