Esempio n. 1
0
    def test_transforms(self):
        key = "im"
        _, im = self.get_im()
        tr = Compose([ToMetaTensord(key), BorderPadd(key, 1), DivisiblePadd(key, 16), FromMetaTensord(key)])
        num_tr = len(tr.transforms)
        data = {key: im, PostFix.meta(key): {"affine": torch.eye(4)}}

        # apply one at a time
        for i, _tr in enumerate(tr.transforms):
            data = _tr(data)
            is_meta = isinstance(_tr, (ToMetaTensord, BorderPadd, DivisiblePadd))
            if is_meta:
                self.assertEqual(len(data), 1 if not config.USE_META_DICT else 2)  # im, im_transforms, compatibility
                self.assertIsInstance(data[key], MetaTensor)
                n_applied = len(data[key].applied_operations)
            else:
                self.assertEqual(len(data), 3)  # im, im_meta_dict, im_transforms
                self.assertIsInstance(data[key], torch.Tensor)
                self.assertNotIsInstance(data[key], MetaTensor)
                n_applied = len(data[PostFix.transforms(key)])

            self.assertEqual(n_applied, i + 1)

        # inverse one at a time
        for i, _tr in enumerate(tr.transforms[::-1]):
            data = _tr.inverse(data)
            is_meta = isinstance(_tr, (FromMetaTensord, BorderPadd, DivisiblePadd))
            if is_meta:
                self.assertEqual(len(data), 1)  # im
                self.assertIsInstance(data[key], MetaTensor)
                n_applied = len(data[key].applied_operations)
            else:
                self.assertEqual(len(data), 3)  # im, im_meta_dict, im_transforms
                self.assertIsInstance(data[key], torch.Tensor)
                self.assertNotIsInstance(data[key], MetaTensor)
                n_applied = len(data[PostFix.transforms(key)])

            self.assertEqual(n_applied, num_tr - i - 1)

        # apply all in one go
        data = tr({key: im, PostFix.meta(key): {"affine": torch.eye(4)}})
        self.assertEqual(len(data), 3)  # im, im_meta_dict, im_transforms
        self.assertIsInstance(data[key], torch.Tensor)
        self.assertNotIsInstance(data[key], MetaTensor)
        n_applied = len(data[PostFix.transforms(key)])
        self.assertEqual(n_applied, num_tr)

        # inverse all in one go
        data = tr.inverse(data)
        self.assertEqual(len(data), 3)  # im, im_meta_dict, im_transforms
        self.assertIsInstance(data[key], torch.Tensor)
        self.assertNotIsInstance(data[key], MetaTensor)
        n_applied = len(data[PostFix.transforms(key)])
        self.assertEqual(n_applied, 0)
Esempio n. 2
0
 def __call__(
     self, data: Mapping[Hashable, NdarrayOrTensor]
 ) -> Dict[Hashable, NdarrayOrTensor]:
     d = dict(data)
     for key in self.key_iterator(d):
         self.push_transform(d, key)
         im = d[key]
         meta = d.pop(PostFix.meta(key), None)
         transforms = d.pop(PostFix.transforms(key), None)
         im = MetaTensor(im, meta=meta,
                         applied_operations=transforms)  # type: ignore
         d[key] = im
     return d
Esempio n. 3
0
 def inverse(
     self, data: Mapping[Hashable, NdarrayOrTensor]
 ) -> Dict[Hashable, NdarrayOrTensor]:
     d = dict(data)
     for key in self.key_iterator(d):
         # check transform
         _ = self.get_most_recent_transform(d, key)
         # do the inverse
         im = d[key]
         meta = d.pop(PostFix.meta(key), None)
         transforms = d.pop(PostFix.transforms(key), None)
         im = MetaTensor(im, meta=meta,
                         applied_operations=transforms)  # type: ignore
         d[key] = im
         # Remove the applied transform
         self.pop_transform(d, key)
     return d
Esempio n. 4
0
    def as_dict(self, key: str) -> dict:
        """
        Get the object as a dictionary for backwards compatibility.
        This method makes a copy of the objects.

        Args:
            key: Base key to store main data. The key for the metadata will be
                determined using `PostFix.meta`.

        Return:
            A dictionary consisting of two keys, the main data (stored under `key`) and
                the metadata.
        """
        return {
            key: self.as_tensor().clone().detach(),
            PostFix.meta(key): deepcopy(self.meta),
            PostFix.transforms(key): deepcopy(self.applied_operations),
        }
Esempio n. 5
0
    def as_dict(self, key: str, output_type=torch.Tensor, dtype=None) -> dict:
        """
        Get the object as a dictionary for backwards compatibility.
        This method does not make a deep copy of the objects.

        Args:
            key: Base key to store main data. The key for the metadata will be determined using `PostFix`.
            output_type: `torch.Tensor` or `np.ndarray` for the main data.
            dtype: dtype of output data. Converted to correct library type (e.g.,
                `np.float32` is converted to `torch.float32` if output type is `torch.Tensor`).
                If left blank, it remains unchanged.

        Return:
            A dictionary consisting of three keys, the main data (stored under `key`) and the metadata.
        """
        if output_type not in (torch.Tensor, np.ndarray):
            raise ValueError(
                f"output_type must be torch.Tensor or np.ndarray, got {output_type}."
            )
        return {
            key: self.get_array(output_type=output_type, dtype=dtype),
            PostFix.meta(key): self.meta,
            PostFix.transforms(key): self.applied_operations,
        }
Esempio n. 6
0
    def test_from_to_meta_tensord(self, device, dtype):
        m1 = self.get_im(device=device, dtype=dtype)
        m2 = self.get_im(device=device, dtype=dtype)
        m3 = self.get_im(device=device, dtype=dtype)
        d_metas = {"m1": m1, "m2": m2, "m3": m3}
        m1_meta = {k: v for k, v in m1.meta.items() if k != "affine"}
        m1_aff = m1.affine

        # FROM -> forward
        t_from_meta = FromMetaTensord(["m1", "m2"])
        d_dict = t_from_meta(d_metas)

        self.assertEqual(
            sorted(d_dict.keys()),
            [
                "m1",
                PostFix.meta("m1"),
                PostFix.transforms("m1"),
                "m2",
                PostFix.meta("m2"),
                PostFix.transforms("m2"),
                "m3",
            ],
        )
        self.check(d_dict["m3"], m3, ids=True)  # unchanged
        self.check(d_dict["m1"], m1.as_tensor(), ids=False)
        meta_out = {
            k: v
            for k, v in d_dict["m1_meta_dict"].items() if k != "affine"
        }
        aff_out = d_dict["m1_meta_dict"]["affine"]
        self.check(aff_out, m1_aff, ids=True)
        self.assertEqual(meta_out, m1_meta)

        # FROM -> inverse
        d_meta_dict_meta = t_from_meta.inverse(d_dict)
        self.assertEqual(sorted(d_meta_dict_meta.keys()), [
            "m1",
            PostFix.transforms("m1"), "m2",
            PostFix.transforms("m2"), "m3"
        ])
        self.check(d_meta_dict_meta["m3"], m3,
                   ids=False)  # unchanged (except deep copy in inverse)
        self.check(d_meta_dict_meta["m1"], m1, ids=False)
        meta_out = {
            k: v
            for k, v in d_meta_dict_meta["m1"].meta.items() if k != "affine"
        }
        aff_out = d_meta_dict_meta["m1"].affine
        self.check(aff_out, m1_aff, ids=False)
        self.assertEqual(meta_out, m1_meta)

        # TO -> Forward
        t_to_meta = ToMetaTensord(["m1", "m2"])
        del d_dict["m1_transforms"]
        del d_dict["m2_transforms"]
        d_dict_meta = t_to_meta(d_dict)
        self.assertEqual(sorted(d_dict_meta.keys()), [
            "m1",
            PostFix.transforms("m1"), "m2",
            PostFix.transforms("m2"), "m3"
        ])
        self.check(d_dict_meta["m3"], m3,
                   ids=True)  # unchanged (except deep copy in inverse)
        self.check(d_dict_meta["m1"], m1, ids=False)
        meta_out = {
            k: v
            for k, v in d_dict_meta["m1"].meta.items() if k != "affine"
        }
        aff_out = d_dict_meta["m1"].meta["affine"]
        self.check(aff_out, m1_aff, ids=False)
        self.assertEqual(meta_out, m1_meta)

        # TO -> Inverse
        d_dict_meta_dict = t_to_meta.inverse(d_dict_meta)
        self.assertEqual(
            sorted(d_dict_meta_dict.keys()),
            [
                "m1",
                PostFix.meta("m1"),
                PostFix.transforms("m1"),
                "m2",
                PostFix.meta("m2"),
                PostFix.transforms("m2"),
                "m3",
            ],
        )
        self.check(d_dict_meta_dict["m3"], m3.as_tensor(),
                   ids=False)  # unchanged (except deep copy in inverse)
        self.check(d_dict_meta_dict["m1"], m1.as_tensor(), ids=False)
        meta_out = {
            k: v
            for k, v in d_dict_meta_dict["m1_meta_dict"].items()
            if k != "affine"
        }
        aff_out = d_dict_meta_dict["m1_meta_dict"]["affine"]
        self.check(aff_out, m1_aff, ids=False)
        self.assertEqual(meta_out, m1_meta)
Esempio n. 7
0
    def test_from_to_meta_tensord(self, device, dtype, data_type="tensor"):
        m1 = self.get_im(device=device, dtype=dtype)
        m2 = self.get_im(device=device, dtype=dtype)
        m3 = self.get_im(device=device, dtype=dtype)
        d_metas = {"m1": m1, "m2": m2, "m3": m3}
        m1_meta = {k: v for k, v in m1.meta.items() if k != "affine"}
        m1_aff = m1.affine

        # FROM -> forward
        t_from_meta = FromMetaTensord(["m1", "m2"], data_type=data_type)
        d_dict = t_from_meta(d_metas)

        self.assertEqual(
            sorted(d_dict.keys()),
            [
                "m1",
                PostFix.meta("m1"),
                PostFix.transforms("m1"),
                "m2",
                PostFix.meta("m2"),
                PostFix.transforms("m2"),
                "m3",
            ],
        )
        self.check(d_dict["m3"], m3, ids=True)  # unchanged
        if data_type == "tensor":
            self.check(d_dict["m1"], m1.as_tensor(), ids=False)
        else:
            self.assertIsInstance(d_dict["m1"], np.ndarray)
        meta_out = {
            k: v
            for k, v in d_dict["m1_meta_dict"].items() if k != "affine"
        }
        aff_out = d_dict["m1_meta_dict"]["affine"]
        self.check(aff_out, m1_aff, ids=False)
        self.assertEqual(meta_out, m1_meta)

        # FROM -> inverse
        d_meta_dict_meta = t_from_meta.inverse(d_dict)
        self.assertEqual(sorted(d_meta_dict_meta.keys()), ["m1", "m2", "m3"])
        if data_type == "numpy":
            m1, m1_aff = m1.cpu(), m1_aff.cpu()
        self.check(d_meta_dict_meta["m1"], m1, ids=False)
        meta_out = {
            k: v
            for k, v in d_meta_dict_meta["m1"].meta.items() if k != "affine"
        }
        aff_out = d_meta_dict_meta["m1"].affine
        self.check(aff_out, m1_aff, ids=False)
        self.assertEqual(meta_out, m1_meta)

        # TO -> Forward
        t_to_meta = ToMetaTensord(["m1", "m2"])
        d_dict_meta = t_to_meta(d_dict)
        self.assertEqual(sorted(d_dict_meta.keys()), ["m1", "m2", "m3"],
                         f"flag: {config.USE_META_DICT}")
        self.check(d_dict_meta["m3"], m3,
                   ids=True)  # unchanged (except deep copy in inverse)
        self.check(d_dict_meta["m1"], m1, ids=False)
        meta_out = {
            k: v
            for k, v in d_dict_meta["m1"].meta.items() if k != "affine"
        }
        aff_out = d_dict_meta["m1"].meta["affine"]
        self.check(aff_out, m1_aff, ids=False)
        self.assertEqual(meta_out, m1_meta)

        # TO -> Inverse
        d_dict_meta_dict = t_to_meta.inverse(d_dict_meta)
        self.assertEqual(
            sorted(d_dict_meta_dict.keys()),
            [
                "m1",
                PostFix.meta("m1"),
                PostFix.transforms("m1"),
                "m2",
                PostFix.meta("m2"),
                PostFix.transforms("m2"),
                "m3",
            ],
        )
        self.check(d_dict_meta_dict["m3"], m3.as_tensor(),
                   ids=False)  # unchanged (except deep copy in inverse)
        self.check(d_dict_meta_dict["m1"], m1.as_tensor(), ids=False)
        meta_out = {
            k: v
            for k, v in d_dict_meta_dict["m1_meta_dict"].items()
            if k != "affine"
        }
        aff_out = d_dict_meta_dict["m1_meta_dict"]["affine"]
        self.check(aff_out, m1_aff, ids=False)
        self.assertEqual(meta_out, m1_meta)