From d2bb0c11fe58bdc6dd88f7688c5d449f5022a384 Mon Sep 17 00:00:00 2001 From: Eliane Briand Date: Mon, 1 Nov 2021 13:42:21 +0000 Subject: [PATCH] Add DSSP v4 support to do_dssp --- api/legacy/include/gromacs/fileio/pdbio.h | 3 +- docs/linkcheckerrc | 2 -- docs/release-notes/2022/major/tools.rst | 9 +++++ src/gromacs/fileio/pdbio.cpp | 43 +++++++++++++++++++++-- src/gromacs/gmxana/gmx_do_dssp.cpp | 39 ++++++++++++++------ 5 files changed, 79 insertions(+), 17 deletions(-) diff --git a/api/legacy/include/gromacs/fileio/pdbio.h b/api/legacy/include/gromacs/fileio/pdbio.h index c34562e095..87da7ead73 100644 --- a/api/legacy/include/gromacs/fileio/pdbio.h +++ b/api/legacy/include/gromacs/fileio/pdbio.h @@ -107,7 +107,8 @@ void write_pdbfile_indexed(FILE* out, int nindex, const int index[], gmx_conect conect, - bool usePqrFormat); + bool usePqrFormat, + bool standardCompliantMode = false); /* REALLY low level */ void write_pdbfile(FILE* out, diff --git a/docs/linkcheckerrc b/docs/linkcheckerrc index 5d9755753a..dd6d9a0446 100644 --- a/docs/linkcheckerrc +++ b/docs/linkcheckerrc @@ -6,5 +6,3 @@ ignore= # This site gives warnings about URLs if you try to refer to page.html\#heading cmake.org -# This site gives warnings because it redirects to itself - http://swift.cmbi.ru.nl/gv/dssp diff --git a/docs/release-notes/2022/major/tools.rst b/docs/release-notes/2022/major/tools.rst index b1612a9822..882df1162f 100644 --- a/docs/release-notes/2022/major/tools.rst +++ b/docs/release-notes/2022/major/tools.rst @@ -44,3 +44,12 @@ removed, because it served no purpose. This makes ``gmx chi`` easier to use. Reporting about file handling and input-file column contents are easier to follow. + +``gmx do_dssp`` supports DSSP version 4 +""""""""""""""""""""""""""""""""""""""" + +The newer DSSP version 4 program can be used by ``do_dssp`` by specifying +option ``-ver 4`` and setting the DSSP environement variable to the ``mkdssp`` +executable path (e.g. ``setenv DSSP /opt/dssp/mkdssp``) + +:issue:`4129` diff --git a/src/gromacs/fileio/pdbio.cpp b/src/gromacs/fileio/pdbio.cpp index 07de14f92c..c3c3995039 100644 --- a/src/gromacs/fileio/pdbio.cpp +++ b/src/gromacs/fileio/pdbio.cpp @@ -296,7 +296,8 @@ void write_pdbfile_indexed(FILE* out, int nindex, const int index[], gmx_conect conect, - bool usePqrFormat) + bool usePqrFormat, + bool standardCompliantMode) { gmx_conect_t* gc = static_cast(conect); PdbRecordType type; @@ -304,8 +305,27 @@ void write_pdbfile_indexed(FILE* out, real occup, bfac; gmx_bool bOccup; + if (standardCompliantMode) + { + fprintf(out, "HEADER GROMACS SIMULATION BOX 01-JAN-00 0000\n"); + fprintf(out, + "TITLE Gromacs simulation box\n" + "COMPND MOL_ID: 1; \n" + "COMPND 2 MOLECULE: GROMACS SIMULATION BOX; \n" + "COMPND 3 CHAIN: A; \n" + "SOURCE MOL_ID: 1;\n" + "SOURCE 2 SYNTHETIC\n" + "KEYWDS GROMACS\n" + "EXPDTA PURE PRODUCT OF COMPUTER SIMULATION\n" + "AUTHOR GROMACS\n" + "REVDAT 1 01-JAN-00 0000 0\n"); + } + else + { + fprintf(out, "TITLE %s\n", (title && title[0]) ? title : gmx::bromacs().c_str()); + } + - fprintf(out, "TITLE %s\n", (title && title[0]) ? title : gmx::bromacs().c_str()); if (box && ((norm2(box[XX]) != 0.0F) || (norm2(box[YY]) != 0.0F) || (norm2(box[ZZ]) != 0.0F))) { gmx_write_pdb_box(out, pbcType, box); @@ -329,6 +349,11 @@ void write_pdbfile_indexed(FILE* out, fprintf(out, "MODEL %8d\n", model_nr > 0 ? model_nr : 1); + // Collect last printed values for TER record + int lastAtomNumber = 0; + std::string lastResName; + int lastResNr = 0; + for (int ii = 0; ii < nindex; ii++) { int i = index[ii]; @@ -391,6 +416,10 @@ void write_pdbfile_indexed(FILE* out, bfac, atoms->atom[i].elem); + lastAtomNumber = i + 1; + lastResName = resnm; + lastResNr = resnr; + if (atoms->pdbinfo && atoms->pdbinfo[i].bAnisotropic) { fprintf(out, @@ -426,7 +455,15 @@ void write_pdbfile_indexed(FILE* out, } } - fprintf(out, "TER\n"); + if (standardCompliantMode) + { + fprintf(out, "TER %5d %4.4s%c%4d\n", lastAtomNumber, lastResName.c_str(), chainid, lastResNr); + } + else + { + fprintf(out, "TER\n"); + } + fprintf(out, "ENDMDL\n"); if (nullptr != gc) diff --git a/src/gromacs/gmxana/gmx_do_dssp.cpp b/src/gromacs/gmxana/gmx_do_dssp.cpp index 36fb601e93..f88a65c567 100644 --- a/src/gromacs/gmxana/gmx_do_dssp.cpp +++ b/src/gromacs/gmxana/gmx_do_dssp.cpp @@ -485,15 +485,15 @@ int gmx_do_dssp(int argc, char* argv[]) "that the dssp executable is located in ", // NOLINTNEXTLINE(bugprone-suspicious-missing-comma) "[TT]" GMX_DSSP_PROGRAM_PATH "[tt]. If this is not the case, then you should", - "set an environment variable [TT]DSSP[tt] pointing to the dssp", + "set an environment variable [TT]DSSP[tt] pointing to the dssp ", "executable, e.g.: [PAR]", "[TT]setenv DSSP /opt/dssp/bin/dssp[tt][PAR]", - "Since version 2.0.0, dssp is invoked with a syntax that differs", - "from earlier versions. If you have an older version of dssp,", - "use the [TT]-ver[tt] option to direct do_dssp to use the older syntax.", + "The dssp program is invoked with a syntax that differs", + "depending on version. Version 1, 2 and 4 are supported, and the correct", + "invocation format can be selected using the [TT]-ver[tt] option.", "By default, do_dssp uses the syntax introduced with version 2.0.0.", - "Even newer versions (which at the time of writing are not yet released)", - "are assumed to have the same syntax as 2.0.0.[PAR]", + "Newer versions might also have executable name [TT]mkdssp[tt] instead", + "of [TT]dssp[tt].[PAR]", "The structure assignment for each residue and time is written to an", "[REF].xpm[ref] matrix file. This file can be visualized with for instance", "[TT]xv[tt] and can be converted to postscript with [TT]xpm2ps[tt].", @@ -523,7 +523,7 @@ int gmx_do_dssp(int argc, char* argv[]) FALSE, etINT, { &dsspVersion }, - "DSSP major version. Syntax changed with version 2" } + "DSSP major version. Syntax changed with version 2 and 4." } }; t_trxstatus* status; @@ -643,14 +643,30 @@ int gmx_do_dssp(int argc, char* argv[]) dsspStrings.tmpfile = tmpfile; if (dsspVersion >= 2) { - if (dsspVersion > 2) + if (dsspVersion == 4) + { + std::string mkdsspCommandLine = dsspStrings.dptr; + mkdsspCommandLine += " --output-format dssp "; + mkdsspCommandLine += dsspStrings.pdbfile; + +#if not HAVE_PIPES && not GMX_NATIVE_WINDOWS + // Without pipe/popen, rely on temporary file for output + mkdsspCommandLine += " " + dsspStrings.tmpfile; +#endif + + GMX_RELEASE_ASSERT(mkdsspCommandLine.size() < 255, "DSSP v4 command line too long"); + strcpy(dssp, mkdsspCommandLine.c_str()); + } + else if (dsspVersion == 2) + { + printDsspResult(dssp, dsspStrings, redirectionString); + } + else { printf("\nWARNING: You use DSSP version %d, which is not explicitly\nsupported by " "do_dssp. Assuming version 2 syntax.\n\n", dsspVersion); } - - printDsspResult(dssp, dsspStrings, redirectionString); } else { @@ -713,7 +729,8 @@ int gmx_do_dssp(int argc, char* argv[]) } gmx_rmpbc(gpbc, natoms, box, x); tapein = gmx_ffopen(pdbfile, "w"); - write_pdbfile_indexed(tapein, nullptr, atoms, x, pbcType, box, ' ', -1, gnx, index, nullptr, FALSE); + write_pdbfile_indexed( + tapein, nullptr, atoms, x, pbcType, box, 'A', -1, gnx, index, nullptr, FALSE, true); gmx_ffclose(tapein); /* strip_dssp returns the number of lines found in the dssp file, i.e. * the number of residues plus the separator lines */ -- 2.22.0