2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012,2013, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
58 enum { ebQuit, ebStart, ebStop, ebRewind, ebGly, ebutNR };
61 #define SX(x) ((int)(((x)+M_PI)*scx))
62 #define SY(y) ((int)((M_PI-(y))*scy))
64 enum { esStop, esGo, esNR };
73 t_windata but[ebutNR];
76 static void plot_pp(t_x11 *x11,Window w,t_phipsi *pp,t_dih dih[])
79 int th=(XTextHeight(x11->font)+6)/2;
81 x0=SX(dih[pp->iphi].ang);
82 y0=SY(dih[pp->ipsi].ang);
83 XFillRectangle(x11->disp,w,x11->gc,x0-1,y0-1,4,4);
86 TextInRect(x11,w,pp->label,x0+6,y0-th,30,2*th,eXLeft,eYCenter);
89 static gmx_bool label_pp(t_x11 *x11,Window w,int npp,t_phipsi pp[],
90 t_dih dih[],int mx,int my)
97 for(i=0; (i<npp); i++) {
98 x0=SX(dih[pp[i].iphi].ang);
99 y0=SY(dih[pp[i].ipsi].ang);
100 d=(mx-x0)*(mx-x0)+(my-y0)*(my-y0);
107 pp[imin].bShow=!pp[imin].bShow;
113 static gmx_bool xrCallBack(struct t_x11 *x11,XEvent *event, Window w, void *data)
120 (void)XTextHeight(x11->font);
123 scx=app->xrwd.width/(2.0*M_PI);
124 scy=app->xrwd.height/(2.0*M_PI);
125 switch (event->type) {
127 XClearWindow(x11->disp,app->xrwd.self);
128 XDrawLine(x11->disp,app->xrwd.self,x11->gc,
129 SX(0),SY(-M_PI)+1,SX(0),SY(M_PI)-1);
130 XDrawLine(x11->disp,app->xrwd.self,x11->gc,
131 SX(-M_PI)+1,SY(0),SX(M_PI)-1,SY(0));
132 TextInRect(x11,app->xrwd.self,"Phi",SX(M_PI)-50,SY(0)+4,46,20,eXRight,eYTop);
133 TextInRect(x11,app->xrwd.self,"Psi",SX(0)+4,4,46,20,eXLeft,eYTop);
134 for(i=0; (i<xr->npp); i++)
135 if (app->bShowGly || !app->bIsGly[i])
136 plot_pp(x11,app->xrwd.self,&(xr->pp[i]),xr->dih);
139 if (label_pp(x11,app->xrwd.self,xr->npp,xr->pp,xr->dih,
140 event->xbutton.x,event->xbutton.y))
141 ExposeWin(x11->disp,app->xrwd.self);
143 case ConfigureNotify:
144 app->xrwd.width=event->xconfigure.width;
145 app->xrwd.height=event->xconfigure.height;
148 if (app->status == esGo) {
149 if (!new_data(app->xr))
152 ExposeWin(x11->disp,app->xrwd.self);
153 sprintf(buf,"Rama: t=%.2f",app->xr->t);
154 XSetStandardProperties(x11->disp,app->wd.self,buf,
155 "Rama",0,NULL,0,NULL);
162 static gmx_bool appCallBack(struct t_x11 *x11,XEvent *event, Window w, void *data)
168 for(win=0; (win<ebutNR); win++)
169 if (app->but[win].self == w)
174 switch(event->type) {
176 TextInWin(x11,&(app->but[win]),app->but[win].text,eXCenter,eYCenter);
184 ExposeWin(x11->disp,app->xrwd.self);
190 rewind_trj(app->xr->traj);
193 app->bShowGly=!app->bShowGly;
194 ExposeWin(x11->disp,app->xrwd.self);
205 static void size_app(t_x11 *x11,t_app *app)
209 th=XTextHeight(x11->font)+4;
210 dx=app->wd.width/ebutNR;
211 for(i=0; (i<ebutNR); i++) {
212 app->but[i].width=dx-4;
213 app->but[i].height=th+4;
214 XMoveResizeWindow(x11->disp,app->but[i].self,i*dx+2,2,dx-4,th+4);
216 XMoveResizeWindow(x11->disp,app->xrwd.self,2,th+10,
217 app->wd.width-6,app->wd.height-th-10-4);
220 static gmx_bool mainCallBack(struct t_x11 *x11,XEvent *event, Window w, void *data)
226 switch (event->type) {
227 case ConfigureNotify:
228 wt=event->xconfigure.width;
229 ht=event->xconfigure.height;
230 if ((app->wd.width != wt) || (app->wd.height != ht)) {
231 fprintf(stderr,"New wxh = %dx%d\n",wt,ht);
241 static t_xrama *init_xrama(t_x11 *x11,Window Parent,int y0,t_app *app)
247 InitWin(&(app->xrwd),2,y0,MAXDEG+1,MAXDEG+1,1,"Ramachandran Movie");
248 app->xrwd.self=XCreateSimpleWindow(x11->disp,Parent,app->xrwd.x,app->xrwd.y,
249 app->xrwd.width,app->xrwd.height,
250 app->xrwd.bwidth,x11->fg,x11->bg);
251 x11->RegisterCallback(x11,app->xrwd.self,Parent,xrCallBack,app);
252 x11->SetInputMask(x11,app->xrwd.self,ButtonPressMask | ExposureMask |
253 StructureNotifyMask);
258 static t_app *init_app(t_x11 *x11,int argc,char *argv[])
260 static const char *but_nm[ebutNR] = { "Quit", "Start", "Stop", "Rewind", "Toggle Gly" };
269 th=XTextHeight(x11->font)+4;
270 InitWin(&(app->wd),0,0,MAXDEG+6,MAXDEG+6+th+6,0,"Ramachandran Movie");
271 dx=app->wd.width/ebutNR;
272 app->wd.self=XCreateSimpleWindow(x11->disp,x11->root,app->wd.x,app->wd.y,
273 app->wd.width,app->wd.height,
274 app->wd.bwidth,x11->fg,x11->bg);
275 x11->RegisterCallback(x11,app->wd.self,x11->root,mainCallBack,app);
276 x11->SetInputMask(x11,app->wd.self,StructureNotifyMask);
278 pm=XCreatePixmapFromBitmapData(x11->disp,x11->root,(char *)rama_bits,
279 rama_width,rama_height,WHITE,BLACK,1);
280 XSetStandardProperties(x11->disp,app->wd.self,app->wd.text,
281 "Rama",pm,argv,argc,&hints);
282 x11->RegisterCallback(x11,app->wd.self,x11->root,appCallBack,app);
283 x11->SetInputMask(x11,app->wd.self,ButtonPressMask | ExposureMask |
284 StructureNotifyMask);
286 app->xr=init_xrama(x11,app->wd.self,th+6,app);
287 for(i=0; (i<ebutNR); i++) {
289 InitWin(wd,i*dx+2,2,dx-4,th,1,but_nm[i]);
290 wd->self=XCreateSimpleWindow(x11->disp,app->wd.self,
291 wd->x,wd->y,wd->width,wd->height,
292 wd->bwidth,x11->fg,x11->bg);
293 x11->RegisterCallback(x11,wd->self,app->wd.self,appCallBack,app);
294 x11->SetInputMask(x11,wd->self,ButtonPressMask | ExposureMask);
299 static void mk_gly(t_app *app)
303 snew(app->bIsGly,app->xr->npp);
304 for(i=0; (i<app->xr->npp); i++) {
305 if (strstr(app->xr->pp[i].label,"GLY") != NULL)
310 int main(int argc,char *argv[])
312 const char *desc[] = {
313 "[TT]g_xrama[tt] shows a Ramachandran movie, that is, it shows",
314 "the Phi/Psi angles as a function of time in an X-Window.[PAR]"
315 "Static Phi/Psi plots for printing can be made with [TT]g_rama[tt].[PAR]",
316 "Some of the more common X command line options can be used:[BR]",
317 "[TT]-bg[tt], [TT]-fg[tt] change colors, [TT]-font fontname[tt], changes the font."
325 { efTRX, "-f", NULL, ffREAD },
326 { efTPX, NULL, NULL, ffREAD }
328 #define NFILE asize(fnm)
330 CopyRight(stderr,argv[0]);
331 parse_common_args(&argc,argv,PCA_CAN_TIME,NFILE,fnm,0,NULL,
332 asize(desc),desc,0,NULL,&oenv);
335 if ((x11=GetX11(&argc,argv)) == NULL) {
336 fprintf(stderr,"Can't open display, set your DISPLAY environment variable\n");
339 XSetForeground(x11->disp,x11->gc,x11->fg);
340 app=init_app(x11,argc,argv);
342 ramatop = init_rama(oenv,ftp2fn(efTRX,NFILE,fnm),ftp2fn(efTPX,NFILE,fnm),
346 XMapWindow(x11->disp,app->wd.self);
347 XMapSubwindows(x11->disp,app->wd.self);