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
Kernels.cpp
1
5
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "Kernels.h"
8
9#include <string>
10#include <vector>
11#include <numeric>
12#include <iostream>
13#include <fstream>
14#include <iomanip>
15#include <sstream>
16
17#include <QVector>
18
19#include <SpiceUsr.h>
20
21#include "FileName.h"
22#include "IException.h"
23#include "NaifStatus.h"
24#include "PvlKeyword.h"
25#include "Pvl.h"
26#include "spiceql.h"
27
28using namespace std;
29
30namespace Isis {
31
34 _kernels.clear();
35 _camVersion = -1;
36 }
37
38
53 Kernels::Kernels(const Kernels &kernels) {
54 _kernels = kernels._kernels;
55 _camVersion = kernels._camVersion;
58 }
59
78 if (this != &kernels) {
79 Clear();
80 _kernels = kernels._kernels;
81 _camVersion = kernels._camVersion;
84 }
85 return (*this);
86 }
87
93 Kernels::Kernels(const QString &filename) {
94 Pvl pvl(filename);
95 Init(pvl);
96 }
97
104 Init(*cube.label());
105 }
106
113 Init(pvl);
114 }
115
121 int Kernels::Missing() const {
122 int nMissing(0);
123 for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
124 if (!_kernels[i].exists) nMissing++;
125 }
126 return (nMissing);
127 }
128
143 void Kernels::Init(Pvl &pvl) {
144 UnLoad();
145 _kernels.clear();
146 addKernels(findKernels(pvl, "TargetPosition"));
147 addKernels(findKernels(pvl, "InstrumentPosition"));
148 addKernels(findKernels(pvl, "InstrumentPointing"));
149 addKernels(findKernels(pvl, "Frame"));
150 addKernels(findKernels(pvl, "TargetAttitudeShape"));
151 addKernels(findKernels(pvl, "Instrument"));
152 addKernels(findKernels(pvl, "InstrumentAddendum"));
153 addKernels(findKernels(pvl, "LeapSecond"));
154 addKernels(findKernels(pvl, "SpacecraftClock"));
155 addKernels(findKernels(pvl, "ShapeModel"));
156 addKernels(findKernels(pvl, "Extra"));
157 _camVersion = getCameraVersion(pvl);
158 return;
159 }
160
179 bool Kernels::Add(const QString &kfile) {
180 if (!findByName(kfile)) {
181 _kernels.push_back(examine(kfile, true));
182 return (true);
183 }
184 return (false);
185 }
186
197 _kernels.clear();
198 }
199
237 _kernels.clear();
238 SpiceInt count;
240 ktotal_c("ALL", &count);
241 int nfound(0);
242 for (int i = 0 ; i < count ; i++) {
243 SpiceChar file[128];
244 SpiceChar ktype[32];
245 SpiceChar source[128];
246 SpiceInt handle;
247 SpiceBoolean found;
248 kdata_c(i, "ALL", sizeof(file), sizeof(ktype), sizeof(source),
249 file, ktype,source, &handle, &found);
250 if (found == SPICETRUE) {
251 _kernels.push_back(examine(file, false));
252 nfound++;
253 }
254 }
256 return (nfound);
257 }
258
259
271 for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
272 _kernels[i].managed = true;
273 }
274 return;
275 }
276
277
290 for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
291 _kernels[i].managed = false;
292 }
293 return;
294 }
295
309 bool Kernels::IsManaged() const {
310 for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
311 if (!_kernels[i].managed) return (false);;
312 }
313 return (true);
314 }
315
316
336 kclear_c();
338 for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
339 _kernels[i].loaded = false;
340 }
341 return;
342 }
343
344
365 int Kernels::Load(const QString &ktypes) {
366 // If no types specified, return them all
367 int nLoaded(0);
368 if (ktypes.isEmpty()) {
369 for (unsigned int k = 0 ; k < _kernels.size() ; k++) {
370 if (Load(_kernels[k])) { nLoaded++; }
371 }
372 }
373 else {
374 // Find types and return requested types
375 QStringList tlist = getTypes(ktypes);
376 for (int t = 0 ; t < tlist.size() ; t++) {
377 for (unsigned int k = 0; k < _kernels.size() ; k++) {
378 if (_kernels[k].ktype == tlist[t]) {
379 if (Load(_kernels[k])) { nLoaded++; }
380 }
381 }
382 }
383 }
384 return (nLoaded);
385 }
386
387
407 // If not types specified, return them all
408 int nLoaded(0);
409 for (unsigned int k = 0 ; k < _kernels.size() ; k++) {
410 if (Load(_kernels[k])) { nLoaded++; }
411 }
412 return (nLoaded);
413 }
414
415
427 int nUnloaded(0);
428 for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
429 if (UnLoad(_kernels[i])) nUnloaded++;
430 }
431 return (nUnloaded);
432 }
433
454 int Kernels::UnLoad(const QString &ktypes) {
455 // If not types specified, return them all
456 int nUnloaded(0);
457 if (ktypes.isEmpty()) {
458 nUnloaded = UnLoad();
459 }
460 else {
461 // Find types and return requested types
462 QStringList tlist = getTypes(ktypes);
463 for (int t = 0 ; t < tlist.size() ; t++) {
464 for (unsigned int k = 0; k < _kernels.size() ; k++) {
465 if (_kernels[k].ktype == tlist[t]) {
466 if (UnLoad(_kernels[k])) nUnloaded++;
467 }
468 }
469 }
470 }
471 return (nUnloaded);
472 }
473
493 int nchanged(0);
494 for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
495 // Use NAIF to determine if it is loaded
496 if (IsNaifType(_kernels[i].ktype)) {
497 SpiceChar ktype[32];
498 SpiceChar source[128];
499 SpiceInt handle;
500 SpiceBoolean found;
501
503 kinfo_c(_kernels[i].fullpath.toLatin1().data(), sizeof(ktype), sizeof(source),
504 ktype,source, &handle, &found);
506
507 if (found == SPICETRUE) {
508 if (!_kernels[i].loaded) nchanged++;
509 _kernels[i].loaded = true;
510 }
511 else {
512 if (_kernels[i].loaded) nchanged++;
513 _kernels[i].loaded = false;
514 }
515 }
516 }
517
518 return (nchanged);
519 }
520
541 int nchanged(0);
542 for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
543 if (_kernels[i].loaded) {
544 _kernels[i].managed = false;
545 nchanged++;
546 }
547 else {
548 _kernels[i].managed = true;
549 }
550 }
551 return (nchanged);
552 }
553
600 int Kernels::Merge(const Kernels &other) {
601 int nAdded(0);
602 for (unsigned int i = 0 ; i < other._kernels.size() ; i++) {
603 KernelFile *kernel = findByName(other._kernels[i].fullpath);
604 if (kernel == 0) {
605 KernelFile kfile = other._kernels[i];
606 kfile.managed = false;
607 _kernels.push_back(kfile);
608 nAdded++;
609 }
610 else {
611 if (other._kernels[i].loaded) {
612 kernel->loaded = true;
613 kernel->managed = false;
614 }
615 }
616 }
617 return (nAdded);
618 }
619
620
652 TypeList kmap = categorizeByType();
653 QStringList types;
654 for (int i = 0 ; i < kmap.size() ; i++) {
655 types.append(kmap.key(i));
656 }
657 return (types);
658 }
659
660
673 QStringList Kernels::getKernelList(const QString &ktypes) const {
674
675 // If not types specified, return them all
676 QStringList flist;
677 if (ktypes.isEmpty()) {
678 for (unsigned int k = 0; k < _kernels.size() ; k++) {
679 flist.push_back(_kernels[k].pathname);
680 }
681 }
682 else {
683 // Find types and return requested types
684 QStringList tlist = getTypes(ktypes);
685 for (int t = 0 ; t < tlist.size() ; t++) {
686 for (unsigned int k = 0; k < _kernels.size() ; k++) {
687 if (_kernels[k].ktype == tlist[t]) {
688 flist.push_back(_kernels[k].pathname);
689 }
690 }
691 }
692 }
693 return (flist);
694 }
695
696
721 QStringList Kernels::getLoadedList(const QString &ktypes)
722 const {
723 QStringList flist;
724 if (ktypes.isEmpty()) {
725 for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
726 if (_kernels[i].loaded) flist.push_back(_kernels[i].pathname);
727 }
728 }
729 else {
730 QStringList tlist = getTypes(ktypes);
731 for (int t = 0 ; t < tlist.size() ; t++ ) {
732 for (unsigned int k = 0; k < _kernels.size() ; k++) {
733 if (_kernels[k].ktype == tlist[t]) {
734 flist.push_back(_kernels[k].pathname);
735 }
736 }
737 }
738 }
739 return (flist);
740 }
741
742
754 QStringList flist;
755 for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
756 if (!_kernels[i].exists) flist.push_back(_kernels[i].pathname);
757 }
758 return (flist);
759 }
760
776 if (IsNaifType(kfile.ktype)) {
777 if (!kfile.loaded) {
779 try {
780 SpiceQL::load(kfile.fullpath.toLatin1().data());
782 kfile.loaded = true;
783 kfile.managed = true;
784 }
785 catch (IException &ie) {
786 return (false);
787 }
788 }
789 }
790 return (kfile.loaded);
791 }
792
816 // If its loaded assume its a loaded NAIF kernel and unload it
817 bool wasLoaded(false);
818 if (kfile.loaded) {
819 if (kfile.managed) {
821 try {
822 unload_c(kfile.fullpath.toLatin1().data());
824 }
825 catch (IException &) {
826 // Errors are trapped and ignored. It may be unloaded by other source
827 }
828 kfile.loaded = false;
829 wasLoaded = true;
830 }
831 }
832 return (wasLoaded);
833 }
834
866 QStringList Kernels::getTypes(const QString &ktypes) const {
867 // Find types and return requested types
868 QStringList tlist = ktypes.split(",");
869 for (int k = 0 ; k < tlist.size() ; k++) {
870 tlist[k] = IString(tlist[k]).Trim(" \r\n\t\v\b\f").UpCase().ToQt();
871 }
872 return (tlist);
873 }
874
882 void Kernels::addKernels(const KernelList &klist) {
883 copy(klist.begin(), klist.end(), back_inserter(_kernels));
884 return;
885 }
886
887
904 Kernels::KernelList Kernels::findKernels(Pvl &pvl,
905 const QString &kname,
906 const bool &manage) {
907 KernelList klist;
908 // Get the kernel group and load main kernels
909 PvlGroup &kernels = pvl.findGroup("Kernels",Pvl::Traverse);
910 // Check for the keyword
911 if (kernels.hasKeyword(kname)) {
912 PvlKeyword &kkey = kernels[kname];
913 for (int i = 0 ; i < kkey.size() ; i++) {
914 if (!kkey.isNull(i)) {
915 if (kkey[i].toLower() != "table") {
916 klist.push_back(examine(kkey[i], manage));
917 }
918 }
919 }
920 }
921
922 return (klist);
923 }
924
925
951 KernelList::iterator klist;
952 for (klist = _kernels.begin() ; klist != _kernels.end() ; ++klist) {
953 if (klist->pathname == kfile) { return (&(*klist)); }
954 if (klist->name == kfile) { return (&(*klist)); }
955 if (klist->fullpath == kfile) { return (&(*klist)); }
956 }
957 return (0);
958 }
959
960
969 Kernels::TypeList Kernels::categorizeByType() const {
970 TypeList ktypes;
971 for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
972 KernelFile *kfile = const_cast<KernelFile *> (&_kernels[i]);
973 if (ktypes.exists(_kernels[i].ktype)) {
974 ktypes.get(_kernels[i].ktype).push_back(kfile);
975 }
976 else {
977 ktypes.add(_kernels[i].ktype, KernelFileList(1, kfile));
978 }
979 }
980 return (ktypes);
981 }
982
983
992 bool Kernels::IsNaifType(const QString &ktype) const {
993 if (ktype.toUpper() == "UNKNOWN") return (false);
994 if (ktype.toUpper() == "DEM") return (false);
995 return (true);
996 }
997
1046 const bool &manage) const {
1047
1048 FileName kernfile(kfile);
1049 KernelFile kf;
1050 kf.pathname = kfile;
1051 kf.name = kernfile.name();
1052 kf.fullpath = kernfile.expanded();
1053 kf.exists = kernfile.fileExists();
1054 kf.ktype = "UNKNOWN";
1055 kf.loaded = false; // Assumes its not loaded
1056 kf.managed = manage;
1057
1058 // Determine type and load info
1059 if (kf.exists) {
1060 kf.ktype = resolveType(kf.fullpath);
1061
1062 // Use NAIF to determine if it is loaded
1063 if (IsNaifType(kf.ktype)) {
1064 SpiceChar ktype[32];
1065 SpiceChar source[128];
1066 SpiceInt handle;
1067 SpiceBoolean found;
1068
1070 kinfo_c(kf.fullpath.toLatin1().data(), sizeof(ktype), sizeof(source), ktype,
1071 source, &handle, &found);
1073
1074 if (found == SPICETRUE) {
1075 kf.loaded = true;
1076 kf.managed = false;
1077 kf.ktype = IString(ktype).UpCase().ToQt();
1078 }
1079 }
1080 }
1081
1082 return (kf);
1083 }
1084
1109 QString Kernels::resolveType(const QString &kfile) const {
1110 FileName kernFile(kfile);
1111 QString kpath = kernFile.expanded();
1112 ifstream ifile(kpath.toLatin1().data(), ios::in | ios::binary);
1113 QString ktype("UNKNOWN");
1114 if (ifile) {
1115 char ibuf[10];
1116 ifile.read(ibuf, 8);
1117 ibuf[8] = '\0';
1118 for (int i = 0 ; i < 8 ; i++)
1119 if (ibuf[i] == '\n') ibuf[i] = '\0';
1120
1121 // See if the file is a known NAIF type. Assume it has been
1122 // extracted from a NAIF compliant kernel
1123 QString istr = IString(ibuf).Trim(" \n\r\f\t\v\b").ToQt();
1124 if (istr.contains("/")) {
1125 ktype = istr.split("/").last();
1126 }
1127
1128 // If type is not resolved, check file extensions and special ISIS types
1129 if ((ktype == "UNKNOWN") || (ktype == "DAF")) {
1130 ktype = resolveTypeByExt(kfile, ktype);
1131 }
1132
1133 }
1134 return (ktype);
1135 }
1136
1182 QString Kernels::resolveTypeByExt(const QString &kfile,
1183 const QString &iktype) const {
1184
1185 QString ktype(iktype); // Set default condition
1186
1187 // Deciminate file parts
1188 FileName kf(kfile);
1189 string ext = IString(kf.extension()).DownCase();
1190
1191 // Check extensions for types
1192 if (ext == "cub") {
1193 ktype = "DEM";
1194 }
1195 else if (ext == "ti") {
1196 // Assume its an instrument kernel but check for ISIS IAK file
1197 ktype = "IK";
1198 string base = IString(kf.baseName()).DownCase();
1199 string::size_type idx = base.find("addendum");
1200 if (idx != string::npos) { // This is an ISIS IK addendum (IAK)
1201 ktype = "IAK";
1202 }
1203 }
1204 else if (ext == "tsc") {
1205 ktype = "SCLK";
1206 }
1207 else if (ext == "tf") {
1208 ktype = "FK";
1209 }
1210 else if (ext == "tls") {
1211 ktype = "LSK";
1212 }
1213 else if (ext == "tpc") {
1214 ktype = "PCK";
1215 }
1216 else if (ext == "bc") {
1217 ktype = "CK";
1218 }
1219 else if (ext == "bsp") {
1220 ktype = "SPK";
1221 }
1222 else if (ext == "bes") {
1223 ktype = "EK";
1224 }
1225 else if (ext == "bds") {
1226 ktype = "DSK";
1227 }
1228 else if (ext == "meta") {
1229 ktype = "META";
1230 }
1231 return (ktype);
1232 }
1233
1234
1235
1249 int Kernels::getCameraVersion(Pvl &pvl) const {
1250 PvlGroup &kernels = pvl.findGroup("Kernels",Pvl::Traverse);
1251 int cv(0);
1252 // Check for the keyword
1253 if (kernels.hasKeyword("CameraVersion")) {
1254 PvlKeyword &kkey = kernels["CameraVersion"];
1255 cv = IString(kkey[0]).ToInteger();
1256 }
1257 return (cv);
1258 }
1259
1260} // namespace Isis
1261
1262
const K & key(int nth) const
Returns the nth key in the collection.
int size() const
Returns the size of the collection.
T & get(const K &key)
Returns the value associated with the name provided.
bool exists(const K &key) const
Checks the existance of a particular key in the list.
void add(const K &key, const T &value)
Adds the element to the list.
IO Handler for Isis Cubes.
Definition Cube.h:168
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition Cube.cpp:1975
int UpdateManagedStatus()
Update the managed state of the kernel file list.
Definition Kernels.cpp:540
void InitializeNaifKernelPool()
Initialize the NAIF kernel keeper pool.
Definition Kernels.cpp:334
bool Add(const QString &kfile)
Add a new kernel to the list.
Definition Kernels.cpp:179
bool IsNaifType(const QString &ktype) const
Determine if the type is a NAIF supported kernel type.
Definition Kernels.cpp:992
void Manage()
Set each kernels management status to managed.
Definition Kernels.cpp:270
KernelFile examine(const QString &fname, const bool &manage=true) const
Determine type of NAIF kernel file.
Definition Kernels.cpp:1045
int Discover()
Determine which NAIF kernels are currently loaded in the pool.
Definition Kernels.cpp:236
int getCameraVersion(Pvl &pvl) const
Determine the ISIS camera model version number.
Definition Kernels.cpp:1249
int UpdateLoadStatus()
Determine the load status of all kernels known to this object.
Definition Kernels.cpp:492
QStringList getTypes(const QString &ktypes) const
Get a vector of comma separated types from a string.
Definition Kernels.cpp:866
KernelFile * findByName(const QString &kfile)
Search kernel file list of a particular pattern.
Definition Kernels.cpp:950
void Init(Pvl &pvl)
Determine Spice kernels in an ISIS label.
Definition Kernels.cpp:143
QString resolveType(const QString &kfile) const
Determines type of NAIF/ISIS kernel we're dealing with.
Definition Kernels.cpp:1109
Kernels()
Default Constructor.
Definition Kernels.cpp:33
QStringList getKernelList(const QString &ktype="") const
Provide a list of all the kernels found.
Definition Kernels.cpp:673
QString resolveTypeByExt(const QString &kfile, const QString &iktype="UNKNOWN") const
Check kernel type by file extension and special ISIS kernels.
Definition Kernels.cpp:1182
void Clear()
Remove all kernel files from internal list.
Definition Kernels.cpp:196
void addKernels(const KernelList &klist)
Add a list of kernel files to internal storage.
Definition Kernels.cpp:882
QStringList getLoadedList(const QString &ktypes="") const
Returns list of kernel currently loaded according to status.
Definition Kernels.cpp:721
int Missing() const
Return count of missing kernel files.
Definition Kernels.cpp:121
bool IsManaged() const
Determine if all kernels are managed by this object.
Definition Kernels.cpp:309
TypeList categorizeByType() const
Categorizes the kernel list by type.
Definition Kernels.cpp:969
std::vector< KernelFile > findKernels(Pvl &pvl, const QString &kname, const bool &manage=true)
Retrieve contents of keyword.
Definition Kernels.cpp:904
int UnLoad()
Unloads all kernels from the NAIF pool.
Definition Kernels.cpp:426
QStringList getMissingList() const
Returns list of kernels that were not found to exist.
Definition Kernels.cpp:753
int Merge(const Kernels &other)
Merge the contents of another Kernels object.
Definition Kernels.cpp:600
int Load()
Load all kernels in list.
Definition Kernels.cpp:406
QStringList getKernelTypes() const
Return list of types in kernel list.
Definition Kernels.cpp:651
Kernels & operator=(const Kernels &kernels)
Copy constructor for existing Kernels objecr.
Definition Kernels.cpp:77
void UnManage()
Set each kernels' management state to unmanaged.
Definition Kernels.cpp:289
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
Namespace for the standard library.