/* * searchPath.c * * Copyright (c) 2008-2016 Ruibang Luo . * * This file is part of SOAPdenovo. * * SOAPdenovo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SOAPdenovo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SOAPdenovo. If not, see . * */ #include "stdinc.h" #include "newhash.h" #include "kmerhash.h" #include "extfunc.h" #include "extvab.h" static int trace_limit = 5000; //the times function is called in a search /* search connection paths which were masked along related contigs start from one contig, end with another path length includes the length of the last contig */ void traceAlongMaskedCnt ( unsigned int destE, unsigned int currE, int max_steps, int min, int max, int index, int len, int *num_route ) { num_trace++; if ( num_trace > trace_limit || *num_route >= max_n_routes ) { return; } unsigned int *array; int num, i, length; CONNECT *ite_cnt; if ( index > 0 ) // there're at most max_steps edges stored in this array including the destination edge { length = len + contig_array[currE].length; } else { length = 0; } if ( index > max_steps || length > max ) { return; } // this is the only situation we stop if ( index > 0 ) // there're at most max_steps edges stored in this array including the destination edge { so_far[index - 1] = currE; } if ( currE == destE && index == 0 ) { fprintf ( stderr, "The traceAlongMaskedCnt: start and destination are the same.\n" ); return; } if ( currE == destE && length >= min && length <= max ) { num = *num_route; array = found_routes[num]; for ( i = 0; i < index; i++ ) { array[i] = so_far[i]; } if ( index < max_steps ) { array[index] = 0; } //indicate the end of the route *num_route = ++num; } // one route is extrated, but we don't terminate searching ite_cnt = contig_array[currE].downwardConnect; while ( ite_cnt ) { if ( !ite_cnt->mask || ite_cnt->deleted ) { ite_cnt = ite_cnt->next; continue; } traceAlongMaskedCnt ( destE, ite_cnt->contigID, max_steps, min, max, index + 1, length + ite_cnt->gapLen, num_route ); ite_cnt = ite_cnt->next; } } // search connection paths from one connect to a contig // path length includes the length of the last contig void traceAlongConnect ( unsigned int destE, CONNECT *currCNT, int max_steps, int min, int max, int index, int len, int *num_route ) { num_trace++; if ( num_trace > trace_limit || *num_route >= max_n_routes ) { return; } unsigned int *array, currE; int num, i, length; CONNECT *ite_cnt; currE = currCNT->contigID; length = len + currCNT->gapLen; length += contig_array[currE].length; if ( index > max_steps || length > max ) { return; } // this is the only situation we stop /* if(globalFlag) printf("B: step %d, ctg %d, length %d\n",index,currCNT->contigID,length); */ if ( currE == destE && index == 1 ) { fprintf ( stderr, "The traceAlongConnect: start and destination are the same.\n" ); return; } so_far[index - 1] = currE; // there're at most max_steps edges stored in this array including the destination edge if ( currE == destE && length >= min && length <= max ) { num = *num_route; array = found_routes[num]; for ( i = 0; i < index; i++ ) { array[i] = so_far[i]; } if ( index < max_steps ) { array[index] = 0; } //indicate the end of the route *num_route = ++num; } // one route is extrated, but we don't terminate searching if ( currCNT->nextInScaf ) { traceAlongConnect ( destE, currCNT->nextInScaf, max_steps, min, max, index + 1, length, num_route ); return; } ite_cnt = contig_array[currE].downwardConnect; while ( ite_cnt ) { if ( ite_cnt->mask || ite_cnt->deleted ) { ite_cnt = ite_cnt->next; continue; } traceAlongConnect ( destE, ite_cnt, max_steps, min, max, index + 1, length, num_route ); ite_cnt = ite_cnt->next; } } //find paths in the graph from currE to destE, its length does not include length of both end contigs void traceAlongArc ( unsigned int destE, unsigned int currE, int max_steps, int min, int max, int index, int len, int *num_route ) { num_trace++; if ( num_trace > trace_limit || *num_route >= max_n_routes ) { return; } unsigned int *array, out_ed, vt; int num, i, pos, length; preARC *parc; pos = index; if ( pos > max_steps || len > max ) { return; } // this is the only situation we stop if ( currE == destE && pos == 0 ) { fprintf ( stderr, "The traceAlongArc: start and destination are the same.\n" ); return; } if ( pos > 0 ) // pos starts with 0 for the starting edge { so_far[pos - 1] = currE; } // there're at most max_steps edges stored in this array including the destination edge if ( currE == destE && len >= min ) { num = *num_route; array = found_routes[num]; for ( i = 0; i < pos; i++ ) { array[i] = so_far[i]; } if ( pos < max_steps ) { array[pos] = 0; } //indicate the end of the route *num_route = ++num; } // one route is extrated, but we don't terminate searching if ( pos == max_steps || len == max ) { return; } if ( pos++ > 0 ) //not the starting edge { length = len + contig_array[currE].length; } else { length = len; } vt = contig_array[currE].to_vt; parc = contig_array[currE].arcs; while ( parc ) { out_ed = parc->to_ed; traceAlongArc ( destE, out_ed, max_steps, min, max, pos, length, num_route ); parc = parc->next; } }