{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"using HDF5\n",
"using Dates \n",
"using Images\n",
"#https://portal.hdfgroup.org/display/HDF5/Introduction+to+HDF5\n",
"# https://docs.julialang.org/en/v1/stdlib/Dates/#Dates.format-Tuple{TimeType,AbstractString} \n",
"# https://cpb-us-w2.wpmucdn.com/sites.wustl.edu/dist/f/1861/files/2019/02/02-imaris-image-properties-and-edit-2jj1avj.pdf"
]
},
{
"cell_type": "code",
"execution_count": 343,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array_to_ims (generic function with 9 methods)"
]
},
"execution_count": 343,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# https://github.com/tlambert03/imarispy/blob/master/imarispy/imaris.py\n",
"function array_to_ims(array, fname::String=\"myfile.ims\",\n",
" subsamp=((1, 1, 1)),\n",
" chunks=((16, 128, 128)),\n",
" compression=2,\n",
" thumbsize=256,\n",
" dx=0.108, dz=0.5, dt_min=10)\n",
"\n",
" df = DateFormat(\"Y-mm-dd HH:MM:SS.sss\")\n",
" RecordingDate = DateTime(2020,5,7,14,19,22,0)\n",
" \n",
" nx, ny, nz, nt = size(array)\n",
" nc = 1\n",
" nr = 1 #nr = length(subsamp)\n",
" \n",
" GROUPS = [\n",
" \"DataSetInfo\",\n",
" \"Thumbnail\",\n",
" \"DataSetTimes\",\n",
" \"DataSetInfo/Imaris\",\n",
" \"DataSetInfo/Image\",\n",
" \"DataSetInfo/TimeInfo\"\n",
" ]\n",
"\n",
"\n",
" ATTRS = [\n",
" (\"/\", \"ImarisDataSet\", \"ImarisDataSet\"),\n",
" (\"/\", \"ImarisVersion\", \"5.5.0\"),\n",
" (\"/\", \"DataSetInfoDirectoryName\", \"DataSetInfo\"),\n",
" (\"/\", \"ThumbnailDirectoryName\", \"Thumbnail\"),\n",
" (\"/\", \"DataSetDirectoryName\", \"DataSet\"),\n",
" (\"DataSetInfo/Imaris\", \"Version\", \"9.5\"),\n",
" (\"DataSetInfo/Imaris\", \"ThumbnailMode\", \"thumbnailMIP\"),\n",
" (\"DataSetInfo/Imaris\", \"ThumbnailSize\", thumbsize),\n",
" (\"DataSetInfo/Image\", \"X\", nx),\n",
" (\"DataSetInfo/Image\", \"Y\", ny),\n",
" (\"DataSetInfo/Image\", \"Z\", nz),\n",
" (\"DataSetInfo/Image\", \"NumberOfChannels\", nc),\n",
" (\"DataSetInfo/Image\", \"Noc\", nc),\n",
" (\"DataSetInfo/Image\", \"Unit\", \"um\"),\n",
" (\"DataSetInfo/Image\", \"Description\", \"Hi\"),\n",
" (\"DataSetInfo/Image\", \"MicroscopeModality\", \"Inverted Microscope\"),\n",
" (\"DataSetInfo/Image\", \"RecordingDate\", Dates.format(RecordingDate, df)),\n",
" (\"DataSetInfo/Image\", \"Name\", \"qblab\"),\n",
" (\"DataSetInfo/Image\", \"ExtMin0\", \"0\"),\n",
" (\"DataSetInfo/Image\", \"ExtMin1\", \"0\"),\n",
" (\"DataSetInfo/Image\", \"ExtMin2\", \"0\"),\n",
" (\"DataSetInfo/Image\", \"ExtMax0\", nx * dx),\n",
" (\"DataSetInfo/Image\", \"ExtMax1\", ny * dx),\n",
" (\"DataSetInfo/Image\", \"ExtMax2\", nz * dz),\n",
" (\"DataSetInfo/Image\", \"LensPower\", \"40x\"),\n",
" (\"DataSetInfo/TimeInfo\", \"DatasetTimePoints\", nt),\n",
" (\"DataSetInfo/TimeInfo\", \"FileTimePoints\", nt)\n",
" ];\n",
" \n",
" COLORS = (\"1 1 1\", \"1 0 1\", \"1 1 0\", \"0 0 1\")\n",
" for c in 0:nc-1\n",
" grp = \"DataSetInfo/Channel $c\"\n",
" push!(GROUPS, grp)\n",
" push!(ATTRS, (grp, \"ColorOpacity\", 1))\n",
" push!(ATTRS, (grp, \"ColorMode\", \"BaseColor\"))\n",
" push!(ATTRS, (grp, \"Color\", COLORS[1]))\n",
" push!(ATTRS, (grp, \"GammaCorrection\", 1))\n",
" push!(ATTRS, (grp, \"ColorRange\", \"0 255\"))\n",
" push!(ATTRS, (grp, \"Name\", \"Channel $c\"))\n",
" end\n",
" \n",
" for t in 0:nt-1\n",
" strr = Dates.format(RecordingDate + Dates.Minute(dt_min*t), df)\n",
" #strr = \"2020-05-07 {:02d}:{:02d}:{:02d}.000\".format(h, m, s)\n",
" push!(ATTRS, (\"DataSetInfo/TimeInfo\", \"TimePoint$t\", strr))\n",
" #TODO: Imaris don't use these timestamps as time axis\n",
" end\n",
" \n",
" h5open(fname, \"w\") do file\n",
" for grp in GROUPS\n",
" g_create(file, grp)\n",
" end\n",
" \n",
" for info in ATTRS\n",
" grp, key = info[1:2]\n",
" value = \"$(info[3])\"\n",
" h5a_write_S1(file[grp], key, value)\n",
" end\n",
"\n",
" file[\"Thumbnail/Data\"] = UInt8.(maximum(array[:,:, 1:20,1], dims=3).>>8)\n",
" \n",
" # add data\n",
" for t in 0:nt-1\n",
" for c in 0:nc-1\n",
" data = array[:, :, :, t+1]\n",
" for r in 0:nr-1\n",
" edges, count = build_histogram(data, 256)\n",
" grp = g_create(file, \"/DataSet/ResolutionLevel $r/TimePoint $t/Channel $c/\")\n",
" grp[\"Histogram\"] = UInt64.(count[1:end])\n",
" h5a_write_S1(grp, \"HistogramMin\", \"1000\")\n",
" h5a_write_S1(grp, \"HistogramMax\", \"$(edges[end])\")\n",
" grp[\"Data\", \"chunk\", (256,256,4), \"compress\", compression] = data\n",
" h5a_write_S1(grp, \"ImageSizeX\", \"$(size(data)[1])\")\n",
" h5a_write_S1(grp, \"ImageSizeY\", \"$(size(data)[2])\")\n",
" h5a_write_S1(grp, \"ImageSizeZ\", \"$(size(data)[3])\")\n",
" end\n",
" end\n",
" end\n",
" end\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 250,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"h5a_write_S1 (generic function with 1 method)"
]
},
"execution_count": 250,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function h5a_write_S1(parent, key, value)\n",
" dspace = dataspace((length(value),))\n",
" try\n",
" attr = a_create(parent, key, HDF5Datatype(HDF5.H5T_C_S1), dspace)\n",
" HDF5.writearray(attr, HDF5.H5T_C_S1, value)\n",
" finally\n",
" close(dspace)\n",
" end\n",
" nothing\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 264,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"┌ Info: Precompiling ImageMagick [6218d12a-5da1-5696-b52f-db25d2ecc6d1]\n",
"└ @ Base loading.jl:1260\n"
]
}
],
"source": [
"img = load(File(format\"TIFF\",\"d16s1_1_otsu_norm.ome.tiff\"));"
]
},
{
"cell_type": "code",
"execution_count": 267,
"metadata": {},
"outputs": [],
"source": [
"x = reshape(img, (512,512, 20, 138));"
]
},
{
"cell_type": "code",
"execution_count": 286,
"metadata": {},
"outputs": [],
"source": [
"test_img = rand(UInt16, (512, 512, 24, 138));"
]
},
{
"cell_type": "code",
"execution_count": 317,
"metadata": {},
"outputs": [],
"source": [
"reinterpret.(N0f8.(x));"
]
},
{
"cell_type": "code",
"execution_count": 335,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 10.019962 seconds (16.66 k allocations: 1.619 GiB, 1.10% gc time)\n"
]
}
],
"source": [
"@time array_to_ims(test_img, \"test.ims\")"
]
},
{
"cell_type": "code",
"execution_count": 344,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 21.177768 seconds (793.12 k allocations: 4.092 GiB, 1.47% gc time)\n"
]
}
],
"source": [
"@time array_to_ims(reinterpret.(real(x)), \"d16s1_1_otsu_norm.ome.tiff.ims\")"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Dict{String,Array{String,1}} with 9 entries:\n",
" \"SamplesPerPixel\" => [\"1\"]\n",
" \"Description\" => [\"(\", \"d\", \"e\", \"s\", \"c\", \"r\", \"i\", \"p\", \"t\", \"i\" … \"s…\n",
" \"ColorRange\" => [\"0\", \".\", \"0\", \"0\", \"0\", \" \", \"8\", \"1\", \"1\", \".\", \"0\", …\n",
" \"GammaCorrection\" => [\"1\", \".\", \"0\", \"0\", \"0\"]\n",
" \"ColorOpacity\" => [\"1\", \".\", \"0\", \"0\", \"0\"]\n",
" \"ColorMode\" => [\"B\", \"a\", \"s\", \"e\", \"C\", \"o\", \"l\", \"o\", \"r\"]\n",
" \"Name\" => [\"(\", \"n\", \"a\", \"m\", \"e\", \" \", \"n\", \"o\", \"t\", \" \", \"s\", …\n",
" \"Color\" => [\"1\", \".\", \"0\", \"0\", \"0\", \" \", \"0\", \".\", \"0\", \"0\", \"0\", …\n",
" \"ID\" => [\"C\", \"h\", \"a\", \"n\", \"n\", \"e\", \"l\", \":\", \"0\", \":\", \"0\"]"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y = h5readattr(\"d16s1_2test.h5\", \"DataSetInfo/Channel 0\")"
]
},
{
"cell_type": "code",
"execution_count": 256,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Dict{String,Array{String,1}} with 6 entries:\n",
" \"ColorRange\" => [\"0\", \" \", \"2\", \"5\", \"5\"]\n",
" \"GammaCorrection\" => [\"1\"]\n",
" \"ColorOpacity\" => [\"1\"]\n",
" \"ColorMode\" => [\"B\", \"a\", \"s\", \"e\", \"C\", \"o\", \"l\", \"o\", \"r\"]\n",
" \"Name\" => [\"C\", \"h\", \"a\", \"n\", \"n\", \"e\", \"l\", \" \", \"0\"]\n",
" \"Color\" => [\"1\", \" \", \"1\", \" \", \"1\"]"
]
},
"execution_count": 256,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"z = h5readattr(\"test.h5\", \"DataSetInfo/Channel 0\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.4.0",
"language": "julia",
"name": "julia-1.4"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.4.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}