#include "pilercr.h" #include #define TRACE 0 extern void Align_Recursion(char *A, int Alen, char *B, int Blen, Trapezoid *b, int current, int comp, int MinLen, double MaxDiff, int Traplen); extern int TSORT(const void *l, const void *r); extern int StSORT(const void *l, const void *r); extern int FnSORT(const void *l, const void *r); // Sort by Lo bool Cmp_Lo(const DPHit &Hit1, const DPHit &Hit2) { if (Hit1.aLo < Hit2.aLo) return true; return false; } // Sort by Hi bool Cmp_Hi(const DPHit &Hit1, const DPHit &Hit2) { if (Hit1.aHi < Hit2.aHi) return true; return false; } // shared with aligntraps.cpp Trapezoid **Tarray = NULL; int *Covered; int SegMax = -1; static int fseg; static int TarMax = -1; void AlignTraps(char *A, int Alen, char *B, int Blen, Trapezoid *Traplist, int Traplen, int comp, const DPParams &DP) { Tarray = NULL; Covered = 0; SegMax = -1; fseg = 0; TarMax = -1; Progress("Initializing trapezoid alignment"); const int MinLen = DP.g_MinHitLength; const double MaxDiff = 1.0 - DP.MinId; Trapezoid *b; int i; if (Traplen >= TarMax) { TarMax = (int) (1.2*Traplen + 500); Tarray = (Trapezoid **) ckrealloc(Tarray,(sizeof(Trapezoid *) + sizeof(int))*TarMax,"Trapezoid array"); Covered = (int *) (Tarray + TarMax); } // Arbitrary number to avoid thrashing g_Hits.reserve(10000); i = 0; b = Traplist; for (i = 0; i < Traplen; i++) { Tarray[i] = b; Covered[i] = 0; if (b == 0) { Traplen = i; Warning("Internal problem: in AlignTraps, b=0, truncating list"); break; } b = b->next; } qsort(Tarray,Traplen,sizeof(Trapezoid *),TSORT); #ifdef SHOW_TRAP { int i; Trapezoid *t; for (i = 0; i < Traplen; i++) { t = Tarray[i]; printf(" [%d,%d] x [%d,%d]\n",t->bot,t->top,t->lft,t->rgt); } } #endif #ifdef REPORT_DPREACH Al_depth = 0; #endif g_HitCount = 0; fseg = g_HitCount; ProgressStart("Aligning trapezoids"); int Step = Traplen/50; if (Step == 0) Step = 1; for (i = 0; i < Traplen; i++) { if (i%Step == 0) ProgressStep(i, Traplen); if (! Covered[i]) { b = Tarray[i]; if (b->top - b->bot < k) continue; #if TRACE Log("Align trap %d,%d - %d,%d\n", b->lft, b->top, b->rgt, b->top); #endif if (b->lft < g_MinDiag) continue; Align_Recursion(A,Alen,B,Blen,b,i,comp,MinLen,MaxDiff,Traplen); } } ProgressDone(); /* Remove lower scoring segments that begin or end at the same point as a higher scoring segment. */ Progress("Removing redundant hits"); if (g_HitCount > fseg) { int i, j; // qsort(g_Hits+fseg,g_HitCount-fseg,sizeof(DPHit),StSORT); std::vector::iterator pFrom = g_Hits.begin(); std::vector::iterator pTo = g_Hits.begin(); pFrom += fseg; pTo -= fseg; std::sort(pFrom, pTo, Cmp_Lo); for (i = fseg; i < g_HitCount; i = j) { for (j = i+1; j < g_HitCount; j++) { if (g_Hits[j].aLo != g_Hits[i].aLo) break; if (g_Hits[j].bLo != g_Hits[i].bLo) break; if (g_Hits[j].score > g_Hits[i].score) { g_Hits[i].score = -1; i = j; } else g_Hits[j].score = -1; } } std::sort(pFrom, pTo, Cmp_Hi); // qsort(g_Hits+fseg,g_HitCount-fseg,sizeof(DPHit),FnSORT); for (i = fseg; i < g_HitCount; i = j) { for (j = i+1; j < g_HitCount; j++) { if (g_Hits[j].aHi != g_Hits[i].aHi) break; if (g_Hits[j].bHi != g_Hits[i].bHi) break; if (g_Hits[j].score > g_Hits[i].score) { g_Hits[i].score = -1; i = j; } else g_Hits[j].score = -1; } } for (i = fseg; i < g_HitCount; i++) if (g_Hits[i].score >= 0) g_Hits[fseg++] = g_Hits[i]; g_HitCount = fseg; } #ifdef REPORT_SIZES printf("\n %9d segments\n",g_HitCount); fflush(stdout); #endif free(Tarray); Tarray = 0; g_HitCount = (int) g_Hits.size(); } int SumDPLengths(const DPHit *DPHits, int HitCount) { int Sum = 0; for (int i = 0; i < HitCount; ++i) { const DPHit &Hit = DPHits[i]; const int Length = Hit.aHi - Hit.aLo; if (Length < 0) Quit("SumDPLengths, Length < 0"); Sum += Length; } return Sum; }