wsim_electricity_basin_loss_factors.R 4.37 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#!/usr/bin/env Rscript

# Copyright (c) 2018 ISciences, LLC.
# All rights reserved.
#
# WSIM is licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License. You may
# obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

suppressMessages({
17
  require(dplyr)
18 19 20 21 22 23 24 25
  require(Rcpp)
})

wsim.io::logging_init('wsim_electricity_basin_losses')

'
Estimate basin-level electrical generation loss risk

26
Usage: wsim_electricity_basin_losses --windows=<file> --stress=<file> --bt_ro=<file>... --bt_ro_fit=<file>... --bt_ro_min_fit=<file>... --output=<file>
27 28

Options:
29 30 31 32 33 34
--windows <file>        Basin integration period (months)
--stress <file>         Basin baseline water stress
--bt_ro <files>         Basin total blue water [m^3]
--bt_ro_fit <files>     Basin total blue water distribution fits
--bt_ro_min_fit <files> Basin annual minimum total blue water distribution fits
--output <file>         Output loss risk by basin
35 36 37 38
'->usage

main <- function(raw_args) {
  args <- wsim.io::parse_args(usage, raw_args)
39

40 41 42
  basin_windows <- wsim.io::read_vars(args$window, expect.nvars=1, as.data.frame=TRUE)
  basin_ids <- basin_windows$id
  basin_bws <- wsim.io::read_vars(args$stress, expect.nvars=1, expect.ids=basin_ids, as.data.frame=TRUE)
43

44 45 46 47 48
  bt_ro_fits            <- wsim.io::read_integrated_vars(wsim.io::expand_inputs(args$bt_ro_fit), basin_ids)
  bt_ro_annual_min_fits <- wsim.io::read_integrated_vars(wsim.io::expand_inputs(args$bt_ro_min_fit), basin_ids)
  bt_ro                 <- wsim.io::read_integrated_vars(wsim.io::expand_inputs(args$bt_ro), basin_ids)
  names(bt_ro) <- c('id', 'flow', 'window')
  
49
  required_windows <- sort(unique(basin_windows$months_storage))
50
  for (w in required_windows) {
51 52
    if (!(w %in% bt_ro$window))
      stop("No blue water data found for integration window of ", w, " months.")
53

54 55
    if (!(w %in% bt_ro_fits$window))
      stop("No blue water fits found for integration window of ", w, " months.")
56 57 58
    
    if (!(w %in% bt_ro_annual_min_fits$window))
      stop("No blue water annual minimum fits found for integration window of ", w, " months.")
59
  }
60

61 62
  quaxxx <- wsim.distributions::find_qua(attr(bt_ro_fits, 'distribution'))
  cdfxxx <- wsim.distributions::find_cdf(attr(bt_ro_fits, 'distribution'))
63

64 65
  cdf_vectorized <- Vectorize(function(val, loc, scale, shape) {
    if(is.na(loc) || is.na(scale) || is.na(shape))
66
      NA_real_
67 68 69
    else
      cdfxxx(val, c(loc, scale, shape))
  })
70

71 72 73 74 75 76
  med_vectorized <- Vectorize(function(loc, scale, shp) {
    if(is.na(loc) || is.na(scale) || is.na(shp))
      loc
    else
      quaxxx(0.5, c(loc, scale, shp))
  })
77

78 79 80 81
  # TODO get rid of dplyr noise about attribute mismatch
  basins <- select(basin_windows, id, window=months_storage) %>%
    inner_join(basin_bws, by='id') %>%
    left_join(bt_ro, by=c('id', 'window')) %>%
82 83 84 85 86
    left_join(select(bt_ro_fits, id, window, month_location=location, month_scale=scale, month_shape=shape), by=c('id', 'window')) %>%
    left_join(select(bt_ro_annual_min_fits, id, window, annual_min_location=location, annual_min_scale=scale, annual_min_shape=shape), by=c('id', 'window')) %>%
    mutate(annual_min_flow_quantile=cdf_vectorized(flow, annual_min_location, annual_min_scale, annual_min_shape),
           annual_min_flow_rp=wsim.distributions::quantile2rp(annual_min_flow_quantile),
           month_flow_median=med_vectorized(month_location, month_scale, month_shape))
Dan Baston's avatar
Dan Baston committed
87

88
  basins$water_cooled_loss <- wsim.electricity::water_cooled_loss(
89
    -basins$annual_min_flow_rp,
90 91
    wsim.electricity::water_cooled_loss_onset(basins$baseline_water_stress),
    wsim.electricity::water_cooled_loss_onset(basins$baseline_water_stress) + 30)
92

93
  basins$hydropower_loss <- wsim.electricity::hydropower_loss(basins$flow, basins$month_flow_median, 0.6)
Dan Baston's avatar
Dan Baston committed
94

95
  wsim.io::write_vars_to_cdf(vars=basins[, c('annual_min_flow_quantile', 'annual_min_flow_rp', 'month_flow_median', 'water_cooled_loss', 'hydropower_loss')],
96
                             filename=args$output,
97
                             ids=basins$id)
98 99
}

100
tryCatch(main(commandArgs(TRUE)), error=wsim.io::die_with_message)