Update copyright statements and change license to LGPL
[alexxy/gromacs.git] / src / kernel / gmxdump.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2004, The GROMACS development team,
6  * check out http://www.gromacs.org for more information.
7  * Copyright (c) 2012, by the GROMACS development team, led by
8  * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9  * others, as listed in the AUTHORS file in the top-level source
10  * directory and at http://www.gromacs.org.
11  *
12  * GROMACS is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public License
14  * as published by the Free Software Foundation; either version 2.1
15  * of the License, or (at your option) any later version.
16  *
17  * GROMACS is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with GROMACS; if not, see
24  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
26  *
27  * If you want to redistribute modifications to GROMACS, please
28  * consider that scientific software is very special. Version
29  * control is crucial - bugs must be traceable. We will be happy to
30  * consider code for inclusion in the official distribution, but
31  * derived work must not be called official GROMACS. Details are found
32  * in the README & COPYING files - if they are missing, get the
33  * official version at http://www.gromacs.org.
34  *
35  * To help us fund GROMACS development, we humbly ask that you cite
36  * the research papers on the package. Check out http://www.gromacs.org.
37  */
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #include <stdio.h>
43 #include <string.h>
44 #include <math.h>
45 #include <assert.h>
46 #include "main.h"
47 #include "macros.h"
48 #include "futil.h"
49 #include "statutil.h"
50 #include "copyrite.h"
51 #include "sysstuff.h"
52 #include "txtdump.h"
53 #include "gmx_fatal.h"
54 #include "xtcio.h"
55 #include "enxio.h"
56 #include "smalloc.h"
57 #include "names.h"
58 #include "gmxfio.h"
59 #include "tpxio.h"
60 #include "trnio.h"
61 #include "txtdump.h"
62 #include "gmxcpp.h"
63 #include "checkpoint.h"
64 #include "mtop_util.h"
65 #include "sparsematrix.h"
66 #include "mtxio.h"
67
68
69 static void list_tpx(const char *fn, gmx_bool bShowNumbers,const char *mdpfn,
70                      gmx_bool bSysTop)
71 {
72   FILE *gp;
73   int         fp,indent,i,j,**gcount,atot;
74   t_state     state;
75   rvec        *f=NULL;
76   t_inputrec  ir;
77   t_tpxheader tpx;
78   gmx_mtop_t  mtop;
79   gmx_groups_t *groups;
80   t_topology  top;
81
82   read_tpxheader(fn,&tpx,TRUE,NULL,NULL);
83
84   read_tpx_state(fn,
85                  tpx.bIr  ? &ir : NULL,
86                  &state,tpx.bF ? f : NULL,
87                  tpx.bTop ? &mtop: NULL);
88   
89   if (mdpfn && tpx.bIr) {
90     gp = gmx_fio_fopen(mdpfn,"w");
91     pr_inputrec(gp,0,NULL,&(ir),TRUE);
92     gmx_fio_fclose(gp);
93   }
94
95   if (!mdpfn) {  
96     if (bSysTop)
97       top = gmx_mtop_t_to_t_topology(&mtop);
98
99     if (available(stdout,&tpx,0,fn)) {
100       indent=0;
101       indent=pr_title(stdout,indent,fn);
102       pr_inputrec(stdout,0,"inputrec",tpx.bIr ? &(ir) : NULL,FALSE);
103       
104       indent = 0;
105       pr_header(stdout,indent,"header",&(tpx));
106       
107       if (!bSysTop)
108         pr_mtop(stdout,indent,"topology",&(mtop),bShowNumbers);
109       else
110         pr_top(stdout,indent,"topology",&(top),bShowNumbers);
111
112       pr_rvecs(stdout,indent,"box",tpx.bBox ? state.box : NULL,DIM);
113       pr_rvecs(stdout,indent,"box_rel",tpx.bBox ? state.box_rel : NULL,DIM);
114       pr_rvecs(stdout,indent,"boxv",tpx.bBox ? state.boxv : NULL,DIM);
115       pr_rvecs(stdout,indent,"pres_prev",tpx.bBox ? state.pres_prev : NULL,DIM);
116       pr_rvecs(stdout,indent,"svir_prev",tpx.bBox ? state.svir_prev : NULL,DIM);
117       pr_rvecs(stdout,indent,"fvir_prev",tpx.bBox ? state.fvir_prev : NULL,DIM);
118       /* leave nosehoover_xi in for now to match the tpr version */
119       pr_doubles(stdout,indent,"nosehoover_xi",state.nosehoover_xi,state.ngtc);
120       /*pr_doubles(stdout,indent,"nosehoover_vxi",state.nosehoover_vxi,state.ngtc);*/
121       /*pr_doubles(stdout,indent,"therm_integral",state.therm_integral,state.ngtc);*/
122       pr_rvecs(stdout,indent,"x",tpx.bX ? state.x : NULL,state.natoms);
123       pr_rvecs(stdout,indent,"v",tpx.bV ? state.v : NULL,state.natoms);
124       if (tpx.bF) {
125         pr_rvecs(stdout,indent,"f",f,state.natoms);
126       }
127     }
128     
129     groups = &mtop.groups;
130
131     snew(gcount,egcNR);
132     for(i=0; (i<egcNR); i++) 
133       snew(gcount[i],groups->grps[i].nr);
134     
135     for(i=0; (i<mtop.natoms); i++) {
136       for(j=0; (j<egcNR); j++) 
137         gcount[j][ggrpnr(groups,j,i)]++;
138     }
139     printf("Group statistics\n");
140     for(i=0; (i<egcNR); i++) {
141       atot=0;
142       printf("%-12s: ",gtypes[i]);
143       for(j=0; (j<groups->grps[i].nr); j++) {
144         printf("  %5d",gcount[i][j]);
145         atot+=gcount[i][j];
146       }
147       printf("  (total %d atoms)\n",atot);
148       sfree(gcount[i]);
149     }
150     sfree(gcount);
151   }
152   done_state(&state);
153   sfree(f);
154 }
155
156 static void list_top(const char *fn)
157 {
158   int status,done;
159 #define BUFLEN 256
160   char buf[BUFLEN];
161   gmx_cpp_t handle;
162   char *cppopts[] = { NULL };
163
164   status = cpp_open_file(fn,&handle,cppopts);
165   if (status != 0) 
166     gmx_fatal(FARGS,cpp_error(&handle,status));
167   do {
168     status = cpp_read_line(&handle,BUFLEN,buf);
169     done = (status == eCPP_EOF);
170     if (!done) {
171       if (status != eCPP_OK)
172         gmx_fatal(FARGS,cpp_error(&handle,status));
173       else 
174         printf("%s\n",buf);
175     }
176   } while (!done);
177   status = cpp_close_file(&handle);
178   if (status != eCPP_OK) 
179     gmx_fatal(FARGS,cpp_error(&handle,status));
180 }
181
182 static void list_trn(const char *fn)
183 {
184   t_fileio    *fpread, *fpwrite;
185   int         nframe,indent;
186   char        buf[256];
187   rvec        *x,*v,*f;
188   matrix      box;
189   t_trnheader trn;
190   gmx_bool        bOK;
191
192   fpread  = open_trn(fn,"r"); 
193   fpwrite = open_tpx(NULL,"w");
194   gmx_fio_setdebug(fpwrite,TRUE);
195   
196   nframe = 0;
197   while (fread_trnheader(fpread,&trn,&bOK)) {
198     snew(x,trn.natoms);
199     snew(v,trn.natoms);
200     snew(f,trn.natoms);
201     if (fread_htrn(fpread,&trn,
202                    trn.box_size ? box : NULL,
203                    trn.x_size   ? x : NULL,
204                    trn.v_size   ? v : NULL,
205                    trn.f_size   ? f : NULL)) {
206       sprintf(buf,"%s frame %d",fn,nframe);
207       indent=0;
208       indent=pr_title(stdout,indent,buf);
209       pr_indent(stdout,indent);
210       fprintf(stdout,"natoms=%10d  step=%10d  time=%12.7e  lambda=%10g\n",
211               trn.natoms,trn.step,trn.t,trn.lambda);
212       if (trn.box_size)
213         pr_rvecs(stdout,indent,"box",box,DIM);
214       if (trn.x_size)
215         pr_rvecs(stdout,indent,"x",x,trn.natoms);
216       if (trn.v_size)
217         pr_rvecs(stdout,indent,"v",v,trn.natoms);
218       if (trn.f_size)
219         pr_rvecs(stdout,indent,"f",f,trn.natoms);
220     } 
221     else
222       fprintf(stderr,"\nWARNING: Incomplete frame: nr %d, t=%g\n",
223               nframe,trn.t);
224     
225     sfree(x);
226     sfree(v);
227     sfree(f);
228     nframe++;
229   }
230   if (!bOK)
231     fprintf(stderr,"\nWARNING: Incomplete frame header: nr %d, t=%g\n",
232             nframe,trn.t);
233   close_tpx(fpwrite);
234   close_trn(fpread);
235 }
236
237 void list_xtc(const char *fn, gmx_bool bXVG)
238 {
239   t_fileio *xd;
240   int    indent;
241   char   buf[256];
242   rvec   *x;
243   matrix box;
244   int    nframe,natoms,step;
245   real   prec,time;
246   gmx_bool   bOK;
247   
248   xd = open_xtc(fn,"r");
249   read_first_xtc(xd,&natoms,&step,&time,box,&x,&prec,&bOK);
250                 
251   nframe=0;
252   do {
253     if (bXVG) {
254       int i,d;
255       
256       fprintf(stdout,"%g",time);
257       for(i=0; i<natoms; i++)
258         for(d=0; d<DIM; d++)
259           fprintf(stdout," %g",x[i][d]);
260       fprintf(stdout,"\n");
261     } else {
262       sprintf(buf,"%s frame %d",fn,nframe);
263       indent=0;
264       indent=pr_title(stdout,indent,buf);
265       pr_indent(stdout,indent);
266       fprintf(stdout,"natoms=%10d  step=%10d  time=%12.7e  prec=%10g\n",
267             natoms,step,time,prec);
268       pr_rvecs(stdout,indent,"box",box,DIM);
269       pr_rvecs(stdout,indent,"x",x,natoms);
270     }
271     nframe++;
272   } while (read_next_xtc(xd,natoms,&step,&time,box,x,&prec,&bOK));
273   if (!bOK)
274     fprintf(stderr,"\nWARNING: Incomplete frame at time %g\n",time);
275   close_xtc(xd);
276 }
277
278 void list_trx(const char *fn,gmx_bool bXVG)
279 {
280   int ftp;
281   
282   ftp = fn2ftp(fn);
283   if (ftp == efXTC)
284     list_xtc(fn,bXVG);
285   else if ((ftp == efTRR) || (ftp == efTRJ))
286     list_trn(fn);
287   else
288     fprintf(stderr,"File %s is of an unsupported type. Try using the command\n 'less %s'\n",
289             fn,fn);
290 }
291
292 void list_ene(const char *fn)
293 {
294     int        ndr;
295     ener_file_t in;
296     gmx_bool       bCont;
297     gmx_enxnm_t *enm=NULL;
298     t_enxframe *fr;
299     int        i,j,nre,b;
300     real       rav,minthird;
301     char       buf[22];
302
303     printf("gmxdump: %s\n",fn);
304     in = open_enx(fn,"r");
305     do_enxnms(in,&nre,&enm);
306     assert(enm);
307
308     printf("energy components:\n");
309     for(i=0; (i<nre); i++) 
310         printf("%5d  %-24s (%s)\n",i,enm[i].name,enm[i].unit);
311
312     minthird=-1.0/3.0;
313     snew(fr,1);
314     do {
315         bCont=do_enx(in,fr);
316
317         if (bCont) 
318         {
319             printf("\n%24s  %12.5e  %12s  %12s\n","time:",
320                    fr->t,"step:",gmx_step_str(fr->step,buf));
321             printf("%24s  %12s  %12s  %12s\n",
322                    "","","nsteps:",gmx_step_str(fr->nsteps,buf));
323             printf("%24s  %12.5e  %12s  %12s\n",
324                    "delta_t:",fr->dt,"sum steps:",gmx_step_str(fr->nsum,buf));
325             if (fr->nre == nre) {
326                 printf("%24s  %12s  %12s  %12s\n",
327                        "Component","Energy","Av. Energy","Sum Energy");
328                 if (fr->nsum > 0) {
329                     for(i=0; (i<nre); i++) 
330                         printf("%24s  %12.5e  %12.5e  %12.5e\n",
331                                enm[i].name,fr->ener[i].e,fr->ener[i].eav,
332                                fr->ener[i].esum);
333                 } else {
334                     for(i=0; (i<nre); i++) 
335                         printf("%24s  %12.5e\n",
336                                enm[i].name,fr->ener[i].e);
337                 }
338             }
339             for(b=0; b<fr->nblock; b++)
340             {
341                 const char *typestr="";
342
343                 t_enxblock *eb=&(fr->block[b]);
344                 printf("Block data %2d (%3d subblocks, id=%d)\n",
345                        b, eb->nsub, eb->id);
346
347                 if (eb->id < enxNR)
348                     typestr=enx_block_id_name[eb->id];
349                 printf("  id='%s'\n", typestr);
350                 for(i=0;i<eb->nsub;i++)
351                 {
352                     t_enxsubblock *sb=&(eb->sub[i]);
353                     printf("  Sub block %3d (%5d elems, type=%s) values:\n", 
354                            i, sb->nr, xdr_datatype_names[sb->type]);
355
356                     switch(sb->type)
357                     {
358                         case xdr_datatype_float:
359                             for(j=0;j<sb->nr;j++)
360                                 printf("%14d   %8.4f\n",j, sb->fval[j]);
361                             break;
362                         case xdr_datatype_double:
363                             for(j=0;j<sb->nr;j++)
364                                 printf("%14d   %10.6f\n",j, sb->dval[j]);
365                             break;
366                         case xdr_datatype_int:
367                             for(j=0;j<sb->nr;j++)
368                                 printf("%14d %10d\n",j, sb->ival[j]);
369                             break;
370                         case xdr_datatype_large_int:
371                             for(j=0;j<sb->nr;j++)
372                                 printf("%14d %s\n",
373                                        j, gmx_step_str(sb->lval[j],buf));
374                             break;
375                         case xdr_datatype_char:
376                             for(j=0;j<sb->nr;j++)
377                                 printf("%14d %1c\n",j, sb->cval[j]);
378                             break;
379                         case xdr_datatype_string:
380                             for(j=0;j<sb->nr;j++)
381                                 printf("%14d %80s\n",j, sb->sval[j]);
382                             break;
383                         default:
384                             gmx_incons("Unknown subblock type");
385                     }
386                 }
387             }
388         }
389     } while (bCont);
390
391     close_enx(in);
392
393     free_enxframe(fr);
394     sfree(fr);
395     sfree(enm);
396 }
397
398 static void list_mtx(const char *fn)
399 {
400   int  nrow,ncol,i,j,k;
401   real *full=NULL,value;
402   gmx_sparsematrix_t * sparse=NULL;
403
404   gmx_mtxio_read(fn,&nrow,&ncol,&full,&sparse);
405
406   if (full == NULL) {
407     snew(full,nrow*ncol);
408     for(i=0;i<nrow*ncol;i++) {
409       full[i] = 0;
410     }
411     
412     for(i=0;i<sparse->nrow;i++) {
413         for(j=0;j<sparse->ndata[i];j++) {
414           k     = sparse->data[i][j].col;
415           value = sparse->data[i][j].value;
416           full[i*ncol+k] = value;
417           full[k*ncol+i] = value;
418         }
419     }
420     gmx_sparsematrix_destroy(sparse);
421   }
422
423   printf("%d %d\n",nrow,ncol);
424   for(i=0; i<nrow; i++) {
425     for(j=0; j<ncol; j++) {
426       printf(" %g",full[i*ncol+j]);
427     }
428     printf("\n");
429   }
430
431   sfree(full);
432 }
433
434 int cmain(int argc,char *argv[])
435 {
436   const char *desc[] = {
437     "[TT]gmxdump[tt] reads a run input file ([TT].tpa[tt]/[TT].tpr[tt]/[TT].tpb[tt]),",
438     "a trajectory ([TT].trj[tt]/[TT].trr[tt]/[TT].xtc[tt]), an energy",
439     "file ([TT].ene[tt]/[TT].edr[tt]), or a checkpoint file ([TT].cpt[tt])",
440     "and prints that to standard output in a readable format.",
441     "This program is essential for checking your run input file in case of",
442     "problems.[PAR]",
443     "The program can also preprocess a topology to help finding problems.",
444     "Note that currently setting [TT]GMXLIB[tt] is the only way to customize",
445     "directories used for searching include files.",
446   };
447   t_filenm fnm[] = {
448     { efTPX, "-s", NULL, ffOPTRD },
449     { efTRX, "-f", NULL, ffOPTRD },
450     { efEDR, "-e", NULL, ffOPTRD },
451     { efCPT, NULL, NULL, ffOPTRD },
452     { efTOP, "-p", NULL, ffOPTRD },
453     { efMTX, "-mtx", "hessian", ffOPTRD }, 
454     { efMDP, "-om", NULL, ffOPTWR }
455   };
456 #define NFILE asize(fnm)
457
458   output_env_t oenv;
459   /* Command line options */
460   static gmx_bool bXVG=FALSE;
461   static gmx_bool bShowNumbers=TRUE;
462   static gmx_bool bSysTop=FALSE;
463   t_pargs pa[] = {
464     { "-xvg", FALSE, etBOOL, {&bXVG}, "HIDDENXVG layout for xtc" },
465     { "-nr",FALSE, etBOOL, {&bShowNumbers},"Show index numbers in output (leaving them out makes comparison easier, but creates a useless topology)" },
466     { "-sys", FALSE, etBOOL, {&bSysTop}, "List the atoms and bonded interactions for the whole system instead of for each molecule type" }
467   };
468   
469   CopyRight(stderr,argv[0]);
470   parse_common_args(&argc,argv,0,NFILE,fnm,asize(pa),pa,
471                     asize(desc),desc,0,NULL,&oenv);
472
473
474   if (ftp2bSet(efTPX,NFILE,fnm))
475     list_tpx(ftp2fn(efTPX,NFILE,fnm),bShowNumbers,
476              ftp2fn_null(efMDP,NFILE,fnm),bSysTop);
477   else if (ftp2bSet(efTRX,NFILE,fnm)) 
478     list_trx(ftp2fn(efTRX,NFILE,fnm),bXVG);
479   else if (ftp2bSet(efEDR,NFILE,fnm))
480     list_ene(ftp2fn(efEDR,NFILE,fnm));
481   else if (ftp2bSet(efCPT,NFILE,fnm))
482     list_checkpoint(ftp2fn(efCPT,NFILE,fnm),stdout);
483   else if (ftp2bSet(efTOP,NFILE,fnm))
484     list_top(ftp2fn(efTOP,NFILE,fnm));
485   else if (ftp2bSet(efMTX,NFILE,fnm))
486     list_mtx(ftp2fn(efMTX,NFILE,fnm));
487     
488   thanx(stderr);
489
490   return 0;
491 }