Docker-in-Docker (DinD) capabilities of public runners deactivated. More info

result_table.ml 2.55 KB
Newer Older
1 2 3
open Core_kernel

type t = {
4 5
  oracle : bool array option;
  scores_per_meth : (string * float option array) list;
6 7
}

8 9
(* invariant: all columns have the same length *)

10
let of_file fn =
11 12 13 14 15 16 17
  match
    In_channel.read_lines fn
    |> List.map ~f:(String.split ~on:'\t')
    |> List.transpose
  with
  | None -> failwith "Variable number of fields"
  | Some cols ->
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
      let cols =
        List.map cols ~f:(function [] -> assert false | h :: t -> (h, t))
      in
      let oracle =
        List.Assoc.find cols "Oracle" ~equal:String.equal
        |> Option.map
             ~f:
               (List.map ~f:(function
                 | "0" -> false
                 | "1" -> true
                 | _ -> failwith "Unexpected element in oracle column"))
        |> Option.map ~f:Array.of_list
      in
      let scores_per_meth =
        List.filter_map cols ~f:(fun (label, values) ->
            if String.(label <> "Oracle" && label <> "Sites") then
              let values =
                List.map values ~f:(function
                  | "NA" -> None
                  | x -> Some (Float.of_string x))
                |> Array.of_list
              in
              Some (label, values)
            else None)
      in
      { oracle; scores_per_meth }

let nrows results =
  match results.oracle with
  | Some oracle -> Array.length oracle
  | None -> (
      match results.scores_per_meth with
      | (_, col) :: _ -> Array.length col
      | [] -> 0 )

type cell = Nullable_float of float option | Bool of bool | Int of int

let string_of_cell = function
  | Bool b -> if b then "1" else "0"
  | Nullable_float None -> "NA"
  | Nullable_float (Some f) -> Float.to_string f
  | Int i -> Int.to_string i

let line_of_cells xs = List.map xs ~f:string_of_cell |> String.concat ~sep:"\t"

let maybe_add o xs = match o with None -> xs | Some h -> h :: xs

let headers results =
  "Site"
  :: maybe_add
       (Option.map results.oracle ~f:(Fn.const "Oracle"))
       (List.map results.scores_per_meth ~f:fst)

let get_oracle res i = Option.map res.oracle ~f:(fun o -> Bool o.(i))

let row res i =
  Int (i + 1)
  :: maybe_add (get_oracle res i)
       (List.map res.scores_per_meth ~f:(fun (_, s) -> Nullable_float s.(i)))

let write_columns oc res =
  let nrows = nrows res in
  Utils.range_iter 0 nrows ~f:(fun i ->
      row res i |> line_of_cells |> Out_channel.fprintf oc "%s\n")

let to_file results ~output =
  let header_str = headers results |> String.concat ~sep:"\t" in
  Out_channel.with_file output ~f:(fun oc ->
      Out_channel.fprintf oc "%s\n" header_str;
      write_columns oc results)