Revised wording in pdb2gmx.c, hopefully clearer now.
[gromacs/rigid-bodies.git] / src / gmxlib / statutil.c
blobfe5a161fdd0b39dc85a80e89644814123306f59a
1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
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 3.2.0
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
33 * And Hey:
34 * GROningen Mixture of Alchemy and Childrens' Stories
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
41 #include <ctype.h>
42 #include "copyrite.h"
43 #include "sysstuff.h"
44 #include "macros.h"
45 #include "string2.h"
46 #include "smalloc.h"
47 #include "pbc.h"
48 #include "statutil.h"
49 #include "names.h"
50 #include "vec.h"
51 #include "futil.h"
52 #include "wman.h"
53 #include "tpxio.h"
54 #include "gmx_fatal.h"
55 #include "network.h"
56 #include "vec.h"
57 #include "mtop_util.h"
58 #include "gmxfio.h"
60 #ifdef GMX_THREADS
61 #include "thread_mpi.h"
62 #endif
64 /* used for npri */
65 #ifdef __sgi
66 #include <sys/schedctl.h>
67 #include <sys/sysmp.h>
68 #endif
70 /* The source code in this file should be thread-safe.
71 Please keep it that way. */
73 /******************************************************************
75 * T R A J E C T O R Y S T U F F
77 ******************************************************************/
79 /* inherently globally shared names: */
80 static const char *program_name=NULL;
81 static char *cmd_line=NULL;
83 #ifdef GMX_THREADS
84 /* For now, some things here are simply not re-entrant, so
85 we have to actively lock them. */
86 static tMPI_Thread_mutex_t init_mutex=TMPI_THREAD_MUTEX_INITIALIZER;
87 #endif
90 /****************************************************************
92 * E X P O R T E D F U N C T I O N S
94 ****************************************************************/
97 /* progam names, etc. */
99 const char *ShortProgram(void)
101 const char *pr,*ret;
102 #ifdef GMX_THREADS
103 tMPI_Thread_mutex_lock(&init_mutex);
104 #endif
105 pr=ret=program_name;
106 #ifdef GMX_THREADS
107 tMPI_Thread_mutex_unlock(&init_mutex);
108 #endif
109 if ((pr=strrchr(ret,DIR_SEPARATOR)) != NULL)
110 ret=pr+1;
111 /* Strip away the libtool prefix if it's still there. */
112 if(strlen(ret) > 3 && !strncmp(ret, "lt-", 3))
113 ret = ret + 3;
114 return ret;
117 const char *Program(void)
119 const char *ret;
120 #ifdef GMX_THREADS
121 tMPI_Thread_mutex_lock(&init_mutex);
122 #endif
123 ret=program_name;
124 #ifdef GMX_THREADS
125 tMPI_Thread_mutex_unlock(&init_mutex);
126 #endif
127 return ret;
130 const char *command_line(void)
132 const char *ret;
133 #ifdef GMX_THREADS
134 tMPI_Thread_mutex_lock(&init_mutex);
135 #endif
136 ret=cmd_line;
137 #ifdef GMX_THREADS
138 tMPI_Thread_mutex_unlock(&init_mutex);
139 #endif
140 return ret;
143 void set_program_name(const char *argvzero)
145 #ifdef GMX_THREADS
146 tMPI_Thread_mutex_lock(&init_mutex);
147 #endif
148 /* When you run a dynamically linked program before installing
149 * it, libtool uses wrapper scripts and prefixes the name with "lt-".
150 * Until libtool is fixed to set argv[0] right, rip away the prefix:
152 if (program_name == NULL)
154 if(strlen(argvzero)>3 && !strncmp(argvzero,"lt-",3))
155 program_name=strdup(argvzero+3);
156 else
157 program_name=strdup(argvzero);
159 if (program_name == NULL)
160 program_name="GROMACS";
161 #ifdef GMX_THREADS
162 tMPI_Thread_mutex_unlock(&init_mutex);
163 #endif
167 void set_command_line(int argc, char *argv[])
169 int i;
170 size_t cmdlength;
172 #ifdef GMX_THREADS
173 tMPI_Thread_mutex_lock(&init_mutex);
174 #endif
175 if (cmd_line==NULL)
177 cmdlength = strlen(argv[0]);
178 for (i=1; i<argc; i++)
180 cmdlength += strlen(argv[i]);
183 /* Fill the cmdline string */
184 snew(cmd_line,cmdlength+argc+1);
185 for (i=0; i<argc; i++)
187 strcat(cmd_line,argv[i]);
188 strcat(cmd_line," ");
191 #ifdef GMX_THREADS
192 tMPI_Thread_mutex_unlock(&init_mutex);
193 #endif
197 /* utility functions */
199 gmx_bool bRmod_fd(double a, double b, double c, gmx_bool bDouble)
201 int iq;
202 double tol;
204 tol = 2*(bDouble ? GMX_DOUBLE_EPS : GMX_FLOAT_EPS);
206 iq = (a - b + tol*a)/c;
208 if (fabs(a - b - c*iq) <= tol*fabs(a))
209 return TRUE;
210 else
211 return FALSE;
214 int check_times2(real t,real t0,real tp, real tpp, gmx_bool bDouble)
216 int r;
217 real margin;
219 #ifndef GMX_DOUBLE
220 /* since t is float, we can not use double precision for bRmod */
221 bDouble = FALSE;
222 #endif
224 if (t-tp>0 && tp-tpp>0)
225 margin = 0.1*min(t-tp,tp-tpp);
226 else
227 margin = 0;
229 r=-1;
230 if ((!bTimeSet(TBEGIN) || (t >= rTimeValue(TBEGIN))) &&
231 (!bTimeSet(TEND) || (t <= rTimeValue(TEND)))) {
232 if (bTimeSet(TDELTA) && !bRmod_fd(t,t0,rTimeValue(TDELTA),bDouble))
233 r = -1;
234 else
235 r = 0;
237 else if (bTimeSet(TEND) && (t >= rTimeValue(TEND)))
238 r = 1;
239 if (debug)
240 fprintf(debug,"t=%g, t0=%g, b=%g, e=%g, dt=%g: r=%d\n",
241 t,t0,rTimeValue(TBEGIN),rTimeValue(TEND),rTimeValue(TDELTA),r);
242 return r;
245 int check_times(real t)
247 return check_times2(t,t,t,t,FALSE);
253 static void set_default_time_unit(const char *time_list[], gmx_bool bCanTime)
255 int i,j;
256 const char *select;
258 if (bCanTime)
260 select = getenv("GMXTIMEUNIT");
261 if (select != NULL)
263 i = 1;
264 while(time_list[i] && strcmp(time_list[i], select) != 0)
266 i++;
270 if (!bCanTime || select == NULL || strcmp(time_list[i], select) != 0)
272 /* Set it to the default: ps */
273 i = 1;
274 while(time_list[i] && strcmp(time_list[i], "ps") != 0)
276 i++;
280 time_list[0] = time_list[i];
284 static void set_default_xvg_format(const char *xvg_list[])
286 int i,j;
287 const char *select,*tmp;
289 select = getenv("GMX_VIEW_XVG");
290 if (select == NULL)
292 /* The default is the first option */
293 xvg_list[0] = xvg_list[1];
295 else
297 i = 1;
298 while (xvg_list[i] && strcmp(xvg_list[i], select) != 0)
300 i++;
302 if (xvg_list[i] != NULL)
304 xvg_list[0] = xvg_list[i];
306 else
308 xvg_list[0] = xvg_list[exvgNONE];
314 /***** T O P O L O G Y S T U F F ******/
316 t_topology *read_top(const char *fn,int *ePBC)
318 int epbc,natoms;
319 t_topology *top;
321 snew(top,1);
322 epbc = read_tpx_top(fn,NULL,NULL,&natoms,NULL,NULL,NULL,top);
323 if (ePBC)
324 *ePBC = epbc;
326 return top;
329 /*************************************************************
331 * P A R S I N G S T U F F
333 *************************************************************/
335 static void usage(const char *type,const char *arg)
337 if (arg != NULL)
338 gmx_fatal(FARGS,"Expected %s argument for option %s\n",type,arg);
341 int iscan(int argc,char *argv[],int *i)
343 int var;
345 if (argc > (*i)+1) {
346 if (!sscanf(argv[++(*i)],"%d",&var))
347 usage("an integer",argv[(*i)-1]);
348 } else
349 usage("an integer",argv[*i]);
351 return var;
354 gmx_large_int_t istepscan(int argc,char *argv[],int *i)
356 gmx_large_int_t var;
358 if (argc > (*i)+1) {
359 if (!sscanf(argv[++(*i)],gmx_large_int_pfmt,&var))
360 usage("an integer",argv[(*i)-1]);
361 } else
362 usage("an integer",argv[*i]);
364 return var;
367 double dscan(int argc,char *argv[],int *i)
369 double var;
371 if (argc > (*i)+1) {
372 if (!sscanf(argv[++(*i)],"%lf",&var))
373 usage("a real",argv[(*i)-1]);
374 } else
375 usage("a real",argv[*i]);
377 return var;
380 char *sscan(int argc,char *argv[],int *i)
382 if (argc > (*i)+1)
384 if ( (argv[(*i)+1][0]=='-') && (argc > (*i)+2) &&
385 (argv[(*i)+2][0]!='-') )
387 fprintf(stderr,"Possible missing string argument for option %s\n\n",
388 argv[*i]);
391 else
392 usage("a string",argv[*i]);
394 return argv[++(*i)];
397 int nenum(const char *const enumc[])
399 int i;
401 i=1;
402 /* we *can* compare pointers directly here! */
403 while(enumc[i] && enumc[0]!=enumc[i])
404 i++;
406 return i;
409 static void pdesc(char *desc)
411 char *ptr,*nptr;
413 ptr=desc;
414 if ((int)strlen(ptr) < 70)
415 fprintf(stderr,"\t%s\n",ptr);
416 else {
417 for(nptr=ptr+70; (nptr != ptr) && (!isspace(*nptr)); nptr--)
419 if (nptr == ptr)
420 fprintf(stderr,"\t%s\n",ptr);
421 else {
422 *nptr='\0';
423 nptr++;
424 fprintf(stderr,"\t%s\n",ptr);
425 pdesc(nptr);
430 static FILE *man_file(const output_env_t oenv,const char *mantp)
432 FILE *fp;
433 char buf[256];
434 const char *pr = output_env_get_short_program_name(oenv);
436 if (strcmp(mantp,"ascii") != 0)
437 sprintf(buf,"%s.%s",pr,mantp);
438 else
439 sprintf(buf,"%s.txt",pr);
440 fp = gmx_fio_fopen(buf,"w");
442 return fp;
445 static int add_parg(int npargs,t_pargs *pa,t_pargs *pa_add)
447 memcpy(&(pa[npargs]),pa_add,sizeof(*pa_add));
449 return npargs+1;
452 static char *mk_desc(t_pargs *pa, const char *time_unit_str)
454 char *newdesc=NULL,*ndesc=NULL,*nptr=NULL;
455 const char*ptr=NULL;
456 int len,k;
458 /* First compute length for description */
459 len = strlen(pa->desc)+1;
460 if ((ptr = strstr(pa->desc,"HIDDEN")) != NULL)
461 len += 4;
462 if (pa->type == etENUM) {
463 len += 10;
464 for(k=1; (pa->u.c[k] != NULL); k++) {
465 len += strlen(pa->u.c[k])+12;
468 snew(newdesc,len);
470 /* add label for hidden options */
471 if (is_hidden(pa))
472 sprintf(newdesc,"[hidden] %s",ptr+6);
473 else
474 strcpy(newdesc,pa->desc);
476 /* change '%t' into time_unit */
477 #define TUNITLABEL "%t"
478 #define NTUNIT strlen(TUNITLABEL)
479 if (pa->type == etTIME)
480 while( (nptr=strstr(newdesc,TUNITLABEL)) != NULL ) {
481 nptr[0]='\0';
482 nptr+=NTUNIT;
483 len+=strlen(time_unit_str)-NTUNIT;
484 snew(ndesc,len);
485 strcpy(ndesc,newdesc);
486 strcat(ndesc,time_unit_str);
487 strcat(ndesc,nptr);
488 sfree(newdesc);
489 newdesc=ndesc;
490 ndesc=NULL;
492 #undef TUNITLABEL
493 #undef NTUNIT
495 /* Add extra comment for enumerateds */
496 if (pa->type == etENUM) {
497 strcat(newdesc,": ");
498 for(k=1; (pa->u.c[k] != NULL); k++) {
499 strcat(newdesc,"[TT]");
500 strcat(newdesc,pa->u.c[k]);
501 strcat(newdesc,"[tt]");
502 /* Print a comma everywhere but at the last one */
503 if (pa->u.c[k+1] != NULL) {
504 if (pa->u.c[k+2] == NULL)
505 strcat(newdesc," or ");
506 else
507 strcat(newdesc,", ");
511 return newdesc;
515 void parse_common_args(int *argc,char *argv[],unsigned long Flags,
516 int nfile,t_filenm fnm[],int npargs,t_pargs *pa,
517 int ndesc,const char **desc,
518 int nbugs,const char **bugs,
519 output_env_t *oenv)
521 gmx_bool bHelp=FALSE,bHidden=FALSE,bQuiet=FALSE,bVersion=FALSE;
522 const char *manstr[] = { NULL, "no", "html", "tex", "nroff", "ascii",
523 "completion", "py", "xml", "wiki", NULL };
524 /* This array should match the order of the enum in oenv.h */
525 const char *xvg_format[] = { NULL, "xmgrace", "xmgr", "none", NULL };
526 /* This array should match the order of the enum in oenv.h */
527 const char *time_units[] = { NULL, "fs", "ps", "ns", "us", "ms", "s",
528 NULL };
529 int nicelevel=0,mantp=0,npri=0,debug_level=0,verbose_level=0;
530 char *deffnm=NULL;
531 real tbegin=0,tend=0,tdelta=0;
532 gmx_bool bView=FALSE;
534 t_pargs *all_pa=NULL;
536 t_pargs npri_pa = { "-npri", FALSE, etINT, {&npri},
537 "HIDDEN Set non blocking priority (try 128)" };
538 t_pargs nice_pa = { "-nice", FALSE, etINT, {&nicelevel},
539 "Set the nicelevel" };
540 t_pargs deffnm_pa = { "-deffnm", FALSE, etSTR, {&deffnm},
541 "Set the default filename for all file options" };
542 t_pargs begin_pa = { "-b", FALSE, etTIME, {&tbegin},
543 "First frame (%t) to read from trajectory" };
544 t_pargs end_pa = { "-e", FALSE, etTIME, {&tend},
545 "Last frame (%t) to read from trajectory" };
546 t_pargs dt_pa = { "-dt", FALSE, etTIME, {&tdelta},
547 "Only use frame when t MOD dt = first time (%t)" };
548 t_pargs view_pa = { "-w", FALSE, etBOOL, {&bView},
549 "View output [TT].xvg[tt], [TT].xpm[tt], [TT].eps[tt] and [TT].pdb[tt] files" };
550 t_pargs xvg_pa = { "-xvg", FALSE, etENUM, {xvg_format},
551 "xvg plot formatting" };
552 t_pargs time_pa = { "-tu", FALSE, etENUM, {time_units},
553 "Time unit" };
554 /* Maximum number of extra arguments */
555 #define EXTRA_PA 16
557 t_pargs pca_pa[] = {
558 { "-h", FALSE, etBOOL, {&bHelp},
559 "Print help info and quit" },
560 { "-version", FALSE, etBOOL, {&bVersion},
561 "Print version info and quit" },
562 { "-verb", FALSE, etINT, {&verbose_level},
563 "HIDDENLevel of verbosity for this program" },
564 { "-hidden", FALSE, etBOOL, {&bHidden},
565 "HIDDENPrint hidden options" },
566 { "-quiet",FALSE, etBOOL, {&bQuiet},
567 "HIDDENDo not print help info" },
568 { "-man", FALSE, etENUM, {manstr},
569 "HIDDENWrite manual and quit" },
570 { "-debug",FALSE, etINT, {&debug_level},
571 "HIDDENWrite file with debug information, 1: short, 2: also x and f" },
573 #define NPCA_PA asize(pca_pa)
574 FILE *fp;
575 gmx_bool bPrint,bExit,bXvgr;
576 int i,j,k,npall,max_pa,cmdlength;
577 char *ptr,*newdesc;
578 const char *envstr;
580 #define FF(arg) ((Flags & arg)==arg)
582 snew(*oenv, 1);
584 cmdlength = strlen(argv[0]);
585 /* Check for double arguments */
586 for (i=1; (i<*argc); i++)
588 cmdlength += strlen(argv[i]);
589 if (argv[i] && (strlen(argv[i]) > 1) && (!isdigit(argv[i][1])))
591 for (j=i+1; (j<*argc); j++)
593 if ( (argv[i][0]=='-') && (argv[j][0]=='-') &&
594 (strcmp(argv[i],argv[j])==0) )
596 if (FF(PCA_NOEXIT_ON_ARGS))
597 fprintf(stderr,"Double command line argument %s\n",
598 argv[i]);
599 else
600 gmx_fatal(FARGS,"Double command line argument %s\n",
601 argv[i]);
606 debug_gmx();
607 set_program_name(argv[0]);
608 set_command_line(*argc, argv);
610 /* Handle the flags argument, which is a bit field
611 * The FF macro returns whether or not the bit is set
613 bPrint = !FF(PCA_SILENT);
615 /* Check ALL the flags ... */
616 max_pa = NPCA_PA + EXTRA_PA + npargs+1;
617 snew(all_pa,max_pa);
619 for(i=npall=0; (i<NPCA_PA); i++)
620 npall = add_parg(npall,all_pa,&(pca_pa[i]));
622 #ifdef __sgi
623 envstr = getenv("GMXNPRIALL");
624 if (envstr)
625 npri=strtol(envstr,NULL,10);
626 if (FF(PCA_BE_NICE)) {
627 envstr = getenv("GMXNPRI");
628 if (envstr)
629 npri=strtol(envstr,NULL,10);
631 npall = add_parg(npall,all_pa,&npri_pa);
632 #endif
634 if (FF(PCA_BE_NICE))
635 nicelevel=19;
636 npall = add_parg(npall,all_pa,&nice_pa);
638 if (FF(PCA_CAN_SET_DEFFNM))
639 npall = add_parg(npall,all_pa,&deffnm_pa);
640 if (FF(PCA_CAN_BEGIN))
641 npall = add_parg(npall,all_pa,&begin_pa);
642 if (FF(PCA_CAN_END))
643 npall = add_parg(npall,all_pa,&end_pa);
644 if (FF(PCA_CAN_DT))
646 npall = add_parg(npall,all_pa,&dt_pa);
648 if (FF(PCA_TIME_UNIT)) {
649 npall = add_parg(npall,all_pa,&time_pa);
651 if (FF(PCA_CAN_VIEW))
652 npall = add_parg(npall,all_pa,&view_pa);
654 bXvgr = FALSE;
655 for(i=0; (i<nfile); i++)
657 bXvgr = bXvgr || (fnm[i].ftp == efXVG);
659 if (bXvgr)
661 npall = add_parg(npall,all_pa,&xvg_pa);
664 /* Now append the program specific arguments */
665 for(i=0; (i<npargs); i++)
666 npall = add_parg(npall,all_pa,&(pa[i]));
668 /* set etENUM options to default */
669 for(i=0; (i<npall); i++)
671 if (all_pa[i].type==etENUM)
673 all_pa[i].u.c[0]=all_pa[i].u.c[1];
676 set_default_time_unit(time_units,FF(PCA_TIME_UNIT));
677 set_default_xvg_format(xvg_format);
679 /* Now parse all the command-line options */
680 get_pargs(argc,argv,npall,all_pa,FF(PCA_KEEP_ARGS));
682 /* set program name, command line, and default values for output options */
683 output_env_init(*oenv, *argc, argv, (time_unit_t)nenum(time_units), bView,
684 (xvg_format_t)nenum(xvg_format), verbose_level, debug_level);
686 if (bVersion) {
687 printf("Program: %s\n",output_env_get_program_name(*oenv));
688 gmx_print_version_info(stdout);
689 exit(0);
692 if (FF(PCA_CAN_SET_DEFFNM) && (deffnm!=NULL))
693 set_default_file_name(deffnm);
695 /* Parse the file args */
696 parse_file_args(argc,argv,nfile,fnm,FF(PCA_KEEP_ARGS),!FF(PCA_NOT_READ_NODE));
698 /* Open the debug file */
699 if (debug_level > 0) {
700 char buf[256];
702 if (gmx_mpi_initialized())
703 sprintf(buf,"%s%d.debug",output_env_get_short_program_name(*oenv),
704 gmx_node_rank());
705 else
706 sprintf(buf,"%s.debug",output_env_get_short_program_name(*oenv));
708 init_debug(debug_level,buf);
709 fprintf(stderr,"Opening debug file %s (src code file %s, line %d)\n",
710 buf,__FILE__,__LINE__);
713 /* Now copy the results back... */
714 for(i=0,k=npall-npargs; (i<npargs); i++,k++)
715 memcpy(&(pa[i]),&(all_pa[k]),(size_t)sizeof(pa[i]));
718 for(i=0; (i<npall); i++)
719 all_pa[i].desc = mk_desc(&(all_pa[i]), output_env_get_time_unit(*oenv));
721 bExit = bHelp || (strcmp(manstr[0],"no") != 0);
723 #if (defined __sgi && USE_SGI_FPE)
724 doexceptions();
725 #endif
727 /* Set the nice level */
728 #ifdef __sgi
729 if (npri != 0 && !bExit) {
730 schedctl(MPTS_RTPRI,0,npri);
732 #endif
734 #ifdef HAVE_UNISTD_H
736 #ifndef GMX_NO_NICE
737 /* The some system, e.g. the catamount kernel on cray xt3 do not have nice(2). */
738 if (nicelevel != 0 && !bExit)
740 #ifdef GMX_THREADS
741 static gmx_bool nice_set=FALSE; /* only set it once */
742 tMPI_Thread_mutex_lock(&init_mutex);
743 if (!nice_set)
745 #endif
746 i=nice(nicelevel); /* assign ret value to avoid warnings */
747 #ifdef GMX_THREADS
748 nice_set=TRUE;
750 tMPI_Thread_mutex_unlock(&init_mutex);
751 #endif
753 #endif
754 #endif
756 /* Update oenv for parsed command line options settings. */
757 (*oenv)->xvg_format = (xvg_format_t)nenum(xvg_format);
758 (*oenv)->time_unit = (time_unit_t)nenum(time_units);
760 if (!(FF(PCA_QUIET) || bQuiet )) {
761 if (bHelp)
762 write_man(stderr,"help",output_env_get_program_name(*oenv),
763 ndesc,desc,nfile, fnm,npall,all_pa, nbugs,bugs,bHidden);
764 else if (bPrint) {
765 pr_fns(stderr,nfile,fnm);
766 print_pargs(stderr,npall,all_pa,FALSE);
770 if (strcmp(manstr[0],"no") != 0) {
771 if(!strcmp(manstr[0],"completion")) {
772 /* one file each for csh, bash and zsh if we do completions */
773 fp=man_file(*oenv,"completion-zsh");
775 write_man(fp,"completion-zsh",output_env_get_program_name(*oenv),
776 ndesc,desc,nfile, fnm, npall,all_pa,nbugs,bugs,bHidden);
777 gmx_fio_fclose(fp);
778 fp=man_file(*oenv,"completion-bash");
779 write_man(fp,"completion-bash",output_env_get_program_name(*oenv),
780 ndesc,desc,nfile, fnm, npall,all_pa,nbugs,bugs,bHidden);
781 gmx_fio_fclose(fp);
782 fp=man_file(*oenv,"completion-csh");
783 write_man(fp,"completion-csh",output_env_get_program_name(*oenv),
784 ndesc,desc,nfile, fnm, npall,all_pa,nbugs,bugs,bHidden);
785 gmx_fio_fclose(fp);
786 } else {
787 fp=man_file(*oenv,manstr[0]);
788 write_man(fp,manstr[0],output_env_get_program_name(*oenv),
789 ndesc,desc,nfile,fnm, npall, all_pa,nbugs,bugs,bHidden);
790 gmx_fio_fclose(fp);
794 /* convert time options, must be done after printing! */
796 for(i=0; i<npall; i++) {
797 if ((all_pa[i].type == etTIME) && (*all_pa[i].u.r >= 0)) {
798 *all_pa[i].u.r *= output_env_get_time_invfactor(*oenv);
802 /* Extract Time info from arguments */
803 if (FF(PCA_CAN_BEGIN) && opt2parg_bSet("-b",npall,all_pa))
804 setTimeValue(TBEGIN,opt2parg_real("-b",npall,all_pa));
806 if (FF(PCA_CAN_END) && opt2parg_bSet("-e",npall,all_pa))
807 setTimeValue(TEND,opt2parg_real("-e",npall,all_pa));
809 if (FF(PCA_CAN_DT) && opt2parg_bSet("-dt",npall,all_pa))
810 setTimeValue(TDELTA,opt2parg_real("-dt",npall,all_pa));
812 /* clear memory */
813 for (i = 0; i < npall; ++i)
814 sfree((void *)all_pa[i].desc);
815 sfree(all_pa);
817 if (!FF(PCA_NOEXIT_ON_ARGS)) {
818 if (*argc > 1) {
819 gmx_cmd(argv[1]);
822 if (bExit) {
823 if (gmx_parallel_env_initialized())
824 /*gmx_abort(gmx_node_rank(),gmx_node_num(),0);*/
825 gmx_finalize();
826 exit(0);
828 #undef FF