Commit 9a086443 authored by Louis Duchemin's avatar Louis Duchemin
Browse files

Implements toolbox.Result_table.to_file

parent 85b9a22e
open Core_kernel open Core_kernel
type t = { type t = {
oracle : bool array option ; oracle : bool array option;
scores_per_meth : (string * float option array) list ; scores_per_meth : (string * float option array) list;
} }
(* invariant: all columns have the same length *)
let of_file fn = let of_file fn =
match match
In_channel.read_lines fn In_channel.read_lines fn
...@@ -13,35 +15,73 @@ let of_file fn = ...@@ -13,35 +15,73 @@ let of_file fn =
with with
| None -> failwith "Variable number of fields" | None -> failwith "Variable number of fields"
| Some cols -> | Some cols ->
let cols = List.map cols ~f:(function let cols =
| [] -> assert false List.map cols ~f:(function [] -> assert false | h :: t -> (h, t))
| h :: t -> h, t in
) let oracle =
in List.Assoc.find cols "Oracle" ~equal:String.equal
let oracle = |> Option.map
List.Assoc.find cols "Oracle" ~equal:String.equal ~f:
|> Option.map ~f:( (List.map ~f:(function
List.map ~f:(function | "0" -> false
| "0" -> false | "1" -> true
| "1" -> true | _ -> failwith "Unexpected element in oracle column"))
| _ -> failwith "Unexpected element in oracle column" |> Option.map ~f:Array.of_list
) in
) let scores_per_meth =
|> Option.map ~f:Array.of_list List.filter_map cols ~f:(fun (label, values) ->
in if String.(label <> "Oracle" && label <> "Sites") then
let scores_per_meth = let values =
List.filter_map cols ~f:(fun (label, values) -> List.map values ~f:(function
if String.(label <> "Oracle" && label <> "Sites") then | "NA" -> None
let values = | x -> Some (Float.of_string x))
List.map values ~f:( |> Array.of_list
function in
| "NA" -> None Some (label, values)
| x -> Some (Float.of_string x) else None)
) in
|> Array.of_list { oracle; scores_per_meth }
in
Some (label, values) let nrows results =
else None match results.oracle with
) | Some oracle -> Array.length oracle
in | None -> (
{ oracle ; scores_per_meth } 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)
(** Format that is expected for the output of a detection method *) (** Format that is expected for the output of a detection method *)
type t = { type t = {
oracle : bool array option ; oracle : bool array option;
scores_per_meth : (string * float option array) list ; scores_per_meth : (string * float option array) list;
} }
val of_file : string -> t val of_file : string -> t
val to_file : t -> output:string -> unit
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment