|
17 | 17 | ) |
18 | 18 | from cognite.client.data_classes.simulators.logs import SimulatorLog |
19 | 19 | from cognite.client.utils._experimental import FeaturePreviewWarning |
| 20 | +from cognite.client.utils._importing import local_import |
20 | 21 | from cognite.client.utils._retry import Backoff |
| 22 | +from cognite.client.utils._text import to_snake_case |
21 | 23 |
|
22 | 24 | if TYPE_CHECKING: |
| 25 | + import pandas |
| 26 | + |
23 | 27 | from cognite.client import CogniteClient |
24 | 28 |
|
25 | 29 | _WARNING = FeaturePreviewWarning(api_maturity="General Availability", sdk_maturity="alpha", feature_name="Simulators") |
@@ -236,6 +240,18 @@ def get_logs(self) -> SimulatorLog | None: |
236 | 240 | """ |
237 | 241 | return self._cognite_client.simulators.logs.retrieve(id=self.log_id) |
238 | 242 |
|
| 243 | + def get_data(self) -> SimulationRunDataItem | None: |
| 244 | + """`Retrieve data associated with this simulation run. <https://developer.cognite.com/api#tag/Simulation-Runs/operation/simulation_data_by_run_id_simulators_runs_data_list_post>`_ |
| 245 | +
|
| 246 | + Returns: |
| 247 | + SimulationRunDataItem | None: Data for the simulation run. |
| 248 | + """ |
| 249 | + data = self._cognite_client.simulators.runs.list_run_data(run_id=self.id) |
| 250 | + if data: |
| 251 | + return data[0] |
| 252 | + |
| 253 | + return None |
| 254 | + |
239 | 255 | def update(self) -> None: |
240 | 256 | """Update the simulation run object to the latest state. Useful if the run was created with wait=False.""" |
241 | 257 | # same logic as Cognite Functions |
@@ -424,10 +440,56 @@ def dump(self, camel_case: bool = True) -> dict[str, Any]: |
424 | 440 | output["outputs"] = [output_.dump(camel_case=camel_case) for output_ in self.outputs] |
425 | 441 | return output |
426 | 442 |
|
| 443 | + def to_pandas( # type: ignore [override] |
| 444 | + self, |
| 445 | + ) -> pandas.DataFrame: |
| 446 | + """Convert the simulation run data to a pandas DataFrame. |
| 447 | +
|
| 448 | + Returns: |
| 449 | + pandas.DataFrame: The dataframe. |
| 450 | + """ |
| 451 | + pd = local_import("pandas") |
| 452 | + |
| 453 | + def _create_row(item: SimulationInput | SimulationOutput) -> dict: |
| 454 | + """Create a row dictionary for an input or output item.""" |
| 455 | + item_type = (isinstance(item, SimulationInput) and "Input") or "Output" |
| 456 | + row = { |
| 457 | + "run_id": self.run_id, |
| 458 | + "type": item_type, |
| 459 | + "reference_id": item.reference_id, |
| 460 | + "value": item.value, |
| 461 | + "unit_name": item.unit.name if item.unit else None, |
| 462 | + "value_type": item.value_type, |
| 463 | + "overridden": getattr(item, "overridden", None), |
| 464 | + "timeseries_external_id": item.timeseries_external_id, |
| 465 | + } |
| 466 | + |
| 467 | + if item.simulator_object_reference: |
| 468 | + for reference_key, reference_value in item.simulator_object_reference.items(): |
| 469 | + snake_key = to_snake_case(reference_key) |
| 470 | + row[snake_key] = reference_value |
| 471 | + |
| 472 | + return row |
| 473 | + |
| 474 | + rows = [_create_row(item) for item in self.inputs + self.outputs] |
| 475 | + |
| 476 | + return pd.DataFrame(rows) |
| 477 | + |
427 | 478 |
|
428 | 479 | class SimulatorRunDataList(CogniteResourceList[SimulationRunDataItem], IdTransformerMixin): |
429 | 480 | _RESOURCE = SimulationRunDataItem |
430 | 481 |
|
| 482 | + def to_pandas( # type: ignore [override] |
| 483 | + self, |
| 484 | + ) -> pandas.DataFrame: |
| 485 | + """Convert the simulation run data list to a pandas DataFrame. |
| 486 | +
|
| 487 | + Returns: |
| 488 | + pandas.DataFrame: The dataframe. |
| 489 | + """ |
| 490 | + pd = local_import("pandas") |
| 491 | + return pd.concat([item.to_pandas() for item in self.data], ignore_index=True) |
| 492 | + |
431 | 493 |
|
432 | 494 | class SimulationRunWriteList(CogniteResourceList[SimulationRunWrite], ExternalIDTransformerMixin): |
433 | 495 | _RESOURCE = SimulationRunWrite |
|
0 commit comments