let somatic_on_region
    ~run_with ?adjust_mapq ~normal ~tumor ~result_prefix region =
  let open KEDSL in
  let name = Filename.basename result_prefix in
  let result_file suffix = result_prefix ^ suffix in
  let varscan_tool = Machine.get_tool run_with Machine.Tool.Default.varscan in
  let snp_output = result_file "-snp.vcf" in
  let indel_output = result_file "-indel.vcf" in
  let normal_pileup = Samtools.mpileup ~run_with ~region ?adjust_mapq normal in
  let tumor_pileup = Samtools.mpileup ~run_with ~region ?adjust_mapq tumor in
  let host = Machine.as_host run_with in
  let tags = [Target_tags.variant_caller; "varscan"in
  let varscan_somatic =
    let name = "somatic-" ^ name in
    let make =
      let big_one_liner =
        "if [ -s " ^ normal_pileup#product#path
        ^ " ] && [ -s " ^ tumor_pileup#product#path ^ " ] ; then "
        ^ sprintf "java -jar $VARSCAN_JAR somatic %s %s --output-snp %s --output-indel %s --output-vcf 1 ; "
          normal_pileup#product#path
          tumor_pileup#product#path
          snp_output
          indel_output
        ^ " else  "
        ^ "echo '" ^ empty_vcf ^ "' > " ^ snp_output ^ " ; "
        ^ "echo '" ^ empty_vcf ^ "' > " ^ indel_output ^ " ; "
        ^ " fi "
      in
      Program.(Machine.Tool.init varscan_tool && sh big_one_liner)
      |> Machine.run_big_program run_with ~name ~processors:1
        ~self_ids:["varscan""somatic"]
    in
    workflow_node ~name ~make
      (single_file snp_output ~host)
      ~tags
      ~edges:[
        depends_on (Machine.Tool.ensure varscan_tool);
        depends_on normal_pileup;
        depends_on tumor_pileup;
        on_failure_activate (Remove.file ~run_with snp_output);
        on_failure_activate (Remove.file ~run_with indel_output);
      ]
  in
  let snp_filtered = result_file "-snpfiltered.vcf" in
  let indel_filtered = result_file "-indelfiltered.vcf" in
  let varscan_filter =
    let name = "filter-" ^ name in
    let make =
      Program.(
        Machine.Tool.init varscan_tool
        && shf "java -jar $VARSCAN_JAR somaticFilter %s --indel-file %s --output-file %s"
          snp_output
          indel_output
          snp_filtered
        && shf "java -jar $VARSCAN_JAR processSomatic %s" snp_filtered
        && shf "java -jar $VARSCAN_JAR processSomatic %s" indel_output
      )
      |> Machine.run_big_program run_with ~name ~processors:1
        ~self_ids:["varscan""somaticfilter"]
    in
    workflow_node ~name
      (single_file snp_filtered ~host) ~make ~tags
      ~edges:[
        depends_on varscan_somatic;
        on_failure_activate (Remove.file ~run_with snp_filtered);
        on_failure_activate (Remove.file ~run_with indel_filtered);
      ]
  in
  varscan_filter