text: REGISTERED_DATASET_CLASSES = {}
  
  
  def register_dataset(cls, name=None):
      global REGISTERED_DATASET_CLASSES
      if name is None:
          name = cls.__name__
      assert name not in REGISTERED_DATASET_CLASSES, f"exist class: {REGISTERED_DATASET_CLASSES}"
      REGISTERED_DATASET_CLASSES[name] = cls
      return cls
  
  
  def get_dataset_class(name):
      global REGISTERED_DATASET_CLASSES
      assert name in REGISTERED_DATASET_CLASSES, f"available class: {REGISTERED_DATASET_CLASSES}"
      return REGISTERED_DATASET_CLASSES[name]
  
  
  class Dataset(object):
      """An abstract class representing a pytorch-like Dataset.
      All other datasets should subclass it. All subclasses should override
      ``__len__``, that provides the size of the dataset, and ``__getitem__``,
      supporting integer indexing in range from 0 to len(self) exclusive.
      """
      NumPointFeatures = -1
  
      def __getitem__(self, index):
          """This function is used for preprocess.
          you need to create a input dict in this function for network inference.
          format: {
              anchors
              voxels
              num_points
              coordinates
              if training:
                  labels
                  reg_targets
              [optional]anchors_mask, slow in SECOND v1.5, don't use this.
              [optional]metadata, in kitti, image index is saved in metadata
          }
          """
          raise NotImplementedError
  
      def __len__(self):
          raise NotImplementedError
  
      def get_sensor_data(self, query):
          """Dataset must provide a unified function to get data.
          Args:
              query: int or dict. this param must support int for training.
                  if dict, should have this format (no example yet): 
                  {
                      sensor_name: {
                          sensor_meta
                      }
                  }
                  if int, will return all sensor data. 
                  (TODO: how to deal with unsynchronized data?)
          Returns:
              sensor_data: dict. 
              if query is int (return all), return a dict with all sensors: 
              {
                  sensor_name: sensor_data
                  ...
                  metadata: ... (for kitti, contains image_idx)
              }
              
              if sensor is lidar (all lidar point cloud must be concatenated to one array): 
              e.g. If your dataset have two lidar sensor, you need to return a single dict:
              {
                  "lidar": {
                      "points": ...
                      ...
                  }
              }
              sensor_data: {
                  points: [N, 3+]
                  [optional]annotations: {
                      "boxes": [N, 7] locs, dims, yaw, in lidar coord system. must tested
                          in provided visualization tools such as second.utils.simplevis
                          or web tool.
                      "names": array of string.
                  }
              }
              if sensor is camera (not used yet):
              sensor_data: {
                  data: image string (array is too large)
                  [optional]annotations: {
                      "boxes": [N, 4] 2d bbox
                      "names": array of string.
                  }
              }
              metadata: {
                  # dataset-specific information.
                  # for kitti, must have image_idx for label file generation.
                  image_idx: ...
              }
              [optional]calib # only used for kitti
          """
          raise NotImplementedError
  
      def evaluation(self, dt_annos, output_dir):
          """Dataset must provide a evaluation function to evaluate model."""
          raise NotImplementedError
  