diff --git a/src/ansys/sherlock/core/errors.py b/src/ansys/sherlock/core/errors.py index 414690bfe..2e58acf46 100644 --- a/src/ansys/sherlock/core/errors.py +++ b/src/ansys/sherlock/core/errors.py @@ -909,3 +909,20 @@ def str_itr(self): assert self.error_array is None return [f"Update part from AVL error: {self.message}"] + + +class SherlockListThermalMapsError(Exception): + """Contains the errors raised when thermal map files for a project cannot be listed.""" + + def __init__(self, message=None, error_array=None): + """Initialize error message.""" + self.message = message + self.error_array = error_array + + def str_itr(self): + """Format error message.""" + if self.message is None: + return [f"List thermal maps error: {error}" for error in self.error_array] + + assert self.error_array is None + return [f"List thermal maps error: {self.message}"] diff --git a/src/ansys/sherlock/core/project.py b/src/ansys/sherlock/core/project.py index 9e712931b..bdab3b4ec 100644 --- a/src/ansys/sherlock/core/project.py +++ b/src/ansys/sherlock/core/project.py @@ -21,6 +21,7 @@ SherlockImportODBError, SherlockListCCAsError, SherlockListStrainMapsError, + SherlockListThermalMapsError, ) from ansys.sherlock.core.grpc_stub import GrpcStub @@ -763,3 +764,61 @@ def add_project(self, project_name: str, project_category: str, project_descript raise SherlockAddProjectError(return_code.message) return return_code.value + + def list_thermal_maps(self, project, cca_names=None): + """List the thermal map files and their type assigned to each CCA of given CCAs. + + Parameters + ---------- + project: str + Name of the Sherlock project. + cca_names : List of str, optional + List of CCA names to provide thermal maps for. The default is ``None``, + in which case all CCAs in the project are returned. + + Returns + ------- + list + All thermal map files or thermal map files and their type for the specified CCAs. + + Examples + -------- + >>> from ansys.sherlock.core.launcher import launch_sherlock + >>> sherlock = launch_sherlock() + >>> thermal_maps = sherlock.project.list_thermal_maps( + "AssemblyTutorial", + ["Main Board","Power Module"] + ) + """ + try: + if project == "": + raise SherlockListThermalMapsError(message="Project name is invalid.") + + if cca_names is not None and type(cca_names) is not list: + raise SherlockListThermalMapsError(message="cca_names is not a list.") + + if not self._is_connection_up(): + LOG.error("There is no connection to a gRPC service.") + return + + request = SherlockProjectService_pb2.ListThermalMapsRequest(project=project) + + if cca_names is not None: + for cca_name in cca_names: + request.cca.append(cca_name) + + response = self.stub.listThermalMaps(request) + + return_code = response.returnCode + + if return_code.value == -1: + if return_code.message == "": + raise SherlockListThermalMapsError(error_array=response.errors) + + raise SherlockListThermalMapsError(message=return_code.message) + + except SherlockListThermalMapsError as e: + LOG.error(str(e)) + raise e + + return response.ccaThermalMaps diff --git a/tests/test_project.py b/tests/test_project.py index c8d0ccaef..5c7a09a7c 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -18,6 +18,7 @@ SherlockImportODBError, SherlockListCCAsError, SherlockListStrainMapsError, + SherlockListThermalMapsError, ) from ansys.sherlock.core.project import Project @@ -38,6 +39,7 @@ def test_all(): helper_test_list_ccas(project) helper_test_add_cca(project) helper_test_list_strain_maps(project) + helper_test_list_thermal_maps(project) project_name = None try: project_name = helper_test_add_project(project) @@ -598,6 +600,75 @@ def helper_test_add_project(project): pytest.fail(str(e)) +def helper_test_list_thermal_maps(project): + """Test list_thermal_maps API""" + + expected_cca_name = "Main Board" + expected_file_names = [ + "Thermal Map.xlsx", + "Thermal Map.tmap", + "Thermal Image.jpg", + "Thermal Map.csv", + ] + expected_file_types = [ + "Thermal Map (Excel)", + "Icepak Thermal Map (TMAP)", + "Thermal Map (Image)", + "Thermal Map (CSV)", + ] + + try: + project.list_thermal_maps("") + pytest.fail("No exception raised when using an invalid parameter") + except SherlockListThermalMapsError as e: + assert str(e.str_itr()) == "['List thermal maps error: Project name is invalid.']" + + try: + project.list_thermal_maps("Tutorial Project", "Not a list") + pytest.fail("No exception raised when using an invalid parameter") + except SherlockListThermalMapsError as e: + assert str(e.str_itr()) == "['List thermal maps error: cca_names is not a list.']" + + if project._is_connection_up(): + try: + project.list_thermal_maps("AssemblyTutorial", ["CCA name that doesn't exist"]) + pytest.fail("No exception raised when using an invalid parameter") + except Exception as e: + assert type(e) == SherlockListThermalMapsError + + try: + thermal_maps = project.list_thermal_maps("Tutorial Project", [expected_cca_name]) + assert len(thermal_maps) == 1 + thermal_map = thermal_maps[0] + assert thermal_map.ccaName == expected_cca_name + assert len(thermal_map.thermalMaps) == len(expected_file_names) + + for i, thermal_map_info in enumerate(thermal_map.thermalMaps): + assert expected_file_names[i] == thermal_map_info.fileName + assert expected_file_types[i] == thermal_map_info.fileType + except SherlockListThermalMapsError as e: + pytest.fail(str(e.str_itr())) + + try: + thermal_maps = project.list_thermal_maps("Tutorial Project") + + for thermal_map in thermal_maps: + assert hasattr(thermal_map, "ccaName") and hasattr(thermal_map, "thermalMaps") + + if thermal_map.thermalMaps: + for i, thermal_map_info in enumerate(thermal_map.thermalMaps): + assert hasattr(thermal_map_info, "fileName") and hasattr( + thermal_map_info, "fileType" + ) + + if thermal_map.ccaName == expected_cca_name: + assert expected_file_names[i] == thermal_map_info.fileName + assert expected_file_types[i] == thermal_map_info.fileType + + except SherlockListThermalMapsError as e: + pytest.fail(str(e.str_itr())) + + def clean_up_after_add(project, project_name): if project_name is not None: project.delete_project(project_name)