Improved version for builds from modified trees.
[gromacs/qmmm-gamess-us.git] / src / ngmx / manager.c
blobae648b868ca5f11197fbf99b77f874edbb7fc73d
1 /*
2 *
3 * This source code is part of
4 *
5 * G R O M A C S
6 *
7 * GROningen MAchine for Chemical Simulations
8 *
9 * VERSION 3.2.0
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
32 * And Hey:
33 * Gyas ROwers Mature At Cryogenic Speed
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
39 #include <sysstuff.h>
40 #include <string.h>
41 #include <smalloc.h>
42 #include <ctype.h>
43 #include <typedefs.h>
44 #include <smalloc.h>
45 #include <tpxio.h>
46 #include <macros.h>
47 #include <maths.h>
48 #include <atomprop.h>
49 #include <names.h>
50 #include "manager.h"
51 #include "futil.h"
52 #include "pbc.h"
53 #include "nmol.h"
54 #include "copyrite.h"
55 #include "gstat.h"
56 #include "vec.h"
57 #include "statutil.h"
58 #include "string2.h"
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,bool bB[])
74 bool *bH=man->bHydro;
75 t_iatom *ia;
76 t_iatom type,ai,aj,ak;
77 int i,delta,ftype;
79 #ifdef DEBUG
80 fprintf(stderr,"Going to make bonds from an ilist with %d entries\n",b->nr);
81 #endif
82 ia=b->iatoms;
83 for(i=0; (i<b->nr); ) {
84 type = ia[0];
85 ai = ia[1];
86 ftype = func[type];
87 delta = interaction_function[ftype].nratoms;
89 if (ftype == F_SETTLE) {
90 aj=ai+1;
91 ak=ai+2;
92 bB[ai]=bB[aj]=bB[ak]=TRUE;
93 add_object(man,eOHBond,ai,aj);
94 add_object(man,eOHBond,ai,ak);
96 else if (IS_CHEMBOND(ftype)) {
97 aj=ia[2];
98 #ifdef DEBUG
99 fprintf(stderr,"Adding bond from %d to %d\n",ai,aj);
100 #endif
101 bB[ai]=bB[aj]=TRUE;
102 if (!(bH[ai] == bH[aj]))
103 add_object(man,eOHBond,ai,aj);
104 else if (!bH[ai] && !bH[aj])
105 add_object(man,eOBond,ai,aj);
107 #ifdef DEBUG
108 fprintf(stderr,"Type: %5d, delta: %5d\n",type,delta);
109 #endif
110 ia += delta+1;
111 i += delta+1;
115 static void add_bpl(t_manager *man,t_idef *idef,bool bB[])
117 int ftype;
119 for(ftype=0; ftype<F_NRE; ftype++)
120 if (IS_CHEMBOND(ftype) || ftype==F_SETTLE)
121 add_bonds(man,idef->functype,&idef->il[ftype],bB);
124 static atom_id which_atom(t_manager *man,int x, int y)
126 #define DELTA 5
127 int i;
128 iv2 *ix=man->ix;
130 for(i=0; (i<man->natom); i++) {
131 if ((abs(ix[i][XX]-x) < DELTA) && (abs(ix[i][YY]-y) < DELTA)) {
132 if (man->bVis[i])
133 return (atom_id) i;
136 return NO_ATID;
139 static void do_label(t_x11 *x11,t_manager *man,int x,int y,bool bSet)
141 atom_id ai;
142 unsigned long col;
144 if ((ai=which_atom(man,x,y)) != NO_ATID) {
145 x=man->ix[ai][XX];
146 y=man->ix[ai][YY];
147 if (bSet && !man->bLabel[ai]) {
148 col=WHITE;
149 man->bLabel[ai]=TRUE;
151 else if (!bSet && man->bLabel[ai]) {
152 col=BLUE;
153 man->bLabel[ai]=FALSE;
155 else
156 return;
157 XSetForeground(x11->disp,x11->gc,col);
158 XDrawString(x11->disp,man->molw->wd.self,x11->gc,x+2,y-2,man->szLab[ai],
159 strlen(man->szLab[ai]));
160 XSetForeground(x11->disp,x11->gc,x11->fg);
164 static void show_label(t_x11 *x11,t_manager *man,int x,int y)
166 do_label(x11,man,x,y,TRUE);
169 static void hide_label(t_x11 *x11,t_manager *man,int x,int y)
171 do_label(x11,man,x,y,FALSE);
174 void set_file(t_x11 *x11,t_manager *man,const char *trajectory,
175 const char *status)
177 gmx_atomprop_t aps;
178 char buf[256],quote[256];
179 t_tpxheader sh;
180 t_atoms *at;
181 bool *bB;
182 int i,idum;
184 read_tpxheader(status,&sh,TRUE,NULL,NULL);
185 snew(man->ix,sh.natoms);
186 snew(man->zz,sh.natoms);
187 snew(man->col,sh.natoms);
188 snew(man->size,sh.natoms);
189 snew(man->vdw,sh.natoms);
190 snew(man->bLabel,sh.natoms);
191 snew(man->bVis,sh.natoms);
192 for(i=0; (i<sh.natoms); i++)
193 man->bVis[i]=FALSE;
195 man->bPbc=FALSE;
197 snew(man->szLab,sh.natoms);
198 snew(man->bHydro,sh.natoms);
199 snew(bB,sh.natoms);
200 read_tpx_top(status,NULL,man->box,&man->natom,NULL,NULL,NULL,&man->top);
202 man->natom=
203 read_first_x(man->oenv,&man->status,trajectory,&(man->time),&(man->x),
204 man->box);
205 man->trajfile=strdup(trajectory);
206 if (man->natom > man->top.atoms.nr)
207 gmx_fatal(FARGS,"Topology %s (%d atoms) and trajectory %s (%d atoms) "
208 "do not match",status,man->top.atoms.nr,
209 trajectory,man->natom);
211 cool_quote(quote,255,NULL);
212 sprintf(buf,"%s: %s",*man->top.name,quote);
213 man->title.text = strdup(buf);
214 man->view = init_view(man->box);
215 at = &(man->top.atoms);
216 aps = gmx_atomprop_init();
217 for(i=0; (i<man->natom); i++) {
218 char *aname=*(at->atomname[i]);
219 t_resinfo *ri=&at->resinfo[at->atom[i].resind];
221 man->col[i]=Type2Color(aname);
222 snew(man->szLab[i],20);
223 if (ri->ic != ' ') {
224 sprintf(man->szLab[i],"%s%d%c, %s",*ri->name,ri->nr,ri->ic,aname);
225 } else {
226 sprintf(man->szLab[i],"%s%d, %s",*ri->name,ri->nr,aname);
228 man->bHydro[i]=(toupper(aname[0])=='H');
229 if ( man->bHydro[i] )
230 man->vdw[i]=0;
231 else if (!gmx_atomprop_query(aps,epropVDW,*ri->name,aname,&(man->vdw[i])))
232 man->vdw[i] = 0;
234 gmx_atomprop_destroy(aps);
235 add_bpl(man,&(man->top.idef),bB);
236 for(i=0; (i<man->natom); i++)
237 if (!bB[i])
238 add_object(man,eOSingle,(atom_id) i,0);
239 sfree(bB);
241 ExposeWin(x11->disp,man->molw->wd.self);
244 void step_message(t_x11 *x11,t_manager *man)
246 XEvent letter;
248 letter.type=ClientMessage;
249 letter.xclient.display=x11->disp;
250 letter.xclient.window=man->wd.self;
251 letter.xclient.message_type=0;
252 letter.xclient.format=32;
253 letter.xclient.data.l[0]=IDSTEP;
254 letter.xclient.data.l[1]=Button1;
255 XSendEvent(x11->disp,letter.xclient.window,True,0,&letter);
258 bool ReadMonfile(char *fn,int *nbars, int *bars)
260 FILE *fp;
261 if ((fp = fopen(fn,"r"))==NULL)
262 return(FALSE);
263 else {
264 for((*nbars)=0; fscanf(fp,"%d",&bars[*nbars])>0; (*nbars)++)
266 fclose(fp);
267 return (TRUE);
271 static void reset_mols(t_block *mols,matrix box,rvec x[])
273 int i,m0,m1,j,m;
274 rvec xcm,icm;
275 real ix,iy,iz;
277 for(i=0; (i<mols->nr); i++) {
278 m0=mols->index[i];
279 m1=mols->index[i+1];
281 clear_rvec(xcm);
282 clear_rvec(icm);
284 for(j=m0; (j<m1); j++) {
285 rvec_inc(xcm,x[j]);
287 for(m=0; (m<DIM); m++)
288 xcm[m]/=(m1-m0);
289 for(m=0; (m<DIM); m++) {
290 if (xcm[m] < 0)
291 icm[m]=box[m][m];
292 else if (xcm[m] >= box[m][m])
293 icm[m]=-box[m][m];
295 ix=icm[XX],iy=icm[YY],iz=icm[ZZ];
297 if ((ix != 0) || (iy != 0) || (iz != 0)) {
298 for(j=m0; (j<m1); j++) {
299 x[j][XX]+=ix;
300 x[j][YY]+=iy;
301 x[j][ZZ]+=iz;
307 static bool step_man(t_manager *man,int *nat)
309 static int ncount=0;
310 static bool bWarn = FALSE;
311 bool bEof;
312 int dum;
313 const char *warn;
315 if (!man->natom) {
316 fprintf(stderr,"Not initiated yet!");
317 exit(1);
319 bEof=read_next_x(man->oenv,man->status,&man->time,man->natom,man->x,man->box);
320 *nat=man->natom;
321 if (ncount == man->nSkip) {
322 switch (man->molw->boxtype) {
323 case esbTri:
324 put_atoms_in_triclinic_unitcell(ecenterDEF,man->box,man->natom,man->x);
325 break;
326 case esbTrunc:
327 warn = put_atoms_in_compact_unitcell(man->molw->ePBC,ecenterDEF,man->box,
328 man->natom,man->x);
329 if (warn && !bWarn) {
330 fprintf(stderr,"\n%s\n",warn);
331 bWarn = TRUE;
333 break;
334 case esbRect:
335 case esbNone:
336 default:
337 break;
339 if (man->bPbc) {
340 rm_pbc(&(man->top.idef),man->molw->ePBC,
341 man->natom,man->box,man->x,man->x);
342 reset_mols(&(man->top.mols),man->box,man->x);
344 ncount=0;
346 else {
347 if (man->nSkip > 0) {
348 ncount++;
349 return step_man(man,nat);
353 return bEof;
356 static void HandleClient(t_x11 *x11,t_manager *man,long data[])
358 int ID,button,x,y;
359 bool bPos;
360 real fac;
362 ID=data[0];
363 button=data[1];
364 x=data[2];
365 y=data[3];
366 bPos=(button==Button1);
367 switch (ID) {
368 case IDROTX:
369 case IDROTY:
370 case IDROTZ:
371 rotate_3d(man->view,ID-IDROTX,bPos);
372 draw_mol(x11,man);
373 break;
374 case IDZOOM:
375 if (bPos)
376 fac=0.8; /* Reduce distance between eye and origin */
377 else
378 fac=1.25;
380 /* zoom changed to scale by Berk Hess 3-7-96
381 if (zoom_3d(man->view,fac))
382 draw_mol(x11,man); */
383 man->view->sc_x/=fac;
384 man->view->sc_y/=fac;
385 draw_mol(x11,man);
386 break;
387 case IDTRANSX:
388 case IDTRANSY:
389 case IDTRANSZ:
390 translate_view(man->view,ID-IDTRANSX,bPos);
391 draw_mol(x11,man);
392 break;
393 case IDREWIND:
394 if (man->status != -1) {
395 rewind_trj(man->status);
396 read_next_x(man->oenv,man->status,&(man->time),man->natom,man->x,
397 man->box);
398 man->bEof=FALSE;
399 draw_mol(x11,man);
401 break;
402 case IDSTEP: {
403 int nat;
405 nat=0;
406 if (!step_man(man,&nat)) {
407 man->bEof=TRUE;
408 man->bStop=TRUE;
410 else {
411 if (nat > 0) {
412 draw_mol(x11,man);
413 usleep(man->nWait*1000);
416 break;
418 case IDFF:
419 man->bStop=FALSE;
420 break;
421 case IDSTOP_ANI:
422 man->bStop=TRUE;
423 break;
424 case IDDRAWMOL:
425 draw_mol(x11,man);
426 break;
427 case IDLABEL:
428 switch (button) {
429 case Button1:
430 case Button2:
431 show_label(x11,man,x,y);
432 break;
433 case Button3:
434 hide_label(x11,man,x,y);
435 break;
437 break;
438 default:
439 break;
441 if (man->bAnimate && !man->bEof && !man->bStop)
442 step_message(x11,man);
445 static bool TitleCallBack(t_x11 *x11,XEvent *event, Window w, void *data)
447 t_windata *wd;
449 wd=(t_windata *)data;
450 switch (event->type) {
451 case Expose:
452 if (wd->text && (wd->width > 10)) {
453 XSetForeground(x11->disp,x11->gc,WHITE);
454 TextInWin(x11,wd,wd->text,eXCenter,eYCenter);
455 XDrawLine(x11->disp,wd->self,x11->gc,0,wd->height,
456 wd->width,wd->height);
458 break;
459 case ConfigureNotify:
460 wd->width=event->xconfigure.width;
461 wd->height=event->xconfigure.height;
462 break;
464 return FALSE;
467 static bool ManCallBack(t_x11 *x11,XEvent *event, Window w, void *data)
469 t_manager *man;
470 int width,height;
472 man=(t_manager *)data;
473 switch(event->type) {
474 case ConfigureNotify:
475 width=event->xconfigure.width;
476 height=event->xconfigure.height;
477 if ((width!=man->wd.width) || (height!=man->wd.height))
478 move_man(x11,man,width,height);
479 break;
480 case ClientMessage:
481 HandleClient(x11,man,event->xclient.data.l);
482 break;
483 default:
484 break;
486 return FALSE;
489 void no_labels(t_x11 *x11,t_manager *man)
491 int i;
493 for(i=0; (i<man->natom); i++)
494 man->bLabel[i]=FALSE;
495 draw_mol(x11,man);
498 void move_man(t_x11 *x11,t_manager *man,int width,int height)
500 int x0,y0,mw,mh,hb;
501 int th;
503 #ifdef DEBUG
504 fprintf(stderr,"Move manager %dx%d\n",width,height);
505 #endif
506 man->wd.width=width;
507 man->wd.height=height;
509 /* Move all subwindows, resize only Mol window */
510 x0=width-EWIDTH-AIR-4*BORDER; /* Starting of ewin etc. */
511 y0=AIR;
513 /* Mol Window */
514 mw=x0-2*AIR-4*BORDER;
515 mh=height-y0-AIR-2*BORDER;
516 XMoveResizeWindow(x11->disp,man->molw->wd.self,AIR,y0,mw,mh);
518 /* Title Window */
519 th=XTextHeight(x11->font);
520 XMoveResizeWindow(x11->disp,man->title.self,0,0,mw,th+AIR);
522 /* Legend Window */
523 XMoveResizeWindow(x11->disp,man->legw->wd.self,x0,y0,EWIDTH,LEGHEIGHT);
524 y0+=LEGHEIGHT+AIR+2*BORDER;
526 if (y0 > height)
527 printf("Error: Windows falling out of main window!\n");
529 /* Button Box */
530 hb=height-y0-AIR-2*BORDER;
531 XMoveResizeWindow(x11->disp,man->bbox->wd.self,x0,y0,EWIDTH,hb);
533 /* Video Box */
534 x0=(mw-man->vbox->wd.width)/2;
535 y0=(mh-2-AIR-man->vbox->wd.height);
536 XMoveWindow(x11->disp,man->vbox->wd.self,x0,y0);
539 void map_man(t_x11 *x11,t_manager *man)
541 XMapWindow(x11->disp,man->wd.self);
542 map_mw(x11,man->molw);
543 XMapWindow(x11->disp,man->title.self);
544 map_legw(x11,man->legw);
545 show_but(x11,man->bbox);
548 bool toggle_animate (t_x11 *x11,t_manager *man)
550 if (man->status != -1) {
551 man->bAnimate=!man->bAnimate;
552 man->bStop=TRUE;
553 man->bEof=FALSE;
554 if (man->bAnimate)
555 show_but(x11,man->vbox);
556 else
557 hide_but(x11,man->vbox);
559 return man->bAnimate;
562 bool toggle_pbc (t_manager *man)
564 man->bPbc=!man->bPbc;
566 return man->bPbc;
570 t_manager *init_man(t_x11 *x11,Window Parent,
571 int x,int y,int width,int height,
572 unsigned long fg,unsigned long bg,
573 int ePBC,matrix box,
574 const output_env_t oenv)
576 t_manager *man;
578 snew(man,1);
579 man->status=-1;
580 man->bPlus=TRUE;
581 man->bSort=TRUE;
582 man->oenv=oenv;
583 InitWin(&(man->wd),x,y,width,height,0,"Manager");
584 man->wd.self=XCreateSimpleWindow(x11->disp,Parent,man->wd.x, man->wd.y,
585 man->wd.width,man->wd.height,
586 man->wd.bwidth,fg,bg);
587 x11->RegisterCallback(x11,man->wd.self,Parent,ManCallBack,man);
588 x11->SetInputMask(x11,man->wd.self,StructureNotifyMask |
589 ExposureMask | ButtonPressMask);
591 /* The order of creating windows is important for the stacking order */
592 /* Mol Window */
593 man->molw=init_mw(x11,man->wd.self,0,0,1,1,WHITE,BLUE,ePBC,box);
595 /* Title Window */
596 InitWin(&(man->title),0,0,1,1,0,NULL);
597 man->title.self=XCreateSimpleWindow(x11->disp,man->molw->wd.self,
598 man->title.x,man->title.y,
599 man->title.width,man->title.height,
600 man->title.bwidth,WHITE,BLUE);
601 x11->RegisterCallback(x11,man->title.self,man->molw->wd.self,
602 TitleCallBack,&(man->title));
603 x11->SetInputMask(x11,man->title.self,ExposureMask | StructureNotifyMask);
605 /* Button box */
606 man->bbox=init_bbox(x11,man->wd.self,man->wd.self,1,WHITE,BLUE);
608 /* Legend Window */
609 man->legw=init_legw(x11,man->wd.self,0,0,EWIDTH,LEGHEIGHT,WHITE,BLUE);
611 /* Video Box */
612 man->vbox=init_vbox(x11,man->molw->wd.self,man->wd.self,WHITE,BLUE);
614 return man;
617 void done_man(t_x11 *x11,t_manager *man)
619 done_bbox(x11,man->vbox);
620 done_bbox(x11,man->bbox);
621 done_mw(x11,man->molw);
622 done_legw(x11,man->legw);
623 x11->UnRegisterCallback(x11,man->title.self);
624 x11->UnRegisterCallback(x11,man->wd.self);
625 sfree(man->x);
626 sfree(man->obj);
627 sfree(man->bHydro);
628 sfree(man->bLabel);
629 sfree(man->szLab);
630 sfree(man->col);
631 sfree(man);
634 void do_filter(t_x11 *x11,t_manager *man,t_filter *filter)
636 int i;
637 atom_id j;
639 for(i=0; (i<man->natom); i++)
640 man->bVis[i]=FALSE;
641 for(i=0; (i<filter->grps->nr); i++) {
642 if (filter->bShow[i])
643 for(j=filter->grps->index[i]; (j<filter->grps->index[i+1]); j++)
644 man->bVis[filter->grps->a[j]]=TRUE;
647 ExposeWin(x11->disp,man->wd.self);