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)
|
||||
|
||||
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||
table.add_array('Cauchy',
|
||||
damask.mechanics.Cauchy(table.get_array(options.defgrad).reshape(-1,3,3),
|
||||
table.get_array(options.stress).reshape(-1,3,3)).reshape(-1,9),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
table.add('Cauchy',
|
||||
damask.mechanics.Cauchy(table.get(options.defgrad).reshape(-1,3,3),
|
||||
table.get(options.stress ).reshape(-1,3,3)).reshape(-1,9),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
|
||||
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)
|
||||
for tensor in options.tensor:
|
||||
table.add_array('det({})'.format(tensor),
|
||||
np.linalg.det(table.get_array(tensor).reshape(-1,3,3)),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
table.add('det({})'.format(tensor),
|
||||
np.linalg.det(table.get(tensor).reshape(-1,3,3)),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
|
||||
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)
|
||||
for tensor in options.tensor:
|
||||
table.add_array('dev({})'.format(tensor),
|
||||
damask.mechanics.deviatoric_part(table.get_array(tensor).reshape(-1,3,3)).reshape((-1,9)),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
table.add('dev({})'.format(tensor),
|
||||
damask.mechanics.deviatoric_part(table.get(tensor).reshape(-1,3,3)).reshape((-1,9)),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
if options.spherical:
|
||||
table.add_array('sph({})'.format(tensor),
|
||||
damask.mechanics.spherical_part(table.get_array(tensor).reshape(-1,3,3)),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
table.add('sph({})'.format(tensor),
|
||||
damask.mechanics.spherical_part(table.get(tensor).reshape(-1,3,3)),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
from io import StringIO
|
||||
from optparse import OptionParser
|
||||
|
||||
import damask
|
||||
|
@ -24,35 +26,16 @@ parser.add_option('-i',
|
|||
dest = 'info', action = 'extend', metavar = '<string LIST>',
|
||||
help = 'items to add')
|
||||
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
if options.info is None:
|
||||
parser.error('no info specified.')
|
||||
|
||||
# --- loop over input files ------------------------------------------------------------------------
|
||||
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
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.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
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -45,12 +45,12 @@ for name in filenames:
|
|||
|
||||
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||
for strain in options.strain:
|
||||
table.add_array('Mises({})'.format(strain),
|
||||
damask.mechanics.Mises_strain(damask.mechanics.symmetric(table.get_array(strain).reshape(-1,3,3))),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
table.add('Mises({})'.format(strain),
|
||||
damask.mechanics.Mises_strain(damask.mechanics.symmetric(table.get(strain).reshape(-1,3,3))),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
for stress in options.stress:
|
||||
table.add_array('Mises({})'.format(stress),
|
||||
damask.mechanics.Mises_stress(damask.mechanics.symmetric(table.get_array(stress).reshape(-1,3,3))),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
table.add('Mises({})'.format(stress),
|
||||
damask.mechanics.Mises_stress(damask.mechanics.symmetric(table.get(stress).reshape(-1,3,3))),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
|
||||
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.add_array('S',
|
||||
damask.mechanics.PK2(table.get_array(options.defgrad).reshape(-1,3,3),
|
||||
table.get_array(options.stress).reshape(-1,3,3)).reshape(-1,9),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
table.add('S',
|
||||
damask.mechanics.PK2(table.get(options.defgrad).reshape(-1,3,3),
|
||||
table.get(options.stress ).reshape(-1,3,3)).reshape(-1,9),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
import os
|
||||
import sys
|
||||
from io import StringIO
|
||||
from optparse import OptionParser
|
||||
import re
|
||||
|
||||
import damask
|
||||
|
||||
|
@ -35,62 +35,18 @@ parser.set_defaults(label = [],
|
|||
)
|
||||
|
||||
(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 len(options.label) != len(options.substitute):
|
||||
parser.error('number of column labels and substitutes do not match.')
|
||||
|
||||
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()
|
||||
|
||||
# ------------------------------------------ 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
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -22,7 +22,7 @@ Uniformly scale column values by given factor.
|
|||
""", version = scriptID)
|
||||
|
||||
parser.add_option('-l','--label',
|
||||
dest = 'label',
|
||||
dest = 'labels',
|
||||
action = 'extend', metavar = '<string LIST>',
|
||||
help ='column(s) to scale')
|
||||
parser.add_option('-f','--factor',
|
||||
|
@ -31,7 +31,7 @@ parser.add_option('-f','--factor',
|
|||
help = 'factor(s) per column')
|
||||
|
||||
parser.set_defaults(label = [],
|
||||
)
|
||||
factor = [])
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
if filenames == []: filenames = [None]
|
||||
|
@ -43,8 +43,9 @@ for name in filenames:
|
|||
damask.util.report(scriptName,name)
|
||||
|
||||
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||
for i,label in enumerate(options.label):
|
||||
table.set_array(label,table.get_array(label)*float(options.factor[i]),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
for i,label in enumerate(options.labels):
|
||||
table.set(label,
|
||||
table.get(label)*float(options.factor[i]),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -22,7 +22,7 @@ Uniformly shift column values by given offset.
|
|||
""", version = scriptID)
|
||||
|
||||
parser.add_option('-l','--label',
|
||||
dest = 'label',
|
||||
dest = 'labels',
|
||||
action = 'extend', metavar = '<string LIST>',
|
||||
help ='column(s) to shift')
|
||||
parser.add_option('-o','--offset',
|
||||
|
@ -31,7 +31,7 @@ parser.add_option('-o','--offset',
|
|||
help = 'offset(s) per column')
|
||||
|
||||
parser.set_defaults(label = [],
|
||||
)
|
||||
offset = [])
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
if filenames == []: filenames = [None]
|
||||
|
@ -43,8 +43,9 @@ for name in filenames:
|
|||
damask.util.report(scriptName,name)
|
||||
|
||||
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||
for i,label in enumerate(options.label):
|
||||
table.set_array(label,table.get_array(label)+float(options.offset[i]),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
for i,label in enumerate(options.labels):
|
||||
table.set(label,
|
||||
table.get(label)+float(options.offset[i]),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
|
||||
import os
|
||||
import sys
|
||||
from io import StringIO
|
||||
from optparse import OptionParser
|
||||
|
||||
import numpy as np
|
||||
|
||||
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',
|
||||
dest = 'keys',
|
||||
dest = 'labels',
|
||||
action = 'extend', metavar = '<string LIST>',
|
||||
help = 'list of column labels (a,b,c,...)')
|
||||
parser.add_option('-r','--reverse',
|
||||
|
@ -38,42 +37,14 @@ parser.set_defaults(reverse = False,
|
|||
)
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
|
||||
|
||||
# --- loop over input files -------------------------------------------------------------------------
|
||||
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
if options.labels is None:
|
||||
parser.error('no labels specified.')
|
||||
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.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
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import random
|
||||
import re
|
||||
|
||||
import pandas as pd
|
||||
|
@ -6,40 +7,40 @@ import numpy as np
|
|||
class Table():
|
||||
"""Store spreadsheet-like data."""
|
||||
|
||||
def __init__(self,array,headings,comments=None):
|
||||
def __init__(self,data,shapes,comments=None):
|
||||
"""
|
||||
New spreadsheet data.
|
||||
New spreadsheet.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
array : numpy.ndarray
|
||||
data : numpy.ndarray
|
||||
Data.
|
||||
headings : dict
|
||||
Column headings. Labels as keys and shape as tuple. Example 'F':(3,3) for a deformation gradient.
|
||||
shapes : dict with str:tuple pairs
|
||||
Shapes of the columns. Example 'F':(3,3) for a deformation gradient.
|
||||
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
|
||||
for label in headings:
|
||||
for components in range(np.prod(headings[label])):
|
||||
d[i] = label
|
||||
for label in shapes.keys():
|
||||
for components in range(np.prod(shapes[label])):
|
||||
labels[i] = label
|
||||
i+=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:
|
||||
self.comments = []
|
||||
else:
|
||||
self.comments = [c for c in comments]
|
||||
|
||||
self.headings = headings
|
||||
self.shapes = shapes
|
||||
|
||||
@staticmethod
|
||||
def from_ASCII(fname):
|
||||
|
@ -47,8 +48,8 @@ class Table():
|
|||
Create table from ASCII file.
|
||||
|
||||
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'.
|
||||
Tensor data labels are indicated by '3x3:1_T, 3x3:2_T, ..., 3x3:9_T'.
|
||||
Vector data column labels are indicated by '1_v, 2_v, ..., n_v'.
|
||||
Tensor data column labels are indicated by '3x3:1_T, 3x3:2_T, ..., 3x3:9_T'.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -69,93 +70,159 @@ class Table():
|
|||
comments = [f.readline()[:-1] for i in range(header-1)]
|
||||
labels = f.readline().split()
|
||||
|
||||
headings = {}
|
||||
shapes = {}
|
||||
for label in labels:
|
||||
tensor_column = re.search(r'[0-9,x]*?:[0-9]*?_',label)
|
||||
if tensor_column:
|
||||
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:
|
||||
vector_column = re.match(r'[0-9]*?_',label)
|
||||
if vector_column:
|
||||
headings[label.split('_',1)[1]] = (int(label.split('_',1)[0]),)
|
||||
shapes[label.split('_',1)[1]] = (int(label.split('_',1)[0]),)
|
||||
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()
|
||||
|
||||
return Table(data,shapes,comments)
|
||||
|
||||
def get_array(self,label):
|
||||
|
||||
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
|
||||
----------
|
||||
label : str
|
||||
Label of the array.
|
||||
Column label.
|
||||
|
||||
"""
|
||||
if re.match(r'[0-9]*?_',label):
|
||||
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:
|
||||
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
|
||||
----------
|
||||
label : str
|
||||
Label for the new data.
|
||||
array : np.ndarray
|
||||
Column label.
|
||||
data : np.ndarray
|
||||
New data.
|
||||
info : str
|
||||
info : str, optional
|
||||
Human-readable information about the new data.
|
||||
|
||||
"""
|
||||
if np.prod(array.shape[1:],dtype=int) == 1:
|
||||
self.comments.append('{}: {}'.format(label,info))
|
||||
else:
|
||||
self.comments.append('{} {}: {}'.format(label,array.shape[1:],info))
|
||||
if info is not None:
|
||||
if np.prod(data.shape[1:],dtype=int) == 1:
|
||||
self.comments.append('{}: {}'.format(label,info))
|
||||
else:
|
||||
self.comments.append('{} {}: {}'.format(label,data.shape[1:],info))
|
||||
|
||||
if re.match(r'[0-9]*?_',label):
|
||||
idx,key = label.split('_',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:
|
||||
self.data[label] = array.reshape(self.data[label].shape)
|
||||
self.data[label] = data.reshape(self.data[label].shape)
|
||||
|
||||
|
||||
def get_labels(self):
|
||||
"""Return the labels of all columns."""
|
||||
return [label for label in self.headings]
|
||||
|
||||
def add_array(self,label,array,info):
|
||||
def add(self,label,data,info=None):
|
||||
"""
|
||||
Add data to the spreadsheet.
|
||||
Add column data.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
label : str
|
||||
Label for the new data.
|
||||
array : np.ndarray
|
||||
New data.
|
||||
info : str
|
||||
Human-readable information about the new data.
|
||||
Column label.
|
||||
data : np.ndarray
|
||||
Modified data.
|
||||
info : str, optional
|
||||
Human-readable information about the modified data.
|
||||
|
||||
"""
|
||||
if np.prod(array.shape[1:],dtype=int) == 1:
|
||||
self.comments.append('{}: {}'.format(label,info))
|
||||
else:
|
||||
self.comments.append('{} {}: {}'.format(label,array.shape[1:],info))
|
||||
if info is not None:
|
||||
if np.prod(data.shape[1:],dtype=int) == 1:
|
||||
self.comments.append('{}: {}'.format(label,info))
|
||||
else:
|
||||
self.comments.append('{} {}: {}'.format(label,data.shape[1:],info))
|
||||
|
||||
self.headings[label] = array.shape[1:] if len(array.shape) > 1 else (1,)
|
||||
size = np.prod(array.shape[1:],dtype=int)
|
||||
new_data = pd.DataFrame(data=array.reshape(-1,size),
|
||||
self.shapes[label] = data.shape[1:] if len(data.shape) > 1 else (1,)
|
||||
size = np.prod(data.shape[1:],dtype=int)
|
||||
new_data = pd.DataFrame(data=data.reshape(-1,size),
|
||||
columns=[label for l in range(size)])
|
||||
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):
|
||||
"""
|
||||
Store as plain text file.
|
||||
|
@ -167,15 +234,15 @@ class Table():
|
|||
|
||||
"""
|
||||
labels = []
|
||||
for l in self.headings:
|
||||
if(self.headings[l] == (1,)):
|
||||
for l in self.shapes:
|
||||
if(self.shapes[l] == (1,)):
|
||||
labels.append('{}'.format(l))
|
||||
elif(len(self.headings[l]) == 1):
|
||||
elif(len(self.shapes[l]) == 1):
|
||||
labels+=['{}_{}'.format(i+1,l)\
|
||||
for i in range(self.headings[l][0])]
|
||||
for i in range(self.shapes[l][0])]
|
||||
else:
|
||||
labels+=['{}:{}_{}'.format('x'.join([str(d) for d in self.headings[l]]),i+1,l)\
|
||||
for i in range(np.prod(self.headings[l],dtype=int))]
|
||||
labels+=['{}:{}_{}'.format('x'.join([str(d) for d in self.shapes[l]]),i+1,l)\
|
||||
for i in range(np.prod(self.shapes[l],dtype=int))]
|
||||
|
||||
header = ['{} header'.format(len(self.comments)+1)]\
|
||||
+ 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,24 +1,39 @@
|
|||
import os
|
||||
|
||||
import pytest
|
||||
import numpy as np
|
||||
|
||||
from damask import Table
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def default():
|
||||
"""Simple Table."""
|
||||
x = np.ones((5,13))
|
||||
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:
|
||||
|
||||
def test_get_tensor(self,default):
|
||||
d = default.get_array('F')
|
||||
assert np.allclose(d,1.0) and d.shape[1:] == (3,3)
|
||||
def test_get_scalar(self,default):
|
||||
d = default.get('s')
|
||||
assert np.allclose(d,1.0) and d.shape[1:] == (1,)
|
||||
|
||||
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,)
|
||||
|
||||
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):
|
||||
default.to_ASCII(str(tmpdir.join('default.txt')))
|
||||
|
@ -31,27 +46,76 @@ class TestTable:
|
|||
with open(tmpdir.join('default.txt')) as f:
|
||||
new = Table.from_ASCII(f)
|
||||
assert all(default.data==new.data)
|
||||
|
||||
@pytest.mark.parametrize('fname',['datatype-mix.txt','whitespace-mix.txt'])
|
||||
def test_read_strange(self,reference_dir,fname):
|
||||
with open(os.path.join(reference_dir,fname)) as f:
|
||||
Table.from_ASCII(f)
|
||||
|
||||
def test_set_array(self,default):
|
||||
default.set_array('F',np.zeros((5,3,3)),'set to zero')
|
||||
d=default.get_array('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)
|
||||
|
||||
def test_get_labels(self,default):
|
||||
assert default.get_labels() == ['F','v','s']
|
||||
def test_labels(self,default):
|
||||
assert default.labels() == ['F','v','s']
|
||||
|
||||
def test_add_array(self,default):
|
||||
def test_add(self,default):
|
||||
d = np.random.random((5,9))
|
||||
default.add_array('nine',d,'random data')
|
||||
assert np.allclose(d,default.get_array('nine'))
|
||||
default.add('nine',d,'random data')
|
||||
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):
|
||||
x = default.get_array('v')
|
||||
x = default.get('v')
|
||||
with pytest.raises(IndexError):
|
||||
Table(x,{'F':(3,3)})
|
||||
|
||||
def test_invalid_set(self,default):
|
||||
x = default.get_array('v')
|
||||
x = default.get('v')
|
||||
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