Skip to content

Commit

Permalink
DOC: Improve explanations for the Find Average C-Axis algorithm. (#741)
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Jackson <[email protected]>
  • Loading branch information
imikejackson authored Oct 17, 2023
1 parent 8ba8129 commit c7fb752
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 6 deletions.
6 changes: 5 additions & 1 deletion src/Plugins/OrientationAnalysis/docs/FindAvgCAxesFilter.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ Statistics (Crystallographic)
This **Filter** determines the average C-axis location of each **Feature** by the following algorithm:

1. Gather all **Elements** that belong to the **Feature**
2. Determine the location of the c-axis in the sample *reference frame* for the rotated quaternions for all **Elements**
2. Determine the location of the c-axis in the sample *reference frame* for the rotated quaternions for all **Elements**. This is achieved by converting the input quaternion to
and orientation matrix (which represents a passive transform matrix), taking the transpose of the matrix to convert it from passive to active, and thne multiplying the
transposed matrix by the crystallographic C-Axis direction vector <001>.
3. Average the locations and store as the average for the **Feature**

*Note:* This **Filter** will only work properly for *Hexagonal* materials. The **Filter** does not apply any symmetry operators because there is only one c-axis (<001>) in *Hexagonal* materials and thus all symmetry operators will leave the c-axis in the same position in the sample *reference frame*. However, in *Cubic* materials, for example, the {100} family of directions are all equivalent and the <001> direction will change location in the sample *reference frame* when symmetry operators are applied.

This filter will error out if **ALL** phases are non-hexagonal. Any non-hexagonal phases will have their computed values set to NaN value.

% Auto generated parameter table will be inserted here

## Example Pipelines
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,26 +85,35 @@ Result<> FindAvgCAxes::operator()()
if(crystalStructureType == EbsdLib::CrystalStructure::Hexagonal_High || crystalStructureType == EbsdLib::CrystalStructure::Hexagonal_Low)
{
const usize quatIndex = i * 4;

// Create the 3x3 Orientation Matrix from the Quaternion. This represents a passive rotation matrix
OrientationF oMatrix = OrientationTransformation::qu2om<QuatF, OrientationF>({quats[quatIndex], quats[quatIndex + 1], quats[quatIndex + 2], quats[quatIndex + 3]});

// Convert the quaternion matrix to a transposed g matrix so when caxis is multiplied by it, it will give the sample direction that the caxis is along
// Convert the passive rotation matrix to an active rotation matrix
g1T = OrientationMatrixToGMatrixTranspose(oMatrix);

// Multiply the active transformation matrix by the C-Axis (as Miller Index). This actively rotates
// the crystallographic C-Axis (which is along the <0,0,1> direction) into the physical sample
// reference frame
c1 = g1T * cAxis;

// normalize so that the magnitude is 1
c1.normalize();

// Compute the running average c-axis and normalize the result
curCAxis[0] = avgCAxes[cAxesIndex] / counter[featureIds[i]];
curCAxis[1] = avgCAxes[cAxesIndex + 1] / counter[featureIds[i]];
curCAxis[2] = avgCAxes[cAxesIndex + 2] / counter[featureIds[i]];

curCAxis.normalize();

// Ensure that angle between the current point's sample reference frame C-Axis
// and the running average sample C-Axis is positive
w = ImageRotationUtilities::CosBetweenVectors(c1, curCAxis);
if(w < 0)
{
c1 *= -1.0f;
}
// Continue summing up the rotations
counter[featureIds[i]]++;
avgCAxes[cAxesIndex] += c1[0];
avgCAxes[cAxesIndex + 1] += c1[1];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,11 @@ Result<> FindAvgOrientations::operator()()
float32 count = counts[featureId];
QuatF curAvgQuat(avgQuats[featureIdOffset] / count, avgQuats[featureIdOffset + 1] / count, avgQuats[featureIdOffset + 2] / count, avgQuats[featureIdOffset + 3] / count);

// Get the pointer to the current voxel's Quaternion
QuatF voxQuat(quats[i * 4], quats[i * 4 + 1], quats[i * 4 + 2], quats[i * 4 + 3]); // Makes a copy into voxQuat!!!!
// Make a copy of the current quaternion from the DataArray into a QuatF object
QuatF voxQuat(quats[i * 4], quats[i * 4 + 1], quats[i * 4 + 2], quats[i * 4 + 3]);
QuatF nearestQuat = orientationOps[crystalStructures[phase]]->getNearestQuat(curAvgQuat, voxQuat);

// Add the running average quat with the current quat
curAvgQuat = curAvgQuat + nearestQuat;
// Copy the new curAvgQuat back into the output array
avgQuats[featureIdOffset] = curAvgQuat.x();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Parameters ImportH5EspritDataFilter::parameters() const
params.insert(std::make_unique<OEMEbsdScanSelectionParameter>(k_SelectedScanNames_Key, "Scan Names", "The name of the scan in the .h5 file. EDAX can store multiple scans in a single file",
OEMEbsdScanSelectionParameter::ValueType{},
/* OEMEbsdScanSelectionParameter::AllowedManufacturers{EbsdLib::OEM::Bruker, EbsdLib::OEM::DREAM3D},*/
OEMEbsdScanSelectionParameter::EbsdReaderType::Esprit, OEMEbsdScanSelectionParameter::ExtensionsType{".h5"}));
OEMEbsdScanSelectionParameter::EbsdReaderType::Esprit, OEMEbsdScanSelectionParameter::ExtensionsType{".h5", ".hdf5"}));
params.insert(std::make_unique<Float32Parameter>(k_ZSpacing_Key, "Z Spacing (Microns)", "The spacing in microns between each layer.", 1.0f));
params.insert(std::make_unique<VectorFloat32Parameter>(k_Origin_Key, "Origin", "The origin of the volume", std::vector<float32>{0.0F, 0.0F, 0.0F}, std::vector<std::string>{"x", "y", "z"}));
params.insert(std::make_unique<BoolParameter>(k_DegreesToRadians_Key, "Convert Euler Angles to Radians", "Whether or not to convert the euler angles to radians", true));
Expand Down

0 comments on commit c7fb752

Please sign in to comment.