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
60 static void add_object(t_manager *man,eObject eO,atom_id ai,atom_id aj)
62 srenew(man->obj,++man->nobj);
63 man->obj[man->nobj-1].eO = eO;
64 man->obj[man->nobj-1].eV = eVNormal;
65 man->obj[man->nobj-1].color = WHITE;
66 man->obj[man->nobj-1].ai = ai;
67 man->obj[man->nobj-1].aj = aj;
68 man->obj[man->nobj-1].z = 0.0;
71 static void add_bonds(t_manager *man,t_functype func[],
72 t_ilist *b,gmx_bool bB[])
74 gmx_bool *bH=man->bHydro;
76 t_iatom type,ai,aj,ak;
80 fprintf(stderr,"Going to make bonds from an ilist with %d entries\n",b->nr);
83 for(i=0; (i<b->nr); ) {
87 delta = interaction_function[ftype].nratoms;
89 if (ftype == F_SETTLE) {
92 bB[ai]=bB[aj]=bB[ak]=TRUE;
93 add_object(man,eOHBond,ai,aj);
94 add_object(man,eOHBond,ai,ak);
96 else if (IS_CHEMBOND(ftype)) {
99 fprintf(stderr,"Adding bond from %d to %d\n",ai,aj);
102 if (!(bH[ai] == bH[aj]))
103 add_object(man,eOHBond,ai,aj);
104 else if (!bH[ai] && !bH[aj])
105 add_object(man,eOBond,ai,aj);
108 fprintf(stderr,"Type: %5d, delta: %5d\n",type,delta);
115 static void add_bpl(t_manager *man,t_idef *idef,gmx_bool bB[])
119 for(ftype=0; ftype<F_NRE; ftype++)
120 if (IS_CHEMBOND(ftype) || ftype==F_SETTLE)
121 add_bonds(man,idef->functype,&idef->il[ftype],bB);
124 static atom_id which_atom(t_manager *man,int x, int y)
130 for(i=0; (i<man->natom); i++) {
131 if ((abs(ix[i][XX]-x) < DELTA) && (abs(ix[i][YY]-y) < DELTA)) {
139 static void do_label(t_x11 *x11,t_manager *man,int x,int y,gmx_bool bSet)
144 if ((ai=which_atom(man,x,y)) != NO_ATID) {
147 if (bSet && !man->bLabel[ai]) {
149 man->bLabel[ai]=TRUE;
151 else if (!bSet && man->bLabel[ai]) {
153 man->bLabel[ai]=FALSE;
157 XSetForeground(x11->disp,x11->gc,col);
158 XDrawString(x11->disp,man->molw->wd.self,x11->gc,x+2,y-2,man->szLab[ai],
159 strlen(man->szLab[ai]));
160 XSetForeground(x11->disp,x11->gc,x11->fg);
164 static void show_label(t_x11 *x11,t_manager *man,int x,int y)
166 do_label(x11,man,x,y,TRUE);
169 static void hide_label(t_x11 *x11,t_manager *man,int x,int y)
171 do_label(x11,man,x,y,FALSE);
174 void set_file(t_x11 *x11,t_manager *man,const char *trajectory,
178 char buf[256],quote[256];
184 read_tpxheader(status,&sh,TRUE,NULL,NULL);
185 snew(man->ix,sh.natoms);
186 snew(man->zz,sh.natoms);
187 snew(man->col,sh.natoms);
188 snew(man->size,sh.natoms);
189 snew(man->vdw,sh.natoms);
190 snew(man->bLabel,sh.natoms);
191 snew(man->bVis,sh.natoms);
192 for(i=0; (i<sh.natoms); i++)
197 snew(man->szLab,sh.natoms);
198 snew(man->bHydro,sh.natoms);
200 read_tpx_top(status,NULL,man->box,&man->natom,NULL,NULL,NULL,&man->top);
201 man->gpbc = gmx_rmpbc_init(&man->top.idef,-1,man->natom,man->box);
204 read_first_x(man->oenv,&man->status,trajectory,&(man->time),&(man->x),
206 man->trajfile=strdup(trajectory);
207 if (man->natom > man->top.atoms.nr)
208 gmx_fatal(FARGS,"Topology %s (%d atoms) and trajectory %s (%d atoms) "
209 "do not match",status,man->top.atoms.nr,
210 trajectory,man->natom);
212 cool_quote(quote,255,NULL);
213 sprintf(buf,"%s: %s",*man->top.name,quote);
214 man->title.text = strdup(buf);
215 man->view = init_view(man->box);
216 at = &(man->top.atoms);
217 aps = gmx_atomprop_init();
218 for(i=0; (i<man->natom); i++) {
219 char *aname=*(at->atomname[i]);
220 t_resinfo *ri=&at->resinfo[at->atom[i].resind];
222 man->col[i]=Type2Color(aname);
223 snew(man->szLab[i],20);
225 sprintf(man->szLab[i],"%s%d%c, %s",*ri->name,ri->nr,ri->ic,aname);
227 sprintf(man->szLab[i],"%s%d, %s",*ri->name,ri->nr,aname);
229 man->bHydro[i]=(toupper(aname[0])=='H');
230 if ( man->bHydro[i] )
232 else if (!gmx_atomprop_query(aps,epropVDW,*ri->name,aname,&(man->vdw[i])))
235 gmx_atomprop_destroy(aps);
236 add_bpl(man,&(man->top.idef),bB);
237 for(i=0; (i<man->natom); i++)
239 add_object(man,eOSingle,(atom_id) i,0);
242 ExposeWin(x11->disp,man->molw->wd.self);
245 void step_message(t_x11 *x11,t_manager *man)
249 letter.type=ClientMessage;
250 letter.xclient.display=x11->disp;
251 letter.xclient.window=man->wd.self;
252 letter.xclient.message_type=0;
253 letter.xclient.format=32;
254 letter.xclient.data.l[0]=IDSTEP;
255 letter.xclient.data.l[1]=Button1;
256 XSendEvent(x11->disp,letter.xclient.window,True,0,&letter);
259 gmx_bool ReadMonfile(char *fn,int *nbars, int *bars)
262 if ((fp = fopen(fn,"r"))==NULL)
265 for((*nbars)=0; fscanf(fp,"%d",&bars[*nbars])>0; (*nbars)++)
272 static void reset_mols(t_block *mols,matrix box,rvec x[])
278 for(i=0; (i<mols->nr); i++) {
285 for(j=m0; (j<m1); j++) {
288 for(m=0; (m<DIM); m++)
290 for(m=0; (m<DIM); m++) {
293 else if (xcm[m] >= box[m][m])
296 ix=icm[XX],iy=icm[YY],iz=icm[ZZ];
298 if ((ix != 0) || (iy != 0) || (iz != 0)) {
299 for(j=m0; (j<m1); j++) {
308 static gmx_bool step_man(t_manager *man,int *nat)
311 static gmx_bool bWarn = FALSE;
317 fprintf(stderr,"Not initiated yet!");
320 bEof=read_next_x(man->oenv,man->status,&man->time,man->natom,man->x,man->box);
322 if (ncount == man->nSkip) {
323 switch (man->molw->boxtype) {
325 put_atoms_in_triclinic_unitcell(ecenterDEF,man->box,man->natom,man->x);
328 warn = put_atoms_in_compact_unitcell(man->molw->ePBC,ecenterDEF,man->box,
330 if (warn && !bWarn) {
331 fprintf(stderr,"\n%s\n",warn);
341 gmx_rmpbc(man->gpbc,man->natom,man->box,man->x);
342 reset_mols(&(man->top.mols),man->box,man->x);
347 if (man->nSkip > 0) {
349 return step_man(man,nat);
356 static void HandleClient(t_x11 *x11,t_manager *man,long data[])
366 bPos=(button==Button1);
371 rotate_3d(man->view,ID-IDROTX,bPos);
376 fac=0.8; /* Reduce distance between eye and origin */
380 /* zoom changed to scale by Berk Hess 3-7-96
381 if (zoom_3d(man->view,fac))
382 draw_mol(x11,man); */
383 man->view->sc_x/=fac;
384 man->view->sc_y/=fac;
390 translate_view(man->view,ID-IDTRANSX,bPos);
395 rewind_trj(man->status);
396 read_next_x(man->oenv,man->status,&(man->time),man->natom,man->x,
406 if (!step_man(man,&nat)) {
413 usleep(man->nWait*1000);
431 show_label(x11,man,x,y);
434 hide_label(x11,man,x,y);
441 if (man->bAnimate && !man->bEof && !man->bStop)
442 step_message(x11,man);
445 static gmx_bool TitleCallBack(t_x11 *x11,XEvent *event, Window w, void *data)
449 wd=(t_windata *)data;
450 switch (event->type) {
452 if (wd->text && (wd->width > 10)) {
453 XSetForeground(x11->disp,x11->gc,WHITE);
454 TextInWin(x11,wd,wd->text,eXCenter,eYCenter);
455 XDrawLine(x11->disp,wd->self,x11->gc,0,wd->height,
456 wd->width,wd->height);
459 case ConfigureNotify:
460 wd->width=event->xconfigure.width;
461 wd->height=event->xconfigure.height;
467 static gmx_bool ManCallBack(t_x11 *x11,XEvent *event, Window w, void *data)
472 man=(t_manager *)data;
473 switch(event->type) {
474 case ConfigureNotify:
475 width=event->xconfigure.width;
476 height=event->xconfigure.height;
477 if ((width!=man->wd.width) || (height!=man->wd.height))
478 move_man(x11,man,width,height);
481 HandleClient(x11,man,event->xclient.data.l);
489 void no_labels(t_x11 *x11,t_manager *man)
493 for(i=0; (i<man->natom); i++)
494 man->bLabel[i]=FALSE;
498 void move_man(t_x11 *x11,t_manager *man,int width,int height)
504 fprintf(stderr,"Move manager %dx%d\n",width,height);
507 man->wd.height=height;
509 /* Move all subwindows, resize only Mol window */
510 x0=width-EWIDTH-AIR-4*BORDER; /* Starting of ewin etc. */
514 mw=x0-2*AIR-4*BORDER;
515 mh=height-y0-AIR-2*BORDER;
516 XMoveResizeWindow(x11->disp,man->molw->wd.self,AIR,y0,mw,mh);
519 th=XTextHeight(x11->font);
520 XMoveResizeWindow(x11->disp,man->title.self,0,0,mw,th+AIR);
523 XMoveResizeWindow(x11->disp,man->legw->wd.self,x0,y0,EWIDTH,LEGHEIGHT);
524 y0+=LEGHEIGHT+AIR+2*BORDER;
527 printf("Error: Windows falling out of main window!\n");
530 hb=height-y0-AIR-2*BORDER;
531 XMoveResizeWindow(x11->disp,man->bbox->wd.self,x0,y0,EWIDTH,hb);
534 x0=(mw-man->vbox->wd.width)/2;
535 y0=(mh-2-AIR-man->vbox->wd.height);
536 XMoveWindow(x11->disp,man->vbox->wd.self,x0,y0);
539 void map_man(t_x11 *x11,t_manager *man)
541 XMapWindow(x11->disp,man->wd.self);
542 map_mw(x11,man->molw);
543 XMapWindow(x11->disp,man->title.self);
544 map_legw(x11,man->legw);
545 show_but(x11,man->bbox);
548 gmx_bool toggle_animate (t_x11 *x11,t_manager *man)
551 man->bAnimate=!man->bAnimate;
555 show_but(x11,man->vbox);
557 hide_but(x11,man->vbox);
559 return man->bAnimate;
562 gmx_bool toggle_pbc (t_manager *man)
564 man->bPbc=!man->bPbc;
570 t_manager *init_man(t_x11 *x11,Window Parent,
571 int x,int y,int width,int height,
572 unsigned long fg,unsigned long bg,
574 const output_env_t oenv)
583 InitWin(&(man->wd),x,y,width,height,0,"Manager");
584 man->wd.self=XCreateSimpleWindow(x11->disp,Parent,man->wd.x, man->wd.y,
585 man->wd.width,man->wd.height,
586 man->wd.bwidth,fg,bg);
587 x11->RegisterCallback(x11,man->wd.self,Parent,ManCallBack,man);
588 x11->SetInputMask(x11,man->wd.self,StructureNotifyMask |
589 ExposureMask | ButtonPressMask);
591 /* The order of creating windows is important for the stacking order */
593 man->molw=init_mw(x11,man->wd.self,0,0,1,1,WHITE,BLUE,ePBC,box);
596 InitWin(&(man->title),0,0,1,1,0,NULL);
597 man->title.self=XCreateSimpleWindow(x11->disp,man->molw->wd.self,
598 man->title.x,man->title.y,
599 man->title.width,man->title.height,
600 man->title.bwidth,WHITE,BLUE);
601 x11->RegisterCallback(x11,man->title.self,man->molw->wd.self,
602 TitleCallBack,&(man->title));
603 x11->SetInputMask(x11,man->title.self,ExposureMask | StructureNotifyMask);
606 man->bbox=init_bbox(x11,man->wd.self,man->wd.self,1,WHITE,BLUE);
609 man->legw=init_legw(x11,man->wd.self,0,0,EWIDTH,LEGHEIGHT,WHITE,BLUE);
612 man->vbox=init_vbox(x11,man->molw->wd.self,man->wd.self,WHITE,BLUE);
617 void done_man(t_x11 *x11,t_manager *man)
619 done_bbox(x11,man->vbox);
620 done_bbox(x11,man->bbox);
621 done_mw(x11,man->molw);
622 done_legw(x11,man->legw);
623 x11->UnRegisterCallback(x11,man->title.self);
624 x11->UnRegisterCallback(x11,man->wd.self);
634 void do_filter(t_x11 *x11,t_manager *man,t_filter *filter)
639 for(i=0; (i<man->natom); i++)
641 for(i=0; (i<filter->grps->nr); i++) {
642 if (filter->bShow[i])
643 for(j=filter->grps->index[i]; (j<filter->grps->index[i+1]); j++)
644 man->bVis[filter->grps->a[j]]=TRUE;
647 ExposeWin(x11->disp,man->wd.self);