]> SALOME platform Git repositories - modules/parametric.git/blob - src/salome/parametric/study.py
Salome HOME
When generating batch job, use Save Study instead of SaveAs when possible to avoid...
[modules/parametric.git] / src / salome / parametric / study.py
1 # Copyright (C) 2012 EDF
2 #
3 # This file is part of SALOME PARAMETRIC module.
4 #
5 # SALOME PARAMETRIC module is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Lesser 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 PARAMETRIC 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 Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public License
16 # along with SALOME PARAMETRIC module.  If not, see <http://www.gnu.org/licenses/>.
17
18 import cPickle
19 import numpy
20
21 from salome.kernel.studyedit import getStudyEditor
22
23 # module constants
24 MODULE_NAME = "PARAMETRIC"
25
26 COMPONENT_NAME = "Parametric"
27 COMPONENT_ICON = "PARAMETRIC_small.png"
28
29 PARAM_STUDY_ICON = "param_study.png"
30 PARAM_STUDY_TYPE_ID = 1
31
32 class ParametricStudyEditor:
33   """
34   This class provides utility methods to edit the component "Parametric" in
35   the study. The parameter `studyId` defines the ID of the study to edit. If
36   it is :const:`None`, the edited study will be the current study.
37   """
38   def __init__(self, study_id = None):
39     self.editor = getStudyEditor(study_id)
40     self.param_comp = None
41
42   def find_or_create_param_component(self):
43     """
44     Find the component "Parametric" or create it if none is found
45     :return: the SComponent found or created.
46     """
47     if self.param_comp is None:
48       self.param_comp = self.editor.findOrCreateComponent(MODULE_NAME, COMPONENT_NAME, COMPONENT_ICON)
49     return self.param_comp
50
51   def add_parametric_study(self, parametric_study):
52     self.find_or_create_param_component()
53     sobj = self.editor.createItem(self.param_comp, "__NEW_STUDY__")
54     self._set_sobj(parametric_study, sobj)
55
56   def set_parametric_study_at_entry(self, parametric_study, entry):
57     sobj = self.editor.study.FindObjectID(entry)
58     self._set_sobj(parametric_study, sobj)
59
60   def _set_sobj(self, parametric_study, sobj):
61     self.editor.setItem(sobj,
62                         name = parametric_study.name,
63                         icon = PARAM_STUDY_ICON,
64                         typeId = PARAM_STUDY_TYPE_ID)
65     attr = self.editor.builder.FindOrCreateAttribute(sobj, "AttributeParameter")
66     attr.SetString("study", cPickle.dumps(parametric_study))
67
68   def get_parametric_study(self, entry):
69     sobj = self.editor.study.FindObjectID(entry)
70     if sobj is None or self.editor.getTypeId(sobj) != PARAM_STUDY_TYPE_ID:
71       raise Exception("No valid parametric study at entry %s" % entry)
72     found, attr = self.editor.builder.FindAttribute(sobj, "AttributeParameter")
73     if not found:
74       raise Exception("No valid parametric study at entry %s" % entry)
75     param_study = cPickle.loads(attr.GetString("study"))
76     param_study.entry = entry
77     return param_study
78
79
80 class ParametricVariable:
81
82   def __init__(self, name, minval = None, maxval = None, step = None):
83     self.name = name
84     self.min = minval
85     self.max = maxval
86     self.step = step
87
88
89 class ParametricStudy:
90   
91   SALOME_COMPONENT = 0
92   PYTHON_SCRIPT = 1
93
94   def __init__(self):
95     self.input_vars = []
96     self.output_vars = []
97     self.solver_code_type = ParametricStudy.SALOME_COMPONENT
98     self.salome_component_name = None
99     self.solver_case_entry = None
100     self.python_script = None
101     self.name = None
102     self.nb_parallel_computations = 1
103     self.data = None
104     self.datasize = 0
105     self._value_dict = None
106     self.entry = None
107
108   def add_input_variable(self, var):
109     self.input_vars.append(var)
110
111   def add_output_variable(self, varname):
112     self.output_vars.append(varname)
113
114   def generate_data(self):
115     self.data = {}
116     self.datasize = 0
117     for var in self.input_vars:
118       self.data[var.name] = []
119     self._value_dict = {}
120     self._fill_data(self.input_vars)
121
122   def _fill_data(self, remaining_var_list):
123     if len(remaining_var_list) == 0:
124       for (name, value) in self._value_dict.iteritems():
125         self.data[name].append(value)
126       self.datasize += 1
127     else:
128       var = remaining_var_list[0]
129       next_var_list = remaining_var_list[1:]
130       for value in numpy.arange(var.min, var.max, var.step):
131         self._value_dict[var.name] = value
132         self._fill_data(next_var_list)
133
134   def export_data_to_csv_file(self, filepath, sep = ","):
135     if self.data is None:
136       raise Exception("Parametric study does not contain any data")
137     f = open(filepath, "w")
138     
139     # Header
140     for invar in self.input_vars:
141       f.write(invar.name + sep)
142     for outvarname in self.output_vars:
143       f.write(outvarname + sep)
144     f.write("Error message\n")
145     
146     # Data
147     for i in range(self.datasize):
148       for invar in self.input_vars:
149         f.write(self._format_value(self.data[invar.name][i]) + sep)
150       for outvarname in self.output_vars:
151         f.write(self._format_value(self.data[outvarname][i]) + sep)
152       f.write(self._format_value(self.data["__ERROR_MESSAGE__"][i]) + "\n")
153
154     f.close()
155
156   def _format_value(self, value):
157     if value is None:
158       val = ""
159     else:
160       val = unicode(value)
161     return val.encode("utf-8")