let of_channel ?(chr_map=ident) ?(increment_bp=0) cin =
  let parse_line' delim line =
    match String.split line delim with
    | [c; i; f] ->
       chr_map c, int_of_string i + increment_bp, Float.of_string f
    | _ -> raise_bad "ill-formed line"
  in
  let parse_line line =
    try parse_line' '\t' line
    with Bad _ ->
      try parse_line' ' ' line
      with Bad msg -> failwith msg
  in
  In_channel.input_lines cin
  |! List.map ~f:parse_line