Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -567,4 +567,7 @@ scratch/

build/
build_man/
venv/
venv/
CmakeFiles
CMakeCache.txt
.devcontainer/
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ Here is an example of building and installing `Argolid` in a Python virtual envi
```
python -m virtualenv venv
source venv/bin/activate
pip install cmake
git clone https://github.com/sameeul/argolid.git
pip install cmake setuptools looseversion
git clone https://github.com/polusai/argolid.git
cd argolid
mkdir build_deps
cd build_deps
sh ../ci_utils/install_prereq_linux.sh
sh ../ci-utils/install_prereq_linux.sh # on linux prefer bash over sh
cd ../
export ARGOLID_DER_DIR=./build_deps/local_install
export ARGOLID_DEP_DIR=./build_deps/local_install
python setup.py install
```

Expand Down
8 changes: 4 additions & 4 deletions ci-utils/install_prereq_linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ if [[ "$OSTYPE" == "darwin"* ]]; then
cd zlib-1.3.1
mkdir build_man
cd build_man
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_INSTALL_PREFIX=/usr/local ..
cmake --build .
cmake --build . --target install
cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_INSTALL_PREFIX=/usr/local ..
cmake --build .
cmake --build . --target install
cd ../../

curl -L https://github.com/libjpeg-turbo/libjpeg-turbo/archive/refs/tags/3.1.0.zip -o 3.1.0.zip
unzip 3.1.0.zip
cd libjpeg-turbo-3.1.0
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["setuptools>=61.0", "wheel", "looseversion", "versioneer", "cmake"]
build-backend = "setuptools.build_meta"
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import os
import re
import sys
import versioneer
import platform
import subprocess

from distutils.version import LooseVersion
from looseversion import LooseVersion
from setuptools import setup, find_packages, Extension
from setuptools.command.build_ext import build_ext

import versioneer

class CMakeExtension(Extension):
def __init__(self, name, sourcedir=""):
Expand Down
46 changes: 29 additions & 17 deletions src/cpp/core/chunked_pyramid_assembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ ImageInfo OmeTiffCollToChunked::Assemble(const std::string& input_dir,
int grid_x_max = 0, grid_y_max = 0, grid_c_max = 0;
int grid_x_min = INT_MAX, grid_y_min = INT_MAX, grid_c_min = INT_MAX;
std::vector<ImageSegment> image_vec;
ImageInfo whole_image;
ImageInfo whole_image {};

auto fp = std::make_unique<FilePattern> (input_dir, pattern);
auto files = fp->getFiles();
Expand Down Expand Up @@ -163,22 +163,34 @@ ImageInfo OmeTiffCollToChunked::Assemble(const std::string& input_dir,
array).value();

tensorstore::IndexTransform<> transform = tensorstore::IdentityTransform(dest.domain());
if(v == VisType::PCNG){
transform = (std::move(transform) | tensorstore::Dims("z", "channel").IndexSlice({z, i._c_grid-grid_c_min})
| tensorstore::Dims(y_dim).SizedInterval((i._y_grid-grid_y_min)*whole_image._chunk_size_y, image_height)
| tensorstore::Dims(x_dim).SizedInterval((i._x_grid-grid_x_min)*whole_image._chunk_size_x, image_width)
| tensorstore::Dims(x_dim, y_dim).Transpose({y_dim, x_dim})).value();

} else if (v == VisType::NG_Zarr){
transform = (std::move(transform) | tensorstore::Dims(c_dim).SizedInterval(i._c_grid-grid_c_min, 1)
| tensorstore::Dims(z_dim).SizedInterval(z, 1)
| tensorstore::Dims(y_dim).SizedInterval((i._y_grid-grid_y_min)*whole_image._chunk_size_y, image_height)
| tensorstore::Dims(x_dim).SizedInterval((i._x_grid-grid_x_min)*whole_image._chunk_size_x, image_width)).value();
} else if (v == VisType::Viv){
transform = (std::move(transform) | tensorstore::Dims(c_dim).SizedInterval(i._c_grid-grid_c_min, 1)
| tensorstore::Dims(z_dim).SizedInterval(z, 1)
| tensorstore::Dims(y_dim).SizedInterval((i._y_grid-grid_y_min)*whole_image._chunk_size_y, image_height)
| tensorstore::Dims(x_dim).SizedInterval((i._x_grid-grid_x_min)*whole_image._chunk_size_x, image_width)).value();
auto yy = (i._y_grid - grid_y_min) * whole_image._chunk_size_y;
auto xx = (i._x_grid - grid_x_min) * whole_image._chunk_size_x;
auto cc = (i._c_grid - grid_c_min);

switch (v) {
case VisType::PCNG:
transform =
(std::move(transform)
| tensorstore::Dims("z", "channel").IndexSlice({z, cc})
| tensorstore::Dims(y_dim).SizedInterval(yy, image_height)
| tensorstore::Dims(x_dim).SizedInterval(xx, image_width)
| tensorstore::Dims(x_dim, y_dim).Transpose({y_dim, x_dim}))
.value();
break;

case VisType::NG_Zarr: // same as Viv
case VisType::Viv:
transform =
(std::move(transform)
| tensorstore::Dims(c_dim).SizedInterval(cc, 1)
| tensorstore::Dims(z_dim).SizedInterval(z, 1)
| tensorstore::Dims(y_dim).SizedInterval(yy, image_height)
| tensorstore::Dims(x_dim).SizedInterval(xx, image_width))
.value();
break;

default:
throw std::invalid_argument("Unsupported VisType");
}
tensorstore::Write(array, dest | transform).value();
});
Expand Down
12 changes: 11 additions & 1 deletion src/cpp/core/ome_tiff_to_chunked_pyramid.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "ome_tiff_to_chunked_pyramid.h"
#include <filesystem>
#include <stdexcept>

namespace fs = std::filesystem;

Expand Down Expand Up @@ -47,7 +48,16 @@ void OmeTiffToChunkedPyramid::GenerateFromCollection(
int base_level_key = 0;
PLOG_INFO << "Assembling base image...";
auto whole_image =_tiff_coll_to_chunk.Assemble(collection_path, stitch_vector_file, chunked_file_dir, std::to_string(base_level_key), v, _th_pool);
int max_level = static_cast<int>(ceil(log2(std::max({whole_image._full_image_width, whole_image._full_image_width}))));

if (whole_image._full_image_height <= 0 ||
whole_image._full_image_width <= 0) {
PLOG_WARNING << "Assembled image height and width must be positive "
<< "(height=" + std::to_string(whole_image._full_image_height) + ", width=" + std::to_string(whole_image._full_image_width) + ")\n"
<< "No (tiff) images images found in the collection_path : " + collection_path + " please check the path"
<< "\n";
return;
}
int max_level = static_cast<int>(ceil(log2(std::max({whole_image._full_image_width, whole_image._full_image_height}))));
int min_level = static_cast<int>(ceil(log2(min_dim)));
auto max_level_key = max_level-min_level+1+base_level_key;
PLOG_INFO << "Generating image pyramids...";
Expand Down
10 changes: 5 additions & 5 deletions src/cpp/utilities/utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,12 +248,12 @@ void WriteTSZattrFilePlateImage(
}

void WriteVivZattrFile(const std::string& tiff_file_name, const std::string& zattr_file_loc, int min_level, int max_level){

json scale_metadata_list = json::array();
for(int i=min_level; i<=max_level; ++i){
json scale_metadata;
scale_metadata["path"] = std::to_string(i);
scale_metadata_list.push_back(scale_metadata);

for (int i = min_level; i <= max_level; ++i) {
scale_metadata_list.emplace_back(json{
{"path", std::to_string(i)}
});
}

json combined_metadata;
Expand Down
20 changes: 16 additions & 4 deletions src/python/argolid/pyramid_generator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
from pydantic import BaseModel, Field, field_validator
from typing import Dict, Optional, List
from enum import IntEnum
from .libargolid import OmeTiffToChunkedPyramidCPP, VisType, DSType, PyramidViewCPP

class LogLevel(IntEnum):
NONE = 0
FATAL = 1
ERROR = 2
WARNING = 3
INFO = 4
DEBUG = 5
VERBOSE = 6


class Downsample(BaseModel):
channel_name: str
method: str
Expand All @@ -10,7 +21,7 @@ class Downsample(BaseModel):
def check_method_config(cls, v):
if v not in {"mean", "mode_max", "mode_min"}:
raise ValueError(f'Value must be "mean", mode_max or "mode_min".')
return v
return v

class PlateVisualizationMetadata(BaseModel):
output_type: str
Expand All @@ -32,16 +43,17 @@ def check_output_type_config(cls, v):
return v

class PyramidGenerartor:
def __init__(self, log_level = None) -> None:
def __init__(self, log_level = LogLevel.NONE) -> None:
self._pyr_generator = OmeTiffToChunkedPyramidCPP()
self.vis_types_dict ={ "NG_Zarr" : VisType.NG_Zarr, "PCNG" : VisType.PCNG, "Viv" : VisType.Viv}
self.ds_types_dict = {"mean" : DSType.Mean, "mode_max" : DSType.Mode_Max, "mode_min" : DSType.Mode_Min}
self._pyr_generator.SetLogLevel(log_level)

def generate_from_single_image(self, input_file, output_dir, min_dim, vis_type, ds_dict = {}):

channel_ds_dict = {}
for c, ds in ds_dict:
channel_ds_dict[c] = self.ds_types_dict[ds]
for c in ds_dict:
channel_ds_dict[c] = self.ds_types_dict[ds_dict[c]]
self._pyr_generator.GenerateFromSingleFile(input_file, output_dir, min_dim, self.vis_types_dict[vis_type], channel_ds_dict)

def generate_from_image_collection(self, collection_path, pattern , image_name, output_dir, min_dim, vis_type, ds_dict = {}):
Expand Down
Loading