06d7be056190c14b85e71bc12523f18ea6815b5e markd Mon Dec 7 00:50:29 2020 -0800 BLAT mmap index support merge with master diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c index 440b04c..85cadb2 100644 --- src/hg/hgTracks/simpleTracks.c +++ src/hg/hgTracks/simpleTracks.c @@ -226,33 +226,30 @@ char *virtModeType = "default"; /* virtual chrom mode type */ char *lastVirtModeType = "default"; char *virtModeShortDescr = ""; /* short description of virt mode */ char *virtModeExtraState = ""; /* Other settings that affect the virtMode state such as padding or some parameter */ char *lastVirtModeExtraState = ""; struct cart *lastDbPosCart = NULL; /* store settings for use in lastDbPos and hgTracks.js setupHistory */ char *organism; /* Name of organism we're working on. */ char *database; /* Name of database we're using. */ char *chromName; /* Name of chromosome sequence . */ int winStart; /* Start of window in sequence. */ int winEnd; /* End of window in sequence. */ char *position = NULL; /* Name of position. */ -int trackTabWidth = 11; -int leftLabelWidthDefaultChars = 20; /* default number of characters allowed for left label */ -int leftLabelWidthChars = 20; /* number of characters allowed for left label */ int insideX; /* Start of area to draw track in in pixels. */ int insideWidth; /* Width of area to draw tracks in in pixels. */ int leftLabelX; /* Start of area to draw left labels on. */ int leftLabelWidth; /* Width of area to draw left labels on. */ float basesPerPixel = 0; /* bases covered by a pixel; a measure of zoom */ boolean zoomedToBaseLevel; /* TRUE if zoomed so we can draw bases. */ boolean zoomedToCodonLevel; /* TRUE if zoomed so we can print codons text in genePreds*/ boolean zoomedToCdsColorLevel; /* TRUE if zoomed so we can color each codon*/ boolean withLeftLabels = TRUE; /* Display left labels? */ boolean withIndividualLabels = TRUE; /* print labels on item-by-item basis (false to skip) */ boolean withCenterLabels = TRUE; /* Display center labels? */ boolean withGuidelines = TRUE; /* Display guidelines? */ boolean withNextExonArrows = FALSE; /* Display next exon navigation buttons near center labels? */ boolean withExonNumbers = FALSE; /* Display exon and intron numbers in mouseOver instead of item name */ @@ -276,42 +273,30 @@ Color shadesOfSea[10+1]; /* Ten sea shades. */ struct rgbColor darkSeaColor = {0, 60, 120}; struct rgbColor lightSeaColor = {200, 220, 255}; struct hash *hgFindMatches; /* The matches found by hgFind that should be highlighted. */ struct trackLayout tl; void initTl() /* Initialize layout around small font and a picture about 600 pixels * wide. */ { trackLayoutInit(&tl, cart); -// label width, but don't exceed 1/2 of image -leftLabelWidthChars = cartUsualInt(cart, "hgt.labelWidth", leftLabelWidthDefaultChars); -if (leftLabelWidthChars < 2) - leftLabelWidthChars = leftLabelWidthDefaultChars; -tl.leftLabelWidth = leftLabelWidthChars*tl.nWidth + trackTabWidth + 3; -int maxLabelWidth = 0.5*tl.picWidth; -if (tl.leftLabelWidth > maxLabelWidth) - { - // overflow, force to 1/2 width - leftLabelWidthChars = maxLabelWidth/tl.nWidth; - tl.leftLabelWidth = leftLabelWidthChars * tl.nWidth; - } } static boolean isTooLightForTextOnWhite(struct hvGfx *hvg, Color color) /* Return TRUE if text in this color would probably be invisible on a white background. */ { struct rgbColor rgbColor = hvGfxColorIxToRgb(hvg, color); int colorTotal = rgbColor.r + 2*rgbColor.g + rgbColor.b; return colorTotal >= 512; } Color darkerColor(struct hvGfx *hvg, Color color) /* Get darker shade of a color - half way between this color and black */ { struct rgbColor rgbColor = hvGfxColorIxToRgb(hvg, color); rgbColor.r = ((int)rgbColor.r)/2; @@ -2681,36 +2666,44 @@ int w = ex - sx; int exonIntronNumber; char *exonIntronText; int numExonIntrons = numExons; if (isExon) { exonIntronText = exonText; } else { exonIntronText = intronText; --numExonIntrons; // introns are one fewer than exons } - if (!revStrand) + char strandChar; + if (!revStrand) { exonIntronNumber = exonIx; - else + strandChar = '+'; + } + else { exonIntronNumber = numExonIntrons-exonIx+1; + strandChar = '-'; + } - safef(mouseOverText, sizeof(mouseOverText), "%s (%d/%d)", exonIntronText, exonIntronNumber, numExonIntrons); + if (!isEmpty(lf->name)) + safef(mouseOverText, sizeof(mouseOverText), "%s, strand %c, %s %d of %d", lf->name, strandChar, exonIntronText, exonIntronNumber, numExonIntrons); + else + safef(mouseOverText, sizeof(mouseOverText), "strand %c, %s %d of %d", strandChar, exonIntronText, exonIntronNumber, numExonIntrons); if (w > 0) // draw exon or intron if width is greater than 0 { tg->mapItem(tg, hvg, item, mouseOverText, tg->mapItemName(tg, item), sItem, eItem, sx, y, w, heightPer); picStart = ex; // prevent pileups. is this right? add 1? does it work? } } } if (isExon) { eLast = e; ref = ref->next; if (!ref) @@ -4063,32 +4056,34 @@ boolean nextItemCompatible(struct track *tg) /* Check to see if we draw nextPrev item buttons on a track. */ { return (withNextExonArrows && tg->nextExonButtonable && tg->nextPrevExon); } boolean exonNumberMapsCompatible(struct track *tg, enum trackVisibility vis) /* Check to see if we draw exon and intron maps labeling their number. */ { if (tg->tdb) { char *type = tg->tdb->type; if (sameString(type, "interact") || sameString(type, "bigInteract")) return FALSE; + if (startsWith("bigGenePred", type) || startsWith("genePred", type)) + return TRUE; } -boolean exonNumbers = sameString(trackDbSettingOrDefault(tg->tdb, "exonNumbers", "on"), "on"); +boolean exonNumbers = sameString(trackDbSettingOrDefault(tg->tdb, "exonNumbers", "off"), "on"); return (withExonNumbers && exonNumbers && (vis==tvFull || vis==tvPack) && (winEnd - winStart < 400000) && (tg->nextPrevExon==linkedFeaturesNextPrevItem)); } void genericMapItem(struct track *tg, struct hvGfx *hvg, void *item, char *itemName, char *mapItemName, int start, int end, int x, int y, int width, int height) /* This is meant to be used by genericDrawItems to set to tg->mapItem in */ /* case tg->mapItem isn't set to anything already. */ { // Don't bother if we are imageV2 and a dense child. if (!theImgBox || tg->limitedVis != tvDense || !tdbIsCompositeChild(tg->tdb)) { char *directUrl = trackDbSetting(tg->tdb, "directUrl"); boolean withHgsid = (trackDbSetting(tg->tdb, "hgsid") != NULL); @@ -12644,58 +12639,137 @@ tg->nextPrevItem = linkedFeaturesLabelNextPrevItem; } void oregannoMethods (struct track *tg) /* load so can allow filtering on type */ { tg->attrTable = NULL; tg->loadItems = loadOreganno; tg->itemColor = oregannoColor; tg->itemNameColor = oregannoColor; tg->nextItemButtonable = TRUE; tg->nextPrevItem = linkedFeaturesLabelNextPrevItem; } +static char *omimGetInheritanceCode(char *inhMode) +/* Translate inheritance mode strings into much shorter codes. */ +{ +static struct dyString *dy = NULL; // re-use this string +if (dy == NULL) + dy = dyStringNew(0); +dyStringClear(dy); + +struct slName *modes = slNameListFromString(inhMode, ','); + +for(; modes; modes = modes->next) + { + stripChar(modes->name, '?'); + char *mode = skipLeadingSpaces(modes->name); + if (sameString(mode, "Autosomal dominant")) + dyStringAppend(dy, "AD"); + else if (sameString(mode, "Autosomal recessive")) + dyStringAppend(dy, "AR"); + else if (sameString(mode, "X-linked")) + dyStringAppend(dy, "XL"); + else if (sameString(mode, "X-linked dominant")) + dyStringAppend(dy, "XLD"); + else if (sameString(mode, "X-linked recessive")) + dyStringAppend(dy, "XLR"); + else if (sameString(mode, "Y-linked")) + dyStringAppend(dy, "YL"); + else if (!isEmpty(mode)) + dyStringAppend(dy, mode); + + if (modes->next) + dyStringAppend(dy, "/"); + } +return dy->string; +} + static char *omimGene2DisorderList(char *name) /* Return list of disorders associated with a OMIM entry. Do not free result! */ { static struct dyString *dy = NULL; struct sqlConnection *conn; -char query[256]; +char query[4096]; if (dy == NULL) dy = dyStringNew(0); dyStringClear(dy); // get gene symbol(s) first conn = hAllocConn(database); sqlSafef(query,sizeof(query), "select geneSymbol from omimGeneMap2 where omimId =%s", name); -char buf[256]; +char buf[4096]; char *ret = sqlQuickQuery(conn, query, buf, sizeof(buf)); if (isNotEmpty(ret)) - dyStringAppend(dy, ret); + { + struct slName *genes = slNameListFromString(ret, ','); + dyStringPrintf(dy, "Gene: %s", genes->name); + genes = genes->next; + if (genes) + { + if (slCount(genes) > 1) + dyStringPrintf(dy, ", Synonyms: "); + else + dyStringPrintf(dy, ", Synonym: "); + for(; genes; genes = genes->next) + { + dyStringPrintf(dy, "%s", genes->name); + if (genes->next) + dyStringPrintf(dy, ","); + } + } + // now phenotype information sqlSafef(query,sizeof(query), - "select distinct description from omimPhenotype, omimGene2 where name='%s' and name=cast(omimId as char) order by description", name); -char *disorders = collapseRowsFromQuery(query, "; ", 20); -if (isNotEmpty(disorders)) + "select GROUP_CONCAT(omimPhenotype.description, '|',inhMode , '|',omimPhenoMapKey SEPARATOR '$') from omimGene2, omimGeneMap, omimPhenotype where omimGene2.name=omimGeneMap.omimId and omimGene2.name=omimPhenotype.omimId and omimGene2.name =%s", name); + ret = sqlQuickQuery(conn, query, buf, sizeof(buf)); + + if (ret) { - dyStringAppend(dy, "; disorder(s): "); - dyStringAppend(dy, disorders); + struct slName *phenotypes = slNameListFromString(ret, '$'); + if (slCount(phenotypes)) + { + if (slCount(phenotypes) > 1) + dyStringPrintf(dy, ", Phenotypes: "); + else + dyStringPrintf(dy, ", Phenotype: "); + + for(; phenotypes; phenotypes = phenotypes->next) + { + struct slName *components = slNameListFromString(phenotypes->name, '|'); + dyStringPrintf(dy, "%s", components->name); + components = components->next; + + char *inhCode = omimGetInheritanceCode(components->name); + if (!isEmpty(inhCode)) + dyStringPrintf(dy, ", %s", inhCode); + components = components->next; + + if (!isEmpty(components->name)) + dyStringPrintf(dy, ", %s", components->name); + + if (phenotypes->next) + dyStringPrintf(dy, "; "); + } + } } + } + hFreeConn(&conn); return(dy->string); } #include "omim.h" boolean isOmimOtherClass(char *omimId) /* check if this omimId belongs to the "Others" phenotype class */ /* NOTE: The definition of Others class is kind of tricky. The Other class is defined as: 1. does not have class 1 or 2 or 3, or 4; some may have class '-1'. 2. for an entry of omimId that the omimPhenotype table does not even have a row with omimId