Skip to content

Commit

Permalink
Add more more detailed documentation about volume data and the RAW 3D…
Browse files Browse the repository at this point in the history
… file format
  • Loading branch information
FreddyFunk committed Jul 30, 2023
1 parent b973c36 commit a88d906
Show file tree
Hide file tree
Showing 18 changed files with 2,175 additions and 6 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
# vds-docs

Official Documentation for Volume Data Suite (VDS)

## Aknowledgements

- ""FREE" Low Poly head" (<https://skfb.ly/6zyEI>) by Daniel Louis is licensed under Creative Commons Attribution (<http://creativecommons.org/licenses/by/4.0/>).
- "3D Coordinate System" (<https://de.wikipedia.org/wiki/Datei:3D_coordinate_system.svg>) by I, Sakurambo is licensed under CC BY-SA 3.0 (<https://creativecommons.org/licenses/by-sa/3.0/deed.de>). All modified versions in this repository are licensed under the same license as the original.
4 changes: 4 additions & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

- [Introduction](./introduction.md)
- [Supported Plattforms](./supported_plattforms.md)
- [About Volume Data](./about_volume_data.md)
- [Importing Static Volume Data](./importing_static_volume_data.md)

- [File Format: RAW 3D](./file_format_raw_3d.md)

- [Visualization](./visualization.md)
- [Development](./development.md)
70 changes: 70 additions & 0 deletions src/about_volume_data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# About Volume Data

## 3D Images and Voxels

A voxel is like a three-dimensional pixel that represents a value on a regular grid in three-dimensional space. It is analogous to a pixel, which represents a value on a regular two-dimensional space, like a 2D image.

| <img src="images/voxels.svg" alt="Voxels" width="200"/>
| :--------------------------------------:
| _3D voxel grid with a highlighted voxel_

When dealing with 3D MRI or 3D CT images, a voxel value usually represents a itensity value (also known as ISO value).

## Orientation and Voxel-Order Terminology

### Basic Direction Terms

**Directions are given relative to the patient or object.** ("Right" is patient's or object's right.) When referring to a location on a screen, it is important to be precise. For instance, patient-right can be located on the left side of the screen. We use the following terms:

Directions | Example
------------------------------ | ---------------------------------------------
**R**ight <-> **L**eft | Patient's right ear <-> patient's left ear
**A**nterior <-> **P**osterior | Patient's nose <-> patient's back of the head
**I**nferior <-> **S**uperior | Patient's jaw <-> patient's skullcap

<img src="images/3D_coordinate_system.svg" alt="3D Coordinate System" width="310"/> | ![Head Reference](images/head.png)
-------------------------------------------------------- | ----------------------------------
3D Coordinate System | Head Reference

> The terms **"up", "down", "front", "back"** are not used because they have ambiguous meanings when dealing with patients in different orientations (e.g. lying down).
### Axes for Spatial Coordinates

To describe locations in space around volume data, we need to agree on a specific set of axes. These axes are used to describe a point's coordinates. There are three axes that could be used in any order, and either direction could be positive. This gives us a total of 48 possible axis schemes.

It seems that three of these schemes are most popular:

| ![3D Coordinate System](images/3D_coordinate_system_ras.svg) | ![3D Coordinate System](images/3D_coordinate_system_las.svg) | ![3D Coordinate System](images/3D_coordinate_system_las.svg) | ![Head Reference](images/head.png) |
|--------|--------------------------|--------------------------|--------------------------|
|**RAS** ("Neurological" convention)<br />+X = R<br />+Y = A<br />+Z = S|**LAS** ("Radiological" convention)<br />+X = L<br />+Y = A<br />+Z = S|**LSA** ("Math" convention)<br />+X = L<br />+Y = S<br />+Z = A|Head Reference|

> **Viewing Direction:** The figures above are shown as viewed looking toward the patient’s face. However, there are also conventions for viewing, such as the neurological view, which is from above/behind the patient and shows patient left on screen left.
The RAS coordinate system is a right-hand coordinate system (thumb = R, 2nd finger = A, middle finger = S.). On the other hand, LAS is a left-hand coordinate system.

The L, A and S axes could provide a right-hand coordinate system if used in the order LSA for example. A right-hand coordinate system is customarily used when performing matrix and vector math and is more attractive for computer graphics developers and APIs. This is why VDS uses LSA internally. However, it seems like no one uses LSA when talking about volume data in a medical context. Therefore you can view volume data in various different coordinate systems (RAS, LAS, LSA).

### Planes for Volume Slice Orientation

There are three commonly used slice planes:

- Axial (Transverse): R-L x A-P plane
- Coronal: R-L x S-I plane
- Sagittal: A-P x S-I plane

The viewing direction on each plane depends on the axis convention used, such as **RAS**, **LAS**, or **LSA**.

![3D Coordinate System with Axial Plane](images/3D_coordinate_system_axial.svg) | ![3D Coordinate System with Coronal Plane](images/3D_coordinate_system_coronal.svg) | ![3D Coordinate System with Sagittal Plane](images/3D_coordinate_system_sagittal.svg) | ![3D Coordinate System with all planes](images/3D_coordinate_system_planes.svg) | ![Head Reference](images/head.png)
------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ----------------------------------
Axial (Traverse) | Coronal | Sagittal | All Planes | Head Reference

## Volume Data Representation in VDS

VDS maps intensity values internally to a floating point range of 0.0 to 1.0 with a 16 bit presicion, where 0.0 represents the lowest possible intensity value and 1.0 represents the highest possible intensity value.

## Great Resources

In case you are interested in more information about volume data, you may also be interested in reading the following articles:

- [Orientation and Voxel-Order Terminology: RAS, LAS, LPI, RPI, XYZ and All That](http://www.grahamwideman.com/gw/brain/orientation/orientterms.htm) by Graham Wideman
- [AFNI Documentation](https://afni.nimh.nih.gov/pub/dist/doc/htmldoc/index.html) is a set of free and open source, which specalized on human brain MRI scans and is way more advanced than VDS. Its documentation goes way more in depth on various volume data information.
5 changes: 3 additions & 2 deletions src/development.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Development

VDS is written in [Rust](https://www.rust-lang.org/) and shaders are written in [WGSL](https://www.w3.org/TR/WGSL/).

Make sure you are using the latest version of stable rust by running `rustup update`. VDS requires a proper graphics driver that provides at least one of the [supported graphics APIs](#cross-platform-support).
Expand All @@ -23,10 +24,10 @@ On Fedora Rawhide you need to run:
2. Run `trunk serve` to build and serve on `http://127.0.0.1:8080`. Trunk will rebuild automatically if you edit the project.
3. Open `http://127.0.0.1:8080/index.html#dev` in a browser. See the warning below.

> `assets/sw.js` script will try to cache our VDS app, and loads the cached version when it cannot connect to server allowing VDS to work offline (like PWA).
> appending `#dev` to `index.html` will skip this caching, allowing to load the latest builds during development.
> `assets/sw.js` script will try to cache our VDS app, and loads the cached version when it cannot connect to server allowing VDS to work offline (like PWA). Appending `#dev` to `index.html` will skip this caching, allowing to load the latest builds during development.
## Deploy for Web

1. Just run `trunk build --release`.
2. It will generate a `dist` directory as a "static html" website
3. Upload the `dist` directory to any of the numerous free hosting websites including [GitHub Pages](https://docs.github.com/en/free-pro-team@latest/github/working-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site).
Expand Down
75 changes: 75 additions & 0 deletions src/file_format_raw_3d.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# File Format: RAW 3D

RAW 3D files are just plain 3D arrays of voxel value data. These files do not contain a header with metadata on how to read or interpret the data. While VDS has a well defined [Volume Data Representation](/about_volume_data.html#volume-data-representation-in-vds), there is no universal applicable standard for memory layout, number type, voxel order, endianess and so on when storing volume data. Therefore, you need to provide the nessesary metadata on how to read and interpret the data when importing a RAW 3D file.

## Typical file extensions:

- *.raw
- *.RAW

## Supported Number Types for Voxels

Each voxel value can be stored as a signed integer, an unsigned integer or as a floating point number. Each of these number types can be stored with various amounts of bits per number, which is known as _"precision"_. A higher precision usually means more details in the image data at the cost of larger file sizes. The following number types are supported by VDS when importing a RAW 3D file:

ID | Number Type | Precision
--- | --------------------- | ---------
u8 | Unsigned Integer | 8 Bit
u16 | Unsigned Integer | 16 Bit
i8 | Signed Integer | 8 Bit
i16 | Signed Integer | 16 Bit
f16 | Floating Point Number | 16 Bit

> Internally, VDS always converts voxel values to f16 before beeing operated on.
## Scaling

VDS supports uniform and non-uniform spacing with different scaling factors for each axis. Non-linear scaling is not supported.

## Voxel Ordering

Some file formats like RAW 3D do not store metadata about the coordinate system. It could be possible, that for example the RAW 3D files content was stored in RAS but the VDS viewer is configured to use LAS.

**Storage Orders** desribe the voxel ordering.

Here is an example for the Storage Order for **LAS** which would be _"R->L within P->A within I->S"_ and means:

1. Voxels ordered from right to left to store a row
2. Rows ordered from posterior to anterior to store a slice
3. Slices stored from inferior to superior to store a volume

By selecting the correct Storage Order, the axis of the file data coordinate system will be mapped correctly to configured VDS viewing coordinate system.

VDS supportes the following voxel orderings for RAW 3D files:

[Axes for Spatial Coordinates](/about_volume_data.html#axes-for-spatial-coordinates) | Storage order in file | [Slice orientation](/about_volume_data.html#planes-for-volume-slice-orientation) (ambiguous) | Known as
------------------------------------------------------------------------------------ | ---------------------------- | -------------------------------------------------------------------------------------------- | ------------
LAS | R->L within P->A within I->S | "Axial" | Radiological
RAS | L->R within P->A within I->S | "Axial" | Neurological
LSA | R->L within I->S within P->A | "Saggital" |
LIA | R->L within S->I within P->A | "Coronal"

> If you select the wrong voxel order while importing a RAW 3D file, then you might see the volume rotated or mirrored along any of the spatial axes of the volume and not mapped correctly to the [Axes for Spatial Coordinates](/about_volume_data.html#axes-for-spatial-coordinates) .
### Converting RAW 3D File Voxel Ordering to an In-Memory Array

Most RAW 3D files are stored as [RAS](/about_volume_data.html#axes-for-spatial-coordinates):

1. _X increases from Left to Right_
2. _Y increases from Posterior to Anterior_
3. _Z increases from Inferior to Superior_

A naive approach to actually read an RAW 3D file into memory in one big blob and treat it as an array would probably result in a wrong access pattern like: Voxels[ X ][ Y ][ Z ].

Popular programming languages like C/C++/Rust use the first index as the slowest-incrementing index into memory. The correct access pattern for this example would be Voxels[ Z ][ Y ][ X ].

## Alignment to Axes for Spatial Coordinates

Sometimes the voxel data in RAW 3D files is not aligned to some exact orthogonal directions. Nonetheless, it's useful to know which set of axes the voxel indices correspond to most closely, as this helps when applying alignment or rotation steps.

Furthermore, the location of the origin is unkown. Even if we know the origin voxel, the location of the origin can be centered in the middle of this central voxel, or on the one of its eight corners.

VDS defaults the origin for RAW 3D files to the center of the volume 3D dimensions after the [Scaling](#scaling) is applied.

## Multiple volumes in a single file

Multiple volumes in a single file could be used for multiple time points. VDS does not support multiple volumes in a single file when importing a RAW 3D file.
Loading

0 comments on commit a88d906

Please sign in to comment.