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 * Copyright (c) 2013,2014, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
46 #include <unistd.h> // for usleep()
51 #include "gromacs/fileio/tpxio.h"
52 #include "gromacs/legacyheaders/copyrite.h"
53 #include "gromacs/legacyheaders/macros.h"
54 #include "gromacs/legacyheaders/names.h"
55 #include "gromacs/legacyheaders/typedefs.h"
56 #include "gromacs/math/utilities.h"
57 #include "gromacs/math/vec.h"
58 #include "gromacs/pbcutil/pbc.h"
59 #include "gromacs/topology/atomprop.h"
60 #include "gromacs/utility/cstringutil.h"
61 #include "gromacs/utility/futil.h"
62 #include "gromacs/utility/smalloc.h"
67 static void add_object(t_manager *man, eObject eO, atom_id ai, atom_id aj)
69 srenew(man->obj, ++man->nobj);
70 man->obj[man->nobj-1].eO = eO;
71 man->obj[man->nobj-1].eV = eVNormal;
72 man->obj[man->nobj-1].color = WHITE;
73 man->obj[man->nobj-1].ai = ai;
74 man->obj[man->nobj-1].aj = aj;
75 man->obj[man->nobj-1].z = 0.0;
78 static void add_bonds(t_manager *man, t_functype func[],
79 t_ilist *b, bool bB[])
81 bool *bH = man->bHydro;
83 t_iatom type, ai, aj, ak;
87 fprintf(stderr, "Going to make bonds from an ilist with %d entries\n", b->nr);
90 for (i = 0; (i < b->nr); )
95 delta = interaction_function[ftype].nratoms;
97 if (ftype == F_SETTLE)
101 bB[ai] = bB[aj] = bB[ak] = true;
102 add_object(man, eOHBond, ai, aj);
103 add_object(man, eOHBond, ai, ak);
105 else if (IS_CHEMBOND(ftype))
109 fprintf(stderr, "Adding bond from %d to %d\n", ai, aj);
111 bB[ai] = bB[aj] = true;
112 if (!(bH[ai] == bH[aj]))
114 add_object(man, eOHBond, ai, aj);
116 else if (!bH[ai] && !bH[aj])
118 add_object(man, eOBond, ai, aj);
122 fprintf(stderr, "Type: %5d, delta: %5d\n", type, delta);
129 static void add_bpl(t_manager *man, t_idef *idef, bool bB[])
133 for (ftype = 0; ftype < F_NRE; ftype++)
135 if (IS_CHEMBOND(ftype) || ftype == F_SETTLE)
137 add_bonds(man, idef->functype, &idef->il[ftype], bB);
142 static atom_id which_atom(t_manager *man, int x, int y)
148 for (i = 0; (i < man->natom); i++)
150 if ((abs(ix[i][XX]-x) < DELTA) && (abs(ix[i][YY]-y) < DELTA))
161 static void do_label(t_x11 *x11, t_manager *man, int x, int y, bool bSet)
166 if ((ai = which_atom(man, x, y)) != NO_ATID)
170 if (bSet && !man->bLabel[ai])
173 man->bLabel[ai] = true;
175 else if (!bSet && man->bLabel[ai])
178 man->bLabel[ai] = false;
184 XSetForeground(x11->disp, x11->gc, col);
185 XDrawString(x11->disp, man->molw->wd.self, x11->gc, x+2, y-2, man->szLab[ai],
186 strlen(man->szLab[ai]));
187 XSetForeground(x11->disp, x11->gc, x11->fg);
191 static void show_label(t_x11 *x11, t_manager *man, int x, int y)
193 do_label(x11, man, x, y, true);
196 static void hide_label(t_x11 *x11, t_manager *man, int x, int y)
198 do_label(x11, man, x, y, false);
201 void set_file(t_x11 *x11, t_manager *man, const char *trajectory,
205 char buf[256], quote[256];
211 read_tpxheader(status, &sh, true, NULL, NULL);
212 snew(man->ix, sh.natoms);
213 snew(man->zz, sh.natoms);
214 snew(man->col, sh.natoms);
215 snew(man->size, sh.natoms);
216 snew(man->vdw, sh.natoms);
217 snew(man->bLabel, sh.natoms);
218 snew(man->bVis, sh.natoms);
219 for (i = 0; (i < sh.natoms); i++)
221 man->bVis[i] = false;
226 snew(man->szLab, sh.natoms);
227 snew(man->bHydro, sh.natoms);
229 read_tpx_top(status, NULL, man->box, &man->natom, NULL, NULL, NULL, &man->top);
230 man->gpbc = gmx_rmpbc_init(&man->top.idef, -1, man->natom);
233 read_first_x(man->oenv, &man->status, trajectory, &(man->time), &(man->x),
235 man->trajfile = gmx_strdup(trajectory);
236 if (man->natom > man->top.atoms.nr)
238 gmx_fatal(FARGS, "Topology %s (%d atoms) and trajectory %s (%d atoms) "
239 "do not match", status, man->top.atoms.nr,
240 trajectory, man->natom);
243 cool_quote(quote, 255, NULL);
244 sprintf(buf, "%s: %s", *man->top.name, quote);
245 man->title.text = gmx_strdup(buf);
246 man->view = init_view(man->box);
247 at = &(man->top.atoms);
248 aps = gmx_atomprop_init();
249 for (i = 0; (i < man->natom); i++)
251 char *aname = *(at->atomname[i]);
252 t_resinfo *ri = &at->resinfo[at->atom[i].resind];
254 man->col[i] = Type2Color(aname);
255 snew(man->szLab[i], 20);
258 sprintf(man->szLab[i], "%s%d%c, %s", *ri->name, ri->nr, ri->ic, aname);
262 sprintf(man->szLab[i], "%s%d, %s", *ri->name, ri->nr, aname);
264 man->bHydro[i] = (toupper(aname[0]) == 'H');
269 else if (!gmx_atomprop_query(aps, epropVDW, *ri->name, aname, &(man->vdw[i])))
274 gmx_atomprop_destroy(aps);
275 add_bpl(man, &(man->top.idef), bB);
276 for (i = 0; (i < man->natom); i++)
280 add_object(man, eOSingle, (atom_id) i, 0);
285 ExposeWin(x11->disp, man->molw->wd.self);
288 void step_message(t_x11 *x11, t_manager *man)
292 letter.type = ClientMessage;
293 letter.xclient.display = x11->disp;
294 letter.xclient.window = man->wd.self;
295 letter.xclient.message_type = 0;
296 letter.xclient.format = 32;
297 letter.xclient.data.l[0] = IDSTEP;
298 letter.xclient.data.l[1] = Button1;
299 XSendEvent(x11->disp, letter.xclient.window, True, 0, &letter);
302 static void reset_mols(t_block *mols, matrix box, rvec x[])
308 for (i = 0; (i < mols->nr); i++)
311 m1 = mols->index[i+1];
316 for (j = m0; (j < m1); j++)
320 for (m = 0; (m < DIM); m++)
324 for (m = 0; (m < DIM); m++)
330 else if (xcm[m] >= box[m][m])
335 ix = icm[XX], iy = icm[YY], iz = icm[ZZ];
337 if ((ix != 0) || (iy != 0) || (iz != 0))
339 for (j = m0; (j < m1); j++)
349 static bool step_man(t_manager *man, int *nat)
351 static int ncount = 0;
352 static bool bWarn = false;
358 fprintf(stderr, "Not initiated yet!");
361 bEof = read_next_x(man->oenv, man->status, &man->time, man->x, man->box);
363 if (ncount == man->nSkip)
365 switch (man->molw->boxtype)
368 put_atoms_in_triclinic_unitcell(ecenterDEF, man->box, man->natom, man->x);
371 warn = put_atoms_in_compact_unitcell(man->molw->ePBC, ecenterDEF, man->box,
375 fprintf(stderr, "\n%s\n", warn);
386 gmx_rmpbc(man->gpbc, man->natom, man->box, man->x);
387 reset_mols(&(man->top.mols), man->box, man->x);
396 return step_man(man, nat);
403 static void HandleClient(t_x11 *x11, t_manager *man, long data[])
405 int ID, button, x, y;
413 bPos = (button == Button1);
419 rotate_3d(man->view, ID-IDROTX, bPos);
425 fac = 0.8; /* Reduce distance between eye and origin */
432 /* zoom changed to scale by Berk Hess 3-7-96
433 if (zoom_3d(man->view,fac))
434 draw_mol(x11,man); */
435 man->view->sc_x /= fac;
436 man->view->sc_y /= fac;
442 translate_view(man->view, ID-IDTRANSX, bPos);
448 rewind_trj(man->status);
449 read_next_x(man->oenv, man->status, &(man->time), man->x,
460 if (!step_man(man, &nat))
470 usleep(man->nWait*1000);
489 show_label(x11, man, x, y);
492 hide_label(x11, man, x, y);
499 if (man->bAnimate && !man->bEof && !man->bStop)
501 step_message(x11, man);
505 static bool TitleCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data)
509 wd = (t_windata *)data;
513 if (wd->text && (wd->width > 10))
515 XSetForeground(x11->disp, x11->gc, WHITE);
516 TextInWin(x11, wd, wd->text, eXCenter, eYCenter);
517 XDrawLine(x11->disp, wd->self, x11->gc, 0, wd->height,
518 wd->width, wd->height);
521 case ConfigureNotify:
522 wd->width = event->xconfigure.width;
523 wd->height = event->xconfigure.height;
529 static bool ManCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data)
534 man = (t_manager *)data;
537 case ConfigureNotify:
538 width = event->xconfigure.width;
539 height = event->xconfigure.height;
540 if ((width != man->wd.width) || (height != man->wd.height))
542 move_man(x11, man, width, height);
546 HandleClient(x11, man, event->xclient.data.l);
554 void no_labels(t_x11 *x11, t_manager *man)
558 for (i = 0; (i < man->natom); i++)
560 man->bLabel[i] = false;
565 void move_man(t_x11 *x11, t_manager *man, int width, int height)
567 int x0, y0, mw, mh, hb;
571 fprintf(stderr, "Move manager %dx%d\n", width, height);
573 man->wd.width = width;
574 man->wd.height = height;
576 /* Move all subwindows, resize only Mol window */
577 x0 = width-EWIDTH-AIR-4*BORDER; /* Starting of ewin etc. */
581 mw = x0-2*AIR-4*BORDER;
582 mh = height-y0-AIR-2*BORDER;
583 XMoveResizeWindow(x11->disp, man->molw->wd.self, AIR, y0, mw, mh);
586 th = XTextHeight(x11->font);
587 XMoveResizeWindow(x11->disp, man->title.self, 0, 0, mw, th+AIR);
590 XMoveResizeWindow(x11->disp, man->legw->wd.self, x0, y0, EWIDTH, LEGHEIGHT);
591 y0 += LEGHEIGHT+AIR+2*BORDER;
595 printf("Error: Windows falling out of main window!\n");
599 hb = height-y0-AIR-2*BORDER;
600 XMoveResizeWindow(x11->disp, man->bbox->wd.self, x0, y0, EWIDTH, hb);
603 x0 = (mw-man->vbox->wd.width)/2;
604 y0 = (mh-2-AIR-man->vbox->wd.height);
605 XMoveWindow(x11->disp, man->vbox->wd.self, x0, y0);
608 void map_man(t_x11 *x11, t_manager *man)
610 XMapWindow(x11->disp, man->wd.self);
611 map_mw(x11, man->molw);
612 XMapWindow(x11->disp, man->title.self);
613 map_legw(x11, man->legw);
614 show_but(x11, man->bbox);
617 bool toggle_animate (t_x11 *x11, t_manager *man)
621 man->bAnimate = !man->bAnimate;
626 show_but(x11, man->vbox);
630 hide_but(x11, man->vbox);
633 return man->bAnimate;
636 bool toggle_pbc (t_manager *man)
638 man->bPbc = !man->bPbc;
644 t_manager *init_man(t_x11 *x11, Window Parent,
645 int x, int y, int width, int height,
646 unsigned long fg, unsigned long bg,
647 int ePBC, matrix box,
648 const output_env_t oenv)
657 InitWin(&(man->wd), x, y, width, height, 0, "Manager");
658 man->wd.self = XCreateSimpleWindow(x11->disp, Parent, man->wd.x, man->wd.y,
659 man->wd.width, man->wd.height,
660 man->wd.bwidth, fg, bg);
661 x11->RegisterCallback(x11, man->wd.self, Parent, ManCallBack, man);
662 x11->SetInputMask(x11, man->wd.self, StructureNotifyMask |
663 ExposureMask | ButtonPressMask);
665 /* The order of creating windows is important for the stacking order */
667 man->molw = init_mw(x11, man->wd.self, 0, 0, 1, 1, WHITE, BLUE, ePBC, box);
670 InitWin(&(man->title), 0, 0, 1, 1, 0, NULL);
671 man->title.self = XCreateSimpleWindow(x11->disp, man->molw->wd.self,
672 man->title.x, man->title.y,
673 man->title.width, man->title.height,
674 man->title.bwidth, WHITE, BLUE);
675 x11->RegisterCallback(x11, man->title.self, man->molw->wd.self,
676 TitleCallBack, &(man->title));
677 x11->SetInputMask(x11, man->title.self, ExposureMask | StructureNotifyMask);
680 man->bbox = init_bbox(x11, man->wd.self, man->wd.self, 1, WHITE, BLUE);
683 man->legw = init_legw(x11, man->wd.self, 0, 0, EWIDTH, LEGHEIGHT, WHITE, BLUE);
686 man->vbox = init_vbox(x11, man->molw->wd.self, man->wd.self, WHITE, BLUE);
691 void done_man(t_x11 *x11, t_manager *man)
693 done_bbox(x11, man->vbox);
694 done_bbox(x11, man->bbox);
695 done_mw(x11, man->molw);
696 done_legw(x11, man->legw);
697 x11->UnRegisterCallback(x11, man->title.self);
698 x11->UnRegisterCallback(x11, man->wd.self);
708 void do_filter(t_x11 *x11, t_manager *man, t_filter *filter)
713 for (i = 0; (i < man->natom); i++)
715 man->bVis[i] = false;
717 for (i = 0; (i < filter->grps->nr); i++)
719 if (filter->bShow[i])
721 for (j = filter->grps->index[i]; (j < filter->grps->index[i+1]); j++)
723 man->bVis[filter->grps->a[j]] = true;
728 ExposeWin(x11->disp, man->wd.self);