@Override
  public Map<String, Object> annotate(
      final RefMetaDataTracker tracker,
      final AnnotatorCompatible walker,
      final ReferenceContext ref,
      final Map<String, AlignmentContext> stratifiedContexts,
      final VariantContext vc,
      final Map<String, PerReadAlleleLikelihoodMap> stratifiedPerReadAlleleLikelihoodMap) {
    // Can only call from UnifiedGenotyper
    if (!(walker instanceof UnifiedGenotyper)) {
      if (!walkerIdentityCheckWarningLogged) {
        if (walker != null)
          logger.warn(
              "Annotation will not be calculated, must be called from UnifiedGenotyper, not "
                  + walker.getClass().getName());
        else logger.warn("Annotation will not be calculated, must be called from UnifiedGenotyper");
        walkerIdentityCheckWarningLogged = true;
      }
      return null;
    }

    if (stratifiedContexts.isEmpty()) return null;

    // not meaningful when we're at an indel location: deletions that start at location N are by
    // definition called at the position  N-1, and at position N-1
    // there are no informative deletions in the pileup
    if (!vc.isSNP()) return null;

    int deletions = 0;
    int depth = 0;
    for (Map.Entry<String, AlignmentContext> sample : stratifiedContexts.entrySet()) {
      for (final PileupElement p : sample.getValue().getBasePileup()) {
        depth++;
        if (p.isDeletion()) deletions++;
      }
    }
    Map<String, Object> map = new HashMap<>();
    map.put(
        getKeyNames().get(0),
        String.format("%.2f", depth == 0 ? 0.0 : (double) deletions / (double) depth));
    return map;
  }
  public CountedData map(
      RefMetaDataTracker tracker, ReferenceContext ref, AlignmentContext context) {

    final CountedData counter = new CountedData();

    // For some reason RodWalkers get map calls with null trackers
    if (tracker == null) return counter;

    VariantContext vcComp = tracker.getFirstValue(alleles);
    if (vcComp == null) return counter;

    // todo - not sure I want this, may be misleading to filter extended indel events.
    if (isInsideExtendedIndel(vcComp, ref)) return counter;

    // Do not operate on variants that are not covered to the optional minimum depth
    if (!context.hasReads()
        || (minDepth > 0 && context.getBasePileup().getBases().length < minDepth)) {
      counter.nUncovered = 1L;
      final GVstatus status = getGVstatus(vcComp);
      if (status == GVstatus.T) counter.nAltNotCalled = 1L;
      else if (status == GVstatus.F) counter.nRefNotCalled = 1L;
      else counter.nNoStatusNotCalled = 1L;

      return counter;
    }

    VariantCallContext call;
    if (vcComp.isSNP()) {
      call = snpEngine.calculateLikelihoodsAndGenotypes(tracker, ref, context).get(0);
    } else if (vcComp.isIndel()) {
      call = indelEngine.calculateLikelihoodsAndGenotypes(tracker, ref, context).get(0);
    } else if (bamIsTruth) {
      // assume it's a SNP if no variation is present; this is necessary so that we can test
      // supposed monomorphic sites against the truth bam
      call = snpEngine.calculateLikelihoodsAndGenotypes(tracker, ref, context).get(0);
    } else {
      logger.info(
          "Not SNP or INDEL "
              + vcComp.getChr()
              + ":"
              + vcComp.getStart()
              + " "
              + vcComp.getAlleles());
      return counter;
    }

    boolean writeVariant = true;

    if (bamIsTruth) {
      if (call.confidentlyCalled) {
        // If truth is a confident REF call
        if (call.isVariant()) {
          if (vcComp.isVariant()) counter.nAltCalledAlt = 1L;
          else {
            counter.nAltCalledRef = 1L;
            if (printInterestingSites)
              System.out.println("Truth=ALT Call=REF at " + call.getChr() + ":" + call.getStart());
          }
        }
        // If truth is a confident ALT call
        else {
          if (vcComp.isVariant()) {
            counter.nRefCalledAlt = 1L;
            if (printInterestingSites)
              System.out.println("Truth=REF Call=ALT at " + call.getChr() + ":" + call.getStart());
          } else counter.nRefCalledRef = 1L;
        }
      } else {
        counter.nNotConfidentCalls = 1L;
        if (printInterestingSites)
          System.out.println("Truth is not confident at " + call.getChr() + ":" + call.getStart());
        writeVariant = false;
      }
    } else {
      //            if (!vcComp.hasExtendedAttribute("GV"))
      //                throw new UserException.BadInput("Variant has no GV annotation in the INFO
      // field. " + vcComp.getChr() + ":" + vcComp.getStart());

      final GVstatus status = getGVstatus(vcComp);
      if (call.isCalledAlt(callConf)) {
        if (status == GVstatus.T) counter.nAltCalledAlt = 1L;
        else if (status == GVstatus.F) {
          counter.nRefCalledAlt = 1L;
          if (printInterestingSites)
            System.out.println("Truth=REF Call=ALT at " + call.getChr() + ":" + call.getStart());
        } else counter.nNoStatusCalledAlt = 1L;
      } else if (call.isCalledRef(callConf)) {
        if (status == GVstatus.T) {
          counter.nAltCalledRef = 1L;
          if (printInterestingSites)
            System.out.println("Truth=ALT Call=REF at " + call.getChr() + ":" + call.getStart());
        } else if (status == GVstatus.F) counter.nRefCalledRef = 1L;
        else counter.nNoStatusCalledRef = 1L;
      } else {
        counter.nNotConfidentCalls = 1L;
        if (status == GVstatus.T) counter.nAltNotCalled = 1L;
        else if (status == GVstatus.F) counter.nRefNotCalled = 1L;
        else counter.nNoStatusNotCalled = 1L;

        if (printInterestingSites)
          System.out.println("Truth is not confident at " + call.getChr() + ":" + call.getStart());
        writeVariant = false;
      }
    }

    if (vcfWriter != null && writeVariant) {
      if (!vcComp.hasAttribute(GATKVCFConstants.GENOTYPE_AND_VALIDATE_STATUS_KEY)) {
        vcfWriter.add(
            new VariantContextBuilder(vcComp)
                .attribute(
                    GATKVCFConstants.GENOTYPE_AND_VALIDATE_STATUS_KEY,
                    call.isCalledAlt(callConf) ? "ALT" : "REF")
                .make());
      } else vcfWriter.add(vcComp);
    }
    return counter;
  }