Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
2cf31dd
StorageDevice introduced - work in progress
nenada Mar 29, 2024
09cc8c9
go2scope device introduced
nenada Apr 3, 2024
67d503b
Storage instance added and MMCore plumbing
nenada Apr 4, 2024
c7fb810
storage instance: further work
nenada Apr 5, 2024
68b53f8
Storage API cleanup
nenada Apr 6, 2024
fdd7dc9
Minimal MMCore interface sketched out
nenada Apr 9, 2024
cc6a4c3
loadDataset added
nenada Apr 23, 2024
8b0b3a3
vector<int> arguments replaced with vector<long> to help with Swig
nenada Apr 30, 2024
9e744a0
implementation of data read functions
nenada Aug 24, 2024
58f105d
storage instance methods populated
nenada Aug 25, 2024
3d95a2f
nlohmann json library added
nenada Aug 28, 2024
8cbb354
StroageMnager copied from go2scope. Requres extensive refactoring
nenada Aug 28, 2024
ccbfbe1
cleaned up API signatures in MMCore
nenada Apr 30, 2024
7b33e5b
storage manager refactored
nenada Sep 16, 2024
8cfa575
acquire zarr linked into the device adapter, other dependencies still…
nenada Aug 9, 2024
b2b3a6f
static runtime selected
nenada Aug 16, 2024
b3b8f89
temporarily commented out zar library
nenada Sep 26, 2024
d9f2c25
Merge branch 'main' of https://github.com/go2scope/mmCoreAndDevicesSD
nenada Aug 16, 2024
de52c7f
zarr storage device created and separated from the upcoming tiff4 sto…
nenada Sep 27, 2024
7f0f9e8
Merge branch 'main' of https://github.com/go2scope/mmCoreAndDevicesSD
nenada Oct 3, 2024
a38091c
API modified to accomodate forwared declaration of pixel type
nenada Sep 28, 2024
bc2a51f
further integration of zarr
nenada Oct 1, 2024
280e1f1
BigTIFF storage added (branch merged manually)
razrock Oct 10, 2024
3273386
G2STIFF parser added to BigTIFF storage driver
razrock Oct 10, 2024
5abc468
BigTIFF storage - Add image, set dataset info
razrock Oct 11, 2024
4148ad0
G2STiff format: Fixes for read & write access on the same file stream
razrock Oct 11, 2024
6595d47
image number initialized in constructor
nenada Oct 14, 2024
cdc8ad0
Set device interface version to 71. This will have to be updated on t…
nenada Oct 14, 2024
0ce7061
bug fix: MMCore requires explicit declaration of any new device on mu…
nenada Oct 14, 2024
1a5ccab
Storage instance bug fix
nenada Oct 14, 2024
821ec13
bug fixes in zarr storage
nenada Oct 15, 2024
7be4a38
MMCoreJ wrapper fix for storage API
razrock Oct 15, 2024
735abf7
MMCore and MMDevice storage API refactored
nenada Oct 15, 2024
f921976
bug fixes and error messages
nenada Oct 16, 2024
e87917a
comments and TODO items
nenada Oct 16, 2024
68358c0
BigTIFF storage bug fixes, improved error reporting, file naming fixed
razrock Oct 16, 2024
27a181e
bug fix in zarr driver, shape
nenada Oct 16, 2024
1bb3fd3
refactoring at various points in the storage pipeline
nenada Oct 17, 2024
0e28e8c
redundant name removed from the MMCore::load API
nenada Oct 17, 2024
c93f624
G2SBigTiff format reader fixes
razrock Oct 17, 2024
a39ada8
Random access support for G2SBigTiff format
razrock Oct 18, 2024
e7156c3
Go2Scope storage driver - DirectIO device property
razrock Oct 21, 2024
78f2da4
G2S storage driver: Write stream flush cycle property
razrock Oct 23, 2024
6a20801
C++ G2S Storage tests
razrock Oct 24, 2024
10313f1
C++ storage tests: Improved measurement and logging
razrock Oct 24, 2024
fc805c7
MMCore java wrapper: Native support for 16-bit (short[]) addImage
razrock Oct 25, 2024
f3f177d
Storage driver / BigTIFF: Axis order inverted (slowest chaning first)
razrock Oct 29, 2024
ba76bde
MMCore java wrapper fix (storage driver getImage)
razrock Oct 29, 2024
ff15d6f
Merge branch 'main' into develop/zarr
nenada Oct 31, 2024
56c2b62
buf fixes for zarr writer
nenada Nov 1, 2024
a6863a6
zarr dimension order corrected
nenada Nov 1, 2024
5ab02c7
update from lum development - support for chunking
nenada Dec 7, 2024
2831421
MMCore storage api extended to accomodate format discovery
nenada Nov 1, 2024
f38005a
more updates from lum: chunking
nenada Dec 7, 2024
748aee4
Merge branch 'develop/format' into develop/zarr
nenada Dec 7, 2024
ca7da23
reduntant files cleanup
nenada Dec 7, 2024
8a22919
API for storage extended with new functions
nenada Dec 8, 2024
1aa7a11
cleaned up unused files
nenada Dec 9, 2024
1d5a9e5
appendImage() added to device api
nenada Dec 11, 2024
0f360e1
bug fixes, missing API implemented
nenada Dec 18, 2024
a814671
isReadOnly added
nenada Dec 18, 2024
73071a7
device adapter bug fixes and update to the latest API changes
nenada Dec 18, 2024
5410231
custom (mutable) metadata API added, non-restricted slowest dimension…
nenada Dec 31, 2024
af67cfa
MMDevice API bug fixes, documentation update
nenada Feb 7, 2025
6e8ef0d
changes for the MMDevice API fix, added saveAndGet to MMCore to get i…
nenada Feb 7, 2025
d14d2c4
Set PlatformToolset to v142 for new projects
marktsuchida Feb 21, 2025
865b11e
changed API naming convention to include "dataset". Added freeze. Del…
nenada Feb 25, 2025
3fa7f05
metadata length parameter added to all functions accepting metadata s…
nenada Apr 4, 2025
d677379
updated storage tests in C++
nenada Apr 4, 2025
3145826
dataset handle type changed from string to int
nenada Apr 5, 2025
020d376
updated storage tests to reflect the new API
nenada Apr 5, 2025
ec66d4f
custom metadata disk layout format changed. Now in separate subdir.
nenada Apr 6, 2025
289a78c
bug fix: storage device included in core properties
nenada Apr 18, 2025
8726eec
handle lookup mechanism added to MMCore to enable mutliple open datas…
nenada Apr 18, 2025
371b0db
attachStoragetoCircularBuffer, partial implementation
nenada Apr 19, 2025
fffe435
changed using to typedef to avoid swig compiler error
nenada Jul 4, 2025
9223f42
device label bug fix in handle map in MMCore
nenada Jul 4, 2025
e033f56
draft implementation of the attached storage
nenada Jul 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
542 changes: 542 additions & 0 deletions DeviceAdapters/go2scope/AcqZarrStorage.cpp

Large diffs are not rendered by default.

92 changes: 92 additions & 0 deletions DeviceAdapters/go2scope/AcqZarrStorage.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
///////////////////////////////////////////////////////////////////////////////
// FILE: AcqZarrStorage.h
// PROJECT: Micro-Manager
// SUBSYSTEM: DeviceAdapters
//-----------------------------------------------------------------------------
// DESCRIPTION: Go2Scope devices. Includes the experimental StorageDevice
//
// AUTHOR: Nenad Amodaj
//
// COPYRIGHT: Nenad Amodaj, Chan Zuckerberg Initiative, 2024
//
// LICENSE: This file is distributed under the BSD license.
// License text is included with the source distribution.
//
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES.
//
// NOTE: Storage Device development is supported in part by
// Chan Zuckerberg Initiative (CZI)
//
///////////////////////////////////////////////////////////////////////////////

#pragma once
#include "MMDevice.h"
#include "DeviceBase.h"

struct ZarrStream_s;

class AcqZarrStorage : public CStorageBase<AcqZarrStorage>
{
public:
AcqZarrStorage();
virtual ~AcqZarrStorage();

// Device API
// ----------
int Initialize();
int Shutdown();

void GetName(char* pszName) const;
bool Busy();

// Storage API
// -----------
int Create(const char* path, const char* name, int numberOfDimensions, const int shape[], MM::StorageDataType pixType, const char* meta, int metaLength, int* handle);
int ConfigureDimension(int handle, int dimension, const char* name, const char* meaning);
int ConfigureCoordinate(int handle, int dimension, int coordinate, const char* name);
int Close(int handle);
int Load(const char* path, int* handle);
int GetShape(int handle, int shape[]);
int GetDataType(int handle, MM::StorageDataType& pixelDataType) { return dataType; }

int Delete(int handle);
int List(const char* path, char** listOfDatasets, int maxItems, int maxItemLength);
int AddImage(int handle, int sizeInBytes, unsigned char* pixels, int coordinates[], int numCoordinates, const char* imageMeta, int metaLength);
int AppendImage(int handle, int sizeInBytes, unsigned char* pixels, const char* imageMeta, int metaLength);
int GetSummaryMeta(int handle, char** meta);
int GetImageMeta(int handle, int coordinates[], int numCoordinates, char** meta);
const unsigned char* GetImage(int handle, int coordinates[], int numCoordinates);
int GetNumberOfDimensions(int handle, int& numDimensions);
int GetDimension(int handle, int dimension, char* name, int nameLength, char* meaning, int meaningLength);
int GetCoordinate(int handle, int dimension, int coordinate, char* name, int nameLength);
int GetImageCount(int handle, int& imgcnt);
bool IsOpen(int handle);
bool IsReadOnly(int handle);
int GetPath(int handle, char* path, int maxPathLength);
int SetCustomMetadata(int handle, const char* key, const char* content, int contentLength) { return DEVICE_UNSUPPORTED_COMMAND; }
int GetCustomMetadata(int handle, const char* key, char** content) { return DEVICE_UNSUPPORTED_COMMAND; }


// action interface
// ----------------

private:
bool initialized;
ZarrStream_s* zarrStream;
std::vector<int> streamDimensions;
MM::StorageDataType dataType;
std::vector<int> currentCoordinate;
int currentImageNumber;
int streamHandle;
std::string getErrorMessage(int code);
void destroyStream();
int ConvertToZarrType(MM::StorageDataType type);
std::string streamPath;
};

113 changes: 113 additions & 0 deletions DeviceAdapters/go2scope/CFileUtil.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
///////////////////////////////////////////////////////////////////////////////
// FILE: G2SFileUtil.cpp
// PROJECT: Micro-Manager
// SUBSYSTEM: DeviceAdapters
//-----------------------------------------------------------------------------
// DESCRIPTION: Go2Scope devices. Includes the experimental StorageDevice
//
// AUTHOR: Milos Jovanovic <milos@tehnocad.rs>
//
// COPYRIGHT: Nenad Amodaj, Chan Zuckerberg Initiative, 2024
//
// LICENSE: This file is distributed under the BSD license.
// License text is included with the source distribution.
//
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES.
//
// NOTE: Storage Device development is supported in part by
// Chan Zuckerberg Initiative (CZI)
//
///////////////////////////////////////////////////////////////////////////////
#include "G2SFileUtil.h"

/**
* Write integer value to a byte buffer
* @param buff Byte buffer
* @param len Value length (in bytes)
* @param val Integer value
* @author Miloš Jovanović <milos@tehnocad.rs>
* @version 1.0
*/
void writeInt(unsigned char* buff, std::uint8_t len, std::uint64_t val) noexcept
{
if(buff == nullptr || len == 0)
return;
for(auto i = 0; i < len; i++)
buff[i] = (val >> (i * 8)) & 0xff;
}

/**
* Read integer value from a byte buffer
* @param buff Byte buffer
* @param len Value length (in bytes)
* @return Integer value
* @author Miloš Jovanović <milos@tehnocad.rs>
* @version 1.0
*/
std::uint64_t readInt(const unsigned char* buff, std::uint8_t len) noexcept
{
if(buff == nullptr || len == 0 || len > 8)
return 0;
std::uint64_t ret = 0;
for(std::uint8_t i = 0; i < len; i++)
{
auto shift = i * 8;
std::uint64_t xval = (std::uint64_t)buff[i] << shift;
ret |= xval;
}
return ret;
}

/**
* Split CSV line into tokens
* @param line CSV line
* @return Tokens list
*/
std::vector<std::string> splitLineCSV(const std::string& line) noexcept
{
std::vector<std::string> ret;
if(line.empty())
return ret;

std::string curr = "";
bool qopen = false;
int qcnt = 0;
for(char c : line)
{
bool endswithQ = curr.size() >= 1 && curr[curr.size() - 1] == '\"';
bool endswithS = curr.size() >= 1 && curr[curr.size() - 1] == ' ';
bool endswithEQ = curr.size() >= 2 && curr[curr.size() - 1] == '\"' && curr[curr.size() - 1] == '\\';
if(c == ',' && (!qopen || (qcnt % 2 == 0 && (endswithQ || endswithS) && !endswithEQ)))
{
if(curr.size() >= 2 && curr[0] == '\"' && curr[curr.size() - 1] == '\"')
curr = curr.substr(1, curr.size() - 2);
ret.push_back(curr);
curr = "";
qcnt = 0;
qopen = false;
}
else if(c == '"')
{
if(qcnt == 0)
qopen = true;
qcnt++;
//if(qcnt > 1 && qcnt % 2 == 1)
curr += "\"";
}
else
curr += c;
}
if(!curr.empty())
{
if(curr.size() >= 2 && curr[0] == '\"' && curr[curr.size() - 1] == '\"')
curr = curr.substr(1, curr.size() - 2);
ret.push_back(curr);
}
return ret;
}
Loading