-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path_setup.py
312 lines (251 loc) · 13.5 KB
/
_setup.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
'''
*
* _setup
* GEOVAR SETUP SUPPORT MODULE
*
* Module designed to delegate "setup" functions that serve the GEOVAR class
*
* VERSION: 0.0.1
* KNOWN ISSUES:
* - Nada atm.
*
*
* AUTHOR : Mohammad Odeh, Fluvio L. Lobo Fenoglietto
* DATE : Jan. 10th, 2019 Year of Our Lord
*
'''
# Python Libraries and Modules
import os, re # Dir/path manipulation, extract numerics from strings
import sys
import numpy as np
from time import sleep, time # Timers/delays
from platform import system # Running platform info
from datetime import datetime # Get date and time
from lxml import etree
from itertools import product # Apply product rule on combinations
# Geovar Libraries and Modules
from _performance import *
# ************************************************************************
# FUNCTIONS =============================================================*
# ************************************************************************
def setup_input_directory( self ):
'''
SETUP INPUT DIRECTORY
'''
print('[{:0.6f}] Setup input directory'.format(current_time( self )))
current_dir = os.getcwd()
input_dir = '{}\\input\\'.format( current_dir )
if os.path.exists( input_dir ) == False:
print('[{:0.6f}] FATAL ERROR :: No input directory detected'.format(current_time( self )))
#os.makedirs( input_dir )
else:
print('[{:0.6f}] Input directory found'.format(current_time( self )))
self.current_dir = current_dir
self.input_dir = input_dir # Passing tetgen path to the .self structure
# ------------------------------------------------------------------------
def setup_output_directory( self ):
'''
SETUP OUTPUT DIRECTORY
'''
self.prog_time = time() - self.prog_start_time
print('[{:0.6f}] Setup output directory'.format(current_time( self )))
current_dir = os.getcwd()
output_dir = '{}\\output\\'.format( current_dir )
dst = '{}{}\\'.format( output_dir, datetime.now().strftime("%Y-%m-%d__%H_%M_%S") )
# ----------------------------------------------------------------------------------------------------------------- # create output (main) directory, if not yet created
if os.path.exists( output_dir ) == False:
print('[{:0.6f}] WARNING :: No output directory found... generating...'.format(current_time( self )))
os.makedirs( output_dir )
else:
print('[{:0.6f}] Output directory found'.format(current_time( self )))
# ----------------------------------------------------------------------------------------------------------------- # create output (execution-specific) directory, if not yet created
if os.path.exists( dst ) == False:
print('[{:0.6f}] WARNING :: No destination directory found... generating...'.format(current_time( self )))
os.makedirs( dst )
else:
print('[{:0.6f}] Destination directory found'.format(current_time( self )))
self.output_dir = output_dir
self.dst = dst
# ------------------------------------------------------------------------
def setup_tetgen_directory( self ):
'''
SETUP TETGEN DIRECTORY
'''
print('[{:0.6f}] Setup TetGen directory'.format(current_time( self )))
dir_list = os.listdir() # List elements within current directory
dir_len = len(dir_list)
test_string = 'tetgen'
test_string_len = len(test_string)
for i in range( 0, dir_len ):
if len( dir_list[i] ) >= test_string_len:
if dir_list[i][0:test_string_len] == test_string:
match_index = i
break
current_dir = os.getcwd()
tetgen_dir = '{}\\{}\\build\\Debug\\'.format(current_dir,dir_list[match_index])
self.tetgen_dir = tetgen_dir # Passing tetgen path to the .self structure
# ------------------------------------------------------------------------
def setup_directories( self ):
'''
SETUO DIRECTORIES
'''
print('[{:0.6f}] Setup directories'.format(current_time( self )))
# ------ UNIX systems ------
if( system()=='Linux' ):
print( " ERROR: geovar() has only been configured for Windows... ")
quit()
# ----- Windows system -----
elif( system()=='Windows' ):
# Define useful paths
setup_input_directory( self )
setup_tetgen_directory( self )
setup_output_directory( self )
# ------------------------------------------------------------------------
def generate_filenames( self, filename):
'''
GENERATE FILENAMES
- This program works on the premise that all input filenames, in
accordance with the program's structure, have the same "name",
while lacking the same extension
'''
print('[{:0.6f}] Setup filenames'.format(current_time( self )))
if filename.rfind('.') is not -1:
filename_woe = filename[:filename.rfind('.')]
elif filename.rfind('.') is -1:
filename_woe = filename
self.input_stl_filename = "{}.stl".format(filename_woe)
self.input_xml_filename = "{}.xml".format(filename_woe)
self.input_vtk_filename = "{}.vtk".format(filename_woe)
self.input_feb_filename = "{}.feb".format(filename_woe)
# ------------------------------------------------------------------------
def check_input_files( self, filename, mode ):
'''
CHECK FOR PRESENCE OR ABSENCE OF INPUT FILENAMES
'''
print('[{:0.6f}] Check input files'.format(current_time( self )))
# ----------------------------------------------------------------------------------------------------------------- # check for all modes
file = self.input_dir + self.input_xml_filename
print('[{:0.6f}] GEOVAR requires input XML file'.format(current_time( self )))
if os.path.exists( file ) == True:
print('[{:0.6f}] Input XML found, program will continue'.format(current_time( self )))
elif os.path.exists( file ) == False:
print('[{:0.6f}] FATAL ERROR :: No input XML file found'.format(current_time( self )))
quit()
# ----------------------------------------------------------------------------------------------------------------- # check for mode 2
if mode == 3:
file = self.input_dir + self.input_feb_filename
print('[{:0.6f}] MODE 3 Requires input FEBio file'.format(current_time( self )))
if os.path.exists( file ) == True:
print('[{:0.6f}] Input FEBio found, program will continue'.format(current_time( self )))
elif os.path.exists( file ) == False:
print('[{:0.6f}] FATAL ERROR :: No input FEBio file found'.format(current_time( self )))
quit()
# ------------------------------------------------------------------------
def read_doc( self, filename ):
'''
READ DOC INFO
Function responsible for reading and extracting information from
the "doc" input file
doc_def contains the identification of the target document within the onshape platform
'''
print('[{:0.6f}] Reading Onshape doc. info. from input XML'.format(current_time( self )))
file = self.input_dir + self.input_xml_filename
if os.path.exists( file ) == False:
print('[{:0.6f}] FATAL ERROR :: No input XML file found'.format(current_time( self )))
quit()
_doc = etree.parse( file )
_doc_address_ele = _doc.find('address')
_doc_address_text = _doc_address_ele.text
_doc_address_text = _doc_address_text.split("/")
for i in range( 0, len( _doc_address_text ) ):
if _doc_address_text[i] == 'documents':
self.did = _doc_address_text[i+1] # Store the document id
elif _doc_address_text[i] == 'w':
self.wid = _doc_address_text[i+1] # Store the workspace id
elif _doc_address_text[i] == 'e':
self.eid = _doc_address_text[i+1] # Store the element id
# ------------------------------------------------------------------------
def read_vars( self, filename ):
'''
READ VAR INFO
Function responsible for reading and extracting information from
the "doc" input file
doc_def contains the identification of the target document within the onshape platform
'''
print('[{:0.6f}] Reading variants info. from input XML'.format(current_time( self )))
file = self.input_dir + self.input_xml_filename
if os.path.exists( file ) == False:
print('[{:0.6f}] FATAL ERROR :: No input XML file found'.format(current_time( self )))
quit()
_doc = etree.parse( file )
_doc_vars_ele = _doc.find('variables')
var = {}
var['nvar'] = len(_doc_vars_ele)
var['names'] = []
for i in range(0, len(_doc_vars_ele) ):
var_name = _doc_vars_ele[i].get("name")
var['names'].append( _doc_vars_ele[i].get("name") )
var[var_name] = {}
var[var_name]['start'] = float( _doc_vars_ele[i].get("start") )
var[var_name]['stop'] = float( _doc_vars_ele[i].get("stop") )
var[var_name]['np'] = int( _doc_vars_ele[i].get("np") )
var[var_name]['ep'] = int( _doc_vars_ele[i].get("ep") )
self.var = var
# ------------------------------------------------------------------------
def generate_variant_array( self ):
'''
GENERATE GEOMETRIC VARIANT ARRAY
- Generates the array of values for every input variable
- Generates all possible combinations for all possible values of each variable
'''
print('[{:0.6f}] Generate geomatric variants array'.format(current_time( self )))
var = self.var # Load var from self structure
arr = [] # Define array 'arr' which will contain all the user input values for each user input variable
for i in range(0, var['nvar']): # Populate 'arr'
_name = var['names'][i]
_start = var[_name]['start']
_stop = var[_name]['stop']
_np = var[_name]['np']
_ep = var[_name]['ep']
var[_name]['vals'] = []
var[_name]['vals'] = np.linspace( _start, _stop, _np, _ep ) # Generate values using linspace
arr.append( var[_name]['vals'] )
print(('[{:0.6f}]\t{}\tvals: {}').format(current_time(self),_name,str(var[_name]['vals']))) # Reporting
arr = np.array(arr) # Convert 'arr' into a numpy array
vals_range = list( range( arr.shape[1] ) )
prods = list( product( vals_range, repeat = arr.shape[0] ) ) # Calculate all possible variable combinations, considering all the values for each variable
self.var = var # Load changes to 'self' structure
self.arr = arr
self.prods = prods
self.Nprods = len( prods )
# ------------------------------------------------------------------------
def query_variants(question, default="yes"):
"""
STOP:
- Halts process until user reviews information
"""
valid = {"yes": True, "y": True, "ye": True,
"no": False, "n": False}
if default is None:
prompt = " [y/n] "
elif default == "yes":
prompt = " [Y/n] "
elif default == "no":
prompt = " [y/N] "
else:
raise ValueError("invalid default answer: '%s'" % default)
while True:
sys.stdout.write(question + prompt)
choice = input().lower()
if default is not None and choice == '':
return valid[default]
elif choice in valid:
if valid[choice] == False:
print('Terminating program...')
quit()
else:
print('Proceed at your own risk..!')
return valid[choice]
else:
sys.stdout.write("Please respond with 'yes' or 'no' "
"(or 'y' or 'n').\n")