let alignment
?ref_seqs ?qname ~flags ?rname ?pos ?mapq ?(cigar=[])
?rnext ?pnext ?tlen ?seq ?(qual=[])
?(optional_fields=[])
()
=
[
(match ref_seqs, rname with
| (None,_) | (_,None) -> None
| Some ref_seqs, Some rname ->
if Set.mem ref_seqs rname then
None
else
Some (
Error.create
"RNAME not defined in any SQ line"
rname sexp_of_string
)
);
(match ref_seqs, rnext with
| (None,_) | (_,None) -> None
| Some _, Some `Equal_to_RNAME ->
None
| Some ref_seqs, Some (`Value rnext) ->
if Set.mem ref_seqs rnext then
None
else
Some (
Error.create
"RNEXT not defined in any SQ line"
rnext sexp_of_string
)
);
(match seq, qual with
| _, [] -> None
| None, _ ->
Some (Error.of_string "QUAL provided without SEQ")
| Some seq, _ ->
let s = String.length seq in
let q = List.length qual in
if s = q then
None
else
Some (Error.create
"SEQ and QUAL lengths differ"
(s, q) <:sexp_of< int * int >>
)
);
(
List.map optional_fields ~f:(fun x -> x.tag)
|> List.find_a_dup
|> Option.map ~f:(fun dup ->
Error.create "TAG occurs more than once" dup sexp_of_string)
);
]
|> List.filter_map ~f:Fn.id
|> function
| [] -> Ok {
qname; flags; rname; pos; mapq; cigar;
rnext; pnext; tlen; seq; qual; optional_fields
}
| errs -> Error (Error.of_list errs)