Exemplo n.º 1
0
int gmx_eneconv(int argc, char *argv[])
{
    const char       *desc[] = {
        "With [IT]multiple files[it] specified for the [TT]-f[tt] option:[PAR]",
        "Concatenates several energy files in sorted order.",
        "In the case of double time frames, the one",
        "in the later file is used. By specifying [TT]-settime[tt] you will be",
        "asked for the start time of each file. The input files are taken",
        "from the command line,",
        "such that the command [TT]gmx eneconv -f *.edr -o fixed.edr[tt] should do",
        "the trick. [PAR]",
        "With [IT]one file[it] specified for [TT]-f[tt]:[PAR]",
        "Reads one energy file and writes another, applying the [TT]-dt[tt],",
        "[TT]-offset[tt], [TT]-t0[tt] and [TT]-settime[tt] options and",
        "converting to a different format if necessary (indicated by file",
        "extentions).[PAR]",
        "[TT]-settime[tt] is applied first, then [TT]-dt[tt]/[TT]-offset[tt]",
        "followed by [TT]-b[tt] and [TT]-e[tt] to select which frames to write."
    };
    const char       *bugs[] = {
        "When combining trajectories the sigma and E^2 (necessary for statistics) are not updated correctly. Only the actual energy is correct. One thus has to compute statistics in another way."
    };
    ener_file_t       in  = NULL, out = NULL;
    gmx_enxnm_t      *enm = NULL;
#if 0
    ener_file_t       in, out = NULL;
    gmx_enxnm_t      *enm = NULL;
#endif
    t_enxframe       *fr, *fro;
    gmx_int64_t       ee_sum_step = 0, ee_sum_nsteps, ee_sum_nsum;
    t_energy         *ee_sum;
    gmx_int64_t       lastfilestep, laststep, startstep_file = 0;
    int               noutfr;
    int               nre, nremax, this_nre, nfile, f, i, kkk, nset, *set = NULL;
    double            last_t;
    char            **fnms;
    real             *readtime, *settime, timestep, tadjust;
    char              buf[22], buf2[22];
    int              *cont_type;
    gmx_bool          bNewFile, bFirst, bNewOutput;
    gmx_output_env_t *oenv;
    gmx_bool          warned_about_dh = FALSE;
    t_enxblock       *blocks          = NULL;
    int               nblocks         = 0;
    int               nblocks_alloc   = 0;

    t_filenm          fnm[] = {
        { efEDR, "-f", NULL,    ffRDMULT },
        { efEDR, "-o", "fixed", ffWRITE  },
    };

#define NFILE asize(fnm)
    gmx_bool         bWrite;
    static real      delta_t   = 0.0, toffset = 0, scalefac = 1;
    static gmx_bool  bSetTime  = FALSE;
    static gmx_bool  bSort     = TRUE, bError = TRUE;
    static real      begin     = -1;
    static real      end       = -1;
    gmx_bool         remove_dh = FALSE;

    t_pargs          pa[] = {
        { "-b",        FALSE, etREAL, {&begin},
          "First time to use"},
        { "-e",        FALSE, etREAL, {&end},
          "Last time to use"},
        { "-dt",       FALSE, etREAL, {&delta_t},
          "Only write out frame when t MOD dt = offset" },
        { "-offset",   FALSE, etREAL, {&toffset},
          "Time offset for [TT]-dt[tt] option" },
        { "-settime",  FALSE, etBOOL, {&bSetTime},
          "Change starting time interactively" },
        { "-sort",     FALSE, etBOOL, {&bSort},
          "Sort energy files (not frames)"},
        { "-rmdh",     FALSE, etBOOL, {&remove_dh},
          "Remove free energy block data" },
        { "-scalefac", FALSE, etREAL, {&scalefac},
          "Multiply energy component by this factor" },
        { "-error",    FALSE, etBOOL, {&bError},
          "Stop on errors in the file" }
    };

    if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa),
                           pa, asize(desc), desc, asize(bugs), bugs, &oenv))
    {
        return 0;
    }
    tadjust  = 0;
    nremax   = 0;
    nset     = 0;
    timestep = 0.0;
    snew(fnms, argc);
    lastfilestep = 0;
    laststep     = 0;

    nfile = opt2fns(&fnms, "-f", NFILE, fnm);

    if (!nfile)
    {
        gmx_fatal(FARGS, "No input files!");
    }

    snew(settime, nfile+1);
    snew(readtime, nfile+1);
    snew(cont_type, nfile+1);

    nre = scan_ene_files(fnms, nfile, readtime, &timestep, &nremax);
    edit_files(fnms, nfile, readtime, settime, cont_type, bSetTime, bSort);

    ee_sum_nsteps = 0;
    ee_sum_nsum   = 0;
    snew(ee_sum, nremax);

    snew(fr, 1);
    snew(fro, 1);
    fro->t   = -1e20;
    fro->nre = nre;
    snew(fro->ener, nremax);

    noutfr = 0;
    bFirst = TRUE;

    last_t = fro->t;
    for (f = 0; f < nfile; f++)
    {
        bNewFile   = TRUE;
        bNewOutput = TRUE;
        in         = open_enx(fnms[f], "r");
        enm        = NULL;
        do_enxnms(in, &this_nre, &enm);
        if (f == 0)
        {
            if (scalefac != 1)
            {
                set = select_it(nre, enm, &nset);
            }

            /* write names to the output file */
            out = open_enx(opt2fn("-o", NFILE, fnm), "w");
            do_enxnms(out, &nre, &enm);
        }

        /* start reading from the next file */
        while ((fro->t <= (settime[f+1] + GMX_REAL_EPS)) &&
               do_enx(in, fr))
        {
            if (bNewFile)
            {
                startstep_file = fr->step;
                tadjust        = settime[f] - fr->t;
                if (cont_type[f+1] == TIME_LAST)
                {
                    settime[f+1]   = readtime[f+1]-readtime[f]+settime[f];
                    cont_type[f+1] = TIME_EXPLICIT;
                }
                bNewFile = FALSE;
            }

            if (tadjust + fr->t <= last_t)
            {
                /* Skip this frame, since we already have it / past it */
                if (debug)
                {
                    fprintf(debug, "fr->step %s, fr->t %.4f\n",
                            gmx_step_str(fr->step, buf), fr->t);
                    fprintf(debug, "tadjust %12.6e + fr->t %12.6e <= t %12.6e\n",
                            tadjust, fr->t, last_t);
                }
                continue;
            }

            fro->step = lastfilestep + fr->step - startstep_file;
            fro->t    = tadjust  + fr->t;

            bWrite = ((begin < 0 || (fro->t >= begin-GMX_REAL_EPS)) &&
                      (end  < 0  || (fro->t <= end  +GMX_REAL_EPS)) &&
                      (fro->t <= settime[f+1]+0.5*timestep));

            if (debug)
            {
                fprintf(debug,
                        "fr->step %s, fr->t %.4f, fro->step %s fro->t %.4f, w %d\n",
                        gmx_step_str(fr->step, buf), fr->t,
                        gmx_step_str(fro->step, buf2), fro->t, bWrite);
            }

            if (bError)
            {
                if ((end > 0) && (fro->t > end+GMX_REAL_EPS))
                {
                    f = nfile;
                    break;
                }
            }

            if (fro->t >= begin-GMX_REAL_EPS)
            {
                if (bFirst)
                {
                    bFirst    = FALSE;
                }
                if (bWrite)
                {
                    update_ee_sum(nre, &ee_sum_step, &ee_sum_nsteps, &ee_sum_nsum, ee_sum,
                                  fr, fro->step);
                }
            }

            /* determine if we should write it */
            if (bWrite && (delta_t == 0 || bRmod(fro->t, toffset, delta_t)))
            {
                laststep = fro->step;
                last_t   = fro->t;
                if (bNewOutput)
                {
                    bNewOutput = FALSE;
                    fprintf(stderr, "\nContinue writing frames from t=%g, step=%s\n",
                            fro->t, gmx_step_str(fro->step, buf));
                }

                /* Copy the energies */
                for (i = 0; i < nre; i++)
                {
                    fro->ener[i].e = fr->ener[i].e;
                }

                fro->nsteps = ee_sum_nsteps;
                fro->dt     = fr->dt;

                if (ee_sum_nsum <= 1)
                {
                    fro->nsum = 0;
                }
                else
                {
                    fro->nsum = gmx_int64_to_int(ee_sum_nsum,
                                                 "energy average summation");
                    /* Copy the energy sums */
                    for (i = 0; i < nre; i++)
                    {
                        fro->ener[i].esum = ee_sum[i].esum;
                        fro->ener[i].eav  = ee_sum[i].eav;
                    }
                }
                /* We wrote the energies, so reset the counts */
                ee_sum_nsteps = 0;
                ee_sum_nsum   = 0;

                if (scalefac != 1)
                {
                    for (kkk = 0; kkk < nset; kkk++)
                    {
                        fro->ener[set[kkk]].e    *= scalefac;
                        if (fro->nsum > 0)
                        {
                            fro->ener[set[kkk]].eav  *= scalefac*scalefac;
                            fro->ener[set[kkk]].esum *= scalefac;
                        }
                    }
                }
                /* Copy restraint stuff */
                /*fro->ndisre       = fr->ndisre;
                   fro->disre_rm3tav = fr->disre_rm3tav;
                   fro->disre_rt     = fr->disre_rt;*/
                fro->nblock       = fr->nblock;
                /*fro->nr           = fr->nr;*/
                fro->block        = fr->block;

                /* check if we have blocks with delta_h data and are throwing
                   away data */
                if (fro->nblock > 0)
                {
                    if (remove_dh)
                    {
                        int i;
                        if (!blocks || nblocks_alloc < fr->nblock)
                        {
                            /* we pre-allocate the blocks */
                            nblocks_alloc = fr->nblock;
                            snew(blocks, nblocks_alloc);
                        }
                        nblocks = 0; /* number of blocks so far */

                        for (i = 0; i < fr->nblock; i++)
                        {
                            if ( (fr->block[i].id != enxDHCOLL) &&
                                 (fr->block[i].id != enxDH) &&
                                 (fr->block[i].id != enxDHHIST) )
                            {
                                /* copy everything verbatim */
                                blocks[nblocks] = fr->block[i];
                                nblocks++;
                            }
                        }
                        /* now set the block pointer to the new blocks */
                        fro->nblock = nblocks;
                        fro->block  = blocks;
                    }
                    else if (delta_t > 0)
                    {
                        if (!warned_about_dh)
                        {
                            for (i = 0; i < fr->nblock; i++)
                            {
                                if (fr->block[i].id == enxDH ||
                                    fr->block[i].id == enxDHHIST)
                                {
                                    int size;
                                    if (fr->block[i].id == enxDH)
                                    {
                                        size = fr->block[i].sub[2].nr;
                                    }
                                    else
                                    {
                                        size = fr->nsteps;
                                    }
                                    if (size > 0)
                                    {
                                        printf("\nWARNING: %s contains delta H blocks or histograms for which\n"
                                               "         some data is thrown away on a block-by-block basis, where each block\n"
                                               "         contains up to %d samples.\n"
                                               "         This is almost certainly not what you want.\n"
                                               "         Use the -rmdh option to throw all delta H samples away.\n"
                                               "         Use g_energy -odh option to extract these samples.\n",
                                               fnms[f], size);
                                        warned_about_dh = TRUE;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }

                do_enx(out, fro);
                if (noutfr % 1000 == 0)
                {
                    fprintf(stderr, "Writing frame time %g    ", fro->t);
                }
                noutfr++;
            }
        }
        if (f == nfile)
        {
            f--;
        }
        printf("\nLast step written from %s: t %g, step %s\n",
               fnms[f], last_t, gmx_step_str(laststep, buf));
        lastfilestep = laststep;

        /* set the next time from the last in previous file */
        if (cont_type[f+1] == TIME_CONTINUE)
        {
            settime[f+1] = fro->t;
            /* in this case we have already written the last frame of
             * previous file, so update begin to avoid doubling it
             * with the start of the next file
             */
            begin = fro->t+0.5*timestep;
            /* cont_type[f+1]==TIME_EXPLICIT; */
        }

        if ((fro->t < end) && (f < nfile-1) &&
            (fro->t < settime[f+1]-1.5*timestep))
        {
            fprintf(stderr,
                    "\nWARNING: There might be a gap around t=%g\n", fro->t);
        }

        /* move energies to lastee */
        close_enx(in);
        free_enxnms(this_nre, enm);

        fprintf(stderr, "\n");
    }
    if (noutfr == 0)
    {
        fprintf(stderr, "No frames written.\n");
    }
    else
    {
        fprintf(stderr, "Last frame written was at step %s, time %f\n",
                gmx_step_str(fro->step, buf), fro->t);
        fprintf(stderr, "Wrote %d frames\n", noutfr);
    }

    return 0;
}
Exemplo n.º 2
0
int gmx_eneconv(int argc,char *argv[])
{
  static char *desc[] = {
    "With [IT]multiple files[it] specified for the [TT]-f[tt] option:[BR]",
    "Concatenates several energy files in sorted order.",
    "In case of double time frames the one",
    "in the later file is used. By specifying [TT]-settime[tt] you will be",
    "asked for the start time of each file. The input files are taken",
    "from the command line,",
    "such that the command [TT]eneconv -o fixed.edr *.edr[tt] should do",
    "the trick. [PAR]",
    "With [IT]one file[it] specified for [TT]-f[tt]:[BR]",
    "Reads one energy file and writes another, applying the [TT]-dt[tt],",
    "[TT]-offset[tt], [TT]-t0[tt] and [TT]-settime[tt] options and",
    "converting to a different format if necessary (indicated by file",
    "extentions).[PAR]",
    "[TT]-settime[tt] is applied first, then [TT]-dt[tt]/[TT]-offset[tt]",
    "followed by [TT]-b[tt] and [TT]-e[tt] to select which frames to write."
  };
  static char *bugs[] = {
    "When combining trajectories the sigma and E^2 (necessary for statistics) are not updated correctly. Only the actual energy is correct. One thus has to compute statistics in another way."
  };
  int        in,out=0;
  t_enxframe *fr,*fro;
  t_energy   *lastee,*startee;
  int        laststep,startstep,startstep_file=0,noutfr;
  int        nre,nremax,this_nre,nfile,i,j,kkk,nset,*set=NULL;
  real       t=0; 
  char       **fnms;
  char       **enm=NULL;
  real       *readtime,*settime,timestep,t1,tadjust;
  char       inputstring[STRLEN],*chptr;
  bool       ok;
  int        *cont_type;
  bool       bNewFile,bFirst,bNewOutput;
  
  t_filenm fnm[] = {
    { efENX, "-f", NULL,    ffRDMULT },
    { efENX, "-o", "fixed", ffWRITE  },
  };

#define NFILE asize(fnm)  
  bool   bWrite;
  static real  delta_t=0.0, toffset=0,scalefac=1;
  static bool  bSetTime=FALSE;
  static bool  bSort=TRUE,bError=TRUE;
  static real  begin=-1;
  static real  end=-1;
  
  t_pargs pa[] = {
    { "-b",        FALSE, etREAL, {&begin},
      "First time to use"},
    { "-e",        FALSE, etREAL, {&end},
      "Last time to use"},
    { "-dt",       FALSE, etREAL, {&delta_t},
      "Only write out frame when t MOD dt = offset" },
    { "-offset",   FALSE, etREAL, {&toffset},
      "Time offset for -dt option" }, 
    { "-settime",  FALSE, etBOOL, {&bSetTime}, 
      "Change starting time interactively" },
    { "-sort",     FALSE, etBOOL, {&bSort},
      "Sort energy files (not frames)"},
    { "-scalefac", FALSE, etREAL, {&scalefac},
      "Multiply energy component by this factor" },
    { "-error",    FALSE, etBOOL, {&bError},
      "Stop on errors in the file" }
  };
  
  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_BE_NICE ,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,asize(bugs),bugs);
  tadjust  = 0;
  nremax   = 0;
  nset     = 0;
  timestep = 0.0;
  snew(fnms,argc);
  nfile=0;
  laststep=startstep=0;
  
  nfile = opt2fns(&fnms,"-f",NFILE,fnm);
  
  if (!nfile)
    gmx_fatal(FARGS,"No input files!");
  
  snew(settime,nfile+1);
  snew(readtime,nfile+1);
  snew(cont_type,nfile+1);
  
  nre=scan_ene_files(fnms,nfile,readtime,&timestep,&nremax);   
  edit_files(fnms,nfile,readtime,settime,cont_type,bSetTime,bSort);     

  snew(fr,1);
  snew(fro,1);
  fro->t = -1;
  fro->nre = nre;
  snew(fro->ener,nremax);

  if(nfile>1)
    snew(lastee,nremax);
  else
    lastee=NULL;

  snew(startee,nremax);
    
  noutfr=0;
  bFirst=TRUE;

  for(i=0;i<nfile;i++) {
    bNewFile=TRUE;
    bNewOutput=TRUE;
    in=open_enx(fnms[i],"r");
    do_enxnms(in,&this_nre,&enm);
    if(i==0) {
      if (scalefac != 1)
	set = select_it(nre,enm,&nset);
      
      /* write names to the output file */
      out=open_enx(opt2fn("-o",NFILE,fnm),"w");  
      do_enxnms(out,&nre,&enm);
    }
    
    /* start reading from the next file */
    while((t<(settime[i+1]-GMX_REAL_EPS)) &&
	  do_enx(in,fr)) {
      if(bNewFile) {
	startstep_file = fr->step;
	tadjust = settime[i] - fr->t;	  
	if(cont_type[i+1]==TIME_LAST) {
	  settime[i+1]   = readtime[i+1]-readtime[i]+settime[i];
	  cont_type[i+1] = TIME_EXPLICIT;
	}
	bNewFile = FALSE;
      }
      fro->step = laststep + fr->step - startstep_file;
      t = tadjust + fr->t;

      /*bWrite = ((begin<0 || (begin>=0 && (t >= begin-GMX_REAL_EPS))) && 
		(end  <0 || (end  >=0 && (t <= end  +GMX_REAL_EPS))) &&
		(t < settime[i+1]-GMX_REAL_EPS));*/
      bWrite = ((begin<0 || (begin>=0 && (t >= begin-GMX_REAL_EPS))) && 
		(end  <0 || (end  >=0 && (t <= end  +GMX_REAL_EPS))) &&
		(t < settime[i+1]-0.5*timestep));
      
      if (bError)      
	if ((end > 0) && (t > end+GMX_REAL_EPS)) {
	  i = nfile;
	  break;
	}
      
      if (t >= begin-GMX_REAL_EPS) {
	if (bFirst) {
	  bFirst = FALSE;
	  startstep = fr->step;	
	  if (begin > 0)
	    copy_ee(fr->ener,startee,nre);
	}
	update_ee(lastee,laststep,startee,startstep,
		  fr->ener,fro->step,fro->ener,nre);
      }	  
      
      /* determine if we should write it */
      if (bWrite && (delta_t==0 || bRmod(t,toffset,delta_t))) {
	fro->t = t;
	if(bNewOutput) {
	  bNewOutput=FALSE;
	  fprintf(stderr,"\nContinue writing frames from t=%g, step=%d\n",
		  t,fro->step);
	}
	if (scalefac != 1) {
	  for(kkk=0; kkk<nset; kkk++) {
	    fro->ener[set[kkk]].e    *= scalefac;
	    fro->ener[set[kkk]].eav  *= scalefac;
	    fro->ener[set[kkk]].esum *= scalefac;
	  }
	}
	/* Copy restraint stuff */
	fro->ndisre       = fr->ndisre;
	fro->disre_rm3tav = fr->disre_rm3tav;
	fro->disre_rt     = fr->disre_rt;
	fro->nblock       = fr->nblock;
	fro->nr           = fr->nr;
	fro->block        = fr->block;
	
	do_enx(out,fro);
	if (noutfr % 1000 == 0)
	  fprintf(stderr,"Writing frame time %g    ",fro->t);
	noutfr++;
      }
    }
    /* copy statistics to old */
    if (lastee != NULL) {
	update_last_ee(lastee,laststep,fr->ener,fro->step,nre);
	laststep = fro->step;
	/* remove the last frame from statistics since gromacs2.0 
	 * repeats it in the next file 
	 */
	remove_last_eeframe(lastee,laststep,fr->ener,nre);
	/* the old part now has (laststep) values, and the new (step+1) */
	printf("laststep=%d step=%d\n",laststep,fro->step);
    }
    
    /* set the next time from the last in previous file */
    if (cont_type[i+1]==TIME_CONTINUE) {
	settime[i+1] = fro->t;
	/* in this case we have already written the last frame of
	 * previous file, so update begin to avoid doubling it
	 * with the start of the next file
	 */
	begin = fro->t+0.5*timestep;
	/* cont_type[i+1]==TIME_EXPLICIT; */
    }
    
    if ((fro->t < end) && (i < nfile-1) &&
	(fro->t < settime[i+1]-1.5*timestep)) 
      fprintf(stderr,
	      "\nWARNING: There might be a gap around t=%g\n",t);
    
    /* move energies to lastee */
    close_enx(in);
    for(kkk=0; kkk<this_nre; kkk++)
      sfree(enm[kkk]);
    sfree(enm);
    enm = NULL;

    fprintf(stderr,"\n");
  }
  if (noutfr == 0)
    fprintf(stderr,"No frames written.\n");
  else {
    fprintf(stderr,"Last frame written was at step %d, time %f\n",
	    fro->step,fro->t);
    fprintf(stderr,"Wrote %d frames\n",noutfr);
  }

  thanx(stderr);
  return 0;
}