docs: def variant_support(variants, allele_support_df, ignore_missing=False):
      '''
      Collect the read evidence support for the given variants.
  
      Parameters
      ----------
  
      variants : iterable of varcode.Variant
  
      allele_support_df : dataframe
          Allele support dataframe, as output by the varlens-allele-support tool.
          It should have columns: source, contig, interbase_start, interbase_end,
          allele. The remaining columns are interpreted as read counts of various
          subsets of reads (e.g. all reads, non-duplicate reads, etc.)
  
      ignore_missing : boolean
          If True, then varaints with no allele counts will be interpreted as
          having 0 depth. If False, then an exception will be raised if any
          variants have no allele counts.
  
      Returns
      ----------
  
      A pandas.Panel4D frame with these axes:
  
      labels (axis=0) : the type of read being counted, i.e. the read count
          fields in allele_support_df.
  
      items (axis=1)  : the type of measurement (num_alt, num_ref, num_other,
          total_depth, alt_fraction, any_alt_fraction)
  
      major axis (axis=2) : the variants
  
      minor axis (axis=3) : the sources
      '''
      missing = [
          c for c in EXPECTED_COLUMNS if c not in allele_support_df.columns
      ]
      if missing:
          raise ValueError("Missing columns: %s" % " ".join(missing))
  
      # Ensure our start and end fields are ints.
      allele_support_df[["interbase_start", "interbase_end"]] = (
          allele_support_df[["interbase_start", "interbase_end"]].astype(int))
  
      sources = sorted(allele_support_df["source"].unique())
  
      allele_support_dict = collections.defaultdict(dict)
      for (i, row) in allele_support_df.iterrows():
          key = (
              row['source'],
              row.contig,
              row.interbase_start,
              row.interbase_end)
          allele_support_dict[key][row.allele] = row["count"]
  
      # We want an exception on bad lookups, so convert to a regular dict.
      allele_support_dict = dict(allele_support_dict)
  
      dataframe_dicts = collections.defaultdict(
          lambda: collections.defaultdict(list))
  
      for variant in variants:
          for source in sources:
              key = (source, variant.contig, variant.start - 1, variant.end)
              try:
                  alleles = allele_support_dict[key]
              except KeyError:
                  message = (
                      "No allele counts in source %s for variant %s" % (
                          source, str(variant)))
                  if ignore_missing:
                      logging.warning(message)
                      alleles = {}
                  else:
                      raise ValueError(message)
  
              alt = alleles.get(variant.alt, 0)
              ref = alleles.get(variant.ref, 0)
              total = sum(alleles.values())
  
              other = total - alt - ref
  
              dataframe_dicts["num_alt"][source].append(alt)
              dataframe_dicts["num_ref"][source].append(ref)
              dataframe_dicts["num_other"][source].append(other)
              dataframe_dicts["total_depth"][source].append(total)
              dataframe_dicts["alt_fraction"][source].append(
                  float(alt) / max(1, total))
              dataframe_dicts["any_alt_fraction"][source].append(
                  float(alt + other) / max(1, total))
  
      dataframes = dict(
          (label, pandas.DataFrame(value, index=variants))
          for (label, value) in dataframe_dicts.items())
  
      return pandas.Panel(dataframes)