Skip to content

Commit

Permalink
Proj Speed Up (#479)
Browse files Browse the repository at this point in the history
* Moved around model construction

* Added verbose option to usgscsm_cam_test

* Cleaned up model instantiation

* Fixed warning from getUsgsModel function

* Removed commented out code

* Removed last line of commented out code

* Fix linux builds

* Removed m_camera delete on reset

* Proj sensor now carries an identifier for the underlying csm model

* Added basic projected sensor model tests

* Added warning for users using the projected model

* Hide dependent library symbols

* Defined proj env var

* Adjusted proj camera tests for specific OSs

* Set proj data dir in tests

* Fixed ConstVelocityProjectedSensorModel, RemoteImageLocus test

* Removed duplicate comment from other test
  • Loading branch information
acpaquette authored Jul 26, 2024
1 parent 568ea46 commit b861a95
Show file tree
Hide file tree
Showing 13 changed files with 566 additions and 133 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci_testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ on:
branches:
- main

env:
PROJ_IGNORE_CELESTIAL_BODY: Yes

jobs:
Build-and-Test-LinuxOsX:
runs-on: ${{ matrix.os }}
Expand Down Expand Up @@ -38,6 +41,7 @@ jobs:
run: |
mkdir -p build
cd build
export PROJ_DATA=$PWD/PROJ/data
cmake -DCMAKE_BUILD_TYPE=RELEASE -DUSGSCSM_EXTERNAL_DEPS=OFF -DUSGSCSM_BUILD_DOCS=OFF ..
cmake --build .
- name: Test Package
Expand Down
22 changes: 15 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ message(STATUS "CMake Module Path: " ${CMAKE_MODULE_PATH})

include(GNUInstallDirs)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 14)

# Set a default build type if none was specified
set(default_build_type "Release")
Expand All @@ -17,6 +17,8 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
STRING "Choose the type of build." FORCE)
endif()

set(VISIBILITY_INLINES_HIDDEN 1)

# Use external or embedded dependencies
option(USGSCSM_EXTERNAL_DEPS "If the library should be built with external or embedded dependencies" OFF)
option(ENABLE_CURL "Set to build the curl components of proj" OFF)
Expand Down Expand Up @@ -61,7 +63,7 @@ if(USGSCSM_EXTERNAL_DEPS)
find_package(Eigen3 3.3 REQUIRED NO_MODULE)

# ALE
find_package(ale REQUIRED)
find_package(ale REQUIRED CONFIG)
set(ALE_TARGET ale::ale)

# Proj
Expand Down Expand Up @@ -160,7 +162,7 @@ else()

# default config is shared
option(BUILD_SHARED_LIBS
"Build PROJ library shared." ON)
"Build PROJ library shared." OFF)

find_package(Threads QUIET)
if(Threads_FOUND AND CMAKE_USE_PTHREADS_INIT)
Expand Down Expand Up @@ -516,7 +518,6 @@ else()
${ALL_LIBPROJ_HEADERS}
${PROJ_RESOURCES}
)
add_library(PROJ::proj ALIAS proj)

if(MSVC OR MINGW)
target_compile_definitions(proj PRIVATE -DNOMINMAX)
Expand Down Expand Up @@ -570,7 +571,9 @@ else()

set_target_properties(proj
PROPERTIES
LINKER_LANGUAGE CXX)
LINKER_LANGUAGE CXX
CXX_VISIBILITY_PRESET hidden
)

##############################################
# Link properties
Expand Down Expand Up @@ -628,6 +631,7 @@ else()
# ALE
# Use Eigen included with ALE
add_library (eigen INTERFACE)
set_target_properties(eigen PROPERTIES CXX_VISIBILITY_PRESET hidden)
add_library (Eigen3::Eigen ALIAS eigen)
target_include_directories (eigen INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/ale/eigen)
Expand All @@ -643,6 +647,7 @@ else()
${CMAKE_CURRENT_SOURCE_DIR}/ale/src/Vectors.cpp)

add_library(ale OBJECT ${ALE_SOURCE_FILES})
set_target_properties(ale PROPERTIES CXX_VISIBILITY_PRESET hidden)
set(ALE_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/ale/include/ale/")

target_include_directories(ale
Expand Down Expand Up @@ -693,10 +698,12 @@ target_include_directories(usgscsm
)

target_link_libraries(usgscsm
PUBLIC
nlohmann_json::nlohmann_json
${CSM_LIBRARY}
${ALE_TARGET}
${PROJ_TARGET}
nlohmann_json::nlohmann_json)
PRIVATE
${PROJ_TARGET})

add_executable(usgscsm_cam_test bin/usgscsm_cam_test.cc)
target_link_libraries(usgscsm_cam_test
Expand All @@ -718,6 +725,7 @@ if(USGSCSM_BUILD_TESTS)
find_package (Threads)

target_link_libraries(usgscsm
PUBLIC
gtest ${CMAKE_THREAD_LIBS_INIT})
include(CTest)
enable_testing()
Expand Down
31 changes: 25 additions & 6 deletions bin/usgscsm_cam_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ struct Options {
std::string modify_sup_file; // the .sup file needing a modified model state
std::string output_model_state; // the output model state in .json format
int sample_rate;
bool verbose;
double subpixel_offset, height_above_datum, desired_precision;
Options(): sample_rate(0), subpixel_offset(0.0), height_above_datum(0.0), desired_precision(0.0)
Options(): sample_rate(0), subpixel_offset(0.0), height_above_datum(0.0), desired_precision(0.0), verbose(false)
{}
};

Expand All @@ -45,10 +46,15 @@ bool parseOptions(int argc, char **argv, Options & opt) {

std::vector<std::string> params;
for (int it = 1; it < argc; it++) {
if (std::string(argv[it]) == std::string("--help")) {
std::string arg = std::string(argv[it]);
if (arg == std::string("--help")) {
printUsage(argv[0]);
return false;
}
if (arg == std::string("--verbose") || arg == std::string("-v")) {
opt.verbose = true;
continue;
}
params.push_back(argv[it]);
}

Expand Down Expand Up @@ -132,7 +138,8 @@ double pixDiffNorm(csm::ImageCoord const& a, csm::ImageCoord const& b) {

// Load a CSM camera model from an ISD or state file. Return true on success.
bool loadCsmCameraModel(std::string const& model_file,
std::shared_ptr<csm::RasterGM> & model) {
std::shared_ptr<csm::RasterGM> & model,
Options & opt) {

// This is needed to trigger loading libusgscsm.so. Otherwise 0
// plugins are detected.
Expand Down Expand Up @@ -163,10 +170,11 @@ bool loadCsmCameraModel(std::string const& model_file,

// First try to construct the model from isd, and if that fails, from the state
csm::Model *csm = NULL;
csm::WarningList* warnings = NULL;
csm::WarningList *warnings = new csm::WarningList;
for (size_t i = 0; i < num_models; i++) {

std::string model_name = (*iter)->getModelName(i);

if (csm_plugin->canModelBeConstructedFromISD(isd, model_name, warnings)) {
// Try to construct the model from the isd
csm = csm_plugin->constructModelFromISD(isd, model_name, warnings);
Expand All @@ -180,10 +188,20 @@ bool loadCsmCameraModel(std::string const& model_file,
<< model_file << ".\n";
success = true;
} else {
// No luck so far
if (opt.verbose) {
std::string startStr = "<<<<<< Warnings from " + model_name + " <<<<<<";
std::cout << startStr << std::endl;
for (auto warning : *warnings)
std::cout << warning.getMessage() << std::endl;
std::string endStr(startStr.size(), '<');
std::cout << endStr << std::endl;
}
warnings->clear();
continue;
}

delete warnings;

csm::RasterGM *modelPtr = dynamic_cast<csm::RasterGM*>(csm);
if (modelPtr == NULL) {
// Normally earlier checks should be enough and this should not happen
Expand All @@ -192,6 +210,7 @@ bool loadCsmCameraModel(std::string const& model_file,
} else {
// Assign to a smart pointer which will handle deallocation
model = std::shared_ptr<csm::RasterGM>(modelPtr);
std::cout << "Final model: " << model->getModelName() << std::endl;
break;
}
}
Expand Down Expand Up @@ -240,7 +259,7 @@ int main(int argc, char **argv) {
// specific model types inherit.
std::shared_ptr<csm::RasterGM> model;

if (!loadCsmCameraModel(opt.model, model))
if (!loadCsmCameraModel(opt.model, model, opt))
return 1;

if (opt.output_model_state != "") {
Expand Down
3 changes: 2 additions & 1 deletion include/usgscsm/UsgsAstroPluginSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <RasterGM.h>
#include <csm/Plugin.h>

csm::RasterGM *getUsgsCsmModel(const std::string &stringIsd, const std::string &modelName, csm::WarningList *warnings);
csm::RasterGM *getUsgsCsmModelFromIsd(const std::string &stringIsd, const std::string &modelName, csm::WarningList *warnings);
csm::RasterGM *getUsgsCsmModelFromState(const std::string &stringState, const std::string &modelName, csm::WarningList *warnings);

#endif // INCLUDE_USGSCSM_USGSASTROPLUGINSUPPORT_H_
11 changes: 9 additions & 2 deletions include/usgscsm/UsgsAstroProjectedSensorModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "spdlog/spdlog.h"

#include <proj.h>

#include "UsgsAstroLsSensorModel.h"

class UsgsAstroProjectedSensorModel : public csm::RasterGM,
Expand Down Expand Up @@ -66,14 +68,19 @@ class UsgsAstroProjectedSensorModel : public csm::RasterGM,
// in the input state string.
static std::string getModelNameFromModelState(const std::string &model_state);

std::string constructStateFromIsd(const std::string imageSupportData,
std::string constructStateFromIsd(const std::string imageSupportData,
const std::string modelName,
csm::WarningList *list);

// State data elements;
double m_majorAxis;
double m_minorAxis;
PJ *m_isdProj = NULL;
PJ *m_ecefProj = NULL;
PJ *m_isdProj2ecefProj = NULL;
std::vector<double> m_geoTransform;
std::string m_projString;
std::string m_subModelName;

// Define logging pointer and file content
std::shared_ptr<spdlog::logger> m_logger = spdlog::get("usgscsm_logger");
Expand Down Expand Up @@ -822,7 +829,7 @@ class UsgsAstroProjectedSensorModel : public csm::RasterGM,
//<

protected:
csm::RasterGM *m_camera;
csm::RasterGM *m_camera = NULL;
};

#endif // INCLUDE_USGSCSM_USGSASTROPROJECTEDSENSORMODEL_H_
75 changes: 28 additions & 47 deletions src/UsgsAstroPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,34 +329,29 @@ csm::Model *UsgsAstroPlugin::constructModelFromISD(
MESSAGE_LOG(spdlog::level::info, "Running constructModelFromISD");
std::string stringIsd = loadImageSupportData(imageSupportDataOriginal);

csm::Model *model = getUsgsCsmModel(stringIsd, modelName, warnings);

// Try to get the projected model, if not return the the unprojected model
UsgsAstroProjectedSensorModel *projModel = new UsgsAstroProjectedSensorModel();

try {
UsgsAstroProjectedSensorModel *projModel = new UsgsAstroProjectedSensorModel();
try {
MESSAGE_LOG(spdlog::level::debug, "Trying to construct a UsgsAstroProjectedSensorModel");
projModel->replaceModelState(
projModel->constructStateFromIsd(stringIsd, warnings));
MESSAGE_LOG(spdlog::level::debug, "Constructed model: {}", modelName);
return projModel;
} catch (std::exception &e) {
delete projModel;
csm::Error::ErrorType aErrorType =
csm::Error::SENSOR_MODEL_NOT_CONSTRUCTIBLE;
std::string aMessage = "Could not construct model [";
aMessage += modelName;
aMessage += "] with error [";
aMessage += e.what();
aMessage += "]";
MESSAGE_LOG(spdlog::level::err, aMessage);
std::string aFunction = "UsgsAstroPlugin::getUsgsCsmModel()";
throw csm::Error(aErrorType, aMessage, aFunction);
}
} catch(std::exception &e) {
MESSAGE_LOG(spdlog::level::info, "Failed to make projected model with error: \n{}", e.what());
return model;
MESSAGE_LOG(spdlog::level::debug, "Trying to construct a UsgsAstroProjectedSensorModel");
projModel->replaceModelState(
projModel->constructStateFromIsd(stringIsd, modelName, warnings));
MESSAGE_LOG(spdlog::level::debug, "Constructed model: {}", modelName);
return projModel;
} catch (std::exception &e) {
delete projModel;
csm::Error::ErrorType aErrorType =
csm::Error::SENSOR_MODEL_NOT_CONSTRUCTIBLE;
std::string aMessage = "Could not construct model [";
aMessage += modelName;
aMessage += "] with error [";
aMessage += e.what();
aMessage += "]";
MESSAGE_LOG(spdlog::level::err, aMessage);
}

csm::Model *model = getUsgsCsmModelFromIsd(stringIsd, modelName, warnings);
return model;
}

csm::Model *UsgsAstroPlugin::constructModelFromState(
Expand All @@ -366,29 +361,15 @@ csm::Model *UsgsAstroPlugin::constructModelFromState(
std::string modelName = state["m_modelName"];
MESSAGE_LOG(spdlog::level::debug, "Using model name: {}", modelName);

if (modelName == UsgsAstroFrameSensorModel::_SENSOR_MODEL_NAME) {
MESSAGE_LOG(spdlog::level::debug, "Constructing a UsgsAstroFrameSensorModel");
UsgsAstroFrameSensorModel *model = new UsgsAstroFrameSensorModel();
model->replaceModelState(modelState);
return model;
} else if (modelName == UsgsAstroLsSensorModel::_SENSOR_MODEL_NAME) {
MESSAGE_LOG(spdlog::level::debug, "Constructing a UsgsAstroLsSensorModel");
UsgsAstroLsSensorModel *model = new UsgsAstroLsSensorModel();
model->replaceModelState(modelState);
return model;
} else if (modelName == UsgsAstroProjectedSensorModel::_SENSOR_MODEL_NAME) {
MESSAGE_LOG(spdlog::level::debug, "Constructing a UsgsAstroProjectedSensorModel");
UsgsAstroProjectedSensorModel *model = new UsgsAstroProjectedSensorModel();
model->replaceModelState(modelState);
return model;
}else if (modelName == UsgsAstroSarSensorModel::_SENSOR_MODEL_NAME) {
MESSAGE_LOG(spdlog::level::debug, "Constructing a UsgsAstroSarSensorModel");
UsgsAstroSarSensorModel *model = new UsgsAstroSarSensorModel();
model->replaceModelState(modelState);
return model;
} else {
try {
return getUsgsCsmModelFromState(modelState, modelName, warnings);
}
catch (std::exception &e) {
csm::Error::ErrorType aErrorType = csm::Error::ISD_NOT_SUPPORTED;
std::string aMessage = "Model" + modelName + " not supported: ";
std::string aMessage = "Model " + modelName + " not supported";
aMessage += " with error: [";
aMessage += e.what();
aMessage += "]";
std::string aFunction = "UsgsAstroPlugin::constructModelFromState()";
MESSAGE_LOG(spdlog::level::err, aMessage);
throw csm::Error(aErrorType, aMessage, aFunction);
Expand Down
Loading

0 comments on commit b861a95

Please sign in to comment.