Skip to content

Basico Model

BasicoModel class for loading and simulating SBML models using the basico package.

BasicoModel

Bases: SysBioModel

Model that loads and simulates SBML models using the basico package. Can load models from an SBML file or download them using a BioModels biomodel_id.

Source code in aiagents4pharma/talk2biomodels/models/basico_model.py
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 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
class BasicoModel(SysBioModel):
    """
    Model that loads and simulates SBML models using the basico package.
    Can load models from an SBML file or download them using a BioModels biomodel_id.
    """
    biomodel_id: Optional[int] = Field(None, description="BioModels model ID to download and load")
    sbml_file_path: Optional[str] = Field(None, description="Path to an SBML file to load")
    simulation_results: Optional[str] = None
    name: Optional[str] = Field("", description="Name of the model")
    description: Optional[str] = Field("", description="Description of the model")

    # Additional attribute not included in the schema
    copasi_model: Optional[object] = None  # Holds the loaded Copasi model

    @model_validator(mode="after")
    def check_biomodel_id_or_sbml_file_path(self):
        """
        Validate that either biomodel_id or sbml_file_path is provided.
        """
        if not self.biomodel_id and not self.sbml_file_path:
            logger.error("Either biomodel_id or sbml_file_path must be provided.")
            raise ValueError("Either biomodel_id or sbml_file_path must be provided.")
        if self.biomodel_id:
            self.copasi_model = basico.load_biomodel(self.biomodel_id)
            self.description = basico.biomodels.get_model_info(self.biomodel_id)["description"]
            self.name = basico.model_info.get_model_name(model=self.copasi_model)
        elif self.sbml_file_path:
            self.copasi_model = basico.load_model(self.sbml_file_path)
            self.description = basico.model_info.get_notes(model=self.copasi_model)
            self.name = basico.model_info.get_model_name(model=self.copasi_model)
        return self

    def update_parameters(self, parameters: Dict[str, Union[float, int]]) -> None:
        """
        Update model parameters with new values.
        """
        # Update parameters in the model
        for param_name, param_value in parameters.items():
            # check if the param_name is not None
            if param_name is None:
                continue
            # if param is a kinetic parameter
            df_all_params = basico.model_info.get_parameters(model=self.copasi_model)
            if param_name in df_all_params.index.tolist():
                basico.model_info.set_parameters(name=param_name,
                                            exact=True,
                                            initial_value=param_value,
                                            model=self.copasi_model)
            # if param is a species
            else:
                basico.model_info.set_species(name=param_name,
                                            exact=True,
                                            initial_concentration=param_value,
                                            model=self.copasi_model)

    def simulate(self, duration: Union[int, float] = 10, interval: int = 10) -> pd.DataFrame:
        """
        Simulate the COPASI model over a specified range of time points.

        Args:
            duration: Duration of the simulation in time units.
            interval: Interval between time points in the simulation.

        Returns:
            Pandas DataFrame with time-course simulation results.
        """
        # Run the simulation and return results
        df_result = basico.run_time_course(model=self.copasi_model,
                                        intervals=interval,
                                        duration=duration)
        # # Replace curly braces in column headers with square brackets
        # # Because curly braces in the world of LLMS are used for
        # # structured output
        # df_result.columns = df_result.columns.str.replace('{', '[', regex=False).\
        #             str.replace('}', ']', regex=False)
        # Reset the index
        df_result.reset_index(inplace=True)
        # Store the simulation results
        self.simulation_results = df_result
        # Return copy of the simulation results
        return df_result.copy()

    def get_model_metadata(self) -> Dict[str, Union[str, int]]:
        """
        Retrieve metadata specific to the COPASI model.

        Returns:
            Dictionary of model metadata.
        """
        return {
            "Model Type": "SBML Model (COPASI)",
            "Parameter Count": len(basico.get_parameters())
        }

check_biomodel_id_or_sbml_file_path()

Validate that either biomodel_id or sbml_file_path is provided.

Source code in aiagents4pharma/talk2biomodels/models/basico_model.py
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
@model_validator(mode="after")
def check_biomodel_id_or_sbml_file_path(self):
    """
    Validate that either biomodel_id or sbml_file_path is provided.
    """
    if not self.biomodel_id and not self.sbml_file_path:
        logger.error("Either biomodel_id or sbml_file_path must be provided.")
        raise ValueError("Either biomodel_id or sbml_file_path must be provided.")
    if self.biomodel_id:
        self.copasi_model = basico.load_biomodel(self.biomodel_id)
        self.description = basico.biomodels.get_model_info(self.biomodel_id)["description"]
        self.name = basico.model_info.get_model_name(model=self.copasi_model)
    elif self.sbml_file_path:
        self.copasi_model = basico.load_model(self.sbml_file_path)
        self.description = basico.model_info.get_notes(model=self.copasi_model)
        self.name = basico.model_info.get_model_name(model=self.copasi_model)
    return self

get_model_metadata()

Retrieve metadata specific to the COPASI model.

Returns:

Type Description
Dict[str, Union[str, int]]

Dictionary of model metadata.

Source code in aiagents4pharma/talk2biomodels/models/basico_model.py
101
102
103
104
105
106
107
108
109
110
111
def get_model_metadata(self) -> Dict[str, Union[str, int]]:
    """
    Retrieve metadata specific to the COPASI model.

    Returns:
        Dictionary of model metadata.
    """
    return {
        "Model Type": "SBML Model (COPASI)",
        "Parameter Count": len(basico.get_parameters())
    }

simulate(duration=10, interval=10)

Simulate the COPASI model over a specified range of time points.

Parameters:

Name Type Description Default
duration Union[int, float]

Duration of the simulation in time units.

10
interval int

Interval between time points in the simulation.

10

Returns:

Type Description
DataFrame

Pandas DataFrame with time-course simulation results.

Source code in aiagents4pharma/talk2biomodels/models/basico_model.py
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
def simulate(self, duration: Union[int, float] = 10, interval: int = 10) -> pd.DataFrame:
    """
    Simulate the COPASI model over a specified range of time points.

    Args:
        duration: Duration of the simulation in time units.
        interval: Interval between time points in the simulation.

    Returns:
        Pandas DataFrame with time-course simulation results.
    """
    # Run the simulation and return results
    df_result = basico.run_time_course(model=self.copasi_model,
                                    intervals=interval,
                                    duration=duration)
    # # Replace curly braces in column headers with square brackets
    # # Because curly braces in the world of LLMS are used for
    # # structured output
    # df_result.columns = df_result.columns.str.replace('{', '[', regex=False).\
    #             str.replace('}', ']', regex=False)
    # Reset the index
    df_result.reset_index(inplace=True)
    # Store the simulation results
    self.simulation_results = df_result
    # Return copy of the simulation results
    return df_result.copy()

update_parameters(parameters)

Update model parameters with new values.

Source code in aiagents4pharma/talk2biomodels/models/basico_model.py
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
def update_parameters(self, parameters: Dict[str, Union[float, int]]) -> None:
    """
    Update model parameters with new values.
    """
    # Update parameters in the model
    for param_name, param_value in parameters.items():
        # check if the param_name is not None
        if param_name is None:
            continue
        # if param is a kinetic parameter
        df_all_params = basico.model_info.get_parameters(model=self.copasi_model)
        if param_name in df_all_params.index.tolist():
            basico.model_info.set_parameters(name=param_name,
                                        exact=True,
                                        initial_value=param_value,
                                        model=self.copasi_model)
        # if param is a species
        else:
            basico.model_info.set_species(name=param_name,
                                        exact=True,
                                        initial_concentration=param_value,
                                        model=self.copasi_model)