dropped support for legacy table
This commit is contained in:
Martin Diehl 2021-03-27 10:10:35 +01:00
parent 111a1a76c6
commit be9e00347b
24 changed files with 98 additions and 96 deletions

View File

@ -1,7 +1,9 @@
SHELL = /bin/sh
########################################################################################
# Makefile for the installation of DAMASK
########################################################################################
###################################################################################################
# One-command-build invoking CMake (meant for developers, should not be part of the distribution)
###################################################################################################
.PHONY: all
all: grid mesh

View File

@ -39,20 +39,20 @@ class Colormap(mpl.colors.ListedColormap):
"""
def __add__(self,other):
"""Concatenate colormaps."""
"""Concatenate."""
return Colormap(np.vstack((self.colors,other.colors)),
f'{self.name}+{other.name}')
def __iadd__(self,other):
"""Concatenate colormaps."""
"""Concatenate (in-place)."""
return self.__add__(other)
def __invert__(self):
"""Return inverted colormap."""
"""Reverse."""
return self.reversed()
def __repr__(self):
"""Show colormap as matplotlib figure."""
"""Show as matplotlib figure."""
fig = plt.figure(self.name,figsize=(5,.5))
ax1 = fig.add_axes([0, 0, 1, 1])
ax1.set_axis_off()
@ -207,7 +207,7 @@ class Colormap(mpl.colors.ListedColormap):
def reversed(self,name=None):
"""
Make a reversed instance of the colormap.
Reverse.
Parameters
----------

View File

@ -31,7 +31,7 @@ class NiceDumper(yaml.SafeDumper):
return super().represent_data(data)
def ignore_aliases(self, data):
"""No references."""
"""Do not use references to existing objects."""
return True
class Config(dict):

View File

@ -9,14 +9,29 @@ from . import Orientation
from . import util
class ConfigMaterial(Config):
"""Material configuration."""
"""
Material configuration.
Manipulate material configurations for storage in YAML format.
A complete material configuration file has the entries 'material',
'phase', and 'homogenization'. For use in DAMASK, it needs to be
stored as 'material.yaml'.
"""
_defaults = {'material': [],
'homogenization': {},
'phase': {}}
def __init__(self,d=_defaults):
"""Initialize object with default dictionary keys."""
"""
New material configuration.
Parameters
----------
d : dictionary, optional
Initial content. Defaults to empty material, homogenization, and phase entries.
"""
super().__init__(d)

View File

@ -17,11 +17,18 @@ from . import Rotation
class Grid:
"""Geometry definition for grid solvers."""
"""
Geometry definition for grid solvers.
Create and manipulate geometry definitions for storage as VTK
rectiliear grid files ('.vtr' extension). A grid contains the
material ID (referring to the entry in 'material.yaml') and
the physical size.
"""
def __init__(self,material,size,origin=[0.0,0.0,0.0],comments=[]):
"""
New grid definition from array of materials, size, and origin.
New geometry definition for grid solvers.
Parameters
----------

View File

@ -47,19 +47,30 @@ class Orientation(Rotation):
The Bravais lattice is one of Orientation.lattice_symmetries:
- aP : triclinic primitive
- mP : monoclinic primitive
- mS : ... base-centered
- oP : orthorhombic primitive
- oS : ... base-centered
- oI : ... body-centered
- oF : ... face-centered
- tP : tetragonal primitive
- tI : ... body-centered
- hP : hexagonal primitive
- cP : cubic primitive
- cI : ... body-centered
- cF : ... face-centered
- triclinic
- aP : primitive
- monoclininic
- mP : primitive
- mS : base-centered
- orthorhombic
- oP : primitive
- oS : base-centered
- oI : body-centered
- oF : face-centered
- tetragonal
- tP : primitive
- tI : body-centered
- hexagonal
- hP : primitive
- cubic
- cP : primitive
- cI : body-centered
- cF : face-centered
and inherits the corresponding crystal family.
Specifying a Bravais lattice, compared to just the crystal family,
@ -111,7 +122,7 @@ class Orientation(Rotation):
alpha = None,beta = None,gamma = None,
degrees = False):
"""
Initialize orientation object.
New orientation.
Parameters
----------

View File

@ -26,14 +26,14 @@ h5py3 = h5py.__version__[0] == '3'
class Result:
"""
Read and write to DADF5 files.
Manipulate and read DADF5 files.
DADF5 (DAMASK HDF5) files contain DAMASK results.
"""
def __init__(self,fname):
"""
Open an existing DADF5 file.
New result view bound to a HDF5 file.
Parameters
----------

View File

@ -51,7 +51,7 @@ class Rotation:
def __init__(self,rotation = np.array([1.0,0.0,0.0,0.0])):
"""
Initialize rotation object.
New rotation.
Parameters
----------
@ -140,7 +140,7 @@ class Rotation:
def __len__(self):
"""Length of leading/leftmost dimension of Rotation array."""
"""Length of leading/leftmost dimension of array."""
return 0 if self.shape == () else self.shape[0]
@ -180,7 +180,7 @@ class Rotation:
def __mul__(self,other):
"""
Compose this rotation with other.
Compose with other.
Parameters
----------
@ -206,7 +206,7 @@ class Rotation:
def __imul__(self,other):
"""
Compose this rotation with other (in-place).
Compose with other (in-place).
Parameters
----------
@ -219,7 +219,7 @@ class Rotation:
def __truediv__(self,other):
"""
Compose this rotation with inverse of other.
Compose with inverse of other.
Parameters
----------
@ -239,7 +239,7 @@ class Rotation:
def __itruediv__(self,other):
"""
Compose this rotation with inverse of other (in-place).
Compose with inverse of other (in-place).
Parameters
----------
@ -252,7 +252,7 @@ class Rotation:
def __matmul__(self,other):
"""
Rotation of vector, second order tensor, or fourth order tensor.
Rotate vector, second order tensor, or fourth order tensor.
Parameters
----------
@ -301,7 +301,7 @@ class Rotation:
def append(self,other):
"""
Extend rotation array along first dimension with other array(s).
Extend array along first dimension with other array(s).
Parameters
----------
@ -313,19 +313,19 @@ class Rotation:
def flatten(self,order = 'C'):
"""Flatten quaternion array."""
"""Flatten array."""
return self.copy(rotation=self.quaternion.reshape((-1,4),order=order))
def reshape(self,shape,order = 'C'):
"""Reshape quaternion array."""
"""Reshape array."""
if isinstance(shape,(int,np.integer)): shape = (shape,)
return self.copy(rotation=self.quaternion.reshape(tuple(shape)+(4,),order=order))
def broadcast_to(self,shape,mode = 'right'):
"""
Broadcast quaternion array to shape.
Broadcast array.
Parameters
----------
@ -343,7 +343,7 @@ class Rotation:
def average(self,weights = None):
"""
Average rotations along last dimension.
Average along last array dimension.
Parameters
----------
@ -382,7 +382,7 @@ class Rotation:
def misorientation(self,other):
"""
Calculate misorientation from self to other Rotation.
Calculate misorientation to other Rotation.
Parameters
----------

View File

@ -7,7 +7,7 @@ import numpy as np
from . import util
class Table:
"""Store spreadsheet-like data."""
"""Manipulate multi-dimensional spreadsheet-like data."""
def __init__(self,data,shapes,comments=None):
"""
@ -77,13 +77,11 @@ class Table:
"""
Load from ASCII table file.
In legacy style, the first line indicates the number of
subsequent header lines as "N header", with the last header line being
interpreted as column labels.
Alternatively, initial comments are marked by '#', with the first non-comment line
Initial comments are marked by '#', the first non-comment line
containing the column labels.
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'.
- 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
----------
@ -97,21 +95,13 @@ class Table:
f = fname
f.seek(0)
try:
N_comment_lines,keyword = f.readline().strip().split(maxsplit=1)
if keyword != 'header':
raise ValueError
else:
comments = [f.readline().strip() for i in range(1,int(N_comment_lines))]
labels = f.readline().split()
except ValueError:
f.seek(0)
comments = []
f.seek(0)
comments = []
line = f.readline().strip()
while line.startswith('#'):
comments.append(line.lstrip('#').strip())
line = f.readline().strip()
while line.startswith('#'):
comments.append(line.lstrip('#').strip())
line = f.readline().strip()
labels = line.split()
labels = line.split()
shapes = {}
for label in labels:
@ -391,7 +381,7 @@ class Table:
return dup
def save(self,fname,legacy=False):
def save(self,fname):
"""
Save as plain text file.
@ -399,9 +389,6 @@ class Table:
----------
fname : file, str, or pathlib.Path
Filename or file for writing.
legacy : Boolean, optional
Write table in legacy style, indicating header lines by "N header"
in contrast to using comment sign ('#') at beginning of lines.
"""
seen = set()
@ -416,13 +403,10 @@ class Table:
labels += [f'{util.srepr(self.shapes[l],"x")}:{i+1}_{l}' \
for i in range(np.prod(self.shapes[l]))]
header = ([f'{len(self.comments)+1} header'] + self.comments) if legacy else \
[f'# {comment}' for comment in self.comments]
try:
fhandle = open(fname,'w',newline='\n')
except TypeError:
fhandle = fname
for line in header + [' '.join(labels)]: fhandle.write(line+'\n')
fhandle.write('\n'.join([f'# {c}' for c in self.comments] + [' '.join(labels)])+'\n')
self.data.to_csv(fhandle,sep=' ',na_rep='nan',index=False,header=False)

View File

@ -22,7 +22,7 @@ class VTK:
def __init__(self,vtk_data):
"""
Initialize from vtk dataset.
New spatial visualization.
Parameters
----------

View File

@ -153,10 +153,12 @@ def scale_to_coprime(v):
"""Denominator of the square of a number."""
return fractions.Fraction(x ** 2).limit_denominator(MAX_DENOMINATOR).denominator
def lcm(a, b):
def lcm(a,b):
"""Least common multiple."""
# Python 3.9 provides math.lcm, see https://stackoverflow.com/questions/51716916.
return a * b // np.gcd(a, b)
try:
return np.lcm(a,b) # numpy > 1.18
except AttributeError:
return a * b // np.gcd(a, b)
m = (np.array(v) * reduce(lcm, map(lambda x: int(get_square_denominator(x)),v)) ** 0.5).astype(int)
m = m//reduce(np.gcd,m)
@ -405,7 +407,7 @@ class return_message:
def __init__(self,message):
"""
Sets return message.
Set return message.
Parameters
----------
@ -429,7 +431,7 @@ class _ProgressBar:
def __init__(self,total,prefix,bar_length):
"""
Inititalize a progress bar to current time as basis for ETA estimation.
Set current time as basis for ETA estimation.
Parameters
----------

View File

@ -1,4 +1,3 @@
1 header
1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos
180.0 45.00000000000001 180.0 1 1
270.0 45.00000000000001 90.0 1 2

View File

@ -1,4 +1,3 @@
1 header
1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos
146.75362934444064 9.976439066337804 256.395594327347 1 1
356.59977719102034 43.39784965440254 12.173896584899929 1 2

View File

@ -1,4 +1,3 @@
1 header
1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos
166.39559432734697 9.976439066337804 236.75362934444058 1 1
352.1156357053931 43.82007387041961 14.074783631236542 1 2

View File

@ -1,4 +1,3 @@
1 header
1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos
114.20342833932975 10.52877936550932 204.20342833932972 1 1
94.3573968784815 80.40593177313954 311.22729452432543 1 2

View File

@ -1,4 +1,3 @@
1 header
1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos
96.91733794010702 83.13253115922213 314.5844440567886 1 1
173.082662059893 83.13253115922211 45.41555594321143 1 2

View File

@ -1,4 +1,3 @@
1 header
1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos
135.41555594321144 83.13253115922213 173.082662059893 1 1
260.26438968275465 90.0 135.0 1 2

View File

@ -1,4 +1,3 @@
1 header
1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos
0.0 45.00000000000001 0.0 1 1
90.0 45.00000000000001 270.0 1 2

View File

@ -1,4 +1,3 @@
1 header
1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos
283.60440567265294 9.976439066337804 33.24637065555936 1 1
167.8261034151001 43.397849654402556 183.40022280897963 1 2

View File

@ -1,4 +1,3 @@
1 header
1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos
303.24637065555936 9.976439066337804 13.604405672652977 1 1
165.92521636876344 43.82007387041961 187.88436429460683 1 2

View File

@ -1,4 +1,3 @@
1 header
1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos
335.7965716606702 10.528779365509317 65.79657166067024 1 1
228.77270547567446 80.40593177313953 85.64260312151849 1 2

View File

@ -1,4 +1,3 @@
1 header
1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos
225.41555594321144 83.13253115922213 83.08266205989301 1 1
134.58444405678856 83.13253115922211 6.917337940107012 1 2

View File

@ -1,4 +1,3 @@
1 header
1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos
6.9173379401070045 83.13253115922213 44.58444405678856 1 1
45.0 89.99999999999999 279.7356103172453 1 2

View File

@ -60,13 +60,6 @@ class TestTable:
new = Table.load(f)
assert all(default.data==new.data) and default.shapes == new.shapes
def test_write_read_legacy_style(self,default,tmp_path):
with open(tmp_path/'legacy.txt','w') as f:
default.save(f,legacy=True)
with open(tmp_path/'legacy.txt') as f:
new = Table.load(f)
assert all(default.data==new.data) and default.shapes == new.shapes
def test_write_invalid_format(self,default,tmp_path):
with pytest.raises(TypeError):
default.save(tmp_path/'shouldnotbethere.txt',format='invalid')