Coverage for steam_pysigma\MainPySIGMA.py: 47%
59 statements
« prev ^ index » next coverage.py v7.4.3, created at 2024-12-16 17:09 +0100
« prev ^ index » next coverage.py v7.4.3, created at 2024-12-16 17:09 +0100
1# STEAM PySigma is a python wrapper of STEAM-SIGMA written in Java.
2# Copyright (C) 2023, CERN, Switzerland. All rights reserved.
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, version 3 of the License.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program. If not, see <https://www.gnu.org/licenses/>.
16import os
17from pathlib import Path
18import logging
19import subprocess
21from steam_pysigma.comsol.BuildComsolModel import BuildComsolModel
22from steam_pysigma.data import DataPySIGMA as dS
23from steam_pysigma.utils.Utils import get_user_settings, read_data_from_yaml
24from steam_pysigma.utils.Utils import make_folder_if_not_existing
26class MainPySIGMA:
27 """
28 Class to generate SIGMA models
29 """
31 def __init__(self, model_folder: str = None, verbose: bool = False):
32 """
34 :param input_file_path: path to input yaml file
35 :param input_coordinates_path: path to file with coordinates to evaluate B_field
36 :param model_folder: Output path of java files and mph model.
37 :param path_to_results: location of comsol-generated results
38 :param verbose:
39 """
41 logger = logging.getLogger()
42 if verbose:
43 logger.setLevel(logging.INFO)
44 else:
45 logger.setLevel(logging.DEBUG)
47 self.model_folder = model_folder
48 make_folder_if_not_existing(self.model_folder)
50 def build(self, input_yaml_file_path: str = None, input_coordinates_path=None, results_folder_name=None, settings=None):
51 """
52 Triggers building of Comsol model
53 """
54 dm = read_data_from_yaml(input_yaml_file_path, dS.DataPySIGMA)
55 input_folder_path = os.path.dirname(input_yaml_file_path)
56 sdm = read_data_from_yaml(f'{os.path.splitext(input_yaml_file_path)[0]}.set', dS.MultipoleSettings)
57 roxie_data = read_data_from_yaml(f'{os.path.splitext(input_yaml_file_path)[0]}.geom', dS.SIGMAGeometry)
58 bh_curve_database = Path(input_folder_path, dm.Sources.bh_curve_source).resolve()
59 if not os.path.exists(bh_curve_database):
60 raise Exception(f'Path to bh_curve_source specified in the input file {input_yaml_file_path} is: {bh_curve_database}, but it does not exist!')
61 if results_folder_name:
62 path_to_results = os.path.join(self.model_folder, results_folder_name)
63 else:
64 path_to_results = self.model_folder
65 make_folder_if_not_existing(path_to_results)
66 if not settings:
67 settings_folder = os.path.join(Path(__file__).parent.parent, 'tests')
68 settings = get_user_settings(settings_folder)
69 BuildComsolModel(model_data=dm, input_conductor_params=sdm, settings=settings,
70 output_path=self.model_folder, path_to_results=path_to_results,
71 input_coordinates_path=input_coordinates_path, roxie_data=roxie_data,
72 bh_curve_database=bh_curve_database)
74 def run_pysigma(self, magnet_name):
75 # Establish necessary paths
76 batch_file_path = os.path.join(self.model_folder, f"{magnet_name}_Model_Compile_and_Open.bat")
77 print(f'Running Comsol model via: {batch_file_path}')
78 current_path = os.getcwd()
79 os.chdir(self.model_folder) # must change path to the folder with .bat file otherwise it does not work
80 proc = subprocess.Popen([batch_file_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE,
81 universal_newlines=True)
82 (stdout, stderr) = proc.communicate()
83 log_file_path = os.path.join(self.model_folder, "log_bat_file.txt")
84 error = False
85 if proc.returncode != 0:
86 print(stderr)
87 raise ValueError(
88 f"Batch file throws an error, COMSOL model could not be completed! Review error at {log_file_path}.")
89 else:
90 print(stdout)
91 error_lines = []
92 for line in stdout.split('\n'):
93 if "error" in line.lower():
94 error = True
95 if error:
96 error_lines.append(line)
97 with open(log_file_path, 'w') as logfile:
98 logfile.write(stdout)
99 os.chdir(current_path)
100 if error:
101 # Additional code to format error_lines into a readable message
102 error_message = '\n'.join(error_lines)
103 error_message = error_message[:200] # Limit error_message to 200 characters
104 raise ValueError(
105 f"Batch file throws an error, COMSOL model could not be completed! Error message:\n{error_message}...\nReview full log at {log_file_path}.")
106 else:
107 print(f"Running batch file passes! See log file at {log_file_path}.")