add IPF color tuple for HDF5 file

This commit is contained in:
chen 2016-10-17 12:24:29 -04:00
parent b04c5801a5
commit fb1e4f0c39
1 changed files with 174 additions and 0 deletions

174
processing/post/h5_addIPFcolor.py Executable file
View File

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