-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
STYLE: Factor out itkOMEZarrNGFFCommon.h #65
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
/*========================================================================= | ||
* | ||
* Copyright NumFOCUS | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0.txt | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* | ||
*=========================================================================*/ | ||
|
||
#ifndef itkOMEZarrNGFFCommon_h | ||
#define itkOMEZarrNGFFCommon_h | ||
#include "IOOMEZarrNGFFExport.h" | ||
|
||
#include <string> | ||
|
||
#include "itkIOCommon.h" | ||
|
||
#include "tensorstore/container_kind.h" | ||
#include "tensorstore/context.h" | ||
#include "tensorstore/index_space/dim_expression.h" | ||
#include "tensorstore/open.h" | ||
#include "tensorstore/index_space/index_domain.h" | ||
#include "tensorstore/index_space/index_domain_builder.h" | ||
#include "tensorstore/index_space/dim_expression.h" | ||
|
||
#include <nlohmann/json.hpp> | ||
|
||
namespace itk | ||
{ | ||
/** \class OMEZarrNGFFAxis | ||
* | ||
* \brief Represent an OME-Zarr NGFF axis | ||
* | ||
* Open Microscopy Environment Zarr Next Generation File Format | ||
* specification can be found at https://github.com/ome/ngff | ||
* | ||
* \ingroup IOOMEZarrNGFF | ||
*/ | ||
struct IOOMEZarrNGFF_EXPORT OMEZarrAxis | ||
{ | ||
std::string name; | ||
std::string type; | ||
std::string unit; | ||
}; | ||
|
||
// Update an existing "read" specification for an "http" driver to retrieve remote files. | ||
// Note that an "http" driver specification may operate on an HTTP or HTTPS connection. | ||
void | ||
makeKVStoreHTTPDriverSpec(nlohmann::json & spec, const std::string & fullPath); | ||
|
||
tensorstore::DataType | ||
itkToTensorstoreComponentType(const IOComponentEnum itkComponentType); | ||
|
||
// Returns TensorStore KvStore driver name appropriate for this path. | ||
// Options are file, zip. TODO: http, gcs (GoogleCouldStorage), etc. | ||
std::string | ||
getKVstoreDriver(std::string path); | ||
|
||
// JSON file path, e.g. "C:/Dev/ITKIOOMEZarrNGFF/v0.4/cyx.ome.zarr/.zgroup" | ||
void | ||
writeJson(nlohmann::json json, std::string path, std::string driver); | ||
|
||
// JSON file path, e.g. "C:/Dev/ITKIOOMEZarrNGFF/v0.4/cyx.ome.zarr/.zattrs" | ||
bool | ||
jsonRead(const std::string path, nlohmann::json & result, std::string driver); | ||
|
||
// We call tensorstoreToITKComponentType for each type. | ||
// Hopefully compiler will optimize it away via constant propagation and inlining. | ||
#define READ_ELEMENT_IF(typeName) \ | ||
else if (tensorstoreToITKComponentType(tensorstore::dtype_v<typeName>) == this->GetComponentType()) \ | ||
{ \ | ||
ReadFromStore<typeName>(store, storeIORegion, reinterpret_cast<typeName *>(buffer)); \ | ||
} | ||
|
||
// We need to specify dtype for opening. As dtype is dependent on component type, this macro is long. | ||
#define ELEMENT_WRITE(typeName) \ | ||
else if (tensorstoreToITKComponentType(tensorstore::dtype_v<typeName>) == this->GetComponentType()) \ | ||
{ \ | ||
if (sizeof(typeName) == 1) \ | ||
{ \ | ||
dtype = "|"; \ | ||
} \ | ||
if (std::numeric_limits<typeName>::is_integer) \ | ||
{ \ | ||
if (std::numeric_limits<typeName>::is_signed) \ | ||
{ \ | ||
dtype += 'i'; \ | ||
} \ | ||
else \ | ||
{ \ | ||
dtype += 'u'; \ | ||
} \ | ||
} \ | ||
else \ | ||
{ \ | ||
dtype += 'f'; \ | ||
} \ | ||
dtype += std::to_string(sizeof(typeName)); \ | ||
\ | ||
auto openFuture = tensorstore::Open( \ | ||
{ \ | ||
{ "driver", "zarr" }, \ | ||
{ "kvstore", { { "driver", driver }, { "path", this->m_FileName + "/" + path } } }, \ | ||
{ "metadata", \ | ||
{ \ | ||
{ "compressor", { { "id", "blosc" } } }, \ | ||
{ "dtype", dtype }, \ | ||
{ "shape", shape }, \ | ||
} }, \ | ||
}, \ | ||
tsContext, \ | ||
tensorstore::OpenMode::create | tensorstore::OpenMode::delete_existing, \ | ||
tensorstore::ReadWriteMode::read_write); \ | ||
TS_EVAL_CHECK(openFuture); \ | ||
\ | ||
auto writeStore = openFuture.value(); \ | ||
auto * p = reinterpret_cast<typeName const *>(buffer); \ | ||
auto arr = tensorstore::Array(p, shape, tensorstore::c_order); \ | ||
auto writeFuture = tensorstore::Write(tensorstore::UnownedToShared(arr), writeStore); \ | ||
TS_EVAL_CHECK(writeFuture); \ | ||
} | ||
|
||
} // end namespace itk | ||
|
||
#endif // itkOMEZarrNGFFCommon_h |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
/*========================================================================= | ||
* | ||
* Copyright NumFOCUS | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0.txt | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* | ||
*=========================================================================*/ | ||
|
||
#ifndef itkOMEZarrNGFFImageIO_h | ||
#define itkOMEZarrNGFFImageIO_h | ||
#include "IOOMEZarrNGFFExport.h" | ||
|
||
|
||
#include <fstream> | ||
#include <string> | ||
#include <vector> | ||
|
||
#include "itkImageIOBase.h" | ||
|
||
#include "itkOMEZarrNGFFCommon.h" | ||
|
||
namespace itk | ||
{ | ||
|
||
/** \class OMEZarrNGFFTransformIO | ||
* | ||
* \brief Read and write OME-Zarr coordinate transformations. | ||
* | ||
* Open Microscopy Environment Zarr Next Generation File Format | ||
* specification can be found at https://github.com/ome/ngff | ||
* | ||
* \ingroup IOFilters | ||
* \ingroup IOOMEZarrNGFF | ||
*/ | ||
template <typename TParametersValueType> | ||
class ITK_TEMPLATE_EXPORT OMEZarrNGFFTransformIOTemplate : public TransformIOBaseTemplate<TParametersValueType> | ||
{ | ||
public: | ||
/** Standard class typedefs. */ | ||
using Self = OMEZarrNGFFTransformIOTemplate; | ||
using Superclass = TransformIOBaseTemplate<TParametersValueType>; | ||
using Pointer = SmartPointer<Self>; | ||
using typename Superclass::TransformListType; | ||
using typename Superclass::TransformPointer; | ||
using typename Superclass::TransformType; | ||
using ParametersType = typename TransformType::ParametersType; | ||
using ParametersValueType = typename TransformType::ParametersValueType; | ||
using FixedParametersType = typename TransformType::FixedParametersType; | ||
using FixedParametersValueType = typename TransformType::FixedParametersValueType; | ||
|
||
using ConstTransformListType = typename TransformIOBaseTemplate<ParametersValueType>::ConstTransformListType; | ||
|
||
/** Method for creation through the object factory. */ | ||
itkNewMacro(Self); | ||
|
||
/** Run-time type information (and related methods). */ | ||
itkTypeMacro(OMEZarrNGFFTransformIOTemplate, TransformIOBaseTemplate); | ||
|
||
static constexpr unsigned MaximumDimension = 5; // OME-NGFF specifies up to 5D data | ||
static constexpr int INVALID_INDEX = -1; // for specifying enumerated axis slice indices | ||
using AxesCollectionType = std::vector<OMEZarrAxis>; | ||
|
||
/** Special in-memory zip interface. An address needs to be provided in | ||
* the "file name", using pattern address.memory, where address is a | ||
* decimal representation of BufferInfo's address. | ||
* Sample filename: "12341234.memory". */ | ||
using BufferInfo = struct | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This feels like it should be part of the common class for imageIO and transformIO. |
||
{ | ||
char * pointer; | ||
size_t size; | ||
}; | ||
|
||
/** Construct a "magic" file name from the provided bufferInfo. */ | ||
static std::string | ||
MakeMemoryFileName(const BufferInfo & bufferInfo) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also should be common for imageIO and transformIO. |
||
{ | ||
size_t bufferInfoAddress = reinterpret_cast<size_t>(&bufferInfo); | ||
return std::to_string(bufferInfoAddress) + ".memory"; | ||
} | ||
|
||
/*-------- This part of the interfaces deals with reading data. ----- */ | ||
|
||
/** Reads the data from disk into the memory buffer provided. */ | ||
void | ||
Read() override; | ||
|
||
bool | ||
CanReadFile(const char *) override; | ||
|
||
/*-------- This part of the interfaces deals with writing data. ----- */ | ||
|
||
/** Determine the file type. Returns true if this TransformIO can write the | ||
* file specified. */ | ||
bool | ||
CanWriteFile(const char *) override; | ||
|
||
void | ||
Write() override; | ||
|
||
protected: | ||
OMEZarrNGFFTransformIOTemplate(); | ||
~OMEZarrNGFFTransformIOTemplate() override = default; | ||
|
||
void | ||
PrintSelf(std::ostream & os, Indent indent) const override; | ||
|
||
/** Read a single array and set relevant metadata. */ | ||
void | ||
ReadArrayMetadata(std::string path, std::string driver); | ||
|
||
private: | ||
// An empty zip file consists of 22 bytes of "end of central directory" record. More: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also common for imageIO and transformIO |
||
// https://github.com/google/tensorstore/blob/45565464b9f9e2567144d780c3bef365ee3c125a/tensorstore/internal/compression/zip_details.h#L64-L76 | ||
constexpr static unsigned m_EmptyZipSize = 22; | ||
char m_EmptyZip[m_EmptyZipSize] = "PK\x05\x06"; // the rest is filled with zeroes | ||
const BufferInfo m_EmptyZipBufferInfo{ m_EmptyZip, m_EmptyZipSize }; | ||
const std::string m_EmptyZipFileName = MakeMemoryFileName(m_EmptyZipBufferInfo); | ||
|
||
ITK_DISALLOW_COPY_AND_MOVE(OMEZarrNGFFTransformIOTemplate); | ||
}; | ||
} // end namespace itk | ||
|
||
#endif // itkOMEZarrNGFFImageIO_h |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/*========================================================================= | ||
* | ||
* Copyright NumFOCUS | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0.txt | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* | ||
*=========================================================================*/ | ||
#ifndef itkOMEZarrNGFFTransformIOFactory_h | ||
#define itkOMEZarrNGFFTransformIOFactory_h | ||
#include "IOOMEZarrNGFFExport.h" | ||
|
||
#include "itkObjectFactoryBase.h" | ||
#include "itkTransformIOBase.h" | ||
|
||
namespace itk | ||
{ | ||
/** \class OMEZarrNGFFTransformIOFactory | ||
* \brief Create instances of OMEZarrNGFFTransformIO objects using an object factory. | ||
* \ingroup ITKIOOMEZarrNGFF | ||
*/ | ||
class IOOMEZarrNGFF_EXPORT OMEZarrNGFFTransformIOFactory : public ObjectFactoryBase | ||
{ | ||
public: | ||
/** Standard class typedefs. */ | ||
using Self = OMEZarrNGFFTransformIOFactory; | ||
using Superclass = ObjectFactoryBase; | ||
using Pointer = SmartPointer<Self>; | ||
using ConstPointer = SmartPointer<const Self>; | ||
|
||
/** Class methods used to interface with the registered factories. */ | ||
const char * | ||
GetITKSourceVersion() const override; | ||
|
||
const char * | ||
GetDescription() const override; | ||
|
||
/** Method for class instantiation. */ | ||
itkFactorylessNewMacro(Self); | ||
|
||
/** Run-time type information (and related methods). */ | ||
itkTypeMacro(OMEZarrNGFFTransformIOFactory, ObjectFactoryBase); | ||
|
||
/** Register one factory of this type */ | ||
static void | ||
RegisterOneFactory() | ||
{ | ||
OMEZarrNGFFTransformIOFactory::Pointer zarrFactory = OMEZarrNGFFTransformIOFactory::New(); | ||
|
||
ObjectFactoryBase::RegisterFactoryInternal(zarrFactory); | ||
} | ||
|
||
protected: | ||
OMEZarrNGFFTransformIOFactory(); | ||
~OMEZarrNGFFTransformIOFactory() override = default; | ||
|
||
private: | ||
ITK_DISALLOW_COPY_AND_MOVE(OMEZarrNGFFTransformIOFactory); | ||
}; | ||
} // end namespace itk | ||
|
||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The upgrade of ITK seems unrelated to/independent of the rest of the commit ("Factor out itkOMEZarrNGFFCommon.h"). If so, preferably make it a separate commit.