Skip to content
Snippets Groups Projects
Commit 5ae463d1 authored by jay's avatar jay
Browse files

Fixes #1, #2, #4 and improves test coverage

parent 8697899e
No related branches found
No related tags found
No related merge requests found
#ifndef MdisNacSensorModel_h #ifndef MdisNacSensorModel_h
#define MdisNacSensorModel_h #define MdisNacSensorModel_h
...@@ -26,6 +27,12 @@ class MdisNacSensorModel : public csm::RasterGM { ...@@ -26,6 +27,12 @@ class MdisNacSensorModel : public csm::RasterGM {
double *achievedPrecision=NULL, double *achievedPrecision=NULL,
csm::WarningList *warnings=NULL) const; csm::WarningList *warnings=NULL) const;
virtual csm::ImageCoord groundToImage(const csm::EcefCoord& ground_pt,
const std::vector<double>& adjustments,
double desired_precision=0.001,
double* achieved_precision=NULL,
csm::WarningList* warnings=NULL) const;
/** /**
* This function determines if a sample, line intersects the target body and if so, where * This function determines if a sample, line intersects the target body and if so, where
* this intersection occurs in body-fixed coordinates. * this intersection occurs in body-fixed coordinates.
...@@ -279,9 +286,6 @@ class MdisNacSensorModel : public csm::RasterGM { ...@@ -279,9 +286,6 @@ class MdisNacSensorModel : public csm::RasterGM {
static const std::string _SENSOR_MODEL_NAME; static const std::string _SENSOR_MODEL_NAME;
protected: protected:
virtual bool setFocalPlane(double dx,double dy,double &undistortedX,double &undistortedY) const; virtual bool setFocalPlane(double dx,double dy,double &undistortedX,double &undistortedY) const;
...@@ -289,17 +293,26 @@ class MdisNacSensorModel : public csm::RasterGM { ...@@ -289,17 +293,26 @@ class MdisNacSensorModel : public csm::RasterGM {
virtual void distortionJacobian(double x, double y, double &Jxx, virtual void distortionJacobian(double x, double y, double &Jxx,
double &Jxy, double &Jyx, double &Jyy) const; double &Jxy, double &Jyx, double &Jyy) const;
private: private:
// Input parameters
static const int m_numParameters;
static const std::string m_parameterName[];
std::vector<double> m_currentParameterValue;
std::vector<double> m_currentParameterCovariance;
std::vector<double> m_noAdjustments;
std::vector<double> m_odtX;
std::vector<double> m_odtY;
static const int _NUM_STATE_KEYWORDS;
static const std::string _STATE_KEYWORD[];
double m_transX[3]; double m_transX[3];
double m_transY[3]; double m_transY[3];
double m_majorAxis; double m_majorAxis;
double m_minorAxis; double m_minorAxis;
double m_omega;
double m_phi;
double m_kappa;
double m_focalLength; double m_focalLength;
double m_spacecraftPosition[3];
double m_spacecraftVelocity[3]; double m_spacecraftVelocity[3];
double m_sunPosition[3]; double m_sunPosition[3];
double m_ccdCenter[2]; double m_ccdCenter[2];
...@@ -311,8 +324,6 @@ class MdisNacSensorModel : public csm::RasterGM { ...@@ -311,8 +324,6 @@ class MdisNacSensorModel : public csm::RasterGM {
double m_ifov; double m_ifov;
std::string m_instrumentID; std::string m_instrumentID;
double m_focalLengthEpsilon; double m_focalLengthEpsilon;
double m_odtX[10];
double m_odtY[10];
double m_originalHalfLines; double m_originalHalfLines;
std::string m_spacecraftName; std::string m_spacecraftName;
double m_pixelPitch; double m_pixelPitch;
...@@ -323,12 +334,16 @@ class MdisNacSensorModel : public csm::RasterGM { ...@@ -323,12 +334,16 @@ class MdisNacSensorModel : public csm::RasterGM {
double m_boresight[3]; double m_boresight[3];
int m_nLines; int m_nLines;
int m_nSamples; int m_nSamples;
int m_nParameters;
double getValue(int index,const std::vector<double> &adjustments) const;
void calcRotationMatrix(double m[3][3]) const; void calcRotationMatrix(double m[3][3]) const;
void losEllipsoidIntersect (double& height, double& xc, void calcRotationMatrix(double m[3][3], const std::vector<double> &adjustments) const;
double& yc, double& zc,
double& xl, double& yl, void losEllipsoidIntersect (const double& height,const double& xc,
double& zl, const double& yc, const double& zc,
const double& xl, const double& yl,
const double& zl,
double& x,double& y, double& z) const; double& x,double& y, double& z) const;
}; };
......
...@@ -52,6 +52,17 @@ class MDIS_EXPORT_API MdisPlugin : public csm::Plugin { ...@@ -52,6 +52,17 @@ class MDIS_EXPORT_API MdisPlugin : public csm::Plugin {
csm::WarningList *warnings = NULL) const; csm::WarningList *warnings = NULL) const;
// TODO when implementing, add any other necessary members. // TODO when implementing, add any other necessary members.
private:
static const MdisPlugin m_registeredPlugin;
static const std::string _PLUGIN_NAME;
static const std::string _MANUFACTURER_NAME;
static const std::string _RELEASE_DATE;
static const int _N_SENSOR_MODELS;
static const int _NUM_ISD_KEYWORDS;
static const std::string _ISD_KEYWORD[];
static const int _NUM_STATE_KEYWORDS;
static const std::string _STATE_KEYWORD[];
}; };
#endif #endif
#include "MdisPlugin.h" #include "MdisPlugin.h"
#include "MdisNacSensorModel.h"
#include <cstdlib> #include <cstdlib>
#include <string> #include <string>
...@@ -8,10 +9,96 @@ ...@@ -8,10 +9,96 @@
#include <csm/Plugin.h> #include <csm/Plugin.h>
#include <csm/Warning.h> #include <csm/Warning.h>
#include "MdisNacSensorModel.h" #include <json/json.hpp>
// Create static instance of self for plugin registration to work with csm::Plugin
//const MdisPlugin MdisPlugin::m_registeredPlugin; using json = nlohmann::json;
// Declaration of static variables
const std::string MdisPlugin::_PLUGIN_NAME = "UsgsAstroFrameMdisPluginCSM";
const std::string MdisPlugin::_MANUFACTURER_NAME = "UsgsAstrogeology";
const std::string MdisPlugin::_RELEASE_DATE = "20170425";
const int MdisPlugin::_N_SENSOR_MODELS = 1;
const int MdisPlugin::_NUM_ISD_KEYWORDS = 36;
const std::string MdisPlugin::_ISD_KEYWORD[] =
{
"model_name",
"starting_detector_sample",
"starting_detector_line",
"target_name",
"ifov",
"instrument_id",
"focal_length",
"focal_length_epsilon",
"x_sensor_origin",
"y_sensor_origin",
"z_sensor_origin",
"x_sensor_velocity",
"y_sensor_velocity",
"z_sensor_velocity",
"x_sun_position",
"y_sun_position",
"z_sun_position",
"omega",
"phi",
"kappa",
"odt_x",
"odt_y",
"ccd_center",
"original_half_lines",
"original_half_samples",
"spacecraft_name",
"pixel_pitch",
"itrans_line",
"itrans_sample",
"ephemeris_time",
"boresight",
"nlines",
"nsamples",
"transx",
"transy",
"semi_major_axis",
"semi_minor_axis"
};
const int MdisPlugin::_NUM_STATE_KEYWORDS = 30;
const std::string MdisPlugin::_STATE_KEYWORD[] =
{
"m_focalLength",
"m_iTransS",
"m_iTransL",
"m_boresight",
"m_transX",
"m_transY",
"m_majorAxis",
"m_minorAxis",
"m_spacecraftVelocity",
"m_sunPosition",
"m_startingDetectorSample",
"m_startingDetectorLine",
"m_targetName",
"m_ifov",
"m_instrumentID",
"m_focalLengthEpsilon",
"m_ccdCenter",
"m_line_pp",
"m_sample_pp",
"m_odtX",
"m_odtY",
"m_originalHalfLines",
"m_originalHalfSamples",
"m_spacecraftName",
"m_pixelPitch",
"m_ephemerisTime",
"m_nLines",
"m_nSamples",
"m_currentParameterValue",
"m_currentParameterCovariance"
};
// Static Instance of itself
const MdisPlugin MdisPlugin::m_registeredPlugin;
MdisPlugin::MdisPlugin() { MdisPlugin::MdisPlugin() {
} }
...@@ -22,27 +109,27 @@ MdisPlugin::~MdisPlugin() { ...@@ -22,27 +109,27 @@ MdisPlugin::~MdisPlugin() {
std::string MdisPlugin::getPluginName() const { std::string MdisPlugin::getPluginName() const {
return "UsgsAstroFrameMdisPluginCSM"; return _PLUGIN_NAME;
} }
std::string MdisPlugin::getManufacturer() const { std::string MdisPlugin::getManufacturer() const {
return "UsgsAstrogeology"; return _MANUFACTURER_NAME;
} }
std::string MdisPlugin::getReleaseDate() const { std::string MdisPlugin::getReleaseDate() const {
return "TBA"; return _RELEASE_DATE;
} }
csm::Version MdisPlugin::getCsmVersion() const { csm::Version MdisPlugin::getCsmVersion() const {
return csm::Version(3, 1, 0); return CURRENT_CSM_VERSION;
} }
size_t MdisPlugin::getNumModels() const { size_t MdisPlugin::getNumModels() const {
return 1; return _N_SENSOR_MODELS;
} }
...@@ -53,12 +140,11 @@ std::string MdisPlugin::getModelName(size_t modelIndex) const { ...@@ -53,12 +140,11 @@ std::string MdisPlugin::getModelName(size_t modelIndex) const {
std::string MdisPlugin::getModelFamily(size_t modelIndex) const { std::string MdisPlugin::getModelFamily(size_t modelIndex) const {
return "Raster"; return CSM_RASTER_FAMILY;
} }
csm::Version MdisPlugin::getModelVersion(const std::string &modelName) const { csm::Version MdisPlugin::getModelVersion(const std::string &modelName) const {
return csm::Version(1, 0, 0); return csm::Version(1, 0, 0);
} }
...@@ -66,25 +152,99 @@ csm::Version MdisPlugin::getModelVersion(const std::string &modelName) const { ...@@ -66,25 +152,99 @@ csm::Version MdisPlugin::getModelVersion(const std::string &modelName) const {
bool MdisPlugin::canModelBeConstructedFromState(const std::string &modelName, bool MdisPlugin::canModelBeConstructedFromState(const std::string &modelName,
const std::string &modelState, const std::string &modelState,
csm::WarningList *warnings) const { csm::WarningList *warnings) const {
return false; bool constructible = true;
// Get the model name from the model state
std::string model_name_from_state;
model_name_from_state = getModelNameFromModelState(modelState, warnings);
// Check that the plugin supports the model
if (modelName != model_name_from_state ||
modelName != MdisNacSensorModel::_SENSOR_MODEL_NAME){
constructible = false;
}
// Check that the necessary keys are there (this does not chek values at all.)
auto state = json::parse(modelState);
for(auto &key : _STATE_KEYWORD){
if (state.find(key) == state.end()){
constructible = false;
}
}
return constructible;
} }
bool MdisPlugin::canModelBeConstructedFromISD(const csm::Isd &imageSupportData, bool MdisPlugin::canModelBeConstructedFromISD(const csm::Isd &imageSupportData,
const std::string &modelName, const std::string &modelName,
csm::WarningList *warnings) const { csm::WarningList *warnings) const {
return canISDBeConvertedToModelState(imageSupportData, modelName, warnings);
}
if (modelName != MdisNacSensorModel::_SENSOR_MODEL_NAME) {
return false; csm::Model *MdisPlugin::constructModelFromState(const std::string& modelState,
csm::WarningList *warnings) const {
csm::Model *sensor_model = 0;
// Get the sensor model name from the sensor model state
std::string model_name_from_state = getModelNameFromModelState(modelState);
if (model_name_from_state != MdisNacSensorModel::_SENSOR_MODEL_NAME){
csm::Error::ErrorType aErrorType = csm::Error::INVALID_SENSOR_MODEL_STATE;
std::string aMessage = "Model name from state is not recognized.";
std::string aFunction = "MdisPlugin::constructModelFromState()";
throw csm::Error(aErrorType, aMessage, aFunction);
} }
return true; // Check that all of the necessary keys are included
canModelBeConstructedFromState(model_name_from_state, modelState);
// Create the model from the state
MdisNacSensorModel* mdsensor_model = new MdisNacSensorModel();
auto state = json::parse(modelState);
mdsensor_model->m_focalLength = state["m_focalLength"];
mdsensor_model->m_majorAxis = state["m_majorAxis"];
mdsensor_model->m_minorAxis = state["m_minorAxis"];
mdsensor_model->m_startingDetectorLine = state["m_startingDetectorLine"];
mdsensor_model->m_startingDetectorSample = state["m_startingDetectorSample"];
mdsensor_model->m_ifov = state["m_ifov"];
mdsensor_model->m_instrumentID = state["m_instrumentID"];
mdsensor_model->m_focalLengthEpsilon = state["m_focalLengthEpsilon"];
mdsensor_model->m_line_pp = state["m_line_pp"];
mdsensor_model->m_sample_pp = state["m_sample_pp"];
mdsensor_model->m_originalHalfLines = state["m_originalHalfLines"];
mdsensor_model->m_originalHalfSamples = state["m_originalHalfSamples"];
mdsensor_model->m_spacecraftName = state["m_spacecraftName"];
mdsensor_model->m_pixelPitch = state["m_pixelPitch"];
mdsensor_model->m_ephemerisTime = state["m_ephemerisTime"];
mdsensor_model->m_nLines = state["m_nLines"];
mdsensor_model->m_nSamples = state["m_nSamples"];
mdsensor_model->m_ccdCenter[0] = state["m_ccdCenter"][0];
mdsensor_model->m_ccdCenter[1] = state["m_ccdCenter"][1];
for (int i=0;i<3;i++){
mdsensor_model->m_boresight[i] = state["m_boresight"][i];
mdsensor_model->m_iTransS[i] = state["m_iTransS"][i];
mdsensor_model->m_iTransL[i] = state["m_iTransL"][i];
mdsensor_model->m_transX[i] = state["m_transX"][i];
mdsensor_model->m_transY[i] = state["m_transY"][i];
mdsensor_model->m_spacecraftVelocity[i] = state["m_spacecraftVelocity"][i];
mdsensor_model->m_sunPosition[i] = state["m_sunPosition"][i];
} }
// Having types as vectors, instead of arrays makes interoperability with
// the JSON library very easy.
mdsensor_model->m_currentParameterValue = state["m_currentParameterValue"].get<std::vector<double>>();
mdsensor_model->m_odtX = state["m_odtX"].get<std::vector<double>>();
mdsensor_model->m_odtY = state["m_odtY"].get<std::vector<double>>();
csm::Model *MdisPlugin::constructModelFromState(const std::string&modelState, mdsensor_model->m_currentParameterCovariance = state["m_currentParameterCovariance"].get<std::vector<double>>();
csm::WarningList *warnings) const {
return NULL; sensor_model = mdsensor_model;
return sensor_model;
} }
...@@ -124,11 +284,11 @@ csm::Model *MdisPlugin::constructModelFromISD(const csm::Isd &imageSupportData, ...@@ -124,11 +284,11 @@ csm::Model *MdisPlugin::constructModelFromISD(const csm::Isd &imageSupportData,
sensorModel->m_focalLengthEpsilon = sensorModel->m_focalLengthEpsilon =
atof(imageSupportData.param("focal_length_epsilon").c_str()); atof(imageSupportData.param("focal_length_epsilon").c_str());
sensorModel->m_spacecraftPosition[0] = sensorModel->m_currentParameterValue[0] =
atof(imageSupportData.param("x_sensor_origin").c_str()); atof(imageSupportData.param("x_sensor_origin").c_str());
sensorModel->m_spacecraftPosition[1] = sensorModel->m_currentParameterValue[1] =
atof(imageSupportData.param("y_sensor_origin").c_str()); atof(imageSupportData.param("y_sensor_origin").c_str());
sensorModel->m_spacecraftPosition[2] = sensorModel->m_currentParameterValue[2] =
atof(imageSupportData.param("z_sensor_origin").c_str()); atof(imageSupportData.param("z_sensor_origin").c_str());
if (imageSupportData.param("x_sensor_origin") == "") { if (imageSupportData.param("x_sensor_origin") == "") {
missingKeywords.push_back("x_sensor_origin"); missingKeywords.push_back("x_sensor_origin");
...@@ -156,9 +316,9 @@ csm::Model *MdisPlugin::constructModelFromISD(const csm::Isd &imageSupportData, ...@@ -156,9 +316,9 @@ csm::Model *MdisPlugin::constructModelFromISD(const csm::Isd &imageSupportData,
atof(imageSupportData.param("z_sun_position").c_str()); atof(imageSupportData.param("z_sun_position").c_str());
// sun position is not strictly necessary, but is required for getIlluminationDirection. // sun position is not strictly necessary, but is required for getIlluminationDirection.
sensorModel->m_omega = atof(imageSupportData.param("omega").c_str()); sensorModel->m_currentParameterValue[3] = atof(imageSupportData.param("omega").c_str());
sensorModel->m_phi = atof(imageSupportData.param("phi").c_str()); sensorModel->m_currentParameterValue[4] = atof(imageSupportData.param("phi").c_str());
sensorModel->m_kappa = atof(imageSupportData.param("kappa").c_str()); sensorModel->m_currentParameterValue[5] = atof(imageSupportData.param("kappa").c_str());
if (imageSupportData.param("omega") == "") { if (imageSupportData.param("omega") == "") {
missingKeywords.push_back("omega"); missingKeywords.push_back("omega");
} }
...@@ -311,19 +471,62 @@ csm::Model *MdisPlugin::constructModelFromISD(const csm::Isd &imageSupportData, ...@@ -311,19 +471,62 @@ csm::Model *MdisPlugin::constructModelFromISD(const csm::Isd &imageSupportData,
std::string MdisPlugin::getModelNameFromModelState(const std::string &modelState, std::string MdisPlugin::getModelNameFromModelState(const std::string &modelState,
csm::WarningList *warnings) const { csm::WarningList *warnings) const {
return "state"; std::string name;
auto state = json::parse(modelState);
if(state.find("model_name") != state.end()){
name = state["model_name"];
}
else{
csm::Error::ErrorType aErrorType = csm::Error::INVALID_SENSOR_MODEL_STATE;
std::string aMessage = "No 'model_name' key in the model state object.";
std::string aFunction = "MdisPlugin::getModelNameFromModelState";
csm::Error csmErr(aErrorType, aMessage, aFunction);
throw(csmErr);
}
if (name != MdisNacSensorModel::_SENSOR_MODEL_NAME){
csm::Error::ErrorType aErrorType = csm::Error::SENSOR_MODEL_NOT_SUPPORTED;
std::string aMessage = "Sensor model not supported.";
std::string aFunction = "MdisPlugin::getModelNameFromModelState()";
csm::Error csmErr(aErrorType, aMessage, aFunction);
throw(csmErr);
}
return MdisNacSensorModel::_SENSOR_MODEL_NAME;
} }
bool MdisPlugin::canISDBeConvertedToModelState(const csm::Isd &imageSupportData, bool MdisPlugin::canISDBeConvertedToModelState(const csm::Isd &imageSupportData,
const std::string &modelName, const std::string &modelName,
csm::WarningList *warnings) const { csm::WarningList *warnings) const {
return false; bool convertible = true;
if (modelName !=MdisNacSensorModel::_SENSOR_MODEL_NAME){
convertible = false;
}
std::string value;
for(auto &key : _ISD_KEYWORD){
value = imageSupportData.param(key);
if (value.empty()){
convertible = false;
}
}
return convertible;
} }
std::string MdisPlugin::convertISDToModelState(const csm::Isd &imageSupportData, std::string MdisPlugin::convertISDToModelState(const csm::Isd &imageSupportData,
const std::string &modelName, const std::string &modelName,
csm::WarningList *warnings) const { csm::WarningList *warnings) const {
return "state"; csm::Model* sensor_model = constructModelFromISD(
imageSupportData, modelName);
if (sensor_model == 0){
csm::Error::ErrorType aErrorType = csm::Error::ISD_NOT_SUPPORTED;
std::string aMessage = "ISD not supported: ";
std::string aFunction = "MdisPlugin::convertISDToModelState()";
throw csm::Error(aErrorType, aMessage, aFunction);
}
return sensor_model->getModelState();
} }
This diff is collapsed.
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
0.0 0.0
], ],
"kappa": -3.072868243248164, "kappa": -3.072868243248164,
"model_name": "ISIS_MDISNAC_USGSAstro_1_Linux64_csm30.so",
"nlines": 1024, "nlines": 1024,
"nsamples": 1024, "nsamples": 1024,
"odt_x": [ "odt_x": [
...@@ -72,6 +73,12 @@ ...@@ -72,6 +73,12 @@
0.013997772676294 0.013997772676294
], ],
"x_sensor_origin": 28892.88978623381, "x_sensor_origin": 28892.88978623381,
"x_sensor_velocity": 0,
"x_sun_position": 0,
"y_sensor_origin": 633940.116378508, "y_sensor_origin": 633940.116378508,
"z_sensor_origin": 2683552.1331144567 "y_sensor_velocity": 0,
"y_sun_position": 0,
"z_sensor_origin": 2683552.1331144567,
"z_sensor_velocity": 0,
"z_sun_position": 0
} }
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
0.0 0.0
], ],
"kappa": -0.963008015000929, "kappa": -0.963008015000929,
"model_name": "ISIS_MDISNAC_USGSAstro_1_Linux64_csm30.so",
"nlines": 1024, "nlines": 1024,
"nsamples": 1024, "nsamples": 1024,
"odt_x": [ "odt_x": [
...@@ -73,9 +74,11 @@ ...@@ -73,9 +74,11 @@
], ],
"x_sensor_origin": 1728181.0340792781, "x_sensor_origin": 1728181.0340792781,
"x_sun_position": -31648725087.588726, "x_sun_position": -31648725087.588726,
"x_sensor_velocity": 0,
"y_sensor_origin": -2088202.591297346, "y_sensor_origin": -2088202.591297346,
"y_sun_position": -60633907522.72863, "y_sun_position": -60633907522.72863,
"y_sensor_velocity": 0,
"z_sensor_origin": 2082707.608992824, "z_sensor_origin": 2082707.608992824,
"z_sensor_velocity" :0,
"z_sun_position": -38729485.77334732 "z_sun_position": -38729485.77334732
} }
...@@ -23,14 +23,82 @@ class TestPlugin: ...@@ -23,14 +23,82 @@ class TestPlugin:
csm_isd.addparam(k, v) csm_isd.addparam(k, v)
return csm_isd return csm_isd
def test_mdis_plugin(self, plugin): def test_nmodels(self, plugin):
assert plugin.name == 'UsgsAstroFrameMdisPluginCSM'
assert plugin.nmodels == 1 assert plugin.nmodels == 1
assert plugin.modelname(1) == 'ISIS_MDISNAC_USGSAstro_1_Linux64_csm30.so'
def test_check_isd_construction(self, plugin, i): def test_check_isd_construction(self, plugin, i):
assert plugin.check_isd_construction(i, plugin.modelname(1)) assert plugin.check_isd_construction(i, plugin.modelname(1))
def test_releasedate(self, plugin):
assert plugin.releasedate == "20170425"
def test_csmversion(self, plugin):
assert plugin.csmversion.version.decode() == "3.0.1"
def test_plugin_name(self, plugin):
assert plugin.name == 'UsgsAstroFrameMdisPluginCSM'
def test_modelname(self, plugin):
assert plugin.modelname(1) == 'ISIS_MDISNAC_USGSAstro_1_Linux64_csm30.so'
def test_modelfamily(self, plugin):
assert plugin.modelfamily(1) == 'Raster'
def test_modelname_from_state(self, plugin, i):
state = {'model_name': 'ISIS_MDISNAC_USGSAstro_1_Linux64_csm30.so'}
name = plugin.modelname_from_state(json.dumps(state))
assert name == state['model_name']
def test_modelname_from_state_bad_key(self, plugin):
state = {'mname':'foo'}
with pytest.raises(RuntimeError) as err:
name = plugin.modelname_from_state(json.dumps(state))
assert "'model_name'" in str(err.value)
def test_modelname_from_state_bad_name(self, plugin):
state = {'model_name':'foo'}
with pytest.raises(RuntimeError) as err:
name = plugin.modelname_from_state(json.dumps(state))
assert "Sensor model not supported." in str(err.value)
def test_can_model_be_constructed_from_state(self, plugin):
name = 'ISIS_MDISNAC_USGSAstro_1_Linux64_csm30.so'
with open(os.path.join(data_path,'nac_state.json'), 'r') as f:
state = json.load(f)
constructible = plugin.can_model_be_constructed_from_state(name, json.dumps(state))
assert constructible == True
name = 'foo'
constructible = plugin.can_model_be_constructed_from_state(name, json.dumps(state))
assert constructible == False
def test_can_isd_be_converted_to_model_state(self, plugin, i):
name = 'ISIS_MDISNAC_USGSAstro_1_Linux64_csm30.so'
res = plugin.can_isd_be_converted_to_model_state(i, name)
assert res == True
def test_convert_isd_to_model_state(self, plugin, i):
name = 'ISIS_MDISNAC_USGSAstro_1_Linux64_csm30.so'
state = plugin.convert_isd_to_state(i, name)
with open(os.path.join(data_path,'nac_state.json'), 'r') as f:
truth = json.load(f)
assert state == truth
def test_convert_isd_to_model_state_bad(self, plugin, i):
# Trash the isd and check error handling
i.clear_params("focal_length")
name = 'ISIS_MDISNAC_USGSAstro_1_Linux64_csm30.so'
with pytest.raises(RuntimeError) as err:
state = plugin.convert_isd_to_state(i, name)
assert "Sensor model support data" in str(err.value)
def test_construct_model_from_state(self, plugin):
with open(os.path.join(data_path,'nac_state.json'), 'r') as f:
state = json.load(f)
camera = plugin.from_state(json.dumps(state))
assert isinstance(camera, cam.mdis.MdisNacSensorModel)
class TestMdisWac: class TestMdisWac:
@pytest.fixture @pytest.fixture
def model(self): def model(self):
......
...@@ -6,12 +6,13 @@ from libcpp.pair cimport pair ...@@ -6,12 +6,13 @@ from libcpp.pair cimport pair
from cycsm.isd cimport CppIsd from cycsm.isd cimport CppIsd
from cycsm.csm cimport CppEcefCoord, CppImageCoord, CppImageVector, CppEcefVector, CppEcefLocus from cycsm.csm cimport CppEcefCoord, CppImageCoord, CppImageVector, CppEcefVector, CppEcefLocus
from cycsm.model cimport CppModel from cycsm.model cimport CppModel
from cycsm.version cimport CppVersion
cdef extern from "MdisNacSensorModel.h": cdef extern from "MdisNacSensorModel.h":
cdef cppclass CppMdisNacSensorModel "MdisNacSensorModel": cdef cppclass CppMdisNacSensorModel "MdisNacSensorModel":
CppMdisNacSensorModel() except + CppMdisNacSensorModel() except +
CppEcefCoord imageToGround(CppImageCoord imagePt, double height, double precision) CppEcefCoord imageToGround(CppImageCoord imagePt, double height, double precision) except +
CppImageCoord groundToImage(CppEcefCoord groundPt, double desiredPrecision) CppImageCoord groundToImage(CppEcefCoord groundPt, double desiredPrecision) except +
CppImageCoord getImageStart() CppImageCoord getImageStart()
CppImageVector getImageSize() CppImageVector getImageSize()
...@@ -42,13 +43,18 @@ cdef extern from "MdisPlugin.h": ...@@ -42,13 +43,18 @@ cdef extern from "MdisPlugin.h":
string getPluginName() string getPluginName()
string getManufacturer() string getManufacturer()
#string getReleaseDate() string getModelNameFromModelState(const string modelState) except +
#string getCsmVersion string getReleaseDate()
CppVersion getCsmVersion()
size_t getNumModels() size_t getNumModels()
string getModelName(size_t modelIndex) string getModelName(size_t modelIndex)
bool canModelBeConstructedFromISD(CppIsd isd, const string modelname) string getModelFamily(size_t modelIndex)
string convertISDToModelState(CppIsd isd, const string modelname) bool canModelBeConstructedFromISD(CppIsd isd, const string modelname) except +
CppModel *constructModelFromISD(CppIsd &isd, string &modelname) bool canModelBeConstructedFromState(const string modelName, const string modelState) except +
bool canISDBeConvertedToModelState(CppIsd isd, const string modelName) except +
string convertISDToModelState(CppIsd isd, const string modelname) except +
CppModel *constructModelFromISD(CppIsd &isd, string &modelname) except +
CppModel *constructModelFromState(string modelState) except +
# For casting from the CSM Model into our specific camera model - I hope. # For casting from the CSM Model into our specific camera model - I hope.
cdef extern from *: cdef extern from *:
......
import numpy as np import numpy as np
import ast import ast
import json
from cython.operator cimport dereference as deref from cython.operator cimport dereference as deref
from cycsm.csm import EcefCoord, ImageCoord from cycsm.csm import EcefCoord, ImageCoord
from cycsm.isd cimport Isd from cycsm.isd cimport Isd
from cycsm.version import Version
cdef class MdisNacSensorModel: cdef class MdisNacSensorModel:
cdef: cdef:
...@@ -261,21 +263,43 @@ cdef class MdisPlugin: ...@@ -261,21 +263,43 @@ cdef class MdisPlugin:
def manufacturer(self): def manufacturer(self):
return self.thisptr.getManufacturer().decode() return self.thisptr.getManufacturer().decode()
#@property @property
#def releasedate(self): def releasedate(self):
# return self.thisptr.getReleaseDate() return self.thisptr.getReleaseDate().decode()
#@property @property
#def version(self): def csmversion(self):
# return self.thisptr.getCsmVersion() return Version(self.thisptr.getCsmVersion().version())
@property @property
def nmodels(self): def nmodels(self):
return self.thisptr.getNumModels() return self.thisptr.getNumModels()
def modelfamily(self, modelindex):
return self.thisptr.getModelFamily(modelindex).decode()
def modelname_from_state(self, state):
state = state.encode()
res = self.thisptr.getModelNameFromModelState(state).decode()
return res
def modelname(self, modelindex): def modelname(self, modelindex):
return self.thisptr.getModelName(modelindex).decode() return self.thisptr.getModelName(modelindex).decode()
def can_model_be_constructed_from_state(self, name, state):
name = name.encode()
state = state.encode()
return self.thisptr.canModelBeConstructedFromState(name, state)
def can_isd_be_converted_to_model_state(self, Isd isd, modelname):
modelname = modelname.encode()
return self.thisptr.canISDBeConvertedToModelState(isd.thisptr[0], modelname)
def convert_isd_to_state(self, Isd isd, modelname):
modelname = modelname.encode()
return json.loads(self.thisptr.convertISDToModelState(isd.thisptr[0], modelname).decode())
def check_isd_construction(self, Isd isd, modelname): def check_isd_construction(self, Isd isd, modelname):
modelname = str(modelname).encode() modelname = str(modelname).encode()
return self.thisptr.canModelBeConstructedFromISD(isd.thisptr[0], modelname) return self.thisptr.canModelBeConstructedFromISD(isd.thisptr[0], modelname)
...@@ -283,3 +307,8 @@ cdef class MdisPlugin: ...@@ -283,3 +307,8 @@ cdef class MdisPlugin:
def from_isd(self, Isd isd, modelname): def from_isd(self, Isd isd, modelname):
modelname = str(modelname).encode() modelname = str(modelname).encode()
return MdisNacSensorModel.factory(dynamic_cast_model_ptr(self.thisptr.constructModelFromISD(isd.thisptr[0], modelname))) return MdisNacSensorModel.factory(dynamic_cast_model_ptr(self.thisptr.constructModelFromISD(isd.thisptr[0], modelname)))
def from_state(self, state):
state = state.encode()
#self.thisptr.constructModelFromState(state)
return MdisNacSensorModel.factory(dynamic_cast_model_ptr(self.thisptr.constructModelFromState(state)))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment