3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
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
33 * Green Red Orange Magenta Azure Cyan Skyblue
49 #include "gmx_fatal.h"
62 static t_charge
*mk_charge(t_atoms
*atoms
,t_block
*cgs
,int *nncg
)
66 int i
,j
,ncg
,resnr
,anr
;
69 /* Find the charged groups */
71 for(i
=0; (i
<cgs
->nr
); i
++) {
73 for(j
=cgs
->index
[i
]; (j
<cgs
->index
[i
+1]); j
++) {
76 if (fabs(qq
) > 1.0e-5) {
81 resnr
=atoms
->atom
[anr
].resind
;
83 *(atoms
->resinfo
[resnr
].name
),
84 atoms
->resinfo
[resnr
].nr
);
85 cg
[ncg
].label
=strdup(buf
);
91 for(i
=0; (i
<ncg
); i
++) {
92 printf("CG: %10s Q: %6g Atoms:",
94 for(j
=cgs
->index
[cg
[i
].cg
]; (j
<cgs
->index
[cg
[i
].cg
+1]); j
++)
102 static real
calc_dist(t_pbc
*pbc
,rvec x
[],t_block
*cgs
,int icg
,int jcg
)
106 real d2
,mindist2
=1000;
108 for(i
=cgs
->index
[icg
]; (i
<cgs
->index
[icg
+1]); i
++) {
109 for(j
=cgs
->index
[jcg
]; (j
<cgs
->index
[jcg
+1]); j
++) {
110 pbc_dx(pbc
,x
[i
],x
[j
],dx
);
116 return sqrt(mindist2
);
119 int gmx_saltbr(int argc
,char *argv
[])
121 const char *desc
[] = {
122 "g_saltbr plots the distance between all combination of charged groups",
123 "as a function of time. The groups are combined in different ways."
124 "A minimum distance can be given, (eg. the cut-off), then groups",
125 "that are never closer than that distance will not be plotted.[BR]",
126 "Output will be in a number of fixed filenames, min-min.xvg, plus-min.xvg",
127 "and plus-plus.xvg, or files for every individual ion-pair if selected"
129 static bool bSep
=FALSE
;
130 static real truncate
=1000.0;
132 { "-t", FALSE
, etREAL
, {&truncate
},
134 { "-sep", FALSE
, etBOOL
, {&bSep
},
135 "Use separate files for each interaction (may be MANY)" }
138 { efTRX
, "-f", NULL
, ffREAD
},
139 { efTPX
, NULL
, NULL
, ffREAD
},
141 #define NFILE asize(fnm)
144 static const char *title
[3] = {
145 "Distance between positively charged groups",
146 "Distance between negatively charged groups",
147 "Distance between oppositely charged groups"
149 static const char *fn
[3] = {
159 int status
,i
,j
,k
,m
,nnn
,teller
,ncg
,n1
,n2
,n3
,natoms
;
172 CopyRight(stderr
,argv
[0]);
174 parse_common_args(&argc
,argv
,PCA_CAN_TIME
| PCA_BE_NICE
,
175 NFILE
,fnm
,asize(pa
),pa
,asize(desc
),desc
,0,NULL
,&oenv
);
177 top
=read_top(ftp2fn(efTPX
,NFILE
,fnm
),&ePBC
);
178 cg
=mk_charge(&top
->atoms
,&(top
->cgs
),&ncg
);
181 for(i
=0; (i
<ncg
); i
++) {
183 snew(nWithin
[i
],ncg
);
186 natoms
=read_first_x(oenv
,&status
,ftp2fn(efTRX
,NFILE
,fnm
),&t
,&x
,box
);
191 srenew(time
,teller
+1);
194 set_pbc(&pbc
,ePBC
,box
);
196 for(i
=0; (i
<ncg
); i
++) {
197 for(j
=i
+1; (j
<ncg
); j
++) {
198 srenew(cgdist
[i
][j
],teller
+1);
199 cgdist
[i
][j
][teller
]=
200 calc_dist(&pbc
,x
,&(top
->cgs
),cg
[i
].cg
,cg
[j
].cg
);
201 if (cgdist
[i
][j
][teller
] < truncate
)
207 } while (read_next_x(oenv
,status
,&t
,natoms
,x
,box
));
208 fprintf(stderr
,"\n");
213 for(i
=0; (i
<ncg
); i
++)
214 for(j
=i
+1; (j
<ncg
); j
++) {
216 sprintf(buf
,"sb-%s:%s.xvg",cg
[i
].label
,cg
[j
].label
);
217 fp
=xvgropen(buf
,buf
,"Time (ps)","Distance (nm)",oenv
);
218 for(k
=0; (k
<teller
); k
++)
219 fprintf(fp
,"%10g %10g\n",time
[k
],cgdist
[i
][j
][k
]);
228 out
[m
]=xvgropen(fn
[m
],title
[m
],"Time (ps)","Distance (nm)",oenv
);
231 for(i
=0; (i
<ncg
); i
++) {
233 for(j
=i
+1; (j
<ncg
); j
++) {
236 sprintf(buf
,"%s:%s",cg
[i
].label
,cg
[j
].label
);
245 xvgr_legend(out
[nnn
],1,&buf
,oenv
);
247 if (output_env_get_xvg_format(oenv
) == exvgXMGR
) {
248 fprintf(out
[nnn
],"@ legend string %d \"%s\"\n",nset
[nnn
],buf
);
249 } else if (output_env_get_xvg_format(oenv
) == exvgXMGRACE
) {
250 fprintf(out
[nnn
],"@ s%d legend \"%s\"\n",nset
[nnn
],buf
);
258 for(k
=0; (k
<teller
); k
++) {
260 fprintf(out
[m
],"%10g",time
[k
]);
262 for(i
=0; (i
<ncg
); i
++) {
263 for(j
=i
+1; (j
<ncg
); j
++) {
266 fprintf(out
[nnn
-1]," %10g",cgdist
[i
][j
][k
]);
270 fprintf(out
[m
],"\n");
272 for(m
=0; (m
<3); m
++) {