Mimi Framework

Output Montecarlo Results for FUND Marginal Model

Hello Mimi community,

I am running a Monte Carlo simulation in FUND to estimate the Social Cost of Methane.

I am looking to produce an array of output for each marginal model that is simulated in the ensemble. Right now, the Monte Carlo ensemble returns only a single list for what I assume is the last run of the Monte Carlo. For example in the code below, I want to return the atmospheric methane concentration (acch4) from the marginal model for 100 simulations. However, the output is only of one simulation.

Example code that I’m running:
m = MimiFUND.get_model()
run(m)
result_ens = MimiFUND.compute_sc(m, year = 2020, gas = :CH4, eta = 0.0, prtp = 0.03, n = 100, seed = 1234, return_mm = true)
result_ens.mm[:climatech4cycle, :acch4]

Output:
1051-element Array{Float64,1}:

  • 0.0
  • 0.0
  • 0.0
  • 0.0…

I imagine the output should be an array with 100 columns for each simulation.

Thoughts on how to implement this in the src/new_marginaldamages.jl code?

@kar5469 sorry we’ve been focused on getting Mimi v1.0.0 released and I missed this question! @ckingdon95 and I will take a look and get back to you ASAP.

Hi Kristina,

You’re correct that the returned MarginalModel only stores the data from the last run of the Monte Carlo simulation. There is not currently a way to return the information you want from FUND’s default compute_sc function, although we would like to add this ability soon in a new version.

For now, I would recommend writing your own version of the compute_sc function where you can pass in as an argument a modified version of the SimulationDefinition that specifies what variables you would like the simulation to save for you. The function could look like this:

using Mimi, MimiFUND

function _my_compute_sc(m::Model=get_model(); 
    simdef = nothing,
    return_si = false,
    gas::Symbol = :CO2, 
    year::Union{Int, Nothing} = nothing, 
    eta::Float64 = 1.45, 
    prtp::Float64 = 0.015, 
    equity_weights::Bool = false, 
    equity_weights_normalization_region::Int = 0,
    last_year::Int = 3000, 
    pulse_size::Float64 = 1e7, 
    return_mm::Bool = false,
    n::Union{Int, Nothing} = nothing,
    trials_output_filename::Union{String, Nothing} = nothing,
    seed::Union{Int, Nothing} = nothing
    )

    year === nothing ? error("Must specify an emission year. Try `compute_sc(year=2020)`.") : nothing
    !(last_year in 1950:3000) ? error("Invlaid value for `last_year`: $last_year. `last_year` must be within the model's time index 1950:3000.") : nothing
    !(year in 1950:last_year) ? error("Invalid value for `year`: $year. `year` must be within the model's time index 1950:$last_year.") : nothing

    mm = MimiFUND.get_marginal_model(m; year = year, gas = gas, pulse_size = pulse_size)

    ntimesteps = MimiFUND.getindexfromyear(last_year)

    if n === nothing
        # Run the "best guess" social cost calculation
        run(mm; ntimesteps = ntimesteps)
        sc = MimiFUND._compute_sc_from_mm(mm, year = year, gas = gas, ntimesteps = ntimesteps, equity_weights = equity_weights, eta = eta, prtp = prtp, equity_weights_normalization_region=equity_weights_normalization_region)
    elseif n < 1
        error("Invalid n = $n. Number of trials must be a positive integer.")
    else
        # Run a Monte Carlo simulation
        if simdef === nothing
            simdef = MimiFUND.getmcs()
        end
        payload = (Array{Float64, 1}(undef, n), year, gas, ntimesteps, equity_weights, equity_weights_normalization_region, eta, prtp) # first item is an array to hold SC values calculated in each trial
        Mimi.set_payload!(simdef, payload) 
        seed !== nothing ? Random.seed!(seed) : nothing
        si = run(simdef, mm, n, ntimesteps = ntimesteps, post_trial_func = MimiFUND._fund_sc_post_trial, trials_output_filename = trials_output_filename)
        sc = Mimi.payload(si)[1]
    end

    if return_mm
        return (sc = sc, mm = mm)
    elseif return_si
        return(sc = sc, si = si)
    else
        return sc
    end
end

And then your code for using this function could look like:

m = MimiFUND.get_model()
run(m)

simdef = MimiFUND.getmcs()
Mimi.addSave!(simdef, :climatech4cycle, :acch4) 
result_ens = _my_compute_sc(m, simdef = simdef, return_si = true, year = 2020, gas = :CH4, eta = 0.0, prtp = 0.03, n = 100, seed = 1234)

si = result_ens.si
# If using Mimi 1.0, do the following to access the results:
getdataframe(si, :climatech4cycle, :acch4) 
# In earlier versions of Mimi, use this instead:
si[:climatech4cycle, :acch4]

I wrote this quickly, so please let me know if this doesn’t work out for you and are still stuck on anything!