Skip to content

Simulate model

Tool for simulating a model.

SimulateModelInput

Bases: BaseModel

Input schema for the SimulateModel tool.

Source code in aiagents4pharma/talk2biomodels/tools/simulate_model.py
26
27
28
29
30
31
32
33
34
35
36
37
38
class SimulateModelInput(BaseModel):
    """
    Input schema for the SimulateModel tool.
    """

    sys_bio_model: ModelData = Field(description="model data", default=None)
    arg_data: ArgumentData = Field(
        description="""time, species, and reocurring data
                                   as well as the simulation name""",
        default=None,
    )
    tool_call_id: Annotated[str, InjectedToolCallId]
    state: Annotated[dict, InjectedState]

SimulateModelTool

Bases: BaseTool

Tool for simulating a model.

Source code in aiagents4pharma/talk2biomodels/tools/simulate_model.py
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
class SimulateModelTool(BaseTool):
    """
    Tool for simulating a model.
    """

    name: str = "simulate_model"
    description: str = "A tool to simulate a biomodel"
    args_schema: type[BaseModel] = SimulateModelInput

    def _run(
        self,
        tool_call_id: Annotated[str, InjectedToolCallId],
        state: Annotated[dict, InjectedState],
        sys_bio_model: ModelData = None,
        arg_data: ArgumentData = None,
    ) -> Command:
        """
        Run the tool.

        Args:
            tool_call_id (str): The tool call ID. This is injected by the system.
            state (dict): The state of the tool.
            sys_bio_model (ModelData): The model data.
            arg_data (ArgumentData): The argument data.

        Returns:
            str: The result of the simulation.
        """
        logger.log(logging.INFO, "Calling simulate_model tool %s, %s", sys_bio_model, arg_data)
        sbml_file_path = state["sbml_file_path"][-1] if len(state["sbml_file_path"]) > 0 else None
        model_object = load_biomodel(sys_bio_model, sbml_file_path=sbml_file_path)
        # Prepare the dictionary of species data
        # that will be passed to the simulate method
        # of the BasicoModel class
        duration = 100.0
        interval = 10
        dic_species_to_be_analyzed_before_experiment = {}
        if arg_data:
            # Prepare the dictionary of species data
            if arg_data.species_to_be_analyzed_before_experiment is not None:
                dic_species_to_be_analyzed_before_experiment = dict(
                    zip(
                        arg_data.species_to_be_analyzed_before_experiment.species_name,
                        arg_data.species_to_be_analyzed_before_experiment.species_concentration,
                        strict=False,
                    )
                )
            # Add reocurring events (if any) to the model
            if arg_data.reocurring_data is not None:
                add_rec_events(model_object, arg_data.reocurring_data)
            # Set the duration and interval
            if arg_data.time_data is not None:
                duration = arg_data.time_data.duration
                interval = arg_data.time_data.interval
        # Update the model parameters
        model_object.update_parameters(dic_species_to_be_analyzed_before_experiment)
        logger.log(
            logging.INFO,
            "Following species/parameters updated in the model %s",
            dic_species_to_be_analyzed_before_experiment,
        )
        # Simulate the model
        df = model_object.simulate(duration=duration, interval=interval)
        logger.log(logging.INFO, "Simulation results ready with shape %s", df.shape)
        dic_simulated_data = {
            "name": arg_data.experiment_name,
            "source": (sys_bio_model.biomodel_id if sys_bio_model.biomodel_id else "upload"),
            "tool_call_id": tool_call_id,
            "data": df.to_dict(),
        }
        # Prepare the dictionary of updated state
        dic_updated_state_for_model = {}
        for key, value in {
            "model_id": [sys_bio_model.biomodel_id],
            "sbml_file_path": [sbml_file_path],
            "dic_simulated_data": [dic_simulated_data],
        }.items():
            if value:
                dic_updated_state_for_model[key] = value
        # Return the updated state of the tool
        return Command(
            update=dic_updated_state_for_model
            | {
                # update the message history
                "messages": [
                    ToolMessage(
                        content=f"Simulation results of {arg_data.experiment_name}",
                        tool_call_id=tool_call_id,
                        artifact=get_model_units(model_object),
                    )
                ],
            }
        )

_run(tool_call_id, state, sys_bio_model=None, arg_data=None)

Run the tool.

Parameters:

Name Type Description Default
tool_call_id str

The tool call ID. This is injected by the system.

required
state dict

The state of the tool.

required
sys_bio_model ModelData

The model data.

None
arg_data ArgumentData

The argument data.

None

Returns:

Name Type Description
str Command

The result of the simulation.

Source code in aiagents4pharma/talk2biomodels/tools/simulate_model.py
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
def _run(
    self,
    tool_call_id: Annotated[str, InjectedToolCallId],
    state: Annotated[dict, InjectedState],
    sys_bio_model: ModelData = None,
    arg_data: ArgumentData = None,
) -> Command:
    """
    Run the tool.

    Args:
        tool_call_id (str): The tool call ID. This is injected by the system.
        state (dict): The state of the tool.
        sys_bio_model (ModelData): The model data.
        arg_data (ArgumentData): The argument data.

    Returns:
        str: The result of the simulation.
    """
    logger.log(logging.INFO, "Calling simulate_model tool %s, %s", sys_bio_model, arg_data)
    sbml_file_path = state["sbml_file_path"][-1] if len(state["sbml_file_path"]) > 0 else None
    model_object = load_biomodel(sys_bio_model, sbml_file_path=sbml_file_path)
    # Prepare the dictionary of species data
    # that will be passed to the simulate method
    # of the BasicoModel class
    duration = 100.0
    interval = 10
    dic_species_to_be_analyzed_before_experiment = {}
    if arg_data:
        # Prepare the dictionary of species data
        if arg_data.species_to_be_analyzed_before_experiment is not None:
            dic_species_to_be_analyzed_before_experiment = dict(
                zip(
                    arg_data.species_to_be_analyzed_before_experiment.species_name,
                    arg_data.species_to_be_analyzed_before_experiment.species_concentration,
                    strict=False,
                )
            )
        # Add reocurring events (if any) to the model
        if arg_data.reocurring_data is not None:
            add_rec_events(model_object, arg_data.reocurring_data)
        # Set the duration and interval
        if arg_data.time_data is not None:
            duration = arg_data.time_data.duration
            interval = arg_data.time_data.interval
    # Update the model parameters
    model_object.update_parameters(dic_species_to_be_analyzed_before_experiment)
    logger.log(
        logging.INFO,
        "Following species/parameters updated in the model %s",
        dic_species_to_be_analyzed_before_experiment,
    )
    # Simulate the model
    df = model_object.simulate(duration=duration, interval=interval)
    logger.log(logging.INFO, "Simulation results ready with shape %s", df.shape)
    dic_simulated_data = {
        "name": arg_data.experiment_name,
        "source": (sys_bio_model.biomodel_id if sys_bio_model.biomodel_id else "upload"),
        "tool_call_id": tool_call_id,
        "data": df.to_dict(),
    }
    # Prepare the dictionary of updated state
    dic_updated_state_for_model = {}
    for key, value in {
        "model_id": [sys_bio_model.biomodel_id],
        "sbml_file_path": [sbml_file_path],
        "dic_simulated_data": [dic_simulated_data],
    }.items():
        if value:
            dic_updated_state_for_model[key] = value
    # Return the updated state of the tool
    return Command(
        update=dic_updated_state_for_model
        | {
            # update the message history
            "messages": [
                ToolMessage(
                    content=f"Simulation results of {arg_data.experiment_name}",
                    tool_call_id=tool_call_id,
                    artifact=get_model_units(model_object),
                )
            ],
        }
    )