Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

Isis 3 Programmer Reference
HiCalConf.cpp
1
6
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 "Preference.h"
27#include "Pvl.h"
28#include "spiceql.h"
29#include "SpecialPixel.h"
30#include "NaifStatus.h"
31
32using namespace std;
33
34namespace Isis {
35
36bool HiCalConf::_naifLoaded = false;
37
41 HiCalConf::HiCalConf() : DbAccess() {
42 _profName.clear();
43 init();
44 }
45
46
51 HiCalConf::HiCalConf(Pvl &label) : DbAccess() {
52 _profName.clear();
53 init(label);
54 }
55
62 HiCalConf::HiCalConf(Pvl &label, const QString &conf) :
63 DbAccess(Pvl(filepath(conf)).findObject("Hical", PvlObject::Traverse)) {
64 _profName.clear();
65 init(label);
66 }
67
73 void HiCalConf::setLabel(Pvl &label) {
74 init(label);
75 return;
76 }
77
90 QString HiCalConf::filepath(const QString &fname) const {
91 FileName efile(fname);
92 if (efile.isVersioned()) {
93 QString path(efile.originalPath());
94 if (!path.isEmpty()) path += "/";
95
96 efile = efile.highestVersion();
97
98 return (path + efile.name());
99 }
100 return (fname);
101 }
102
103
113 void HiCalConf::setConf(const QString &conf) {
114 load(Pvl(filepath(conf)).findObject("Hical", PvlObject::Traverse));
115 }
116
126 void HiCalConf::selectProfile(const QString &profile) {
127 _profName = profile;
128 return;
129 }
130
138 QString HiCalConf::getProfileName() const {
139 return (_profName);
140 }
141
155 QString HiCalConf::getMatrixSource(const QString &name) const {
156 return (getMatrixSource(name, getMatrixProfile()));
157 }
158
173 QString HiCalConf::getMatrixSource(const QString &name,
174 const DbProfile &matconf) const {
175
176 QString mfile = parser(matconf.value(name),
177 getList(matconf,"OptionKeywords"),
178 matconf);
179
180// Translate and return
181 return (filepath(mfile));
182 }
183
184 HiVector HiCalConf::getMatrix(const QString &name,
185 int expected_size) const {
186 return (getMatrix(name,getMatrixProfile(), expected_size));
187 }
188
189
190 QString HiCalConf::resolve(const QString &composite,
191 const DbProfile &matconf) const {
192 return (parser(composite,getList(matconf,"OptionKeywords"), matconf));
193 }
194
195
196
220 HiVector HiCalConf::getMatrix(const QString &name,
221 const DbProfile &profile,
222 int expected_size) const {
223
224 QString mfile = getMatrixSource(name, profile);
225
226// Crack the file and read the appropriate band
227 Cube cube;
228 cube.open(mfile);
229
230// Check for proper size if specifeid
231 if (expected_size != 0) {
232 if (cube.sampleCount() != expected_size) {
233 ostringstream mess;
234 mess << "Specifed matrix (" << name
235 << ") from file \"" << mfile
236 << "\" does not have expected samples (" << expected_size
237 << ") but has " << cube.sampleCount();
238 cube.close();
239 throw IException(IException::User, mess.str(), _FILEINFO_);
240 }
241 }
242
243// Read the specifed region
244 Brick bandio(cube.sampleCount(), 1, 1, Real);
245 bandio.SetBasePosition(1,1,getMatrixBand(profile));
246 cube.read(bandio);
247
248// Now create the output buffer with some TNT funny business
249 HiVector temp(cube.sampleCount(), bandio.DoubleBuffer());
250 HiVector out(cube.sampleCount());
251 out.inject(temp);
252 cube.close();
253 return (out);
254 }
255
270 HiVector HiCalConf::getScalar(const QString &name,
271 const DbProfile &profile,
272 int expected_size) const {
273 int nvals = profile.count(name);
274
275 // Check for proper size if specifeid
276 if (expected_size != 0) {
277 if (nvals != expected_size) {
278 ostringstream mess;
279 mess << "Specifed scalar (" << name
280 << ") does not have expected size (" << expected_size
281 << ") but has " << nvals;
282 throw IException(IException::User, mess.str(), _FILEINFO_);
283 }
284 }
285// All is OK
286 HiVector mtx(nvals, Null);
287 for (int i = 0 ; i < nvals ; i++) {
288 mtx[i] = ToDouble(profile(name, i));
289 }
290 return (mtx);
291 }
292
301 double HiCalConf::sunDistanceAU(Cube *cube) {
302 double sunkm = 0.0;
303 try {
304 Camera *cam;
305 cam = cube->camera();
306 cam->SetImage(0.5, 0.5);
307 sunkm = cam->sunToBodyDist();
308 NaifStatus::CheckErrors();
309 }
310 catch (IException &e) {
311 try {
312 QString scStartTime = getKey("SpacecraftClockStartCount", "Instrument");
313 NaifStatus::CheckErrors();
314 bool useWeb = QString(Preference::Preferences().findGroup("SpiceQL")["UseSpiceQL"]).toUpper() == "TRUE";
315 double obsStartTime = SpiceQL::strSclkToEt(-74999, scStartTime.toLatin1().data(), "hirise", useWeb).first;
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
326 std::vector<double> etStart = {obsStartTime};
327 vector<vector<double>> sunLt = SpiceQL::getTargetStates(etStart, targetName.toLatin1().data(), "sun", "J2000", "LT+S", "hirise", {"reconstructed"}, {"reconstructed"}, useWeb).first;
328 std::copy(sunLt[0].begin(), sunLt[0].begin()+3, sunv);
329
330 sunkm = vnorm_c(sunv);
331
332 NaifStatus::CheckErrors();
333 }
334 catch(IException &e) {
335 QString msg = "Unable to determine the distance from the target to the sun";
336 throw IException(e, IException::User, msg, _FILEINFO_);
337 }
338 }
339
340 // Return in AU units
341 return (sunkm/1.49597870691E8);
342 }
343
344
359 int HiCalConf::getMatrixBand() const {
360 Pvl label = _label;
361 DbProfile parms = makeParameters(label);
362 return (getMatrixBand(parms));
363 }
364
377
378 int HiCalConf::getMatrixBand(const DbProfile &p) const {
379 return (getChannelIndex(ToInteger(p("CCD")), ToInteger(p("CHANNEL"))));
380 }
381
394 HiCalConf::ValueList HiCalConf::getList(const DbProfile &profile,
395 const QString &key) const {
396 ValueList slist;
397
398// Get keyword parameters
399 if ( profile.exists(key) ) {
400 int nvals = profile.count(key);
401 for (int i = 0 ; i < nvals ; i++) {
402 slist.push_back(profile.value(key, i));
403 }
404 }
405 return (slist);
406 }
407
411void HiCalConf::init() {
412 _label.clear();
413 return;
414}
415
425void HiCalConf::init(Pvl &label) {
426 init();
427 _label = label;
428 return;
429}
430
442PvlKeyword &HiCalConf::getKey(const QString &key,
443 const QString &group) {
444 if (!group.isEmpty()) {
445 PvlGroup &grp = _label.findGroup(group, Pvl::Traverse);
446 return (grp[key]);
447 }
448 else {
449 return (_label.findKeyword(key));
450 }
451}
452
471DbProfile HiCalConf::getMatrixProfile(const QString &profile) const {
472 QString myprof = (!profile.isEmpty()) ? profile : _profName;
473 DbProfile matconf = getProfile(myprof);
474 if (!matconf.isValid()) {
475 ostringstream mess;
476 mess << "Specifed matrix profile (" << matconf.Name()
477 << ") does not exist or is invalid!";
478 throw IException(IException::User, mess.str(), _FILEINFO_);
479 }
480
481 // Profile the label and merge them. Order is important.
482 matconf = DbProfile(getLabelProfile(matconf), matconf, matconf.Name());
483
484 // Add special parameters. Again, order is important.
485 matconf = DbProfile(matconf, makeParameters(matconf), matconf.Name());
486
487// Load any optional ones
488 ValueList profkeys = getList(matconf,"OptionKeywords");
489 ValueList proforder = getList(matconf,"ProfileOptions");
490 QString pName(matconf.Name());
491 for (unsigned int i = 0 ; i < proforder.size() ; i++) {
492 QString profile = parser(proforder[i], profkeys, matconf);
493 if (profileExists(profile)) {
494 pName += "+[" + profile + "]";
495 matconf = DbProfile(matconf,getProfile(profile), pName);
496 }
497 }
498 return (matconf);
499}
500
501
502DbProfile HiCalConf::getLabelProfile(const DbProfile &profile) const {
503 DbProfile lblprof("Label");
504 if ( profile.exists("LabelGroups") ) {
505 int ngroups = profile.count("LabelGroups");
506 Pvl label = _label;
507 for ( int g = 0 ; g < ngroups ; g++ ) {
508 QString group = profile("LabelGroups", g);
509 PvlGroup grp = label.findGroup(group, Pvl::Traverse);
510 lblprof = DbProfile(lblprof,DbProfile(grp));
511 }
512 }
513 return (lblprof);
514}
515
516int HiCalConf::getChannelIndex(const int &ccd, const int &channel) const {
517 return(1 + (ccd*2) + channel);
518}
519
520DbProfile HiCalConf::makeParameters(Pvl &label) const {
521 PvlGroup inst = label.findGroup("Instrument", Pvl::Traverse);
522 DbProfile parms("Parameters");
523
524 int ccd = CpmmToCcd((int) inst["CpmmNumber"]);
525 int channel = inst["ChannelNumber"];
526 parms.add("CCD",ToString(ccd));
527 parms.add("CHANNEL", ToString(channel));
528 parms.add("TDI", inst["Tdi"]);
529 parms.add("BIN", inst["Summing"]);
530 parms.add("FILTER", CcdToFilter(ccd));
531 parms.add("CCDCHANNELINDEX", ToString(getChannelIndex(ccd, channel)));
532 return (parms);
533}
534
535DbProfile HiCalConf::makeParameters(const DbProfile &profile) const {
536 DbProfile parms("Parameters");
537 int ccd = CpmmToCcd(ToInteger(profile("CpmmNumber")));
538 int channel = ToInteger(profile("ChannelNumber"));
539 parms.add("CCD",ToString(ccd));
540 parms.add("CHANNEL", ToString(channel));
541 parms.add("TDI", profile("Tdi"));
542 parms.add("BIN", profile("Summing"));
543 parms.add("FILTER", CcdToFilter(ccd));
544 parms.add("CCDCHANNELINDEX", ToString(getChannelIndex(ccd, channel)));
545 return (parms);
546}
547
548QString HiCalConf::makePattern(const QString &str) const {
549 return (QString("{" + str + "}"));
550}
551
563QString HiCalConf::parser(const QString &s, const ValueList &vlist,
564 const DbProfile &prof) const {
565 QString sout(s);
566
567 ValueList::const_iterator ciVlist;
568 for ( ciVlist = vlist.begin() ; ciVlist != vlist.end() ; ++ciVlist ) {
569 QString str(*ciVlist);
570 if ( prof.exists(str) ) {
571 sout = sout.replace(makePattern(str), prof(str));
572 }
573 }
574
575 return (sout);
576}
577
578} // namespace Isis
DbAccess manages programatic access to a database through profiles.
Definition DbAccess.h:106
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:76
int CpmmToCcd(int cpmm)
Convert HiRISE Cpmm number to Ccd number.
Definition HiCalUtil.h:61
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:236
double ToDouble(const T &value)
Helper function to convert values to doubles.
Definition HiCalUtil.h:224
int ToInteger(const T &value)
Helper function to convert values to Integers.
Definition HiCalUtil.h:212
Namespace for the standard library.