Source code for easistrain.EDD.coordTransformation
import os
from typing import Sequence
import h5py
import numpy
from easistrain.EDD.utils import run_from_cli
[docs]
def transformationMatrix(
rx: float, ry: float, rz: float, tx: float, ty: float, tz: float
):
rx = numpy.deg2rad(rx)
ry = numpy.deg2rad(ry)
rz = numpy.deg2rad(rz)
transfMat = numpy.zeros((4, 4), "float64")
rotx = numpy.array(
[
[1, 0, 0],
[0, numpy.cos(rx), -numpy.sin(rx)],
[0, numpy.sin(rx), numpy.cos(rx)],
]
) ### Rotation matrix around x, x is in the direction of the beam ###
roty = numpy.array(
[
[numpy.cos(ry), 0, numpy.sin(ry)],
[0, 1, 0],
[-numpy.sin(ry), 0, numpy.cos(ry)],
]
) ### Rotation matrix around y, y is perpendicular to the beam and in its plane ###
rotz = numpy.array(
[
[numpy.cos(rz), -numpy.sin(rz), 0],
[numpy.sin(rz), numpy.cos(rz), 0],
[0, 0, 1],
]
) ### Rotation matrix around z, z iz perpendicular to the beam and out of the beam plane ###
rotxyz = numpy.dot(
rotz, numpy.dot(roty, rotx)
) ### Rotation matrix for 3 rotations: first around x, second around y and third around z ###
transfMat[0:3, 0:3] = rotxyz[0:3, 0:3]
transfMat[3, 0:3] = 0
transfMat[0, 3] = tx
transfMat[1, 3] = ty
transfMat[2, 3] = tz
transfMat[3, 3] = 1
return transfMat
[docs]
def coordTransformation(
fileRead: str, fileSave: str, numberOfPeaks: int, gonioToSample: Sequence[float]
):
with h5py.File(fileRead, "r") as h5Read: ## Read the h5 file of raw data
scanList = list(h5Read.keys()) ## list of the scans
lengthCounter = 0
for scan in scanList:
shapeDsetPeak = h5Read[f"{scan}/tthPositionsGroup/peak_0000"].shape[0]
lengthCounter = (
lengthCounter + shapeDsetPeak
) ## shape of the matrix on which all the points for one peak will be saved
transfMat = transformationMatrix(
gonioToSample[0],
gonioToSample[1],
gonioToSample[2],
gonioToSample[3],
gonioToSample[4],
gonioToSample[5],
)
if os.path.dirname(fileSave):
os.makedirs(os.path.dirname(fileSave), exist_ok=True)
with h5py.File(fileSave, "a") as h5Save: ## create/append h5 file to save in
globalGroup = h5Save.create_group(
"global",
) ## Creation of the global group in which all peaks positions of all the points will be put
for peakNumber in range(numberOfPeaks):
globalPeak = globalGroup.create_dataset(
f"peak_{str(peakNumber).zfill(4)}",
dtype="float64",
data=numpy.zeros((lengthCounter, 13), "float64"),
) ## creation of the dataset of peak info (coordinate in gonio, center, ...) for each peak
globalPeakInSample = globalGroup.create_dataset(
f"inSample_peak_{str(peakNumber).zfill(4)}",
dtype="float64",
data=numpy.zeros((lengthCounter, 13), "float64"),
) ## creation of the dataset of peak info (coordinate in sample, center, ...) for each peak
uncertaintyGlobalPeak = globalGroup.create_dataset(
f"uncertaintyPeak_{str(peakNumber).zfill(4)}",
dtype="float64",
data=numpy.zeros((lengthCounter, 13), "float64"),
) ## creation of the dataset of uncertainty for each peak (gonio coordinates)
uncertaintyGlobalPeakInSample = globalGroup.create_dataset(
f"inSample_uncertaintyPeak_{str(peakNumber).zfill(4)}",
dtype="float64",
data=numpy.zeros((lengthCounter, 13), "float64"),
) ## creation of the dataset of uncertainty for each peak (sample coordinates)
rowsCounter = 0
for scan in scanList:
with h5py.File(
fileRead, "r"
) as h5Read: ## Read the h5 file of raw data
shapeDsetPeak = h5Read[f"{scan}/tthPositionsGroup/peak_0000"].shape[
0
]
globalPeak[rowsCounter : rowsCounter + shapeDsetPeak, :] = h5Read[
f"{scan}/tthPositionsGroup/peak_{str(peakNumber).zfill(4)}"
][
()
] ## put peak info (coordinate in gonio, center, ...) in global dataset regrouping all point for one peak
uncertaintyGlobalPeak[
rowsCounter : rowsCounter + shapeDsetPeak, :
] = h5Read[
f"{scan}/tthPositionsGroup/uncertaintyPeak_{str(peakNumber).zfill(4)}"
][
()
] ## put uncertainty of peak info (coordinate, center, ...) in global dataset regrouping all point for one peak
globalPeakInSample[
rowsCounter : rowsCounter + shapeDsetPeak, :
] = h5Read[
f"{scan}/tthPositionsGroup/peak_{str(peakNumber).zfill(4)}"
][
()
] ## same as above, then belwo convert the coordinate from gonio to sample
uncertaintyGlobalPeakInSample[
rowsCounter : rowsCounter + shapeDsetPeak, :
] = h5Read[
f"{scan}/tthPositionsGroup/uncertaintyPeak_{str(peakNumber).zfill(4)}"
][
()
] ## same as above, then belwo convert the coordinate from gonio to sample
rowsCounter = rowsCounter + shapeDsetPeak
for icount in range(len(globalPeakInSample)):
coordInSample = numpy.dot(
transfMat,
[
-globalPeakInSample[icount, 0],
-globalPeakInSample[icount, 1],
-globalPeakInSample[icount, 2],
1,
],
)
globalPeakInSample[icount, 0] = coordInSample[0]
globalPeakInSample[icount, 1] = coordInSample[1]
globalPeakInSample[icount, 2] = coordInSample[2]
uncertaintyGlobalPeakInSample[:, 0:3] = globalPeakInSample[:, 0:3]
if __name__ == "__main__":
run_from_cli(coordTransformation)