Skip to content

Commit 2338404

Browse files
authored
MetaTensor -- whats new/migration guide (#4543)
* whats new/migration guide
1 parent 8b9a27b commit 2338404

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

docs/source/whatsnew_metatensor.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# What's new -- `MetaTensor`
2+
3+
- New class `MetaTensor`. Stores meta data, image affine, and stack of transforms that have been applied to an image.
4+
- Meta data will now be stored in `MetaTensor`, as opposed to using a dictionary in an adjacent key of the dictionary. This keeps the meta data more closely associated with the principal data, and allows array transforms to be aware (and update) meta data, not just our dictionary transforms.
5+
- Previously, MONAI was fairly agnostic to the use of NumPy arrays and PyTorch tensors in its transforms. With the addition of `MetaTensor`,
6+
Transforms largely use `torch.Tensor`. Input will be converted to `MetaTensor` by default.
7+
8+
## Manipulating `MetaTensor`
9+
10+
A `MetaTensor` can be created with e.g., `img=MetaTensor(torch.ones((1,4,5,6))`, which will use the default meta data (empty), and default affine transformation matrix (identity). These can be altered with input arguments.
11+
12+
With the `MetaTensor` created, the extra information can be accessed as follows:
13+
14+
- Meta data: `img.meta`,
15+
- Affine: `img.affine`, and
16+
- Applied operations (normally the traced/invertible transforms): `img.applied_operations`.
17+
18+
## Inverse array transforms
19+
20+
Previously, only dictionary transforms were invertible. Now, array transforms are, too!
21+
22+
```python
23+
tr = Compose([LoadImage(), AddChannel(), Orientation(), Spacing()])
24+
im = MetaTensor(...)
25+
im_fwd = tr(im)
26+
im_fwd_inv = tr.inverse(im_fwd)
27+
print(im_fwd.applied_operations) # prints list of invertible transforms
28+
print(im_fwd_inv.applied_operations) # should be back to 0
29+
```
30+
31+
## Converting to and from `MetaTensor`
32+
33+
Users may, for example, want to use their own transforms which they developed prior to these changes. In a chain of transforms, you may have previously had something like this:
34+
35+
```python
36+
transforms = Compose([
37+
LoadImaged(), AddChanneld(), MyOwnTransformd(), Spacingd(),
38+
])
39+
```
40+
41+
If `MyOwnTransformd` expects the old type of data structure, then the transform stack can be modified to this:
42+
43+
```python
44+
transforms = Compose([
45+
LoadImaged(), AddChanneld(), FromMetaTensord(),
46+
MyOwnTransformd(), ToMetaTensord(), Spacingd(),
47+
])
48+
```
49+
50+
That is to say, you can use `FromMetaTensord` to convert from e.g., `{"img": MetaTensor(...)}` to `{"img": torch.Tensor(...), "img_meta_dict: {...}` and `ToMetaTensord` will do the opposite.
51+
52+
## Batches of `MetaTensor`
53+
54+
The end user should not really need to modify this logic, it is here for interest.
55+
56+
We use a flag inside of the meta data to determine whether a `MetaTensor` is in fact a batch of multiple images. This logic is contained in our `default_collate`:
57+
58+
```python
59+
im1, im2 = MetaTensor(...), MetaTensor(...)
60+
print(im1.meta.is_batch) # False
61+
batch = default_collate([im1, im2])
62+
print(batch.meta.is_batch) # True
63+
```
64+
65+
Similar functionality can be seen with the `DataLoader`:
66+
```python
67+
ds = Dataset([im1, im2])
68+
print(ds[0].meta.is_batch) # False
69+
dl = DataLoader(ds, batch_size=2)
70+
batch = next(iter(dl))
71+
print(batch.meta.is_batch) # True
72+
```
73+
74+
**We recommend using MONAI's Dataset where possible, as this will use the correct collation method and ensure that MONAI is made aware of when a batch of data is being used or just a single image.**
75+
76+
## Disabling `MetaTensor`
77+
78+
This should ideally be a last resort, but if you are experiencing problems due to `MetaTensor`, `set_track_meta(False)` can be used.
79+
80+
Output will be returned as `torch.Tensor` instead of `MetaTensor`. This won't necessarily match prevoius functionality, as the meta data will no longer be present and so won't be used or stored. Further, more data will be converted from `numpy.ndarray` to `torch.Tensor`.

0 commit comments

Comments
 (0)