Fix detection of i386 in tmpi
[gromacs/AngularHB.git] / src / ngmx / manager.c
blob1dce3dbb562c36195432247882c8c5e3f60047e9
1 /*
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.
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
42 #include <sysstuff.h>
43 #include <string.h>
44 #include <smalloc.h>
45 #include <ctype.h>
46 #include <typedefs.h>
47 #include <smalloc.h>
48 #include <tpxio.h>
49 #include <macros.h>
50 #include <maths.h>
51 #include <atomprop.h>
52 #include <names.h>
53 #include "manager.h"
54 #include "futil.h"
55 #include "pbc.h"
56 #include "nmol.h"
57 #include "copyrite.h"
58 #include "gstat.h"
59 #include "vec.h"
60 #include "statutil.h"
61 #include "string2.h"
63 static void add_object(t_manager *man, eObject eO, atom_id ai, atom_id aj)
65 srenew(man->obj, ++man->nobj);
66 man->obj[man->nobj-1].eO = eO;
67 man->obj[man->nobj-1].eV = eVNormal;
68 man->obj[man->nobj-1].color = WHITE;
69 man->obj[man->nobj-1].ai = ai;
70 man->obj[man->nobj-1].aj = aj;
71 man->obj[man->nobj-1].z = 0.0;
74 static void add_bonds(t_manager *man, t_functype func[],
75 t_ilist *b, gmx_bool bB[])
77 gmx_bool *bH = man->bHydro;
78 t_iatom *ia;
79 t_iatom type, ai, aj, ak;
80 int i, delta, ftype;
82 #ifdef DEBUG
83 fprintf(stderr, "Going to make bonds from an ilist with %d entries\n", b->nr);
84 #endif
85 ia = b->iatoms;
86 for (i = 0; (i < b->nr); )
88 type = ia[0];
89 ai = ia[1];
90 ftype = func[type];
91 delta = interaction_function[ftype].nratoms;
93 if (ftype == F_SETTLE)
95 aj = ia[2];
96 ak = ia[3];
97 bB[ai] = bB[aj] = bB[ak] = TRUE;
98 add_object(man, eOHBond, ai, aj);
99 add_object(man, eOHBond, ai, ak);
101 else if (IS_CHEMBOND(ftype))
103 aj = ia[2];
104 #ifdef DEBUG
105 fprintf(stderr, "Adding bond from %d to %d\n", ai, aj);
106 #endif
107 bB[ai] = bB[aj] = TRUE;
108 if (!(bH[ai] == bH[aj]))
110 add_object(man, eOHBond, ai, aj);
112 else if (!bH[ai] && !bH[aj])
114 add_object(man, eOBond, ai, aj);
117 #ifdef DEBUG
118 fprintf(stderr, "Type: %5d, delta: %5d\n", type, delta);
119 #endif
120 ia += delta+1;
121 i += delta+1;
125 static void add_bpl(t_manager *man, t_idef *idef, gmx_bool bB[])
127 int ftype;
129 for (ftype = 0; ftype < F_NRE; ftype++)
131 if (IS_CHEMBOND(ftype) || ftype == F_SETTLE)
133 add_bonds(man, idef->functype, &idef->il[ftype], bB);
138 static atom_id which_atom(t_manager *man, int x, int y)
140 #define DELTA 5
141 int i;
142 iv2 *ix = man->ix;
144 for (i = 0; (i < man->natom); i++)
146 if ((abs(ix[i][XX]-x) < DELTA) && (abs(ix[i][YY]-y) < DELTA))
148 if (man->bVis[i])
150 return (atom_id) i;
154 return NO_ATID;
157 static void do_label(t_x11 *x11, t_manager *man, int x, int y, gmx_bool bSet)
159 atom_id ai;
160 unsigned long col;
162 if ((ai = which_atom(man, x, y)) != NO_ATID)
164 x = man->ix[ai][XX];
165 y = man->ix[ai][YY];
166 if (bSet && !man->bLabel[ai])
168 col = WHITE;
169 man->bLabel[ai] = TRUE;
171 else if (!bSet && man->bLabel[ai])
173 col = BLUE;
174 man->bLabel[ai] = FALSE;
176 else
178 return;
180 XSetForeground(x11->disp, x11->gc, col);
181 XDrawString(x11->disp, man->molw->wd.self, x11->gc, x+2, y-2, man->szLab[ai],
182 strlen(man->szLab[ai]));
183 XSetForeground(x11->disp, x11->gc, x11->fg);
187 static void show_label(t_x11 *x11, t_manager *man, int x, int y)
189 do_label(x11, man, x, y, TRUE);
192 static void hide_label(t_x11 *x11, t_manager *man, int x, int y)
194 do_label(x11, man, x, y, FALSE);
197 void set_file(t_x11 *x11, t_manager *man, const char *trajectory,
198 const char *status)
200 gmx_atomprop_t aps;
201 char buf[256], quote[256];
202 t_tpxheader sh;
203 t_atoms *at;
204 gmx_bool *bB;
205 int i, idum;
207 read_tpxheader(status, &sh, TRUE, NULL, NULL);
208 snew(man->ix, sh.natoms);
209 snew(man->zz, sh.natoms);
210 snew(man->col, sh.natoms);
211 snew(man->size, sh.natoms);
212 snew(man->vdw, sh.natoms);
213 snew(man->bLabel, sh.natoms);
214 snew(man->bVis, sh.natoms);
215 for (i = 0; (i < sh.natoms); i++)
217 man->bVis[i] = FALSE;
220 man->bPbc = FALSE;
222 snew(man->szLab, sh.natoms);
223 snew(man->bHydro, sh.natoms);
224 snew(bB, sh.natoms);
225 read_tpx_top(status, NULL, man->box, &man->natom, NULL, NULL, NULL, &man->top);
226 man->gpbc = gmx_rmpbc_init(&man->top.idef, -1, man->natom, man->box);
228 man->natom =
229 read_first_x(man->oenv, &man->status, trajectory, &(man->time), &(man->x),
230 man->box);
231 man->trajfile = strdup(trajectory);
232 if (man->natom > man->top.atoms.nr)
234 gmx_fatal(FARGS, "Topology %s (%d atoms) and trajectory %s (%d atoms) "
235 "do not match", status, man->top.atoms.nr,
236 trajectory, man->natom);
239 cool_quote(quote, 255, NULL);
240 sprintf(buf, "%s: %s", *man->top.name, quote);
241 man->title.text = strdup(buf);
242 man->view = init_view(man->box);
243 at = &(man->top.atoms);
244 aps = gmx_atomprop_init();
245 for (i = 0; (i < man->natom); i++)
247 char *aname = *(at->atomname[i]);
248 t_resinfo *ri = &at->resinfo[at->atom[i].resind];
250 man->col[i] = Type2Color(aname);
251 snew(man->szLab[i], 20);
252 if (ri->ic != ' ')
254 sprintf(man->szLab[i], "%s%d%c, %s", *ri->name, ri->nr, ri->ic, aname);
256 else
258 sprintf(man->szLab[i], "%s%d, %s", *ri->name, ri->nr, aname);
260 man->bHydro[i] = (toupper(aname[0]) == 'H');
261 if (man->bHydro[i])
263 man->vdw[i] = 0;
265 else if (!gmx_atomprop_query(aps, epropVDW, *ri->name, aname, &(man->vdw[i])))
267 man->vdw[i] = 0;
270 gmx_atomprop_destroy(aps);
271 add_bpl(man, &(man->top.idef), bB);
272 for (i = 0; (i < man->natom); i++)
274 if (!bB[i])
276 add_object(man, eOSingle, (atom_id) i, 0);
279 sfree(bB);
281 ExposeWin(x11->disp, man->molw->wd.self);
284 void step_message(t_x11 *x11, t_manager *man)
286 XEvent letter;
288 letter.type = ClientMessage;
289 letter.xclient.display = x11->disp;
290 letter.xclient.window = man->wd.self;
291 letter.xclient.message_type = 0;
292 letter.xclient.format = 32;
293 letter.xclient.data.l[0] = IDSTEP;
294 letter.xclient.data.l[1] = Button1;
295 XSendEvent(x11->disp, letter.xclient.window, True, 0, &letter);
298 gmx_bool ReadMonfile(char *fn, int *nbars, int *bars)
300 FILE *fp;
301 if ((fp = fopen(fn, "r")) == NULL)
303 return(FALSE);
305 else
307 for ((*nbars) = 0; fscanf(fp, "%d", &bars[*nbars]) > 0; (*nbars)++)
311 fclose(fp);
312 return (TRUE);
316 static void reset_mols(t_block *mols, matrix box, rvec x[])
318 int i, m0, m1, j, m;
319 rvec xcm, icm;
320 real ix, iy, iz;
322 for (i = 0; (i < mols->nr); i++)
324 m0 = mols->index[i];
325 m1 = mols->index[i+1];
327 clear_rvec(xcm);
328 clear_rvec(icm);
330 for (j = m0; (j < m1); j++)
332 rvec_inc(xcm, x[j]);
334 for (m = 0; (m < DIM); m++)
336 xcm[m] /= (m1-m0);
338 for (m = 0; (m < DIM); m++)
340 if (xcm[m] < 0)
342 icm[m] = box[m][m];
344 else if (xcm[m] >= box[m][m])
346 icm[m] = -box[m][m];
349 ix = icm[XX], iy = icm[YY], iz = icm[ZZ];
351 if ((ix != 0) || (iy != 0) || (iz != 0))
353 for (j = m0; (j < m1); j++)
355 x[j][XX] += ix;
356 x[j][YY] += iy;
357 x[j][ZZ] += iz;
363 static gmx_bool step_man(t_manager *man, int *nat)
365 static int ncount = 0;
366 static gmx_bool bWarn = FALSE;
367 gmx_bool bEof;
368 int dum;
369 const char *warn;
371 if (!man->natom)
373 fprintf(stderr, "Not initiated yet!");
374 exit(1);
376 bEof = read_next_x(man->oenv, man->status, &man->time, man->natom, man->x, man->box);
377 *nat = man->natom;
378 if (ncount == man->nSkip)
380 switch (man->molw->boxtype)
382 case esbTri:
383 put_atoms_in_triclinic_unitcell(ecenterDEF, man->box, man->natom, man->x);
384 break;
385 case esbTrunc:
386 warn = put_atoms_in_compact_unitcell(man->molw->ePBC, ecenterDEF, man->box,
387 man->natom, man->x);
388 if (warn && !bWarn)
390 fprintf(stderr, "\n%s\n", warn);
391 bWarn = TRUE;
393 break;
394 case esbRect:
395 case esbNone:
396 default:
397 break;
399 if (man->bPbc)
401 gmx_rmpbc(man->gpbc, man->natom, man->box, man->x);
402 reset_mols(&(man->top.mols), man->box, man->x);
404 ncount = 0;
406 else
408 if (man->nSkip > 0)
410 ncount++;
411 return step_man(man, nat);
415 return bEof;
418 static void HandleClient(t_x11 *x11, t_manager *man, long data[])
420 int ID, button, x, y;
421 gmx_bool bPos;
422 real fac;
424 ID = data[0];
425 button = data[1];
426 x = data[2];
427 y = data[3];
428 bPos = (button == Button1);
429 switch (ID)
431 case IDROTX:
432 case IDROTY:
433 case IDROTZ:
434 rotate_3d(man->view, ID-IDROTX, bPos);
435 draw_mol(x11, man);
436 break;
437 case IDZOOM:
438 if (bPos)
440 fac = 0.8; /* Reduce distance between eye and origin */
442 else
444 fac = 1.25;
447 /* zoom changed to scale by Berk Hess 3-7-96
448 if (zoom_3d(man->view,fac))
449 draw_mol(x11,man); */
450 man->view->sc_x /= fac;
451 man->view->sc_y /= fac;
452 draw_mol(x11, man);
453 break;
454 case IDTRANSX:
455 case IDTRANSY:
456 case IDTRANSZ:
457 translate_view(man->view, ID-IDTRANSX, bPos);
458 draw_mol(x11, man);
459 break;
460 case IDREWIND:
461 if (man->status)
463 rewind_trj(man->status);
464 read_next_x(man->oenv, man->status, &(man->time), man->natom, man->x,
465 man->box);
466 man->bEof = FALSE;
467 draw_mol(x11, man);
469 break;
470 case IDSTEP:
472 int nat;
474 nat = 0;
475 if (!step_man(man, &nat))
477 man->bEof = TRUE;
478 man->bStop = TRUE;
480 else
482 if (nat > 0)
484 draw_mol(x11, man);
485 usleep(man->nWait*1000);
488 break;
490 case IDFF:
491 man->bStop = FALSE;
492 break;
493 case IDSTOP_ANI:
494 man->bStop = TRUE;
495 break;
496 case IDDRAWMOL:
497 draw_mol(x11, man);
498 break;
499 case IDLABEL:
500 switch (button)
502 case Button1:
503 case Button2:
504 show_label(x11, man, x, y);
505 break;
506 case Button3:
507 hide_label(x11, man, x, y);
508 break;
510 break;
511 default:
512 break;
514 if (man->bAnimate && !man->bEof && !man->bStop)
516 step_message(x11, man);
520 static gmx_bool TitleCallBack(t_x11 *x11, XEvent *event, Window w, void *data)
522 t_windata *wd;
524 wd = (t_windata *)data;
525 switch (event->type)
527 case Expose:
528 if (wd->text && (wd->width > 10))
530 XSetForeground(x11->disp, x11->gc, WHITE);
531 TextInWin(x11, wd, wd->text, eXCenter, eYCenter);
532 XDrawLine(x11->disp, wd->self, x11->gc, 0, wd->height,
533 wd->width, wd->height);
535 break;
536 case ConfigureNotify:
537 wd->width = event->xconfigure.width;
538 wd->height = event->xconfigure.height;
539 break;
541 return FALSE;
544 static gmx_bool ManCallBack(t_x11 *x11, XEvent *event, Window w, void *data)
546 t_manager *man;
547 int width, height;
549 man = (t_manager *)data;
550 switch (event->type)
552 case ConfigureNotify:
553 width = event->xconfigure.width;
554 height = event->xconfigure.height;
555 if ((width != man->wd.width) || (height != man->wd.height))
557 move_man(x11, man, width, height);
559 break;
560 case ClientMessage:
561 HandleClient(x11, man, event->xclient.data.l);
562 break;
563 default:
564 break;
566 return FALSE;
569 void no_labels(t_x11 *x11, t_manager *man)
571 int i;
573 for (i = 0; (i < man->natom); i++)
575 man->bLabel[i] = FALSE;
577 draw_mol(x11, man);
580 void move_man(t_x11 *x11, t_manager *man, int width, int height)
582 int x0, y0, mw, mh, hb;
583 int th;
585 #ifdef DEBUG
586 fprintf(stderr, "Move manager %dx%d\n", width, height);
587 #endif
588 man->wd.width = width;
589 man->wd.height = height;
591 /* Move all subwindows, resize only Mol window */
592 x0 = width-EWIDTH-AIR-4*BORDER; /* Starting of ewin etc. */
593 y0 = AIR;
595 /* Mol Window */
596 mw = x0-2*AIR-4*BORDER;
597 mh = height-y0-AIR-2*BORDER;
598 XMoveResizeWindow(x11->disp, man->molw->wd.self, AIR, y0, mw, mh);
600 /* Title Window */
601 th = XTextHeight(x11->font);
602 XMoveResizeWindow(x11->disp, man->title.self, 0, 0, mw, th+AIR);
604 /* Legend Window */
605 XMoveResizeWindow(x11->disp, man->legw->wd.self, x0, y0, EWIDTH, LEGHEIGHT);
606 y0 += LEGHEIGHT+AIR+2*BORDER;
608 if (y0 > height)
610 printf("Error: Windows falling out of main window!\n");
613 /* Button Box */
614 hb = height-y0-AIR-2*BORDER;
615 XMoveResizeWindow(x11->disp, man->bbox->wd.self, x0, y0, EWIDTH, hb);
617 /* Video Box */
618 x0 = (mw-man->vbox->wd.width)/2;
619 y0 = (mh-2-AIR-man->vbox->wd.height);
620 XMoveWindow(x11->disp, man->vbox->wd.self, x0, y0);
623 void map_man(t_x11 *x11, t_manager *man)
625 XMapWindow(x11->disp, man->wd.self);
626 map_mw(x11, man->molw);
627 XMapWindow(x11->disp, man->title.self);
628 map_legw(x11, man->legw);
629 show_but(x11, man->bbox);
632 gmx_bool toggle_animate (t_x11 *x11, t_manager *man)
634 if (man->status)
636 man->bAnimate = !man->bAnimate;
637 man->bStop = TRUE;
638 man->bEof = FALSE;
639 if (man->bAnimate)
641 show_but(x11, man->vbox);
643 else
645 hide_but(x11, man->vbox);
648 return man->bAnimate;
651 gmx_bool toggle_pbc (t_manager *man)
653 man->bPbc = !man->bPbc;
655 return man->bPbc;
659 t_manager *init_man(t_x11 *x11, Window Parent,
660 int x, int y, int width, int height,
661 unsigned long fg, unsigned long bg,
662 int ePBC, matrix box,
663 const output_env_t oenv)
665 t_manager *man;
667 snew(man, 1);
668 man->status = NULL;
669 man->bPlus = TRUE;
670 man->bSort = TRUE;
671 man->oenv = oenv;
672 InitWin(&(man->wd), x, y, width, height, 0, "Manager");
673 man->wd.self = XCreateSimpleWindow(x11->disp, Parent, man->wd.x, man->wd.y,
674 man->wd.width, man->wd.height,
675 man->wd.bwidth, fg, bg);
676 x11->RegisterCallback(x11, man->wd.self, Parent, ManCallBack, man);
677 x11->SetInputMask(x11, man->wd.self, StructureNotifyMask |
678 ExposureMask | ButtonPressMask);
680 /* The order of creating windows is important for the stacking order */
681 /* Mol Window */
682 man->molw = init_mw(x11, man->wd.self, 0, 0, 1, 1, WHITE, BLUE, ePBC, box);
684 /* Title Window */
685 InitWin(&(man->title), 0, 0, 1, 1, 0, NULL);
686 man->title.self = XCreateSimpleWindow(x11->disp, man->molw->wd.self,
687 man->title.x, man->title.y,
688 man->title.width, man->title.height,
689 man->title.bwidth, WHITE, BLUE);
690 x11->RegisterCallback(x11, man->title.self, man->molw->wd.self,
691 TitleCallBack, &(man->title));
692 x11->SetInputMask(x11, man->title.self, ExposureMask | StructureNotifyMask);
694 /* Button box */
695 man->bbox = init_bbox(x11, man->wd.self, man->wd.self, 1, WHITE, BLUE);
697 /* Legend Window */
698 man->legw = init_legw(x11, man->wd.self, 0, 0, EWIDTH, LEGHEIGHT, WHITE, BLUE);
700 /* Video Box */
701 man->vbox = init_vbox(x11, man->molw->wd.self, man->wd.self, WHITE, BLUE);
703 return man;
706 void done_man(t_x11 *x11, t_manager *man)
708 done_bbox(x11, man->vbox);
709 done_bbox(x11, man->bbox);
710 done_mw(x11, man->molw);
711 done_legw(x11, man->legw);
712 x11->UnRegisterCallback(x11, man->title.self);
713 x11->UnRegisterCallback(x11, man->wd.self);
714 sfree(man->x);
715 sfree(man->obj);
716 sfree(man->bHydro);
717 sfree(man->bLabel);
718 sfree(man->szLab);
719 sfree(man->col);
720 sfree(man);
723 void do_filter(t_x11 *x11, t_manager *man, t_filter *filter)
725 int i;
726 atom_id j;
728 for (i = 0; (i < man->natom); i++)
730 man->bVis[i] = FALSE;
732 for (i = 0; (i < filter->grps->nr); i++)
734 if (filter->bShow[i])
736 for (j = filter->grps->index[i]; (j < filter->grps->index[i+1]); j++)
738 man->bVis[filter->grps->a[j]] = TRUE;
743 ExposeWin(x11->disp, man->wd.self);