d48268237da501db3dfe40a8712bf18ad4ff53cb kate Sat Feb 1 14:09:18 2014 -0800 Support multiple canonical motifs for a TF. Also simplify hgc code for motifs. refs #9092 diff --git src/hg/hgc/peakClusters.c src/hg/hgc/peakClusters.c index e07fdf6..a94aaf5 100644 --- src/hg/hgc/peakClusters.c +++ src/hg/hgc/peakClusters.c @@ -365,153 +365,101 @@ tdb->track); printf("List all items assayed"); printf("</A><BR>\n"); webNewSection("Track Description"); printTrackHtml(tdb); hFreeConn(&conn); } void doClusterMotifDetails(struct sqlConnection *conn, struct trackDb *tdb, struct factorSource *cluster) /* Display details about TF binding motif(s) in cluster */ { char *motifTable = trackDbSetting(tdb, "motifTable"); // localizations char *motifPwmTable = trackDbSetting(tdb, "motifPwmTable"); // PWM used to draw sequence logo char *motifMapTable = trackDbSetting(tdb, "motifMapTable"); // map target to motif -char *motifName = cluster->name; /* default to same as target */ +struct slName *motifNames = NULL, *mn; // list of canonical motifs for the factor struct dnaMotif *motif = NULL; -struct dnaSeq **seqs = NULL; -struct bed6FloatScore *hits = NULL; +struct bed6FloatScore *hit = NULL, *maxHit = NULL; char **row; -#ifdef SHOW_MAX_SCORE -struct sqlResult *sr; -#endif -char query[256], buf[256]; +char query[256]; if (motifTable != NULL && sqlTableExists(conn, motifTable)) { struct sqlResult *sr; int rowOffset; char where[256]; - if (motifMapTable != NULL && sqlTableExists(conn, motifMapTable)) + if (motifMapTable == NULL || !sqlTableExists(conn, motifMapTable)) + { + // Assume cluster name is motif name if there is no map table + motifNames = slNameNew(cluster->name); + } + else { sqlSafef(query, sizeof(query), "select motif from %s where target = '%s'", motifMapTable, cluster->name); - // TODO: perhaps sqlQuickString ? - motifName = sqlQuickQuery(conn, query, buf, sizeof(buf)); - if (motifName == NULL) + char *ret = sqlQuickString(conn, query); + if (ret == NULL) return; + motifNames = slNameListFromString(ret, ','); } - #define HIGHEST_SCORING - #ifdef HIGHEST_SCORING - sqlSafefFrag(where, sizeof(where), "name = '%s' order by score desc", motifName); - #else - sqlSafefFrag(where, sizeof(where), "name = '%s'", motifName); - #endif + for (mn = motifNames; mn != NULL; mn = mn->next) + { + sqlSafefFrag(where, sizeof(where), "name='%s' order by score desc limit 1", mn->name); sr = hRangeQuery(conn, motifTable, cluster->chrom, cluster->chromStart, cluster->chromEnd, where, &rowOffset); - #ifdef HIGHEST_SCORING if ((row = sqlNextRow(sr)) != NULL) - #else - while ((row = sqlNextRow(sr)) != NULL) - #endif { - struct bed6FloatScore *hit = NULL; - AllocVar(hit); - hit->chromStart = sqlUnsigned(row[rowOffset + 1]); - hit->chromEnd = sqlUnsigned(row[rowOffset + 2]); - hit->score = sqlFloat(row[rowOffset + 4]); - hit->strand[0] = row[rowOffset + 5][0]; - slAddHead(&hits, hit); + hit = bed6FloatScoreLoad(row + rowOffset); + if (maxHit == NULL || maxHit->score < hit->score) + maxHit = hit; } sqlFreeResult(&sr); } -if (hits == NULL) + } +if (maxHit == NULL) { // Maintain table layout webNewEmptySection(); return; } - -int hitCount = 0; -if (motifPwmTable != NULL && sqlTableExists(conn, motifPwmTable)) - { - motif = loadDnaMotif(motifName, motifPwmTable); - } -struct bed6FloatScore *hit = NULL; -int i; -seqs = needMem(sizeof(struct dnaSeq *) * slCount(hits)); -char posLink[1024]; -hitCount = slCount(hits); +hit = maxHit; webNewSection("Canonical Motif in Cluster"); - -#ifdef SHOW_MAX_SCORE -float maxScore = -1; -sqlSafef(query, sizeof(query), - "select max(score) from %s where name = '%s'", motifTable, motifName); -sr = sqlGetResult(conn, query); -if ((row = sqlNextRow(sr)) != NULL) - { - if(!isEmpty(row[0])) - { - maxScore = sqlFloat(row[0]); - } - } -sqlFreeResult(&sr); -#endif - -for (hit = hits, i = 0; hit != NULL; hit = hit->next, i++) - { - struct dnaSeq *seq = hDnaFromSeq(database, - seqName, hit->chromStart, hit->chromEnd, dnaLower); - if(hit->strand[0] == '-') - reverseComplement(seq->dna, seq->size); - seqs[i] = seq; - // TODO: move to hgc.c (with other pos printers) +char posLink[1024]; safef(posLink, sizeof(posLink),"<a href=\"%s&db=%s&position=%s%%3A%d-%d\">%s:%d-%d</a>", hgTracksPathAndSettings(), database, cluster->chrom, hit->chromStart+1, hit->chromEnd, cluster->chrom, hit->chromStart+1, hit->chromEnd); - printf("<b>Motif Name:</b> %s<br>\n", motifName); +printf("<b>Motif Name:</b> %s<br>\n", hit->name); printf("<b>Motif Score"); - if (hitCount > 1) - { - printf("#%d", i + 1); - #ifdef SHOW_MAX_SCORE - printf(":</b> %.2f (%s max: %.2f) at %s on <b>%c</font></b> strand<br>", - hit->score, cluster->name, maxScore, posLink, (int)hit->strand[0]); - #else - printf(":</b> %.2f at %s on <b>%c</font></b> strand<br>", - hit->score, posLink, (int)hit->strand[0]); - #endif - } - else - { - #ifdef SHOW_MAX_SCORE - printf(":</b> %.2f (%s max: %.2f)<br>\n", hit->score, cluster->name, maxScore); - #else printf(":</b> %.2f<br>\n", hit->score); - #endif printf("<b>Motif Position:</b> %s<br>\n", posLink); printf("<b>Motif Strand:</b> %c<br>\n", (int)hit->strand[0]); - } - } -if (seqs != NULL && motif != NULL) + +struct dnaSeq *seq = hDnaFromSeq(database, seqName, hit->chromStart, hit->chromEnd, dnaLower); +if (seq == NULL) + return; +if (hit->strand[0] == '-') + reverseComplement(seq->dna, seq->size); +if (motifPwmTable != NULL && sqlTableExists(conn, motifPwmTable)) { - motifLogoAndMatrix(seqs, hitCount, motif); + motif = loadDnaMotif(hit->name, motifPwmTable); + if (motif == NULL) + return; + motifLogoAndMatrix(&seq, 1, motif); } } void doFactorSource(struct sqlConnection *conn, struct trackDb *tdb, char *item, int start) /* Display detailed info about a cluster of TFBS peaks from other tracks. */ { int rowOffset = hOffsetPastBin(database, seqName, tdb->table); char **row; struct sqlResult *sr; char query[256]; sqlSafef(query, sizeof(query), "select * from %s where name = '%s' and chrom = '%s' and chromStart = %d", tdb->table, item, seqName, start); sr = sqlGetResult(conn, query);