a520a3e8703485e62c9bbabb43443f02a08c45ad
max
Wed Aug 19 07:29:21 2020 -0700
committing code for the "related tracks" feature. This will have no effect on the RR, as the table does not exist there. The main point of the commit is to allow chris to start modifying the code without a manual copy. refs #25721
diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c
index b59e42b..f82f4cc 100644
--- src/hg/hgc/hgc.c
+++ src/hg/hgc/hgc.c
@@ -1,26852 +1,26925 @@
/* hgc - Human Genome Click processor - gets called when user clicks
* on something in human tracks display. */
/* Copyright (C) 2014 The Regents of the University of California
* See README in this or parent directory for licensing information. */
#include "common.h"
#include
#include "obscure.h"
#include "hCommon.h"
#include "hash.h"
#include "binRange.h"
#include "bits.h"
#include "memgfx.h"
#include "hvGfx.h"
#include "portable.h"
#include "regexHelper.h"
#include "errAbort.h"
#include "dystring.h"
#include "nib.h"
#include "cheapcgi.h"
#include "htmshell.h"
#include "cart.h"
#include "jksql.h"
#include "dnautil.h"
#include "dnaseq.h"
#include "fa.h"
#include "fuzzyFind.h"
#include "seqOut.h"
#include "hdb.h"
#include "spDb.h"
#include "hui.h"
#include "hgRelate.h"
#include "htmlPage.h"
#include "psl.h"
#include "cogs.h"
#include "cogsxra.h"
#include "bed.h"
#include "cgh.h"
#include "agpFrag.h"
#include "agpGap.h"
#include "ctgPos.h"
#include "contigAcc.h"
#include "ctgPos2.h"
#include "clonePos.h"
#include "bactigPos.h"
#include "rmskOut.h"
#include "xenalign.h"
#include "isochores.h"
#include "simpleRepeat.h"
#include "cpgIsland.h"
#include "cpgIslandExt.h"
#include "genePred.h"
#include "genePredReader.h"
#include "pepPred.h"
#include "peptideAtlasPeptide.h"
#include "wabAli.h"
#include "genomicDups.h"
#include "est3.h"
#include "rnaGene.h"
#include "tRNAs.h"
#include "gbRNAs.h"
#include "encode/encodeRna.h"
#include "hgMaf.h"
#include "maf.h"
#include "stsMarker.h"
#include "stsMap.h"
#include "rhMapZfishInfo.h"
#include "recombRate.h"
#include "recombRateRat.h"
#include "recombRateMouse.h"
#include "stsInfo.h"
#include "stsInfo2.h"
#include "mouseSyn.h"
#include "mouseSynWhd.h"
#include "ensPhusionBlast.h"
#include "cytoBand.h"
#include "knownMore.h"
#include "snp125.h"
#include "snp125Ui.h"
#include "snp132Ext.h"
#include "snp.h"
#include "snpMap.h"
#include "snpExceptions.h"
#include "snp125Exceptions.h"
#include "snp125CodingCoordless.h"
#include "cnpIafrate.h"
#include "cnpIafrate2.h"
#include "cnpLocke.h"
#include "cnpSebat.h"
#include "cnpSebat2.h"
#include "cnpSharp.h"
#include "cnpSharp2.h"
#include "delHinds2.h"
#include "delConrad2.h"
#include "dgv.h"
#include "dgvPlus.h"
#include "tokenizer.h"
#include "softberryHom.h"
#include "borkPseudoHom.h"
#include "sanger22extra.h"
#include "ncbiRefLink.h"
#include "ncbiRefSeqLink.h"
#include "refLink.h"
#include "hgConfig.h"
#include "estPair.h"
#include "softPromoter.h"
#include "customTrack.h"
#include "trackHub.h"
#include "hubConnect.h"
#include "sage.h"
#include "sageExp.h"
#include "pslWScore.h"
#include "lfs.h"
#include "mcnBreakpoints.h"
#include "fishClones.h"
#include "featureBits.h"
#include "web.h"
#include "dbDb.h"
#include "jaxOrtholog.h"
#include "dnaProbe.h"
#include "ancientRref.h"
#include "jointalign.h"
#include "gcPercent.h"
#include "genMapDb.h"
#include "altGraphX.h"
#include "geneGraph.h"
#include "stsMapMouse.h"
#include "stsInfoMouse.h"
#include "dbSnpRs.h"
#include "genomicSuperDups.h"
#include "celeraDupPositive.h"
#include "celeraCoverage.h"
#include "sample.h"
#include "axt.h"
#include "axtInfo.h"
#include "jaxQTL.h"
#include "jaxQTL3.h"
#include "wgRna.h"
#include "ncRna.h"
#include "gbProtAnn.h"
#include "hgSeq.h"
#include "chain.h"
#include "chainDb.h"
#include "chainNetDbLoad.h"
#include "chainToPsl.h"
#include "chainToAxt.h"
#include "netAlign.h"
#include "stsMapRat.h"
#include "stsInfoRat.h"
#include "stsMapMouseNew.h"
#include "stsInfoMouseNew.h"
#include "vegaInfo.h"
#include "vegaInfoZfish.h"
#include "ensInfo.h"
#include "scoredRef.h"
#include "blastTab.h"
#include "hdb.h"
#include "hgc.h"
#include "genbank.h"
#include "pseudoGeneLink.h"
#include "axtLib.h"
#include "ensFace.h"
#include "bdgpGeneInfo.h"
#include "flyBaseSwissProt.h"
#include "flyBase2004Xref.h"
#include "affy10KDetails.h"
#include "affy120KDetails.h"
#include "encode/encodeRegionInfo.h"
#include "encode/encodeErge.h"
#include "encode/encodeErgeHssCellLines.h"
#include "encode/encodeStanfordPromoters.h"
#include "encode/encodeStanfordPromotersAverage.h"
#include "encode/encodeIndels.h"
#include "encode/encodeHapMapAlleleFreq.h"
#include "hapmapSnps.h"
#include "hapmapAllelesOrtho.h"
#include "hapmapAllelesSummary.h"
#include "sgdDescription.h"
#include "sgdClone.h"
#include "tfbsCons.h"
#include "tfbsConsMap.h"
#include "tfbsConsSites.h"
#include "tfbsConsFactors.h"
#include "simpleNucDiff.h"
#include "bgiGeneInfo.h"
#include "bgiSnp.h"
#include "bgiGeneSnp.h"
#include "botDelay.h"
#include "vntr.h"
#include "zdobnovSynt.h"
#include "HInv.h"
#include "bed5FloatScore.h"
#include "bed6FloatScore.h"
#include "pscreen.h"
#include "jalview.h"
#include "flyreg.h"
#include "putaInfo.h"
#include "gencodeIntron.h"
#include "cutter.h"
#include "switchDbTss.h"
#include "chicken13kInfo.h"
#include "gapCalc.h"
#include "chainConnect.h"
#include "dv.h"
#include "dvBed.h"
#include "dvXref2.h"
#include "omimTitle.h"
#include "dless.h"
#include "gv.h"
#include "gvUi.h"
#include "protVar.h"
#include "oreganno.h"
#include "oregannoUi.h"
#include "pgSnp.h"
#include "pgPhenoAssoc.h"
#include "pgSiftPred.h"
#include "pgPolyphenPred.h"
#include "bedDetail.h"
#include "ec.h"
#include "transMapClick.h"
#include "retroClick.h"
#include "mgcClick.h"
#include "ccdsClick.h"
#include "gencodeClick.h"
#include "memalloc.h"
#include "trashDir.h"
#include "kg1ToKg2.h"
#include "wikiTrack.h"
#include "grp.h"
#include "omicia.h"
#include "atomDb.h"
#include "pcrResult.h"
#include "twoBit.h"
#include "itemConf.h"
#include "chromInfo.h"
#include "gbWarn.h"
#include "lsSnpPdbChimera.h"
#include "mammalPsg.h"
#include "net.h"
#include "jsHelper.h"
#include "virusClick.h"
#include "gwasCatalog.h"
#include "parClick.h"
#include "mdb.h"
#include "yaleGencodeAssoc.h"
#include "itemDetailsHtml.h"
#include "trackVersion.h"
#include "numtsClick.h"
#include "geneReviewsClick.h"
#include "bigBed.h"
#include "bigPsl.h"
#include "bedTabix.h"
#include "longRange.h"
#include "hmmstats.h"
#include "aveStats.h"
#include "trix.h"
#include "bPlusTree.h"
#include "customFactory.h"
#include "iupac.h"
static char *rootDir = "hgcData";
#define LINESIZE 70 /* size of lines in comp seq feature */
struct cart *cart; /* User's settings. */
char *seqName; /* Name of sequence we're working on. */
int winStart, winEnd; /* Bounds of sequence. */
char *database; /* Name of mySQL database. */
char *organism; /* Colloquial name of organism. */
char *genome; /* common name, e.g. Mouse, Human */
char *scientificName; /* Scientific name of organism. */
struct hash *trackHash; /* A hash of all tracks - trackDb valued */
void printLines(FILE *f, char *s, int lineSize);
char mousedb[] = "mm3";
#define NUMTRACKS 9
int prevColor[NUMTRACKS]; /* used to optimize color change html commands */
int currentColor[NUMTRACKS]; /* used to optimize color change html commands */
int maxShade = 9; /* Highest shade in a color gradient. */
Color shadesOfGray[10+1]; /* 10 shades of gray from white to black */
Color shadesOfRed[16];
boolean exprBedColorsMade = FALSE; /* Have the shades of red been made? */
int maxRGBShade = 16;
struct bed *sageExpList = NULL;
char ncbiOmimUrl[255] = {"https://www.ncbi.nlm.nih.gov/omim/"};
struct palInfo
{
char *chrom;
int left;
int right;
char *rnaName;
};
/* See this NCBI web doc for more info about entrezFormat:
* https://www.ncbi.nlm.nih.gov/entrez/query/static/linking.html */
char *entrezFormat = "https://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Search&db=%s&term=%s&doptcmdl=%s&tool=genome.ucsc.edu";
char *entrezPureSearchFormat = "https://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=PureSearch&db=%s&details_term=%s[%s] ";
char *ncbiGeneFormat = "https://www.ncbi.nlm.nih.gov/gene/%s";
char *entrezUidFormat = "https://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=%s&list_uids=%d&dopt=%s&tool=genome.ucsc.edu";
/* db=unists is not mentioned in NCBI's doc... so stick with this usage: */
char *unistsnameScript = "https://www.ncbi.nlm.nih.gov:80/entrez/query.fcgi?db=unists";
char *unistsScript = "https://www.ncbi.nlm.nih.gov/genome/sts/sts.cgi?uid=";
char *gdbScript = "http://www.gdb.org/gdb-bin/genera/accno?accessionNum=";
char *cloneDbScript = "https://www.ncbi.nlm.nih.gov/clone?term=";
char *traceScript = "https://www.ncbi.nlm.nih.gov/Traces/trace.cgi?cmd=retrieve&val=";
char *genMapDbScript = "http://genomics.med.upenn.edu/perl/genmapdb/byclonesearch.pl?clone=";
char *uniprotFormat = "http://www.uniprot.org/uniprot/%s";
char *dbSnpFormat = "https://www.ncbi.nlm.nih.gov/SNP/snp_ref.cgi?type=rs&rs=%s";
char *clinVarFormat = "https://www.ncbi.nlm.nih.gov/clinvar/?term=%s[clv_acc]";
/* variables for gv tables */
char *gvPrevCat = NULL;
char *gvPrevType = NULL;
/* initialized by getCtList() if necessary: */
struct customTrack *theCtList = NULL;
/* getDNA stuff actually works when the database doesn't exist! */
boolean dbIsFound = FALSE;
/* forwards */
char *getPredMRnaProtSeq(struct genePred *gp);
void doAltGraphXDetails(struct trackDb *tdb, char *item);
char* getEntrezNucleotideUrl(char *accession)
/* get URL for Entrez browser on a nucleotide. free resulting string */
{
char url[512];
safef(url, sizeof(url), entrezFormat, "Nucleotide", accession, "GenBank");
return cloneString(url);
}
void printNcbiGeneUrl(FILE *f, char *gene)
/* Print URL for Entrez browser on a nucleotide. */
{
fprintf(f, ncbiGeneFormat, gene);
}
void printEntrezNucleotideUrl(FILE *f, char *accession)
/* Print URL for Entrez browser on a nucleotide. */
{
fprintf(f, entrezFormat, "Nucleotide", accession, "GenBank");
}
void printEntrezEstUrl(FILE *f, char *accession)
/* Print URL for Entrez browser on a nucleotide. */
{
fprintf(f, entrezFormat, "nucest", accession, "GenBank");
}
void printEntrezProteinUrl(FILE *f, char *accession)
/* Print URL for Entrez browser on a protein. */
{
fprintf(f, entrezFormat, "Protein", accession, "GenPept");
}
static void printEntrezPubMedUrl(FILE *f, char *term)
/* Print URL for Entrez browser on a PubMed search. */
{
fprintf(f, entrezFormat, "PubMed", term, "DocSum");
}
static void printEntrezPubMedPureSearchUrl(FILE *f, char *term, char *keyword)
/* Print URL for Entrez browser on a PubMed search. */
{
fprintf(f, entrezPureSearchFormat, "PubMed", term, keyword);
}
void printEntrezPubMedUidAbstractUrl(FILE *f, int pmid)
/* Print URL for Entrez browser on a PubMed search. */
{
fprintf(f, entrezUidFormat, "PubMed", pmid, "Abstract");
}
void printEntrezPubMedUidUrl(FILE *f, int pmid)
/* Print URL for Entrez browser on a PubMed search. */
{
fprintf(f, entrezUidFormat, "PubMed", pmid, "Summary");
}
void printEntrezGeneUrl(FILE *f, int geneid)
/* Print URL for Entrez browser on a gene details page. */
{
fprintf(f, entrezUidFormat, "gene", geneid, "Graphics");
}
static void printEntrezOMIMUrl(FILE *f, int id)
/* Print URL for Entrez browser on an OMIM search. */
{
char buf[64];
snprintf(buf, sizeof(buf), "%d", id);
fprintf(f, entrezFormat, "OMIM", buf, "Detailed");
}
void printSwissProtAccUrl(FILE *f, char *accession)
/* Print URL for Swiss-Prot protein accession. */
{
fprintf(f, uniprotFormat, accession);
}
static void printSwissProtProteinUrl(FILE *f, char *accession)
/* Print URL for Swiss-Prot NiceProt on a protein. */
{
char *spAcc;
/* make sure accession number is used (not display ID) when linking to Swiss-Prot */
spAcc = uniProtFindPrimAcc(accession);
if (spAcc != NULL)
{
printSwissProtAccUrl(f, accession);
}
else
{
fprintf(f, uniprotFormat, accession);
}
}
static void printSwissProtVariationUrl(FILE *f, char *accession)
/* Print URL for Swiss-Prot variation data on a protein. */
{
if (accession != NULL)
{
fprintf(f, "\"http://www.expasy.org/cgi-bin/get-sprot-variant.pl?%s\"", accession);
}
}
static void printOmimUrl(FILE *f, char *term)
/* Print URL for OMIM data on a protein. */
{
if (term != NULL)
{
fprintf(f, "\"https://www.ncbi.nlm.nih.gov/omim/%s\"", term);
}
}
static void printEntrezUniSTSUrl(FILE *f, char *name)
/* Print URL for Entrez browser on a STS name. */
{
fprintf(f, "\"%s&term=%s\"", unistsnameScript, name);
}
static void printUnistsUrl(FILE *f, int id)
/* Print URL for UniSTS record for an id. */
{
fprintf(f, "\"%s%d\"", unistsScript, id);
}
/* Print URL for GDB browser for an id
* GDB currently inoperative, so have temporarily disabled this function
*
static void printGdbUrl(FILE *f, char *id)
{
fprintf(f, "%s", id);
}
*/
static void printCloneDbUrl(FILE *f, char *clone)
/* Print URL for Clone Registry at NCBI for a clone */
{
fprintf(f, "\"%s%s\"", cloneDbScript, clone);
}
static void printTraceTiUrl(FILE *f, char *name)
/* Print URL for Trace Archive at NCBI for a trace id (TI) */
{
fprintf(f, "\"%s%s\"", traceScript, name);
}
static void printTraceUrl(FILE *f, char *idType, char *name)
/* Print URL for Trace Archive at NCBI for an identifier specified by type */
{
fprintf(f, "\"%s%s%%3D%%27%s%%27\"", traceScript, idType, name);
}
static void printGenMapDbUrl(FILE *f, char *clone)
/* Print URL for GenMapDb at UPenn for a clone */
{
fprintf(f, "\"%s%s\"", genMapDbScript, clone);
}
static void printFlyBaseUrl(FILE *f, char *fbId)
/* Print URL for FlyBase browser. */
{
fprintf(f, "\"http://flybase.net/.bin/fbidq.html?%s\"", fbId);
}
static void printBDGPUrl(FILE *f, char *bdgpName)
/* Print URL for Berkeley Drosophila Genome Project browser. */
{
fprintf(f, "\"http://www.fruitfly.org/cgi-bin/annot/gene?%s\"", bdgpName);
}
char *hgTracksPathAndSettings()
/* Return path with hgTracks CGI path and session state variable. */
{
static struct dyString *dy = NULL;
if (dy == NULL)
{
dy = newDyString(128);
dyStringPrintf(dy, "%s?%s", hgTracksName(), cartSidUrlString(cart));
}
return dy->string;
}
char *hgcPathAndSettings()
/* Return path with this CGI script and session state variable. */
{
static struct dyString *dy = NULL;
if (dy == NULL)
{
dy = newDyString(128);
dyStringPrintf(dy, "%s?%s", hgcName(), cartSidUrlString(cart));
}
return dy->string;
}
void hgcAnchorSomewhere(char *group, char *item, char *other, char *chrom)
/* Generate an anchor that calls click processing program with item
* and other parameters. */
{
char *tbl = cgiUsualString("table", cgiString("g"));
char *itemSafe = cgiEncode(item);
printf("",
hgcPathAndSettings(), group, itemSafe, chrom, winStart, winEnd, other,
tbl);
freeMem(itemSafe);
}
void hgcAnchorPosition(char *group, char *item)
/* Generate an anchor that calls click processing program with item
* and group parameters. */
{
char *tbl = cgiUsualString("table", cgiString("g"));
printf("",
hgcPathAndSettings(), group, item, tbl);
}
void hgcAnchorWindow(char *group, char *item, int thisWinStart,
int thisWinEnd, char *other, char *chrom)
/* Generate an anchor that calls click processing program with item
* and other parameters, INCLUDING the ability to specify left and
* right window positions different from the current window*/
{
printf("",
hgcPathAndSettings(), group, item, chrom,
thisWinStart, thisWinEnd, other);
}
void hgcAnchorJalview(char *item, char *fa)
/* Generate an anchor to jalview. */
{
struct dyString *dy = cgiUrlString();
printf("",
hgcName(), dy->string);
dyStringFree(&dy);
}
void hgcAnchorTranslatedChain(int item, char *other, char *chrom, int cdsStart, int cdsEnd)
/* Generate an anchor that calls click processing program with item
* and other parameters. */
{
char *tbl = cgiUsualString("table", cgiString("g"));
printf("",
hgcPathAndSettings(), "htcChainTransAli", item, chrom, winStart, winEnd, other,
tbl, cdsStart, cdsEnd);
}
void hgcAnchorPseudoGene(char *item, char *other, char *chrom, char *tag, int start, int end, char *qChrom, int qStart, int qEnd, int chainId, char *db2)
/* Generate an anchor to htcPseudoGene. */
{
char *encodedItem = cgiEncode(item);
printf("",
hgcPathAndSettings(), "htcPseudoGene", encodedItem, chrom, start, end,
other, db2, chainId, qChrom, qStart, qEnd, tag);
}
void hgcAnchorSomewhereDb(char *group, char *item, char *other,
char *chrom, char *db)
/* Generate an anchor that calls click processing program with item
* and other parameters. */
{
printf("",
hgcPathAndSettings(), group, item, chrom, winStart, winEnd, other, db);
}
void hgcAnchor(char *group, char *item, char *other)
/* Generate an anchor that calls click processing program with item
* and other parameters. */
{
hgcAnchorSomewhere(group, item, other, seqName);
}
void writeFramesetType()
/* Write document type that shows a frame set, rather than regular HTML. */
{
fputs("\n", stdout);
}
void htmlFramesetStart(char *title)
/* Write DOCTYPE HTML and HEAD sections for framesets. */
{
/* Print start of HTML. */
writeFramesetType();
puts("");
char *meta = getCspMetaHeader();
printf("\n%s%s\n\n\n", meta, title);
freeMem(meta);
}
boolean clipToChrom(int *pStart, int *pEnd)
/* Clip start/end coordinates to fit in chromosome. */
{
static int chromSize = -1;
if (chromSize < 0)
chromSize = hChromSize(database, seqName);
if (*pStart < 0) *pStart = 0;
if (*pEnd > chromSize) *pEnd = chromSize;
return *pStart < *pEnd;
}
struct genbankCds getCds(struct sqlConnection *conn, char *acc)
/* obtain and parse the CDS, errAbort if not found or invalid */
{
char query[256];
sqlSafef(query, sizeof(query), "select c.name from %s,%s c where (acc=\"%s\") and (c.id=cds)",
gbCdnaInfoTable,cdsTable, acc);
char *cdsStr = sqlQuickString(conn, query);
if (cdsStr == NULL)
errAbort("no CDS found for %s", acc);
struct genbankCds cds;
if (!genbankCdsParse(cdsStr, &cds))
errAbort("can't parse CDS for %s: %s", acc, cdsStr);
return cds;
}
void printCappedSequence(int start, int end, int extra)
/* Print DNA from start to end including extra at either end.
* Capitalize bits from start to end. */
{
struct dnaSeq *seq;
int s, e, i;
struct cfm *cfm;
if (!clipToChrom(&start, &end))
return;
s = start - extra;
e = end + extra;
clipToChrom(&s, &e);
printf("Here is the sequence around this feature: bases %d to %d of %s. "
"The bases that contain the feature itself are in upper case.
\n",
s, e, seqName);
seq = hDnaFromSeq(database, seqName, s, e, dnaLower);
toUpperN(seq->dna + (start-s), end - start);
printf("");
cfm = cfmNew(10, 50, TRUE, FALSE, stdout, s);
for (i=0; isize; ++i)
{
cfmOut(cfm, seq->dna[i], 0);
}
cfmFree(&cfm);
printf("
");
}
void printBand(char *chrom, int start, int end, boolean tableFormat)
/* Print all matching chromosome bands. */
/* Ignore end if it is zero. */
{
char sband[32], eband[32];
boolean gotS = FALSE;
boolean gotE = FALSE;
if (start < 0)
return;
gotS = hChromBand(database, chrom, start, sband);
/* if the start lookup fails, don't bother with the end lookup */
if (!gotS)
return;
/* if no end chrom, print start band and exit */
if (end == 0)
{
if (tableFormat)
printf("Band: | %s |
\n",sband);
else
printf("Band: %s
\n", sband);
return;
}
gotE = hChromBand(database, chrom, end-1, eband);
/* if eband equals sband, just use sband */
if (gotE && sameString(sband,eband))
gotE = FALSE;
if (!gotE)
{
if (tableFormat)
printf("Band: | %s |
\n",sband);
else
printf("Band: %s
\n", sband);
return;
}
if (tableFormat)
printf("Bands: | %s - %s |
\n",sband, eband);
else
printf("Bands: %s - %s
\n", sband, eband);
}
void printPosOnChrom(char *chrom, int start, int end, char *strand,
boolean featDna, char *item)
/* Print position lines referenced to chromosome. Strand argument may be NULL */
{
printf("Position: "
"",
hgTracksPathAndSettings(), database, chrom, start+1, end);
printf("%s:%d-%d
\n", chrom, start+1, end);
/* printBand(chrom, (start + end)/2, 0, FALSE); */
printBand(chrom, start, end, FALSE);
printf("Genomic Size: %d
\n", end - start);
if (strand != NULL && differentString(strand,".") && isNotEmpty(strand))
printf("Strand: %s
\n", strand);
else
strand = "?";
if (featDna && end > start)
{
char *tbl = cgiUsualString("table", cgiString("g"));
strand = cgiEncode(strand);
printf(""
"View DNA for this feature (%s/%s)
\n", hgcPathAndSettings(),
start, (item != NULL ? cgiEncode(item) : ""),
chrom, start, end, strand, tbl, trackHubSkipHubName(database), trackHubSkipHubName(hGenome(database)));
}
}
void printPosOnScaffold(char *chrom, int start, int end, char *strand)
/* Print position lines referenced to scaffold. 'strand' argument may be null. */
{
char *scaffoldName;
int scaffoldStart, scaffoldEnd;
if (!hScaffoldPos(database, chrom, start, end, &scaffoldName, &scaffoldStart, &scaffoldEnd))
{
printPosOnChrom(chrom, start,end,strand, FALSE, NULL);
return;
}
printf("Scaffold: %s
\n", scaffoldName);
printf("Begin in Scaffold: %d
\n", scaffoldStart+1);
printf("End in Scaffold: %d
\n", scaffoldEnd);
printf("Genomic Size: %d
\n", scaffoldEnd - scaffoldStart);
if (strand != NULL)
printf("Strand: %s
\n", strand);
else
strand = "?";
}
void printPos(char *chrom, int start, int end, char *strand, boolean featDna,
char *item)
/* Print position lines. 'strand' argument may be null. */
{
if (sameWord(organism, "Fugu"))
/* Fugu is the only chrUn-based scaffold assembly, so it
* has non-general code here. Later scaffold assemblies
* treat scaffolds as chroms.*/
printPosOnScaffold(chrom, start, end, strand);
else
printPosOnChrom(chrom, start, end, strand, featDna, item);
}
void samplePrintPos(struct sample *smp, int smpSize)
/* Print first three fields of a sample 9 type structure in
* standard format. */
{
if ( smpSize != 9 )
errAbort("Invalid sample entry!\n It has %d fields instead of 9\n",
smpSize);
printf("Item: %s
\n", smp->name);
printf("Score: %d
\n", smp->score);
printf("Strand: %s
\n", smp->strand);
printPos(smp->chrom, smp->chromStart, smp->chromEnd, NULL, TRUE, smp->name);
}
void bedPrintPos(struct bed *bed, int bedSize, struct trackDb *tdb)
/* Print first bedSize fields of a bed type structure in
* standard format. */
{
char *strand = NULL;
if (bedSize >= 4 && bed->name[0] != 0)
{
char *label = "Item", *tdbLabel = NULL;
if (tdb && ((tdbLabel = trackDbSetting(tdb, "bedNameLabel")) != NULL))
label = tdbLabel;
printf("%s: %s
\n", label, bed->name);
}
if (bedSize >= 5)
{
if (!tdb || !trackDbSetting(tdb, "noScoreFilter"))
{
char *scoreLabel = trackDbSettingOrDefault(tdb, "scoreLabel", "Score");
printf("%s: %d
\n", scoreLabel, bed->score);
}
}
if (bedSize >= 6)
{
strand = bed->strand;
}
printPos(bed->chrom, bed->chromStart, bed->chromEnd, strand, TRUE, bed->name);
}
void genericHeader(struct trackDb *tdb, char *item)
/* Put up generic track info. */
{
if (item != NULL && item[0] != 0)
cartWebStart(cart, database, "%s (%s)", tdb->longLabel, item);
else
cartWebStart(cart, database, "%s", tdb->longLabel);
}
void printItemDetailsHtml(struct trackDb *tdb, char *itemName)
/* if track has an itemDetailsHtml, retrieve and print the HTML */
{
char *tableName = trackDbSetting(tdb, "itemDetailsHtmlTable");
if (tableName != NULL)
{
struct sqlConnection *conn = hAllocConn(database);
struct itemDetailsHtml *html, *htmls;
// if the details table has chrom/start/end columns, then use these to lookup html
if (sqlColumnExists(conn, tableName, "chrom"))
{
char *chrom = cgiString("c");
int start = cgiInt("o");
int end = cgiInt("t");
htmls = sqlQueryObjs(conn, (sqlLoadFunc)itemDetailsHtmlLoad, sqlQueryMulti,
"select name, html from %s where \
name = '%s' and \
chrom = '%s' and \
start = '%d' and \
end = '%d'", tableName, itemName, chrom, start, end);
}
// otherwise, assume that the itemName is unique
else
htmls = sqlQueryObjs(conn, (sqlLoadFunc)itemDetailsHtmlLoad, sqlQueryMulti,
"select name, html from %s where name = '%s'", tableName, itemName);
for (html = htmls; html != NULL; html = html->next)
printf("
\n%s\n", html->html);
itemDetailsHtmlFreeList(&htmls);
hFreeConn(&conn);
}
}
char *getIdInUrl(struct trackDb *tdb, char *itemName)
/* If we have an idInUrlSql tag, look up itemName in that, else just
* return itemName. */
{
char *sql = trackDbSetting(tdb, "idInUrlSql");
char *id = itemName;
if (sql != NULL)
{
char query[1024];
sqlSafef(query, sizeof(query), sql, itemName);
struct sqlConnection *conn = hAllocConn(database);
id = sqlQuickString(conn, query);
hFreeConn(&conn);
}
return id;
}
char *getUrlSetting(struct trackDb *tdb, char* urlSetting)
/* get the "url" setting for the current track */
{
char *url;
if (sameWord(urlSetting, "url"))
url = tdb->url;
else
url = trackDbSetting(tdb, urlSetting);
return url;
}
void printIframe(struct trackDb *tdb, char *itemName)
/* print an iframe with the URL specified in trackDb (iframeUrl), can have
* the standard codes in it (like $$ for itemName, etc)
*/
{
char *url = getUrlSetting(tdb, "iframeUrl");
if (url==NULL)
return;
char *eUrl = replaceInUrl(url, itemName, cart, database, seqName, winStart, winEnd,
tdb->track, FALSE, NULL);
if (eUrl==NULL)
return;
char *iframeOptions = trackDbSettingOrDefault(tdb, "iframeOptions", "width='100%%' height='1024'");
// Resizing requires the hgcDetails pages to include a bit of javascript.
//
// Explanation how this works and why the javascript is needed:
// http://stackoverflow.com/questions/153152/resizing-an-iframe-based-on-content
// In short:
// - iframes have a fixed size in html, resizing can only be done in javascript
// - the iframed page cannot call the resize() function in the hgc html directly, as they have
// been loaded from different webservers
// - one way around it is that the iframed page includes a helper page on our server and
// send their size to the helper page (pages can call functions of included pages)
// - the helper page then sends the size back to hgc (pages on the same server can
// call each others' functions)
// width='%s' height='%s' src='%s' seamless scrolling='%s' frameborder='%s'
printf(" \
\
\
\
", eUrl, iframeOptions);
}
void printCustomUrlWithLabel(struct trackDb *tdb, char *itemName, char *itemLabel,
char *urlSetting, boolean encode, struct slPair *fields)
/* Print custom URL specified in trackDb settings. */
{
char urlLabelSetting[32];
// replace the $$ and other wildchards with the url given in tdb
char *url = getUrlSetting(tdb, urlSetting);
//char* eUrl = constructUrl(tdb, url, itemName, encode);
if (url==NULL || isEmpty(url))
return;
char *eUrl = replaceInUrl(url, itemName, cart, database, seqName, winStart, winEnd, tdb->track,
encode, fields);
if (eUrl==NULL)
return;
/* create the url label setting for trackDb from the url
setting prefix */
safef(urlLabelSetting, sizeof(urlLabelSetting), "%sLabel", urlSetting);
char *linkLabel = trackDbSettingOrDefault(tdb, urlLabelSetting, "Outside Link:");
// if we got no item name from hgTracks or the item name does not appear in the URL
// there is no need to show the item name at all
if (isEmpty(itemName) || !stringIn("$$", url))
{
printf("%s
",eUrl, linkLabel);
return;
}
printf("%s ",linkLabel);
printf("", eUrl);
if (sameWord(tdb->table, "npredGene"))
{
printf("%s (%s)
\n", itemName, "NCBI MapView");
}
else
{
char *label = itemName;
if (isNotEmpty(itemLabel) && differentString(itemName, itemLabel))
label = itemLabel;
printf("%s
\n", label);
}
//freeMem(&eUrl); small memory leak
}
void printCustomUrlWithFields(struct trackDb *tdb, char *itemName, char *itemLabel, boolean encode, struct slPair *fields)
/* Wrapper to call printCustomUrlWithLabel with additional fields to substitute */
{
char urlSetting[10];
safef(urlSetting, sizeof(urlSetting), "url");
printCustomUrlWithLabel(tdb, itemName, itemLabel, urlSetting, encode, fields);
}
void printCustomUrl(struct trackDb *tdb, char *itemName, boolean encode)
/* Wrapper to call printCustomUrlWithLabel using the url setting in trackDb */
{
printCustomUrlWithFields(tdb, itemName, itemName, encode, NULL);
}
void printOtherCustomUrlWithFields(struct trackDb *tdb, char *itemName, char *urlSetting,
boolean encode, struct slPair *fields)
/* Wrapper to call printCustomUrlWithLabel to use another url setting other than url in trackDb e.g. url2, this allows the use of multiple urls for a track
to be set in trackDb. */
{
printCustomUrlWithLabel(tdb, itemName, itemName, urlSetting, encode, fields);
}
void printOtherCustomUrl(struct trackDb *tdb, char *itemName, char* urlSetting, boolean encode)
/* Wrapper to call printCustomUrlWithLabel to use another url setting other than url in trackDb e.g. url2, this allows the use of multiple urls for a track
to be set in trackDb. */
{
printCustomUrlWithLabel(tdb, itemName, itemName, urlSetting, encode, NULL);
}
void genericSampleClick(struct sqlConnection *conn, struct trackDb *tdb,
char *item, int start, int smpSize)
/* Handle click in generic sample (wiggle) track. */
{
char table[HDB_MAX_TABLE_STRING];
boolean hasBin;
struct sample *smp;
char query[512];
struct sqlResult *sr;
char **row;
boolean firstTime = TRUE;
if (!hFindSplitTable(database, seqName, tdb->table, table, sizeof table, &hasBin))
errAbort("genericSampleClick track %s not found", tdb->table);
sqlSafef(query, sizeof query, "select * from %s where name = '%s' and chrom = '%s' and chromStart = %d",
table, item, seqName, start);
/*errAbort( "select * from %s where name = '%s' and chrom = '%s' and chromStart = %d",
table, item, seqName, start);*/
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
if (firstTime)
firstTime = FALSE;
else
htmlHorizontalLine();
smp = sampleLoad(row+hasBin);
samplePrintPos(smp, smpSize);
}
}
void showBedTopScorers(struct bed *bedList, char *item, int start, int max)
/* Show a list of track items sorted by descending score,
* with current item highlighted.
* max is upper bound on how many items will be displayed. */
{
int i;
struct bed *bed;
puts("Top-scoring elements in window:
");
for (i=0, bed=bedList; bed != NULL && i < max; bed=bed->next, i++)
{
if (sameWord(item, bed->name) && bed->chromStart == start)
printf(" %s ", bed->name);
else
printf(" %s ", bed->name);
printf("(%s:%d-%d) %d
\n",
bed->chrom, bed->chromStart+1, bed->chromEnd, bed->score);
}
if (bed != NULL)
printf("(list truncated -- more than %d elements)
\n", max);
}
void showBedTopScorersInWindow(struct sqlConnection *conn,
struct trackDb *tdb, char *item, int start,
int maxScorers, char *filterTable, int filterCt)
/* Show a list of track items in the current browser window, ordered by
* score. Track must be BED 5 or greater. maxScorers is upper bound on
* how many items will be displayed. If filterTable is not NULL and exists,
* it contains the 100K top-scorers in the entire track, and filterCt
* is the threshold for how many are candidates for display. */
{
struct sqlResult *sr = NULL;
char **row = NULL;
struct bed *bedList = NULL, *bed = NULL;
char table[HDB_MAX_TABLE_STRING];
boolean hasBin = FALSE;
char query[512];
if (filterTable)
{
/* Track display only shows top-scoring N elements -- restrict
* the list to these. Get them from the filter table */
hasBin = hOffsetPastBin(database, hDefaultChrom(database), filterTable);
sqlSafef(query, sizeof(query), "select * from %s order by score desc limit %d",
filterTable, filterCt);
}
else
{
if (!hFindSplitTable(database, seqName, tdb->table, table, sizeof table, &hasBin))
errAbort("showBedTopScorersInWindow track %s not found", tdb->table);
sqlSafef(query, sizeof(query),
"select * from %s where chrom = '%s' and chromEnd > %d and "
"chromStart < %d order by score desc",
table, seqName, winStart, winEnd);
}
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
bed = bedLoadN(row+hasBin, 5);
if (!filterTable
|| ( sameString(bed->chrom, seqName)
&& bed->chromStart < winEnd
&& bed->chromEnd > winStart))
{
slAddHead(&bedList, bed);
}
else
bedFree(&bed);
}
sqlFreeResult(&sr);
if (bedList == NULL)
return;
slReverse(&bedList);
showBedTopScorers(bedList, item, start, maxScorers);
}
void getBedTopScorers(struct sqlConnection *conn, struct trackDb *tdb,
char *table, char *item, int start, int bedSize)
/* This function determines if showTopScorers is set in trackDb and also */
/* if the filterTopScorers setting is on. Then it passes the relevant */
/* settings to showBedTopScorersInWindow() so that the top N scoring */
/* items in the window are listed on the details page */
{
char *showTopScorers = trackDbSetting(tdb, "showTopScorers");
char *filterTopScorers = trackDbSetting(tdb,"filterTopScorers");
boolean doFilterTopScorers = FALSE;
char *words[3];
char cartVar[512];
int filterTopScoreCt = 0;
char *filterTopScoreTable = NULL;
safef(cartVar, sizeof cartVar, "%s.%s", table, "filterTopScorersOn");
if (filterTopScorers != NULL)
{
if (chopLine(cloneString(filterTopScorers), words) == 3)
{
doFilterTopScorers = sameString(words[0], "on");
filterTopScoreCt = atoi(words[1]);
filterTopScoreTable = words[2];
}
}
if (bedSize >= 5 && showTopScorers != NULL)
{
/* list top-scoring elements in window */
int maxScorers = sqlUnsigned(showTopScorers);
doFilterTopScorers = cartCgiUsualBoolean(cart, cartVar, doFilterTopScorers);
if (doFilterTopScorers && hTableExists(database, filterTopScoreTable))
{
/* limit to those in the top N, from table */
safef(cartVar, sizeof cartVar, "%s.%s", table, "filterTopScorersCt");
filterTopScoreCt = cartCgiUsualInt(cart, cartVar, filterTopScoreCt);
}
else
/* show all */
filterTopScoreTable = NULL;
showBedTopScorersInWindow(conn, tdb, item, start, maxScorers,
filterTopScoreTable, filterTopScoreCt);
}
}
void linkToOtherBrowser(char *otherDb, char *chrom, int start, int end);
void linkToOtherBrowserExtra(char *otherDb, char *chrom, int start, int end, char *extra);
static void printCompareGenomeLinks(struct trackDb *tdb,char *name)
/* if "compareGenomeLinks" exists then a table of the same name in n different databases is sought.
if a row exist in the other db table matching the current item, then a link is printed */
{
char *setting = trackDbSettingClosestToHome(tdb,"compareGenomeLinks");
if (setting == NULL)
return;
struct sqlConnection *conn = hAllocConn(database); // Need only to connect to one db
if (conn == NULL)
return;
char *words[20];
setting = cloneString(setting);
int ix,cnt = chopLine(setting, words);
char query[512];
char extra[128];
boolean gotOne = FALSE;
for (ix=0;ixtable;
else
{
*table++ = '\0'; // assigns before advance
if ((words[ix] = strchr(table,'.')) != NULL)
{
*words[ix] = '\0';
column = ++words[ix]; // advance before assigns
}
}
sqlSafef(query,sizeof(query),"select chrom,chromStart,chromEnd from %s.%s where %s=\"%s\";",
db,table,column,name);
struct sqlResult *sr = sqlGetResult(conn, query);
if (sr == NULL)
continue;
char **row = sqlNextRow(sr);
if (row == NULL)
continue;
char *chrom = *row++;
int beg = atoi(*row++);
int end = atoi(*row);
if (!gotOne)
{
gotOne = TRUE;
printf("The item \"%s\" has been located in other genomes:\n
\n",name);
}
printf("- ");
safef(extra,sizeof(extra),"%s=full",tdb->track);
linkToOtherBrowserExtra(db, chrom, beg, end, extra);
printf("%s
\n",strSwapChar(title,'_',' '));
sqlFreeResult(&sr);
}
hFreeConn(&conn);
freeMem(setting);
if (gotOne)
printf("
\n");
else
printf("Currently the item \"%s\" has not been located in another genome.\n",name);
}
void mafPrettyOut(FILE *f, struct mafAli *maf, int lineSize,
boolean onlyDiff, int blockNo);
void doAtom( struct trackDb *tdb, char *item)
{
char table[HDB_MAX_TABLE_STRING];
boolean hasBin;
//struct bed *bed;
char query[512];
struct sqlResult *sr;
char **row;
//boolean firstTime = TRUE;
int start = cartInt(cart, "o");
//struct sqlConnection *conn = hAllocConn(database);
char *user = cfgOption("db.user");
char *password = cfgOption("db.password");
struct sqlConnection *sc;
struct atom ret;
genericHeader(tdb, item);
if (!hFindSplitTable(database, seqName, tdb->table, table, sizeof table, &hasBin))
errAbort("mafPrettyOut track %s not found", tdb->table);
#if 0
sqlSafef(query, sizeof query, "select * from %s where name = '%s' and chrom = '%s' and chromStart = %d", table, escapedName, seqName, start);
sr = sqlGetResult(conn, query);
printf("This is the item you clicked on:
\n");
while ((row = sqlNextRow(sr)) != NULL)
{
if (firstTime)
firstTime = FALSE;
else
htmlHorizontalLine();
bed = bedLoadN(row+hasBin, 4);
bedPrintPos(bed, 4, tdb);
}
sqlFreeResult(&sr);
sqlSafef(query, sizeof query, "select * from %s where name = '%s'", table, escapedName);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
bed = bedLoadN(row+hasBin, 4);
if (bed->chromStart != start)
{
htmlHorizontalLine();
firstTime = FALSE;
printf("Another instances on %s:
\n",database);
bedPrintPos(bed, 4, tdb);
}
}
sqlFreeResult(&sr);
#endif
sc = sqlConnectRemote("localhost", user, password, "hgFixed");
sqlSafef(query, sizeof(query),
"select * from %s where name = '%s'", table, item);
sr = sqlGetResult(sc, query);
printf("Atom %s instances ('*' marks item you clicked on)
\n",item);
printf("
\n");
//printf("Ins#\tSpecies\t\tChrom\tStart\tEnd\tStrand\n");
printf( " # %-10s %-5s %12s %12s %10s %s %-10s %-10s\n",
"species","chrom", "start", "end", "length", "strand","fivePrime","threePrime");
while ((row = sqlNextRow(sr)) != NULL)
{
atomStaticLoad(row, &ret);
//atomOutput(&ret, stdout, '\t', '\n');
linkToOtherBrowser(ret.species, ret.chrom, ret.start, ret.end);
if (sameString(ret.chrom, seqName) && (start == ret.start) &&
sameString(ret.species, database))
printf("* ");
else
printf(" ");
printf( "%4d %-10s %-5s %12d %12d %10d %c %-10s %-10s\n",
ret.instance, ret.species,ret.chrom, ret.start + 1, ret.end,
ret.end - ret.start + 1, ret.strand[0],ret.fivePrime,ret.threePrime);
}
printf("");
sqlFreeResult(&sr);
if (!sameString("atom20080226d", table))
return;
printf("
");
printf("");
printf("");
printf("");
printf("Suh Trees \n");
printf(" ",item);
printf(" |  ",item);
printf(" |
---|
");
printf("NJ Trees \n");
printf(" ",item);
printf(" |  ",item);
printf(" |
---|
");
/*
printf("Gap UPGMA Trees \n");
printf(" ",item);
printf(" |  ",item);
printf(" |
---|
");
*/
return;
char buffer[4096];
struct mafFile *mf;
safef(buffer, sizeof buffer, "/gbdb/hgFixed/%s/%s.maf",table, item);
mf = mafMayOpen(buffer);
if (mf != NULL)
{
mafFileFree(&mf);
mf = mafReadAll(buffer);
struct mafAli *mafAli;
int count = 1;
int numBlocks = 0;
for (mafAli=mf->alignments; mafAli; mafAli = mafAli->next)
numBlocks++;
for (mafAli=mf->alignments; mafAli; mafAli = mafAli->next)
{
printf("
Multiple Alignment Block %d of %d
",
count, numBlocks);
mafPrettyOut(stdout, mafAli, 70, FALSE, count++);
if (mafAli->next != NULL)
{
struct mafAli *next = mafAli->next;
struct mafComp *comp1 = mafAli->components;
struct mafComp *comp2 = next->components;
printf("
Gaps:\n");
for(; comp1 ; comp1 = comp1->next, comp2 = comp2->next)
{
int diff;
char dbOnly[4096];
diff = comp2->start - (comp1->start + comp1->size);
safef(dbOnly, sizeof(dbOnly), "%s", comp1->src);
chopPrefix(dbOnly);
printf("%-20s %d\n",hOrganism(dbOnly), diff);
}
printf("
");
}
}
}
}
char **getIdNameMap(struct trackDb *tdb, struct asColumn *col, int *size)
/* Allocate and fill an array mapping id to name. Currently limited to specific columns. */
{
char *idNameTable = trackDbSetting(tdb, "sourceTable");
if (!idNameTable || differentString("sourceIds", col->name))
return NULL;
struct sqlResult *sr;
char query[256];
char **row;
char **idNames;
sqlSafef(query, sizeof(query), "select max(id) from %s", idNameTable);
struct sqlConnection *conn = hAllocConnTrack(database, tdb);
int maxId = sqlQuickNum(conn, query);
AllocArray(idNames, maxId+1);
sqlSafef(query, sizeof(query), "select id, name from %s", idNameTable);
sr = sqlGetResult(conn, query);
int id;
while ((row = sqlNextRow(sr)) != NULL)
{
id = sqlUnsigned(row[0]);
if (id > maxId)
errAbort("Internal error: id %d > maxId %d in %s", id, maxId, idNameTable);
idNames[id] = cloneString(row[1]);
}
sqlFreeResult(&sr);
hFreeConn(&conn);
if (size)
*size = maxId+1;
return idNames;
}
void printIdOrLinks(struct asColumn *col, struct hash *fieldToUrl, struct trackDb *tdb, char *idList)
/* if trackDb does not contain a "urls" entry for current column name, just print idList as it is.
* Otherwise treat idList as a comma-sep list of IDs and print one row per id, with a link to url,
* ($$ in url is OK, wildcards like $P, $p, are also OK)
* */
{
// try to find a fieldName=url setting in the "urls" tdb statement, print id if not found
char *url = NULL;
if (fieldToUrl != NULL)
url = (char*)hashFindVal(fieldToUrl, col->name);
if (url == NULL)
{
printf("%s | \n", idList);
return;
}
// split the id into parts and print each part as a link
struct slName *slIds = slNameListFromComma(idList);
struct slName *itemId = NULL;
// handle id->name mapping for multi-source items
int nameCount;
char **idNames = getIdNameMap(tdb, col, &nameCount);
printf("");
for (itemId = slIds; itemId!=NULL; itemId = itemId->next)
{
if (itemId != slIds)
printf(", ");
char *itemName = trimSpaces(itemId->name);
if (idNames)
{
unsigned int id = sqlUnsigned(itemName);
if (id < nameCount)
itemName = idNames[sqlUnsigned(itemName)];
}
// a | character can optionally be used to separate the ID used for $$ from the name shown in the link (like in Wikimedia markup)
char *idForUrl = itemName;
boolean encode = TRUE;
if (strstr(itemName, "|"))
{
char *parts[2];
chopString(itemName, "|", parts, ArraySize(parts));
idForUrl = parts[0];
itemName = parts[1];
encode = FALSE; // assume the link is already encoded
}
if (startsWith("http", itemName)) // the ID may be a full URL already, encoding would destroy it
encode = FALSE;
char *idUrl = replaceInUrl(url, idForUrl, cart, database, seqName, winStart,
winEnd, tdb->track, encode, NULL);
printf("%s", idUrl, itemName);
}
printf(" | \n");
freeMem(slIds);
//freeMem(idNames);
}
int extraFieldsStart(struct trackDb *tdb, int fieldCount, struct asObject *as)
/* return the index of the first extra field */
{
int start = 0;
char *type = cloneString(tdb->type);
char *word = nextWord(&type);
if (word && (sameWord(word,"bed") || startsWith("big", word)))
{
if (NULL != (word = nextWord(&type)))
start = sqlUnsigned(word);
else // custom beds and bigBeds may not have full type "begBed 9 +"
start = max(0,slCount(as->columnList) - fieldCount);
}
return start;
}
struct slPair *getExtraFields(struct trackDb *tdb, char **fields, int fieldCount)
/* return the extra field names and their values as a list of slPairs. */
{
struct asObject *as = asForDb(tdb, database);
if (as == NULL)
return NULL;
struct asColumn *col = as->columnList;
int start = extraFieldsStart(tdb, fieldCount, as);
// skip past known fields
for (;start !=0 && col != NULL;col=col->next)
if (start > 0)
start--;
struct slPair *extraFields = 0;
int count = 0;
for (;col != NULL && count < fieldCount;col=col->next)
{
struct slPair *slp;
AllocVar(slp);
char *fieldName = col->name;
char *fieldVal = fields[count];
slp->name = fieldName;
slp->val = fieldVal;
slAddHead(&extraFields, slp);
count++;
//printf("name %s, val %s, idx %d
", fieldName, fieldVal, count);
}
slReverse(extraFields);
return extraFields;
}
struct slPair *getFields(struct trackDb *tdb, char **row)
/* return field names and their values as a list of slPairs. */
// TODO: refactor with getExtraFields
{
struct asObject *as = asForDb(tdb, database);
if (as == NULL)
return NULL;
int fieldCount = slCount(as->columnList);
struct slPair *fields = NULL;
struct asColumn *col = as->columnList;
int count = 0;
for (count = 0; col != NULL && count < fieldCount; col = col->next)
{
struct slPair *field;
AllocVar(field);
char *fieldName = col->name;
char *fieldVal = row[count];
field->name = fieldName;
field->val = fieldVal;
slAddHead(&fields, field);
count++;
}
slReverse(fields);
return fields;
}
int extraFieldsPrint(struct trackDb *tdb,struct sqlResult *sr,char **fields,int fieldCount)
// Any extra bed or bigBed fields (defined in as and occurring after N in bed N + types.
// sr may be null for bigBeds.
// Returns number of extra fields actually printed.
{
struct asObject *as = asForDb(tdb, database);
if (as == NULL)
return 0;
// We are trying to print extra fields so we need to figure out how many fields to skip
int start = extraFieldsStart(tdb, fieldCount, as);
struct asColumn *col = as->columnList;
char *urlsStr = trackDbSettingClosestToHomeOrDefault(tdb, "urls", NULL);
struct hash* fieldToUrl = hashFromString(urlsStr);
boolean skipEmptyFields = trackDbSettingOn(tdb, "skipEmptyFields");
// make list of fields to skip
char *skipFieldsStr = trackDbSetting(tdb, "skipFields");
struct slName *skipIds = NULL;
if (skipFieldsStr)
skipIds = slNameListFromComma(skipFieldsStr);
// make list of fields that are separated from other fields
char *sepFieldsStr = trackDbSetting(tdb, "sepFields");
struct slName *sepFields = NULL;
if (sepFieldsStr)
sepFields = slNameListFromComma(sepFieldsStr);
// iterate over fields, print as table rows
int count = 0;
for (;col != NULL && count < fieldCount;col=col->next)
{
if (start > 0) // skip past already known fields
{
start--;
continue;
}
int ix = count;
if (sr != NULL)
{
ix = sqlFieldColumn(sr, col->name); // If sr provided, name must match sql columnn name!
if (ix == -1 || ix > fieldCount) // so extraField really just provides a label
continue;
}
char *fieldName = col->name;
if (count == 0)
printf("
\n\n
\n");
return count;
}
void genericBedClick(struct sqlConnection *conn, struct trackDb *tdb,
char *item, int start, int bedSize)
/* Handle click in generic BED track. */
{
char table[HDB_MAX_TABLE_STRING];
boolean hasBin;
struct bed *bed;
char query[512];
struct sqlResult *sr;
char **row;
boolean firstTime = TRUE;
if (!hFindSplitTable(database, seqName, tdb->table, table, sizeof table, &hasBin))
errAbort("genericBedClick track %s not found", tdb->table);
if (bedSize <= 3)
sqlSafef(query, sizeof query, "select * from %s where chrom = '%s' and chromStart = %d", table, seqName, start);
else
{
struct hTableInfo *hti = hFindTableInfoWithConn(conn, seqName, tdb->table);
if (hti && *hti->nameField && differentString("name", hti->nameField))
sqlSafef(query, sizeof query, "select * from %s where %s = '%s' and chrom = '%s' and chromStart = %d",
table, hti->nameField, item, seqName, start);
else
sqlSafef(query, sizeof query, "select * from %s where name = '%s' and chrom = '%s' and chromStart = %d",
table, item, seqName, start);
}
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
if (firstTime)
firstTime = FALSE;
else
htmlHorizontalLine();
bed = bedLoadN(row+hasBin, bedSize);
bedPrintPos(bed, bedSize, tdb);
extraFieldsPrint(tdb,sr,row,sqlCountColumns(sr));
// check for seq1 and seq2 in columns 7+8 (eg, pairedTagAlign)
char *setting = trackDbSetting(tdb, BASE_COLOR_USE_SEQUENCE);
if (bedSize == 6 && setting && sameString(setting, "seq1Seq2"))
printf("
Sequence 1: %s
Sequence 2: %s
\n",row[hasBin+6], row[hasBin+7]);
printCompareGenomeLinks(tdb,bed->name);
}
sqlFreeResult(&sr);
getBedTopScorers(conn, tdb, table, item, start, bedSize);
printItemDetailsHtml(tdb, item);
}
#define INTRON 10
#define CODINGA 11
#define CODINGB 12
#define UTR5 13
#define UTR3 14
#define STARTCODON 15
#define STOPCODON 16
#define SPLICESITE 17
#define NONCONSPLICE 18
#define INFRAMESTOP 19
#define INTERGENIC 20
#define REGULATORY 21
#define LABEL 22
#define RED 0xFF0000
#define GREEN 0x00FF00
#define LTGREEN 0x33FF33
#define BLUE 0x0000FF
#define MEDBLUE 0x6699FF
#define PURPLE 0x9900cc
#define BLACK 0x000000
#define CYAN 0x00FFFF
#define ORANGE 0xDD6600
#define BROWN 0x663300
#define YELLOW 0xFFFF00
#define MAGENTA 0xFF00FF
#define GRAY 0xcccccc
#define LTGRAY 0x999999
#define WHITE 0xFFFFFF
int setAttributeColor(int class)
{
switch (class)
{
case STARTCODON:
return GREEN;
case STOPCODON:
return RED;
case CODINGA:
return MEDBLUE;
case CODINGB:
return PURPLE;
case UTR5:
case UTR3:
return ORANGE;
case INTRON:
return LTGRAY;
case SPLICESITE:
case NONCONSPLICE:
return BLACK;
case INFRAMESTOP:
return MAGENTA;
case REGULATORY:
return YELLOW;
case INTERGENIC:
return GRAY;
case LABEL:
default:
return BLACK;
}
}
void startColorStr(struct dyString *dy, int color, int track)
{
currentColor[track] = color;
if (prevColor[track] != currentColor[track])
dyStringPrintf(dy,"",color);
}
void stopColorStr(struct dyString *dy, int track)
{
prevColor[track] = currentColor[track];
}
void addTag(struct dyString *dy, struct dyString *tag)
{
dyStringPrintf(dy,"",tag->string);
}
void setClassStr(struct dyString *dy, int class, int track)
{
if (class == STARTCODON)
dyStringAppend(dy,"");
startColorStr(dy,setAttributeColor(class),track);
}
void resetClassStr(struct dyString *dy, int track)
{
stopColorStr(dy,track);
}
boolean isBlue(char *s)
/* check for to see if this is colored blue (coding region)*/
{
/* check for blue */
if (strstr(s,"6699FF") == NULL)
return FALSE;
else
return TRUE;
}
int numberOfGaps(char *q,int size)
/* count number of gaps in a string array */
{
int i;
int count = 0;
for (i = 0 ; itable, table, sizeof table, &hasBin))
errAbort("pseudoGeneClick track %s not found", tdb->table);
if (bedSize <= 3)
sqlSafef(query, sizeof query, "select * from %s where chrom = '%s' and chromStart = %d", table, seqName, start);
else
sqlSafef(query, sizeof query, "select * from %s where name = '%s' and chrom = '%s' and chromStart = %d",
table, item, seqName, start);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
if (firstTime)
firstTime = FALSE;
else
htmlHorizontalLine();
bed = bedLoadN(row+hasBin, bedSize);
bedPrintPos(bed, bedSize, tdb);
}
}
void axtOneGeneOut(char *otherDb, struct axt *axtList, int lineSize,
FILE *f, struct genePred *gp, char *nibFile)
/* Output axt and orf in pretty format. */
{
struct axt *axt;
int oneSize;
int i;
int tCodonPos = 1;
int qCodonPos = 1;
int tStart;
int tEnd;
int nextStart= gp->exonStarts[0] ;
int nextEnd = gp->exonEnds[0];
int nextEndIndex = 0;
int tCoding=FALSE;
int qCoding=FALSE;
int qStopCodon = FALSE;
int tFlip=TRUE; /* flag to control target alternating colors for exons (blue and purple) */
int qFlip=TRUE; /* flag to control query alternating colors for exons (blue and purple) */
int qClass=INTERGENIC;
int tClass=INTERGENIC;
int prevTclass=INTERGENIC;
int prevQclass=INTERGENIC;
int posStrand;
DNA qCodon[4];
DNA tCodon[4];
AA qProt, tProt = 0;
int tPtr = 0;
int prevEnd = 500000000;
int intronTruncated=FALSE;
if (gp->strand[0] == '+')
{
nextEndIndex = 0;
nextStart = gp->exonStarts[nextEndIndex] ;
nextEnd = gp->exonEnds[nextEndIndex];
tStart = gp->cdsStart ;
tEnd = gp->cdsEnd-3 ;
posStrand=TRUE;
if (axtList != NULL)
tPtr = axtList->tStart;
}
else if (gp->strand[0] == '-')
{
nextEndIndex = (gp->exonCount)-1;
nextStart = (gp->exonEnds[nextEndIndex]);
nextEnd = (gp->exonStarts[nextEndIndex]);
tStart = gp->cdsEnd ;
tEnd = gp->cdsStart ;
posStrand=FALSE;
if (axtList != NULL)
tPtr = axtList->tEnd;
}
else
{
errAbort("cannot determine start_codon position for %s on %s\n",gp->name,gp->chrom);
exit(0);
}
/* safef(nibFile, sizeof(nibFile), "%s/%s.nib",nibDir,gp->chrom); */
/* if no alignment , make a bad one */
if (axtList == NULL)
{
if (gp->strand[0] == '+')
axtList = createAxtGap(nibFile,gp->chrom,tStart,tEnd ,gp->strand[0]);
else
axtList = createAxtGap(nibFile,gp->chrom,tEnd,tStart ,gp->strand[0]);
}
/* append unaligned coding region to list */
if (posStrand)
{
if ((axtList->tStart)-1 > tStart)
{
struct axt *axtGap = createAxtGap(nibFile,gp->chrom,tStart,axtList->tStart,gp->strand[0]);
slAddHead(&axtList, axtGap);
tPtr = axtList->tStart;
}
}
else
{
if (axtList->tEnd < tStart)
{
struct axt *axtGap = createAxtGap(nibFile,gp->chrom,axtList->tEnd, tStart+1,gp->strand[0]);
axtListReverse(&axtGap, database);
slAddHead(&axtList, axtGap);
tPtr = axtList->tEnd;
}
}
for (axt = axtList; axt != NULL; axt = axt->next)
{
char *q = axt->qSym;
char *t = axt->tSym;
int size = axt->symCount;
int sizeLeft = size;
int qPtr ;
char qStrand = (axt->qStrand == gp->strand[0] ? '+' : '-');
int qStart = axt->qStart;
int qEnd = axt->qEnd;
int qSize = 0;
if (!sameString(axt->qName, "gap"))
qSize = hChromSize(otherDb, axt->qName);
if (qStrand == '-')
{
qStart = qSize - axt->qEnd;
qEnd = qSize - axt->qStart;
}
/* fprintf(f, ">%s:%d-%d %s:%d-%d (%c) score %d coding %d-%d utr/coding %d-%d gene %c alignment %c\n",
* axt->tName, axt->tStart+1, axt->tEnd,
* axt->qName, qStart+1, qEnd, qStrand, axt->score, tStart+1, tEnd, gp->txStart+1, gp->txEnd, gp->strand[0], axt->qStrand); */
qPtr = qStart;
if (gp->exonFrames == NULL)
qCodonPos = tCodonPos; /* put translation back in sync */
if (!posStrand)
{
qPtr = qEnd;
/* skip to next exon if we are starting in the middle of a gene - should not happen */
while ((tPtr < nextEnd) && (nextEndIndex > 0))
{
nextEndIndex--;
prevEnd = nextEnd;
nextStart = (gp->exonEnds[nextEndIndex]);
nextEnd = (gp->exonStarts[nextEndIndex]);
if (nextStart > tStart)
tClass = INTRON;
}
}
else
{
/* skip to next exon if we are starting in the middle of a gene - should not happen */
while ((tPtr > nextEnd) && (nextEndIndex < gp->exonCount-2))
{
nextEndIndex++;
prevEnd = nextEnd;
nextStart = gp->exonStarts[nextEndIndex];
nextEnd = gp->exonEnds[nextEndIndex];
if (nextStart > tStart)
tClass = INTRON;
}
}
/* loop thru one base at a time */
while (sizeLeft > 0)
{
struct dyString *dyT = newDyString(1024);
struct dyString *dyQ = newDyString(1024);
struct dyString *dyQprot = newDyString(1024);
struct dyString *dyTprot = newDyString(1024);
struct dyString *exonTag = newDyString(1024);
oneSize = sizeLeft;
if (oneSize > lineSize)
oneSize = lineSize;
setClassStr(dyT,tClass, 0);
setClassStr(dyQ,qClass, 1);
/* break up into linesize chunks */
for (i=0; i= nextStart) && (tPtr >= tStart) && (tPtr < tEnd))
{
tCoding=TRUE;
dyStringPrintf(exonTag, "exon%d",nextEndIndex+1);
addTag(dyT,exonTag);
if (gp->exonFrames != NULL && gp->exonFrames[nextEndIndex] != -1)
tCodonPos = gp->exonFrames[nextEndIndex]+1;
if (qStopCodon == FALSE)
{
qCoding=TRUE;
qCodonPos = tCodonPos; /* put translation back in sync */
qFlip = tFlip;
}
}
else if ((tPtr >= nextStart) && (tPtr < tStart))
{ /* start of UTR 5'*/
tClass=UTR5; qClass=UTR5;
}
}
else{
if ((tClass==INTRON) && (tPtr <= nextStart) && (tPtr <= tStart) && (tPtr > tEnd))
{ /*look for start of exon on neg strand */
tCoding=TRUE;
dyStringPrintf(exonTag, "exon%d",nextEndIndex+1);
addTag(dyT,exonTag);
if (qStopCodon == FALSE)
{
qCoding=TRUE;
if (gp->exonFrames != NULL && gp->exonFrames[nextEndIndex] != -1)
tCodonPos = gp->exonFrames[nextEndIndex]+1;
qCodonPos = tCodonPos; /* put translation back in sync */
qFlip = tFlip;
}
}
else if ((tPtr <= nextStart-1) && (tPtr > tStart))
{ /* start of UTR 5'*/
tClass=UTR5; qClass=UTR5;
}
}
/* toggle between blue / purple color for exons */
if (tCoding && tFlip )
tClass=CODINGA;
if (tCoding && (tFlip == FALSE) )
tClass=CODINGB;
if (qCoding && qFlip && !qStopCodon)
qClass=CODINGA;
if (qCoding && (qFlip == FALSE) && !qStopCodon)
qClass=CODINGB;
if (posStrand)
{
/* look for end of exon */
if (tPtr == nextEnd)
{
tCoding=FALSE;
qCoding=FALSE;
tClass=INTRON;
qClass=INTRON;
nextEndIndex++;
nextStart = gp->exonStarts[nextEndIndex];
prevEnd = nextEnd;
nextEnd = gp->exonEnds[nextEndIndex];
if (gp->exonFrames != NULL && gp->exonFrames[nextEndIndex] != -1)
tCodonPos = gp->exonFrames[nextEndIndex]+1;
}
}
else
{
/* look for end of exon negative strand */
if (tPtr == nextEnd && tPtr != tEnd)
{
tCoding=FALSE;
qCoding=FALSE;
tClass=INTRON;
qClass=INTRON;
nextEndIndex--;
nextStart = (gp->exonEnds[nextEndIndex]);
prevEnd = nextEnd;
nextEnd = (gp->exonStarts[nextEndIndex]);
}
}
if (posStrand)
{
/* look for start codon and color it green*/
if ((tPtr >= (tStart)) && (tPtr <=(tStart+2)))
{
if (gp->exonFrames != NULL && gp->cdsStartStat == cdsComplete)
{
tClass=STARTCODON;
qClass=STARTCODON;
}
else if(tClass != CODINGB)
{
tClass=CODINGA;
qClass=CODINGA;
}
tCoding=TRUE;
qCoding=TRUE;
if (tPtr == tStart)
{
if (gp->exonFrames != NULL && gp->exonFrames[nextEndIndex] != -1)
tCodonPos = gp->exonFrames[nextEndIndex]+1;
else
tCodonPos=1;
qCodonPos=tCodonPos;
}
}
/* look for stop codon and color it red */
if ((tPtr >= tEnd) && (tPtr <= (tEnd+2)))
{
if (gp->exonFrames != NULL && gp->cdsEndStat == cdsComplete)
{
tClass=STOPCODON;
qClass=STOPCODON;
}
tCoding=FALSE;
qCoding=FALSE;
}
}
else
{
/* look for start codon and color it green negative strand case*/
if ((tPtr <= (tStart)) && (tPtr >=(tStart-2)))
{
if (gp->exonFrames != NULL && gp->cdsStartStat == cdsComplete)
{
tClass=STARTCODON;
qClass=STARTCODON;
}
else if (tClass!=CODINGB)
{
tClass=CODINGA;
qClass=CODINGA;
}
tCoding=TRUE;
qCoding=TRUE;
if (tPtr == tStart)
{
if (gp->exonFrames != NULL && gp->exonFrames[nextEndIndex] != -1)
tCodonPos = gp->exonFrames[nextEndIndex]+1;
else
tCodonPos=1;
}
qCodonPos=tCodonPos;
}
/* look for stop codon and color it red - negative strand*/
if ((tPtr <= tEnd+3) && (tPtr >= (tEnd+1)))
{
if (gp->exonFrames != NULL && gp->cdsEndStat == cdsComplete)
{
tClass=STOPCODON;
qClass=STOPCODON;
}
tCoding=FALSE;
qCoding=FALSE;
}
}
if (posStrand)
{
/* look for 3' utr and color it orange */
if (tPtr == (tEnd +3) )
{
tClass = UTR3;
qClass = UTR3;
}
}
else
{
/* look for 3' utr and color it orange negative strand case*/
if (tPtr == (tEnd) )
{
tClass = UTR3;
qClass = UTR3;
}
}
if (qCoding && qCodonPos == 3)
{
/* look for in frame stop codon and color it magenta */
qCodon[qCodonPos-1] = q[i];
qCodon[3] = 0;
qProt = lookupCodon(qCodon);
if (qProt == 'X') qProt = ' ';
if (qProt == 0)
{
qProt = '*'; /* stop codon is * */
qClass = INFRAMESTOP;
}
}
/* write html to change color for all above cases t strand */
if (tClass != prevTclass)
{
setClassStr(dyT,tClass,0);
prevTclass = tClass;
}
dyStringAppendC(dyT,t[i]);
/* write html to change color for all above cases q strand */
if (qClass != prevQclass)
{
setClassStr(dyQ,qClass,0);
prevQclass = qClass;
}
dyStringAppendC(dyQ,q[i]);
if (tCoding && tFlip && (tCodonPos == 3))
{
tFlip=FALSE;
}
else if (tCoding && (tFlip == FALSE) && (tCodonPos == 3))
{
tFlip=TRUE;
}
if (qCoding && qFlip && (qCodonPos == 3))
{
qFlip=FALSE;
}
else if (qCoding && (qFlip == FALSE) && (qCodonPos == 3))
{
qFlip=TRUE;
}
/* translate dna to protein and append html */
if (tCoding && tCodonPos == 3)
{
tCodon[tCodonPos-1] = t[i];
tCodon[3] = 0;
tProt = lookupCodon(tCodon);
if (tProt == 'X') tProt = ' ';
if (tProt == 0) tProt = '*'; /* stop codon is * */
dyStringAppendC(dyTprot,tProt);
}
else
{
dyStringAppendC(dyTprot,' ');
}
if (qCoding && qCodonPos == 3)
{
qCodon[qCodonPos-1] = q[i];
qCodon[3] = 0;
qProt = lookupCodon(qCodon);
if (qProt == 'X') qProt = ' ';
if (qProt == 0)
{
qProt = '*'; /* stop codon is * */
/* qClass = INFRAMESTOP; */
qStopCodon = FALSE;
qCoding = TRUE;
}
if (tProt == qProt) qProt = '|'; /* if the AA matches print | */
dyStringAppendC(dyQprot,qProt);
}
else
{
dyStringAppendC(dyQprot,' ');
}
/* move to next base and update reading frame */
if (t[i] != '-')
{
if (posStrand)
{
tPtr++;
qPtr++;
}
else
{
tPtr--;
qPtr--;
}
if (tCoding)
{
tCodon[tCodonPos-1] = t[i];
tCodonPos++;
}
if (tCodonPos>3) tCodonPos=1;
}
/*else
{
tClass=INTRON;
}*/
/* update reading frame on other species */
if (q[i] != '-')
{
if (qCoding)
{
qCodon[qCodonPos-1] = q[i];
qCodonPos++;
}
if (qCodonPos>3) qCodonPos=1;
}
/*else
{
qClass=INTRON;
}*/
}
/* write labels in black */
resetClassStr(dyT,0);
setClassStr(dyT,LABEL,0);
if (posStrand)
{
dyStringPrintf(dyT, " %d ",tPtr);
if (tCoding)
dyStringPrintf(dyT, "exon %d",(nextEndIndex == 0) ? 1 : nextEndIndex+1);
}
else
{
dyStringPrintf(dyT, " %d ",tPtr+1);
if (tCoding)
dyStringPrintf(dyT, "exon %d", (nextEndIndex == 0) ? 1 : nextEndIndex+1);
}
#if 0 /* debug version */
if (posStrand)
dyStringPrintf(dyT, " %d thisExon=%d-%d xon %d",tPtr, gp->exonStarts[(nextEndIndex == 0) ? 0 : nextEndIndex - 1]+1, gp->exonEnds[(nextEndIndex == 0) ? 0 : nextEndIndex - 1],(nextEndIndex == 0) ? 1 : nextEndIndex);
else
dyStringPrintf(dyT, " %d thisExon=%d-%d xon %d",tPtr, gp->exonStarts[(nextEndIndex == gp->exonCount) ? gp->exonCount : nextEndIndex ]+1, gp->exonEnds[(nextEndIndex == gp->exonCount) ? gp->exonCount : nextEndIndex ],(nextEndIndex == 0) ? 1 : nextEndIndex);
#endif
dyStringAppendC(dyT,'\n');
resetClassStr(dyT,0);
resetClassStr(dyQ,1);
setClassStr(dyQ,LABEL,1);
if (posStrand)
dyStringPrintf(dyQ, " %d ",qPtr);
else
dyStringPrintf(dyQ, " %d ",qPtr);
dyStringAppendC(dyQ,'\n');
resetClassStr(dyQ,1);
dyStringAppendC(dyQprot,'\n');
dyStringAppendC(dyTprot,'\n');
#if 0 /* debug version */
if (posStrand)
printf(" %d nextExon=%d-%d xon %d t %d prevEnd %d diffs %d %d
",qPtr, nextStart+1,nextEnd,nextEndIndex+1, tPtr,prevEnd, tPtr-nextStart-70, tPtr-(prevEnd+70));
else
printf(" %d nextExon=%d-%d xon %d t %d prevEnd %d diffs %d %d
",qPtr, nextStart+1,nextEnd,nextEndIndex, tPtr, prevEnd, tPtr-nextStart-70, tPtr-(prevEnd+70));
#endif
/* write out alignment, unless we are deep inside an intron */
if (tClass != INTRON || (tClass == INTRON && tPtr < nextStart-LINESIZE && tPtr< (prevEnd + posStrand ? LINESIZE : -LINESIZE)))
{
intronTruncated = 0;
fputs(dyTprot->string,f);
fputs(dyT->string,f);
for (i=0; istring,f);
fputs(dyQprot->string,f);
fputc('\n', f);
}
else
{
if (!(intronTruncated == TRUE))
{
printf("...intron truncated...
");
intronTruncated = TRUE;
}
}
/* look for end of line */
if (oneSize > lineSize)
oneSize = lineSize;
sizeLeft -= oneSize;
q += oneSize;
t += oneSize;
freeDyString(&dyT);
freeDyString(&dyQ);
freeDyString(&dyQprot);
freeDyString(&dyTprot);
}
}
}
struct axt *getAxtListForGene(struct genePred *gp, char *nib, char *fromDb, char *toDb,
struct lineFile *lf)
/* get all axts for a gene */
{
struct axt *axt, *axtGap;
struct axt *axtList = NULL;
int prevEnd = gp->txStart;
// int prevStart = gp->txEnd; unused variable
int tmp;
while ((axt = axtRead(lf)) != NULL)
{
if (sameString(gp->chrom, axt->tName)
&& ( ( (axt->tStart <= gp->cdsStart && axt->tEnd >= gp->cdsStart)
|| (axt->tStart <= gp->cdsEnd && axt->tEnd >= gp->cdsEnd ) )
|| ( axt->tStart < gp->cdsEnd && axt->tEnd > gp->cdsStart ) ) )
{
if (gp->strand[0] == '-')
{
reverseComplement(axt->qSym, axt->symCount);
reverseComplement(axt->tSym, axt->symCount);
tmp = hChromSize(fromDb, axt->qName) - axt->qStart;
axt->qStart = hChromSize(fromDb, axt->qName) - axt->qEnd;
axt->qEnd = tmp;
if (prevEnd < (axt->tStart)-1)
{
axtGap = createAxtGap(nib,gp->chrom,prevEnd,(axt->tStart),gp->strand[0]);
reverseComplement(axtGap->qSym, axtGap->symCount);
reverseComplement(axtGap->tSym, axtGap->symCount);
slAddHead(&axtList, axtGap);
}
}
else if (prevEnd < (axt->tStart))
{
axtGap = createAxtGap(nib,gp->chrom,prevEnd,(axt->tStart),gp->strand[0]);
slAddHead(&axtList, axtGap);
}
slAddHead(&axtList, axt);
prevEnd = axt->tEnd;
// prevStart = axt->tStart; unused variable
}
if (sameString(gp->chrom, axt->tName) && (axt->tStart > gp->txEnd))
{
if ((prevEnd < axt->tStart) && prevEnd < min(gp->txEnd, axt->tStart))
{
axtGap = createAxtGap(nib,gp->chrom,prevEnd,min(axt->tStart,gp->txEnd),gp->strand[0]);
if (gp->strand[0] == '-')
{
reverseComplement(axtGap->qSym, axtGap->symCount);
reverseComplement(axtGap->tSym, axtGap->symCount);
}
slAddHead(&axtList, axtGap);
}
else
if (axtList == NULL)
{
axtGap = createAxtGap(nib,gp->chrom,prevEnd,gp->txEnd,gp->strand[0]);
if (gp->strand[0] == '-')
{
reverseComplement(axtGap->qSym, axtGap->symCount);
reverseComplement(axtGap->tSym, axtGap->symCount);
}
slAddHead(&axtList, axtGap);
}
break;
}
}
if (gp->strand[0] == '+')
slReverse(&axtList);
return axtList ;
}
struct axt *getAxtListForRange(struct genePred *gp, char *nib, char *fromDb, char *toDb,
char *alignment, char *qChrom, int qStart, int qEnd)
/* get all axts for a chain */
{
struct lineFile *lf ;
struct axt *axt, *axtGap;
struct axt *axtList = NULL;
int prevEnd = gp->txStart;
// int prevStart = gp->txEnd; unused variable
int tmp;
lf = lineFileOpen(getAxtFileName(gp->chrom, toDb, alignment, fromDb), TRUE);
printf("file %s\n",lf->fileName);
while ((axt = axtRead(lf)) != NULL)
{
/* if (sameString(gp->chrom , axt->tName))
* printf("axt %s qstart %d axt tStart %d\n",axt->qName, axt->qStart,axt->tStart); */
if ( sameString(gp->chrom, axt->tName)
&& sameString( qChrom, axt->qName)
&& positiveRangeIntersection( qStart, qEnd, axt->qStart, axt->qEnd)
&& positiveRangeIntersection(gp->txStart, gp->txEnd, axt->tStart, axt->tEnd) )
{
if (gp->strand[0] == '-')
{
reverseComplement(axt->qSym, axt->symCount);
reverseComplement(axt->tSym, axt->symCount);
tmp = hChromSize(fromDb, axt->qName) - axt->qStart;
axt->qStart = hChromSize(fromDb, axt->qName) - axt->qEnd;
axt->qEnd = tmp;
if (prevEnd < (axt->tStart)-1)
{
axtGap = createAxtGap(nib,gp->chrom,prevEnd,(axt->tStart)-1,gp->strand[0]);
reverseComplement(axtGap->qSym, axtGap->symCount);
reverseComplement(axtGap->tSym, axtGap->symCount);
slAddHead(&axtList, axtGap);
}
}
else if (prevEnd < (axt->tStart)-1)
{
axtGap = createAxtGap(nib,gp->chrom,prevEnd,(axt->tStart)-1,gp->strand[0]);
slAddHead(&axtList, axtGap);
}
slAddHead(&axtList, axt);
prevEnd = axt->tEnd;
// prevStart = axt->tStart; unused variable
}
if (sameString(gp->chrom, axt->tName) && (axt->tStart > gp->txEnd+20000))
{
if (axt->tStart > prevEnd)
{
axtGap = createAxtGap(nib,gp->chrom,prevEnd+1,(axt->tStart)-1,gp->strand[0]);
if (gp->strand[0] == '-')
{
reverseComplement(axtGap->qSym, axtGap->symCount);
reverseComplement(axtGap->tSym, axtGap->symCount);
}
slAddHead(&axtList, axtGap);
}
break;
}
}
if (gp->strand[0] == '+')
slReverse(&axtList);
return axtList ;
}
void printCdsStatus(enum cdsStatus cdsStatus)
/* print a description of a genePred cds status */
{
switch (cdsStatus)
{
case cdsNone: /* "none" - No CDS (non-coding) */
printf("none (non-coding)
\n");
break;
case cdsUnknown: /* "unk" - CDS is unknown (coding, but not known) */
printf("unknown (coding, but not known)
\n");
break;
case cdsIncomplete: /* "incmpl" - CDS is not complete at this end */
printf("not complete
\n");
break;
case cdsComplete: /* "cmpl" - CDS is complete at this end */
printf("complete
\n");
break;
}
}
void showGenePos(char *name, struct trackDb *tdb)
/* Show gene prediction position and other info. */
{
char *rootTable = tdb->table;
char query[512];
struct sqlConnection *conn = hAllocConn(database);
struct genePred *gpList = NULL, *gp = NULL;
char table[HDB_MAX_TABLE_STRING];
struct sqlResult *sr = NULL;
char **row = NULL;
char *classTable = trackDbSetting(tdb, GENEPRED_CLASS_TBL);
if (!hFindSplitTable(database, seqName, rootTable, table, sizeof table, NULL))
errAbort("showGenePos track %s not found", rootTable);
sqlSafefFrag(query, sizeof(query), "name = \"%s\"", name);
gpList = genePredReaderLoadQuery(conn, table, query);
for (gp = gpList; gp != NULL; gp = gp->next)
{
printPos(gp->chrom, gp->txStart, gp->txEnd, gp->strand, FALSE, NULL);
if(sameString(tdb->type,"genePred")
&& startsWith("ENCODE Gencode",tdb->longLabel)
&& startsWith("ENST",name))
{
char *ensemblIdUrl = trackDbSetting(tdb, "ensemblIdUrl");
printf("Ensembl Transcript Id: ");
if (ensemblIdUrl != NULL)
printf("%s
", ensemblIdUrl,name,name);
else
printf("%s
",name);
}
if (gp->name2 != NULL && strlen(trimSpaces(gp->name2))> 0)
{
/* in Ensembl gene info downloaded from ftp site, sometimes the
name2 field is populated with "noXref" because there is
no alternate name. Replace this with "none" */
printf("Gene Symbol:");
if ((strlen(gp->name2) < 1) || (sameString(gp->name2, "noXref")))
printf(" none
\n");
else
printf(" %s
\n",gp->name2);
}
char *ensemblSource = NULL;
if (sameString("ensGene", table))
{
if (hTableExists(database, "ensemblSource"))
{
sqlSafef(query, sizeof(query),
"select source from ensemblSource where name='%s'", name);
ensemblSource = sqlQuickString(conn, query);
}
}
if ((gp->exonFrames != NULL) && (!genbankIsRefSeqNonCodingMRnaAcc(gp->name)))
{
if (ensemblSource && differentString("protein_coding",ensemblSource))
{
printf("CDS Start: none (non-coding)
\n");
printf("CDS End: none (non-coding)
\n");
}
else
{
printf("CDS Start: ");
printCdsStatus((gp->strand[0] == '+') ? gp->cdsStartStat : gp->cdsEndStat);
printf("CDS End: ");
printCdsStatus((gp->strand[0] == '+') ? gp->cdsEndStat : gp->cdsStartStat);
}
}
/* if a gene class table exists, get gene class and print */
if (classTable != NULL)
{
if (hTableExists(database, classTable))
{
sqlSafef(query, sizeof(query),
"select class from %s where name = \"%s\"", classTable, name);
sr = sqlGetResult(conn, query);
/* print class */
if ((row = sqlNextRow(sr)) != NULL)
printf("Prediction Class: %s
\n", row[0]);
sqlFreeResult(&sr);
if (sqlFieldIndex(conn, classTable, "level") > 0 )
{
sqlSafef(query, sizeof(query),
"select level from %s where name = \"%s\"", classTable, name);
sr = sqlGetResult(conn, query);
if ((row = sqlNextRow(sr)) != NULL)
printf("Level:  %s
\n", row[0]);
sqlFreeResult(&sr);
}
if (sqlFieldIndex(conn, classTable, "transcriptType") > 0 )
{
sqlSafef(query, sizeof(query),
"select transcriptType from %s where name = \"%s\"", classTable, name);
sr = sqlGetResult(conn, query);
if ((row = sqlNextRow(sr)) != NULL)
printf("Transcript type:  %s
\n", row[0]);
sqlFreeResult(&sr);
}
if (sqlFieldIndex(conn, classTable, "geneDesc") > 0 )
{
sqlSafef(query, sizeof(query),
"select geneDesc from %s where name = \"%s\"", classTable, name);
sr = sqlGetResult(conn, query);
if ((row = sqlNextRow(sr)) != NULL)
if (differentString("NULL",row[0]))
printf("Gene Description : %s
\n", row[0]);
sqlFreeResult(&sr);
}
if (sqlFieldIndex(conn, classTable, "type") > 0 )
{
sqlSafef(query, sizeof(query),
"select type from %s where name = \"%s\"", classTable, name);
sr = sqlGetResult(conn, query);
if ((row = sqlNextRow(sr)) != NULL)
if (differentString("NULL",row[0]))
printf("Gene Type : %s
\n", row[0]);
}
}
}
if (gp->next != NULL)
printf("
");
}
genePredFreeList(&gpList);
sqlFreeResult(&sr);
hFreeConn(&conn);
}
void showGenePosMouse(char *name, struct trackDb *tdb,
struct sqlConnection *connMm)
/* Show gene prediction position and other info. */
{
char query[512];
char *rootTable = tdb->table;
struct sqlResult *sr;
char **row;
struct genePred *gp = NULL;
boolean hasBin;
int posCount = 0;
char table[HDB_MAX_TABLE_STRING];
if (!hFindSplitTable(database, seqName, rootTable, table, sizeof table, &hasBin))
errAbort("showGenePosMouse track %s not found", rootTable);
sqlSafef(query, sizeof query, "select * from %s where name = '%s'", table, name);
sr = sqlGetResult(connMm, query);
while ((row = sqlNextRow(sr)) != NULL)
{
if (posCount > 0)
printf("
\n");
++posCount;
gp = genePredLoad(row + hasBin);
printPos(gp->chrom, gp->txStart, gp->txEnd, gp->strand, FALSE, NULL);
genePredFree(&gp);
}
sqlFreeResult(&sr);
}
void linkToPal(char *track, char *chrom, int start, int end, char *geneName)
/* Make anchor tag to open pal window */
{
printf("",
geneName, hgPalName(), track, geneName, chrom, start, end);
printf("CDS FASTA alignment from multiple alignment");
}
void addPalLink(struct sqlConnection *conn, char *track,
char *chrom, int start, int end, char *geneName)
{
struct slName *list = hTrackTablesOfType(conn, "wigMaf%%");
if (list != NULL)
{
puts("\n");
linkToPal( track, chrom, start, end, geneName);
puts("\n");
}
}
void geneShowPosAndLinksPal(char *geneName, char *pepName, struct trackDb *tdb,
char *pepTable, char *pepClick,
char *mrnaClick, char *genomicClick, char *mrnaDescription,
struct palInfo *palInfo)
/* Show parts of gene common to everything. If pepTable is not null,
* it's the old table name, but will check gbSeq first. */
{
char *geneTable = tdb->table;
boolean foundPep = FALSE;
showGenePos(geneName, tdb);
if (startsWith("ENCODE Gencode",tdb->longLabel))
{
char *yaleTable = trackDbSetting(tdb, "yalePseudoAssoc");
if ((yaleTable != NULL) && (hTableExists(database, yaleTable)))
{
struct sqlConnection *conn = hAllocConn(database);
char query[512];
sqlSafef(query, sizeof(query),
"select * from %s where transcript = '%s'", yaleTable, geneName);
char buffer[512];
struct sqlResult *sr = sqlGetResult(conn, query);
char *yaleUrl = trackDbSetting(tdb, "yaleUrl");
char **row;
while ((row = sqlNextRow(sr)) != NULL)
{
struct yaleGencodeAssoc *ya = yaleGencodeAssocLoad(row);
safef(buffer, sizeof buffer, "%s/%s",yaleUrl,ya->yaleId);
printf("Yale pseudogene: %s
\n", buffer, ya->yaleId);
}
sqlFreeResult(&sr);
hFreeConn(&conn);
}
}
printf("Links to sequence:
\n");
printf("\n");
if ((pepTable != NULL) && hGenBankHaveSeq(database, pepName, pepTable))
{
puts("- \n");
hgcAnchorSomewhere(pepClick, pepName, pepTable, seqName);
printf("Predicted Protein
\n");
puts("\n");
foundPep = TRUE;
}
if (!foundPep)
{
char *autoTranslate = trackDbSetting(tdb, "autoTranslate");
if (autoTranslate == NULL || differentString(autoTranslate, "0"))
{
puts("\n");
/* put out correct message to describe translated mRNA */
if ( sameString(geneTable, "ensGene")
|| sameString(geneTable, "ws245Genes")
|| sameString(geneTable, "vegaGene")
|| sameString(geneTable, "vegaPseudoGene")
|| genbankIsRefSeqNonCodingMRnaAcc(geneName)
|| sameString(geneTable, "lincRNAsTranscripts") )
{
printf("Non-protein coding gene or gene fragment, no protein prediction available.");
}
else
{
hgcAnchorSomewhere("htcTranslatedPredMRna", geneName, "translate", seqName);
printf("Translated Protein from ");
if (sameString(geneTable, "refGene") )
{
printf("genomic DNA\n");
}
else
{
printf("predicted mRNA \n");
}
foundPep = TRUE;
}
puts("\n");
}
}
puts("\n");
hgcAnchorSomewhere(mrnaClick, geneName, geneTable, seqName);
/* hack to put out a correct message describing the mRNA */
if (sameString(mrnaClick, "htcGeneMrna"))
printf("%s from genomic sequences\n", mrnaDescription);
else
printf("%s (may be different from the genomic sequence)\n",
mrnaDescription);
puts("\n");
puts("\n");
hgcAnchorSomewhere(genomicClick, geneName, geneTable, seqName);
printf("Genomic Sequence from assembly\n");
puts("\n");
if (palInfo)
{
struct sqlConnection *conn = hAllocConn(database);
addPalLink(conn, tdb->track, palInfo->chrom, palInfo->left,
palInfo->right, palInfo->rnaName);
hFreeConn(&conn);
}
printf("\n");
}
void geneShowPosAndLinks(char *geneName, char *pepName, struct trackDb *tdb,
char *pepTable, char *pepClick,
char *mrnaClick, char *genomicClick, char *mrnaDescription)
{
geneShowPosAndLinksPal(geneName, pepName, tdb,
pepTable, pepClick,
mrnaClick, genomicClick, mrnaDescription, NULL);
}
void geneShowPosAndLinksDNARefseq(char *geneName, char *pepName, struct trackDb *tdb,
char *pepTable, char *pepClick,
char *mrnaClick, char *genomicClick, char *mrnaDescription)
/* Show parts of a DNA based RefSeq gene */
{
char *geneTable = tdb->table;
showGenePos(geneName, tdb);
printf("Links to sequence:
\n");
printf("\n");
puts("- \n");
hgcAnchorSomewhere(genomicClick, geneName, geneTable, seqName);
printf("Genomic Sequence from assembly\n");
puts("
\n");
printf("
\n");
}
void geneShowPosAndLinksMouse(char *geneName, char *pepName,
struct trackDb *tdb, char *pepTable,
struct sqlConnection *connMm, char *pepClick,
char *mrnaClick, char *genomicClick, char *mrnaDescription)
/* Show parts of gene common to everything */
{
char *geneTrack = tdb->track;
showGenePosMouse(geneName, tdb, connMm);
printf("Links to sequence:
\n");
printf("\n");
if (pepTable != NULL && hTableExists(database, pepTable))
{
hgcAnchorSomewhereDb(pepClick, pepName, pepTable, seqName, mousedb);
printf("- Translated Protein \n");
}
hgcAnchorSomewhereDb(mrnaClick, geneName, geneTrack, seqName, mousedb);
printf("
- %s\n", mrnaDescription);
hgcAnchorSomewhereDb(genomicClick, geneName, geneTrack, seqName, mousedb);
printf("
- Genomic Sequence DNA sequence from assembly\n");
printf("
\n");
}
void geneShowCommon(char *geneName, struct trackDb *tdb, char *pepTable)
/* Show parts of gene common to everything */
{
geneShowPosAndLinks(geneName, geneName, tdb, pepTable, "htcTranslatedProtein",
"htcGeneMrna", "htcGeneInGenome", "Predicted mRNA");
char *txInfo = trackDbSetting(tdb, "txInfo");
if (txInfo != NULL)
showTxInfo(geneName, tdb, txInfo);
char *cdsEvidence = trackDbSetting(tdb, "cdsEvidence");
if (cdsEvidence != NULL)
showCdsEvidence(geneName, tdb, cdsEvidence);
}
void geneShowMouse(char *geneName, struct trackDb *tdb, char *pepTable,
struct sqlConnection *connMm)
/* Show parts of gene common to everything */
{
geneShowPosAndLinksMouse(geneName, geneName, tdb, pepTable, connMm,
"htcTranslatedProtein", "htcGeneMrna", "htcGeneInGenome",
"Predicted mRNA");
}
void genericGenePredClick(struct sqlConnection *conn, struct trackDb *tdb,
char *item, int start, char *pepTable, char *mrnaTable)
/* Handle click in generic genePred track. */
{
char *oldToNew = trackDbSetting(tdb, "oldToNew");
if (oldToNew != NULL && sqlTableExists(conn, oldToNew))
{
char query[512];
sqlSafef(query, sizeof(query),
"select * from %s where oldId = '%s' and oldChrom='%s' and oldStart=%d",
oldToNew, item, seqName, start);
struct sqlResult *sr = sqlGetResult(conn, query);
char **row;
while ((row = sqlNextRow(sr)) != NULL)
{
struct kg1ToKg2 *x = kg1ToKg2Load(row);
printf("Old ID: %s
\n", x->oldId);
printf("New ID: %s
\n", naForEmpty(x->newId));
printf("Old/New Mapping: %s
\n", x->status);
if (x->note[0] != 0)
printf("Notes: %s
\n", x->note);
printf("
\n");
}
sqlFreeResult(&sr);
}
geneShowCommon(item, tdb, pepTable);
printItemDetailsHtml(tdb, item);
}
void pslDumpHtml(struct psl *pslList)
/* print out psl header and data */
{
struct psl* psl;
printf("\n");
printf("#match\tmisMatches\trepMatches\tnCount\tqNumInsert\tqBaseInsert\ttNumInsert\tBaseInsert\tstrand\tqName\tqSize\tqStart\tqEnd\ttName\ttSize\ttStart\ttEnd\tblockCount\tblockSizes\tqStarts\ttStarts\n");
for (psl = pslList; psl != NULL; psl = psl->next)
{
pslTabOut(psl, stdout);
}
printf("
\n");
}
void genericBigPslClick(struct sqlConnection *conn, struct trackDb *tdb,
char *item, int start, int end)
/* Handle click in big psl track. */
{
struct psl* pslList = NULL;
char *fileName = bbiNameFromSettingOrTable(tdb, conn, tdb->table);
struct bbiFile *bbi = bigBedFileOpen(fileName);
struct lm *lm = lmInit(0);
int ivStart = start, ivEnd = end;
if (start == end)
{
// item is an insertion; expand the search range from 0 bases to 2 so we catch it:
ivStart = max(0, start-1);
ivEnd++;
}
boolean showEvery = sameString(item, "PrintAllSequences");
boolean showAll = trackDbSettingOn(tdb, "showAll");
unsigned seqTypeField = bbExtraFieldIndex(bbi, "seqType");
struct bigBedInterval *bb, *bbList = NULL;
// If showAll is on, show all alignments with this qName, not just the
// selected one.
if (showEvery)
{
struct bbiChromInfo *chrom, *chromList = bbiChromList(bbi);
for (chrom = chromList; chrom != NULL; chrom = chrom->next)
{
char *chromName = chrom->name;
int start = 0, end = chrom->size;
int itemsLeft = 0; // Zero actually means no limit....
struct bigBedInterval *intervalList = bigBedIntervalQuery(bbi, chromName,
start, end, itemsLeft, lm);
slCat(&bbList, intervalList);
}
}
else if (showAll)
{
int fieldIx;
struct bptFile *bpt = bigBedOpenExtraIndex(bbi, "name", &fieldIx);
bbList = bigBedNameQuery(bbi, bpt, fieldIx, item, lm);
}
else
bbList = bigBedIntervalQuery(bbi, seqName, ivStart, ivEnd, 0, lm);
/* print out extra fields */
for (bb = bbList; bb != NULL; bb = bb->next)
{
char *restFields[256];
int restCount = chopTabs(cloneString(bb->rest), restFields);
if (sameString(restFields[0], item))
{
int bedSize = 25;
int restBedFields = bedSize - 3;
if (restCount > restBedFields)
{
char **extraFields = (restFields + restBedFields);
int extraFieldCount = restCount - restBedFields;
int printCount = extraFieldsPrint(tdb,NULL,extraFields, extraFieldCount);
printCount += 0;
}
}
}
char *bedRow[32];
char startBuf[16], endBuf[16];
int lastChromId = -1;
char chromName[bbi->chromBpt->keySize+1];
for (bb = bbList; bb != NULL; bb = bb->next)
{
bbiCachedChromLookup(bbi, bb->chromId, lastChromId, chromName, sizeof(chromName));
lastChromId=bb->chromId;
bigBedIntervalToRow(bb, chromName, startBuf, endBuf, bedRow, 4);
if (showEvery || sameString(bedRow[3], item))
{
struct psl *psl= pslFromBigPsl(chromName, bb, seqTypeField, NULL, NULL);
slAddHead(&pslList, psl);
}
}
char *sort = cartUsualString(cart, "sort", pslSortList[0]);
pslSortListByVar(&pslList, sort);
if (showEvery)
printf("Genomic Alignments
");
else
printf("%s/Genomic Alignments
", item);
if (showEvery || pslIsProtein(pslList))
printAlignmentsSimple(pslList, start, "htcBigPslAli", tdb->table, item);
else
printAlignmentsExtra(pslList, start, "htcBigPslAli", "htcBigPslAliInWindow",
tdb->table, item);
pslFreeList(&pslList);
printItemDetailsHtml(tdb, item);
}
void genericPslClick(struct sqlConnection *conn, struct trackDb *tdb,
char *item, int start, char *subType)
/* Handle click in generic psl track. */
{
struct psl* pslList = getAlignments(conn, tdb->table, item);
/* check if there is an alignment available for this sequence. This checks
* both genbank sequences and other sequences in the seq table. If so,
* set it up so they can click through to the alignment. */
if (hGenBankHaveSeq(database, item, NULL))
{
printf("%s/Genomic Alignments
", item);
if (sameString("protein", subType))
printAlignments(pslList, start, "htcProteinAli", tdb->table, item);
else
printAlignments(pslList, start, "htcCdnaAli", tdb->table, item);
}
else
{
/* just dump the psls */
pslDumpHtml(pslList);
}
pslFreeList(&pslList);
printItemDetailsHtml(tdb, item);
}
static char *getParentTableName(struct trackDb *tdb)
/* Get the track table or composite track parent table if applicable. */
{
tdb = trackDbTopLevelSelfOrParent(tdb);
return tdb->table;
}
static char *getParentTrackName(struct trackDb *tdb)
/* Get the track name or composite track parent name if applicable. */
{
tdb = trackDbTopLevelSelfOrParent(tdb);
return tdb->track;
}
void printTBSchemaLink(struct trackDb *tdb)
/* Make link to TB schema -- unless this is an on-the-fly (tableless) track. */
{
if (hTableOrSplitExists(database, tdb->table))
{
char *trackTable = getParentTableName(tdb);
printf(""
"View table schema
\n",
database, tdb->grp, trackTable, tdb->table,
seqName, winStart+1, winEnd);
}
}
void printTrackUiLink(struct trackDb *tdb)
/* Make link to hgTrackUi. */
{
char *trackName = getParentTrackName(tdb);
struct trackDb *parentTdb = tdb;
if (!sameString(trackName, tdb->track))
parentTdb = hTrackDbForTrack(database, trackName);
printf(""
"Go to %s track controls
\n",
hTrackUiForTrack(tdb->track), trackName, cartSidUrlString(cart), parentTdb->shortLabel);
}
void printDataRestrictionDate(struct trackDb *tdb)
/* If this annotation has a dateUnrestricted trackDb setting, print it */
{
char *restrictionDate = encodeRestrictionDateDisplay(database,tdb);
if (restrictionDate != NULL)
{
printf("Restricted until: %s
\n",
restrictionDate);
freeMem(restrictionDate);
}
}
static void printOrigAssembly(struct trackDb *tdb)
/* If this annotation has been lifted, print the original
* freeze, as indicated by the "origAssembly" trackDb setting */
{
trackDbPrintOrigAssembly(tdb, database);
}
static char *getHtmlFromSelfOrParent(struct trackDb *tdb)
/* Get html from self or from parent if not in self. */
{
for (;tdb != NULL; tdb = tdb->parent)
{
if (tdb->html != NULL && tdb->html[0] != 0)
return tdb->html;
}
return NULL;
}
+void printHtmlAddRelated(struct trackDb *tdb, char *html)
+/* print the track description html and try to inject the "related track" section */
+{
+struct sqlConnection *conn = hAllocConn(database);
+if (!sqlTableExists(conn, "relatedTrack"))
+ {
+ puts(html);
+ hFreeConn(&conn);
+ return;
+ }
+
+char query[256];
+sqlSafef(query, sizeof(query),
+ "select track1, track2, why from relatedTrack where track1='%s' or track2='%s'", tdb->track, tdb->track);
+
+char **row;
+struct sqlResult *sr;
+sr = sqlGetResult(conn, query);
+row = sqlNextRow(sr);
+if (row == NULL)
+ {
+ puts(html);
+ hFreeConn(&conn);
+ sqlFreeResult(&sr);
+ return;
+ }
+
+char *lines[10000];
+int lineCount = chopByChar(html, '\n', lines, ArraySize(lines));
+
+char* refLine1 = "References
";
+char* refLine2 = "References
";
+
+int lineIdx;
+for (lineIdx = 0; lineIdx < lineCount; lineIdx++)
+ {
+ char *line = lines[lineIdx];
+ if ( !sameWord(line, "") && !sameWord(line, refLine1) && !sameWord(line, refLine2))
+ {
+ puts(line);
+ continue;
+ }
+
+ puts("Related tracks
\n");
+ puts("\n");
+ do
+ {
+ char *track1 = row[0];
+ char *track2 = row[1];
+ char *why = row[2];
+
+ char* otherTrack;
+ if (sameWord(track1, tdb->track))
+ otherTrack = track2;
+ else
+ otherTrack = track1;
+
+ struct trackDb *otherTdb = hashFindVal(trackHash, otherTrack);
+ puts("- ");
+ puts(otherTdb->shortLabel);
+ puts(": ");
+ puts(why);
+ } while ((row = sqlNextRow(sr)) != NULL);
+ puts("
\n");
+
+ if (sameWord(line, refLine1) || sameWord(line, refLine2))
+ puts(line);
+ }
+
+hFreeConn(&conn);
+sqlFreeResult(&sr);
+}
+
void printTrackHtml(struct trackDb *tdb)
/* If there's some html associated with track print it out. Also print
* last update time for data table and make a link
* to the TB table schema page for this table. */
{
if (!isCustomTrack(tdb->track))
{
extraUiLinks(database, tdb);
printTrackUiLink(tdb);
printOrigAssembly(tdb);
printDataVersion(database, tdb);
printUpdateTime(database, tdb, NULL);
printDataRestrictionDate(tdb);
}
char *html = getHtmlFromSelfOrParent(tdb);
if (html != NULL && html[0] != 0)
{
htmlHorizontalLine();
// Add pennantIcon
printPennantIconNote(tdb);
// Wrap description html in div with limited width, so when the page is very wide
// due to long details, the user doesn't have to scroll right to read the description.
puts("");
- puts(html);
+ printHtmlAddRelated(tdb, html);
puts("
");
}
hPrintf("
\n");
}
void qChainRangePlusStrand(struct chain *chain, int *retQs, int *retQe)
/* Return range of bases covered by chain on q side on the plus
* strand. */
{
if (chain == NULL)
errAbort("Can't find range in null query chain.");
if (chain->qStrand == '-')
{
*retQs = chain->qSize - chain->qEnd+1;
*retQe = chain->qSize - chain->qStart;
}
else
{
*retQs = chain->qStart+1;
*retQe = chain->qEnd;
}
}
struct chain *chainDbLoad(struct sqlConnection *conn, char *db, char *track,
char *chrom, int id)
/* Load chain. */
{
char table[HDB_MAX_TABLE_STRING];
char query[256];
struct sqlResult *sr;
char **row;
boolean hasBin;
struct chain *chain;
if (!hFindSplitTable(db, seqName, track, table, sizeof table, &hasBin))
errAbort("No %s track in database %s for %s", track, db, seqName);
sqlSafef(query, sizeof(query),
"select * from %s where id = %d", table, id);
sr = sqlGetResult(conn, query);
row = sqlNextRow(sr);
if (row == NULL)
errAbort("Can't find %d in %s", id, table);
chain = chainHeadLoad(row + hasBin);
sqlFreeResult(&sr);
chainDbAddBlocks(chain, track, conn);
return chain;
}
void linkToOtherBrowserExtra(char *otherDb, char *chrom, int start, int end, char *extra)
/* Make anchor tag to open another browser window. */
{
printf("",
hgTracksName(), otherDb, extra, chrom, start+1, end);
}
void linkToOtherBrowserSearch(char *otherDb, char *tag)
/* Make anchor tag to open another browser window. */
{
printf("",
hgTracksName(), otherDb, tag);
}
void linkToOtherBrowser(char *otherDb, char *chrom, int start, int end)
/* Make anchor tag to open another browser window. */
{
printf("",
hgTracksName(), otherDb, chrom, start+1, end);
}
void linkToOtherBrowserTitle(char *otherDb, char *chrom, int start, int end, char *title)
/* Make anchor tag to open another browser window. */
{
printf("",
title, hgTracksName(), otherDb, chrom, start+1, end);
}
void chainToOtherBrowser(struct chain *chain, char *otherDb, char *otherOrg)
/* Put up link that lets us use chain to browser on
* corresponding window of other species. */
{
struct chain *subChain = NULL, *toFree = NULL;
int qs,qe;
chainSubsetOnT(chain, winStart, winEnd, &subChain, &toFree);
if (subChain != NULL && otherOrg != NULL)
{
qChainRangePlusStrand(subChain, &qs, &qe);
linkToOtherBrowser(otherDb, subChain->qName, qs-1, qe);
printf("Open %s browser at position corresponding to the part of chain that is in this window.
\n", otherOrg);
}
chainFree(&toFree);
}
void genericChainClick(struct sqlConnection *conn, struct trackDb *tdb,
char *item, int start, char *otherDb)
/* Handle click in chain track, at least the basics. */
{
char *thisOrg = hOrganism(database);
char *otherOrg = NULL;
struct chain *chain = NULL, *subChain = NULL, *toFree = NULL;
int chainWinSize;
double subSetScore = 0.0;
int qs, qe;
boolean nullSubset = FALSE;
if (! sameWord(otherDb, "seq"))
{
otherOrg = hOrganism(otherDb);
}
if (otherOrg == NULL)
{
/* use first word of chain label (count on org name as first word) */
otherOrg = firstWordInLine(cloneString(tdb->shortLabel));
}
if (startsWith("big", tdb->type))
{
char *fileName = bbiNameFromSettingOrTable(tdb, conn, tdb->table);
char *linkFileName = trackDbSetting(tdb, "linkDataUrl");
chain = chainLoadIdRangeHub(fileName, linkFileName, seqName, winStart, winEnd, atoi(item));
}
else
{
chain = chainLoadIdRange(database, tdb->table, seqName, winStart, winEnd, atoi(item));
}
chainSubsetOnT(chain, winStart, winEnd, &subChain, &toFree);
if (subChain == NULL)
nullSubset = TRUE;
else if (hDbIsActive(otherDb) && subChain != chain)
{
char *linearGap = trackDbSettingOrDefault(tdb, "chainLinearGap", "loose");
struct gapCalc *gapCalc = gapCalcFromFile(linearGap);
struct axtScoreScheme *scoreScheme = axtScoreSchemeDefault();
int qStart = subChain->qStart;
int qEnd = subChain->qEnd ;
struct dnaSeq *tSeq = hDnaFromSeq(database, subChain->tName, subChain->tStart, subChain->tEnd, dnaLower);
struct dnaSeq *qSeq = NULL;
char *matrix = trackDbSetting(tdb, "matrix");
if (matrix != NULL)
{
char *words[64];
int size = chopByWhite(matrix, words, 64) ;
if (size == 2 && atoi(words[0]) == 16)
{
scoreScheme = axtScoreSchemeFromBlastzMatrix(words[1], 400, 30);
}
else
{
if (size != 2)
errAbort("error parsing matrix entry in trackDb, expecting 2 word got %d ",
size);
else
errAbort("error parsing matrix entry in trackDb, size 16 matrix, got %d ",
atoi(words[0]));
}
}
if (subChain->qStrand == '-')
reverseIntRange(&qStart, &qEnd, subChain->qSize);
qSeq = hChromSeq(otherDb, subChain->qName, qStart, qEnd);
if (subChain->qStrand == '-')
reverseComplement(qSeq->dna, qSeq->size);
subChain->score = chainCalcScoreSubChain(subChain, scoreScheme, gapCalc,
qSeq, tSeq);
subSetScore = subChain->score;
}
chainFree(&toFree);
printf("%s position: %s:%d-%d"
" size: %d
\n",
thisOrg, hgTracksName(), cartSidUrlString(cart), database,
chain->tName, chain->tStart+1, chain->tEnd, chain->tName, chain->tStart+1, chain->tEnd,
chain->tEnd-chain->tStart);
printf("Strand: %c
\n", chain->qStrand);
qChainRangePlusStrand(chain, &qs, &qe);
if (sameWord(otherDb, "seq"))
{
printf("%s position: %s:%d-%d size: %d
\n",
otherOrg, chain->qName, qs, qe, chain->qEnd - chain->qStart);
}
else
{
/* prints link to other db browser only if db exists and is active */
/* else just print position with no link for the other db */
printf("%s position: ", otherOrg);
if (hDbIsActive(otherDb))
printf(" ",
hgTracksName(), otherDb, chain->qName, qs, qe);
printf("%s:%d-%d", chain->qName, qs, qe);
if (hDbIsActive(otherDb))
printf("");
printf(" size: %d
\n", chain->qEnd - chain->qStart);
}
printf("Chain ID: %s
\n", item);
printf("Score: %1.0f\n", chain->score);
if (nullSubset)
printf("Score within browser window: N/A (no aligned bases)
\n");
else if (hDbIsActive(otherDb) && subChain != chain)
printf(" Approximate Score within browser window: %1.0f
\n",
subSetScore);
else
printf("
\n");
boolean normScoreAvailable = chainDbNormScoreAvailable(tdb);
if (normScoreAvailable)
{
char tableName[HDB_MAX_TABLE_STRING];
if (!hFindSplitTable(database, chain->tName, tdb->table, tableName, sizeof tableName, NULL))
errAbort("genericChainClick track %s not found", tdb->table);
char query[256];
struct sqlResult *sr;
char **row;
sqlSafef(query, ArraySize(query),
"select normScore from %s where id = '%s'", tableName, item);
sr = sqlGetResult(conn, query);
if ((row = sqlNextRow(sr)) != NULL)
{
double normScore = atof(row[0]);
int basesAligned = chain->score / normScore;
printf("Normalized Score: %1.0f (aligned bases: %d)", normScore, basesAligned);
}
sqlFreeResult(&sr);
printf("
\n");
}
printf("
Fields above refer to entire chain or gap, not just the part inside the window.
\n");
printf("
\n");
chainWinSize = min(winEnd-winStart, chain->tEnd - chain->tStart);
/* Show alignment if the database exists and */
/* if there is a chromInfo table for that database and the sequence */
/* file exists. This means that alignments can be shown on the archive */
/* server (or in other cases) if there is a database with a chromInfo table, */
/* the sequences are available and there is an entry added to dbDb for */
/* the otherDb. */
if (!startsWith("big", tdb->type) && sqlDatabaseExists(otherDb) && chromSeqFileExists(otherDb, chain->qName))
{
if (chainWinSize < 1000000)
{
printf("View ");
hgcAnchorSomewhere("htcChainAli", item, tdb->track, chain->tName);
printf("DNA sequence alignment details of parts of chain within browser "
"window.
\n");
}
else
{
printf("Zoom so that browser window covers 1,000,000 bases or less "
"and return here to see alignment details.
\n");
}
if (!sameWord(otherDb, "seq") && (hDbIsActive(otherDb)))
{
chainToOtherBrowser(chain, otherDb, otherOrg);
}
}
/*
if (!sameWord(otherDb, "seq") && (hDbIsActive(otherDb)))
{
chainToOtherBrowser(chain, otherDb, otherOrg);
}
*/
chainFree(&chain);
}
char *trackTypeInfo(char *track)
/* Return type info on track. You can freeMem result when done. */
{
struct slName *trackDbs = hTrackDbList(), *oneTrackDb;
struct sqlConnection *conn = hAllocConn(database);
char buf[512];
char query[256];
for (oneTrackDb = trackDbs; oneTrackDb != NULL; oneTrackDb = oneTrackDb->next)
{
if (sqlTableExists(conn, oneTrackDb->name))
{
sqlSafef(query, sizeof(query),
"select type from %s where tableName = '%s'", oneTrackDb->name, track);
if (sqlQuickQuery(conn, query, buf, sizeof(buf)) != NULL)
break;
}
}
if (oneTrackDb == NULL)
errAbort("%s isn't in the trackDb from the hg.conf", track);
slNameFreeList(&trackDbs);
hFreeConn(&conn);
return cloneString(buf);
}
void findNib(char *db, char *chrom, char nibFile[512])
/* Find nib file corresponding to chromosome in given database. */
{
struct sqlConnection *conn = sqlConnect(db);
char query[256];
sqlSafef(query, sizeof(query),
"select fileName from chromInfo where chrom = '%s'", chrom);
if (sqlQuickQuery(conn, query, nibFile, 512) == NULL)
errAbort("Sequence %s isn't in database %s", chrom, db);
sqlDisconnect(&conn);
}
struct dnaSeq *loadGenomePart(char *db,
char *chrom, int start, int end)
/* Load genomic dna from given database and position. */
{
char nibFile[512];
findNib(db, chrom, nibFile);
return hFetchSeq(nibFile, chrom, start, end);
}
void printLabeledNumber(char *org, char *label, long long number)
/* Print label: in bold face, and number with commas. */
{
char *space = " ";
if (org == NULL)
org = space = "";
printf("%s%s%s: ", org, space, label);
printLongWithCommas(stdout, number);
printf("
\n");
}
void printLabeledPercent(char *org, char *label, long p, long q)
/* Print label: in bold, then p, and then 100 * p/q */
{
char *space = " ";
if (org == NULL)
org = space = "";
printf("%s%s%s: ", org, space, label);
printLongWithCommas(stdout, p);
if (q != 0)
printf(" (%3.1f%%)", 100.0 * p / q);
printf("
\n");
}
void genericNetClick(struct sqlConnection *conn, struct trackDb *tdb,
char *item, int start, char *otherDb, char *chainTrack)
/* Generic click handler for net tracks. */
{
char table[HDB_MAX_TABLE_STRING];
boolean hasBin;
char query[256];
struct sqlResult *sr;
char **row;
struct netAlign *net;
char *org = hOrganism(database);
char *otherOrg = hOrganism(otherDb);
char *otherOrgBrowser = otherOrg;
int tSize, qSize;
int netWinSize;
struct chain *chain;
if (otherOrg == NULL)
{
/* use first word in short track label */
otherOrg = firstWordInLine(cloneString(tdb->shortLabel));
}
if (!hFindSplitTable(database, seqName, tdb->table, table, sizeof table, &hasBin))
errAbort("genericNetClick track %s not found", tdb->table);
sqlSafef(query, sizeof(query),
"select * from %s where tName = '%s' and tStart <= %d and tEnd > %d "
"and level = %s",
table, seqName, start, start, item);
sr = sqlGetResult(conn, query);
if ((row = sqlNextRow(sr)) == NULL)
errAbort("Couldn't find %s:%d in %s", seqName, start, table);
net = netAlignLoad(row+hasBin);
sqlFreeResult(&sr);
tSize = net->tEnd - net->tStart;
qSize = net->qEnd - net->qStart;
if (net->chainId != 0)
{
netWinSize = min(winEnd-winStart, net->tEnd - net->tStart);
printf("
\n");
/* Show alignment if the database exists and */
/* if there is a chromInfo table for that database and the sequence */
/* file exists. This means that alignments can be shown on the archive */
/* server (or in other cases) if there is a database with a chromInfo */
/* table, the sequences are available and there is an entry added to */
/* dbDb for the otherDb. */
if (chromSeqFileExists(otherDb, net->qName))
{
if (netWinSize < 1000000)
{
int ns = max(winStart, net->tStart);
int ne = min(winEnd, net->tEnd);
if (ns < ne)
{
char id[20];
snprintf(id, sizeof(id), "%d", net->chainId);
hgcAnchorWindow("htcChainAli", id, ns, ne, chainTrack, seqName);
printf("View alignment details of parts of net within browser window.
\n");
}
else
{
printf("Odd, net not in window
\n");
}
}
else
{
printf("To see alignment details zoom so that the browser window covers 1,000,000 bases or less.
\n");
}
}
chain = chainDbLoad(conn, database, chainTrack, seqName, net->chainId);
if (chain != NULL)
{
/* print link to browser for otherDb only if otherDb is active */
if (hDbIsActive(otherDb))
chainToOtherBrowser(chain, otherDb, otherOrgBrowser);
chainFree(&chain);
}
htmlHorizontalLine();
}
printf("Type: %s
\n", net->type);
printf("Level: %d
\n", (net->level+1)/2);
printf("%s position: %s:%d-%d
\n",
org, net->tName, net->tStart+1, net->tEnd);
printf("%s position: %s:%d-%d
\n",
otherOrg, net->qName, net->qStart+1, net->qEnd);
printf("Strand: %c
\n", net->strand[0]);
printLabeledNumber(NULL, "Score", net->score);
if (net->chainId)
{
printf("Chain ID: %u
\n", net->chainId);
printLabeledNumber(NULL, "Bases aligning", net->ali);
if (net->qOver >= 0)
printLabeledNumber(otherOrg, "parent overlap", net->qOver);
if (net->qFar >= 0)
printLabeledNumber(otherOrg, "parent distance", net->qFar);
if (net->qDup >= 0)
printLabeledNumber(otherOrg, "bases duplicated", net->qDup);
}
if (net->tN >= 0)
printLabeledPercent(org, "N's", net->tN, tSize);
if (net->qN >= 0)
printLabeledPercent(otherOrg, "N's", net->qN, qSize);
if (net->tTrf >= 0)
printLabeledPercent(org, "tandem repeat (trf) bases", net->tTrf, tSize);
if (net->qTrf >= 0)
printLabeledPercent(otherOrg, "tandem repeat (trf) bases", net->qTrf, qSize);
if (net->tR >= 0)
printLabeledPercent(org, "RepeatMasker bases", net->tR, tSize);
if (net->qR >= 0)
printLabeledPercent(otherOrg, "RepeatMasker bases", net->qR, qSize);
if (net->tOldR >= 0)
printLabeledPercent(org, "old repeat bases", net->tOldR, tSize);
if (net->qOldR >= 0)
printLabeledPercent(otherOrg, "old repeat bases", net->qOldR, qSize);
if (net->tNewR >= 0)
printLabeledPercent(org, "new repeat bases", net->tOldR, tSize);
if (net->qNewR >= 0)
printLabeledPercent(otherOrg, "new repeat bases", net->qOldR, qSize);
if (net->tEnd >= net->tStart)
printLabeledNumber(org, "size", net->tEnd - net->tStart);
if (net->qEnd >= net->qStart)
printLabeledNumber(otherOrg, "size", net->qEnd - net->qStart);
printf("
Fields above refer to entire chain or gap, not just the part inside the window.
\n");
netAlignFree(&net);
}
void tfbsConsSites(struct trackDb *tdb, char *item)
/* detail page for tfbsConsSites track */
{
boolean printedPlus = FALSE;
boolean printedMinus = FALSE;
int start = cartInt(cart, "o");
struct sqlConnection *conn = hAllocConn(database);
char table[HDB_MAX_TABLE_STRING];
boolean hasBin;
char query[512];
struct sqlResult *sr;
char **row;
struct tfbsConsSites *tfbsConsSites;
struct tfbsConsSites *tfbsConsSitesList = NULL;
struct tfbsConsFactors *tfbsConsFactor;
struct tfbsConsFactors *tfbsConsFactorList = NULL;
boolean firstTime = TRUE;
char *mappedId = NULL;
genericHeader(tdb, item);
if (!hFindSplitTable(database, seqName, tdb->table, table, sizeof table, &hasBin))
errAbort("tfbsConsSites track %s not found", tdb->table);
sqlSafef(query, sizeof query, "select * from %s where name = '%s' and chrom = '%s' and chromStart = %d",
table, item, seqName, start);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
tfbsConsSites = tfbsConsSitesLoad(row+hasBin);
slAddHead(&tfbsConsSitesList, tfbsConsSites);
}
sqlFreeResult(&sr);
slReverse(&tfbsConsSitesList);
if (!hFindSplitTable(database, seqName, "tfbsConsFactors", table, sizeof table, &hasBin))
errAbort("tfbsConsSites table tfbsConsFactors not found");
sqlSafef(query, sizeof query, "select * from %s where name = '%s' ", table, item);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
tfbsConsFactor = tfbsConsFactorsLoad(row+hasBin);
slAddHead(&tfbsConsFactorList, tfbsConsFactor);
}
sqlFreeResult(&sr);
slReverse(&tfbsConsFactorList);
if (tfbsConsFactorList)
mappedId = cloneString(tfbsConsFactorList->ac);
printf("Transcription Factor Binding Site information:
");
for(tfbsConsSites=tfbsConsSitesList ; tfbsConsSites != NULL ; tfbsConsSites = tfbsConsSites->next)
{
/* print each strand only once */
if ((printedMinus && (tfbsConsSites->strand[0] == '-')) || (printedPlus && (tfbsConsSites->strand[0] == '+')))
continue;
if (!firstTime)
htmlHorizontalLine();
else
firstTime = FALSE;
printf("Item: %s
\n", tfbsConsSites->name);
if (mappedId != NULL)
printCustomUrl(tdb, mappedId, FALSE);
printf("Score: %d
\n", tfbsConsSites->score );
printf("zScore: %.2f
\n", tfbsConsSites->zScore );
printf("Strand: %s
\n", tfbsConsSites->strand);
printPos(tfbsConsSites->chrom, tfbsConsSites->chromStart, tfbsConsSites->chromEnd, NULL, TRUE, tfbsConsSites->name);
printedPlus = printedPlus || (tfbsConsSites->strand[0] == '+');
printedMinus = printedMinus || (tfbsConsSites->strand[0] == '-');
}
if (tfbsConsFactorList)
{
htmlHorizontalLine();
printf("Transcription Factors known to bind to this site:
");
for(tfbsConsFactor =tfbsConsFactorList ; tfbsConsFactor != NULL ; tfbsConsFactor = tfbsConsFactor ->next)
{
if (!sameString(tfbsConsFactor->species, "N"))
{
printf("
Factor: %s
\n", tfbsConsFactor->factor);
printf("Species: %s
\n", tfbsConsFactor->species);
printf("SwissProt ID: %s
\n", sameString(tfbsConsFactor->id, "N")? "unknown": tfbsConsFactor->id);
}
}
}
printTrackHtml(tdb);
hFreeConn(&conn);
}
void tfbsCons(struct trackDb *tdb, char *item)
/* detail page for tfbsCons track */
{
boolean printFactors = FALSE;
boolean printedPlus = FALSE;
boolean printedMinus = FALSE;
int start = cartInt(cart, "o");
struct sqlConnection *conn = hAllocConn(database);
char table[HDB_MAX_TABLE_STRING];
boolean hasBin;
char query[512];
struct sqlResult *sr;
char **row;
struct tfbsCons *tfbs;
struct tfbsCons *tfbsConsList = NULL;
struct tfbsConsMap tfbsConsMap;
boolean firstTime = TRUE;
char *mappedId = NULL;
genericHeader(tdb, item);
if (!hFindSplitTable(database, seqName, tdb->table, table, sizeof table, &hasBin))
errAbort("tfbsCons track %s not found", tdb->table);
sqlSafef(query, sizeof query, "select * from %s where name = '%s' and chrom = '%s' and chromStart = %d",
table, item, seqName, start);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
tfbs = tfbsConsLoad(row+hasBin);
slAddHead(&tfbsConsList, tfbs);
}
sqlFreeResult(&sr);
slReverse(&tfbsConsList);
if (hTableExists(database, "tfbsConsMap"))
{
sqlSafef(query, sizeof query, "select * from tfbsConsMap where id = '%s'", tfbsConsList->name);
sr = sqlGetResult(conn, query);
if ((row = sqlNextRow(sr)) != NULL)
{
tfbsConsMapStaticLoad(row, &tfbsConsMap);
mappedId = cloneString(tfbsConsMap.ac);
}
}
sqlFreeResult(&sr);
printf("Transcription Factor Binding Site information:
");
for(tfbs=tfbsConsList ; tfbs != NULL ; tfbs = tfbs->next)
{
if (!sameString(tfbs->species, "N"))
printFactors = TRUE;
/* print each strand only once */
if ((printedMinus && (tfbs->strand[0] == '-')) || (printedPlus && (tfbs->strand[0] == '+')))
continue;
if (!firstTime)
htmlHorizontalLine();
else
firstTime = FALSE;
printf("Item: %s
\n", tfbs->name);
if (mappedId != NULL)
printCustomUrl(tdb, mappedId, FALSE);
printf("Score: %d
\n", tfbs->score );
printf("Strand: %s
\n", tfbs->strand);
printPos(tfbsConsList->chrom, tfbs->chromStart, tfbs->chromEnd, NULL, TRUE, tfbs->name);
printedPlus = printedPlus || (tfbs->strand[0] == '+');
printedMinus = printedMinus || (tfbs->strand[0] == '-');
}
if (printFactors)
{
htmlHorizontalLine();
printf("Transcription Factors known to bind to this site:
");
for(tfbs=tfbsConsList ; tfbs != NULL ; tfbs = tfbs->next)
{
/* print only the positive strand when factors are on both strands */
if ((tfbs->strand[0] == '-') && printedPlus)
continue;
if (!sameString(tfbs->species, "N"))
{
printf("
Factor: %s
\n", tfbs->factor);
printf("Species: %s
\n", tfbs->species);
printf("SwissProt ID: %s
\n", sameString(tfbs->id, "N")? "unknown": tfbs->id);
}
}
}
printTrackHtml(tdb);
hFreeConn(&conn);
}
void firstEF(struct trackDb *tdb, char *item)
{
int start = cartInt(cart, "o");
struct sqlConnection *conn = hAllocConn(database);
char table[HDB_MAX_TABLE_STRING];
boolean hasBin;
struct bed *bed;
char query[512];
struct sqlResult *sr;
char **row;
boolean firstTime = TRUE;
/* itemForUrl = item; */
genericHeader(tdb, item);
printCustomUrl(tdb, item, FALSE);
/* printCustomUrl(tdb, itemForUrl, item == itemForUrl); */
if (!hFindSplitTable(database, seqName, tdb->table, table, sizeof table, &hasBin))
errAbort("firstEF track %s not found", tdb->table);
sqlSafef(query, sizeof query, "select * from %s where name = '%s' and chrom = '%s' and chromStart = %d",
table, item, seqName, start);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
if (firstTime)
firstTime = FALSE;
else
htmlHorizontalLine();
bed = bedLoadN(row+hasBin, 6);
printf("Item: %s
\n", bed->name);
printf("Probability: %g
\n", bed->score / 1000.0);
printf("Strand: %s
\n", bed->strand);
printPos(bed->chrom, bed->chromStart, bed->chromEnd, NULL, TRUE, bed->name);
}
printTrackHtml(tdb);
hFreeConn(&conn);
}
void doBed5FloatScore(struct trackDb *tdb, char *item)
/* Handle click in BED 5+ track: BED 5 with 0-1000 score (for useScore
* shading in hgTracks) plus real score for display in details page. */
{
struct sqlConnection *conn = hAllocConn(database);
struct sqlResult *sr = NULL;
char table[HDB_MAX_TABLE_STRING];
boolean hasBin;
struct bed5FloatScore *b5;
struct dyString *query = newDyString(512);
char **row;
boolean firstTime = TRUE;
int start = cartInt(cart, "o");
int bedSize = 5;
if (!hFindSplitTable(database, seqName, tdb->table, table, sizeof table, &hasBin))
errAbort("doBed5FloatScore track %s not found", tdb->table);
sqlDyStringPrintf(query, "select * from %s where chrom = '%s' and ",
table, seqName);
hAddBinToQuery(winStart, winEnd, query);
sqlDyStringPrintf(query, "name = '%s' and chromStart = %d", item, start);
sr = sqlGetResult(conn, query->string);
while ((row = sqlNextRow(sr)) != NULL)
{
if (firstTime)
firstTime = FALSE;
else
htmlHorizontalLine();
b5 = bed5FloatScoreLoad(row+hasBin);
bedPrintPos((struct bed *)b5, 4, tdb);
printf("Score: %f
\n", b5->floatScore);
if (sameString(tdb->type, "bed5FloatScoreWithFdr"))
{
if (row[7] != NULL)
printf("False Discovery Rate (FDR): %s%%
\n", row[7]);
}
}
getBedTopScorers(conn, tdb, table, item, start, bedSize);
sqlFreeResult(&sr);
hFreeConn(&conn);
/* printTrackHtml is done in genericClickHandlerPlus. */
}
void doBed6FloatScore(struct trackDb *tdb, char *item)
/* Handle click in BED 4+ track that's like BED 6 but with floating pt score */
{
struct sqlConnection *conn = hAllocConn(database);
struct sqlResult *sr = NULL;
char table[HDB_MAX_TABLE_STRING];
boolean hasBin;
struct bed6FloatScore *b6 = NULL;
struct dyString *query = newDyString(512);
char **row;
boolean firstTime = TRUE;
int start = cartInt(cart, "o");
genericHeader(tdb, item);
if (!hFindSplitTable(database, seqName, tdb->table, table, sizeof table, &hasBin))
errAbort("doBed6FloatScore track %s not found", tdb->table);
sqlDyStringPrintf(query, "select * from %s where chrom = '%s' and ",
table, seqName);
hAddBinToQuery(winStart, winEnd, query);
sqlDyStringPrintf(query, "name = '%s' and chromStart = %d", item, start);
sr = sqlGetResult(conn, query->string);
while ((row = sqlNextRow(sr)) != NULL)
{
if (firstTime)
firstTime = FALSE;
else
htmlHorizontalLine();
b6 = bed6FloatScoreLoad(row+hasBin);
bedPrintPos((struct bed *)b6, 4, tdb);
printf("Score: %f
\n", b6->score);
printf("Strand: %s
\n", b6->strand);
}
sqlFreeResult(&sr);
// Support for motif display if configured in trackDb
// TODO - share code with factorSource
char *motifPwmTable = trackDbSetting(tdb, "motifPwmTable");
struct dnaMotif *motif = NULL;
if (motifPwmTable != NULL && sqlTableExists(conn, motifPwmTable))
{
motif = loadDnaMotif(b6->name, motifPwmTable);
if (motif == NULL)
return;
struct dnaSeq *seq = hDnaFromSeq(database, b6->chrom, b6->chromStart, b6->chromEnd, dnaLower);
motifLogoAndMatrix(&seq, 1, motif);
}
hFreeConn(&conn);
/* printTrackHtml is done in genericClickHandlerPlus. */
}
void doColoredExon(struct trackDb *tdb, char *item)
/* Print information for coloredExon type tracks. */
{
struct sqlConnection *conn = hAllocConn(database);
struct sqlResult *sr;
char query[256];
char **row;
genericHeader(tdb, item);
sqlSafef(query, sizeof(query), "select chrom,chromStart,chromEnd,name,score,strand from %s where name='%s'", tdb->table, item);
sr = sqlGetResult(conn, query);
if ((row = sqlNextRow(sr)) != NULL)
{
struct bed *itemBed = bedLoad6(row);
bedPrintPos(itemBed, 6, tdb);
bedFree(&itemBed);
}
else
{
hPrintf("Could not find info for %s
\n", item);
}
sqlFreeResult(&sr);
printTrackHtml(tdb);
hFreeConn(&conn);
}
void doImageItemBed(struct trackDb *tdb, char *item)
/* Print bed plus an image */
{
}
void doChromGraph(struct trackDb *tdb)
/* Print information for coloredExon type tracks. */
{
genericHeader(tdb, NULL);
printTrackHtml(tdb);
}
static void genericContainerClick(struct sqlConnection *conn, char *containerType,
struct trackDb *tdb, char *item, char *itemForUrl)
/* Print page for container of some sort. */
{
if (sameString(containerType, "multiWig"))
{
errAbort("It's suprising that multiWig container gets to hgc. It should go to hgTrackUi.");
}
else
{
errAbort("Unrecognized container type %s for %s", containerType, tdb->track);
}
}
static void doLongTabix(struct trackDb *tdb, char *item)
/* Handle a click on a long range interaction */
{
char *bigDataUrl = hashFindVal(tdb->settingsHash, "bigDataUrl");
struct bedTabixFile *btf = bedTabixFileMayOpen(bigDataUrl, NULL, 0, 0);
char *chromName = cartString(cart, "c");
struct bed *list = bedTabixReadBeds(btf, chromName, winStart, winEnd, bedLoad5);
bedTabixFileClose(&btf);
unsigned maxWidth;
struct longRange *longRangeList = parseLongTabix(list, &maxWidth, 0);
struct longRange *longRange, *ourLongRange = NULL;
unsigned itemNum = sqlUnsigned(item);
unsigned count = slCount(longRangeList);
double *doubleArray;
AllocArray(doubleArray, count);
int ii = 0;
for(longRange = longRangeList; longRange; longRange = longRange->next, ii++)
{
if (longRange->id == itemNum)
{
ourLongRange = longRange;
}
doubleArray[ii] = longRange->score;
}
if (ourLongRange == NULL)
errAbort("cannot find long range item with id %d\n", itemNum);
printf("Item you clicked on:
\n");
printf(" ID: %u
\n", ourLongRange->id);
if (!ourLongRange->hasColor)
// if there's color, then there's no score in this format
printf("Score: %g
\n", ourLongRange->score);
unsigned padding = (ourLongRange->e - ourLongRange->s) / 10;
int s = ourLongRange->s - padding;
int e = ourLongRange->e + padding;
if (s < 0 )
s = 0;
int chromSize = hChromSize(database, seqName);
if (e > chromSize)
e = chromSize;
char sStartPosBuf[1024], sEndPosBuf[1024];
char eStartPosBuf[1024], eEndPosBuf[1024];
// FIXME: longRange should store region starts, not centers
sprintLongWithCommas(sStartPosBuf, ourLongRange->s - ourLongRange->sw/2 + 1);
sprintLongWithCommas(sEndPosBuf, ourLongRange->s + ourLongRange->sw/2 + 1);
sprintLongWithCommas(eStartPosBuf, ourLongRange->e - ourLongRange->ew/2 + 1);
sprintLongWithCommas(eEndPosBuf, ourLongRange->e + ourLongRange->ew/2 + 1);
char sWidthBuf[1024], eWidthBuf[1024];
char regionWidthBuf[1024];
sprintLongWithCommas(sWidthBuf, ourLongRange->sw);
sprintLongWithCommas(eWidthBuf, ourLongRange->ew);
sprintLongWithCommas(regionWidthBuf, ourLongRange->ew + ourLongRange->e - ourLongRange->s);
if (differentString(ourLongRange->sChrom, ourLongRange->eChrom))
{
printf("Current region: ");
printf("%s:%s-%s (%s bp)
\n",
ourLongRange->sChrom, sStartPosBuf, sEndPosBuf,
ourLongRange->sChrom, sStartPosBuf,sEndPosBuf, sWidthBuf);
printf("Paired region: ");
printf("%s:%s-%s (%s bp)
\n",
ourLongRange->eChrom, eStartPosBuf, eEndPosBuf,
ourLongRange->eChrom, eStartPosBuf, eEndPosBuf, eWidthBuf);
}
else
{
printf("Lower region: ");
printf("%s:%s-%s (%s bp)
\n",
ourLongRange->sChrom, sStartPosBuf,sEndPosBuf,
ourLongRange->sChrom, sStartPosBuf,sEndPosBuf, sWidthBuf);
printf("Upper region: ");
printf("%s:%s-%s (%s bp)
\n",
ourLongRange->eChrom, eStartPosBuf, eEndPosBuf,
ourLongRange->eChrom, eStartPosBuf, eEndPosBuf, eWidthBuf);
printf("Interaction region: ");
printf("%s:%s-%s (%s bp)
\n",
ourLongRange->eChrom, sStartPosBuf, eEndPosBuf,
ourLongRange->eChrom, sStartPosBuf, eEndPosBuf, regionWidthBuf);
}
if (ourLongRange->hasColor)
return;
struct aveStats *as = aveStatsCalc(doubleArray, count);
printf("
Statistics on the scores of all items in window (go to track controls to set minimum score to display):\n");
printf("\n");
printf("Q1 | %f |
\n", as->q1);
printf("median | %f |
\n", as->median);
printf("Q3 | %f |
\n", as->q3);
printf("average | %f |
\n", as->average);
printf("min | %f |
\n", as->minVal);
printf("max | %f |
\n", as->maxVal);
printf("count | %d |
\n", as->count);
printf("total | %f |
\n", as->total);
printf("standard deviation | %f |
\n", as->stdDev);
printf("
\n");
}
void genericClickHandlerPlus(
struct trackDb *tdb, char *item, char *itemForUrl, char *plus)
/* Put up generic track info, with additional text appended after item. */
{
char *dupe, *type, *words[16], *headerItem;
int wordCount;
int start = cartInt(cart, "o");
int end = cartInt(cart, "t");
struct sqlConnection *conn = NULL;
char *imagePath = trackDbSetting(tdb, ITEM_IMAGE_PATH);
char *container = trackDbSetting(tdb, "container");
if (!trackHubDatabase(database))
conn = hAllocConnTrack(database, tdb);
if (itemForUrl == NULL)
itemForUrl = item;
dupe = cloneString(tdb->type);
wordCount = chopLine(dupe, words);
headerItem = cloneString(item);
type = words[0];
/* Suppress printing item name in page header, as it is not informative for these types of
* tracks... */
if (container == NULL && wordCount > 0)
{
if (sameString(type, "maf") || sameString(type, "wigMaf") || sameString(type, "bigMaf") || sameString(type, "netAlign")
|| sameString(type, "encodePeak"))
headerItem = NULL;
else if (( sameString(type, "narrowPeak")
|| sameString(type, "broadPeak")
|| sameString(type, "gappedPeak") )
&& headerItem
&& sameString(headerItem, ".") )
headerItem = NULL;
}
/* Print header. */
genericHeader(tdb, headerItem);
if (differentString(type, "bigInteract") && differentString(type, "interact"))
{
// skip generic URL code as these may have multiple items returned for a click
itemForUrl = getIdInUrl(tdb, item);
if (itemForUrl != NULL && trackDbSetting(tdb, "url"))
{
printCustomUrl(tdb, itemForUrl, item == itemForUrl);
printIframe(tdb, itemForUrl);
}
}
if (plus != NULL)
{
fputs(plus, stdout);
}
if (container != NULL)
{
genericContainerClick(conn, container, tdb, item, itemForUrl);
}
else if (wordCount > 0)
{
type = words[0];
if (sameString(type, "bed"))
{
int num = 0;
if (wordCount > 1)
num = atoi(words[1]);
if (num < 3) num = 3;
genericBedClick(conn, tdb, item, start, num);
}
else if (sameString(type, "bigGenePred"))
{
int num = 12;
genericBigBedClick(conn, tdb, item, start, end, num);
}
else if (sameString(type, "bigBed"))
{
int num = 0;
if (wordCount > 1)
num = atoi(words[1]);
if (num < 3) num = 3;
genericBigBedClick(conn, tdb, item, start, end, num);
}
else if (sameString(type, "sample"))
{
int num = 9;
genericSampleClick(conn, tdb, item, start, num);
}
else if (sameString(type, "genePred"))
{
char *pepTable = NULL, *mrnaTable = NULL;
if ((wordCount > 1) && !sameString(words[1], "."))
pepTable = words[1];
if ((wordCount > 2) && !sameString(words[2], "."))
mrnaTable = words[2];
genericGenePredClick(conn, tdb, item, start, pepTable, mrnaTable);
}
else if ( sameString(type, "bigPsl")) {
genericBigPslClick(conn, tdb, item, start, end);
}
else if (sameString(type, "psl"))
{
char *subType = ".";
if (wordCount > 1)
subType = words[1];
genericPslClick(conn, tdb, item, start, subType);
}
else if (sameString(type, "netAlign"))
{
if (wordCount < 3)
errAbort("Missing field in netAlign track type field");
genericNetClick(conn, tdb, item, start, words[1], words[2]);
}
else if (sameString(type, "chain") || sameString(type, "bigChain") )
{
if (wordCount < 2)
errAbort("Missing field in chain track type field");
genericChainClick(conn, tdb, item, start, words[1]);
}
else if (sameString(type, "maf"))
{
genericMafClick(conn, tdb, item, start);
}
else if (sameString(type, "wigMaf") || sameString(type, "bigMaf"))
{
genericMafClick(conn, tdb, item, start);
}
else if (startsWith("wigMafProt", type))
{
genericMafClick(conn, tdb, item, start);
}
else if (sameString(type, "axt"))
{
genericAxtClick(conn, tdb, item, start, words[1]);
}
else if (sameString(type, "expRatio"))
{
doExpRatio(tdb, item, NULL);
}
else if (sameString(type, "coloredExon"))
{
doColoredExon(tdb, item);
}
else if (sameString(type, "encodePeak") || sameString(type, "narrowPeak") ||
sameString(type, "broadPeak") || sameString(type, "gappedPeak"))
{
doEncodePeak(tdb, NULL, item);
}
else if (sameString(type, "bigNarrowPeak"))
{
doBigEncodePeak(tdb, NULL, item);
}
else if (sameString(type, "encodeFiveC"))
{
doEncodeFiveC(conn, tdb);
}
else if (sameString(type, "peptideMapping"))
{
doPeptideMapping(conn, tdb, item);
}
else if (sameString(type, "chromGraph"))
{
doChromGraph(tdb);
}
else if (sameString(type, "wig"))
{
genericWiggleClick(conn, tdb, item, start);
}
else if (sameString(type, "bigWig"))
{
genericBigWigClick(conn, tdb, item, start);
}
else if (sameString(type, "factorSource"))
{
doFactorSource(conn, tdb, item, start, end);
}
else if (sameString(type, "bed5FloatScore") ||
sameString(type, "bed5FloatScoreWithFdr"))
{
doBed5FloatScore(tdb, item);
}
else if (sameString(type, "bed6FloatScore"))
{
doBed6FloatScore(tdb, item);
}
else if (sameString(type, "altGraphX"))
{
doAltGraphXDetails(tdb,item);
}
//add bedDetail here
else if (startsWith("bedDetail", type))
{
doBedDetail(tdb, NULL, item);
}
else if (sameString(type, "bigLolly") )
{
int num = 12;
genericBigBedClick(conn, tdb, item, start, end, num);
}
else if (sameString(type, "bigDbSnp") )
{
doBigDbSnp(tdb, item);
}
else if (sameString(type, "interaction") )
{
int num = 12;
genericBedClick(conn, tdb, item, start, num);
}
else if (startsWith("gvf", type))
{
doGvf(tdb, item);
}
else if (sameString(type, "bam"))
doBamDetails(tdb, item);
else if ( startsWith("longTabix", type))
doLongTabix(tdb, item);
else if (sameWord("interact", type) || sameWord("bigInteract", type))
doInteractDetails(tdb, item);
}
if (imagePath)
{
char *bigImagePath = trackDbSettingClosestToHome(tdb, ITEM_BIG_IMAGE_PATH);
char *bothWords[2];
int shouldBeTwo = chopLine(imagePath, bothWords);
if (shouldBeTwo != 2)
errAbort("itemImagePath setting for %s track incorrect. Needs to be \"itemImagePath \".", tdb->track);
printf("

\n", bothWords[0], item, bothWords[1]);
shouldBeTwo = chopLine(bigImagePath, bothWords);
if (shouldBeTwo != 2)
errAbort("bigItemImagePath setting for %s track incorrect. Needs to be \"itemImagePath \".", tdb->track);
printf("Download Original Image
\n", bothWords[0], item, bothWords[1]);
}
if ((sameString(tdb->table,"altLocations") || sameString(tdb->table,"fixLocations")) &&
strchr(item,'_'))
{
// Truncate item (alt/fix sequence name) at colon if found:
char itemCpy[strlen(item)+1];
safecpy(itemCpy, sizeof(itemCpy), item);
char *p = strchr(itemCpy, ':');
if (p)
*p = '\0';
char *hgsid = cartSessionId(cart);
char *desc = sameString(tdb->table, "altLocations") ? "alternate haplotype" : "fix patch";
printf(""
"Show this %s placed on its chromosome
\n",
hgsid, itemCpy, desc);
}
printTrackHtml(tdb);
freez(&dupe);
hFreeConn(&conn);
}
void genericClickHandler(struct trackDb *tdb, char *item, char *itemForUrl)
/* Put up generic track info */
{
#ifdef OLD /* Called now by cartWebStart... */
jsIncludeFile("jquery.js", NULL);
jsIncludeFile("utils.js",NULL);
#endif /* OLD */
genericClickHandlerPlus(tdb, item, itemForUrl, NULL);
}
void savePosInTextBox(char *chrom, int start, int end)
/* Save basic position/database info in text box and hidden var.
Positions becomes chrom:start-end*/
{
char position[128];
char *newPos;
snprintf(position, 128, "%s:%d-%d", chrom, start, end);
newPos = addCommasToPos(database, position);
cgiMakeTextVar("getDnaPos", newPos, strlen(newPos) + 2);
cgiContinueHiddenVar("db");
}
char *hgTablesUrl(boolean usePos, char *track)
/* Make up URL for table browser. */
{
struct dyString *url = dyStringNew(0);
dyStringAppend(url, "../cgi-bin/hgTables?");
dyStringAppend(url, cartSidUrlString(cart));
dyStringPrintf(url, "&db=%s", database);
if (usePos)
{
dyStringPrintf(url, "&position=%s:%d-%d", seqName, winStart+1, winEnd);
dyStringAppend(url, "&hgta_regionType=range");
}
if (track != NULL)
{
struct trackDb *tdb = hashFindVal(trackHash, track);
if (tdb != NULL)
{
char *grp = tdb->grp;
if (grp != NULL && grp[0] != 0)
{
dyStringPrintf(url, "&hgta_group=%s", grp);
dyStringPrintf(url, "&hgta_track=%s", track);
dyStringPrintf(url, "&hgta_table=%s", track);
}
}
}
return dyStringCannibalize(&url);
}
char *traceUrl(char *traceId)
/* Make up URL for trace archive. */
{
struct dyString *url = dyStringNew(0);
dyStringAppend(url, "https://www.ncbi.nlm.nih.gov/Traces/trace.cgi?");
dyStringPrintf(url, "cmd=retrieve&size=1&val=%s&", traceId);
dyStringAppend(url, "file=trace&dopt=trace");
return dyStringCannibalize(&url);
}
void doGetDna1()
/* Do first get DNA dialog. */
{
struct hTableInfo *hti = NULL;
char *tbl = cgiUsualString("table", "");
if (dbIsFound && tbl[0] != 0)
{
char rootName[256];
char parsedChrom[32];
hParseTableName(database, tbl, rootName, parsedChrom);
if (!trackHubDatabase(database))
hti = hFindTableInfo(database, seqName, rootName);
}
char *thisOrg = hOrganism(database);
cartWebStart(cart, database, "Get DNA in Window (%s/%s)", database, thisOrg);
printf("Get DNA for
\n");
printf("");
if (dbIsFound)
puts("Note: The \"Mask repeats\" option applies only to \"get DNA\", not to \"extended case/color options\".
");
}
boolean dnaIgnoreTrack(char *track)
/* Return TRUE if this is one of the tracks too boring
* to put DNA on. */
{
return (sameString("cytoBand", track) ||
sameString("gcPercent", track) ||
sameString("gold", track) ||
sameString("gap", track) ||
startsWith("mouseSyn", track));
}
struct customTrack *getCtList()
/* initialize theCtList if necessary and return it */
{
if (theCtList == NULL)
theCtList = customTracksParseCart(database, cart, NULL, NULL);
return(theCtList);
}
struct trackDb *tdbForCustomTracks()
/* Load custom tracks (if any) and translate to list of trackDbs */
{
struct customTrack *ctList = getCtList();
struct customTrack *ct;
struct trackDb *tdbList = NULL, *tdb;
for (ct=ctList; ct != NULL; ct=ct->next)
{
AllocVar(tdb);
tdb->track = ct->tdb->track;
tdb->table = ct->tdb->table;
tdb->shortLabel = ct->tdb->shortLabel;
tdb->type = ct->tdb->type;
tdb->longLabel = ct->tdb->longLabel;
tdb->visibility = ct->tdb->visibility;
tdb->priority = ct->tdb->priority;
tdb->colorR = ct->tdb->colorR;
tdb->colorG = ct->tdb->colorG;
tdb->colorB = ct->tdb->colorB;
tdb->altColorR = ct->tdb->altColorR;
tdb->altColorG = ct->tdb->altColorG;
tdb->altColorB = ct->tdb->altColorB;
tdb->useScore = ct->tdb->useScore;
tdb->private = ct->tdb->private;
tdb->url = ct->tdb->url;
tdb->grp = ct->tdb->grp;
tdb->canPack = ct->tdb->canPack;
trackDbPolish(tdb);
slAddHead(&tdbList, tdb);
}
slReverse(&tdbList);
return(tdbList);
}
struct customTrack *lookupCt(char *name)
/* Return custom track for name, or NULL. */
{
struct customTrack *ct;
for (ct=getCtList(); ct != NULL; ct=ct->next)
if (sameString(name, ct->tdb->track))
return(ct);
return(NULL);
}
void parseSs(char *ss, char **retPslName, char **retFaName, char **retQName)
/* Parse space separated 'ss' item. */
{
static char buf[512*2];
int wordCount;
char *words[4];
strcpy(buf, ss);
wordCount = chopLine(buf, words);
if (wordCount < 1)
errAbort("Empty user cart variable ss.");
*retPslName = words[0];
if (retFaName != NULL)
{
if (wordCount < 2)
errAbort("Expecting psl filename and fa filename in cart variable ss, but only got one word: %s", ss);
*retFaName = words[1];
}
if (retQName != NULL)
{
if (wordCount < 3)
errAbort("Expecting psl filename, fa filename and query name in cart variable ss, but got this: %s", ss);
*retQName = words[2];
}
}
boolean ssFilesExist(char *ss)
/* Return TRUE if both files in ss exist. -- Copied from hgTracks! */
{
char *faFileName, *pslFileName;
parseSs(ss, &pslFileName, &faFileName, NULL);
return fileExists(pslFileName) && fileExists(faFileName);
}
struct trackDb *tdbForUserPsl()
/* Load up user's BLAT results into trackDb. */
{
char *ss = cartOptionalString(cart, "ss");
if ((ss != NULL) && !ssFilesExist(ss))
{
ss = NULL;
cartRemove(cart, "ss");
}
if (ss == NULL)
return(NULL);
else
{
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);
}
}
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);
}
void doGetDnaExtended1()
/* Do extended case/color get DNA options. */
{
struct trackDb *tdbList = hTrackDb(database), *tdb;
struct trackDb *ctdbList = tdbForCustomTracks();
struct trackDb *utdbList = tdbForUserPsl();
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);
int lineWidth = cartUsualInt(cart, "lineWidth", 60);
char *casing = cartUsualString(cart, "hgSeq.casing", "");
char *repMasking = cartUsualString(cart, "hgSeq.repMasking", "");
boolean caseUpper= FALSE;
char *pos = NULL;
ctdbList = slCat(ctdbList, tdbList);
tdbList = slCat(utdbList, ctdbList);
cartWebStart(cart, database, "Extended DNA Case/Color");
if (NULL != (pos = stripCommas(cartOptionalString(cart, "getDnaPos"))))
hgParseChromRange(database, pos, &seqName, &winStart, &winEnd);
if (winEnd - winStart > 5000000)
{
printf("Please zoom in to 5 million bases or less to color the DNA");
return;
}
printf("
Extended DNA Case/Color Options
\n");
puts(
"Use this page to highlight features in genomic DNA text. "
"DNA covered by a particular track can be highlighted by "
"case, underline, bold, italic, or color. See below for "
"details about color, and for examples. Tracks in "
""hide" display mode are not shown in the grid below. ");
if (cgiBooleanDefined("hgSeq.maskRepeats"))
cartSetBoolean(cart, "hgSeq.maskRepeats", maskRep);
if (*repMasking != 0)
cartSetString(cart, "hgSeq.repMasking", repMasking);
if (maskRep)
{
struct trackDb *rtdb;
char *visString = cartOptionalString(cart, "rmsk");
for (rtdb = tdbList; rtdb != NULL; rtdb=rtdb->next)
{
if (startsWith(rtdb->table, "rmsk"))
break;
}
printf("
Note: repeat masking style from previous page will not apply to this page.\n");
if ((rtdb != NULL) &&
((visString == NULL) || !sameString(visString, "hide")))
printf("Use the case/color options for the RepeatMasker track below.
\n");
else
printf("Unhide the RepeatMasker track in the genome browser, then return to this page and use the case/color options for the RepeatMasker track below.
\n");
}
cartSetInt(cart, "padding5", padding5);
cartSetInt(cart, "padding3", padding3);
if (sameString(casing, "upper"))
caseUpper = TRUE;
if (*casing != 0)
cartSetString(cart, "hgSeq.casing", casing);
printf("
\n");
printf("Coloring Information and Examples
\n");
puts("The color values range from 0 (darkest) to 255 (lightest) and are additive.\n");
puts("The examples below show a few ways to highlight individual tracks, "
"and their interplay. It's good to keep it simple at first. It's easy "
"to make pretty, but completely cryptic, displays with this feature.");
puts(
""
"- To put exons from RefSeq Genes in upper case red text, check the "
"appropriate box in the Toggle Case column and set the color to pure "
"red, RGB (255,0,0). Upon submitting, any RefSeq Gene within the "
"designated chromosomal interval will now appear in red capital letters.\n"
"
- To see the overlap between RefSeq Genes and Genscan predictions try "
"setting the RefSeq Genes to red (255,0,0) and Genscan to green (0,255,0). "
"Places where the RefSeq Genes and Genscan overlap will be painted yellow "
"(255,255,0).\n"
"
- To get a level-of-coverage effect for tracks like Spliced Ests with "
"multiple overlapping items, initially select a darker color such as deep "
"green, RGB (0,64,0). Nucleotides covered by a single EST will appear dark "
"green, while regions covered with more ESTs get progressively brighter — "
"saturating at 4 ESTs."
"
- Another track can be used to mask unwanted features. Setting the "
"RepeatMasker track to RGB (255,255,255) will white-out Genscan predictions "
"of LINEs but not mainstream host genes; masking with RefSeq Genes will show "
"what is new in the gene prediction sector."
"
");
puts("Further Details and Ideas
");
puts("Copying and pasting the web page output to a text editor such as Word "
"will retain upper case but lose colors and other formatting. That is still "
"useful because other web tools such as "
"NCBI Blast "
"can be set to ignore lower case. To fully capture formatting such as color "
"and underlining, view the output as \"source\" in your web browser, or download "
"it, or copy the output page into an html editor.
");
puts("The default line width of 60 characters is standard, but if you have "
"a reasonable sized monitor it's useful to set this higher - to 125 characters "
"or more. You can see more DNA at once this way, and fewer line breaks help "
"in finding DNA strings using the web browser search function.
");
puts("Be careful about requesting complex formatting for a very large "
"chromosomal region. After all the html tags are added to the output page, "
"the file size may exceed size limits that your browser, clipboard, and "
"other software can safely display. The tool will format 10 Mb and more, however.
");
trackDbFreeList(&tdbList);
}
void doGetBlastPep(char *readName, char *table)
/* get predicted protein */
{
int qStart;
struct psl *psl;
int start, end;
struct sqlResult *sr;
struct sqlConnection *conn = hAllocConn(database);
struct dnaSeq *tSeq;
char query[256], **row;
char fullTable[HDB_MAX_TABLE_STRING];
boolean hasBin;
char *buffer, *str;
int i, j;
char *ptr;
start = cartInt(cart, "o");
if (!hFindSplitTable(database, seqName, table, fullTable, sizeof fullTable, &hasBin))
errAbort("doGetBlastPep track %s not found", table);
sqlSafef(query, sizeof query, "select * from %s where qName = '%s' and tName = '%s' and tStart=%d",
fullTable, readName, seqName, start);
sr = sqlGetResult(conn, query);
if ((row = sqlNextRow(sr)) == NULL)
errAbort("Couldn't find alignment for %s at %d", readName, start);
psl = pslLoad(row+hasBin);
sqlFreeResult(&sr);
hFreeConn(&conn);
printf("");
end = psl->tEnd;
if (psl->strand[1] == '+')
end = psl->tStarts[psl->blockCount - 1] + psl->blockSizes[psl->blockCount - 1] *3;
if ((ptr = strchr(readName, '.')) != NULL)
*ptr++ = 0;
printf(">%s-%s\n", readName,database);
tSeq = hDnaFromSeq(database, psl->tName, start, end, dnaLower);
if (psl->strand[1] == '-')
{
start = psl->tSize - end;
reverseComplement(tSeq->dna, tSeq->size);
}
str = buffer = needMem(psl->qSize + 1);
qStart = 0;
for (i=0; iblockCount; ++i)
{
int ts = psl->tStarts[i] - start;
int sz = psl->blockSizes[i];
for (;qStart < psl->qStarts[i]; qStart++)
*str++ = 'X';
for (j=0; jdna[codonStart];
if ((*str = lookupCodon(codon)) == 0)
*str = '*';
str++;
qStart++;
}
}
*str = 0;
printLines(stdout, buffer, 50);
printf("
");
}
void doGetDna2()
/* Do second DNA dialog (or just fetch DNA) */
{
char *tbl = cgiUsualString("table", "");
char *action = cgiUsualString("submit", "");
int itemCount;
char *pos = NULL;
char *chrom = NULL;
int start = 0;
int end = 0;
if (sameString(action, EXTENDED_DNA_BUTTON))
{
doGetDnaExtended1();
return;
}
// This output probably should be just text/plain but
// trying to support the fancy warn handler box requires html.
// But we want to keep it very simple and close to a plain text dump.
cartHtmlStart("DNA");
puts("");
if (tbl[0] == 0)
{
itemCount = 1;
if ( NULL != (pos = stripCommas(cartOptionalString(cart, "getDnaPos"))) &&
hgParseChromRange((dbIsFound ? database : NULL), pos, &chrom, &start, &end))
{
hgSeqRange(database, chrom, start, end, '?', "dna");
}
else
{
hgSeqRange(database, seqName, cartInt(cart, "l"), cartInt(cart, "r"),
'?', "dna");
}
}
else
{
struct hTableInfo *hti = NULL;
char rootName[256];
char parsedChrom[32];
/* use the values from the dnaPos dialog box */
if (!( NULL != (pos = stripCommas(cartOptionalString(cart, "getDnaPos"))) &&
hgParseChromRange(database, pos, &chrom, &start, &end)))
{
/* if can't get DnaPos from dialog box, use "o" and "t" */
start = cartInt(cart, "o");
end = cartInt(cart, "t");
}
/* Table might be a custom track if it's not in the database,
* or bigBed if it is in the database but has only one column called 'fileName';
* in which case, just get DNA as if no table were given. */
hParseTableName(database, tbl, rootName, parsedChrom);
if (!trackHubDatabase(database))
hti = hFindTableInfo(database, seqName, rootName);
if (hti == NULL || hti->startField[0] == 0)
{
itemCount = 1;
hgSeqRange(database, seqName, start, end, '?', tbl);
}
else
{
char *where = NULL;
char *item = cgiUsualString("i", "");
char buf[256];
if ((hti->nameField[0] != 0) && (item[0] != 0))
{
char *quotedItem = makeQuotedString(item, '\'');
safef(buf, sizeof(buf), "%s = %s", hti->nameField, quotedItem);
where = buf;
freeMem(quotedItem);
}
itemCount = hgSeqItemsInRange(database, tbl, seqName, start, end, where);
}
}
if (itemCount == 0)
printf("\n# No results returned from query.\n\n");
puts("
");
}
struct hTableInfo *ctToHti(struct customTrack *ct)
/* Create an hTableInfo from a customTrack. */
{
struct hTableInfo *hti;
AllocVar(hti);
hti->rootName = cloneString(ct->tdb->table);
hti->isPos = TRUE;
hti->isSplit = FALSE;
hti->hasBin = FALSE;
hti->type = cloneString(ct->tdb->type);
int fieldCount = 3;
if (sameWord(ct->dbTrackType, "bedDetail"))
fieldCount = ct->fieldCount - 2;
else if (sameWord(ct->dbTrackType, "pgSnp"))
fieldCount = 4;
else
fieldCount = ct->fieldCount;
if (fieldCount >= 3)
{
strncpy(hti->chromField, "chrom", 32);
strncpy(hti->startField, "chromStart", 32);
strncpy(hti->endField, "chromEnd", 32);
}
if (fieldCount >= 4)
{
strncpy(hti->nameField, "name", 32);
}
if (fieldCount >= 5)
{
strncpy(hti->scoreField, "score", 32);
}
if (fieldCount >= 6)
{
strncpy(hti->strandField, "strand", 32);
}
if (fieldCount >= 8)
{
strncpy(hti->cdsStartField, "thickStart", 32);
strncpy(hti->cdsEndField, "thickEnd", 32);
hti->hasCDS = TRUE;
}
if (fieldCount >= 12)
{
strncpy(hti->countField, "blockCount", 32);
strncpy(hti->startsField, "chromStarts", 32);
strncpy(hti->endsSizesField, "blockSizes", 32);
hti->hasBlocks = TRUE;
}
return(hti);
}
struct hTableInfo *htiForUserPsl()
/* Create an hTableInfo for user's BLAT results. */
{
struct hTableInfo *hti;
AllocVar(hti);
hti->rootName = cloneString(USER_PSL_TRACK_NAME);
hti->isPos = TRUE;
hti->isSplit = FALSE;
hti->hasBin = FALSE;
hti->type = cloneString("psl");
strncpy(hti->chromField, "tName", 32);
strncpy(hti->startField, "tStart", 32);
strncpy(hti->endField, "tEnd", 32);
strncpy(hti->nameField, "qName", 32);
/* psl can be scored... but strictly speaking, does not have a score field! */
strncpy(hti->strandField, "strand", 32);
hti->hasCDS = FALSE;
strncpy(hti->countField, "blockCount", 32);
strncpy(hti->startsField, "tStarts", 32);
strncpy(hti->endsSizesField, "tSizes", 32);
hti->hasBlocks = TRUE;
return(hti);
}
struct bed *bedFromUserPsl()
/* Load up user's BLAT results into bedList. */
{
struct bed *bedList = NULL;
char *ss = cartOptionalString(cart, "ss");
if ((ss != NULL) && ! ssFilesExist(ss))
{
ss = NULL;
cartRemove(cart, "ss");
}
if (ss == NULL)
return(NULL);
else
{
struct lineFile *f;
struct psl *psl;
enum gfType qt, tt;
char *faFileName, *pslFileName;
int i;
parseSs(ss, &pslFileName, &faFileName, NULL);
pslxFileOpen(pslFileName, &qt, &tt, &f);
while ((psl = pslNext(f)) != NULL)
{
struct bed *bed;
AllocVar(bed);
bed->chrom = cloneString(seqName);
bed->chromStart = psl->tStart;
bed->chromEnd = psl->tEnd;
bed->name = cloneString(psl->qName);
bed->score = pslScore(psl);
if ((psl->strand[0] == '-' && psl->strand[1] == '+') ||
(psl->strand[0] == '+' && psl->strand[1] == '-'))
strncpy(bed->strand, "-", 2);
else
strncpy(bed->strand, "+", 2);
bed->thickStart = bed->chromStart;
bed->thickEnd = bed->chromEnd;
bed->blockCount = psl->blockCount;
bed->chromStarts = needMem(bed->blockCount * sizeof(int));
bed->blockSizes = needMem(bed->blockCount * sizeof(int));
for (i=0; i < bed->blockCount; i++)
{
bed->chromStarts[i] = psl->tStarts[i];
bed->blockSizes[i] = psl->blockSizes[i];
}
if (qt == gftProt)
for (i=0; i < bed->blockCount; i++)
{
/* If query is protein, blockSizes are in aa units; fix 'em. */
bed->blockSizes[i] *= 3;
}
if (psl->strand[1] == '-')
{
/* psl: if target strand is '-', flip the coords.
* (this is the target part of pslRc from src/lib/psl.c) */
for (i=0; i < bed->blockCount; ++i)
{
bed->chromStarts[i] =
psl->tSize - (bed->chromStarts[i] +
bed->blockSizes[i]);
}
reverseInts(bed->chromStarts, bed->blockCount);
reverseInts(bed->blockSizes, bed->blockCount);
assert(bed->chromStart == bed->chromStarts[0]);
}
/* translate absolute starts to relative starts (after handling
* target-strand coord-flipping) */
for (i=0; i < bed->blockCount; i++)
{
bed->chromStarts[i] -= bed->chromStart;
}
slAddHead(&bedList, bed);
pslFree(&psl);
}
lineFileClose(&f);
slReverse(&bedList);
return(bedList);
}
}
void addColorToRange(int r, int g, int b, struct rgbColor *colors, int start, int end)
/* Add rgb values to colors array from start to end. Don't let values
* exceed 255 */
{
struct rgbColor *c;
int rr, gg, bb;
int i;
for (i=start; ir + r;
if (rr > 255) rr = 255;
c->r = rr;
gg = c->g + g;
if (gg > 255) gg = 255;
c->g = gg;
bb = c->b + b;
if (bb > 255) bb = 255;
c->b = bb;
}
}
void getDnaHandleBits(char *track, char *type, Bits *bits,
int winStart, int winEnd, boolean isRc,
struct featureBits *fbList)
/* See if track_type variable exists, and if so set corresponding bits. */
{
char buf[256];
struct featureBits *fb;
int s,e;
int winSize = winEnd - winStart;
safef(buf, sizeof buf, "%s_%s", track, type);
if (cgiBoolean(buf))
{
for (fb = fbList; fb != NULL; fb = fb->next)
{
s = fb->start - winStart;
e = fb->end - winStart;
if (isRc)
reverseIntRange(&s, &e, winSize);
bitSetRange(bits, s, e - s);
}
}
}
void doGetDna3()
/* Fetch DNA in extended color format */
{
struct dnaSeq *seq;
struct cfm *cfm;
int i;
boolean isRc = cartUsualBoolean(cart, "hgSeq.revComp", FALSE);
boolean defaultUpper = sameString(cartString(cart, "hgSeq.casing"), "upper");
int winSize;
int lineWidth = cartInt(cart, "lineWidth");
struct rgbColor *colors;
struct trackDb *tdbList = hTrackDb(database), *tdb;
struct trackDb *ctdbList = tdbForCustomTracks();
struct trackDb *utdbList = tdbForUserPsl();
char *pos = NULL;
Bits *uBits; /* Underline bits. */
Bits *iBits; /* Italic bits. */
Bits *bBits; /* Bold bits. */
if (NULL != (pos = stripCommas(cartOptionalString(cart, "getDnaPos"))))
hgParseChromRange(database, pos, &seqName, &winStart, &winEnd);
winSize = winEnd - winStart;
uBits = bitAlloc(winSize); /* Underline bits. */
iBits = bitAlloc(winSize); /* Italic bits. */
bBits = bitAlloc(winSize); /* Bold bits. */
ctdbList = slCat(ctdbList, tdbList);
tdbList = slCat(utdbList, ctdbList);
cartWebStart(cart, database, "Extended DNA Output");
printf("");
printf(">%s:%d-%d %s\n", seqName, winStart+1, winEnd,
(isRc ? "(reverse complement)" : ""));
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
|| ( tdbVisLimitedByAncestors(cart,tdb,TRUE,TRUE) != tvHide
&& forestHasUnderstandableTrack(database, tdb) ) )
{
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);
hasSettings |= (cgiOptionalInt(buf, 0) != 0);
safef(buf, sizeof(buf), "%s_green", track);
hasSettings |= (cgiOptionalInt(buf, 0) != 0);
safef(buf, sizeof(buf), "%s_blue", track);
hasSettings |= (cgiOptionalInt(buf, 0) != 0);
if (! hasSettings)
continue;
if (sameString(USER_PSL_TRACK_NAME, track))
{
struct hTableInfo *hti = htiForUserPsl();
struct bedFilter *bf;
struct bed *bedList, *bedList2;
AllocVar(bf);
bedList = bedFromUserPsl();
bedList2 = bedFilterListInRange(bedList, bf, seqName, winStart,
winEnd);
fbList = fbFromBed(database, track, hti, bedList2, winStart, winEnd,
TRUE, FALSE);
bedFreeList(&bedList);
bedFreeList(&bedList2);
}
else if (ct != NULL)
{
struct hTableInfo *hti = ctToHti(ct);
struct bedFilter *bf;
struct bed *bedList2, *ctBedList = NULL;
AllocVar(bf);
if (ct->dbTrack)
{
struct bed *bed;
int fieldCount = ct->fieldCount;
char query[512];
int rowOffset;
char **row;
struct sqlConnection *conn = hAllocConn(CUSTOM_TRASH);
struct sqlResult *sr = NULL;
sqlSafef(query, sizeof(query), "select * from %s", ct->dbTableName);
sr = hRangeQuery(conn, ct->dbTableName, seqName,
winStart, winEnd, NULL, &rowOffset);
while ((row = sqlNextRow(sr)) != NULL)
{
bed = bedLoadN(row+rowOffset, fieldCount);
if (bf == NULL || bedFilterOne(bf, bed))
{
struct bed *copy = cloneBed(bed);
slAddHead(&ctBedList, copy);
}
}
sqlFreeResult(&sr);
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
{
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);
}
freeMem(refLeaf);
}
}
else
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. */
safef(buf, sizeof 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;
int size = fb->end - fb->start;
if (isRc)
reverseIntRange(&start, &end, seq->size);
dna = seq->dna + start;
if (defaultUpper)
toLowerN(dna, size);
else
toUpperN(dna, size);
}
}
/* Add in RGB values if necessary. */
safef(buf, sizeof buf, "%s_red", track);
r = cartInt(cart, buf);
safef(buf, sizeof buf, "%s_green", track);
g = cartInt(cart, buf);
safef(buf, sizeof buf, "%s_blue", track);
b = cartInt(cart, buf);
if (r != 0 || g != 0 || b != 0)
{
for (fb = fbList; fb != NULL; fb = fb->next)
{
int s = fb->start - winStart;
int e = fb->end - winStart;
if (isRc)
reverseIntRange(&s, &e, winEnd - winStart);
addColorToRange(r, g, b, colors, s, e);
}
}
}
}
cfm = cfmNew(0, lineWidth, FALSE, FALSE, stdout, 0);
for (i=0; isize; ++i)
{
struct rgbColor *color = colors+i;
int c = (color->r<<16) + (color->g<<8) + color->b;
cfmOutExt(cfm, seq->dna[i], c,
bitReadOne(uBits, i), bitReadOne(bBits, i), bitReadOne(iBits, i));
}
cfmFree(&cfm);
freeDnaSeq(&seq);
bitFree(&uBits);
bitFree(&iBits);
bitFree(&bBits);
}
void medlineLinkedTermLine(char *title, char *text, char *search, char *keyword)
/* Produce something that shows up on the browser as
* TITLE: value
* with the value hyperlinked to medline using a specified search term. */
{
char *encoded = cgiEncode(search);
char *encodedKeyword = cgiEncode(keyword);
printf("%s: ", title);
if (sameWord(text, "n/a") || sameWord(text, "none"))
printf("n/a
\n");
else
{
printf("%s
\n", text);
}
freeMem(encoded);
}
void medlineLinkedLine(char *title, char *text, char *search)
/* Produce something that shows up on the browser as
* TITLE: value
* with the value hyperlinked to medline. */
{
char *encoded = cgiEncode(search);
printf("%s: ", title);
if (sameWord(text, "n/a"))
printf("n/a
\n");
else
{
printf("%s
\n", text);
}
freeMem(encoded);
}
void medlineProductLinkedLine(char *title, char *text)
/* Produce something that shows up on the browser as
* TITLE: value
* with the value hyperlinked to medline.
* Replaces commas in the product name with spaces, as commas sometimes
* interfere with PubMed search */
{
subChar(text, ',', ' ');
medlineLinkedLine(title, text, text);
}
void appendAuthor(struct dyString *dy, char *gbAuthor, int len)
/* Convert from Kent,W.J. to Kent WJ and append to dy.
* gbAuthor gets eaten in the process.
* Also strip web URLs since Entrez doesn't like those. */
{
char buf[2048];
char *ptr;
if (len >= sizeof(buf))
warn("author %s too long to process", gbAuthor);
else
{
memcpy(buf, gbAuthor, len);
buf[len] = 0;
stripChar(buf, '.');
subChar(buf, ',' , ' ');
if ((ptr = strstr(buf, " http://")) != NULL)
*ptr = 0;
dyStringAppend(dy, buf);
dyStringAppend(dy, " ");
}
}
void gbToEntrezAuthor(char *authors, struct dyString *dy)
/* Convert from Genbank author format:
* Kent,W.J., Haussler,D. and Zahler,A.M.
* to Entrez search format:
* Kent WJ,Haussler D,Zahler AM
*/
{
char *s = authors, *e;
/* Parse first authors, which will be terminated by '.,' */
while ((e = strstr(s, ".,i ")) != NULL)
{
int len = e - s + 1;
appendAuthor(dy, s, len);
s += len+2;
}
if ((e = strstr(s, " and")) != NULL)
{
int len = e - s;
appendAuthor(dy, s, len);
s += len+4;
}
if ((s = skipLeadingSpaces(s)) != NULL && s[0] != 0)
{
int len = strlen(s);
appendAuthor(dy, s, len);
}
}
/* --- !!! Riken code is under development Fan. 4/16/02 */
void printRikenInfo(char *acc, struct sqlConnection *conn )
/* Print Riken annotation info */
{
struct sqlResult *sr;
char **row;
char query[512];
char *seqid, *accession, *comment;
// char *qualifier, *anntext, *datasrc, *srckey, *href, *evidence;
accession = acc;
sqlSafef(query, sizeof(query),
"select seqid from rikenaltid where altid='%s';", accession);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
if (row != NULL)
{
seqid=cloneString(row[0]);
sqlSafef(query, sizeof(query),
"select Qualifier, Anntext, Datasrc, Srckey, Href, Evidence "
"from rikenann where seqid='%s';", seqid);
sqlFreeResult(&sr);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
while (row !=NULL)
{
// qualifier = row[0]; unused variable
// anntext = row[1]; unused variable
// datasrc = row[2]; unused variable
// srckey = row[3]; unused variable
// href = row[4]; unused variable
// evidence = row[5]; unused variable
row = sqlNextRow(sr);
}
sqlSafef(query, sizeof(query),
"select comment from rikenseq where id='%s';", seqid);
sqlFreeResult(&sr);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
if (row != NULL)
{
comment = row[0];
printf("Riken/comment: %s
\n",comment);
}
}
}
void printGeneCards(char *geneName)
/* Print out a link to GeneCards (Human only). */
{
if (startsWith("hg", database) && isNotEmpty(geneName))
{
printf("GeneCards: "
"%s
\n",
geneName, geneName);
}
}
int getImageId(struct sqlConnection *conn, char *acc)
/* get the image id for a clone, or 0 if none */
{
int imageId = 0;
if (sqlTableExists(conn, imageCloneTable))
{
struct sqlResult *sr;
char **row;
char query[128];
sqlSafef(query, sizeof(query),
"select imageId from %s where acc = '%s'",imageCloneTable, acc);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
if (row != NULL)
imageId = sqlUnsigned(row[0]);
sqlFreeResult(&sr);
}
return imageId;
}
void htcDisplayMrna(char *acc)
/* Display mRNA available from genback or seq table.. */
{
struct dnaSeq *seq = hGenBankGetMrna(database, acc, NULL);
if (seq == NULL)
errAbort("mRNA sequence %s not found", acc);
cartHtmlStart("mRNA sequence");
printf("");
faWriteNext(stdout, seq->name, seq->dna, seq->size);
printf("
");
dnaSeqFree(&seq);
}
static int getEstTranscriptionDir(struct sqlConnection *conn, struct psl *psl)
/* get the direction of transcription for an EST; return splice support count */
{
char query[256], estOrient[64];
sqlSafef(query, sizeof(query),
"select intronOrientation from %s.estOrientInfo where chrom = '%s' and chromStart = %d and name = '%s'",
database, psl->tName, psl->tStart, psl->qName);
if (sqlQuickQuery(conn, query, estOrient, sizeof(estOrient)) != NULL)
return sqlSigned(estOrient) * ((psl->strand[0] == '+') ? 1 : -1);
else
return 0;
}
static struct gbWarn *checkGbWarn(struct sqlConnection *conn, char *acc)
/* check if there is a gbWarn entry for this accession, return NULL if none */
{
struct gbWarn *gbWarn = NULL;
if (sqlTableExists(conn, gbWarnTable))
gbWarn = sqlQueryObjs(conn, (sqlLoadFunc)gbWarnLoad, sqlQuerySingle,
"SELECT * FROM %s WHERE acc = \"%s\"", gbWarnTable, acc);
return gbWarn;
}
static void printGbWarn(char *acc, struct gbWarn *gbWarn)
/* print descriptive information about an accession in the gbWarn table */
{
char *msg = NULL;
switch (gbWarn->reason) {
case gbWarnInvitroNorm:
msg = "is from the InVitroGen/Genoscope full-length library. Some of the entries "
"associated with this dataset appear to have been aligned to the reference "
"genome and the sequences subsequently modified to match the genome. This "
"process may have resulted in apparent high-quality alignments to pseudogenes.";
break;
case gbWarnAthRage:
msg = "is from the Athersys RAGE library. These sequences were created by inducing expression and may not "
"be an indication of in vivo expression.";
break;
case gbWarnOrestes:
msg = "is from an ORESTES library. This protocol includes a PCR step subject to genomic contamination.";
break;
}
assert(msg != NULL);
char *msg2= "Care should be taken in using alignments of this sequence as evidence of transcription.";
printf("Warning: %s %s %s
\n", acc, msg, msg2);
}
static void printRnaSpecs(struct trackDb *tdb, char *acc, struct psl *psl)
/* Print auxiliarry info on RNA. */
{
struct dyString *dy = newDyString(1024);
struct sqlConnection *conn = hAllocConn(database);
struct sqlConnection *conn2= hAllocConn(database);
struct sqlResult *sr;
char **row;
char rgdEstId[512];
char query[256];
char *type,*direction,*orgFullName,*library,*clone,*sex,*tissue,
*development,*cell,*cds,*description, *author,*geneName,
*date,*productName;
// char *source; unused variable
// int seqSize,fileSize; unused variables
// long fileOffset; unused variable
// char *extFile; unused variable
boolean hasVersion = hHasField(database, gbCdnaInfoTable, "version");
boolean haveGbSeq = sqlTableExists(conn, gbSeqTable);
char *seqTbl = haveGbSeq ? gbSeqTable : "seq";
char *version = NULL;
struct trackDb *tdbRgdEst;
char *chrom = cartString(cart, "c");
int start = cartInt(cart, "o");
int end = cartUsualInt(cart, "t",0);
struct gbWarn *gbWarn = checkGbWarn(conn, acc);
/* This sort of query and having to keep things in sync between
* the first clause of the select, the from clause, the where
* clause, and the results in the row ... is really tedious.
* One of my main motivations for going to a more object
* based rather than pure relational approach in general,
* and writing 'autoSql' to help support this. However
* the pure relational approach wins for pure search speed,
* and these RNA fields are searched. So it looks like
* the code below stays. Be really careful when you modify
* it.
*
* Uses the gbSeq table if available, otherwise use seq for older databases.
*/
sqlDyStringPrintf(dy,
"select g.type,g.direction,"
"so.name,o.name,l.name,m.name,"
"se.name,t.name,dev.name,ce.name,cd.name,"
"des.name,a.name,gene.name,p.name,"
"gbS.size,g.moddate,gbS.gbExtFile,gbS.file_offset,gbS.file_size ");
/* If the gbCdnaInfoTAble table has a "version" column then will show it */
if (hasVersion)
{
sqlDyStringPrintf(dy,
", g.version ");
}
sqlDyStringPrintf(dy,
" from %s g,%s gbS,%s so,%s o,%s l,%s m,%s se,%s t,"
"%s dev,%s ce,%s cd,%s des,%s a,%s gene,%s p"
" where g.acc = '%s' and g.id = gbS.id ",
gbCdnaInfoTable,seqTbl, sourceTable, organismTable, libraryTable, mrnaCloneTable, sexTable, tissueTable, developmentTable, cellTable, cdsTable, descriptionTable, authorTable, geneNameTable, productNameTable, acc);
sqlDyStringPrintf(dy,
"and g.source = so.id and g.organism = o.id "
"and g.library = l.id and g.mrnaClone = m.id "
"and g.sex = se.id and g.tissue = t.id "
"and g.development = dev.id and g.cell = ce.id "
"and g.cds = cd.id and g.description = des.id "
"and g.author = a.id and g.geneName = gene.id "
"and g.productName = p.id");
sr = sqlMustGetResult(conn, dy->string);
row = sqlNextRow(sr);
if (row != NULL)
{
type=row[0];direction=row[1];
// source=row[2]; unused variable
orgFullName=row[3];library=row[4];clone=row[5];
sex=row[6];tissue=row[7];development=row[8];cell=row[9];cds=row[10];description=row[11];
author=row[12];geneName=row[13];productName=row[14];
// seqSize = sqlUnsigned(row[15]); unused variable
date = row[16];
// ext_file = row[17]; unused variable
// fileOffset=sqlUnsigned(row[18]); unused variable
// fileSize=sqlUnsigned(row[19]); unused variable
boolean isEst = sameWord(type, "est");
if (hasVersion)
{
version = row[20];
}
/* Now we have all the info out of the database and into nicely named
* local variables. There's still a few hoops to jump through to
* format this prettily on the web with hyperlinks to NCBI. */
printf("Information on %s %s
\n", acc);
printf("Description: %s
\n", description);
if (gbWarn != NULL)
printGbWarn(acc, gbWarn);
medlineLinkedLine("Gene", geneName, geneName);
medlineProductLinkedLine("Product", productName);
dyStringClear(dy);
gbToEntrezAuthor(author, dy);
medlineLinkedLine("Author", author, dy->string);
printf("Organism: ");
printf("",
cgiEncode(orgFullName));
printf("%s
\n", orgFullName);
printf("Tissue: %s
\n", tissue);
printf("Development stage: %s
\n", development);
printf("Cell line: %s
\n", cell);
printf("Sex: %s
\n", sex);
printf("Library: %s
\n", library);
printf("Clone: %s
\n", clone);
if (isEst)
{
printf("Read direction: ");
if (direction[0] != '0')
printf("%s' (guessed from GenBank description)
\n", direction);
else
printf("unknown (can't guess from GenBank description)
");
}
else
printf("CDS: %s
\n", cds);
printf("Date: %s
\n", date);
if (hasVersion)
{
printf("Version: %s
\n", version);
}
/* print RGD EST Report link if it is Rat genome and it has a link to RGD */
if (sameWord(organism, "Rat"))
{
if (hTableExists(database, "rgdEstLink"))
{
sqlSafef(query, sizeof(query),
"select id from %s.rgdEstLink where name = '%s';", database, acc);
if (sqlQuickQuery(conn2, query, rgdEstId, sizeof(rgdEstId)) != NULL)
{
tdbRgdEst = hashFindVal(trackHash, "rgdEst");
printf("RGD EST Report: ");
printf("", tdbRgdEst->url, rgdEstId);
printf("RGD:%s
\n", rgdEstId);
}
}
}
if (isEst && hTableExists(database, "estOrientInfo") && (psl != NULL))
{
int estOrient = getEstTranscriptionDir(conn2, psl);
if (estOrient != 0)
printf("EST transcribed from %c strand (supported by %d splice sites).
\n",
(estOrient > 0 ? '+' : '-' ), abs(estOrient));
}
if (hGenBankHaveSeq(database, acc, NULL))
{
printf("%s sequence: ", type);
hgcAnchorSomewhere("htcDisplayMrna", acc, tdb->track, seqName);
printf("%s
\n", acc);
}
}
else
{
warn("Couldn't find %s in %s table", gbCdnaInfoTable, acc);
}
if (end != 0 && differentString(chrom,"0") && isNotEmpty(chrom))
{
printf("Position: "
"",
hgTracksPathAndSettings(), database, chrom, start+1, end);
printf("%s:%d-%d
\n", chrom, start+1, end);
}
gbWarnFree(&gbWarn);
sqlFreeResult(&sr);
freeDyString(&dy);
hFreeConn(&conn);
hFreeConn(&conn2);
}
static boolean isPslToPrintByClick(struct psl *psl, int startFirst, boolean isClicked)
/* Determine if a psl should be printed based on if it was or was not the one that was clicked
* on.
*/
{
return ((psl->tStart == startFirst) && sameString(psl->tName, seqName)) == isClicked;
}
void printAlignmentsSimple(struct psl *pslList, int startFirst, char *hgcCommand,
char *tableName, char *itemIn)
/* Print list of mRNA alignments, don't add extra textual link when
* doesn't honor hgcCommand. */
{
struct psl *psl;
int aliCount = slCount(pslList);
boolean isClicked;
if (pslList == NULL || tableName == NULL)
return;
boolean showEvery = sameString(itemIn, "PrintAllSequences");
if (!showEvery && (aliCount > 1))
printf("The alignment you clicked on is first in the table below.
\n");
printf("");
if (startsWith("chr", pslList->tName))
printf("BROWSER | SIZE IDENTITY CHROMOSOME STRAND START END QUERY START END TOTAL\n");
else
printf("BROWSER | SIZE IDENTITY SCAFFOLD STRAND START END QUERY START END TOTAL\n");
printf("-----------------------------------------------------------------------------------------------------\n");
for (isClicked = 1; isClicked >= 0; isClicked -= 1)
{
for (psl = pslList; psl != NULL; psl = psl->next)
{
if (isPslToPrintByClick(psl, startFirst, isClicked))
{
char otherString[512];
char *qName = itemIn;
if (sameString(itemIn, "PrintAllSequences"))
qName = psl->qName;
safef(otherString, sizeof(otherString), "%d&aliTable=%s", psl->tStart, tableName);
printf("browser | ",
hgTracksPathAndSettings(), database, psl->tName, psl->tStart+1, psl->tEnd);
hgcAnchorWindow(hgcCommand, qName, psl->tStart, psl->tEnd, otherString, psl->tName);
printf("%5d %5.1f%% %9s %s %9d %9d %20s %5d %5d %5d",
psl->match + psl->misMatch + psl->repMatch,
100.0 - pslCalcMilliBad(psl, TRUE) * 0.1,
skipChr(psl->tName), psl->strand, psl->tStart + 1, psl->tEnd,
psl->qName, psl->qStart+1, psl->qEnd, psl->qSize);
printf("\n");
}
}
}
printf("
");
}
void printAlignmentsExtra(struct psl *pslList, int startFirst, char *hgcCommand, char *hgcCommandInWindow,
char *tableName, char *itemIn)
/* Print list of mRNA alignments with special "in window" alignment function. */
{
if (pslList == NULL || tableName == NULL)
return;
printAlignmentsSimple(pslList, startFirst, hgcCommand, tableName, itemIn);
struct psl *psl = pslList;
for (psl = pslList; psl != NULL; psl = psl->next)
{
if ( pslTrimToTargetRange(psl, winStart, winEnd) != NULL
&&
!startsWith("xeno", tableName)
&& !(startsWith("user", tableName) && pslIsProtein(psl))
&& psl->tStart == startFirst
&& sameString(psl->tName, seqName)
)
{
char otherString[512];
safef(otherString, sizeof(otherString), "%d&aliTable=%s",
psl->tStart, tableName);
hgcAnchorSomewhere(hgcCommandInWindow, itemIn, otherString, psl->tName);
printf("
View details of parts of alignment within browser window.
\n");
}
}
}
void printAlignments(struct psl *pslList, int startFirst, char *hgcCommand,
char *tableName, char *itemIn)
/* Print list of mRNA alignments. */
{
printAlignmentsExtra(pslList, startFirst, hgcCommand, "htcCdnaAliInWindow", tableName, itemIn);
}
static struct psl *getAlignmentsTName(struct sqlConnection *conn, char *table, char *acc,
char *tName)
/* get the list of alignments for the specified acc and tName (if given). */
{
struct sqlResult *sr = NULL;
char **row;
struct psl *psl, *pslList = NULL;
boolean hasBin;
char splitTable[HDB_MAX_TABLE_STRING];
char query[1024];
if (!hFindSplitTable(database, seqName, table, splitTable, sizeof splitTable, &hasBin))
errAbort("can't find table %s or %s_%s", table, seqName, table);
if (isNotEmpty(tName))
sqlSafef(query, sizeof(query), "select * from %s where qName = '%s' and tName = '%s'",
splitTable, acc, tName);
else
sqlSafef(query, sizeof(query), "select * from %s where qName = '%s'", splitTable, acc);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
psl = pslLoad(row+hasBin);
slAddHead(&pslList, psl);
}
sqlFreeResult(&sr);
slReverse(&pslList);
return pslList;
}
struct psl *getAlignments(struct sqlConnection *conn, char *table, char *acc)
/* get the list of alignments for the specified acc */
{
return getAlignmentsTName(conn, table, acc, NULL);
}
struct psl *loadPslRangeT(char *table, char *qName, char *tName, int tStart, int tEnd)
/* Load a list of psls given qName tName tStart tEnd */
{
struct sqlResult *sr = NULL;
char **row;
struct psl *psl = NULL, *pslList = NULL;
boolean hasBin;
char splitTable[HDB_MAX_TABLE_STRING];
char query[256];
struct sqlConnection *conn = hAllocConn(database);
if (!hFindSplitTable(database, seqName, table, splitTable, sizeof splitTable, &hasBin))
errAbort("loadPslRangeT track %s not found", table);
sqlSafef(query, sizeof(query), "select * from %s where qName = '%s' and tName = '%s' and tEnd > %d and tStart < %d", splitTable, qName, tName, tStart, tEnd);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
psl = pslLoad(row+hasBin);
slAddHead(&pslList, psl);
}
sqlFreeResult(&sr);
slReverse(&pslList);
hFreeConn(&conn);
return pslList;
}
void doHgRna(struct trackDb *tdb, char *acc)
/* Click on an individual RNA. */
{
char *track = tdb->track;
char *table = tdb->table;
struct sqlConnection *conn = hAllocConn(database);
char *type;
int start = cartInt(cart, "o");
struct psl *pslList = NULL;
if (sameString("xenoMrna", track) || sameString("xenoBestMrna", track) || sameString("xenoEst", track) || sameString("sim4", track) )
{
char temp[256];
safef(temp, sizeof temp, "non-%s RNA", organism);
type = temp;
}
else if ( sameWord("blatzHg17KG", track) )
{
type = "Human mRNA";
}
else if (stringIn("estFiltered",track))
{
type = "EST";
}
else if (stringIn("est", track) || stringIn("Est", track))
{
type = "EST";
// table = "all_est"; // Should fall out of wash now
}
else if (startsWith("psu", track))
{
type = "Pseudo & Real Genes";
table = "psu";
}
else if (sameWord("xenoBlastzMrna", track) )
{
type = "Blastz to foreign mRNA";
}
else if (startsWith("mrnaBlastz",track ))
{
type = "mRNA";
}
else if (startsWith("pseudoMrna",track) || startsWith("pseudoGeneLink",track))
{
type = "mRNA";
table = "pseudoMrna";
}
else if (startsWith("celeraMrna",track))
{
type = "mRNA";
}
else if (startsWith("all_mrnaFiltered",track))
{
type = "mRNA";
}
else
{
type = "mRNA";
// table = "all_mrna"; // should fall out of wash now
}
/* Print non-sequence info. */
cartWebStart(cart, database, "%s", acc);
printRnaSpecs(tdb, acc, pslList);
/* Get alignment info. */
pslList = getAlignments(conn, table, acc);
if (pslList == NULL)
{
/* this was not actually a click on an aligned item -- we just
* want to display RNA info, so leave here */
hFreeConn(&conn);
htmlHorizontalLine();
printf("mRNA %s alignment does not meet minimum alignment criteria on this assembly.", acc);
return;
}
htmlHorizontalLine();
printf("%s/Genomic Alignments
", type);
if (startsWith("mrnaBlastz",tdb->table))
slSort(&pslList, pslCmpScoreDesc);
printAlignments(pslList, start, "htcCdnaAli", table, acc);
printTrackHtml(tdb);
hFreeConn(&conn);
}
void printPslFormat(struct sqlConnection *conn, struct trackDb *tdb, char *item, int start,
char *subType)
/* Handles click in affyU95 or affyU133 tracks */
{
struct psl *pslList = getAlignments(conn, tdb->table, item);
struct psl *psl;
char *face = "Times"; /* specifies font face to use */
char *fsize = "+1"; /* specifies font size */
/* check if there is an alignment available for this sequence. This checks
* both genbank sequences and other sequences in the seq table. If so,
* set it up so they can click through to the alignment. */
if (hGenBankHaveSeq(database, item, NULL))
{
printf("%s/Genomic Alignments
", item);
printAlignments(pslList, start, "htcCdnaAli", tdb->table, item);
}
else
{
/* print out the psls */
printf("");
printf("\n", face, fsize);
for (psl = pslList; psl != NULL; psl = psl->next)
{
pslOutFormat(psl, stdout, '\n', '\n');
}
printf("
\n");
}
pslFreeList(&pslList);
}
void doAffy(struct trackDb *tdb, char *item, char *itemForUrl)
/* Display information for Affy tracks*/
{
char *dupe, *type, *words[16];
char *orthoTable = trackDbSetting(tdb, "orthoTable");
char *otherDb = trackDbSetting(tdb, "otherDb");
int wordCount;
int start = cartInt(cart, "o");
char query[256];
char **row;
struct sqlResult *sr = NULL;
struct sqlConnection *conn = hAllocConn(database);
struct sqlConnection *conn2 = hAllocConn(database);
if (itemForUrl == NULL)
itemForUrl = item;
dupe = cloneString(tdb->type);
genericHeader(tdb, item);
wordCount = chopLine(dupe, words);
printCustomUrl(tdb, itemForUrl, item == itemForUrl);
/* If this is the affyZebrafish track, check for human ortholog information */
if (sameString("affyZebrafish", tdb->table))
{
if (orthoTable != NULL && hTableExists(database, orthoTable))
{
sqlSafef(query, sizeof(query), "select geneSymbol, description from %s where name = '%s' ", orthoTable, item);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
if (row != NULL)
{
printf("
\n\n");
printf("Human %s Ortholog: | %s |
\n", otherDb, row[0]);
printf("Ortholog Description: | %s |
\n",row[1]);
printf("
\n");
}
}
}
if (wordCount > 0)
{
type = words[0];
if (sameString(type, "psl"))
{
char *subType = ".";
if (wordCount > 1)
subType = words[1];
printPslFormat(conn2, tdb, item, start, subType);
}
}
printTrackHtml(tdb);
freez(&dupe);
hFreeConn(&conn);
hFreeConn(&conn2);
}
void doZfishRHmap(struct trackDb *tdb, char *itemName)
/* Put up Radiation Hybrid map information for Zebrafish */
{
char *dupe, *type, *words[16];
char query[256];
struct sqlResult *sr = NULL;
char **row = NULL;
struct rhMapZfishInfo *rhInfo = NULL;
int wordCount;
int start = cartInt(cart, "o");
struct sqlConnection *conn = hAllocConn(database);
struct sqlConnection *conn1 = hAllocConn(database);
boolean rhMapInfoExists = sqlTableExists(conn, "rhMapZfishInfo");
dupe = cloneString(tdb->type);
wordCount = chopLine(dupe, words);
genericHeader(tdb, itemName);
/* Print out RH map information if available */
if (rhMapInfoExists)
{
sqlSafef(query, sizeof query, "SELECT * FROM rhMapZfishInfo WHERE name = '%s'", itemName);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
if (row != NULL)
{
rhInfo = rhMapZfishInfoLoad(row);
if (rhInfo != NULL)
{
printf("Information on %s
\n", itemName);
if (!sameString(rhInfo->zfinId, ""))
{
printf("");
printCustomUrl(tdb, rhInfo->zfinId, TRUE);
printf("
\n");
}
printf("
\n\n");
printf("Linkage group: | %s |
\n", rhInfo->linkageGp);
printf("Position on linkage group: | %d |
\n", rhInfo->position);
printf("Distance (cR): | %d |
\n", rhInfo->distance);
printf("Marker type: | %s |
\n", rhInfo->markerType);
printf("Marker source: | %s |
\n", rhInfo->source);
printf("Mapping institution: | %s |
\n", rhInfo->mapSite);
printf("Forward Primer: | %s |
\n", rhInfo->leftPrimer);
printf("Reverse Primer: | %s |
\n", rhInfo->rightPrimer);
printf("
\n");
}
}
}
dupe = cloneString(tdb->type);
wordCount = chopLine(dupe, words);
if (wordCount > 0)
{
type = words[0];
if (sameString(type, "psl"))
{
char *subType = ".";
if (wordCount > 1)
subType = words[1];
printPslFormat(conn1, tdb, itemName, start, subType);
}
}
printTrackHtml(tdb);
freez(&dupe);
hFreeConn(&conn);
hFreeConn(&conn1);
}
void doRikenRna(struct trackDb *tdb, char *item)
/* Put up Riken RNA stuff. */
{
char query[512];
struct sqlResult *sr;
char **row;
struct sqlConnection *conn = sqlConnect("mgsc");
genericHeader(tdb, item);
sqlSafef(query, sizeof query, "select * from rikenMrna where qName = '%s'", item);
sr = sqlGetResult(conn, query);
printf("\n");
printf("#match\tmisMatches\trepMatches\tnCount\tqNumInsert\tqBaseInsert\ttNumInsert\tBaseInsert\tstrand\tqName\tqSize\tqStart\tqEnd\ttName\ttSize\ttStart\ttEnd\tblockCount\tblockSizes\tqStarts\ttStarts\n");
while ((row = sqlNextRow(sr)) != NULL)
{
struct psl *psl = pslLoad(row+1);
pslTabOut(psl, stdout);
}
printf("
\n");
sqlDisconnect(&conn);
printTrackHtml(tdb);
}
void doYaleTars(struct trackDb *tdb, char *item, char *itemForUrl)
/* Display information for Affy tracks*/
{
char *dupe, *type, *words[16], *chrom = NULL, *strand = NULL;
char *item2 = NULL;
int wordCount, end = 0;
int start = cartInt(cart, "o");
char query[256];
char **row;
struct sqlResult *sr = NULL;
struct sqlConnection *conn = hAllocConn(database);
struct sqlConnection *conn2 = hAllocConn(database);
if (itemForUrl == NULL)
{
if (startsWith("TAR", item))
{
/* Remove TAR prefix from item */
item2 = strchr(item, 'R');
item2++;
itemForUrl = item2;
}
else
itemForUrl = item;
}
dupe = cloneString(tdb->type);
genericHeader(tdb, item);
wordCount = chopLine(dupe, words);
printCustomUrl(tdb, itemForUrl, item == itemForUrl);
sqlSafef(query, sizeof(query), "select tName, tEnd, strand from %s where qName='%s' and tStart=%d;", tdb->table, item, start);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
/* load PSL into struct */
if (row != NULL)
{
chrom = cloneString(row[0]);
end = sqlUnsigned(row[1]);
strand = cloneString(row[2]);
}
printPos(chrom, start, end, strand, TRUE, item);
if (wordCount > 0)
{
type = words[0];
if (sameString(type, "psl"))
{
char *subType = ".";
if (wordCount > 1)
subType = words[1];
printPslFormat(conn2, tdb, item, start, subType);
}
}
printTrackHtml(tdb);
freez(&dupe);
hFreeConn(&conn);
hFreeConn(&conn2);
}
void printPcrTargetMatch(struct targetDb *target, struct psl *tpsl,
boolean mustGetItem)
/* Show the non-genomic target PCR result and its genomic mapping. */
{
char *acc = pcrResultItemAccession(tpsl->tName);
char *name = pcrResultItemName(tpsl->tName);
char niceName[256];
if (name == NULL || sameString(acc, name))
safecpy(niceName, sizeof(niceName), acc);
else
safef(niceName, sizeof(niceName), "%s (%s)", name, acc);
printf("Position in %s: %s"
":%d-%d
\n",
target->description, hgTracksName(), cartSidUrlString(cart), database,
acc, niceName, tpsl->tStart+1, tpsl->tEnd);
printf("Size in %s: %d
\n", niceName,
tpsl->tEnd - tpsl->tStart);
if (tpsl->strand[0] == '-')
printf(" "
"Warning: the match is on the reverse strand of %s
\n",
niceName);
struct psl *itemPsl = NULL, *otherPsls = NULL, *gpsl;
int itemStart = cartInt(cart, "o");
int itemEnd = cartInt(cart, "t");
int rowOffset = hOffsetPastBin(database, seqName, target->pslTable);
struct sqlConnection *conn = hAllocConn(database);
struct sqlResult *sr;
char **row;
char query[2048];
sqlSafef(query, sizeof(query), "select * from %s where qName = '%s'",
target->pslTable, acc);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
gpsl = pslLoad(row+rowOffset);
struct psl *pslTrimmed = pslTrimToQueryRange(gpsl, tpsl->tStart,
tpsl->tEnd);
if (sameString(gpsl->tName, seqName) &&
((gpsl->tStart == itemStart && gpsl->tEnd == itemEnd) ||
(pslTrimmed->tStart == itemStart && pslTrimmed->tEnd == itemEnd)))
itemPsl = pslTrimmed;
else
slAddHead(&otherPsls, pslTrimmed);
pslFree(&gpsl);
}
hFreeConn(&conn);
if (mustGetItem && itemPsl == NULL)
errAbort("Did not find record for amplicon in %s at %s:%d-%d",
niceName, seqName, itemStart, itemEnd);
char strand[2];
strand[1] = '\0';
if (itemPsl != NULL)
{
if (itemPsl->strand[1] == '\0')
strand[0] = itemPsl->strand[0];
else if (itemPsl->strand[0] != itemPsl->strand[1])
strand[0] = '-';
else
strand[0] = '+';
if (itemPsl != NULL)
printPosOnChrom(itemPsl->tName, itemPsl->tStart, itemPsl->tEnd,
strand, FALSE, tpsl->tName);
}
slSort(&otherPsls, pslCmpTarget);
if (itemPsl != NULL && otherPsls != NULL)
printf("Other matches in genomic alignments of %s:
\n",
niceName);
for (gpsl = otherPsls; gpsl != NULL; gpsl = gpsl->next)
{
if (gpsl->strand[1] == '\0')
strand[0] = gpsl->strand[0];
else if (gpsl->strand[0] != gpsl->strand[1])
strand[0] = '-';
else
strand[0] = '+';
printPosOnChrom(gpsl->tName, gpsl->tStart, gpsl->tEnd, strand, FALSE,
tpsl->tName);
}
pslFree(&itemPsl);
pslFreeList(&otherPsls);
}
static void upperMatch(char *dna, char *primer, int size)
/* Uppercase DNA where it matches primer. -- copied from gfPcrLib.c. */
{
int i;
for (i=0; itEnd - psl->tStart;
char *ffPrimer = cloneString(fPrimer);
char *rrPrimer = cloneString(rPrimer);
int rPrimerSize = strlen(rPrimer);
struct dnaSeq *seq;
if (target != NULL)
{
/* Use seq+extFile if specified; otherwise just retrieve from seqFile. */
if (isNotEmpty(target->seqTable) && isNotEmpty(target->extFileTable))
{
struct sqlConnection *conn = hAllocConn(database);
seq = hDnaSeqGet(database, psl->tName, target->seqTable,
target->extFileTable);
hFreeConn(&conn);
char *dna = cloneStringZ(seq->dna + psl->tStart, productSize);
freeMem(seq->dna);
seq->dna = dna;
}
else
{
struct twoBitFile *tbf = twoBitOpen(target->seqFile);
seq = twoBitReadSeqFrag(tbf, psl->tName, psl->tStart,
psl->tEnd);
twoBitClose(&tbf);
}
}
else
seq = hChromSeq(database, psl->tName, psl->tStart, psl->tEnd);
char *dna = seq->dna;
tolowers(dna);
if (psl->strand[0] == '-')
reverseComplement(dna, productSize);
printf("");
/* The rest of this is loosely copied from gfPcrLib.c:outputFa(): */
char *tNameForPos = (target != NULL ? pcrResultItemAccession(psl->tName) : psl->tName);
printf(">tStart+1, psl->tEnd);
printf("\">%s:%d%c%d %dbp %s %s\n",
psl->tName, psl->tStart+1, psl->strand[0], psl->tEnd,
productSize, fPrimer, rPrimer);
/* Flip reverse primer to be in same direction and case as sequence, to
* compare with sequence: */
reverseComplement(rrPrimer, rPrimerSize);
tolowers(rrPrimer);
tolowers(ffPrimer);
/* Capitalize where sequence and primer match, and write out sequence. */
upperMatch(dna, ffPrimer, strlen(ffPrimer));
upperMatch(dna + productSize - rPrimerSize, rrPrimer, rPrimerSize);
faWriteNext(stdout, NULL, dna, productSize);
printf("
");
}
void doPcrResult(char *track, char *item)
/* Process click on PCR of user's primers. */
{
struct trackDb *tdb = pcrResultFakeTdb();
char *pslFileName, *primerFileName;
struct targetDb *target;
cartWebStart(cart, database, "PCR Results");
if (! pcrResultParseCart(database, cart, &pslFileName, &primerFileName, &target))
errAbort("PCR Result track has disappeared!");
char *fPrimer, *rPrimer;
pcrResultGetPrimers(primerFileName, &fPrimer, &rPrimer);
printf("PCR Results (%s %s)
\n", fPrimer, rPrimer);
printf("Forward primer: 5' %s 3'
\n", fPrimer);
printf("Reverse primer: 5' %s 3'
\n", rPrimer);
if (target != NULL)
printf("Search target: %s
\n", target->description);
struct psl *itemPsl = NULL, *otherPsls = NULL, *psl;
if (target != NULL)
{
/* item (from hgTracks) is |-separated: target sequence name,
* amplicon start offset in target sequence, and amplicon end offset. */
char *words[3];
int wordCount = chopByChar(cloneString(item), '|', words, ArraySize(words));
if (wordCount != 3)
errAbort("doPcrResult: expected 3 |-sep'd words but got '%s'", item);
char *targetSeqName = words[0];
if (endsWith(targetSeqName, "__"))
targetSeqName[strlen(targetSeqName)-2] = '\0';
int ampStart = atoi(words[1]), ampEnd = atoi(words[2]);
pcrResultGetPsl(pslFileName, target, targetSeqName, seqName, ampStart, ampEnd,
&itemPsl, &otherPsls);
printPcrTargetMatch(target, itemPsl, TRUE);
}
else
{
pcrResultGetPsl(pslFileName, target, item,
seqName, cartInt(cart, "o"), cartInt(cart, "t"),
&itemPsl, &otherPsls);
printPosOnChrom(itemPsl->tName, itemPsl->tStart, itemPsl->tEnd,
itemPsl->strand, FALSE, NULL);
}
if (otherPsls != NULL)
{
puts("
");
printf("Other matches for these primers:
\n");
for (psl = otherPsls; psl != NULL; psl = psl->next)
{
puts("
");
if (target != NULL)
printPcrTargetMatch(target, psl, FALSE);
else
printPosOnChrom(psl->tName, psl->tStart, psl->tEnd,
psl->strand, FALSE, NULL);
}
puts("
");
}
printPcrSequence(target, itemPsl, fPrimer, rPrimer);
puts("
");
printTrackHtml(tdb);
}
void doUserPsl(char *track, char *item)
/* Process click on user-defined alignment. */
{
int start = cartInt(cart, "o");
struct lineFile *lf;
struct psl *pslList = NULL, *psl;
char *pslName, *faName, *qName;
enum gfType qt, tt;
cartWebStart(cart, database, "BLAT Search Alignments");
printf("BLAT Search Alignments
\n");
printf("Click on a line to see detailed letter-by-letter display
");
parseSs(item, &pslName, &faName, &qName);
pslxFileOpen(pslName, &qt, &tt, &lf);
while ((psl = pslNext(lf)) != NULL)
{
if (sameString(psl->qName, qName))
{
slAddHead(&pslList, psl);
}
else
{
pslFree(&psl);
}
}
slSort(&pslList, pslCmpScore);
lineFileClose(&lf);
printAlignments(pslList, start, "htcUserAli", "user", item);
pslFreeList(&pslList);
webIncludeHelpFile(USER_PSL_TRACK_NAME, TRUE);
}
void doHgGold(struct trackDb *tdb, char *fragName)
/* Click on a fragment of golden path. */
{
struct sqlConnection *conn = hAllocConn(database);
struct sqlConnection *conn2 = hAllocConn(database);
struct sqlConnection *conn3 = hAllocConn(database);
char query[256];
struct sqlResult *sr;
char **row;
char query2[256];
struct sqlResult *sr2;
char **row2;
char query3[256];
struct sqlResult *sr3;
char **row3;
struct agpFrag frag;
struct contigAcc contigAcc;
int start = cartInt(cart, "o");
boolean hasBin;
char splitTable[HDB_MAX_TABLE_STRING];
char *chp;
char *accession1, *accession2, *spanner, *variation, *varEvidence,
*contact, *remark, *comment;
// char *evaluation; unused variable
char *secondAcc, *secondAccVer;
char *tmpString;
int first;
cartWebStart(cart, database, "%s", fragName);
if (!hFindSplitTable(database, seqName, tdb->table, splitTable, sizeof splitTable, &hasBin))
errAbort("doHgGold track %s not found", tdb->table);
sqlSafef(query, sizeof query, "select * from %s where frag = '%s' and chromStart = %d",
splitTable, fragName, start);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
agpFragStaticLoad(row+hasBin, &frag);
printf("Entrez nucleotide: %s
\n", fragName, fragName);
printf("Clone Fragment ID: %s
\n", frag.frag);
printf("Clone Fragment Type: %s
\n", frag.type);
printf("Clone Bases: %d-%d
\n", frag.fragStart+1, frag.fragEnd);
if (hTableExists(database, "contigAcc"))
{
sqlSafef(query2, sizeof query2, "select * from contigAcc where contig = '%s'", frag.frag);
if ((sr2 = sqlGetResult(conn2, query2)))
{
row = sqlNextRow(sr2);
if (row)
{
contigAccStaticLoad(row, &contigAcc);
printf("Genbank Accession: %s
\n", contigAcc.acc);
}
sqlFreeResult(&sr2);
}
}
printPos(frag.chrom, frag.chromStart, frag.chromEnd, frag.strand, FALSE, NULL);
if (hTableExists(database, "certificate"))
{
first = 1;
again:
tmpString = cloneString(frag.frag);
chp = strstr(tmpString, ".");
if (chp != NULL) *chp = '\0';
if (first)
{
sqlSafef(query2, sizeof query2, "select * from certificate where accession1='%s';", tmpString);
}
else
{
sqlSafef(query2, sizeof query2, "select * from certificate where accession2='%s';", tmpString);
}
sr2 = sqlMustGetResult(conn2, query2);
row2 = sqlNextRow(sr2);
while (row2 != NULL)
{
printf("
");
accession1 = row2[0];
accession2 = row2[1];
spanner = row2[2];
// evaluation = row2[3]; unused variable
variation = row2[4];
varEvidence = row2[5];
contact = row2[6];
remark = row2[7];
comment = row2[8];
if (first)
{
secondAcc = accession2;
}
else
{
secondAcc = accession1;
}
sqlSafef(query3, sizeof query3, "select frag from %s where frag like '%s.%c';",
splitTable, secondAcc, '%');
sr3 = sqlMustGetResult(conn3, query3);
row3 = sqlNextRow(sr3);
if (row3 != NULL)
{
secondAccVer = row3[0];
}
else
{
secondAccVer = secondAcc;
}
printf("Non-standard Join Certificate:
\n");
printf("The join between %s and %s is not standard due to a ", frag.frag, secondAccVer);
printf("sub-optimal sequence alignment between the overlapping regions of the ");
printf("clones. The following details are provided by the ");
printf("sequencing center to support the joining of these two clones:
");
printf("Joined with Fragment: %s
\n", secondAccVer);
if (strcmp(spanner, "") != 0) printf("Spanner: %s
\n", spanner);
/* if (strcmp(evaluation, "") != 0) printf("Evaluation: %s
\n", evaluation); */
if (strcmp(variation, "") != 0) printf("Variation: %s
\n", variation);
if (strcmp(varEvidence, "")!= 0) printf("Variation Evidence: %s
\n", varEvidence);
if (strcmp(remark, "") != 0) printf("Remark: %s
\n", remark);
if (strcmp(comment, "") != 0) printf("Comment: %s
\n", comment);
if (strcmp(contact, "") != 0)
printf("Contact: %s
", contact, contact);
sqlFreeResult(&sr3);
row2 = sqlNextRow(sr2);
}
sqlFreeResult(&sr2);
if (first)
{
first = 0;
goto again;
}
}
sqlFreeResult(&sr);
hFreeConn(&conn);
hFreeConn(&conn2);
hFreeConn(&conn3);
printTrackHtml(tdb);
}
void doHgGap(struct trackDb *tdb, char *gapType)
/* Print a teeny bit of info about a gap. */
{
struct sqlConnection *conn = hAllocConn(database);
char query[256];
struct sqlResult *sr;
char **row;
struct agpGap gap;
int start = cartInt(cart, "o");
boolean hasBin;
char splitTable[HDB_MAX_TABLE_STRING];
cartWebStart(cart, database, "Gap in Sequence");
if (!hFindSplitTable(database, seqName, tdb->table, splitTable, sizeof splitTable, &hasBin))
errAbort("doHgGap track %s not found", tdb->table);
if (sameString(tdb->table, splitTable))
sqlSafef(query, sizeof(query), "select * from %s where chrom = '%s' and "
"chromStart = %d",
splitTable, seqName, start);
else
sqlSafef(query, sizeof(query), "select * from %s where chromStart = %d",
splitTable, start);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
if (row == NULL)
errAbort("Couldn't find gap at %s:%d", seqName, start);
agpGapStaticLoad(row+hasBin, &gap);
printf("Gap Type: %s
\n", gap.type);
printf("Bridged: %s
\n", gap.bridge);
printPos(gap.chrom, gap.chromStart, gap.chromEnd, NULL, FALSE, NULL);
printTrackHtml(tdb);
sqlFreeResult(&sr);
hFreeConn(&conn);
}
void selectOneRow(struct sqlConnection *conn, char *table, char *query,
struct sqlResult **retSr, char ***retRow)
/* Do query and return one row offset by bin as needed. */
{
char fullTable[HDB_MAX_TABLE_STRING];
boolean hasBin;
char **row;
if (!hFindSplitTable(database, seqName, table, fullTable, sizeof fullTable, &hasBin))
errAbort("Table %s doesn't exist in database", table);
*retSr = sqlGetResult(conn, query);
if ((row = sqlNextRow(*retSr)) == NULL)
errAbort("No match to query '%s'", query);
*retRow = row + hasBin;
}
void doHgContig(struct trackDb *tdb, char *ctgName)
/* Click on a contig. */
{
struct sqlConnection *conn = hAllocConn(database);
struct sqlConnection *conn2 = hAllocConn(database);
char query[256], query2[256], ctgUrl[256];
struct sqlResult *sr, *sr2;
char **row;
struct ctgPos *ctg;
struct ctgPos2 *ctg2 = NULL;
int cloneCount;
struct contigAcc contigAcc;
char *ncbiTerm = cgiEncode(ctgName);
safef(ctgUrl, sizeof(ctgUrl), "%s%s", NUCCORE_SEARCH, ncbiTerm);
genericHeader(tdb, ctgName);
char *url = tdb->url;
if (sameWord(database,"oryCun2"))
printf("Name: %s
\n", ctgName);
else if (isNotEmpty(url))
{
if (sameWord(url, "none"))
printf("Name: %s
\n", ctgName);
else
printCustomUrl(tdb, ctgName, TRUE);
}
else
printf("Name: %s
\n",
ctgUrl, ctgName);
freeMem(ncbiTerm);
sqlSafef(query, sizeof(query), "select * from %s where contig = '%s'",
tdb->table, ctgName);
selectOneRow(conn, tdb->table, query, &sr, &row);
if (sameString("ctgPos2", tdb->table))
{
ctg2 = ctgPos2Load(row);
printf("Type: %s
\n", ctg2->type);
ctg = (struct ctgPos*)ctg2;
}
else
ctg = ctgPosLoad(row);
sqlFreeResult(&sr);
if (hTableExists(database, "contigAcc"))
{
sqlSafef(query2, sizeof query2, "select * from contigAcc where contig = '%s'", ctgName);
if ((sr2 = sqlGetResult(conn2, query2)))
{
row = sqlNextRow(sr2);
if (row)
{
contigAccStaticLoad(row, &contigAcc);
printf("Genbank Accession: %s
\n", contigAcc.acc);
}
sqlFreeResult(&sr2);
}
}
if (hTableExists(database, "clonePos"))
{
sqlSafef(query, sizeof query, "select count(*) from clonePos"
" where chrom = '%s' and chromEnd >= %d and chromStart <= %d",
ctg->chrom, ctg->chromStart, ctg->chromEnd);
cloneCount = sqlQuickNum(conn, query);
printf("Total Clones: %d
\n", cloneCount);
}
printPos(ctg->chrom, ctg->chromStart, ctg->chromEnd, NULL, TRUE, ctg->contig);
printTrackHtml(tdb);
hFreeConn(&conn);
hFreeConn(&conn2);
}
char *cloneStageName(char *stage)
/* Expand P/D/F. */
{
switch (stage[0])
{
case 'P':
return "predraft (less than 4x coverage shotgun)";
case 'D':
return "draft (at least 4x coverage shotgun)";
case 'F':
return "finished";
default:
return "unknown";
}
}
void doHgCover(struct trackDb *tdb, char *cloneName)
/* Respond to click on clone. */
{
struct sqlConnection *conn = hAllocConn(database);
char query[256];
struct sqlResult *sr;
char **row;
struct clonePos *clone;
int fragCount;
cartWebStart(cart, database, "%s", cloneName);
sqlSafef(query, sizeof query, "select * from %s where name = '%s'", tdb->table, cloneName);
selectOneRow(conn, tdb->table, query, &sr, &row);
clone = clonePosLoad(row);
sqlFreeResult(&sr);
sqlSafef(query, sizeof query,
"select count(*) from %s_gl where end >= %d and start <= %d and frag like '%s%%'",
clone->chrom, clone->chromStart, clone->chromEnd, clone->name);
fragCount = sqlQuickNum(conn, query);
printf("Information on %s
\n", cloneName);
printf("GenBank: %s
\n", cloneName);
printf("Status: %s
\n", cloneStageName(clone->stage));
printf("Fragments: %d
\n", fragCount);
printf("Size: %d bases
\n", clone->seqSize);
printf("Chromosome: %s
\n", skipChr(clone->chrom));
printf("
\n");
hFreeConn(&conn);
printTrackHtml(tdb);
}
void doHgClone(struct trackDb *tdb, char *fragName)
/* Handle click on a clone. */
{
char cloneName[128];
fragToCloneVerName(fragName, cloneName);
doHgCover(tdb, cloneName);
}
void doBactigPos(struct trackDb *tdb, char *bactigName)
/* Click on a bactig. */
{
struct bactigPos *bactig;
struct sqlConnection *conn = hAllocConn(database);
struct sqlResult *sr;
char **row;
char query[256];
char goldTable[16];
char ctgStartStr[16];
int ctgStart;
genericHeader(tdb, bactigName);
sqlSafef(query, sizeof query, "select * from %s where name = '%s'", tdb->table, bactigName);
selectOneRow(conn, tdb->table, query, &sr, &row);
bactig = bactigPosLoad(row);
sqlFreeResult(&sr);
printf("Name: %s
\n", bactigName);
snprintf(goldTable, sizeof(goldTable), "%s_gold", seqName);
puts("First contig:");
if (hTableExists(database, goldTable))
{
sqlSafef(query, sizeof(query),
"select chromStart from %s where frag = \"%s\"",
goldTable, bactig->startContig);
ctgStart = sqlQuickNum(conn, query);
snprintf(ctgStartStr, sizeof(ctgStartStr), "%d", ctgStart);
hgcAnchor("gold", bactig->startContig, ctgStartStr);
}
printf("%s
\n", bactig->startContig);
puts("Last contig:");
if (hTableExists(database, goldTable))
{
sqlSafef(query, sizeof(query),
"select chromStart from %s where frag = \"%s\"",
goldTable, bactig->endContig);
ctgStart = sqlQuickNum(conn, query);
snprintf(ctgStartStr, sizeof(ctgStartStr), "%d", ctgStart);
hgcAnchor("gold", bactig->endContig, ctgStartStr);
}
printf("%s
\n", bactig->endContig);
printPos(bactig->chrom, bactig->chromStart, bactig->chromEnd, NULL, FALSE,NULL);
printTrackHtml(tdb);
hFreeConn(&conn);
}
int showGfAlignment(struct psl *psl, bioSeq *qSeq, FILE *f,
enum gfType qType, int qStart, int qEnd, char *qName)
/* Show protein/DNA alignment or translated DNA alignment. */
{
int blockCount;
int tStart = psl->tStart;
int tEnd = psl->tEnd;
char tName[256];
struct dnaSeq *tSeq;
/* protein psl's have a tEnd that isn't quite right */
if ((psl->strand[1] == '+') && (qType == gftProt))
tEnd = psl->tStarts[psl->blockCount - 1] + psl->blockSizes[psl->blockCount - 1] * 3;
tSeq = hDnaFromSeq(database, seqName, tStart, tEnd, dnaLower);
freez(&tSeq->name);
tSeq->name = cloneString(psl->tName);
safef(tName, sizeof(tName), "%s.%s", organism, psl->tName);
if (qName == NULL)
fprintf(f, "Alignment of %s and %s:%d-%d
\n",
psl->qName, psl->tName, psl->tStart+1, psl->tEnd);
else
fprintf(f, "Alignment of %s and %s:%d-%d
\n",
qName, psl->tName, psl->tStart+1, psl->tEnd);
fputs("Click on links in the frame to the left to navigate through "
"the alignment.\n", f);
blockCount = pslShowAlignment(psl, qType == gftProt,
qName, qSeq, qStart, qEnd,
tName, tSeq, tStart, tEnd, f);
freeDnaSeq(&tSeq);
return blockCount;
}
struct ffAli *pslToFfAliAndSequence(struct psl *psl, struct dnaSeq *qSeq,
boolean *retIsRc, struct dnaSeq **retSeq,
int *retTStart)
/* Given psl, dig up target sequence and convert to ffAli.
* Note: if strand is -, this does a pslRc to psl! */
{
int tStart, tEnd, tRcAdjustedStart;
struct dnaSeq *dnaSeq;
tStart = psl->tStart - 100;
if (tStart < 0) tStart = 0;
if (retTStart)
*retTStart = tStart;
tEnd = psl->tEnd + 100;
if (tEnd > psl->tSize) tEnd = psl->tSize;
dnaSeq = hDnaFromSeq(database, seqName, tStart, tEnd, dnaLower);
freez(&dnaSeq->name);
dnaSeq->name = cloneString(psl->tName);
if (retSeq)
*retSeq = dnaSeq;
tRcAdjustedStart = tStart;
if (psl->strand[1] == '-')
pslRc(psl);
if (psl->strand[0] == '-')
{
if (retIsRc)
*retIsRc = TRUE;
reverseComplement(dnaSeq->dna, dnaSeq->size);
pslRc(psl);
tRcAdjustedStart = psl->tSize - tEnd;
}
return pslToFfAli(psl, qSeq, dnaSeq, tRcAdjustedStart);
}
int showPartialDnaAlignment(struct psl *wholePsl,
struct dnaSeq *rnaSeq, FILE *body,
int cdsS, int cdsE, boolean restrictToWindow)
/* Show (part of) alignment for accession. wholePsl is the whole alignment;
* if restrictToWindow then display the part of the alignment in the current
* browser window. */
{
struct dnaSeq *dnaSeq;
int wholeTStart;
int partTStart = wholePsl->tStart, partTEnd = wholePsl->tEnd;
DNA *rna;
int rnaSize;
boolean isRc = FALSE;
struct ffAli *wholeFfAli;
int blockCount;
/* Get RNA sequence and convert psl to ffAli. */
rna = rnaSeq->dna;
rnaSize = rnaSeq->size;
/* Don't forget -- this may change wholePsl! */
wholeFfAli = pslToFfAliAndSequence(wholePsl, rnaSeq, &isRc, &dnaSeq,
&wholeTStart);
if (restrictToWindow)
{
partTStart = max(wholePsl->tStart, winStart);
partTEnd = min(wholePsl->tEnd, winEnd);
}
/* Write body heading info. */
fprintf(body, "Alignment of %s and %s:%d-%d
\n",
wholePsl->qName, wholePsl->tName, partTStart+1, partTEnd);
fprintf(body, "Click on links in the frame to the left to navigate through "
"the alignment.\n");
if (rnaSize != wholePsl->qSize)
{
fprintf(body, "Cannot display alignment. Size of rna %s is %d has changed since alignment was performed when it was %d.\n",
wholePsl->qName, rnaSize, wholePsl->qSize);
return 0;
}
blockCount = ffShAliPart(body, wholeFfAli, wholePsl->qName,
rna, rnaSize, 0,
dnaSeq->name, dnaSeq->dna, dnaSeq->size,
wholeTStart, 8, FALSE, isRc,
FALSE, TRUE, TRUE, TRUE, TRUE,
cdsS, cdsE, partTStart, partTEnd);
return blockCount;
}
void showSomeAlignment(struct psl *psl, bioSeq *oSeq,
enum gfType qType, int qStart, int qEnd,
char *qName, int cdsS, int cdsE)
/* Display protein or DNA alignment in a frame. */
{
int blockCount, i;
struct tempName indexTn, bodyTn;
FILE *index, *body;
trashDirFile(&indexTn, "index", "index", ".html");
trashDirFile(&bodyTn, "body", "body", ".html");
/* Writing body of alignment. */
body = mustOpen(bodyTn.forCgi, "w");
htmStartDirDepth(body, psl->qName, 2);
if (qType == gftRna || qType == gftDna)
blockCount = showPartialDnaAlignment(psl, oSeq, body, cdsS, cdsE, FALSE);
else
blockCount = showGfAlignment(psl, oSeq, body, qType, qStart, qEnd, qName);
htmEnd(body);
fclose(body);
chmod(bodyTn.forCgi, 0666);
/* Write index. */
index = mustOpen(indexTn.forCgi, "w");
if (qName == NULL)
qName = psl->qName;
htmStartDirDepth(index, qName, 2);
fprintf(index, "Alignment of %s
", qName);
fprintf(index, "%s
\n", bodyTn.forCgi, qName);
fprintf(index, "%s.%s
\n", bodyTn.forCgi, hOrganism(database), psl->tName);
for (i=1; i<=blockCount; ++i)
{
fprintf(index, "block%d
\n",
bodyTn.forCgi, i, i);
}
fprintf(index, "together
\n", bodyTn.forCgi);
htmEnd(index);
fclose(index);
chmod(indexTn.forCgi, 0666);
/* Write (to stdout) the main html page containing just the frame info. */
puts("");
puts("\n");
exit(0); /* Avoid cartHtmlEnd. */
}
void showSomePartialDnaAlignment(struct psl *partPsl, struct psl *wholePsl,
bioSeq *oSeq, char *qName, int cdsS, int cdsE)
/* Display protein or DNA alignment in a frame. */
{
int blockCount, i;
struct tempName indexTn, bodyTn;
FILE *index, *body;
trashDirFile(&indexTn, "index", "index", ".html");
trashDirFile(&bodyTn, "body", "body", ".html");
/* Writing body of alignment. */
body = mustOpen(bodyTn.forCgi, "w");
htmStartDirDepth(body, partPsl->qName, 2);
blockCount = showPartialDnaAlignment(wholePsl, oSeq, body, cdsS, cdsE, TRUE);
htmEnd(body);
fclose(body);
chmod(bodyTn.forCgi, 0666);
/* Write index. */
index = mustOpen(indexTn.forCgi, "w");
if (qName == NULL)
qName = partPsl->qName;
htmStartDirDepth(index, qName, 2);
fprintf(index, "Alignment of %s
", qName);
fprintf(index, "%s
\n", bodyTn.forCgi, qName);
if (partPsl != wholePsl)
fprintf(index, "%s in browser window
\n", bodyTn.forCgi, qName);
fprintf(index, "%s.%s
\n", bodyTn.forCgi, hOrganism(database), partPsl->tName);
for (i=1; i<=blockCount; ++i)
{
fprintf(index, "block%d
\n",
bodyTn.forCgi, i, i);
}
fprintf(index, "together
\n", bodyTn.forCgi);
htmEnd(index);
fclose(index);
chmod(indexTn.forCgi, 0666);
/* Write (to stdout) the main html page containing just the frame info. */
if (partPsl != wholePsl)
printf("