(BfxBiokepi.EDSL.Semantics) = struct

  module Insane_library = Pipeline_insane(Bfx)

  let vc =
    let normal =
      Insane_library.(fastq_list  ~dataset:(fst normal) (snd normal))
    in
    let tumor =
      Insane_library.(fastq_list  ~dataset:(fst tumor) (snd tumor))
    in
    let ot_hla =
      normal |> Bfx.concat |> Bfx.optitype `DNA |> Bfx.to_unit
    in
    let align fastq =
      Bfx.list_map fastq ~f:(Bfx.lambda (fun fq ->
          Bfx.bwa_mem fq
            ~reference_build:"b37"
          |> Bfx.picard_mark_duplicates
            ~configuration:Biokepi.Tools.Picard.Mark_duplicates_settings.default
        )) in
    let normal_bam = align normal |> Bfx.merge_bams in
    let tumor_bam = align tumor |> Bfx.merge_bams in
    let bam_pair = Bfx.pair normal_bam tumor_bam in
    let indel_realigned_pair =
      Bfx.gatk_indel_realigner_joint bam_pair
        ~configuration: Biokepi.Tools.Gatk.Configuration.default_indel_realigner
    in
    let final_normal_bam =
      Bfx.pair_first indel_realigned_pair
      |> Bfx.gatk_bqsr
        ~configuration: Biokepi.Tools.Gatk.Configuration.default_bqsr
    in
    let final_tumor_bam =
      Bfx.pair_second indel_realigned_pair
      |> Bfx.gatk_bqsr
        ~configuration: Biokepi.Tools.Gatk.Configuration.default_bqsr
    in
    let vcfs =
      let normal, tumor = final_normal_bam, final_tumor_bam in
      Bfx.list [
        Bfx.mutect ~normal ~tumor ();
        Bfx.somaticsniper ~normal ~tumor ();
        Bfx.strelka ~normal ~tumor ();
      ] in
    Bfx.list [
      Bfx.to_unit vcfs;
      ot_hla;
    ] |> Bfx.to_unit

  let run () =
    Bfx.observe (fun () -> vc)
end