d781bc31ad6c4a86a3b8e1f0e78827a08c544128 tdreszer Fri Oct 1 11:05:56 2010 -0700 Fixing git mess (I hope) created from an accidental 'git add .' diff --git src/hg/hgTracks/wigMafTrack.c.old src/hg/hgTracks/wigMafTrack.c.old deleted file mode 100644 index 890239d..0000000 --- src/hg/hgTracks/wigMafTrack.c.old +++ /dev/null @@ -1,2530 +0,0 @@ -/* wigMafTrack - display multiple alignment files with score wiggle - * and base-level alignment, or else density plot of pairwise alignments - * (zoomed out) */ - -#include "common.h" -#include "hash.h" -#include "linefile.h" -#include "jksql.h" -#include "hdb.h" -#include "hgTracks.h" -#include "maf.h" -#include "scoredRef.h" -#include "wiggle.h" -#include "hCommon.h" -#include "hgMaf.h" -#include "mafTrack.h" -#include "customTrack.h" -#include "mafSummary.h" -#include "mafFrames.h" -#include "phyloTree.h" - -static char const rcsid[] = "$Id: wigMafTrack.c,v 1.146 2010/05/11 01:43:28 kent Exp $"; - -#define GAP_ITEM_LABEL "Gaps" -#define MAX_SP_SIZE 2000 - -struct wigMafItem -/* A maf track item -- - * a line of bases (base level) or pairwise density gradient (zoomed out). */ - { - struct wigMafItem *next; - char *name; /* Common name */ - char *db; /* Database */ - int group; /* number of species group/clade */ - int ix; /* Position in list. */ - int height; /* Pixel height of item. */ - int inserts[128]; - int insertsSize; - int seqEnds[128]; - int seqEndsSize; - int brackStarts[128]; - int brackStartsSize; - int brackEnds[128]; - int brackEndsSize; - }; - -static void wigMafItemFree(struct wigMafItem **pEl) -/* Free up a wigMafItem. */ -{ -struct wigMafItem *el = *pEl; -if (el != NULL) - { - freeMem(el->name); - freeMem(el->db); - freez(pEl); - } -} - -void wigMafItemFreeList(struct wigMafItem **pList) -/* Free a list of dynamically allocated wigMafItem's */ -{ -struct wigMafItem *el, *next; - -for (el = *pList; el != NULL; el = next) - { - next = el->next; - wigMafItemFree(&el); - } -*pList = NULL; -} - -Color wigMafItemLabelColor(struct track *tg, void *item, struct hvGfx *hvg) -/* Return color to draw a maf item based on the species group it is in */ -{ -struct wigMafItem *mi = (struct wigMafItem *)item; -if (sameString(mi->name, GAP_ITEM_LABEL)) - return getOrangeColor(); -return (((struct wigMafItem *)item)->group % 2 ? - tg->ixAltColor : tg->ixColor); -} - -static struct mafAli *wigMafLoadInRegion(struct sqlConnection *conn, - struct sqlConnection *conn2, char *table, char *chrom, int start, int end, char *file) -/* Load mafs from region */ -{ - return mafLoadInRegion2(conn, conn2, table, chrom, start, end, file); -} - -static struct wigMafItem *newMafItem(char *s, int g, boolean lowerFirstChar) -/* Allocate and initialize a maf item. Species param can be a db or name */ -{ -struct wigMafItem *mi; -char *val; - -AllocVar(mi); -if ((val = hGenome(s)) != NULL) - { - /* it's a database name */ - mi->db = cloneString(s); - mi->name = val; - } -else - { - mi->db = cloneString(s); - mi->name = cloneString(s); - } -mi->name = hgDirForOrg(mi->name); -if (lowerFirstChar) - *mi->name = tolower(*mi->name); -mi->height = tl.fontHeight; -mi->group = g; -return mi; -} - -struct wigMafItem *getSpeciesFromMaf(struct track *track, int height) -{ -struct wigMafItem *mi = NULL, *miList = NULL; -struct hash *hash = newHash(8); /* keyed by database. */ -struct mafPriv *mp = getMafPriv(track); -struct mafAli *maf; -char buf[64]; -char *otherOrganism; - -if (mp->list == (struct mafAli *)-1) - return NULL; -for (maf = mp->list; maf != NULL; maf = maf->next) - { - struct mafComp *mc; - for (mc = maf->components; mc != NULL; mc = mc->next) - { - mafSrcDb(mc->src, buf, sizeof(buf)); - if (sameString(buf, database)) - continue; - if (hashLookup(hash, buf) == NULL) - { - AllocVar(mi); - mi->db = cloneString(buf); - otherOrganism = hOrganism(mi->db); - mi->name = - (otherOrganism == NULL ? cloneString(buf) : otherOrganism); - - mi->height = tl.fontHeight; - slAddHead(&miList, mi); - hashAdd(hash, mi->db, mi); - } - } - } -hashFree(&hash); - -return miList; -} - -struct wigMafItem *newSpeciesItems(struct track *track, int height) -/* Make up item list for all species configured in track settings */ -{ -struct dyString *order = dyStringNew(256); -char option[MAX_SP_SIZE]; -char *species[MAX_SP_SIZE]; -char *groups[20]; -char *defaultOff[MAX_SP_SIZE]; -char sGroup[24]; -struct wigMafItem *mi = NULL, *miList = NULL; -int group; -int i; -int speciesCt = 0, groupCt = 1; -int speciesOffCt = 0; -struct hash *speciesOffHash = newHash(0); -char buffer[128]; -char *speciesTarget = trackDbSetting(track->tdb, SPECIES_TARGET_VAR); -char *speciesTree = trackDbSetting(track->tdb, SPECIES_TREE_VAR); -bool useTarg; /* use phyloTree to find shortest path */ -struct phyloTree *tree = NULL; -char *speciesUseFile = trackDbSetting(track->tdb, SPECIES_USE_FILE); -char *msaTable = NULL; - -/* either speciesOrder or speciesGroup is specified in trackDb */ -char *speciesOrder = trackDbSetting(track->tdb, SPECIES_ORDER_VAR); -char *speciesGroup = trackDbSetting(track->tdb, SPECIES_GROUP_VAR); -char *speciesOff = trackDbSetting(track->tdb, SPECIES_DEFAULT_OFF_VAR); - -bool lowerFirstChar = TRUE; -char *firstCase; - -firstCase = trackDbSetting(track->tdb, ITEM_FIRST_CHAR_CASE); -if (firstCase != NULL) - { - if (sameWord(firstCase, "noChange")) lowerFirstChar = FALSE; - } - -char *cfgPrefix = compositeViewControlNameFromTdb(track->tdb); -safef(buffer, sizeof(buffer), "%s.vis",/*cfgPrefix*/track->track); -if (!cartVarExists(cart, buffer) && (speciesTarget != NULL)) - useTarg = TRUE; -else - { - char *val; - - val = cartUsualString(cart, buffer, "useCheck"); - useTarg = sameString("useTarg",val); - } - -if (useTarg && (tree = phyloParseString(speciesTree)) == NULL) - useTarg = FALSE; - -if (speciesOrder == NULL && speciesGroup == NULL && speciesUseFile == NULL) - return getSpeciesFromMaf(track, height); - -if (speciesGroup) - groupCt = chopLine(cloneString(speciesGroup), groups); - -if (speciesUseFile) - { - if ((speciesGroup != NULL) || (speciesOrder != NULL)) - errAbort("Can't specify speciesUseFile and speciesGroup or speciesOrder"); - if (hIsGsidServer()) - { - msaTable = trackDbSetting(track->tdb, "msaTable"); - if (msaTable != NULL) - { - speciesOrder = cartGetOrderFromFileAndMsaTable(database, cart, speciesUseFile, msaTable); - } - else - { - speciesOrder = cartGetOrderFromFile(database, cart, speciesUseFile); - } - } - else - { - speciesOrder = cartGetOrderFromFile(database, cart, speciesUseFile); - } - speciesOff = NULL; - } - -/* keep track of species configured off initially for track */ -if (speciesOff) - { - speciesOffCt = chopLine(cloneString(speciesOff), defaultOff); - for (i = 0; i < speciesOffCt; i++) - hashAdd(speciesOffHash, defaultOff[i], NULL); - } - -/* Make up items for other organisms by scanning through group & species - track settings */ -for (group = 0; group < groupCt; group++) - { - if (groupCt != 1 || !speciesOrder) - { - safef(sGroup, sizeof sGroup, "%s%s", - SPECIES_GROUP_PREFIX, groups[group]); - speciesOrder = trackDbRequiredSetting(track->tdb, sGroup); - } - if (useTarg) - { - char *ptr, *path; - struct hash *orgHash = newHash(0); - int numNodes, ii; - char *nodeNames[512]; - char *species = NULL; - char *lowerString; - - path = phyloNodeNames(tree); - numNodes = chopLine(path, nodeNames); - for(ii=0; ii < numNodes; ii++) - { - if ((ptr = hOrganism(nodeNames[ii])) != NULL) - { - ptr[0] = tolower(ptr[0]); - hashAdd(orgHash, ptr, nodeNames[ii]); - } - else - { - hashAdd(orgHash, nodeNames[ii], nodeNames[ii]); - } - } - - lowerString = cartUsualString(cart, SPECIES_HTML_TARGET,speciesTarget); - lowerString[0] = tolower(lowerString[0]); - species = hashFindVal(orgHash, lowerString); - if ((ptr = phyloFindPath(tree, database, species)) != NULL) - speciesOrder = ptr; - } - - - safef(option, sizeof(option), "%s.speciesOrder", /*cfgPrefix*/track->track); - speciesCt = chopLine(cloneString(speciesOrder), species); - - for (i = 0; i < speciesCt; i++) - { - if (!useTarg) - { - /* skip this species if UI checkbox was unchecked */ - safef(option, sizeof(option), "%s.%s", cfgPrefix, species[i]); - if (!cartVarExists(cart, option)) - if (hashLookup(speciesOffHash, species[i])) - cartSetBoolean(cart, option, FALSE); - if (!cartUsualBoolean(cart, option, TRUE)) - continue; - } - mi = newMafItem(species[i], group, lowerFirstChar); - slAddHead(&miList, mi); - } - } - -slReverse(&miList); -for (mi = miList; mi != NULL; mi = mi->next) - { - mi->height = height; - dyStringPrintf(order, "%s ",mi->db); - } -safef(option, sizeof(option), "%s.speciesOrder", /*cfgPrefix*/track->track); -cartSetString(cart, option, order->string); -compositeViewControlNameFree(&cfgPrefix); -slReverse(&miList); - -return miList; -} - -static struct wigMafItem *scoreItem(int scoreHeight, char *label) -/* Make up item that will show the score */ -{ -struct wigMafItem *mi; - -AllocVar(mi); -mi->name = cloneString(label); -mi->height = scoreHeight; -return mi; -} - -struct mafPriv *getMafPriv(struct track *track) -{ -struct mafPriv *mp = track->customPt; - -if (mp == NULL) - { - AllocVar(mp); - track->customPt = mp; - } - -return mp; -} - -char *getTrackMafFile(struct track *track) -/* look up MAF file name in track setting, return NULL if not found */ -{ -return hashFindVal(track->tdb->settingsHash, "mafFile"); -} - -char *getCustomMafFile(struct track *track) -{ -char *fileName = getTrackMafFile(track); -if (fileName == NULL) - errAbort("cannot find custom maf setting"); -return fileName; -} - -static void loadMafsToTrack(struct track *track) -/* load mafs in region to track custom pointer */ -{ -struct sqlConnection *conn; -struct sqlConnection *conn2; -struct mafPriv *mp = getMafPriv(track); - -if (winBaseCount > MAF_SUMMARY_VIEW) - return; - -/* we open two connections to the database - * that has the maf track in it. One is - * for the scoredRefs, the other to access - * the extFile database. We could get away - * with just one connection, but then we'd - * have to allocate more memory to hold - * the scoredRefs (whereas now we just use - * one statically loaded scoredRef). - */ -if (mp->ct) - { - char *fileName = getCustomMafFile(track); - - conn = hAllocConn(CUSTOM_TRASH); - conn2 = hAllocConn(CUSTOM_TRASH); - mp->list = wigMafLoadInRegion(conn, conn2, mp->ct->dbTableName, - chromName, winStart - 2 , winEnd + 2, fileName); - hFreeConn(&conn); - hFreeConn(&conn2); - } -else - { - char *fileName = getTrackMafFile(track); // optional - conn = hAllocConn(database); - conn2 = hAllocConn(database); - mp->list = wigMafLoadInRegion(conn, conn2, track->table, - chromName, winStart - 2 , winEnd + 2, fileName); - hFreeConn(&conn); - hFreeConn(&conn2); - } -} - -static struct wigMafItem *loadBaseByBaseItems(struct track *track) -/* Make up base-by-base track items. */ -{ -struct wigMafItem *miList = NULL, *speciesList = NULL, *mi; -int scoreHeight = 0; - -bool lowerFirstChar = TRUE; -char *firstCase; - -firstCase = trackDbSetting(track->tdb, ITEM_FIRST_CHAR_CASE); -if (firstCase != NULL) - { - if (sameWord(firstCase, "noChange")) lowerFirstChar = FALSE; - } - -loadMafsToTrack(track); - -/* NOTE: we are building up the item list backwards */ - -/* Add items for conservation wiggles */ -struct track *wigTrack = track->subtracks; -if (wigTrack) - { - enum trackVisibility wigVis = (wigTrack->limitedVis == tvDense ? tvDense : tvFull); - while (wigTrack != NULL) - { - scoreHeight = wigTotalHeight(wigTrack, wigVis); - mi = scoreItem(scoreHeight, wigTrack->shortLabel); - slAddHead(&miList, mi); - wigTrack = wigTrack->next; - } - } - -/* Make up item that will show gaps in this organism. */ -AllocVar(mi); - -mi->name = GAP_ITEM_LABEL; -mi->height = tl.fontHeight; -slAddHead(&miList, mi); - -/* Make up item for this organism. */ -mi = newMafItem(database, 0, lowerFirstChar); -slAddHead(&miList, mi); -speciesList = newSpeciesItems(track, tl.fontHeight); -/* Make items for other species */ -miList = slCat(speciesList, miList); - -slReverse(&miList); -return miList; -} - -static char *summarySetting(struct track *track) -/* Return the setting for the MAF summary table - * or NULL if none set */ -{ -return trackDbSetting(track->tdb, SUMMARY_VAR); -} - -static char *pairwiseSuffix(struct track *track) -/* Return the suffix for the wiggle tables for the pairwise alignments, - * or NULL if none set */ -{ -char *suffix = trackDbSetting(track->tdb, PAIRWISE_VAR); -if (suffix != NULL) - suffix = firstWordInLine(cloneString(suffix)); -return suffix; -} - -static int pairwiseWigHeight(struct track *track) -/* Return the height of a pairwise wiggle for this track, or 0 if n/a - * NOTE: set one pixel smaller than we actually want, to - * leave a border at the bottom of the wiggle. - */ -{ -char *words[2]; -int wordCount; -char *settings; -struct track *wigTrack = track->subtracks; -int pairwiseHeight = tl.fontHeight; -int consWigHeight = 0; - -settings = cloneString(trackDbSetting(track->tdb, PAIRWISE_HEIGHT)); -if (settings != NULL) - return(atoi(firstWordInLine(settings))); - -if (wigTrack) - { - consWigHeight = wigTotalHeight(wigTrack, tvFull); - pairwiseHeight = max(consWigHeight/3 - 1, pairwiseHeight); - } - -settings = cloneString(trackDbSetting(track->tdb, PAIRWISE_VAR)); -if (settings == NULL) - return pairwiseHeight; - -/* get height for pairwise wiggles */ -if ((wordCount = chopLine(settings, words)) > 1) - { - int settingsHeight = atoi(words[1]); - if (settingsHeight < tl.fontHeight) - pairwiseHeight = tl.fontHeight; - else if (settingsHeight > consWigHeight && consWigHeight > 0) - pairwiseHeight = consWigHeight; - else - pairwiseHeight = settingsHeight; - } -freez(&settings); -return pairwiseHeight; -} - -static char *getWigTablename(char *species, char *suffix) -/* generate tablename for wiggle pairwise: "<species>_<table>_wig" */ -{ -char table[64]; - -safef(table, sizeof(table), "%s_%s_wig", species, suffix); -return cloneString(table); -} - -static char *getMafTablename(char *species, char *suffix) -/* generate tablename for wiggle maf: "<species>_<table>" */ -{ -char table[64]; - -safef(table, sizeof(table), "%s_%s", species, suffix); -return cloneString(table); -} - -static boolean displayPairwise(struct track *track) -/* determine if tables are present for pairwise display */ -{ -return winBaseCount < MAF_SUMMARY_VIEW || isCustomTrack(track->table) || - pairwiseSuffix(track) || summarySetting(track); -} - -static boolean displayZoomedIn(struct track *track) -/* determine if mafs are loaded -- zoomed in display */ -{ -struct mafPriv *mp = getMafPriv(track); - -return mp->list != (char *)-1; -} - -static void markNotPairwiseItem(struct wigMafItem *mi) -{ - mi->ix = -1; -} -static boolean isPairwiseItem(struct wigMafItem *mi) -{ - return mi->ix != -1; -} - -static struct wigMafItem *loadPairwiseItems(struct track *track) -/* Make up items for modes where pairwise data are shown. - First an item for the score wiggle, then a pairwise item - for each "other species" in the multiple alignment. - These may be density plots (pack) or wiggles (full). - Return item list. Also set customPt with mafList if - zoomed in */ -{ -struct wigMafItem *miList = NULL, *speciesItems = NULL, *mi; -struct track *wigTrack = track->subtracks; -int scoreHeight = tl.fontHeight * 4; - -if (winBaseCount < MAF_SUMMARY_VIEW) - { - /* "close in" display uses actual alignments from file */ - struct mafPriv *mp = getMafPriv(track); - struct sqlConnection *conn, *conn2; - - if (mp->ct) - { - char *fileName = getCustomMafFile(track); - conn = hAllocConn(CUSTOM_TRASH); - conn2 = hAllocConn(CUSTOM_TRASH); - mp->list = wigMafLoadInRegion(conn, conn2, mp->ct->dbTableName, - chromName, winStart, winEnd, fileName); - hFreeConn(&conn); - hFreeConn(&conn2); - } - else - { - char *fileName = getTrackMafFile(track); // optional - conn = hAllocConn(database); - conn2 = hAllocConn(database); - mp->list = wigMafLoadInRegion(conn, conn2, track->table, - chromName, winStart, winEnd, fileName); - hFreeConn(&conn); - hFreeConn(&conn2); - } -#ifdef DEBUG - slSort(&mp->list, mafCmp); -#endif - } -while (wigTrack != NULL) - { - /* display score graph along with pairs only if a wiggle - * is provided */ - scoreHeight = wigTotalHeight(wigTrack, tvFull); - mi = scoreItem(scoreHeight, wigTrack->shortLabel); - /* mark this as not a pairwise item */ - markNotPairwiseItem(mi); - slAddHead(&miList, mi); - wigTrack = wigTrack->next; - } -if (displayPairwise(track)) - /* make up items for other organisms by scanning through - * all mafs and looking at database prefix to source. */ - { - speciesItems = newSpeciesItems(track, track->limitedVis == tvFull ? - pairwiseWigHeight(track) : - tl.fontHeight); - miList = slCat(speciesItems, miList); - } -slReverse(&miList); -return miList; -} - -static struct wigMafItem *loadWigMafItems(struct track *track, - boolean isBaseLevel) -/* Load up items */ -{ -struct wigMafItem *miList = NULL, *mi; -int scoreHeight = tl.fontHeight * 4; -struct track *wigTrack = track->subtracks; - -struct mafPriv *mp = getMafPriv(track); -mp->list = (char *)-1; /* no maf's loaded or attempted to load */ - -/* if we're out in summary view and rendering a custom - * track we force dense mode since we don't have - * a summary table (yet). */ -if ((winBaseCount >= MAF_SUMMARY_VIEW) && isCustomTrack(track->table)) - track->limitedVis = tvDense; - -/* Load up mafs and store in track so drawer doesn't have - * to do it again. */ -/* Make up tracks for display. */ -if (track->limitedVis == tvFull || track->limitedVis == tvPack) - { - if (isBaseLevel) - { - miList = loadBaseByBaseItems(track); - } - /* zoomed out */ - else - { - miList = loadPairwiseItems(track); - } - } -else if (track->limitedVis == tvSquish) - { - if (!wigTrack) - { - scoreHeight = tl.fontHeight * 4; - if (winBaseCount < MAF_SUMMARY_VIEW) - loadMafsToTrack(track); - /* not a real meausre of conservation, so don't label it so */ - miList = scoreItem(scoreHeight, ""); - } - else while (wigTrack) - { - /* have a wiggle */ - scoreHeight = wigTotalHeight(wigTrack, tvFull); - mi = scoreItem(scoreHeight, wigTrack->shortLabel); - slAddTail(&miList, mi); - wigTrack = wigTrack->next; - } - } -else - { - /* dense mode, zoomed out - show density plot, with track label */ - if (!wigTrack) - { - /* no wiggle -- use mafs if close in */ - if (winBaseCount < MAF_SUMMARY_VIEW) -#ifndef NOTYET - loadMafsToTrack(track); - AllocVar(miList); - miList->name = cloneString(track->shortLabel); - miList->height = tl.fontHeight; -#else - miList = loadPairwiseItems(track); - - /* remove components that aren't selected */ - struct wigMafItem *mil = miList; - struct hash *nameHash = newHash(5); - for(;mil; mil = mil->next) - hashStore(nameHash, mil->name); - - struct mafPriv *mp = getMafPriv(track); - struct mafAli *mafList = mp->list; - struct mafComp *mc; - - for(; mafList; mafList = mafList->next) - { - struct mafComp *prev = mafList->components; - - /* start after the master component */ - for(mc = mafList->components->next; mc; mc = mc->next) - { - char *ptr = strchr(mc->src, '.'); - if (ptr) - *ptr = 0; - char *ptr2 = hOrganism(mc->src); - *ptr2 = tolower(*ptr2); - if (!hashLookup(nameHash, ptr2)) - /* delete this component */ - prev->next = mc->next; - else - { - if (ptr) - *ptr = '.'; - prev = mc; - } - } - } - - /* label with the track name */ - miList->name = cloneString(track->shortLabel); - miList->next = NULL; -#endif /* NOTYET */ - } - else while (wigTrack) - { - AllocVar(mi); - mi->name = cloneString(wigTrack->shortLabel); - mi->height = tl.fontHeight + 1; - slAddTail(&miList, mi); - wigTrack = wigTrack->next; - } - } -return miList; -} - -static void wigMafLoad(struct track *track) -/* Load up maf tracks. What this will do depends on - * the zoom level and the display density. */ -{ -struct wigMafItem *miList = NULL; -struct track *wigTrack = track->subtracks; - -// Make sure visibility takes into account any composite track with multi-views -track->limitedVis = tvMin(track->visibility,limitedVisFromComposite(track)); -track->limitedVisSet = (track->limitedVis != tvHide && track->visibility != track->limitedVis); - -miList = loadWigMafItems(track, zoomedToBaseLevel); -track->items = miList; - -while (wigTrack != NULL) - // load wiggle subtrack items - { - /* update track visibility from parent track, - * since hgTracks will update parent vis before loadItems */ - wigTrack->visibility = track->visibility; - wigTrack->limitedVis = track->limitedVis; - wigTrack->loadItems(wigTrack); - wigTrack = wigTrack->next; - } -} - -static int wigMafTotalHeight(struct track *track, enum trackVisibility vis) -/* Return total height of maf track. */ -{ -struct wigMafItem *mi; -int total = 0,count=0; -for (mi = track->items; mi != NULL; mi = mi->next) - { - total += mi->height; - count++; - } - -track->height = total; -if (track->limitedVis == tvDense) - track->height=(tl.fontHeight+1)*count; // Evidence that track-height comes in as 9 but should be 10! -return track->height; -} - -static int wigMafItemHeight(struct track *track, void *item) -/* Return total height of maf track. */ -{ -struct wigMafItem *mi = item; -return mi->height; -} - -static void wigMafFree(struct track *track) -/* Free up maf items. */ -{ -struct mafPriv *mp = getMafPriv(track); -if (mp->list != NULL && mp->list != (char *)-1) - mafAliFreeList((struct mafAli **)&mp->list); -if (track->items != NULL) - wigMafItemFreeList((struct wigMafItem **)&track->items); -} - -static char *wigMafItemName(struct track *track, void *item) -/* Return name of maf level track. */ -{ -struct wigMafItem *mi = item; -return mi->name; -} - -static void processInserts(char *text, struct mafAli *maf, - struct hash *itemHash, - int insertCounts[], int baseCount) -/* Make up insert line from sequence of reference species. - It has a gap count at each displayed base position, and is generated by - counting up '-' chars in the sequence, where */ -{ -int i, baseIx = 0; -struct mafComp *mc; -char c; - -for (i=0; i < maf->textSize && baseIx < baseCount - 1; i++) - { - c = text[i]; - if (c == '-') - { - for (mc = maf->components; mc != NULL; mc = mc->next) - { - char buf[64]; - mafSrcDb(mc->src, buf, sizeof buf); - if (hashLookup(itemHash, buf) == NULL) - continue; - if (mc->text == NULL) - /* empty row annotation */ - continue; - if (mc->text[i] != '-') - { - insertCounts[baseIx]++; - break; - } - } - } - else - baseIx++; - } -} - - -static int processSeq(char *text, char *masterText, int textSize, - char *outLine, int offset, int outSize, - int *inserts, int insertCounts) -/* Add text to outLine, suppressing copy where there are dashes - * in masterText. This effectively projects the alignment onto - * the master genome. - * If no dash exists in this sequence, count up size - * of the insert and save in the line. - */ -{ -int i, outIx = 0, outPositions = 0; -int insertSize = 0, previousInserts = 0; -int previousBreaks = 0; - -outLine = outLine + offset + previousBreaks + (previousInserts * 2); -for (i=0; i < textSize /*&& outPositions < outSize*/; i++) - { - if (masterText[i] != '-') - { - if (insertSize != 0) - { - inserts[insertCounts++] = offset + outIx + 1; - insertSize = 0; - } - outLine[outIx++] = text[i]; - outPositions++; - } - else - { - /* gap in master (reference) sequence but not in this species */ - switch(text[i]) - { - case 'N': - case '-': - case '=': - case ' ': - break; - default: - insertSize++; - } - } - } - if (insertSize != 0) - { - inserts[insertCounts++] = offset + outIx + 1; - } -return insertCounts; -} - -static int drawScore(float score, int chromStart, int chromEnd, int seqStart, - double scale, struct hvGfx *hvg, int xOff, int yOff, - int height, Color color, enum trackVisibility vis) -/* Draw density plot or graph based on score. Return last X drawn */ -{ -int x1,x2,y,w; -int height1 = height-1; - -x1 = round((chromStart - seqStart)*scale); -x2 = round((chromEnd - seqStart)*scale); -w = x2-x1+1; -if (vis == tvFull) - { - y = score * height1; - hvGfxBox(hvg, x1 + xOff, yOff + height1 - y, w, y+1, color); - } -else - { - Color c; - int shade = (score * maxShade) + 1; - if (shade < 0) - shade = 0; - else if (shade > maxShade) - shade = maxShade; - c = shadesOfGray[shade]; - hvGfxBox(hvg, x1 + xOff, yOff, w, height1, c); - } -return xOff + x1 + w - 1; -} - -static void drawScoreSummary(struct mafSummary *summaryList, int height, - int seqStart, int seqEnd, - struct hvGfx *hvg, int xOff, int yOff, - int width, MgFont *font, - Color color, Color altColor, - enum trackVisibility vis, boolean chainBreaks) -/* Draw density plot or graph for summary maf scores */ -{ -struct mafSummary *ms; -double scale = scaleForPixels(width); -boolean isDouble = FALSE; -int x1, x2; -int w = 0; -int chromStart = seqStart; -int lastX; - -/* draw chain before first alignment */ -ms = summaryList; -if (chainBreaks && ms->chromStart > chromStart) - { - if (isContigOrTandem(ms->leftStatus[0]) || - ms->leftStatus[0] == MAF_INSERT_STATUS) - { - isDouble = (ms->leftStatus[0] == MAF_INSERT_STATUS); - x1 = xOff; - x2 = round((double)((int)ms->chromStart-1 - seqStart) * scale) + xOff; - w = x2 - x1; - if (w > 0) - drawMafChain(hvg, x1, yOff, w, height, isDouble); - } - else if (ms->leftStatus[0] == MAF_MISSING_STATUS ) - { - Color fuzz = shadesOfGray[1]; - - x1 = xOff; - x2 = round((double)((int)ms->chromStart-1 - seqStart) * scale) + xOff; - w = x2 - x1; - hvGfxBox(hvg, x1, yOff, w, height, fuzz); - } - } -for (ms = summaryList; ms != NULL; ms = ms->next) - { - lastX = drawScore(ms->score, ms->chromStart, ms->chromEnd, seqStart, - scale, hvg, xOff, yOff, height, color, vis); - - /* draw chain after alignment */ - if (chainBreaks && ms->chromEnd < seqEnd && ms->next != NULL) - { - if (isContigOrTandem(ms->rightStatus[0]) || - ms->rightStatus[0] == MAF_INSERT_STATUS) - { - isDouble = (ms->rightStatus[0] == MAF_INSERT_STATUS); - x1 = round((double)((int)ms->chromEnd+1 - seqStart) * scale) + xOff; - x2 = round((double)((int)ms->next->chromStart-1 - seqStart) * scale) - + xOff; - w = x2 - x1; - if (w == 1 && x1 == lastX) - continue; - if (w > 0); - drawMafChain(hvg, x1, yOff, w, height, isDouble); - } - else if (ms->rightStatus[0] == MAF_MISSING_STATUS ) - { - Color fuzz = shadesOfGray[2]; - - x1 = round((double)((int)ms->chromEnd+1 - seqStart) * scale) + xOff; - x2 = round((double)((int)ms->next->chromStart-1 - seqStart) * scale) + xOff ; - w = x2 - x1; - if (w == 1 && x1 == lastX) - continue; - if (w > 0) - hvGfxBox(hvg, x1, yOff, w, height, fuzz); - } - } - } -} - -static void drawScoreOverviewC(struct sqlConnection *conn, - char *tableName, int height, - int seqStart, int seqEnd, - struct hvGfx *hvg, int xOff, int yOff, - int width, MgFont *font, - Color color, Color altColor, - enum trackVisibility vis) -/* Draw density plot or graph for overall maf scores rather than computing - * by sections, for speed. Don't actually load the mafs -- just - * the scored refs from the table. - * TODO: reuse code in mafTrack.c - */ -{ -char **row; -int rowOffset; -struct sqlResult *sr = hRangeQuery(conn, tableName, chromName, - seqStart, seqEnd, NULL, &rowOffset); - -double scale = scaleForPixels(width); -while ((row = sqlNextRow(sr)) != NULL) - { - struct scoredRef ref; - scoredRefStaticLoad(row + rowOffset, &ref); - drawScore(ref.score, ref.chromStart, ref.chromEnd, seqStart, scale, - hvg, xOff, yOff, height, color, vis); - } -sqlFreeResult(&sr); -} - -static void drawScoreOverview(char *tableName, - int height, int seqStart, int seqEnd, - struct hvGfx *hvg, int xOff, int yOff, - int width, MgFont *font, - Color color, Color altColor, - enum trackVisibility vis) -{ -struct sqlConnection *conn = hAllocConn(database); - -drawScoreOverviewC(conn, tableName, height, seqStart, seqEnd, - hvg, xOff, yOff, width, font, color, altColor, vis); - -hFreeConn(&conn); -} - -static void drawScoreOverviewCT(char *tableName, - int height, int seqStart, int seqEnd, - struct hvGfx *hvg, int xOff, int yOff, - int width, MgFont *font, - Color color, Color altColor, - enum trackVisibility vis) -{ -struct sqlConnection *conn = hAllocConn(CUSTOM_TRASH); - -drawScoreOverviewC(conn, tableName, height, seqStart, seqEnd, - hvg, xOff, yOff, width, font, color, altColor, vis); - -hFreeConn(&conn); -} - - -static boolean drawPairsFromSummary(struct track *track, - int seqStart, int seqEnd, - struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, - Color color, enum trackVisibility vis) -{ -/* Draw pairwise display for this multiple alignment */ -char *summary; -struct wigMafItem *miList = track->items, *mi = miList; -struct sqlConnection *conn; -struct sqlResult *sr = NULL; -char **row = NULL; -int rowOffset = 0; -struct mafSummary *ms, *summaryList; -struct hash *componentHash = newHash(6); -struct hashEl *hel; -struct hashCookie cookie; -struct dyString *where = dyStringNew(256); -char *whereClause = NULL; -boolean useIrowChains = TRUE; -char option[64]; - -if (miList == NULL) - return FALSE; - -/* get summary table name from trackDb */ -if ((summary = summarySetting(track)) == NULL) - return FALSE; - -char *cfgPrefix = compositeViewControlNameFromTdb(track->tdb); - -safef(option, sizeof(option), "%s.%s", cfgPrefix, MAF_CHAIN_VAR); -compositeViewControlNameFree(&cfgPrefix); -if (cartVarExists(cart, option)) - useIrowChains = cartCgiUsualBoolean(cart, option, TRUE); -else - { - char *irowString = trackDbSetting(track->tdb, "irows"); - if (irowString && sameString(irowString, "off")) - useIrowChains = FALSE; - cartSetBoolean(cart, option, useIrowChains); - } - -/* Create SQL where clause that will load up just the - * summaries for the species that we are including. */ -conn = hAllocConn(database); -dyStringAppend(where, "src in ("); -for (mi = miList; mi != NULL; mi = mi->next) - { - if (!isPairwiseItem(mi)) - /* exclude non-species items (e.g. conservation wiggle */ - continue; - dyStringPrintf(where, "'%s'", mi->db); - if (mi->next != NULL) - dyStringAppend(where, ","); - } -dyStringAppend(where, ")"); -/* check for empty where clause */ -if (!sameString(where->string,"src in ()")) - whereClause = where->string; -sr = hOrderedRangeQuery(conn, summary, chromName, seqStart, seqEnd, - whereClause, &rowOffset); - -boolean hasFieldLeftStatus = hHasField(database, summary, "leftStatus"); - -/* Loop through result creating a hash of lists of maf summary blocks. - * The hash is keyed by species. */ -while ((row = sqlNextRow(sr)) != NULL) - { - if (hasFieldLeftStatus) - ms = mafSummaryLoad(row + rowOffset); - else - /* previous table schema didn't have status fields */ - ms = mafSummaryMiniLoad(row + rowOffset); - /* prune to fit in window bounds */ - if (ms->chromStart < seqStart) - ms->chromStart = seqStart; - if (ms->chromEnd > seqEnd) - ms->chromEnd = seqEnd; - if ((hel = hashLookup(componentHash, ms->src)) == NULL) - hashAdd(componentHash, ms->src, ms); - else - slAddHead(&(hel->val), ms); - } -sqlFreeResult(&sr); - -/* reverse summary lists */ -cookie = hashFirst(componentHash); -while ((hel = hashNext(&cookie)) != NULL) - slReverse(&hel->val); -hFreeConn(&conn); - -/* display pairwise items */ -for (mi = miList; mi != NULL; mi = mi->next) - { - if (mi->ix < 0) - /* ignore item for the score */ - continue; - summaryList = (struct mafSummary *)hashFindVal(componentHash, mi->db); - if (summaryList == NULL) - summaryList = (struct mafSummary *)hashFindVal(componentHash, mi->name); - - if (summaryList != NULL) - { - if (vis == tvFull) - { - hvGfxSetClip(hvg, xOff, yOff, width, 16); - drawScoreSummary(summaryList, mi->height, seqStart, seqEnd, hvg, - xOff, yOff, width, font, track->ixAltColor, - track->ixAltColor, tvFull, useIrowChains); - hvGfxUnclip(hvg); - } - else - { - /* pack */ - /* get maf table, containing pairwise alignments for this organism */ - /* display pairwise alignments in this region in dense format */ - hvGfxSetClip(hvg, xOff, yOff, width, mi->height); - drawScoreSummary(summaryList, mi->height, seqStart, seqEnd, hvg, - xOff, yOff, width, font, color, color, tvDense, - useIrowChains); - hvGfxUnclip(hvg); - } - } - yOff += mi->height; - } -return TRUE; -} - -static boolean drawPairsFromPairwiseMafScores(struct track *track, - int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, - int width, MgFont *font, Color color, enum trackVisibility vis) -/* Draw pairwise display for this multiple alignment */ -{ -char *suffix; -char *tableName; -Color pairColor; -struct track *wigTrack = track->subtracks; -int pairwiseHeight = pairwiseWigHeight(track); -struct wigMafItem *miList = track->items, *mi = miList; - -if (miList == NULL) - return FALSE; - -/* get pairwise table suffix from trackDb */ -suffix = pairwiseSuffix(track); - -if (vis == tvFull && !isCustomTrack(track->table)) - { - double minY = 50.0; - double maxY = 100.0; - - /* NOTE: later, remove requirement for wiggle */ - if (wigTrack == NULL) - return FALSE; - /* swap colors for pairwise wiggles */ - pairColor = wigTrack->ixColor; - wigTrack->ixColor = wigTrack->ixAltColor; - wigTrack->ixAltColor = pairColor; - wigSetCart(wigTrack, MIN_Y, (void *)&minY); - wigSetCart(wigTrack, MAX_Y, (void *)&maxY); - } - -/* display pairwise items */ -for (mi = miList; mi != NULL; mi = mi->next) - { - if (mi->ix < 0) - /* ignore item for the score */ - continue; - if (isCustomTrack(track->table)) - { - struct mafPriv *mp = getMafPriv(track); - drawScoreOverviewCT(mp->ct->dbTableName, mi->height, - seqStart, seqEnd, - hvg, xOff, yOff, width, font, color, color, vis); - hvGfxUnclip(hvg); - } - else if (vis == tvFull) - { - /* get wiggle table, of pairwise - for example, percent identity */ - tableName = getWigTablename(mi->name, suffix); - if (!hTableExists(database, tableName)) - tableName = getWigTablename(mi->db, suffix); - if (hTableExists(database, tableName)) - { - /* reuse the wigTrack for pairwise tables */ - wigTrack->track = tableName; - wigTrack->table = tableName; - wigTrack->loadItems(wigTrack); - wigTrack->height = wigTrack->lineHeight = wigTrack->heightPer = - pairwiseHeight - 1; - /* clip, but leave 1 pixel border */ - hvGfxSetClip(hvg, xOff, yOff, width, wigTrack->height); - wigTrack->drawItems(wigTrack, seqStart, seqEnd, hvg, xOff, yOff, - width, font, color, tvFull); - hvGfxUnclip(hvg); - } - else - { - /* no wiggle table for this -- compute a graph on-the-fly - from mafs */ - hvGfxSetClip(hvg, xOff, yOff, width, mi->height); - tableName = getMafTablename(mi->name, suffix); - if (!hTableExists(database, tableName)) - tableName = getMafTablename(mi->db, suffix); - if (hTableExists(database, tableName)) - drawScoreOverview(tableName, mi->height, seqStart, seqEnd, hvg, - xOff, yOff, width, font, track->ixAltColor, - track->ixAltColor, tvFull); - hvGfxUnclip(hvg); - } - /* need to add extra space between wiggles (for now) */ - mi->height = pairwiseHeight; - } - else - { - /* pack */ - /* get maf table, containing pairwise alignments for this organism */ - /* display pairwise alignments in this region in dense format */ - hvGfxSetClip(hvg, xOff, yOff, width, mi->height); - tableName = getMafTablename(mi->name, suffix); - if (!hTableExists(database, tableName)) - tableName = getMafTablename(mi->db, suffix); - if (hTableExists(database, tableName)) - drawScoreOverview(tableName, mi->height, seqStart, seqEnd, hvg, - xOff, yOff, width, font, color, color, tvDense); - hvGfxUnclip(hvg); - } - yOff += mi->height; - } -return TRUE; -} - -static boolean drawPairsFromMultipleMaf(struct track *track, - int seqStart, int seqEnd, - struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, - Color color, enum trackVisibility vis) -/* Draw pairwise display from maf of multiple alignment. - * Extract pairwise alignments from maf and rescore. - * This is used only when zoomed-in. - */ -{ -struct wigMafItem *miList = track->items, *mi = miList; -int graphHeight = 0; -Color pairColor = (vis == tvFull ? track->ixAltColor : color); -boolean useIrowChains = TRUE; -char option[64]; - -struct mafPriv *mp = getMafPriv(track); -if (miList == NULL || mp->list == NULL) - return FALSE; - -char *cfgPrefix = compositeViewControlNameFromTdb(track->tdb); - -safef(option, sizeof(option), "%s.%s", cfgPrefix, MAF_CHAIN_VAR); -compositeViewControlNameFree(&cfgPrefix); -if (cartVarExists(cart, option)) - useIrowChains = cartCgiUsualBoolean(cart, option, TRUE); -else - { - char *irowString = trackDbSetting(track->tdb, "irows"); - if (irowString && sameString(irowString, "off")) - useIrowChains = FALSE; - cartSetBoolean(cart, option, useIrowChains); - } - -if (vis == tvFull) - graphHeight = pairwiseWigHeight(track); - -/* display pairwise items */ -for (mi = miList; mi != NULL; mi = mi->next) - { - struct mafAli *mafList = NULL, *maf, *pairMaf; - struct mafComp *mcThis, *mcPair = NULL, *mcMaster = NULL; - - if (mi->ix < 0) - /* ignore item for the score */ - continue; - - /* using maf sequences from file */ - /* create pairwise maf list from the multiple maf */ - struct mafPriv *mp = getMafPriv(track); - for (maf = mp->list; maf != NULL; maf = maf->next) - { - if ((mcThis = mafMayFindCompSpecies(maf, mi->db, '.')) == NULL) - continue; - //if (mcPair->srcSize != 0) - // TODO: replace with a cloneMafComp() - AllocVar(mcPair); - mcPair->src = cloneString(mcThis->src); - mcPair->srcSize = mcThis->srcSize; - mcPair->strand = mcThis->strand; - mcPair->start = mcThis->start; - mcPair->size = mcThis->size; - mcPair->text = cloneString(mcThis->text); - mcPair->leftStatus = mcThis->leftStatus; - mcPair->leftLen = mcThis->leftLen; - mcPair->rightStatus = mcThis->rightStatus; - mcPair->rightLen = mcThis->rightLen; - - mcThis = mafFindCompSpecies(maf, database, '.'); - AllocVar(mcMaster); - mcMaster->src = cloneString(mcThis->src); - mcMaster->srcSize = mcThis->srcSize; - mcMaster->strand = mcThis->strand; - mcMaster->start = mcThis->start; - mcMaster->size = mcThis->size; - mcMaster->text = cloneString(mcThis->text); - mcMaster->next = mcPair; - - AllocVar(pairMaf); - pairMaf->components = mcMaster; - pairMaf->textSize = maf->textSize; - slAddHead(&mafList, pairMaf); - } - slReverse(&mafList); - - /* compute a graph or density on-the-fly from mafs */ - hvGfxSetClip(hvg, xOff, yOff, width, mi->height); - drawMafRegionDetails(mafList, mi->height, seqStart, seqEnd, hvg, xOff, yOff, - width, font, pairColor, pairColor, vis, FALSE, - useIrowChains); - hvGfxUnclip(hvg); - - /* need to add extra space between graphs ?? (for now) */ - if (vis == tvFull) - mi->height = graphHeight; - - yOff += mi->height; - mafAliFreeList(&mafList); - } -return TRUE; -} - -static boolean wigMafDrawPairwise(struct track *track, int seqStart, int seqEnd, - struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, - Color color, enum trackVisibility vis) -/* Draw pairwise display for this multiple alignment - * When zoomed in, use on-the-fly scoring of alignments extracted from multiple - * When zoomed out: - * if "pairwise" setting is on, use pairwise tables (maf or wiggle) - * <species>_<suffix> for maf, <species>_<suffix>_wig for wiggle - * For full mode, display graph. - * for pack mode, display density plot. - * if "summary" setting is on, use maf summary table - * (saves space, and performs better) */ -{ - if (displayZoomedIn(track)) - return drawPairsFromMultipleMaf(track, seqStart, seqEnd, hvg, - xOff, yOff, width, font, color, vis); - if (isCustomTrack(track->table) || pairwiseSuffix(track)) - return drawPairsFromPairwiseMafScores(track, seqStart, seqEnd, hvg, - xOff, yOff, width, font, color, vis); - if (summarySetting(track)) - return drawPairsFromSummary(track, seqStart, seqEnd, hvg, - xOff, yOff, width, font, color, vis); - return FALSE; -} - -static void alternateBlocksBehindChars(struct hvGfx *hvg, int x, int y, - int width, int height, int charWidth, int charCount, - int stripeCharWidth, Color a, Color b) -/* Draw blocks that alternate between color a and b. */ -{ -int x1,x2 = x + width; -int color = a; -int i; -for (i=0; i<charCount; i += stripeCharWidth) - { - x1 = i * width / charCount; - x2 = (i+stripeCharWidth) * width/charCount; - hvGfxBox(hvg, x1+x, y, x2-x1, height, color); - if (color == a) - color = b; - else - color = a; - } -} - -void alignSeqToUpperN(char *line) -/* force base chars to upper, ignoring insert counts */ -{ -int i; -for (i=0; line[i] != 0; i++) - line[i] = toupper(line[i]); -} - -void complementUpperAlignSeq(DNA *dna, int size) -/* Complement DNA (not reverse), ignoring insert counts. - * Assumed to be all upper case bases */ -{ -int i; -for (i = 0; i < size; i++, dna++) - { - if (*dna == 'A') - *dna = 'T'; - else if (*dna == 'C') - *dna = 'G'; - else if (*dna == 'G') - *dna = 'C'; - else if (*dna == 'T') - *dna = 'A'; - } -} - -void reverseForStrand(DNA *dna, int length, char strand, bool alreadyComplemented) -{ -if (strand == '-') - { - if (alreadyComplemented) - reverseBytes(dna, length); - else - reverseComplement(dna, length); - } -else - { - if (alreadyComplemented) - complement(dna, length); - } -} - -#define ISGAP(x) (((x) == '=') || (((x) == '-'))) -#define ISN(x) ((x) == 'N') -#define ISSPACE(x) ((x) == ' ') -#define ISGAPSPACEORN(x) (ISSPACE(x) || ISGAP(x) || ISN(x)) - -static AA lookupAndCheckCodon(char *codon) -{ -AA retValue; - -if ((retValue = lookupCodon(codon)) == 0) - return '*'; - -return retValue; -} - -static void translateCodons(struct sqlConnection *conn, - struct sqlConnection *conn2, char *tableName, char *compName, - DNA *dna, int start, int length, int frame, char strand, - int prevEnd, int nextStart, bool alreadyComplemented, - int x, int y, int width, int height, struct hvGfx *hvg, char *mafFile) -{ -int size = length; -DNA *ptr; -int color; -int end = start + length; -int x1; -char masterChrom[128]; -struct mafAli *ali, *sub = NULL; -struct mafComp *comp = NULL; -int mult = 1; -char codon[4]; -int fillBox = FALSE; - -safef(masterChrom, sizeof(masterChrom), "%s.%s", database, chromName); - -dna += start; - -reverseForStrand(dna, length, strand, alreadyComplemented); - -ptr = dna; -color = shadesOfSea[0]; - -mult = 0; -if (frame && (prevEnd == -1)) - { - switch(frame) - { - case 1: - if (0)//!( ISGAPSPACEORN(ptr[0]) ||ISGAPSPACEORN(ptr[1]))) - { - fillBox = TRUE; - *ptr++ = 'X'; - *ptr++ = 'X'; - mult = 2; - } - else - { - reverseForStrand(ptr, 2, strand, alreadyComplemented); - ptr +=2; - } - length -=2; - break; - case 2: - if (0)//!( ISGAPSPACEORN(ptr[0]))) - { - fillBox = TRUE; - *ptr++ = 'X'; - length -=1; - mult = 1; - } - else - { - reverseForStrand(ptr, 1, strand, alreadyComplemented); - ptr++; - } - length -=1; - break; - } - } -else if (frame && (prevEnd != -1)) - { - memset(codon, 0, sizeof(codon)); - switch(frame) - { - case 1: - ali = mafLoadInRegion2(conn, conn2, tableName, chromName, prevEnd , prevEnd + 1, mafFile ); - if (ali != NULL) - { - sub = mafSubset(ali, masterChrom, prevEnd , prevEnd + 1 ); - comp = mafMayFindCompSpecies(sub, compName, '.'); - } - if (comp && comp->text && (!(ISGAPSPACEORN(comp->text[0]) ||ISGAPSPACEORN(ptr[0]) ||ISGAPSPACEORN(ptr[1])))) - { - if (strand == '-') - complement(comp->text, 1); - codon[0] = comp->text[0]; - codon[1] = ptr[0]; - codon[2] = ptr[1]; - fillBox = TRUE; - mult = 2; - *ptr++ = ' '; - *ptr++ = lookupAndCheckCodon(codon); - } - else - ptr+=2; - length -= 2; - break; - case 2: - if (strand == '-') - { - ali = mafLoadInRegion2(conn, conn2, tableName, chromName, - prevEnd, prevEnd + 2, mafFile); - if (ali != NULL) - sub = mafSubset(ali, masterChrom, prevEnd, prevEnd + 2 ); - } - else - { - ali = mafLoadInRegion2(conn, conn2, tableName, chromName, - prevEnd - 1, prevEnd + 1, mafFile); - if (ali != NULL) - sub = mafSubset(ali, masterChrom, prevEnd - 1, prevEnd + 1); - } - if (sub != NULL) - comp = mafMayFindCompSpecies(sub, compName, '.'); - if (comp && comp->text && (!(ISGAPSPACEORN(comp->text[0])||ISGAPSPACEORN(comp->text[1]) ||ISGAPSPACEORN(*ptr)))) - { - if (strand == '-') - reverseComplement(comp->text, 2); - codon[0] = comp->text[0]; - codon[1] = comp->text[1]; - codon[2] = *ptr; - fillBox = TRUE; - mult = 1; - *ptr++ = lookupAndCheckCodon(codon); - } - else - ptr++; - length -= 1; - break; - } - } -if (fillBox) - { - if (strand == '-') - { - x1 = x + ( end - ( 5 - frame) ) * width / winBaseCount; - } - else - { - x1 = x + (start - 2) * width / winBaseCount; - } - hvGfxBox(hvg, x1, y, mult*width/winBaseCount + 1 , height, color); - } - -for (;length > 2; ptr +=3 , length -=3) - { - if (!(ISGAPSPACEORN(ptr[0]) || ISGAPSPACEORN(ptr[1]) || ISGAPSPACEORN(ptr[2]) )) - { - ptr[1] = lookupAndCheckCodon(ptr); - ptr[0] = ' '; - ptr[2] = ' '; - - if (strand == '-') - { - x1 = x + ( start + length - 3 - 2) * width / winBaseCount; - } - else - { - x1 = x + (end - length - 2) * width / winBaseCount; - } - - if (color == shadesOfSea[0]) - color = shadesOfSea[1]; - else - color = shadesOfSea[0]; - hvGfxBox(hvg, x1, y, 3*width/winBaseCount + 1 , height, color); - } - } - -if (length && (nextStart != -1)) - { - char codon[4]; - int mult = 1; - boolean fillBox = FALSE; - - memset(codon, 0, sizeof(codon)); - sub = NULL; - - if (strand == '-') - { - ali = mafLoadInRegion2(conn, conn2, tableName, chromName, - nextStart - 2 + length, nextStart + 1, mafFile ); - if (ali != NULL) - sub = mafSubset(ali, masterChrom, - nextStart - 2 + length, nextStart + 1); - } - else - { - ali = mafLoadInRegion2(conn, conn2, tableName, chromName, - nextStart , nextStart + 2, mafFile ); - if (ali != NULL) - sub = mafSubset(ali, masterChrom, nextStart , nextStart + 2); - } - if (sub != NULL) - comp = mafMayFindCompSpecies(sub, compName, '.'); - if (sub && comp && comp->text) - { - switch(length) - { - case 2: - if (strand == '-') - complement(comp->text, 1); - codon[0] = *ptr; - codon[1] = *(1 + ptr); - codon[2] = *comp->text; - - if (!(ISGAPSPACEORN(codon[0]) ||ISGAPSPACEORN(codon[1]) ||ISGAPSPACEORN(codon[2]))) - { - fillBox = TRUE; - *ptr++ = ' '; - *ptr++ = lookupAndCheckCodon(codon); - mult = 2; - } - break; - case 1: - if (strand == '-') - reverseComplement(comp->text, 2); - codon[0] = *ptr; - codon[1] = comp->text[0]; - codon[2] = comp->text[1]; - if (!(ISGAPSPACEORN(codon[0]) ||ISGAPSPACEORN(codon[1]) ||ISGAPSPACEORN(codon[2]))) - { - *ptr++ = lookupAndCheckCodon(codon); - fillBox = TRUE; - } - break; - } - if (fillBox) - { - if (strand == '-') - { - x1 = x + ( start - 2 ) * width / winBaseCount; - } - else - { - x1 = x + (end - length - 2) * width / winBaseCount; - } - if (color == shadesOfSea[0]) - color = shadesOfSea[1]; - else - color = shadesOfSea[0]; - hvGfxBox(hvg, x1, y, mult*width/winBaseCount + 1 , height, color); - } - } - } -else if (length) /* broken frame, just show nucs */ - { - if (strand == '-') - { - if (!alreadyComplemented) - complement(ptr, length); - } - else - { - if (alreadyComplemented) - complement(ptr, length); - } - } - -if (strand == '-') - reverseBytes(dna, size); -} - -static int wigMafDrawBases(struct track *track, int seqStart, int seqEnd, - struct hvGfx *hvg, int xOff, int yOff, int width, - MgFont *font, Color color, enum trackVisibility vis, - struct wigMafItem *miList) -/* Draw base-by-base view, return new Y offset. */ -{ -struct wigMafItem *mi; -struct mafAli *mafList, *maf, *sub; -struct mafComp *mc, *mcMaster; -int lineCount = slCount(miList); -char **lines = NULL, *selfLine, *insertLine; -int *insertCounts; -int i, x = xOff, y = yOff; -struct dnaSeq *seq = NULL; -struct hash *miHash = newHash(9); -struct hash *srcHash = newHash(0); -char dbChrom[64]; -char buf[1024]; -char option[64]; -int alignLineLength = winBaseCount * 2; - /* doubled to allow space for insert counts */ -boolean complementBases = cartUsualBooleanDb(cart, database, COMPLEMENT_BASES_VAR, FALSE); -bool dots = FALSE; /* configuration option */ -/* this line must be longer than the longest base-level display */ -char noAlignment[2000]; -boolean useIrowChains = TRUE; -int offset; -char *framesTable = NULL; -char *defaultCodonSpecies = cartUsualString(cart, SPECIES_CODON_DEFAULT, NULL); -char *codonTransMode = NULL; -boolean startSub2 = FALSE; - -int mafOrig = 0; -int mafOrigOffset = 0; -char query[256]; -struct mafPriv *mp = getMafPriv(track); -char *mafFile = NULL; -struct sqlConnection *conn2 = NULL; -struct sqlConnection *conn3 = NULL; -char *tableName = NULL; - -if (mp->ct != NULL) - { - conn2 = hAllocConn(CUSTOM_TRASH); - conn3 = hAllocConn(CUSTOM_TRASH); - tableName = mp->ct->dbTableName; - mafFile = getCustomMafFile(track); - } -else - { - conn2 = hAllocConn(database); - conn3 = hAllocConn(database); - tableName = track->table; - mafFile = getTrackMafFile(track); // optional - } - -if (hIsGsidServer()) - { - /* decide the value of mafOrigOffset to be used to display xxAaMaf tracks. */ - struct sqlConnection *conn = hAllocConn(database); - safef(query, sizeof(query), "select chromStart from %s", track->table); - mafOrig = atoi(sqlNeedQuickString(conn, query)); - mafOrigOffset = (mafOrig % 3) - 1; - /* offset has to be non-negative */ - if (mafOrigOffset < 0) mafOrigOffset = mafOrigOffset +3; - - hFreeConn(&conn); - } - -if (defaultCodonSpecies == NULL) - defaultCodonSpecies = trackDbSetting(track->tdb, "speciesCodonDefault"); - -if (defaultCodonSpecies == NULL) - defaultCodonSpecies = database; - -if (seqStart > 2) - { - startSub2 = TRUE; - seqStart -=2; - } -seqEnd +=2; -if (seqEnd > seqBaseCount) - seqEnd = seqBaseCount; - -char *cfgPrefix = compositeViewControlNameFromTdb(track->tdb); - -safef(option, sizeof(option), "%s.%s", cfgPrefix, MAF_DOT_VAR); -if (cartVarExists(cart, option)) - { - dots = cartCgiUsualBoolean(cart, option, FALSE); - } -else - { - char *dotString = trackDbSetting(track->tdb, MAF_DOT_VAR); - if (dotString && sameString(dotString, "on")) - { - dots = TRUE; - cartSetBoolean(cart, option, TRUE); - } - } - -safef(buf, sizeof(buf), "%s.frames",/*cfgPrefix*/track->track); -if (cartVarExists(cart, buf)) - framesTable = cartUsualString(cart, buf, NULL); -else - framesTable = trackDbSetting(track->tdb, "frames"); - -if (framesTable) - { - safef(buf, sizeof(buf), "%s.codons",cfgPrefix); - codonTransMode = cartUsualString(cart, buf, "codonDefault"); - if (sameString("codonNone", codonTransMode)) - framesTable = NULL; - } - -boolean newTableType = FALSE; - -if (framesTable != NULL) - newTableType = hHasField(database, framesTable, "isExonStart"); - -/* initialize "no alignment" string to o's */ -for (i = 0; i < sizeof noAlignment - 1; i++) - noAlignment[i] = UNALIGNED_SEQ; - - -safef(option, sizeof(option), "%s.%s", cfgPrefix, MAF_CHAIN_VAR); -if (cartVarExists(cart, option)) - useIrowChains = cartCgiUsualBoolean(cart, option, TRUE); -else - { - char *irowString = trackDbSetting(track->tdb, "irows"); - if (irowString && sameString(irowString, "off")) - useIrowChains = FALSE; - cartSetBoolean(cart, option, useIrowChains); - } - -/* Allocate a line of characters for each item. */ -AllocArray(lines, lineCount); -lines[0] = needMem(alignLineLength); -for (i=1; i<lineCount; ++i) - { - lines[i] = needMem(alignLineLength); - memset(lines[i], ' ', alignLineLength - 1); - } - -/* Give nice names to first two. */ -insertLine = lines[0]; -selfLine = lines[1]; - -/* Allocate a line for recording gap sizes in reference */ -AllocArray(insertCounts, alignLineLength); - -/* Load up self-line with DNA */ -seq = hChromSeqMixed(database, chromName, seqStart , seqEnd); -memcpy(selfLine, seq->dna, winBaseCount + 4); -//toUpperN(selfLine, winBaseCount); -freeDnaSeq(&seq); - -/* Make hash of species items keyed by database. */ -i = 0; -for (mi = miList; mi != NULL; mi = mi->next) - { - mi->ix = i++; - if (mi->db != NULL) - hashAdd(miHash, mi->db, mi); - } - -/* Go through the mafs saving relevant info in lines. */ -mafList = mp->list; -safef(dbChrom, sizeof(dbChrom), "%s.%s", database, chromName); - -for (maf = mafList; maf != NULL; maf = maf->next) - { - int mafStart; - /* get info about sequences from full alignment, - for use later, when determining if sequence is unaligned or missing */ - for (mc = maf->components; mc != NULL; mc = mc->next) - if (!hashFindVal(srcHash, mc->src)) - hashAdd(srcHash, mc->src, maf); - - mcMaster = mafFindComponent(maf, dbChrom); - mafStart = mcMaster->start; - /* get portion of maf in this window */ - if (startSub2) - sub = mafSubset(maf, dbChrom, winStart - 2, winEnd + 2); - else - sub = mafSubset(maf, dbChrom, winStart , winEnd + 2); - if (sub != NULL) - { - int subStart,subEnd; - int lineOffset, subSize; - int startInserts = 0; - char *ptr; - - /* process alignment for reference ("master") species */ - for(ptr = mcMaster->text; *ptr == '-'; ptr++) - startInserts++; - - mcMaster = mafFindComponent(sub, dbChrom); - if (mcMaster->strand == '-') - mafFlipStrand(sub); - subStart = mcMaster->start; - subEnd = subStart + mcMaster->size; - subSize = subEnd - subStart; - lineOffset = subStart - seqStart; - processInserts(mcMaster->text, sub, miHash, - &insertCounts[lineOffset], subSize); - insertCounts[lineOffset] = max(insertCounts[lineOffset],startInserts); - - /* fill in bases for each species */ - for (mi = miList; mi != NULL; mi = mi->next) - { - char *seq; - bool needToFree = FALSE; - int size = sub->textSize; - if (mi->ix == 1) - /* reference */ - continue; - if (mi->db == NULL) - /* not a species line -- it's the gaps line, or... */ - continue; - if ((mc = mafMayFindCompSpecies(sub, mi->db, '.')) == NULL) - continue; - if (mafStart == subStart) - { - if (mc->size && mc->leftStatus == MAF_INSERT_STATUS && (*mc->text != '-') && - !((lineOffset) && (((lines[mi->ix][lineOffset-1]) == '=') || (lines[mi->ix][lineOffset-1]) == '-'))) - { - insertCounts[lineOffset] = max(insertCounts[lineOffset],mc->leftLen); - mi->inserts[mi->insertsSize] = (subStart - seqStart)+ 1; - mi->insertsSize++; - } - } - if (startInserts) - { - struct mafComp *mc1; - if (((mc1 = mafMayFindCompSpecies(maf, mi->db, '.')) != NULL) && - ((mc1->text) && (countNonDash(mc1->text, startInserts) > 0))) - { - mi->inserts[mi->insertsSize] = (subStart - seqStart)+ 1; - mi->insertsSize++; - } - } - seq = mc->text; - if ( mc->text == NULL ) - { - /* if no alignment here, but MAF annotation indicates continuity - * of flanking alignments, fill with dashes or ='s */ - if (!useIrowChains) - continue; - if (isContigOrTandem(mc->leftStatus) && - isContigOrTandem(mc->rightStatus)) - { - char fill = '-'; - seq = needMem(size+1); - needToFree = TRUE; - memset(seq, fill, size); - } - else if (mc->leftStatus == MAF_INSERT_STATUS && mc->rightStatus == MAF_INSERT_STATUS) - { - char fill = MAF_DOUBLE_GAP; - seq = needMem(size+1); - needToFree = TRUE; - memset(seq, fill, size); - } - else if (mc->leftStatus == MAF_MISSING_STATUS && mc->rightStatus == MAF_MISSING_STATUS) - { - char fill = 'N'; - seq = needMem(size+1); - needToFree = TRUE; - memset(seq, fill, size); - } - else - continue; - } - - if (((mc->leftStatus == MAF_NEW_STATUS || - mc->rightStatus == MAF_NEW_STATUS ) - || (mc->leftStatus == MAF_NEW_NESTED_STATUS || - mc->rightStatus == MAF_NEW_NESTED_STATUS ))) - { - int i; - char *p; - seq = needMem(size+1); - needToFree = TRUE; - for (p = seq, i = 0; i < size; p++, i++) - *p = ' '; - p = seq; - if (mc->text != NULL) - strcpy(p, mc->text); - if (mc->leftStatus == MAF_NEW_STATUS) - { - char *m = mcMaster->text; - if (mafStart == subStart) - mi->seqEnds[mi->seqEndsSize] = (subStart - seqStart) + 1; - while(*p == '-') - { - if ((*m++ != '-') && (mafStart == subStart)) - mi->seqEnds[mi->seqEndsSize]++; - *p++ = ' '; - } - - if (mafStart == subStart) - mi->seqEndsSize++; - } - if (mc->leftStatus == MAF_NEW_NESTED_STATUS) - { - char *m = mcMaster->text; - if (mafStart == subStart) - mi->brackStarts[mi->brackStartsSize] = (subStart - seqStart)+ 1; - while(*p == '-') - { - *p++ = '='; - if ((*m++ != '-') && (mafStart == subStart)) - mi->brackStarts[mi->brackStartsSize]++; - } - if (mafStart == subStart) - mi->brackStartsSize++; - } - if (mc->rightStatus == MAF_NEW_NESTED_STATUS) - { - char *p = seq + size - 1; - char *m = mcMaster->text + size - 1; - if (subEnd <= seqEnd) - mi->brackEnds[mi->brackEndsSize] = (subStart - seqStart)+ subSize + 1; - while(*p == '-') - { - if ((*m-- != '-') && (subEnd <= seqEnd)) - mi->brackEnds[mi->brackEndsSize]--; - *p-- = '='; - } - if (subEnd <= seqEnd) - mi->brackEndsSize++; - } - if (mc->rightStatus == MAF_NEW_STATUS) - { - char *p = seq + size - 1; - char *m = mcMaster->text + size - 1; - - if (mc->size && ((subEnd <= seqEnd))) - mi->seqEnds[mi->seqEndsSize] = (subStart - seqStart)+ subSize + 1; - while(*p == '-') - { - if ((*m-- != '-') && (mc->size && (subEnd <= seqEnd))) - mi->seqEnds[mi->seqEndsSize]--; - *p-- = ' '; - } - if (mc->size && ((subEnd <= seqEnd))) - mi->seqEndsSize++; - } - } - if (mc->text && ((mc->leftStatus == MAF_MISSING_STATUS))) - { - char *p = seq; - while(*p == '-') - *p++ = 'N'; - } - if (mc->text && ((mc->leftStatus == MAF_INSERT_STATUS))) - { - char *p = seq; - while(*p == '-') - *p++ = '='; - } - if (mc->text && ((mc->rightStatus == MAF_MISSING_STATUS))) - { - char *p = seq + size - 1; - while(*p == '-') - *p-- = 'N'; - } - if (mc->text && ((mc->rightStatus == MAF_INSERT_STATUS))) - { - char *m = mcMaster->text + size - 1; - char *p = seq + size - 1; - while((*p == '-') || (*m == '-')) - { - *p-- = '='; - m--; - } - } - - mi->insertsSize = processSeq(seq, mcMaster->text, size, lines[mi->ix], lineOffset, subSize, - mi->inserts, mi->insertsSize); - if (needToFree) - freeMem(seq); - } - } - mafAliFree(&sub); - } -/* draw inserts line */ -mi = miList; - -for(offset=startSub2*2; (offset < alignLineLength) && (offset < winBaseCount + startSub2 * 2); offset++) - { - int x1, x2; - - x1 = (offset - startSub2 * 2) * width/winBaseCount; - x2 = ((offset - startSub2 * 2)+1) * width/winBaseCount - 1; - if (insertCounts[offset] != 0) - { - struct dyString *label = newDyString(20); - int haveRoomFor = (width/winBaseCount)/tl.mWidth; - - /* calculate number of AAs instead of bases if it is wigMafProt */ - if (strstr(track->tdb->type, "wigMafProt")) - { - dyStringPrintf(label, "%d",insertCounts[offset]/3); - } - else - { - dyStringPrintf(label, "%d",insertCounts[offset]); - } - - if (label->stringSize > haveRoomFor) - { - dyStringClear(label); - dyStringPrintf(label, "%c",(insertCounts[offset] % 3) == 0 ? '*' : '+'); - } - hvGfxTextCentered(hvg, x1+x - (width/winBaseCount)/2, y, x2-x1, mi->height, - getOrangeColor(), font, label->string); - dyStringFree(&label); - } - } -y += mi->height; - -/* draw alternating colors behind base-level alignments */ - { - int alternateColorBaseCount, alternateColorBaseOffset; - safef(buf, sizeof(buf), "%s.%s", cfgPrefix, BASE_COLORS_VAR); - alternateColorBaseCount = cartCgiUsualInt(cart, buf, 0); - safef(buf, sizeof(buf), "%s.%s", cfgPrefix, BASE_COLORS_OFFSET_VAR); - alternateColorBaseOffset = cartCgiUsualInt(cart, buf, 0); - if (alternateColorBaseCount != 0) - { - int baseWidth = spreadStringCharWidth(width, winBaseCount); - int colorX = x + alternateColorBaseOffset * baseWidth; - alternateBlocksBehindChars(hvg, colorX, y-1, width, - mi->height*(lineCount-1), tl.mWidth, winBaseCount, - alternateColorBaseCount, shadesOfSea[0], MG_WHITE); - } - } -compositeViewControlNameFree(&cfgPrefix); - -/* draw base-level alignments */ -for (mi = miList->next, i=1; mi != NULL && mi->db != NULL; mi = mi->next, i++) - { - char *line; - - line = lines[i]; - /* TODO: leave lower case in to indicate masking ? - * NOTE: want to make sure that all sequences are soft-masked - * if we do this */ - /* HAVE DONE: David doesn't like lower case by default - * TODO: casing based on quality values ?? */ - alignSeqToUpperN(line); - if (complementBases) - { - complement(line, strlen(line)); - } - /* draw sequence letters for alignment */ - hvGfxSetClip(hvg, x, y-1, width, mi->height); - - if (framesTable != NULL) - { - int rowOffset; - char **row; - struct sqlConnection *conn = hAllocConn(database); - struct sqlResult *sr; - char extra[512]; - boolean found = FALSE; - - if (sameString("codonDefault", codonTransMode)) - { - safef(extra, sizeof(extra), "src='%s'",defaultCodonSpecies); - - found = TRUE; - } - else if (sameString("codonFrameDef", codonTransMode)) - { - safef(extra, sizeof(extra), "src='%s'",mi->db); - - found = FALSE; - } - else if (sameString("codonFrameNone", codonTransMode)) - { - safef(extra, sizeof(extra), "src='%s'",mi->db); - - found = TRUE; - } - else - errAbort("unknown codon translation mode %s",codonTransMode); -tryagain: - sr = hRangeQuery(conn, framesTable, chromName, seqStart, seqEnd, extra, &rowOffset); - while ((row = sqlNextRow(sr)) != NULL) - { - struct mafFrames mf; - int start, end, w; - int frame; - - found = TRUE; - if (newTableType) - mafFramesStaticLoad(row + rowOffset, &mf); - else - mafFramesStaticLoadOld(row + rowOffset, &mf); - - if (mf.chromStart < seqStart) - start = 0; - else - start = mf.chromStart-seqStart; - frame = mf.frame; - if (mf.strand[0] == '-') - { - if (mf.chromEnd > seqEnd) - frame = (frame + mf.chromEnd-seqEnd ) % 3; - } - else - { - if (mf.chromStart < seqStart) - frame = (frame + seqStart-mf.chromStart ) % 3; - } - - end = mf.chromEnd > seqEnd ? seqEnd - seqStart : mf.chromEnd - seqStart; - w= end - start; - - translateCodons(conn2, conn3, tableName, mi->db, line, start , - w, frame, mf.strand[0],mf.prevFramePos,mf.nextFramePos, - complementBases, x, y, width, mi->height, hvg, mafFile); - - } - sqlFreeResult(&sr); - - if (!found) - { - /* try the default species */ - safef(extra, sizeof(extra), "src='%s'",defaultCodonSpecies); - - found = TRUE; /* don't try again */ - goto tryagain; - } - - hFreeConn(&conn); - } - - if (startSub2) - { - if (strstr(track->tdb->type, "wigMafProt")) - { - spreadAlignStringProt(hvg, x, y, width, mi->height-1, color, - font, &line[2], &selfLine[2], winBaseCount, dots, FALSE, seqStart, mafOrigOffset); - } - else - { - /* make sure we have bases to display before printing them */ - if (strlen(line) > 2) - spreadAlignString(hvg, x, y, width, mi->height-1, color, - font, &line[2], &selfLine[2], winBaseCount, dots, FALSE); - } - } - else - spreadAlignString(hvg, x, y, width, mi->height-1, color, - font, line, selfLine, winBaseCount, dots, FALSE); - for(offset = 0; offset < mi->seqEndsSize; offset++) - { - int x1; - - x1 = x + (mi->seqEnds[offset] -1 - startSub2 * 2) * width/winBaseCount; - hvGfxBox(hvg, x1, y-1, 1, mi->height-1, getChromBreakBlueColor()); - } - for(offset = 0; offset < mi->insertsSize; offset++) - { - int x1; - - x1 = x + (mi->inserts[offset] -1 - startSub2 * 2) * width/winBaseCount; - hvGfxBox(hvg, x1, y-1, 1, mi->height-1, getOrangeColor()); - } - for(offset = 0; offset < mi->brackStartsSize; offset++) - { - int x1; - - x1 = x + (mi->brackStarts[offset] -1- startSub2 * 2) * width/winBaseCount; - hvGfxBox(hvg, x1, y-1, 2, 1, getChromBreakGreenColor()); - hvGfxBox(hvg, x1, y-1, 1, mi->height-1, getChromBreakGreenColor()); - hvGfxBox(hvg, x1, y + mi->height-3, 2, 1, getChromBreakGreenColor()); - } - for(offset = 0; offset < mi->brackEndsSize; offset++) - { - int x1; - - x1 = x + (mi->brackEnds[offset] -1- startSub2 * 2) * width/winBaseCount; - hvGfxBox(hvg, x1-1, y-1, 2, 1, getChromBreakGreenColor()); - hvGfxBox(hvg, x1, y-1, 1, mi->height-1, getChromBreakGreenColor()); - hvGfxBox(hvg, x1-1, y + mi->height-3, 2, 1, getChromBreakGreenColor()); - } - - hvGfxUnclip(hvg); - y += mi->height; - } - -/* Clean up */ -/* -for (i=0; i<lineCount-1; ++i) - freeMem(lines[i]); -freez(&lines); -*/ -hFreeConn(&conn2); -hFreeConn(&conn3); -hashFree(&miHash); -return y; -} - -static int wigMafDrawScoreGraph(struct track *track, int seqStart, int seqEnd, - struct hvGfx *hvg, int xOff, int yOff, int width, - MgFont *font, Color color, enum trackVisibility vis) -{ -/* Draw routine for score graph, returns new Y offset */ -struct track *wigTrack = track->subtracks; -enum trackVisibility scoreVis; - -scoreVis = (vis == tvDense ? tvDense : tvFull); - -if (wigTrack == NULL) - { - /* no wiggle */ - int height = tl.fontHeight * 4; - if (vis == tvFull || vis == tvPack) - /* suppress graph if other items displayed (bases or pairs) */ - return yOff; - else if (vis == tvDense) - height = track->height; // Evidence that track-height comes in as 9 but should be 10! - /* draw some kind of graph from multiple alignment */ - struct mafPriv *mp = getMafPriv(track); - if (mp->list != (char *)-1 && mp->list != NULL) - { - /* use mafs */ - drawMafRegionDetails(mp->list, height, seqStart, seqEnd, - hvg, xOff, yOff, width, font, - color, color, scoreVis, FALSE, FALSE); - } - else if (mp->ct != NULL) - { - /* use or scored refs from maf table*/ - drawScoreOverviewCT(mp->ct->dbTableName, height, seqStart, seqEnd, - hvg, xOff, yOff, width, font, color, color, scoreVis); - yOff++; - } - else - { - /* use or scored refs from maf table*/ - drawScoreOverview(track->table, height, seqStart, seqEnd, hvg, - xOff, yOff, width, font, color, color, scoreVis); - yOff++; - } - yOff += height; - } -else - { - Color wigColor = 0; - while (wigTrack != NULL) - { - /* draw conservation wiggles */ - if (!wigColor) - wigColor = hvGfxFindRgb(hvg, &wigTrack->color); - else - wigColor = slightlyLighterColor(hvg, wigColor); - wigTrack->ixColor = wigColor; - wigTrack->ixAltColor = hvGfxFindRgb(hvg, &wigTrack->altColor); - hvGfxSetClip(hvg, xOff, yOff, width, wigTotalHeight(wigTrack, scoreVis) - 1); - wigTrack->drawItems(wigTrack, seqStart, seqEnd, hvg, xOff, yOff, - width, font, color, scoreVis); - hvGfxUnclip(hvg); - yOff += wigTotalHeight(wigTrack, scoreVis); - wigTrack = wigTrack->next; - } - } -return yOff; -} - - -static void wigMafDraw(struct track *track, int seqStart, int seqEnd, - struct hvGfx *hvg, int xOff, int yOff, int width, - MgFont *font, Color color, enum trackVisibility vis) -/* Draw routine for wigmaf type tracks */ -{ -int y = yOff; -y = wigMafDrawScoreGraph(track, seqStart, seqEnd, hvg, xOff, y, width, - font, color, vis); -if (vis == tvFull || vis == tvPack) - { - if (zoomedToBaseLevel) - { - struct wigMafItem *wiList = track->items; - /* skip over cons wiggles */ - struct track *wigTrack = track->subtracks; - while (wigTrack) - { - wiList = wiList->next; - wigTrack = wigTrack->next; - } - y = wigMafDrawBases(track, seqStart, seqEnd, hvg, xOff, y, width, font, - color, vis, wiList); - //MG_RED, vis, wiList); - } - else - wigMafDrawPairwise(track, seqStart, seqEnd, hvg, xOff, y, - width, font, color, vis); - } -mapBoxHc(hvg, seqStart, seqEnd, xOff, yOff, width, track->height, track->track, - track->track, NULL); -} - -void wigMafMethods(struct track *track, struct trackDb *tdb, - int wordCount, char *words[]) -/* Make track for maf multiple alignment. */ -{ -struct track *wigTrack; -int i; -struct dyString *wigType; -struct consWiggle *consWig, *consWigList = NULL; - -track->loadItems = wigMafLoad; -track->freeItems = wigMafFree; -track->drawItems = wigMafDraw; -track->itemName = wigMafItemName; -track->mapItemName = wigMafItemName; -track->totalHeight = wigMafTotalHeight; -track->itemHeight = wigMafItemHeight; -track->itemStart = tgItemNoStart; -track->itemEnd = tgItemNoEnd; -track->itemLabelColor = wigMafItemLabelColor; -track->mapsSelf = TRUE; -//track->canPack = TRUE; - -/* deal with conservation wiggle(s) */ -consWigList = wigMafWiggles(database, tdb); -if (consWigList == NULL) - return; - -/* determine which conservation wiggles to use -- from cart, - or if none there, use first entry in trackDb setting */ -boolean first = TRUE; -for (consWig = consWigList; consWig != NULL; consWig = consWig->next) - { - if (differentString(consWig->leftLabel, DEFAULT_CONS_LABEL)) - { - char *wigVar = wigMafWiggleVar(tdb, consWig); - if (!cartCgiUsualBoolean(cart, wigVar, first)) - continue; - } - first = FALSE; - - // Manufacture and initialize wiggle subtrack, both tdb and track - struct trackDb *wigTdb = CloneVar(tdb); - wigType = newDyString(64); - dyStringPrintf(wigType, "type wig "); - for (i = 1; i < wordCount; i++) - dyStringPrintf(wigType, "%s ", words[i]); - wigTdb->type = cloneString(wigType->string); - wigTdb->track = consWig->table; - wigTdb->table= consWig->table; - - /* Tweak wiggle left labels: replace underscore with space and - * append 'Cons' */ - struct dyString *ds = dyStringNew(0); - dyStringAppend(ds, consWig->leftLabel); - if (differentString(consWig->leftLabel, DEFAULT_CONS_LABEL)) - dyStringAppend(ds, " Cons"); - wigTdb->shortLabel = dyStringCannibalize(&ds); - subChar(wigTdb->shortLabel, '_', ' '); - - wigTrack = trackFromTrackDb(wigTdb); - - - /* setup wiggle methods in subtrack */ - wigMethods(wigTrack, tdb, wordCount, words); - - wigTrack->mapsSelf = FALSE; - wigTrack->drawLeftLabels = NULL; - wigTrack->next = NULL; - slAddTail(&track->subtracks, wigTrack); - dyStringFree(&wigType); - } -} - -