diff --git a/include/openPMD/IO/IOTask.hpp b/include/openPMD/IO/IOTask.hpp index 8ded6f1775..70bde5ef3d 100644 --- a/include/openPMD/IO/IOTask.hpp +++ b/include/openPMD/IO/IOTask.hpp @@ -142,6 +142,7 @@ struct OPENPMDAPI_EXPORT Parameter std::string name = ""; IterationEncoding encoding = IterationEncoding::groupBased; + std::string openPMDversion; }; template <> diff --git a/include/openPMD/RecordComponent.tpp b/include/openPMD/RecordComponent.tpp index dc796c8180..e695d54aa1 100644 --- a/include/openPMD/RecordComponent.tpp +++ b/include/openPMD/RecordComponent.tpp @@ -21,6 +21,8 @@ #pragma once +#include "openPMD/Datatype.hpp" +#include "openPMD/Error.hpp" #include "openPMD/RecordComponent.hpp" #include "openPMD/Span.hpp" #include "openPMD/auxiliary/Memory.hpp" @@ -29,6 +31,7 @@ #include "openPMD/auxiliary/UniquePtr.hpp" #include +#include namespace openPMD { @@ -92,12 +95,34 @@ inline std::shared_ptr RecordComponent::loadChunk(Offset o, Extent e) #endif } +namespace detail +{ + template + struct do_convert + { + template + static std::optional call(Attribute &attr) + { + if constexpr (std::is_convertible_v) + { + return std::make_optional(attr.get()); + } + else + { + return std::nullopt; + } + } + + static constexpr char const *errorMsg = "is_conversible"; + }; +} // namespace detail + template inline void RecordComponent::loadChunk(std::shared_ptr data, Offset o, Extent e) { Datatype dtype = determineDatatype(data); - if (dtype != getDatatype()) + if (dtype != getDatatype() && !constant()) if (!isSameInteger(getDatatype()) && !isSameFloatingPoint(getDatatype()) && !isSameComplexFloatingPoint(getDatatype()) && @@ -159,10 +184,25 @@ RecordComponent::loadChunk(std::shared_ptr data, Offset o, Extent e) for (auto const &dimensionSize : extent) numPoints *= dimensionSize; - T value = rc.m_constantValue.get(); + std::optional val = + switchNonVectorType>( + /* from = */ getDatatype(), rc.m_constantValue); - T *raw_ptr = data.get(); - std::fill(raw_ptr, raw_ptr + numPoints, value); + if (val.has_value()) + { + T *raw_ptr = data.get(); + std::fill(raw_ptr, raw_ptr + numPoints, *val); + } + else + { + std::string const data_type_str = datatypeToString(getDatatype()); + std::string const requ_type_str = + datatypeToString(determineDatatype()); + std::string err_msg = + "Type conversion during chunk loading not possible! "; + err_msg += "Data: " + data_type_str + "; Load as: " + requ_type_str; + throw error::WrongAPIUsage(err_msg); + } } else { @@ -250,7 +290,7 @@ void RecordComponent::storeChunkRaw(T *ptr, Offset offset, Extent extent) template inline typename std::enable_if_t< - auxiliary::IsContiguousContainer_v > + auxiliary::IsContiguousContainer_v> RecordComponent::storeChunk(T_ContiguousContainer &data, Offset o, Extent e) { uint8_t dim = getDimensionality(); diff --git a/src/IO/JSON/JSONIOHandlerImpl.cpp b/src/IO/JSON/JSONIOHandlerImpl.cpp index 02c9e0710e..c1fd9095a2 100644 --- a/src/IO/JSON/JSONIOHandlerImpl.cpp +++ b/src/IO/JSON/JSONIOHandlerImpl.cpp @@ -455,6 +455,13 @@ void JSONIOHandlerImpl::createFile( access::write(m_handler->m_backendAccess), "[JSON] Creating a file in read-only mode is not possible."); + if (m_attributeModeSpecificationVia == SpecificationVia::DefaultValue) + { + m_attributeMode = parameters.openPMDversion >= "2." + ? AttributeMode::Short + : AttributeMode::Long; + } + if (!writable->written) { std::string name = parameters.name + m_originalExtension; diff --git a/src/Iteration.cpp b/src/Iteration.cpp index 9e402f419d..3e79dff449 100644 --- a/src/Iteration.cpp +++ b/src/Iteration.cpp @@ -206,6 +206,7 @@ void Iteration::flushFileBased( /* create file */ Parameter fCreate; fCreate.name = filename; + fCreate.openPMDversion = s.openPMD(); IOHandler()->enqueue(IOTask(&s.writable(), fCreate)); /* create basePath */ diff --git a/src/Series.cpp b/src/Series.cpp index cebba774f8..60d468e426 100644 --- a/src/Series.cpp +++ b/src/Series.cpp @@ -926,6 +926,7 @@ void Series::flushGorVBased( Parameter fCreate; fCreate.name = series.m_name; fCreate.encoding = iterationEncoding(); + fCreate.openPMDversion = openPMD(); IOHandler()->enqueue(IOTask(this, fCreate)); }