Merge branch 'development' of magit1.mpie.de:damask/DAMASK into miscImprovements

This commit is contained in:
Martin Diehl 2016-09-05 01:29:09 +02:00
commit 4bbd69309d
1 changed files with 72 additions and 69 deletions

View File

@ -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)):