/* free exonInfo list */ static void freeGIList(struct exonInfo *list) { struct exonInfo *giNext; for(; list ; list = giNext) { giNext = list->next; mafAliFreeList(&list->ali); } }
void mafFileFree(struct mafFile **pObj) /* Free up a maf file. */ { struct mafFile *obj = *pObj; if (obj == NULL) return; lineFileClose(&obj->lf); freeMem(obj->scoring); mafAliFreeList(&obj->alignments); freez(pObj); }
static struct mafAli *mafFromBed12(char *database, char *track, struct bed *bed, struct slName *orgList) /* Construct a maf out of exons in bed. */ { /* Loop through all block in bed, collecting a list of mafs, one * for each block. While we're at make a hash of all species seen. */ struct hash *speciesHash = hashNew(0); struct mafAli *mafList = NULL, *maf, *bigMaf; struct mafComp *comp, *bigComp; int totalTextSize = 0; int i; for (i=0; i<bed->blockCount; ++i) { int start = bed->chromStart + bed->chromStarts[i]; int end = start + bed->blockSizes[i]; if (thickOnly) { start = max(start, bed->thickStart); end = min(end, bed->thickEnd); } if (start < end) { maf = hgMafFrag(database, track, bed->chrom, start, end, '+', database, NULL); slAddHead(&mafList, maf); for (comp = maf->components; comp != NULL; comp = comp->next) hashStore(speciesHash, comp->src); totalTextSize += maf->textSize; } } slReverse(&mafList); /* Add species in order list too */ struct slName *org; for (org = orgList; org != NULL; org = org->next) hashStore(speciesHash, org->name); /* Allocate memory for return maf that contains all blocks concatenated together. * Also fill in components with any species seen at all. */ AllocVar(bigMaf); bigMaf->textSize = totalTextSize; struct hashCookie it = hashFirst(speciesHash); struct hashEl *hel; while ((hel = hashNext(&it)) != NULL) { AllocVar(bigComp); bigComp->src = cloneString(hel->name); bigComp->text = needLargeMem(totalTextSize + 1); memset(bigComp->text, '.', totalTextSize); bigComp->text[totalTextSize] = 0; bigComp->strand = '+'; bigComp->srcSize = totalTextSize; /* It's safe if a bit of a lie. */ hel->val = bigComp; slAddHead(&bigMaf->components, bigComp); } /* Loop through maf list copying in data. */ int textOffset = 0; for (maf = mafList; maf != NULL; maf = maf->next) { for (comp = maf->components; comp != NULL; comp = comp->next) { bigComp = hashMustFindVal(speciesHash, comp->src); memcpy(bigComp->text + textOffset, comp->text, maf->textSize); bigComp->size += comp->size; } textOffset += maf->textSize; } /* Cope with strand of darkness. */ if (bed->strand[0] == '-') { for (comp = bigMaf->components; comp != NULL; comp = comp->next) reverseComplement(comp->text, bigMaf->textSize); } /* If got an order list then reorder components according to it. */ if (orgList != NULL) { struct mafComp *newList = NULL; for (org = orgList; org != NULL; org = org->next) { comp = hashMustFindVal(speciesHash, org->name); slAddHead(&newList, comp); } slReverse(&newList); bigMaf->components = newList; } /* Rename our own component to bed name */ comp = hashMustFindVal(speciesHash, database); freeMem(comp->src); comp->src = cloneString(bed->name); /* Clean up and go home. */ hashFree(&speciesHash); mafAliFreeList(&mafList); return bigMaf; }
static void mafOrAxtClick2(struct sqlConnection *conn, struct sqlConnection *conn2, struct trackDb *tdb, char *axtOtherDb, char *fileName) /* Display details for MAF or AXT tracks. */ { hgBotDelay(); if (winEnd - winStart > 30000) { printf("Zoom so that window is 30,000 bases or less to see alignments and conservation statistics\n"); } else { struct mafAli *mafList = NULL, *maf, *subList = NULL; int aliIx = 0, realCount = 0; char dbChrom[64]; char option[128]; char *capTrack; struct consWiggle *consWig, *consWiggles; struct hash *speciesOffHash = NULL; char *speciesOrder = NULL; char *speciesTarget = trackDbSetting(tdb, SPECIES_TARGET_VAR); char buffer[1024]; int useTarg = FALSE; int useIrowChains = FALSE; safef(option, sizeof(option), "%s.%s", tdb->track, MAF_CHAIN_VAR); if (cartCgiUsualBoolean(cart, option, FALSE) && trackDbSetting(tdb, "irows") != NULL) useIrowChains = TRUE; safef(buffer, sizeof(buffer), "%s.vis",tdb->track); if (useIrowChains) { if (!cartVarExists(cart, buffer) && (speciesTarget != NULL)) useTarg = TRUE; else { char *val; val = cartUsualString(cart, buffer, "useCheck"); useTarg = sameString("useTarg",val); } } if (sameString(tdb->type, "bigMaf")) { char *fileName = trackDbSetting(tdb, "bigDataUrl"); struct bbiFile *bbi = bigBedFileOpen(fileName); mafList = bigMafLoadInRegion(bbi, seqName, winStart, winEnd); } else mafList = mafOrAxtLoadInRegion2(conn,conn2, tdb, seqName, winStart, winEnd, axtOtherDb, fileName); safef(dbChrom, sizeof(dbChrom), "%s.%s", hubConnectSkipHubPrefix(database), seqName); safef(option, sizeof(option), "%s.speciesOrder", tdb->track); speciesOrder = cartUsualString(cart, option, NULL); if (speciesOrder == NULL) speciesOrder = trackDbSetting(tdb, "speciesOrder"); for (maf = mafList; maf != NULL; maf = maf->next) { int mcCount = 0; struct mafComp *mc; struct mafAli *subset; struct mafComp *nextMc; /* remove empty components and configured off components * from MAF, and ignore * the entire MAF if all components are empty * (solely for gap annotation) */ if (!useTarg) { for (mc = maf->components->next; mc != NULL; mc = nextMc) { char buf[64]; char *organism; mafSrcDb(mc->src, buf, sizeof buf); organism = hOrganism(buf); if (!organism) organism = buf; nextMc = mc->next; safef(option, sizeof(option), "%s.%s", tdb->track, buf); if (!cartUsualBoolean(cart, option, TRUE)) { if (speciesOffHash == NULL) speciesOffHash = newHash(4); hashStoreName(speciesOffHash, organism); } if (!cartUsualBoolean(cart, option, TRUE)) slRemoveEl(&maf->components, mc); else mcCount++; } } if (mcCount == 0) continue; if (speciesOrder) { int speciesCt; char *species[2048]; struct mafComp **newOrder, *mcThis; int i; mcCount = 0; speciesCt = chopLine(cloneString(speciesOrder), species); newOrder = needMem((speciesCt + 1) * sizeof (struct mafComp *)); newOrder[mcCount++] = maf->components; for (i = 0; i < speciesCt; i++) { if ((mcThis = mafMayFindCompSpecies(maf, species[i], '.')) == NULL) continue; newOrder[mcCount++] = mcThis; } maf->components = NULL; for (i = 0; i < mcCount; i++) { newOrder[i]->next = 0; slAddHead(&maf->components, newOrder[i]); } slReverse(&maf->components); } subset = mafSubsetE(maf, dbChrom, winStart, winEnd, TRUE); if (subset != NULL) { /* Reformat MAF if needed so that sequence from current * database is the first component and on the * plus strand. */ mafMoveComponentToTop(subset, dbChrom); if (subset->components->strand == '-') mafFlipStrand(subset); subset->score = mafScoreMultiz(subset); slAddHead(&subList, subset); ++realCount; } } slReverse(&subList); mafAliFreeList(&mafList); if (subList != NULL) { char *showVarName = "hgc.showMultiBase"; char *showVarVal = cartUsualString(cart, showVarName, "all"); boolean onlyDiff = sameWord(showVarVal, "diff"); #ifdef ADDEXONCAPITAL char *codeVarName = "hgc.multiCapCoding"; char *codeVarVal = cartUsualString(cart, codeVarName, "coding"); boolean onlyCds = sameWord(codeVarVal, "coding"); #endif /* add links for conservation score statistics */ consWiggles = wigMafWiggles(database, tdb); int wigCount = slCount(consWiggles); if (wigCount == 1) { conservationStatsLink(tdb, "Conservation score statistics", consWiggles->table); } else if (wigCount > 1) { /* multiple wiggles. List all that have been turned on with * checkboxes */ /* Scan for cart variables -- do any exist, are any turned on ? */ boolean wigSet = FALSE; boolean wigOn = FALSE; for (consWig = consWiggles; consWig != NULL; consWig = consWig->next) { char *wigVarSuffix = NULL; (void)wigMafWiggleVar(tdb->track, consWig, &wigVarSuffix); if (cartVarExistsAnyLevel(cart, tdb, FALSE, wigVarSuffix)) { wigSet = TRUE; if (cartBooleanClosestToHome(cart, tdb, FALSE, wigVarSuffix)) wigOn = TRUE; } } /* If there are no cart vars, turn on the first (default) wig */ if (!wigSet) { char *prefix = tdb->track; // use when setting things to the cart if (tdbIsContainerChild(tdb)) prefix = tdbGetContainer(tdb)->track; cartSetBoolean(cart, wigMafWiggleVar(prefix, consWiggles, NULL), TRUE); wigOn = TRUE; } if (wigOn) { boolean first = TRUE; for (consWig = consWiggles; consWig != NULL; consWig = consWig->next) { if (first) { printf("Conservation score statistics:"); first = FALSE; } char *wigVarSuffix = NULL; (void)wigMafWiggleVar(tdb->track, consWig, &wigVarSuffix); if (cartUsualBooleanClosestToHome(cart, tdb, FALSE, wigVarSuffix,FALSE)) { printf(" "); subChar(consWig->uiLabel, '_', ' '); conservationStatsLink(tdb, consWig->uiLabel, consWig->table); } } } } puts("</P>\n"); /* no alignment to display when in visibilities where only wiggle is shown */ char *vis = cartOptionalString(cart, tdb->track); if (vis) { enum trackVisibility tv = hTvFromStringNoAbort(vis); if (tv == tvSquish || tv == tvDense) return; } #ifdef ADDEXONCAPITAL puts("<FORM ACTION=\"../cgi-bin/hgc\" NAME=\"gpForm\" METHOD=\"GET\">"); cartSaveSession(cart); cgiContinueHiddenVar("g"); cgiContinueHiddenVar("c"); cgiContinueHiddenVar("i"); printf("Capitalize "); cgiMakeDropListFull(codeVarName, codeAll, codeAll, ArraySize(codeAll), codeVarVal, autoSubmit); printf("exons based on "); capTrack = genePredDropDown(cart, trackHash, "gpForm", "hgc.multiCapTrack"); #endif printf("show "); cgiMakeDropListFull(showVarName, showAll, showAll, ArraySize(showAll), showVarVal, autoSubmit); printf("bases"); printf("<BR>\n"); printf("</FORM>\n"); #ifdef REVERSESTRAND /* notify if bases are complemented (hgTracks is on reverse strand) */ if (cartCgiUsualBoolean(cart, COMPLEMENT_BASES_VAR, FALSE)) puts("<EM>Alignment displayed on reverse strand</EM><BR>"); #endif puts("Place cursor over species for alignment detail. Click on 'B' to link to browser "); puts("for aligned species, click on 'D' to get DNA for aligned species.<BR>"); printf("<TT><PRE>"); /* notify if species removed from alignment */ if (speciesOffHash) { char *species; struct hashCookie hc = hashFirst(speciesOffHash); puts("<B>Components not displayed:</B> "); while ((species = hashNextName(&hc)) != NULL) printf("%s ", species); puts("<BR>"); } for (maf = subList; maf != NULL; maf = maf->next) { mafLowerCase(maf); #ifdef ADDEXONCAPITAL if (capTrack != NULL) capMafOnTrack(maf, capTrack, onlyCds); #endif printf("<B>Alignment block %d of %d in window, %d - %d, %d bps </B>\n", ++aliIx,realCount,maf->components->start + 1, maf->components->start + maf->components->size, maf->components->size); mafPrettyOut(stdout, maf, 70,onlyDiff, aliIx); } mafAliFreeList(&subList); } else { printf("No multiple alignment in browser window"); } printf("</PRE></TT>"); } }
struct mafAli *hgMafFrag( char *database, /* Database, must already have hSetDb to this */ char *track, /* Name of MAF track */ char *chrom, /* Chromosome (in database genome) */ int start, int end, /* start/end in chromosome */ char strand, /* Chromosome strand. */ char *outName, /* Optional name to use in first component */ struct slName *orderList /* Optional order of organisms. */ ) /* mafFrag- Extract maf sequences for a region from database. * This creates a somewhat unusual MAF that extends from start * to end whether or not there are actually alignments. Where * there are no alignments (or alignments missing a species) * a . character fills in. The score is always zero, and * the sources just indicate the species. You can mafFree this * as normal. */ { int chromSize = hChromSize(database, chrom); struct sqlConnection *conn = hAllocConn(database); struct dnaSeq *native = hChromSeq(database, chrom, start, end); struct mafAli *maf, *mafList = mafLoadInRegion(conn, track, chrom, start, end); char masterSrc[128]; struct hash *orgHash = newHash(10); struct oneOrg *orgList = NULL, *org, *nativeOrg = NULL; int curPos = start, symCount = 0; struct slName *name; int order = 0; /* Check that the mafs are really copacetic, the particular * subtype we think is in the database that this (relatively) * simple code can handle. */ safef(masterSrc, sizeof(masterSrc), "%s.%s", database, chrom); mafCheckFirstComponentSrc(mafList, masterSrc); mafCheckFirstComponentStrand(mafList, '+'); slSort(&mafList, mafCmp); /* Prebuild organisms if possible from input orderList. */ for (name = orderList; name != NULL; name = name->next) { AllocVar(org); slAddHead(&orgList, org); hashAddSaveName(orgHash, name->name, org, &org->name); org->dy = dyStringNew(native->size*1.5); org->order = order++; if (nativeOrg == NULL) nativeOrg = org; } if (orderList == NULL) { AllocVar(org); slAddHead(&orgList, org); hashAddSaveName(orgHash, database, org, &org->name); org->dy = dyStringNew(native->size*1.5); if (nativeOrg == NULL) nativeOrg = org; } /* Go through all mafs in window, mostly building up * org->dy strings. */ for (maf = mafList; maf != NULL; maf = maf->next) { struct mafComp *mc, *mcMaster = maf->components; struct mafAli *subMaf = NULL; order = 0; if (curPos < mcMaster->start) { fillInMissing(nativeOrg, orgList, native, start, curPos, mcMaster->start); symCount += mcMaster->start - curPos; } if (curPos < mcMaster->start + mcMaster->size) /* Prevent worst * backtracking */ { if (mafNeedSubset(maf, masterSrc, curPos, end)) { subMaf = mafSubset(maf, masterSrc, curPos, end); if (subMaf == NULL) continue; } else subMaf = maf; for (mc = subMaf->components; mc != NULL; mc = mc->next, ++order) { /* Extract name up to dot into 'orgName' */ char buf[128], *e, *orgName; if ((mc->size == 0) || (mc->srcSize == 0)) /* skip over components without sequence */ continue; mc->leftStatus = mc->rightStatus = 0; /* squash annotation */ e = strchr(mc->src, '.'); if (e == NULL) orgName = mc->src; else { int len = e - mc->src; if (len >= sizeof(buf)) errAbort("organism/database name %s too long", mc->src); memcpy(buf, mc->src, len); buf[len] = 0; orgName = buf; } /* Look up dyString corresponding to org, and create a * new one if necessary. */ org = hashFindVal(orgHash, orgName); if (org == NULL) { if (orderList != NULL) errAbort("%s is not in orderList", orgName); AllocVar(org); slAddHead(&orgList, org); hashAddSaveName(orgHash, orgName, org, &org->name); org->dy = dyStringNew(native->size*1.5); dyStringAppendMultiC(org->dy, '.', symCount); if (nativeOrg == NULL) nativeOrg = org; } if (orderList == NULL && order > org->order) org->order = order; org->hit = TRUE; /* Fill it up with alignment. */ dyStringAppendN(org->dy, mc->text, subMaf->textSize); } for (org = orgList; org != NULL; org = org->next) { if (!org->hit) dyStringAppendMultiC(org->dy, '.', subMaf->textSize); org->hit = FALSE; } symCount += subMaf->textSize; curPos = mcMaster->start + mcMaster->size; if (subMaf != maf) mafAliFree(&subMaf); } } if (curPos < end) { fillInMissing(nativeOrg, orgList, native, start, curPos, end); symCount += end - curPos; } mafAliFreeList(&mafList); slSort(&orgList, oneOrgCmp); if (strand == '-') { for (org = orgList; org != NULL; org = org->next) reverseComplement(org->dy->string, org->dy->stringSize); } /* Construct our maf */ AllocVar(maf); maf->textSize = symCount; for (org = orgList; org != NULL; org = org->next) { struct mafComp *mc; AllocVar(mc); if (org == orgList) { if (outName != NULL) { mc->src = cloneString(outName); mc->srcSize = native->size; mc->strand = '+'; mc->start = 0; mc->size = native->size; } else { mc->src = cloneString(masterSrc); mc->srcSize = chromSize; mc->strand = strand; if (strand == '-') reverseIntRange(&start, &end, chromSize); mc->start = start; mc->size = end-start; } } else { int size = countAlpha(org->dy->string); mc->src = cloneString(org->name); mc->srcSize = size; mc->strand = '+'; mc->start = 0; mc->size = size; } mc->text = cloneString(org->dy->string); dyStringFree(&org->dy); slAddHead(&maf->components, mc); } slReverse(&maf->components); slFreeList(&orgList); freeHash(&orgHash); hFreeConn(&conn); return maf; }