cfa97200252eecb2b8dfe20d9d65cd5afd0f3ba3
max
Thu May 28 02:37:57 2020 -0700
more OMIM hgc changes, refs #18419
diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c
index 460a48e..32ee090 100644
--- src/hg/hgc/hgc.c
+++ src/hg/hgc/hgc.c
@@ -1,26851 +1,26843 @@
/* 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
}
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 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);
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("