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 
30 using namespace std;
31 
32 namespace Isis {
33 
34 bool 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();
307  }
308  catch (IException &e) {
309  try {
310  loadNaifTiming();
311 
312  QString scStartTime = getKey("SpacecraftClockStartCount", "Instrument");
313  double obsStartTime;
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 
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 
412 void HiCalConf::loadNaifTiming( ) {
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());
438 
439 // Ensure it is loaded only once
440  _naifLoaded = true;
441  }
442  return;
443 }
444 
448 void HiCalConf::init() {
449  _label.clear();
450  return;
451 }
452 
462 void HiCalConf::init(Pvl &label) {
463  init();
464  _label = label;
465  return;
466 }
467 
479 PvlKeyword &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 
508 DbProfile 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 
539 DbProfile 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 
553 int HiCalConf::getChannelIndex(const int &ccd, const int &channel) const {
554  return(1 + (ccd*2) + channel);
555 }
556 
557 DbProfile 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 
572 DbProfile 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 
585 QString HiCalConf::makePattern(const QString &str) const {
586  return (QString("{" + str + "}"));
587 }
588 
600 QString 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
Isis::ToString
QString ToString(const T &value)
Helper function to convert values to strings.
Definition: HiCalUtil.h:246
Isis::FileName
File name manipulation and expansion.
Definition: FileName.h:100
Isis::NaifStatus::CheckErrors
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
Definition: NaifStatus.cpp:28
Isis::PvlObject::Traverse
@ Traverse
Search child objects.
Definition: PvlObject.h:158
Isis::ToInteger
int ToInteger(const T &value)
Helper function to convert values to Integers.
Definition: HiCalUtil.h:222
Isis::HiVector
TNT::Array1D< double > HiVector
1-D Buffer
Definition: HiCalTypes.h:27
Isis::Null
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:95
Isis::ToDouble
double ToDouble(const T &value)
Helper function to convert values to doubles.
Definition: HiCalUtil.h:234
std
Namespace for the standard library.
Isis::CpmmToCcd
int CpmmToCcd(int cpmm)
Convert HiRISE Cpmm number to Ccd number.
Definition: HiCalUtil.h:71
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::IException::User
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition: IException.h:126
Isis::CcdToFilter
QString CcdToFilter(int ccd)
Convert HiRISE Ccd number to string filter name.
Definition: HiCalUtil.h:86