Skip to content

Commit

Permalink
ENH: Fix issues reading some 3rd party written .dream3d files
Browse files Browse the repository at this point in the history
Some data arrays had their component dimensions attribute written incorrectly.

Signed-off-by: Michael Jackson <[email protected]>
(cherry picked from commit b74f717)
  • Loading branch information
imikejackson committed Oct 29, 2024
1 parent a3821da commit 2a174de
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 27 deletions.
1 change: 0 additions & 1 deletion cmake/CopyDataFile.cmake.in

This file was deleted.

23 changes: 1 addition & 22 deletions cmake/Utility.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -145,35 +145,14 @@ function(download_test_data)
file(APPEND "${FETCH_FILE_PATH}" "${FETCH_FILE_CONTENTS}")
file(REMOVE "${fetch_data_file}") # Remove the temporary file

if(ARGS_COPY_DATA)
configure_file(${simplnx_SOURCE_DIR}/cmake/CopyDataFile.cmake.in
${fetch_data_file}
@ONLY
)
file(READ "${fetch_data_file}" FETCH_FILE_CONTENTS)
file(APPEND "${FETCH_FILE_PATH}" "${FETCH_FILE_CONTENTS}")
file(REMOVE "${fetch_data_file}")
endif()

#-----
# If we are installing the data files then we need to create a custom install
# rule to ensure the archive contents are actually decompressed and available. Since
# we are possibly making a copy into the binary directory, use that as the source
# location of the data. Running the unit tests might remove the decompressed data
# as a by product.
if(ARGS_INSTALL)
# If we did NOT already copy the data, then do that now during the build
if(NOT ARGS_COPY_DATA)
configure_file(${simplnx_SOURCE_DIR}/cmake/CopyDataFile.cmake.in
${fetch_data_file}
@ONLY
)
file(READ "${fetch_data_file}" FETCH_FILE_CONTENTS)
file(APPEND "${FETCH_FILE_PATH}" "${FETCH_FILE_CONTENTS}")
file(REMOVE "${fetch_data_file}")
endif()

if(is_multi_config)
if(is_multi_config)
set(CX_CONFIG_DIR "$<CONFIG>")
else()
set(CX_CONFIG_DIR ".")
Expand Down
57 changes: 53 additions & 4 deletions src/simplnx/Utilities/Parsing/DREAM3D/Dream3dIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,7 @@ Result<> readLegacyDataArrayDims(const nx::core::HDF5::DatasetReader& dataArrayR
return nx::core::MakeWarningVoidResult(Legacy::k_FailedReadingTupleDims_Code, ss);
}
tDims = tupleAttrib.readAsVector<usize>();
std::reverse(tDims.begin(), tDims.end()); // SIMPL writes the Tuple Dimensions in reverse order to this attribute
// std::reverse(tDims.begin(), tDims.end()); // SIMPL writes the Tuple Dimensions in reverse order to this attribute
}

return {};
Expand Down Expand Up @@ -868,7 +868,17 @@ Result<> readLegacyStringArray(DataStructure& dataStructure, const nx::core::HDF
return {};
}

Result<IDataArray*> readLegacyDataArray(DataStructure& dataStructure, const nx::core::HDF5::DatasetReader& dataArrayReader, DataObject::IdType parentId, bool preflight = false)
/**
* @brief
* @param dataStructure
* @param dataArrayReader
* @param parentId
* @param amTDims
* @param preflight
* @return
*/
Result<IDataArray*> readLegacyDataArray(DataStructure& dataStructure, const nx::core::HDF5::DatasetReader& dataArrayReader, DataObject::IdType parentId, std::vector<uint64>& amTDims,
bool preflight = false)
{
auto size = H5Dget_storage_size(dataArrayReader.getId());
auto typeId = dataArrayReader.getTypeId();
Expand All @@ -883,6 +893,44 @@ Result<IDataArray*> readLegacyDataArray(DataStructure& dataStructure, const nx::
}

Result<IDataArray*> daResult;
// Let's do some sanity checking of the tuple dims and the comp dims
// This is here because some 3rd party apps are trying to write .dream3d
// files but are getting confused about the Tuple Dims and the component
// dims. This bit of code will try to fix the specific issue where the
// .dream3d file essentially had _all_ the dimensions shoved in the
// tuple dimensions.
if(!amTDims.empty()) // If the amTDims are empty we are just reading a Data Array without an Attribute Matrix so skip.
{
//
if(tDims.size() > amTDims.size() && cDims.size() == 1 && cDims[0] == 1)
{
daResult.warnings().push_back(
{-9543, fmt::format(".dream3d file Tuple and Component Dimensions are not correct. DataSet {} does not have correct component dimensions of they are missing.", dataArrayReader.getName())});
cDims.clear();
// Find the index of the first non-matching dimension value.
for(size_t idx = 0; idx < tDims.size(); idx++)
{
// If we are past the end of the AM Dimensions, then copy the value to the component dimensions
if(idx >= amTDims.size())
{
cDims.push_back(tDims[idx]);
}
else if(amTDims[idx] != tDims[idx]) // something went wrong here. Each vector should have the same exact values at the start of the vector
{
// This should not happen at all. If so, bail out now.
cDims.clear(); // just put things back the way they were and fail.
cDims.push_back(1ULL);
daResult.errors().push_back({-9545, fmt::format(".dream3d file Tuple and Component Dimensions are not correct. DataSet {} does not have correct component dimensions of they are missing. An "
"attempt was made to correct this situation but ultimately failed.",
dataArrayReader.getName())});

break; // The first parts of the dimensions should MATCH for this algorithm to work.
}
}
tDims.resize(amTDims.size());
}
}

if(H5Tequal(typeId, H5T_NATIVE_FLOAT) > 0)
{
daResult = createLegacyDataArray<float32>(dataStructure, parentId, dataArrayReader, tDims, cDims, preflight);
Expand Down Expand Up @@ -1092,7 +1140,7 @@ Result<> readLegacyAttributeMatrix(DataStructure& dataStructure, const nx::core:
}
else
{
Result<> result = ConvertResult(std::move(readLegacyDataArray(dataStructure, dataArraySet, attributeMatrix->getId(), preflight)));
Result<> result = ConvertResult(std::move(readLegacyDataArray(dataStructure, dataArraySet, attributeMatrix->getId(), tDims, preflight)));
daResults.push_back(result);
}
}
Expand Down Expand Up @@ -1154,7 +1202,8 @@ void readGenericGeomDims(IGeometry* geom, const nx::core::HDF5::GroupReader& geo
Result<IDataArray*> readLegacyGeomArray(DataStructure& dataStructure, IGeometry* geometry, const nx::core::HDF5::GroupReader& geomGroup, const std::string& arrayName, bool preflight)
{
auto dataArraySet = geomGroup.openDataset(arrayName);
return readLegacyDataArray(dataStructure, dataArraySet, geometry->getId(), preflight);
std::vector<uint64> tDims;
return readLegacyDataArray(dataStructure, dataArraySet, geometry->getId(), tDims, preflight);
}

template <typename T>
Expand Down

0 comments on commit 2a174de

Please sign in to comment.