Quick start¶
This notebook is for a quick start to plot basic result from the G50 fabric analyser.
import xarrayaita.loadData_aita as lda #here are some function to build xarrayaita structure
import xarrayaita.aita as xa
import xarrayuvecs.uvecs as xu
import xarrayuvecs.lut2d as lut2d
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
Load your data¶
# path to data and microstructure
path_data='orientation_test.dat'
path_micro='micro_test.bmp'
data=lda.aita5col(path_data,path_micro)
data
<xarray.Dataset> Dimensions: (uvecs: 2, x: 1000, y: 2500) Coordinates: * x (x) float64 0.0 0.02 0.04 0.06 0.08 ... 19.92 19.94 19.96 19.98 * y (y) float64 49.98 49.96 49.94 49.92 49.9 ... 0.06 0.04 0.02 0.0 Dimensions without coordinates: uvecs Data variables: orientation (y, x, uvecs) float64 2.395 0.6451 5.377 ... 0.6098 0.6473 quality (y, x) int64 0 90 92 93 92 92 94 94 ... 96 96 96 96 96 97 97 96 micro (y, x) float64 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 grainId (y, x) int64 1 1 1 1 1 1 1 1 1 1 1 1 ... 1 1 1 1 1 1 1 1 1 1 1 Attributes: date: Thursday, 19 Nov 2015, 11:24 am unit: millimeters step_size: 0.02 path_dat: orientation_test.dat
- uvecs: 2
- x: 1000
- y: 2500
- x(x)float640.0 0.02 0.04 ... 19.94 19.96 19.98
array([ 0. , 0.02, 0.04, ..., 19.94, 19.96, 19.98])
- y(y)float6449.98 49.96 49.94 ... 0.04 0.02 0.0
array([4.998e+01, 4.996e+01, 4.994e+01, ..., 4.000e-02, 2.000e-02, 0.000e+00])
- orientation(y, x, uvecs)float642.395 0.6451 ... 0.6098 0.6473
array([[[2.39476627, 0.64507369], [5.37718489, 1.04999008], [5.38905313, 1.05627326], ..., [2.05826679, 0.49654617], [5.65731024, 0.94160513], [5.68523551, 1.03218772]], [[5.35955707, 1.15837502], [5.35885894, 1.12975162], [5.3613024 , 1.11701072], ..., [2.07659274, 0.52063172], [5.64753639, 0.94073247], [5.67912685, 1.04143796]], [[5.36304773, 1.23045712], [5.36165146, 1.23132979], [2.38656322, 0.57246799], ..., ... ..., [0.62378067, 0.625526 ], [0.61784656, 0.61994095], [0.61645029, 0.61400683]], [[0.68085294, 1.12399204], [0.68050388, 1.12730816], [0.67840948, 1.13900187], ..., [0.64123397, 0.62954026], [0.62430427, 0.63529985], [0.61575216, 0.62203535]], [[0.67701322, 1.13236962], [0.67753682, 1.13690747], [0.67840948, 1.13149695], ..., [0.63652158, 0.61418136], [0.61645029, 0.63948864], [0.60981804, 0.64734262]]])
- quality(y, x)int640 90 92 93 92 92 ... 96 96 97 97 96
array([[ 0, 90, 92, ..., 0, 85, 90], [81, 82, 83, ..., 0, 84, 89], [81, 80, 3, ..., 0, 79, 88], ..., [90, 91, 91, ..., 95, 95, 95], [91, 92, 91, ..., 95, 95, 95], [92, 92, 91, ..., 97, 97, 96]])
- micro(y, x)float640.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0
array([[0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], ..., [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.]])
- grainId(y, x)int641 1 1 1 1 1 1 1 ... 1 1 1 1 1 1 1 1
array([[1, 1, 1, ..., 1, 1, 1], [1, 1, 1, ..., 1, 1, 1], [1, 1, 1, ..., 1, 1, 1], ..., [1, 1, 1, ..., 1, 1, 1], [1, 1, 1, ..., 1, 1, 1], [1, 1, 1, ..., 1, 1, 1]])
- date :
- Thursday, 19 Nov 2015, 11:24 am
- unit :
- millimeters
- step_size :
- 0.02
- path_dat :
- orientation_test.dat
With G50 fabric analyser we usually filter the value with a quality
below \(75\).
data.aita.filter(75)
Plot colormap¶
Plotting a colormap using a color wheel is done using xarrayuvecs
Full colorwheel¶
data['FullColormap']=data.orientation.uvecs.calc_colormap()
Therfore the FullColormap
variable is store in the xarray.Dataset
data
<xarray.Dataset> Dimensions: (img: 3, uvecs: 2, x: 1000, y: 2500) Coordinates: * x (x) float64 0.0 0.02 0.04 0.06 ... 19.92 19.94 19.96 19.98 * y (y) float64 49.98 49.96 49.94 49.92 ... 0.06 0.04 0.02 0.0 Dimensions without coordinates: img, uvecs Data variables: orientation (y, x, uvecs) float64 nan nan 5.377 ... 0.6395 0.6098 0.6473 quality (y, x) int64 0 90 92 93 92 92 94 94 ... 96 96 96 96 97 97 96 micro (y, x) float64 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 grainId (y, x) int64 1 1 1 1 1 1 1 1 1 1 1 1 ... 1 1 1 1 1 1 1 1 1 1 1 FullColormap (y, x, img) float64 255.0 255.0 255.0 0.0 ... 0.0 0.425 0.1756 Attributes: date: Thursday, 19 Nov 2015, 11:24 am unit: millimeters step_size: 0.02 path_dat: orientation_test.dat
- img: 3
- uvecs: 2
- x: 1000
- y: 2500
- x(x)float640.0 0.02 0.04 ... 19.94 19.96 19.98
array([ 0. , 0.02, 0.04, ..., 19.94, 19.96, 19.98])
- y(y)float6449.98 49.96 49.94 ... 0.04 0.02 0.0
array([4.998e+01, 4.996e+01, 4.994e+01, ..., 4.000e-02, 2.000e-02, 0.000e+00])
- orientation(y, x, uvecs)float64nan nan 5.377 ... 0.6098 0.6473
array([[[ nan, nan], [5.37718489, 1.04999008], [5.38905313, 1.05627326], ..., [ nan, nan], [5.65731024, 0.94160513], [5.68523551, 1.03218772]], [[5.35955707, 1.15837502], [5.35885894, 1.12975162], [5.3613024 , 1.11701072], ..., [ nan, nan], [5.64753639, 0.94073247], [5.67912685, 1.04143796]], [[5.36304773, 1.23045712], [5.36165146, 1.23132979], [ nan, nan], ..., ... ..., [0.62378067, 0.625526 ], [0.61784656, 0.61994095], [0.61645029, 0.61400683]], [[0.68085294, 1.12399204], [0.68050388, 1.12730816], [0.67840948, 1.13900187], ..., [0.64123397, 0.62954026], [0.62430427, 0.63529985], [0.61575216, 0.62203535]], [[0.67701322, 1.13236962], [0.67753682, 1.13690747], [0.67840948, 1.13149695], ..., [0.63652158, 0.61418136], [0.61645029, 0.63948864], [0.60981804, 0.64734262]]])
- quality(y, x)int640 90 92 93 92 92 ... 96 96 97 97 96
array([[ 0, 90, 92, ..., 0, 85, 90], [81, 82, 83, ..., 0, 84, 89], [81, 80, 3, ..., 0, 79, 88], ..., [90, 91, 91, ..., 95, 95, 95], [91, 92, 91, ..., 95, 95, 95], [92, 92, 91, ..., 97, 97, 96]])
- micro(y, x)float640.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0
array([[0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], ..., [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.]])
- grainId(y, x)int641 1 1 1 1 1 1 1 ... 1 1 1 1 1 1 1 1
array([[1, 1, 1, ..., 1, 1, 1], [1, 1, 1, ..., 1, 1, 1], [1, 1, 1, ..., 1, 1, 1], ..., [1, 1, 1, ..., 1, 1, 1], [1, 1, 1, ..., 1, 1, 1], [1, 1, 1, ..., 1, 1, 1]])
- FullColormap(y, x, img)float64255.0 255.0 255.0 ... 0.425 0.1756
array([[[2.55000000e+02, 2.55000000e+02, 2.55000000e+02], [0.00000000e+00, 8.31045169e-02, 6.10959406e-01], [0.00000000e+00, 8.90701755e-02, 6.12236792e-01], ..., [2.55000000e+02, 2.55000000e+02, 2.55000000e+02], [0.00000000e+00, 2.28316246e-01, 5.68812202e-01], [0.00000000e+00, 2.59752088e-01, 6.03720578e-01]], [[0.00000000e+00, 7.49569122e-02, 6.46222356e-01], [0.00000000e+00, 7.43507078e-02, 6.36260675e-01], [0.00000000e+00, 7.56859421e-02, 6.34053901e-01], ..., [2.55000000e+02, 2.55000000e+02, 2.55000000e+02], [0.00000000e+00, 2.22896964e-01, 5.69848094e-01], [0.00000000e+00, 2.59186683e-01, 6.09126329e-01]], [[0.00000000e+00, 7.98101564e-02, 6.65606609e-01], [0.00000000e+00, 7.98101564e-02, 6.65606609e-01], [2.55000000e+02, 2.55000000e+02, 2.55000000e+02], ..., ... ..., [0.00000000e+00, 4.12136046e-01, 1.64803780e-01], [0.00000000e+00, 4.10516023e-01, 1.66295797e-01], [0.00000000e+00, 4.06654374e-01, 1.65337632e-01]], [[0.00000000e+00, 6.37331154e-01, 2.20848021e-01], [0.00000000e+00, 6.37331154e-01, 2.20848021e-01], [0.00000000e+00, 6.43371492e-01, 2.24232987e-01], ..., [0.00000000e+00, 4.17068553e-01, 1.60356448e-01], [0.00000000e+00, 4.19868931e-01, 1.66723966e-01], [0.00000000e+00, 4.12767430e-01, 1.68749936e-01]], [[0.00000000e+00, 6.39478712e-01, 2.23263009e-01], [0.00000000e+00, 6.41631020e-01, 2.25679655e-01], [0.00000000e+00, 6.39478712e-01, 2.23263009e-01], ..., [0.00000000e+00, 4.07106160e-01, 1.55990853e-01], [0.00000000e+00, 4.20488704e-01, 1.70665444e-01], [0.00000000e+00, 4.25000087e-01, 1.75577224e-01]]])
- date :
- Thursday, 19 Nov 2015, 11:24 am
- unit :
- millimeters
- step_size :
- 0.02
- path_dat :
- orientation_test.dat
The plot can be done using :
plt.figure(figsize=(5,10))
data.FullColormap.plot.imshow()
plt.axis('equal')
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
(-0.01, 19.990000000000002, -0.010000000000001563, 49.99000000000001)

The associated colorwheel can be plot using :
lut_f=lut2d.lut()
plt.figure(figsize=(3,3))
plt.imshow(lut_f)
plt.axis('equal')
plt.axis('off')
plt.title('Full colorwheel')
Text(0.5, 1.0, 'Full colorwheel')

Semi colorwheel¶
The same figure can be done using a “semi” colorwheel.
Warning
\((x,y,z)\) and \((-x,-y,z)\) share the same colorcoding.
data['SemiColormap']=data.orientation.uvecs.calc_colormap(semi=True)
plt.figure(figsize=(5,10))
data.SemiColormap.plot.imshow()
plt.axis('equal')
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
(-0.01, 19.990000000000002, -0.010000000000001563, 49.99000000000001)

lut_s=lut2d.lut(semi=True)
plt.figure(figsize=(3,3))
plt.imshow(lut_s)
plt.axis('equal')
plt.axis('off')
plt.title('Semi colorwheel')
Text(0.5, 1.0, 'Semi colorwheel')

Plot ODF¶
ODF stand for Orientation Density Function. It is a probability density function for orientation. Therefore it’s integral over the sphere is equal to 1.
Warning
The plotODF function
is very quite sensible to the bw
input parameter that is the bandwidth of kernel for the kde estimation. See documentation here (Need to document this in xarrayuvecs)
The ODF¶
plt.figure(figsize=(7,7))
data.orientation.uvecs.plotODF(bw=0.2,cmap=cm.viridis)

The 2nd order orientation tensor¶
The second order orientation tensor of a set of \(x_i\) vector is defnied by :
\(OT2nd=\frac{1}{N}\sum_{i=1}^{N}x_i \otimes x_i\)
There for you can extract the eigen value and eigen vector of it. It is what xu.uvec.OT2nd
does.
e_val,e_vec=data.orientation.uvecs.OT2nd()
print('The 1st eigen value is :',e_val[0],'. Associated with the vector :',e_vec[:,0] )
print('The 2nd eigen value is :',e_val[1],'. Associated with the vector :',e_vec[:,1] )
print('The 3rd eigen value is :',e_val[2],'. Associated with the vector :',e_vec[:,2] )
The 1st eigen value is : 0.36842623 . Associated with the vector : [ 0.95692456 0.00752591 -0.29023907]
The 2nd eigen value is : 0.3406706 . Associated with the vector : [0.24083522 0.5377383 0.8079826 ]
The 3rd eigen value is : 0.2909032 . Associated with the vector : [-0.16215347 0.8430782 -0.5127625 ]
Work on subset¶
Only on grain¶
gId=100
ds=data.where(data.grainId==gId,drop=True)
plt.figure(figsize=(10,7))
plt.subplot(1,2,1)
ds.SemiColormap.plot.imshow()
plt.axis('equal')
plt.title('Orientation semi')
plt.subplot(1,2,2)
ds.FullColormap.plot.imshow()
plt.axis('equal')
plt.title('Orientation full')
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Text(0.5, 1.0, 'Orientation full')

plt.figure(figsize=(7,7))
ds.orientation.uvecs.plotODF(nbr=100)

More grains¶
ds2=data.where((data.grainId==4)+(data.grainId==5),drop=True)
plt.figure(figsize=(10,7))
plt.subplot(1,2,1)
ds2.SemiColormap.plot.imshow()
plt.axis('equal')
plt.title('Orientation semi')
plt.subplot(1,2,2)
ds2.FullColormap.plot.imshow()
plt.axis('equal')
plt.title('Orientation full')
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Text(0.5, 1.0, 'Orientation full')
