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