Merge branch 'new-ASCII' into grid-filters
This commit is contained in:
commit
274aaa7359
|
@ -41,9 +41,9 @@ for name in filenames:
|
||||||
damask.util.report(scriptName,name)
|
damask.util.report(scriptName,name)
|
||||||
|
|
||||||
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||||
table.add_array('Cauchy',
|
table.add('Cauchy',
|
||||||
damask.mechanics.Cauchy(table.get_array(options.defgrad).reshape(-1,3,3),
|
damask.mechanics.Cauchy(table.get(options.defgrad).reshape(-1,3,3),
|
||||||
table.get_array(options.stress).reshape(-1,3,3)).reshape(-1,9),
|
table.get(options.stress ).reshape(-1,3,3)).reshape(-1,9),
|
||||||
scriptID+' '+' '.join(sys.argv[1:]))
|
scriptID+' '+' '.join(sys.argv[1:]))
|
||||||
|
|
||||||
table.to_ASCII(sys.stdout if name is None else name)
|
table.to_ASCII(sys.stdout if name is None else name)
|
||||||
|
|
|
@ -38,8 +38,8 @@ for name in filenames:
|
||||||
|
|
||||||
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||||
for tensor in options.tensor:
|
for tensor in options.tensor:
|
||||||
table.add_array('det({})'.format(tensor),
|
table.add('det({})'.format(tensor),
|
||||||
np.linalg.det(table.get_array(tensor).reshape(-1,3,3)),
|
np.linalg.det(table.get(tensor).reshape(-1,3,3)),
|
||||||
scriptID+' '+' '.join(sys.argv[1:]))
|
scriptID+' '+' '.join(sys.argv[1:]))
|
||||||
|
|
||||||
table.to_ASCII(sys.stdout if name is None else name)
|
table.to_ASCII(sys.stdout if name is None else name)
|
||||||
|
|
|
@ -40,12 +40,12 @@ for name in filenames:
|
||||||
|
|
||||||
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||||
for tensor in options.tensor:
|
for tensor in options.tensor:
|
||||||
table.add_array('dev({})'.format(tensor),
|
table.add('dev({})'.format(tensor),
|
||||||
damask.mechanics.deviatoric_part(table.get_array(tensor).reshape(-1,3,3)).reshape((-1,9)),
|
damask.mechanics.deviatoric_part(table.get(tensor).reshape(-1,3,3)).reshape((-1,9)),
|
||||||
scriptID+' '+' '.join(sys.argv[1:]))
|
scriptID+' '+' '.join(sys.argv[1:]))
|
||||||
if options.spherical:
|
if options.spherical:
|
||||||
table.add_array('sph({})'.format(tensor),
|
table.add('sph({})'.format(tensor),
|
||||||
damask.mechanics.spherical_part(table.get_array(tensor).reshape(-1,3,3)),
|
damask.mechanics.spherical_part(table.get(tensor).reshape(-1,3,3)),
|
||||||
scriptID+' '+' '.join(sys.argv[1:]))
|
scriptID+' '+' '.join(sys.argv[1:]))
|
||||||
|
|
||||||
table.to_ASCII(sys.stdout if name is None else name)
|
table.to_ASCII(sys.stdout if name is None else name)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
from io import StringIO
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
|
|
||||||
import damask
|
import damask
|
||||||
|
@ -24,35 +26,16 @@ parser.add_option('-i',
|
||||||
dest = 'info', action = 'extend', metavar = '<string LIST>',
|
dest = 'info', action = 'extend', metavar = '<string LIST>',
|
||||||
help = 'items to add')
|
help = 'items to add')
|
||||||
|
|
||||||
|
|
||||||
(options,filenames) = parser.parse_args()
|
(options,filenames) = parser.parse_args()
|
||||||
|
if filenames == []: filenames = [None]
|
||||||
|
|
||||||
if options.info is None:
|
if options.info is None:
|
||||||
parser.error('no info specified.')
|
parser.error('no info specified.')
|
||||||
|
|
||||||
# --- loop over input files ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
if filenames == []: filenames = [None]
|
|
||||||
|
|
||||||
for name in filenames:
|
for name in filenames:
|
||||||
try: table = damask.ASCIItable(name = name,
|
|
||||||
buffered = False)
|
|
||||||
except: continue
|
|
||||||
damask.util.report(scriptName,name)
|
damask.util.report(scriptName,name)
|
||||||
|
|
||||||
# ------------------------------------------ assemble header ---------------------------------------
|
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||||
|
table.comments += options.info
|
||||||
|
|
||||||
table.head_read()
|
table.to_ASCII(sys.stdout if name is None else name)
|
||||||
table.info_append(options.info)
|
|
||||||
table.head_write()
|
|
||||||
|
|
||||||
# ------------------------------------------ pass through data -------------------------------------
|
|
||||||
|
|
||||||
outputAlive = True
|
|
||||||
|
|
||||||
while outputAlive and table.data_read(): # read next data line of ASCII table
|
|
||||||
outputAlive = table.data_write() # output processed line
|
|
||||||
|
|
||||||
# ------------------------------------------ output finalization -----------------------------------
|
|
||||||
|
|
||||||
table.close() # close ASCII tables
|
|
||||||
|
|
|
@ -45,12 +45,12 @@ for name in filenames:
|
||||||
|
|
||||||
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||||
for strain in options.strain:
|
for strain in options.strain:
|
||||||
table.add_array('Mises({})'.format(strain),
|
table.add('Mises({})'.format(strain),
|
||||||
damask.mechanics.Mises_strain(damask.mechanics.symmetric(table.get_array(strain).reshape(-1,3,3))),
|
damask.mechanics.Mises_strain(damask.mechanics.symmetric(table.get(strain).reshape(-1,3,3))),
|
||||||
scriptID+' '+' '.join(sys.argv[1:]))
|
scriptID+' '+' '.join(sys.argv[1:]))
|
||||||
for stress in options.stress:
|
for stress in options.stress:
|
||||||
table.add_array('Mises({})'.format(stress),
|
table.add('Mises({})'.format(stress),
|
||||||
damask.mechanics.Mises_stress(damask.mechanics.symmetric(table.get_array(stress).reshape(-1,3,3))),
|
damask.mechanics.Mises_stress(damask.mechanics.symmetric(table.get(stress).reshape(-1,3,3))),
|
||||||
scriptID+' '+' '.join(sys.argv[1:]))
|
scriptID+' '+' '.join(sys.argv[1:]))
|
||||||
|
|
||||||
table.to_ASCII(sys.stdout if name is None else name)
|
table.to_ASCII(sys.stdout if name is None else name)
|
||||||
|
|
|
@ -42,9 +42,9 @@ for name in filenames:
|
||||||
|
|
||||||
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||||
|
|
||||||
table.add_array('S',
|
table.add('S',
|
||||||
damask.mechanics.PK2(table.get_array(options.defgrad).reshape(-1,3,3),
|
damask.mechanics.PK2(table.get(options.defgrad).reshape(-1,3,3),
|
||||||
table.get_array(options.stress).reshape(-1,3,3)).reshape(-1,9),
|
table.get(options.stress ).reshape(-1,3,3)).reshape(-1,9),
|
||||||
scriptID+' '+' '.join(sys.argv[1:]))
|
scriptID+' '+' '.join(sys.argv[1:]))
|
||||||
|
|
||||||
table.to_ASCII(sys.stdout if name is None else name)
|
table.to_ASCII(sys.stdout if name is None else name)
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from io import StringIO
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
import re
|
|
||||||
|
|
||||||
import damask
|
import damask
|
||||||
|
|
||||||
|
@ -35,62 +35,18 @@ parser.set_defaults(label = [],
|
||||||
)
|
)
|
||||||
|
|
||||||
(options,filenames) = parser.parse_args()
|
(options,filenames) = parser.parse_args()
|
||||||
|
|
||||||
pattern = [re.compile('^()(.+)$'), # label pattern for scalar
|
|
||||||
re.compile('^(\d+_)?(.+)$'), # label pattern for multidimension
|
|
||||||
]
|
|
||||||
|
|
||||||
# --- loop over input files -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
if filenames == []: filenames = [None]
|
if filenames == []: filenames = [None]
|
||||||
|
|
||||||
|
if len(options.label) != len(options.substitute):
|
||||||
|
parser.error('number of column labels and substitutes do not match.')
|
||||||
|
|
||||||
for name in filenames:
|
for name in filenames:
|
||||||
try: table = damask.ASCIItable(name = name,
|
|
||||||
buffered = False)
|
|
||||||
except: continue
|
|
||||||
damask.util.report(scriptName,name)
|
damask.util.report(scriptName,name)
|
||||||
|
|
||||||
# ------------------------------------------ read header ------------------------------------------
|
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||||
|
for i,label in enumerate(options.label):
|
||||||
|
table.rename(label,
|
||||||
|
options.substitute[i],
|
||||||
|
scriptID+' '+' '.join(sys.argv[1:]))
|
||||||
|
|
||||||
table.head_read()
|
table.to_ASCII(sys.stdout if name is None else name)
|
||||||
|
|
||||||
# ------------------------------------------ process labels ---------------------------------------
|
|
||||||
|
|
||||||
errors = []
|
|
||||||
remarks = []
|
|
||||||
|
|
||||||
if len(options.label) == 0:
|
|
||||||
errors.append('no labels specified.')
|
|
||||||
elif len(options.label) != len(options.substitute):
|
|
||||||
errors.append('mismatch between number of labels ({}) and substitutes ({}).'.format(len(options.label),
|
|
||||||
len(options.substitute)))
|
|
||||||
else:
|
|
||||||
indices = table.label_index (options.label)
|
|
||||||
dimensions = table.label_dimension(options.label)
|
|
||||||
for i,index in enumerate(indices):
|
|
||||||
if index == -1: remarks.append('label "{}" not present...'.format(options.label[i]))
|
|
||||||
else:
|
|
||||||
m = pattern[int(dimensions[i]>1)].match(table.tags[index]) # isolate label name
|
|
||||||
for j in range(dimensions[i]):
|
|
||||||
table.tags[index+j] = table.tags[index+j].replace(m.group(2),options.substitute[i]) # replace name with substitute
|
|
||||||
|
|
||||||
if remarks != []: damask.util.croak(remarks)
|
|
||||||
if errors != []:
|
|
||||||
damask.util.croak(errors)
|
|
||||||
table.close(dismiss = True)
|
|
||||||
continue
|
|
||||||
|
|
||||||
# ------------------------------------------ assemble header ---------------------------------------
|
|
||||||
|
|
||||||
table.info_append(scriptID + '\t' + ' '.join(sys.argv[1:]))
|
|
||||||
table.head_write()
|
|
||||||
|
|
||||||
# ------------------------------------------ process data ------------------------------------------
|
|
||||||
|
|
||||||
outputAlive = True
|
|
||||||
while outputAlive and table.data_read(): # read next data line of ASCII table
|
|
||||||
outputAlive = table.data_write() # output processed line
|
|
||||||
|
|
||||||
# ------------------------------------------ output finalization -----------------------------------
|
|
||||||
|
|
||||||
table.close() # close ASCII tables
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ Uniformly scale column values by given factor.
|
||||||
""", version = scriptID)
|
""", version = scriptID)
|
||||||
|
|
||||||
parser.add_option('-l','--label',
|
parser.add_option('-l','--label',
|
||||||
dest = 'label',
|
dest = 'labels',
|
||||||
action = 'extend', metavar = '<string LIST>',
|
action = 'extend', metavar = '<string LIST>',
|
||||||
help ='column(s) to scale')
|
help ='column(s) to scale')
|
||||||
parser.add_option('-f','--factor',
|
parser.add_option('-f','--factor',
|
||||||
|
@ -31,7 +31,7 @@ parser.add_option('-f','--factor',
|
||||||
help = 'factor(s) per column')
|
help = 'factor(s) per column')
|
||||||
|
|
||||||
parser.set_defaults(label = [],
|
parser.set_defaults(label = [],
|
||||||
)
|
factor = [])
|
||||||
|
|
||||||
(options,filenames) = parser.parse_args()
|
(options,filenames) = parser.parse_args()
|
||||||
if filenames == []: filenames = [None]
|
if filenames == []: filenames = [None]
|
||||||
|
@ -43,8 +43,9 @@ for name in filenames:
|
||||||
damask.util.report(scriptName,name)
|
damask.util.report(scriptName,name)
|
||||||
|
|
||||||
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||||
for i,label in enumerate(options.label):
|
for i,label in enumerate(options.labels):
|
||||||
table.set_array(label,table.get_array(label)*float(options.factor[i]),
|
table.set(label,
|
||||||
|
table.get(label)*float(options.factor[i]),
|
||||||
scriptID+' '+' '.join(sys.argv[1:]))
|
scriptID+' '+' '.join(sys.argv[1:]))
|
||||||
|
|
||||||
table.to_ASCII(sys.stdout if name is None else name)
|
table.to_ASCII(sys.stdout if name is None else name)
|
||||||
|
|
|
@ -22,7 +22,7 @@ Uniformly shift column values by given offset.
|
||||||
""", version = scriptID)
|
""", version = scriptID)
|
||||||
|
|
||||||
parser.add_option('-l','--label',
|
parser.add_option('-l','--label',
|
||||||
dest = 'label',
|
dest = 'labels',
|
||||||
action = 'extend', metavar = '<string LIST>',
|
action = 'extend', metavar = '<string LIST>',
|
||||||
help ='column(s) to shift')
|
help ='column(s) to shift')
|
||||||
parser.add_option('-o','--offset',
|
parser.add_option('-o','--offset',
|
||||||
|
@ -31,7 +31,7 @@ parser.add_option('-o','--offset',
|
||||||
help = 'offset(s) per column')
|
help = 'offset(s) per column')
|
||||||
|
|
||||||
parser.set_defaults(label = [],
|
parser.set_defaults(label = [],
|
||||||
)
|
offset = [])
|
||||||
|
|
||||||
(options,filenames) = parser.parse_args()
|
(options,filenames) = parser.parse_args()
|
||||||
if filenames == []: filenames = [None]
|
if filenames == []: filenames = [None]
|
||||||
|
@ -43,8 +43,9 @@ for name in filenames:
|
||||||
damask.util.report(scriptName,name)
|
damask.util.report(scriptName,name)
|
||||||
|
|
||||||
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||||
for i,label in enumerate(options.label):
|
for i,label in enumerate(options.labels):
|
||||||
table.set_array(label,table.get_array(label)+float(options.offset[i]),
|
table.set(label,
|
||||||
|
table.get(label)+float(options.offset[i]),
|
||||||
scriptID+' '+' '.join(sys.argv[1:]))
|
scriptID+' '+' '.join(sys.argv[1:]))
|
||||||
|
|
||||||
table.to_ASCII(sys.stdout if name is None else name)
|
table.to_ASCII(sys.stdout if name is None else name)
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from io import StringIO
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
import damask
|
import damask
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,7 +25,7 @@ With coordinates in columns "x", "y", and "z"; sorting with x slowest and z fast
|
||||||
|
|
||||||
|
|
||||||
parser.add_option('-l','--label',
|
parser.add_option('-l','--label',
|
||||||
dest = 'keys',
|
dest = 'labels',
|
||||||
action = 'extend', metavar = '<string LIST>',
|
action = 'extend', metavar = '<string LIST>',
|
||||||
help = 'list of column labels (a,b,c,...)')
|
help = 'list of column labels (a,b,c,...)')
|
||||||
parser.add_option('-r','--reverse',
|
parser.add_option('-r','--reverse',
|
||||||
|
@ -38,42 +37,14 @@ parser.set_defaults(reverse = False,
|
||||||
)
|
)
|
||||||
|
|
||||||
(options,filenames) = parser.parse_args()
|
(options,filenames) = parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
# --- loop over input files -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
if filenames == []: filenames = [None]
|
if filenames == []: filenames = [None]
|
||||||
|
|
||||||
|
if options.labels is None:
|
||||||
|
parser.error('no labels specified.')
|
||||||
for name in filenames:
|
for name in filenames:
|
||||||
try: table = damask.ASCIItable(name = name,
|
|
||||||
buffered = False)
|
|
||||||
except: continue
|
|
||||||
damask.util.report(scriptName,name)
|
damask.util.report(scriptName,name)
|
||||||
|
|
||||||
# ------------------------------------------ assemble header ---------------------------------------
|
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||||
|
table.sort_by(options.labels,not options.reverse)
|
||||||
|
|
||||||
table.head_read()
|
table.to_ASCII(sys.stdout if name is None else name)
|
||||||
table.info_append(scriptID + '\t' + ' '.join(sys.argv[1:]))
|
|
||||||
table.head_write()
|
|
||||||
|
|
||||||
# ------------------------------------------ process data ---------------------------------------
|
|
||||||
|
|
||||||
table.data_readArray()
|
|
||||||
|
|
||||||
keys = table.labels(raw = True)[::-1] if options.keys is None else options.keys[::-1] # numpy sorts with most significant column as last
|
|
||||||
|
|
||||||
cols = []
|
|
||||||
remarks = []
|
|
||||||
for i,column in enumerate(table.label_index(keys)):
|
|
||||||
if column < 0: remarks.append('label "{}" not present...'.format(keys[i]))
|
|
||||||
else: cols += [table.data[:,column]]
|
|
||||||
if remarks != []: damask.util.croak(remarks)
|
|
||||||
|
|
||||||
ind = np.lexsort(cols) if cols != [] else np.arange(table.data.shape[0])
|
|
||||||
if options.reverse: ind = ind[::-1]
|
|
||||||
|
|
||||||
# ------------------------------------------ output result ---------------------------------------
|
|
||||||
|
|
||||||
table.data = table.data[ind]
|
|
||||||
table.data_writeArray()
|
|
||||||
table.close() # close ASCII table
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import random
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
@ -6,40 +7,40 @@ import numpy as np
|
||||||
class Table():
|
class Table():
|
||||||
"""Store spreadsheet-like data."""
|
"""Store spreadsheet-like data."""
|
||||||
|
|
||||||
def __init__(self,array,headings,comments=None):
|
def __init__(self,data,shapes,comments=None):
|
||||||
"""
|
"""
|
||||||
New spreadsheet data.
|
New spreadsheet.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
array : numpy.ndarray
|
data : numpy.ndarray
|
||||||
Data.
|
Data.
|
||||||
headings : dict
|
shapes : dict with str:tuple pairs
|
||||||
Column headings. Labels as keys and shape as tuple. Example 'F':(3,3) for a deformation gradient.
|
Shapes of the columns. Example 'F':(3,3) for a deformation gradient.
|
||||||
comments : iterable of str, optional
|
comments : iterable of str, optional
|
||||||
Additional, human-readable information
|
Additional, human-readable information.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.data = pd.DataFrame(data=array)
|
self.data = pd.DataFrame(data=data)
|
||||||
|
|
||||||
d = {}
|
labels = {}
|
||||||
i = 0
|
i = 0
|
||||||
for label in headings:
|
for label in shapes.keys():
|
||||||
for components in range(np.prod(headings[label])):
|
for components in range(np.prod(shapes[label])):
|
||||||
d[i] = label
|
labels[i] = label
|
||||||
i+=1
|
i+=1
|
||||||
|
|
||||||
if i != self.data.shape[1]:
|
if i != self.data.shape[1]:
|
||||||
raise IndexError('Mismatch between array shape and headings')
|
raise IndexError('Shape mismatch between shapes and data')
|
||||||
|
|
||||||
self.data.rename(columns=d,inplace=True)
|
self.data.rename(columns=labels,inplace=True)
|
||||||
|
|
||||||
if comments is None:
|
if comments is None:
|
||||||
self.comments = []
|
self.comments = []
|
||||||
else:
|
else:
|
||||||
self.comments = [c for c in comments]
|
self.comments = [c for c in comments]
|
||||||
|
|
||||||
self.headings = headings
|
self.shapes = shapes
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_ASCII(fname):
|
def from_ASCII(fname):
|
||||||
|
@ -47,8 +48,8 @@ class Table():
|
||||||
Create table from ASCII file.
|
Create table from ASCII file.
|
||||||
|
|
||||||
The first line needs to indicate the number of subsequent header lines as 'n header'.
|
The first line needs to indicate the number of subsequent header lines as 'n header'.
|
||||||
Vector data labels are indicated by '1_v, 2_v, ..., n_v'.
|
Vector data column labels are indicated by '1_v, 2_v, ..., n_v'.
|
||||||
Tensor data labels are indicated by '3x3:1_T, 3x3:2_T, ..., 3x3:9_T'.
|
Tensor data column labels are indicated by '3x3:1_T, 3x3:2_T, ..., 3x3:9_T'.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
@ -69,93 +70,159 @@ class Table():
|
||||||
comments = [f.readline()[:-1] for i in range(header-1)]
|
comments = [f.readline()[:-1] for i in range(header-1)]
|
||||||
labels = f.readline().split()
|
labels = f.readline().split()
|
||||||
|
|
||||||
headings = {}
|
shapes = {}
|
||||||
for label in labels:
|
for label in labels:
|
||||||
tensor_column = re.search(r'[0-9,x]*?:[0-9]*?_',label)
|
tensor_column = re.search(r'[0-9,x]*?:[0-9]*?_',label)
|
||||||
if tensor_column:
|
if tensor_column:
|
||||||
my_shape = tensor_column.group().split(':',1)[0].split('x')
|
my_shape = tensor_column.group().split(':',1)[0].split('x')
|
||||||
headings[label.split('_',1)[1]] = tuple([int(d) for d in my_shape])
|
shapes[label.split('_',1)[1]] = tuple([int(d) for d in my_shape])
|
||||||
else:
|
else:
|
||||||
vector_column = re.match(r'[0-9]*?_',label)
|
vector_column = re.match(r'[0-9]*?_',label)
|
||||||
if vector_column:
|
if vector_column:
|
||||||
headings[label.split('_',1)[1]] = (int(label.split('_',1)[0]),)
|
shapes[label.split('_',1)[1]] = (int(label.split('_',1)[0]),)
|
||||||
else:
|
else:
|
||||||
headings[label]=(1,)
|
shapes[label]=(1,)
|
||||||
|
|
||||||
return Table(np.loadtxt(f),headings,comments)
|
data = pd.read_csv(f,names=[i for i in range(len(labels))],sep=r'\s+').to_numpy()
|
||||||
|
|
||||||
def get_array(self,label):
|
return Table(data,shapes,comments)
|
||||||
|
|
||||||
|
|
||||||
|
def labels(self):
|
||||||
|
"""Return the labels of all columns."""
|
||||||
|
return list(self.shapes.keys())
|
||||||
|
|
||||||
|
|
||||||
|
def get(self,label):
|
||||||
"""
|
"""
|
||||||
Return data as array.
|
Get column data.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
label : str
|
label : str
|
||||||
Label of the array.
|
Column label.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if re.match(r'[0-9]*?_',label):
|
if re.match(r'[0-9]*?_',label):
|
||||||
idx,key = label.split('_',1)
|
idx,key = label.split('_',1)
|
||||||
return self.data[key].to_numpy()[:,int(idx)-1]
|
return self.data[key].to_numpy()[:,int(idx)-1].reshape((-1,1))
|
||||||
else:
|
else:
|
||||||
return self.data[label].to_numpy().reshape((-1,)+self.headings[label])
|
return self.data[label].to_numpy().reshape((-1,)+self.shapes[label])
|
||||||
|
|
||||||
def set_array(self,label,array,info):
|
def set(self,label,data,info=None):
|
||||||
"""
|
"""
|
||||||
Modify data in the spreadsheet.
|
Set column data.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
label : str
|
label : str
|
||||||
Label for the new data.
|
Column label.
|
||||||
array : np.ndarray
|
data : np.ndarray
|
||||||
New data.
|
New data.
|
||||||
info : str
|
info : str, optional
|
||||||
Human-readable information about the new data.
|
Human-readable information about the new data.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if np.prod(array.shape[1:],dtype=int) == 1:
|
if info is not None:
|
||||||
|
if np.prod(data.shape[1:],dtype=int) == 1:
|
||||||
self.comments.append('{}: {}'.format(label,info))
|
self.comments.append('{}: {}'.format(label,info))
|
||||||
else:
|
else:
|
||||||
self.comments.append('{} {}: {}'.format(label,array.shape[1:],info))
|
self.comments.append('{} {}: {}'.format(label,data.shape[1:],info))
|
||||||
|
|
||||||
if re.match(r'[0-9]*?_',label):
|
if re.match(r'[0-9]*?_',label):
|
||||||
idx,key = label.split('_',1)
|
idx,key = label.split('_',1)
|
||||||
iloc = self.data.columns.get_loc(key).tolist().index(True) + int(idx) -1
|
iloc = self.data.columns.get_loc(key).tolist().index(True) + int(idx) -1
|
||||||
self.data.iloc[:,iloc] = array
|
self.data.iloc[:,iloc] = data
|
||||||
else:
|
else:
|
||||||
self.data[label] = array.reshape(self.data[label].shape)
|
self.data[label] = data.reshape(self.data[label].shape)
|
||||||
|
|
||||||
|
def add(self,label,data,info=None):
|
||||||
def get_labels(self):
|
|
||||||
"""Return the labels of all columns."""
|
|
||||||
return [label for label in self.headings]
|
|
||||||
|
|
||||||
def add_array(self,label,array,info):
|
|
||||||
"""
|
"""
|
||||||
Add data to the spreadsheet.
|
Add column data.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
label : str
|
label : str
|
||||||
Label for the new data.
|
Column label.
|
||||||
array : np.ndarray
|
data : np.ndarray
|
||||||
New data.
|
Modified data.
|
||||||
info : str
|
info : str, optional
|
||||||
Human-readable information about the new data.
|
Human-readable information about the modified data.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if np.prod(array.shape[1:],dtype=int) == 1:
|
if info is not None:
|
||||||
|
if np.prod(data.shape[1:],dtype=int) == 1:
|
||||||
self.comments.append('{}: {}'.format(label,info))
|
self.comments.append('{}: {}'.format(label,info))
|
||||||
else:
|
else:
|
||||||
self.comments.append('{} {}: {}'.format(label,array.shape[1:],info))
|
self.comments.append('{} {}: {}'.format(label,data.shape[1:],info))
|
||||||
|
|
||||||
self.headings[label] = array.shape[1:] if len(array.shape) > 1 else (1,)
|
self.shapes[label] = data.shape[1:] if len(data.shape) > 1 else (1,)
|
||||||
size = np.prod(array.shape[1:],dtype=int)
|
size = np.prod(data.shape[1:],dtype=int)
|
||||||
new_data = pd.DataFrame(data=array.reshape(-1,size),
|
new_data = pd.DataFrame(data=data.reshape(-1,size),
|
||||||
columns=[label for l in range(size)])
|
columns=[label for l in range(size)])
|
||||||
self.data = pd.concat([self.data,new_data],axis=1)
|
self.data = pd.concat([self.data,new_data],axis=1)
|
||||||
|
|
||||||
|
def delete(self,label):
|
||||||
|
"""
|
||||||
|
Delete column data.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
label : str
|
||||||
|
Column label.
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.data.drop(columns=label,inplace=True)
|
||||||
|
|
||||||
|
del self.shapes[label]
|
||||||
|
|
||||||
|
def rename(self,label_old,label_new,info=None):
|
||||||
|
"""
|
||||||
|
Rename column data.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
label_old : str
|
||||||
|
Old column label.
|
||||||
|
label_new : str
|
||||||
|
New column label.
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.data.rename(columns={label_old:label_new},inplace=True)
|
||||||
|
|
||||||
|
comments = '{} => {}'.format(label_old,label_new)
|
||||||
|
comments += ': {}'.format(info) if info is not None else ''
|
||||||
|
self.comments.append(comments)
|
||||||
|
|
||||||
|
self.shapes[label_new] = self.shapes.pop(label_old)
|
||||||
|
|
||||||
|
|
||||||
|
def sort_by(self,labels,ascending=True):
|
||||||
|
"""
|
||||||
|
Get column data.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
label : list of str or str
|
||||||
|
Column labels.
|
||||||
|
ascending : bool, optional
|
||||||
|
Set sort order.
|
||||||
|
|
||||||
|
"""
|
||||||
|
_temp = []
|
||||||
|
_labels = []
|
||||||
|
for label in labels if isinstance(labels,list) else [labels]:
|
||||||
|
if re.match(r'[0-9]*?_',label):
|
||||||
|
_temp.append(str(random.getrandbits(128)))
|
||||||
|
self.add(_temp[-1],self.get(label))
|
||||||
|
_labels.append(_temp[-1])
|
||||||
|
else:
|
||||||
|
_labels.append(label)
|
||||||
|
|
||||||
|
self.data.sort_values(_labels,axis=0,inplace=True,ascending=ascending)
|
||||||
|
for t in _temp: self.delete(t)
|
||||||
|
self.comments.append('sorted by [{}]'.format(', '.join(labels)))
|
||||||
|
|
||||||
def to_ASCII(self,fname):
|
def to_ASCII(self,fname):
|
||||||
"""
|
"""
|
||||||
Store as plain text file.
|
Store as plain text file.
|
||||||
|
@ -167,15 +234,15 @@ class Table():
|
||||||
|
|
||||||
"""
|
"""
|
||||||
labels = []
|
labels = []
|
||||||
for l in self.headings:
|
for l in self.shapes:
|
||||||
if(self.headings[l] == (1,)):
|
if(self.shapes[l] == (1,)):
|
||||||
labels.append('{}'.format(l))
|
labels.append('{}'.format(l))
|
||||||
elif(len(self.headings[l]) == 1):
|
elif(len(self.shapes[l]) == 1):
|
||||||
labels+=['{}_{}'.format(i+1,l)\
|
labels+=['{}_{}'.format(i+1,l)\
|
||||||
for i in range(self.headings[l][0])]
|
for i in range(self.shapes[l][0])]
|
||||||
else:
|
else:
|
||||||
labels+=['{}:{}_{}'.format('x'.join([str(d) for d in self.headings[l]]),i+1,l)\
|
labels+=['{}:{}_{}'.format('x'.join([str(d) for d in self.shapes[l]]),i+1,l)\
|
||||||
for i in range(np.prod(self.headings[l],dtype=int))]
|
for i in range(np.prod(self.shapes[l],dtype=int))]
|
||||||
|
|
||||||
header = ['{} header'.format(len(self.comments)+1)]\
|
header = ['{} header'.format(len(self.comments)+1)]\
|
||||||
+ self.comments\
|
+ self.comments\
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
1 header
|
||||||
|
a b
|
||||||
|
1.0 hallo
|
||||||
|
0.1 "hallo test"
|
|
@ -0,0 +1,6 @@
|
||||||
|
1 header
|
||||||
|
a b 1_c 2_c
|
||||||
|
1 2 3 4
|
||||||
|
5 6 7 8
|
||||||
|
9 10. 12. 12
|
||||||
|
|
|
@ -1,25 +1,40 @@
|
||||||
|
import os
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from damask import Table
|
from damask import Table
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def default():
|
def default():
|
||||||
"""Simple Table."""
|
"""Simple Table."""
|
||||||
x = np.ones((5,13))
|
x = np.ones((5,13))
|
||||||
return Table(x,{'F':(3,3),'v':(3,),'s':(1,)},['test data','contains only ones'])
|
return Table(x,{'F':(3,3),'v':(3,),'s':(1,)},['test data','contains only ones'])
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def reference_dir(reference_dir_base):
|
||||||
|
"""Directory containing reference results."""
|
||||||
|
return os.path.join(reference_dir_base,'Table')
|
||||||
|
|
||||||
class TestTable:
|
class TestTable:
|
||||||
|
|
||||||
def test_get_tensor(self,default):
|
def test_get_scalar(self,default):
|
||||||
d = default.get_array('F')
|
d = default.get('s')
|
||||||
assert np.allclose(d,1.0) and d.shape[1:] == (3,3)
|
assert np.allclose(d,1.0) and d.shape[1:] == (1,)
|
||||||
|
|
||||||
def test_get_vector(self,default):
|
def test_get_vector(self,default):
|
||||||
d = default.get_array('v')
|
d = default.get('v')
|
||||||
assert np.allclose(d,1.0) and d.shape[1:] == (3,)
|
assert np.allclose(d,1.0) and d.shape[1:] == (3,)
|
||||||
|
|
||||||
|
def test_get_tensor(self,default):
|
||||||
|
d = default.get('F')
|
||||||
|
assert np.allclose(d,1.0) and d.shape[1:] == (3,3)
|
||||||
|
|
||||||
|
def test_get_component(self,default):
|
||||||
|
d = default.get('5_F')
|
||||||
|
assert np.allclose(d,1.0) and d.shape[1:] == (1,)
|
||||||
|
|
||||||
def test_write_read_str(self,default,tmpdir):
|
def test_write_read_str(self,default,tmpdir):
|
||||||
default.to_ASCII(str(tmpdir.join('default.txt')))
|
default.to_ASCII(str(tmpdir.join('default.txt')))
|
||||||
new = Table.from_ASCII(str(tmpdir.join('default.txt')))
|
new = Table.from_ASCII(str(tmpdir.join('default.txt')))
|
||||||
|
@ -32,26 +47,75 @@ class TestTable:
|
||||||
new = Table.from_ASCII(f)
|
new = Table.from_ASCII(f)
|
||||||
assert all(default.data==new.data)
|
assert all(default.data==new.data)
|
||||||
|
|
||||||
def test_set_array(self,default):
|
@pytest.mark.parametrize('fname',['datatype-mix.txt','whitespace-mix.txt'])
|
||||||
default.set_array('F',np.zeros((5,3,3)),'set to zero')
|
def test_read_strange(self,reference_dir,fname):
|
||||||
d=default.get_array('F')
|
with open(os.path.join(reference_dir,fname)) as f:
|
||||||
|
Table.from_ASCII(f)
|
||||||
|
|
||||||
|
def test_set(self,default):
|
||||||
|
default.set('F',np.zeros((5,3,3)),'set to zero')
|
||||||
|
d=default.get('F')
|
||||||
assert np.allclose(d,0.0) and d.shape[1:] == (3,3)
|
assert np.allclose(d,0.0) and d.shape[1:] == (3,3)
|
||||||
|
|
||||||
def test_get_labels(self,default):
|
def test_labels(self,default):
|
||||||
assert default.get_labels() == ['F','v','s']
|
assert default.labels() == ['F','v','s']
|
||||||
|
|
||||||
def test_add_array(self,default):
|
def test_add(self,default):
|
||||||
d = np.random.random((5,9))
|
d = np.random.random((5,9))
|
||||||
default.add_array('nine',d,'random data')
|
default.add('nine',d,'random data')
|
||||||
assert np.allclose(d,default.get_array('nine'))
|
assert np.allclose(d,default.get('nine'))
|
||||||
|
|
||||||
|
def test_rename_equivalent(self,default):
|
||||||
|
v = default.get('v')
|
||||||
|
default.rename('v','u')
|
||||||
|
u = default.get('u')
|
||||||
|
assert np.all(v == u)
|
||||||
|
|
||||||
|
def test_rename_gone(self,default):
|
||||||
|
default.rename('v','V')
|
||||||
|
with pytest.raises(KeyError):
|
||||||
|
default.get('v')
|
||||||
|
|
||||||
|
def test_delete(self,default):
|
||||||
|
default.delete('v')
|
||||||
|
with pytest.raises(KeyError):
|
||||||
|
default.get('v')
|
||||||
|
|
||||||
|
|
||||||
def test_invalid_initialization(self,default):
|
def test_invalid_initialization(self,default):
|
||||||
x = default.get_array('v')
|
x = default.get('v')
|
||||||
with pytest.raises(IndexError):
|
with pytest.raises(IndexError):
|
||||||
Table(x,{'F':(3,3)})
|
Table(x,{'F':(3,3)})
|
||||||
|
|
||||||
def test_invalid_set(self,default):
|
def test_invalid_set(self,default):
|
||||||
x = default.get_array('v')
|
x = default.get('v')
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
default.set_array('F',x,'does not work')
|
default.set('F',x,'does not work')
|
||||||
|
|
||||||
|
def test_invalid_get(self,default):
|
||||||
|
with pytest.raises(KeyError):
|
||||||
|
default.get('n')
|
||||||
|
|
||||||
|
def test_sort_scalar(self):
|
||||||
|
x = np.random.random((5,13))
|
||||||
|
t = Table(x,{'F':(3,3),'v':(3,),'s':(1,)},['random test data'])
|
||||||
|
unsort = t.get('s')
|
||||||
|
t.sort_by('s')
|
||||||
|
sort = t.get('s')
|
||||||
|
assert np.all(np.sort(unsort,0)==sort)
|
||||||
|
|
||||||
|
def test_sort_component(self):
|
||||||
|
x = np.random.random((5,12))
|
||||||
|
t = Table(x,{'F':(3,3),'v':(3,)},['random test data'])
|
||||||
|
unsort = t.get('4_F')
|
||||||
|
t.sort_by('4_F')
|
||||||
|
sort = t.get('4_F')
|
||||||
|
assert np.all(np.sort(unsort,0)==sort)
|
||||||
|
|
||||||
|
def test_sort_revert(self):
|
||||||
|
x = np.random.random((5,12))
|
||||||
|
t = Table(x,{'F':(3,3),'v':(3,)},['random test data'])
|
||||||
|
t.sort_by('4_F',False)
|
||||||
|
sort = t.get('4_F')
|
||||||
|
assert np.all(np.sort(sort,0)==sort[::-1,:])
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue