code: def allele_mismatches(evalv, truev):
      """Determines the set of allele mismatch discordances between evalv and truev.
  
      Compares the alleles present in evalv and truev to determine if there are any
      disagreements between the set of called alleles in the two Variant protos. The
      type of differences basically boil down to:
  
      -- Are there duplicate alt alleles?
      -- Can we find a matching allele in the truev for each allele in evalv, and
        vice versa?
  
      Two alleles A and B match when they would produce the same sequence of bases
      in ref and alt haplotypes starting at the same position. So CA=>TA is the same
      as C=>T (position is the same, replacing A by A is a noop) but AC=>AT isn't
      the same as C=>T because the former event changes bases 1 bp further along in
      the reference genome than the C=>T allele.
  
      Args:
        evalv: A nucleus.genomics.v1.Variant.
        truev: A nucleus.genomics.v1.Variant.
  
      Returns:
        A set of AlleleMismatchType values.
      """
      unmatched_eval_alleles = []
      # Use set removes duplicate alleles in truth and eval variants.
      allele_matches = {alt: [] for alt in set(truev.alternate_bases)}
      for eval_alt in set(evalv.alternate_bases):
          # Loop over each possible alt allele, adding eval_alt to each matching alt
          # allele.
          found_match = False
          for true_alt in allele_matches:
              if simplify_alleles(
                  evalv.reference_bases, eval_alt
              ) == simplify_alleles(truev.reference_bases, true_alt):
                  # We are a match to true_alt, so record that fact in allele_matches
                  allele_matches[true_alt].append(eval_alt)
                  found_match = True
          if not found_match:
              # We never found a match for eval_alt.
              unmatched_eval_alleles.append(eval_alt)
  
      # At this point we've checked every alt against every eval allele, and are
      # ready to summarize the differences using our AlleleMismatchType enum.
      types = set()
      if len(set(evalv.alternate_bases)) != len(evalv.alternate_bases):
          types.add(AlleleMismatchType.duplicate_eval_alleles)
      if len(set(truev.alternate_bases)) != len(truev.alternate_bases):
          types.add(AlleleMismatchType.duplicate_true_alleles)
      if unmatched_eval_alleles:
          types.add(AlleleMismatchType.unmatched_eval_alleles)
      if any(
          len(match) != 1 for match in six.itervalues(allele_matches)
      ):
          types.add(AlleleMismatchType.unmatched_true_alleles)
      return types
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import collections
  import enum
  import itertools
  import six
  from third_party.nucleus.protos import variants_pb2
  from third_party.nucleus.util import ranges
  from third_party.nucleus.util import variantcall_utils
  from third_party.nucleus.util import vcf_constants
label_desc: Use image node_id 23 for calling a global function with example usage: allele_mismatches(evalv, truev) and returns: types