diff --git a/CMakeLists.txt b/CMakeLists.txt index 3538c206be..61f4282307 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,7 +53,7 @@ enable_vcpkg_manifest_feature(TEST_VAR COMPLEX_ENABLE_ITKImageProcessing FEATURE # Is the OrientationAnalysis Plugin enabled [DEFAULT=ON] # -------------------------------------------------------------------------------------------------- option(COMPLEX_ENABLE_OrientationAnalysis "Enable the OrientationAnalysis Plugin" ON) -enable_vcpkg_manifest_feature(TEST_VAR COMPLEX_ENABLE_OrientationAnalysis FEATURE "ebsd") +#enable_vcpkg_manifest_feature(TEST_VAR COMPLEX_ENABLE_OrientationAnalysis FEATURE "ebsd") option(COMPLEX_CONDA_BUILD "Enables conda-build specific layout" OFF) diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/ImportHDF5Dataset.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/ImportHDF5Dataset.cpp index 2364372892..cdb970acd3 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/ImportHDF5Dataset.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/ImportHDF5Dataset.cpp @@ -126,10 +126,6 @@ IFilter::PreflightResult ImportHDF5Dataset::preflightImpl(const DataStructure& d fs::path inputFilePath(inputFile); std::string ext = inputFilePath.extension().string(); - if(ext != ".h5" && ext != ".hdf5" && ext != ".dream3d") - { - return {nonstd::make_unexpected(std::vector{Error{-20002, fmt::format("The selected file '{}' is not an HDF5 file.", inputFilePath.filename().string())}})}; - } if(!fs::exists(inputFilePath)) { diff --git a/src/Plugins/OrientationAnalysis/CMakeLists.txt b/src/Plugins/OrientationAnalysis/CMakeLists.txt index aa64f45d68..dcdc444ecb 100644 --- a/src/Plugins/OrientationAnalysis/CMakeLists.txt +++ b/src/Plugins/OrientationAnalysis/CMakeLists.txt @@ -1,9 +1,12 @@ # ------------------------------------------------------------------------------ # Required EbsdLib and H5Support # ------------------------------------------------------------------------------ -find_package(H5Support REQUIRED) +#find_package(H5Support REQUIRED) -find_package(EbsdLib REQUIRED) +#find_package(EbsdLib REQUIRED) + +add_subdirectory(${complex_SOURCE_DIR}/../H5Support ${complex_BINARY_DIR}/H5Support) +add_subdirectory(${complex_SOURCE_DIR}/../EbsdLib ${complex_BINARY_DIR}/EbsdLib) # ------------------------------------------------------------------------------ # EbsdLib needs install rules for creating packages @@ -63,6 +66,7 @@ set(FilterList GenerateQuaternionConjugateFilter ImportH5EspritDataFilter ImportH5OimDataFilter + ImportH5OinaDataFilter INLWriterFilter MergeTwinsFilter NeighborOrientationCorrelationFilter @@ -196,6 +200,7 @@ set(filter_algorithms GroupFeatures ImportH5EspritData ImportH5OimData + ImportH5OinaData INLWriter MergeTwins NeighborOrientationCorrelation diff --git a/src/Plugins/OrientationAnalysis/docs/Images/Hexagonal_Axis_Alignment.png b/src/Plugins/OrientationAnalysis/docs/Images/Hexagonal_Axis_Alignment.png new file mode 100644 index 0000000000..3c6a773d91 Binary files /dev/null and b/src/Plugins/OrientationAnalysis/docs/Images/Hexagonal_Axis_Alignment.png differ diff --git a/src/Plugins/OrientationAnalysis/docs/Images/ImportH5OinaFilter_1.png b/src/Plugins/OrientationAnalysis/docs/Images/ImportH5OinaFilter_1.png new file mode 100644 index 0000000000..eefb59821d Binary files /dev/null and b/src/Plugins/OrientationAnalysis/docs/Images/ImportH5OinaFilter_1.png differ diff --git a/src/Plugins/OrientationAnalysis/docs/ImportH5OinaDataFilter.md b/src/Plugins/OrientationAnalysis/docs/ImportH5OinaDataFilter.md new file mode 100644 index 0000000000..b04620349f --- /dev/null +++ b/src/Plugins/OrientationAnalysis/docs/ImportH5OinaDataFilter.md @@ -0,0 +1,96 @@ +# Import Oxford AZtec H5OINA Data File (.h5oina) + +## Group (Subgroup) + +Import/Export (Import) + +## Description + +This filter will read data from a single .h5oina file into a new **Image Geometry**, allowing the immediate use of +**Filters** on the data instead of having to generate the intermediate .h5ebsd file. A **Cell Attribute Matrix** and +**Ensemble Attribute Matrix** will also be created to hold the imported EBSD information. Currently, the user has no control +over the names of the created **Attribute Arrays**. + +### Limitations of the Filter + +The current implementation only understands the FORMAT VERSION 2.0 of the H5OINA file. This means that a user +can use a newer H5OINA file but the filter will only extract out the VERSION 2.0 headers and data. If the user +needs additional data from the file, the "Import HDF5 Dataset" filter can be used to agment this filter. + +![Overview of the user interface.](Images/ImportH5OinaFilter_1.png) + +## Notes About Reference Frames + +In order to bring the crystal reference frame and sample reference frame into coincidence, rotations **MAY** need to be applied to the data. There are 2 filters that can perform the necessary rotations. + ++ [Rotate Euler Reference Frame](../RotateEulerRefFrameFilter/index.html) ++ [Rotate Sample Reference Frame](../RotateSampleRefFrameFilter/index.html) + +Historical reference frame operations for a .ctf file are the following: + ++ Sample Reference Frame: 180o about the <010> Axis ++ Crystal Reference Frame: None + +The user also may want to assign un-indexed pixels to be ignored by flagging them as "bad". The Threshold Objects **Filter** can be used to define this *mask* by thresholding on values such as *Error* = 0. + +### Radians and Degrees + +All orientation data in the H5OINA file are in radians. + +### The Axis Alignment Issue for Hexagonal Symmetry [1] + ++ The issue with hexagonal materials is the alignment of the Cartesian coordinate system used for calculations with the crystal coordinate system (the Bravais lattice). ++ In one convention (e.g. EDAX.TSL), the x-axis, i.e. [1,0,0], is aligned with the crystal a1 axis, i.e. the [2,-1,-1,0] direction. In this case, the y-axis is aligned with the [0,1,-1,0] direction. (Green Axis in Figure 1) ++ In the other convention, (e.g. Oxford Instr, Univ. Metz software), the x-axis, i.e. [1,0,0], is aligned with the crystal [1,0,-1,0] direction. In this case, the y-axis is aligned with the [-1,2,-1,0] direction. (Red Axis in Figure 1) ++ This is important because texture analysis can lead to an ambiguity as to the alignment of [2,-1,-1,0] versus [1,0,-1,0], with apparent **30 Degree** shifts in the data. ++ Caution: it appears that the axis alignment is a choice that must be made when installing TSL software so determination of which convention is in use must be made on a case-by-case basis. It is fixed to the y-convention in the HKL software. ++ The main clue that something is wrong in a conversion is that either the 2110 & 1010 pole figures are transposed, or that a peak in the inverse pole figure that should be present at 2110 has shifted over to 1010. ++ DREAM.3D uses the TSL/EDAX convention. ++ __The result of this is that the filter will by default add 30 degrees to the second Euler Angle (phi2) when reading Oxford Instr (.ctf) files. This can be disabled by the user if necessary.__ + +| Figure 1 | +|--------| +| ![Figure showing 30 Degree conversions](Images/Hexagonal_Axis_Alignment.png) | +| **Figure 1:** showing TSL and Oxford Instr. conventions. EDAX/TSL is in **Green**. Oxford Inst. is in **Red** | + +## Parameters + +| Name | Type | Description | +|------|------| ----------- | +| Input File | File Path | The input .h5 file path | +| Scan Name | String | The name of the scan in the .h5oina file. | +| Z Spacing | float | The spacing in microns between each layer. | +| Origin | float (3x1) | The origin of the volume | +| Import Pattern Data | bool | Default=OFF | +| Hexagonal Axis Alignment | bool | Should the filter convert a Hexagonal phase to the EDAX standard for x-axis alignment | +| Convert Phase data to Int32 | bool | Should the phase data be converted to Int32 or keep the original uint8 | + +## Created Objects + +| Kind | Default Name | Type | Comp Dims | Description | +|-------------|--------------|------|-----------|----------------------------------------| +| Data Container | ImageDataContainer | N/A | N/A | Created Data Container name with an **Image Geometry** | +| Attribute Matrix | CellData | Cell | N/A | Created **Cell Attribute Matrix** name | +| Attribute Matrix | CellEnsembleData | Cell Ensemble | N/A | Created **Cell Ensemble Attribute Matrix** name | +| Cell Attribute Array | Band Contrast | uint8 | (1) | | +| Cell Attribute Array | Band Slope | uint8 | (1) | | +| Cell Attribute Array | Bands | uint8 | (1) | | +| Cell Attribute Array | Error | uint8 | (1) | The error descriptions are saved as attributes in the .h5oina file | +| Cell Attribute Array | Euler | float | (3) | Three angles defining the orientation of the **Cell** in Bunge convention (Z-X-Z) | +| Cell Attribute Array | MeanAngularDeviation | float | (1) | | +| Cell Attribute Array | Phase | uint8 | (1) | | +| Cell Attribute Array | X | float | (1) | The X Position of the scan point | +| Cell Attribute Array | Y | float | (1) | The Y Position of the scan point | +| Ensemble Attribute Array | CrystalStructures | uint32_t | (1) | Enumeration representing the crystal structure for each **Ensemble** | +| Ensemble Attribute Array | LatticeConstants | float | (6) | The 6 values that define the lattice constants for each **Ensemble**| +| Ensemble Attribute Array | MaterialName | String | (1) | Name of each **Ensemble** | + +## Example Pipelines + +## References + +[1] Rollett, A.D. Lecture Slides located at [http://pajarito.materials.cmu.edu/rollett/27750/L17-EBSD-analysis-31Mar16.pdf](http://pajarito.materials.cmu.edu/rollett/27750/L17-EBSD-analysis-31Mar16.pdf) + +## DREAM3DNX Help + +Check out our GitHub community page at [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues) to report bugs, ask the community for help, discuss features, or get help from the developers. diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/ImportH5OinaData.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/ImportH5OinaData.cpp new file mode 100644 index 0000000000..088b3791b4 --- /dev/null +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/ImportH5OinaData.cpp @@ -0,0 +1,133 @@ +#include "ImportH5OinaData.hpp" + +#include "complex/DataStructure/DataArray.hpp" +#include "complex/DataStructure/Geometry/ImageGeom.hpp" + +using namespace complex; + +namespace +{ + +template +void copyRawData(const ImportH5DataInputValues* m_InputValues, size_t totalPoints, DataStructure& m_DataStructure, H5OINAReader& m_Reader, const std::string& name, usize offset) +{ + using ArrayType = DataArray; + auto& dataRef = m_DataStructure.getDataRefAs(m_InputValues->CellAttributeMatrixPath.createChildPath(name)); + auto* dataStorePtr = dataRef.getDataStore(); + + usize numElements = m_Reader.getNumberOfElements(); + const nonstd::span rawDataPtr(reinterpret_cast(m_Reader.getPointerByName(name)), numElements); + std::copy(rawDataPtr.begin(), rawDataPtr.end(), dataStorePtr->begin() + offset); +} + +template +void convertHexEulerAngle(const ImportH5DataInputValues* m_InputValues, size_t totalPoints, DataStructure& m_DataStructure) +{ + using ArrayType = DataArray; + + if(m_InputValues->EdaxHexagonalAlignment) + { + auto& crystalStructuresRef = m_DataStructure.getDataRefAs(m_InputValues->CellEnsembleAttributeMatrixPath.createChildPath(EbsdLib::AngFile::CrystalStructures)); + auto& crystalStructuresDSRef = crystalStructuresRef.getDataStoreRef(); + + auto& cellPhasesRef = m_DataStructure.getDataRefAs(m_InputValues->CellAttributeMatrixPath.createChildPath(EbsdLib::H5OINA::Phase)); + auto& cellPhasesDSRef = cellPhasesRef.getDataStoreRef(); + + auto& eulerRef = m_DataStructure.getDataRefAs(m_InputValues->CellAttributeMatrixPath.createChildPath(EbsdLib::H5OINA::Euler)); + auto& eulerDataStoreRef = eulerRef.getDataStoreRef(); + + for(size_t i = 0; i < totalPoints; i++) + { + if(crystalStructuresDSRef[cellPhasesDSRef[i]] == EbsdLib::CrystalStructure::Hexagonal_High) + { + eulerDataStoreRef[3 * i + 2] = eulerDataStoreRef[3 * i + 2] + 30.0F; // See the documentation for this correction factor + } + } + } +} + +} // namespace + +// ----------------------------------------------------------------------------- +ImportH5OinaData::ImportH5OinaData(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, ImportH5DataInputValues* inputValues) +: ImportH5Data(dataStructure, mesgHandler, shouldCancel, inputValues) +{ +} + +// ----------------------------------------------------------------------------- +ImportH5OinaData::~ImportH5OinaData() noexcept = default; + +// ----------------------------------------------------------------------------- +Result<> ImportH5OinaData::operator()() +{ + return execute(); +} + +// ----------------------------------------------------------------------------- +Result<> ImportH5OinaData::copyRawEbsdData(int index) +{ + const auto& imageGeom = m_DataStructure.getDataRefAs(m_InputValues->ImageGeometryPath); + const usize totalPoints = imageGeom.getNumXCells() * imageGeom.getNumYCells(); + const usize offset = index * totalPoints; + + copyRawData(m_InputValues, totalPoints, m_DataStructure, *m_Reader, EbsdLib::H5OINA::BandContrast, offset); + copyRawData(m_InputValues, totalPoints, m_DataStructure, *m_Reader, EbsdLib::H5OINA::BandSlope, offset); + copyRawData(m_InputValues, totalPoints, m_DataStructure, *m_Reader, EbsdLib::H5OINA::Bands, offset); + copyRawData(m_InputValues, totalPoints, m_DataStructure, *m_Reader, EbsdLib::H5OINA::Error, offset); + copyRawData(m_InputValues, totalPoints * 3, m_DataStructure, *m_Reader, EbsdLib::H5OINA::Euler, offset); + copyRawData(m_InputValues, totalPoints, m_DataStructure, *m_Reader, EbsdLib::H5OINA::MeanAngularDeviation, offset); + if(m_InputValues->ConvertPhaseToInt32) + { + const nonstd::span rawDataPtr(reinterpret_cast(m_Reader->getPointerByName(EbsdLib::H5OINA::Phase)), totalPoints); + using ArrayType = DataArray; + auto& dataRef = m_DataStructure.getDataRefAs(m_InputValues->CellAttributeMatrixPath.createChildPath(EbsdLib::H5OINA::Phase)); + auto* dataStorePtr = dataRef.getDataStore(); + for(size_t i = 0; i < totalPoints; i++) + { + dataStorePtr->setValue(i + offset, static_cast(rawDataPtr[i])); + } + } + else + { + copyRawData(m_InputValues, totalPoints, m_DataStructure, *m_Reader, EbsdLib::H5OINA::Phase, offset); + } + copyRawData(m_InputValues, totalPoints, m_DataStructure, *m_Reader, EbsdLib::H5OINA::X, offset); + copyRawData(m_InputValues, totalPoints, m_DataStructure, *m_Reader, EbsdLib::H5OINA::Y, offset); + + if(m_InputValues->EdaxHexagonalAlignment) + { + if(m_InputValues->ConvertPhaseToInt32) + { + convertHexEulerAngle(m_InputValues, totalPoints, m_DataStructure); + } + else + { + convertHexEulerAngle(m_InputValues, totalPoints, m_DataStructure); + } + } + + + if(m_InputValues->ReadPatternData) + { + const uint16* patternDataPtr = m_Reader->getPatternData(); + std::array pDims = {{0, 0}}; + m_Reader->getPatternDims(pDims); + if(pDims[0] != 0 && pDims[1] != 0) + { + std::vector pDimsV(2); + pDimsV[0] = pDims[0]; + pDimsV[1] = pDims[1]; + auto& patternData = m_DataStructure.getDataRefAs(m_InputValues->CellAttributeMatrixPath.createChildPath(EbsdLib::H5OINA::UnprocessedPatterns)); + const usize numComponents = patternData.getNumberOfComponents(); + for(usize i = 0; i < totalPoints; i++) + { + for(usize j = 0; j < numComponents; ++j) + { + patternData[offset + numComponents * i + j] = patternDataPtr[numComponents * i + j]; + } + } + } + } + + return {}; +} diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/ImportH5OinaData.hpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/ImportH5OinaData.hpp new file mode 100644 index 0000000000..7146d9493a --- /dev/null +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/Algorithms/ImportH5OinaData.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include "OrientationAnalysis/OrientationAnalysis_export.hpp" +#include "OrientationAnalysis/utilities/ImportH5Data.hpp" + +namespace complex +{ + +/** + * @class ImportH5OinaData + * @brief This filter will read a single .h5 file into a new Image Geometry, allowing the immediate use of Filters on the data instead of having to generate the + * intermediate .h5ebsd file. + */ + +class ORIENTATIONANALYSIS_EXPORT ImportH5OinaData : public ImportH5Data +{ +public: + ImportH5OinaData(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, ImportH5DataInputValues* inputValues); + ~ImportH5OinaData() noexcept override; + + ImportH5OinaData(const ImportH5OinaData&) = delete; + ImportH5OinaData(ImportH5OinaData&&) noexcept = delete; + ImportH5OinaData& operator=(const ImportH5OinaData&) = delete; + ImportH5OinaData& operator=(ImportH5OinaData&&) noexcept = delete; + + Result<> operator()(); + + Result<> copyRawEbsdData(int index) override; + +}; + +} // namespace complex diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/ImportH5EspritDataFilter.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/ImportH5EspritDataFilter.cpp index 3b27a3e27d..a18260ed57 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/ImportH5EspritDataFilter.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/ImportH5EspritDataFilter.cpp @@ -67,7 +67,7 @@ Parameters ImportH5EspritDataFilter::parameters() const params.insertSeparator(Parameters::Separator{"Input Parameters"}); params.insert(std::make_unique(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::AllowedManufacturers{EbsdLib::OEM::Bruker, EbsdLib::OEM::DREAM3D},*/ OEMEbsdScanSelectionParameter::EbsdReaderType::Esprit, OEMEbsdScanSelectionParameter::ExtensionsType{".h5"})); params.insert(std::make_unique(k_ZSpacing_Key, "Z Spacing (Microns)", "The spacing in microns between each layer.", 1.0f)); params.insert(std::make_unique(k_Origin_Key, "Origin", "The origin of the volume", std::vector{0.0F, 0.0F, 0.0F}, std::vector{"x", "y", "z"})); diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/ImportH5OimDataFilter.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/ImportH5OimDataFilter.cpp index 7fa8089441..a0a8b93b40 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/ImportH5OimDataFilter.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/ImportH5OimDataFilter.cpp @@ -64,7 +64,8 @@ Parameters ImportH5OimDataFilter::parameters() const // Create the parameter descriptors that are needed for this filter params.insertSeparator(Parameters::Separator{"Input Parameters"}); params.insert(std::make_unique(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::EDAX}, + OEMEbsdScanSelectionParameter::ValueType{}, + /* OEMEbsdScanSelectionParameter::AllowedManufacturers{EbsdLib::OEM::EDAX},*/ OEMEbsdScanSelectionParameter::EbsdReaderType::Oim, OEMEbsdScanSelectionParameter::ExtensionsType{".h5"})); params.insert(std::make_unique(k_ZSpacing_Key, "Z Spacing (Microns)", "The spacing in microns between each layer.", 1.0f)); params.insert(std::make_unique(k_Origin_Key, "Origin", "The origin of the volume", std::vector{0.0F, 0.0F, 0.0F}, std::vector{"x", "y", "z"})); diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/ImportH5OinaDataFilter.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/ImportH5OinaDataFilter.cpp new file mode 100644 index 0000000000..1a0c6c4d73 --- /dev/null +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/ImportH5OinaDataFilter.cpp @@ -0,0 +1,215 @@ +#include "ImportH5OinaDataFilter.hpp" + +#include "OrientationAnalysis/Filters/Algorithms/ImportH5OinaData.hpp" +#include "OrientationAnalysis/Parameters/OEMEbsdScanSelectionParameter.h" + +#include "complex/DataStructure/DataPath.hpp" +#include "complex/DataStructure/Geometry/ImageGeom.hpp" +#include "complex/Filter/Actions/CreateArrayAction.hpp" +#include "complex/Filter/Actions/CreateAttributeMatrixAction.hpp" +#include "complex/Filter/Actions/CreateImageGeometryAction.hpp" +#include "complex/Filter/Actions/CreateStringArrayAction.hpp" +#include "complex/Parameters/BoolParameter.hpp" +#include "complex/Parameters/DataGroupCreationParameter.hpp" +#include "complex/Parameters/DataObjectNameParameter.hpp" +#include "complex/Parameters/FileSystemPathParameter.hpp" +#include "complex/Parameters/NumberParameter.hpp" +#include "complex/Parameters/VectorParameter.hpp" + +#include "EbsdLib/IO/HKL/CtfFields.h" +#include "EbsdLib/IO/HKL/H5OINAReader.h" + +#include +namespace fs = std::filesystem; + +using namespace complex; + +namespace complex +{ +//------------------------------------------------------------------------------ +std::string ImportH5OinaDataFilter::name() const +{ + return FilterTraits::name.str(); +} + +//------------------------------------------------------------------------------ +std::string ImportH5OinaDataFilter::className() const +{ + return FilterTraits::className; +} + +//------------------------------------------------------------------------------ +Uuid ImportH5OinaDataFilter::uuid() const +{ + return FilterTraits::uuid; +} + +//------------------------------------------------------------------------------ +std::string ImportH5OinaDataFilter::humanName() const +{ + return "Import Oxford Aztec Data (.h5oina)"; +} + +//------------------------------------------------------------------------------ +std::vector ImportH5OinaDataFilter::defaultTags() const +{ + return {className(), "IO", "Input", "Read", "Import", "Oxford", "CTF", "H5OINA", "EBSD"}; +} + +//------------------------------------------------------------------------------ +Parameters ImportH5OinaDataFilter::parameters() const +{ + Parameters params; + + // Create the parameter descriptors that are needed for this filter + params.insertSeparator(Parameters::Separator{"Input Parameters"}); + params.insert(std::make_unique(k_SelectedScanNames_Key, "Scan Names", "The name of the scan in the .h5oina file. Oxford can store multiple scans in a single file", + OEMEbsdScanSelectionParameter::ValueType{}, + /* OEMEbsdScanSelectionParameter::AllowedManufacturers{EbsdLib::OEM::EDAX}, */ + OEMEbsdScanSelectionParameter::EbsdReaderType::H5Oina, + OEMEbsdScanSelectionParameter::ExtensionsType{".h5oina"})); + params.insert(std::make_unique(k_EdaxHexagonalAlignment_Key, "Convert Hexagonal X-Axis to EDAX Standard", + "Whether or not to convert a Hexagonal phase to the EDAX standard for x-axis alignment", true)); + params.insert(std::make_unique(k_ConvertPhaseToInt32_Key, "Convert Phase Data to In32", + "Native Phases data value is uint8. Convert to Int32 for better filter compatibility", true)); + params.insert(std::make_unique(k_ZSpacing_Key, "Z Spacing (Microns)", "The spacing in microns between each layer.", 1.0f)); + params.insert(std::make_unique(k_Origin_Key, "Origin", "The origin of the volume", std::vector{0.0F, 0.0F, 0.0F}, std::vector{"x", "y", "z"})); + params.insert(std::make_unique(k_ReadPatternData_Key, "Import Pattern Data", "Whether or not to import the pattern data", false)); + params.insert(std::make_unique(k_ImageGeometryName_Key, "Image Geometry", "The path to the created Image Geometry", DataPath({ImageGeom::k_TypeName}))); + params.insertSeparator(Parameters::Separator{"Cell Data"}); + params.insert(std::make_unique(k_CellAttributeMatrixName_Key, "Cell Attribute Matrix", "The name of the cell data attribute matrix for the created Image Geometry", + ImageGeom::k_CellDataName)); + params.insertSeparator(Parameters::Separator{"Cell Ensemble Data"}); + params.insert(std::make_unique(k_CellEnsembleAttributeMatrixName_Key, "Cell Ensemble Attribute Matrix", + "The name of the cell ensemble data attribute matrix for the created Image Geometry", "Cell Ensemble Data")); + + return params; +} + +//------------------------------------------------------------------------------ +IFilter::UniquePointer ImportH5OinaDataFilter::clone() const +{ + return std::make_unique(); +} + +//------------------------------------------------------------------------------ +IFilter::PreflightResult ImportH5OinaDataFilter::preflightImpl(const DataStructure& dataStructure, const Arguments& filterArgs, const MessageHandler& messageHandler, + const std::atomic_bool& shouldCancel) const +{ + auto pSelectedScanNamesValue = filterArgs.value(k_SelectedScanNames_Key); + auto pZSpacingValue = filterArgs.value(k_ZSpacing_Key); + auto pOriginValue = filterArgs.value(k_Origin_Key); + auto pReadPatternDataValue = filterArgs.value(k_ReadPatternData_Key); + auto pImageGeometryNameValue = filterArgs.value(k_ImageGeometryName_Key); + auto pCellAttributeMatrixNameValue = filterArgs.value(k_CellAttributeMatrixName_Key); + auto pCellEnsembleAttributeMatrixNameValue = filterArgs.value(k_CellEnsembleAttributeMatrixName_Key); + auto pConvertPhaseData = filterArgs.value(k_ConvertPhaseToInt32_Key); + + + DataPath cellEnsembleAMPath = pImageGeometryNameValue.createChildPath(pCellEnsembleAttributeMatrixNameValue); + DataPath cellAMPath = pImageGeometryNameValue.createChildPath(pCellAttributeMatrixNameValue); + + PreflightResult preflightResult; + complex::Result resultOutputActions; + std::vector preflightUpdatedValues; + + if(pZSpacingValue <= 0) + { + return MakePreflightErrorResult(-9580, "The Z Spacing field contains a value that is non-positive. The Z Spacing field must be set to a positive value."); + } + if(pSelectedScanNamesValue.scanNames.empty()) + { + return MakePreflightErrorResult(-9581, "At least one scan must be chosen. Please select a scan from the list."); + } + + // read in the necessary info from the input h5 file + H5OINAReader reader; + reader.setFileName(pSelectedScanNamesValue.inputFilePath.string()); + reader.setReadPatternData(pReadPatternDataValue); + reader.setHDF5Path(pSelectedScanNamesValue.scanNames.front()); + if(const int err = reader.readHeaderOnly(); err < 0) + { + return MakePreflightErrorResult(-9582, fmt::format("An error occurred while reading the header data\n{} : {}", err, reader.getErrorMessage())); + } + + // create the Image Geometry and it's attribute matrices + const CreateImageGeometryAction::DimensionType dims = {static_cast(reader.getXDimension()), static_cast(reader.getYDimension()), pSelectedScanNamesValue.scanNames.size()}; + const std::vector tupleDims = {dims[2], dims[1], dims[0]}; + { + CreateImageGeometryAction::SpacingType spacing = {reader.getXStep(), reader.getYStep(), pZSpacingValue}; + + auto createDataGroupAction = std::make_unique(pImageGeometryNameValue, dims, pOriginValue, spacing, pCellAttributeMatrixNameValue); + resultOutputActions.value().appendAction(std::move(createDataGroupAction)); + } + const auto phases = reader.getPhaseVector(); + std::vector ensembleTupleDims{phases.size() + 1}; + { + auto createAttributeMatrixAction = std::make_unique(cellEnsembleAMPath, ensembleTupleDims); + resultOutputActions.value().appendAction(std::move(createAttributeMatrixAction)); + } + + // create the cell ensemble arrays + { + auto createArrayAction = std::make_unique(DataType::uint32, ensembleTupleDims, std::vector{1}, cellEnsembleAMPath.createChildPath(EbsdLib::CtfFile::CrystalStructures)); + resultOutputActions.value().appendAction(std::move(createArrayAction)); + } + { + auto createArrayAction = std::make_unique(DataType::float32, ensembleTupleDims, std::vector{6}, cellEnsembleAMPath.createChildPath(EbsdLib::CtfFile::LatticeConstants)); + resultOutputActions.value().appendAction(std::move(createArrayAction)); + } + { + auto createArrayAction = std::make_unique(ensembleTupleDims, cellEnsembleAMPath.createChildPath(EbsdLib::CtfFile::MaterialName)); + resultOutputActions.value().appendAction(std::move(createArrayAction)); + } + + // create the cell data arrays + resultOutputActions.value().appendAction(std::make_unique(DataType::uint8, tupleDims, std::vector{1}, cellAMPath.createChildPath(EbsdLib::H5OINA::BandContrast))); + resultOutputActions.value().appendAction(std::make_unique(DataType::uint8, tupleDims, std::vector{1}, cellAMPath.createChildPath(EbsdLib::H5OINA::BandSlope))); + resultOutputActions.value().appendAction(std::make_unique(DataType::uint8, tupleDims, std::vector{1}, cellAMPath.createChildPath(EbsdLib::H5OINA::Bands))); + resultOutputActions.value().appendAction(std::make_unique(DataType::uint8, tupleDims, std::vector{1}, cellAMPath.createChildPath(EbsdLib::H5OINA::Error))); + resultOutputActions.value().appendAction(std::make_unique(DataType::float32, tupleDims, std::vector{3}, cellAMPath.createChildPath(EbsdLib::H5OINA::Euler))); + resultOutputActions.value().appendAction(std::make_unique(DataType::float32, tupleDims, std::vector{1}, cellAMPath.createChildPath(EbsdLib::H5OINA::MeanAngularDeviation))); + if(pConvertPhaseData) + { + resultOutputActions.value().appendAction(std::make_unique(DataType::int32, tupleDims, std::vector{1}, cellAMPath.createChildPath(EbsdLib::H5OINA::Phase))); + } + else + { + resultOutputActions.value().appendAction(std::make_unique(DataType::uint8, tupleDims, std::vector{1}, cellAMPath.createChildPath(EbsdLib::H5OINA::Phase))); + } + resultOutputActions.value().appendAction(std::make_unique(DataType::float32, tupleDims, std::vector{1}, cellAMPath.createChildPath(EbsdLib::H5OINA::X))); + resultOutputActions.value().appendAction(std::make_unique(DataType::float32, tupleDims, std::vector{1}, cellAMPath.createChildPath(EbsdLib::H5OINA::Y))); + + if(pReadPatternDataValue) + { + std::array patternDims = {{0, 0}}; + reader.getPatternDims(patternDims); + if(patternDims[0] == 0 || patternDims[1] == 0) + { + return MakePreflightErrorResult(-9583, fmt::format("The parameter 'Read Pattern Data' has been enabled but there does not seem to be any pattern data in the file for the scan name selected")); + } + auto createArrayAction = std::make_unique(DataType::uint16, tupleDims, std::vector{static_cast(patternDims[0]), static_cast(patternDims[1])}, + cellAMPath.createChildPath(EbsdLib::H5OINA::UnprocessedPatterns)); + resultOutputActions.value().appendAction(std::move(createArrayAction)); + } + + return {std::move(resultOutputActions), std::move(preflightUpdatedValues)}; +} + +//------------------------------------------------------------------------------ +Result<> ImportH5OinaDataFilter::executeImpl(DataStructure& dataStructure, const Arguments& filterArgs, const PipelineFilter* pipelineNode, const MessageHandler& messageHandler, + const std::atomic_bool& shouldCancel) const +{ + ImportH5DataInputValues inputValues; + + inputValues.SelectedScanNames = filterArgs.value(k_SelectedScanNames_Key); + inputValues.ReadPatternData = filterArgs.value(k_ReadPatternData_Key); + inputValues.ImageGeometryPath = filterArgs.value(k_ImageGeometryName_Key); + inputValues.CellEnsembleAttributeMatrixPath = inputValues.ImageGeometryPath.createChildPath(filterArgs.value(k_CellEnsembleAttributeMatrixName_Key)); + inputValues.CellAttributeMatrixPath = inputValues.ImageGeometryPath.createChildPath(filterArgs.value(k_CellAttributeMatrixName_Key)); + inputValues.ConvertPhaseToInt32 = filterArgs.value(k_ConvertPhaseToInt32_Key); + inputValues.EdaxHexagonalAlignment = filterArgs.value(k_EdaxHexagonalAlignment_Key); + + return ImportH5OinaData(dataStructure, messageHandler, shouldCancel, &inputValues)(); +} +} // namespace complex diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/ImportH5OinaDataFilter.hpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/ImportH5OinaDataFilter.hpp new file mode 100644 index 0000000000..8a846418ca --- /dev/null +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Filters/ImportH5OinaDataFilter.hpp @@ -0,0 +1,105 @@ +#pragma once + +#include "OrientationAnalysis/OrientationAnalysis_export.hpp" + +#include "complex/Filter/FilterTraits.hpp" +#include "complex/Filter/IFilter.hpp" + +namespace complex +{ +/** + * @class ImportH5OinaDataFilter + * @brief This filter will read a single .h5 file into a new Image Geometry, allowing the immediate use of Filters on the data instead of having to generate the + * intermediate .h5ebsd file. + */ +class ORIENTATIONANALYSIS_EXPORT ImportH5OinaDataFilter : public IFilter +{ +public: + ImportH5OinaDataFilter() = default; + ~ImportH5OinaDataFilter() noexcept override = default; + + ImportH5OinaDataFilter(const ImportH5OinaDataFilter&) = delete; + ImportH5OinaDataFilter(ImportH5OinaDataFilter&&) noexcept = delete; + + ImportH5OinaDataFilter& operator=(const ImportH5OinaDataFilter&) = delete; + ImportH5OinaDataFilter& operator=(ImportH5OinaDataFilter&&) noexcept = delete; + + // Parameter Keys + static inline constexpr StringLiteral k_SelectedScanNames_Key = "selected_scan_names"; + static inline constexpr StringLiteral k_ZSpacing_Key = "z_spacing"; + static inline constexpr StringLiteral k_Origin_Key = "origin"; + static inline constexpr StringLiteral k_ReadPatternData_Key = "read_pattern_data"; + static inline constexpr StringLiteral k_ImageGeometryName_Key = "image_geometry_name"; + static inline constexpr StringLiteral k_CellAttributeMatrixName_Key = "cell_attribute_matrix_name"; + static inline constexpr StringLiteral k_CellEnsembleAttributeMatrixName_Key = "cell_ensemble_attribute_matrix_name"; + static inline constexpr StringLiteral k_EdaxHexagonalAlignment_Key = "edax_hexagonal_alignment"; + static inline constexpr StringLiteral k_ConvertPhaseToInt32_Key = "convert_phase_to_int32"; + + /** + * @brief Returns the name of the filter. + * @return + */ + std::string name() const override; + + /** + * @brief Returns the C++ classname of this filter. + * @return + */ + std::string className() const override; + + /** + * @brief Returns the uuid of the filter. + * @return + */ + Uuid uuid() const override; + + /** + * @brief Returns the human readable name of the filter. + * @return + */ + std::string humanName() const override; + + /** + * @brief Returns the default tags for this filter. + * @return + */ + std::vector defaultTags() const override; + + /** + * @brief Returns the parameters of the filter (i.e. its inputs) + * @return + */ + Parameters parameters() const override; + + /** + * @brief Returns a copy of the filter. + * @return + */ + UniquePointer clone() const override; + +protected: + /** + * @brief Takes in a DataStructure and checks that the filter can be run on it with the given arguments. + * Returns any warnings/errors. Also returns the changes that would be applied to the DataStructure. + * Some parts of the actions may not be completely filled out if all the required information is not available at preflight time. + * @param dataStructure The input DataStructure instance + * @param filterArgs These are the input values for each parameter that is required for the filter + * @param messageHandler The MessageHandler object + * @return Returns a Result object with error or warning values if any of those occurred during execution of this function + */ + PreflightResult preflightImpl(const DataStructure& dataStructure, const Arguments& filterArgs, const MessageHandler& messageHandler, const std::atomic_bool& shouldCancel) const override; + + /** + * @brief Applies the filter's algorithm to the DataStructure with the given arguments. Returns any warnings/errors. + * On failure, there is no guarantee that the DataStructure is in a correct state. + * @param ds The input DataStructure instance + * @param filterArgs These are the input values for each parameter that is required for the filter + * @param messageHandler The MessageHandler object + * @return Returns a Result object with error or warning values if any of those occurred during execution of this function + */ + Result<> executeImpl(DataStructure& data, const Arguments& filterArgs, const PipelineFilter* pipelineNode, const MessageHandler& messageHandler, const std::atomic_bool& shouldCancel) const override; +}; +} // namespace complex + +COMPLEX_DEF_FILTER_TRAITS(complex, ImportH5OinaDataFilter, "fad3d47f-f1e1-4429-bc65-5e021be62ba0"); +/* LEGACY UUID FOR THIS FILTER 3ff4701b-3a0c-52e3-910a-fa927aa6584c */ diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Parameters/OEMEbsdScanSelectionParameter.cpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Parameters/OEMEbsdScanSelectionParameter.cpp index e1b617e82d..b7352b362e 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Parameters/OEMEbsdScanSelectionParameter.cpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Parameters/OEMEbsdScanSelectionParameter.cpp @@ -4,13 +4,13 @@ #include "complex/Common/StringLiteral.hpp" #include "complex/Utilities/StringUtilities.hpp" -#include "H5Support/H5ScopedSentinel.h" -#include "H5Support/H5Utilities.h" - -#include "EbsdLib/IO/BrukerNano/EspritConstants.h" -#include "EbsdLib/IO/BrukerNano/H5EspritReader.h" -#include "EbsdLib/IO/HKL/CtfFields.h" -#include "EbsdLib/IO/TSL/H5OIMReader.h" +//#include "H5Support/H5ScopedSentinel.h" +//#include "H5Support/H5Utilities.h" +// +//#include "EbsdLib/IO/BrukerNano/EspritConstants.h" +//#include "EbsdLib/IO/BrukerNano/H5EspritReader.h" +//#include "EbsdLib/IO/HKL/CtfFields.h" +//#include "EbsdLib/IO/TSL/H5OIMReader.h" #include #include @@ -28,10 +28,10 @@ constexpr StringLiteral k_ScanNames = "scan_names"; //----------------------------------------------------------------------------- OEMEbsdScanSelectionParameter::OEMEbsdScanSelectionParameter(const std::string& name, const std::string& humanName, const std::string& helpText, const ValueType& defaultValue, - const AllowedManufacturers& allowedManufacturers, const EbsdReaderType& readerType, const ExtensionsType& extensionsType) + /* const AllowedManufacturers& allowedManufacturers,*/ const EbsdReaderType& readerType, const ExtensionsType& extensionsType) : ValueParameter(name, humanName, helpText) , m_DefaultValue(defaultValue) -, m_AllowedManufacturers(allowedManufacturers) +//, m_AllowedManufacturers(allowedManufacturers) , m_AvailableExtensions(extensionsType) , m_ReaderType(readerType) { @@ -111,11 +111,13 @@ Result OEMEbsdScanSelectionParameter::fromJson(const nlohmann::json& j } } + constexpr int32 k_LowtoHigh = 0; + constexpr int32 k_HightoLow = 1; const auto orderCheck = json[k_StackingOrder].get(); - if(orderCheck != EbsdLib::RefFrameZDir::LowtoHigh && orderCheck != EbsdLib::RefFrameZDir::HightoLow) + if(orderCheck != k_LowtoHigh && orderCheck != k_HightoLow) { return MakeErrorResult(FilterParameter::Constants::k_Json_Value_Not_Enumeration, fmt::format("{}JSON value for key '{}' was not a valid ordering Value. [{}|{}] allowed.", prefix.view(), - k_StackingOrder.view(), EbsdLib::RefFrameZDir::LowtoHigh, EbsdLib::RefFrameZDir::HightoLow)); + k_StackingOrder.view(), k_LowtoHigh, k_HightoLow)); } ValueType value; @@ -161,7 +163,7 @@ Result OEMEbsdScanSelectionParameter::fromJson(const nlohmann::json& j //----------------------------------------------------------------------------- IParameter::UniquePointer OEMEbsdScanSelectionParameter::clone() const { - return std::make_unique(name(), humanName(), helpText(), m_DefaultValue, m_AllowedManufacturers, m_ReaderType, m_AvailableExtensions); + return std::make_unique(name(), humanName(), helpText(), m_DefaultValue, m_ReaderType, m_AvailableExtensions); } //----------------------------------------------------------------------------- @@ -194,50 +196,51 @@ Result<> OEMEbsdScanSelectionParameter::validate(const std::any& valueRef) const return {nonstd::make_unexpected(std::vector{{-20032, fmt::format("File extension '{}' is not a valid file extension.", value.inputFilePath.extension().string())}})}; } - if(value.stackingOrder != EbsdLib::RefFrameZDir::LowtoHigh && value.stackingOrder != EbsdLib::RefFrameZDir::HightoLow) - { - errors.push_back({-20033, fmt::format("{} is not a valid value for the stacking order. Please choose either {} or {}", value.stackingOrder, EbsdLib::RefFrameZDir::LowtoHigh, - EbsdLib::RefFrameZDir::HightoLow)}); - return {nonstd::make_unexpected(std::move(errors))}; - } - - std::list scanNames; - int32 err = 0; - if(m_ReaderType == EbsdReaderType::Oim) - { - const H5OIMReader::Pointer reader = H5OIMReader::New(); - reader->setFileName(value.inputFilePath.string()); - err = reader->readScanNames(scanNames); - } - else - { - const H5EspritReader::Pointer reader = H5EspritReader::New(); - reader->setFileName(value.inputFilePath.string()); - err = reader->readScanNames(scanNames); - } - - if(err < 0) - { - errors.push_back({-20034, fmt::format("H5 file '{}' could not be opened. Reported error code from the H5OIMReader class is '{}'", value.inputFilePath.string(), err)}); - return {nonstd::make_unexpected(std::move(errors))}; - } - - const ManufacturerType manufacturer = ReadManufacturer(value.inputFilePath.string()); - if(m_AllowedManufacturers.find(manufacturer) == m_AllowedManufacturers.end()) - { - errors.push_back({-20035, fmt::format("Original data source type {} is not a valid manufacturer", fmt::underlying(manufacturer))}); - return {nonstd::make_unexpected(std::move(errors))}; - } - - if(value.scanNames.empty()) - { - errors.push_back({-20036, fmt::format("At least one scan must be chosen. Please select a scan from the list.")}); - return {nonstd::make_unexpected(std::move(errors))}; - } +// if(value.stackingOrder != EbsdLib::RefFrameZDir::LowtoHigh && value.stackingOrder != EbsdLib::RefFrameZDir::HightoLow) +// { +// errors.push_back({-20033, fmt::format("{} is not a valid value for the stacking order. Please choose either {} or {}", value.stackingOrder, EbsdLib::RefFrameZDir::LowtoHigh, +// EbsdLib::RefFrameZDir::HightoLow)}); +// return {nonstd::make_unexpected(std::move(errors))}; +// } +// +// std::list scanNames; +// int32 err = 0; +// if(m_ReaderType == EbsdReaderType::Oim) +// { +// const H5OIMReader::Pointer reader = H5OIMReader::New(); +// reader->setFileName(value.inputFilePath.string()); +// err = reader->readScanNames(scanNames); +// } +// else +// { +// const H5EspritReader::Pointer reader = H5EspritReader::New(); +// reader->setFileName(value.inputFilePath.string()); +// err = reader->readScanNames(scanNames); +// } +// +// if(err < 0) +// { +// errors.push_back({-20034, fmt::format("H5 file '{}' could not be opened. Reported error code from the H5OIMReader class is '{}'", value.inputFilePath.string(), err)}); +// return {nonstd::make_unexpected(std::move(errors))}; +// } +// +// const ManufacturerType manufacturer = ReadManufacturer(value.inputFilePath.string()); +// if(m_AllowedManufacturers.find(manufacturer) == m_AllowedManufacturers.end()) +// { +// errors.push_back({-20035, fmt::format("Original data source type {} is not a valid manufacturer", fmt::underlying(manufacturer))}); +// return {nonstd::make_unexpected(std::move(errors))}; +// } +// +// if(value.scanNames.empty()) +// { +// errors.push_back({-20036, fmt::format("At least one scan must be chosen. Please select a scan from the list.")}); +// return {nonstd::make_unexpected(std::move(errors))}; +// } return {}; } +#if 0 //----------------------------------------------------------------------------- OEMEbsdScanSelectionParameter::ManufacturerType OEMEbsdScanSelectionParameter::ReadManufacturer(const std::string& inputFile) { @@ -285,6 +288,8 @@ OEMEbsdScanSelectionParameter::ManufacturerType OEMEbsdScanSelectionParameter::R return manuf; } +#endif + //----------------------------------------------------------------------------- OEMEbsdScanSelectionParameter::ExtensionsType OEMEbsdScanSelectionParameter::getAvailableExtensions() const { diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Parameters/OEMEbsdScanSelectionParameter.h b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Parameters/OEMEbsdScanSelectionParameter.h index 767f1886a3..4458318eb8 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Parameters/OEMEbsdScanSelectionParameter.h +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/Parameters/OEMEbsdScanSelectionParameter.h @@ -5,7 +5,7 @@ #include "complex/Utilities/FilePathGenerator.hpp" #include "complex/complex_export.hpp" -#include "EbsdLib/Core/EbsdLibConstants.h" +//#include "EbsdLib/Core/EbsdLibConstants.h" #include #include @@ -26,16 +26,17 @@ class COMPLEX_EXPORT OEMEbsdScanSelectionParameter : public ValueParameter struct ValueType { fs::path inputFilePath; - int32 stackingOrder = EbsdLib::RefFrameZDir::LowtoHigh; + int32 stackingOrder = 0; // Low to High This is the same from EbsdLib. If EbsdLib changes, this should change std::list scanNames = {}; }; - using ManufacturerType = EbsdLib::OEM; - using AllowedManufacturers = std::unordered_set; +// using ManufacturerType = EbsdLib::OEM; +// using AllowedManufacturers = std::unordered_set; using ExtensionsType = std::unordered_set; enum EbsdReaderType : uint8 { Oim = 0, - Esprit = 1 + Esprit = 1, + H5Oina = 2 }; OEMEbsdScanSelectionParameter() = delete; @@ -47,7 +48,8 @@ class COMPLEX_EXPORT OEMEbsdScanSelectionParameter : public ValueParameter * @param helpText The help text that should be displayed to a user * @param defaultValue The default value for the parameter */ - OEMEbsdScanSelectionParameter(const std::string& name, const std::string& humanName, const std::string& helpText, const ValueType& defaultValue, const AllowedManufacturers& allowedManufacturers, + OEMEbsdScanSelectionParameter(const std::string& name, const std::string& humanName, const std::string& helpText, const ValueType& defaultValue, + /* const AllowedManufacturers& allowedManufacturers, */ const EbsdReaderType& readerType, const ExtensionsType& extensionsType); ~OEMEbsdScanSelectionParameter() override = default; @@ -117,11 +119,11 @@ class COMPLEX_EXPORT OEMEbsdScanSelectionParameter : public ValueParameter * @param inputFile * @return */ - static ManufacturerType ReadManufacturer(const std::string& inputFile); + //static ManufacturerType ReadManufacturer(const std::string& inputFile); private: ValueType m_DefaultValue = {}; - AllowedManufacturers m_AllowedManufacturers = {}; +// AllowedManufacturers m_AllowedManufacturers = {}; ExtensionsType m_AvailableExtensions = {}; EbsdReaderType m_ReaderType = {}; }; diff --git a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/utilities/ImportH5Data.hpp b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/utilities/ImportH5Data.hpp index 2735fcf774..1cdd05b7c8 100644 --- a/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/utilities/ImportH5Data.hpp +++ b/src/Plugins/OrientationAnalysis/src/OrientationAnalysis/utilities/ImportH5Data.hpp @@ -10,6 +10,7 @@ #include "EbsdLib/IO/BrukerNano/H5EspritReader.h" #include "EbsdLib/IO/TSL/H5OIMReader.h" +#include "EbsdLib/IO/HKL/H5OINAReader.h" namespace complex { @@ -20,6 +21,8 @@ struct ORIENTATIONANALYSIS_EXPORT ImportH5DataInputValues DataPath ImageGeometryPath; DataPath CellAttributeMatrixPath; DataPath CellEnsembleAttributeMatrixPath; + bool EdaxHexagonalAlignment; + bool ConvertPhaseToInt32; }; /** @@ -55,6 +58,8 @@ class ORIENTATIONANALYSIS_EXPORT ImportH5Data int index = 0; for(const auto& currentScanName : m_InputValues->SelectedScanNames.scanNames) { + m_MessageHandler({IFilter::Message::Type::Info, fmt::format("Importing Index {}", currentScanName)}); + Result<> readResults = readData(currentScanName); if(readResults.invalid()) { diff --git a/src/Plugins/OrientationAnalysis/wrapping/python/orientationanalysis.cpp b/src/Plugins/OrientationAnalysis/wrapping/python/orientationanalysis.cpp index 58d0dfb048..58bba1439c 100644 --- a/src/Plugins/OrientationAnalysis/wrapping/python/orientationanalysis.cpp +++ b/src/Plugins/OrientationAnalysis/wrapping/python/orientationanalysis.cpp @@ -43,23 +43,13 @@ PYBIND11_MODULE(orientationanalysis, mod) oemEbsdScanSelectionEbsdReaderType.value("Oim", OEMEbsdScanSelectionParameter::EbsdReaderType::Oim); oemEbsdScanSelectionEbsdReaderType.value("Esprit", OEMEbsdScanSelectionParameter::EbsdReaderType::Esprit); - py::enum_ oemEbsdScanSelectionManufacturerType(oemEbsdScanSelectionParameter, "ManufacturerType"); - oemEbsdScanSelectionManufacturerType.value("EDAX", OEMEbsdScanSelectionParameter::ManufacturerType::EDAX); - oemEbsdScanSelectionManufacturerType.value("Oxford", OEMEbsdScanSelectionParameter::ManufacturerType::Oxford); - oemEbsdScanSelectionManufacturerType.value("Bruker", OEMEbsdScanSelectionParameter::ManufacturerType::Bruker); - oemEbsdScanSelectionManufacturerType.value("HEDM", OEMEbsdScanSelectionParameter::ManufacturerType::HEDM); - oemEbsdScanSelectionManufacturerType.value("Zeiss", OEMEbsdScanSelectionParameter::ManufacturerType::Zeiss); - oemEbsdScanSelectionManufacturerType.value("Phillips", OEMEbsdScanSelectionParameter::ManufacturerType::Phillips); - oemEbsdScanSelectionManufacturerType.value("ThermoFisher", OEMEbsdScanSelectionParameter::ManufacturerType::ThermoFisher); - oemEbsdScanSelectionManufacturerType.value("DREAM3D", OEMEbsdScanSelectionParameter::ManufacturerType::DREAM3D); - oemEbsdScanSelectionManufacturerType.value("Unknown", OEMEbsdScanSelectionParameter::ManufacturerType::Unknown); - BindParameterConstructor(h5EbsdReaderParameter); oemEbsdScanSelectionParameter.def( - py::init(), - "name"_a, "human_name"_a, "help_text"_a, "default_value"_a, "allowed_manufacturers"_a, "reader_type"_a, "extensions_type"_a); + "name"_a, "human_name"_a, "help_text"_a, "default_value"_a, "reader_type"_a, "extensions_type"_a); internals.addConversion(); internals.addConversion(); diff --git a/vcpkg-configuration.json b/vcpkg-configuration.json index 1b8b96e351..0527509613 100644 --- a/vcpkg-configuration.json +++ b/vcpkg-configuration.json @@ -8,11 +8,9 @@ "blosc", "boost-mp11", "catch2", - "ebsdlib", "eigen3", "expected-lite", "fmt", - "h5support", "hdf5", "lz4", "itk", diff --git a/vcpkg.json b/vcpkg.json index f7a1f04959..0141c46343 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -69,14 +69,6 @@ } ] }, - "ebsd": { - "description": "Ebsd data processing", - "dependencies": [ - { - "name": "ebsdlib" - } - ] - }, "compressors": { "description": "Compressors for binary data", "dependencies": [