code: def get_class_balanced_patients(
      class_targets, batch_size, num_classes, slack_factor=0.1
  ):
      """
      samples patients towards equilibrium of classes on a roi-level. For highly imbalanced datasets, this might be a too strong requirement.
      Hence a slack factor determines the ratio of the batch, that is randomly sampled, before class-balance is triggered.
      :param class_targets: list of patient targets. where each patient target is a list of class labels of respective rois.
      :param batch_size:
      :param num_classes:
      :param slack_factor:
      :return: batch_ixs: list of indices referring to a subset in class_targets-list, sampled to build one batch.
      """
      batch_ixs = []
      class_count = {k: 0 for k in range(num_classes)}
      weakest_class = 0
      for ix in range(batch_size):
          keep_looking = True
          while keep_looking:
              # choose a random patient.
              cand = np.random.choice(len(class_targets), 1)[0]
              # check the least occuring class among this patient's rois.
              tmp_weakest_class = np.argmin(
                  [
                      class_targets[cand].count(ii)
                      for ii in range(num_classes)
                  ]
              )
              # if current batch already bigger than the slack_factor ratio, then
              # check that weakest class in this patient is not the weakest in current batch (since needs to be boosted)
              # also that at least one roi of this patient belongs to weakest class. If True, keep patient, else keep looking.
              if (
                  tmp_weakest_class != weakest_class
                  and class_targets[cand].count(weakest_class) > 0
              ) or ix < int(batch_size * slack_factor):
                  keep_looking = False
  
          for c in range(num_classes):
              class_count[c] += class_targets[cand].count(c)
          weakest_class = np.argmin(
              ([class_count[c] for c in range(num_classes)])
          )
          batch_ixs.append(cand)
  
      return batch_ixs
  
file_path: medicaldetectiontoolkit/utils/dataloader_utils.py
imports: import numpy
  import os
  from multiprocessing import Pool
label_desc: Use image node_id 1 for calling a global function with example usage: get_class_balanced_patients(class_targets, batch_size, num_classes, slack_factor) and returns: batch_ixs