cesci_model / app.py
smejak's picture
Update app.py
18c04b6
import pandas as pd
import numpy as np
from random import normalvariate, random
import plotly.express as px
from cadCAD.configuration.utils import config_sim
from cadCAD.configuration import Experiment
from cadCAD.engine import ExecutionContext, Executor
from cadCAD import configs
import streamlit as st
from PIL import Image
# Additional dependencies
# For analytics
import numpy as np
# For visualization
import plotly.express as px
pd.options.plotting.backend = "plotly"
st.header('CeSci Value Flow Model')
image = Image.open('cesci.png')
st.image(image, caption='CeSci value flow schema')
def p_value_flow(params, substep, state_history, previous_state):
funding = 0
management_costs = 0
to_researcher = 0
to_journal = 0
salary = 0
losses = 0
if random() < params['probability_funding'] and (previous_state['funding_pool'] > funding):
funding = params['funding_round']
management_costs = funding * params['alpha']
to_researcher = funding - management_costs
losses = management_costs
research_value = funding * (1-params['epsilon'])
losses += to_researcher - research_value
salary = research_value * params['beta']
to_journal = research_value + params['cost_publishing']
if random() < params['probability_buying']:
salary = salary - params['cost_buying']
to_journal += params['cost_buying']
# losses = funding - to_journal
return {'update_researcher_funding': to_researcher,
'update_funding_pool': -funding,
'update_journal': to_journal,
'update_researcher_done': salary,
'update_losses': losses}
def s_researcher_value(params, substep, state_history, previous_state, policy_input):
research_funding = policy_input['update_researcher_funding']
research_salary = policy_input['update_researcher_done']
research_value = previous_state['researcher_value']
if research_salary == 0:
updated_researcher_value = research_funding + research_value
return 'researcher_value', updated_researcher_value
else:
updated_researcher_value = research_salary + research_value
return 'researcher_value', updated_researcher_value
def s_journal_value(params, substep, state_history, previous_state, policy_input):
to_journal = policy_input['update_journal']
journal_value = previous_state['journal_value']
updated_journal_value = to_journal + journal_value
return 'journal_value', updated_journal_value
def s_funding_pool(params, substep, state_history, previous_state, policy_input):
funding_pool = previous_state['funding_pool']
updated_funding_pool = funding_pool + policy_input['update_funding_pool']
if updated_funding_pool < 0:
updated_funding_pool = 0
return 'funding_pool', updated_funding_pool
def s_losses(params, substep, state_history, previous_state, policy_input):
losses = previous_state['losses']
updated_losses = losses + policy_input['update_losses']
return 'losses', updated_losses
st.subheader('Initial Value Allocation')
funding_pool = st.slider('Initial Funding Pool', min_value=1000, max_value=10000, value=1000, step=10)
researcher_value = st.slider('Initial Researcher Tokens', min_value=0, max_value=1000, value=0, step=1)
journal_value = st.slider('Initial Journal Tokens', min_value=0, max_value=1000, value=0, step=1)
st.subheader('Simulation Parameters')
st.write('Set the funding disbursed each round from the funding pool')
funding_round = st.slider('Funding Round', min_value=100, max_value=1000, value=100, step=1)
st.write('Set the relative value leakages in the model.')
alpha = st.slider('Management Cost Weight', min_value=0., max_value=1., value=0.1, step=0.0001)
epsilon = st.slider('Work Inefficiency Weight', min_value=0., max_value=1., value=0.1, step=0.0001)
st.write('Set the portion of grant funding to be used as researcher salary.')
beta = st.slider('Salary Weight', min_value=0., max_value=1., value=0.4, step=0.0001)
st.write('Set the cost of publishing to a journal and the cost of getting access to papers.')
cost_publishing = st.slider('Cost of Publishing', min_value=10., max_value=100., value=10., step=0.1)
cost_buying = st.slider('Cost of Buying', min_value=10., max_value=100., value=10., step=0.1)
st.write('Set the probability a researcher will buy access to a paper at each timestep.')
probability_buying = st.slider('Researcher Probability of Buying', min_value=0., max_value=1., value=0.1, step=0.0001)
st.write('Set the probability the grant funding agency will disburse funding each round.')
probability_funding = st.slider('Probability of Disbursing Funding', min_value=0., max_value=1., value=0.9, step=0.0001)
st.write('Set the number of timesteps in the simulation.')
timesteps = st.slider('Timesteps', min_value=10, max_value=1000, value=100, step=1)
initial_state = {
'funding_pool': funding_pool,
'researcher_value': researcher_value,
'journal_value': journal_value,
'losses': 0
}
system_params = {
'funding_pool': [funding_pool],
'funding_round': [funding_round],
'alpha': [alpha],
'beta': [beta],
'epsilon': [epsilon],
'cost_publishing': [cost_publishing],
'cost_buying': [cost_buying],
'probability_buying': [probability_buying],
'probability_funding': [probability_funding]
}
def generate_sim_config(monte_carlo_runs=1,
timesteps=timesteps,
system_params=system_params):
sim_config = config_sim({
'N': monte_carlo_runs, # the number of times we'll run the simulation ("Monte Carlo runs")
'T': range(timesteps), # the number of timesteps the simulation will run for
'M': system_params # the parameters of the system
})
return sim_config
def configure_experiment(initial_state,
partial_state_update_blocks,
sim_config):
experiment = Experiment()
experiment.append_configs(
initial_state=initial_state,
partial_state_update_blocks=partial_state_update_blocks,
sim_configs=sim_config
)
return experiment
partial_state_update_blocks = [
{
'policies': {
'p_value_flow': p_value_flow
},
'variables': {
'funding_pool': s_funding_pool,
'researcher_value': s_researcher_value,
'journal_value': s_journal_value,
'losses': s_losses
}
}
]
def execute_simulation(experiment):
exec_context = ExecutionContext()
configs = experiment.configs
simulation = Executor(exec_context=exec_context, configs=configs)
raw_result, tensor_field, sessions = simulation.execute()
return raw_result
if st.button('Run Simulation'):
sim_config = generate_sim_config()
experiment = configure_experiment(initial_state, partial_state_update_blocks, sim_config)
raw_result = execute_simulation(experiment)
df = pd.DataFrame(raw_result)
fig1 = df.plot(kind='line', x='timestep', y=['funding_pool','researcher_value', 'journal_value'], width=1000)
fig2 = df.plot(kind='line', x='timestep', y=['funding_pool', 'losses'], width=1000)
st.subheader('Results')
st.plotly_chart(fig1)
st.plotly_chart(fig2)