code: def test_multiscaleTransforms(self):
      samplers = [GridSampling3D(0.25), None, GridSampling3D(0.5)]
      search = [
          RadiusNeighbourFinder(
              0.5, 100, ConvolutionFormat.PARTIAL_DENSE.value
          ),
          RadiusNeighbourFinder(
              0.5, 150, ConvolutionFormat.PARTIAL_DENSE.value
          ),
          RadiusNeighbourFinder(
              1, 200, ConvolutionFormat.PARTIAL_DENSE.value
          ),
      ]
      upsampler = [KNNInterpolate(1), KNNInterpolate(1)]
  
      N = 10
      x = np.linspace(0, 1, N)
      y = np.linspace(0, 1, N)
      xv, yv = np.meshgrid(x, y)
  
      pos = torch.tensor(
          [xv.flatten(), yv.flatten(), np.zeros(N * N)]
      ).T
      x = torch.ones_like(pos)
      d = Data(pos=pos, x=x).contiguous()
      ms_transform = MultiScaleTransform(
          {
              "sampler": samplers,
              "neighbour_finder": search,
              "upsample_op": upsampler,
          }
      )
  
      transformed = ms_transform(d.clone())
      npt.assert_almost_equal(transformed.x.numpy(), x.numpy())
      npt.assert_almost_equal(transformed.pos.numpy(), pos.numpy())
  
      ms = transformed.multiscale
      npt.assert_almost_equal(ms[0].pos.numpy(), ms[1].pos.numpy())
      npt.assert_almost_equal(
          ms[0].pos.numpy(), samplers[0](d.clone()).pos.numpy()
      )
      npt.assert_almost_equal(
          ms[2].pos.numpy(), samplers[2](ms[0].clone()).pos.numpy()
      )
  
      self.assertEqual(ms[0].__inc__("idx_neighboors", 0), pos.shape[0])
      idx = search[0](
          d.pos,
          ms[0].pos,
          torch.zeros((d.pos.shape[0]), dtype=torch.long),
          torch.zeros((ms[0].pos.shape[0]), dtype=torch.long),
      )
      for i in range(len(ms[0].idx_neighboors)):
          self.assertEqual(
              set(ms[0].idx_neighboors[i].tolist()),
              set(idx[i].tolist()),
          )
      self.assertEqual(ms[1].idx_neighboors.shape[1], 150)
      self.assertEqual(ms[2].idx_neighboors.shape[1], 200)
  
      upsample = transformed.upsample
      self.assertEqual(upsample[0].num_nodes, ms[1].num_nodes)
      self.assertEqual(upsample[1].num_nodes, pos.shape[0])
      self.assertEqual(upsample[1].x_idx.max(), ms[0].num_nodes - 1)
      self.assertEqual(upsample[1].y_idx.max(), pos.shape[0] - 1)
      self.assertEqual(upsample[1].__inc__("x_idx", 0), ms[0].num_nodes)
      self.assertEqual(upsample[1].__inc__("y_idx", 0), pos.shape[0])
  
imports: import unittest
  import sys
  import os
  import torch_geometric.transforms
  import numpy
  import numpy.testing
  import torch
  from torch_geometric.data import Data
  from omegaconf.dictconfig import DictConfig
  from omegaconf.listconfig import ListConfig
  from omegaconf import OmegaConf
  from torch_points3d.core.data_transform import instantiate_transform, instantiate_transforms, GridSampling3D, MultiScaleTransform, Random3AxisRotation, AddFeatByKey, AddFeatsByKeys, RemoveAttributes, RandomDropout, ShiftVoxels, PCACompute, RandomCoordsFlip, XYZFeature, ScalePos, RandomWalkDropout, NormalizeFeature, SphereCrop, CubeCrop, RandomSphereDropout, DensityFilter, LotteryTransform, ClampBatchSize, RandomParamTransform, Select, ComposeTransform
  from torch_points3d.core.spatial_ops import RadiusNeighbourFinder, KNNInterpolate
  from torch_points3d.utils.enums import ConvolutionFormat
  from torch_points3d.datasets.multiscale_data import MultiScaleBatch
label_desc: Use image node_id 3 for calling the Testhelpers obj's underlying member method code with example usage: obj.test_multiscaleTransforms() without return types