4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Copyright (c) 1991-2001, University of Groningen, The Netherlands
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * If you want to redistribute modifications, please consider that
18 * scientific software is very special. Version control is crucial -
19 * bugs must be traceable. We will be happy to consider code for
20 * inclusion in the official distribution, but derived work must not
21 * be called official GROMACS. Details are found in the README & COPYING
22 * files - if they are missing, get the official version at www.gromacs.org.
24 * To help us fund GROMACS development, we humbly ask that you cite
25 * the papers on the package - you can find them in the top README file.
27 * For more info, check our website at http://www.gromacs.org
30 * Gromacs Runs One Microsecond At Cannonball Speeds
60 static real
tick_spacing(real range
,int minticks
)
64 sp
= 0.2*exp(log(10)*ceil(log(range
)/log(10)));
65 while (range
/sp
< minticks
-1)
71 static void write_xvgr_graphs(char *file
,int ngraphs
,
72 char *title
,char *xlabel
,char **ylabel
,
73 int n
,real
*x
, real
**y
,
74 real scale_x
,bool bZero
, bool bSplit
)
81 for(g
=0; g
<ngraphs
; g
++) {
85 if (y
[g
][i
]<min
) min
=y
[g
][i
];
86 if (y
[g
][i
]>max
) max
=y
[g
][i
];
91 min
=min
-0.1*(max
-min
);
92 max
=max
+0.1*(max
-min
);
93 xsp
=tick_spacing((x
[n
-1]-x
[0])*scale_x
,4);
94 ysp
=tick_spacing(max
-min
,3);
95 fprintf(out
,"@ with g%d\n@ g%d on\n",g
,g
);
96 fprintf(out
,"@ g%d autoscale type AUTO\n",g
);
98 fprintf(out
,"@ title \"%s\"\n",title
);
100 fprintf(out
,"@ xaxis label \"%s\"\n",xlabel
);
102 fprintf(out
,"@ xaxis ticklabel off\n");
103 fprintf(out
,"@ world xmin %g\n",x
[0]*scale_x
);
104 fprintf(out
,"@ world xmax %g\n",x
[n
-1]*scale_x
);
105 fprintf(out
,"@ world ymin %g\n",min
);
106 fprintf(out
,"@ world ymax %g\n",max
);
107 fprintf(out
,"@ view xmin 0.15\n");
108 fprintf(out
,"@ view xmax 0.85\n");
109 fprintf(out
,"@ view ymin %g\n",0.15+(ngraphs
-1-g
)*0.7/ngraphs
);
110 fprintf(out
,"@ view ymax %g\n",0.15+(ngraphs
-g
)*0.7/ngraphs
);
111 fprintf(out
,"@ yaxis label \"%s\"\n",ylabel
[g
]);
112 fprintf(out
,"@ xaxis tick major %g\n",xsp
);
113 fprintf(out
,"@ xaxis tick minor %g\n",xsp
/2);
114 fprintf(out
,"@ xaxis ticklabel start type spec\n");
115 fprintf(out
,"@ xaxis ticklabel start %g\n",ceil(min
/xsp
)*xsp
);
116 fprintf(out
,"@ yaxis tick major %g\n",ysp
);
117 fprintf(out
,"@ yaxis tick minor %g\n",ysp
/2);
118 fprintf(out
,"@ yaxis ticklabel start type spec\n");
119 fprintf(out
,"@ yaxis ticklabel start %g\n",ceil(min
/ysp
)*ysp
);
120 if ((min
<0) && (max
>0)) {
121 fprintf(out
,"@ zeroxaxis bar on\n");
122 fprintf(out
,"@ zeroxaxis bar linestyle 3\n");
125 if ( bSplit
&& i
>0 && abs(x
[i
])<1e-5 )
127 fprintf(out
,"%10.4f %10.5f\n",x
[i
]*scale_x
,y
[g
][i
]);
134 static void compare(int natoms
,int n1
,rvec
**eigvec1
,int n2
,rvec
**eigvec2
,
135 char *Eig1File
,char *Eig2File
)
137 int n
,neig1
,neig2
,nrow
;
140 double sum1
,sum2
,trace1
,trace2
,sab
,samsb2
,tmp
,ip
;
144 neig1
= read_xvg(Eig1File
,&eig1
,&nrow
);
145 neig2
= read_xvg(Eig2File
,&eig2
,&nrow
);
146 fprintf(stdout
,"\nRead %d and %d eigenvalues\n",neig1
,neig2
);
147 n
= min(n
,min(neig1
,neig2
));
148 fprintf(stdout
,"Will compare the covariance matrices using %d dimensions\n",
156 eig1
[1][i
] = sqrt(eig1
[1][i
]);
159 for(i
=n
; i
<neig1
; i
++)
160 trace1
+= eig1
[1][i
];
166 eig2
[1][i
] = sqrt(eig2
[1][i
]);
169 for(i
=n
; i
<neig2
; i
++)
170 trace2
+= eig1
[1][i
];
172 fprintf(stdout
,"Trace of the two matrices: %g and %g\n",sum1
,sum2
);
173 if (neig1
!=n
|| neig2
!=n
)
174 fprintf(stdout
,"this is %d%% and %d%% of the total trace\n",
175 (int)(100*sum1
/trace1
+0.5),(int)(100*sum2
/trace2
+0.5));
176 fprintf(stdout
,"Square root of the traces: %g and %g\n",
177 sqrt(sum1
),sqrt(sum2
));
184 for(k
=0; k
<natoms
; k
++)
185 ip
+= iprod(eigvec1
[i
][k
],eigvec2
[j
][k
]);
186 tmp
+= eig2
[1][j
]*ip
*ip
;
188 sab
+= eig1
[1][i
]*tmp
;
191 samsb2
= sum1
+sum2
-2*sab
;
195 fprintf(stdout
,"The overlap of the covariance matrices:\n");
196 fprintf(stdout
," normalized: %.3f\n",1-sqrt(samsb2
/(sum1
+sum2
)));
197 tmp
= 1-sab
/sqrt(sum1
*sum2
);
200 fprintf(stdout
," shape: %.3f\n",1-sqrt(tmp
));
203 static void inprod_matrix(char *matfile
,int natoms
,
204 int nvec1
,int *eignr1
,rvec
**eigvec1
,
205 int nvec2
,int *eignr2
,rvec
**eigvec2
,
206 bool bSelect
,int noutvec
,int *outvec
)
210 int i
,x1
,y1
,x
,y
,nlevels
;
212 real inp
,*t_x
,*t_y
,max
;
219 for(y1
=0; y1
<nx
; y1
++)
220 if (outvec
[y1
] < nvec2
) {
221 t_y
[ny
] = eignr2
[outvec
[y1
]]+1;
228 t_y
[y
] = eignr2
[y
]+1;
231 fprintf(stderr
,"Calculating inner-product matrix of %dx%d eigenvectors\n",
237 for(x1
=0; x1
<nx
; x1
++) {
243 t_x
[x1
] = eignr1
[x
]+1;
244 fprintf(stderr
," %d",eignr1
[x
]+1);
245 for(y1
=0; y1
<ny
; y1
++) {
248 while (outvec
[y1
] >= nvec2
)
253 for(i
=0; i
<natoms
; i
++)
254 inp
+= iprod(eigvec1
[x
][i
],eigvec2
[y
][i
]);
255 mat
[x1
][y1
] = fabs(inp
);
260 fprintf(stderr
,"\n");
261 rlo
.r
= 1; rlo
.g
= 1; rlo
.b
= 1;
262 rhi
.r
= 0; rhi
.g
= 0; rhi
.b
= 0;
264 out
= ffopen(matfile
,"w");
265 write_xpm(out
,"Eigenvector inner-products","in.prod.","run 1","run 2",
266 nx
,ny
,t_x
,t_y
,mat
,0.0,max
,rlo
,rhi
,&nlevels
);
270 static void overlap(char *outfile
,int natoms
,
272 int nvec2
,int *eignr2
,rvec
**eigvec2
,
273 int noutvec
,int *outvec
)
279 fprintf(stderr
,"Calculating overlap between eigenvectors of set 2 with eigenvectors\n");
280 for(i
=0; i
<noutvec
; i
++)
281 fprintf(stderr
,"%d ",outvec
[i
]+1);
282 fprintf(stderr
,"\n");
284 out
=xvgropen(outfile
,"Subspace overlap",
285 "Eigenvectors of trajectory 2","Overlap");
286 fprintf(out
,"@ subtitle \"using %d eigenvectors of trajectory 1\"\n",
289 for(x
=0; x
<nvec2
; x
++) {
290 for(v
=0; v
<noutvec
; v
++) {
293 for(i
=0; i
<natoms
; i
++)
294 inp
+=iprod(eigvec1
[vec
][i
],eigvec2
[x
][i
]);
297 fprintf(out
,"%5d %5.3f\n",eignr2
[x
]+1,overlap
/noutvec
);
303 static void project(char *trajfile
,t_topology
*top
,matrix topbox
,rvec
*xtop
,
304 char *projfile
,char *twodplotfile
,char *threedplotfile
,
305 char *filterfile
,int skip
,
306 char *extremefile
,bool bExtrAll
,real extreme
,int nextr
,
307 t_atoms
*atoms
,int natoms
,atom_id
*index
,
308 bool bFit
,rvec
*xref
,int nfit
,atom_id
*ifit
,real
*w_rls
,
309 real
*sqrtm
,rvec
*xav
,
310 int *eignr
,rvec
**eigvec
,
311 int noutvec
,int *outvec
, bool bSplit
)
314 int status
,out
=0,nat
,i
,j
,d
,v
,vec
,nfr
,nframes
=0,snew_size
,frame
;
315 int noutvec_extr
,*imin
,*imax
;
319 real t
,inp
,**inprod
=NULL
,min
=0,max
=0;
320 char str
[STRLEN
],str2
[STRLEN
],**ylabel
,*c
;
325 noutvec_extr
=noutvec
;
331 snew(inprod
,noutvec
+1);
334 fprintf(stderr
,"Writing a filtered trajectory to %s using eigenvectors\n",
336 for(i
=0; i
<noutvec
; i
++)
337 fprintf(stderr
,"%d ",outvec
[i
]+1);
338 fprintf(stderr
,"\n");
339 out
=open_trx(filterfile
,"w");
344 nat
=read_first_x(&status
,trajfile
,&t
,&xread
,box
);
346 fatal_error(0,"the number of atoms in your trajectory (%d) is larger than the number of atoms in your structure file (%d)",nat
,atoms
->nr
);
351 if (nfr
% skip
== 0) {
353 rm_pbc(&(top
->idef
),nat
,box
,xread
,xread
);
354 if (nframes
>=snew_size
) {
356 for(i
=0; i
<noutvec
+1; i
++)
357 srenew(inprod
[i
],snew_size
);
359 inprod
[noutvec
][nframes
]=t
;
360 /* calculate x: a fitted struture of the selected atoms */
361 if (bFit
&& (xref
==NULL
)) {
362 reset_x(nfit
,ifit
,nat
,NULL
,xread
,w_rls
);
363 do_fit(nat
,w_rls
,xtop
,xread
);
365 for (i
=0; i
<natoms
; i
++)
366 copy_rvec(xread
[index
[i
]],x
[i
]);
368 reset_x(natoms
,all_at
,natoms
,NULL
,x
,w_rls
);
369 do_fit(natoms
,w_rls
,xref
,x
);
372 for(v
=0; v
<noutvec
; v
++) {
374 /* calculate (mass-weighted) projection */
376 for (i
=0; i
<natoms
; i
++) {
377 inp
+=(eigvec
[vec
][i
][0]*(x
[i
][0]-xav
[i
][0])+
378 eigvec
[vec
][i
][1]*(x
[i
][1]-xav
[i
][1])+
379 eigvec
[vec
][i
][2]*(x
[i
][2]-xav
[i
][2]))*sqrtm
[i
];
381 inprod
[v
][nframes
]=inp
;
384 for(i
=0; i
<natoms
; i
++)
385 for(d
=0; d
<DIM
; d
++) {
386 /* misuse xread for output */
387 xread
[index
[i
]][d
] = xav
[i
][d
];
388 for(v
=0; v
<noutvec
; v
++)
389 xread
[index
[i
]][d
] +=
390 inprod
[v
][nframes
]*eigvec
[outvec
[v
]][i
][d
]/sqrtm
[i
];
392 write_trx(out
,natoms
,index
,atoms
,0,t
,box
,xread
,NULL
);
397 } while (read_next_x(status
,&t
,nat
,xread
,box
));
404 snew(xread
,atoms
->nr
);
408 snew(ylabel
,noutvec
);
409 for(v
=0; v
<noutvec
; v
++) {
410 sprintf(str
,"vec %d",eignr
[outvec
[v
]]+1);
411 ylabel
[v
]=strdup(str
);
413 sprintf(str
,"projection on eigenvectors (%s)",proj_unit
);
414 write_xvgr_graphs(projfile
, noutvec
, str
, xvgr_tlabel(),
415 ylabel
, nframes
, inprod
[noutvec
], inprod
,
416 time_factor(), FALSE
, bSplit
);
420 sprintf(str
,"projection on eigenvector %d (%s)",
421 eignr
[outvec
[0]]+1,proj_unit
);
422 sprintf(str2
,"projection on eigenvector %d (%s)",
423 eignr
[outvec
[noutvec
-1]]+1,proj_unit
);
424 xvgrout
=xvgropen(twodplotfile
,"2D projection of trajectory",str
,str2
);
425 for(i
=0; i
<nframes
; i
++) {
426 if ( bSplit
&& i
>0 && abs(inprod
[noutvec
][i
])<1e-5 )
427 fprintf(xvgrout
,"&\n");
428 fprintf(xvgrout
,"%10.5f %10.5f\n",inprod
[0][i
],inprod
[noutvec
-1][i
]);
433 if (threedplotfile
) {
438 char *resnm
,*atnm
, pdbform
[STRLEN
];
443 fatal_error(0,"You have selected less than 3 eigenvectors");
446 bPDB
= fn2ftp(threedplotfile
)==efPDB
;
448 box
[XX
][XX
] = box
[YY
][YY
] = box
[ZZ
][ZZ
] = 1;
450 b4D
= bPDB
&& (noutvec
>= 4);
452 fprintf(stderr
, "You have selected four or more eigenvectors:\n"
453 "fourth eigenvector will be plotted "
454 "in bfactor field of pdb file\n");
455 sprintf(str
,"4D proj. of traj. on eigenv. %d, %d, %d and %d",
456 eignr
[outvec
[0]]+1,eignr
[outvec
[1]]+1,
457 eignr
[outvec
[2]]+1,eignr
[outvec
[3]]+1);
459 sprintf(str
,"3D proj. of traj. on eigenv. %d, %d and %d",
460 eignr
[outvec
[0]]+1,eignr
[outvec
[1]]+1,eignr
[outvec
[2]]+1);
462 init_t_atoms(&atoms
,nframes
,FALSE
);
467 for(i
=0; i
<nframes
; i
++) {
468 atoms
.resname
[i
]=&resnm
;
469 atoms
.atomname
[i
]=&atnm
;
470 atoms
.atom
[i
].resnr
=i
;
471 x
[i
][XX
]=inprod
[0][i
];
472 x
[i
][YY
]=inprod
[1][i
];
473 x
[i
][ZZ
]=inprod
[2][i
];
477 if ( ( b4D
|| bSplit
) && bPDB
) {
478 strcpy(pdbform
,pdbformat
);
479 strcat(pdbform
,"%8.4f%8.4f\n");
481 out
=ffopen(threedplotfile
,"w");
482 fprintf(out
,"HEADER %s\n",str
);
484 fprintf(out
,"REMARK %s\n","fourth dimension plotted as B-factor");
486 for(i
=0; i
<atoms
.nr
; i
++) {
487 if ( j
>0 && bSplit
&& abs(inprod
[noutvec
][i
])<1e-5 ) {
488 fprintf(out
,"TER\n");
491 fprintf(out
,pdbform
,"ATOM",i
+1,"C","PRJ",' ',j
+1,
492 PR_VEC(10*x
[i
]), 1.0, 10*b
[i
]);
494 fprintf(out
,"CONECT%5d%5d\n", i
, i
+1);
497 fprintf(out
,"TER\n");
500 write_sto_conf(threedplotfile
,str
,&atoms
,x
,NULL
,box
);
501 free_t_atoms(&atoms
);
506 fprintf(stderr
,"%11s %17s %17s\n","eigenvector","Minimum","Maximum");
508 "%11s %10s %10s %10s %10s\n","","value","time","value","time");
509 snew(imin
,noutvec_extr
);
510 snew(imax
,noutvec_extr
);
511 for(v
=0; v
<noutvec_extr
; v
++) {
512 for(i
=0; i
<nframes
; i
++) {
513 if (inprod
[v
][i
]<inprod
[v
][imin
[v
]])
515 if (inprod
[v
][i
]>inprod
[v
][imax
[v
]])
518 min
=inprod
[v
][imin
[v
]];
519 max
=inprod
[v
][imax
[v
]];
520 fprintf(stderr
,"%7d %10.6f %10.1f %10.6f %10.1f\n",
522 min
,inprod
[noutvec
][imin
[v
]],max
,inprod
[noutvec
][imax
[v
]]);
529 /* build format string for filename: */
530 strcpy(str
,extremefile
);/* copy filename */
531 c
=strrchr(str
,'.'); /* find where extention begins */
532 strcpy(str2
,c
); /* get extention */
533 sprintf(c
,"%%d%s",str2
); /* append '%s' and extention to filename */
534 for(v
=0; v
<noutvec_extr
; v
++) {
535 /* make filename using format string */
537 strcpy(str2
,extremefile
);
539 sprintf(str2
,str
,eignr
[outvec
[v
]]+1);
540 fprintf(stderr
,"Writing %d frames along eigenvector %d to %s\n",
541 nextr
,outvec
[v
]+1,str2
);
542 out
=open_trx(str2
,"w");
543 for(frame
=0; frame
<nextr
; frame
++) {
544 if ((extreme
==0) && (nextr
<=3))
545 for(i
=0; i
<natoms
; i
++)
546 atoms
->atom
[index
[i
]].chain
='A'+frame
;
547 for(i
=0; i
<natoms
; i
++)
550 (xav
[i
][d
] + (min
*(nextr
-frame
-1)+max
*frame
)/(nextr
-1)
551 *eigvec
[outvec
[v
]][i
][d
]/sqrtm
[i
]);
552 write_trx(out
,natoms
,index
,atoms
,0,frame
,topbox
,xread
,NULL
);
557 fprintf(stderr
,"\n");
560 static void components(char *outfile
,int natoms
,real
*sqrtm
,
561 int *eignr
,rvec
**eigvec
,
562 int noutvec
,int *outvec
)
566 char str
[STRLEN
],**ylabel
;
568 fprintf(stderr
,"Writing atom displacements to %s\n",outfile
);
570 snew(ylabel
,noutvec
);
573 for(i
=0; i
<natoms
; i
++)
575 for(g
=0; g
<noutvec
; g
++) {
577 sprintf(str
,"vec %d",eignr
[v
]+1);
578 ylabel
[g
]=strdup(str
);
580 for(i
=0; i
<natoms
; i
++)
581 y
[g
][i
] = norm(eigvec
[v
][i
])/sqrtm
[i
];
583 write_xvgr_graphs(outfile
,noutvec
,"Atom displacements (nm)","Atom number",
584 ylabel
,natoms
,x
,y
,1,TRUE
,FALSE
);
585 fprintf(stderr
,"\n");
588 int main(int argc
,char *argv
[])
590 static char *desc
[] = {
591 "[TT]g_anaeig[tt] analyzes eigenvectors. The eigenvectors can be of a",
592 "covariance matrix ([TT]g_covar[tt]) or of a Normal Modes anaysis",
593 "([TT]g_nmeig[tt]).[PAR]",
595 "When a trajectory is projected on eigenvectors, all structures are",
596 "fitted to the structure in the eigenvector file, if present, otherwise",
597 "to the structure in the structure file. When no run input file is",
598 "supplied, periodicity will not be taken into account. Most analyses",
599 "are performed on eigenvectors [TT]-first[tt] to [TT]-last[tt], but when",
600 "[TT]-first[tt] is set to -1 you will be prompted for a selection.[PAR]",
602 "[TT]-disp[tt]: plot all atom displacements of eigenvectors",
603 "[TT]-first[tt] to [TT]-last[tt].[PAR]",
605 "[TT]-proj[tt]: calculate projections of a trajectory on eigenvectors",
606 "[TT]-first[tt] to [TT]-last[tt].",
607 "The projections of a trajectory on the eigenvectors of its",
608 "covariance matrix are called principal components (pc's).",
609 "It is often useful to check the cosine content the pc's,",
610 "since the pc's of random diffusion are cosines with the number",
611 "of periods equal to half the pc index.",
612 "The cosine content of the pc's can be calculated with the program",
613 "[TT]g_analyze[tt].[PAR]",
615 "[TT]-2d[tt]: calculate a 2d projection of a trajectory on eigenvectors",
616 "[TT]-first[tt] and [TT]-last[tt].[PAR]",
618 "[TT]-3d[tt]: calculate a 3d projection of a trajectory on the first",
619 "three selected eigenvectors.[PAR]",
621 "[TT]-filt[tt]: filter the trajectory to show only the motion along",
622 "eigenvectors [TT]-first[tt] to [TT]-last[tt].[PAR]",
624 "[TT]-extr[tt]: calculate the two extreme projections along a trajectory",
625 "on the average structure and interpolate [TT]-nframes[tt] frames",
626 "between them, or set your own extremes with [TT]-max[tt]. The",
627 "eigenvector [TT]-first[tt] will be written unless [TT]-first[tt] and",
628 "[TT]-last[tt] have been set explicitly, in which case all eigenvectors",
629 "will be written to separate files. Chain identifiers will be added",
630 "when writing a [TT].pdb[tt] file with two or three structures (you",
631 "can use [TT]rasmol -nmrpdb[tt] to view such a pdb file).[PAR]",
633 " Overlap calculations between covariance analysis:[BR]",
634 " NOTE: the analysis should use the same fitting structure[PAR]",
636 "[TT]-over[tt]: calculate the subspace overlap of the eigenvectors in",
637 "file [TT]-v2[tt] with eigenvectors [TT]-first[tt] to [TT]-last[tt]",
638 "in file [TT]-v[tt].[PAR]",
640 "[TT]-inpr[tt]: calculate a matrix of inner-products between",
641 "eigenvectors in files [TT]-v[tt] and [TT]-v2[tt]. All eigenvectors",
642 "of both files will be used unless [TT]-first[tt] and [TT]-last[tt]",
643 "have been set explicitly.[PAR]",
645 "When [TT]-v[tt], [TT]-eig1[tt], [TT]-v2[tt] and [TT]-eig2[tt] are given,",
646 "a single number for the overlap between the covariance matrices is",
647 "generated. The formulas are:[BR]",
648 " difference = sqrt(tr((sqrt(M1) - sqrt(M2))^2))[BR]",
649 "normalized overlap = 1 - difference/sqrt(tr(M1) + tr(M2))[BR]",
650 " shape overlap = 1 - sqrt(tr((sqrt(M1/tr(M1)) - sqrt(M2/tr(M2)))^2))[BR]",
651 "where M1 and M2 are the two covariance matrices and tr is the trace",
652 "of a matrix. The numbers are proportional to the overlap of the square",
653 "root of the fluctuations. The normalized overlap is the most useful",
654 "number, it is 1 for identical matrices and 0 when the sampled",
655 "subspaces are orthogonal."
657 static int first
=1,last
=8,skip
=1,nextr
=2;
659 static bool bSplit
=FALSE
;
661 { "-first", FALSE
, etINT
, {&first
},
662 "First eigenvector for analysis (-1 is select)" },
663 { "-last", FALSE
, etINT
, {&last
},
664 "Last eigenvector for analysis (-1 is till the last)" },
665 { "-skip", FALSE
, etINT
, {&skip
},
666 "Only analyse every nr-th frame" },
667 { "-max", FALSE
, etREAL
, {&max
},
668 "Maximum for projection of the eigenvector on the average structure, "
669 "max=0 gives the extremes" },
670 { "-nframes", FALSE
, etINT
, {&nextr
},
671 "Number of frames for the extremes output" },
672 { "-split", FALSE
, etBOOL
, {&bSplit
},
673 "Split eigenvector projections where time is zero" }
675 #define NPA asize(pa)
681 rvec
*xtop
,*xref1
,*xref2
;
682 bool bDMR1
,bDMA1
,bDMR2
,bDMA2
;
683 int nvec1
,nvec2
,*eignr1
=NULL
,*eignr2
=NULL
;
684 rvec
*x
,*xread
,*xav1
,*xav2
,**eigvec1
=NULL
,**eigvec2
=NULL
;
686 real xid
,totmass
,*sqrtm
,*w_rls
,t
,lambda
;
688 char *grpname
,*indexfile
,title
[STRLEN
];
690 int nout
,*iout
,noutvec
,*outvec
,nfit
;
691 atom_id
*index
,*ifit
;
692 char *Vec2File
,*topfile
;
693 char *Eig1File
,*Eig2File
;
694 char *CompFile
,*ProjOnVecFile
;
695 char *TwoDPlotFile
,*ThreeDPlotFile
;
696 char *FilterFile
,*ExtremeFile
;
697 char *OverlapFile
,*InpMatFile
;
698 bool bFit1
,bFit2
,bM
,bIndex
,bTPS
,bTop
,bVec2
,bProj
;
699 bool bFirstToLast
,bFirstLastSet
,bTraj
,bCompare
,bPDB3D
;
702 { efTRN
, "-v", "eigenvec", ffREAD
},
703 { efTRN
, "-v2", "eigenvec2", ffOPTRD
},
704 { efTRX
, "-f", NULL
, ffOPTRD
},
705 { efTPS
, NULL
, NULL
, ffOPTRD
},
706 { efNDX
, NULL
, NULL
, ffOPTRD
},
707 { efXVG
, "-eig1", "eigenval1", ffOPTRD
},
708 { efXVG
, "-eig2", "eigenval2", ffOPTRD
},
709 { efXVG
, "-disp", "eigdisp", ffOPTWR
},
710 { efXVG
, "-proj", "proj", ffOPTWR
},
711 { efXVG
, "-2d", "2dproj", ffOPTWR
},
712 { efSTO
, "-3d", "3dproj.pdb", ffOPTWR
},
713 { efTRX
, "-filt", "filtered", ffOPTWR
},
714 { efTRX
, "-extr", "extreme.pdb", ffOPTWR
},
715 { efXVG
, "-over", "overlap", ffOPTWR
},
716 { efXPM
, "-inpr", "inprod", ffOPTWR
}
718 #define NFILE asize(fnm)
720 CopyRight(stderr
,argv
[0]);
721 parse_common_args(&argc
,argv
,PCA_CAN_TIME
| PCA_TIME_UNIT
| PCA_CAN_VIEW
| PCA_BE_NICE
,
722 NFILE
,fnm
,NPA
,pa
,asize(desc
),desc
,0,NULL
);
724 indexfile
=ftp2fn_null(efNDX
,NFILE
,fnm
);
726 Vec2File
= opt2fn_null("-v2",NFILE
,fnm
);
727 topfile
= ftp2fn(efTPS
,NFILE
,fnm
);
728 Eig1File
= opt2fn_null("-eig1",NFILE
,fnm
);
729 Eig2File
= opt2fn_null("-eig2",NFILE
,fnm
);
730 CompFile
= opt2fn_null("-disp",NFILE
,fnm
);
731 ProjOnVecFile
= opt2fn_null("-proj",NFILE
,fnm
);
732 TwoDPlotFile
= opt2fn_null("-2d",NFILE
,fnm
);
733 ThreeDPlotFile
= opt2fn_null("-3d",NFILE
,fnm
);
734 FilterFile
= opt2fn_null("-filt",NFILE
,fnm
);
735 ExtremeFile
= opt2fn_null("-extr",NFILE
,fnm
);
736 OverlapFile
= opt2fn_null("-over",NFILE
,fnm
);
737 InpMatFile
= ftp2fn_null(efXPM
,NFILE
,fnm
);
738 bTop
= fn2bTPX(topfile
);
739 bProj
= ProjOnVecFile
|| TwoDPlotFile
|| ThreeDPlotFile
740 || FilterFile
|| ExtremeFile
;
742 opt2parg_bSet("-first",NPA
,pa
) && opt2parg_bSet("-last",NPA
,pa
);
743 bFirstToLast
= CompFile
|| ProjOnVecFile
|| FilterFile
|| OverlapFile
||
744 ((ExtremeFile
|| InpMatFile
) && bFirstLastSet
);
745 bVec2
= Vec2File
|| OverlapFile
|| InpMatFile
;
746 bM
= CompFile
|| bProj
;
747 bTraj
= ProjOnVecFile
|| FilterFile
|| (ExtremeFile
&& (max
==0))
748 || TwoDPlotFile
|| ThreeDPlotFile
;
749 bIndex
= bM
|| bProj
;
750 bTPS
= ftp2bSet(efTPS
,NFILE
,fnm
) || bM
|| bTraj
||
751 FilterFile
|| (bIndex
&& indexfile
);
752 bCompare
= Vec2File
&& Eig1File
&& Eig2File
;
753 bPDB3D
= fn2ftp(ThreeDPlotFile
)==efPDB
;
755 read_eigenvectors(opt2fn("-v",NFILE
,fnm
),&natoms
,&bFit1
,
756 &xref1
,&bDMR1
,&xav1
,&bDMA1
,&nvec1
,&eignr1
,&eigvec1
);
758 read_eigenvectors(Vec2File
,&i
,&bFit2
,
759 &xref2
,&bDMR2
,&xav2
,&bDMA2
,&nvec2
,&eignr2
,&eigvec2
);
761 fatal_error(0,"Dimensions in the eigenvector files don't match");
764 if ((!bFit1
|| xref1
) && !bDMR1
&& !bDMA1
)
766 if ((xref1
==NULL
) && (bM
|| bTraj
))
776 bTop
=read_tps_conf(ftp2fn(efTPS
,NFILE
,fnm
),
777 title
,&top
,&xtop
,NULL
,topbox
,bM
);
779 rm_pbc(&(top
.idef
),atoms
->nr
,topbox
,xtop
,xtop
);
780 /* Fitting is only needed when we need to read a trajectory */
782 if ((xref1
==NULL
) || (bM
&& bDMR1
)) {
784 printf("\nNote: the structure in %s should be the same\n"
785 " as the one used for the fit in g_covar\n",topfile
);
786 printf("\nSelect the index group that was used for the least squares fit in g_covar\n");
787 get_index(atoms
,indexfile
,1,&nfit
,&ifit
,&grpname
);
788 snew(w_rls
,atoms
->nr
);
789 for(i
=0; (i
<nfit
); i
++)
791 w_rls
[ifit
[i
]]=atoms
->atom
[ifit
[i
]].m
;
796 /* make the fit index in xref instead of xtop */
800 for(i
=0; (i
<nfit
); i
++) {
802 w_rls
[i
]=atoms
->atom
[ifit
[i
]].m
;
807 /* make the fit non mass weighted on xref */
811 for(i
=0; i
<nfit
; i
++) {
820 printf("\nSelect an index group of %d elements that corresponds to the eigenvectors\n",natoms
);
821 get_index(atoms
,indexfile
,1,&i
,&index
,&grpname
);
823 fatal_error(0,"you selected a group with %d elements instead of %d",
830 proj_unit
="u\\S1/2\\Nnm";
831 for(i
=0; (i
<natoms
); i
++)
832 sqrtm
[i
]=sqrt(atoms
->atom
[index
[i
]].m
);
835 for(i
=0; (i
<natoms
); i
++)
842 for(i
=0; (i
<natoms
); i
++)
843 for(d
=0;(d
<DIM
);d
++) {
844 t
+=sqr((xav1
[i
][d
]-xav2
[i
][d
])*sqrtm
[i
]);
845 totmass
+=sqr(sqrtm
[i
]);
847 fprintf(stdout
,"RMSD (without fit) between the two average structures:"
848 " %.3f (nm)\n\n",sqrt(t
/totmass
));
855 /* make an index from first to last */
858 for(i
=0; i
<nout
; i
++)
860 } else if (ThreeDPlotFile
) {
861 /* make an index of first+(0,1,2) and last */
862 nout
= bPDB3D
? 4 : 3;
863 nout
= min(last
-first
+1, nout
);
871 /* make an index of first and last */
879 printf("Select eigenvectors for output, end your selection with 0\n");
885 scanf("%d",&iout
[nout
]);
887 } while (iout
[nout
]>=0);
890 /* make an index of the eigenvectors which are present */
893 for(i
=0; i
<nout
; i
++) {
895 while ((j
<nvec1
) && (eignr1
[j
]!=iout
[i
]))
897 if ((j
<nvec1
) && (eignr1
[j
]==iout
[i
])) {
902 fprintf(stderr
,"%d eigenvectors selected for output",noutvec
);
903 if (noutvec
<= 100) {
905 for(j
=0; j
<noutvec
; j
++)
906 fprintf(stderr
," %d",eignr1
[outvec
[j
]]+1);
908 fprintf(stderr
,"\n");
911 components(CompFile
,natoms
,sqrtm
,eignr1
,eigvec1
,noutvec
,outvec
);
914 project(bTraj
? opt2fn("-f",NFILE
,fnm
) : NULL
,
915 bTop
? &top
: NULL
,topbox
,xtop
,
916 ProjOnVecFile
,TwoDPlotFile
,ThreeDPlotFile
,FilterFile
,skip
,
917 ExtremeFile
,bFirstLastSet
,max
,nextr
,atoms
,natoms
,index
,
918 bFit1
,xref1
,nfit
,ifit
,w_rls
,
919 sqrtm
,xav1
,eignr1
,eigvec1
,noutvec
,outvec
,bSplit
);
922 overlap(OverlapFile
,natoms
,
923 eigvec1
,nvec2
,eignr2
,eigvec2
,noutvec
,outvec
);
926 inprod_matrix(InpMatFile
,natoms
,
927 nvec1
,eignr1
,eigvec1
,nvec2
,eignr2
,eigvec2
,
928 bFirstLastSet
,noutvec
,outvec
);
931 compare(natoms
,nvec1
,eigvec1
,nvec2
,eigvec2
,Eig1File
,Eig2File
);
933 if (!CompFile
&& !bProj
&& !OverlapFile
&& !InpMatFile
&& !bCompare
)
934 fprintf(stderr
,"\nIf you want some output,"
935 " set one (or two or ...) of the output file options\n");
937 view_all(NFILE
, fnm
);