From 953d3e7aa050a4a7076db723ebec14bf8d4c56a4 Mon Sep 17 00:00:00 2001 From: Mark Abraham Date: Mon, 17 Apr 2017 16:40:12 +0200 Subject: [PATCH] Cleaned up memory usage in gmx traj and trjconv These have test coverage, so their memory leaks can show up in Jenkins, so need fixing. Removed the frame title from t_trxframe. This was only ever relevant for the non-binary file formats, and was not really used consistently there. For example, trjconv always constructed a title, because it needs to do so if the file that it read was a binary trajectory file, which is a frequent use case when writing a non-binary trajectory file (e.g. export xtc to pdb). The g96 format was also handled differently from gro and pdb, which was not necessary. Because sometimes a non-binary conformation file is read and used to create a topology, a symbol table entry was managed when it was not required when that file was actually being treated as a trajectory file. Nowhere was a title being read into a t_trxframe, and later written from that t_trxframe in a different scope, so there is no need to store it. Removed close_trj. This duplicated function makes it hard to implement C-style cleanup that works properly and is maintainable without leaking memory in one place or another. Removed premature initialization of t_topology in trjconv. The initial contents are over-written in read_tps_conf(). Documented that the caller of that function must call done_top(). Reading g96 files was uselessly creating a symtab. This is only needed if fr->atoms is valid, but if so then there would be a symtab to pass in. fr->atoms is valid when we write, and in read_stx_conf, but this is not the case for general trajectory-frame reading. Memory allocated by TNG was leaking, so created free_wrapper() so we can have an RAII guard for that. Initialized some more pointers in trjconv. Change-Id: I3c7ca63cc39f21c69810997a90ae2b45b6845263 --- src/contrib/do_multiprot.c | 2 +- src/contrib/do_shift.c | 2 +- src/contrib/gmx_sdf.c | 2 +- src/gromacs/fileio/checkpoint.cpp | 1 - src/gromacs/fileio/confio.cpp | 26 ++++++------------ src/gromacs/fileio/confio.h | 4 +-- src/gromacs/fileio/espio.cpp | 9 ++++-- src/gromacs/fileio/espio.h | 7 +++-- src/gromacs/fileio/g96io.cpp | 25 +++++++++-------- src/gromacs/fileio/g96io.h | 12 +++++--- src/gromacs/fileio/groio.cpp | 11 ++++---- src/gromacs/fileio/groio.h | 5 ++-- src/gromacs/fileio/pdbio.cpp | 7 +++-- src/gromacs/fileio/pdbio.h | 7 +++-- src/gromacs/fileio/tngio.cpp | 18 +++++++----- src/gromacs/fileio/trxio.cpp | 44 ++++++++---------------------- src/gromacs/fileio/trxio.h | 7 +---- src/gromacs/gmxana/anadih.cpp | 2 +- src/gromacs/gmxana/gmx_covar.cpp | 4 +-- src/gromacs/gmxana/gmx_density.cpp | 4 +-- src/gromacs/gmxana/gmx_densmap.cpp | 2 +- src/gromacs/gmxana/gmx_densorder.cpp | 2 +- src/gromacs/gmxana/gmx_dipoles.cpp | 2 +- src/gromacs/gmxana/gmx_disre.cpp | 2 +- src/gromacs/gmxana/gmx_do_dssp.cpp | 2 +- src/gromacs/gmxana/gmx_dos.cpp | 2 +- src/gromacs/gmxana/gmx_gyrate.cpp | 2 +- src/gromacs/gmxana/gmx_hbond.cpp | 2 +- src/gromacs/gmxana/gmx_helix.cpp | 2 +- src/gromacs/gmxana/gmx_helixorient.cpp | 2 +- src/gromacs/gmxana/gmx_hydorder.cpp | 2 +- src/gromacs/gmxana/gmx_mdmat.cpp | 2 +- src/gromacs/gmxana/gmx_mindist.cpp | 2 +- src/gromacs/gmxana/gmx_msd.cpp | 2 +- src/gromacs/gmxana/gmx_order.cpp | 4 +-- src/gromacs/gmxana/gmx_potential.cpp | 2 +- src/gromacs/gmxana/gmx_principal.cpp | 2 +- src/gromacs/gmxana/gmx_rms.cpp | 4 +-- src/gromacs/gmxana/gmx_rmsdist.cpp | 2 +- src/gromacs/gmxana/gmx_rmsf.cpp | 2 +- src/gromacs/gmxana/gmx_rotacf.cpp | 2 +- src/gromacs/gmxana/gmx_rotmat.cpp | 4 +-- src/gromacs/gmxana/gmx_saltbr.cpp | 2 +- src/gromacs/gmxana/gmx_sans.cpp | 2 +- src/gromacs/gmxana/gmx_sorient.cpp | 2 +- src/gromacs/gmxana/gmx_spol.cpp | 2 +- src/gromacs/gmxana/gmx_tcaf.cpp | 2 +- src/gromacs/gmxana/gmx_traj.cpp | 41 ++++++++++++++++++++++------ src/gromacs/gmxana/gmx_trjcat.cpp | 8 +++--- src/gromacs/gmxana/gmx_trjconv.cpp | 31 +++++++++++++++------ src/gromacs/gmxana/gmx_trjorder.cpp | 2 +- src/gromacs/gmxana/gmx_vanhove.cpp | 2 +- src/gromacs/gmxana/gmx_velacc.cpp | 2 +- src/gromacs/gmxpreprocess/genconf.cpp | 2 +- src/gromacs/gmxpreprocess/grompp.cpp | 4 +-- src/gromacs/mdlib/tpi.cpp | 2 +- src/gromacs/tools/check.cpp | 4 +-- src/gromacs/topology/index.cpp | 24 ++++++---------- src/gromacs/topology/index.h | 6 +--- src/gromacs/topology/symtab.h | 4 ++- src/gromacs/trajectory/trajectoryframe.cpp | 4 --- src/gromacs/trajectory/trajectoryframe.h | 2 -- src/gromacs/utility/unique_cptr.h | 13 ++++++++- src/programs/mdrun/md.cpp | 2 +- 64 files changed, 216 insertions(+), 196 deletions(-) diff --git a/src/contrib/do_multiprot.c b/src/contrib/do_multiprot.c index dfd8849954..cddc1d2825 100644 --- a/src/contrib/do_multiprot.c +++ b/src/contrib/do_multiprot.c @@ -430,7 +430,7 @@ int main(int argc,char *argv[]) gmx_ffclose(fo); gmx_ffclose(frc); fprintf(stderr,"\n"); - close_trj(status); + close_trx(status); if (trxout != NULL) { close_trx(trxout); } diff --git a/src/contrib/do_shift.c b/src/contrib/do_shift.c index fce2869ebb..bd44853142 100644 --- a/src/contrib/do_shift.c +++ b/src/contrib/do_shift.c @@ -179,7 +179,7 @@ int main(int argc,char *argv[]) nframe++; } } while(read_next_x(status,&t,natoms,x,box)); - close_trj(status); + close_trx(status); gmx_ffclose(out); gmx_thanx(stderr); diff --git a/src/contrib/gmx_sdf.c b/src/contrib/gmx_sdf.c index 725a3aeb19..6818a77b1b 100644 --- a/src/contrib/gmx_sdf.c +++ b/src/contrib/gmx_sdf.c @@ -539,7 +539,7 @@ structure if needed */ gmx_rmpbc_done(gpbc); - close_trj(status); + close_trx(status); sfree(x); diff --git a/src/gromacs/fileio/checkpoint.cpp b/src/gromacs/fileio/checkpoint.cpp index 67c1254648..9377b60f45 100644 --- a/src/gromacs/fileio/checkpoint.cpp +++ b/src/gromacs/fileio/checkpoint.cpp @@ -2546,7 +2546,6 @@ void read_checkpoint_trxframe(t_fileio *fp, t_trxframe *fr) read_checkpoint_data(fp, &simulation_part, &step, &t, &state, nullptr, nullptr); fr->natoms = state.natoms; - fr->bTitle = FALSE; fr->bStep = TRUE; fr->step = gmx_int64_to_int(step, "conversion of checkpoint to trajectory"); diff --git a/src/gromacs/fileio/confio.cpp b/src/gromacs/fileio/confio.cpp index 9888e6407a..b9015383b4 100644 --- a/src/gromacs/fileio/confio.cpp +++ b/src/gromacs/fileio/confio.cpp @@ -80,8 +80,6 @@ void write_sto_conf_indexed(const char *outfile, const char *title, break; case efG96: clear_trxframe(&fr, TRUE); - fr.bTitle = TRUE; - fr.title = title; fr.natoms = atoms->nr; fr.bAtoms = TRUE; fr.atoms = const_cast(atoms); @@ -95,7 +93,7 @@ void write_sto_conf_indexed(const char *outfile, const char *title, fr.bBox = TRUE; copy_mat(box, fr.box); out = gmx_fio_fopen(outfile, "w"); - write_g96_conf(out, &fr, nindex, index); + write_g96_conf(out, title, &fr, nindex, index); gmx_fio_fclose(out); break; case efPDB: @@ -134,8 +132,6 @@ void write_sto_conf(const char *outfile, const char *title, const t_atoms *atoms break; case efG96: clear_trxframe(&fr, TRUE); - fr.bTitle = TRUE; - fr.title = title; fr.natoms = atoms->nr; fr.bAtoms = TRUE; fr.atoms = const_cast(atoms); // TODO check @@ -149,7 +145,7 @@ void write_sto_conf(const char *outfile, const char *title, const t_atoms *atoms fr.bBox = TRUE; copy_mat(box, fr.box); out = gmx_fio_fopen(outfile, "w"); - write_g96_conf(out, &fr, -1, nullptr); + write_g96_conf(out, title, &fr, -1, nullptr); gmx_fio_fclose(out); break; case efPDB: @@ -218,14 +214,12 @@ static void get_stx_coordnum(const char *infile, int *natoms) case efG96: { in = gmx_fio_fopen(infile, "r"); - fr.title = nullptr; fr.natoms = -1; fr.atoms = nullptr; fr.x = nullptr; fr.v = nullptr; fr.f = nullptr; - *natoms = read_g96_conf(in, infile, &fr, nullptr, g96_line); - sfree(const_cast(fr.title)); + *natoms = read_g96_conf(in, infile, nullptr, &fr, nullptr, g96_line); gmx_fio_fclose(in); break; } @@ -305,7 +299,7 @@ static void tpx_make_chain_identifiers(t_atoms *atoms, t_block *mols) } static void read_stx_conf(const char *infile, - t_symtab *symtab, char ***name, t_atoms *atoms, + t_symtab *symtab, char **name, t_atoms *atoms, rvec x[], rvec *v, int *ePBC, matrix box) { FILE *in; @@ -334,18 +328,15 @@ static void read_stx_conf(const char *infile, gmx_gro_read_conf(infile, symtab, name, atoms, x, v, box); break; case efG96: - fr.title = nullptr; fr.natoms = atoms->nr; fr.atoms = atoms; fr.x = x; fr.v = v; fr.f = nullptr; in = gmx_fio_fopen(infile, "r"); - read_g96_conf(in, infile, &fr, symtab, g96_line); + read_g96_conf(in, infile, name, &fr, symtab, g96_line); gmx_fio_fclose(in); copy_mat(fr.box, box); - *name = put_symtab(symtab, fr.title); - sfree(const_cast(fr.title)); break; case efPDB: case efBRK: @@ -361,7 +352,7 @@ static void read_stx_conf(const char *infile, } static void readConfAndAtoms(const char *infile, - t_symtab *symtab, char ***name, t_atoms *atoms, + t_symtab *symtab, char **name, t_atoms *atoms, int *ePBC, rvec **x, rvec **v, matrix box) { @@ -428,7 +419,7 @@ void readConfAndTopology(const char *infile, else { t_symtab symtab; - char **name; + char *name; t_atoms atoms; open_symtab(&symtab); @@ -436,7 +427,8 @@ void readConfAndTopology(const char *infile, readConfAndAtoms(infile, &symtab, &name, &atoms, ePBC, x, v, box); init_mtop(mtop); - convertAtomsToMtop(&symtab, name, &atoms, mtop); + convertAtomsToMtop(&symtab, put_symtab(&symtab, name), &atoms, mtop); + sfree(name); } } diff --git a/src/gromacs/fileio/confio.h b/src/gromacs/fileio/confio.h index 18fe339aa4..be8b299669 100644 --- a/src/gromacs/fileio/confio.h +++ b/src/gromacs/fileio/confio.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -97,7 +97,7 @@ void readConfAndTopology(const char *infile, * their presence is signaled with the \p haveMass flag in t_atoms of \p top. * * \param[in] infile Input file name - * \param[out] top The topology, either complete or only atom data + * \param[out] top The topology, either complete or only atom data. Caller is responsible for calling done_top(). * \param[out] ePBC Enum reporting the type of PBC * \param[in,out] x Coordinates will be stored when *x!=NULL * \param[in,out] v Velocities will be stored when *v!=NULL diff --git a/src/gromacs/fileio/espio.cpp b/src/gromacs/fileio/espio.cpp index f7ee9fea2c..34eaa711b3 100644 --- a/src/gromacs/fileio/espio.cpp +++ b/src/gromacs/fileio/espio.cpp @@ -164,7 +164,7 @@ static const char *const esp_prop[espNR] = { }; void gmx_espresso_read_conf(const char *infile, - t_symtab *symtab, char ***name, t_atoms *atoms, + t_symtab *symtab, char **name, t_atoms *atoms, rvec x[], rvec *v, matrix box) { FILE *fp; @@ -174,8 +174,11 @@ void gmx_espresso_read_conf(const char *infile, double d; gmx_bool bFoundParticles, bFoundProp, bFoundVariable, bMol; - // No title reading implemented for espresso files - *name = put_symtab(symtab, ""); + if (name != nullptr) + { + // No title reading implemented for espresso files + *name = gmx_strdup(""); + } clear_mat(box); diff --git a/src/gromacs/fileio/espio.h b/src/gromacs/fileio/espio.h index 91cd979474..3de1138bcd 100644 --- a/src/gromacs/fileio/espio.h +++ b/src/gromacs/fileio/espio.h @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 2005, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -44,8 +44,11 @@ struct t_atoms; struct t_symtab; void gmx_espresso_read_conf(const char *infile, - t_symtab *symtab, char ***name, t_atoms *atoms, + t_symtab *symtab, char **name, t_atoms *atoms, rvec x[], rvec *v, matrix box); +/* If name is not nullptr, gmx_strdup the title string into + * it. Reading a title from espresso format is not , so this will + * always be an empty string. */ int get_espresso_coordnum(const char *infile); diff --git a/src/gromacs/fileio/g96io.cpp b/src/gromacs/fileio/g96io.cpp index b1dd3f6326..208c42d9cc 100644 --- a/src/gromacs/fileio/g96io.cpp +++ b/src/gromacs/fileio/g96io.cpp @@ -48,6 +48,7 @@ #include "gromacs/trajectory/trajectoryframe.h" #include "gromacs/utility/cstringutil.h" #include "gromacs/utility/fatalerror.h" +#include "gromacs/utility/gmxassert.h" #include "gromacs/utility/smalloc.h" #define CHAR_SHIFT 24 @@ -65,6 +66,10 @@ static int read_g96_pos(char line[], t_symtab *symtab, nwanted = fr->natoms; + if (fr->atoms != nullptr) + { + GMX_RELEASE_ASSERT(symtab != nullptr, "Reading a conformation from a g96 format with atom data requires a valid symbol table"); + } atoms = fr->atoms; if (atoms != nullptr) { @@ -223,7 +228,7 @@ static int read_g96_vel(char line[], FILE *fp, const char *infile, return natoms; } -int read_g96_conf(FILE *fp, const char *infile, t_trxframe *fr, +int read_g96_conf(FILE *fp, const char *infile, char **name, t_trxframe *fr, t_symtab *symtab, char *line) { gmx_bool bAtStart, bTime, bAtoms, bPos, bVel, bBox, bEnd, bFinished; @@ -238,14 +243,15 @@ int read_g96_conf(FILE *fp, const char *infile, t_trxframe *fr, if (bAtStart) { - while (!fr->bTitle && fgets2(line, STRLEN, fp)) + bool foundTitle = false; + while (!foundTitle && fgets2(line, STRLEN, fp)) { - fr->bTitle = (std::strcmp(line, "TITLE") == 0); + foundTitle = (std::strcmp(line, "TITLE") == 0); } - if (fr->title == nullptr) + fgets2(line, STRLEN, fp); + if (name != nullptr) { - fgets2(line, STRLEN, fp); - fr->title = gmx_strdup(line); + *name = gmx_strdup(line); } bEnd = FALSE; while (!bEnd && fgets2(line, STRLEN, fp)) @@ -344,7 +350,7 @@ int read_g96_conf(FILE *fp, const char *infile, t_trxframe *fr, return natoms; } -void write_g96_conf(FILE *out, const t_trxframe *fr, +void write_g96_conf(FILE *out, const char *title, const t_trxframe *fr, int nindex, const int *index) { t_atoms *atoms; @@ -361,10 +367,7 @@ void write_g96_conf(FILE *out, const t_trxframe *fr, nout = fr->natoms; } - if (fr->bTitle) - { - fprintf(out, "TITLE\n%s\nEND\n", fr->title); - } + fprintf(out, "TITLE\n%s\nEND\n", title); if (fr->bStep || fr->bTime) { /* Officially the time format is %15.9, which is not enough for 10 ns */ diff --git a/src/gromacs/fileio/g96io.h b/src/gromacs/fileio/g96io.h index 1f4a8f6572..b33d55cdbc 100644 --- a/src/gromacs/fileio/g96io.h +++ b/src/gromacs/fileio/g96io.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,7 +47,7 @@ extern "C" { struct t_symtab; struct t_trxframe; -int read_g96_conf(FILE *fp, const char *infile, struct t_trxframe *fr, +int read_g96_conf(FILE *fp, const char *infile, char **name, struct t_trxframe *fr, struct t_symtab *symtab, char *line); /* read a Gromos96 coordinate or trajectory file, * * returns the number of atoms * @@ -56,9 +56,13 @@ int read_g96_conf(FILE *fp, const char *infile, struct t_trxframe *fr, * nwanted is the number of wanted coordinates, * * set this to -1 if you want to know the number of atoms in the file * * title, atoms, x, v can all be NULL, in which case they won't be read * - * line holds the previous line for trajectory reading */ + * line holds the previous line for trajectory reading * + * + * symtab only needs to be valid if fr->atoms is valid + * + * If name is not nullptr, gmx_strdup the first g96 title string into it. */ -void write_g96_conf(FILE *out, const t_trxframe *fr, int nindex, const int *index); +void write_g96_conf(FILE *out, const char *title, const t_trxframe *fr, int nindex, const int *index); /* write a Gromos96 coordinate file or trajectory frame * * index can be NULL */ diff --git a/src/gromacs/fileio/groio.cpp b/src/gromacs/fileio/groio.cpp index c0f041c28e..08fa47ddc8 100644 --- a/src/gromacs/fileio/groio.cpp +++ b/src/gromacs/fileio/groio.cpp @@ -308,14 +308,17 @@ static gmx_bool get_w_conf(FILE *in, const char *infile, char *title, } void gmx_gro_read_conf(const char *infile, - t_symtab *symtab, char ***name, t_atoms *atoms, + t_symtab *symtab, char **name, t_atoms *atoms, rvec x[], rvec *v, matrix box) { FILE *in = gmx_fio_fopen(infile, "r"); int ndec; char title[STRLEN]; get_w_conf(in, infile, title, symtab, atoms, &ndec, x, v, box); - *name = put_symtab(symtab, title); + if (name != nullptr) + { + *name = gmx_strdup(title); + } gmx_fio_fclose(in); } @@ -359,8 +362,6 @@ gmx_bool gro_next_x_or_v(FILE *status, t_trxframe *fr) { fr->prec *= 10; } - fr->title = title; - fr->bTitle = TRUE; fr->bX = TRUE; fr->bBox = TRUE; @@ -401,8 +402,6 @@ int gro_first_x_or_v(FILE *status, t_trxframe *fr) get_coordnum_fp(status, title, &fr->natoms); frewind(status); fprintf(stderr, " '%s', %d atoms.\n", title, fr->natoms); - fr->bTitle = TRUE; - fr->title = title; if (fr->natoms == 0) { gmx_file("No coordinates in gro file"); diff --git a/src/gromacs/fileio/groio.h b/src/gromacs/fileio/groio.h index 53448ca1ff..82fa543c57 100644 --- a/src/gromacs/fileio/groio.h +++ b/src/gromacs/fileio/groio.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -53,8 +53,9 @@ struct t_trxframe; void get_coordnum(const char *infile, int *natoms); void gmx_gro_read_conf(const char *infile, - t_symtab *symtab, char ***name, t_atoms *atoms, + t_symtab *symtab, char **name, t_atoms *atoms, rvec x[], rvec *v, matrix box); +/* If name is not nullptr, gmx_strdup the title string into it. */ gmx_bool gro_next_x_or_v(FILE *status, struct t_trxframe *fr); int gro_first_x_or_v(FILE *status, struct t_trxframe *fr); diff --git a/src/gromacs/fileio/pdbio.cpp b/src/gromacs/fileio/pdbio.cpp index cab5fa06aa..a07a1549af 100644 --- a/src/gromacs/fileio/pdbio.cpp +++ b/src/gromacs/fileio/pdbio.cpp @@ -1024,13 +1024,16 @@ void get_pdb_coordnum(FILE *in, int *natoms) } void gmx_pdb_read_conf(const char *infile, - t_symtab *symtab, char ***name, t_atoms *atoms, + t_symtab *symtab, char **name, t_atoms *atoms, rvec x[], int *ePBC, matrix box) { FILE *in = gmx_fio_fopen(infile, "r"); char title[STRLEN]; read_pdbfile(in, title, nullptr, atoms, symtab, x, ePBC, box, TRUE, nullptr); - *name = put_symtab(symtab, title); + if (name != nullptr) + { + *name = gmx_strdup(title); + } gmx_fio_fclose(in); } diff --git a/src/gromacs/fileio/pdbio.h b/src/gromacs/fileio/pdbio.h index c5a0ee3e22..27d5106d53 100644 --- a/src/gromacs/fileio/pdbio.h +++ b/src/gromacs/fileio/pdbio.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -126,12 +126,13 @@ int read_pdbfile(FILE *in, char *title, int *model_nr, */ void gmx_pdb_read_conf(const char *infile, - t_symtab *symtab, char ***name, t_atoms *atoms, + t_symtab *symtab, char **name, t_atoms *atoms, rvec x[], int *ePBC, matrix box); /* Read a pdb file and extract ATOM and HETATM fields. * Read a box from the CRYST1 line, return 0 box when no CRYST1 is found. * ePBC may be NULL. - */ + * + * If name is not nullptr, gmx_strdup the title string into it. */ void get_pdb_coordnum(FILE *in, int *natoms); /* Read a pdb file and count the ATOM and HETATM fields. */ diff --git a/src/gromacs/fileio/tngio.cpp b/src/gromacs/fileio/tngio.cpp index 28725ed036..fc05623f53 100644 --- a/src/gromacs/fileio/tngio.cpp +++ b/src/gromacs/fileio/tngio.cpp @@ -60,6 +60,7 @@ #include "gromacs/utility/programcontext.h" #include "gromacs/utility/smalloc.h" #include "gromacs/utility/sysinfo.h" +#include "gromacs/utility/unique_cptr.h" static const char *modeToVerb(char mode) { @@ -1306,13 +1307,15 @@ gmx_bool gmx_read_next_tng_frame(tng_trajectory_t input, } fr->natoms = numberOfAtoms; - if (!gmx_get_tng_data_block_types_of_next_frame(input, - fr->step, - numRequestedIds, - requestedIds, - &frameNumber, - &nBlocks, - &blockIds)) + bool nextFrameExists = gmx_get_tng_data_block_types_of_next_frame(input, + fr->step, + numRequestedIds, + requestedIds, + &frameNumber, + &nBlocks, + &blockIds); + gmx::unique_cptr blockIdsGuard(blockIds); + if (!nextFrameExists) { return FALSE; } @@ -1452,6 +1455,7 @@ gmx_bool gmx_read_next_tng_frame(tng_trajectory_t input, fr->time = frameTime / PICO; fr->bTime = TRUE; + // TODO This does not leak, but is not exception safe. /* values must be freed before leaving this function */ sfree(values); diff --git a/src/gromacs/fileio/trxio.cpp b/src/gromacs/fileio/trxio.cpp index 16ca193e5c..42540681f1 100644 --- a/src/gromacs/fileio/trxio.cpp +++ b/src/gromacs/fileio/trxio.cpp @@ -282,7 +282,6 @@ float trx_get_time_of_final_frame(t_trxstatus *status) void clear_trxframe(t_trxframe *fr, gmx_bool bFirst) { fr->not_ok = 0; - fr->bTitle = FALSE; fr->bStep = FALSE; fr->bTime = FALSE; fr->bLambda = FALSE; @@ -297,7 +296,6 @@ void clear_trxframe(t_trxframe *fr, gmx_bool bFirst) { fr->bDouble = FALSE; fr->natoms = -1; - fr->title = nullptr; fr->step = 0; fr->time = 0; fr->lambda = 0; @@ -432,7 +430,8 @@ int write_trxframe_indexed(t_trxstatus *status, const t_trxframe *fr, int nind, } break; case efG96: - write_g96_conf(gmx_fio_getfp(status->fio), fr, nind, ind); + sprintf(title, "frame t= %.3f", fr->time); + write_g96_conf(gmx_fio_getfp(status->fio), title, fr, nind, ind); break; default: gmx_fatal(FARGS, "Sorry, write_trxframe_indexed can not write %s", @@ -584,7 +583,7 @@ int write_trxframe(t_trxstatus *status, t_trxframe *fr, gmx_conect gc) } break; case efG96: - write_g96_conf(gmx_fio_getfp(status->fio), fr, -1, nullptr); + write_g96_conf(gmx_fio_getfp(status->fio), title, fr, -1, nullptr); break; default: gmx_fatal(FARGS, "Sorry, write_trxframe can not write %s", @@ -633,6 +632,10 @@ void close_trx(t_trxstatus *status) #if GMX_USE_PLUGINS sfree(status->vmdplugin); #endif + /* The memory in status->xframe is lost here, + * but the read_first_x/read_next_x functions are deprecated anyhow. + * read_first_frame/read_next_frame and close_trx should be used. + */ sfree(status); } @@ -839,12 +842,9 @@ gmx_bool read_next_frame(const gmx_output_env_t *oenv, t_trxstatus *status, t_tr break; case efG96: { - t_symtab *symtab; - snew(symtab, 1); - open_symtab(symtab); - read_g96_conf(gmx_fio_getfp(status->fio), nullptr, fr, + t_symtab *symtab = nullptr; + read_g96_conf(gmx_fio_getfp(status->fio), nullptr, nullptr, fr, symtab, status->persistent_line); - free_symtab(symtab); bRet = (fr->natoms > 0); break; } @@ -974,11 +974,8 @@ int read_first_frame(const gmx_output_env_t *oenv, t_trxstatus **status, /* allocate the persistent line */ snew((*status)->persistent_line, STRLEN+1); } - t_symtab *symtab; - snew(symtab, 1); - open_symtab(symtab); - read_g96_conf(gmx_fio_getfp(fio), fn, fr, symtab, (*status)->persistent_line); - free_symtab(symtab); + t_symtab *symtab = nullptr; + read_g96_conf(gmx_fio_getfp(fio), fn, nullptr, fr, symtab, (*status)->persistent_line); gmx_fio_close(fio); clear_trxframe(fr, FALSE); if (flags & (TRX_READ_X | TRX_NEED_X)) @@ -1122,25 +1119,6 @@ gmx_bool read_next_x(const gmx_output_env_t *oenv, t_trxstatus *status, real *t, return bRet; } -void close_trj(t_trxstatus *status) -{ - if (status == nullptr) - { - return; - } - gmx_tng_close(&status->tng); - if (status->fio) - { - gmx_fio_close(status->fio); - } - - /* The memory in status->xframe is lost here, - * but the read_first_x/read_next_x functions are deprecated anyhow. - * read_first_frame/read_next_frame and close_trx should be used. - */ - sfree(status); -} - void rewind_trj(t_trxstatus *status) { initcount(status); diff --git a/src/gromacs/fileio/trxio.h b/src/gromacs/fileio/trxio.h index 1995e27f73..0f6495967d 100644 --- a/src/gromacs/fileio/trxio.h +++ b/src/gromacs/fileio/trxio.h @@ -133,7 +133,7 @@ void write_tng_frame(t_trxstatus *status, void close_trx(t_trxstatus *status); /* Close trajectory file as opened with read_first_x, read_first_frame - * or open_trx. Identical to close_trj. + * or open_trx. * Also frees memory in the structure. */ @@ -227,11 +227,6 @@ gmx_bool read_next_x(const gmx_output_env_t *oenv, t_trxstatus *status, real *t, * status is the integer set in read_first_x. */ -void close_trj(t_trxstatus *status); -/* Close trajectory file as opened with read_first_x, read_first_frame - * or open_trx. Identical to close_trx. - */ - void rewind_trj(t_trxstatus *status); /* Rewind trajectory file as opened with read_first_x */ diff --git a/src/gromacs/gmxana/anadih.cpp b/src/gromacs/gmxana/anadih.cpp index 15759e5376..2393f556f0 100644 --- a/src/gromacs/gmxana/anadih.cpp +++ b/src/gromacs/gmxana/anadih.cpp @@ -1001,7 +1001,7 @@ void read_ang_dih(const char *trj_fn, teller++; } while (read_next_x(oenv, status, &t, x, box)); - close_trj(status); + close_trx(status); sfree(x); sfree(angles[cur]); diff --git a/src/gromacs/gmxana/gmx_covar.cpp b/src/gromacs/gmxana/gmx_covar.cpp index ef9bacc70b..3bdb367078 100644 --- a/src/gromacs/gmxana/gmx_covar.cpp +++ b/src/gromacs/gmxana/gmx_covar.cpp @@ -286,7 +286,7 @@ int gmx_covar(int argc, char *argv[]) } } while (read_next_x(oenv, status, &t, xread, box)); - close_trj(status); + close_trx(status); inv_nframes = 1.0/nframes0; for (i = 0; i < natoms; i++) @@ -353,7 +353,7 @@ int gmx_covar(int argc, char *argv[]) } while (read_next_x(oenv, status, &t, xread, box) && (bRef || nframes < nframes0)); - close_trj(status); + close_trx(status); gmx_rmpbc_done(gpbc); fprintf(stderr, "Read %d frames\n", nframes); diff --git a/src/gromacs/gmxana/gmx_density.cpp b/src/gromacs/gmxana/gmx_density.cpp index e92661be9f..f62f4180e6 100644 --- a/src/gromacs/gmxana/gmx_density.cpp +++ b/src/gromacs/gmxana/gmx_density.cpp @@ -300,7 +300,7 @@ void calc_electron_density(const char *fn, int **index, int gnx[], gmx_rmpbc_done(gpbc); /*********** done with status file **********/ - close_trj(status); + close_trx(status); /* slDensity now contains the total number of electrons per slice, summed over all frames. Now divide by nr_frames and volume of slice @@ -449,7 +449,7 @@ void calc_density(const char *fn, int **index, int gnx[], gmx_rmpbc_done(gpbc); /*********** done with status file **********/ - close_trj(status); + close_trx(status); /* slDensity now contains the total mass per slice, summed over all frames. Now divide by nr_frames and volume of slice diff --git a/src/gromacs/gmxana/gmx_densmap.cpp b/src/gromacs/gmxana/gmx_densmap.cpp index 84784621f4..de5e182276 100644 --- a/src/gromacs/gmxana/gmx_densmap.cpp +++ b/src/gromacs/gmxana/gmx_densmap.cpp @@ -369,7 +369,7 @@ int gmx_densmap(int argc, char *argv[]) nfr++; } while (read_next_x(oenv, status, &t, x, box)); - close_trj(status); + close_trx(status); /* normalize gridpoints */ maxgrid = 0; diff --git a/src/gromacs/gmxana/gmx_densorder.cpp b/src/gromacs/gmxana/gmx_densorder.cpp index 6aaf4b291d..beb764c348 100644 --- a/src/gromacs/gmxana/gmx_densorder.cpp +++ b/src/gromacs/gmxana/gmx_densorder.cpp @@ -264,7 +264,7 @@ static void density_in_time (const char *fn, int **index, int gnx[], real bw, re /*Free memory we no longer need and exit.*/ gmx_rmpbc_done(gpbc); - close_trj(status); + close_trx(status); if (0) { diff --git a/src/gromacs/gmxana/gmx_dipoles.cpp b/src/gromacs/gmxana/gmx_dipoles.cpp index fc19a482e9..b10f25364a 100644 --- a/src/gromacs/gmxana/gmx_dipoles.cpp +++ b/src/gromacs/gmxana/gmx_dipoles.cpp @@ -1337,7 +1337,7 @@ static void do_dip(const t_topology *top, int ePBC, real volume, if (!bMU) { - close_trj(status); + close_trx(status); } xvgrclose(outmtot); diff --git a/src/gromacs/gmxana/gmx_disre.cpp b/src/gromacs/gmxana/gmx_disre.cpp index d70512f17d..824808f73a 100644 --- a/src/gromacs/gmxana/gmx_disre.cpp +++ b/src/gromacs/gmxana/gmx_disre.cpp @@ -917,7 +917,7 @@ int gmx_disre(int argc, char *argv[]) j++; } while (read_next_x(oenv, status, &t, x, box)); - close_trj(status); + close_trx(status); if (ir->ePBC != epbcNONE) { gmx_rmpbc_done(gpbc); diff --git a/src/gromacs/gmxana/gmx_do_dssp.cpp b/src/gromacs/gmxana/gmx_do_dssp.cpp index 70c4256cfb..1d2ee996b2 100644 --- a/src/gromacs/gmxana/gmx_do_dssp.cpp +++ b/src/gromacs/gmxana/gmx_do_dssp.cpp @@ -685,7 +685,7 @@ int gmx_do_dssp(int argc, char *argv[]) } while (read_next_x(oenv, status, &t, x, box)); fprintf(stderr, "\n"); - close_trj(status); + close_trx(status); if (fTArea) { xvgrclose(fTArea); diff --git a/src/gromacs/gmxana/gmx_dos.cpp b/src/gromacs/gmxana/gmx_dos.cpp index 072999b613..26b3d3a83c 100644 --- a/src/gromacs/gmxana/gmx_dos.cpp +++ b/src/gromacs/gmxana/gmx_dos.cpp @@ -398,7 +398,7 @@ int gmx_dos(int argc, char *argv[]) } while (read_next_frame(oenv, status, &fr)); - close_trj(status); + close_trx(status); if (nframes < min_frames) { diff --git a/src/gromacs/gmxana/gmx_gyrate.cpp b/src/gromacs/gmxana/gmx_gyrate.cpp index ed2f590921..4b61de02a5 100644 --- a/src/gromacs/gmxana/gmx_gyrate.cpp +++ b/src/gromacs/gmxana/gmx_gyrate.cpp @@ -375,7 +375,7 @@ int gmx_gyrate(int argc, char *argv[]) j++; } while (read_next_x(oenv, status, &t, x, box)); - close_trj(status); + close_trx(status); if (nz == 0) { gmx_rmpbc_done(gpbc); diff --git a/src/gromacs/gmxana/gmx_hbond.cpp b/src/gromacs/gmxana/gmx_hbond.cpp index b9706ae5f0..bf44b6becf 100644 --- a/src/gromacs/gmxana/gmx_hbond.cpp +++ b/src/gromacs/gmxana/gmx_hbond.cpp @@ -3156,7 +3156,7 @@ int gmx_hbond(int argc, char *argv[]) free_grid(ngrid, &grid); - close_trj(status); + close_trx(status); if (donor_properties) { diff --git a/src/gromacs/gmxana/gmx_helix.cpp b/src/gromacs/gmxana/gmx_helix.cpp index 71657455a2..5589c4e94e 100644 --- a/src/gromacs/gmxana/gmx_helix.cpp +++ b/src/gromacs/gmxana/gmx_helix.cpp @@ -274,7 +274,7 @@ int gmx_helix(int argc, char *argv[]) gmx_rmpbc_done(gpbc); - close_trj(status); + close_trx(status); for (i = 0; (i < nres); i++) { diff --git a/src/gromacs/gmxana/gmx_helixorient.cpp b/src/gromacs/gmxana/gmx_helixorient.cpp index 89c0901a88..8b5a3c9bcf 100644 --- a/src/gromacs/gmxana/gmx_helixorient.cpp +++ b/src/gromacs/gmxana/gmx_helixorient.cpp @@ -480,7 +480,7 @@ int gmx_helixorient(int argc, char *argv[]) gmx_ffclose(fptheta2); gmx_ffclose(fptheta3); - close_trj(status); + close_trx(status); return 0; } diff --git a/src/gromacs/gmxana/gmx_hydorder.cpp b/src/gromacs/gmxana/gmx_hydorder.cpp index a1ad9703cd..88877f682c 100644 --- a/src/gromacs/gmxana/gmx_hydorder.cpp +++ b/src/gromacs/gmxana/gmx_hydorder.cpp @@ -366,7 +366,7 @@ static void calc_tetra_order_interface(const char *fnNDX, const char *fnTPS, con } while (read_next_x(oenv, status, &t, x, box)); - close_trj(status); + close_trx(status); sfree(grpname); sfree(index); diff --git a/src/gromacs/gmxana/gmx_mdmat.cpp b/src/gromacs/gmxana/gmx_mdmat.cpp index 56ee263c29..191b635b7f 100644 --- a/src/gromacs/gmxana/gmx_mdmat.cpp +++ b/src/gromacs/gmxana/gmx_mdmat.cpp @@ -345,7 +345,7 @@ int gmx_mdmat(int argc, char *argv[]) } while (read_next_x(oenv, status, &t, x, box)); fprintf(stderr, "\n"); - close_trj(status); + close_trx(status); gmx_rmpbc_done(gpbc); if (bFrames) { diff --git a/src/gromacs/gmxana/gmx_mindist.cpp b/src/gromacs/gmxana/gmx_mindist.cpp index b2a05a954c..202eda2b10 100644 --- a/src/gromacs/gmxana/gmx_mindist.cpp +++ b/src/gromacs/gmxana/gmx_mindist.cpp @@ -556,7 +556,7 @@ void dist_plot(const char *fn, const char *afile, const char *dfile, } while (read_next_x(oenv, status, &t, x0, box)); - close_trj(status); + close_trx(status); xvgrclose(dist); if (num) { diff --git a/src/gromacs/gmxana/gmx_msd.cpp b/src/gromacs/gmxana/gmx_msd.cpp index faa8d1fdbd..e3eed38da7 100644 --- a/src/gromacs/gmxana/gmx_msd.cpp +++ b/src/gromacs/gmxana/gmx_msd.cpp @@ -828,7 +828,7 @@ int corr_loop(t_corr *curr, const char *fn, const t_topology *top, int ePBC, gmx_rmpbc_done(gpbc); } - close_trj(status); + close_trx(status); return natoms; } diff --git a/src/gromacs/gmxana/gmx_order.cpp b/src/gromacs/gmxana/gmx_order.cpp index 65549beccb..2b5f1bb15d 100644 --- a/src/gromacs/gmxana/gmx_order.cpp +++ b/src/gromacs/gmxana/gmx_order.cpp @@ -319,7 +319,7 @@ static void calc_tetra_order_parm(const char *fnNDX, const char *fnTPS, nframes++; } while (read_next_x(oenv, status, &t, x, box)); - close_trj(status); + close_trx(status); gmx_rmpbc_done(gpbc); sfree(grpname); @@ -846,7 +846,7 @@ void write_bfactors(t_filenm *fnm, int nfile, int *index, int *a, int nslices, nout = nslices*ngrps; read_first_frame(oenv, &status, ftp2fn(efTRX, nfile, fnm), &fr, TRX_NEED_X); - close_trj(status); + close_trx(status); frout = fr; frout.natoms = nout; frout.bF = FALSE; diff --git a/src/gromacs/gmxana/gmx_potential.cpp b/src/gromacs/gmxana/gmx_potential.cpp index 034ac993b8..277c035a88 100644 --- a/src/gromacs/gmxana/gmx_potential.cpp +++ b/src/gromacs/gmxana/gmx_potential.cpp @@ -228,7 +228,7 @@ void calc_potential(const char *fn, int **index, int gnx[], gmx_rmpbc_done(gpbc); /*********** done with status file **********/ - close_trj(status); + close_trx(status); /* slCharge now contains the total charge per slice, summed over all frames. Now divide by nr_frames and integrate twice diff --git a/src/gromacs/gmxana/gmx_principal.cpp b/src/gromacs/gmxana/gmx_principal.cpp index 149b228b6b..312aaa4991 100644 --- a/src/gromacs/gmxana/gmx_principal.cpp +++ b/src/gromacs/gmxana/gmx_principal.cpp @@ -179,7 +179,7 @@ int gmx_principal(int argc, char *argv[]) gmx_rmpbc_done(gpbc); - close_trj(status); + close_trx(status); xvgrclose(axis1); xvgrclose(axis2); diff --git a/src/gromacs/gmxana/gmx_rms.cpp b/src/gromacs/gmxana/gmx_rms.cpp index c80debaea8..a285a3abe4 100644 --- a/src/gromacs/gmxana/gmx_rms.cpp +++ b/src/gromacs/gmxana/gmx_rms.cpp @@ -722,7 +722,7 @@ int gmx_rms(int argc, char *argv[]) } } while (read_next_x(oenv, status, &t, x, box)); - close_trj(status); + close_trx(status); if (bFile2) { @@ -790,7 +790,7 @@ int gmx_rms(int argc, char *argv[]) } } while (read_next_x(oenv, status, &t, x, box)); - close_trj(status); + close_trx(status); } else { diff --git a/src/gromacs/gmxana/gmx_rmsdist.cpp b/src/gromacs/gmxana/gmx_rmsdist.cpp index f12bee4b17..4cf174ed51 100644 --- a/src/gromacs/gmxana/gmx_rmsdist.cpp +++ b/src/gromacs/gmxana/gmx_rmsdist.cpp @@ -806,7 +806,7 @@ int gmx_rmsdist(int argc, char *argv[]) xvgrclose(fp); - close_trj(status); + close_trx(status); calc_rms(isize, teller, dtot, dtot2, rms, &rmsmax, rmsc, &rmscmax, mean, &meanmax); fprintf(stderr, "rmsmax = %g, rmscmax = %g\n", rmsmax, rmscmax); diff --git a/src/gromacs/gmxana/gmx_rmsf.cpp b/src/gromacs/gmxana/gmx_rmsf.cpp index 6c78ce2165..354f092b02 100644 --- a/src/gromacs/gmxana/gmx_rmsf.cpp +++ b/src/gromacs/gmxana/gmx_rmsf.cpp @@ -400,7 +400,7 @@ int gmx_rmsf(int argc, char *argv[]) teller++; } while (read_next_x(oenv, status, &t, x, box)); - close_trj(status); + close_trx(status); if (bFit) { diff --git a/src/gromacs/gmxana/gmx_rotacf.cpp b/src/gromacs/gmxana/gmx_rotacf.cpp index c429143af5..771efcaf65 100644 --- a/src/gromacs/gmxana/gmx_rotacf.cpp +++ b/src/gromacs/gmxana/gmx_rotacf.cpp @@ -209,7 +209,7 @@ int gmx_rotacf(int argc, char *argv[]) teller++; } while (read_next_x(oenv, status, &t, x, box)); - close_trj(status); + close_trx(status); fprintf(stderr, "\nDone with trajectory\n"); gmx_rmpbc_done(gpbc); diff --git a/src/gromacs/gmxana/gmx_rotmat.cpp b/src/gromacs/gmxana/gmx_rotmat.cpp index a37b4781b1..ea5c2f4222 100644 --- a/src/gromacs/gmxana/gmx_rotmat.cpp +++ b/src/gromacs/gmxana/gmx_rotmat.cpp @@ -110,7 +110,7 @@ static void get_refx(gmx_output_env_t *oenv, const char *trxfn, int nfitdim, int nfr_all++; } while (read_next_x(oenv, status, &ti[nfr], x, box)); - close_trj(status); + close_trx(status); sfree(x); gmx_rmpbc_done(gpbc); @@ -307,7 +307,7 @@ int gmx_rotmat(int argc, char *argv[]) gmx_rmpbc_done(gpbc); - close_trj(status); + close_trx(status); xvgrclose(out); diff --git a/src/gromacs/gmxana/gmx_saltbr.cpp b/src/gromacs/gmxana/gmx_saltbr.cpp index b3e3333171..6fdd9c575c 100644 --- a/src/gromacs/gmxana/gmx_saltbr.cpp +++ b/src/gromacs/gmxana/gmx_saltbr.cpp @@ -226,7 +226,7 @@ int gmx_saltbr(int argc, char *argv[]) } while (read_next_x(oenv, status, &t, x, box)); fprintf(stderr, "\n"); - close_trj(status); + close_trx(status); if (bSep) { diff --git a/src/gromacs/gmxana/gmx_sans.cpp b/src/gromacs/gmxana/gmx_sans.cpp index 93a8fa4cd2..b9b608dbb9 100644 --- a/src/gromacs/gmxana/gmx_sans.cpp +++ b/src/gromacs/gmxana/gmx_sans.cpp @@ -342,7 +342,7 @@ int gmx_sans(int argc, char *argv[]) sfree(sqframecurrent); } while (read_next_x(oenv, status, &t, x, box)); - close_trj(status); + close_trx(status); /* normalize histo */ normalize_probability(pr->grn, pr->gr); diff --git a/src/gromacs/gmxana/gmx_sorient.cpp b/src/gromacs/gmxana/gmx_sorient.cpp index 757d9e0c8f..90f440c5d4 100644 --- a/src/gromacs/gmxana/gmx_sorient.cpp +++ b/src/gromacs/gmxana/gmx_sorient.cpp @@ -368,7 +368,7 @@ int gmx_sorient(int argc, char *argv[]) /* clean up */ sfree(x); - close_trj(status); + close_trx(status); gmx_rmpbc_done(gpbc); /* Add the bin for the exact maximum to the previous bin */ diff --git a/src/gromacs/gmxana/gmx_spol.cpp b/src/gromacs/gmxana/gmx_spol.cpp index 25a78c08ae..d166e44d2d 100644 --- a/src/gromacs/gmxana/gmx_spol.cpp +++ b/src/gromacs/gmxana/gmx_spol.cpp @@ -360,7 +360,7 @@ int gmx_spol(int argc, char *argv[]) /* clean up */ sfree(x); - close_trj(status); + close_trx(status); fprintf(stderr, "Average number of molecules within %g nm is %.1f\n", rmax, static_cast(ntot)/nf); diff --git a/src/gromacs/gmxana/gmx_tcaf.cpp b/src/gromacs/gmxana/gmx_tcaf.cpp index 140be7d22c..940a51c9ff 100644 --- a/src/gromacs/gmxana/gmx_tcaf.cpp +++ b/src/gromacs/gmxana/gmx_tcaf.cpp @@ -480,7 +480,7 @@ int gmx_tcaf(int argc, char *argv[]) nframes++; } while (read_next_frame(oenv, status, &fr)); - close_trj(status); + close_trx(status); dt = (t1-t0)/(nframes-1); diff --git a/src/gromacs/gmxana/gmx_traj.cpp b/src/gromacs/gmxana/gmx_traj.cpp index 445f8148be..2bddf5dcb9 100644 --- a/src/gromacs/gmxana/gmx_traj.cpp +++ b/src/gromacs/gmxana/gmx_traj.cpp @@ -41,6 +41,7 @@ #include #include +#include #include "gromacs/commandline/pargs.h" #include "gromacs/commandline/viewit.h" @@ -818,12 +819,13 @@ int gmx_traj(int argc, char *argv[]) } flags = 0; + std::string label(output_env_get_xvgr_tlabel(oenv)); if (bOX) { flags = flags | TRX_READ_X; outx = xvgropen(opt2fn("-ox", NFILE, fnm), bCom ? "Center of mass" : "Coordinate", - output_env_get_xvgr_tlabel(oenv), "Coordinate (nm)", oenv); + label, "Coordinate (nm)", oenv); make_legend(outx, ngroups, isize0[0], index0[0], grpname, bCom, bMol, bDim, oenv); } if (bOXT) @@ -836,21 +838,21 @@ int gmx_traj(int argc, char *argv[]) flags = flags | TRX_READ_V; outv = xvgropen(opt2fn("-ov", NFILE, fnm), bCom ? "Center of mass velocity" : "Velocity", - output_env_get_xvgr_tlabel(oenv), "Velocity (nm/ps)", oenv); + label, "Velocity (nm/ps)", oenv); make_legend(outv, ngroups, isize0[0], index0[0], grpname, bCom, bMol, bDim, oenv); } if (bOF) { flags = flags | TRX_READ_F; outf = xvgropen(opt2fn("-of", NFILE, fnm), "Force", - output_env_get_xvgr_tlabel(oenv), "Force (kJ mol\\S-1\\N nm\\S-1\\N)", + label, "Force (kJ mol\\S-1\\N nm\\S-1\\N)", oenv); make_legend(outf, ngroups, isize0[0], index0[0], grpname, bCom, bMol, bDim, oenv); } if (bOB) { outb = xvgropen(opt2fn("-ob", NFILE, fnm), "Box vector elements", - output_env_get_xvgr_tlabel(oenv), "(nm)", oenv); + label, "(nm)", oenv); xvgr_legend(outb, 6, box_leg, oenv); } @@ -862,7 +864,7 @@ int gmx_traj(int argc, char *argv[]) bDum[DIM] = TRUE; flags = flags | TRX_READ_V; outt = xvgropen(opt2fn("-ot", NFILE, fnm), "Temperature", - output_env_get_xvgr_tlabel(oenv), "(K)", oenv); + label, "(K)", oenv); make_legend(outt, ngroups, isize[0], index[0], grpname, bCom, bMol, bDum, oenv); } if (bEKT) @@ -873,7 +875,7 @@ int gmx_traj(int argc, char *argv[]) bDum[DIM] = TRUE; flags = flags | TRX_READ_V; outekt = xvgropen(opt2fn("-ekt", NFILE, fnm), "Center of mass translation", - output_env_get_xvgr_tlabel(oenv), "Energy (kJ mol\\S-1\\N)", oenv); + label, "Energy (kJ mol\\S-1\\N)", oenv); make_legend(outekt, ngroups, isize[0], index[0], grpname, bCom, bMol, bDum, oenv); } if (bEKR) @@ -884,7 +886,7 @@ int gmx_traj(int argc, char *argv[]) bDum[DIM] = TRUE; flags = flags | TRX_READ_X | TRX_READ_V; outekr = xvgropen(opt2fn("-ekr", NFILE, fnm), "Center of mass rotation", - output_env_get_xvgr_tlabel(oenv), "Energy (kJ mol\\S-1\\N)", oenv); + label, "Energy (kJ mol\\S-1\\N)", oenv); make_legend(outekr, ngroups, isize[0], index[0], grpname, bCom, bMol, bDum, oenv); } if (bVD) @@ -1059,7 +1061,7 @@ int gmx_traj(int argc, char *argv[]) } /* clean up a bit */ - close_trj(status); + close_trx(status); if (bOX) { @@ -1136,5 +1138,28 @@ int gmx_traj(int argc, char *argv[]) /* view it */ view_all(oenv, NFILE, fnm); + done_top(&top); + // Free index and isize only if they are distinct from index0 and isize0 + if (bMol) + { + for (int i = 0; i < ngroups; i++) + { + sfree(index[i]); + } + sfree(index); + sfree(isize); + } + for (int i = 0; i < ngroups; i++) + { + sfree(index0[i]); + sfree(grpname[i]); + } + sfree(index0); + sfree(isize0); + sfree(grpname); + done_filenms(NFILE, fnm); + done_frame(&fr); + output_env_done(oenv); + return 0; } diff --git a/src/gromacs/gmxana/gmx_trjcat.cpp b/src/gromacs/gmxana/gmx_trjcat.cpp index 9c951195db..950c87fee7 100644 --- a/src/gromacs/gmxana/gmx_trjcat.cpp +++ b/src/gromacs/gmxana/gmx_trjcat.cpp @@ -130,7 +130,7 @@ static void scan_trj_files(char **fnms, int nfiles, real *readtime, timestep[i] = 0; } - close_trj(status); + close_trx(status); if (fr.bX) { sfree(fr.x); @@ -702,7 +702,7 @@ int gmx_trjcat(int argc, char *argv[]) } lastTimeSet = TRUE; bKeepLastAppend = TRUE; - close_trj(status); + close_trx(status); trxout = open_trx(out_file, "a"); } else if (bOverwrite) @@ -738,7 +738,7 @@ int gmx_trjcat(int argc, char *argv[]) lasttime = fr.time; lastTimeSet = TRUE; fpos = gmx_fio_ftell(stfio); - close_trj(status); + close_trx(status); trxout = open_trx(out_file, "r+"); if (gmx_fio_seek(trx_get_fileio(trxout), fpos)) { @@ -914,7 +914,7 @@ int gmx_trjcat(int argc, char *argv[]) } while (read_next_frame(oenv, status, &fr)); - close_trj(status); + close_trx(status); } if (trxout) { diff --git a/src/gromacs/gmxana/gmx_trjconv.cpp b/src/gromacs/gmxana/gmx_trjconv.cpp index 41f5ab8915..45d8686b89 100644 --- a/src/gromacs/gmxana/gmx_trjconv.cpp +++ b/src/gromacs/gmxana/gmx_trjconv.cpp @@ -871,8 +871,8 @@ int gmx_trjconv(int argc, char *argv[]) int ePBC = -1; t_atoms *atoms = nullptr, useatoms; matrix top_box; - int *index, *cindex; - char *grpnm; + int *index = nullptr, *cindex = nullptr; + char *grpnm = nullptr; int *frindex, nrfri; char *frname; int ifit, my_clust = -1; @@ -923,7 +923,6 @@ int gmx_trjconv(int argc, char *argv[]) } top_file = ftp2fn(efTPS, NFILE, fnm); - init_top(&top); /* Check command line */ in_file = opt2fn("-f", NFILE, fnm); @@ -1181,7 +1180,7 @@ int gmx_trjconv(int argc, char *argv[]) gmx_fatal(FARGS, "Could not read a frame from %s", in_file); } natoms = fr.natoms; - close_trj(trxin); + close_trx(trxin); sfree(fr.x); snew(index, natoms); for (i = 0; i < natoms; i++) @@ -1831,10 +1830,10 @@ int gmx_trjconv(int argc, char *argv[]) frout.ePBC, frout.box, ' ', model_nr, gc, TRUE); break; case efG96: - frout.title = title; + const char *outputTitle = ""; if (bSeparate || bTDump) { - frout.bTitle = TRUE; + outputTitle = title; if (bTPS) { frout.bAtoms = TRUE; @@ -1845,12 +1844,15 @@ int gmx_trjconv(int argc, char *argv[]) } else { - frout.bTitle = (outframe == 0); + if (outframe == 0) + { + outputTitle = title; + } frout.bAtoms = FALSE; frout.bStep = TRUE; frout.bTime = TRUE; } - write_g96_conf(out, &frout, -1, nullptr); + write_g96_conf(out, outputTitle, &frout, -1, nullptr); } if (bSeparate || bSplitHere) { @@ -1893,7 +1895,7 @@ int gmx_trjconv(int argc, char *argv[]) } fprintf(stderr, "\n"); - close_trj(trxin); + close_trx(trxin); sfree(outf_base); if (bRmPBC) @@ -1922,8 +1924,19 @@ int gmx_trjconv(int argc, char *argv[]) } sfree(mtop); + done_top(&top); + sfree(xp); + sfree(xmem); + sfree(vmem); + sfree(fmem); + sfree(grpnm); + sfree(index); + sfree(cindex); + done_filenms(NFILE, fnm); + done_frame(&fr); do_view(oenv, out_file, nullptr); + output_env_done(oenv); return 0; } diff --git a/src/gromacs/gmxana/gmx_trjorder.cpp b/src/gromacs/gmxana/gmx_trjorder.cpp index 9f1bd408ed..59d25fcee7 100644 --- a/src/gromacs/gmxana/gmx_trjorder.cpp +++ b/src/gromacs/gmxana/gmx_trjorder.cpp @@ -366,7 +366,7 @@ int gmx_trjorder(int argc, char *argv[]) } } while (read_next_x(oenv, status, &t, x, box)); - close_trj(status); + close_trx(status); if (out) { close_trx(out); diff --git a/src/gromacs/gmxana/gmx_vanhove.cpp b/src/gromacs/gmxana/gmx_vanhove.cpp index 5d7b248a78..dcd2374122 100644 --- a/src/gromacs/gmxana/gmx_vanhove.cpp +++ b/src/gromacs/gmxana/gmx_vanhove.cpp @@ -223,7 +223,7 @@ int gmx_vanhove(int argc, char *argv[]) /* clean up */ sfree(x); - close_trj(status); + close_trx(status); fprintf(stderr, "Read %d frames\n", nfr); diff --git a/src/gromacs/gmxana/gmx_velacc.cpp b/src/gromacs/gmxana/gmx_velacc.cpp index 1b0c0f41f8..902b9617cf 100644 --- a/src/gromacs/gmxana/gmx_velacc.cpp +++ b/src/gromacs/gmxana/gmx_velacc.cpp @@ -343,7 +343,7 @@ int gmx_velacc(int argc, char *argv[]) } while (read_next_frame(oenv, status, &fr)); - close_trj(status); + close_trx(status); if (counter >= 4) { diff --git a/src/gromacs/gmxpreprocess/genconf.cpp b/src/gromacs/gmxpreprocess/genconf.cpp index e652b34dc1..6c64e16ad1 100644 --- a/src/gromacs/gmxpreprocess/genconf.cpp +++ b/src/gromacs/gmxpreprocess/genconf.cpp @@ -284,7 +284,7 @@ int gmx_genconf(int argc, char *argv[]) } if (bTRX) { - close_trj(status); + close_trx(status); } /* make box bigger */ diff --git a/src/gromacs/gmxpreprocess/grompp.cpp b/src/gromacs/gmxpreprocess/grompp.cpp index 6c37eb71f1..b9916e5f86 100644 --- a/src/gromacs/gmxpreprocess/grompp.cpp +++ b/src/gromacs/gmxpreprocess/grompp.cpp @@ -787,7 +787,7 @@ static void cont_status(const char *slog, const char *ener, { clear_rvec(state->v[i]); } - close_trj(fp); + close_trx(fp); /* Search for a frame without velocities */ bReadVel = FALSE; read_first_frame(oenv, &fp, slog, &fr, TRX_NEED_X); @@ -810,7 +810,7 @@ static void cont_status(const char *slog, const char *ener, copy_state(slog, &fr, bReadVel, state, &use_time); } - close_trj(fp); + close_trx(fp); /* Set the relative box lengths for preserving the box shape. * Note that this call can lead to differences in the last bit diff --git a/src/gromacs/mdlib/tpi.cpp b/src/gromacs/mdlib/tpi.cpp index bd738cf8fe..ffe16be00d 100644 --- a/src/gromacs/mdlib/tpi.cpp +++ b/src/gromacs/mdlib/tpi.cpp @@ -839,7 +839,7 @@ double do_tpi(FILE *fplog, t_commrec *cr, const gmx::MDLogger gmx_unused &mdlog, } /* End of the loop */ walltime_accounting_end(walltime_accounting); - close_trj(status); + close_trx(status); if (fp_tpi != nullptr) { diff --git a/src/gromacs/tools/check.cpp b/src/gromacs/tools/check.cpp index 9751122e10..6b665a79a7 100644 --- a/src/gromacs/tools/check.cpp +++ b/src/gromacs/tools/check.cpp @@ -177,7 +177,7 @@ static void comp_trx(const gmx_output_env_t *oenv, const char *fn1, const char * { fprintf(stdout, "\nEnd of file on %s but not on %s\n", fn[1-i], fn[i]); } - close_trj(status[i]); + close_trx(status[i]); } } if (!b[0] && !b[1]) @@ -494,7 +494,7 @@ void chk_trj(const gmx_output_env_t *oenv, const char *fn, const char *tpr, real fprintf(stderr, "\n"); - close_trj(status); + close_trx(status); fprintf(stderr, "\nItem #frames"); if (bShowTimestep) diff --git a/src/gromacs/topology/index.cpp b/src/gromacs/topology/index.cpp index 2f5255e34e..4db21b8e1a 100644 --- a/src/gromacs/topology/index.cpp +++ b/src/gromacs/topology/index.cpp @@ -1009,21 +1009,6 @@ void rd_index(const char *statfile, int ngrps, int isize[], sfree(grps); } -void rd_index_nrs(char *statfile, int ngrps, int isize[], - int *index[], char *grpnames[], int grpnr[]) -{ - char **gnames; - t_blocka *grps; - - if (!statfile) - { - gmx_fatal(FARGS, "No index file specified"); - } - grps = init_index(statfile, &gnames); - - rd_groups(grps, gnames, grpnames, ngrps, isize, index, grpnr); -} - void get_index(const t_atoms *atoms, const char *fnm, int ngrps, int isize[], int *index[], char *grpnames[]) { @@ -1049,6 +1034,15 @@ void get_index(const t_atoms *atoms, const char *fnm, int ngrps, } rd_groups(grps, *gnames, grpnames, ngrps, isize, index, grpnr); + for (int i = 0; i < grps->nr; ++i) + { + sfree((*gnames)[i]); + } + sfree(*gnames); + sfree(gnames); + sfree(grpnr); + done_blocka(grps); + sfree(grps); } t_cluster_ndx *cluster_index(FILE *fplog, const char *ndx) diff --git a/src/gromacs/topology/index.h b/src/gromacs/topology/index.h index f22ca9084e..504b6c4deb 100644 --- a/src/gromacs/topology/index.h +++ b/src/gromacs/topology/index.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2016,2017, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -75,10 +75,6 @@ void rd_index(const char *statfile, int ngrps, int isize[], * the dimension of the isize and grpnames arrays are ngrps. */ -void rd_index_nrs(char *statfile, int ngrps, int isize[], - int *index[], char *grpnames[], int grpnr[]); -/* the same but also reads the number of the selected group*/ - void get_index(const t_atoms *atoms, const char *fnm, int ngrps, int isize[], int *index[], char *grpnames[]); /* Does the same as rd_index, but if the fnm pointer is NULL it diff --git a/src/gromacs/topology/symtab.h b/src/gromacs/topology/symtab.h index d395e58c5f..40213d9a5b 100644 --- a/src/gromacs/topology/symtab.h +++ b/src/gromacs/topology/symtab.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2017, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -75,6 +75,8 @@ void close_symtab(t_symtab *symtab); /* Undoes the effect of open_symtab(), after invoking this function, * no value can be added to the symbol table, only values can be * retrieved using get_symtab(). + * + * Note that this does no work. */ void free_symtab(t_symtab *symtab); diff --git a/src/gromacs/trajectory/trajectoryframe.cpp b/src/gromacs/trajectory/trajectoryframe.cpp index 1abda4ee3f..7508d1c7f4 100644 --- a/src/gromacs/trajectory/trajectoryframe.cpp +++ b/src/gromacs/trajectory/trajectoryframe.cpp @@ -51,10 +51,6 @@ void comp_frame(FILE *fp, t_trxframe *fr1, t_trxframe *fr2, fprintf(fp, "\n"); cmp_int(fp, "not_ok", -1, fr1->not_ok, fr2->not_ok); cmp_int(fp, "natoms", -1, fr1->natoms, fr2->natoms); - if (cmp_bool(fp, "bTitle", -1, fr1->bTitle, fr2->bTitle)) - { - cmp_str(fp, "title", -1, fr1->title, fr2->title); - } if (cmp_bool(fp, "bStep", -1, fr1->bStep, fr2->bStep)) { cmp_int(fp, "step", -1, fr1->step, fr2->step); diff --git a/src/gromacs/trajectory/trajectoryframe.h b/src/gromacs/trajectory/trajectoryframe.h index 2c8e34798a..3901eaaef7 100644 --- a/src/gromacs/trajectory/trajectoryframe.h +++ b/src/gromacs/trajectory/trajectoryframe.h @@ -55,8 +55,6 @@ typedef struct t_trxframe int not_ok; /* integrity flags */ gmx_bool bDouble; /* Double precision? */ int natoms; /* number of atoms (atoms, x, v, f, index) */ - gmx_bool bTitle; - const char *title; /* title of the frame */ gmx_bool bStep; gmx_int64_t step; /* MD step number */ gmx_bool bTime; diff --git a/src/gromacs/utility/unique_cptr.h b/src/gromacs/utility/unique_cptr.h index 058abfa124..b98d0b4e6b 100644 --- a/src/gromacs/utility/unique_cptr.h +++ b/src/gromacs/utility/unique_cptr.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2016,2017, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,6 +43,8 @@ #ifndef GMX_UTILITY_UNIQUE_PTR_SFREE_H #define GMX_UTILITY_UNIQUE_PTR_SFREE_H +#include + #include #include "gromacs/utility/smalloc.h" @@ -50,6 +52,15 @@ namespace gmx { +/*! \brief Wrapper of standard library free(), to be used as + * unique_cptr deleter for memory allocated by malloc, e.g. by an + * external library such as TNG. */ +template +inline void free_wrapper(T *p) +{ + free(p); +} + //! sfree wrapper to be used as unique_cptr deleter template inline void sfree_wrapper(T *p) diff --git a/src/programs/mdrun/md.cpp b/src/programs/mdrun/md.cpp index 0a52bbe301..39c743eb99 100644 --- a/src/programs/mdrun/md.cpp +++ b/src/programs/mdrun/md.cpp @@ -1807,7 +1807,7 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, const gmx::MDLogger &mdlog, if (bRerunMD && MASTER(cr)) { - close_trj(status); + close_trx(status); } if (!(cr->duty & DUTY_PME)) -- 2.11.4.GIT