753c0bb7aacde00fa0e2c07bcb3c67e2f3bb8e4b tdreszer Thu Nov 10 13:57:11 2011 -0800 Get DNA color feature: added support for composites and limited to currently visible tracks. This is for redmine 685. diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c index 0f7797f..116d5ba 100644 --- src/hg/hgc/hgc.c +++ src/hg/hgc/hgc.c @@ -4205,30 +4205,52 @@ { struct trackDb *tdb; AllocVar(tdb); tdb->track = cloneString(USER_PSL_TRACK_NAME); tdb->table = cloneString(USER_PSL_TRACK_NAME); tdb->shortLabel = cloneString(USER_PSL_TRACK_LABEL); tdb->type = cloneString("psl"); tdb->longLabel = cloneString(USER_PSL_TRACK_LONGLABEL); tdb->visibility = tvFull; tdb->priority = 11.0; trackDbPolish(tdb); return(tdb); } } +#define AND_SUBTRACKS_TOO +#ifdef AND_SUBTRACKS_TOO +struct trackDb *rFindUnderstandableTrack(char *db, struct trackDb *tdb) +// If any leaf is usable in getting DNA then that leaf's tdb is returned. +{ +if (tdb->subtracks != NULL) + return rFindUnderstandableTrack(db,tdb->subtracks); + +if (fbUnderstandTrack(db, tdb->table) && !dnaIgnoreTrack(tdb->table)) + return tdb; +else + return NULL; +} + +boolean forestHasUnderstandableTrack(char *db, struct trackDb *tdb) +// TRUE if any leaf is usable in getting DNA. +{ +return (rFindUnderstandableTrack(db, tdb) != NULL); +} +#endif///def AND_SUBTRACKS_TOO + + void doGetDnaExtended1() /* Do extended case/color get DNA options. */ { struct trackDb *tdbList = hTrackDb(database), *tdb; struct trackDb *ctdbList = tdbForCustomTracks(); struct trackDb *utdbList = tdbForUserPsl(); boolean isRc = cartUsualBoolean(cart, "hgc.dna.rc", FALSE); boolean revComp = cartUsualBoolean(cart, "hgSeq.revComp", FALSE); boolean maskRep = cartUsualBoolean(cart, "hgSeq.maskRepeats", FALSE); int padding5 = cartUsualInt(cart, "hgSeq.padding5", 0); int padding3 = cartUsualInt(cart, "hgSeq.padding3", 0); char *casing = cartUsualString(cart, "hgSeq.casing", ""); char *repMasking = cartUsualString(cart, "hgSeq.repMasking", ""); boolean caseUpper= FALSE; char *pos = NULL; @@ -4305,31 +4327,36 @@ printf(" Default case: "); cgiMakeRadioButton("case", "upper", caseUpper); printf(" Upper "); cgiMakeRadioButton("case", "lower", !caseUpper); printf(" Lower "); cgiMakeButton("Submit", "submit"); printf("<BR>\n"); printf("<TABLE BORDER=1>\n"); printf("<TR><TD>Track<BR>Name</TD><TD>Toggle<BR>Case</TD><TD>Under-<BR>line</TD><TD>Bold</TD><TD>Italic</TD><TD>Red</TD><TD>Green</TD><TD>Blue</TD></TR>\n"); for (tdb = tdbList; tdb != NULL; tdb = tdb->next) { char *table = tdb->table; char *track = tdb->track; if (sameString(USER_PSL_TRACK_NAME, table) || (lookupCt(track) != NULL) || +#ifdef AND_SUBTRACKS_TOO + ( tdbVisLimitedByAncestors(cart,tdb,TRUE,TRUE) != tvHide + && forestHasUnderstandableTrack(database, tdb))) +#else///ifndef AND_SUBTRACKS_TOO (fbUnderstandTrack(database, table) && !dnaIgnoreTrack(table))) +#endif///ndef AND_SUBTRACKS_TOO { char *visString = cartUsualString(cart, track, hStringFromTv(tdb->visibility)); if (differentString(visString, "hide") && tdb->parent) { char *parentVisString = cartUsualString(cart, tdb->parentName, hStringFromTv(tdb->parent->visibility)); if (sameString("hide", parentVisString)) visString = "hide"; } char buf[128]; if (sameString(visString, "hide")) { char varName[256]; sprintf(varName, "%s_case", track); cartSetBoolean(cart, varName, FALSE); @@ -4864,31 +4891,36 @@ seq = hDnaFromSeq(database, seqName, winStart, winEnd, dnaLower); if (isRc) reverseComplement(seq->dna, seq->size); if (defaultUpper) touppers(seq->dna); AllocArray(colors, winSize); for (tdb = tdbList; tdb != NULL; tdb = tdb->next) { char *track = tdb->track; char *table = tdb->table; struct featureBits *fbList = NULL, *fb; struct customTrack *ct = lookupCt(track); if (sameString(USER_PSL_TRACK_NAME, table) || (ct != NULL) || +#ifdef AND_SUBTRACKS_TOO + ( tdbVisLimitedByAncestors(cart,tdb,TRUE,TRUE) != tvHide + && forestHasUnderstandableTrack(database, tdb))) +#else///ifndef AND_SUBTRACKS_TOO (fbUnderstandTrack(database, table) && !dnaIgnoreTrack(table))) +#endif///ndef AND_SUBTRACKS_TOO { char buf[256]; int r,g,b; /* to save a LOT of time, don't fetch track features unless some * coloring/formatting has been specified for them. */ boolean hasSettings = FALSE; safef(buf, sizeof(buf), "%s_u", track); hasSettings |= cgiBoolean(buf); safef(buf, sizeof(buf), "%s_b", track); hasSettings |= cgiBoolean(buf); safef(buf, sizeof(buf), "%s_i", track); hasSettings |= cgiBoolean(buf); safef(buf, sizeof(buf), "%s_case", track); hasSettings |= cgiBoolean(buf); safef(buf, sizeof(buf), "%s_red", track); @@ -4946,31 +4978,54 @@ hFreeConn(&conn); } else { ctBedList = ct->bedList; } bedList2 = bedFilterListInRange(ctBedList, bf, seqName, winStart, winEnd); fbList = fbFromBed(database, track, hti, bedList2, winStart, winEnd, TRUE, FALSE); bedFreeList(&bedList2); if (!ct->bedList) bedFreeList(&ctBedList); } else + { +#ifdef AND_SUBTRACKS_TOO + if (tdb->subtracks) + { + struct slRef *refLeaves = trackDbListGetRefsToDescendantLeaves(tdb->subtracks); + struct slRef *refLeaf = NULL; + while ((refLeaf = slPopHead(&refLeaves)) != NULL) + { + struct trackDb *tdbLeaf = refLeaf->val; + if (tdbVisLimitedByAncestors(cart,tdbLeaf,TRUE,TRUE) != tvHide + && fbUnderstandTrack(database, tdbLeaf->table) + && !dnaIgnoreTrack(tdbLeaf->table)) + { + struct featureBits *fbLeafList = fbGetRange(database, tdbLeaf->table, seqName, winStart, winEnd); + if (fbLeafList != NULL) + fbList = slCat(fbList,fbLeafList); // TODO: merge featureBits to overlaps? + } + freeMem(refLeaf); + } + } + else +#endif///def AND_SUBTRACKS_TOO fbList = fbGetRange(database, tdb->table, seqName, winStart, winEnd); + } /* Flip underline/italic/bold bits. */ getDnaHandleBits(track, "u", uBits, winStart, winEnd, isRc, fbList); getDnaHandleBits(track, "b", bBits, winStart, winEnd, isRc, fbList); getDnaHandleBits(track, "i", iBits, winStart, winEnd, isRc, fbList); /* Toggle case if necessary. */ sprintf(buf, "%s_case", track); if (cgiBoolean(buf)) { for (fb = fbList; fb != NULL; fb = fb->next) { DNA *dna; int start = fb->start - winStart; int end = fb->end - winStart;