File failed to load: https://isis.astrogeology.usgs.gov/6.0.0/Object/assets/jax/output/NativeMML/config.js
Isis 3 Programmer Reference
Kernels.cpp
1 
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 
27 using namespace std;
28 
29 namespace Isis {
30 
32  Kernels::Kernels() {
33  _kernels.clear();
34  _camVersion = -1;
35  }
36 
37 
52  Kernels::Kernels(const Kernels &kernels) {
53  _kernels = kernels._kernels;
54  _camVersion = kernels._camVersion;
55  UpdateLoadStatus();
56  UpdateManagedStatus();
57  }
58 
76  Kernels &Kernels::operator=(const Kernels &kernels) {
77  if (this != &kernels) {
78  Clear();
79  _kernels = kernels._kernels;
80  _camVersion = kernels._camVersion;
81  UpdateLoadStatus();
82  UpdateManagedStatus();
83  }
84  return (*this);
85  }
86 
92  Kernels::Kernels(const QString &filename) {
93  Pvl pvl(filename);
94  Init(pvl);
95  }
96 
102  Kernels::Kernels(Cube &cube) {
103  Init(*cube.label());
104  }
105 
111  Kernels::Kernels(Pvl &pvl) {
112  Init(pvl);
113  }
114 
120  int Kernels::Missing() const {
121  int nMissing(0);
122  for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
123  if (!_kernels[i].exists) nMissing++;
124  }
125  return (nMissing);
126  }
127 
142  void Kernels::Init(Pvl &pvl) {
143  UnLoad();
144  _kernels.clear();
145  addKernels(findKernels(pvl, "TargetPosition"));
146  addKernels(findKernels(pvl, "InstrumentPosition"));
147  addKernels(findKernels(pvl, "InstrumentPointing"));
148  addKernels(findKernels(pvl, "Frame"));
149  addKernels(findKernels(pvl, "TargetAttitudeShape"));
150  addKernels(findKernels(pvl, "Instrument"));
151  addKernels(findKernels(pvl, "InstrumentAddendum"));
152  addKernels(findKernels(pvl, "LeapSecond"));
153  addKernels(findKernels(pvl, "SpacecraftClock"));
154  addKernels(findKernels(pvl, "ShapeModel"));
155  addKernels(findKernels(pvl, "Extra"));
156  _camVersion = getCameraVersion(pvl);
157  return;
158  }
159 
178  bool Kernels::Add(const QString &kfile) {
179  if (!findByName(kfile)) {
180  _kernels.push_back(examine(kfile, true));
181  return (true);
182  }
183  return (false);
184  }
185 
195  void Kernels::Clear() {
196  _kernels.clear();
197  }
198 
235  int Kernels::Discover() {
236  _kernels.clear();
237  SpiceInt count;
238  NaifStatus::CheckErrors();
239  ktotal_c("ALL", &count);
240  int nfound(0);
241  for (int i = 0 ; i < count ; i++) {
242  SpiceChar file[128];
243  SpiceChar ktype[32];
244  SpiceChar source[128];
245  SpiceInt handle;
246  SpiceBoolean found;
247  kdata_c(i, "ALL", sizeof(file), sizeof(ktype), sizeof(source),
248  file, ktype,source, &handle, &found);
249  if (found == SPICETRUE) {
250  _kernels.push_back(examine(file, false));
251  nfound++;
252  }
253  }
254  NaifStatus::CheckErrors();
255  return (nfound);
256  }
257 
258 
269  void Kernels::Manage() {
270  for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
271  _kernels[i].managed = true;
272  }
273  return;
274  }
275 
276 
288  void Kernels::UnManage() {
289  for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
290  _kernels[i].managed = false;
291  }
292  return;
293  }
294 
308  bool Kernels::IsManaged() const {
309  for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
310  if (!_kernels[i].managed) return (false);;
311  }
312  return (true);
313  }
314 
315 
333  void Kernels::InitializeNaifKernelPool() {
334  NaifStatus::CheckErrors();
335  kclear_c();
336  NaifStatus::CheckErrors();
337  for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
338  _kernels[i].loaded = false;
339  }
340  return;
341  }
342 
343 
364  int Kernels::Load(const QString &ktypes) {
365  // If no types specified, return them all
366  int nLoaded(0);
367  if (ktypes.isEmpty()) {
368  for (unsigned int k = 0 ; k < _kernels.size() ; k++) {
369  if (Load(_kernels[k])) { nLoaded++; }
370  }
371  }
372  else {
373  // Find types and return requested types
374  QStringList tlist = getTypes(ktypes);
375  for (int t = 0 ; t < tlist.size() ; t++) {
376  for (unsigned int k = 0; k < _kernels.size() ; k++) {
377  if (_kernels[k].ktype == tlist[t]) {
378  if (Load(_kernels[k])) { nLoaded++; }
379  }
380  }
381  }
382  }
383  return (nLoaded);
384  }
385 
386 
405  int Kernels::Load() {
406  // If not types specified, return them all
407  int nLoaded(0);
408  for (unsigned int k = 0 ; k < _kernels.size() ; k++) {
409  if (Load(_kernels[k])) { nLoaded++; }
410  }
411  return (nLoaded);
412  }
413 
414 
425  int Kernels::UnLoad() {
426  int nUnloaded(0);
427  for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
428  if (UnLoad(_kernels[i])) nUnloaded++;
429  }
430  return (nUnloaded);
431  }
432 
453  int Kernels::UnLoad(const QString &ktypes) {
454  // If not types specified, return them all
455  int nUnloaded(0);
456  if (ktypes.isEmpty()) {
457  nUnloaded = UnLoad();
458  }
459  else {
460  // Find types and return requested types
461  QStringList tlist = getTypes(ktypes);
462  for (int t = 0 ; t < tlist.size() ; t++) {
463  for (unsigned int k = 0; k < _kernels.size() ; k++) {
464  if (_kernels[k].ktype == tlist[t]) {
465  if (UnLoad(_kernels[k])) nUnloaded++;
466  }
467  }
468  }
469  }
470  return (nUnloaded);
471  }
472 
491  int Kernels::UpdateLoadStatus() {
492  int nchanged(0);
493  for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
494  // Use NAIF to determine if it is loaded
495  if (IsNaifType(_kernels[i].ktype)) {
496  SpiceChar ktype[32];
497  SpiceChar source[128];
498  SpiceInt handle;
499  SpiceBoolean found;
500 
501  NaifStatus::CheckErrors();
502  kinfo_c(_kernels[i].fullpath.toLatin1().data(), sizeof(ktype), sizeof(source),
503  ktype,source, &handle, &found);
504  NaifStatus::CheckErrors();
505 
506  if (found == SPICETRUE) {
507  if (!_kernels[i].loaded) nchanged++;
508  _kernels[i].loaded = true;
509  }
510  else {
511  if (_kernels[i].loaded) nchanged++;
512  _kernels[i].loaded = false;
513  }
514  }
515  }
516 
517  return (nchanged);
518  }
519 
539  int Kernels::UpdateManagedStatus() {
540  int nchanged(0);
541  for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
542  if (_kernels[i].loaded) {
543  _kernels[i].managed = false;
544  nchanged++;
545  }
546  else {
547  _kernels[i].managed = true;
548  }
549  }
550  return (nchanged);
551  }
552 
599  int Kernels::Merge(const Kernels &other) {
600  int nAdded(0);
601  for (unsigned int i = 0 ; i < other._kernels.size() ; i++) {
602  KernelFile *kernel = findByName(other._kernels[i].fullpath);
603  if (kernel == 0) {
604  KernelFile kfile = other._kernels[i];
605  kfile.managed = false;
606  _kernels.push_back(kfile);
607  nAdded++;
608  }
609  else {
610  if (other._kernels[i].loaded) {
611  kernel->loaded = true;
612  kernel->managed = false;
613  }
614  }
615  }
616  return (nAdded);
617  }
618 
619 
650  QStringList Kernels::getKernelTypes() const {
651  TypeList kmap = categorizeByType();
652  QStringList types;
653  for (int i = 0 ; i < kmap.size() ; i++) {
654  types.append(kmap.key(i));
655  }
656  return (types);
657  }
658 
659 
672  QStringList Kernels::getKernelList(const QString &ktypes) const {
673 
674  // If not types specified, return them all
675  QStringList flist;
676  if (ktypes.isEmpty()) {
677  for (unsigned int k = 0; k < _kernels.size() ; k++) {
678  flist.push_back(_kernels[k].pathname);
679  }
680  }
681  else {
682  // Find types and return requested types
683  QStringList tlist = getTypes(ktypes);
684  for (int t = 0 ; t < tlist.size() ; t++) {
685  for (unsigned int k = 0; k < _kernels.size() ; k++) {
686  if (_kernels[k].ktype == tlist[t]) {
687  flist.push_back(_kernels[k].pathname);
688  }
689  }
690  }
691  }
692  return (flist);
693  }
694 
695 
720  QStringList Kernels::getLoadedList(const QString &ktypes)
721  const {
722  QStringList flist;
723  if (ktypes.isEmpty()) {
724  for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
725  if (_kernels[i].loaded) flist.push_back(_kernels[i].pathname);
726  }
727  }
728  else {
729  QStringList tlist = getTypes(ktypes);
730  for (int t = 0 ; t < tlist.size() ; t++ ) {
731  for (unsigned int k = 0; k < _kernels.size() ; k++) {
732  if (_kernels[k].ktype == tlist[t]) {
733  flist.push_back(_kernels[k].pathname);
734  }
735  }
736  }
737  }
738  return (flist);
739  }
740 
741 
752  QStringList Kernels::getMissingList() const {
753  QStringList flist;
754  for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
755  if (!_kernels[i].exists) flist.push_back(_kernels[i].pathname);
756  }
757  return (flist);
758  }
759 
774  bool Kernels::Load(Kernels::KernelFile &kfile) {
775  if (IsNaifType(kfile.ktype)) {
776  if (!kfile.loaded) {
777  NaifStatus::CheckErrors();
778  try {
779  furnsh_c(kfile.fullpath.toLatin1().data());
780  NaifStatus::CheckErrors();
781  kfile.loaded = true;
782  kfile.managed = true;
783  }
784  catch (IException &ie) {
785  return (false);
786  }
787  }
788  }
789  return (kfile.loaded);
790  }
791 
814  bool Kernels::UnLoad(KernelFile &kfile) {
815  // If its loaded assume its a loaded NAIF kernel and unload it
816  bool wasLoaded(false);
817  if (kfile.loaded) {
818  if (kfile.managed) {
819  NaifStatus::CheckErrors();
820  try {
821  unload_c(kfile.fullpath.toLatin1().data());
822  NaifStatus::CheckErrors();
823  }
824  catch (IException &) {
825  // Errors are trapped and ignored. It may be unloaded by other source
826  }
827  kfile.loaded = false;
828  wasLoaded = true;
829  }
830  }
831  return (wasLoaded);
832  }
833 
865  QStringList Kernels::getTypes(const QString &ktypes) const {
866  // Find types and return requested types
867  QStringList tlist = ktypes.split(",");
868  for (int k = 0 ; k < tlist.size() ; k++) {
869  tlist[k] = IString(tlist[k]).Trim(" \r\n\t\v\b\f").UpCase().ToQt();
870  }
871  return (tlist);
872  }
873 
881  void Kernels::addKernels(const KernelList &klist) {
882  copy(klist.begin(), klist.end(), back_inserter(_kernels));
883  return;
884  }
885 
886 
903  Kernels::KernelList Kernels::findKernels(Pvl &pvl,
904  const QString &kname,
905  const bool &manage) {
906  KernelList klist;
907  // Get the kernel group and load main kernels
908  PvlGroup &kernels = pvl.findGroup("Kernels",Pvl::Traverse);
909  // Check for the keyword
910  if (kernels.hasKeyword(kname)) {
911  PvlKeyword &kkey = kernels[kname];
912  for (int i = 0 ; i < kkey.size() ; i++) {
913  if (!kkey.isNull(i)) {
914  if (kkey[i].toLower() != "table") {
915  klist.push_back(examine(kkey[i], manage));
916  }
917  }
918  }
919  }
920 
921  return (klist);
922  }
923 
924 
949  Kernels::KernelFile *Kernels::findByName(const QString &kfile) {
950  KernelList::iterator klist;
951  for (klist = _kernels.begin() ; klist != _kernels.end() ; ++klist) {
952  if (klist->pathname == kfile) { return (&(*klist)); }
953  if (klist->name == kfile) { return (&(*klist)); }
954  if (klist->fullpath == kfile) { return (&(*klist)); }
955  }
956  return (0);
957  }
958 
959 
968  Kernels::TypeList Kernels::categorizeByType() const {
969  TypeList ktypes;
970  for (unsigned int i = 0 ; i < _kernels.size() ; i++) {
971  KernelFile *kfile = const_cast<KernelFile *> (&_kernels[i]);
972  if (ktypes.exists(_kernels[i].ktype)) {
973  ktypes.get(_kernels[i].ktype).push_back(kfile);
974  }
975  else {
976  ktypes.add(_kernels[i].ktype, KernelFileList(1, kfile));
977  }
978  }
979  return (ktypes);
980  }
981 
982 
991  bool Kernels::IsNaifType(const QString &ktype) const {
992  if (ktype.toUpper() == "UNKNOWN") return (false);
993  if (ktype.toUpper() == "DEM") return (false);
994  return (true);
995  }
1044  Kernels::KernelFile Kernels::examine(const QString &kfile,
1045  const bool &manage) const {
1046 
1047  FileName kernfile(kfile);
1048  KernelFile kf;
1049  kf.pathname = kfile;
1050  kf.name = kernfile.name();
1051  kf.fullpath = kernfile.expanded();
1052  kf.exists = kernfile.fileExists();
1053  kf.ktype = "UNKNOWN";
1054  kf.loaded = false; // Assumes its not loaded
1055  kf.managed = manage;
1056 
1057  // Determine type and load info
1058  if (kf.exists) {
1059  kf.ktype = resolveType(kf.fullpath);
1060 
1061  // Use NAIF to determine if it is loaded
1062  if (IsNaifType(kf.ktype)) {
1063  SpiceChar ktype[32];
1064  SpiceChar source[128];
1065  SpiceInt handle;
1066  SpiceBoolean found;
1067 
1068  NaifStatus::CheckErrors();
1069  kinfo_c(kf.fullpath.toLatin1().data(), sizeof(ktype), sizeof(source), ktype,
1070  source, &handle, &found);
1071  NaifStatus::CheckErrors();
1072 
1073  if (found == SPICETRUE) {
1074  kf.loaded = true;
1075  kf.managed = false;
1076  kf.ktype = IString(ktype).UpCase().ToQt();
1077  }
1078  }
1079  }
1080 
1081  return (kf);
1082  }
1083 
1108  QString Kernels::resolveType(const QString &kfile) const {
1109  FileName kernFile(kfile);
1110  QString kpath = kernFile.expanded();
1111  ifstream ifile(kpath.toLatin1().data(), ios::in | ios::binary);
1112  QString ktype("UNKNOWN");
1113  if (ifile) {
1114  char ibuf[10];
1115  ifile.read(ibuf, 8);
1116  ibuf[8] = '\0';
1117  for (int i = 0 ; i < 8 ; i++)
1118  if (ibuf[i] == '\n') ibuf[i] = '\0';
1119 
1120  // See if the file is a known NAIF type. Assume it has been
1121  // extracted from a NAIF compliant kernel
1122  QString istr = IString(ibuf).Trim(" \n\r\f\t\v\b").ToQt();
1123  if (istr.contains("/")) {
1124  ktype = istr.split("/").last();
1125  }
1126 
1127  // If type is not resolved, check file extensions and special ISIS types
1128  if ((ktype == "UNKNOWN") || (ktype == "DAF")) {
1129  ktype = resolveTypeByExt(kfile, ktype);
1130  }
1131 
1132  }
1133  return (ktype);
1134  }
1135 
1181  QString Kernels::resolveTypeByExt(const QString &kfile,
1182  const QString &iktype) const {
1183 
1184  QString ktype(iktype); // Set default condition
1185 
1186  // Deciminate file parts
1187  FileName kf(kfile);
1188  string ext = IString(kf.extension()).DownCase();
1189 
1190  // Check extensions for types
1191  if (ext == "cub") {
1192  ktype = "DEM";
1193  }
1194  else if (ext == "ti") {
1195  // Assume its an instrument kernel but check for ISIS IAK file
1196  ktype = "IK";
1197  string base = IString(kf.baseName()).DownCase();
1198  string::size_type idx = base.find("addendum");
1199  if (idx != string::npos) { // This is an ISIS IK addendum (IAK)
1200  ktype = "IAK";
1201  }
1202  }
1203  else if (ext == "tsc") {
1204  ktype = "SCLK";
1205  }
1206  else if (ext == "tf") {
1207  ktype = "FK";
1208  }
1209  else if (ext == "tls") {
1210  ktype = "LSK";
1211  }
1212  else if (ext == "tpc") {
1213  ktype = "PCK";
1214  }
1215  else if (ext == "bc") {
1216  ktype = "CK";
1217  }
1218  else if (ext == "bsp") {
1219  ktype = "SPK";
1220  }
1221  else if (ext == "bes") {
1222  ktype = "EK";
1223  }
1224  else if (ext == "bds") {
1225  ktype = "DSK";
1226  }
1227  else if (ext == "meta") {
1228  ktype = "META";
1229  }
1230  return (ktype);
1231  }
1232 
1233 
1234 
1248  int Kernels::getCameraVersion(Pvl &pvl) const {
1249  PvlGroup &kernels = pvl.findGroup("Kernels",Pvl::Traverse);
1250  int cv(0);
1251  // Check for the keyword
1252  if (kernels.hasKeyword("CameraVersion")) {
1253  PvlKeyword &kkey = kernels["CameraVersion"];
1254  cv = IString(kkey[0]).ToInteger();
1255  }
1256  return (cv);
1257  }
1258 
1259 } // namespace Isis
1260 
1261 
Isis::PvlObject::findGroup
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:129
Isis::IString::DownCase
IString DownCase()
Converts all upper case letters in the object IString into lower case characters.
Definition: IString.cpp:644
Isis::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
Isis::Kernels
Determine SPICE kernels defined in an ISIS file.
Definition: Kernels.h:94
Isis::FileName::name
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition: FileName.cpp:162
Isis::FileName
File name manipulation and expansion.
Definition: FileName.h:100
Isis::FileName::fileExists
bool fileExists() const
Returns true if the file exists; false otherwise.
Definition: FileName.cpp:449
Isis::IString::Trim
IString Trim(const std::string &chars)
Removes characters from the beginning and end of the IString.
Definition: IString.cpp:525
Isis::CollectorMap::get
T & get(const K &key)
Returns the value associated with the name provided.
Definition: CollectorMap.h:567
Isis::CollectorMap::size
int size() const
Returns the size of the collection.
Definition: CollectorMap.h:512
Isis::PvlContainer::hasKeyword
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Definition: PvlContainer.cpp:159
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::IString::ToInteger
int ToInteger() const
Returns the object string as an integer.
Definition: IString.cpp:718
QStringList
Isis::FileName::baseName
QString baseName() const
Returns the name of the file without the path and without extensions.
Definition: FileName.cpp:145
Isis::IString::UpCase
IString UpCase()
Converst any lower case characters in the object IString with uppercase characters.
Definition: IString.cpp:617
Isis::CollectorMap::exists
bool exists(const K &key) const
Checks the existance of a particular key in the list.
Definition: CollectorMap.h:551
Isis::FileName::expanded
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:196
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::CollectorMap::key
const K & key(int nth) const
Returns the nth key in the collection.
Definition: CollectorMap.h:673
Isis::Kernels::KernelFile
Definition: Kernels.h:145
Isis::Cube
IO Handler for Isis Cubes.
Definition: Cube.h:167
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::CollectorMap::add
void add(const K &key, const T &value)
Adds the element to the list.
Definition: CollectorMap.h:540
Isis::FileName::extension
QString extension() const
Returns the last extension of the file name.
Definition: FileName.cpp:178
std
Namespace for the standard library.
Isis::CollectorMap
Collector/container for arbitrary items.
Definition: CollectorMap.h:419
Isis::Cube::label
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition: Cube.cpp:1701
Isis::PvlKeyword::isNull
bool isNull(const int index=0) const
Decides whether a value is null or not at a given index.
Definition: PvlKeyword.cpp:102
Isis::PvlKeyword::size
int size() const
Returns the number of values stored in this keyword.
Definition: PvlKeyword.h:125
Isis::IString
Adds specific functionality to C++ strings.
Definition: IString.h:165
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::IString::ToQt
QString ToQt() const
Retuns the object string as a QString.
Definition: IString.cpp:869

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the USGS Astrogeology Discussion Board
To report a bug, or suggest a feature go to: ISIS Github
File Modified: 07/13/2023 15:16:46