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.
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
;
79 t_iatom type
, ai
, aj
, ak
;
83 fprintf(stderr
, "Going to make bonds from an ilist with %d entries\n", b
->nr
);
86 for (i
= 0; (i
< b
->nr
); )
91 delta
= interaction_function
[ftype
].nratoms
;
93 if (ftype
== F_SETTLE
)
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
))
105 fprintf(stderr
, "Adding bond from %d to %d\n", ai
, aj
);
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
);
118 fprintf(stderr
, "Type: %5d, delta: %5d\n", type
, delta
);
125 static void add_bpl(t_manager
*man
, t_idef
*idef
, gmx_bool bB
[])
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
)
144 for (i
= 0; (i
< man
->natom
); i
++)
146 if ((abs(ix
[i
][XX
]-x
) < DELTA
) && (abs(ix
[i
][YY
]-y
) < DELTA
))
157 static void do_label(t_x11
*x11
, t_manager
*man
, int x
, int y
, gmx_bool bSet
)
162 if ((ai
= which_atom(man
, x
, y
)) != NO_ATID
)
166 if (bSet
&& !man
->bLabel
[ai
])
169 man
->bLabel
[ai
] = TRUE
;
171 else if (!bSet
&& man
->bLabel
[ai
])
174 man
->bLabel
[ai
] = FALSE
;
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
,
201 char buf
[256], quote
[256];
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
;
222 snew(man
->szLab
, sh
.natoms
);
223 snew(man
->bHydro
, 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
);
229 read_first_x(man
->oenv
, &man
->status
, trajectory
, &(man
->time
), &(man
->x
),
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);
254 sprintf(man
->szLab
[i
], "%s%d%c, %s", *ri
->name
, ri
->nr
, ri
->ic
, aname
);
258 sprintf(man
->szLab
[i
], "%s%d, %s", *ri
->name
, ri
->nr
, aname
);
260 man
->bHydro
[i
] = (toupper(aname
[0]) == 'H');
265 else if (!gmx_atomprop_query(aps
, epropVDW
, *ri
->name
, aname
, &(man
->vdw
[i
])))
270 gmx_atomprop_destroy(aps
);
271 add_bpl(man
, &(man
->top
.idef
), bB
);
272 for (i
= 0; (i
< man
->natom
); i
++)
276 add_object(man
, eOSingle
, (atom_id
) i
, 0);
281 ExposeWin(x11
->disp
, man
->molw
->wd
.self
);
284 void step_message(t_x11
*x11
, t_manager
*man
)
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
)
301 if ((fp
= fopen(fn
, "r")) == NULL
)
307 for ((*nbars
) = 0; fscanf(fp
, "%d", &bars
[*nbars
]) > 0; (*nbars
)++)
316 static void reset_mols(t_block
*mols
, matrix box
, rvec x
[])
322 for (i
= 0; (i
< mols
->nr
); i
++)
325 m1
= mols
->index
[i
+1];
330 for (j
= m0
; (j
< m1
); j
++)
334 for (m
= 0; (m
< DIM
); m
++)
338 for (m
= 0; (m
< DIM
); m
++)
344 else if (xcm
[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
++)
363 static gmx_bool
step_man(t_manager
*man
, int *nat
)
365 static int ncount
= 0;
366 static gmx_bool bWarn
= FALSE
;
373 fprintf(stderr
, "Not initiated yet!");
376 bEof
= read_next_x(man
->oenv
, man
->status
, &man
->time
, man
->natom
, man
->x
, man
->box
);
378 if (ncount
== man
->nSkip
)
380 switch (man
->molw
->boxtype
)
383 put_atoms_in_triclinic_unitcell(ecenterDEF
, man
->box
, man
->natom
, man
->x
);
386 warn
= put_atoms_in_compact_unitcell(man
->molw
->ePBC
, ecenterDEF
, man
->box
,
390 fprintf(stderr
, "\n%s\n", warn
);
401 gmx_rmpbc(man
->gpbc
, man
->natom
, man
->box
, man
->x
);
402 reset_mols(&(man
->top
.mols
), man
->box
, man
->x
);
411 return step_man(man
, nat
);
418 static void HandleClient(t_x11
*x11
, t_manager
*man
, long data
[])
420 int ID
, button
, x
, y
;
428 bPos
= (button
== Button1
);
434 rotate_3d(man
->view
, ID
-IDROTX
, bPos
);
440 fac
= 0.8; /* Reduce distance between eye and origin */
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
;
457 translate_view(man
->view
, ID
-IDTRANSX
, bPos
);
463 rewind_trj(man
->status
);
464 read_next_x(man
->oenv
, man
->status
, &(man
->time
), man
->natom
, man
->x
,
475 if (!step_man(man
, &nat
))
485 usleep(man
->nWait
*1000);
504 show_label(x11
, man
, x
, y
);
507 hide_label(x11
, man
, x
, y
);
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
)
524 wd
= (t_windata
*)data
;
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
);
536 case ConfigureNotify
:
537 wd
->width
= event
->xconfigure
.width
;
538 wd
->height
= event
->xconfigure
.height
;
544 static gmx_bool
ManCallBack(t_x11
*x11
, XEvent
*event
, Window w
, void *data
)
549 man
= (t_manager
*)data
;
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
);
561 HandleClient(x11
, man
, event
->xclient
.data
.l
);
569 void no_labels(t_x11
*x11
, t_manager
*man
)
573 for (i
= 0; (i
< man
->natom
); i
++)
575 man
->bLabel
[i
] = FALSE
;
580 void move_man(t_x11
*x11
, t_manager
*man
, int width
, int height
)
582 int x0
, y0
, mw
, mh
, hb
;
586 fprintf(stderr
, "Move manager %dx%d\n", width
, height
);
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. */
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
);
601 th
= XTextHeight(x11
->font
);
602 XMoveResizeWindow(x11
->disp
, man
->title
.self
, 0, 0, mw
, th
+AIR
);
605 XMoveResizeWindow(x11
->disp
, man
->legw
->wd
.self
, x0
, y0
, EWIDTH
, LEGHEIGHT
);
606 y0
+= LEGHEIGHT
+AIR
+2*BORDER
;
610 printf("Error: Windows falling out of main window!\n");
614 hb
= height
-y0
-AIR
-2*BORDER
;
615 XMoveResizeWindow(x11
->disp
, man
->bbox
->wd
.self
, x0
, y0
, EWIDTH
, hb
);
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
)
636 man
->bAnimate
= !man
->bAnimate
;
641 show_but(x11
, man
->vbox
);
645 hide_but(x11
, man
->vbox
);
648 return man
->bAnimate
;
651 gmx_bool
toggle_pbc (t_manager
*man
)
653 man
->bPbc
= !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
)
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 */
682 man
->molw
= init_mw(x11
, man
->wd
.self
, 0, 0, 1, 1, WHITE
, BLUE
, ePBC
, box
);
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
);
695 man
->bbox
= init_bbox(x11
, man
->wd
.self
, man
->wd
.self
, 1, WHITE
, BLUE
);
698 man
->legw
= init_legw(x11
, man
->wd
.self
, 0, 0, EWIDTH
, LEGHEIGHT
, WHITE
, BLUE
);
701 man
->vbox
= init_vbox(x11
, man
->molw
->wd
.self
, man
->wd
.self
, WHITE
, BLUE
);
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
);
723 void do_filter(t_x11
*x11
, t_manager
*man
, t_filter
*filter
)
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
);