From 4dae3643c9c57127830b04126e279699625a41a1 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 20 Jun 2020 17:15:13 +0200 Subject: [PATCH] vectorized IPF color working results also uses the vectorized form. Still needs careful checking --- python/damask/_orientation.py | 30 +++++++++++++++++++----------- python/damask/_result.py | 21 ++++++++------------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 794bf9900..1704987b4 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -3,7 +3,7 @@ import numpy as np from . import Lattice from . import Rotation -class Orientation: # make subclass or Rotation? +class Orientation: # ToDo: make subclass of lattice and Rotation """ Crystallographic orientation. @@ -105,12 +105,14 @@ class Orientation: # make subclass or Rotation? is added to the left of the rotation array. """ - symmetry_operations = self.lattice.symmetry.symmetry_operations + s = self.lattice.symmetry.symmetry_operations + s = s.reshape(s.shape[:1]+(1,)*len(self.rotation.shape)+(4,)) + s = Rotation(np.broadcast_to(s,s.shape[:1]+self.rotation.quaternion.shape)) - q = np.block([self.rotation.quaternion]*symmetry_operations.shape[0]) - r = Rotation(q.reshape(symmetry_operations.shape+self.rotation.quaternion.shape)) + r = np.broadcast_to(self.rotation.quaternion,s.shape[:1]+self.rotation.quaternion.shape) + r = Rotation(r) - return self.__class__(symmetry_operations.broadcast_to(r.shape)@r,self.lattice) + return self.__class__(s@r,self.lattice) def equivalentOrientations(self,members=[]): @@ -156,10 +158,10 @@ class Orientation: # make subclass or Rotation? """Axis rotated according to orientation (using crystal symmetry to ensure location falls into SST).""" if SST: # pole requested to be within SST for i,o in enumerate(self.equivalentOrientations()): # test all symmetric equivalent quaternions - pole = o.rotation*axis # align crystal direction to axis + pole = o.rotation@axis # align crystal direction to axis if self.lattice.symmetry.inSST(pole,proper): break # found SST version else: - pole = self.rotation*axis # align crystal direction to axis + pole = self.rotation@axis # align crystal direction to axis return (pole,i if SST else 0) @@ -169,7 +171,7 @@ class Orientation: # make subclass or Rotation? color = np.zeros(3,'d') for o in self.equivalentOrientations(): - pole = o.rotation*axis # align crystal direction to axis + pole = o.rotation@axis # align crystal direction to axis inSST,color = self.lattice.symmetry.inSST(pole,color=True) if inSST: break @@ -178,12 +180,18 @@ class Orientation: # make subclass or Rotation? def IPF_color(self,axis): """TSL color of inverse pole figure for given axis.""" - color = np.zeros(self.rotation.shape) eq = self.equivalent - pole = eq.rotation @ np.broadcast_to(axis,eq.rotation.shape+(3,)) + pole = eq.rotation @ np.broadcast_to(axis/np.linalg.norm(axis),eq.rotation.shape+(3,)) in_SST, color = self.lattice.symmetry.in_SST(pole,color=True) - return color[in_SST] + # ignore duplicates (occur for highly symmetric orientations) + found = np.zeros_like(in_SST[1],dtype=bool) + c = np.empty(color.shape[1:]) + for s in range(in_SST.shape[0]): + c = np.where(np.expand_dims(np.logical_and(in_SST[s],~found),-1),color[s],c) + found = np.logical_or(in_SST[s],found) + + return c @staticmethod diff --git a/python/damask/_result.py b/python/damask/_result.py index 56c0eac17..e6dac9370 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -10,6 +10,7 @@ from functools import partial import h5py import numpy as np +from numpy.lib import recfunctions as rfn from . import VTK from . import Table @@ -267,7 +268,7 @@ class Result: def rename(self,name_old,name_new): """ Rename datasets. - + Parameters ---------- name_old : str @@ -733,23 +734,17 @@ class Result: @staticmethod def _add_IPFcolor(q,l): - d = np.array(l) - d_unit = d/np.linalg.norm(d) - m = util.scale_to_coprime(d) - colors = np.empty((len(q['data']),3),np.uint8) + m = util.scale_to_coprime(np.array(l)) - lattice = q['meta']['Lattice'] - - for i,qu in enumerate(q['data']): - o = Orientation(np.array([qu['w'],qu['x'],qu['y'],qu['z']]),lattice).reduced() - colors[i] = np.uint8(o.IPFcolor(d_unit)*255) + o = Orientation(Rotation(rfn.structured_to_unstructured(q['data'])), + lattice = q['meta']['Lattice']) return { - 'data': colors, + 'data': np.uint8(o.IPF_color(l)*255), 'label': 'IPFcolor_[{} {} {}]'.format(*m), 'meta' : { - 'Unit': 'RGB (8bit)', - 'Lattice': lattice, + 'Unit': '8-bit RGB', + 'Lattice': q['meta']['Lattice'], 'Description': 'Inverse Pole Figure (IPF) colors along sample direction [{} {} {}]'.format(*m), 'Creator': inspect.stack()[0][3][1:] }