code: def download(self, process_features, min_num_samples_per_class):
      if self._check_integrity():
          return
  
      from sklearn.datasets import fetch_openml
  
      data = fetch_openml(data_id=self.open_ml_id)
      features = data.data
      targets = data.target
      feature_names = np.array(data.feature_names)
  
      # drop V1 and V2. V1 is the index of the choral, and V2 is the event number: index
      # (starting from 1) of the event inside the chorale.
      features_to_drop = np.array(["V1", "V2"])
      idx_drop = [
          np.where(feature_names == v)[0][0] for v in features_to_drop
      ]
      idx_keep = np.array([True] * feature_names.shape[0])
      for i in idx_drop:
          idx_keep[i] = False
  
      features = features[:, idx_keep]
      feature_names = feature_names[idx_keep]
  
      # get categorical feature names
      feature_names_cat = []
      for v in feature_names:
          if v in data.categories.keys():
              feature_names_cat.append(v)
      feature_names_cat = np.array(feature_names_cat)
  
      # get numerical feature names
      feature_names_num = []
      for fname in feature_names:
          if fname not in feature_names_cat:
              feature_names_num.append(fname)
      feature_names_num = np.array(feature_names_num)
  
      assert feature_names_num.shape[0] + feature_names_cat.shape[
          0
      ] == len(feature_names)
  
      is_categorical = np.array(
          [
              feature_name in feature_names_cat
              for feature_name in feature_names
          ]
      )
      is_numerical = np.array(
          [
              feature_name in feature_names_num
              for feature_name in feature_names
          ]
      )
  
      # get categories
      categories = []
      for i in range(feature_names_cat.shape[0]):
          categories_i = np.unique(features[:, is_categorical][:, i])
          categories.append(categories_i.tolist())
  
      if process_features:
          from sklearn.preprocessing import OneHotEncoder
  
          ohe = OneHotEncoder(
              categories=categories, sparse=False, dtype=np.float
          )
  
      # for each meta-data-split, get the labels, then check which data-point belongs to the set (via a mask).
      # then, retrieve the features and targets belonging to the set. Then create hdf5 file for these features.
      for s, split in enumerate(["train", "val", "test"]):
          targets_assets_split = get_asset(
              self.folder, "{0}.json".format(split)
          )
  
          is_in_split = [t in targets_assets_split for t in targets]
          features_split = features[is_in_split, :]
          targets_split = targets[is_in_split]
          assert targets_split.shape[0] == features_split.shape[0]
  
          unique_targets_split = np.unique(targets_split)
  
          # first we check how many data-points are associated with each class. If it is less than the threshold,
          # min_num_samples_per_class, then we discard the whole class.
          num_dat_per_class = []
          for label in unique_targets_split:
              num_dat_per_class.append(
                  features_split[targets_split == label, :].shape[0]
              )
          num_dat_per_class = np.array(num_dat_per_class)
  
          # remove labels which have less data-points associate with them than the threshold min_num_data_per_class.
          classes_to_keep = (
              num_dat_per_class >= min_num_samples_per_class
          )
          unique_targets_with_enough_data_split = unique_targets_split[
              classes_to_keep
          ]
  
          if (
              unique_targets_with_enough_data_split.shape[0]
              < unique_targets_split.shape[0]
          ):
              print(
                  "split: ({2}): number of unique targets with enough data ({0}) is smaller than "
                  "number of unique targets in assets ({1})".format(
                      unique_targets_with_enough_data_split.shape[0],
                      unique_targets_split.shape[0],
                      split,
                  )
              )
  
          # write unique targets to json file.
          labels_filename = os.path.join(
              self.root, self.filename_labels.format(split)
          )
          with open(labels_filename, "w") as f:
              json.dump(
                  unique_targets_with_enough_data_split.tolist(), f
              )
  
          # get pre-processing stats from the meta-train split
          if split == "train":
              # numerical features
              lower, upper = np.zeros(features.shape[1]), np.ones(
                  features.shape[1]
              )
              if process_features:
                  # lower upper
                  lower = np.min(features[:, is_numerical], axis=0)
                  upper = np.max(features[:, is_numerical], axis=0)
              self._lower_upper = {
                  "lower": lower.tolist(),
                  "upper": upper.tolist(),
                  "features_names": feature_names_num.tolist(),
              }
  
          # apply pre-processing of features
          if process_features:
              features_split_num = np.true_divide(
                  (features_split[:, is_numerical] - lower),
                  (upper - lower),
              )
              features_split_cat = ohe.fit_transform(
                  features_split[:, is_categorical]
              )
              features_split = np.hstack(
                  [features_split_num, features_split_cat]
              )
  
          # write data (features and class labels)
          filename = os.path.join(
              self.root, self.filename.format(split)
          )
          with h5py.File(filename, "w") as f:
              group = f.create_group("datasets")
  
              for i, label in enumerate(
                  tqdm(
                      unique_targets_with_enough_data_split,
                      desc=filename,
                  )
              ):
                  data_class = features_split[targets_split == label, :]
                  group.create_dataset(label, data=data_class)
  
      # store meta-data of the dataset (not the meta-dataset).
      # Extend this dictionary if you want to store more meta-data of the meta-dataset.
      meta_data = {
          "min_num_data_per_class": min_num_samples_per_class,
          "lower": lower.tolist(),
          "upper": upper.tolist(),
          "feature_names_numerical": feature_names_num.tolist(),
          "feature_names_categorical": feature_names_cat.tolist(),
          "categories": categories,
          "dropped_features": features_to_drop.tolist(),
      }
  
      with open(self.split_filename_meta_data, "w") as f:
          json.dump(meta_data, f)
  
imports: import numpy
  import os
  import json
  import h5py
  from tqdm import tqdm
  from torchmeta.utils.data import Dataset, ClassDataset, CombinationMetaDataset
  from torchmeta.datasets.utils import get_asset
label_desc: Use image node_id 11 for calling the BachClassDataset obj's underlying member method code with example usage: obj.download(process_features, min_num_samples_per_class) without return types