diff --git a/CHANGELOG.md b/CHANGELOG.md index 346cc9a0efe284c21e27ddfda95acd28efabac5f..d02a0a20e66ae3471ca72de28731ef6546e00974 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ ctest FunctionalTestJigsawApollo to validate this output. [#5710](https://github - Added support for reading, writing, and viewing GeoTIFFs in ISIS. [#5618](https://github.com/DOI-USGS/ISIS3/pull/5618) ### Changed +- Enhanced csminit by removing the need to specify model and plugin [#5585](https://github.com/DOI-USGS/ISIS3/issues/5585) ### Fixed - Fixed kaguyatc2isis invalid BandBin values [#5629](https://github.com/DOI-USGS/ISIS3/issues/5629) diff --git a/isis/src/base/apps/csminit/csminit.cpp b/isis/src/base/apps/csminit/csminit.cpp index ca58e98334801c7a9f130bf92bf9145198ecab09..859e2618e1206a7a0cc15a6fc96417fbce1f0402 100644 --- a/isis/src/base/apps/csminit/csminit.cpp +++ b/isis/src/base/apps/csminit/csminit.cpp @@ -169,12 +169,62 @@ namespace Isis { buffer << file.rdbuf(); QString stateString = QString::fromStdString(buffer.str()); - if (!ui.WasEntered("PLUGINNAME") && !ui.WasEntered("MODELNAME")) { - QString message = "When using a State string, PLUGINNAME and MODELNAME must be specified"; + QList<QStringList> possibleModels; + for (const csm::Plugin * plugin : csm::Plugin::getList()) { + QString currentPluginName = QString::fromStdString(plugin->getPluginName()); + if (ui.WasEntered("PLUGINNAME") && currentPluginName != ui.GetString("PLUGINNAME")) { + continue; + } + + for (size_t modelIndex = 0; modelIndex < plugin->getNumModels(); modelIndex++) { + QString currentModelName = QString::fromStdString(plugin->getModelName(modelIndex)); + if (ui.WasEntered("MODELNAME") && currentModelName != ui.GetString("MODELNAME")) { + continue; + } + + if (plugin->canModelBeConstructedFromState(currentModelName.toStdString(), stateString.toStdString())){ + QStringList modelSpec = { + currentPluginName, + currentModelName}; + possibleModels.append(modelSpec); + continue; + } + } + } + + if (possibleModels.size() > 1) { + QString message = "Multiple models can be created from the State [" + stateFilePath.toString() + "]. " + "Re-run with the PLUGINNAME and MODELNAME parameters. " + "Possible plugin & model names:\n"; + for (const QStringList &modelSpec : possibleModels) { + message += "Plugin [" + modelSpec[0] + "], Model [" + modelSpec[1] + "]\n"; + } + throw IException(IException::User, message, _FILEINFO_); + } + + if (possibleModels.empty()) { + QString message = "No loaded model could be created from the State [" + stateFilePath.toString() + "]." + "Loaded plugin & model names:\n"; + for (const csm::Plugin * plugin : csm::Plugin::getList()) { + QString currentPluginName = QString::fromStdString(plugin->getPluginName()); + for (size_t modelIndex = 0; modelIndex < plugin->getNumModels(); modelIndex++) { + QString modelName = QString::fromStdString(plugin->getModelName(modelIndex)); + message += "Plugin [" + currentPluginName + "], Model [" + modelName + "]\n"; + } + } + throw IException(IException::User, message, _FILEINFO_); + } + + // If we are here, then we have exactly 1 model + QStringList modelSpec = possibleModels.front(); + + if (modelSpec.size() != 2) { + QString message = "Model specification [" + modelSpec.join(" ") + "] has [" + modelSpec.size() + "] elements " + "when it should have 2 elements."; throw IException(IException::Programmer, message, _FILEINFO_); } - pluginName = ui.GetString("PLUGINNAME"); - modelName = ui.GetString("MODELNAME"); + pluginName = modelSpec[0]; + modelName = modelSpec[1]; const csm::Plugin *plugin = csm::Plugin::findPlugin(pluginName.toStdString()); if (plugin == NULL) { diff --git a/isis/tests/FunctionalTestsCsminit.cpp b/isis/tests/FunctionalTestsCsminit.cpp index d0669411907988c8d9fb63103feedcea679bfe1e..7d4d5f021024da14a93a9dc1d31baf24a86082d2 100644 --- a/isis/tests/FunctionalTestsCsminit.cpp +++ b/isis/tests/FunctionalTestsCsminit.cpp @@ -428,31 +428,13 @@ TEST_F(CSMPluginFixture, CSMInitStateStringFails) { csminit(options); } catch (IException &e) { - EXPECT_THAT(e.what(), testing::HasSubstr("When using a State string, PLUGINNAME and MODELNAME must be specified")); - } - - QVector<QString> argsWithModel = { - "from="+filename, - "state="+statePath, - "modelname=TestCsmModel", - "pluginname=TestCsmPlugin"}; - - UserInterface optionsWithModel(APP_XML, argsWithModel); - - // Expect a failure due to a bad state string. - try { - csminit(optionsWithModel); - } - catch (IException &e) { - EXPECT_THAT(e.what(), testing::HasSubstr("Could not construct sensor model using STATE string and MODELNAME")); + EXPECT_THAT(e.what(), testing::HasSubstr("No loaded model could be created from the State")); } QVector<QString> argsWithIsdAndState = { "from="+filename, "isd=fakePath", - "state="+statePath, - "modelname=TestCsmModel", - "pluginname=TestCsmPlugin"}; + "state="+statePath}; UserInterface optionsWithIsdAndState(APP_XML, argsWithIsdAndState);