BioLib  4.3.0
A GUI-less version of Bio .NET library for editing & annotating various microscopy image formats.
Loading...
Searching...
No Matches
BioLib.Zarr Class Reference

Bridges BioLib's BioImage to the OmeZarrWriter, exporting a full 5D image as an OME-Zarr v3 dataset on local disk. More...

Static Public Member Functions

static async void SaveZarr (BioImage b, string outputDir)
 Saves the full 5D content of a BioImage as an OME-Zarr v3 dataset at outputDir . All pyramid resolution levels in b.Resolutions are written.
 
static async Task SavePyramidalZarr (BioImage[] levels, string outputDir)
 Saves already-processed pyramid levels as an OME-Zarr multiscale dataset. Each entry in levels is written as one resolution level in the output pyramid.
 
static void SaveROIs (BioImage b, string outputDir)
 Writes all annotations on b as a JSON sidecar file at <outputDir>/rois.json.
 
static List< ROI > LoadROIs (string zarrDir)
 Reads <zarrDir>/rois.json and returns the deserialized list of ROI objects. Returns an empty list when no sidecar file exists.
 
static List< ROI > LoadLabelsAsROIs (BioImage b, string zarrDir)
 Reads every label image stored under <zarrDir>/labels/ according to the OME-NGFF labels spec and converts each unique non-zero integer label ID into a ROI of type ROI.Type.Mask.
 

Static Public Attributes

const string RoiFileName = "rois.json"
 The file name used for the ROI sidecar that sits beside the Zarr dataset.
 

Detailed Description

Bridges BioLib's BioImage to the OmeZarrWriter, exporting a full 5D image as an OME-Zarr v3 dataset on local disk.

XY planes are written in tile-sized chunks so that even whole-slide images never require a full plane to be resident in memory at once. Peak allocation is bounded to a single tile (tileW × tileH × bytesPerSample).

RGB-interleaved buffers are deinterleaved into separate C planes so the output array shape is always (T, C, Z, Y, X) with scalar pixels.

All resolution levels present in b.Resolutions are written, producing a proper OME-NGFF multiscale pyramid.

Member Function Documentation

◆ LoadLabelsAsROIs()

static List< ROI > BioLib.Zarr.LoadLabelsAsROIs ( BioImage b,
string zarrDir )
static

Reads every label image stored under <zarrDir>/labels/ according to the OME-NGFF labels spec and converts each unique non-zero integer label ID into a ROI of type ROI.Type.Mask.

For each label sub-store the finest resolution level (index 0) is read one plane at a time (iterating Z, C, T from the parent b ). Every distinct pixel value > 0 in a plane becomes a separate ROI.Mask whose float array contains 1.0 wherever that label is present and 0.0 elsewhere.

The method is a no-op when no labels/ sub-directory exists, so it is safe to call unconditionally after opening any Zarr store.

Parameters
bThe parent BioImage that supplies physical-size calibration and ZCT extents.
zarrDirRoot path of the Zarr dataset on local disk (the directory that contains zarr.json).
Returns
List of ROI objects (one per unique label ID per plane). Returns an empty list when no labels are found.
1058 {
1059 var result = new List<ROI>();
1060
1061 string labelsDir = Path.Combine(zarrDir, "labels");
1062 if (!Directory.Exists(labelsDir))
1063 return result;
1064
1065 try
1066 {
1067 File.AppendAllText(@"log.txt",
1068 "[BioLib.LoadLabelsAsROIs] zarrDir=" + zarrDir +
1069 " labelsDirExists=True\n");
1070 }
1071 catch { }
1072
1073 // Each sub-directory of labels/ is one label image.
1074 foreach (string labelPath in Directory.GetDirectories(labelsDir))
1075 {
1076 string labelName = Path.GetFileName(labelPath);
1077 try
1078 {
1079 try
1080 {
1081 File.AppendAllText(@"log.txt",
1082 "[BioLib.LoadLabelsAsROIs] labelPath=" + labelPath +
1083 " labelName=" + labelName + "\n");
1084 }
1085 catch { }
1086 result.AddRange(ReadOneLabelStore(b, labelPath, labelName));
1087 }
1088 catch (Exception ex)
1089 {
1090 Console.WriteLine($"[Zarr.LoadLabelsAsROIs] Skipping label '{labelName}': {ex.Message}");
1091 try
1092 {
1093 File.AppendAllText(@"log.txt",
1094 "[BioLib.LoadLabelsAsROIs] EXCEPTION labelName=" + labelName +
1095 " type=" + ex.GetType().Name +
1096 " message=" + ex.Message + "\n");
1097 }
1098 catch { }
1099 }
1100 }
1101
1102 Recorder.Record($"Zarr.LoadLabelsAsROIs({b}, \"{zarrDir}\");");
1103 return result;
1104 }
System.IO.Path Path
Definition Bio.cs:57
return b
Definition Bio.cs:7393
Definition Recorder.cs:12
static void Record(MethodInfo inf, bool isInternal, params object[] args)
Definition Recorder.cs:20

◆ LoadROIs()

static List< ROI > BioLib.Zarr.LoadROIs ( string zarrDir)
static

Reads <zarrDir>/rois.json and returns the deserialized list of ROI objects. Returns an empty list when no sidecar file exists.

969 {
970 var result = new List<ROI>();
971 string path = Path.Combine(zarrDir, RoiFileName);
972
973 if (!File.Exists(path))
974 return result;
975
976 string json = File.ReadAllText(path);
977 var dtos = JsonSerializer.Deserialize<List<RoiDto>>(json);
978 if (dtos == null)
979 return result;
980
981 foreach (var dto in dtos)
982 {
983 var an = new ROI
984 {
985 roiID = dto.RoiId,
986 roiName = dto.RoiName,
987 type = (ROI.Type)Enum.Parse(typeof(ROI.Type), dto.Type),
988 id = dto.Id,
989 shapeIndex = dto.ShapeIndex,
990 Text = dto.Text,
991 serie = dto.Serie,
992 coord = new AForge.ZCT(dto.Z, dto.C, dto.T),
993 strokeWidth= dto.StrokeWidth,
994 fontSize = dto.FontSize,
995 };
996
997 // Closed shapes
998 if (an.type == ROI.Type.Freeform || an.type == ROI.Type.Polygon)
999 an.closed = true;
1000
1001 // Restore colours
1002 if (!string.IsNullOrEmpty(dto.StrokeColor))
1003 {
1004 var sc = dto.StrokeColor.Split(',');
1005 an.strokeColor = AForge.Color.FromArgb(
1006 int.Parse(sc[0]), int.Parse(sc[1]),
1007 int.Parse(sc[2]), int.Parse(sc[3]));
1008 }
1009 if (!string.IsNullOrEmpty(dto.FillColor))
1010 {
1011 var fc = dto.FillColor.Split(',');
1012 an.fillColor = AForge.Color.FromArgb(
1013 int.Parse(fc[0]), int.Parse(fc[1]),
1014 int.Parse(fc[2]), int.Parse(fc[3]));
1015 }
1016
1017 // Restore points then bounding box
1018 if (!string.IsNullOrEmpty(dto.Points))
1019 an.AddPoints(an.stringToPoints(dto.Points));
1020
1021 an.BoundingBox = new AForge.RectangleD(dto.X, dto.Y, dto.W, dto.H);
1022
1023 result.Add(an);
1024 }
1025
1026 Recorder.Record($"Zarr.LoadROIs(\"{zarrDir}\");");
1027 return result;
1028 }
static int serie
Definition Bio.cs:10659
Definition ROI.cs:26
void AddPoints(PointD[] p, bool convertPixelSpace=false, double physX=1, double physY=1)
Definition ROI.cs:1652
Type
Definition ROI.cs:29
const string RoiFileName
The file name used for the ROI sidecar that sits beside the Zarr dataset.
Definition Zarr.cs:874

◆ SavePyramidalZarr()

static async Task BioLib.Zarr.SavePyramidalZarr ( BioImage[] levels,
string outputDir )
static

Saves already-processed pyramid levels as an OME-Zarr multiscale dataset. Each entry in levels is written as one resolution level in the output pyramid.

290 {
291 if (levels == null || levels.Length == 0)
292 throw new ArgumentException("No pyramid levels were provided.", nameof(levels));
293
294 if (Directory.Exists(outputDir))
295 Directory.Delete(outputDir, true);
296 if (File.Exists(outputDir))
297 File.Delete(outputDir);
298
299 var root = levels[0];
300 if (root == null)
301 throw new ArgumentNullException(nameof(levels));
302
303 if (root.SizeX <= 0 || root.SizeY <= 0 || root.SizeZ <= 0 || root.SizeC <= 0 || root.SizeT <= 0)
304 throw new InvalidOperationException(
305 $"Invalid pyramid root dimensions: X={root.SizeX} Y={root.SizeY} Z={root.SizeZ} C={root.SizeC} T={root.SizeT}.");
306
307 int bitsPerSample = DetermineSourceBitsPerSample(root);
308 var sourcePixelFormat = DetermineSourcePixelFormat(root);
309 bool sourceIsInterleavedRgb = IsInterleavedRgbFormat(sourcePixelFormat);
310 int sourceChannelCount = sourceIsInterleavedRgb ? BioImage.GetBands(sourcePixelFormat) : 1;
311 bool sourceIsBGRA = IsBGRAFormat(sourcePixelFormat);
312 int bytesPerSample = bitsPerSample / 8;
313 int tileW = 512;
314 int tileH = 512;
315
316 BioImage.Progress = 0;
317 BioImage.Status = "Preparing pyramid Zarr writer";
318
319 var levelDescriptors = new List<ResolutionLevelDescriptor>();
320 int lastSizeX = int.MaxValue;
321 int lastSizeY = int.MaxValue;
322 bool haveLast = false;
323 var basePixelFormat = DetermineSourcePixelFormat(root);
324
325 for (int lvl = 0; lvl < levels.Length; lvl++)
326 {
327 BioImage levelImage = levels[lvl];
328 if (levelImage == null)
329 continue;
330
331 int levelWidth =
332 levelImage.Resolutions.Count > 0 && levelImage.Resolutions[0].SizeX > 0
333 ? levelImage.Resolutions[0].SizeX
334 : levelImage.SizeX;
335 int levelHeight =
336 levelImage.Resolutions.Count > 0 && levelImage.Resolutions[0].SizeY > 0
337 ? levelImage.Resolutions[0].SizeY
338 : levelImage.SizeY;
339 if (levelWidth <= 0 || levelHeight <= 0)
340 continue;
341
342 var levelPixelFormat = DetermineSourcePixelFormat(levelImage);
343 if (haveLast && levelPixelFormat != basePixelFormat)
344 break;
345
346 if (haveLast && (levelWidth > lastSizeX || levelHeight > lastSizeY))
347 break;
348
349 if (haveLast && levelWidth == lastSizeX && levelHeight == lastSizeY)
350 continue;
351
352 double dsample = root.SizeX > 0 ? (double)root.SizeX / levelWidth : 1.0;
353 if (!double.IsFinite(dsample) || dsample <= 0)
354 dsample = 1.0;
355
356 levelDescriptors.Add(new ResolutionLevelDescriptor(levelWidth, levelHeight, dsample));
357 Log($"[SaveZarr] level={lvl} size={levelWidth}x{levelHeight} downsample={dsample} fmt={levelPixelFormat}");
358 lastSizeX = levelWidth;
359 lastSizeY = levelHeight;
360 haveLast = true;
361 }
362
363 if (levelDescriptors.Count == 0)
364 levelDescriptors.Add(new ResolutionLevelDescriptor(root.SizeX, root.SizeY, 1.0));
365
366 // Fallback: if there is somehow no Resolutions list, use the image dims.
367 var coord = new ZarrNET.Core.ZCT(root.SizeZ, root.SizeC, root.SizeT);
368 var baseDescriptor = new BioImageDescriptor(root.SizeX, root.SizeY, coord)
369 {
370 Name = Path.GetFileNameWithoutExtension(root.Filename),
371 DataType = MapDataType(bitsPerSample),
372 PhysicalSizeX = root.PhysicalSizeX,
373 PhysicalSizeY = root.PhysicalSizeY,
374 PhysicalSizeZ = root.PhysicalSizeZ,
375 ChunkY = tileH,
376 ChunkX = tileW,
377 };
378
379 var writer = await OmeZarrWriter.CreateAsync(outputDir, baseDescriptor, levelDescriptors).ConfigureAwait(false);
380 try
381 {
382 long totalPlanes = Math.Max(1L, (long)levelDescriptors.Count * root.SizeT * root.SizeZ * root.SizeC);
383 long writtenPlanes = 0;
384
385 for (int levelIndex = 0; levelIndex < levels.Length; levelIndex++)
386 {
387 BioImage levelImage = levels[levelIndex];
388 if (levelImage == null)
389 continue;
390
391 ResolutionLevelDescriptor lvlDesc = levelDescriptors[Math.Min(levelIndex, levelDescriptors.Count - 1)];
392 int levelBitsPerSample = DetermineSourceBitsPerSample(levelImage);
393 int levelBytesPerSample = levelBitsPerSample / 8;
394 var levelPixelFormat = DetermineSourcePixelFormat(levelImage);
395 bool levelIsInterleavedRgb = IsInterleavedRgbFormat(levelPixelFormat);
396 int levelChannelCount = levelIsInterleavedRgb ? BioImage.GetBands(levelPixelFormat) : 1;
397 bool levelIsBGRA = IsBGRAFormat(levelPixelFormat);
398
399 BioImage.Status = $"Writing pyramid level {levelIndex + 1}/{levels.Length}";
400
401 for (int t = 0; t < levelImage.SizeT; t++)
402 {
403 for (int z = 0; z < levelImage.SizeZ; z++)
404 {
405 for (int c = 0; c < levelImage.SizeC; c++)
406 {
407 if (levelIsInterleavedRgb)
408 {
409 await WritePlaneInTiles(
410 writer, levelImage, lvlDesc,
411 t, c, z,
412 levelBytesPerSample, tileW, tileH,
413 levelIndex: levelIndex,
414 rgbChannelIndex: c,
415 srcChannelCount: levelChannelCount,
416 isBGRA: levelIsBGRA,
417 logicalC: 0).ConfigureAwait(false);
418 }
419 else
420 {
421 // Pyramid results are full-frame level images. Their
422 // PyramidalOrigin reflects viewport state, not where the
423 // level pixels should be placed in the output pyramid.
424 int originX = 0;
425 int originY = 0;
426
427 await WritePlaneFromBuffer(
428 writer, levelImage, lvlDesc,
429 t, c, z,
430 levelBytesPerSample, tileW, tileH,
431 levelIndex: levelIndex,
432 originX: originX,
433 originY: originY,
434 sourceLevelIndex: 0).ConfigureAwait(false);
435 }
436
437 writtenPlanes++;
438 BioImage.Progress = (float)(writtenPlanes * 100.0 / totalPlanes);
439 }
440 }
441 }
442 }
443 }
444 finally
445 {
446 try
447 {
448 await writer.DisposeAsync().ConfigureAwait(false);
449 }
450 catch
451 {
452 }
453 }
454
455 Recorder.Record($"Zarr.SavePyramidalZarr(new BioImage[] {{ {string.Join(", ", levels.Select(level => level.ToString()))} }}, \"{outputDir}\");");
456 BioImage.Progress = 100;
457 }
List< ResolutionLevelNode > levels
Definition Bio.cs:5268
Definition Bio.cs:1872
int SizeT
Definition Bio.cs:2893
int SizeY
Definition Bio.cs:2873
List< Resolution > Resolutions
Definition Bio.cs:1979
int SizeX
Definition Bio.cs:2864
int SizeC
Definition Bio.cs:2886
int SizeZ
Definition Bio.cs:2882

◆ SaveROIs()

static void BioLib.Zarr.SaveROIs ( BioImage b,
string outputDir )
static

Writes all annotations on b as a JSON sidecar file at <outputDir>/rois.json.

Call this after SaveZarr so that both image data and ROIs live in the same directory and can be round-tripped together.

915 {
916 var dtos = new List<RoiDto>(b.Annotations.Count);
917
918 foreach (ROI an in b.Annotations)
919 {
920 // Encode points as "x,y x,y …" (invariant culture) — same
921 // format used by BioImage.ROIToString / stringToPoints.
922 PointD[] pts = an.GetPoints();
923 var ptSb = new System.Text.StringBuilder();
924 for (int i = 0; i < pts.Length; i++)
925 {
926 if (i > 0) ptSb.Append(' ');
927 ptSb.Append(pts[i].X.ToString(CultureInfo.InvariantCulture));
928 ptSb.Append(',');
929 ptSb.Append(pts[i].Y.ToString(CultureInfo.InvariantCulture));
930 }
931
932 dtos.Add(new RoiDto
933 {
934 RoiId = an.roiID,
935 RoiName = an.roiName,
936 Type = an.type.ToString(),
937 Id = an.id,
938 ShapeIndex = an.shapeIndex,
939 Text = an.Text,
940 Serie = an.serie,
941 Z = an.coord.Z,
942 C = an.coord.C,
943 T = an.coord.T,
944 X = an.X,
945 Y = an.Y,
946 W = an.W,
947 H = an.H,
948 Points = ptSb.ToString(),
949 StrokeColor = $"{an.strokeColor.A},{an.strokeColor.R},{an.strokeColor.G},{an.strokeColor.B}",
950 StrokeWidth = an.strokeWidth,
951 FillColor = $"{an.fillColor.A},{an.fillColor.R},{an.fillColor.G},{an.fillColor.B}",
952 FontSize = an.fontSize,
953 });
954 }
955
956 var opts = new JsonSerializerOptions { WriteIndented = true };
957 string json = JsonSerializer.Serialize(dtos, opts);
958 File.WriteAllText(Path.Combine(outputDir, RoiFileName), json);
959
960 Recorder.Record($"Zarr.SaveROIs({b}, \"{outputDir}\");");
961 }
AForge.PointD PointD
Definition Bio.cs:60
string roiName
Definition ROI.cs:190
ZCT coord
Definition ROI.cs:184
double X
Definition ROI.cs:46
int shapeIndex
Definition ROI.cs:196
PointD[] GetPoints()
Definition ROI.cs:1613
double H
Definition ROI.cs:82
string id
Definition ROI.cs:188
Type type
Definition ROI.cs:105
double Y
Definition ROI.cs:57
string Text
Definition ROI.cs:962
double strokeWidth
Definition ROI.cs:195
string roiID
Definition ROI.cs:189
float fontSize
Definition ROI.cs:180
double W
Definition ROI.cs:68
int serie
Definition ROI.cs:192

◆ SaveZarr()

static async void BioLib.Zarr.SaveZarr ( BioImage b,
string outputDir )
static

Saves the full 5D content of a BioImage as an OME-Zarr v3 dataset at outputDir . All pyramid resolution levels in b.Resolutions are written.

119 {
120 // ------------------------------------------------------------------
121 // 1. Resolve dimensions and data type from the BioImage
122 // ------------------------------------------------------------------
123
124 // Guard against zero-size dimensions which cause ZarrNET to throw
125 // "regionStart[0] = 0 is out of bounds [0, 0)".
126 if (b.SizeX <= 0 || b.SizeY <= 0 || b.SizeZ <= 0 || b.SizeC <= 0 || b.SizeT <= 0)
127 throw new InvalidOperationException(
128 $"BioImage has invalid dimensions: X={b.SizeX} Y={b.SizeY} Z={b.SizeZ} C={b.SizeC} T={b.SizeT}. " +
129 "Ensure the image is fully loaded before saving as Zarr.");
130
131 // Derive the saved scalar bit depth from BioImage metadata instead of
132 // the current display buffer. The display buffer may be 8-bit even
133 // when the source image is 16-bit, which would incorrectly write the
134 // Zarr as uint8 and make it appear nearly black on reopen.
135 int bitsPerSample = DetermineSourceBitsPerSample(b);
136 var sourcePixelFormat = DetermineSourcePixelFormat(b);
137 bool sourceIsInterleavedRgb = IsInterleavedRgbFormat(sourcePixelFormat);
138 int sourceChannelCount = sourceIsInterleavedRgb ? BioImage.GetBands(sourcePixelFormat) : 1;
139 bool sourceIsBGRA = IsBGRAFormat(sourcePixelFormat);
140 int exportChannelCount = sourceIsInterleavedRgb && b.SizeC == 1
141 ? Math.Min(3, sourceChannelCount)
142 : b.SizeC;
143
144 var bytesPerSample = bitsPerSample / 8;
145 var zarrDataType = MapDataType(bitsPerSample);
146 var totalChannels = exportChannelCount;
147
148 int tileW = 512;
149 int tileH = 512;
150
151 s_debugTileLogs = 0;
152 Log($"[SaveZarr] file={b.Filename} out={outputDir} size={b.SizeX}x{b.SizeY} zct={b.SizeZ}/{b.SizeC}/{b.SizeT} " +
153 $"bits={bitsPerSample} bytesPerSample={bytesPerSample} srcPixFmt={sourcePixelFormat} " +
154 $"rgb={sourceIsInterleavedRgb} bands={sourceChannelCount}");
155 BioImage.Progress = 0;
156 BioImage.Status = "Preparing Zarr writer";
157
158 // ------------------------------------------------------------------
159 // 2. Build per-level descriptors from b.Resolutions
160 // Level 0 is always the full-resolution image (b.SizeX / b.SizeY).
161 // Subsequent levels are taken directly from b.Resolutions[1..N].
162 // ------------------------------------------------------------------
163
164 var levelDescriptors = new List<ResolutionLevelDescriptor>();
165 int lastSizeX = int.MaxValue;
166 int lastSizeY = int.MaxValue;
167 bool haveLast = false;
168 var basePixelFormat = b.Resolutions.Count > 0 ? b.Resolutions[0].PixelFormat : DetermineSourcePixelFormat(b);
169
170 for (int lvl = 0; lvl < b.Resolutions.Count; lvl++)
171 {
172 var res = b.Resolutions[lvl];
173 if (res.SizeX <= 0 || res.SizeY <= 0)
174 continue;
175
176 if (haveLast && res.PixelFormat != basePixelFormat)
177 break;
178
179 if (haveLast && (res.SizeX > lastSizeX || res.SizeY > lastSizeY))
180 break;
181
182 if (haveLast && res.SizeX == lastSizeX && res.SizeY == lastSizeY)
183 continue;
184
185 double dsample = b.GetLevelDownsample(lvl);
186 if (!double.IsFinite(dsample) || dsample <= 0)
187 dsample = 1.0;
188
189 levelDescriptors.Add(new ResolutionLevelDescriptor(res.SizeX, res.SizeY, dsample));
190 Log($"[SaveZarr] level={lvl} size={res.SizeX}x{res.SizeY} downsample={dsample} fmt={res.PixelFormat}");
191 lastSizeX = res.SizeX;
192 lastSizeY = res.SizeY;
193 haveLast = true;
194 }
195
196 // Fallback: if there is somehow no Resolutions list, use the image dims.
197 var coord = new ZarrNET.Core.ZCT(b.SizeZ, totalChannels, b.SizeT);
198
199 var baseDescriptor = new BioImageDescriptor(b.SizeX, b.SizeY, coord)
200 {
201 Name = Path.GetFileNameWithoutExtension(b.Filename),
202 DataType = zarrDataType,
203 PhysicalSizeX = b.PhysicalSizeX,
204 PhysicalSizeY = b.PhysicalSizeY,
205 PhysicalSizeZ = b.PhysicalSizeZ,
206 ChunkY = tileH,
207 ChunkX = tileW,
208 };
209
210 // ------------------------------------------------------------------
211 // 4. Create the writer (bootstraps zarr.json metadata on disk for
212 // all levels at once)
213 // ------------------------------------------------------------------
214
215 var writer = OmeZarrWriter.CreateAsync(outputDir, baseDescriptor, levelDescriptors).Result;
216
217 try
218 {
219 // ------------------------------------------------------------------
220 // 5. Stream tiles into each resolution level
221 // ------------------------------------------------------------------
222 long totalPlanes = Math.Max(1L, (long)levelDescriptors.Count * b.SizeT * b.SizeZ * b.SizeC);
223 long writtenPlanes = 0;
224
225 for (int levelIndex = 0; levelIndex < levelDescriptors.Count; levelIndex++)
226 {
227 var lvlDesc = levelDescriptors[levelIndex];
228 BioImage.Status = $"Writing resolution level {levelIndex + 1}/{levelDescriptors.Count}";
229
230 for (int t = 0; t < b.SizeT; t++)
231 {
232 for (int z = 0; z < b.SizeZ; z++)
233 {
234 for (int c = 0; c < exportChannelCount; c++)
235 {
236 BioImage.Status = $"Writing level {levelIndex + 1}/{levelDescriptors.Count} plane T{t + 1}/{b.SizeT} Z{z + 1}/{b.SizeZ} C{c + 1}/{b.SizeC}";
237 if (sourceIsInterleavedRgb)
238 {
239 await WritePlaneInTiles(
240 writer, b, lvlDesc,
241 t, c, z,
242 bytesPerSample, tileW, tileH,
243 levelIndex: levelIndex,
244 rgbChannelIndex: c,
245 srcChannelCount: sourceChannelCount,
246 isBGRA: sourceIsBGRA,
247 logicalC: 0);
248 }
249 else
250 {
251 await WritePlaneInTiles(
252 writer, b, lvlDesc,
253 t, c, z,
254 bytesPerSample, tileW, tileH,
255 levelIndex: levelIndex);
256 }
257
258 writtenPlanes++;
259 BioImage.Progress = (float)(writtenPlanes * 100.0 / totalPlanes);
260 }
261 }
262 }
263 }
264 }
265 catch (Exception e)
266 {
267 Console.WriteLine(e.ToString());
268 }
269
270 try
271 {
272 BioImage.Status = "Verifying saved Zarr";
273 PostSaveReadback(outputDir).GetAwaiter().GetResult();
274 }
275 catch (Exception e)
276 {
277 Log($"[PostSaveReadback] EXCEPTION: {e.GetType().Name}: {e.Message}");
278 }
279
280 Recorder.Record($"Zarr.SaveZarr({b}, \"{outputDir}\");");
281 BioImage.Progress = 100;
282 }

Member Data Documentation

◆ RoiFileName

const string BioLib.Zarr.RoiFileName = "rois.json"
static

The file name used for the ROI sidecar that sits beside the Zarr dataset.


The documentation for this class was generated from the following file: