#include "utils/commons.h"
#include "wavefront_debug.h"
#include "wavefront_align.h"
#include "wavefront_compute.h"
bool wavefront_check_alignment(
FILE* const stream,
wavefront_aligner_t* const wf_aligner) {
wavefront_sequences_t* const sequences = (wf_aligner->bialigner==NULL) ?
&wf_aligner->sequences : &wf_aligner->bialigner->wf_forward->sequences;
const char* const pattern = sequences->pattern_buffer;
const int pattern_length = sequences->pattern_buffer_length;
const char* const text = sequences->text_buffer;
const int text_length = sequences->text_buffer_length;
cigar_t* const cigar = wf_aligner->cigar;
char* const operations = cigar->operations;
const int begin_offset = cigar->begin_offset;
const int end_offset = cigar->end_offset;
bool alignment_correct = true;
int pattern_pos=0, text_pos=0, i;
for (i=begin_offset;i<end_offset;++i) {
switch (operations[i]) {
case 'M': {
if (sequences->mode != wf_sequences_lambda) {
const bool is_match = (pattern[pattern_pos]==text[text_pos]);
if (!is_match) {
fprintf(stream,"[WFA::Check] Alignment not matching (pattern[%d]=%c != text[%d]=%c)\n",
pattern_pos,pattern[pattern_pos],
text_pos,text[text_pos]);
alignment_correct = false;
break;
}
}
++pattern_pos;
++text_pos;
break;
}
case 'X': {
if (sequences->mode != wf_sequences_lambda) {
const bool is_match = (pattern[pattern_pos]==text[text_pos]);
if (is_match) {
fprintf(stream,"[WFA::Check] Alignment not mismatching (pattern[%d]=%c == text[%d]=%c)\n",
pattern_pos,pattern[pattern_pos],
text_pos,text[text_pos]);
alignment_correct = false;
break;
}
}
++pattern_pos;
++text_pos;
break;
}
case 'I':
++text_pos;
break;
case 'D':
++pattern_pos;
break;
default:
fprintf(stream,"[WFA::Check] Unknown edit operation '%c'\n",operations[i]);
exit(1);
break;
}
}
if (pattern_pos != pattern_length) {
fprintf(stream,
"[WFA::Check] Alignment incorrect length (pattern-aligned=%d,pattern-length=%d)\n",
pattern_pos,pattern_length);
alignment_correct = false;
}
if (text_pos != text_length) {
fprintf(stream,
"[WFA::Check] Alignment incorrect length (text-aligned=%d,text-length=%d)\n",
text_pos,text_length);
alignment_correct = false;
}
return alignment_correct;
}
void wavefront_report_lite(
FILE* const stream,
wavefront_aligner_t* const wf_aligner,
const bool alignment_completed) {
wavefront_sequences_t* const sequences = (wf_aligner->bialigner==NULL) ?
&wf_aligner->sequences : &wf_aligner->bialigner->wf_forward->sequences;
const char* const pattern = sequences->pattern;
const int pattern_length = sequences->pattern_length;
const char* const text = sequences->text;
const int text_length = sequences->text_length;
const int status = wf_aligner->align_status.status;
const uint64_t memory_used = wf_aligner->align_status.memory_used;
const bool has_cigar = alignment_completed && !cigar_is_null(wf_aligner->cigar);
if (alignment_completed) {
fprintf(stream,"[WFA::Debug]");
} else {
fprintf(stream,"[WFA::Debug::BEGIN]");
}
const int score = wf_aligner->cigar->score;
if (alignment_completed && score!=INT32_MIN) {
fprintf(stream,"\t%d",score);
if (has_cigar) {
const int edit_dist = cigar_score_edit(wf_aligner->cigar);
fprintf(stream,"/%1.2f",(float)edit_dist/(float)MAX(pattern_length,text_length));
}
} else {
fprintf(stream,"\t*");
}
fprintf(stream,"\t%d",pattern_length);
fprintf(stream,"\t%d",text_length);
fprintf(stream,"\t%s",wavefront_align_strerror_short(status));
if (alignment_completed) {
fprintf(stream,"\t%2.3f",TIMER_GET_TOTAL_MS(&wf_aligner->system.timer));
} else {
fprintf(stream,"\t-");
}
if (alignment_completed) {
fprintf(stream,"\t%luMB\t",CONVERT_B_TO_MB(memory_used));
} else {
fprintf(stream,"\t-\t");
}
fprintf(stream,"[");
wavefront_aligner_print_mode(stream,wf_aligner);
fprintf(stream,";");
wavefront_aligner_print_scope(stream,wf_aligner);
fprintf(stream,";");
wavefront_penalties_print(stream,&wf_aligner->penalties);
fprintf(stream,";");
wavefront_aligner_print_conf(stream,wf_aligner);
fprintf(stream,";");
wavefront_heuristic_print(stream,&wf_aligner->heuristic);
fprintf(stream,";");
fprintf(stream,"(%d,%d,%d)",
wf_aligner->wf_components.num_wavefronts,
wf_aligner->wf_components.historic_min_lo,
wf_aligner->wf_components.historic_max_hi);
fprintf(stream,"]\t");
if (!has_cigar) {
fprintf(stream,"-");
} else {
cigar_print(stream,wf_aligner->cigar,true);
}
if (sequences->mode == wf_sequences_lambda) {
fprintf(stream,"\t-\t-");
} else {
fprintf(stream,"\t%.*s\t%.*s",pattern_length,pattern,text_length,text);
}
fprintf(stream,"\n");
}
void wavefront_debug_begin(
wavefront_aligner_t* const wf_aligner) {
if (wf_aligner->system.verbose >= 1) {
timer_reset(&wf_aligner->system.timer);
timer_start(&wf_aligner->system.timer);
if (wf_aligner->system.verbose >= 4) {
wavefront_report_lite(stderr,wf_aligner,false);
}
}
}
void wavefront_debug_end(
wavefront_aligner_t* const wf_aligner) {
if (wf_aligner->system.verbose >= 1) {
timer_stop(&wf_aligner->system.timer);
wavefront_report_lite(stderr,wf_aligner,true);
}
}
void wavefront_debug_check_correct(
wavefront_aligner_t* const wf_aligner) {
if (wf_aligner->system.check_alignment_correct &&
wf_aligner->align_status.status == WF_STATUS_ALG_COMPLETED &&
wf_aligner->alignment_scope == compute_alignment) {
if (!wavefront_check_alignment(stderr,wf_aligner)) {
fprintf(stderr,"[WFA::Check] Error: Alignment incorrect\n");
exit(1);
}
}
}