changed reading hint
[gromacs/adressmacs.git] / src / ngmx / manager.c
blob9df6a643ffb12f97af5eb32858a46c000af0035b
1 /*
2 * $Id$
3 *
4 * This source code is part of
5 *
6 * G R O M A C S
7 *
8 * GROningen MAchine for Chemical Simulations
9 *
10 * VERSION 2.0
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
16 * Please refer to:
17 * GROMACS: A message-passing parallel molecular dynamics implementation
18 * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19 * Comp. Phys. Comm. 91, 43-56 (1995)
21 * Also check out our WWW page:
22 * http://md.chem.rug.nl/~gmx
23 * or e-mail to:
24 * gromacs@chem.rug.nl
26 * And Hey:
27 * Great Red Oystrich Makes All Chemists Sane
29 static char *SRCID_manager_c = "$Id$";
31 #include <sysstuff.h>
32 #include <string.h>
33 #include <smalloc.h>
34 #include <ctype.h>
35 #include <typedefs.h>
36 #include <smalloc.h>
37 #include <tpxio.h>
38 #include <macros.h>
39 #include <maths.h>
40 #include <atomprop.h>
41 #include <names.h>
42 #include "manager.h"
43 #include "futil.h"
44 #include "pbc.h"
45 #include "nmol.h"
46 #include "copyrite.h"
47 #include "gstat.h"
48 #include "vec.h"
49 #include "statutil.h"
51 static void add_object(t_manager *man,eObject eO,atom_id ai,atom_id aj)
53 srenew(man->obj,++man->nobj);
54 man->obj[man->nobj-1].eO = eO;
55 man->obj[man->nobj-1].eV = eVNormal;
56 man->obj[man->nobj-1].color = WHITE;
57 man->obj[man->nobj-1].ai = ai;
58 man->obj[man->nobj-1].aj = aj;
59 man->obj[man->nobj-1].z = 0.0;
62 static void add_bonds(t_manager *man,t_functype func[],
63 t_ilist *b,bool bB[])
65 bool *bH=man->bHydro;
66 t_iatom *ia;
67 t_iatom type,ai,aj,ak;
68 int i,delta,ftype;
70 #ifdef DEBUG
71 fprintf(stderr,"Going to make bonds from an ilist with %d entries\n",b->nr);
72 #endif
73 ia=b->iatoms;
74 for(i=0; (i<b->nr); ) {
75 type = ia[0];
76 ai = ia[1];
77 ftype = func[type];
78 delta = interaction_function[ftype].nratoms;
80 if (ftype == F_SETTLE) {
81 aj=ai+1;
82 ak=ai+2;
83 bB[ai]=bB[aj]=bB[ak]=TRUE;
84 add_object(man,eOHBond,ai,aj);
85 add_object(man,eOHBond,ai,ak);
87 else if ( interaction_function[ftype].flags & IF_CONNECT ) {
88 aj=ia[2];
89 #ifdef DEBUG
90 fprintf(stderr,"Adding bond from %d to %d\n",ai,aj);
91 #endif
92 bB[ai]=bB[aj]=TRUE;
93 if (!(bH[ai] == bH[aj]))
94 add_object(man,eOHBond,ai,aj);
95 else if (!bH[ai] && !bH[aj])
96 add_object(man,eOBond,ai,aj);
98 #ifdef DEBUG
99 fprintf(stderr,"Type: %5d, delta: %5d\n",type,delta);
100 #endif
101 ia += delta+1;
102 i += delta+1;
106 static void add_bpl(t_manager *man,t_idef *idef,bool bB[])
108 add_bonds(man,idef->functype,&idef->il[F_BONDS],bB);
109 add_bonds(man,idef->functype,&idef->il[F_G96BONDS],bB);
110 add_bonds(man,idef->functype,&idef->il[F_MORSE],bB);
111 add_bonds(man,idef->functype,&idef->il[F_SHAKE],bB);
112 add_bonds(man,idef->functype,&idef->il[F_SETTLE],bB);
115 static atom_id which_atom(t_manager *man,int x, int y)
117 #define DELTA 5
118 int i;
119 iv2 *ix=man->ix;
121 for(i=0; (i<man->natom); i++) {
122 if ((abs(ix[i][XX]-x) < DELTA) && (abs(ix[i][YY]-y) < DELTA)) {
123 if (man->bVis[i])
124 return (atom_id) i;
127 return NO_ATID;
130 static void do_label(t_x11 *x11,t_manager *man,int x,int y,bool bSet)
132 atom_id ai;
133 unsigned long col;
135 if ((ai=which_atom(man,x,y)) != NO_ATID) {
136 x=man->ix[ai][XX];
137 y=man->ix[ai][YY];
138 if (bSet && !man->bLabel[ai]) {
139 col=WHITE;
140 man->bLabel[ai]=TRUE;
142 else if (!bSet && man->bLabel[ai]) {
143 col=BLUE;
144 man->bLabel[ai]=FALSE;
146 else
147 return;
148 XSetForeground(x11->disp,x11->gc,col);
149 XDrawString(x11->disp,man->molw->wd.self,x11->gc,x+2,y-2,man->szLab[ai],
150 strlen(man->szLab[ai]));
151 XSetForeground(x11->disp,x11->gc,x11->fg);
155 static void show_label(t_x11 *x11,t_manager *man,int x,int y)
157 do_label(x11,man,x,y,TRUE);
160 static void hide_label(t_x11 *x11,t_manager *man,int x,int y)
162 do_label(x11,man,x,y,FALSE);
165 void set_file(t_x11 *x11,t_manager *man,char *trajectory,char *status)
167 char buf[256];
168 t_tpxheader sh;
169 t_atoms *at;
170 bool *bB;
171 int i,idum;
172 real rdum;
174 read_tpxheader(status,&sh);
175 snew(man->ix,sh.natoms);
176 snew(man->zz,sh.natoms);
177 snew(man->col,sh.natoms);
178 snew(man->size,sh.natoms);
179 snew(man->vdw,sh.natoms);
180 snew(man->bLabel,sh.natoms);
181 snew(man->bVis,sh.natoms);
182 for(i=0; (i<sh.natoms); i++)
183 man->bVis[i]=FALSE;
185 man->bPbc=FALSE;
187 snew(man->szLab,sh.natoms);
188 snew(man->bHydro,sh.natoms);
189 snew(bB,sh.natoms);
190 read_tpx(status,&(man->step),&(man->time),&rdum,NULL,man->box,
191 &man->natom,NULL,NULL,NULL,&man->top);
193 man->natom=
194 read_first_x(&man->status,trajectory,&(man->time),&(man->x),man->box);
195 man->trajfile=strdup(trajectory);
197 sprintf(buf,"%s: %s",*man->top.name,cool_quote());
198 man->title.text=strdup(buf);
199 man->view=init_view(man->box);
200 at=&(man->top.atoms);
201 for(i=0; (i<man->natom); i++) {
202 char *aname=*(at->atomname[i]);
203 int resnr=at->atom[i].resnr;
205 man->col[i]=Type2Color(aname);
206 snew(man->szLab[i],20);
207 sprintf(man->szLab[i],"%s%d, %s",*(at->resname[resnr]),resnr+1,aname);
208 man->bHydro[i]=(toupper(aname[0])=='H');
209 if ( man->bHydro[i] )
210 man->vdw[i]=0;
211 else
212 man->vdw[i]=get_vdw(*(at->resname[resnr]),aname,0);
214 add_bpl(man,&(man->top.idef),bB);
215 for(i=0; (i<man->natom); i++)
216 if (!bB[i])
217 add_object(man,eOSingle,(atom_id) i,0);
218 sfree(bB);
220 ExposeWin(x11->disp,man->molw->wd.self);
223 void step_message(t_x11 *x11,t_manager *man)
225 XEvent letter;
227 letter.type=ClientMessage;
228 letter.xclient.display=x11->disp;
229 letter.xclient.window=man->wd.self;
230 letter.xclient.message_type=0;
231 letter.xclient.format=32;
232 letter.xclient.data.l[0]=IDSTEP;
233 letter.xclient.data.l[1]=Button1;
234 XSendEvent(x11->disp,letter.xclient.window,True,0,&letter);
237 bool ReadMonfile(char *fn,int *nbars, int *bars)
239 FILE *fp;
240 if ((fp = fopen(fn,"r"))==NULL)
241 return(FALSE);
242 else {
243 for((*nbars)=0; fscanf(fp,"%d",&bars[*nbars])>0; (*nbars)++)
245 fclose(fp);
246 return (TRUE);
250 static void reset_mols(t_block *mols,matrix box,rvec x[])
252 int i,aj,m0,m1,j,m;
253 rvec xcm,icm;
254 real ix,iy,iz;
256 for(i=0; (i<mols->nr); i++) {
257 m0=mols->index[i];
258 m1=mols->index[i+1];
260 clear_rvec(xcm);
261 clear_rvec(icm);
263 for(j=m0; (j<m1); j++) {
264 aj=mols->a[j];
265 rvec_inc(xcm,x[aj]);
267 for(m=0; (m<DIM); m++)
268 xcm[m]/=(m1-m0);
269 for(m=0; (m<DIM); m++) {
270 if (xcm[m] < 0)
271 icm[m]=box[m][m];
272 else if (xcm[m] >= box[m][m])
273 icm[m]=-box[m][m];
275 ix=icm[XX],iy=icm[YY],iz=icm[ZZ];
277 if ((ix != 0) || (iy != 0) || (iz != 0)) {
278 for(j=m0; (j<m1); j++) {
279 aj=mols->a[j];
280 x[aj][XX]+=ix;
281 x[aj][YY]+=iy;
282 x[aj][ZZ]+=iz;
288 static bool step_man(t_manager *man,int *nat)
290 static int ncount=0;
291 bool bEof;
292 real rdum;
293 int dum;
295 if (!man->natom) {
296 fprintf(stderr,"Not initiated yet!");
297 exit(1);
299 bEof=read_next_x(man->status,&man->time,man->natom,man->x,man->box);
300 *nat=man->natom;
301 if (ncount == man->nSkip) {
302 if (man->bPbc) {
303 rm_pbc(&(man->top.idef),man->natom,man->box,man->x,man->x);
304 reset_mols(&(man->top.blocks[ebMOLS]),man->box,man->x);
306 ncount=0;
308 else {
309 if (man->nSkip > 0) {
310 ncount++;
311 return step_man(man,nat);
315 return bEof;
318 static void HandleClient(t_x11 *x11,t_manager *man,long data[])
320 int ID,button,x,y;
321 bool bPos;
322 real fac;
324 ID=data[0];
325 button=data[1];
326 x=data[2];
327 y=data[3];
328 bPos=(button==Button1);
329 switch (ID) {
330 case IDROTX:
331 case IDROTY:
332 case IDROTZ:
333 rotate_3d(man->view,ID-IDROTX,bPos);
334 draw_mol(x11,man);
335 break;
336 case IDZOOM:
337 if (bPos)
338 fac=0.8; /* Reduce distance between eye and origin */
339 else
340 fac=1.25;
342 /* zoom changed to scale by Berk Hess 3-7-96
343 if (zoom_3d(man->view,fac))
344 draw_mol(x11,man); */
345 man->view->sc_x/=fac;
346 man->view->sc_y/=fac;
347 draw_mol(x11,man);
348 break;
349 case IDTRANSX:
350 case IDTRANSY:
351 case IDTRANSZ:
352 translate_view(man->view,ID-IDTRANSX,bPos);
353 draw_mol(x11,man);
354 break;
355 case IDREWIND:
356 if (man->status != -1) {
357 rewind_trj(man->status);
358 read_next_x(man->status,&(man->time),man->natom,man->x,man->box);
359 man->bEof=FALSE;
360 draw_mol(x11,man);
362 break;
363 case IDSTEP: {
364 int nat;
366 nat=0;
367 if (!step_man(man,&nat)) {
368 man->bEof=TRUE;
369 man->bStop=TRUE;
371 else {
372 if (nat > 0)
373 draw_mol(x11,man);
375 break;
377 case IDFF:
378 man->bStop=FALSE;
379 break;
380 case IDSTOP_ANI:
381 man->bStop=TRUE;
382 break;
383 case IDDRAWMOL:
384 draw_mol(x11,man);
385 break;
386 case IDLABEL:
387 switch (button) {
388 case Button1:
389 case Button2:
390 show_label(x11,man,x,y);
391 break;
392 case Button3:
393 hide_label(x11,man,x,y);
394 break;
396 break;
397 default:
398 break;
400 if (man->bAnimate && !man->bEof && !man->bStop)
401 step_message(x11,man);
404 static bool TitleCallBack(t_x11 *x11,XEvent *event, Window w, void *data)
406 t_windata *wd;
408 wd=(t_windata *)data;
409 switch (event->type) {
410 case Expose:
411 if (wd->text && (wd->width > 10)) {
412 XSetForeground(x11->disp,x11->gc,WHITE);
413 TextInWin(x11,wd,wd->text,eXCenter,eYCenter);
414 XDrawLine(x11->disp,wd->self,x11->gc,0,wd->height,
415 wd->width,wd->height);
417 break;
418 case ConfigureNotify:
419 wd->width=event->xconfigure.width;
420 wd->height=event->xconfigure.height;
421 break;
423 return FALSE;
426 static bool ManCallBack(t_x11 *x11,XEvent *event, Window w, void *data)
428 t_manager *man;
429 int width,height;
431 man=(t_manager *)data;
432 switch(event->type) {
433 case ConfigureNotify:
434 width=event->xconfigure.width;
435 height=event->xconfigure.height;
436 if ((width!=man->wd.width) || (height!=man->wd.height))
437 move_man(x11,man,width,height);
438 break;
439 case ClientMessage:
440 HandleClient(x11,man,event->xclient.data.l);
441 break;
442 default:
443 break;
445 return FALSE;
448 void no_labels(t_x11 *x11,t_manager *man)
450 int i;
452 for(i=0; (i<man->natom); i++)
453 man->bLabel[i]=FALSE;
454 draw_mol(x11,man);
457 void move_man(t_x11 *x11,t_manager *man,int width,int height)
459 int x0,y0,mw,mh,hb;
460 int th;
462 #ifdef DEBUG
463 fprintf(stderr,"Move manager %dx%d\n",width,height);
464 #endif
465 man->wd.width=width;
466 man->wd.height=height;
468 /* Move all subwindows, resize only Mol window */
469 x0=width-EWIDTH-AIR-4*BORDER; /* Starting of ewin etc. */
470 y0=AIR;
472 /* Mol Window */
473 mw=x0-2*AIR-4*BORDER;
474 mh=height-y0-AIR-2*BORDER;
475 XMoveResizeWindow(x11->disp,man->molw->wd.self,AIR,y0,mw,mh);
477 /* Title Window */
478 th=XTextHeight(x11->font);
479 XMoveResizeWindow(x11->disp,man->title.self,0,0,mw,th+AIR);
481 /* Legend Window */
482 XMoveResizeWindow(x11->disp,man->legw->wd.self,x0,y0,EWIDTH,LEGHEIGHT);
483 y0+=LEGHEIGHT+AIR+2*BORDER;
485 if (y0 > height)
486 printf("Error: Windows falling out of main window!\n");
488 /* Button Box */
489 hb=height-y0-AIR-2*BORDER;
490 XMoveResizeWindow(x11->disp,man->bbox->wd.self,x0,y0,EWIDTH,hb);
492 /* Video Box */
493 x0=(mw-man->vbox->wd.width)/2;
494 y0=(mh-2-AIR-man->vbox->wd.height);
495 XMoveWindow(x11->disp,man->vbox->wd.self,x0,y0);
498 void map_man(t_x11 *x11,t_manager *man)
500 XMapWindow(x11->disp,man->wd.self);
501 map_mw(x11,man->molw);
502 XMapWindow(x11->disp,man->title.self);
503 map_legw(x11,man->legw);
504 show_but(x11,man->bbox);
507 bool toggle_animate (t_x11 *x11,t_manager *man)
509 if (man->status != -1) {
510 man->bAnimate=!man->bAnimate;
511 man->bStop=TRUE;
512 man->bEof=FALSE;
513 if (man->bAnimate)
514 show_but(x11,man->vbox);
515 else
516 hide_but(x11,man->vbox);
518 return man->bAnimate;
521 bool toggle_pbc (t_manager *man)
523 man->bPbc=!man->bPbc;
525 return man->bPbc;
529 t_manager *init_man(t_x11 *x11,Window Parent,
530 int x,int y,int width,int height,
531 unsigned long fg,unsigned long bg)
533 t_manager *man;
535 snew(man,1);
536 man->status=-1;
537 man->bPlus=TRUE;
538 man->bSort=TRUE;
539 InitWin(&(man->wd),x,y,width,height,0,"Manager");
540 man->wd.self=XCreateSimpleWindow(x11->disp,Parent,man->wd.x, man->wd.y,
541 man->wd.width,man->wd.height,
542 man->wd.bwidth,fg,bg);
543 x11->RegisterCallback(x11,man->wd.self,Parent,ManCallBack,man);
544 x11->SetInputMask(x11,man->wd.self,StructureNotifyMask |
545 ExposureMask | ButtonPressMask);
547 /* The order of creating windows is important for the stacking order */
548 /* Mol Window */
549 man->molw=init_mw(x11,man->wd.self,0,0,1,1,WHITE,BLUE);
551 /* Title Window */
552 InitWin(&(man->title),0,0,1,1,0,NULL);
553 man->title.self=XCreateSimpleWindow(x11->disp,man->molw->wd.self,
554 man->title.x,man->title.y,
555 man->title.width,man->title.height,
556 man->title.bwidth,WHITE,BLUE);
557 x11->RegisterCallback(x11,man->title.self,man->molw->wd.self,
558 TitleCallBack,&(man->title));
559 x11->SetInputMask(x11,man->title.self,ExposureMask | StructureNotifyMask);
561 /* Button box */
562 man->bbox=init_bbox(x11,man->wd.self,man->wd.self,1,WHITE,BLUE);
564 /* Legend Window */
565 man->legw=init_legw(x11,man->wd.self,0,0,EWIDTH,LEGHEIGHT,WHITE,BLUE);
567 /* Video Box */
568 man->vbox=init_vbox(x11,man->molw->wd.self,man->wd.self,WHITE,BLUE);
570 return man;
573 void done_man(t_x11 *x11,t_manager *man)
575 done_bbox(x11,man->vbox);
576 done_bbox(x11,man->bbox);
577 done_mw(x11,man->molw);
578 done_legw(x11,man->legw);
579 x11->UnRegisterCallback(x11,man->title.self);
580 x11->UnRegisterCallback(x11,man->wd.self);
581 sfree(man->x);
582 sfree(man->obj);
583 sfree(man->bHydro);
584 sfree(man->bLabel);
585 sfree(man->szLab);
586 sfree(man->col);
587 sfree(man);
590 void do_filter(t_x11 *x11,t_manager *man,t_filter *filter)
592 int i;
593 atom_id j;
595 for(i=0; (i<man->natom); i++)
596 man->bVis[i]=FALSE;
597 for(i=0; (i<filter->grps->nr); i++) {
598 if (filter->bShow[i])
599 for(j=filter->grps->index[i]; (j<filter->grps->index[i+1]); j++)
600 man->bVis[filter->grps->a[j]]=TRUE;
603 ExposeWin(x11->disp,man->wd.self);