///|
fn quality_bool_points(value : Bool, points : Int) -> Int {
if value {
points
} else {
0
}
}
///|
fn annotation_has_attributes(annotation : Annotation) -> Bool {
for feature in annotation.features {
if feature.attributes.length() > 0 {
return true
}
}
false
}
///|
fn annotation_has_hierarchy(annotation : Annotation) -> Bool {
let models = annotation.to_gene_models()
if models.length() == 0 {
false
} else {
for gene in models {
if gene.transcripts.length() > 0 {
for tx in gene.transcripts {
if tx.exons.length() > 0 {
return true
}
}
}
}
false
}
}
///|
fn quality_score(
metrics : AnnotationMetrics,
report : ValidationReport,
has_required_hierarchy : Bool,
has_attributes : Bool,
has_multiple_seqids : Bool,
) -> Int {
let mut score = 0
score += quality_bool_points(metrics.feature_count > 0, 10)
score += quality_bool_points(metrics.gene_count > 0, 15)
score += quality_bool_points(metrics.transcript_count > 0, 15)
score += quality_bool_points(metrics.exon_count > 0, 15)
score += quality_bool_points(has_required_hierarchy, 20)
score += quality_bool_points(has_attributes, 10)
score += quality_bool_points(has_multiple_seqids, 5)
score -= report.error_count() * 20
score -= report.warning_count() * 5
if score < 0 {
0
} else if score > 100 {
100
} else {
score
}
}
///|
pub fn Annotation::quality_report(self : Annotation) -> QualityReport {
let metrics = self.metrics()
let validation = self.validate()
let has_required_hierarchy = annotation_has_hierarchy(self)
let has_attributes = annotation_has_attributes(self)
let has_multiple_seqids = metrics.seqid_count > 1
{
score: quality_score(
metrics, validation, has_required_hierarchy, has_attributes, has_multiple_seqids,
),
feature_count: metrics.feature_count,
gene_count: metrics.gene_count,
transcript_count: metrics.transcript_count,
exon_count: metrics.exon_count,
validation_errors: validation.error_count(),
validation_warnings: validation.warning_count(),
has_required_hierarchy,
has_attributes,
has_multiple_seqids,
}
}
///|
pub fn QualityReport::grade(self : QualityReport) -> String {
if self.score >= 90 {
"A"
} else if self.score >= 75 {
"B"
} else if self.score >= 60 {
"C"
} else if self.score >= 40 {
"D"
} else {
"F"
}
}
///|
pub fn QualityReport::to_text(self : QualityReport) -> String {
[
"score\t\{self.score}",
"grade\t\{self.grade()}",
"features\t\{self.feature_count}",
"genes\t\{self.gene_count}",
"transcripts\t\{self.transcript_count}",
"exons\t\{self.exon_count}",
"validation_errors\t\{self.validation_errors}",
"validation_warnings\t\{self.validation_warnings}",
"has_required_hierarchy\t\{self.has_required_hierarchy}",
"has_attributes\t\{self.has_attributes}",
"has_multiple_seqids\t\{self.has_multiple_seqids}",
].join("\n") +
"\n"
}