4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
34 * Green Red Orange Magenta Azure Cyan Skyblue
74 static char *pdbtp
[epdbNR
]={"ATOM ","HETATM"};
76 real
calc_mass(t_atoms
*atoms
,bool bGetMass
,void *atomprop
)
82 for(i
=0; (i
<atoms
->nr
); i
++) {
84 (void) query_atomprop(atomprop
,epropMass
,
85 *atoms
->resname
[atoms
->atom
[i
].resnr
],
86 *atoms
->atomname
[i
],&(atoms
->atom
[i
].m
));
87 tmass
+= atoms
->atom
[i
].m
;
93 real
calc_geom(int isize
,atom_id
*index
,
94 rvec
*x
, rvec geom_center
, rvec min
, rvec max
,bool bDiam
)
100 clear_rvec(geom_center
);
110 for (j
=0; j
<DIM
; j
++)
111 min
[j
]=max
[j
]=x
[ii
][j
];
112 for (i
=0; i
<isize
; i
++) {
117 rvec_inc(geom_center
,x
[ii
]);
118 for (j
=0; j
<DIM
; j
++) {
119 if (x
[ii
][j
] < min
[j
]) min
[j
]=x
[ii
][j
];
120 if (x
[ii
][j
] > max
[j
]) max
[j
]=x
[ii
][j
];
124 for (j
=i
+1; j
<isize
; j
++) {
125 d
= distance2(x
[ii
],x
[index
[j
]]);
126 diam2
= max(d
,diam2
);
129 for (j
=i
+1; j
<isize
; j
++) {
130 d
= distance2(x
[i
],x
[j
]);
131 diam2
= max(d
,diam2
);
135 svmul(1.0/isize
,geom_center
,geom_center
);
141 void center_conf(int natom
, rvec
*x
, rvec center
, rvec geom_cent
)
146 rvec_sub(center
,geom_cent
,shift
);
148 printf(" shift :%7.3f%7.3f%7.3f (nm)\n",
149 shift
[XX
],shift
[YY
],shift
[ZZ
]);
151 for (i
=0; (i
<natom
); i
++)
152 rvec_inc(x
[i
], shift
);
155 void scale_conf(int natom
,rvec x
[],matrix box
,rvec scale
)
159 for(i
=0; i
<natom
; i
++) {
160 for (j
=0; j
<DIM
; j
++)
163 for (i
=0; i
<DIM
; i
++)
164 for (j
=0; j
<DIM
; j
++)
165 box
[i
][j
] *= scale
[j
];
168 void rm_gropbc(t_atoms
*atoms
,rvec x
[],matrix box
)
173 /* check periodic boundary */
174 for(n
=1;(n
<atoms
->nr
);n
++) {
175 for(m
=DIM
-1; m
>=0; m
--) {
176 dist
= x
[n
][m
]-x
[n
-1][m
];
177 if (fabs(dist
) > 0.9*box
[m
][m
]) {
180 x
[n
][d
] -= box
[m
][d
];
183 x
[n
][d
] += box
[m
][d
];
189 void read_bfac(char *fn
, int *n_bfac
, double **bfac_val
, int **bfac_nr
)
194 *n_bfac
= get_lines(fn
, &bfac_lines
);
195 snew(*bfac_val
, *n_bfac
);
196 snew(*bfac_nr
, *n_bfac
);
197 fprintf(stderr
, "Reading %d B-factors from %s\n",*n_bfac
,fn
);
198 for(i
=0; (i
<*n_bfac
); i
++) {
199 /*fprintf(stderr, "Line %d: %s",i,bfac_lines[i]);*/
200 sscanf(bfac_lines
[i
],"%d %lf",&(*bfac_nr
)[i
],&(*bfac_val
)[i
]);
201 /*fprintf(stderr," nr %d val %g\n",(*bfac_nr)[i],(*bfac_val)[i]);*/
206 void set_pdb_conf_bfac(int natoms
,int nres
,t_atoms
*atoms
,
207 int n_bfac
,double *bfac
,int *bfac_nr
,
211 real bfac_min
,bfac_max
;
218 for(i
=0; (i
<n_bfac
); i
++) {
219 if (bfac_nr
[i
]-1>=atoms
->nres
)
221 if ((bfac_nr
[i
]-1<0) || (bfac_nr
[i
]-1>=atoms
->nr
))
222 fatal_error(0,"Index of B-Factor %d is out of range: %d (%g)",
223 i
+1,bfac_nr
[i
],bfac
[i
]);
224 if (bfac
[i
] > bfac_max
)
226 if (bfac
[i
] < bfac_min
)
229 while ( (bfac_max
> 99.99) || (bfac_min
< -99.99) ) {
230 fprintf(stderr
,"Range of values for B-factors too large (min %g, max %g) "
231 "will scale down a factor 10\n",bfac_min
,bfac_max
);
232 for(i
=0; (i
<n_bfac
); i
++)
237 while ( (fabs(bfac_max
) < 0.5) && (fabs(bfac_min
) < 0.5) ) {
238 fprintf(stderr
,"Range of values for B-factors too small (min %g, max %g) "
239 "will scale up a factor 10\n",bfac_min
,bfac_max
);
240 for(i
=0; (i
<n_bfac
); i
++)
246 for(i
=0; (i
<natoms
); i
++)
247 atoms
->pdbinfo
[i
].bfac
=0;
250 fprintf(stderr
,"Will attach %d B-factors to %d residues\n",
252 for(i
=0; (i
<n_bfac
); i
++) {
254 for(n
=0; (n
<natoms
); n
++)
255 if ( bfac_nr
[i
] == (atoms
->atom
[n
].resnr
+1) ) {
256 atoms
->pdbinfo
[n
].bfac
=bfac
[i
];
260 sprintf(buf
,"Residue nr %d not found\n",bfac_nr
[i
]);
265 fprintf(stderr
,"Will attach %d B-factors to %d atoms\n",n_bfac
,natoms
);
266 for(i
=0; (i
<n_bfac
); i
++) {
267 atoms
->pdbinfo
[bfac_nr
[i
]-1].bfac
=bfac
[i
];
272 void pdb_legend(FILE *out
,int natoms
,int nres
,t_atoms
*atoms
,rvec x
[])
274 real bfac_min
,bfac_max
,xmin
,ymin
,zmin
;
282 for (i
=0; (i
<natoms
); i
++) {
283 xmin
= min(xmin
,x
[i
][XX
]);
284 ymin
= min(ymin
,x
[i
][YY
]);
285 zmin
= min(zmin
,x
[i
][ZZ
]);
286 bfac_min
= min(bfac_min
,atoms
->pdbinfo
[i
].bfac
);
287 bfac_max
= max(bfac_max
,atoms
->pdbinfo
[i
].bfac
);
289 fprintf(stderr
,"B-factors range from %g to %g\n",bfac_min
,bfac_max
);
290 for (i
=1; (i
<12); i
++) {
291 fprintf(out
,pdbformat
,
292 "ATOM ",natoms
+1+i
,"CA","LEG",' ',nres
+1,
293 (xmin
+(i
*0.12))*10,ymin
*10,zmin
*10,1.0,
294 bfac_min
+ ((i
-1.0)*(bfac_max
-bfac_min
)/10) );
297 void visualize_images(char *fn
,matrix box
)
305 init_t_atoms(&atoms
,nat
,FALSE
);
310 for(i
=0; i
<nat
; i
++) {
311 atoms
.atomname
[i
] = &c
;
312 atoms
.atom
[i
].resnr
= i
;
313 atoms
.resname
[i
] = &ala
;
314 atoms
.atom
[i
].chain
= 'A'+i
/NCUCVERT
;
316 calc_triclinic_images(box
,img
+1);
318 write_sto_conf(fn
,"Images",&atoms
,img
,NULL
,box
);
320 free_t_atoms(&atoms
);
325 void visualize_box(FILE *out
,int a0
,int r0
,matrix box
,rvec gridsize
)
329 int nx
,ny
,nz
,nbox
,nat
;
331 int rectedge
[24] = { 0,1, 1,3, 3,2, 0,2, 0,4, 1,5, 3,7, 2,6, 4,5, 5,7, 7,6, 6,4 };
336 nx
= (int)(gridsize
[XX
]+0.5);
337 ny
= (int)(gridsize
[YY
]+0.5);
338 nz
= (int)(gridsize
[ZZ
]+0.5);
340 if (TRICLINIC(box
)) {
343 calc_compact_unitcell_vertices(box
,vert
);
347 for(x
=0; x
<nx
; x
++) {
349 shift
[i
] = x
*box
[0][i
]+y
*box
[1][i
]+z
*box
[2][i
];
350 for(i
=0; i
<NCUCVERT
; i
++) {
351 rvec_add(vert
[i
],shift
,vert
[j
]);
356 for(i
=0; i
<nat
; i
++) {
357 fprintf(out
,pdbformat
,"ATOM",a0
+i
,"C","BOX",'K'+i
/NCUCVERT
,r0
+i
,
358 10*vert
[i
][XX
],10*vert
[i
][YY
],10*vert
[i
][ZZ
]);
362 edge
= compact_unitcell_edges();
363 for(j
=0; j
<nbox
; j
++)
364 for(i
=0; i
<NCUCEDGE
; i
++)
365 fprintf(out
,"CONECT%5d%5d\n",
366 a0
+ j
*NCUCVERT
+ edge
[2*i
],
367 a0
+ j
*NCUCVERT
+ edge
[2*i
+1]);
374 for(x
=0; x
<=1; x
++) {
375 fprintf(out
,pdbformat
,"ATOM",a0
+i
,"C","BOX",'K'+i
/8,r0
+i
,
376 x
*10*box
[XX
][XX
],y
*10*box
[YY
][YY
],z
*10*box
[ZZ
][ZZ
]);
381 fprintf(out
,"CONECT%5d%5d\n",a0
+rectedge
[i
],a0
+rectedge
[i
+1]);
385 int main(int argc
, char *argv
[])
387 static char *desc
[] = {
388 "editconf converts generic structure format to [TT].gro[tt], [TT].g96[tt]",
391 "The box can be modified with options [TT]-box[tt], [TT]-d[tt] and",
392 "[TT]-angles[tt]. Both [TT]-box[tt] and [TT]-d[tt]",
393 "will center the system in the box.",
395 "Option [TT]-bt[tt] determines the box type: [TT]tric[tt] is a",
396 "triclinic box, [TT]cubic[tt] is a cubic box, [TT]dodecahedron[tt] is",
397 "a rhombic dodecahedron and [TT]octahedron[tt] is a truncated octahedron.",
398 "The last two are special cases of a triclinic box.",
399 "The length of the three box vectors of the truncated octahedron is the",
400 "shortest distance between two opposite hexagons.",
401 "The volume of a dodecahedron is 0.71 and that of a truncated octahedron",
402 "is 0.77 of that of a cubic box with the same periodic image distance.",
404 "Option [TT]-box[tt] requires only",
405 "one value for a cubic box, dodecahedron and a truncated octahedron.",
406 "With [TT]-d[tt] and [TT]tric[tt] the size of the system in the x, y",
407 "and z directions is used. With [TT]-d[tt] and [TT]cubic[tt],",
408 "[TT]dodecahedron[tt] or [TT]octahedron[tt] the diameter of the system",
409 "is used, which is the largest distance between two atoms.",
411 "Option [TT]-angles[tt] is only meaningful with option [TT]-box[tt] and",
412 "a triclinic box and can not be used with option [TT]-d[tt].",
414 "When [TT]-n[tt] or [TT]-ndef[tt] is set, a group",
415 "can be selected for calculating the size and the geometric center,",
416 "otherwise the whole system is used.",
418 "[TT]-rotate[tt] rotates the coordinates and velocities.",
419 "[TT]-princ[tt] aligns the principal axes of the system along the",
420 "coordinate axes, this may allow you to decrease the box volume,",
421 "but beware that molecules can rotate significantly in a nanosecond.[PAR]",
422 "Scaling is applied before any of the other operations are",
423 "performed. Boxes can be scaled to give a certain density (option",
424 "[TT]-density[tt]). A special feature of the scaling option, when the",
425 "factor -1 is given in one dimension, one obtains a mirror image,",
426 "mirrored in one of the plains, when one uses -1 in three dimensions",
427 "a point-mirror image is obtained.[PAR]",
428 "Groups are selected after all operations have been applied.[PAR]",
429 "Periodicity can be removed in a crude manner.",
430 "It is important that the box sizes at the bottom of your input file",
431 "are correct when the periodicity is to be removed.",
433 "The program can optionally rotate the solute molecule to align the",
434 "molecule along its principal axes ([TT]-rotate[tt])",
436 "When writing [TT].pdb[tt] files, B-factors can be",
437 "added with the [TT]-bf[tt] option. B-factors are read",
438 "from a file with with following format: first line states number of",
439 "entries in the file, next lines state an index",
440 "followed by a B-factor. The B-factors will be attached per residue",
441 "unless an index is larger than the number of residues or unless the",
442 "[TT]-atom[tt] option is set. Obviously, any type of numeric data can",
443 "be added instead of B-factors. [TT]-legend[tt] will produce",
444 "a row of CA atoms with B-factors ranging from the minimum to the",
445 "maximum value found, effectively making a legend for viewing.",
447 "With the option -mead a special pdb file for the MEAD electrostatics",
448 "program (Poisson-Boltzmann solver) can be made. A further prerequisite",
449 "is that the input file is a run input file.",
450 "The B-factor field is then filled with the Van der Waals radius",
451 "of the atoms while the occupancy field will hold the charge.",
453 "The option -grasp is similar, but it puts the charges in the B-factor",
454 "and the radius in the occupancy.",
456 "Finally with option [TT]-label[tt] editconf can add a chain identifier",
457 "to a pdb file, which can be useful for analysis with e.g. rasmol."
459 "To convert a truncated octrahedron file produced by a package which uses",
460 "a cubic box with the corners cut off (such as Gromos) use:[BR]",
461 "[TT]editconf -f <in> -rotate 0 -45 -35.264 -bt o -box <veclen> -o <out>[tt][BR]",
462 "where [TT]veclen[tt] is the size of the cubic box times sqrt(3)/2."
464 static char *bugs
[] = {
465 "For complex molecules, the periodicity removal routine may break down, "
466 "in that case you can use trjconv"
468 static real dist
=0.0,rbox
=0.0,to_diam
=0.0;
469 static bool bNDEF
=FALSE
,bRMPBC
=FALSE
,bCenter
=FALSE
,bVOL
=TRUE
;
470 static bool peratom
=FALSE
,bLegend
=FALSE
,bOrient
=FALSE
,bMead
=FALSE
,bGrasp
=FALSE
;
471 static rvec scale
={1,1,1},newbox
={0,0,0},newang
={90,90,90};
472 static real rho
=1000.0,rvdw
=0.12;
473 static rvec center
={0,0,0},translation
={0,0,0},rotangles
={0,0,0};
474 static char *btype
[]={ NULL
, "tric", "cubic", "dodecahedron", "octahedron", NULL
},*label
="A";
475 static rvec visbox
={0,0,0};
477 { "-ndef", FALSE
, etBOOL
, {&bNDEF
},
478 "Choose output from default index groups" },
479 { "-visbox", FALSE
, etRVEC
, {visbox
},
480 "HIDDENVisualize a grid of boxes, -1 visualizes the 14 box images" },
481 { "-bt", FALSE
, etENUM
, {btype
},
482 "Box type for -box and -d" },
483 { "-box", FALSE
, etRVEC
, {newbox
}, "Box vector lengths (a,b,c)" },
484 { "-angles", FALSE
, etRVEC
, {newang
},
485 "Angles between the box vectors (bc,ac,ab)" },
486 { "-d", FALSE
, etREAL
, {&dist
},
487 "Distance between the solute and the box" },
488 { "-c", FALSE
, etBOOL
, {&bCenter
},
489 "Center molecule in box (implied by -box and -d)" },
490 { "-center", FALSE
, etRVEC
, {center
}, "Coordinates of geometrical center"},
491 { "-translate", FALSE
, etRVEC
, {translation
},
493 { "-rotate", FALSE
, etRVEC
, {rotangles
},
494 "Rotation around the X, Y and Z axes in degrees" },
495 { "-princ", FALSE
, etBOOL
, {&bOrient
}, "Orient molecule(s) along their principal axes" },
496 { "-scale", FALSE
, etRVEC
, {scale
}, "Scaling factor" },
497 { "-density",FALSE
, etREAL
, {&rho
},
498 "Density (g/l) of the output box achieved by scaling" },
499 { "-vol", FALSE
, etBOOL
, {&bVOL
},
500 "Compute and print volume of the box" },
501 { "-pbc", FALSE
, etBOOL
, {&bRMPBC
},
502 "Remove the periodicity (make molecule whole again)" },
503 { "-mead", FALSE
, etBOOL
, {&bMead
},
504 "Store the charge of the atom in the occupancy field and the radius of the atom in the B-factor field" },
505 { "-grasp", FALSE
, etBOOL
, {&bGrasp
},
506 "Store the charge of the atom in the B-factor field and the radius of the atom in the occupancy field" },
507 { "-rvdw", FALSE
, etREAL
, {&rvdw
},
508 "Default Van der Waals radius if one can not be found in the database" },
509 { "-atom", FALSE
, etBOOL
, {&peratom
}, "Force B-factor attachment per atom" },
510 { "-legend", FALSE
, etBOOL
, {&bLegend
}, "Make B-factor legend" },
511 { "-label", FALSE
, etSTR
, {&label
}, "Add chain label for all residues" }
513 #define NPA asize(pa)
517 char *infile
,*outfile
,title
[STRLEN
];
518 int outftp
,natom
,i
,j
,n_bfac
;
523 char *grpname
,*sgrpname
;
525 atom_id
*index
,*sindex
;
526 rvec
*x
,*v
,gc
,min
,max
,size
;
528 bool bIndex
,bSetSize
,bSetAng
,bCubic
,bDist
,bSetCenter
;
529 bool bHaveV
,bScale
,bRho
,bTranslate
,bRotate
,bCalcGeom
,bCalcDiam
;
530 real xs
,ys
,zs
,xcent
,ycent
,zcent
,diam
=0,mass
=0,d
,vdw
;
532 { efSTX
, "-f", NULL
, ffREAD
},
533 { efNDX
, "-n", NULL
, ffOPTRD
},
534 { efSTO
, NULL
, NULL
, ffWRITE
},
535 { efDAT
, "-bf", "bfact", ffOPTRD
}
537 #define NFILE asize(fnm)
539 CopyRight(stderr
,argv
[0]);
540 parse_common_args(&argc
,argv
,PCA_CAN_VIEW
,NFILE
,fnm
,NPA
,pa
,
541 asize(desc
),desc
,asize(bugs
),bugs
);
543 bIndex
= opt2bSet("-n",NFILE
,fnm
) || bNDEF
;
544 bSetSize
= opt2parg_bSet("-box" ,NPA
,pa
);
545 bSetAng
= opt2parg_bSet("-angles" ,NPA
,pa
);
546 bSetCenter
= opt2parg_bSet("-center" ,NPA
,pa
);
547 bDist
= opt2parg_bSet("-d" ,NPA
,pa
);
548 bCenter
= bCenter
|| bDist
|| bSetCenter
|| bSetSize
;
549 bScale
= opt2parg_bSet("-scale" ,NPA
,pa
);
550 bRho
= opt2parg_bSet("-density",NPA
,pa
);
551 bTranslate
= opt2parg_bSet("-translate",NPA
,pa
);
552 bRotate
= opt2parg_bSet("-rotate",NPA
,pa
);
554 fprintf(stderr
,"WARNING: setting -density overrides -scale\n");
555 bScale
= bScale
|| bRho
;
556 bCalcGeom
= bCenter
|| bTranslate
|| bRotate
|| bOrient
|| bScale
;
557 bCalcDiam
= btype
[0][0]=='c' || btype
[0][0]=='d' || btype
[0][0]=='o';
559 infile
= ftp2fn(efSTX
,NFILE
,fnm
);
560 outfile
= ftp2fn(efSTO
,NFILE
,fnm
);
561 outftp
= fn2ftp(outfile
);
562 atomprop
= get_atomprop();
563 if (bMead
&& bGrasp
) {
564 fprintf(stderr
,"Incompatible options -mead and -grasp. Turning off -grasp\n");
567 if ((bMead
|| bGrasp
) && (outftp
!= efPDB
))
568 fatal_error(0,"Output file should be a .pdb file"
569 " when using the -mead option\n");
570 if ((bMead
|| bGrasp
) && !((fn2ftp(infile
) == efTPR
) ||
571 (fn2ftp(infile
) == efTPA
) ||
572 (fn2ftp(infile
) == efTPB
)))
573 fatal_error(0,"Input file should be a .tp[abr] file"
574 " when using the -mead option\n");
576 get_stx_coordnum(infile
,&natom
);
577 init_t_atoms(&atoms
,natom
,TRUE
);
580 read_stx_conf(infile
,title
,&atoms
,x
,v
,box
);
581 printf("Read %d atoms\n",atoms
.nr
);
584 printf("Volume: %g nm^3, corresponds to roughly %d electrons\n",
585 vol
,100*((int)(vol
*4.5)));
588 if (bMead
|| bGrasp
) {
589 top
= read_top(infile
);
590 if (atoms
.nr
!= top
->atoms
.nr
)
591 fatal_error(0,"Atom numbers don't match (%d vs. %d)",
592 atoms
.nr
,top
->atoms
.nr
);
593 for(i
=0; (i
<atoms
.nr
); i
++) {
594 /* Factor of 10 for Angstroms */
595 if (query_atomprop(atomprop
,epropVDW
,
596 *top
->atoms
.resname
[top
->atoms
.atom
[i
].resnr
],
597 *top
->atoms
.atomname
[i
],&vdw
))
602 atoms
.pdbinfo
[i
].occup
= top
->atoms
.atom
[i
].q
;
603 atoms
.pdbinfo
[i
].bfac
= vdw
;
606 /* Factor of 10 for Angstroms */
607 atoms
.pdbinfo
[i
].occup
= vdw
;
608 atoms
.pdbinfo
[i
].bfac
= top
->atoms
.atom
[i
].q
;
613 for (i
=0; (i
<natom
) && !bHaveV
; i
++)
614 for (j
=0; (j
<DIM
) && !bHaveV
; j
++)
615 bHaveV
=bHaveV
|| (v
[i
][j
]!=0);
616 printf("%selocities found\n",bHaveV
?"V":"No v");
620 fatal_error(0,"Sorry, can not visualize box with index groups");
622 fatal_error(0,"Sorry, can only visualize box with a pdb file");
623 } else if (visbox
[0] == -1)
624 visualize_images("images.pdb",box
);
628 rm_gropbc(&atoms
,x
,box
);
632 fprintf(stderr
,"\nSelect a group for determining the system size:\n");
633 get_index(&atoms
,ftp2fn_null(efNDX
,NFILE
,fnm
),
634 1,&ssize
,&sindex
,&sgrpname
);
639 diam
=calc_geom(ssize
,sindex
,x
,gc
,min
,max
,bCalcDiam
);
640 rvec_sub(max
, min
, size
);
641 printf(" system size :%7.3f%7.3f%7.3f (nm)\n",
642 size
[XX
], size
[YY
], size
[ZZ
]);
644 printf(" diameter :%7.3f (nm)\n",diam
);
645 printf(" center :%7.3f%7.3f%7.3f (nm)\n", gc
[XX
], gc
[YY
], gc
[ZZ
]);
646 printf(" box vectors :%7.3f%7.3f%7.3f (nm)\n",
647 norm(box
[XX
]), norm(box
[YY
]), norm(box
[ZZ
]));
648 printf(" box angles :%7.2f%7.2f%7.2f (degrees)\n",
649 norm2(box
[ZZ
])==0 ? 0 :
650 RAD2DEG
*acos(cos_angle_no_table(box
[YY
],box
[ZZ
])),
651 norm2(box
[ZZ
])==0 ? 0 :
652 RAD2DEG
*acos(cos_angle_no_table(box
[XX
],box
[ZZ
])),
653 norm2(box
[YY
])==0 ? 0 :
654 RAD2DEG
*acos(cos_angle_no_table(box
[XX
],box
[YY
])));
655 printf(" box volume :%7.2f (nm^3)\n",det(box
));
659 mass
= calc_mass(&atoms
,!fn2bTPX(infile
),atomprop
);
665 /* Get a group for principal component analysis */
666 fprintf(stderr
,"\nSelect group for orientation of molecule:\n");
667 get_index(&atoms
,ftp2fn_null(efNDX
,NFILE
,fnm
),1,&isize
,&index
,&grpnames
);
669 /* Orient the principal axes along the coordinate axes */
670 orient_princ(&atoms
,isize
,index
,natom
,x
,bHaveV
? v
: NULL
, NULL
);
676 /* scale coordinates and box */
678 /* Compute scaling constant */
682 dens
= (mass
*AMU
)/(vol
*NANO
*NANO
*NANO
);
683 fprintf(stderr
,"Volume of input %g (nm^3)\n",vol
);
684 fprintf(stderr
,"Mass of input %g (a.m.u.)\n",mass
);
685 fprintf(stderr
,"Density of input %g (g/l)\n",dens
);
686 if (vol
==0 || mass
==0)
687 fatal_error(0,"Cannot scale density with "
688 "zero mass (%g) or volume (%g)\n",mass
,vol
);
690 scale
[XX
] = scale
[YY
] = scale
[ZZ
] = pow(dens
/rho
,1.0/3.0);
691 fprintf(stderr
,"Scaling all box vectors by %g\n",scale
[XX
]);
693 scale_conf(atoms
.nr
,x
,box
,scale
);
697 printf("Translating by %g %g %g nm\n",translation
[XX
],translation
[YY
],translation
[ZZ
]);
698 for(i
=0; i
<natom
; i
++)
699 rvec_inc(x
[i
],translation
);
703 printf("Rotating %g, %g, %g degrees around the X, Y and Z axis respectively\n",rotangles
[XX
],rotangles
[YY
],rotangles
[ZZ
]);
705 rotangles
[i
] *= DEG2RAD
;
706 rotate_conf(natom
,x
,v
,rotangles
[XX
],rotangles
[YY
],rotangles
[ZZ
]);
710 /* recalc geometrical center and max and min coordinates and size */
711 calc_geom(ssize
,sindex
,x
,gc
,min
,max
,FALSE
);
712 rvec_sub(max
, min
, size
);
713 if (bScale
|| bOrient
|| bRotate
)
714 printf("new system size : %6.3f %6.3f %6.3f\n",
715 size
[XX
],size
[YY
],size
[ZZ
]);
718 if (bSetSize
|| bDist
|| (btype
[0][0]=='t' && bSetAng
)) {
719 if (!(bSetSize
|| bDist
))
720 for (i
=0; i
<DIM
; i
++)
721 newbox
[i
] = norm(box
[i
]);
723 /* calculate new boxsize */
728 newbox
[i
] = size
[i
]+2*dist
;
730 box
[XX
][XX
] = newbox
[XX
];
731 box
[YY
][YY
] = newbox
[YY
];
732 box
[ZZ
][ZZ
] = newbox
[ZZ
];
734 svmul(DEG2RAD
,newang
,newang
);
735 box
[XX
][XX
] = newbox
[XX
];
736 box
[YY
][XX
] = newbox
[YY
]*cos(newang
[ZZ
]);
737 box
[YY
][YY
] = newbox
[YY
]*sin(newang
[ZZ
]);
738 box
[ZZ
][XX
] = newbox
[ZZ
]*cos(newang
[YY
]);
739 box
[ZZ
][YY
] = newbox
[ZZ
]
740 *(cos(newang
[XX
])-cos(newang
[YY
])*cos(newang
[ZZ
]))/sin(newang
[ZZ
]);
741 box
[ZZ
][ZZ
] = sqrt(sqr(newbox
[ZZ
])
742 -box
[ZZ
][XX
]*box
[ZZ
][XX
]-box
[ZZ
][YY
]*box
[ZZ
][YY
]);
744 if (bDist
&& TRICLINIC(box
))
745 fprintf(stderr
,"WARNING: the box is triclinic, the minimum distance between the solute and the box might be less than %f\nYou can check this with g_mindist -pi\n",dist
);
754 if (btype
[0][0] == 'c')
757 else if (btype
[0][0] == 'd') {
762 box
[ZZ
][ZZ
] = d
*sqrt(2)/2;
766 box
[YY
][YY
] = d
*sqrt(2)*2/3;
768 box
[ZZ
][YY
] = d
*sqrt(2)/3;
769 box
[ZZ
][ZZ
] = d
*sqrt(6)/3;
775 /* calculate new coords for geometrical center */
777 calc_box_center(box
,center
);
779 /* center molecule on 'center' */
781 center_conf(natom
,x
,center
,gc
);
785 calc_geom(ssize
,sindex
,x
, gc
, min
, max
, FALSE
);
786 printf("new center :%7.3f%7.3f%7.3f (nm)\n",gc
[XX
],gc
[YY
],gc
[ZZ
]);
788 if (bOrient
|| bScale
|| bDist
|| bSetSize
) {
789 printf("new box vectors :%7.3f%7.3f%7.3f (nm)\n",
790 norm(box
[XX
]), norm(box
[YY
]), norm(box
[ZZ
]));
791 printf("new box angles :%7.2f%7.2f%7.2f (degrees)\n",
792 norm2(box
[ZZ
])==0 ? 0 :
793 RAD2DEG
*acos(cos_angle_no_table(box
[YY
],box
[ZZ
])),
794 norm2(box
[ZZ
])==0 ? 0 :
795 RAD2DEG
*acos(cos_angle_no_table(box
[XX
],box
[ZZ
])),
796 norm2(box
[YY
])==0 ? 0 :
797 RAD2DEG
*acos(cos_angle_no_table(box
[XX
],box
[YY
])));
798 printf("new box volume :%7.2f (nm^3)\n",det(box
));
802 printf("\nWARNING: %s\n",check_box(box
));
805 fprintf(stderr
,"\nSelect a group for output:\n");
806 get_index(&atoms
,opt2fn_null("-n",NFILE
,fnm
),
807 1,&isize
,&index
,&grpname
);
808 if (opt2bSet("-bf",NFILE
,fnm
))
809 fatal_error(0,"combination not implemented: -bf -n or -bf -ndef");
811 write_sto_conf_indexed(outfile
,title
,&atoms
,x
,bHaveV
?v
:NULL
,box
,
815 if (outftp
!= efPDB
) {
816 write_sto_conf(outfile
,title
,&atoms
,x
,bHaveV
?v
:NULL
,box
);
819 out
=ffopen(outfile
,"w");
820 if (opt2bSet("-bf",NFILE
,fnm
)) {
821 read_bfac(opt2fn("-bf",NFILE
,fnm
),&n_bfac
,&bfac
,&bfac_nr
);
822 set_pdb_conf_bfac(atoms
.nr
,atoms
.nres
,&atoms
,
823 n_bfac
,bfac
,bfac_nr
,peratom
);
825 if (opt2parg_bSet("-label",NPA
,pa
)) {
826 for(i
=0; (i
<atoms
.nr
); i
++)
827 atoms
.atom
[i
].chain
=label
[0];
829 if (bMead
|| bGrasp
) {
831 set_pdb_wide_format(TRUE
);
832 fprintf(out
,"REMARK "
833 "The b-factors in this file hold atomic radii\n");
834 fprintf(out
,"REMARK "
835 "The occupancy in this file hold atomic charges\n");
838 fprintf(out
,"GRASP PDB FILE\nFORMAT NUMBER=1\n");
839 fprintf(out
,"REMARK "
840 "The b-factors in this file hold atomic charges\n");
841 fprintf(out
,"REMARK "
842 "The occupancy in this file hold atomic radii\n");
845 write_pdbfile(out
,title
,&atoms
,x
,box
,0,-1);
847 pdb_legend(out
,atoms
.nr
,atoms
.nres
,&atoms
,x
);
849 visualize_box(out
,bLegend
? atoms
.nr
+12 : atoms
.nr
,
850 bLegend
? atoms
.nres
=12 : atoms
.nres
,box
,visbox
);
854 done_atomprop(&atomprop
);
856 do_view(outfile
,NULL
);