Merge branch 'development' of magit1.mpie.de:damask/DAMASK into miscImprovements
This commit is contained in:
commit
4bbd69309d
|
@ -16,9 +16,17 @@ class Test():
|
|||
"""
|
||||
|
||||
variants = []
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
|
||||
def __init__(self,description = ''):
|
||||
|
||||
defaults = {'description': '',
|
||||
'keep': False,
|
||||
'accept': False,
|
||||
'update': False,
|
||||
}
|
||||
for arg in defaults.keys():
|
||||
setattr(self,arg,kwargs.get(arg) if kwargs.get(arg) else defaults[arg])
|
||||
|
||||
fh = logging.FileHandler('test.log') # create file handler which logs even debug messages
|
||||
fh.setLevel(logging.DEBUG)
|
||||
fh.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s: \n%(message)s'))
|
||||
|
@ -34,80 +42,72 @@ class Test():
|
|||
|
||||
logging.info('\n'.join(['+'*40,
|
||||
'-'*40,
|
||||
'| '+description,
|
||||
'| '+self.description,
|
||||
'-'*40,
|
||||
]))
|
||||
|
||||
self.dirBase = os.path.dirname(os.path.realpath(sys.modules[self.__class__.__module__].__file__))
|
||||
|
||||
self.parser = OptionParser(description = '{} (using class: {})'.format(description,damask.version),
|
||||
self.parser = OptionParser(description = '{} (Test class version: {})'.format(self.description,damask.version),
|
||||
usage = './test.py [options]')
|
||||
self.updateRequested = False
|
||||
self.parser.add_option("-d", "--debug",
|
||||
self.parser.add_option("-k", "--keep",
|
||||
action = "store_true",
|
||||
dest = "debug",
|
||||
help = "debug run, don't calculate but use existing results")
|
||||
self.parser.add_option("-p", "--pass",
|
||||
dest = "keep",
|
||||
help = "keep current results, just run postprocessing")
|
||||
self.parser.add_option("--ok", "--accept",
|
||||
action = "store_true",
|
||||
dest = "accept",
|
||||
help = "calculate results but always consider test as successfull")
|
||||
self.parser.set_defaults(debug = False,
|
||||
accept = False,
|
||||
|
||||
self.parser.set_defaults(keep = self.keep,
|
||||
accept = self.accept,
|
||||
update = self.update,
|
||||
)
|
||||
|
||||
|
||||
def execute(self):
|
||||
"""Run all variants and report first failure."""
|
||||
if self.options.debug:
|
||||
for variant in xrange(len(self.variants)):
|
||||
try:
|
||||
self.postprocess(variant)
|
||||
if not self.compare(variant):
|
||||
return variant+1 # return culprit
|
||||
except Exception as e :
|
||||
logging.critical('\nWARNING:\n {}\n'.format(e))
|
||||
return variant+1 # return culprit
|
||||
return 0
|
||||
else:
|
||||
if not self.options.keep:
|
||||
if not self.feasible(): return -1
|
||||
|
||||
self.clean()
|
||||
self.prepareAll()
|
||||
|
||||
for variant,name in enumerate(self.variants):
|
||||
try:
|
||||
for variant,name in enumerate(self.variants):
|
||||
try:
|
||||
if not self.options.keep:
|
||||
self.prepare(variant)
|
||||
self.run(variant)
|
||||
self.postprocess(variant)
|
||||
if self.updateRequested: # update requested
|
||||
self.update(variant)
|
||||
elif not (self.options.accept or self.compare(variant)): # no update, do comparison
|
||||
return variant+1 # return culprit
|
||||
except Exception as e :
|
||||
logging.critical('\nWARNING:\n {}\n'.format(e))
|
||||
return variant+1 # return culprit
|
||||
return 0
|
||||
|
||||
self.postprocess(variant)
|
||||
|
||||
if self.options.update and not self.update(variant):
|
||||
logging.critical('update for "{}" failed.'.format(name))
|
||||
elif not (self.options.accept or self.compare(variant)): # no update, do comparison
|
||||
return variant+1 # return culprit
|
||||
|
||||
except Exception as e :
|
||||
logging.critical('exception during variant execution: {}'.format(e))
|
||||
return variant+1 # return culprit
|
||||
return 0
|
||||
|
||||
def feasible(self):
|
||||
"""Check whether test is possible or not (e.g. no license available)."""
|
||||
return True
|
||||
|
||||
def clean(self):
|
||||
"""Delete directory tree containing current results."""
|
||||
status = True
|
||||
|
||||
try:
|
||||
shutil.rmtree(self.dirCurrent())
|
||||
except:
|
||||
logging.warning('removal of directory "{}" not possible...'.format(self.dirCurrent()))
|
||||
status = status and False
|
||||
|
||||
try:
|
||||
os.mkdir(self.dirCurrent())
|
||||
return True
|
||||
except:
|
||||
logging.critical('creation of directory "{}" failed...'.format(self.dirCurrent()))
|
||||
status = status and False
|
||||
|
||||
return status
|
||||
|
||||
logging.critical('creation of directory "{}" failed.'.format(self.dirCurrent()))
|
||||
return False
|
||||
|
||||
def prepareAll(self):
|
||||
"""Do all necessary preparations for the whole test"""
|
||||
return True
|
||||
|
@ -134,8 +134,8 @@ class Test():
|
|||
|
||||
def update(self,variant):
|
||||
"""Update reference with current results."""
|
||||
logging.debug('Update not necessary')
|
||||
return True
|
||||
logging.critical('update not supported.')
|
||||
return False
|
||||
|
||||
|
||||
def dirReference(self):
|
||||
|
@ -458,12 +458,12 @@ class Test():
|
|||
|
||||
|
||||
def compare_Tables(self,
|
||||
files = [None,None], # list of file names
|
||||
files = [None,None], # list of file names
|
||||
columns = [None], # list of list of column labels (per file)
|
||||
rtol = 1e-5,
|
||||
atol = 1e-8,
|
||||
debug = False):
|
||||
"""compare tables with np.allclose"""
|
||||
rtol = 1e-5,
|
||||
atol = 1e-8,
|
||||
debug = False):
|
||||
"""compare multiple tables with np.allclose"""
|
||||
if not (isinstance(files, Iterable) and not isinstance(files, str)): # check whether list of files is requested
|
||||
files = [str(files)]
|
||||
|
||||
|
@ -477,7 +477,7 @@ class Test():
|
|||
columns = columns[:len(files)] # truncate to same length as files
|
||||
|
||||
for i,column in enumerate(columns):
|
||||
if column is None: columns[i] = tables[i].labels(raw = True) # if no column is given, use all
|
||||
if column is None: columns[i] = tables[i].labels(raw = False) # if no column is given, use all
|
||||
|
||||
logging.info('comparing ASCIItables')
|
||||
for i in xrange(len(columns)):
|
||||
|
@ -485,35 +485,38 @@ class Test():
|
|||
([columns[i]] if not (isinstance(columns[i], Iterable) and not isinstance(columns[i], str)) else \
|
||||
columns[i]
|
||||
)
|
||||
logging.info(files[i]+':'+','.join(columns[i]))
|
||||
logging.info(files[i]+': '+','.join(columns[i]))
|
||||
|
||||
# peek into the ASCII table to figure out real table size
|
||||
# the cryptic table header does not share the same size as real
|
||||
# table
|
||||
table.data_readArray(columns[0])
|
||||
maximum = np.zeros(table.data.shape[1], dtype='f')
|
||||
data = [] # list of feature table extracted from each file (ASCII table)
|
||||
for table, labels in zip(tables, columns):
|
||||
table.data_readArray(labels)
|
||||
for label in labels:
|
||||
idx = table.label_indexrange(label)
|
||||
maximum[idx] = np.maximum(maximum[idx],
|
||||
np.amax(np.linalg.norm(table.data[:,idx],axis=1)))
|
||||
data.append(table.data)
|
||||
table.close()
|
||||
dimensions = tables[0].label_dimension(columns[0]) # width of each requested column
|
||||
maximum = np.zeros_like(columns[0],dtype=float) # one magnitude per column entry
|
||||
data = [] # list of feature table extracted from each file (ASCII table)
|
||||
|
||||
maximum = np.where(maximum > 0.0, maximum, 1) # avoid div by zero for empty columns
|
||||
for i,(table,labels) in enumerate(zip(tables,columns)):
|
||||
if np.any(dimensions != table.label_dimension(labels)): # check data object consistency
|
||||
logging.critical('Table {} differs in data layout.'.format(files[i]))
|
||||
return False
|
||||
table.data_readArray(labels) # read data, ...
|
||||
data.append(table.data) # ... store, ...
|
||||
table.close() # ... close
|
||||
|
||||
for j,label in enumerate(labels): # iterate over object labels
|
||||
maximum[j] = np.maximum(\
|
||||
maximum[j],
|
||||
np.amax(np.linalg.norm(table.data[:,table.label_indexrange(label)],
|
||||
axis=1))
|
||||
) # find maximum Euclidean norm across rows
|
||||
|
||||
maximum = np.where(maximum > 0.0, maximum, 1.0) # avoid div by zero for zero columns
|
||||
maximum = np.repeat(maximum,dimensions) # spread maximum over columns of each object
|
||||
|
||||
# normalize each table
|
||||
for i in xrange(len(data)):
|
||||
data[i] /= maximum
|
||||
data[i] /= maximum # normalize each table
|
||||
|
||||
if debug:
|
||||
logging.debug(str(maximum))
|
||||
allclose = np.absolute(data[0]-data[1]) <= (atol + rtol*np.absolute(data[1]))
|
||||
for ok,valA,valB in zip(allclose,data[0],data[1]):
|
||||
logging.debug('{}:\n {}\n{}\n'.format(ok,valA,valB))
|
||||
logging.debug('{}:\n{}\n{}'.format(ok,valA,valB))
|
||||
|
||||
allclose = True # start optimistic
|
||||
for i in xrange(1,len(data)):
|
||||
|
|
Loading…
Reference in New Issue