code: def convert_data_type(
      data: Any,
      output_type: type[NdarrayTensor] | None = None,
      device: None | str | torch.device = None,
      dtype: DtypeLike | torch.dtype = None,
      wrap_sequence: bool = False,
      safe: bool = False,
  ) -> tuple[NdarrayTensor, type, torch.device | None]:
      """
      Convert to `MetaTensor`, `torch.Tensor` or `np.ndarray` from `MetaTensor`, `torch.Tensor`,
      `np.ndarray`, `float`, `int`, etc.
  
      Args:
          data: data to be converted
          output_type: `monai.data.MetaTensor`, `torch.Tensor`, or `np.ndarray` (if `None`, unchanged)
          device: if output is `MetaTensor` or `torch.Tensor`, select device (if `None`, unchanged)
          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.
          wrap_sequence: if `False`, then lists will recursively call this function.
              E.g., `[1, 2]` -> `[array(1), array(2)]`. If `True`, then `[1, 2]` -> `array([1, 2])`.
          safe: if `True`, then do safe dtype convert when intensity overflow. default to `False`.
              E.g., `[256, -12]` -> `[array(0), array(244)]`. If `True`, then `[256, -12]` -> `[array(255), array(0)]`.
  
      Returns:
          modified data, orig_type, orig_device
  
      Note:
          When both `output_type` and `dtype` are specified with different backend
          (e.g., `torch.Tensor` and `np.float32`), the `output_type` will be used as the primary type,
          for example::
  
              >>> convert_data_type(1, torch.Tensor, dtype=np.float32)
              (1.0, <class 'torch.Tensor'>, None)
  
      """
      orig_type: type
      if isinstance(data, monai.data.MetaTensor):
          orig_type = monai.data.MetaTensor
      elif isinstance(data, torch.Tensor):
          orig_type = torch.Tensor
      elif isinstance(data, np.ndarray):
          orig_type = np.ndarray
      elif has_cp and isinstance(data, cp.ndarray):
          orig_type = cp.ndarray
      else:
          orig_type = type(data)
  
      orig_device = (
          data.device if isinstance(data, torch.Tensor) else None
      )
  
      output_type = output_type or orig_type
      dtype_ = get_equivalent_dtype(dtype, output_type)
  
      data_: NdarrayTensor
      if issubclass(output_type, torch.Tensor):
          track_meta = issubclass(output_type, monai.data.MetaTensor)
          data_ = convert_to_tensor(
              data,
              dtype=dtype_,
              device=device,
              wrap_sequence=wrap_sequence,
              track_meta=track_meta,
              safe=safe,
          )
          return data_, orig_type, orig_device
      if issubclass(output_type, np.ndarray):
          data_ = convert_to_numpy(
              data, dtype=dtype_, wrap_sequence=wrap_sequence, safe=safe
          )
          return data_, orig_type, orig_device
      elif has_cp and issubclass(output_type, cp.ndarray):
          data_ = convert_to_cupy(
              data, dtype=dtype_, wrap_sequence=wrap_sequence, safe=safe
          )
          return data_, orig_type, orig_device
      raise ValueError(f"Unsupported output type: {output_type}")
  
imports: from __future__ import annotations
  import re
  from collections.abc import Sequence
  from typing import Any
  import numpy
  import torch
  import monai
  from monai.config.type_definitions import DtypeLike, NdarrayTensor
  from monai.utils import optional_import
label_desc: Use image node_id 10 for calling a global function with example usage: convert_data_type(data, output_type, device, dtype, wrap_sequence, safe) and returns: data_,  orig_type,  orig_device, data_,  orig_type,  orig_device, data_,  orig_type,  orig_device