Merge branch 'new-ASCII' into grid-filters

This commit is contained in:
Martin Diehl 2019-12-05 10:50:56 +01:00
commit 274aaa7359
14 changed files with 280 additions and 227 deletions

View File

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

View File

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

View File

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

View File

@ -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, damask.util.report(scriptName,name)
buffered = False)
except: continue
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

View File

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

View File

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

View File

@ -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, damask.util.report(scriptName,name)
buffered = False)
except: continue
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

View File

@ -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,
scriptID+' '+' '.join(sys.argv[1:])) table.get(label)*float(options.factor[i]),
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)

View File

@ -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,
scriptID+' '+' '.join(sys.argv[1:])) table.get(label)+float(options.offset[i]),
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)

View File

@ -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, damask.util.report(scriptName,name)
buffered = False)
except: continue
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

View File

@ -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:
self.comments.append('{}: {}'.format(label,info)) if np.prod(data.shape[1:],dtype=int) == 1:
else: self.comments.append('{}: {}'.format(label,info))
self.comments.append('{} {}: {}'.format(label,array.shape[1:],info)) else:
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:
self.comments.append('{}: {}'.format(label,info)) if np.prod(data.shape[1:],dtype=int) == 1:
else: self.comments.append('{}: {}'.format(label,info))
self.comments.append('{} {}: {}'.format(label,array.shape[1:],info)) else:
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\

View File

@ -0,0 +1,4 @@
1 header
a b
1.0 hallo
0.1 "hallo test"

View File

@ -0,0 +1,6 @@
1 header
a b 1_c 2_c
1 2 3 4
5 6 7 8
9 10. 12. 12

View File

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