#include "pilercr.h" #include #include unsigned char CompChar[256]; int CharToLetter[256]; static void InitCharToLetter() { for (int i = 0; i < 256; ++i) CharToLetter[i] = 4; CharToLetter['A'] = 0; CharToLetter['a'] = 0; CharToLetter['C'] = 1; CharToLetter['c'] = 1; CharToLetter['G'] = 2; CharToLetter['g'] = 2; CharToLetter['T'] = 3; CharToLetter['t'] = 3; } static void InitCompChar() { for (unsigned i = 0; i < 256; ++i) CompChar[i] = (unsigned char) i; CompChar['a'] = 't'; CompChar['c'] = 'g'; CompChar['g'] = 'c'; CompChar['t'] = 'a'; CompChar['n'] = 'n'; CompChar['A'] = 'T'; CompChar['C'] = 'G'; CompChar['G'] = 'C'; CompChar['T'] = 'A'; } static bool InitUtils() { InitCompChar(); InitCharToLetter(); return true; } static bool UtilsInitialized = InitUtils(); char *strsave(const char *s) { if (0 == s) return 0; char *ptrCopy = strdup(s); if (0 == ptrCopy) Quit("Out of memory"); return ptrCopy; } static char *StdioStrMode(FILEIO_MODE Mode) { switch (Mode) { case FILEIO_MODE_ReadOnly: return FILIO_STRMODE_ReadOnly; case FILEIO_MODE_WriteOnly: return FILIO_STRMODE_WriteOnly; case FILEIO_MODE_ReadWrite: return FILIO_STRMODE_ReadWrite; } Quit("StdioStrMode: Invalid mode"); return "r"; } FILE *OpenStdioFile(const char *FileName, FILEIO_MODE Mode) { char *strMode = StdioStrMode(Mode); FILE *f = fopen(FileName, strMode); if (0 == f) Quit("Cannot open %s, %s [%d]", FileName, strerror(errno), errno); return f; } FILE *CreateStdioFile(const char *FileName) { FILE *f = fopen(FileName, "wb+"); if (0 == f) Quit("Cannot open %s, %s [%d]", FileName, strerror(errno), errno); return f; } int GetFileSize(FILE *f) { long CurrPos = ftell(f); if (CurrPos < 0) Quit("FileSize: ftell<0 (CurrPos), errno=%d", errno); int Ok = fseek(f, 0, SEEK_END); if (Ok != 0) Quit("FileSize fseek(END) != 0 errno=%d", errno); long Size = ftell(f); if (Size < 0) Quit("FileSize: ftell<0 (size), errno=%d", errno); Ok = fseek(f, CurrPos, SEEK_SET); if (Ok != 0) Quit("FileSize fseek(restore curr pos) != 0 errno=%d", errno); long NewPos = ftell(f); if (CurrPos < 0) Quit("FileSize: ftell=%ld != CurrPos=%ld", CurrPos, NewPos); return (int) Size; } // 4^n int pow4(int n) { assert(n >= 0 && n < 16); return (1 << (2*n)); } // 4^d, but much less likely to under or overflow double pow4d(int n) { return pow(4.0, n); } double log4(double x) { static double LOG4 = log(4.0); return log(x)/LOG4; } // Ukonnen's Lemma int MinWordsPerFilterHit(int HitLength, int WordLength, int MaxErrors) { return HitLength + 1 - WordLength*(MaxErrors + 1); } int StringToCode(const char s[], int len) { int code = 0; for (int i = 0; i < len; ++i) { char c = s[i]; switch (c) { case 'a': case 'A': code <<= 2; code |= 0x00; break; case 'c': case 'C': code <<= 2; code |= 0x01; break; case 'g': case 'G': code <<= 2; code |= 0x02; break; case 't': case 'T': code <<= 2; code |= 0x03; break; default: return -1; } } return code; } char *CodeToString(int code, int len) { static char Str[100]; static char Symbol[] = { 'A', 'C', 'G', 'T' }; int i; assert(len < sizeof(Str)); Str[len] = 0; for (i = len-1; i >= 0; --i) { Str[i] = Symbol[code & 0x3]; code >>= 2; } return Str; } void *ckalloc(int size, const char *where) { void *p; p = malloc(size); if (p == NULL) Quit("Out of memory (ckalloc)"); return (p); } void *ckrealloc(void *p, int size, const char *where) { p = realloc(p,size); if (p == NULL) Quit("Out of memory (ckrealloc)"); return (p); } int RevCompKmer(int Kmer) { // Log("Kmer=%s", CodeToString(Kmer, k)); int RCKmer = 0; for (int i = 0; i < k; ++i) { int x = Kmer & 3; int cx = 3 - x; int shift = 2*(k - i - 1); RCKmer |= (cx << shift); Kmer >>= 2; } // Log(" Comp=%s\n", CodeToString(RCKmer, k)); return RCKmer; } int GetHitLength(const DPHit &Hit) { assert(Hit.aHi >= Hit.aLo); // Plus only assert(Hit.bHi >= Hit.bLo); return (Hit.aHi - Hit.aLo + 1 + Hit.bHi - Hit.bLo + 1)/2; } int GetSpacerLength(const DPHit &Hit) { assert(Hit.aHi >= Hit.aLo); // Plus only assert(Hit.bHi >= Hit.bLo); return Hit.bLo - Hit.aHi; } int GetOverlap(unsigned lo1, unsigned hi1, unsigned lo2, unsigned hi2) { int maxlo = std::max(lo1, lo2); int minhi = std::min(hi1, hi2); if (maxlo > minhi) return 0; return minhi - maxlo + 1; } double GetRatio(int x, int y) { if (x == 0 && y == 0) return 0; if (x < y) return (double) x / (double) y; else return (double) y / (double) x; } int GetPileLength(const PileData &Pile) { return Pile.Hi - Pile.Lo + 1; } int GetSpacerLength(const PileData &Pile1, const PileData &Pile2) { assert(Pile2.Lo >= Pile1.Hi); return Pile2.Lo - Pile1.Hi; } void DeletePile(int PileIndex) { assert(PileIndex >= 0 && PileIndex < g_PileCount); g_Piles[PileIndex].Deleted = true; } const ImageData &GetImage(int ImageIndex) { assert(ImageIndex >= 0 && ImageIndex < g_ImageCount); return g_Images[ImageIndex]; } const DPHit &GetHit(int HitIndex) { assert(HitIndex >= 0 && HitIndex < g_HitCount); return g_Hits[HitIndex]; } const PileData &GetPile(int PileIndex) { assert(PileIndex >= 0 && PileIndex < g_PileCount); return g_Piles[PileIndex]; } PileData &GetModifiablePile(int PileIndex) { assert(PileIndex >= 0 && PileIndex < g_PileCount); return g_Piles[PileIndex]; } DPHit &GetModifiableHit(int HitIndex) { assert(HitIndex >= 0 && HitIndex < g_HitCount); return g_Hits[HitIndex]; } int GetHitLength(int ImageIndex) { const ImageData &Image = GetImage(ImageIndex); const DPHit &Hit = GetHit(Image.HitIndex); return GetHitLength(Hit); } int GetSpacerLengthFromImage(int ImageIndex) { const ImageData &Image = GetImage(ImageIndex); const DPHit &Hit = GetHit(Image.HitIndex); return GetSpacerLength(Hit); } int GetOverlap(const ImageData &Image1, const ImageData &Image2) { return GetOverlap(Image1.Lo, Image1.Hi, Image2.Lo, Image2.Hi); } void LogHit(const DPHit &Hit) { Log("pos1=%d pos2=%d hitlen=%d space=%d", Hit.aLo, Hit.bLo, GetHitLength(Hit), GetSpacerLength(Hit)); } void LogHit(int HitIndex) { const DPHit &Hit = GetHit(HitIndex); Log("Hit%d ", HitIndex); LogHit(Hit); if (IsDeletedHit(HitIndex)) Log(" DEL"); } bool IsDeletedHit(int HitIndex) { assert(HitIndex >= 0 && HitIndex < g_HitCount); const DPHit &Hit = g_Hits[HitIndex]; if (Hit.Deleted) return true; if (g_PileCount > 0) { int PileIndex = g_HitIndexToPileIndexA[HitIndex]; const PileData &Pile = GetPile(PileIndex); if (Pile.Deleted) return true; } return false; } void DeleteHit(int HitIndex) { assert(HitIndex >= 0 && HitIndex < g_HitCount); DPHit &Hit = g_Hits[HitIndex]; Hit.Deleted = true; int PileIndex = g_HitIndexToPileIndexA[HitIndex]; PileData &Pile = GetModifiablePile(PileIndex); Pile.Deleted = true; }