static void initNtChars() { static boolean initted = FALSE; if (!initted) { zeroBytes(ntChars, sizeof(ntChars)); ntChars['a'] = ntChars['A'] = 'a'; ntChars['c'] = ntChars['C'] = 'c'; ntChars['g'] = ntChars['G'] = 'g'; ntChars['t'] = ntChars['T'] = 't'; ntChars['n'] = ntChars['N'] = 'n'; ntChars['u'] = ntChars['U'] = 'u'; ntChars['-'] = 'n'; initted = TRUE; } }
void wormFaCommentIntoInfo(char *faComment, struct wormCdnaInfo *retInfo) /* Process line from .fa file containing information about cDNA into binary * structure. */ { if (retInfo) { char *s; zeroBytes(retInfo, sizeof(*retInfo)); /* Separate out first word and use it as name. */ s = strchr(faComment, ' '); if (s == NULL) errAbort("Expecting lots of info, just got %s", faComment); *s++ = 0; retInfo->name = faComment+1; retInfo->motherString = faComment; parseRestOfCdnaInfo(s, retInfo); } }
void flyFaCommentIntoInfo(char *faComment, struct wormCdnaInfo *retInfo) /* Process line from .fa file containing information about cDNA into binary * structure. */ { if (retInfo) { char *s; zeroBytes(retInfo, sizeof(*retInfo)); /* Separate out first word and use it as name. */ s = strchr(faComment, ' '); if (s != NULL) *s++ = 0; retInfo->name = faComment+1; retInfo->motherString = faComment; s = strrchr(retInfo->name, '.'); retInfo->orientation = '+'; if (s != NULL) retInfo->orientation = (s[1] == '3' ? '-' : '+'); } }
boolean internetIpToDottedQuad(bits32 ip, char dottedQuad[17]) /* Convert IP4 address in host byte order to dotted quad * notation. Warn and return FALSE if there's a * problem. */ { #ifndef __CYGWIN32__ struct in_addr ia; zeroBytes(dottedQuad, 17); ZeroVar(&ia); ia.s_addr = htonl(ip); if (inet_ntop(AF_INET, &ia, dottedQuad, 16) == NULL) { warn("conversion problem on 0x%x in internetIpToDottedQuad: %s", ip, strerror(errno)); return FALSE; } return TRUE; #else warn("Sorry, internetIpToDottedQuad not supported in Windows."); return FALSE; #endif }
void doOneAcc(char *acc, struct psl *pslList, int threshold, int trimSize, struct hash *probeHash, FILE *misAsm) /* Process alignments of one piece of mRNA. */ { struct psl *psl; int qSize; int *scoreTrack = NULL; int milliScore; int goodAliCount = 0; int i, start, end, size; struct probe *probe; struct psl *longestPsl = NULL; int longestBases = 0; int bases; boolean disordered = FALSE; int blockIx; if (pslList == NULL) return; qSize = pslList->qSize; AllocArray(scoreTrack, qSize+1); for (psl = pslList; psl != NULL; psl = psl->next) { bases = 0; milliScore = calcMilliScore(psl); if (milliScore >= threshold) { ++goodAliCount; bases = setScoreTrack(scoreTrack, qSize, milliScore, psl); } bases *= milliScore; if (bases > longestBases) { longestBases = bases; longestPsl = psl; } } /* Calculate size of trimmed aligning parts. */ start = trimSize; end = qSize - trimSize; size = 0; for (i=start; i<end; ++i) { if (scoreTrack[i] > 0) ++size; } probe = hashFindVal(probeHash, acc); if (probe != NULL) { probe->aliSize = size; /* Figure out if have any reversals. */ if (longestPsl != NULL) { int exonTrim = 10; /* Amount to trim from side of exons. */ probe->bestPsl = longestPsl; zeroBytes(scoreTrack, (qSize+1) * sizeof(scoreTrack[0])); setScoreTrack(scoreTrack, qSize, 1, longestPsl); for (psl = pslList; psl != NULL; psl = psl->next) { if (psl != longestPsl) { milliScore = calcMilliScore(psl); if (milliScore >= threshold) { int missCount = 0; for (blockIx = 0; blockIx < psl->blockCount; ++blockIx) { size = psl->blockSizes[blockIx]; start = psl->qStarts[blockIx]; end = start+size; if (psl->strand[0] == '-') { int s, e; s = psl->qSize - end; e = psl->qSize - start; start = s; end = e; } start += exonTrim; end -= exonTrim; if (start < end) { for (i=start; i<end; ++i) { if (!scoreTrack[i]) { ++missCount; } } } } if (missCount > 0) { if (!disordered) { fprintf(misAsm, "%s %s:%d-%d(%d%s%d)", psl->qName, longestPsl->tName, longestPsl->tStart, longestPsl->tEnd, longestPsl->qStart, longestPsl->strand, longestPsl->qEnd); disordered = TRUE; } fprintf(misAsm, " %s:%d-%d(%d%s%d)", psl->tName, psl->tStart, psl->tEnd, psl->qStart, psl->strand, psl->qEnd); } } } } if (disordered) fprintf(misAsm, "\n"); } probe->disordered = disordered; } else { warn("%s not found in in.lst file", acc); notFoundCount += 1; } freeMem(scoreTrack); }
void outputPicks(struct scoredWindow *winList, char *database, struct hash *chromLimitHash, struct stats *stats, FILE *f) /* Output picked regions. */ { struct scoredWindow *strata[strataCount][strataCount]; double geneCuts[strataCount], consCuts[strataCount]; struct scoredWindow *win, *next; int geneIx, consIx, pickIx; FILE *html = NULL; struct region *avoidList = NULL, *avoid; /* Get list of regions to avoid */ if (avoidFile != NULL) avoidList = loadRegionFile(database, avoidFile); if (htmlOutput != NULL) { html = mustOpen(htmlOutput, "w"); htmStart(html, "Random Regions for 1% Project"); } fprintf(f, "Cuts at:\n"); calcCuts(stats->consCounts, histSize, stats->totalConsCount, 1.0, consCuts, strataCount); uglyf("cons %f %f %f\n", consCuts[0], consCuts[1], consCuts[2]); fprintf(f, "cons %f %f %f\n", consCuts[0], consCuts[1], consCuts[2]); calcCuts(stats->geneCounts, histSize, stats->totalGeneCount, 1.0/geneScale, geneCuts, strataCount); uglyf("gene %f %f %f\n", geneCuts[0], geneCuts[1], geneCuts[2]); uglyf("gene %f %f %f\n", geneCuts[0], geneCuts[1], geneCuts[2]); fprintf(f, "\n"); /* Move winList to strata. */ zeroBytes(strata, sizeof(strata)); for (win = winList; win != NULL; win = next) { /* Calculate appropriate strata and move. */ next = win->next; consIx = cutIx(consCuts, strataCount, win->consRatio); geneIx = cutIx(geneCuts, strataCount, win->geneRatio); slAddHead(&strata[consIx][geneIx], win); } /* Shuffle strata and output first picks in each. */ srand(randSeed); for (consIx=strataCount-1; consIx>=0; --consIx) { for (geneIx=strataCount-1; geneIx>=0; --geneIx) { int cs=0, gs=0; if (geneIx>0) gs = round(100*genoCuts[geneIx-1]); if (consIx>0) cs = round(100*genoCuts[consIx-1]); fprintf(f, "consNonTx %d%%-%d%%, gene %d%%-%d%%\n", cs, round(100*genoCuts[consIx]), gs, round(100*genoCuts[geneIx])); if (html) { fprintf(html, "<H2>consNonTx %d%% - %d%%, gene %d%% - %d%%</H3>\n", cs, round(100*genoCuts[consIx]), gs, round(100*genoCuts[geneIx])); } shuffleList(&strata[consIx][geneIx]); pickIx = 0; for (win = strata[consIx][geneIx]; win != NULL; win = win->next) { int end = win->start + bigWinSize; if (!hitsRegions(win->chrom, win->start, end, avoidList)) { if (withinChromLimits(chromLimitHash, win->chrom)) { AllocVar(avoid); avoid->chrom = cloneString(win->chrom); avoid->start = win->start; avoid->end = end; slAddHead(&avoidList, avoid); fprintf(f, "%s:%d-%d\t", win->chrom, win->start+1, end); fprintf(f, "consNonTx %4.1f%%, gene %4.1f%%\n", 100*win->consRatio, 100*win->geneRatio); if (html) { fprintf(html, "<A HREF=\"http://genome.ucsc.edu/cgi-bin/"); fprintf(html, "hgTracks?db=%s&position=%s:%d-%d\">", database, win->chrom, win->start+1, end); fprintf(html, "%s:%d-%d</A>", win->chrom, win->start+1, end); fprintf(html, "\tconsNonTx %4.1f%%, gene %4.1f%%<BR>\n", 100*win->consRatio, 100*win->geneRatio); } if (++pickIx >= picksPer) break; } } } fprintf(f, "\n"); } } if (html) { htmEnd(html); carefulClose(&html); } }
void hgKnownMore(char *database, char *loc2ref, char *mim2loc, char *omimIds, char *nomeIds) /* hgKnownMore - Create the knownMore table from a variety of sources.. */ { struct hash *pgiHash = NULL; /* Hash of rsInfo indexed by gi. */ struct hash *locHash = NULL; /* Hash of rsInfo indexed by locusLink IDs. */ struct rsInfo *rs; struct hash *hmOmimHash = NULL, *hmSymbolHash = NULL; struct hash *mimHash = NULL; struct hugoMulti *hmList = NULL, *hm; struct hash *nameOmimHash = NULL, *omimNameHash = NULL; struct nameOmim *nameOmimList = NULL, *nameOmim; struct knownInfo *kiList = NULL, *ki; struct knownMore km; struct sqlConnection *conn; char *tabName = "knownMore.tab"; FILE *f = NULL; char *omimIdString = NULL; char query[256]; readLoc2ref(loc2ref, &pgiHash, &locHash); readMim(mim2loc, &mimHash); readHugoMultiTable(nomeIds, &hmList, &hmOmimHash, &hmSymbolHash); printf("Read %d elements in %s\n", slCount(hmList), nomeIds); readNameOmim(omimIds, &nameOmimList, &nameOmimHash, &omimNameHash); printf("Read %d elements in %s\n", slCount(nameOmimList), omimIds); conn = sqlConnect(database); kiList = loadKnownInfo(conn); printf("Read %d elements from knownInfo table in %s\n", slCount(kiList), database); printf("Writing %s\n", tabName); f = mustOpen(tabName, "w"); for (ki = kiList; ki != NULL; ki = ki->next) { /* Fill out a knownMore data structure. Start with all zero * just to avoid garbage. */ zeroBytes(&km, sizeof(km)); /* First fields come from knownInfo generally. */ km.name = ki->name; /* The name displayed in the browser: OMIM, gbGeneName, or transId */ km.transId = ki->transId; /* Transcript id. Genie generated ID. */ km.geneId = ki->geneId; /* Gene (not transcript) Genie ID */ km.gbGeneName = ki->geneName; /* Connect to geneName table. Genbank gene name */ km.gbProductName = ki->productName; /* Connects to productName table. Genbank product name */ km.gbProteinAcc = ki->proteinId; /* Genbank accession of protein */ km.gbNgi = ki->ngi; /* Genbank gi of nucleotide seq. */ km.gbPgi = ki->pgi; /* Genbank gi of protein seq. */ /* Fill in rest with acceptable values for no-data-present. */ km.omimId = 0; /* OMIM ID or 0 if none */ km.omimName = ""; /* OMIM primary name */ km.hugoId = 0; /* HUGO Nomeclature Committee ID or 0 if none */ km.hugoSymbol = ""; /* HUGO short name */ km.hugoName = ""; /* HUGO descriptive name */ km.hugoMap = ""; /* HUGO Map position */ km.pmId1 = 0; /* I have no idea - grabbed from a HUGO nomeids.txt */ km.pmId2 = 0; /* Likewise, I have no idea */ km.refSeqAcc = ""; /* Accession of RefSeq mRNA */ km.aliases = ""; /* Aliases if any. Comma and space separated list */ km.locusLinkId = 0; /* Locus link ID */ km.gdbId = ""; /* NCBI GDB database ID */ /* See if it's a disease gene with extra info. */ omimIdString = NULL; rs = hashFindVal(pgiHash, km.gbPgi); if (rs != NULL && rs->locusLinkId != NULL) { km.locusLinkId = atoi(rs->locusLinkId); omimIdString = hashFindVal(mimHash, rs->locusLinkId); } if (rs != NULL && rs->mrnaAcc != NULL) km.refSeqAcc = rs->mrnaAcc; if (omimIdString != NULL) { km.omimId = atoi(omimIdString); /* OMIM ID or 0 if none */ nameOmim = hashFindVal(omimNameHash, omimIdString); if (nameOmim != NULL) { km.name = km.omimName = nameOmim->name; } hm = hashFindVal(hmOmimHash, omimIdString); if (hm != NULL) { km.hugoId = hm->hgnc; /* HUGO Nomeclature Committee ID or 0 if none */ km.name = km.hugoSymbol = hm->symbol; /* HUGO short name */ km.hugoName = hm->name; /* HUGO descriptive name */ km.hugoMap = hm->map; /* HUGO Map position */ km.pmId1 = hm->pmId1; /* I have no idea - grabbed from a HUGO nomeids.txt */ km.pmId2 = hm->pmId2; /* Likewise, I have no idea */ km.refSeqAcc = hm->refSeqAcc; /* Accession of RefSeq mRNA */ km.aliases = hm->aliases; /* Aliases if any. Comma and space separated list */ km.locusLinkId = hm->locusLinkId; /* Locus link ID */ km.gdbId = hm->gdbId; /* NCBI GDB database ID */ } } knownMoreTabOut(&km, f); } carefulClose(&f); printf("Loading database %s\n", database); sqlUpdate(conn, "NOSQLINJ delete from knownMore"); sqlSafef(query, sizeof query, "load data local infile '%s' into table knownMore", tabName); sqlUpdate(conn, query); sqlDisconnect(&conn); }
int ffShAliPart(FILE *f, struct ffAli *aliList, char *needleName, DNA *needle, int needleSize, int needleNumOffset, char *haystackName, DNA *haystack, int haySize, int hayNumOffset, int blockMaxGap, boolean rcNeedle, boolean rcHaystack, boolean showJumpTable, boolean showNeedle, boolean showHaystack, boolean showSideBySide, boolean upcMatch, int cdsS, int cdsE, int hayPartS, int hayPartE) /* Display parts of alignment on html page. If hayPartS..hayPartE is a * smaller subrange of the alignment, highlight that part of the alignment * in both needle and haystack with underline & bold, and show only that * part of the haystack (plus padding). Returns number of blocks (after * merging blocks separated by blockMaxGap or less). */ { long i; struct ffAli *ali; struct ffAli *lastAli; struct ffAli *leftAli = aliList; struct ffAli *rightAli = aliList; int maxSize = (needleSize > haySize ? needleSize : haySize); char *colorFlags = needMem(maxSize); int anchorCount = 0; boolean restrictToWindow = FALSE; int hayOffStart = 0, hayOffEnd = haySize; int hayPaddedOffStart = 0, hayPaddedOffEnd = haySize; int hayExtremity = rcHaystack ? (hayNumOffset + haySize) : hayNumOffset; int nPartS=0, nPartE=0; if (aliList != NULL) { while (leftAli->left != NULL) leftAli = leftAli->left; while (rightAli->right != NULL) rightAli = rightAli->right; } /* If we are only showing part of the alignment, translate haystack window * coords to needle window coords and haystack-offset window coords: */ if (hayPartS > (hayNumOffset + (leftAli->hStart - haystack)) || (hayPartE > 0 && hayPartE < (hayNumOffset + (rightAli->hEnd - haystack)))) { DNA *haystackPartS; DNA *haystackPartE; restrictToWindow = TRUE; if (rcHaystack) { haystackPartS = haystack + (haySize - (hayPartE - hayNumOffset)); haystackPartE = haystack + (haySize - (hayPartS - hayNumOffset)); } else { haystackPartS = haystack + hayPartS - hayNumOffset; haystackPartE = haystack + hayPartE - hayNumOffset; } boolean foundStart = FALSE; hayOffStart = haystackPartS - haystack; hayOffEnd = haystackPartE - haystack; for (ali = leftAli; ali != NULL; ali = ali->right) { if (haystackPartS < ali->hEnd && !foundStart) { int offset = haystackPartS - ali->hStart; if (offset < 0) offset = 0; nPartS = offset + ali->nStart - needle; hayOffStart = offset + ali->hStart - haystack; foundStart = TRUE; } if (haystackPartE > ali->hStart) { if (haystackPartE > ali->hEnd) { nPartE = ali->nEnd - needle; hayOffEnd = ali->hEnd - haystack; } else { nPartE = haystackPartE - ali->hStart + ali->nStart - needle; hayOffEnd = haystackPartE - haystack; } } } hayPaddedOffStart = max(0, (hayOffStart - 100)); hayPaddedOffEnd = min(haySize, (hayOffEnd + 100)); if (rcHaystack) hayExtremity = hayNumOffset + haySize - hayPaddedOffStart; else hayExtremity = hayNumOffset + hayPaddedOffStart; } if (showJumpTable) { fputs("<CENTER><P><TABLE BORDER=1 WIDTH=\"97%\"><TR>", f); fputs("<TD WIDTH=\"23%\"><P ALIGN=CENTER><A HREF=\"#cDNA\">cDNA Sequence</A></TD>", f); if (restrictToWindow) fputs("<TD WIDTH=\"23%\"><P ALIGN=CENTER><A HREF=\"#cDNAStart\">cDNA Sequence in window</A></TD>", f); fputs("<TD WIDTH=\"27%\"><P ALIGN=\"CENTER\"><A HREF=\"#genomic\">Genomic Sequence</A></TD>", f); fputs("<TD WIDTH=\"29%\"><P ALIGN=\"CENTER\"><A HREF=\"#1\">cDNA in Genomic</A></TD>", f); fputs("<TD WIDTH=\"21%\"><P ALIGN=\"CENTER\"><A HREF=\"#ali\">Side by Side</A></TD>", f); fputs("</TR></TABLE>\n", f); } if (cdsE > 0) { fprintf(f, "Matching bases in coding regions of cDNA and genomic sequences are colored blue%s. ", (upcMatch ? " and capitalized" : "")); fprintf(f, "Matching bases in UTR regions of cDNA and genomic sequences are colored red%s. ", (upcMatch ? " and capitalized" : "")); fputs("Light blue (coding) or orange (UTR) bases mark the boundaries of gaps in either sequence " "(often splice sites).\n", f); } else { fprintf(f, "Matching bases in cDNA and genomic sequences are colored blue%s. ", (upcMatch ? " and capitalized" : "")); fputs("Light blue bases mark the boundaries of gaps in either sequence " "(often splice sites).\n", f); } if (showNeedle && restrictToWindow) fputs("Bases that were in the selected browser region are shown in bold " "and underlined, " "and only the alignment for these bases is displayed in the " "Genomic and Side by Side sections.\n", f); if (showJumpTable) fputs("</P></CENTER>\n", f); htmHorizontalLine(f); fprintf(f, "<H4><A NAME=cDNA></A>cDNA %s%s</H4>\n", needleName, (rcNeedle ? " (reverse complemented)" : "")); if (rcNeedle) reverseComplement(needle, needleSize); if (showNeedle) { ffShNeedle(f, needle, needleSize, needleNumOffset, colorFlags, aliList, upcMatch, cdsS, cdsE, restrictToWindow, nPartS, nPartE); } if (showHaystack) { struct cfm *cfm = cfmNew(10, 50, TRUE, rcHaystack, f, hayExtremity); char *h = cloneMem(haystack, haySize); char *accentFlags = needMem(haySize); zeroBytes(accentFlags, haySize); fprintf(f, "<H4><A NAME=genomic></A>Genomic %s %s:</H4>\n", haystackName, (rcHaystack ? "(reverse strand)" : "")); fprintf(f, "<PRE><TT>\n"); zeroBytes(colorFlags, haySize); for (ali = leftAli; ali != NULL; ali = ali->right) { boolean utr = FALSE; int i; int off = ali->hStart-haystack; int count = ali->hEnd - ali->hStart; int offn = ali->nStart-needle; if ((cdsE > 0) && ((cdsS-offn-1) > 0)) utr = TRUE; for (i=0; i<count; ++i) { if (!utr && (i > (cdsE-offn-1)) && (cdsE > 0)) utr = TRUE; if (utr && (i == (cdsS-offn))) utr = FALSE; if (toupper(ali->hStart[i]) == toupper(ali->nStart[i])) { if (utr) colorFlags[off+i] = ((i == 0 || i == count-1) ? socOrange : socRed); else colorFlags[off+i] = ((i == 0 || i == count-1) ? socBrightBlue : socBlue); if (upcMatch) h[off+i] = toupper(h[off+i]); } if (restrictToWindow && off+i >= hayOffStart && off+i < hayOffEnd) accentFlags[off+i] = TRUE; } } ali = leftAli; lastAli = NULL; while (ali && (ali->hEnd - haystack) <= hayPaddedOffStart) ali = ali->right; for (i = hayPaddedOffStart; i < hayPaddedOffEnd; ++i) { /* Put down "anchor" on first match position in haystack * so user can hop here with a click on the needle. */ if (ali != NULL && i == ali->hStart - haystack) { if (lastAli == NULL || ali->hStart - lastAli->hEnd > blockMaxGap) { fprintf(f, "<A NAME=%d></A>", ++anchorCount); } lastAli = ali; ali = ali->right; } cfmOutExt(cfm, h[i], seqOutColorLookup[(int)colorFlags[i]], accentFlags[i], accentFlags[i], FALSE); } cfmFree(&cfm); freeMem(h); fprintf(f, "</TT></PRE>\n"); htmHorizontalLine(f); } if (showSideBySide) { fprintf(f, "<H4><A NAME=ali></A>Side by Side Alignment</H4>\n"); ffShowSideBySide(f, leftAli, needle, needleNumOffset, haystack, hayNumOffset, haySize, hayOffStart, hayOffEnd, blockMaxGap, rcHaystack, TRUE); fprintf(f, "<HR ALIGN=\"CENTER\">"); fprintf(f, "<EM>*Aligned Blocks with gaps <= %d bases are merged for " "this display when only one sequence has a gap, or when gaps in " "both sequences are of the same size.</EM>\n", blockMaxGap); } if (rcNeedle) reverseComplement(needle, needleSize); return anchorCount; }
static void ffShNeedle(FILE *f, DNA *needle, int needleSize, int needleNumOffset, char *colorFlags, struct ffAli *aliList, boolean upcMatch, int cdsS, int cdsE, boolean accentRange, int accentStart, int accentEnd) /* Display the needle sequence with HTML highlighting. */ { struct cfm *cfm = cfmNew(10, 50, TRUE, FALSE, f, needleNumOffset); char *n = cloneMem(needle, needleSize); char *accentFlags = needMem(needleSize); struct ffAli *leftAli = aliList; struct ffAli *ali; long i; zeroBytes(colorFlags, needleSize); zeroBytes(accentFlags, needleSize); fprintf(f, "<PRE><TT>\n"); if (aliList != NULL) { for (leftAli = aliList; leftAli->left != NULL; leftAli = leftAli->left) ; } for (ali = leftAli; ali != NULL; ali = ali->right) { boolean utr = FALSE; int off = ali->nStart-needle; int count = ali->nEnd - ali->nStart; if ((cdsE > 0) && ((cdsS-off-1) > 0)) utr = TRUE; for (i=0; i<count; ++i) { if (!utr && (i > (cdsE-off-1)) && (cdsE > 0)) utr = TRUE; if (utr && (i == (cdsS-off))) utr = FALSE; if (toupper(ali->hStart[i]) == toupper(ali->nStart[i])) { if (utr) colorFlags[off+i] = ((i == 0 || i == count-1) ? socOrange : socRed); else colorFlags[off+i] = ((i == 0 || i == count-1) ? socBrightBlue : socBlue); if (upcMatch) n[off+i] = toupper(n[off+i]); } if (accentRange) { if (off+i >= accentStart && off+i < accentEnd) accentFlags[off+i] = TRUE; } } } for (i=0; i<needleSize; ++i) { if (accentRange && i == accentStart) fprintf(f, "<A NAME=cDNAStart></A>"); cfmOutExt(cfm, n[i], seqOutColorLookup[(int)colorFlags[i]], accentFlags[i], accentFlags[i], FALSE); } cfmFree(&cfm); freeMem(n); freeMem(accentFlags); fprintf(f, "</TT></PRE>\n"); htmHorizontalLine(f); }
void qacAgpLift(char *agpFile, char *qacInName, char *qacOutName) /* qacAgpLift - Use AGP to combine per-scaffold qac into per-chrom qac. */ { struct hash *qacHash = qacReadToHash(qacInName); struct chrom *chrom, *chromList = readChromScaffoldsFromAgp(agpFile); FILE *f = mustOpen(qacOutName, "w"); struct qaSeq qa; struct agpFrag *frag; struct qac *qac; int bufSize = 0; UBYTE *buf = NULL; int qaMaxSize = 0; int fragSize; int count = 0; qacWriteHead(f); ZeroVar(&qa); for (chrom = chromList; chrom != NULL; chrom = chrom->next) { /* Set up qa to hold uncompressed quals for whole chrom. */ qa.name = chrom->list->chrom; verbose(1, " %s size=%d\n", chrom->list->chrom, chrom->size); qa.size = chrom->size; if (qaMaxSize < qa.size) { qa.qa = needHugeZeroedMem(qa.size); qaMaxSize = qa.size; } else { zeroBytes(qa.qa, qa.size); } /* Uncompress contig quality scores and copy into chrom's quality buffer. */ for (frag = chrom->list; frag != NULL; frag = frag->next) { struct hashEl *hel; fragSize = frag->fragEnd - frag->fragStart; if ((hel = hashLookup(qacHash, frag->frag)) != NULL) { qac = (struct qac *) hel->val; if (bufSize < qac->uncSize) { freez(&buf); bufSize = qac->uncSize; buf = needMem(bufSize); } rleUncompress(qac->data, qac->compSize, buf, qac->uncSize); if (frag->strand[0] == '-') reverseBytes((char*)buf, qac->uncSize); memcpy(qa.qa + frag->chromStart, buf + frag->fragStart, fragSize); } else { /* agp frag not found in qac hash -- missing data */ if (mScore < 0) errAbort("missing data: no quality scores for %s", frag->frag); /* fill in missing data with specified score */ memset(qa.qa + frag->chromStart, mScore, fragSize); } } /* Compress and write it out. */ qacWriteNext(f, &qa); ++count; } carefulClose(&f); }