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); )
88 delta = interaction_function[ftype].nratoms;
90 if (ftype == F_SETTLE)
94 bB[ai] = bB[aj] = bB[ak] = TRUE;
95 add_object(man, eOHBond, ai, aj);
96 add_object(man, eOHBond, ai, ak);
98 else if (IS_CHEMBOND(ftype))
102 fprintf(stderr, "Adding bond from %d to %d\n", ai, aj);
104 bB[ai] = bB[aj] = TRUE;
105 if (!(bH[ai] == bH[aj]))
107 add_object(man, eOHBond, ai, aj);
109 else if (!bH[ai] && !bH[aj])
111 add_object(man, eOBond, ai, aj);
115 fprintf(stderr, "Type: %5d, delta: %5d\n", type, delta);
122 static void add_bpl(t_manager *man, t_idef *idef, gmx_bool bB[])
126 for (ftype = 0; ftype < F_NRE; ftype++)
128 if (IS_CHEMBOND(ftype) || ftype == F_SETTLE)
130 add_bonds(man, idef->functype, &idef->il[ftype], bB);
135 static atom_id which_atom(t_manager *man, int x, int y)
141 for (i = 0; (i < man->natom); i++)
143 if ((abs(ix[i][XX]-x) < DELTA) && (abs(ix[i][YY]-y) < DELTA))
154 static void do_label(t_x11 *x11, t_manager *man, int x, int y, gmx_bool bSet)
159 if ((ai = which_atom(man, x, y)) != NO_ATID)
163 if (bSet && !man->bLabel[ai])
166 man->bLabel[ai] = TRUE;
168 else if (!bSet && man->bLabel[ai])
171 man->bLabel[ai] = FALSE;
177 XSetForeground(x11->disp, x11->gc, col);
178 XDrawString(x11->disp, man->molw->wd.self, x11->gc, x+2, y-2, man->szLab[ai],
179 strlen(man->szLab[ai]));
180 XSetForeground(x11->disp, x11->gc, x11->fg);
184 static void show_label(t_x11 *x11, t_manager *man, int x, int y)
186 do_label(x11, man, x, y, TRUE);
189 static void hide_label(t_x11 *x11, t_manager *man, int x, int y)
191 do_label(x11, man, x, y, FALSE);
194 void set_file(t_x11 *x11, t_manager *man, const char *trajectory,
198 char buf[256], quote[256];
204 read_tpxheader(status, &sh, TRUE, NULL, NULL);
205 snew(man->ix, sh.natoms);
206 snew(man->zz, sh.natoms);
207 snew(man->col, sh.natoms);
208 snew(man->size, sh.natoms);
209 snew(man->vdw, sh.natoms);
210 snew(man->bLabel, sh.natoms);
211 snew(man->bVis, sh.natoms);
212 for (i = 0; (i < sh.natoms); i++)
214 man->bVis[i] = FALSE;
219 snew(man->szLab, sh.natoms);
220 snew(man->bHydro, sh.natoms);
222 read_tpx_top(status, NULL, man->box, &man->natom, NULL, NULL, NULL, &man->top);
223 man->gpbc = gmx_rmpbc_init(&man->top.idef, -1, man->natom, man->box);
226 read_first_x(man->oenv, &man->status, trajectory, &(man->time), &(man->x),
228 man->trajfile = strdup(trajectory);
229 if (man->natom > man->top.atoms.nr)
231 gmx_fatal(FARGS, "Topology %s (%d atoms) and trajectory %s (%d atoms) "
232 "do not match", status, man->top.atoms.nr,
233 trajectory, man->natom);
236 cool_quote(quote, 255, NULL);
237 sprintf(buf, "%s: %s", *man->top.name, quote);
238 man->title.text = strdup(buf);
239 man->view = init_view(man->box);
240 at = &(man->top.atoms);
241 aps = gmx_atomprop_init();
242 for (i = 0; (i < man->natom); i++)
244 char *aname = *(at->atomname[i]);
245 t_resinfo *ri = &at->resinfo[at->atom[i].resind];
247 man->col[i] = Type2Color(aname);
248 snew(man->szLab[i], 20);
251 sprintf(man->szLab[i], "%s%d%c, %s", *ri->name, ri->nr, ri->ic, aname);
255 sprintf(man->szLab[i], "%s%d, %s", *ri->name, ri->nr, aname);
257 man->bHydro[i] = (toupper(aname[0]) == 'H');
262 else if (!gmx_atomprop_query(aps, epropVDW, *ri->name, aname, &(man->vdw[i])))
267 gmx_atomprop_destroy(aps);
268 add_bpl(man, &(man->top.idef), bB);
269 for (i = 0; (i < man->natom); i++)
273 add_object(man, eOSingle, (atom_id) i, 0);
278 ExposeWin(x11->disp, man->molw->wd.self);
281 void step_message(t_x11 *x11, t_manager *man)
285 letter.type = ClientMessage;
286 letter.xclient.display = x11->disp;
287 letter.xclient.window = man->wd.self;
288 letter.xclient.message_type = 0;
289 letter.xclient.format = 32;
290 letter.xclient.data.l[0] = IDSTEP;
291 letter.xclient.data.l[1] = Button1;
292 XSendEvent(x11->disp, letter.xclient.window, True, 0, &letter);
295 gmx_bool ReadMonfile(char *fn, int *nbars, int *bars)
298 if ((fp = fopen(fn, "r")) == NULL)
304 for ((*nbars) = 0; fscanf(fp, "%d", &bars[*nbars]) > 0; (*nbars)++)
313 static void reset_mols(t_block *mols, matrix box, rvec x[])
319 for (i = 0; (i < mols->nr); i++)
322 m1 = mols->index[i+1];
327 for (j = m0; (j < m1); j++)
331 for (m = 0; (m < DIM); m++)
335 for (m = 0; (m < DIM); m++)
341 else if (xcm[m] >= box[m][m])
346 ix = icm[XX], iy = icm[YY], iz = icm[ZZ];
348 if ((ix != 0) || (iy != 0) || (iz != 0))
350 for (j = m0; (j < m1); j++)
360 static gmx_bool step_man(t_manager *man, int *nat)
362 static int ncount = 0;
363 static gmx_bool bWarn = FALSE;
370 fprintf(stderr, "Not initiated yet!");
373 bEof = read_next_x(man->oenv, man->status, &man->time, man->natom, man->x, man->box);
375 if (ncount == man->nSkip)
377 switch (man->molw->boxtype)
380 put_atoms_in_triclinic_unitcell(ecenterDEF, man->box, man->natom, man->x);
383 warn = put_atoms_in_compact_unitcell(man->molw->ePBC, ecenterDEF, man->box,
387 fprintf(stderr, "\n%s\n", warn);
398 gmx_rmpbc(man->gpbc, man->natom, man->box, man->x);
399 reset_mols(&(man->top.mols), man->box, man->x);
408 return step_man(man, nat);
415 static void HandleClient(t_x11 *x11, t_manager *man, long data[])
417 int ID, button, x, y;
425 bPos = (button == Button1);
431 rotate_3d(man->view, ID-IDROTX, bPos);
437 fac = 0.8; /* Reduce distance between eye and origin */
444 /* zoom changed to scale by Berk Hess 3-7-96
445 if (zoom_3d(man->view,fac))
446 draw_mol(x11,man); */
447 man->view->sc_x /= fac;
448 man->view->sc_y /= fac;
454 translate_view(man->view, ID-IDTRANSX, bPos);
460 rewind_trj(man->status);
461 read_next_x(man->oenv, man->status, &(man->time), man->natom, man->x,
472 if (!step_man(man, &nat))
482 usleep(man->nWait*1000);
501 show_label(x11, man, x, y);
504 hide_label(x11, man, x, y);
511 if (man->bAnimate && !man->bEof && !man->bStop)
513 step_message(x11, man);
517 static gmx_bool TitleCallBack(t_x11 *x11, XEvent *event, Window w, void *data)
521 wd = (t_windata *)data;
525 if (wd->text && (wd->width > 10))
527 XSetForeground(x11->disp, x11->gc, WHITE);
528 TextInWin(x11, wd, wd->text, eXCenter, eYCenter);
529 XDrawLine(x11->disp, wd->self, x11->gc, 0, wd->height,
530 wd->width, wd->height);
533 case ConfigureNotify:
534 wd->width = event->xconfigure.width;
535 wd->height = event->xconfigure.height;
541 static gmx_bool ManCallBack(t_x11 *x11, XEvent *event, Window w, void *data)
546 man = (t_manager *)data;
549 case ConfigureNotify:
550 width = event->xconfigure.width;
551 height = event->xconfigure.height;
552 if ((width != man->wd.width) || (height != man->wd.height))
554 move_man(x11, man, width, height);
558 HandleClient(x11, man, event->xclient.data.l);
566 void no_labels(t_x11 *x11, t_manager *man)
570 for (i = 0; (i < man->natom); i++)
572 man->bLabel[i] = FALSE;
577 void move_man(t_x11 *x11, t_manager *man, int width, int height)
579 int x0, y0, mw, mh, hb;
583 fprintf(stderr, "Move manager %dx%d\n", width, height);
585 man->wd.width = width;
586 man->wd.height = height;
588 /* Move all subwindows, resize only Mol window */
589 x0 = width-EWIDTH-AIR-4*BORDER; /* Starting of ewin etc. */
593 mw = x0-2*AIR-4*BORDER;
594 mh = height-y0-AIR-2*BORDER;
595 XMoveResizeWindow(x11->disp, man->molw->wd.self, AIR, y0, mw, mh);
598 th = XTextHeight(x11->font);
599 XMoveResizeWindow(x11->disp, man->title.self, 0, 0, mw, th+AIR);
602 XMoveResizeWindow(x11->disp, man->legw->wd.self, x0, y0, EWIDTH, LEGHEIGHT);
603 y0 += LEGHEIGHT+AIR+2*BORDER;
607 printf("Error: Windows falling out of main window!\n");
611 hb = height-y0-AIR-2*BORDER;
612 XMoveResizeWindow(x11->disp, man->bbox->wd.self, x0, y0, EWIDTH, hb);
615 x0 = (mw-man->vbox->wd.width)/2;
616 y0 = (mh-2-AIR-man->vbox->wd.height);
617 XMoveWindow(x11->disp, man->vbox->wd.self, x0, y0);
620 void map_man(t_x11 *x11, t_manager *man)
622 XMapWindow(x11->disp, man->wd.self);
623 map_mw(x11, man->molw);
624 XMapWindow(x11->disp, man->title.self);
625 map_legw(x11, man->legw);
626 show_but(x11, man->bbox);
629 gmx_bool toggle_animate (t_x11 *x11, t_manager *man)
633 man->bAnimate = !man->bAnimate;
638 show_but(x11, man->vbox);
642 hide_but(x11, man->vbox);
645 return man->bAnimate;
648 gmx_bool toggle_pbc (t_manager *man)
650 man->bPbc = !man->bPbc;
656 t_manager *init_man(t_x11 *x11, Window Parent,
657 int x, int y, int width, int height,
658 unsigned long fg, unsigned long bg,
659 int ePBC, matrix box,
660 const output_env_t oenv)
669 InitWin(&(man->wd), x, y, width, height, 0, "Manager");
670 man->wd.self = XCreateSimpleWindow(x11->disp, Parent, man->wd.x, man->wd.y,
671 man->wd.width, man->wd.height,
672 man->wd.bwidth, fg, bg);
673 x11->RegisterCallback(x11, man->wd.self, Parent, ManCallBack, man);
674 x11->SetInputMask(x11, man->wd.self, StructureNotifyMask |
675 ExposureMask | ButtonPressMask);
677 /* The order of creating windows is important for the stacking order */
679 man->molw = init_mw(x11, man->wd.self, 0, 0, 1, 1, WHITE, BLUE, ePBC, box);
682 InitWin(&(man->title), 0, 0, 1, 1, 0, NULL);
683 man->title.self = XCreateSimpleWindow(x11->disp, man->molw->wd.self,
684 man->title.x, man->title.y,
685 man->title.width, man->title.height,
686 man->title.bwidth, WHITE, BLUE);
687 x11->RegisterCallback(x11, man->title.self, man->molw->wd.self,
688 TitleCallBack, &(man->title));
689 x11->SetInputMask(x11, man->title.self, ExposureMask | StructureNotifyMask);
692 man->bbox = init_bbox(x11, man->wd.self, man->wd.self, 1, WHITE, BLUE);
695 man->legw = init_legw(x11, man->wd.self, 0, 0, EWIDTH, LEGHEIGHT, WHITE, BLUE);
698 man->vbox = init_vbox(x11, man->molw->wd.self, man->wd.self, WHITE, BLUE);
703 void done_man(t_x11 *x11, t_manager *man)
705 done_bbox(x11, man->vbox);
706 done_bbox(x11, man->bbox);
707 done_mw(x11, man->molw);
708 done_legw(x11, man->legw);
709 x11->UnRegisterCallback(x11, man->title.self);
710 x11->UnRegisterCallback(x11, man->wd.self);
720 void do_filter(t_x11 *x11, t_manager *man, t_filter *filter)
725 for (i = 0; (i < man->natom); i++)
727 man->bVis[i] = FALSE;
729 for (i = 0; (i < filter->grps->nr); i++)
731 if (filter->bShow[i])
733 for (j = filter->grps->index[i]; (j < filter->grps->index[i+1]); j++)
735 man->bVis[filter->grps->a[j]] = TRUE;
740 ExposeWin(x11->disp, man->wd.self);