Repository: fepegar/torchio

Issue:
Transforms history is not retrieved from batch
### Is there an existing issue for this?

- [X] I have searched the existing issues

### Bug summary

As reported by @Bigsealion in #743, the batch reconstructed from the `DataLoader` doesn't retrieve the transforms for inversion.

### Code for reproduction

```python
import torchio as tio
from torch.utils.data import DataLoader

subject_a = tio.datasets.Colin27()
subjects_list = [subject_a]

# transform
onehot = tio.OneHot()
pad = tio.CropOrPad((96, 112, 96))
transforms = [onehot, pad]
transform = tio.Compose(transforms)

# load data by torch
subjects_dataset = tio.SubjectsDataset(subjects_list, transform=transform)
training_loader = DataLoader(
    subjects_dataset,
    collate_fn=tio.utils.history_collate,
)

for subjects_batch in training_loader:
    tio_subj = tio.utils.get_subjects_from_batch(subjects_batch)[0]
    tio_subj = tio_subj.apply_inverse_transform()
    print('raw shape: {}'.format(subject_a.t1.shape))
    print('new shape: {}'.format(tio_subj.brain.shape))
```


### Actual outcome

The inverse transforms are not added to the newly created subject and thus not applied.

### Error messages

```python-traceback
# Not really an error

/Users/fernando/git/torchio/torchio/transforms/augmentation/composition.py:69: RuntimeWarning: No invertible transforms found
  warnings.warn('No invertible transforms found', RuntimeWarning)
raw shape: (1, 181, 217, 181)
new shape: (2, 96, 112, 96)
```


### Expected outcome

```python-traceback
/Users/fernando/git/torchio/torchio/transforms/augmentation/composition.py:65: RuntimeWarning: Skipping OneHot as it is not invertible
  warnings.warn(message, RuntimeWarning)
raw shape: (1, 181, 217, 181)
new shape: (2, 181, 217, 181)
```

### System info

```shell
Platform:   macOS-10.15.7-x86_64-i386-64bit
TorchIO:    0.18.65
PyTorch:    1.10.0
SimpleITK:  2.1.0 (ITK 5.2)
NumPy:      1.21.0
Python:     3.8.10 (default, May 19 2021, 11:01:55)
[Clang 10.0.0 ]
```


Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/fepegar/torchio/pull/745?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Fernando+P%C3%A9rez-Garc%C3%ADa) Report
> Merging [#745](https://codecov.io/gh/fepegar/torchio/pull/745?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Fernando+P%C3%A9rez-Garc%C3%ADa) (0c67bc8) into [main](https://codecov.io/gh/fepegar/torchio/commit/588227bbf66b6c3f15cb941ae152aede96f11057?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Fernando+P%C3%A9rez-Garc%C3%ADa) (588227b) will **decrease** coverage by `0.06%`.
> The diff coverage is `25.00%`.

[![Impacted file tree graph](https://codecov.io/gh/fepegar/torchio/pull/745/graphs/tree.svg?width=650&height=150&src=pr&token=TL9bitRrRZ&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Fernando+P%C3%A9rez-Garc%C3%ADa)](https://codecov.io/gh/fepegar/torchio/pull/745?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Fernando+P%C3%A9rez-Garc%C3%ADa)

```diff
@@            Coverage Diff             @@
##             main     #745      +/-   ##
==========================================
- Coverage   93.83%   93.76%   -0.07%     
==========================================
  Files          72       72              
  Lines        4441     4445       +4     
==========================================
+ Hits         4167     4168       +1     
- Misses        274      277       +3     
```


| [Impacted Files](https://codecov.io/gh/fepegar/torchio/pull/745?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Fernando+P%C3%A9rez-Garc%C3%ADa) | Coverage Δ | |
|---|---|---|
| [torchio/utils.py](https://codecov.io/gh/fepegar/torchio/pull/745/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Fernando+P%C3%A9rez-Garc%C3%ADa#diff-dG9yY2hpby91dGlscy5weQ==) | `73.30% <25.00%> (-0.96%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/fepegar/torchio/pull/745?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Fernando+P%C3%A9rez-Garc%C3%ADa).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Fernando+P%C3%A9rez-Garc%C3%ADa)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/fepegar/torchio/pull/745?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Fernando+P%C3%A9rez-Garc%C3%ADa). Last update [588227b...0c67bc8](https://codecov.io/gh/fepegar/torchio/pull/745?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Fernando+P%C3%A9rez-Garc%C3%ADa). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Fernando+P%C3%A9rez-Garc%C3%ADa).


Patch:
diff --git a/torchio/utils.py b/torchio/utils.py
index 7fc38f0..ce1da1c 100644
--- a/torchio/utils.py
+++ b/torchio/utils.py
@@ -256,6 +256,10 @@ def get_subjects_from_batch(batch: Dict) -> List:
             image = klass(tensor=data, affine=affine, filename=path.name)
             subject_dict[image_name] = image
         subject = Subject(subject_dict)
+        if constants.HISTORY in batch:
+            applied_transforms = batch[constants.HISTORY][i]
+            for transform in applied_transforms:
+                transform.add_transform_to_subject_history(subject)
         subjects.append(subject)
     return subjects
 


Test patch:
diff --git a/tests/transforms/test_transforms.py b/tests/transforms/test_transforms.py
index 75761ef..f592ca1 100644
--- a/tests/transforms/test_transforms.py
+++ b/tests/transforms/test_transforms.py
@@ -270,6 +270,21 @@ class TestTransform(TorchioTestCase):
         with self.assertRaises(RuntimeError):
             transform.inverse()
 
+    def test_batch_history(self):
+        # https://github.com/fepegar/torchio/discussions/743
+        subject = self.sample_subject
+        original_shape = subject.spatial_shape
+        transform = tio.Compose([tio.RandomAffine(), tio.CropOrPad(5)])
+        dataset = tio.SubjectsDataset([subject], transform=transform)
+        loader = torch.utils.data.DataLoader(
+            dataset,
+            collate_fn=tio.utils.history_collate
+        )
+        batch = tio.utils.get_first_item(loader)
+        subject: tio.Subject = tio.utils.get_subjects_from_batch(batch)[0]
+        inverse = subject.apply_inverse_transform()
+        assert inverse.spatial_shape == original_shape
+
     def test_bad_bounds_mask(self):
         transform = tio.ZNormalization(masking_method='test')
         with self.assertRaises(ValueError):