3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
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.
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.
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.
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.
30 * For more info, check our website at http://www.gromacs.org
33 * Gyas ROwers Mature At Cryogenic Speed
52 #include "gromacs/commandline/cmdlinemodulemanager.h"
57 ebQuit, ebStart, ebStop, ebRewind, ebGly, ebutNR
61 #define SX(x) ((int)(((x)+M_PI)*scx))
62 #define SY(y) ((int)((M_PI-(y))*scy))
75 t_windata but[ebutNR];
78 static void plot_pp(t_x11 *x11, Window w, t_phipsi *pp, t_dih dih[])
81 int th = (XTextHeight(x11->font)+6)/2;
83 x0 = SX(dih[pp->iphi].ang);
84 y0 = SY(dih[pp->ipsi].ang);
85 XFillRectangle(x11->disp, w, x11->gc, x0-1, y0-1, 4, 4);
89 TextInRect(x11, w, pp->label, x0+6, y0-th, 30, 2*th, eXLeft, eYCenter);
93 static gmx_bool label_pp(t_x11 *x11, Window w, int npp, t_phipsi pp[],
94 t_dih dih[], int mx, int my)
101 for (i = 0; (i < npp); i++)
103 x0 = SX(dih[pp[i].iphi].ang);
104 y0 = SY(dih[pp[i].ipsi].ang);
105 d = (mx-x0)*(mx-x0)+(my-y0)*(my-y0);
114 pp[imin].bShow = !pp[imin].bShow;
120 static gmx_bool xrCallBack(struct t_x11 *x11, XEvent *event, Window w, void *data)
127 (void)XTextHeight(x11->font);
130 scx = app->xrwd.width/(2.0*M_PI);
131 scy = app->xrwd.height/(2.0*M_PI);
135 XClearWindow(x11->disp, app->xrwd.self);
136 XDrawLine(x11->disp, app->xrwd.self, x11->gc,
137 SX(0), SY(-M_PI)+1, SX(0), SY(M_PI)-1);
138 XDrawLine(x11->disp, app->xrwd.self, x11->gc,
139 SX(-M_PI)+1, SY(0), SX(M_PI)-1, SY(0));
140 TextInRect(x11, app->xrwd.self, "Phi", SX(M_PI)-50, SY(0)+4, 46, 20, eXRight, eYTop);
141 TextInRect(x11, app->xrwd.self, "Psi", SX(0)+4, 4, 46, 20, eXLeft, eYTop);
142 for (i = 0; (i < xr->npp); i++)
144 if (app->bShowGly || !app->bIsGly[i])
146 plot_pp(x11, app->xrwd.self, &(xr->pp[i]), xr->dih);
151 if (label_pp(x11, app->xrwd.self, xr->npp, xr->pp, xr->dih,
152 event->xbutton.x, event->xbutton.y))
154 ExposeWin(x11->disp, app->xrwd.self);
157 case ConfigureNotify:
158 app->xrwd.width = event->xconfigure.width;
159 app->xrwd.height = event->xconfigure.height;
162 if (app->status == esGo)
164 if (!new_data(app->xr))
166 app->status = ebStop;
170 ExposeWin(x11->disp, app->xrwd.self);
171 sprintf(buf, "Rama: t=%.2f", app->xr->t);
172 XSetStandardProperties(x11->disp, app->wd.self, buf,
173 "Rama", 0, NULL, 0, NULL);
180 static gmx_bool appCallBack(struct t_x11 *x11, XEvent *event, Window w, void *data)
186 for (win = 0; (win < ebutNR); win++)
188 if (app->but[win].self == w)
201 TextInWin(x11, &(app->but[win]), app->but[win].text, eXCenter, eYCenter);
210 ExposeWin(x11->disp, app->xrwd.self);
213 app->status = esStop;
216 rewind_trj(app->xr->traj);
219 app->bShowGly = !app->bShowGly;
220 ExposeWin(x11->disp, app->xrwd.self);
223 XBell(x11->disp, 50);
231 static void size_app(t_x11 *x11, t_app *app)
235 th = XTextHeight(x11->font)+4;
236 dx = app->wd.width/ebutNR;
237 for (i = 0; (i < ebutNR); i++)
239 app->but[i].width = dx-4;
240 app->but[i].height = th+4;
241 XMoveResizeWindow(x11->disp, app->but[i].self, i*dx+2, 2, dx-4, th+4);
243 XMoveResizeWindow(x11->disp, app->xrwd.self, 2, th+10,
244 app->wd.width-6, app->wd.height-th-10-4);
247 static gmx_bool mainCallBack(struct t_x11 *x11, XEvent *event, Window w, void *data)
255 case ConfigureNotify:
256 wt = event->xconfigure.width;
257 ht = event->xconfigure.height;
258 if ((app->wd.width != wt) || (app->wd.height != ht))
260 fprintf(stderr, "New wxh = %dx%d\n", wt, ht);
270 static t_xrama *init_xrama(t_x11 *x11, Window Parent, int y0, t_app *app)
276 InitWin(&(app->xrwd), 2, y0, MAXDEG+1, MAXDEG+1, 1, "Ramachandran Movie");
277 app->xrwd.self = XCreateSimpleWindow(x11->disp, Parent, app->xrwd.x, app->xrwd.y,
278 app->xrwd.width, app->xrwd.height,
279 app->xrwd.bwidth, x11->fg, x11->bg);
280 x11->RegisterCallback(x11, app->xrwd.self, Parent, xrCallBack, app);
281 x11->SetInputMask(x11, app->xrwd.self, ButtonPressMask | ExposureMask |
282 StructureNotifyMask);
287 static t_app *init_app(t_x11 *x11, int argc, char *argv[])
289 static const char *but_nm[ebutNR] = { "Quit", "Start", "Stop", "Rewind", "Toggle Gly" };
298 th = XTextHeight(x11->font)+4;
299 InitWin(&(app->wd), 0, 0, MAXDEG+6, MAXDEG+6+th+6, 0, "Ramachandran Movie");
300 dx = app->wd.width/ebutNR;
301 app->wd.self = XCreateSimpleWindow(x11->disp, x11->root, app->wd.x, app->wd.y,
302 app->wd.width, app->wd.height,
303 app->wd.bwidth, x11->fg, x11->bg);
304 x11->RegisterCallback(x11, app->wd.self, x11->root, mainCallBack, app);
305 x11->SetInputMask(x11, app->wd.self, StructureNotifyMask);
307 pm = XCreatePixmapFromBitmapData(x11->disp, x11->root, (char *)rama_bits,
308 rama_width, rama_height, WHITE, BLACK, 1);
309 XSetStandardProperties(x11->disp, app->wd.self, app->wd.text,
310 "Rama", pm, argv, argc, &hints);
311 x11->RegisterCallback(x11, app->wd.self, x11->root, appCallBack, app);
312 x11->SetInputMask(x11, app->wd.self, ButtonPressMask | ExposureMask |
313 StructureNotifyMask);
315 app->xr = init_xrama(x11, app->wd.self, th+6, app);
316 for (i = 0; (i < ebutNR); i++)
319 InitWin(wd, i*dx+2, 2, dx-4, th, 1, but_nm[i]);
320 wd->self = XCreateSimpleWindow(x11->disp, app->wd.self,
321 wd->x, wd->y, wd->width, wd->height,
322 wd->bwidth, x11->fg, x11->bg);
323 x11->RegisterCallback(x11, wd->self, app->wd.self, appCallBack, app);
324 x11->SetInputMask(x11, wd->self, ButtonPressMask | ExposureMask);
329 static void mk_gly(t_app *app)
333 snew(app->bIsGly, app->xr->npp);
334 for (i = 0; (i < app->xr->npp); i++)
336 if (strstr(app->xr->pp[i].label, "GLY") != NULL)
338 app->bIsGly[i] = TRUE;
343 int gmx_xrama(int argc, char *argv[])
345 const char *desc[] = {
346 "[TT]g_xrama[tt] shows a Ramachandran movie, that is, it shows",
347 "the Phi/Psi angles as a function of time in an X-Window.[PAR]"
348 "Static Phi/Psi plots for printing can be made with [TT]g_rama[tt].[PAR]",
349 "Some of the more common X command line options can be used:[BR]",
350 "[TT]-bg[tt], [TT]-fg[tt] change colors, [TT]-font fontname[tt], changes the font."
357 { efTRX, "-f", NULL, ffREAD },
358 { efTPX, NULL, NULL, ffREAD }
360 #define NFILE asize(fnm)
362 if (!parse_common_args(&argc, argv, PCA_CAN_TIME, NFILE, fnm,
363 0, NULL, asize(desc), desc, 0, NULL, &oenv))
369 if ((x11 = GetX11(&argc, argv)) == NULL)
371 fprintf(stderr, "Can't open display, set your DISPLAY environment variable\n");
374 XSetForeground(x11->disp, x11->gc, x11->fg);
375 app = init_app(x11, argc, argv);
377 init_rama(oenv, ftp2fn(efTRX, NFILE, fnm), ftp2fn(efTPX, NFILE, fnm),
381 XMapWindow(x11->disp, app->wd.self);
382 XMapSubwindows(x11->disp, app->wd.self);
389 int main(int argc, char *argv[])
391 return gmx::CommandLineModuleManager::runAsMainCMain(argc, argv, &gmx_xrama);