///|
pub fn pipeline_map(
document : VcfDocument,
transform : (VcfRecord) -> VcfRecord,
) -> VcfDocument {
{ header: document.header, records: document.records.map(transform) }
}
///|
pub fn pipeline_filter(
document : VcfDocument,
keep : (VcfRecord) -> Bool,
) -> VcfDocument {
{ header: document.header, records: document.records.filter(keep) }
}
///|
pub fn pipeline_take(document : VcfDocument, count : Int) -> VcfDocument {
{
header: document.header,
records: if count <= 0 {
[]
} else {
document.records[:min_pipeline(count, document.records.length())].to_owned()
},
}
}
///|
pub fn pipeline_drop(document : VcfDocument, count : Int) -> VcfDocument {
{
header: document.header,
records: if count <= 0 {
document.records
} else if count >= document.records.length() {
[]
} else {
document.records[count:].to_owned()
},
}
}
///|
pub fn pipeline_limit_by_contig(
document : VcfDocument,
chrom : String,
) -> VcfDocument {
pipeline_filter(document, fn(record) { record.chrom == chrom })
}
///|
pub fn pipeline_limit_by_interval(
document : VcfDocument,
chrom : String,
interval : GenomicInterval?,
) -> VcfDocument {
pipeline_filter(document, fn(record) {
record.chrom == chrom && interval_contains(interval, record.pos)
})
}
///|
pub fn pipeline_sort(document : VcfDocument) -> VcfDocument {
{ header: document.header, records: sort_records(document.records) }
}
///|
pub fn pipeline_dedupe(document : VcfDocument) -> VcfDocument {
let records : Array[VcfRecord] = []
let keys : Array[String] = []
for record in document.records {
let key = record_key(record)
if !pipeline_contains(keys, key) {
keys.push(key)
records.push(record)
}
}
{ header: document.header, records }
}
///|
pub fn pipeline_concat(documents : Array[VcfDocument]) -> VcfDocument? {
if documents.length() == 0 {
None
} else {
let first = documents[0]
let records : Array[VcfRecord] = []
for document in documents {
if document.header == first.header {
for record in document.records {
records.push(record)
}
} else {
return None
}
}
Some({ header: first.header, records })
}
}
///|
pub fn pipeline_split_by_filter(
document : VcfDocument,
filter : String,
) -> (VcfDocument, VcfDocument) {
let yes : Array[VcfRecord] = []
let no : Array[VcfRecord] = []
for record in document.records {
if record.filters.contains(filter) {
yes.push(record)
} else {
no.push(record)
}
}
(
{ header: document.header, records: yes },
{ header: document.header, records: no },
)
}
///|
pub fn pipeline_split_by_qualification(
document : VcfDocument,
threshold : Double,
) -> (VcfDocument, VcfDocument) {
let yes : Array[VcfRecord] = []
let no : Array[VcfRecord] = []
for record in document.records {
match record.qual {
Some(value) if value >= threshold => yes.push(record)
_ => no.push(record)
}
}
(
{ header: document.header, records: yes },
{ header: document.header, records: no },
)
}
///|
pub fn pipeline_apply_normalization(document : VcfDocument) -> VcfDocument {
let records : Array[VcfRecord] = []
for record in document.records {
match normalize_record(record) {
Changed(value) | Unchanged(value) => records.push(value)
Invalid(_) => records.push(record)
}
}
{ header: document.header, records }
}
///|
pub fn pipeline_split_multiallelic(document : VcfDocument) -> VcfDocument {
let records : Array[VcfRecord] = []
for record in document.records {
for split in split_multi_allelic(record, header=document.header) {
records.push(split)
}
}
{ header: document.header, records }
}
///|
pub fn pipeline_project_info(
document : VcfDocument,
keys : Array[String],
) -> VcfDocument {
pipeline_map(document, fn(record) { select_info_fields(record, keys) })
}
///|
pub fn pipeline_project_samples(
document : VcfDocument,
names : Array[String],
) -> VcfDocument raise ParseError {
select_document_samples(document, names)
}
///|
pub fn pipeline_validate(
document : VcfDocument,
strict : Bool,
) -> ValidationReport {
validate_document(document, options=ValidationOptions::{ strict, })
}
///|
pub fn pipeline_stats(document : VcfDocument) -> VcfStats {
summarize(document)
}
///|
pub fn pipeline_count(document : VcfDocument) -> Int {
document.records.length()
}
///|
pub fn pipeline_is_empty(document : VcfDocument) -> Bool {
document.records.length() == 0
}
///|
pub fn pipeline_first(document : VcfDocument) -> VcfRecord? {
if document.records.length() == 0 {
None
} else {
Some(document.records[0])
}
}
///|
pub fn pipeline_last(document : VcfDocument) -> VcfRecord? {
if document.records.length() == 0 {
None
} else {
Some(document.records[document.records.length() - 1])
}
}
///|
pub fn pipeline_contigs(document : VcfDocument) -> Array[String] {
let names : Array[String] = []
for record in document.records {
if !pipeline_contains(names, record.chrom) {
names.push(record.chrom)
}
}
names
}
///|
pub fn pipeline_filters(document : VcfDocument) -> Array[String] {
let names : Array[String] = []
for record in document.records {
for filter in record.filters {
if !pipeline_contains(names, filter) {
names.push(filter)
}
}
}
names
}
///|
pub fn pipeline_info_keys(document : VcfDocument) -> Array[String] {
let names : Array[String] = []
for record in document.records {
for pair in record.info {
if !pipeline_contains(names, pair.0) {
names.push(pair.0)
}
}
}
names
}
///|
pub fn pipeline_record_counts_by_class(
document : VcfDocument,
) -> Array[(VariantClass, Int)] {
let counts : Array[(VariantClass, Int)] = []
for record in document.records {
let class = record_variant_class(record)
let mut found = false
for index, pair in counts {
if pair.0 == class {
counts[index] = (class, pair.1 + 1)
found = true
break
}
}
if !found {
counts.push((class, 1))
}
}
counts
}
///|
pub fn pipeline_pairwise(
left : VcfDocument,
right : VcfDocument,
) -> Array[RecordDiff] {
diff_documents(left, right)
}
///|
pub fn pipeline_merge(
left : VcfDocument,
right : VcfDocument,
) -> VcfDocument raise ParseError {
merge_documents(left, right)
}
///|
pub fn pipeline_query(
document : VcfDocument,
chrom : String,
start : Int,
end : Int,
) -> Array[VcfRecord] {
query_index(build_index(document), chrom, start, end)
}
///|
pub fn pipeline_format(document : VcfDocument) -> String {
format_document(document)
}
///|
pub fn pipeline_round_trip(
document : VcfDocument,
) -> VcfDocument raise ParseError {
parse_document(format_document(document))
}
///|
fn pipeline_contains(values : Array[String], wanted : String) -> Bool {
for value in values {
if value == wanted {
return true
}
}
false
}
///|
fn min_pipeline(left : Int, right : Int) -> Int {
if left < right {
left
} else {
right
}
}