1
- import os , itertools , shutil , re , string
1
+ import os , itertools , shutil , re , string , sys
2
2
import numpy as np
3
3
4
4
def dict_product (dicts ):
@@ -11,9 +11,9 @@ def dict_product(dicts):
11
11
eg: from: {'a': [0,1], 'b': [2,3], 'c': [4]}
12
12
13
13
outputs: [{'a': 0, 'b': 2, 'c': 4},
14
- {'a': 0, 'b': 3, 'c': 4},
15
- {'a': 1, 'b': 2, 'c': 4},
16
- {'a': 1, 'b': 3, 'c': 4}]
14
+ {'a': 0, 'b': 3, 'c': 4},
15
+ {'a': 1, 'b': 2, 'c': 4},
16
+ {'a': 1, 'b': 3, 'c': 4}]
17
17
"""
18
18
# from http://stackoverflow.com/questions/5228158/cartesian-product-of-a-dictionary-of-lists
19
19
return (dict (itertools .izip (dicts , x )) for x in itertools .product (* dicts .itervalues ()))
@@ -61,31 +61,46 @@ def input_directory_builder(folder_name, base_path):
61
61
finally :
62
62
os .chdir (calling_dir )
63
63
64
- def build_input_files (base_file , params , base_path = 'input_files' , test_name = '' ):
65
- """
66
- build_input_files(base_file, params, base_path = 'input_files')
67
-
68
- takes a 'well-formated' input file, a set of parameters in a dict,
69
- and outputs a directory structure with the properly formated input files
70
- created in them.
71
- """
72
- calling_dir = os .getcwd ()
73
-
74
- with open (base_file , 'r' ) as f :
75
- txt = f .read ()
76
-
77
- for value_set in dict_builder (params , test_name = test_name ):
78
- tmp_txt = txt
79
- # make a directory
80
- input_directory_builder (value_set ['TITLE' ], base_path )
81
- # populate the input file
82
- tmp_txt = tmp_txt .format (** value_set )
83
- # create the file name
84
- fname = os .path .join (calling_dir , base_path ,
85
- value_set ['TITLE' ], value_set ['TITLE' ]+ '.fds' )
86
- # write the input file to the directory
87
- with open (fname , 'w' ) as f :
88
- f .write (str (tmp_txt ))
64
+ def build_input_files (filename , base_path = 'input_files' , out = sys .stdout ):
65
+ """
66
+ build_input_files(filename, base_path = 'input_files')
67
+
68
+ takes a 'well-formated' input fileand outputs a
69
+ directory structure with the properly formated input files
70
+ created in them.
71
+ """
72
+ calling_dir = os .getcwd ()
73
+
74
+ # I'm doing this because I need it later
75
+ file_path , file_name = os .path .split (filename )
76
+
77
+ with open (filename , 'r' ) as f :
78
+ txt = f .read ()
79
+
80
+ formatted_trials , logfile , out = FDSa_parser (filename , base_path , out )
81
+
82
+ for i , value_set in enumerate (formatted_trials ):
83
+ tmp_txt = txt
84
+ # make a directory
85
+ case_name = 'case_' + int2base (i , 26 )
86
+ # FDS uses uppercase reseved keywords, and so will we
87
+ value_set ['TITLE' ] = case_name
88
+ input_directory_builder (case_name , base_path )
89
+ # populate the input file
90
+ tmp_txt = tmp_txt .format (** value_set )
91
+ # create the file name
92
+ fname = os .path .join (calling_dir , base_path ,
93
+ case_name , case_name + '.fds' )
94
+ # write the input file to the directory
95
+ with open (fname , 'w' ) as f :
96
+ f .write (str (tmp_txt ))
97
+
98
+ log_path_name = os .path .join (calling_dir , base_path , file_name [:- 4 ] + '.log' )
99
+
100
+ with open (log_path_name , 'a' ) as f :
101
+ f .write (logfile )
102
+
103
+ return out
89
104
90
105
def input_file_paths (base_path ):
91
106
"""
@@ -96,18 +111,17 @@ def input_file_paths(base_path):
96
111
"""
97
112
paths = []
98
113
for dirpath , dirnames , filenames in os .walk (base_path ):
99
- for onefile in filenames :
100
- # the following if statement is due to OS X .DsStore bullshit...
101
- if not onefile .startswith ('.DS' ):
102
- #paths.append(dirpath+"/"+onefile)
103
- paths .append (os .path .join (os .getcwd (), dirpath , onefile ))
114
+ for onefile in filenames :
115
+ # the following if statement is due to OS X .DsStore bullshit...
116
+ if not onefile .startswith ('.DS' ):
117
+ #paths.append(dirpath+"/"+onefile)
118
+ paths .append (os .path .join (os .getcwd (), dirpath , onefile ))
104
119
return paths
105
-
106
- def int2base (x , base ):
120
+
121
+ def int2base (x , base = 26 ):
107
122
"""
108
- int2base(x, base) takes an integer and returns the base representation in
109
- alphabetical order like one would see in excel column labeling
110
- (0 -> a, 27 -> ab in base 26)
123
+ int2base(x, base) takes an integer and returns the base 26 representation (defualt) in letters
124
+ like one would see in excel column labeling (0 -> a, 63 -> cl)
111
125
112
126
based on https://stackoverflow.com/questions/2267362
113
127
"""
@@ -130,4 +144,91 @@ def int2base(x, base):
130
144
digits .append ('-' )
131
145
digits .reverse ()
132
146
#
133
- return '' .join (digits )[::- 1 ]
147
+ return '' .join (digits )[::- 1 ]
148
+
149
+ def FDSa_parser (filename , base_path , out = sys .stdout ):
150
+ """
151
+ FDSa_parser(filename, base_path, out) takes in an augmented FDS file and determines how many parametric will be created from that
152
+ it also parses the augmented syntax to build the dictionary used in generating the specific case FDS files
153
+ """
154
+ # I'm doing this because I need it later
155
+ file_path , file_name = os .path .split (filename )
156
+ # open the augmented fds input file
157
+ with open (os .path .join (file_path , file_name ), 'r' ) as f :
158
+ read_data = f .read ()
159
+
160
+ regex_find = re .findall ('\{*[0-9a-zA-Z_:,.\s]*\}' , read_data )
161
+
162
+ params = []
163
+ params_raw = []
164
+
165
+ for param in regex_find :
166
+ params_raw .append (param .strip ('{}' ))
167
+ params .append (param .strip ('{}' ).split ('SWEEP' ))
168
+
169
+ params = [item .strip () for sublist in params for item in sublist ]
170
+
171
+ # if length of params is non-even that means I can assume a title parameter
172
+ # double check with the occurance of FDSa 'reserved' keywords 'title' or 'name'
173
+ if (len (params ) % 2 != 0 ) and (params [0 ].lower () == ('title' )):
174
+ # based on the following idiom
175
+ # https://stackoverflow.com/questions/3303213
176
+ param_dict = dict (zip (params [1 ::2 ], params [2 ::2 ]))
177
+ param_list = [params [0 ]]
178
+ param_list .extend (params [1 ::2 ])
179
+ params_name_dict = dict (zip (param_list , params_raw ))
180
+ else :
181
+ param_dict = dict (zip (params [::2 ], params [1 ::2 ]))
182
+ param_list = params [::2 ]
183
+ params_name_dict = dict (zip (param_list , params_raw ))
184
+
185
+
186
+ out .write ('-' * 10 + 'ParFDS input file interpreter' + '-' * 10 + '\n ' )
187
+ out .write ('the following are the keys and values' + '\n ' )
188
+ out .write ('seen in ' + filename + '\n ' )
189
+
190
+ permutations = 1
191
+ for key , value in param_dict .iteritems ():
192
+ value_str = 'np.linspace(' + value .replace ("'" , "" ) + ')'
193
+ param_dict [key ] = eval (value_str , {"__builtins__" :None },
194
+ {"np" : np ,"np.linspace" :np .linspace ,"np.logspace" :np .logspace })
195
+ value_split = value .split (',' )
196
+
197
+ assert float (value_split [2 ]) >= 1 , "the number of steps is not an integer: %r" % float (value_split [2 ].strip ())
198
+
199
+ permutations *= int (value_split [2 ])
200
+
201
+ out .write (key + ' varied between ' + str (value_split [0 ]) + \
202
+ ' and ' + str (value_split [1 ]) + ' in ' + str (value_split [2 ]) + ' step(s)' + '\n ' )
203
+
204
+ out .write ('-' * 10 + ' ' * 10 + '-' * 10 + ' ' * 10 + '-' * 10 + '\n ' )
205
+ out .write ('for a total of ' + str (permutations ) + ' trials' + '\n ' )
206
+
207
+ trials = dict_product (param_dict )
208
+
209
+ logfile = 'There are a total of ' + str (permutations ) + ' trials \n '
210
+ newline = '\n ' # for the newlines
211
+ formatted_trials = []
212
+
213
+ base = 26
214
+ for i , v in enumerate (trials ):
215
+ case_temp = 'case ' + int2base (i , base ) + ': '
216
+ logfile += case_temp
217
+ out .write (case_temp ,)
218
+ for key , val in v .iteritems ():
219
+ kv_temp = key + ' ' + str (round (val , 2 )) + ' '
220
+ logfile += kv_temp + ' '
221
+ out .write (kv_temp ,)
222
+ out .write (newline )
223
+ logfile += newline
224
+ formatted_trials .append ({params_name_dict [key ] : round (value , 3 ) for key , value in v .items () })
225
+ # write the augmented fds log file
226
+
227
+ """
228
+ >>> important_dict = {'x':1, 'y':2, 'z':3}
229
+ >>> name_replacer = {'x':'a', 'y':'b', 'z':'c'}
230
+ >>> {name_replacer[key] : value for key, value in important_dict.items() }
231
+ {'a': 1, 'b': 2, 'c': 3}
232
+ """
233
+ # out.getvalue().strip()
234
+ return formatted_trials , logfile , out
0 commit comments