From c1b77693274ef7e532c59bc20db40d44b813595a Mon Sep 17 00:00:00 2001 From: Test User Date: Fri, 21 Dec 2018 07:22:54 +0100 Subject: [PATCH 1/6] [skip ci] updated version information after successful test of v2.0.2-1236-g1ef82e35 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 4fd318a98..2ad825361 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.2-1187-gcd8ee450 +v2.0.2-1236-g1ef82e35 From 0541cceb2cec4475a73e42919a9c7ad4405b9849 Mon Sep 17 00:00:00 2001 From: Test User Date: Fri, 21 Dec 2018 12:26:41 +0100 Subject: [PATCH 2/6] [skip ci] updated version information after successful test of v2.0.2-1239-g9bdd4d1d --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 4fd318a98..d161a8ad6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.2-1187-gcd8ee450 +v2.0.2-1239-g9bdd4d1d From a852729d4d7ce028fbada072add19be878d5ede5 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 1 Jan 2019 16:59:35 +0100 Subject: [PATCH 3/6] [skip ci] it's 2019 now --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 630dc3a84..1ab20178c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2011-18 Max-Planck-Institut für Eisenforschung GmbH +Copyright 2011-19 Max-Planck-Institut für Eisenforschung GmbH DAMASK is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by From b5d62c8e29a426158ca338458666088015022291 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Thu, 3 Jan 2019 11:28:03 -0500 Subject: [PATCH 4/6] [skip ci] print estimated remaining processing time for postResults --- lib/damask/util.py | 13 ++++++++++--- processing/post/postResults.py | 12 ++++++++---- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/damask/util.py b/lib/damask/util.py index e7d4a16bc..45347ae88 100644 --- a/lib/damask/util.py +++ b/lib/damask/util.py @@ -134,7 +134,7 @@ class extendableOption(Option): # Print iterations progress # from https://gist.github.com/aubricus/f91fb55dc6ba5557fbab06119420dd6a -def progressBar(iteration, total, prefix='', suffix='', decimals=1, bar_length=100): +def progressBar(iteration, total, start=None, prefix='', suffix='', decimals=1, bar_length=50): """ Call in a loop to create terminal progress bar @@ -146,12 +146,19 @@ def progressBar(iteration, total, prefix='', suffix='', decimals=1, bar_length=1 decimals - Optional : positive number of decimals in percent complete (Int) bar_length - Optional : character length of bar (Int) """ - str_format = "{0:." + str(decimals) + "f}" + import time + + if suffix == '' and start is not None and iteration > 0: + remainder = (total - iteration) * (time.time()-start)/iteration + suffix = '{: 3d}:'.format(int( remainder//3600)) + \ + '{:02d}:'.format(int((remainder//60)%60)) + \ + '{:02d}' .format(int( remainder %60)) + str_format = "{{0:{}.{}f}}".format(decimals+4,decimals) percents = str_format.format(100 * (iteration / float(total))) filled_length = int(round(bar_length * iteration / float(total))) bar = '█' * filled_length + '-' * (bar_length - filled_length) - sys.stderr.write('\r%s |%s| %s%s %s' % (prefix, bar, percents, '%', suffix)), + sys.stderr.write('\r%s |%s| %s %s' % (prefix, bar, percents+'%', suffix)), if iteration == total: sys.stderr.write('\n\n') sys.stderr.flush() diff --git a/processing/post/postResults.py b/processing/post/postResults.py index a5a2669d7..cf4353ac5 100755 --- a/processing/post/postResults.py +++ b/processing/post/postResults.py @@ -830,9 +830,10 @@ if options.info: elementsOfNode = {} Nelems = stat['NumberOfElements'] +starttime = time.time() for e in range(Nelems): if options.verbose and Nelems > 100 and e%(Nelems//100) == 0: # report in 1% steps if possible and avoid modulo by zero - damask.util.progressBar(iteration=e,total=Nelems,prefix='1/3: connecting elements') + damask.util.progressBar(iteration=e,total=Nelems,start=starttime,prefix='1/3: connecting elements') for n in map(p.node_sequence,p.element(e).items): if n not in elementsOfNode: elementsOfNode[n] = [p.element_id(e)] @@ -855,9 +856,10 @@ damask.util.progressBar(iteration=1,total=1,prefix='1/3: connecting elements') if options.nodalScalar: Npoints = stat['NumberOfNodes'] + starttime = time.time() for n in range(Npoints): if options.verbose and Npoints > 100 and e%(Npoints//100) == 0: # report in 1% steps if possible and avoid modulo by zero - damask.util.progressBar(iteration=n,total=Npoints,prefix='2/3: scanning nodes ') + damask.util.progressBar(iteration=n,total=Npoints,start=starttime,prefix='2/3: scanning nodes ') myNodeID = p.node_id(n) myNodeCoordinates = [p.node(n).x, p.node(n).y, p.node(n).z] myElemID = 0 @@ -892,9 +894,10 @@ if options.nodalScalar: else: Nelems = stat['NumberOfElements'] + starttime = time.time() for e in range(Nelems): if options.verbose and Nelems > 100 and e%(Nelems//100) == 0: # report in 1% steps if possible and avoid modulo by zero - damask.util.progressBar(iteration=e,total=Nelems,prefix='2/3: scanning elements ') + damask.util.progressBar(iteration=e,total=Nelems,start=starttime,prefix='2/3: scanning elements ') myElemID = p.element_id(e) myIpCoordinates = ipCoords(p.element(e).type, list(map(lambda node: [node.x, node.y, node.z], list(map(p.node, map(p.node_sequence, p.element(e).items)))))) @@ -1032,10 +1035,11 @@ for incCount,position in enumerate(locations): # walk through locations member = 0 Ngroups = len(groups) + starttime = time.time() for j,group in enumerate(groups): f = incCount*Ngroups + j if options.verbose and (Ngroups*Nincs) > 100 and f%((Ngroups*Nincs)//100) == 0: # report in 1% steps if possible and avoid modulo by zero - damask.util.progressBar(iteration=f,total=Ngroups*Nincs,prefix='3/3: processing points ') + damask.util.progressBar(iteration=f,total=Ngroups*Nincs,start=starttime,prefix='3/3: processing points ') N = 0 # group member counter for (e,n,i,g,n_local) in group[1:]: # loop over group members member += 1 From bcd4288f1eba6eba0fe21b35326ed5447415eb69 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Thu, 3 Jan 2019 18:25:28 -0500 Subject: [PATCH 5/6] [skip ci] groupTable according to unique values in more than one column --- processing/post/groupTable.py | 44 +++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/processing/post/groupTable.py b/processing/post/groupTable.py index 67d07a7d1..f78566304 100755 --- a/processing/post/groupTable.py +++ b/processing/post/groupTable.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python3 # -*- coding: UTF-8 no BOM -*- import os,sys @@ -21,18 +21,19 @@ scriptID = ' '.join([scriptName,damask.version]) # -------------------------------------------------------------------- parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [file[s]]', description = """ -Apply a user-specified function to condense all rows for which column 'label' has identical values into a single row. -Output table will contain as many rows as there are different (unique) values in the grouping column. +Apply a user-specified function to condense into a single row all those rows for which columns 'label' have identical values. +Output table will contain as many rows as there are different (unique) values in the grouping column(s). Periodic domain averaging of coordinate values is supported. Examples: For grain averaged values, replace all rows of particular 'texture' with a single row containing their average. -""", version = scriptID) +{name} --label texture --function np.average data.txt +""".format(name = scriptName), version = scriptID) parser.add_option('-l','--label', dest = 'label', - type = 'string', metavar = 'string', - help = 'column label for grouping rows') + action = 'extend', metavar = '', + help = 'column label(s) for grouping rows') parser.add_option('-f','--function', dest = 'function', type = 'string', metavar = 'string', @@ -40,7 +41,7 @@ parser.add_option('-f','--function', parser.add_option('-a','--all', dest = 'all', action = 'store_true', - help = 'apply mapping function also to grouping column') + help = 'apply mapping function also to grouping column(s)') group = OptionGroup(parser, "periodic averaging", "") @@ -57,6 +58,7 @@ parser.add_option_group(group) parser.set_defaults(function = 'np.average', all = False, + label = [], boundary = [0.0, 1.0]) (options,filenames) = parser.parse_args() @@ -71,7 +73,7 @@ try: except: mapFunction = None -if options.label is None: +if options.label is []: parser.error('no grouping column specified.') if not hasattr(mapFunction,'__call__'): parser.error('function "{}" is not callable.'.format(options.function)) @@ -89,13 +91,20 @@ for name in filenames: # ------------------------------------------ sanity checks --------------------------------------- + remarks = [] + errors = [] + table.head_read() - if table.label_dimension(options.label) != 1: - damask.util.croak('column {} is not of scalar dimension.'.format(options.label)) - table.close(dismiss = True) # close ASCIItable and remove empty file + grpColumns = table.label_index(options.label)[::-1] + grpColumns = grpColumns[np.where(grpColumns>=0)] + + if len(grpColumns) == 0: errors.append('no valid grouping column present.') + + if remarks != []: damask.util.croak(remarks) + if errors != []: + damask.util.croak(errors) + table.close(dismiss=True) continue - else: - grpColumn = table.label_index(options.label) # ------------------------------------------ assemble info --------------------------------------- @@ -108,10 +117,9 @@ for name in filenames: indexrange = table.label_indexrange(options.periodic) if options.periodic is not None else [] rows,cols = table.data.shape - table.data = table.data[np.lexsort([table.data[:,grpColumn]])] # sort data by grpColumn - - values,index = np.unique(table.data[:,grpColumn], return_index = True) # unique grpColumn values and their positions - index = np.append(index,rows) # add termination position + table.data = table.data[np.lexsort(table.data[:,grpColumns].T)] # sort data by grpColumn(s) + values,index = np.unique(table.data[:,grpColumns], axis=0, return_index=True) # unique grpColumn values and their positions + index = sorted(np.append(index,rows)) # add termination position grpTable = np.empty((len(values), cols)) # initialize output for i in range(len(values)): # iterate over groups (unique values in grpColumn) @@ -119,7 +127,7 @@ for name in filenames: grpTable[i,indexrange] = \ periodicAverage(table.data[index[i]:index[i+1],indexrange],options.boundary) # apply periodicAverage mapping function - if not options.all: grpTable[i,grpColumn] = table.data[index[i],grpColumn] # restore grouping column value + if not options.all: grpTable[i,grpColumns] = table.data[index[i],grpColumns] # restore grouping column value table.data = grpTable From 3c5df0a4a43f5ddabb0c17a49e50d9474c5cf1ee Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Fri, 4 Jan 2019 16:34:04 -0500 Subject: [PATCH 6/6] [skip ci] viewTable acknowledges requested output type(s) --- processing/post/viewTable.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/processing/post/viewTable.py b/processing/post/viewTable.py index c01bdcddb..309f229e1 100755 --- a/processing/post/viewTable.py +++ b/processing/post/viewTable.py @@ -61,7 +61,14 @@ for name in filenames: table = damask.ASCIItable(name = name, buffered = False, labeled = options.labeled, readonly = True) except: continue - damask.util.report(scriptName,name) + details = ', '.join( + (['header'] if options.table else []) + + (['info'] if options.head or options.info else []) + + (['labels'] if options.head or options.labels else []) + + (['data'] if options.data else []) + + [] + ) + damask.util.report(scriptName,name + ('' if details == '' else ' -- '+details)) # ------------------------------------------ output head ---------------------------------------