Isis 3 Programmer Reference
CameraFactory.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 
8 #include <csm/Plugin.h>
9 #include <QDir>
10 #include <QDirIterator>
11 #include <QFileInfo>
12 #include <QLibrary>
13 
14 #include "CameraFactory.h"
15 
16 #include "Camera.h"
17 #include "CSMCamera.h"
18 #include "FileName.h"
19 #include "IException.h"
20 #include "Plugin.h"
21 #include "Preference.h"
22 
23 #include "csm/csm.h"
24 #include "csm/Model.h"
25 #include "csm/Plugin.h"
26 
27 using namespace csm;
28 using namespace std;
29 
30 namespace Isis {
31  Plugin CameraFactory::m_cameraPlugin;
32  bool CameraFactory::m_initialized = false;
33 
45  Camera *CameraFactory::Create(Cube &cube) {
46  // Try to load a plugin file in the current working directory and then
47  // load the system file
48 
49  initPlugin();
50 
51  try {
52  // Is there a CSM blob on the cube?
53  if (cube.hasBlob("CSMState", "String")) {
54  // Create ISIS CSM Camera Model
55  try {
56  return new CSMCamera(cube);
57  }
58  catch (IException &e) {
59  QString msg = "Unable to create CSM camera using CSMState Cube blob.";
60  throw IException(e, IException::Unknown, msg, _FILEINFO_);
61  }
62  }
63  else {
64  // First get the spacecraft and instrument and combine them
65  Pvl &lab = *cube.label();
66  PvlGroup &inst = lab.findGroup("Instrument", Isis::Pvl::Traverse);
67  QString spacecraft = (QString) inst["SpacecraftName"];
68  QString name = (QString) inst["InstrumentId"];
69  spacecraft = spacecraft.toUpper();
70  name = name.toUpper();
71  QString group = spacecraft + "/" + name;
72  group = group.remove(" ");
73 
74  PvlGroup &kerns = lab.findGroup("Kernels", Isis::Pvl::Traverse);
75  // Default version 1 for backwards compatibility (spiceinit'd cubes before camera model versioning)
76  if (!kerns.hasKeyword("CameraVersion")) {
77  kerns.addKeyword(PvlKeyword("CameraVersion", "1"));
78  }
79 
80  int cameraOriginalVersion = (int)kerns["CameraVersion"];
81  int cameraNewestVersion = CameraVersion(cube);
82 
83  if (cameraOriginalVersion != cameraNewestVersion) {
84  string msg = "The camera model used to create a camera for this cube is out of date, " \
85  "please re-run spiceinit on the file or process with an old Isis version " \
86  "that has the correct camera model.";
87  throw IException(IException::Unknown, msg, _FILEINFO_);
88  }
89 
90  // See if we have a camera model plugin
91  QFunctionPointer ptr;
92  try {
93  ptr = m_cameraPlugin.GetPlugin(group);
94  }
95  catch(IException &e) {
96  QString msg = "Unsupported camera model, unable to find plugin for ";
97  msg += "SpacecraftName [" + spacecraft + "] with InstrumentId [";
98  msg += name + "]";
99  throw IException(e, IException::Unknown, msg, _FILEINFO_);
100  }
101 
102  // Now cast that pointer in the proper way
103  Camera * (*plugin)(Isis::Cube &cube);
104  plugin = (Camera * ( *)(Isis::Cube &cube)) ptr;
105 
106  // Create the camera as requested
107  return (*plugin)(cube);
108  }
109  }
110  catch(IException &e) {
111  string message = "Unable to initialize camera model in Camera Factory.";
112  throw IException(e, IException::Unknown, message, _FILEINFO_);
113  }
114  }
115 
116 
121  void CameraFactory::initPlugin() {
122  if (!m_initialized) {
123  // Handle the ISIS camera plugins
124  if (m_cameraPlugin.fileName() == "") {
125  FileName localFile("Camera.plugin");
126  if (localFile.fileExists())
127  m_cameraPlugin.read(localFile.expanded());
128 
129  FileName systemFile("$ISISROOT/lib/Camera.plugin");
130  if (systemFile.fileExists())
131  m_cameraPlugin.read(systemFile.expanded());
132  }
133 
134  // Find the CSM plugins by searching the directories identified in the Preferences.
135  // Load the found libraries. This causes the static instance(s) to be constructed,
136  // and thus registering the model with the csm Plugin class.
137  Preference &p = Preference::Preferences();
138  PvlGroup &grp = p.findGroup("Plugins", Isis::Pvl::Traverse);
139  for (int i = 0; i<grp["CSMDirectory"].size(); i++) {
140  FileName csmDir = grp["CSMDirectory"][i];
141 
142  QDirIterator csmLib(csmDir.expanded(), {"*.so", "*.dylib"}, QDir::Files);
143  while (csmLib.hasNext()) {
144  QString csmLibName = csmLib.next();
145  QLibrary csmDynamicLib(csmLibName);
146  csmDynamicLib.load();
147  }
148  }
149  }
150  m_initialized = true;
151  }
152 
153 
161  int CameraFactory::CameraVersion(Cube &cube) {
162  return CameraVersion(*cube.label());
163  }
164 
165 
173  int CameraFactory::CameraVersion(Pvl &lab) {
174  // Try to load a plugin file in the current working directory and then
175  // load the system file
176  initPlugin();
177 
178  try {
179  // First get the spacecraft and instrument and combine them
180  PvlGroup &inst = lab.findGroup("Instrument", Isis::Pvl::Traverse);
181  QString spacecraft = (QString) inst["SpacecraftName"];
182  QString name = (QString) inst["InstrumentId"];
183  spacecraft = spacecraft.toUpper();
184  name = name.toUpper();
185  QString group = spacecraft + "/" + name;
186  group = group.remove(" ");
187 
188  PvlGroup plugin;
189  try {
190  bool found = false;
191  // Find the most recent (last) version of the camera model
192  for (int i = m_cameraPlugin.groups() - 1; i >= 0; i--) {
193  if (m_cameraPlugin.group(i) == group) {
194  plugin = m_cameraPlugin.group(i);
195  found = true;
196  break;
197  }
198  }
199  if (!found) {
200  QString msg = "Unable to find PVL group [" + group + "].";
201  throw IException(IException::Unknown, msg, _FILEINFO_);
202  }
203  }
204  catch(IException &e) {
205  QString msg = "Unsupported camera model, unable to find plugin for ";
206  msg += "SpacecraftName [" + spacecraft + "] with InstrumentId [";
207  msg += name + "]";
208  throw IException(e, IException::Unknown, msg, _FILEINFO_);
209  }
210 
211  if (!plugin.hasKeyword("Version")) {
212  QString msg = "Camera model identified by [" + group + "] does not have a version number";
213  throw IException(IException::Programmer, msg, _FILEINFO_);
214  }
215 
216  return (int)plugin["Version"];
217  }
218  catch(IException &e) {
219  string msg = "Unable to locate latest camera model version number from group [Instrument]";
220  throw IException(e, IException::Unknown, msg, _FILEINFO_);
221  }
222  }
223 } // end namespace isis
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::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
Isis::PvlContainer::addKeyword
void addKeyword(const PvlKeyword &keyword, const InsertMode mode=Append)
Add a keyword to the container.
Definition: PvlContainer.cpp:202
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::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::Camera
Definition: Camera.h:236
Isis::Cube::hasBlob
bool hasBlob(const QString &name, const QString &type)
Check to see if the cube contains a BLOB.
Definition: Cube.cpp:2019
Isis::PvlObject::Traverse
@ Traverse
Search child objects.
Definition: PvlObject.h:158
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::Preference
Reads user preferences from a data file.
Definition: Preference.h:60
Isis::Cube
IO Handler for Isis Cubes.
Definition: Cube.h:167
Isis::IException
Isis exception class.
Definition: IException.h:91
std
Namespace for the standard library.
Isis::Cube::label
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition: Cube.cpp:1701
Isis::CSMCamera
Definition: CSMCamera.h:25
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16