Salome HOME
Documentation and models update, pst4mod
[modules/adao.git] / src / daComposant / daNumerics / pst4mod / modelica_libraries / write_in_dsin.py
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (C) 2016-2024 EDF R&D
4 #
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License.
9 #
10 # This library 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 GNU
13 # Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18
19 from os import path,getcwd,rename,remove,replace
20 from sys import exit
21
22 class Write_in_dsin:
23     """
24     This class has been written to change dsin.txt (a file that is generated by
25     Dymola and that contains the values of the parameters of a simulation). Changing
26     the values of parameters in dsin.txt lets the user launch a different simulation.
27     This can also be done with method modelicares.exps.write_params.
28     The present class has been written in case in order to make it possible to
29     change the parameters values in dsin.txt without importing modelicares.
30
31     New features introduced 02/2019:
32     - possibility of change a dsin.txt type file having a different name
33     - by default, the previous use of this module should remain unchanged
34
35     New features introduced 09/2022:
36     - script adapted to the situations in which the variables are described on
37       a single line (instead of 2 traditionnally) in the dsin file
38     """
39
40     def __init__(self,dict_inputs,filedir=path.abspath(getcwd()),dsin_name='dsin.txt',old_file_name='dsin_old.txt',new_file_name='dsin.txt'):
41         self.__dict_inputs = dict_inputs.copy() #this way the dictionary is not emptied
42         self.__filedir = filedir
43         self.__dsin_name = dsin_name
44         self.__old_file_name = old_file_name
45         self.__new_file_name = new_file_name
46         self.__maybe_par_dict = {}
47
48     @property
49     def dict_inputs(self):
50         """
51         Dictionary associating to each variable whose value has to be given to
52         dsin.txt (inputs + iteration variables if necessary) its value.
53         """
54         return self.__dict_inputs
55
56     @property
57     def dsin_name(self):
58         """
59         Name of the dsin.txt file to change, it might have a different name
60         """
61         return self.__dsin_name
62
63     @property
64     def maybe_par_dict(self):
65         """
66         List of variables to be changed which are not identified as 'parameter' in the dsin.txt.
67         """
68         return self.__maybe_par_dict
69
70     @property
71     def filedir(self):
72         """
73         Path of the directory in which the file dsin.txt is located.
74         The new version of this file will also be saved in this directory.
75         """
76         return self.__filedir
77
78     @property
79     def old_file_name(self):
80         """
81         The original file dsin.txt that is modified is saved under a name that can be chosen.
82         dsin_old.txt seems appropriate
83         """
84         return self.__old_file_name
85
86     @property
87     def new_file_name(self):
88         """
89         The new version of dsin.txt is given a name that can be chosen through
90         this attribute. In order to be able to launch a simulation, this name has
91         to be dsin.txt.
92         """
93         return self.__new_file_name
94
95 ########################################################################
96 #                            MAIN METHODS                              #
97 ########################################################################
98     def write_in_dsin(self):
99         """
100         Main method of this class.
101         This method creates a new dsin.txt file.
102         The original file is renamed 'dsin_old.txt'.
103         The new file is named 'dsin.txt'
104         """
105         #reading has value 1 while the part of the file currently being
106         #read is the part of the file in which the variables are given
107         #values. Only this part of the file has to be changed in order
108         #to change the parameters values.
109         reading=0
110         in_line1,in_line2=None,None
111         with open(path.join(self.filedir,self.dsin_name),'r') as lines:
112             with open(path.join(self.filedir,'dsin_tmp.txt'),'w') as output:
113                 for line in lines:
114                     if reading==1 and len(line)>1 and not line[0] == '#':
115                         if in_line1 == None:
116                             in_line1 = line
117                         else:
118                             in_line2 = line
119                     else:
120                         output.write(line)
121
122                     if 'initialValue' in line:
123                         reading=1
124                     #If the structure of file dsin.txt generated by
125                     #Dymola was changed, the following line could have
126                     #to be changed
127                     if '# Matrix with 6 columns' in line:
128                         reading=0
129
130                     # - START - Take into account the possibility of handling dsin.txt files with one single line for describin variables
131                     if in_line1 != None and len(in_line1.split())>4 and reading==1: #Case where there is one line per parameter rather than two in the dsin file
132
133                         line_list = in_line1.split() #The variable name may contain spaces...
134                         valtype1,val,elem13,elem14,valtype2,elem16,elem17 = line_list[0],line_list[1],line_list[2],line_list[3],line_list[4],line_list[5],line_list[6]
135
136                         var = ''
137                         for reste in line_list[7:]:
138                             var = var + reste
139
140                         if var in self.dict_inputs.keys():
141                             val = self.dict_inputs[var]
142                             #The format is not the same depending on the length of some variables
143                             if len(str(val))<=7 and len(elem14)<=7:
144                                 txt ='{elem11:>3} {elem12:>7} {elem13:>18} {elem14:>7} {elem15:>18} {elem16:>5} {elem17:>3} {elem18:<}\n'
145                             if len(str(val))<=7 and len(elem14)>7:
146                                 txt ='{elem11:>3} {elem12:>7} {elem13:>18} {elem14:>23} {elem15:>2} {elem16:>5} {elem17:>3} {elem18:<}\n'
147                             if len(str(val))>7 and len(elem14)<=7:
148                                 txt ='{elem11:>3} {elem12:>23} {elem13:>2} {elem14:>7} {elem15:>18} {elem16:>5} {elem17:>3} {elem18:<}\n'
149                             if len(str(val))>7 and len(elem14)>7:
150                                 txt ='{elem11:>3} {elem12:>23} {elem13:>2} {elem14:>23} {elem15:>2} {elem16:>5} {elem17:>3} {elem18:<}\n'
151
152                             out_line = txt.format(elem11=valtype1,elem12=val,elem13=elem13,elem14=elem14,elem15=valtype2,elem16=elem16,elem17=elem17,elem18=var)
153
154                             if valtype1 != '-1' or (valtype2 != '1' and valtype2 != '2') : #(0,6) combination looks like the only case to look into
155                                 self.__maybe_par_dict[var] = val
156                             self.__dict_inputs.pop(var) #Deleting the variable from the list of 'to do'
157
158                         else:
159                             out_line = in_line1
160
161                         output.write(out_line)
162
163                         in_line1=None
164                         # - END - Take into account the possibility of handling dsin.txt files with one single line for describin variables
165
166
167                     elif in_line2 != None:
168                         valtype1,val,elem13,elem14 = in_line1.split()
169                         #valtype2,elem22,elem23,var = in_line2.split()
170                         line2_list = in_line2.split() #The variable name may contain spaces...
171                         valtype2 = line2_list[0]
172                         var = ''
173                         for reste in line2_list[3:]:
174                             var = var + reste
175
176                         if var in self.dict_inputs.keys():
177                             val = self.dict_inputs[var]
178                             out_line1 = '{elem11:>3} {elem12:>23} {elem13:23} {elem14:>23}\n'.format(elem11=valtype1,elem12=val,elem13=elem13,elem14=elem14)
179                             if valtype1 != '-1' or (valtype2 != '1' and valtype2 != '2') : #(0,6) combination looks like the only case to look into
180                                 self.__maybe_par_dict[var] = val
181                             self.__dict_inputs.pop(var) #Deleting the variable from the list of 'to do'
182                         else:
183                             out_line1 = in_line1
184                         out_line2 = in_line2
185
186                         output.write(out_line1)
187                         output.write(out_line2)
188
189                         in_line1,in_line2=None,None
190
191 #       rename(path.join(self.filedir,'dsin.txt'),path.join(self.filedir,self.old_file_name))
192         replace(path.join(self.filedir,self.dsin_name),path.join(self.filedir,self.old_file_name)) # resolve the conflit with old version
193
194         if len(self.dict_inputs) > 0 : #At least one variable was not changed
195             remove(path.join(self.filedir,'dsin_tmp.txt'))
196             raise KeyError("The following variables were not found in dsin.txt:\n %s" % list(self.dict_inputs.keys()))
197
198         rename(path.join(self.filedir,'dsin_tmp.txt'),path.join(self.filedir,self.new_file_name))
199
200 if __name__ == '__main__':
201     print('\n  AUTODIAGNOSTIC\n  ==============\n')