Merge branch release-4-6
[alexxy/gromacs.git] / src / gromacs / gmxana / gmx_wheel.c
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  *                        VERSION 3.2.0
10  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12  * Copyright (c) 2001-2004, The GROMACS development team,
13  * check out http://www.gromacs.org for more information.
14
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * If you want to redistribute modifications, please consider that
21  * scientific software is very special. Version control is crucial -
22  * bugs must be traceable. We will be happy to consider code for
23  * inclusion in the official distribution, but derived work must not
24  * be called official GROMACS. Details are found in the README & COPYING
25  * files - if they are missing, get the official version at www.gromacs.org.
26  *
27  * To help us fund GROMACS development, we humbly ask that you cite
28  * the papers on the package - you can find them in the top README file.
29  *
30  * For more info, check our website at http://www.gromacs.org
31  *
32  * And Hey:
33  * Green Red Orange Magenta Azure Cyan Skyblue
34  */
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include <math.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include "sysstuff.h"
43 #include "physics.h"
44 #include "string2.h"
45 #include "typedefs.h"
46 #include "smalloc.h"
47 #include "macros.h"
48 #include "vec.h"
49 #include "xvgr.h"
50 #include "pbc.h"
51 #include "gromacs/fileio/futil.h"
52 #include "strdb.h"
53 #include "statutil.h"
54 #include "pbc.h"
55 #include "index.h"
56 #include "gstat.h"
57 #include "gmx_fatal.h"
58 #include "writeps.h"
59 #include "strdb.h"
60 #include "gmx_ana.h"
61
62 static gmx_bool *bPhobics(int nres, char *resnm[])
63 {
64     int       i, nb;
65     char    **cb;
66     gmx_bool *bb;
67
68     nb = get_strings("phbres.dat", &cb);
69     snew(bb, nres);
70
71     for (i = 0; (i < nres); i++)
72     {
73         if (search_str(nb, cb, resnm[i]) != -1)
74         {
75             bb[i] = TRUE;
76         }
77     }
78     return bb;
79 }
80
81 void wheel(const char *fn, int nres, char *resnm[], int r0, real rot0, char *title)
82 {
83     const real fontsize  = 16;
84     const real gray      = 0.9;
85     const real fontasp   = 0.6;
86     const real fontwidth = fontsize*fontasp;
87
88     t_psdata   out;
89     int        i, sl, slen;
90     real       ring, inner, outer;
91     real       xc, yc, box;
92     gmx_bool  *bPh;
93     char     **rnms;
94     char       sign;
95
96     inner = 75.0;
97     slen  = 0;
98     snew(rnms, nres);
99     for (i = 0; (i < nres); i++)
100     {
101         snew(rnms[i], 256);
102         sl   = strlen(resnm[i]);
103         sign = resnm[i][sl-1];
104         if ((sign == '+') || (sign == '-'))
105         {
106             resnm[i][sl-1] = '\0';
107         }
108         sprintf(rnms[i], "%s-%d", resnm[i], i+r0);
109         if ((sign == '+') || (sign == '-'))
110         {
111             sl            = strlen(rnms[i]);
112             rnms[i][sl]   = sign;
113             rnms[i][sl+1] = '\0';
114         }
115
116         slen = max(slen, (int)strlen(rnms[i]));
117     }
118     ring  = (2+slen)*fontwidth;
119     outer = inner+ring;
120     box   = inner*1.5+(1+(nres / 18))*ring;
121
122     bPh = bPhobics(nres, resnm);
123
124     out = ps_open(fn, 0, 0, 2.0*box, 2.0*box);
125     xc  = box;
126     yc  = box;
127
128     ps_font(out, efontHELV, 1.5*fontsize);
129     ps_translate(out, xc, yc);
130     if (title)
131     {
132         ps_ctext(out, 0, -fontsize*1.5/2.0, title, eXCenter);
133     }
134     ps_font(out, efontHELV, fontsize);
135     ps_rotate(out, rot0);
136     for (i = 0; (i < nres); )
137     {
138         if (bPh[i])
139         {
140             ps_color(out, gray, gray, gray);
141             ps_fillarcslice(out, 0, 0, inner, outer, -10, 10);
142             ps_color(out, 0, 0, 0);
143         }
144         ps_arcslice(out, 0, 0, inner, outer, -10, 10);
145
146         ps_ctext(out, inner+fontwidth, -fontsize/2.0, rnms[i], eXLeft);
147         ps_rotate(out, -100);
148         i++;
149
150         if ((i % 18) == 0)
151         {
152             inner  = outer;
153             outer += ring;
154         }
155     }
156     ps_close(out);
157 }
158
159 void wheel2(const char *fn, int nres, char *resnm[], real rot0, char *title)
160 {
161     const real fontsize  = 14;
162     const real gray      = 0.9;
163     const real fontasp   = 0.45;
164     const int  angle     = 9;
165     const real fontwidth = fontsize*fontasp;
166
167     t_psdata   out;
168     int        i, slen;
169     real       ring, inner, outer;
170     real       xc, yc, box;
171
172     inner = 60.0;
173     slen  = 0;
174     for (i = 0; (i < nres); i++)
175     {
176         slen = max(slen, (int)strlen(resnm[i]));
177     }
178     fprintf(stderr, "slen = %d\n", slen);
179     ring  = (slen)*fontwidth;
180     outer = inner+ring;
181     box   = (1+(nres / (2*angle)))*outer;
182
183     out = ps_open(fn, 0, 0, 2.0*box, 2.0*box);
184     xc  = box;
185     yc  = box;
186
187     ps_font(out, efontHELV, 1.5*fontsize);
188     ps_translate(out, xc, yc);
189     ps_color(out, 0, 0, 0);
190     if (title)
191     {
192         ps_ctext(out, 0, -fontsize*1.5/2.0, title, eXCenter);
193     }
194     ps_font(out, efontHELV, fontsize);
195
196     ps_rotate(out, rot0);
197     for (i = 0; (i < nres); )
198     {
199         if ((i % 5) == 4)
200         {
201             ps_color(out, gray, gray, 1.0);
202             ps_fillarcslice(out, 0, 0, inner, outer, -angle, angle);
203             ps_color(out, 0, 0, 0);
204         }
205         ps_arcslice(out, 0, 0, inner, outer, -angle, angle);
206
207         ps_ctext(out, inner+fontwidth, -fontsize/2.0, resnm[i], eXLeft);
208         ps_rotate(out, -2*angle);
209         i++;
210
211         if ((i % (2*angle)) == 0)
212         {
213             inner  = outer;
214             outer += ring;
215         }
216     }
217     ps_close(out);
218 }
219
220 int gmx_wheel(int argc, char *argv[])
221 {
222     const char     *desc[] = {
223         "[TT]g_wheel[tt] plots a helical wheel representation of your sequence.",
224         "The input sequence is in the [TT].dat[tt] file where the first line contains",
225         "the number of residues and each consecutive line contains a residue "
226         "name."
227     };
228     output_env_t    oenv;
229     static real     rot0  = 0;
230     static gmx_bool bNum  = TRUE;
231     static char    *title = NULL;
232     static int      r0    = 1;
233     t_pargs         pa [] = {
234         { "-r0",  FALSE, etINT, {&r0},
235           "The first residue number in the sequence" },
236         { "-rot0", FALSE, etREAL, {&rot0},
237           "Rotate around an angle initially (90 degrees makes sense)" },
238         { "-T",   FALSE, etSTR, {&title},
239           "Plot a title in the center of the wheel (must be shorter than 10 characters, or it will overwrite the wheel)" },
240         { "-nn",  FALSE, etBOOL, {&bNum},
241           "Toggle numbers" }
242     };
243     t_filenm        fnm[] = {
244         { efDAT, "-f", NULL,  ffREAD  },
245         { efEPS, "-o", NULL,  ffWRITE }
246     };
247 #define NFILE asize(fnm)
248
249     int    i, nres;
250     char **resnm;
251
252     if (!parse_common_args(&argc, argv, PCA_BE_NICE, NFILE, fnm, asize(pa), pa,
253                            asize(desc), desc, 0, NULL, &oenv))
254     {
255         return 0;
256     }
257
258     for (i = 1; (i < argc); i++)
259     {
260         if (strcmp(argv[i], "-r0") == 0)
261         {
262             r0 = strtol(argv[++i], NULL, 10);
263             fprintf(stderr, "First residue is %d\n", r0);
264         }
265         else if (strcmp(argv[i], "-rot0") == 0)
266         {
267             rot0 = strtod(argv[++i], NULL);
268             fprintf(stderr, "Initial rotation is %g\n", rot0);
269         }
270         else if (strcmp(argv[i], "-T") == 0)
271         {
272             title = strdup(argv[++i]);
273             fprintf(stderr, "Title will be '%s'\n", title);
274         }
275         else if (strcmp(argv[i], "-nn") == 0)
276         {
277             bNum = FALSE;
278             fprintf(stderr, "No residue numbers\n");
279         }
280         else
281         {
282             gmx_fatal(FARGS, "Incorrect usage of option %s", argv[i]);
283         }
284     }
285
286     nres = get_lines(ftp2fn(efDAT, NFILE, fnm), &resnm);
287     if (bNum)
288     {
289         wheel(ftp2fn(efEPS, NFILE, fnm), nres, resnm, r0, rot0, title);
290     }
291     else
292     {
293         wheel2(ftp2fn(efEPS, NFILE, fnm), nres, resnm, rot0, title);
294     }
295
296     return 0;
297 }