code: def enumerate_all_possible_haplotypes(
      variants, ref, enumeration_type
  ):
      """Returns all possible haplotype/genotype combinations for variants.
  
      Args:
        variants: list[nucleus.protos.Variant]. A list of candidate variants, in
          coordinate-sorted order, all on the same chromosome.
        ref: ReferenceRegion. Used to get reference bases for variants. Must cover
          at least the span of the variants.
        enumeration_type: EnumerationType enum value. What kind of enumeration do we
          want to do? Can be either CANDIDATES or TRUTH.
  
      Returns:
        Dict[Haplotypes, List[Genotypes]]
          where
          Genotypes = List[Genotype]
          Haplotypes = FrozenSet[str]
  
        Haplotypes is a set of either one or two strings, where each string is a
        haplotype (i.e., a series of bases) generated by the genotypes assigned to
        each variant. genotypes is a list of genotype tuples, in the same order as
        variants, indicating the genotype assignment for each variant. These
        genotypes are phased, so [(0, 1), (0, 1)] is not the same as
        [(0, 1), (1, 0)].
      """
  
      def create_haplotypes_recursive(variants_and_genotypes, last_pos):
          """Recursive driver to enumerate all haplotypes."""
          if not variants_and_genotypes:
              yield {
                  ref.bases(last_pos, ref.end)
              } if last_pos != ref.end else {""}
          else:
              group, remaining = split_independent_variants(
                  variants_and_genotypes
              )
              (
                  group_haplotypes,
                  next_pos,
              ) = phased_genotypes_to_haplotypes(group, last_pos, ref)
              prefix_haplotypes = list(
                  all_diploid_haplotypes(group, group_haplotypes)
              )
  
              if not prefix_haplotypes:
                  # prefix_haplotypes can be empty when group contains incompatible
                  # variants making it impossible to construct any haplotypes for group.
                  # For example, if group is:
                  #   variant(start=6, alleles=("AAT", "A"), genotype=(0, 1))
                  #   variant(start=7, alleles=("AT", "T"), genotype=(1, 1))
                  # prefix_haplotypes will be empty because there's no way to construct
                  # the haplotype where the variant@6 has a 1 genotype since it is
                  # deleting away bases that overlap the variant@7 which has a genotype of
                  # (1, 1), meaning it *has* to be present in some haplotype. In this
                  # situation we raise a ImpossibleHaplotype exception, which is caught
                  # in the outer loop, allowing us to bail out of the search ASAP.
                  raise ImpossibleHaplotype
  
              for haplotypes in create_haplotypes_recursive(
                  remaining, next_pos
              ):
                  for result in extend_haplotypes(
                      prefix_haplotypes, haplotypes
                  ):
                      yield result
  
      def create_haplotypes(variants_and_genotypes, last_pos):
          try:
              for r in create_haplotypes_recursive(
                  variants_and_genotypes, last_pos
              ):
                  yield r
          except ImpossibleHaplotype:
              # See comment in create_haplotypes_recursive for more information, but in
              # this case we simply `pass`, as we cannot construct any valid haplotypes.
              pass
  
      genotype_options = genotype_options_for_variants(
          variants, enumeration_type
      )
      haplotypes_to_genotypes_dict = collections.OrderedDict()
      for genotypes in itertools.product(*genotype_options):
          paired = [
              VariantAndGenotypes(v, g)
              for v, g in zip(variants, genotypes)
          ]
          for haplotypes in create_haplotypes(paired, ref.start):
              key = frozenset(haplotypes)
              if key not in haplotypes_to_genotypes_dict:
                  haplotypes_to_genotypes_dict[key] = []
              haplotypes_to_genotypes_dict[key].append(genotypes)
      return haplotypes_to_genotypes_dict
  
imports: import collections
  import copy
  import enum
  import heapq
  import itertools
  from absl import logging
  from deepvariant.labeler import variant_labeler
  from deepvariant.protos import deepvariant_pb2
  from third_party.nucleus.io import fasta
  from third_party.nucleus.util import ranges
  from third_party.nucleus.util import variant_utils
  from third_party.nucleus.util import variantcall_utils
label_desc: Use image node_id 4 for calling a global function with example usage: enumerate_all_possible_haplotypes(variants, ref, enumeration_type) and returns: haplotypes_to_genotypes_dict