1 /* @source polydot application
2 **
3 ** Create a polydot from a multiple sequence file.
4 ** @author Copyright (C) Peter Rice (pmr@ebi.ac.uk)
5 ** @@
6 **
7 ** This program is free software; you can redistribute it and/or
8 ** modify it under the terms of the GNU General Public License
9 ** as published by the Free Software Foundation; either version 2
10 ** of the License, or (at your option) any later version.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; if not, write to the Free Software
19 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 ******************************************************************************/
21 
22 #include "emboss.h"
23 
24 
25 static float xstart = 0;
26 static float ystart = 0;
27 static ajint *lines;
28 static ajint *pts;
29 static ajint which;
30 
31 
32 
33 
34 static void polydot_drawPlotlines(void *x, void *cl);
35 static void polydot_plotMatches(const AjPList list);
36 
37 
38 
39 
40 /* @prog polydot **************************************************************
41 **
42 ** Displays all-against-all dotplots of a set of sequences
43 **
44 ******************************************************************************/
45 
main(int argc,char ** argv)46 int main(int argc, char **argv)
47 {
48 
49     AjPSeqset seqset;
50     const AjPSeq seq1;
51     const AjPSeq seq2;
52     ajint wordlen;
53     AjPTable seq1MatchTable = NULL;
54     AjPList matchlist ;
55     AjPGraph graph = 0;
56     ajuint i;
57     ajuint j;
58     float total=0;
59     ajuint acceptableticks[]=
60     {
61 	1,10,50,100,200,500,1000,1500,10000,50000,
62 	100000,500000,1000000,5000000
63     };
64     ajint numbofticks = 10;
65     ajint gap,tickgap;
66     AjBool boxit    = AJTRUE;
67     AjBool dumpfeat = AJFALSE;
68     float xmargin;
69     float ymargin;
70     float k;
71     char ptr[10];
72     float ticklen;
73     float onefifth;
74     AjPFeattable *tabptr = NULL;
75     AjPFeattabOut seq1out = NULL;
76     AjPStr sajb = NULL;
77     float flen1;
78     float flen2;
79     ajuint tui;
80 
81     embInit("polydot", argc, argv);
82 
83     wordlen  = ajAcdGetInt("wordsize");
84     seqset   = ajAcdGetSeqset("sequences");
85     graph    = ajAcdGetGraph("graph");
86     gap      = ajAcdGetInt("gap");
87     boxit    = ajAcdGetBoolean("boxit");
88     seq1out  = ajAcdGetFeatout("outfeat");
89     dumpfeat = ajAcdGetToggle("dumpfeat");
90 
91     sajb = ajStrNew();
92     embWordLength(wordlen);
93 
94     AJCNEW(lines,ajSeqsetGetSize(seqset));
95     AJCNEW(pts,ajSeqsetGetSize(seqset));
96     AJCNEW(tabptr,ajSeqsetGetSize(seqset));
97 
98     for(i=0;i<ajSeqsetGetSize(seqset);i++)
99     {
100 	seq1 = ajSeqsetGetseqSeq(seqset, i);
101 	total += ajSeqGetLen(seq1);
102 
103     }
104 
105     total +=(float)(gap*(ajSeqsetGetSize(seqset)-1));
106 
107     xmargin = total*(float)0.15;
108     ymargin = total*(float)0.15;
109 
110     ticklen = xmargin*(float)0.1;
111     onefifth  = xmargin*(float)0.2;
112 
113     i = 0;
114     while(acceptableticks[i]*numbofticks < ajSeqsetGetLen(seqset))
115 	i++;
116 
117     if(i<=13)
118 	tickgap = acceptableticks[i];
119     else
120 	tickgap = acceptableticks[13];
121 
122     ajGraphAppendTitleS(graph, ajSeqsetGetUsa(seqset));
123 
124     ajGraphOpenWin(graph, (float)0.0-xmargin,(total+xmargin)*(float)1.35,
125 		   (float)0.0-ymargin,
126 		   total+ymargin);
127     ajGraphicsSetCharscale((float)0.3);
128 
129 
130     for(i=0;i<ajSeqsetGetSize(seqset);i++)
131     {
132 	which = i;
133 	seq1 = ajSeqsetGetseqSeq(seqset, i);
134 	tui = ajSeqGetLen(seq1);
135 	flen1 = (float) tui;
136 
137 	if(embWordGetTable(&seq1MatchTable, seq1)){ /* get table of words */
138 	    for(j=0;j<ajSeqsetGetSize(seqset);j++)
139 	    {
140 		seq2 = ajSeqsetGetseqSeq(seqset, j);
141 		tui  = ajSeqGetLen(seq2);
142 		flen2 = (float) tui;
143 
144 		if(boxit)
145 		    ajGraphicsDrawposRect(xstart,ystart,
146                                           xstart+flen1,
147                                           ystart+flen2);
148 
149 		matchlist = embWordBuildMatchTable(seq1MatchTable, seq2,
150 						   ajTrue);
151 		if(matchlist)
152 		    polydot_plotMatches(matchlist);
153 
154 		if(i<j && dumpfeat)
155 		    embWordMatchListConvToFeat(matchlist,&tabptr[i],
156 					       &tabptr[j],seq1,
157 					       seq2);
158 
159 		if(matchlist)	       /* free the match structures */
160 		    embWordMatchListDelete(&matchlist);
161 
162 		if(j==0)
163 		{
164 		    for(k=0.0;k<ajSeqGetLen(seq1);k+=tickgap)
165 		    {
166 			ajGraphicsDrawposLine(xstart+k,ystart,xstart+k,
167 				    ystart-ticklen);
168 
169 			sprintf(ptr,"%d",(ajint)k);
170 			ajGraphicsDrawposTextAtmid(xstart+k,
171                                                    ystart-(onefifth),
172                                                    ptr);
173 		    }
174 		    ajGraphicsDrawposTextAtmid(
175                         xstart+(flen1/(float)2.0),
176                         ystart-(3*onefifth),
177                         ajStrGetPtr(ajSeqsetGetseqNameS(seqset, i)));
178 		}
179 
180 		if(i==0)
181 		{
182 		    for(k=0.0;k<ajSeqGetLen(seq2);k+=tickgap)
183 		    {
184 			ajGraphicsDrawposLine(xstart,ystart+k,xstart-ticklen,
185 				    ystart+k);
186 
187 			sprintf(ptr,"%d",(ajint)k);
188 			ajGraphicsDrawposTextAtend(xstart-(onefifth),
189                                                    ystart+k,
190                                                    ptr);
191 		    }
192 		    ajGraphicsDrawposTextAtlineJustify(
193                         xstart-(3*onefifth),
194                         ystart+(flen2/(float)2.0),
195                         xstart-(3*onefifth),ystart+flen2,
196                         ajStrGetPtr(ajSeqsetGetseqNameS(seqset, j)),0.5);
197 		}
198 		ystart += flen2+(float)gap;
199 	    }
200 	}
201 	embWordFreeTable(&seq1MatchTable);
202 	seq1MatchTable = NULL;
203 	xstart += flen1+(float)gap;
204 	ystart = 0.0;
205     }
206 
207     ajGraphicsDrawposTextAtstart(total+onefifth,total-(onefifth),
208 		     "No. Length  Lines  Points Sequence");
209 
210     for(i=0;i<ajSeqsetGetSize(seqset);i++)
211     {
212 	seq1 = ajSeqsetGetseqSeq(seqset, i);
213 	ajFmtPrintS(&sajb,"%3u %6d %5d %6d %s",i+1,
214 		    ajSeqGetLen(seq1),lines[i],
215 		    pts[i],ajSeqGetNameC(seq1));
216 
217 	ajGraphicsDrawposTextAtstart(total+onefifth,total-(onefifth*(i+2)),
218                                      ajStrGetPtr(sajb));
219     }
220 
221     if(dumpfeat && seq1out)
222     {
223 	for(i=0;i<ajSeqsetGetSize(seqset);i++)
224 	{
225 	    ajFeattableWrite(seq1out, tabptr[i]);
226 	    ajFeattableDel(&tabptr[i]);
227 	}
228     }
229 
230     ajGraphicsClose();
231     ajGraphxyDel(&graph);
232 
233     ajStrDel(&sajb);
234     AJFREE(lines);
235     AJFREE(pts);
236     AJFREE(tabptr);
237 
238     ajSeqsetDel(&seqset);
239     ajFeattabOutDel(&seq1out);;
240 
241     embExit();
242 
243     return 0;
244 }
245 
246 
247 
248 
249 /* @funcstatic polydot_drawPlotlines ******************************************
250 **
251 ** Undocumented.
252 **
253 ** @param [r] x [void*] Undocumented
254 ** @param [r] cl [void*] Undocumented
255 ** @return [void]
256 ** @@
257 ******************************************************************************/
258 
polydot_drawPlotlines(void * x,void * cl)259 static void polydot_drawPlotlines(void *x, void *cl)
260 {
261     EmbPWordMatch p;
262     PLFLT x1;
263     PLFLT y1;
264     PLFLT x2;
265     PLFLT y2;
266 
267     (void) cl;				/*make it used */
268 
269     p = (EmbPWordMatch)x;
270 
271     lines[which]++;
272     pts[which]+= p->length;
273     x1 = x2 = (p->seq1start)+xstart;
274     y1 = y2 = (PLFLT)(p->seq2start)+ystart;
275     x2 += p->length;
276     y2 += (PLFLT)p->length;
277 
278     ajGraphicsDrawposLine(x1, y1, x2, y2);
279 
280     return;
281 }
282 
283 
284 
285 
286 /* @funcstatic polydot_plotMatches ********************************************
287 **
288 ** Undocumented.
289 **
290 ** @param [r] list [const AjPList] Undocumented
291 ** @return [void]
292 ** @@
293 ******************************************************************************/
294 
polydot_plotMatches(const AjPList list)295 static void polydot_plotMatches(const AjPList list)
296 {
297     ajListMapread(list, &polydot_drawPlotlines, NULL);
298 
299     return;
300 }
301