Source code for simulation

# -*- coding: utf-8 -*-
"""
:Author: Dominic Hunt
"""
import logging
import copy
import fire

import pandas as pd
import numpy as np

import outputting

from taskGenerator import TaskGeneration
from modelGenerator import ModelGen


[docs]def run(task_name='Basic', task_changing_properties=None, task_constant_properties=None, model_name='QLearn', model_changing_properties=None, model_constant_properties=None, model_changing_properties_repetition=1, label=None, config_file=None, output_path=None, pickle=False, min_log_level='INFO', numpy_error_level="log"): """ A framework for letting models interact with tasks and record the data Parameters ---------- task_name : string The name of the file where a tasks.taskTemplate.Task class can be found. Default ``Basic`` task_changing_properties : dictionary of floats or lists of floats Parameters are the options that you are or are likely to change across task instances. When a parameter contains a list, an instance of the task will be created for every combination of this parameter with all the others. Default ``None`` task_constant_properties : dictionary of float, string or binary valued elements These contain all the the task options that describe the task being studied but do not vary across task instances. Default ``None`` model_name : string The name of the file where a model.modelTemplate.Model class can be found. Default ``QLearn`` model_changing_properties : dictionary containing floats or lists of floats, optional Parameters are the options that you are or are likely to change across model instances. When a parameter contains a list, an instance of the model will be created for every combination of this parameter with all the others. Default ``None`` model_constant_properties : dictionary of float, string or binary valued elements, optional These contain all the the model options that define the version of the model being studied. Default ``None`` model_changing_properties_repetition : int, optional The number of times each parameter combination is repeated. config_file : string, optional The file name and path of a ``.yaml`` configuration file. Overrides all other parameters if found. Default ``None`` output_path : string, optional The path that will be used for the run output. Default ``None`` pickle : bool, optional If true the data for each model, task and participant is recorded. Default is ``False`` label : string, optional The label for the simulation. Default ``None``, which means nothing will be saved min_log_level : str, optional Defines the level of the log from (``DEBUG``, ``INFO``, ``WARNING``, ``ERROR``, ``CRITICAL``). Default ``INFO`` numpy_error_level : {'log', 'raise'} Defines the response to numpy errors. Default ``log``. See numpy.seterr See Also -------- tasks.taskTemplate, model.modelTemplate """ config = copy.deepcopy(locals()) tasks = TaskGeneration(task_name=task_name, parameters=task_changing_properties, other_options=task_constant_properties) if model_changing_properties_repetition > 1: repeated_key = model_changing_properties.keys()[0] repeated_values = np.repeat(model_changing_properties[repeated_key], model_changing_properties_repetition) model_changing_properties[repeated_key] = repeated_values.tolist() models = ModelGen(model_name=model_name, parameters=model_changing_properties, other_options=model_constant_properties) with outputting.Saving(config=config) as file_name_generator: logger = logging.getLogger('Overview') simID = 0 message = "Beginning the simulation set" logger.debug(message) for task_number in tasks.iter_task_ID(): for model in models: task = tasks.new_task(task_number) log_simulation_parameters(task.params(), model.params(), simID=str(simID)) message = "Beginning task" logger.debug(message) for state in task: model.observe(state) action = model.action() task.receiveAction(action) response = task.feedback() model.feedback(response) task.proceed() model.setsimID(str(simID)) message = "Task completed" logger.debug(message) if file_name_generator is not None: record_simulation(file_name_generator, task.returnTaskState(), model.returnTaskState(), str(simID), pickle=pickle) simID += 1
[docs]def record_simulation(file_name_generator, task_data, model_data, simID, pickle=False): """ Records the data from an task-model run. Creates a pickled version Parameters ---------- file_name_generator : function Creates a new file with the name <handle> and the extension <extension>. It takes two string parameters: (``handle``, ``extension``) and returns one ``fileName`` string task_data : dict The data from the task model_data : dict The data from the model simID : str The label identifying the simulation pickle : bool, optional If true the data for each model, task and participant is recorded. Default is ``False`` See Also -------- pickleLog : records the picked data """ logger = logging.getLogger('Framework') message = "Beginning simulation output processing" logger.debug(message) label = "_sim-" + simID message = "Store data for simulation " + simID logger.debug(message) csv_model_simulation(model_data, simID, file_name_generator) if pickle: outputting.pickleLog(task_data, file_name_generator, "_taskData" + label) outputting.pickleLog(model_data, file_name_generator, "_modelData" + label)
[docs]def log_simulation_parameters(task_parameters, model_parameters, simID): """ Writes to the log the description and the label of the task and model Parameters ---------- task_parameters : dict The task parameters model_parameters : dict The model parameters simID : string The identifier for each simulation. See Also -------- recordSimParams : Records these parameters for later use """ task_description = task_parameters.pop('Name') + ": " task_descriptors = [k + ' = ' + repr(v) for k, v in task_parameters.items()] task_description += ", ".join(task_descriptors) model_description = model_parameters.pop('Name') + ": " model_descriptors = [k + ' = ' + repr(v) for k, v in model_parameters.items()] model_description += ", ".join(model_descriptors) message = "Simulation " + simID + " contains the task " + task_description + "." message += "The model used is " + model_description + "." logger_sim = logging.getLogger('Simulation') logger_sim.info(message)
[docs]def csv_model_simulation(modelData, simID, file_name_generator): # type: (dict, str, function) -> None """ Saves the fitting data to a CSV file Parameters ---------- modelData : dict The data from the model simID : string The identifier for the simulation file_name_generator : function Creates a new file with the name <handle> and the extension <extension>. It takes two string parameters: (``handle``, ``extension``) and returns one ``fileName`` string """ data = outputting.newListDict(modelData) record = pd.DataFrame(data) name = "data/modelSim_" + simID outputFile = file_name_generator(name, 'csv') record.to_csv(outputFile)
if __name__ == '__main__': fire.Fire(run)