add IPF color tuple for HDF5 file
This commit is contained in:
parent
b04c5801a5
commit
fb1e4f0c39
|
@ -0,0 +1,174 @@
|
||||||
|
#!/usr/bin/env python2.7
|
||||||
|
# -*- coding: UTF-8 no BOM -*-
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import math
|
||||||
|
import damask
|
||||||
|
import numpy as np
|
||||||
|
from optparse import OptionParser
|
||||||
|
|
||||||
|
scriptName = os.path.splitext(os.path.basename(__file__))[0]
|
||||||
|
scriptID = ' '.join([scriptName, damask.version])
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
# This implementation will have to iterate through the array one
|
||||||
|
# element at a time, maybe there are some other ways to make this
|
||||||
|
# faster.
|
||||||
|
|
||||||
|
|
||||||
|
# ----- Helper functions ----- #
|
||||||
|
# ref: http://stackoverflow.com/questions/16801322/how-can-i-check-that-a-list-
|
||||||
|
# has-one-and-only-one-truthy-value
|
||||||
|
# NOTE:
|
||||||
|
# These functions might be useful in the future
|
||||||
|
def n_trues(iterable, n=1):
|
||||||
|
"""N(trues) = n"""
|
||||||
|
i = iter(iterable)
|
||||||
|
return all(any(i) for j in range(n)) and not any(i)
|
||||||
|
|
||||||
|
|
||||||
|
def up_to_n_trues(iterable, n=1):
|
||||||
|
i = iter(iterable)
|
||||||
|
all(any(i) for j in range(n))
|
||||||
|
return not any(i)
|
||||||
|
|
||||||
|
|
||||||
|
def at_least_n_trues(iterable, n=1):
|
||||||
|
i = iter(iterable)
|
||||||
|
return all(any(i) for j in range(n))
|
||||||
|
|
||||||
|
|
||||||
|
def m_to_n_trues(iterable, m=1, n=1):
|
||||||
|
i = iter(iterable)
|
||||||
|
assert m <= n
|
||||||
|
return at_least_n_trues(i, m) and up_to_n_trues(i, n - m)
|
||||||
|
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------
|
||||||
|
# MAIN
|
||||||
|
# --------------------------------------------------------------------
|
||||||
|
desp = "Add RGB color value corresponding to TSL-OIM scheme for IPF."
|
||||||
|
parser = OptionParser(option_class=damask.extendableOption,
|
||||||
|
usage='%prog options [file[s]]',
|
||||||
|
description=desp,
|
||||||
|
version=scriptID)
|
||||||
|
parser.add_option('-p', '--pole',
|
||||||
|
dest='pole',
|
||||||
|
type='float', nargs=3, metavar='float float float',
|
||||||
|
help='lab frame direction for IPF [%default]')
|
||||||
|
msg = ', '.join(damask.Symmetry.lattices[1:])
|
||||||
|
parser.add_option('-s', '--symmetry',
|
||||||
|
dest='symmetry',
|
||||||
|
type='choice', choices=damask.Symmetry.lattices[1:],
|
||||||
|
metavar='string',
|
||||||
|
help='crystal symmetry [%default] {{{}}} '.format(msg))
|
||||||
|
parser.add_option('-e', '--eulers',
|
||||||
|
dest='eulers',
|
||||||
|
type='string', metavar='string',
|
||||||
|
help='Euler angles label')
|
||||||
|
parser.add_option('-d', '--degrees',
|
||||||
|
dest='degrees',
|
||||||
|
action='store_true',
|
||||||
|
help='Euler angles are given in degrees [%default]')
|
||||||
|
parser.add_option('-m', '--matrix',
|
||||||
|
dest='matrix',
|
||||||
|
type='string', metavar='string',
|
||||||
|
help='orientation matrix label')
|
||||||
|
parser.add_option('-a',
|
||||||
|
dest='a',
|
||||||
|
type='string', metavar='string',
|
||||||
|
help='crystal frame a vector label')
|
||||||
|
parser.add_option('-b',
|
||||||
|
dest='b',
|
||||||
|
type='string', metavar='string',
|
||||||
|
help='crystal frame b vector label')
|
||||||
|
parser.add_option('-c',
|
||||||
|
dest='c',
|
||||||
|
type='string', metavar='string',
|
||||||
|
help='crystal frame c vector label')
|
||||||
|
parser.add_option('-q', '--quaternion',
|
||||||
|
dest='quaternion',
|
||||||
|
type='string', metavar='string',
|
||||||
|
help='quaternion label')
|
||||||
|
|
||||||
|
parser.set_defaults(pole=(0.0, 0.0, 1.0),
|
||||||
|
symmetry=damask.Symmetry.lattices[-1],
|
||||||
|
degrees=False)
|
||||||
|
|
||||||
|
(options, filenames) = parser.parse_args()
|
||||||
|
|
||||||
|
# safe guarding to have only one orientation representation
|
||||||
|
# use dynamic typing to group a,b,c into frame
|
||||||
|
options.frame = [options.a, options.b, options.c]
|
||||||
|
input = [options.eulers is not None,
|
||||||
|
all(options.frame),
|
||||||
|
options.matrix is not None,
|
||||||
|
options.quaternion is not None]
|
||||||
|
|
||||||
|
if np.sum(input) != 1:
|
||||||
|
parser.error('needs exactly one input format.')
|
||||||
|
|
||||||
|
# select input label that was requested (active)
|
||||||
|
label_active = np.where(input)[0][0]
|
||||||
|
(label, dim, inputtype) = [(options.eulers, 3, 'eulers'),
|
||||||
|
(options.frame, [3, 3, 3], 'frame'),
|
||||||
|
(options.matrix, 9, 'matrix'),
|
||||||
|
(options.quaternion, 4, 'quaternion')][label_active]
|
||||||
|
|
||||||
|
# rescale degrees to radians
|
||||||
|
toRadians = math.pi/180.0 if options.degrees else 1.0
|
||||||
|
|
||||||
|
# only use normalized pole
|
||||||
|
pole = np.array(options.pole)
|
||||||
|
pole /= np.linalg.norm(pole)
|
||||||
|
|
||||||
|
# ----- Loop over input files ----- #
|
||||||
|
for name in filenames:
|
||||||
|
try:
|
||||||
|
h5f = damask.H5Table(name, new_file=False)
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
damask.util.report(scriptName, name)
|
||||||
|
|
||||||
|
# extract data from HDF5 file
|
||||||
|
if inputtype == 'eulers':
|
||||||
|
orieData = h5f.get_data(label)
|
||||||
|
elif inputtype == 'matrix':
|
||||||
|
orieData = h5f.get_data(label)
|
||||||
|
orieData = orieData.reshape(orieData.shape[0], 3, 3)
|
||||||
|
elif inputtype == 'frame':
|
||||||
|
vctr_a = h5f.get_data(label[0])
|
||||||
|
vctr_b = h5f.get_data(label[1])
|
||||||
|
vctr_c = h5f.get_data(label[2])
|
||||||
|
frame = np.column_stack((vctr_a, vctr_b, vctr_c))
|
||||||
|
orieData = frame.reshape(frame.shape[0], 3, 3)
|
||||||
|
elif inputtype == 'quaternion':
|
||||||
|
orieData = h5f.get_data(label)
|
||||||
|
|
||||||
|
# calculate the IPF color
|
||||||
|
rgbArrays = np.zeros((orieData.shape[0], 3))
|
||||||
|
for ci in xrange(rgbArrays.shape[0]):
|
||||||
|
if inputtype == 'eulers':
|
||||||
|
o = damask.Orientation(Eulers=np.array(orieData[ci, :])*toRadians,
|
||||||
|
symmetry=options.symmetry).reduced()
|
||||||
|
elif inputtype == 'matrix':
|
||||||
|
o = damask.Orientation(matrix=orieData[ci, :, :].transpose(),
|
||||||
|
symmetry=options.symmetry).reduced()
|
||||||
|
elif inputtype == 'frame':
|
||||||
|
o = damask.Orientation(matrix=orieData[ci, :, :],
|
||||||
|
symmetry=options.symmetry).reduced()
|
||||||
|
elif inputtype == 'quaternion':
|
||||||
|
o = damask.Orientation(quaternion=orieData[ci, :],
|
||||||
|
symmetry=options.symmetry).reduced()
|
||||||
|
rgbArrays[ci, :] = o.IPFcolor(pole)
|
||||||
|
|
||||||
|
# compose labels/headers for IPF color (RGB)
|
||||||
|
labelIPF = 'IPF_{:g}{:g}{:g}_{sym}'.format(*options.pole,
|
||||||
|
sym=options.symmetry.lower())
|
||||||
|
|
||||||
|
# compose cmd history (go with dataset)
|
||||||
|
cmd_log = scriptID + '\t' + ' '.join(sys.argv[1:])
|
||||||
|
|
||||||
|
# write data to HDF5 file
|
||||||
|
h5f.add_data(labelIPF, rgbArrays, cmd_log=cmd_log)
|
Loading…
Reference in New Issue