Skip to content

Commit

Permalink
improve documentation - "coordinate systems" (#122)
Browse files Browse the repository at this point in the history
* Add coordinate systems documentation and diagram

Added a new documentation file `coordinate_systems.markdown` to the
Doxyfile's INPUT section. Introduced a "Coordinate Systems" section
in the new file with a header and placeholder description for CZI and
libCZI coordinate systems. Also, added a new diagram in
`coordinate_systems.drawio` named "Page-1" that includes graphical
elements representing a coordinate system with labeled axes.

* Update coordinate systems documentation in libCZI

* Improve documentation clarity for coordinate systems

Rephrased a sentence in `coordinate_systems.markdown` for clarity. Updated comments in `libCZI.h` to clarify bounding boxes and coordinate systems. Enhanced `libCZI_Compositor.h` comments to specify ROI and positions in the 'raw-subblock-coordinate-system'. Removed summary tags and redundant information to streamline documentation. These changes provide clearer and more precise descriptions of coordinate systems and bounding boxes in libCZI.

* Update project to version 0.62.7

Updated CMakeLists.txt to change project version from 0.62.6 to 0.62.7.
Added a new entry in version-history.markdown for version 0.62.7, documenting a "documentation update" linked to pull request #122.

* remove "high-res-bitmaps"

* fix table

* cosmetic

* Update Src/libCZI/Doc/coordinate_systems.markdown

Co-authored-by: m-aXimilian <[email protected]>

* Update Src/libCZI/Doc/coordinate_systems.markdown

Co-authored-by: m-aXimilian <[email protected]>

---------

Co-authored-by: m-aXimilian <[email protected]>
  • Loading branch information
ptahmose and m-aXimilian authored Dec 5, 2024
1 parent d615ba9 commit ae43e1b
Show file tree
Hide file tree
Showing 9 changed files with 172 additions and 57 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.15)
cmake_policy(SET CMP0091 NEW) # enable new "MSVC runtime library selection" (https://cmake.org/cmake/help/latest/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html)

project(libCZI
VERSION 0.62.6
VERSION 0.62.7
HOMEPAGE_URL "https://github.com/ZEISS/libczi"
DESCRIPTION "libCZI is an Open Source Cross-Platform C++ library to read and write CZI")

Expand Down
1 change: 1 addition & 0 deletions Src/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,7 @@ INPUT = ./libCZI/libCZI.h \
./libCZI/Doc/multichannelcomposition.markdown \
./libCZI/Doc/stream_objects.markdown \
./libCZI/Doc/CZICmd_usage.markdown \
./libCZI/Doc/coordinate_systems.markdown \
./libCZI/Doc/write_czi.markdown \
./libCZI/Doc/Todos.markdown \
./libCZI/Doc/version-history.markdown
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
58 changes: 58 additions & 0 deletions Src/libCZI/Doc/Images/drawings/coordinate_systems.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/25.0.2 Chrome/128.0.6613.186 Electron/32.2.5 Safari/537.36" version="25.0.2">
<diagram name="Page-1" id="s-giWtpM9g9LvuQPyBwT">
<mxGraphModel dx="1464" dy="1093" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="pwWKmZNdiIpO54-NTEOH-1" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="80" y="160" as="sourcePoint" />
<mxPoint x="360" y="160" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="pwWKmZNdiIpO54-NTEOH-2" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="80" y="160" as="sourcePoint" />
<mxPoint x="80" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="pwWKmZNdiIpO54-NTEOH-4" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
<mxGeometry x="210" y="250" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="pwWKmZNdiIpO54-NTEOH-6" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
<mxGeometry x="240" y="320" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="pwWKmZNdiIpO54-NTEOH-7" value="x" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="330" y="160" width="60" height="20" as="geometry" />
</mxCell>
<mxCell id="pwWKmZNdiIpO54-NTEOH-8" value="y" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="40" y="380" width="60" height="20" as="geometry" />
</mxCell>
<mxCell id="pwWKmZNdiIpO54-NTEOH-9" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="80" y="480" as="sourcePoint" />
<mxPoint x="360" y="480" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="pwWKmZNdiIpO54-NTEOH-10" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="80" y="480" as="sourcePoint" />
<mxPoint x="80" y="710" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="pwWKmZNdiIpO54-NTEOH-11" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
<mxGeometry x="80" y="480" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="pwWKmZNdiIpO54-NTEOH-12" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
<mxGeometry x="110" y="550" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="pwWKmZNdiIpO54-NTEOH-13" value="x" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="330" y="480" width="60" height="20" as="geometry" />
</mxCell>
<mxCell id="pwWKmZNdiIpO54-NTEOH-14" value="y" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="40" y="700" width="60" height="20" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
58 changes: 58 additions & 0 deletions Src/libCZI/Doc/coordinate_systems.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
Coordinate Systems {#coordinatesystems}
==================

## coordinate systems

As far as libCZI is concerned, there are two coordinate systems that are of interest:

1. The _raw-subblock-coordinate-system_ is the coordinate system in which the X-Y-positions of the subblocks
are physically stored in the file, and it is also the coordinate system which is used in libCZI.
The API [ISubBlock::GetSubBlockInfo](https://zeiss.github.io/libczi/classlib_c_z_i_1_1_i_sub_block.html#a557108549db08e25b1df1ef8fae37a07) is returning the X-Y-position of the subblock in this
coordinate system ([SubBlockInfo::logicalRect](https://zeiss.github.io/libczi/structlib_c_z_i_1_1_sub_block_info.html)), which is
unmodified wrt to the actual file content.
Conceptually, the _raw-subblock-coordinate-system_ has the following characteristics:
* The X and Y-axis are such that the subblock's logicalRect are axis-aligned.
* Orientation of the Y-axis is such that the Y-coordinate increases from top to bottom; X-coordinates increase from left to right.
* The origin of the coordinate system is arbitrary, there is no special geometric meaning to the origin.
![Raw SubBlock Coordinate System](raw_subblock_coordinate_system_400x.png)
2. The _CZI-Pixel-Coordinate-System_ is a coordinate system where the top-left subblock (of pyramid-layer 0) has the
the coordinate (0,0). It is related to the _raw_subblock-coordinate system_ by a translation.
The _CZI-Pixel-Coordinate-System_ is the recommended way for relating to an X-Y-position in the CZI-document.
The characteristics of the _CZI-Pixel-Coordinate-System_ are:
* The X and Y-axis are such that the subblock's logicalRect are axis-aligned.
* Orientation of the Y-axis is such that the Y-coordinate increases from top to bottom; X-coordinates increase from left to right.
* The origin is such that the coordinate (of the logicalRect) of the top-most and left-most pyramid-layer0 subblock is (0,0).
![CZI Pixel Coordinate System](CZI_pixel_coordinate_system_400x.png)

## usage in libCZI

libCZI at this point is using the _raw-subblock-coordinate-system_ for all its operations. There are only a few
operations where the choice of coordinate system is relevant: the accessor-functions which give tile-compositions.
This includes:
- [ISingleChannelTileAccessor](https://zeiss.github.io/libczi/classlib_c_z_i_1_1_i_single_channel_tile_accessor.html)
- [ISingleChannelPyramidLayerTileAccessor](https://zeiss.github.io/libczi/classlib_c_z_i_1_1_i_single_channel_pyramid_layer_tile_accessor.html)
- [ISingleChannelScalingTileAccessor](https://zeiss.github.io/libczi/classlib_c_z_i_1_1_i_single_channel_scaling_tile_accessor.html)

The coordinates of the ROIs passed in here are in the _raw-subblock-coordinate-system_.

## conversion

The primary source of information regarding the "placement of subblocks on the XY-plane" is the method [ISubBlockRepository::GetStatistics()](https://zeiss.github.io/libczi/classlib_c_z_i_1_1_i_sub_block_repository.html#a6e44c1a929a27036ef77195d516dd719).
The structure [SubBlockStatistics](https://zeiss.github.io/libczi/structlib_c_z_i_1_1_sub_block_statistics.html) contains two
rectangles:

| property | description |
|----------------------|-----------------------------------------------------------------------------|
| boundingBox | The minimal AABB (= axis-aligned-bounding-box) of the logicalRects of all subblocks (in all pyramid-layers). |
| boundingBoxLayer0Only| The minimal AABB of the logicalRects of all subblocks in pyramid-layer 0. |

Converting from the _raw-subblock-coordinate-system_ to the _CZI-Pixel-Coordinate-System_ is now straightforward:
subtract the top-left point of the boundingBoxLayer0Only rectangle. The translation vector between the coordinate systems
is then given by the top-left point of the boundingBoxLayer0Only rectangle.

Translating between both coordinate systems might be necessary when coordinate information is given from an external source
(or by information embedded in the CZI itself). Since the _CZI-Pixel-Coordinate-System_ is the recommended way to relate to
spatial positions in a CZI, such external data will most likely be given in this coordinate system.
Within libCZI itself, no coordinate transformation is taking place so far, so all operations are consistently done in the
_raw-subblock-coordinate-system_.
3 changes: 2 additions & 1 deletion Src/libCZI/Doc/version-history.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ version history {#version_history}
0.62.3 | [116](https://github.com/ZEISS/libczi/pull/116) | enable long paths on Windows for CZIcmd, add Windows-ARM64 build
0.62.4 | [117](https://github.com/ZEISS/libczi/pull/117) | fix build with private RapidJSON library
0.62.5 | [119](https://github.com/ZEISS/libczi/pull/119) | fix a discrepancy between code and documentation
0.62.6 | [120](https://github.com/ZEISS/libczi/pull/120) | fix workload identity in the azure blob inputstream
0.62.6 | [120](https://github.com/ZEISS/libczi/pull/120) | fix workload identity in the azure blob inputstream
0.62.7 | [122](https://github.com/ZEISS/libczi/pull/122) | documentation update
8 changes: 5 additions & 3 deletions Src/libCZI/libCZI.h
Original file line number Diff line number Diff line change
Expand Up @@ -447,12 +447,14 @@ namespace libCZI
/// If no valid M-index was present, then this member will have the value std::numeric_limits<int>::min().
int maxMindex;

/// The bounding box determined from all sub-blocks in the
/// The minimal axis-aligned-bounding-box determined from all logical coordinates of all sub-blocks in the
/// document.
IntRect boundingBox;

/// The bounding box determined only from the sub-blocks of pyramid-layer0 in the
/// document.
/// The minimal axis-aligned-bounding box determined only from the logical coordinates of the sub-blocks on pyramid-layer0 in the
/// document. The top-left corner of this bounding-box gives the coordinate of the origin of the 'CZI-Pixel-Coordinate-System' in
/// the coordinate system used by libCZI (which is refered to as 'raw-subblock-coordinate-system'). See @ref coordinatesystems for
/// additional information.
IntRect boundingBoxLayer0Only;

/// The dimension bounds - the minimum and maximum dimension index determined
Expand Down
Loading

0 comments on commit ae43e1b

Please sign in to comment.