Salome HOME
f045f9b77d0a6d93d4b37bc5a0806cfc50280939
[modules/hydrosolver.git] / src / salome_hydro / study.py
1 #  Copyright (C) 2012-2013 EDF
2 #
3 #  This file is part of SALOME HYDRO module.
4 #
5 #  SALOME HYDRO module is free software: you can redistribute it and/or modify
6 #  it under the terms of the GNU General Public License as published by
7 #  the Free Software Foundation, either version 3 of the License, or
8 #  (at your option) any later version.
9 #
10 #  SALOME HYDRO module is distributed in the hope that it will be useful,
11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 #  GNU General Public License for more details.
14 #
15 #  You should have received a copy of the GNU General Public License
16 #  along with SALOME HYDRO module.  If not, see <http://www.gnu.org/licenses/>.
17
18 import os
19 import types
20
21 from salome.kernel.studyedit import getStudyEditor
22 from salome.kernel.parametric import study_exchange_vars
23
24 import HYDROSOLVER_ORB
25
26 # module constants
27 MODULE_NAME = "HYDROSOLVER"
28
29 COMPONENT_NAME = "HydroSolver"
30 COMPONENT_ICON = "HYDRO_small.png"
31
32 MASCARET_FILE_TYPE = "MASCARET_EFICAS_FILE"
33 MASCARET_ICON = "case1d.png"
34 MASCARET_CASE_TYPE_ID = 1
35
36 VARS_ICON = "icon_variables.png"
37
38 LOG_ICON = "log.png"
39 LOG_TYPE_ID = 2
40
41 TELEMAC2D_FILE_TYPE = "TELEMAC2D_EFICAS_FILE"
42 TELEMAC2D_ICON = "case2d.png"
43 TELEMAC2D_CASE_TYPE_ID = 3
44
45 COUPLING1D2D_FILE_TYPE = "COUPLING1D2D_EFICAS_FILE"
46 COUPLING1D2D_ICON = "case_couplage.png"
47 COUPLING1D2D_CASE_TYPE_ID = 4
48
49 PYTEL_FILE_TYPE = "PYTEL_EFICAS_FILE"
50 PYTEL_ICON = "case_pytel.png"
51 PYTEL_CASE_TYPE_ID = 5
52
53 # Dictionary used to map Eficas parameters to Mascaret file types
54 mascaretFileTypeDict = {"FICHIER_ABAQUES" : "abaques",
55                         "FICHIER_DICO" : "dico",
56                         "FICHIER_CASIER" : "casier",
57                         "FICHIER_GEOMETRIE" : "geo",
58                         "FICHIER_LOI" : "loi",
59                         "FICHIER_MOT_CLE" : "cas",
60                         "LISTING" : "listing",
61                         "FICHIER_DAMOCLE" : "damocle",
62                         "RESULTAT" : "res",
63                         "LISTING_CASIER" : "listing_casier",
64                         "LISTING_LIAISON" : "listing_liaison",
65                         "RESULTAT_CASIER" : "res_casier",
66                         "RESULTAT_LIAISON" : "res_liaison"
67                        }
68
69 def jdc_to_dict(jdc, command_list):
70     """
71     This tricky function transforms a JdC with a single command into a
72     dictionary that can be used more easily from a Python context (thanks to
73     M. Courtois and G. Boulant).
74     """
75     context = {}
76     for command in command_list:
77         context[command] = _args_to_dict
78     exec "parameters = " + jdc.strip() in context
79     return context['parameters']
80
81 def _args_to_dict(**kwargs):
82     return kwargs
83
84 def get_jdc_dict_var_as_tuple(jdc_dict, varname):
85     if not jdc_dict.has_key(varname):
86         return tuple()
87     elif not isinstance(jdc_dict[varname], types.TupleType):
88         return (jdc_dict[varname],)
89     else:
90         return jdc_dict[varname]
91
92 class HydroStudyEditor:
93     """
94     This class provides utility methods to edit the component "Hydro" in
95     the study. The parameter `studyId` defines the ID of the study to edit. If
96     it is :const:`None`, the edited study will be the current study.
97     """
98     def __init__(self, studyId = None):
99         self.editor = getStudyEditor(studyId)
100         self.hydroComp = None
101
102     def find_or_create_hydro_component(self):
103         """
104         Find the component "Hydro" or create it if none is found
105         :return: the SComponent found or created.
106         """
107         if self.hydroComp is None:
108             self.hydroComp = self.editor.findOrCreateComponent(MODULE_NAME,
109                                                                COMPONENT_NAME,
110                                                                COMPONENT_ICON)
111         return self.hydroComp
112
113     def find_or_create_mascaret_case(self, filePath):
114         self.find_or_create_hydro_component()
115         itemName = os.path.splitext(os.path.basename(filePath))[0]
116         sobj = self.editor.findOrCreateItem(self.hydroComp,
117                                             name = itemName,
118                                             fileType = MASCARET_FILE_TYPE,
119                                             fileName = filePath,
120                                             icon = MASCARET_ICON,
121                                             comment = str(filePath),
122                                             typeId = MASCARET_CASE_TYPE_ID)
123         # Create "Variables" item
124         (file_list, lig_file, input_vars, output_vars) = self.get_mascaret_params_from_case(sobj)
125         input_varname_list = [var["NOM"].strip() for var in input_vars]
126         # Remove duplicates
127         input_varname_list = list(set(input_varname_list))
128         input_var_list = [study_exchange_vars.Variable(varname) for varname in input_varname_list]
129         output_var_list = [study_exchange_vars.Variable(var["NOM"].strip()) for var in output_vars]
130         exchange_vars = study_exchange_vars.ExchangeVariables(input_var_list, output_var_list)
131         study_exchange_vars.createSObjectForExchangeVariables(sobj, exchange_vars, icon = VARS_ICON)
132
133     def get_mascaret_params_from_case(self, sobj):
134         jdcpath = sobj.GetComment()
135         with open(jdcpath) as jdcfile:
136             jdc = jdcfile.read()
137         params = jdc_to_dict(jdc, ["MASCARET", "_F"])
138         input_vars = get_jdc_dict_var_as_tuple(params, "VARIABLE_ENTREE")
139         output_vars = get_jdc_dict_var_as_tuple(params, "VARIABLE_SORTIE")
140         file_list = []
141         for (key, value) in params.iteritems():
142             if key == "FICHIER_LOI":
143                 file_list += [HYDROSOLVER_ORB.MascaretFile(f["NOM"], mascaretFileTypeDict[key]) for f in value]
144             elif key != "FICHIER_LIG" and key != "VARIABLE_SORTIE" and key != "VARIABLE_ENTREE":
145                 file_list.append(HYDROSOLVER_ORB.MascaretFile(value, mascaretFileTypeDict[key]))
146         return (file_list, params["FICHIER_LIG"], input_vars, output_vars)
147
148     def add_results_to_mascaret_case(self, sobj, output_variables, output_values):
149         results = self.editor.createItem(sobj, "Results")
150         for (var, value) in zip(output_variables, output_values):
151             self.editor.createItem(results, var, comment = unicode(value))
152
153     def add_coupling_log(self, varname, log):
154         self.find_or_create_hydro_component()
155         sObj = self.editor.createItem(self.hydroComp,
156                                       name = varname,
157                                       icon = LOG_ICON,
158                                       typeId = LOG_TYPE_ID)
159         attr = self.editor.builder.FindOrCreateAttribute(sObj,
160                                                          "AttributeParameter")
161         attr.SetString("log", log)
162
163     def find_or_create_telemac2d_case(self, filePath):
164         self.find_or_create_hydro_component()
165         itemName = os.path.splitext(os.path.basename(filePath))[0]
166         sobj = self.editor.findOrCreateItem(self.hydroComp,
167                                             name = itemName,
168                                             fileType = TELEMAC2D_FILE_TYPE,
169                                             fileName = filePath,
170                                             icon = TELEMAC2D_ICON,
171                                             comment = str(filePath),
172                                             typeId = TELEMAC2D_CASE_TYPE_ID)
173
174     def generate_study_script(self, filePath):
175         """
176         Generating a python script from the eficas info
177         """
178         # Create "Python script" item
179         from TelApy.api.generate_study import generate_study_script
180         with open(filePath) as jdcfile:
181             jdc = jdcfile.read()
182         params = jdc_to_dict(jdc, ["TELEMAC2D", "_F"])
183
184         # Generation script string
185         python_script = generate_study_script(params)
186
187         # Computing name of the file (same as filePath)
188         file_dir, filename = os.path.split(filePath)
189         root, sfx = os.path.splitext(filename)
190         python_file = os.path.join(file_dir,root+".py")
191
192         # Writting to file
193         with open(python_file,'w') as pfile:
194             pfile.write(python_script)
195
196     def generate_study_yacs(self, filePath):
197         """
198         Generating a yacs file from the eficas info
199         """
200         # Create "Python script" item
201         from TelApy.api.generate_study import generate_study_yacs
202         with open(filePath) as jdcfile:
203             jdc = jdcfile.read()
204         params = jdc_to_dict(jdc, ["TELEMAC2D", "_F"])
205
206         # Generation YACS scheme
207         yacs_scheme = generate_study_yacs(params)
208
209         # Computing name of the file (same as filePath)
210         file_dir, filename = os.path.split(filePath)
211         root, sfx = os.path.splitext(filename)
212         yacs_file = os.path.join(file_dir,root+".xml")
213
214         # Writting to file
215         yacs_scheme.saveSchema(yacs_file)
216
217     def find_or_create_coupling1d2d_case(self, filePath):
218         self.find_or_create_hydro_component()
219         itemName = os.path.splitext(os.path.basename(filePath))[0]
220         sobj = self.editor.findOrCreateItem(self.hydroComp,
221                                             name = itemName,
222                                             fileType = COUPLING1D2D_FILE_TYPE,
223                                             fileName = filePath,
224                                             icon = COUPLING1D2D_ICON,
225                                             comment = str(filePath),
226                                             typeId = COUPLING1D2D_CASE_TYPE_ID)
227
228     def find_or_create_pytel_case(self, filePath):
229         self.find_or_create_hydro_component()
230         itemName = os.path.splitext(os.path.basename(filePath))[0]
231         sobj = self.editor.findOrCreateItem(self.hydroComp,
232                                             name = itemName,
233                                             fileType = PYTEL_FILE_TYPE,
234                                             fileName = filePath,
235                                             icon = PYTEL_ICON,
236                                             comment = str(filePath),
237                                             typeId = PYTEL_CASE_TYPE_ID)