### Install Shyft Package Source: https://github.com/felixmatt/shyft/blob/master/README.md After successful building and testing, use this command to install Shyft globally. Ensure the `LD_LIBRARY_PATH` is correctly set to locate necessary libraries. ```bash cd $SHYFT_WORKSPACE/shyft python setup.py install ``` -------------------------------- ### Install Dependencies and Build Shyft Source: https://github.com/felixmatt/shyft/blob/master/README.md Use this command to install project dependencies and build the Python extensions in-place. Ensure environment variables like `SHYFT_DEPENDENCIES_DIR` are set if dependencies are managed externally. ```bash pip install -r requirements.txt python setup.py build_ext --inplace ``` -------------------------------- ### Define and Install Python Extension Targets Source: https://github.com/felixmatt/shyft/blob/master/shyft/api/CMakeLists.txt Iterates through source files to create shared library targets for Python extensions and configures their installation paths. ```cmake # Compile extensions api extension foreach(python_api_extension "api" ) file(GLOB cpps ${CMAKE_SOURCE_DIR}/api/boostpython/${python_api_extension}*.cpp ) add_library(${python_api_extension} SHARED ${CXX_FILES} ${cpps} ) set_target_properties(${python_api_extension} PROPERTIES OUTPUT_NAME ${python_api_extension}) # Python extensions do not use the 'lib' prefix set_target_properties(${python_api_extension} PROPERTIES PREFIX "_" INSTALL_RPATH "$ORIGIN/../lib") set_property(TARGET ${python_api_extension} APPEND PROPERTY COMPILE_DEFINITIONS SHYFT_EXTENSION) target_link_libraries(${python_api_extension} shyftcore shyftapi ${LIBS} ) install(TARGETS ${python_api_extension} DESTINATION ${CMAKE_SOURCE_DIR}/shyft/api) endforeach(python_api_extension) # then for each sub module foreach(python_extension "pt_gs_k" "pt_ss_k" "pt_hs_k" "hbv_stack" "pt_hps_k") add_library(${python_extension} SHARED ${CXX_FILES} ${CMAKE_SOURCE_DIR}/api/boostpython/${python_extension}.cpp) set_target_properties(${python_extension} PROPERTIES OUTPUT_NAME ${python_extension}) # Python extensions do not use the 'lib' prefix set_target_properties(${python_extension} PROPERTIES PREFIX "_" INSTALL_RPATH "$ORIGIN/../../lib") set_property(TARGET ${python_extension} APPEND PROPERTY COMPILE_DEFINITIONS SHYFT_EXTENSION) target_link_libraries(${python_extension} shyftcore shyftapi ${LIBS} ) install(TARGETS ${python_extension} DESTINATION ${CMAKE_SOURCE_DIR}/shyft/api/${python_extension}) endforeach(python_extension) ``` -------------------------------- ### Install Python Dependencies Source: https://github.com/felixmatt/shyft/blob/master/README.md Installs required Python packages for running tests using pip or conda. ```bash $ pip install -r requirements.txt ``` ```bash $ cat requirements.txt | xargs conda install ``` -------------------------------- ### Get Source Values at Specific Time Source: https://context7.com/felixmatt/shyft/llms.txt Retrieves the values from all temperature sources at a specified time. The result is a numpy array. ```python # Get values from all sources at specific time temp_at_t = temp_sources.values_at_time(ta.time(10)) # Returns numpy array ``` -------------------------------- ### Define Time Period and Get Time Series Source: https://context7.com/felixmatt/shyft/llms.txt Defines a time period using the api.UtcPeriod and retrieves time series data for specified input types from a repository. ```python # Define time period utc = api.Calendar() period = api.UtcPeriod( utc.time(2015, 1, 1), utc.time(2015, 1, 11) ) # Get time series input_types = ['temperature', 'precipitation', 'wind_speed', 'relative_humidity', 'radiation'] sources = repo.get_timeseries(input_types, period) ``` -------------------------------- ### Initialize DefaultSimulator with Mock Repositories Source: https://context7.com/felixmatt/shyft/llms.txt Sets up the DefaultSimulator using mock repositories for region models, time series, interpolation, and states. This is useful for testing or when actual repositories are not available. ```python from shyft.orchestration.simulator import DefaultSimulator from shyft import api class MockRegionModelRepo: def get_region_model(self, region_id, catchments=None): from shyft.api import pt_gs_k gcds = api.GeoCellDataVector() for i in range(10): gp = api.GeoPoint(500000 + 1000*i, 6500000, 500) ltf = api.LandTypeFractions(0.01, 0.05, 0.19, 0.3, 0.45) gcd = api.GeoCellData(gp, 1e6, 0, 0.9, ltf) gcds.append(gcd) return pt_gs_k.PTGSKModel(gcds, pt_gs_k.PTGSKParameter()) class MockGeoTsRepo: def get_timeseries(self, types, period, geo_location_criteria=None): return {} class MockInterpolationRepo: def get_parameters(self, interp_id): return api.InterpolationParameter() class MockStateRepo: def get_state(self, state_id): from shyft.api import pt_gs_k states = pt_gs_k.PTGSKStateWithIdVector() return states simulator = DefaultSimulator( region_id="my_region", interpolation_id=0, region_model_repository=MockRegionModelRepo(), geo_ts_repository=MockGeoTsRepo(), interpolation_parameter_repository=MockInterpolationRepo(), initial_state_repository=MockStateRepo(), catchments=None ) ta = simulator.time_axis ``` -------------------------------- ### Create and Configure Static Library Source: https://github.com/felixmatt/shyft/blob/master/core/CMakeLists.txt Generates a static library named 'shyftcore' from the defined sources and sets its output name. Includes a conditional prefix for MSVC. ```cmake message(STATUS "Generating Makefile for the SHyFT static library...") add_library(shyftcore STATIC ${SOURCES} ) set_target_properties(shyftcore PROPERTIES OUTPUT_NAME shyftcore) if (MSVC) set_target_properties(shyftcore PROPERTIES PREFIX lib) endif() ``` -------------------------------- ### Configure and Run BOBYQA Optimization Source: https://context7.com/felixmatt/shyft/llms.txt Sets parameter bounds and runs the BOBYQA optimization algorithm. Ensure parameter bounds are correctly defined before optimization. ```python p_min = pt_gs_k.PTGSKParameter() p_max = pt_gs_k.PTGSKParameter() p_min.kirchner.c1 = -3.0 p_max.kirchner.c1 = -1.9 p_min.kirchner.c2 = 0.80 p_max.kirchner.c2 = 0.99 optimizer.target_specification = target_spec optimizer.parameter_lower_bound = p_min optimizer.parameter_upper_bound = p_max optimizer.set_verbose_level(1) p_init = pt_gs_k.PTGSKParameter() p_init.kirchner.c1 = -2.5 p_init.kirchner.c2 = 0.9 p_opt = optimizer.optimize( p_init, max_n_evaluations=1500, tr_start=0.1, tr_stop=1e-5 ) goal = optimizer.calculate_goal_function(p_opt) print(f"Optimized kirchner.c1={p_opt.kirchner.c1:.4f}") print(f"Optimized kirchner.c2={p_opt.kirchner.c2:.4f}") print(f"Goal function value: {goal:.4f}") ``` -------------------------------- ### Build Static Library with CMake Source: https://github.com/felixmatt/shyft/blob/master/api/CMakeLists.txt Configures CMake to build a static library named 'shyftapi' using the defined sources. Includes setting output name and prefix for MSVC. ```cmake message(STATUS "Generating Makefile for the SHyFT api static library...") add_library(shyftapi STATIC ${SOURCES}) set_target_properties(shyftapi PROPERTIES OUTPUT_NAME shyftapi) if (MSVC) set_target_properties(shyftapi PROPERTIES PREFIX lib) endif() target_link_libraries(shyftapi ${LIBS}) ``` -------------------------------- ### Configure Simulation Environment Source: https://context7.com/felixmatt/shyft/llms.txt Set up interpolation parameters and region environments for running hydrological simulations. ```python from shyft import api from shyft.api import pt_gs_k import numpy as np # Assume model is created as in previous example # ... model creation code ... # Create interpolation parameters ip = api.InterpolationParameter() ip.use_idw_for_temperature = True ip.temperature_idw.default_temp_gradient = -0.005 # Create region environment with sources utc = api.Calendar() t0 = utc.time(2015, 1, 1) dt = api.deltahours(1) n = 240 ta = api.TimeAxisFixedDeltaT(t0, dt, n) region_env = api.ARegionEnvironment() mid_point = api.GeoPoint(500000 + 10000, 6500000, 750) ``` -------------------------------- ### Clone Shyft Repositories Source: https://github.com/felixmatt/shyft/blob/master/README.md Initializes a workspace directory and clones the main code, data, and documentation repositories. ```bash mkdir shyft_workspace && cd shyft_workspace export SHYFT_WORKSPACE=`pwd` git clone https://github.com/statkraft/shyft.git git clone https://github.com/statkraft/shyft-data.git git clone https://github.com/statkraft/shyft-doc.git ``` -------------------------------- ### Create Geo-Located Temperature Source Source: https://context7.com/felixmatt/shyft/llms.txt Demonstrates creating a single geo-located temperature time series source. Ensure 'api' and 'numpy' are imported. ```python from shyft import api import numpy as np utc = api.Calendar() t0 = utc.time(2015, 1, 1) dt = api.deltahours(1) n = 240 ta = api.TimeAxis(t0, dt, n) # Create temperature source with geo-location temp_values = api.DoubleVector.from_numpy( 10.0 + 5.0 * np.sin(np.linspace(0, 2*np.pi, n)) ) temp_ts = api.TimeSeries(ta=ta, values=temp_values, point_fx=api.POINT_AVERAGE_VALUE) temp_source = api.TemperatureSource(api.GeoPoint(500000, 6500000, 100), temp_ts) temp_source.uid = "station_001" # Optional unique identifier ``` -------------------------------- ### Run Simulation and Extract Results Source: https://context7.com/felixmatt/shyft/llms.txt Configures meteorological inputs, initializes states, executes the simulation, and retrieves time series data for discharge and snow metrics. ```python # Add meteorological inputs (simplified - use actual data in practice) def add_source(vector, source_type, point, value): tv = api.UtcTimeVector([ta.total_period().start]) vv = api.DoubleVector([value]) ts = api.TsFactory().create_time_point_ts(ta.total_period(), tv, vv, api.POINT_AVERAGE_VALUE) vector.append(source_type(point, ts)) add_source(region_env.temperature, api.TemperatureSource, mid_point, 5.0) add_source(region_env.precipitation, api.PrecipitationSource, mid_point, 3.0) add_source(region_env.wind_speed, api.WindSpeedSource, mid_point, 2.0) add_source(region_env.rel_hum, api.RelHumSource, mid_point, 0.7) add_source(region_env.radiation, api.RadiationSource, mid_point, 200.0) # Run interpolation model.interpolate(ip, region_env) # Set initial state s0 = pt_gs_k.PTGSKStateVector() for i in range(model.size()): si = pt_gs_k.PTGSKState() si.kirchner.q = 40.0 # Initial discharge state s0.append(si) model.set_states(s0) # Enable state collection for output model.set_state_collection(-1, True) # -1 means all cells # Run simulation model.run_cells() # Full simulation # Or run in steps: model.run_cells(use_ncore=0, start_step=0, n_steps=24) # Extract results cids = api.IntVector() # Empty = all catchments discharge_ts = model.statistics.discharge(cids) discharge_value = model.statistics.discharge_value(cids, 0) # First timestep temperature_ts = model.statistics.temperature(cids) precipitation_ts = model.statistics.precipitation(cids) # Snow model outputs sca_ts = model.gamma_snow_response.sca(cids) # Snow covered area albedo_ts = model.gamma_snow_state.albedo(cids) print(f"Total discharge at t=0: {discharge_value:.2f} m³/s") print(f"Discharge time series size: {discharge_ts.size()}") ``` -------------------------------- ### Run C++ Core Tests Source: https://github.com/felixmatt/shyft/blob/master/README.md Execute the C++ core tests by navigating to the build test directory and using the `make test` command. This requires the `shyft-data` repository to be a sibling of the `shyft` repository. ```bash cd $SHYFT_WORKSPACE/shyft/build/test make test ``` -------------------------------- ### Quick API Test Source: https://github.com/felixmatt/shyft/blob/master/README.md Run this command to perform a basic check of the Shyft API import. If an `ImportError` related to `libboost_python3.so` occurs, it indicates an issue with the `LD_LIBRARY_PATH`. ```python python -c "from shyft import api" ``` -------------------------------- ### Configure Shyft CMake Build System Source: https://github.com/felixmatt/shyft/blob/master/CMakeLists.txt Initializes the project, sets build options, and configures environment-specific dependencies and compiler flags. ```cmake cmake_minimum_required(VERSION 3.4.0) project(shyft) # Get the full version for Shyft file(READ ${CMAKE_CURRENT_SOURCE_DIR}/VERSION SHYFT_VERSION_STRING) message("Configuring for Shyft version: " ${SHYFT_VERSION_STRING}) #if ccache, use it, but require cmake 3.4.0.. find_program(CCACHE_FOUND ccache) if(CCACHE_FOUND) set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) endif(CCACHE_FOUND) # options option(BUILD_TESTING "Build test programs for SHYFT C++ core library" ON) option(BUILD_PYTHON_EXTENSIONS "Build Python extensions for SHYFT" ON) set(SHYFT_DEFAULT_BUILD_TYPE "Release") if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "No build type specified. Defaulting to '${SHYFT_DEFAULT_BUILD_TYPE}'.") set(CMAKE_BUILD_TYPE ${SHYFT_DEFAULT_BUILD_TYPE} CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() # The dependencies directory if(DEFINED ENV{SHYFT_DEPENDENCIES_DIR}) set(SHYFT_DEPENDENCIES_DIR $ENV{SHYFT_DEPENDENCIES_DIR}) else() set(SHYFT_DEPENDENCIES_DIR "${PROJECT_SOURCE_DIR}/../shyft_dependencies") endif() # Our code requires an absolute directory for the dependencies get_filename_component(SHYFT_DEPENDENCIES ${SHYFT_DEPENDENCIES_DIR} ABSOLUTE) message("SHYFT_DEPENDENCIES directory: " ${SHYFT_DEPENDENCIES}) message("You can override the above via the $SHYFT_DEPENDENCIES_DIR environment variable.") # The flags for compile the beast set(CMAKE_CXX_FLAGS "-Wno-deprecated-declarations -std=c++14 -fPIC -fexceptions -pthread -Winvalid-pch -L${SHYFT_DEPENDENCIES}/lib" CACHE STRING "CXX flags." FORCE) # add defines that need to be consistent across sub-projects, notice that we need MINIMIZE_SIZE to ensure g++ vs. ms c++ compat add_definitions("-DARMA_DONT_USE_WRAPPER -DARMA_USE_CXX11 -DARMA_NO_DEBUG -DBOOST_VARIANT_MINIMIZE_SIZE ") # The directories to be included include_directories(${CMAKE_SOURCE_DIR} ${SHYFT_DEPENDENCIES}/include) # C++ core and tests if(BUILD_TESTING) enable_testing() add_subdirectory(core) add_subdirectory(api) add_subdirectory(test) endif(BUILD_TESTING) # Python extensions if(BUILD_PYTHON_EXTENSIONS) add_subdirectory(shyft/api) endif(BUILD_PYTHON_EXTENSIONS) ``` -------------------------------- ### Run Python API Test Suite Source: https://github.com/felixmatt/shyft/blob/master/README.md Navigate to the API test directory within the Shyft repository and run the Python API tests. This is a subset of the full test suite. ```bash cd $SHYFT_WORKSPACE/shyft/shyft/tests/api nosetests ``` -------------------------------- ### Set Environment Variables and Build Shyft (Manual) Source: https://github.com/felixmatt/shyft/blob/master/README.md Manually set up environment variables for the workspace and dependencies, then navigate to the Shyft repository to build the extensions. This is an alternative to setting environment variables within a conda environment. ```bash # assumes you are still in the shyft_workspace directory containing # the git repositories export SHYFT_WORKSPACE=`pwd` mkdir shyft-dependencies export SHYFT_DEPENDENCIES_DIR=$SHYFT_WORKSPACE/shyft-dependencies cd shyft #the shyft repository python setup.py build_ext --inplace ``` -------------------------------- ### Initialize Region Models Source: https://context7.com/felixmatt/shyft/llms.txt Construct a region model from GeoCellData and configure specific model parameters and execution settings. ```python from shyft import api from shyft.api import pt_gs_k # Priestley-Taylor, Gamma Snow, Kirchner # Build model from geo cell data num_cells = 20 cell_area = 1000 * 1000 # 1 km² gcds = api.GeoCellDataVector() for i in range(num_cells): gp = api.GeoPoint(500000 + 1000*i, 6500000, 500 + 25*i) ltf = api.LandTypeFractions(0.01, 0.05, 0.19, 0.3, 0.45) gcd = api.GeoCellData(gp, cell_area, i % 3, 0.9, ltf) gcds.append(gcd) # Create region model with default parameters region_param = pt_gs_k.PTGSKParameter() model = pt_gs_k.PTGSKModel(gcds, region_param) print(f"Model size: {model.size()} cells") # Configure model parameters region_param = model.get_region_parameter() region_param.gs.snow_cv_forest_factor = 0.1 region_param.gs.snow_cv_altitude_factor = 0.0001 region_param.kirchner.c1 = -2.5 region_param.kirchner.c2 = 0.9 # Set parallel execution threads model.ncore = 4 # Use 4 threads # Initialize time axis for simulation utc = api.Calendar() time_axis = api.TimeAxisFixedDeltaT( utc.time(2015, 1, 1), api.deltahours(1), 240 ) model.initialize_cell_environment(time_axis) ``` -------------------------------- ### Define Test Executable and Sources Source: https://github.com/felixmatt/shyft/blob/master/test/CMakeLists.txt Configures the main test executable and lists all source files for the test suite. Ensure all test source files are included here. ```cmake set(sources actual_evapotranspiration_test.cpp api_test.cpp calibration_test.cpp cell_builder_test.cpp dtss_test.cpp gamma_snow_test.cpp glacier_melt_test.cpp gridpp_test.cpp hbv_actual_evapotranspiration_test.cpp hbv_snow_test.cpp hbv_soil_test.cpp hbv_stack_test.cpp hbv_tank_test.cpp inverse_distance_test.cpp kalman_test.cpp kirchner_test.cpp kriging_test.cpp max_abs_average_accessor_test.cpp merge_test.cpp mocks.cpp predictor_test.cpp priestley_taylor_test.cpp pt_gs_k_test.cpp pt_hs_k_test.cpp pt_ss_k_test.cpp qm_test.cpp region_model_test.cpp routing_test.cpp runner.cpp sceua_test.cpp serialization_test.cpp skaugen_test.cpp time_axis_test.cpp time_series_average_test.cpp time_series_fixup_test.cpp time_series_test.cpp utctime_utilities_test.cpp hbv_physical_snow_test.cpp pt_hps_k_test.cpp test_ice_packing.cpp ) set(target "test_shyft") # Flags add_definitions("-D__UNIT_TEST__ -DVERBOSE=0 ") find_package(PNG REQUIRED) find_package(LAPACK REQUIRED) add_executable(${target} ${sources}) ``` -------------------------------- ### Create Region Environment with Meteorological Sources Source: https://context7.com/felixmatt/shyft/llms.txt Bundles meteorological input sources for hydrological simulation into a RegionEnvironment. Uses a helper function to create constant geo-located time series. ```python from shyft import api import numpy as np utc = api.Calendar() t0 = utc.time(2015, 1, 1) dt = api.deltahours(1) n = 240 ta = api.TimeAxis(t0, dt, n) def create_constant_geo_ts(geo_ts_type, geo_point, period, value): """Helper to create constant geo-located time series.""" tv = api.UtcTimeVector([period.start]) vv = api.DoubleVector([value]) cts = api.TsFactory().create_time_point_ts(period, tv, vv, api.POINT_AVERAGE_VALUE) return geo_ts_type(geo_point, cts) # Create region environment region_env = api.ARegionEnvironment() mid_point = api.GeoPoint(500000, 6500000, 500) period = ta.total_period() # Add meteorological sources region_env.temperature.append( create_constant_geo_ts(api.TemperatureSource, mid_point, period, 10.0) ) region_env.precipitation.append( create_constant_geo_ts(api.PrecipitationSource, mid_point, period, 5.0) ) region_env.wind_speed.append( create_constant_geo_ts(api.WindSpeedSource, mid_point, period, 2.0) ) region_env.rel_hum.append( create_constant_geo_ts(api.RelHumSource, mid_point, period, 0.7) ) region_env.radiation.append( create_constant_geo_ts(api.RadiationSource, mid_point, period, 300.0) ) # Access values print(f"Number of temperature sources: {len(region_env.temperature)}") print(f"Temperature value: {region_env.temperature[0].ts.value(0)}") ``` -------------------------------- ### Calibrate Model Parameters Source: https://context7.com/felixmatt/shyft/llms.txt Sets up an optimizer and target specifications to calibrate model parameters against observed discharge data. ```python from shyft import api from shyft.api import pt_gs_k # Create and setup model (see previous examples) # ... model creation, interpolation, initial state ... # Create optimizer from model optimizer = pt_gs_k.PTGSKOptModel.optimizer_t(model) # Create target specification from observed discharge utc = api.Calendar() t0 = utc.time(2015, 1, 1) dt = api.deltahours(1) n = 240 ta = api.TimeAxis(t0, dt, n) # Observed discharge time series obs_values = api.DoubleVector.from_numpy(np.random.exponential(50, n)) obs_ts = api.TimeSeries(ta=ta, values=obs_values, point_fx=api.POINT_AVERAGE_VALUE) # Target specification cids = api.IntVector([0]) # Catchment IDs to calibrate target = api.TargetSpecificationPts( obs_ts, cids, scale_factor=1.0, calc_mode=api.KLING_GUPTA, # Or api.NASH_SUTCLIFFE, api.ABS_DIFF s_r=1.0, s_a=1.0, s_b=1.0, # Kling-Gupta weights catchment_property=api.DISCHARGE, uid='calibration_target' ) target_spec = api.TargetSpecificationVector() target_spec.append(target) ``` -------------------------------- ### Run All Tests Source: https://github.com/felixmatt/shyft/blob/master/README.md Execute the comprehensive test suite for Shyft from the root repository directory. This command runs both C++ and Python unit and integration tests. ```bash $ nosetests ``` -------------------------------- ### Run C++ and Python Tests Source: https://github.com/felixmatt/shyft/blob/master/README.md Execute C++ tests using `make test` and Python tests using `nosetests`. Ensure `LD_LIBRARY_PATH` and `PYTHONPATH` are correctly configured for the tests to run successfully. ```bash $ export LD_LIBRARY_PATH=$SHYFT_DEPENDENCIES_DIR/local/lib $ make test # run the C++ tests $ export PYTHONPATH=$SHYFT_SOURCES $ nosetests .. # run the Python tests ``` -------------------------------- ### Load Simulation Configuration Source: https://context7.com/felixmatt/shyft/llms.txt Loads simulation configuration from a YAML file. Ensure the configuration file exists before attempting to load. ```python config_file = "/absolute/path/to/simulation_config.yaml" if os.path.exists(config_file): sim_config = YAMLSimConfig(config_file, "simulation") # Access configuration properties ta = sim_config.time_axis region_repo = sim_config.get_region_model_repo() geots_repo = sim_config.get_geots_repo() interp_repo = sim_config.get_interp_repo() # Get initial and end state repositories init_state_repo = sim_config.get_initial_state_repo() end_state_repo = sim_config.get_end_state_repo() ``` -------------------------------- ### Manual CMake Compilation Steps Source: https://github.com/felixmatt/shyft/blob/master/README.md Compile Shyft manually using CMake. This involves setting source and dependency directories, configuring the build, and then compiling the C++ sources. This method is recommended for developers. ```bash $ export SHYFT_SOURCES=$SHYFT_WORKSPACE # absolute path required! $ cd $SHYFT_SOURCES $ mkdir build $ cd build $ export SHYFT_DEPENDENCIES_DIR=$SHYFT_SOURCES/.. # directory_to_keep_dependencies, absolute path $ cmake .. # configuration step; or "ccmake .." for curses interface $ make -j 4 # do the actual compilation of C++ sources (using 4 processes) $ make install # copy Python extensions somewhere in $SHYFT_SOURCES ``` -------------------------------- ### Configure Interpolation Parameters Source: https://context7.com/felixmatt/shyft/llms.txt Sets up interpolation parameters for meteorological inputs using IDW or Bayesian Kriging. Includes specific settings for temperature and precipitation. ```python from shyft import api # Create interpolation parameters ip = api.InterpolationParameter() # Temperature IDW settings ip.temperature_idw.default_temp_gradient = -0.005 # -0.5°C per 100m ip.temperature_idw.gradient_by_equation = True # Compute gradient from data ip.temperature_idw.max_members = 6 # Max sources to use ip.temperature_idw.max_distance = 20000 # 20 km max distance ip.temperature_idw.zscale = 0.5 # Elevation scaling factor ip.temperature_idw.distance_measure_factor = 1.0 # Linear weighting # Enable IDW for temperature (vs Bayesian Kriging) ip.use_idw_for_temperature = True # Precipitation settings ip.precipitation.scale_factor = 1.02 # Precipitation correction factor # Bayesian Kriging parameters for temperature btk = api.BTKParameter( temperature_gradient=-0.6, # °C per 100m temperature_gradient_sd=0.25, # Standard deviation sill=25.0, # Variogram sill nugget=0.5, # Variogram nugget range=20000.0, # Variogram range in meters zscale=20.0 # Elevation scaling ) ``` -------------------------------- ### Load Calibration Configuration Source: https://context7.com/felixmatt/shyft/llms.txt Loads calibration configuration from a YAML file. This includes optimization methods and target data for calibration. ```python calib_file = "/absolute/path/to/calibration_config.yaml" if os.path.exists(calib_file): calib_config = YAMLCalibConfig(calib_file, "calibration") target_repo = calib_config.get_target_repo() ``` -------------------------------- ### Link Libraries for Test Executable Source: https://github.com/felixmatt/shyft/blob/master/test/CMakeLists.txt Links the necessary libraries to the test executable, including core Shyft libraries, Boost, dlib, PNG, and LAPACK. Ensure these libraries are available in the specified paths. ```cmake target_link_libraries(${target} shyftcore shyftapi ${SHYFT_DEPENDENCIES}/lib/libboost_filesystem.so ${SHYFT_DEPENDENCIES}/lib/libboost_system.so ${SHYFT_DEPENDENCIES}/lib/libboost_serialization.so ${SHYFT_DEPENDENCIES}/lib/libdlib.so ${PNG_LIBRARY} ${LAPACK_LIBRARIES} ) ``` -------------------------------- ### Define Individual Test Cases Source: https://github.com/felixmatt/shyft/blob/master/test/CMakeLists.txt Defines individual test cases that can be run using the main test executable. Each 'add_test' command specifies a test name and the test suite to execute. ```cmake add_test(inverse_distance ${target} -nv --test-suite=inverse_distance) ``` ```cmake add_test(time_axis ${target} -nv --test-suite=time_axis) ``` ```cmake add_test(region_model ${target} -nv --test-suite=region_model) ``` ```cmake add_test(priestley_taylor ${target} -nv --test-suite=priestley_taylor) ``` ```cmake add_test(gamma_snow ${target} -nv --test-suite=gamma_snow) ``` ```cmake add_test(universal_snow ${target} -nv --test-suite=universal_snow) ``` ```cmake add_test(kirchner ${target} -nv --test-suite=kirchner) ``` ```cmake add_test(bayesian_kriging ${target} -nv --test-suite=bayesian_kriging) ``` ```cmake add_test(utctime_utilities ${target} -nv --test-suite=utctime_utilities) ``` ```cmake add_test(pt_gs_k ${target} -nv --test-suite=pt_gs_k) ``` ```cmake add_test(actual_evapotranspiration ${target} -nv --test-suite=actual_evapotranspiration) ``` ```cmake add_test(calibration ${target} -nv --test-suite=calibration) ``` ```cmake add_test(hbv_snow ${target} -nv --test-suite=hbv_snow) ``` ```cmake add_test(hbv_physical_snow ${target} -nv --test-suite=hbv_physical_snow) ``` ```cmake add_test(pt_hs_k ${target} -nv --test-suite=pt_hs_k) ``` ```cmake add_test(pt_ss_k ${target} -nv --test-suite=pt_ss_k) ``` ```cmake add_test(pt_hps_k ${target} -nv --test-suite=pt_hps_k) ``` ```cmake add_test(time_series ${target} -nv --test-suite=time_series) ``` ```cmake add_test(api ${target} -nv --test-suite=api) ``` ```cmake add_test(cell_builder ${target} -nv --test-suite=cell_builder) ``` ```cmake add_test(skaugen ${target} -nv --test-suite=skaugen) ``` ```cmake add_test(sceua ${target} -nv --test-suite=sceua) ``` ```cmake add_test(gridpp ${target} -nv --test-suite=gridpp) ``` ```cmake add_test(kalman ${target} -nv --test-suite=kalman) ``` ```cmake add_test(hbv_tank ${target} -nv --test-suite=hbv_tank) ``` ```cmake add_test(hbv_soil ${target} -nv --test-suite=hbv_soil) ``` ```cmake add_test(hbv_actual_evapotranspiration ${target} -nv --test-suite=hbv_actual_evapotranspiration) ``` ```cmake add_test(glacier_melt ${target} -nv --test-suite=glacier_melt) ``` ```cmake add_test(kriging ${target} -nv --test-suite=kriging) ``` ```cmake add_test(serialization ${target} -nv --test-suite=serialization) ``` ```cmake add_test(routing ${target} -nv --test-suite=routing) ``` ```cmake add_test(dtss ${target} -nv --test-suite=dtss) ``` ```cmake add_test(qm ${target} -nv --test-suite=qm) ``` ```cmake add_test(predictors ${target} -nv --test-suite=predictors) ``` ```cmake add_test(ts_merge ${target} -nv --test-suite=ts_merge) ``` ```cmake add_test(pt_hps_k ${target} -nv --test-suite=pt_hps_k) ``` ```cmake add_test(hbv_physical_snow ${target} --test-suite=hbv_physical_snow) ``` -------------------------------- ### Configure IDW and Kriging Parameters Source: https://context7.com/felixmatt/shyft/llms.txt Define parameter objects for Inverse Distance Weighting (IDW) and Ordinary Kriging (OK) interpolation methods. ```python # IDW parameter objects for different variables idw_temp = api.IDWTemperatureParameter() idw_temp.max_distance = 200000 idw_temp.max_members = 20 idw_precip = api.IDWPrecipitationParameter() idw_generic = api.IDWParameter() # For wind, radiation, humidity # Ordinary Kriging parameters ok = api.OKParameter( c=1.0, # Sill a=10000.0, # Range in meters cov_type=api.OKCovarianceType.EXPONENTIAL, # Or GAUSSIAN z_scale=1.0 ) ``` -------------------------------- ### Set LD_LIBRARY_PATH for Boost Libraries Source: https://github.com/felixmatt/shyft/blob/master/README.md Configure the `LD_LIBRARY_PATH` environment variable to ensure that the Boost libraries are discoverable by the system. This is crucial for Shyft to function correctly after building. ```bash export LD_LIBRARY_PATH=$SHYFT_DEPENDENCIES_DIR/local/lib ``` -------------------------------- ### Create NetCDF Data Repository Source: https://context7.com/felixmatt/shyft/llms.txt Initializes a CFDataRepository to read geo-located time series from NetCDF files. Supports selection by bounding box or unique IDs. ```python from shyft.repository.netcdf.cf_geo_ts_repository import CFDataRepository from shyft import api # Create repository for NetCDF data repo = CFDataRepository( epsg=32633, # UTM zone 33N stations_met="/path/to/meteorological_data.nc", selection_criteria={ 'bbox': [[450000, 550000, 550000, 450000], # x coordinates [6400000, 6400000, 6600000, 6600000]] # y coordinates } # Or use unique_id selection: # selection_criteria={'unique_id': ['station1', 'station2']} ) ``` -------------------------------- ### Configure Compiler Flags and Library Dependencies Source: https://github.com/felixmatt/shyft/blob/master/shyft/api/CMakeLists.txt Sets compiler flags and defines the list of required libraries for linking. ```cmake find_package(LAPACK REQUIRED) #find_package(CBLAS REQUIRED) #find_package(dlib REQUIRED dblib_shared) # Include files in core directory # ensure to have python last, since it could contain ref to another boost version include_directories( ${PROJECT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} ${SHYFT_DEPENDENCIES}/include ${include_python} ${include_numpy} ) # Set the compiler flags (for gcc and clang) set(C_FLAGS -O3 -shared -L${lib_python} -pthread -s -fPIC -std=c++14 -DARMA_DONT_USE_WRAPPER -DARMA_USE_CXX11 ) set(LIBS "-L${SHYFT_DEPENDENCIES}/lib -lboost_python3 -lboost_serialization -lboost_filesystem -lboost_system -ldlib ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES}") ``` -------------------------------- ### Model Performance Metrics (Nash-Sutcliffe, Kling-Gupta) Source: https://context7.com/felixmatt/shyft/llms.txt Calculates Nash-Sutcliffe and Kling-Gupta efficiency coefficients for comparing observed and modeled time series. Demonstrates both function calls and convenience methods on TimeSeries objects. ```python from shyft import api import numpy as np utc = api.Calendar() t0 = utc.time(2016, 1, 1) dt = api.deltahours(1) n = 240 ta = api.TimeAxis(t0, dt, n) # Create observed and modeled time series obs_values = api.DoubleVector.from_numpy( np.sin(np.linspace(0, 4*np.pi, n)) + 5.0 ) mod_values = api.DoubleVector.from_numpy( np.sin(np.linspace(0.1, 4*np.pi + 0.1, n)) + 5.2 ) obs_ts = api.TimeSeries(ta=ta, values=obs_values, point_fx=api.POINT_AVERAGE_VALUE) mod_ts = api.TimeSeries(ta=ta, values=mod_values, point_fx=api.POINT_AVERAGE_VALUE) # Nash-Sutcliffe efficiency (1.0 = perfect match) ns = api.nash_sutcliffe(obs_ts, mod_ts, ta) print(f"Nash-Sutcliffe: {ns:.4f}") # Kling-Gupta efficiency with scale factors # s_r: correlation weight, s_a: relative average weight, s_b: relative std weight kg = api.kling_gupta(obs_ts, mod_ts, ta, s_r=1.0, s_a=1.0, s_b=1.0) print(f"Kling-Gupta: {kg:.4f}") # Convenience methods on TimeSeries objects ns_direct = obs_ts.nash_sutcliffe(mod_ts) kg_direct = obs_ts.kling_gupta(mod_ts, s_r=1.0, s_a=1.0, s_b=1.0) # Perfect match verification perfect_ns = api.nash_sutcliffe(obs_ts, obs_ts, ta) # Returns 1.0 perfect_kg = api.kling_gupta(obs_ts, obs_ts, ta, 1.0, 1.0, 1.0) # Returns 1.0 ``` -------------------------------- ### Define C++ Core Library Sources Source: https://github.com/felixmatt/shyft/blob/master/core/CMakeLists.txt Lists the source files for the C++ core library. Ensure all listed files exist in the project. ```cmake set(SOURCES dtss_client.cpp dtss.cpp experimental.cpp dream_optimizer.cpp sceua_optimizer.cpp time_series_dd.cpp core_serialization.cpp time_series_serialization.cpp utctime_utilities.cpp expression_serialization.cpp ) ``` -------------------------------- ### Add River to Network and Connect Catchment Source: https://context7.com/felixmatt/shyft/llms.txt Demonstrates adding a river to the routing network and connecting a catchment cell to it. Ensure the model is created and run before adding routing. ```python from shyft import api from shyft.api import pt_gs_k model.river_network.add( api.River( 1, api.RoutingInfo(0, 3000.0), api.UHGParameter(1/3.6, 7.0, 0.0) ) ) catchment_id = 0 river_id = 1 model.connect_catchment_to_river(catchment_id, river_id) print(f"Model has routing: {model.has_routing()}") model.run_cells() river_out = model.river_output_flow_m3s(river_id) river_local = model.river_local_inflow_m3s(river_id) river_upstream = model.river_upstream_inflow_m3s(river_id) print(f"River output at t=8h: {river_out.value(8):.2f} m³/s") model.connect_catchment_to_river(catchment_id, 0) print(f"Model has routing: {model.has_routing()}") ``` -------------------------------- ### Manage and Serialize Model States Source: https://context7.com/felixmatt/shyft/llms.txt Extracts, serializes, and restores model states for warm-starting or persistence. Includes methods for adjusting states to match observed flow. ```python from shyft import api from shyft.api import pt_gs_k # Assume model is created and run # ... model creation and simulation ... # Extract state with cell IDs cids_all = api.IntVector() # Empty = all catchments cids_1 = api.IntVector([1]) # Specific catchment # Get states with IDs for traceability states_all = model.state.extract_state(cids_all) states_cid1 = model.state.extract_state(cids_1) print(f"Total states: {len(states_all)}") print(f"Catchment 1 states: {len(states_cid1)}") # Access individual state values for i, state_with_id in enumerate(states_cid1): print(f"Cell {state_with_id.id.cid}: q={state_with_id.state.kirchner.q:.2f}") # Serialize state to string (for YAML storage) state_str = states_all.serialize_to_str() restored_states = pt_gs_k.PTGSKStateWithIdVector.deserialize_from_str(state_str) # Serialize state to bytes (for binary storage) state_bytes = states_all.serialize_to_bytes() api.byte_vector_to_file("state.bin", state_bytes) loaded_bytes = api.byte_vector_from_file("state.bin") restored_states_bin = pt_gs_k.deserialize_from_bytes(loaded_bytes) # Apply state to model unapplied = model.state.apply_state(states_all, cids_all) if len(unapplied) > 0: print(f"Warning: {len(unapplied)} states could not be applied") # Set as initial state for next simulation model.initial_state = model.current_state # Revert to initial state model.revert_to_initial_state() # Adjust state to match observed discharge cids = api.IntVector([0]) target_q = 50.0 # Target discharge m³/s adjust_result = model.adjust_state_to_target_flow( target_q, cids, start_step=10, scale_range=3.0, scale_eps=1e-3, max_iter=350 ) print(f"Adjusted to q={adjust_result.q_r:.2f} from q_0={adjust_result.q_0:.2f}") ``` -------------------------------- ### Link Dependencies to Static Library Source: https://github.com/felixmatt/shyft/blob/master/core/CMakeLists.txt Links the necessary libraries to the 'shyftcore' static library. Ensure the ${LIBS} variable is correctly defined elsewhere in the CMake configuration. ```cmake target_link_libraries(shyftcore ${LIBS}) ``` -------------------------------- ### Geospatial Operations with GeoPoint and GeoCellData Source: https://context7.com/felixmatt/shyft/llms.txt Shows how to create and manipulate geographic points (GeoPoint) and define properties for model grid cells (GeoCellData), including calculating distances and setting land type fractions. ```python from shyft import api # Create geographic points (x, y, z in meters) gp1 = api.GeoPoint(500000, 6500000, 500) # UTM coordinates, 500m elevation gp2 = api.GeoPoint(501000, 6501000, 600) # Calculate distances xy_dist = api.GeoPoint.xy_distance(gp1, gp2) # Horizontal distance diff = api.GeoPoint.difference(gp1, gp2) # Vector difference print(f"Point: ({gp1.x}, {gp1.y}, {gp1.z})") # Create land type fractions (glacier, lake, reservoir, forest, unspecified) ltf = api.LandTypeFractions(0.01, 0.05, 0.10, 0.30, 0.54) ltf.set_fractions(glacier=0.02, lake=0.05, reservoir=0.10, forest=0.30) print(f"Glacier: {ltf.glacier()}, Forest: {ltf.forest()}") # Create geo cell data for model cells cell_area = 1000 * 1000 # 1 km² in m² catchment_id = 1 radiation_slope_factor = 0.9 geo_cell = api.GeoCellData(gp1, cell_area, catchment_id, radiation_slope_factor, ltf) print(f"Cell area: {geo_cell.area()}") print(f"Catchment ID: {geo_cell.catchment_id()}") print(f"Mid point: {geo_cell.mid_point()}") ``` -------------------------------- ### Define C++ API Library Sources Source: https://github.com/felixmatt/shyft/blob/master/api/CMakeLists.txt Specifies the source files for the C++ API library. Ensure these files exist in the source directory. ```cmake set(SOURCES api.cpp api_serialization.cpp ) ``` -------------------------------- ### Locate Python and NumPy paths via CMake Source: https://github.com/felixmatt/shyft/blob/master/shyft/api/CMakeLists.txt Uses execute_process to query the Python interpreter for library and include paths, as well as NumPy include directories. ```cmake find_package(PythonInterp REQUIRED) execute_process( COMMAND ${PYTHON_EXECUTABLE} "-c" "from distutils import sysconfig; print(sysconfig.get_python_lib())" RESULT_VARIABLE rv OUTPUT_VARIABLE lib_python_output ERROR_VARIABLE lib_python_error OUTPUT_STRIP_TRAILING_WHITESPACE ) if(rv) message("Python lib output:" ${lib_python_output}) message("Python lib error:" ${lib_python_error}) message(FATAL_ERROR "Errors occurred. Leaving now!") return() else() string(LENGTH ${lib_python_output} len) math(EXPR pathend "${len} - 14") # remove "/site-packages" at the end string(SUBSTRING ${lib_python_output} 0 ${pathend} lib_python) endif() message("lib_python: " ${lib_python}) execute_process( COMMAND ${PYTHON_EXECUTABLE} "-c" "from distutils import sysconfig; print(sysconfig.get_python_inc())" RESULT_VARIABLE rv OUTPUT_VARIABLE include_python ERROR_VARIABLE include_python_error OUTPUT_STRIP_TRAILING_WHITESPACE ) if (rv) message("Python include:" ${include_python}) message("Python import error:" ${include_python_error}) message(FATAL_ERROR "Errors occurred. Leaving now!") return() endif() message("include_python: " ${include_python}) execute_process( COMMAND ${PYTHON_EXECUTABLE} "-c" "import numpy as np; print(np.get_include())" RESULT_VARIABLE rv OUTPUT_VARIABLE include_numpy ERROR_VARIABLE include_numpy_error OUTPUT_STRIP_TRAILING_WHITESPACE ) if (rv) message("NumPy include:" ${include_numpy}) message("NumPy import error:" ${include_numpy_error}) message(FATAL_ERROR "Errors occurred. Leaving now!") return() endif() message("include_numpy: " ${include_numpy}) ```