//  [python]
def _get_data(self, data, split_name, **config):
        def _read_image(path):
            image = tf.read_file(path)
            image = tf.image.decode_png(image, channels=3)
            return image

        def _py_read_depth(path, scale):
            with h5py.File(path.decode('utf-8'), 'r') as f:
                depth = f['depth'].value
            return (depth*scale).astype(np.float32)

        def _resize_max(image, resize):
            target_size = tf.to_float(tf.convert_to_tensor(resize))
            current_size = tf.to_float(tf.shape(image)[:2])
            scale = target_size / tf.reduce_max(current_size)
            new_size = tf.to_int32(current_size * scale)
            return tf.image.resize_images(
                image, new_size, method=tf.image.ResizeMethod.BILINEAR)

        # TODO: fix principal point coordinates
        def _rotate_intrinsics(K, image, rot):
            shape = tf.to_float(tf.shape(image))
            h, w = shape[0], shape[1]
            fx, fy, cx, cy = K[0, 0], K[1, 1], K[0, 2], K[1, 2]
            def r0():  # noqa E306
                return K
            def r1():  # noqa E306
                return tf.convert_to_tensor([[fy, 0., cy],
                                             [0., fx, w-1-cx],
                                             [0., 0., 1.]])
            def r2():  # noqa E306
                return tf.convert_to_tensor([[fx, 0., w-1-cx],
                                             [0., fy, h-1-cy],
                                             [0., 0., 1.]])
            def r3():  # noqa E306
                return tf.convert_to_tensor([[fy, 0., h-1-cy],
                                             [0., fx, cx],
                                             [0., 0., 1.]])

            return tf.case([(tf.equal(rot, i), f)
                            for i, f in enumerate([r0, r1, r2, r3])])

        def _rotate_extrinsics(T_2to1, rot1, rot2):
            T = tf.matmul(rotation_matrices[rot1], T_2to1)
            return tf.matmul(T, tf.linalg.inv(rotation_matrices[rot2]))

        def _preprocess(data):
            image, depth, K = data['image'], data['depth'], data['K']
            tf.Tensor.set_shape(image, [None, None, 3])
            tf.Tensor.set_shape(depth, [None, None])
            if config['preprocessing']['grayscale']:
                image = tf.image.rgb_to_grayscale(image)
            original_size = tf.shape(image)[:2]
            if config['preprocessing']['resize_max']:
                image = _resize_max(
                    image, config['preprocessing']['resize_max'])
                new_size = tf.shape(image)[:2]
                depth = tf.image.resize_images(
                    depth[..., tf.newaxis], new_size,
                    method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)[..., 0]
                scale = tf.to_float(new_size) / tf.to_float(original_size)
                scale = tf.diag(tf.concat([scale, [1.]], 0))
                K = tf.matmul(scale, K)
            if config['preprocessing']['upright']:
                rot = data['rot']
                K = _rotate_intrinsics(K, image, rot)
                image = tf.image.rot90(image, rot)
                depth = tf.image.rot90(depth[..., None], rot)[..., 0]
            data['image'] = tf.to_float(image)
            data['depth'] = depth
            data['K'] = K
            return data

        def _parse(data):
            images = tf.data.Dataset.from_tensor_slices(data['image'])
            images = images.map_parallel(_read_image)
            depth = tf.data.Dataset.from_tensor_slices(data['depth'])
            scales = tf.data.Dataset.from_tensor_slices(data['scale'])
            rotations = tf.data.Dataset.from_tensor_slices(data['rot'])
            depth = tf.data.Dataset.zip((depth, scales)).map_parallel(
                lambda d, s: tf.py_func(_py_read_depth, [d, s], tf.float32))
            intrinsics = tf.data.Dataset.from_tensor_slices(
                np.array(data['K'], dtype=np.float32))
            names = tf.data.Dataset.from_tensor_slices(data['name'])
            dataset = tf.data.Dataset.zip(
                {'image': images, 'depth': depth, 'K': intrinsics,
                 'rot': rotations, 'name': names})
            dataset = dataset.map_parallel(_preprocess)
            return dataset

        dataset = _parse(data)

        if config['make_pairs']:
            entries = ['image', 'depth', 'K', 'name', 'rot']
            data2 = {k: data[k+'2'] for k in entries}
            data2['scale'] = data['scale']
            dataset2 = _parse(data2)
            dataset2 = dataset2.map(lambda d: {k+'2': d[k] for k in entries})
            T = tf.data.Dataset.from_tensor_slices(
                np.array(data['1_T_2'], dtype=np.float32))
            if config['preprocessing']['upright']:
                T = tf.data.Dataset.zip(
                        (T,
                         tf.data.Dataset.from_tensor_slices(data['rot']),
                         tf.data.Dataset.from_tensor_slices(data['rot2'])))
                T = T.map_parallel(_rotate_extrinsics)
            dataset = tf.data.Dataset.zip(
                (dataset, dataset2, T)).map(
                    lambda d1, d2, t: {**d1, **d2, '1_T_2': t})

        return dataset