diff --git a/.Rbuildignore b/.Rbuildignore index 722cfa5..d4b755f 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -7,3 +7,4 @@ ^\.Rproj\.user$ ^docker-compose.yml$ ^dashboard_output_dir +^pacta-data/ diff --git a/.dockerignore b/.dockerignore index 23afe46..7500a75 100644 --- a/.dockerignore +++ b/.dockerignore @@ -11,3 +11,5 @@ benchmarks_dir/**/* dashboard_data_dir dashboard_data_dir/**/* docker-compose.yml +pacta-data/**/* +^tests/**/* diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index ae813e7..6244c95 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -21,10 +21,27 @@ jobs: with: do-check-r-sysdeps: false + test: + name: Test + uses: ./.github/workflows/test.yml + needs: [docker] + secrets: inherit + strategy: + fail-fast: false + matrix: + config-name: + - default_2022Q4 + - default_2023Q4 + - full_params_2022Q4 + - full_params_2023Q4 + with: + full-image-name: ${{ needs.docker.outputs.full-image-name }} + config-name: ${{ matrix.config-name }} + gh-pages: name: gh-pages uses: ./.github/workflows/gh-pages.yml - needs: [docker] + needs: [docker, test] secrets: inherit with: full-image-name: ${{ needs.docker.outputs.full-image-name }} diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 650339d..c0d62e4 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -1,3 +1,4 @@ +--- name: Deploy to GitHub Pages on: @@ -21,68 +22,35 @@ jobs: - name: Checkout uses: actions/checkout@v4 - # https://github.com/Azure/login?tab=readme-ov-file#login-with-openid-connect-oidc-recommended - - name: Azure Login - uses: azure/login@v2 + - uses: actions/download-artifact@v4 with: - client-id: ${{ secrets.AZURE_CLIENT_ID }} - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + pattern: dashboard-build-* + merge-multiple: false + path: extracted_builds - - name: Download Analysis Outputs - id: download-analysis-outputs - uses: RMI-PACTA/actions/actions/azure/blob-copy@main - with: - source: https://pactadatadev.blob.core.windows.net/ghactions-workflow-pacta-results/main/latest/full_params_2023Q4/analysis_output_dir - destination: tmp_analysis_output_dir - - - name: Download Benchmarks - id: download-benchmarks - uses: RMI-PACTA/actions/actions/azure/blob-copy@main - with: - source: https://pactadatadev.blob.core.windows.net/benchmarks-webapp/2023Q4/2023Q4_20240529T002355Z - destination: tmp_benchmarks_dir - - - name: move output and analysis files to correct directory - run: | - mv tmp_analysis_output_dir/main/latest/full_params_2023Q4/analysis_output_dir analysis_output_dir - ls analysis_output_dir - mv tmp_benchmarks_dir/2023Q4/2023Q4_20240529T002355Z benchmarks_dir - ls benchmarks_dir - - - name: Create Output Directories - run: | - mkdir -p dashboard_output_dir/data - - - name: Run Docker Image - env: - FULL_IMAGE_NAME: ${{ inputs.full-image-name }} - WORKSPACE: ${{ github.workspace }} - PARAMETERS: "" - ANALYSIS_OUTPUT_DIR: "analysis_output_dir" - BENCHMARKS_DIR: "benchmarks_dir" - DASHBOARD_DATA_DIR: "dashboard_output_dir/data" - DASHBOARD_OUTPUT_DIR: "dashboard_output_dir" + - name: Generate PR landing page + working-directory: extracted_builds + shell: bash run: | - docker run \ - --network none \ - --user $(id -u):$(id -g) \ - --env LOG_LEVEL=TRACE \ - --env ANALYSIS_OUTPUT_DIR="/mnt/analysis_output_dir" \ - --env BENCHMARKS_DIR="/mnt/benchmarks_dir" \ - --env DASHBOARD_DATA_DIR="/mnt/dashboard_output_dir/data" \ - --env DASHBOARD_OUTPUT_DIR="/mnt/dashboard_output_dir" \ - --mount type=bind,readonly,source=${WORKSPACE}/${BENCHMARKS_DIR},target=/mnt/benchmarks_dir \ - --mount type=bind,source=${WORKSPACE}/${ANALYSIS_OUTPUT_DIR},target=/mnt/analysis_output_dir \ - --mount type=bind,source=${WORKSPACE}/${DASHBOARD_OUTPUT_DIR},target=/mnt/dashboard_output_dir \ - --mount type=bind,source=${WORKSPACE}/${DASHBOARD_DATA_DIR},target=/mnt/dashboard_output_dir/data \ - $FULL_IMAGE_NAME \ - "$PARAMETERS" + echo "" > index.html + for target_page in $(find */index.html) + do + echo "$target_page" + link_text="$( \ + echo "$target_page" | \ + sed 's/^dashboard-build-//' | \ + sed 's/\/index\.html//' \ + )" + echo "$link_text" + echo "$link_text
" >> index.html + done + echo "" >> index.html + cat index.html - - name: chmod & List outputs + - name: Show files run: | - ls -lR dashboard_output_dir + ls -laR extracted_builds - name: Add nojekyll file if: github.event.action != 'closed' @@ -103,7 +71,7 @@ jobs: if: ${{ github.event_name == 'pull_request' }} uses: rossjrw/pr-preview-action@v1 with: - source-dir: dashboard_output_dir + source-dir: extracted_builds preview-branch: gh-pages umbrella-dir: pr-preview action: auto diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..03902d6 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,153 @@ +--- +name: Test docker image + +on: + workflow_call: + inputs: + full-image-name: + required: true + type: string + config-name: + required: true + type: string + +jobs: + test: + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + steps: + + - name: Checkout workflow + uses: actions/checkout@v4 + + - name: Prepare environment + id: prepare + env: + CONFIG_NAME: ${{ inputs.config-name }} + GITHUB_REF_NAME: ${{ github.ref_name}} + GITHUB_RUN_ATTEMPT: ${{ github.run_attempt }} + GITHUB_RUN_NUMBER: ${{ github.run_number }} + WORKSPACE: ${{ github.workspace }} + run: | + config_file="tests/config/$CONFIG_NAME.json" + echo "config_file: $config_file" + + HOLDINGS_DATE="$(jq -rc '.holdingsDate' $config_file)" + echo "holdings-date=$HOLDINGS_DATE" + echo "holdings-date=$HOLDINGS_DATE" >> "$GITHUB_OUTPUT" + + PACTA_DATA_URL="$(jq -rc '.pactaDataURL' $config_file)" + echo "pacta-data-url=$PACTA_DATA_URL" + echo "pacta-data-url=$PACTA_DATA_URL" >> "$GITHUB_OUTPUT" + + BENCHMARKS_URL="$(jq -rc '.benchmarksURL' $config_file)" + echo "benchmarks-url=$BENCHMARKS_URL" + echo "benchmarks-url=$BENCHMARKS_URL" >> "$GITHUB_OUTPUT" + + # includes handling for null/missing keys + PARAMETERS="$(jq -rc '.parameters | select( . != null )' $config_file)" + echo "parameters=$PARAMETERS" + echo "parameters=$PARAMETERS" >> "$GITHUB_OUTPUT" + + TEST_DIR="$WORKSPACE/$GITHUB_REF_NAME/$GITHUB_RUN_NUMBER/$GITHUB_RUN_ATTEMPT/$CONFIG_NAME" + mkdir -p $TEST_DIR + echo "test-dir=$TEST_DIR" + echo "test-dir=$TEST_DIR" >> "$GITHUB_OUTPUT" + + DASHBOARD_OUTPUT_DIR="$TEST_DIR/dashboard_output_dir" + mkdir -p "$DASHBOARD_OUTPUT_DIR" + chmod -R 777 "$DASHBOARD_OUTPUT_DIR" + echo "dashboard-output-dir=$DASHBOARD_OUTPUT_DIR" + echo "dashboard-output-dir=$DASHBOARD_OUTPUT_DIR" >> "$GITHUB_OUTPUT" + + DASHBOARD_DATA_DIR="$DASHBOARD_OUTPUT_DIR/data" + mkdir -p "$DASHBOARD_DATA_DIR" + chmod -R 777 "$DASHBOARD_DATA_DIR" + echo "dashboard-data-dir=$DASHBOARD_DATA_DIR" + echo "dashboard-data-dir=$DASHBOARD_DATA_DIR" >> "$GITHUB_OUTPUT" + + ANALYSIS_OUTPUT_DIR="$TEST_DIR/analysis_output_dir" + mkdir -p "$ANALYSIS_OUTPUT_DIR" + chmod -R 777 "$ANALYSIS_OUTPUT_DIR" + echo "analysis-output-dir=$ANALYSIS_OUTPUT_DIR" + echo "analysis-output-dir=$ANALYSIS_OUTPUT_DIR" >> "$GITHUB_OUTPUT" + + # https://github.com/Azure/login?tab=readme-ov-file#login-with-openid-connect-oidc-recommended + - name: Azure Login + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + - name: Download pacta-data + id: download-pacta-data + uses: RMI-PACTA/actions/actions/azure/blob-copy@main + with: + source: ${{ steps.prepare.outputs.pacta-data-url }} + destination: tmp_pacta_data_dir + + - name: Download Benchmarks + id: download-benchmarks + uses: RMI-PACTA/actions/actions/azure/blob-copy@main + with: + source: ${{ steps.prepare.outputs.benchmarks-url }} + destination: tmp_benchmarks_dir + + - name: Show TEST_DIR + id: ls-test-dir + env: + TEST_DIR: ${{ steps.prepare.outputs.test-dir }} + run: | + mkdir -p pacta-data + mv tmp_pacta_data_dir/*/*/* pacta-data + mkdir -p benchmarks_dir + mv tmp_benchmarks_dir/*/*/* benchmarks_dir + ls -laR "$TEST_DIR" + + - name: Run Docker Image + env: + FULL_IMAGE_NAME: ${{ inputs.full-image-name }} + WORKSPACE: ${{ github.workspace }} + PARAMETERS: ${{ steps.prepare.outputs.parameters }} + ANALYSIS_OUTPUT_DIR: ${{ steps.prepare.outputs.analysis-output-dir }} + BENCHMARKS_DIR: benchmarks_dir + PACTA_DATA_DIR: pacta-data + PORTFOLIO_DIR: tests/portfolios + DASHBOARD_DATA_DIR: ${{ steps.prepare.outputs.dashboard-data-dir }} + DASHBOARD_OUTPUT_DIR: ${{ steps.prepare.outputs.dashboard-output-dir }} + run: | + + docker run \ + --network none \ + --env LOG_LEVEL=TRACE \ + --env ANALYSIS_OUTPUT_DIR="/mnt/analysis_output_dir" \ + --env OUTPUT_DIR="/mnt/analysis_output_dir" \ + --env BENCHMARKS_DIR="/mnt/benchmarks_dir" \ + --env PACTA_DATA_DIR="/mnt/pacta-data" \ + --env PORTFOLIO_DIR="/mnt/portfolios" \ + --env DASHBOARD_OUTPUT_DIR="/mnt/dashboard_output_dir" \ + --env DASHBOARD_DATA_DIR="/mnt/dashboard_output_dir/data" \ + --mount type=bind,readonly,source=${WORKSPACE}/${BENCHMARKS_DIR},target=/mnt/benchmarks_dir \ + --mount type=bind,readonly,source=${WORKSPACE}/${PACTA_DATA_DIR},target=/mnt/pacta-data \ + --mount type=bind,readonly,source=${WORKSPACE}/${PORTFOLIO_DIR},target=/mnt/portfolios \ + --mount type=bind,source=${ANALYSIS_OUTPUT_DIR},target=/mnt/analysis_output_dir \ + --mount type=bind,source=${DASHBOARD_OUTPUT_DIR},target=/mnt/dashboard_output_dir \ + --mount type=bind,source=${DASHBOARD_DATA_DIR},target=/mnt/dashboard_output_dir/data \ + $FULL_IMAGE_NAME \ + "$PARAMETERS" + + - name: List outputs + env: + DASHBOARD_OUTPUT_DIR: ${{ steps.prepare.outputs.dashboard-output-dir }} + run: | + ls -lR $DASHBOARD_OUTPUT_DIR + + - name: Upload built dashboard as artifact + uses: actions/upload-artifact@v4 + with: + name: dashboard-build-${{ inputs.config-name }} + path: ${{ steps.prepare.outputs.dashboard-output-dir }} + if-no-files-found: error diff --git a/.gitignore b/.gitignore index 84720e4..a3aee08 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ analysis_output_dir/**/* benchmarks_dir/**/* dashboard_output_dir/**/* !dashboard_output_dir/data/.gitkeep +pacta-data/**/* diff --git a/DESCRIPTION b/DESCRIPTION index adb6b89..ac4a0f4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: workflow.pacta.dashboard Title: Run PACTA dashboard JSON generation -Version: 0.0.0.9006 +Version: 0.0.0.9008 Authors@R: c(person(given = "Alex", family = "Axthelm", @@ -29,11 +29,16 @@ Imports: dplyr, glue, jsonlite, + logger, magrittr, pacta.portfolio.utils, + pacta.workflow.utils, readr, rlang, stringr, - tidyr + tidyr, + workflow.pacta Remotes: - RMI-PACTA/pacta.portfolio.utils + RMI-PACTA/pacta.portfolio.utils, + RMI-PACTA/pacta.workflow.utils, + RMI-PACTA/workflow.pacta diff --git a/NAMESPACE b/NAMESPACE index 7334320..486fe37 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,5 +1,7 @@ # Generated by roxygen2: do not edit by hand +export(prepare_schema_files) +export(run_dashboard_workflow) importFrom(dplyr,across) importFrom(dplyr,all_of) importFrom(dplyr,arrange) @@ -30,6 +32,11 @@ importFrom(dplyr,summarise) importFrom(dplyr,tibble) importFrom(dplyr,transmute) importFrom(dplyr,ungroup) +importFrom(logger,log_debug) +importFrom(logger,log_error) +importFrom(logger,log_info) +importFrom(logger,log_trace) +importFrom(logger,log_warn) importFrom(magrittr,"%>%") importFrom(rlang,":=") importFrom(rlang,.data) diff --git a/R/build_dashboard.R b/R/build_dashboard.R index 9121a83..b9cf777 100644 --- a/R/build_dashboard.R +++ b/R/build_dashboard.R @@ -8,11 +8,13 @@ build_dashboard <- function( ) { prepare_pacta_dashboard_data( + params = params, analysis_output_dir = analysis_output_dir, dashboard_data_dir = dashboard_data_dir, benchmarks_dir = benchmarks_dir ) + log_info("Copying dashboard files.") dashboard_copy_success <- copy_dashboard_files( dashboard_skeleton_files_dir = dashboard_skeleton_files_dir, dashboard_output_dir = dashboard_output_dir @@ -20,6 +22,7 @@ build_dashboard <- function( dashboard_output_data_dir <- file.path(dashboard_output_dir, "data") if (dashboard_data_dir != dashboard_output_data_dir) { + log_info("Copying dashboard data to correct location.") if (!dir.exists(dashboard_output_data_dir)) { dir.create(dashboard_output_data_dir, recursive = TRUE) } @@ -30,4 +33,39 @@ build_dashboard <- function( ) } + out <- list( + input_files = c( + list.files( + dashboard_data_dir, + full.names = TRUE, + recursive = TRUE + ), + list.files( + dashboard_skeleton_files_dir, + full.names = TRUE, + recursive = TRUE + ), + list.files( + analysis_output_dir, + full.names = TRUE, + recursive = TRUE + ), + list.files( + benchmarks_dir, + full.names = TRUE, + recursive = TRUE + ) + ), + output_files = c( + list.files( + dashboard_output_dir, + full.names = TRUE, + recursive = TRUE + ) + ), + params = params + ) + + return(out) + } diff --git a/R/prepare_pacta_dashboard_data.R b/R/prepare_pacta_dashboard_data.R index bfb82f9..ee408d8 100644 --- a/R/prepare_pacta_dashboard_data.R +++ b/R/prepare_pacta_dashboard_data.R @@ -5,29 +5,25 @@ prepare_pacta_dashboard_data <- function( benchmarks_dir = Sys.getenv("BENCHMARKS_DIR") ) { -# input and output directories ------------------------------------------------- - -input_dir <- analysis_output_dir -output_dir <- dashboard_data_dir -data_dir <- benchmarks_dir - +log_info("Preparing data for the PACTA dashboard.") # portfolio/user parameters ---------------------------------------------------- +log_debug("Reading portfolio/user parameters.") -investor_name <- "investor_name" -portfolio_name <- "portfolio_name" -peer_group <- "peer_group" -language_select <- "EN" +investor_name <- params[["user"]][["name"]] +portfolio_name <- params[["portfolio"]][["name"]] +peer_group <- params[["user"]][["peerGroup"]] +language_select <- params[["user"]][["languageSelect"]] -currency_exchange_value <- 1 -display_currency <- "USD" +currency_exchange_value <- params[["user"]][["currencyExchangeValue"]] +display_currency <- params[["user"]][["displayCurrency"]] -select_scenario_other <- "WEO2023_NZE_2050" -select_scenario <- "WEO2023_NZE_2050" +select_scenario_other <- params[["reporting"]][["scenarioOther"]] +select_scenario <- params[["reporting"]][["selectScenario"]] -green_techs <- c("RenewablesCap", "HydroCap", "NuclearCap", "Hybrid", "Electric", "FuelCell", "Hybrid_HDV", "Electric_HDV", "FuelCell_HDV","Electric Arc Furnace") -tech_roadmap_sectors <- c("Automotive", "Power", "Oil&Gas", "Coal") -pacta_sectors_not_analysed <- c("Steel", "Aviation", "Cement") +green_techs <- params[["reporting"]][["greenTechs"]] +tech_roadmap_sectors <- params[["reporting"]][["techRoadmapSectors"]] +pacta_sectors_not_analysed <- params[["reporting"]][["pactaSectorsNotAnalysed"]] power_tech_levels = c("RenewablesCap", "HydroCap", "NuclearCap", "GasCap", "OilCap", "CoalCap") oil_gas_levels = c("Oil", "Gas") @@ -40,8 +36,9 @@ all_tech_levels = c(power_tech_levels, auto_levels, oil_gas_levels, coal_levels, # config parameters from manifest ---------------------------------------------- +log_debug("Reading config parameters from analysis outputs manifest.") -manifest <- jsonlite::read_json(path = file.path(input_dir, "manifest.json")) +manifest <- jsonlite::read_json(path = file.path(analysis_output_dir, "manifest.json")) start_year <- manifest$params$analysis$startYear year_span <- manifest$params$analysis$timeHorizon @@ -51,24 +48,29 @@ scen_geo_levels <- unlist(manifest$params$analysis$scenarioGeographiesList) # load results from input directory -------------------------------------------- +log_debug("Loading results from input directory.") -audit_file <- readRDS(file.path(input_dir, "audit_file.rds")) -emissions <- readRDS(file.path(input_dir, "emissions.rds")) -equity_results_portfolio <- readRDS(file.path(input_dir, "Equity_results_portfolio.rds")) -bonds_results_portfolio <- readRDS(file.path(input_dir, "Bonds_results_portfolio.rds")) -equity_results_company <- readRDS(file.path(input_dir, "Equity_results_company.rds")) -bonds_results_company <- readRDS(file.path(input_dir, "Bonds_results_company.rds")) +audit_file <- readRDS(file.path(analysis_output_dir, "audit_file.rds")) +emissions <- readRDS(file.path(analysis_output_dir, "emissions.rds")) +equity_results_portfolio <- readRDS(file.path(analysis_output_dir, "Equity_results_portfolio.rds")) +bonds_results_portfolio <- readRDS(file.path(analysis_output_dir, "Bonds_results_portfolio.rds")) +equity_results_company <- readRDS(file.path(analysis_output_dir, "Equity_results_company.rds")) +bonds_results_company <- readRDS(file.path(analysis_output_dir, "Bonds_results_company.rds")) # data from PACTA inputs used to generate the results -------------------------- +log_debug("Loading benchmark results.") + +indices_bonds_results_portfolio <- readRDS(file.path(benchmarks_dir, "Indices_bonds_results_portfolio.rds")) +indices_equity_results_portfolio <- readRDS(file.path(benchmarks_dir, "Indices_equity_results_portfolio.rds")) -indices_bonds_results_portfolio <- readRDS(file.path(data_dir, "Indices_bonds_results_portfolio.rds")) -indices_equity_results_portfolio <- readRDS(file.path(data_dir, "Indices_equity_results_portfolio.rds")) +log_debug("Loading peer results.") peers_bonds_results_portfolio <- pacta.portfolio.utils::empty_portfolio_results() peers_equity_results_portfolio <- pacta.portfolio.utils::empty_portfolio_results() # translations ----------------------------------------------------------------- +log_debug("Loading translations.") dataframe_translations <- readr::read_csv( system.file("extdata/translation/dataframe_labels.csv", package = "workflow.pacta.dashboard"), @@ -100,6 +102,7 @@ header_dictionary <- replace_contents(header_dictionary, display_currency) # add investor_name and portfolio_name to results data frames because ---------- # pacta.portfolio.report functions expect that --------------------------------- +log_debug("Adding investor_name and portfolio_name to results data frames.") audit_file <- audit_file %>% @@ -146,6 +149,7 @@ bonds_results_company <- # data_included_table.json ----------------------------------------------------- +log_info("Preparing data_included_table.json.") audit_file %>% prep_audit_table( investor_name = investor_name, @@ -154,11 +158,12 @@ audit_file %>% ) %>% translate_df_contents("data_included_table", dictionary, inplace = TRUE) %>% translate_df_headers("data_included_table", language_select, header_dictionary) %>% - jsonlite::write_json(path = file.path(output_dir, "data_included_table.json")) + jsonlite::write_json(path = file.path(dashboard_data_dir, "data_included_table.json")) # data_value_pie_bonds.json ---------------------------------------------------- +log_info("Preparing data_value_pie_bonds.json.") audit_file %>% prep_exposure_pie( asset_type = "Bonds", @@ -168,11 +173,12 @@ audit_file %>% currency_exchange_value = currency_exchange_value ) %>% translate_df_contents("data_value_pie_bonds", dictionary) %>% - jsonlite::write_json(path = file.path(output_dir, "data_value_pie_bonds.json")) + jsonlite::write_json(path = file.path(dashboard_data_dir, "data_value_pie_bonds.json")) # data_emissions_equity.json --------------------------------------------------- +log_info("Preparing data_emissions_equity.json.") emissions %>% prep_emissions_pie( asset_type = "Equity", @@ -181,11 +187,12 @@ emissions %>% pacta_sectors = pacta_sectors ) %>% translate_df_contents("data_emissions_pie_equity", dictionary) %>% - jsonlite::write_json(path = file.path(output_dir, "data_emissions_pie_equity.json")) + jsonlite::write_json(path = file.path(dashboard_data_dir, "data_emissions_pie_equity.json")) # data_emissions_bonds.json ---------------------------------------------------- +log_info("Preparing data_emissions_bonds.json.") emissions %>% prep_emissions_pie( asset_type = "Bonds", @@ -194,11 +201,12 @@ emissions %>% pacta_sectors = pacta_sectors ) %>% translate_df_contents("data_emissions_pie_bonds", dictionary) %>% - jsonlite::write_json(path = file.path(output_dir, "data_emissions_pie_bonds.json")) + jsonlite::write_json(path = file.path(dashboard_data_dir, "data_emissions_pie_bonds.json")) # data_value_pie_equity.json --------------------------------------------------- +log_info("Preparing data_value_pie_equity.json.") audit_file %>% prep_exposure_pie( asset_type = "Equity", @@ -208,11 +216,12 @@ audit_file %>% currency_exchange_value = currency_exchange_value ) %>% translate_df_contents("data_value_pie_equity", dictionary) %>% - jsonlite::write_json(path = file.path(output_dir, "data_value_pie_equity.json")) + jsonlite::write_json(path = file.path(dashboard_data_dir, "data_value_pie_equity.json")) # data_techmix.json ------------------------------------------------------------ +log_info("Preparing data_techmix.json.") prep_techexposure( equity_results_portfolio = equity_results_portfolio, bonds_results_portfolio = bonds_results_portfolio, @@ -231,11 +240,12 @@ prep_techexposure( all_tech_levels = all_tech_levels ) %>% translate_df_contents("techexposure_data", dictionary) %>% - jsonlite::write_json(path = file.path(output_dir, "data_techexposure.json")) + jsonlite::write_json(path = file.path(dashboard_data_dir, "data_techexposure.json")) # data_techmix_sector.json ----------------------------------------------------- +log_info("Preparing data_techmix_sector.json.") prep_techmix_sector( equity_results_portfolio, bonds_results_portfolio, @@ -251,10 +261,11 @@ prep_techmix_sector( green_techs, all_tech_levels ) %>% - jsonlite::write_json(path = file.path(output_dir, "data_techmix_sector.json")) + jsonlite::write_json(path = file.path(dashboard_data_dir, "data_techmix_sector.json")) # data_trajectory_alignment.json ----------------------------------------------- +log_info("Preparing data_trajectory_alignment.json.") prep_trajectory_alignment( equity_results_portfolio = equity_results_portfolio, bonds_results_portfolio = bonds_results_portfolio, @@ -272,11 +283,12 @@ prep_trajectory_alignment( all_tech_levels = all_tech_levels ) %>% translate_df_contents("data_trajectory_alignment", dictionary) %>% - jsonlite::write_json(path = file.path(output_dir, "data_trajectory_alignment.json")) + jsonlite::write_json(path = file.path(dashboard_data_dir, "data_trajectory_alignment.json")) # data_emissions.json ---------------------------------------------------------- +log_info("Preparing data_emissions.json.") prep_emissions_trajectory( equity_results_portfolio = equity_results_portfolio, bonds_results_portfolio = bonds_results_portfolio, @@ -286,10 +298,11 @@ prep_emissions_trajectory( start_year = start_year ) %>% translate_df_contents("data_emissions", dictionary) %>% - jsonlite::write_json(path = file.path(output_dir, "data_emissions.json")) + jsonlite::write_json(path = file.path(dashboard_data_dir, "data_emissions.json")) # data_exposure_stats.json +log_info("Preparing data_exposure_stats.json.") prep_exposure_stats( audit_file = audit_file, investor_name = investor_name, @@ -297,11 +310,12 @@ prep_exposure_stats( pacta_sectors = pacta_sectors, currency_exchange_value = currency_exchange_value ) %>% - jsonlite::write_json(path = file.path(output_dir, "data_exposure_stats.json")) + jsonlite::write_json(path = file.path(dashboard_data_dir, "data_exposure_stats.json")) # data_company_bubble.json ----------------------------------------------------- +log_info("Preparing data_company_bubble.json.") prep_company_bubble( equity_results_company = equity_results_company, bonds_results_company = bonds_results_company, @@ -310,11 +324,12 @@ prep_company_bubble( green_techs = green_techs ) %>% translate_df_contents("data_company_bubble", dictionary) %>% - jsonlite::write_json(path = file.path(output_dir, "data_company_bubble.json")) + jsonlite::write_json(path = file.path(dashboard_data_dir, "data_company_bubble.json")) # data_techexposure_company_companies.json ------------------------------------- +log_info("Preparing data_techexposure_company_companies.json.") prep_key_bars_company( equity_results_company = equity_results_company, bonds_results_company = bonds_results_company, @@ -324,11 +339,12 @@ prep_key_bars_company( all_tech_levels = all_tech_levels ) %>% translate_df_contents("data_key_bars_company", dictionary) %>% - jsonlite::write_json(path = file.path(output_dir, "data_techexposure_company_companies.json")) + jsonlite::write_json(path = file.path(dashboard_data_dir, "data_techexposure_company_companies.json")) # data_techexposure_company_portfolio.json ------------------------------------- +log_info("Preparing data_techexposure_company_portfolio.json.") prep_key_bars_portfolio( equity_results_portfolio = equity_results_portfolio, bonds_results_portfolio = bonds_results_portfolio, @@ -338,36 +354,39 @@ prep_key_bars_portfolio( all_tech_levels = all_tech_levels ) %>% translate_df_contents("data_key_bars_portfolio", dictionary) %>% - jsonlite::write_json(path = file.path(output_dir, "data_techexposure_company_portfolio.json")) + jsonlite::write_json(path = file.path(dashboard_data_dir, "data_techexposure_company_portfolio.json")) # put JSON and CSV outputs into a zip archive ---------------------------------- -zip_outputs(output_dir) +zip_outputs(dashboard_data_dir) } -zip_outputs <- function(output_dir) { - json_filenames <- list.files(output_dir, pattern = "[.]json$") +zip_outputs <- function(dashboard_data_dir) { + log_debug("Preparing outputs zip archive.") + json_filenames <- list.files(dashboard_data_dir, pattern = "[.]json$") zip_temp <- file.path(tempdir(), "zip_temp") dir.create(zip_temp, showWarnings = FALSE) for (json_filename in json_filenames) { + log_trace(paste("Adding", json_filename, "to zip archive.")) file.copy( - from = file.path(output_dir, json_filename), + from = file.path(dashboard_data_dir, json_filename), to = file.path(zip_temp, json_filename) ) csv_filename <- sub("[.]json$", ".csv", json_filename) df <- jsonlite::read_json( - path = file.path(output_dir, json_filename), + path = file.path(dashboard_data_dir, json_filename), simplifyVector = TRUE ) if (inherits(df, "data.frame")) { + log_trace(paste("Adding", csv_filename, "to zip archive.")) readr::write_csv( x = df, file = file.path(zip_temp, csv_filename), @@ -377,8 +396,9 @@ zip_outputs <- function(output_dir) { } } + log_debug("Creating zip archive.") utils::zip( - zipfile = file.path(output_dir, "archive.zip"), + zipfile = file.path(dashboard_data_dir, "archive.zip"), files = list.files(zip_temp, full.names = TRUE), flags = "-r9Xjq" ) diff --git a/R/prepare_schema_files.R b/R/prepare_schema_files.R new file mode 100644 index 0000000..40d9749 --- /dev/null +++ b/R/prepare_schema_files.R @@ -0,0 +1,54 @@ +#' Copy parameter files to directory +#' +#' Copy schema files from dependency packages to a (temporary) directory. This +#' is required, as `jsonvalidate` requires referenced schema files to exist in +#' the same directory as the referencing schema. +#' +#' @param directory Directory to copy parameter files to. +#' @return directory +#' +#' @export +prepare_schema_files <- function(directory) { + log_debug("Preparing schema files.") + log_debug("Schema tempdir: ", directory) + dashboard_schema_files <- list.files( + system.file( + "extdata", "schema", + package = "workflow.pacta.dashboard" + ), + full.names = TRUE + ) + dashboard_schema_copied <- file.copy( + from = dashboard_schema_files, + to = file.path( + directory, + basename(dashboard_schema_files) + ) + ) + + portfolio_schema_copied <- file.copy( + from = system.file( + "extdata", "schema", "portfolio.json", + package = "workflow.pacta" + ), + to = file.path( + directory, + "portfolio.json" + ) + ) + portfolio_schema_copied <- file.copy( + from = system.file( + "extdata", "schema", "portfolioParameters.json", + package = "workflow.pacta" + ), + to = file.path( + directory, + "portfolioParameters.json" + ) + ) + stopifnot( + dashboard_schema_copied, + portfolio_schema_copied + ) + return(directory) +} diff --git a/R/run_dashboard_workflow.R b/R/run_dashboard_workflow.R new file mode 100644 index 0000000..0a71c2f --- /dev/null +++ b/R/run_dashboard_workflow.R @@ -0,0 +1,84 @@ +#' Run Dashboard workflow +#' +#' Run steps required to prepare a PACTA analysis and dashboard +#' +#' @param params (`list`) A list of parameters to be used in the analysis and +#' dashboard process. See JSON Schema for details. +#' @param raw_params (`character`) Raw JSON string of parameters. +#' @param run_analysis (`logical`) Run the analysis process. +#' @param run_dashboard (`logical`) Run the dashboard creation process. +#' @param analysis_output_dir Directory containing the PACTA analysis results. +#' @param benchmarks_dir filepath: Directory containing the benchmark analysis +#' results. +#' @param pacta_data_dir filepath: Directory with "pacta-data" +#' @param portfolio_dir filepath: Directory with portfolio files +#' @param dashboard_output_dir Directory where the dashboard will be +#' saved. +#' @return (invisible) `TRUE` if the workflow was successful. Primarily called +#' for side effect of rendering files. +#' @export +run_dashboard_workflow <- function( + params, + raw_params, + run_analysis = TRUE, + run_dashboard = TRUE, + analysis_output_dir = Sys.getenv("ANALYSIS_OUTPUT_DIR"), + benchmarks_dir = Sys.getenv("BENCHMARKS_DIR"), + pacta_data_dir = Sys.getenv("PACTA_DATA_DIR"), + portfolio_dir = Sys.getenv("PORTFOLIO_DIR"), + dashboard_output_dir = Sys.getenv("DASHBOARD_OUTPUT_DIR") +) { + + log_trace("preparing manifest paths.") + analysis_manifest_path <- file.path( + analysis_output_dir, + "manifest.json" + ) + log_trace("Analysis manifest path: ", analysis_manifest_path) + dashboard_manifest_path <- file.path( + dashboard_output_dir, + "manifest.json" + ) + log_trace("Dashboard manifest path: ", dashboard_manifest_path) + + if (run_analysis || !file.exists(analysis_manifest_path)) { + + log_trace("running analysis workflow.") + analysis_manifest_info <- workflow.pacta::run_pacta( + params = params, + pacta_data_dir = pacta_data_dir, + output_dir = analysis_output_dir, + portfolio_dir = portfolio_dir + ) + + log_trace("exporting analysis manifest.") + pacta.workflow.utils::export_manifest( + input_files = analysis_manifest_info[["input_files"]], + output_files = analysis_manifest_info[["output_files"]], + params = analysis_manifest_info[["params"]], + manifest_path = analysis_manifest_path, + raw_params = raw_params + ) + + } + + if (run_dashboard) { + + log_trace("running dashboard workflow.") + dashboard_manifest_info <- build_dashboard( + params = params + ) + + log_trace("exporting dashboard manifest.") + pacta.workflow.utils::export_manifest( + input_files = dashboard_manifest_info[["input_files"]], + output_files = dashboard_manifest_info[["output_files"]], + params = dashboard_manifest_info[["params"]], + manifest_path = dashboard_manifest_path, + raw_params = raw_params + ) + + } + return(invisible(TRUE)) +} + diff --git a/R/workflow.pacta.dashboard-package.R b/R/workflow.pacta.dashboard-package.R index ac090cb..4fd1011 100644 --- a/R/workflow.pacta.dashboard-package.R +++ b/R/workflow.pacta.dashboard-package.R @@ -32,6 +32,11 @@ #' @importFrom dplyr tibble #' @importFrom dplyr transmute #' @importFrom dplyr ungroup +#' @importFrom logger log_debug +#' @importFrom logger log_error +#' @importFrom logger log_info +#' @importFrom logger log_trace +#' @importFrom logger log_warn #' @importFrom magrittr %>% #' @importFrom rlang := #' @importFrom rlang .data diff --git a/dashboard_output_dir/data/.gitkeep b/dashboard_output_dir/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docker-compose.yml b/docker-compose.yml index 50a095e..8c9edbe 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,16 +4,25 @@ services: build: . # stdin_open: true # tty: true - # entrypoint: ["bash"] # entrypoint: ["R", "--args"] - # command: '{\"portfolio\": {\"files\": [\"default_portfolio.csv\"], \"holdingsDate\": \"2023-12-31\", \"name\": \"FooPortfolio\"}, \"inherit\": \"GENERAL_2023Q4\"}' + command: '{\"portfolio\": {\"files\": [\"default_portfolio.csv\"], \"holdingsDate\": \"2023-12-31\", \"name\": \"FooPortfolio\"}, \"inherit\": \"GENERAL_2023Q4\"}' environment: LOG_LEVEL: TRACE ANALYSIS_OUTPUT_DIR: "/mnt/analysis_output_dir" BENCHMARKS_DIR: "/mnt/benchmarks_dir" DASHBOARD_DATA_DIR: "/mnt/dashboard_output_dir/data" DASHBOARD_OUTPUT_DIR: "/mnt/dashboard_output_dir" + PACTA_DATA_DIR: "/mnt/pacta-data" + PORTFOLIO_DIR: "/mnt/portfolios" volumes: + - type: bind + source: ${data_dir:-./pacta-data/} + target: /mnt/pacta-data + read_only: true + - type: bind + source: ${input_dir:-./tests/portfolios/} + target: /mnt/portfolios + read_only: true - type: bind source: ${benchmarks_dir:-./benchmarks_dir} target: /mnt/benchmarks_dir/ @@ -21,7 +30,7 @@ services: - type: bind source: ${analysis_output_dir:-./analysis_output_dir} target: /mnt/analysis_output_dir - read_only: true + read_only: false - type: bind source: ${dashboard_data_dir:-./dashboard_output_dir/data} target: /mnt/dashboard_output_dir/data diff --git a/inst/extdata/parameters/GENERAL_2022Q4.json b/inst/extdata/parameters/GENERAL_2022Q4.json new file mode 100644 index 0000000..e187151 --- /dev/null +++ b/inst/extdata/parameters/GENERAL_2022Q4.json @@ -0,0 +1,6 @@ +{ + "inherit": [ + "analysis_GENERAL_2022Q4", + "report_GENERAL_2022Q4" + ] +} diff --git a/inst/extdata/parameters/GENERAL_2023Q4.json b/inst/extdata/parameters/GENERAL_2023Q4.json new file mode 100644 index 0000000..11ee25f --- /dev/null +++ b/inst/extdata/parameters/GENERAL_2023Q4.json @@ -0,0 +1,6 @@ +{ + "inherit": [ + "analysis_GENERAL_2023Q4", + "report_GENERAL_2023Q4" + ] +} diff --git a/inst/extdata/parameters/report_GENERAL.json b/inst/extdata/parameters/report_GENERAL.json new file mode 100644 index 0000000..7bf665c --- /dev/null +++ b/inst/extdata/parameters/report_GENERAL.json @@ -0,0 +1,7 @@ +{ + "reporting": { + "projectCode": "GENERAL", + "projectReportName": "general" + }, + "inherit": "report_default" +} diff --git a/inst/extdata/parameters/report_GENERAL_2022Q4.json b/inst/extdata/parameters/report_GENERAL_2022Q4.json new file mode 100644 index 0000000..d7ac08d --- /dev/null +++ b/inst/extdata/parameters/report_GENERAL_2022Q4.json @@ -0,0 +1,8 @@ +{ + "reporting": { + "scenarioOther": "GECO2022_1.5C", + "selectScenario": "WEO2022_NZE_2050" + }, + "inherit": "report_GENERAL" +} + diff --git a/inst/extdata/parameters/report_GENERAL_2023Q4.json b/inst/extdata/parameters/report_GENERAL_2023Q4.json new file mode 100644 index 0000000..943285e --- /dev/null +++ b/inst/extdata/parameters/report_GENERAL_2023Q4.json @@ -0,0 +1,8 @@ +{ + "reporting": { + "scenarioOther": "WEO2023_NZE_2050", + "selectScenario": "WEO2023_NZE_2050" + }, + "inherit": "report_GENERAL" +} + diff --git a/inst/extdata/parameters/report_default.json b/inst/extdata/parameters/report_default.json new file mode 100644 index 0000000..a7a6f57 --- /dev/null +++ b/inst/extdata/parameters/report_default.json @@ -0,0 +1,42 @@ +{ + "reporting": { + "scenarioGeography": "Global", + "sectorList": [ + "Power", + "Automotive", + "Oil&Gas", + "Coal", + "Steel", + "Aviation", + "Cement" + ], + "portfolioAllocationMethod": "portfolio_weight", + "techRoadmapSectors": [ + "Power", + "Automotive", + "Oil&Gas", + "Coal" + ], + "pactaSectorsNotAnalysed": [ + "Steel", + "Aviation", + "Cement" + ], + "greenTechs": [ + "RenewablesCap", + "HydroCap", + "NuclearCap", + "Hybrid", + "Electric", + "FuelCell", + "Electric Arc Furnace" + ] + }, + "user": { + "currencyExchangeValue": 1, + "displayCurrency": "USD", + "name": "Default Investor", + "languageSelect": "EN", + "peerGroup": "bank" + } +} diff --git a/inst/extdata/schema/rawParameters.json b/inst/extdata/schema/rawParameters.json new file mode 100644 index 0000000..1515ed1 --- /dev/null +++ b/inst/extdata/schema/rawParameters.json @@ -0,0 +1,31 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "https://raw.githubusercontent.com/RMI-PACTA/workflow.pacta/main/inst/extdata/schema/rawParameters.json", + "title": "rawPortfolioParameters", + "description": "Valid input parameters for the PACTA workflow. Less than full parameters, since PACTA handles inheritence.", + "$comment": "Created by Alex Axthelm, aaxthelm@rmi.org", + "type": "object", + "properties": { + "portfolio": { + "$ref": "portfolio.json" + }, + "inherit": { + "type": "string", + "description": "Path to a file with inheritance information." + } + }, + "anyOf": [ + { + "required": [ + "inherit" + ] + }, + { + "$ref": "reportingParameters.json" + } + ], + "required": [ + "portfolio" + ], + "additionalProperties": true +} diff --git a/inst/extdata/schema/reportingParameters.json b/inst/extdata/schema/reportingParameters.json new file mode 100644 index 0000000..28962b3 --- /dev/null +++ b/inst/extdata/schema/reportingParameters.json @@ -0,0 +1,180 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "https://raw.githubusercontent.com/RMI-PACTA/workflow.pacta/main/inst/extdata/schema/portfolioParameters.json", + "title": "portfolioParameters", + "description": "Full Parameters required to run workflow.pacta.", + "$comment": "Created by Alex Axthelm, aaxthelm@rmi.org", + "type": "object", + "properties": { + "portfolio": { + "$ref": "portfolio.json" + }, + "user": { + "type": "object", + "description": "User information.", + "properties": { + "name": { + "type": "string", + "description": "User name." + }, + "languageSelect": { + "type": "string", + "description": "Language selection.", + "enum": [ + "EN", + "ES", + "FR", + "DE" + ] + }, + "peerGroup": { + "type": "string", + "description": "Peer group selection.", + "enum": [ + "assetmanager", + "bank", + "insurance", + "other", + "pensionfund" + ] + }, + "currencyExchangeValue": { + "type": "number", + "description": "Currency exchange value for displayCurrency", + "exclusiveMinimum": 0, + "default": 1 + }, + "displayCurrency": { + "type": "string", + "description": "Currency for display. ISO 4217 currency code.", + "pattern": "^[A-Z]{3}$" + } + }, + "required": [ + "name", + "languageSelect", + "peerGroup", + "currencyExchangeValue", + "displayCurrency" + ], + "additionalProperties": true + } + }, + "reporting": { + "type": "object", + "description": "Parameters for reporting.", + "properties": { + "projectCode": { + "type": "string", + "description": "Project code.", + "enum": [ + "GENERAL" + ] + }, + "projectReportName": { + "type": "string", + "description": "Project code.", + "enum": [ + "general" + ] + }, + "greenTechs": { + "type": "array", + "description": "Green technologies to be included in the report.", + "items": { + "type": "string", + "enum": [ + "RenewablesCap", + "HydroCap", + "NuclearCap", + "Hybrid", + "Electric", + "FuelCell", + "Electric Arc Furnace" + ] + } + }, + "pactaSectorsNotAnalysed": { + "type": "array", + "description": "Sectors not analysed in the report.", + "items": { + "type": "string", + "enum": [ + "Automotive", + "Aviation", + "Cement", + "Coal", + "Oil&Gas", + "Power", + "Steel" + ] + } + }, + "portfolioAllocationMethod": { + "type": "string", + "description": "Portfolio allocation method.", + "enum": [ + "portfolio_weight", + "ownership_weight" + ] + }, + "scenarioGeography": { + "type": "string", + "description": "Scenario geography." + }, + "scenarioOther": { + "type": "string", + "description": "Scenario other." + }, + "selectScenario": { + "type": "string", + "description": "default scenario to display." + }, + "techRoadmapSectors": { + "type": "array", + "description": "Sectors with technology roadmap to be included in the report.", + "items": { + "type": "string", + "enum": [ + "Automotive", + "Aviation", + "Cement", + "Coal", + "Oil&Gas", + "Power", + "Steel" + ] + } + } + }, + "required": [ + "projectCode", + "projectReportName", + "greenTechs", + "pactaSectorsNotAnalysed", + "portfolioAllocationMethod", + "scenarioGeography", + "scenarioOther", + "selectScenario", + "techRoadmapSectors" + ], + "additionalProperties": true + }, + "allOf": [ + { + "required": [ + "portfolio", + "reporting", + "user" + ] + }, + { + "not": { + "required": [ + "inherit" + ] + } + } + ], + "additionalProperties": true +} diff --git a/inst/extdata/scripts/prepare_dashboard_data.R b/inst/extdata/scripts/prepare_dashboard_data.R index 7273865..ceb6413 100644 --- a/inst/extdata/scripts/prepare_dashboard_data.R +++ b/inst/extdata/scripts/prepare_dashboard_data.R @@ -1,31 +1,29 @@ -# logger::log_threshold(Sys.getenv("LOG_LEVEL", "INFO")) +logger::log_threshold(Sys.getenv("LOG_LEVEL", "INFO")) -# raw_params <- commandArgs(trailingOnly = TRUE) -# params <- pacta.workflow.utils::parse_raw_params( -# json = raw_params, -# inheritence_search_paths = system.file( -# "extdata", "parameters", -# package = "workflow.pacta.report" -# ) , -# schema_file = system.file( -# "extdata", "schema", "reportingParameters.json", -# package = "workflow.pacta.report" -# ), -# raw_schema_file = system.file( -# "extdata", "schema", "rawParameters.json", -# package = "workflow.pacta.report" -# ), -# force_array = c("portfolio", "files") -# ) +schema_tempdir <- tempdir() +workflow.pacta.dashboard:::prepare_schema_files( + directory = schema_tempdir +) -manifest_info <- workflow.pacta.dashboard:::build_dashboard( - # params = params +raw_params <- commandArgs(trailingOnly = TRUE) +params <- pacta.workflow.utils::parse_raw_params( + json = raw_params, + inheritence_search_paths = c( + system.file( + "extdata", "parameters", + package = "workflow.pacta.dashboard" + ), + system.file( + "extdata", "parameters", + package = "workflow.pacta" + ) + ), + schema_file = file.path(schema_tempdir, "reportingParameters.json"), + raw_schema_file = file.path(schema_tempdir, "rawParameters.json"), + force_array = c("portfolio", "files") ) -# pacta.workflow.utils::export_manifest( -# input_files = manifest_info[["input_files"]], -# output_files = manifest_info[["output_files"]], -# params = manifest_info[["params"]], -# manifest_path = file.path(Sys.getenv("REPORT_OUTPUT_DIR"), "manifest.json"), -# raw_params = raw_params -# ) +manifest_info <- workflow.pacta.dashboard:::run_dashboard_workflow( + params = params, + raw_params = raw_params +) diff --git a/man/prepare_schema_files.Rd b/man/prepare_schema_files.Rd new file mode 100644 index 0000000..6dc2cb4 --- /dev/null +++ b/man/prepare_schema_files.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/prepare_schema_files.R +\name{prepare_schema_files} +\alias{prepare_schema_files} +\title{Copy parameter files to directory} +\usage{ +prepare_schema_files(directory) +} +\arguments{ +\item{directory}{Directory to copy parameter files to.} +} +\value{ +directory +} +\description{ +Copy schema files from dependency packages to a (temporary) directory. This +is required, as \code{jsonvalidate} requires referenced schema files to exist in +the same directory as the referencing schema. +} diff --git a/man/run_dashboard_workflow.Rd b/man/run_dashboard_workflow.Rd new file mode 100644 index 0000000..ffda951 --- /dev/null +++ b/man/run_dashboard_workflow.Rd @@ -0,0 +1,47 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/run_dashboard_workflow.R +\name{run_dashboard_workflow} +\alias{run_dashboard_workflow} +\title{Run Dashboard workflow} +\usage{ +run_dashboard_workflow( + params, + raw_params, + run_analysis = TRUE, + run_dashboard = TRUE, + analysis_output_dir = Sys.getenv("ANALYSIS_OUTPUT_DIR"), + benchmarks_dir = Sys.getenv("BENCHMARKS_DIR"), + pacta_data_dir = Sys.getenv("PACTA_DATA_DIR"), + portfolio_dir = Sys.getenv("PORTFOLIO_DIR"), + dashboard_output_dir = Sys.getenv("DASHBOARD_OUTPUT_DIR") +) +} +\arguments{ +\item{params}{(\code{list}) A list of parameters to be used in the analysis and +dashboard process. See JSON Schema for details.} + +\item{raw_params}{(\code{character}) Raw JSON string of parameters.} + +\item{run_analysis}{(\code{logical}) Run the analysis process.} + +\item{run_dashboard}{(\code{logical}) Run the dashboard creation process.} + +\item{analysis_output_dir}{Directory containing the PACTA analysis results.} + +\item{benchmarks_dir}{filepath: Directory containing the benchmark analysis +results.} + +\item{pacta_data_dir}{filepath: Directory with "pacta-data"} + +\item{portfolio_dir}{filepath: Directory with portfolio files} + +\item{dashboard_output_dir}{Directory where the dashboard will be +saved.} +} +\value{ +(invisible) \code{TRUE} if the workflow was successful. Primarily called +for side effect of rendering files. +} +\description{ +Run steps required to prepare a PACTA analysis and dashboard +} diff --git a/tests/config/default_2022Q4.json b/tests/config/default_2022Q4.json new file mode 100644 index 0000000..12e6456 --- /dev/null +++ b/tests/config/default_2022Q4.json @@ -0,0 +1,15 @@ +{ + "holdingsDate": "2022Q4", + "pactaDataURL": "https://pactadatadev.blob.core.windows.net/pacta-data-webapp/2022Q4/2022Q4_20240426T113151Z", + "benchmarksURL": "https://pactadatadev.blob.core.windows.net/benchmarks-webapp/2022Q4/2022Q4_20240529T002407Z", + "parameters": { + "portfolio": { + "holdingsDate": "2022-12-31", + "files": [ + "default_portfolio.csv" + ], + "name": "Default Portfolio" + }, + "inherit": "GENERAL_2022Q4" + } +} diff --git a/tests/config/default_2023Q4.json b/tests/config/default_2023Q4.json new file mode 100644 index 0000000..7b65a21 --- /dev/null +++ b/tests/config/default_2023Q4.json @@ -0,0 +1,15 @@ +{ + "holdingsDate": "2023Q4", + "pactaDataURL": "https://pactadatadev.blob.core.windows.net/pacta-data-webapp/2023Q4/2023Q4_20240424T120055Z", + "benchmarksURL": "https://pactadatadev.blob.core.windows.net/benchmarks-webapp/2023Q4/2023Q4_20240529T002355Z", + "parameters": { + "portfolio": { + "holdingsDate": "2023-12-31", + "files": [ + "default_portfolio.csv" + ], + "name": "Default Portfolio" + }, + "inherit": "GENERAL_2023Q4" + } +} diff --git a/tests/config/full_params_2022Q4.json b/tests/config/full_params_2022Q4.json new file mode 100644 index 0000000..661140b --- /dev/null +++ b/tests/config/full_params_2022Q4.json @@ -0,0 +1,76 @@ +{ + "holdingsDate": "2022Q4", + "pactaDataURL": "https://pactadatadev.blob.core.windows.net/pacta-data-webapp/2022Q4/2022Q4_20240426T113151Z", + "benchmarksURL": "https://pactadatadev.blob.core.windows.net/benchmarks-webapp/2022Q4/2022Q4_20240529T002407Z", + "parameters": { + "portfolio": { + "holdingsDate": "2022-12-31", + "files": [ + "default_portfolio.csv" + ], + "name": "Default Portfolio" + }, + "analysis": { + "equityMarketList": [ + "GlobalMarket", + "DevelopedMarket", + "EmergingMarket" + ], + "scenarioGeographiesList": [ + "Global", + "GlobalAggregate", + "NonOECD", + "OECD" + ], + "scenarioSourcesList": [ + "GECO2022", + "ISF2021", + "WEO2022" + ], + "sectorList": [ + "Power", + "Automotive", + "Coal", + "Steel", + "Aviation", + "Cement" + ], + "startYear": 2022, + "timeHorizon": 5 + }, + "user": { + "name": "Default Investor", + "languageSelect": "EN", + "peerGroup": "bank", + "currencyExchangeValue": 1, + "displayCurrency": "USD" + }, + "reporting": { + "projectCode": "GENERAL", + "projectReportName": "general", + "greenTechs": [ + "RenewablesCap", + "HydroCap", + "NuclearCap", + "Hybrid", + "Electric", + "FuelCell", + "Electric Arc Furnace" + ], + "pactaSectorsNotAnalysed": [ + "Steel", + "Aviation", + "Cement" + ], + "portfolioAllocationMethod": "portfolio_weight", + "scenarioGeography": "Global", + "scenarioOther": "GECO2022_1.5C", + "selectScenario": "WEO2022_NZE_2050", + "techRoadmapSectors": [ + "Power", + "Automotive", + "Coal" + ] + } + } +} diff --git a/tests/config/full_params_2023Q4.json b/tests/config/full_params_2023Q4.json new file mode 100644 index 0000000..6d42ad5 --- /dev/null +++ b/tests/config/full_params_2023Q4.json @@ -0,0 +1,76 @@ +{ + "holdingsDate": "2023Q4", + "pactaDataURL": "https://pactadatadev.blob.core.windows.net/pacta-data-webapp/2023Q4/2023Q4_20240424T120055Z", + "benchmarksURL": "https://pactadatadev.blob.core.windows.net/benchmarks-webapp/2023Q4/2023Q4_20240529T002355Z", + "parameters": { + "portfolio": { + "holdingsDate": "2023-12-31", + "files": [ + "default_portfolio.csv" + ], + "name": "Default Portfolio" + }, + "analysis": { + "equityMarketList": [ + "GlobalMarket", + "DevelopedMarket", + "EmergingMarket" + ], + "scenarioGeographiesList": [ + "Global", + "GlobalAggregate", + "NonOECD", + "OECD" + ], + "scenarioSourcesList": [ + "GECO2023", + "ISF2023", + "WEO2023" + ], + "sectorList": [ + "Power", + "Automotive", + "Coal", + "Steel", + "Aviation", + "Cement" + ], + "startYear": 2023, + "timeHorizon": 5 + }, + "user": { + "name": "Default Investor", + "languageSelect": "EN", + "peerGroup": "bank", + "currencyExchangeValue": 1, + "displayCurrency": "USD" + }, + "reporting": { + "projectCode": "GENERAL", + "projectReportName": "general", + "greenTechs": [ + "RenewablesCap", + "HydroCap", + "NuclearCap", + "Hybrid", + "Electric", + "FuelCell", + "Electric Arc Furnace" + ], + "pactaSectorsNotAnalysed": [ + "Steel", + "Aviation", + "Cement" + ], + "portfolioAllocationMethod": "portfolio_weight", + "scenarioGeography": "Global", + "scenarioOther": "WEO2023_NZE_2050", + "selectScenario": "WEO2023_NZE_2050", + "techRoadmapSectors": [ + "Power", + "Automotive", + "Coal" + ] + } + } +} diff --git a/tests/portfolios/default_portfolio.csv b/tests/portfolios/default_portfolio.csv new file mode 100644 index 0000000..de58d78 --- /dev/null +++ b/tests/portfolios/default_portfolio.csv @@ -0,0 +1,91 @@ +isin,market_value,currency +XS1297557172,6821206,USD +DE000A1R07L4,4724723,USD +US345370BV11,5619252,USD +CND10001QD60,1124438,USD +XS2356040357,3076756,USD +US31428XAY22,8235607,USD +FR0012650281,641235,USD +FR001400F2Q0,4190307,USD +USQ94606AE22,4118654,USD +US911312BB15,5414864,USD +INE331A07273,2972779,USD +INE481G07166,3244497,USD +INE010A08065,4488737,USD +US86614RAF47,5793655,USD +FR0124261621,1581767,USD +US60937CAA36,900439,USD +US93317QAD79,9993273,USD +TH0148034703,8657460,USD +XS2325566847,9459870,USD +US02076XAC65,3952496,USD +US880779BA01,3506143,USD +USU88125AC04,3401211,USD +INE208A07281,8670483,USD +US69373UAA51,267878,USD +US12594KAA07,4094599,USD +US205677AB38,3309593,USD +US69370RAK32,3519158,USD +US707887A@47,1577541,USD +US166764AA86,6575752,USD +US71654QCP54,7084677,USD +INE206D08162,6210214,USD +US745310AB85,709698,USD +CA44882ZXZ12,2809584,USD +JP360540AR10,9641731,USD +CA44885ZEQ96,9683822,USD +INE017A08235,3910673,USD +XS1555576641,2598631,USD +XS1381693248,2117715,USD +NO0010892870,8899756,USD +NO0010806912,7280862,USD +USU85795AQ29,2560264,USD +JP338603AA35,6806168,USD +DE000A2GESQ1,1567613,USD +INE114A07802,8605761,USD +US03938LAA26,2698943,USD +KR7005380001,9338795,USD +CNE100000Q35,1068423,USD +KYG3777B1032,9637388,USD +US5787871038,5467105,USD +SE0016844831,4168401,USD +TW0002646007,6371201,USD +INE646L01027,8355228,USD +US38045R2067,7952384,USD +PHY1234G1032,180886,USD +US00910M1009,6809079,USD +INE070A01015,1013567,USD +CNE000000XV4,8873793,USD +PK0059501012,5829360,USD +INE583C01021,6059486,USD +MYL5000OO004,6433976,USD +AU000000BCB5,9186193,USD +US03940R1077,265189,USD +ID1000162902,1712519,USD +US03485P3001,4712749,USD +CNE0000017V2,5989615,USD +NL0010545661,3343735,USD +CNE000000FH0,8915246,USD +US6937181088,9800223,USD +US9288541082,7226287,USD +CA62910L1022,9449577,USD +IL0011419699,7746343,USD +SE0020180917,1788562,USD +AU000000BUY9,1578448,USD +KR7096770003,860209,USD +US45325E2019,4071578,USD +CA45790B7088,8510107,USD +US0188021085,7030638,USD +JP3981200003,344741,USD +GB00B1VNSX38,6493591,USD +BRENGICDAM16,9257903,USD +MHY271836006,1571628,USD +MHY2687W1241,2627572,USD +TH0363010R10,8711798,USD +JP3247600004,4447848,USD +IL0065100930,1121308,USD +QA000A0KD6K3,6405719,USD +US92023R4074,8204370,USD +JP3342000001,8564047,USD +US88031M1099,149263,USD +TW0009957001,4538558,USD