code: def _group_batches_shared(xs, caller_batch_fn, prep_data_fn):
      
      singles = []
      batch_groups = collections.defaultdict(list)
      for args in xs:
          data = utils.to_single_data(args)
          caller, batch = caller_batch_fn(data)
          region = _list_to_tuple(data["region"]) if "region" in data else ()
          if batch is not None:
              batches = batch if isinstance(batch, (list, tuple)) else [batch]
              for b in batches:
                  batch_groups[(b, region, caller)].append(utils.deepish_copy(data))
          else:
              data = prep_data_fn(data, [data])
              singles.append(data)
      batches = []
      for batch, items in batch_groups.items():
          batch_data = utils.deepish_copy(_pick_lead_item(items))
          # For nested primary batches, split permanently by batch
          if tz.get_in(["metadata", "batch"], batch_data):
              batch_name = batch[0]
              batch_data["metadata"]["batch"] = batch_name
          batch_data = prep_data_fn(batch_data, items)
          batch_data["group_orig"] = _collapse_subitems(batch_data, items)
          batch_data["group"] = batch
          batches.append(batch_data)
      return singles + batches
docs: Shared functionality for grouping by batches for variant calling and joint calling.