/* @source dottup application ** ** Dotplot of two sequences ** ** @author Copyright (C) Ian Longden ** @modified: Alan Bleasby. Added non-proportional plot ** @@ ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License ** as published by the Free Software Foundation; either version 2 ** of the License, or (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ******************************************************************************/ #include "emboss.h" static void dottup_drawPlotlines(void *x, void *cl); static void dottup_plotMatches(const AjPList list); static void dottup_stretchplot(AjPGraph graph, const AjPList matchlist, const AjPSeq seq1, const AjPSeq seq2, ajint begin1, ajint begin2, ajint end1, ajint end2); static PLFLT offset1; static PLFLT offset2; /* @prog dottup *************************************************************** ** ** Displays a wordmatch dotplot of two sequences ** ******************************************************************************/ int main(int argc, char **argv) { AjPSeq seq1; AjPSeq seq2; ajint wordlen; AjPTable seq1MatchTable = 0; AjPList matchlist = NULL; AjPGraph graph = NULL; AjPGraph xygraph = NULL; AjBool boxit; /* ** Different ticks as they need to be different for x and y due to ** length of string being important on x */ ajuint acceptableticksx[]= { 1,10,50,100,500,1000,1500,10000, 500000,1000000,5000000 }; ajuint acceptableticks[]= { 1,10,50,100,200,500,1000,2000,5000,10000,15000, 500000,1000000,5000000 }; ajint numbofticks = 10; float xmargin; float ymargin; float ticklen; float tickgap; float onefifth = 0.0; ajint i; float k; float max; char ptr[10]; ajint begin1; ajint begin2; ajint end1; ajint end2; ajuint len1; ajuint len2; float fbegin1; float fbegin2; float fend1; float fend2; float flen1; float flen2; AjBool stretch; embInit("dottup", argc, argv); wordlen = ajAcdGetInt("wordsize"); seq1 = ajAcdGetSeq("asequence"); seq2 = ajAcdGetSeq("bsequence"); graph = ajAcdGetGraph("graph"); boxit = ajAcdGetBoolean("boxit"); stretch = ajAcdGetToggle("stretch"); xygraph = ajAcdGetGraphxy("xygraph"); begin1 = ajSeqGetBegin(seq1); begin2 = ajSeqGetBegin(seq2); end1 = ajSeqGetEnd(seq1); end2 = ajSeqGetEnd(seq2); len1 = end1 - begin1 + 1; len2 = end2 - begin2 + 1; flen1 = (float) len1; flen2 = (float) len2; fbegin1 = (float) begin1; fbegin2 = (float) begin2; fend1 = (float) end1; fend2 = (float) end2; offset1 = fbegin1; offset2 = fbegin2; ajSeqTrim(seq1); ajSeqTrim(seq2); embWordLength(wordlen); if(embWordGetTable(&seq1MatchTable, seq1)) matchlist = embWordBuildMatchTable(seq1MatchTable, seq2, ajTrue); if(stretch) { dottup_stretchplot(xygraph,matchlist,seq1,seq2,begin1,begin2,end1, end2); if(matchlist) embWordMatchListDelete(&matchlist); /* free the match structures */ } else { /* only here if stretch is false */ max= flen1; if(flen2 > max) max = flen2; xmargin = ymargin = max * (float)0.15; ajGraphOpenWin(graph, fbegin1-ymargin,fend1+ymargin, fbegin2-xmargin,(float)fend2+xmargin); ajGraphicsSetCharscale(0.5); if(matchlist) dottup_plotMatches(matchlist); if(boxit) { ajGraphicsDrawposRect(fbegin1, fbegin2, fend1, fend2); i = 0; while(acceptableticksx[i]*numbofticks < len1) i++; if(i<=13) tickgap = (float) acceptableticksx[i]; else tickgap = (float) acceptableticksx[10]; ticklen = xmargin * (float) 0.1; onefifth = xmargin * (float)0.2; ajGraphicsDrawposTextAtmid(fbegin1+flen1*(float)0.5, fbegin1-(onefifth*(float)3.0), ajGraphGetYlabelC(graph)); if(len2/len1 > 10 ) { /* a lot smaller then just label start and end */ ajGraphicsDrawposLine(fbegin1,fbegin2,fbegin1, fbegin2-ticklen); sprintf(ptr,"%u",ajSeqGetOffset(seq1)); ajGraphicsDrawposTextAtmid(fbegin1,fbegin2-(onefifth),ptr); ajGraphicsDrawposLine(fend1,fbegin2, fend1,fbegin2-ticklen); sprintf(ptr,"%d",end1); ajGraphicsDrawposTextAtmid(fend1,fbegin2-(onefifth),ptr); } else for(k=fbegin1;k 10 ) { /* a lot smaller then just label start and end */ ajGraphicsDrawposLine(fbegin1,fbegin2,fbegin1-ticklen, fbegin2); sprintf(ptr,"%u",ajSeqGetOffset(seq2)); ajGraphicsDrawposTextAtend(fbegin1-(onefifth),fbegin2,ptr); ajGraphicsDrawposLine(fbegin1,fend2,fbegin1-ticklen, fend2); sprintf(ptr,"%d",end2); ajGraphicsDrawposTextAtend(fbegin2-(onefifth),fend2,ptr); } else for(k=fbegin2;kseq1start); y1 = y2 = offset2 + (PLFLT)(p->seq2start); x2 += (PLFLT)p->length - (PLFLT)1.0; y2 += (PLFLT)p->length - (PLFLT)1.0; ajGraphicsDrawposLine(x1, y1, x2, y2); return; } /* @funcstatic dottup_plotMatches ********************************************* ** ** Undocumented. ** ** @param [r] list [const AjPList] Undocumented ** @return [void] ** @@ ******************************************************************************/ static void dottup_plotMatches(const AjPList list) { ajListMapread(list,dottup_drawPlotlines, NULL); return; } #endif /* @funcstatic dottup_stretchplot ********************************************* ** ** Undocumented. ** ** @param [u] graph [AjPGraph] Undocumented ** @param [r] matchlist [const AjPList] Undocumented ** @param [r] seq1 [const AjPSeq] Undocumented ** @param [r] seq2 [const AjPSeq] Undocumented ** @param [r] begin1 [ajint] Undocumented ** @param [r] begin2 [ajint] Undocumented ** @param [r] end1 [ajint] Undocumented ** @param [r] end2 [ajint] Undocumented ** @return [void] ** @@ ******************************************************************************/ static void dottup_stretchplot(AjPGraph graph, const AjPList matchlist, const AjPSeq seq1, const AjPSeq seq2, ajint begin1, ajint begin2, ajint end1, ajint end2) { EmbPWordMatch wmp = NULL; float xa[1]; float ya[2]; AjPGraphdata gdata = NULL; AjPStr tit = NULL; float x1; float y1; float x2; float y2; AjIList iter = NULL; tit = ajStrNew(); ajFmtPrintS(&tit,"%S",ajGraphGetTitleS(graph)); gdata = ajGraphdataNewI(1); xa[0] = (float)begin1; ya[0] = (float)begin2; ajGraphSetTitleC(graph,ajStrGetPtr(tit)); ajGraphSetXlabelC(graph,ajSeqGetNameC(seq1)); ajGraphSetYlabelC(graph,ajSeqGetNameC(seq2)); ajGraphdataSetTypeC(gdata,"2D Plot Float"); ajGraphdataSetMinmax(gdata,(float)begin1,(float)end1,(float)begin2, (float)end2); ajGraphdataSetTruescale(gdata,(float)begin1,(float)end1,(float)begin2, (float)end2); ajGraphxySetXstartF(graph,(float)begin1); ajGraphxySetXendF(graph,(float)end1); ajGraphxySetYstartF(graph,(float)begin2); ajGraphxySetYendF(graph,(float)end2); ajGraphxySetXrangeII(graph,begin1,end1); ajGraphxySetYrangeII(graph,begin2,end2); if(matchlist) { iter = ajListIterNewread(matchlist); while((wmp = ajListIterGet(iter))) { x1 = x2 = (float) (wmp->seq1start + begin1); y1 = y2 = (float) (wmp->seq2start + begin2); x2 += (float) wmp->length-1; y2 += (float) wmp->length-1; ajGraphAddLine(graph,x1,y1,x2,y2,0); } ajListIterDel(&iter); } ajGraphdataAddXY(gdata,xa,ya); ajGraphDataReplace(graph,gdata); ajGraphxyDisplay(graph,ajFalse); ajGraphicsClose(); ajStrDel(&tit); return; }