Re-organize BlueGene toolchain files
[gromacs.git] / src / ngmx / manager.c
blob396cd7a6e39e9cf777522396d0dbe61ff7b76253
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, 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); ) {
87 type = ia[0];
88 ai = ia[1];
89 ftype = func[type];
90 delta = interaction_function[ftype].nratoms;
92 if (ftype == F_SETTLE) {
93 aj = ia[2];
94 ak = ia[3];
95 bB[ai]=bB[aj]=bB[ak]=TRUE;
96 add_object(man,eOHBond,ai,aj);
97 add_object(man,eOHBond,ai,ak);
99 else if (IS_CHEMBOND(ftype)) {
100 aj=ia[2];
101 #ifdef DEBUG
102 fprintf(stderr,"Adding bond from %d to %d\n",ai,aj);
103 #endif
104 bB[ai]=bB[aj]=TRUE;
105 if (!(bH[ai] == bH[aj]))
106 add_object(man,eOHBond,ai,aj);
107 else if (!bH[ai] && !bH[aj])
108 add_object(man,eOBond,ai,aj);
110 #ifdef DEBUG
111 fprintf(stderr,"Type: %5d, delta: %5d\n",type,delta);
112 #endif
113 ia += delta+1;
114 i += delta+1;
118 static void add_bpl(t_manager *man,t_idef *idef,gmx_bool bB[])
120 int ftype;
122 for(ftype=0; ftype<F_NRE; ftype++)
123 if (IS_CHEMBOND(ftype) || ftype==F_SETTLE)
124 add_bonds(man,idef->functype,&idef->il[ftype],bB);
127 static atom_id which_atom(t_manager *man,int x, int y)
129 #define DELTA 5
130 int i;
131 iv2 *ix=man->ix;
133 for(i=0; (i<man->natom); i++) {
134 if ((abs(ix[i][XX]-x) < DELTA) && (abs(ix[i][YY]-y) < DELTA)) {
135 if (man->bVis[i])
136 return (atom_id) i;
139 return NO_ATID;
142 static void do_label(t_x11 *x11,t_manager *man,int x,int y,gmx_bool bSet)
144 atom_id ai;
145 unsigned long col;
147 if ((ai=which_atom(man,x,y)) != NO_ATID) {
148 x=man->ix[ai][XX];
149 y=man->ix[ai][YY];
150 if (bSet && !man->bLabel[ai]) {
151 col=WHITE;
152 man->bLabel[ai]=TRUE;
154 else if (!bSet && man->bLabel[ai]) {
155 col=BLUE;
156 man->bLabel[ai]=FALSE;
158 else
159 return;
160 XSetForeground(x11->disp,x11->gc,col);
161 XDrawString(x11->disp,man->molw->wd.self,x11->gc,x+2,y-2,man->szLab[ai],
162 strlen(man->szLab[ai]));
163 XSetForeground(x11->disp,x11->gc,x11->fg);
167 static void show_label(t_x11 *x11,t_manager *man,int x,int y)
169 do_label(x11,man,x,y,TRUE);
172 static void hide_label(t_x11 *x11,t_manager *man,int x,int y)
174 do_label(x11,man,x,y,FALSE);
177 void set_file(t_x11 *x11,t_manager *man,const char *trajectory,
178 const char *status)
180 gmx_atomprop_t aps;
181 char buf[256],quote[256];
182 t_tpxheader sh;
183 t_atoms *at;
184 gmx_bool *bB;
185 int i,idum;
187 read_tpxheader(status,&sh,TRUE,NULL,NULL);
188 snew(man->ix,sh.natoms);
189 snew(man->zz,sh.natoms);
190 snew(man->col,sh.natoms);
191 snew(man->size,sh.natoms);
192 snew(man->vdw,sh.natoms);
193 snew(man->bLabel,sh.natoms);
194 snew(man->bVis,sh.natoms);
195 for(i=0; (i<sh.natoms); i++)
196 man->bVis[i]=FALSE;
198 man->bPbc=FALSE;
200 snew(man->szLab,sh.natoms);
201 snew(man->bHydro,sh.natoms);
202 snew(bB,sh.natoms);
203 read_tpx_top(status,NULL,man->box,&man->natom,NULL,NULL,NULL,&man->top);
204 man->gpbc = gmx_rmpbc_init(&man->top.idef,-1,man->natom,man->box);
206 man->natom=
207 read_first_x(man->oenv,&man->status,trajectory,&(man->time),&(man->x),
208 man->box);
209 man->trajfile=strdup(trajectory);
210 if (man->natom > man->top.atoms.nr)
211 gmx_fatal(FARGS,"Topology %s (%d atoms) and trajectory %s (%d atoms) "
212 "do not match",status,man->top.atoms.nr,
213 trajectory,man->natom);
215 cool_quote(quote,255,NULL);
216 sprintf(buf,"%s: %s",*man->top.name,quote);
217 man->title.text = strdup(buf);
218 man->view = init_view(man->box);
219 at = &(man->top.atoms);
220 aps = gmx_atomprop_init();
221 for(i=0; (i<man->natom); i++) {
222 char *aname=*(at->atomname[i]);
223 t_resinfo *ri=&at->resinfo[at->atom[i].resind];
225 man->col[i]=Type2Color(aname);
226 snew(man->szLab[i],20);
227 if (ri->ic != ' ') {
228 sprintf(man->szLab[i],"%s%d%c, %s",*ri->name,ri->nr,ri->ic,aname);
229 } else {
230 sprintf(man->szLab[i],"%s%d, %s",*ri->name,ri->nr,aname);
232 man->bHydro[i]=(toupper(aname[0])=='H');
233 if ( man->bHydro[i] )
234 man->vdw[i]=0;
235 else if (!gmx_atomprop_query(aps,epropVDW,*ri->name,aname,&(man->vdw[i])))
236 man->vdw[i] = 0;
238 gmx_atomprop_destroy(aps);
239 add_bpl(man,&(man->top.idef),bB);
240 for(i=0; (i<man->natom); i++)
241 if (!bB[i])
242 add_object(man,eOSingle,(atom_id) i,0);
243 sfree(bB);
245 ExposeWin(x11->disp,man->molw->wd.self);
248 void step_message(t_x11 *x11,t_manager *man)
250 XEvent letter;
252 letter.type=ClientMessage;
253 letter.xclient.display=x11->disp;
254 letter.xclient.window=man->wd.self;
255 letter.xclient.message_type=0;
256 letter.xclient.format=32;
257 letter.xclient.data.l[0]=IDSTEP;
258 letter.xclient.data.l[1]=Button1;
259 XSendEvent(x11->disp,letter.xclient.window,True,0,&letter);
262 gmx_bool ReadMonfile(char *fn,int *nbars, int *bars)
264 FILE *fp;
265 if ((fp = fopen(fn,"r"))==NULL)
266 return(FALSE);
267 else {
268 for((*nbars)=0; fscanf(fp,"%d",&bars[*nbars])>0; (*nbars)++)
270 fclose(fp);
271 return (TRUE);
275 static void reset_mols(t_block *mols,matrix box,rvec x[])
277 int i,m0,m1,j,m;
278 rvec xcm,icm;
279 real ix,iy,iz;
281 for(i=0; (i<mols->nr); i++) {
282 m0=mols->index[i];
283 m1=mols->index[i+1];
285 clear_rvec(xcm);
286 clear_rvec(icm);
288 for(j=m0; (j<m1); j++) {
289 rvec_inc(xcm,x[j]);
291 for(m=0; (m<DIM); m++)
292 xcm[m]/=(m1-m0);
293 for(m=0; (m<DIM); m++) {
294 if (xcm[m] < 0)
295 icm[m]=box[m][m];
296 else if (xcm[m] >= box[m][m])
297 icm[m]=-box[m][m];
299 ix=icm[XX],iy=icm[YY],iz=icm[ZZ];
301 if ((ix != 0) || (iy != 0) || (iz != 0)) {
302 for(j=m0; (j<m1); j++) {
303 x[j][XX]+=ix;
304 x[j][YY]+=iy;
305 x[j][ZZ]+=iz;
311 static gmx_bool step_man(t_manager *man,int *nat)
313 static int ncount=0;
314 static gmx_bool bWarn = FALSE;
315 gmx_bool bEof;
316 int dum;
317 const char *warn;
319 if (!man->natom) {
320 fprintf(stderr,"Not initiated yet!");
321 exit(1);
323 bEof=read_next_x(man->oenv,man->status,&man->time,man->natom,man->x,man->box);
324 *nat=man->natom;
325 if (ncount == man->nSkip) {
326 switch (man->molw->boxtype) {
327 case esbTri:
328 put_atoms_in_triclinic_unitcell(ecenterDEF,man->box,man->natom,man->x);
329 break;
330 case esbTrunc:
331 warn = put_atoms_in_compact_unitcell(man->molw->ePBC,ecenterDEF,man->box,
332 man->natom,man->x);
333 if (warn && !bWarn) {
334 fprintf(stderr,"\n%s\n",warn);
335 bWarn = TRUE;
337 break;
338 case esbRect:
339 case esbNone:
340 default:
341 break;
343 if (man->bPbc) {
344 gmx_rmpbc(man->gpbc,man->natom,man->box,man->x);
345 reset_mols(&(man->top.mols),man->box,man->x);
347 ncount=0;
349 else {
350 if (man->nSkip > 0) {
351 ncount++;
352 return step_man(man,nat);
356 return bEof;
359 static void HandleClient(t_x11 *x11,t_manager *man,long data[])
361 int ID,button,x,y;
362 gmx_bool bPos;
363 real fac;
365 ID=data[0];
366 button=data[1];
367 x=data[2];
368 y=data[3];
369 bPos=(button==Button1);
370 switch (ID) {
371 case IDROTX:
372 case IDROTY:
373 case IDROTZ:
374 rotate_3d(man->view,ID-IDROTX,bPos);
375 draw_mol(x11,man);
376 break;
377 case IDZOOM:
378 if (bPos)
379 fac=0.8; /* Reduce distance between eye and origin */
380 else
381 fac=1.25;
383 /* zoom changed to scale by Berk Hess 3-7-96
384 if (zoom_3d(man->view,fac))
385 draw_mol(x11,man); */
386 man->view->sc_x/=fac;
387 man->view->sc_y/=fac;
388 draw_mol(x11,man);
389 break;
390 case IDTRANSX:
391 case IDTRANSY:
392 case IDTRANSZ:
393 translate_view(man->view,ID-IDTRANSX,bPos);
394 draw_mol(x11,man);
395 break;
396 case IDREWIND:
397 if (man->status) {
398 rewind_trj(man->status);
399 read_next_x(man->oenv,man->status,&(man->time),man->natom,man->x,
400 man->box);
401 man->bEof=FALSE;
402 draw_mol(x11,man);
404 break;
405 case IDSTEP: {
406 int nat;
408 nat=0;
409 if (!step_man(man,&nat)) {
410 man->bEof=TRUE;
411 man->bStop=TRUE;
413 else {
414 if (nat > 0) {
415 draw_mol(x11,man);
416 usleep(man->nWait*1000);
419 break;
421 case IDFF:
422 man->bStop=FALSE;
423 break;
424 case IDSTOP_ANI:
425 man->bStop=TRUE;
426 break;
427 case IDDRAWMOL:
428 draw_mol(x11,man);
429 break;
430 case IDLABEL:
431 switch (button) {
432 case Button1:
433 case Button2:
434 show_label(x11,man,x,y);
435 break;
436 case Button3:
437 hide_label(x11,man,x,y);
438 break;
440 break;
441 default:
442 break;
444 if (man->bAnimate && !man->bEof && !man->bStop)
445 step_message(x11,man);
448 static gmx_bool TitleCallBack(t_x11 *x11,XEvent *event, Window w, void *data)
450 t_windata *wd;
452 wd=(t_windata *)data;
453 switch (event->type) {
454 case Expose:
455 if (wd->text && (wd->width > 10)) {
456 XSetForeground(x11->disp,x11->gc,WHITE);
457 TextInWin(x11,wd,wd->text,eXCenter,eYCenter);
458 XDrawLine(x11->disp,wd->self,x11->gc,0,wd->height,
459 wd->width,wd->height);
461 break;
462 case ConfigureNotify:
463 wd->width=event->xconfigure.width;
464 wd->height=event->xconfigure.height;
465 break;
467 return FALSE;
470 static gmx_bool ManCallBack(t_x11 *x11,XEvent *event, Window w, void *data)
472 t_manager *man;
473 int width,height;
475 man=(t_manager *)data;
476 switch(event->type) {
477 case ConfigureNotify:
478 width=event->xconfigure.width;
479 height=event->xconfigure.height;
480 if ((width!=man->wd.width) || (height!=man->wd.height))
481 move_man(x11,man,width,height);
482 break;
483 case ClientMessage:
484 HandleClient(x11,man,event->xclient.data.l);
485 break;
486 default:
487 break;
489 return FALSE;
492 void no_labels(t_x11 *x11,t_manager *man)
494 int i;
496 for(i=0; (i<man->natom); i++)
497 man->bLabel[i]=FALSE;
498 draw_mol(x11,man);
501 void move_man(t_x11 *x11,t_manager *man,int width,int height)
503 int x0,y0,mw,mh,hb;
504 int th;
506 #ifdef DEBUG
507 fprintf(stderr,"Move manager %dx%d\n",width,height);
508 #endif
509 man->wd.width=width;
510 man->wd.height=height;
512 /* Move all subwindows, resize only Mol window */
513 x0=width-EWIDTH-AIR-4*BORDER; /* Starting of ewin etc. */
514 y0=AIR;
516 /* Mol Window */
517 mw=x0-2*AIR-4*BORDER;
518 mh=height-y0-AIR-2*BORDER;
519 XMoveResizeWindow(x11->disp,man->molw->wd.self,AIR,y0,mw,mh);
521 /* Title Window */
522 th=XTextHeight(x11->font);
523 XMoveResizeWindow(x11->disp,man->title.self,0,0,mw,th+AIR);
525 /* Legend Window */
526 XMoveResizeWindow(x11->disp,man->legw->wd.self,x0,y0,EWIDTH,LEGHEIGHT);
527 y0+=LEGHEIGHT+AIR+2*BORDER;
529 if (y0 > height)
530 printf("Error: Windows falling out of main window!\n");
532 /* Button Box */
533 hb=height-y0-AIR-2*BORDER;
534 XMoveResizeWindow(x11->disp,man->bbox->wd.self,x0,y0,EWIDTH,hb);
536 /* Video Box */
537 x0=(mw-man->vbox->wd.width)/2;
538 y0=(mh-2-AIR-man->vbox->wd.height);
539 XMoveWindow(x11->disp,man->vbox->wd.self,x0,y0);
542 void map_man(t_x11 *x11,t_manager *man)
544 XMapWindow(x11->disp,man->wd.self);
545 map_mw(x11,man->molw);
546 XMapWindow(x11->disp,man->title.self);
547 map_legw(x11,man->legw);
548 show_but(x11,man->bbox);
551 gmx_bool toggle_animate (t_x11 *x11,t_manager *man)
553 if (man->status) {
554 man->bAnimate=!man->bAnimate;
555 man->bStop=TRUE;
556 man->bEof=FALSE;
557 if (man->bAnimate)
558 show_but(x11,man->vbox);
559 else
560 hide_but(x11,man->vbox);
562 return man->bAnimate;
565 gmx_bool toggle_pbc (t_manager *man)
567 man->bPbc=!man->bPbc;
569 return man->bPbc;
573 t_manager *init_man(t_x11 *x11,Window Parent,
574 int x,int y,int width,int height,
575 unsigned long fg,unsigned long bg,
576 int ePBC,matrix box,
577 const output_env_t oenv)
579 t_manager *man;
581 snew(man,1);
582 man->status=NULL;
583 man->bPlus=TRUE;
584 man->bSort=TRUE;
585 man->oenv=oenv;
586 InitWin(&(man->wd),x,y,width,height,0,"Manager");
587 man->wd.self=XCreateSimpleWindow(x11->disp,Parent,man->wd.x, man->wd.y,
588 man->wd.width,man->wd.height,
589 man->wd.bwidth,fg,bg);
590 x11->RegisterCallback(x11,man->wd.self,Parent,ManCallBack,man);
591 x11->SetInputMask(x11,man->wd.self,StructureNotifyMask |
592 ExposureMask | ButtonPressMask);
594 /* The order of creating windows is important for the stacking order */
595 /* Mol Window */
596 man->molw=init_mw(x11,man->wd.self,0,0,1,1,WHITE,BLUE,ePBC,box);
598 /* Title Window */
599 InitWin(&(man->title),0,0,1,1,0,NULL);
600 man->title.self=XCreateSimpleWindow(x11->disp,man->molw->wd.self,
601 man->title.x,man->title.y,
602 man->title.width,man->title.height,
603 man->title.bwidth,WHITE,BLUE);
604 x11->RegisterCallback(x11,man->title.self,man->molw->wd.self,
605 TitleCallBack,&(man->title));
606 x11->SetInputMask(x11,man->title.self,ExposureMask | StructureNotifyMask);
608 /* Button box */
609 man->bbox=init_bbox(x11,man->wd.self,man->wd.self,1,WHITE,BLUE);
611 /* Legend Window */
612 man->legw=init_legw(x11,man->wd.self,0,0,EWIDTH,LEGHEIGHT,WHITE,BLUE);
614 /* Video Box */
615 man->vbox=init_vbox(x11,man->molw->wd.self,man->wd.self,WHITE,BLUE);
617 return man;
620 void done_man(t_x11 *x11,t_manager *man)
622 done_bbox(x11,man->vbox);
623 done_bbox(x11,man->bbox);
624 done_mw(x11,man->molw);
625 done_legw(x11,man->legw);
626 x11->UnRegisterCallback(x11,man->title.self);
627 x11->UnRegisterCallback(x11,man->wd.self);
628 sfree(man->x);
629 sfree(man->obj);
630 sfree(man->bHydro);
631 sfree(man->bLabel);
632 sfree(man->szLab);
633 sfree(man->col);
634 sfree(man);
637 void do_filter(t_x11 *x11,t_manager *man,t_filter *filter)
639 int i;
640 atom_id j;
642 for(i=0; (i<man->natom); i++)
643 man->bVis[i]=FALSE;
644 for(i=0; (i<filter->grps->nr); i++) {
645 if (filter->bShow[i])
646 for(j=filter->grps->index[i]; (j<filter->grps->index[i+1]); j++)
647 man->bVis[filter->grps->a[j]]=TRUE;
650 ExposeWin(x11->disp,man->wd.self);