forked from e-dub/DesOptPy1
/
OptHis2HTML.py
378 lines (315 loc) · 17.3 KB
/
OptHis2HTML.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
# -*- coding: utf-8 -*-
'''
----------------------------------------------------------------------------------------------------
Title: OptHis2HTML.py
Units: Unitless
Date: December 07, 2015
Author: F. Wachter
Contributors: E.J. Wehrle
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
Description
----------------------------------------------------------------------------------------------------
Open the optimization history (the .cue and .bin file) and processes them into HTML format
during runtime so one can check the status and progress of the optimization.
----------------------------------------------------------------------------------------------------
To do and ideas
----------------------------------------------------------------------------------------------------
see DesOpt.py
'''
import csv
import glob
import os
import shutil
from time import localtime, strftime, time
import numpy as np
from pyOpt import History
from Normalize import normalize, denormalize
def OptHis2HTML(OptName, Alg, DesOptDir, xL, xU, DesVarNorm, inform, starttime, StatusDirectory=""):
# ----------------------------------------------------------------------------------------------------
# General calculations for the uppermost information table are computed like time running, algorithm
# name, optimization problem name etc.
# ----------------------------------------------------------------------------------------------------
StartTime = str(starttime)[0:10] + "000"
EndTime = ""
RefRate = '2000'
if inform != "Running":
EndTime = str(time())[0:10] + "000"
RefRate = '1000000'
Iteration = 'Iteration' # Label and Legends may be Iteration, Generation or Evaluations depending on Algorithm
if StatusDirectory == "": # Change the target directory for the status report files if the user wants to
StatusDirectory = DesOptDir
# Variables for the data extraction
pos_of_best_ind = [] # position of the best individual if a GA or ES is used as algorithm
fIter = [] # objective function array
xIter = [] # design vector array
gIter = [] # constraint vector array
# template_directory= DesOpt_Base + "/.DesOptPy/_OptStatusReport/" # directory with the html files etc.
template_directory = os.path.dirname(
os.path.realpath(__file__)) + "/StatusReportFiles/" # directory with the html files etc.
OptHist = History(OptName, "r") # open the history file generated by pyOpt or own algorithm
# read the obj fct, design and constraint vector values into the array
fAll = OptHist.read([0, -1], ["obj"])[0]["obj"]
xAll = OptHist.read([0, -1], ["x"])[0]["x"]
gAll = OptHist.read([0, -1], ["con"])[0]["con"]
# ----------------------------------------------------------------------------------------------------
# The next lines manipulate the data corresponding to the used algorithm. pyOpt Histories are different
# depending on the used algorithm
# ----------------------------------------------------------------------------------------------------
if Alg.name == "NLPQLP":
gAll = [x * -1 for x in gAll]
fGradIter = OptHist.read([0, -1], ["grad_obj"])[0]["grad_obj"]
if Alg.name == "COBYLA":
fIter = fAll
xIter = xAll
gIter = gAll
# If NSGA2 is used the best individual of a population is considered the objective fct, otherwise every
# individual would be shown in the graphs
elif Alg.name == "NSGA-II":
Iteration = 'Generation'
if inform == 0:
inform = 'Optimization terminated successfully'
PopSize = Alg.options['PopSize'][1]
for i in range(0, fAll.__len__() / PopSize): # Iteration trough the Populations
best_fitness = 9999999
max_violation_of_all_g = np.empty(PopSize)
max_violation_of_all_g.fill(99999999)
for u in range(0, PopSize): # Iteration trough the Individuals of the actual population
if np.max(gAll[i * PopSize + u]) < max_violation_of_all_g[u]:
max_violation_of_all_g[u] = np.max(gAll[i * PopSize + u])
pos_smallest_violation = np.argmin(max_violation_of_all_g)
# only not feasible designs, so choose the less violated one as best
if max_violation_of_all_g[pos_smallest_violation] > 0:
fIter.append(fAll[i * PopSize + pos_smallest_violation])
xIter.append(xAll[i * PopSize + pos_smallest_violation])
gIter.append(gAll[i * PopSize + pos_smallest_violation])
else: # find the best feasible one
# Iteration trough the Individuals of the actual population
for u in range(0, PopSize):
if np.max(fAll[i * PopSize + u]) < best_fitness:
if np.max(gAll[i * PopSize + u]) <= 0:
best_fitness = fAll[i * PopSize + u]
pos_of_best_ind = i * PopSize + u
fIter.append(fAll[pos_of_best_ind])
xIter.append(xAll[pos_of_best_ind])
gIter.append(gAll[pos_of_best_ind])
else:
fIter = [[]] * len(fGradIter)
xIter = [[]] * len(fGradIter)
gIter = [[]] * len(fGradIter)
for ii in range(len(fIter)):
Posdg = OptHist.cues["grad_con"][ii][0]
Posf = OptHist.cues["obj"][ii][0]
iii = 0
while Posdg > Posf:
iii = iii + 1
try:
Posf = OptHist.cues["obj"][iii][0]
except:
Posf = Posdg + 1
iii = iii - 1
fIter[ii] = fAll[iii]
xIter[ii] = xAll[iii]
gIter[ii] = gAll[iii]
if Alg.name != "NSGA-II":
if len(fGradIter) == 0: # first calculation
fIter = fAll
xIter = xAll
gIter = gAll
OptHist.close()
# convert the arrays to numpy arrays
fIter = np.asarray(fIter)
xIter = np.asarray(xIter)
gIter = np.asarray(gIter)
niter = len(fIter) - 1
# ----------------------------------------------------------------------------------------------------
# The design variables are normalized or denormalized so both can be displayed in the graphs and tables
# ----------------------------------------------------------------------------------------------------
if xIter.size != 0:
if DesVarNorm == False:
xIter_denormalized = np.zeros((niter + 1, len(xIter[0])))
for y in range(0, niter + 1):
xIter_denormalized[y] = xIter[y]
for y in range(0, niter + 1):
[xIter[y, :], xLnorm, xUnorm] = normalize(xIter_denormalized[y, :], xL, xU, "xLxU")
else:
xIter_denormalized = np.zeros((niter + 1, len(xIter[0])))
for y in range(0, niter + 1):
xIter_denormalized[y, :] = denormalize(xIter[y, :], xL, xU, DesVarNorm)
time_now = strftime("%Y-%b-%d %H:%M:%S", localtime()) # update the time for the information table
number_des_vars = "0"
number_constraints = "0"
# ----------------------------------------------------------------------------------------------------
# The .csv files are created and the first row is filled with the correct labels. Those .csv files
# are loaded by the javascript library. Afterwards the files are closed.
# ----------------------------------------------------------------------------------------------------
with open('objFct_maxCon.csv', 'wb') as csvfile:
datawriter = csv.writer(csvfile, dialect='excel')
datawriter.writerow(['Iteration', 'Objective function', 'Constraint'])
csvfile.close()
with open('desVarsNorm.csv', 'wb') as csvfile:
datawriter = csv.writer(csvfile, delimiter=',', escapechar=' ', quoting=csv.QUOTE_NONE)
labels = ['Iteration']
if xIter.size != 0:
for i in range(1, xIter.shape[1] + 1):
labels = labels + ['x' + str(i)]
datawriter.writerow(labels)
csvfile.close()
with open('desVars.csv', 'wb') as csvfile:
datawriter = csv.writer(csvfile, delimiter=',', escapechar=' ', quoting=csv.QUOTE_NONE)
labels = ['Iteration']
if xIter.size != 0:
for i in range(1, xIter.shape[1] + 1):
labels = labels + ['x' + str(i)]
datawriter.writerow(labels)
csvfile.close()
with open('constraints.csv', 'wb') as csvfile:
datawriter = csv.writer(csvfile, delimiter=',', escapechar=' ', quoting=csv.QUOTE_NONE)
labels = ['Iteration']
if gIter.size != 0:
for i in range(1, gIter.shape[1] + 1):
labels = labels + ['g' + str(i)]
datawriter.writerow(labels)
csvfile.close()
# ----------------------------------------------------------------------------------------------------
# Now the real data like obj fct value and constraint values are writen into the .csv files
# ----------------------------------------------------------------------------------------------------
# Objective function and maximum constraint values
for x in range(0, niter + 1):
with open('objFct_maxCon.csv', 'ab') as csvfile:
datawriter = csv.writer(csvfile, dialect='excel')
datawriter.writerow([x, str(float(fIter[x])), float(np.max(gIter[x]))])
csvfile.close()
# Normalized design variables
if xIter.size != 0:
for x in range(0, niter + 1):
datasets = str(xIter[x][:].tolist()).strip('[]')
with open('desVarsNorm.csv', 'ab') as csvfile:
datawriter = csv.writer(csvfile, dialect='excel', quotechar=' ')
datawriter.writerow([x, datasets])
csvfile.close()
# non normalized design variables
if xIter.size != 0:
for x in range(0, niter + 1):
datasets_denorm = str(xIter_denormalized[x][:].tolist()).strip('[]')
with open('desVars.csv', 'ab') as csvfile:
datawriter = csv.writer(csvfile, dialect='excel', quotechar=' ')
datawriter.writerow([x, datasets_denorm])
csvfile.close()
# constraint variables
if gIter.size != 0:
for x in range(0, niter + 1):
datasetsg = str(gIter[x][:].tolist()).strip('[]')
with open('constraints.csv', 'ab') as csvfile:
datawriter = csv.writer(csvfile, dialect='excel', quotechar=' ')
datawriter.writerow([x, datasetsg])
csvfile.close()
# ----------------------------------------------------------------------------------------------------
# The data for the graphs is generated, now follows the table generation routine
# ----------------------------------------------------------------------------------------------------
# Objective function table generation
ObjFct_table = "<td></td>"
if xIter.size != 0:
if gIter.size != 0:
for x in range(0, niter + 1):
ObjFct_table += "<tr>\n<td>" + str(x) + "</td>\n<td>" + str(round(fIter[x], 4)) + "</td>\n<td>" + str(
round(np.max(gIter[x]), 4)) + "</td>\n</tr>"
else:
for x in range(0, niter + 1):
ObjFct_table += "<tr>\n<td>" + str(x) + "</td>\n<td>" + str(
round(fIter[x], 4)) + "</td>\n<td> no constraints </td>\n</tr>"
# Design Variable table generation
DesVar_table = "<td></td>"
if xIter.size != 0:
number_des_vars = str(len(xIter[0]))
for x in range(0, len(xIter[0])):
DesVar_table += "<td>" + "x̂<sub>" + str(x + 1) + "</sub></td>" + "<td>" + "x<sub>" + str(
x + 1) + " </sub></td>"
for y in range(0, niter + 1):
DesVar_table += "<tr>\n<td>" + str(y) + "</td>"
for x in range(0, len(xIter[0])):
DesVar_table += "<td>" + str(round(xIter[y][x], 4)) + "</td><td>" + str(
round(xIter_denormalized[y][x], 4)) + "</td>"
DesVar_table += "</tr>"
# Constraint table generation
Constraint_table = "<td></td>"
if gIter.size != 0:
number_constraints = str(len(gIter[0]))
for x in range(0, len(gIter[0])):
Constraint_table += "<td>" + "g<sub>" + str(x + 1) + "</sub></td>"
for y in range(0, niter + 1):
Constraint_table += "<tr>\n<td>" + str(y) + "</td>"
for x in range(0, len(gIter[0])):
if (round(gIter[y][x], 4) > 0):
Constraint_table += "<td class=\"negativ\">" + str(round(gIter[y][x], 4)) + "</td>"
else:
Constraint_table += "<td class=\"positiv\">" + str(round(gIter[y][x], 4)) + "</td>"
Constraint_table += "</tr>"
# ----------------------------------------------------------------------------------------------------
# Everything is computed, now the html master template is opened and the placeholders are replaced
# with the right values
# ----------------------------------------------------------------------------------------------------
html = open(template_directory + '/initial.html', 'r') # open template
hstr = html.read()
html.close()
# replace the placeholder values with the true values
if gIter.size != 0 or gIter.size > 100:
hstrnew = hstr.replace('xxxxName', OptName)
hstrnew = hstrnew.replace('xxxxTime', time_now)
hstrnew = hstrnew.replace('xxxxtableObjFct', ObjFct_table)
hstrnew = hstrnew.replace('xxxxtableDesVar', DesVar_table)
hstrnew = hstrnew.replace('xxxxnumber_des_var', number_des_vars * 2)
hstrnew = hstrnew.replace('xxxxtableConstr', Constraint_table)
hstrnew = hstrnew.replace('xxxxnumber_constraints', number_constraints)
hstrnew = hstrnew.replace('xxxxAlg', Alg.name)
hstrnew = hstrnew.replace('xxxxStatus', str(inform))
hstrnew = hstrnew.replace('xxxxRefRate', RefRate)
hstrnew = hstrnew.replace('xxxxStartTime', StartTime)
hstrnew = hstrnew.replace('xxxxEndTime', EndTime)
hstrnew = hstrnew.replace('xxxxIteration', Iteration)
else:
hstrnew = hstr.replace('xxxxName', OptName)
hstrnew = hstrnew.replace('xxxxTime', time_now)
hstrnew = hstrnew.replace('xxxxtableObjFct', ObjFct_table)
hstrnew = hstrnew.replace('xxxxtableDesVar', DesVar_table)
hstrnew = hstrnew.replace('xxxxAlg', Alg.name)
hstrnew = hstrnew.replace('xxxxStatus', inform)
hstrnew = hstrnew.replace('xxxxRefRate', RefRate)
hstrnew = hstrnew.replace('xxxxStartTime', StartTime)
hstrnew = hstrnew.replace('xxxxEndTime', EndTime)
hstrnew = hstrnew.replace('xxxxIteration', Iteration)
# remove the hmtl parts which are only needed for constrained problems
try:
for i in range(0, 10):
hstrnew = hstrnew[0:hstrnew.find("<!--Start of constraint html part-->")] + hstrnew[hstrnew.find(
"<!--End of constraint html part-->") + 34:-1]
except:
print ""
# generate a new html file which is filled with the actual content
html = open('initial1.html', 'w')
html.write(hstrnew)
html.close()
# copy everything needed to the result directory
if not os.path.exists(StatusDirectory + os.sep + "Results" + os.sep + OptName):
os.makedirs(StatusDirectory + os.sep + "Results" + os.sep + OptName)
shutil.copy("initial1.html",
StatusDirectory + os.sep + "Results" + os.sep + OptName + os.sep + OptName + "_Status.html")
shutil.copy("objFct_maxCon.csv",
StatusDirectory + os.sep + "Results" + os.sep + OptName + os.sep + "objFct_maxCon.csv")
shutil.copy("desVars.csv",
StatusDirectory + os.sep + "Results" + os.sep + OptName + os.sep + "desVars.csv")
shutil.copy("desVarsNorm.csv",
StatusDirectory + os.sep + "Results" + os.sep + OptName + os.sep + "desVarsNorm.csv")
shutil.copy("constraints.csv",
StatusDirectory + os.sep + "Results" + os.sep + OptName + os.sep + "constraints.csv")
for file in glob.glob(template_directory + "*.png"):
shutil.copy(file, StatusDirectory + os.sep + "Results" + os.sep + OptName + os.sep)
for file in glob.glob(template_directory + "*.js"):
shutil.copy(file, StatusDirectory + os.sep + "Results" + os.sep + OptName + os.sep)
for file in glob.glob(template_directory + "*.css"):
shutil.copy(file, StatusDirectory + os.sep + "Results" + os.sep + OptName + os.sep)
for file in glob.glob(template_directory + "*.ico"):
shutil.copy(file, StatusDirectory + os.sep + "Results" + os.sep + OptName + os.sep)
for file in glob.glob(template_directory + "view_results.py"):
shutil.copy(file, StatusDirectory + os.sep + "Results" + os.sep + OptName + os.sep)
return 0