Convert gmx-sas to the C++ framework
authorTeemu Murtola <teemu.murtola@gmail.com>
Sat, 26 Oct 2013 05:25:28 +0000 (08:25 +0300)
committerRoland Schulz <roland@rschulz.eu>
Fri, 28 Feb 2014 01:26:02 +0000 (02:26 +0100)
An example of converting a non-trivial analysis tool to the new
framework.  Most functionality is intact, but the command-line interface
is changed a bit.  Changes in behavior:
 - Writing a position restraint file is not implemented.  Would not be
   very difficult to add.
 - Solvation free energy estimates are written into a separate file
   instead of the main output file, and only if requested with an -odg
   option.
 - The calculation group is specified as a selection with -surface.
   Can be a dynamic selection.  The total area of this group is always
   written out.
 - There can be 0..* extra output groups, specified as selections with
   -output.  All can be dynamic, and must always be a subset of the
   calculation group.
 - There is no longer a separate concept of hydrophilic and hydrophobic
   surface area.  The user can trivially calculate such things by
   providing two different output groups.  The old hydrophobicity
   definition is easily expressed as "... and charge {-0.2 to 0.2}".
 - tpr file is no longer required for most of the output.
 - Output precision is different from the old tool.  The current
   precision (fixed to three decimal places) should be sufficient for
   most uses, but it could be considered to use %g for formatting like
   the old tool if really necessary.

Future TODOs:
 - Consider if the legends on the plots could be improved.
 - Add unit tests for the actual surface area calculation routine.

Part of #665.

Change-Id: Iee60c13b927b3b63b6e218164cd961971f2f3fce

18 files changed:
cmake/legacy_and_external.supp
src/gromacs/gmxana/gmx_ana.h
src/gromacs/gmxana/gmx_sas.c [deleted file]
src/gromacs/selection/selection.h
src/gromacs/trajectoryanalysis/CMakeLists.txt
src/gromacs/trajectoryanalysis/modules.cpp
src/gromacs/trajectoryanalysis/modules/nsc.c [moved from src/gromacs/gmxana/nsc.c with 97% similarity]
src/gromacs/trajectoryanalysis/modules/nsc.h [moved from src/gromacs/gmxana/nsc.h with 91% similarity]
src/gromacs/trajectoryanalysis/modules/sasa.cpp [new file with mode: 0644]
src/gromacs/trajectoryanalysis/modules/sasa.h [new file with mode: 0644]
src/gromacs/trajectoryanalysis/tests/CMakeLists.txt
src/gromacs/trajectoryanalysis/tests/lysozyme.gro [new file with mode: 0644]
src/gromacs/trajectoryanalysis/tests/refdata/SasaModuleTest_BasicTest.xml [new file with mode: 0644]
src/gromacs/trajectoryanalysis/tests/refdata/SasaModuleTest_HandlesDynamicCalculationGroup.xml [new file with mode: 0644]
src/gromacs/trajectoryanalysis/tests/refdata/SasaModuleTest_HandlesDynamicOutputGroup.xml [new file with mode: 0644]
src/gromacs/trajectoryanalysis/tests/refdata/SasaModuleTest_WritesConnollySurfaceWithSolute.xml [new file with mode: 0644]
src/gromacs/trajectoryanalysis/tests/sasa.cpp [new file with mode: 0644]
src/programs/legacymodules.cpp

index 97faf162b1d05390d47eb2868ed408323c1a9670..8f88b86d435d1e5387fdfb84c09fa48331805054 100644 (file)
@@ -3,6 +3,25 @@
 # Memory leaks in the legacy code are excluded
 # Other problems besides memory leaks should NOT be excluded for legacy code
 
+# Ugly memory leak that depends on global variables being used to pass
+# information between routines.
+{
+   nsc_dclm_pbc
+   Memcheck:Leak
+   fun:calloc
+   fun:save_calloc
+   fun:ico_dot_dod
+   fun:make_unsp
+   fun:nsc_dclm_pbc
+}
+
+{
+   ctime_r
+   Memcheck:Leak
+   ...
+   fun:ctime_r
+}
+
 {
    libz
    Memcheck:Cond
index 841151f5278ecf2ec98c63f6d4c32159ca08d2fa..aebec12c4a3ab6ac7625482d3ee7542674e62b1d 100644 (file)
@@ -216,9 +216,6 @@ gmx_rotacf(int argc, char *argv[]);
 int
 gmx_saltbr(int argc, char *argv[]);
 
-int
-gmx_sas(int argc, char *argv[]);
-
 int
 gmx_sham(int argc, char *argv[]);
 
diff --git a/src/gromacs/gmxana/gmx_sas.c b/src/gromacs/gmxana/gmx_sas.c
deleted file mode 100644 (file)
index 64d0cfc..0000000
+++ /dev/null
@@ -1,788 +0,0 @@
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2007, The GROMACS development team.
- * Copyright (c) 2013,2014, 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.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <math.h>
-#include <stdlib.h>
-
-#include "sysstuff.h"
-#include <string.h>
-#include "typedefs.h"
-#include "smalloc.h"
-#include "macros.h"
-#include "vec.h"
-#include "xvgr.h"
-#include "pbc.h"
-#include "copyrite.h"
-#include "gromacs/fileio/futil.h"
-#include "gromacs/commandline/pargs.h"
-#include "index.h"
-#include "nsc.h"
-#include "gromacs/fileio/pdbio.h"
-#include "gromacs/fileio/confio.h"
-#include "rmpbc.h"
-#include "names.h"
-#include "atomprop.h"
-#include "physics.h"
-#include "gromacs/fileio/tpxio.h"
-#include "gromacs/fileio/trxio.h"
-#include "gmx_ana.h"
-
-
-typedef struct {
-    atom_id  aa, ab;
-    real     d2a, d2b;
-} t_conect;
-
-void add_rec(t_conect c[], atom_id i, atom_id j, real d2)
-{
-    if (c[i].aa == NO_ATID)
-    {
-        c[i].aa  = j;
-        c[i].d2a = d2;
-    }
-    else if (c[i].ab == NO_ATID)
-    {
-        c[i].ab  = j;
-        c[i].d2b = d2;
-    }
-    else if (d2 < c[i].d2a)
-    {
-        c[i].aa  = j;
-        c[i].d2a = d2;
-    }
-    else if (d2 < c[i].d2b)
-    {
-        c[i].ab  = j;
-        c[i].d2b = d2;
-    }
-    /* Swap them if necessary: a must be larger than b */
-    if (c[i].d2a < c[i].d2b)
-    {
-        j        = c[i].ab;
-        c[i].ab  = c[i].aa;
-        c[i].aa  = j;
-        d2       = c[i].d2b;
-        c[i].d2b = c[i].d2a;
-        c[i].d2a = d2;
-    }
-}
-
-void do_conect(const char *fn, int n, rvec x[])
-{
-    FILE     *fp;
-    int       i, j;
-    t_conect *c;
-    rvec      dx;
-    real      d2;
-
-    fprintf(stderr, "Building CONECT records\n");
-    snew(c, n);
-    for (i = 0; (i < n); i++)
-    {
-        c[i].aa = c[i].ab = NO_ATID;
-    }
-
-    for (i = 0; (i < n); i++)
-    {
-        for (j = i+1; (j < n); j++)
-        {
-            rvec_sub(x[i], x[j], dx);
-            d2 = iprod(dx, dx);
-            add_rec(c, i, j, d2);
-            add_rec(c, j, i, d2);
-        }
-    }
-    fp = gmx_ffopen(fn, "a");
-    for (i = 0; (i < n); i++)
-    {
-        if ((c[i].aa == NO_ATID) || (c[i].ab == NO_ATID))
-        {
-            fprintf(stderr, "Warning dot %d has no conections\n", i+1);
-        }
-        fprintf(fp, "CONECT%5d%5d%5d\n", i+1, c[i].aa+1, c[i].ab+1);
-    }
-    gmx_ffclose(fp);
-    sfree(c);
-}
-
-void connelly_plot(const char *fn, int ndots, real dots[], rvec x[], t_atoms *atoms,
-                   t_symtab *symtab, int ePBC, matrix box, gmx_bool bSave)
-{
-    static const char *atomnm = "DOT";
-    static const char *resnm  = "DOT";
-    static const char *title  = "Connely Dot Surface Generated by g_sas";
-
-    int                i, i0, r0, ii0, k;
-    rvec              *xnew;
-    t_atoms            aaa;
-
-    if (bSave)
-    {
-        i0 = atoms->nr;
-        r0 = atoms->nres;
-        srenew(atoms->atom, atoms->nr+ndots);
-        srenew(atoms->atomname, atoms->nr+ndots);
-        srenew(atoms->resinfo, r0+1);
-        atoms->atom[i0].resind = r0;
-        t_atoms_set_resinfo(atoms, i0, symtab, resnm, r0+1, ' ', 0, ' ');
-        srenew(atoms->pdbinfo, atoms->nr+ndots);
-        snew(xnew, atoms->nr+ndots);
-        for (i = 0; (i < atoms->nr); i++)
-        {
-            copy_rvec(x[i], xnew[i]);
-        }
-        for (i = k = 0; (i < ndots); i++)
-        {
-            ii0                        = i0+i;
-            atoms->atomname[ii0]       = put_symtab(symtab, atomnm);
-            atoms->pdbinfo[ii0].type   = epdbATOM;
-            atoms->pdbinfo[ii0].atomnr = ii0;
-            atoms->atom[ii0].resind    = r0;
-            xnew[ii0][XX]              = dots[k++];
-            xnew[ii0][YY]              = dots[k++];
-            xnew[ii0][ZZ]              = dots[k++];
-            atoms->pdbinfo[ii0].bfac   = 0.0;
-            atoms->pdbinfo[ii0].occup  = 0.0;
-        }
-        atoms->nr   = i0+ndots;
-        atoms->nres = r0+1;
-        write_sto_conf(fn, title, atoms, xnew, NULL, ePBC, box);
-        atoms->nres = r0;
-        atoms->nr   = i0;
-    }
-    else
-    {
-        init_t_atoms(&aaa, ndots, TRUE);
-        aaa.atom[0].resind = 0;
-        t_atoms_set_resinfo(&aaa, 0, symtab, resnm, 1, ' ', 0, ' ');
-        snew(xnew, ndots);
-        for (i = k = 0; (i < ndots); i++)
-        {
-            ii0                     = i;
-            aaa.atomname[ii0]       = put_symtab(symtab, atomnm);
-            aaa.pdbinfo[ii0].type   = epdbATOM;
-            aaa.pdbinfo[ii0].atomnr = ii0;
-            aaa.atom[ii0].resind    = 0;
-            xnew[ii0][XX]           = dots[k++];
-            xnew[ii0][YY]           = dots[k++];
-            xnew[ii0][ZZ]           = dots[k++];
-            aaa.pdbinfo[ii0].bfac   = 0.0;
-            aaa.pdbinfo[ii0].occup  = 0.0;
-        }
-        aaa.nr = ndots;
-        write_sto_conf(fn, title, &aaa, xnew, NULL, ePBC, box);
-        do_conect(fn, ndots, xnew);
-        free_t_atoms(&aaa, FALSE);
-    }
-    sfree(xnew);
-}
-
-real calc_radius(char *atom)
-{
-    real r;
-
-    switch (atom[0])
-    {
-        case 'C':
-            r = 0.16;
-            break;
-        case 'O':
-            r = 0.13;
-            break;
-        case 'N':
-            r = 0.14;
-            break;
-        case 'S':
-            r = 0.2;
-            break;
-        case 'H':
-            r = 0.1;
-            break;
-        default:
-            r = 1e-3;
-    }
-    return r;
-}
-
-void sas_plot(int nfile, t_filenm fnm[], real solsize, int ndots,
-              real qcut, gmx_bool bSave, real minarea, gmx_bool bPBC,
-              real dgs_default, gmx_bool bFindex, const output_env_t oenv)
-{
-    FILE             *fp, *fp2, *fp3 = NULL, *vp;
-    const char       *flegend[] = {
-        "Hydrophobic", "Hydrophilic",
-        "Total", "D Gsolv"
-    };
-    const char       *vlegend[]          = { "Volume (nm\\S3\\N)", "Density (g/l)" };
-    const char       *or_and_oa_legend[] = { "Average (nm\\S2\\N)", "Standard deviation (nm\\S2\\N)" };
-    const char       *vfile;
-    real              t;
-    gmx_atomprop_t    aps  = NULL;
-    gmx_rmpbc_t       gpbc = NULL;
-    t_trxstatus      *status;
-    int               ndefault;
-    int               i, j, ii, nfr, natoms, flag, nsurfacedots, res;
-    rvec             *xtop, *x;
-    matrix            topbox, box;
-    t_topology        top;
-    char              title[STRLEN];
-    int               ePBC;
-    gmx_bool          bTop;
-    t_atoms          *atoms;
-    gmx_bool         *bOut, *bPhobic;
-    gmx_bool          bConnelly;
-    gmx_bool          bResAt, bITP, bDGsol;
-    real             *radius, *dgs_factor = NULL, *area = NULL, *surfacedots = NULL;
-    real              at_area, *atom_area = NULL, *atom_area2 = NULL;
-    real             *res_a = NULL, *res_area = NULL, *res_area2 = NULL;
-    real              totarea, totvolume, totmass = 0, density, harea, tarea, fluc2;
-    atom_id         **index, *findex;
-    int              *nx, nphobic, npcheck, retval;
-    char            **grpname, *fgrpname;
-    real              dgsolv;
-
-    bITP   = opt2bSet("-i", nfile, fnm);
-    bResAt = opt2bSet("-or", nfile, fnm) || opt2bSet("-oa", nfile, fnm) || bITP;
-
-    bTop = read_tps_conf(ftp2fn(efTPS, nfile, fnm), title, &top, &ePBC,
-                         &xtop, NULL, topbox, FALSE);
-    atoms = &(top.atoms);
-
-    if (!bTop)
-    {
-        fprintf(stderr, "No tpr file, will not compute Delta G of solvation\n");
-        bDGsol = FALSE;
-    }
-    else
-    {
-        bDGsol = strcmp(*(atoms->atomtype[0]), "?") != 0;
-        if (!bDGsol)
-        {
-            fprintf(stderr, "Warning: your tpr file is too old, will not compute "
-                    "Delta G of solvation\n");
-        }
-        else
-        {
-            printf("In case you use free energy of solvation predictions:\n");
-            please_cite(stdout, "Eisenberg86a");
-        }
-    }
-
-    aps = gmx_atomprop_init();
-
-    if ((natoms = read_first_x(oenv, &status, ftp2fn(efTRX, nfile, fnm),
-                               &t, &x, box)) == 0)
-    {
-        gmx_fatal(FARGS, "Could not read coordinates from statusfile\n");
-    }
-
-    if ((ePBC != epbcXYZ) || (TRICLINIC(box)))
-    {
-        fprintf(stderr, "\n\nWARNING: non-rectangular boxes may give erroneous results or crashes.\n"
-                "Analysis based on vacuum simulations (with the possibility of evaporation)\n"
-                "will certainly crash the analysis.\n\n");
-    }
-    snew(nx, 2);
-    snew(index, 2);
-    snew(grpname, 2);
-    fprintf(stderr, "Select a group for calculation of surface and a group for output:\n");
-    get_index(atoms, ftp2fn_null(efNDX, nfile, fnm), 2, nx, index, grpname);
-
-    if (bFindex)
-    {
-        fprintf(stderr, "Select a group of hydrophobic atoms:\n");
-        get_index(atoms, ftp2fn_null(efNDX, nfile, fnm), 1, &nphobic, &findex, &fgrpname);
-    }
-    snew(bOut, natoms);
-    for (i = 0; i < nx[1]; i++)
-    {
-        bOut[index[1][i]] = TRUE;
-    }
-
-    /* Now compute atomic readii including solvent probe size */
-    snew(radius, natoms);
-    snew(bPhobic, nx[0]);
-    if (bResAt)
-    {
-        snew(atom_area, nx[0]);
-        snew(atom_area2, nx[0]);
-        snew(res_a, atoms->nres);
-        snew(res_area, atoms->nres);
-        snew(res_area2, atoms->nres);
-    }
-    if (bDGsol)
-    {
-        snew(dgs_factor, nx[0]);
-    }
-
-    /* Get a Van der Waals radius for each atom */
-    ndefault = 0;
-    for (i = 0; (i < natoms); i++)
-    {
-        if (!gmx_atomprop_query(aps, epropVDW,
-                                *(atoms->resinfo[atoms->atom[i].resind].name),
-                                *(atoms->atomname[i]), &radius[i]))
-        {
-            ndefault++;
-        }
-        /* radius[i] = calc_radius(*(top->atoms.atomname[i])); */
-        radius[i] += solsize;
-    }
-    if (ndefault > 0)
-    {
-        fprintf(stderr, "WARNING: could not find a Van der Waals radius for %d atoms\n", ndefault);
-    }
-    /* Determine which atom is counted as hydrophobic */
-    if (bFindex)
-    {
-        npcheck = 0;
-        for (i = 0; (i < nx[0]); i++)
-        {
-            ii = index[0][i];
-            for (j = 0; (j < nphobic); j++)
-            {
-                if (findex[j] == ii)
-                {
-                    bPhobic[i] = TRUE;
-                    if (bOut[ii])
-                    {
-                        npcheck++;
-                    }
-                }
-            }
-        }
-        if (npcheck != nphobic)
-        {
-            gmx_fatal(FARGS, "Consistency check failed: not all %d atoms in the hydrophobic index\n"
-                      "found in the normal index selection (%d atoms)", nphobic, npcheck);
-        }
-    }
-    else
-    {
-        nphobic = 0;
-    }
-
-    for (i = 0; (i < nx[0]); i++)
-    {
-        ii = index[0][i];
-        if (!bFindex)
-        {
-            bPhobic[i] = fabs(atoms->atom[ii].q) <= qcut;
-            if (bPhobic[i] && bOut[ii])
-            {
-                nphobic++;
-            }
-        }
-        if (bDGsol)
-        {
-            if (!gmx_atomprop_query(aps, epropDGsol,
-                                    *(atoms->resinfo[atoms->atom[ii].resind].name),
-                                    *(atoms->atomtype[ii]), &(dgs_factor[i])))
-            {
-                dgs_factor[i] = dgs_default;
-            }
-        }
-        if (debug)
-        {
-            fprintf(debug, "Atom %5d %5s-%5s: q= %6.3f, r= %6.3f, dgsol= %6.3f, hydrophobic= %s\n",
-                    ii+1, *(atoms->resinfo[atoms->atom[ii].resind].name),
-                    *(atoms->atomname[ii]),
-                    atoms->atom[ii].q, radius[ii]-solsize, dgs_factor[i],
-                    EBOOL(bPhobic[i]));
-        }
-    }
-    fprintf(stderr, "%d out of %d atoms were classified as hydrophobic\n",
-            nphobic, nx[1]);
-
-    fp = xvgropen(opt2fn("-o", nfile, fnm), "Solvent Accessible Surface", "Time (ps)",
-                  "Area (nm\\S2\\N)", oenv);
-    xvgr_legend(fp, asize(flegend) - (bDGsol ? 0 : 1), flegend, oenv);
-    vfile = opt2fn_null("-tv", nfile, fnm);
-    if (vfile)
-    {
-        if (!bTop)
-        {
-            gmx_fatal(FARGS, "Need a tpr file for option -tv");
-        }
-        vp = xvgropen(vfile, "Volume and Density", "Time (ps)", "", oenv);
-        xvgr_legend(vp, asize(vlegend), vlegend, oenv);
-        totmass  = 0;
-        ndefault = 0;
-        for (i = 0; (i < nx[0]); i++)
-        {
-            real mm;
-            ii = index[0][i];
-            /*
-               if (!query_atomprop(atomprop,epropMass,
-             *(top->atoms.resname[top->atoms.atom[ii].resnr]),
-             *(top->atoms.atomname[ii]),&mm))
-               ndefault++;
-               totmass += mm;
-             */
-            totmass += atoms->atom[ii].m;
-        }
-        if (ndefault)
-        {
-            fprintf(stderr, "WARNING: Using %d default masses for density calculation, which most likely are inaccurate\n", ndefault);
-        }
-    }
-    else
-    {
-        vp = NULL;
-    }
-
-    gmx_atomprop_destroy(aps);
-
-    if (bPBC)
-    {
-        gpbc = gmx_rmpbc_init(&top.idef, ePBC, natoms);
-    }
-
-    nfr = 0;
-    do
-    {
-        if (bPBC)
-        {
-            gmx_rmpbc(gpbc, natoms, box, x);
-        }
-
-        bConnelly = (nfr == 0 && opt2bSet("-q", nfile, fnm));
-        if (bConnelly)
-        {
-            if (!bTop)
-            {
-                gmx_fatal(FARGS, "Need a tpr file for Connelly plot");
-            }
-            flag = FLAG_ATOM_AREA | FLAG_DOTS;
-        }
-        else
-        {
-            flag = FLAG_ATOM_AREA;
-        }
-        if (vp)
-        {
-            flag = flag | FLAG_VOLUME;
-        }
-
-        if (debug)
-        {
-            write_sto_conf("check.pdb", "pbc check", atoms, x, NULL, ePBC, box);
-        }
-
-        retval = nsc_dclm_pbc(x, radius, nx[0], ndots, flag, &totarea,
-                              &area, &totvolume, &surfacedots, &nsurfacedots,
-                              index[0], ePBC, bPBC ? box : NULL);
-        if (retval)
-        {
-            gmx_fatal(FARGS, "Something wrong in nsc_dclm_pbc");
-        }
-
-        if (bConnelly)
-        {
-            connelly_plot(ftp2fn(efPDB, nfile, fnm),
-                          nsurfacedots, surfacedots, x, atoms,
-                          &(top.symtab), ePBC, box, bSave);
-        }
-        harea  = 0;
-        tarea  = 0;
-        dgsolv = 0;
-        if (bResAt)
-        {
-            for (i = 0; i < atoms->nres; i++)
-            {
-                res_a[i] = 0;
-            }
-        }
-        for (i = 0; (i < nx[0]); i++)
-        {
-            ii = index[0][i];
-            if (bOut[ii])
-            {
-                at_area = area[i];
-                if (bResAt)
-                {
-                    atom_area[i]                  += at_area;
-                    atom_area2[i]                 += sqr(at_area);
-                    res_a[atoms->atom[ii].resind] += at_area;
-                }
-                tarea += at_area;
-                if (bDGsol)
-                {
-                    dgsolv += at_area*dgs_factor[i];
-                }
-                if (bPhobic[i])
-                {
-                    harea += at_area;
-                }
-            }
-        }
-        if (bResAt)
-        {
-            for (i = 0; i < atoms->nres; i++)
-            {
-                res_area[i]  += res_a[i];
-                res_area2[i] += sqr(res_a[i]);
-            }
-        }
-        fprintf(fp, "%10g  %10g  %10g  %10g", t, harea, tarea-harea, tarea);
-        if (bDGsol)
-        {
-            fprintf(fp, "  %10g\n", dgsolv);
-        }
-        else
-        {
-            fprintf(fp, "\n");
-        }
-
-        /* Print volume */
-        if (vp)
-        {
-            density = totmass*AMU/(totvolume*NANO*NANO*NANO);
-            fprintf(vp, "%12.5e  %12.5e  %12.5e\n", t, totvolume, density);
-        }
-        if (area)
-        {
-            sfree(area);
-            area = NULL;
-        }
-        if (surfacedots)
-        {
-            sfree(surfacedots);
-            surfacedots = NULL;
-        }
-        nfr++;
-    }
-    while (read_next_x(oenv, status, &t, x, box));
-
-    if (bPBC)
-    {
-        gmx_rmpbc_done(gpbc);
-    }
-
-    fprintf(stderr, "\n");
-    close_trj(status);
-    gmx_ffclose(fp);
-    if (vp)
-    {
-        gmx_ffclose(vp);
-    }
-
-    /* if necessary, print areas per atom to file too: */
-    if (bResAt)
-    {
-        for (i = 0; i < atoms->nres; i++)
-        {
-            res_area[i]  /= nfr;
-            res_area2[i] /= nfr;
-        }
-        for (i = 0; i < nx[0]; i++)
-        {
-            atom_area[i]  /= nfr;
-            atom_area2[i] /= nfr;
-        }
-        fprintf(stderr, "Printing out areas per atom\n");
-        fp  = xvgropen(opt2fn("-or", nfile, fnm), "Area per residue over the trajectory", "Residue",
-                       "Area (nm\\S2\\N)", oenv);
-        xvgr_legend(fp, asize(or_and_oa_legend), or_and_oa_legend, oenv);
-        fp2 = xvgropen(opt2fn("-oa", nfile, fnm), "Area per atom over the trajectory", "Atom #",
-                       "Area (nm\\S2\\N)", oenv);
-        xvgr_legend(fp2, asize(or_and_oa_legend), or_and_oa_legend, oenv);
-        if (bITP)
-        {
-            fp3 = ftp2FILE(efITP, nfile, fnm, "w");
-            fprintf(fp3, "[ position_restraints ]\n"
-                    "#define FCX 1000\n"
-                    "#define FCY 1000\n"
-                    "#define FCZ 1000\n"
-                    "; Atom  Type  fx   fy   fz\n");
-        }
-        for (i = 0; i < nx[0]; i++)
-        {
-            ii  = index[0][i];
-            res = atoms->atom[ii].resind;
-            if (i == nx[0]-1 || res != atoms->atom[index[0][i+1]].resind)
-            {
-                fluc2 = res_area2[res]-sqr(res_area[res]);
-                if (fluc2 < 0)
-                {
-                    fluc2 = 0;
-                }
-                fprintf(fp, "%10d  %10g %10g\n",
-                        atoms->resinfo[res].nr, res_area[res], sqrt(fluc2));
-            }
-            fluc2 = atom_area2[i]-sqr(atom_area[i]);
-            if (fluc2 < 0)
-            {
-                fluc2 = 0;
-            }
-            fprintf(fp2, "%d %g %g\n", index[0][i]+1, atom_area[i], sqrt(fluc2));
-            if (bITP && (atom_area[i] > minarea))
-            {
-                fprintf(fp3, "%5d   1     FCX  FCX  FCZ\n", ii+1);
-            }
-        }
-        if (bITP)
-        {
-            gmx_ffclose(fp3);
-        }
-        gmx_ffclose(fp);
-    }
-
-    /* Be a good citizen, keep our memory free! */
-    sfree(x);
-    sfree(nx);
-    for (i = 0; i < 2; i++)
-    {
-        sfree(index[i]);
-        sfree(grpname[i]);
-    }
-    sfree(bOut);
-    sfree(radius);
-    sfree(bPhobic);
-
-    if (bResAt)
-    {
-        sfree(atom_area);
-        sfree(atom_area2);
-        sfree(res_a);
-        sfree(res_area);
-        sfree(res_area2);
-    }
-    if (bDGsol)
-    {
-        sfree(dgs_factor);
-    }
-}
-
-int gmx_sas(int argc, char *argv[])
-{
-    const char     *desc[] = {
-        "[THISMODULE] computes hydrophobic, hydrophilic and total solvent",
-        "accessible surface area. See Eisenhaber F, Lijnzaad P, Argos P,",
-        "Sander C, & Scharf M (1995) J. Comput. Chem. 16, 273-284.",
-        "As a side effect, the Connolly surface can be generated as well in",
-        "a [TT].pdb[tt] file where the nodes are represented as atoms and the",
-        "vertice connecting the nearest nodes as CONECT records.",
-        "The program will ask for a group for the surface calculation",
-        "and a group for the output. The calculation group should always",
-        "consists of all the non-solvent atoms in the system.",
-        "The output group can be the whole or part of the calculation group.",
-        "The average and standard deviation of the area over the trajectory can be plotted",
-        "per residue and atom as well (options [TT]-or[tt] and [TT]-oa[tt]).",
-        "In combination with the latter option an [TT].itp[tt] file can be",
-        "generated (option [TT]-i[tt])",
-        "which can be used to restrain surface atoms.[PAR]",
-
-        "By default, periodic boundary conditions are taken into account,",
-        "this can be turned off using the [TT]-nopbc[tt] option.[PAR]",
-
-        "With the [TT]-tv[tt] option the total volume and density of the",
-        "molecule can be computed.",
-        "Please consider whether the normal probe radius is appropriate",
-        "in this case or whether you would rather use e.g. 0. It is good",
-        "to keep in mind that the results for volume and density are very",
-        "approximate. For example, in ice Ih, one can easily fit water molecules in the",
-        "pores which would yield a volume that is too low, and surface area and density",
-        "that are both too high."
-    };
-
-    output_env_t    oenv;
-    static real     solsize = 0.14;
-    static int      ndots   = 24;
-    static real     qcut    = 0.2;
-    static real     minarea = 0.5, dgs_default = 0;
-    static gmx_bool bSave   = TRUE, bPBC = TRUE, bFindex = FALSE;
-    t_pargs         pa[]    = {
-        { "-probe", FALSE, etREAL, {&solsize},
-          "Radius of the solvent probe (nm)" },
-        { "-ndots",   FALSE, etINT,  {&ndots},
-          "Number of dots per sphere, more dots means more accuracy" },
-        { "-qmax",    FALSE, etREAL, {&qcut},
-          "The maximum charge (e, absolute value) of a hydrophobic atom" },
-        { "-f_index", FALSE, etBOOL, {&bFindex},
-          "Determine from a group in the index file what are the hydrophobic atoms rather than from the charge" },
-        { "-minarea", FALSE, etREAL, {&minarea},
-          "The minimum area (nm^2) to count an atom as a surface atom when writing a position restraint file  (see help)" },
-        { "-pbc",     FALSE, etBOOL, {&bPBC},
-          "Take periodicity into account" },
-        { "-prot",    FALSE, etBOOL, {&bSave},
-          "Output the protein to the Connelly [TT].pdb[tt] file too" },
-        { "-dgs",     FALSE, etREAL, {&dgs_default},
-          "Default value for solvation free energy per area (kJ/mol/nm^2)" }
-    };
-    t_filenm        fnm[] = {
-        { efTRX, "-f",   NULL,       ffREAD },
-        { efTPS, "-s",   NULL,       ffREAD },
-        { efXVG, "-o",   "area",     ffWRITE },
-        { efXVG, "-or",  "resarea",  ffOPTWR },
-        { efXVG, "-oa",  "atomarea", ffOPTWR },
-        { efXVG, "-tv",  "volume",   ffOPTWR },
-        { efPDB, "-q",   "connelly", ffOPTWR },
-        { efNDX, "-n",   "index",    ffOPTRD },
-        { efITP, "-i",   "surfat",   ffOPTWR }
-    };
-#define NFILE asize(fnm)
-
-    if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE,
-                           NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv))
-    {
-        return 0;
-    }
-    if (solsize < 0)
-    {
-        solsize = 1e-3;
-        fprintf(stderr, "Probe size too small, setting it to %g\n", solsize);
-    }
-    if (ndots < 20)
-    {
-        ndots = 20;
-        fprintf(stderr, "Ndots too small, setting it to %d\n", ndots);
-    }
-
-    please_cite(stderr, "Eisenhaber95");
-
-    sas_plot(NFILE, fnm, solsize, ndots, qcut, bSave, minarea, bPBC, dgs_default, bFindex,
-             oenv);
-
-    do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy");
-    do_view(oenv, opt2fn_null("-or", NFILE, fnm), "-nxy");
-    do_view(oenv, opt2fn_null("-oa", NFILE, fnm), "-nxy");
-
-    return 0;
-}
index 2c3a6abf0dc781e4854e802e37d4f7b1ba4de618..a09167d5a53875dc5d5ba89e1b2352c232046767 100644 (file)
@@ -305,6 +305,17 @@ class Selection
         //! Returns whether the selection object is initialized.
         bool isValid() const { return sel_ != NULL; }
 
+        //! Returns whether two selection objects wrap the same selection.
+        bool operator==(const Selection &other) const
+        {
+            return sel_ == other.sel_;
+        }
+        //! Returns whether two selection objects wrap different selections.
+        bool operator!=(const Selection &other) const
+        {
+            return !operator==(other);
+        }
+
         //! Returns the name of the selection.
         const char *name() const  { return data().name(); }
         //! Returns the string that was parsed to produce this selection.
index 504f706769bf7f3390be4631db6929559d77a507..0bbbe0fb936707bd09de7fd7e98575bc8d1f4941 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2010,2013, by the GROMACS development team, led by
+# Copyright (c) 2010,2013,2014, 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.
@@ -32,7 +32,7 @@
 # To help us fund GROMACS development, we humbly ask that you cite
 # the research papers on the package. Check out http://www.gromacs.org.
 
-file(GLOB TRAJECTORYANALYSIS_SOURCES *.cpp modules/*.cpp)
+file(GLOB TRAJECTORYANALYSIS_SOURCES *.cpp modules/*.cpp modules/*.c)
 set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${TRAJECTORYANALYSIS_SOURCES} PARENT_SCOPE)
 
 set(TRAJECTORYANALYSIS_PUBLIC_HEADERS
index 1e7dd516365d4767d533d84c02b88a37deaebd06..bea3ad50ab3b3099f70b108f64a23c751fbab0a4 100644 (file)
@@ -47,6 +47,7 @@
 #include "modules/angle.h"
 #include "modules/distance.h"
 #include "modules/freevolume.h"
+#include "modules/sasa.h"
 #include "modules/select.h"
 
 namespace gmx
@@ -87,6 +88,7 @@ void registerTrajectoryAnalysisModules(CommandLineModuleManager *manager)
     registerModule<AngleInfo>(manager, group);
     registerModule<DistanceInfo>(manager, group);
     registerModule<FreeVolumeInfo>(manager, group);
+    registerModule<SasaInfo>(manager, group);
     registerModule<SelectInfo>(manager, group);
 }
 //! \endcond
similarity index 97%
rename from src/gromacs/gmxana/nsc.c
rename to src/gromacs/trajectoryanalysis/modules/nsc.c
index ece162dd3b88fb9f3ee151c73169de8c11098295..ce7f5d66253694c5db031ec24facde63b8c6af5f 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2007, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
@@ -61,7 +61,6 @@
 
 real   *xpunsp = NULL;
 real    del_cube;
-int    *ico_wk = NULL, *ico_pt = NULL;
 int     n_dot, ico_cube, last_n_dot = 0, last_densit = 0, last_unsp = 0;
 int     last_cubus = 0;
 
@@ -530,6 +529,7 @@ int unsp_type(int densit)
 
 int make_unsp(int densit, int mode, int * num_dot, int cubus)
 {
+    int  *ico_wk, *ico_pt;
     int   ndot, ico_cube_cb, i, j, k, l, ijk, tn, tl, tl2;
     real *xus;
     int  *work;
@@ -539,10 +539,6 @@ int make_unsp(int densit, int mode, int * num_dot, int cubus)
     {
         free(xpunsp);
     }
-    if (ico_wk)
-    {
-        free(ico_wk);
-    }
 
     k = 1; if (mode < 0)
     {
@@ -647,7 +643,8 @@ int make_unsp(int densit, int mode, int * num_dot, int cubus)
             } /* cycle k */
         }     /* cycle j */
     }         /* cycle i */
-    free(work);
+    sfree(ico_wk);
+    sfree(work);
 
     return 0;
 }
@@ -660,31 +657,32 @@ typedef struct _stwknb {
     real dot;
 } Neighb;
 
-int nsc_dclm_pbc(rvec *coords, real *radius, int nat,
+int nsc_dclm_pbc(const rvec *coords, real *radius, int nat,
                  int  densit, int mode,
                  real *value_of_area, real **at_area,
                  real *value_of_vol,
                  real **lidots, int *nu_dots,
                  atom_id index[], int ePBC, matrix box)
 {
-    int      iat, i, ii, iii, ix, iy, iz, ixe, ixs, iye, iys, ize, izs, i_ac;
-    int      jat, j, jj, jjj, jx, jy, jz;
-    int      distribution;
-    int      l;
-    int      maxnei, nnei, last, maxdots = 0;
-    int     *wkdot = NULL, *wkbox = NULL, *wkat1 = NULL, *wkatm = NULL;
-    Neighb  *wknb, *ctnb;
-    int      iii1, iii2, iiat, lfnr = 0, i_at, j_at;
-    real     dx, dy, dz, dd, ai, aisq, ajsq, aj, as, a;
-    real     xi, yi, zi, xs = 0., ys = 0., zs = 0.;
-    real     dotarea, area, vol = 0.;
-    real    *xus, *dots = NULL, *atom_area = NULL;
-    int      nxbox, nybox, nzbox, nxy, nxyz;
-    real     xmin = 0, ymin = 0, zmin = 0, xmax, ymax, zmax, ra2max, d, *pco;
+    int         iat, i, ii, iii, ix, iy, iz, ixe, ixs, iye, iys, ize, izs, i_ac;
+    int         jat, j, jj, jjj, jx, jy, jz;
+    int         distribution;
+    int         l;
+    int         maxnei, nnei, last, maxdots = 0;
+    int        *wkdot = NULL, *wkbox = NULL, *wkat1 = NULL, *wkatm = NULL;
+    Neighb     *wknb, *ctnb;
+    int         iii1, iii2, iiat, lfnr = 0, i_at, j_at;
+    real        dx, dy, dz, dd, ai, aisq, ajsq, aj, as, a;
+    real        xi, yi, zi, xs = 0., ys = 0., zs = 0.;
+    real        dotarea, area, vol = 0.;
+    real       *xus, *dots = NULL, *atom_area = NULL;
+    int         nxbox, nybox, nzbox, nxy, nxyz;
+    real        xmin = 0, ymin = 0, zmin = 0, xmax, ymax, zmax, ra2max, d;
+    const real *pco;
     /* Added DvdS 2006-07-19 */
-    t_pbc    pbc;
-    rvec     ddx, *x = NULL;
-    int      iat_xx, jat_xx;
+    t_pbc       pbc;
+    rvec        ddx, *x = NULL;
+    int         iat_xx, jat_xx;
 
     distribution = unsp_type(densit);
     if (distribution != -last_unsp || last_cubus != 4 ||
similarity index 91%
rename from src/gromacs/gmxana/nsc.h
rename to src/gromacs/trajectoryanalysis/modules/nsc.h
index 929ff6f9ae3f61350bdb78b1c7dc8e971c292dde..6394c56a6b9ec2c77b4d44628e44279b7a411bf0 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014, 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.
 #define FLAG_VOLUME     02
 #define FLAG_ATOM_AREA  04
 
+#ifdef __cplusplus
+extern "C"
+{
+#endif
 
-
-extern int nsc_dclm_pbc(rvec *coords, real *radius, int nat,
-                        int  densit, int mode,
-                        real *value_of_area, real **at_area,
-                        real *value_of_vol,
-                        real **lidots, int *nu_dots,
-                        atom_id index[], int ePBC, matrix box);
+int nsc_dclm_pbc(const rvec *coords, real *radius, int nat,
+                 int  densit, int mode,
+                 real *value_of_area, real **at_area,
+                 real *value_of_vol,
+                 real **lidots, int *nu_dots,
+                 atom_id index[], int ePBC, matrix box);
 
 /*
     User notes :
@@ -135,3 +138,7 @@ extern int nsc_dclm_pbc(rvec *coords, real *radius, int nat,
    }
 
  */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/gromacs/trajectoryanalysis/modules/sasa.cpp b/src/gromacs/trajectoryanalysis/modules/sasa.cpp
new file mode 100644 (file)
index 0000000..8b918e6
--- /dev/null
@@ -0,0 +1,1065 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2006, The GROMACS development team.
+ * Copyright (c) 2008,2009,2010,2011,2012,2013,2014, 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.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * Implements gmx::analysismodules::Sasa.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com> (C++ conversion)
+ * \ingroup module_trajectoryanalysis
+ */
+#include "sasa.h"
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "gromacs/legacyheaders/atomprop.h"
+#include "gromacs/legacyheaders/copyrite.h"
+#include "gromacs/legacyheaders/pbc.h"
+#include "gromacs/legacyheaders/physics.h"
+#include "gromacs/legacyheaders/smalloc.h"
+#include "gromacs/legacyheaders/symtab.h"
+#include "gromacs/legacyheaders/vec.h"
+
+#include "gromacs/analysisdata/analysisdata.h"
+#include "gromacs/analysisdata/modules/average.h"
+#include "gromacs/analysisdata/modules/plot.h"
+#include "gromacs/fileio/confio.h"
+#include "gromacs/fileio/futil.h"
+#include "gromacs/fileio/pdbio.h"
+#include "gromacs/options/basicoptions.h"
+#include "gromacs/options/filenameoption.h"
+#include "gromacs/options/options.h"
+#include "gromacs/selection/selection.h"
+#include "gromacs/selection/selectionoption.h"
+#include "gromacs/trajectoryanalysis/analysismodule.h"
+#include "gromacs/trajectoryanalysis/analysissettings.h"
+#include "gromacs/utility/exceptions.h"
+#include "gromacs/utility/stringutil.h"
+
+#include "nsc.h"
+
+namespace gmx
+{
+
+namespace analysismodules
+{
+
+namespace
+{
+
+//! \addtogroup module_trajectoryanalysis
+//! \{
+
+//! Tracks information on two nearest neighbors of a single surface dot.
+struct t_conect
+{
+    //! Index of the second nearest neighbor dot.
+    atom_id  aa;
+    //! Index of the nearest neighbor dot.
+    atom_id  ab;
+    //! Squared distance to `aa`.
+    real     d2a;
+    //! Squared distance to `ab`.
+    real     d2b;
+};
+
+/*! \brief
+ * Updates nearest neighbor information for a surface dot.
+ *
+ * \param[in,out] c  Nearest neighbor information array to update.
+ * \param[in]     i  Index in `c` to update.
+ * \param[in]     j  Index of the other surface dot to add to the array.
+ * \param[in]     d2 Squared distance between `i` and `j`.
+ */
+void add_rec(t_conect c[], atom_id i, atom_id j, real d2)
+{
+    if (c[i].aa == NO_ATID)
+    {
+        c[i].aa  = j;
+        c[i].d2a = d2;
+    }
+    else if (c[i].ab == NO_ATID)
+    {
+        c[i].ab  = j;
+        c[i].d2b = d2;
+    }
+    else if (d2 < c[i].d2a)
+    {
+        c[i].aa  = j;
+        c[i].d2a = d2;
+    }
+    else if (d2 < c[i].d2b)
+    {
+        c[i].ab  = j;
+        c[i].d2b = d2;
+    }
+    /* Swap them if necessary: a must be larger than b */
+    if (c[i].d2a < c[i].d2b)
+    {
+        j        = c[i].ab;
+        c[i].ab  = c[i].aa;
+        c[i].aa  = j;
+        d2       = c[i].d2b;
+        c[i].d2b = c[i].d2a;
+        c[i].d2a = d2;
+    }
+}
+
+/*! \brief
+ * Adds CONECT records for surface dots.
+ *
+ * \param[in] fn  PDB file to append the CONECT records to.
+ * \param[in] n   Number of dots in `x`.
+ * \param[in] x   Array of surface dot positions.
+ *
+ * Adds a CONECT record that connects each surface dot to its two nearest
+ * neighbors.  The function is copied verbatim from the old gmx_sas.c
+ * implementation.
+ */
+void do_conect(const char *fn, int n, rvec x[])
+{
+    FILE     *fp;
+    int       i, j;
+    t_conect *c;
+    rvec      dx;
+    real      d2;
+
+    fprintf(stderr, "Building CONECT records\n");
+    snew(c, n);
+    for (i = 0; (i < n); i++)
+    {
+        c[i].aa = c[i].ab = NO_ATID;
+    }
+
+    for (i = 0; (i < n); i++)
+    {
+        for (j = i+1; (j < n); j++)
+        {
+            rvec_sub(x[i], x[j], dx);
+            d2 = iprod(dx, dx);
+            add_rec(c, i, j, d2);
+            add_rec(c, j, i, d2);
+        }
+    }
+    fp = gmx_ffopen(fn, "a");
+    for (i = 0; (i < n); i++)
+    {
+        if ((c[i].aa == NO_ATID) || (c[i].ab == NO_ATID))
+        {
+            fprintf(stderr, "Warning dot %d has no conections\n", i+1);
+        }
+        fprintf(fp, "CONECT%5d%5d%5d\n", i+1, c[i].aa+1, c[i].ab+1);
+    }
+    gmx_ffclose(fp);
+    sfree(c);
+}
+
+/*! \brief
+ * Plots the surface into a PDB file, optionally including the original atoms.
+ */
+void connolly_plot(const char *fn, int ndots, real dots[], rvec x[], t_atoms *atoms,
+                   t_symtab *symtab, int ePBC, const matrix box, gmx_bool bIncludeSolute)
+{
+    const char *const  atomnm = "DOT";
+    const char *const  resnm  = "DOT";
+    const char *const  title  = "Connolly Dot Surface Generated by gmx sasa";
+
+    int                i, i0, r0, ii0, k;
+    rvec              *xnew;
+    t_atoms            aaa;
+
+    if (bIncludeSolute)
+    {
+        i0 = atoms->nr;
+        r0 = atoms->nres;
+        srenew(atoms->atom, atoms->nr+ndots);
+        memset(&atoms->atom[i0], 0, sizeof(*atoms->atom)*ndots);
+        srenew(atoms->atomname, atoms->nr+ndots);
+        srenew(atoms->resinfo, r0+1);
+        atoms->atom[i0].resind = r0;
+        t_atoms_set_resinfo(atoms, i0, symtab, resnm, r0+1, ' ', 0, ' ');
+        if (atoms->pdbinfo != NULL)
+        {
+            srenew(atoms->pdbinfo, atoms->nr+ndots);
+        }
+        snew(xnew, atoms->nr+ndots);
+        for (i = 0; (i < atoms->nr); i++)
+        {
+            copy_rvec(x[i], xnew[i]);
+        }
+        for (i = k = 0; (i < ndots); i++)
+        {
+            ii0                        = i0+i;
+            atoms->atomname[ii0]       = put_symtab(symtab, atomnm);
+            atoms->atom[ii0].resind    = r0;
+            xnew[ii0][XX]              = dots[k++];
+            xnew[ii0][YY]              = dots[k++];
+            xnew[ii0][ZZ]              = dots[k++];
+            if (atoms->pdbinfo != NULL)
+            {
+                atoms->pdbinfo[ii0].type   = epdbATOM;
+                atoms->pdbinfo[ii0].atomnr = ii0;
+                atoms->pdbinfo[ii0].bfac   = 0.0;
+                atoms->pdbinfo[ii0].occup  = 0.0;
+            }
+        }
+        atoms->nr   = i0+ndots;
+        atoms->nres = r0+1;
+        write_sto_conf(fn, title, atoms, xnew, NULL, ePBC, const_cast<rvec *>(box));
+        atoms->nres = r0;
+        atoms->nr   = i0;
+    }
+    else
+    {
+        init_t_atoms(&aaa, ndots, TRUE);
+        aaa.atom[0].resind = 0;
+        t_atoms_set_resinfo(&aaa, 0, symtab, resnm, 1, ' ', 0, ' ');
+        snew(xnew, ndots);
+        for (i = k = 0; (i < ndots); i++)
+        {
+            ii0                     = i;
+            aaa.atomname[ii0]       = put_symtab(symtab, atomnm);
+            aaa.pdbinfo[ii0].type   = epdbATOM;
+            aaa.pdbinfo[ii0].atomnr = ii0;
+            aaa.atom[ii0].resind    = 0;
+            xnew[ii0][XX]           = dots[k++];
+            xnew[ii0][YY]           = dots[k++];
+            xnew[ii0][ZZ]           = dots[k++];
+            aaa.pdbinfo[ii0].bfac   = 0.0;
+            aaa.pdbinfo[ii0].occup  = 0.0;
+        }
+        aaa.nr = ndots;
+        write_sto_conf(fn, title, &aaa, xnew, NULL, ePBC, const_cast<rvec *>(box));
+        do_conect(fn, ndots, xnew);
+        free_t_atoms(&aaa, FALSE);
+    }
+    sfree(xnew);
+}
+
+/********************************************************************
+ * Actual analysis module
+ */
+
+/*! \brief
+ * Implements `gmx sas` trajectory analysis module.
+ */
+class Sasa : public TrajectoryAnalysisModule
+{
+    public:
+        Sasa();
+
+        virtual void initOptions(Options                    *options,
+                                 TrajectoryAnalysisSettings *settings);
+        virtual void initAnalysis(const TrajectoryAnalysisSettings &settings,
+                                  const TopologyInformation        &top);
+
+        virtual TrajectoryAnalysisModuleDataPointer startFrames(
+            const AnalysisDataParallelOptions &opt,
+            const SelectionCollection         &selections);
+        virtual void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
+                                  TrajectoryAnalysisModuleData *pdata);
+
+        virtual void finishAnalysis(int nframes);
+        virtual void writeOutput();
+
+    private:
+        /*! \brief
+         * Surface areas as a function of time.
+         *
+         * First column is for the calculation group, and the rest for the
+         * output groups.  This data is always produced.
+         */
+        AnalysisData            area_;
+        /*! \brief
+         * Per-atom surface areas as a function of time.
+         *
+         * Contains one data set for each column in `area_`.
+         * Each column corresponds to a selection position in `surfaceSel_`.
+         * This data is only produced if atom or residue areas have been
+         * requested.
+         */
+        AnalysisData            atomArea_;
+        /*! \brief
+         * Per-residue surface areas as a function of time.
+         *
+         * Contains one data set for each column in `area_`.
+         * Each column corresponds to a distinct residue `surfaceSel_`.
+         * For example, if `surfaceSel_` selects residues 2, 5, and 7, there
+         * will be three columns here.
+         * This data is only produced if atom or residue areas have been
+         * requested.
+         */
+        AnalysisData            residueArea_;
+        /*! \brief
+         * Free energy estimates as a function of time.
+         *
+         * Column layout is the same as for `area_`.
+         * This data is only produced if the output is requested.
+         */
+        AnalysisData            dgSolv_;
+        /*! \brief
+         * Total volume and density of the calculation group as a function of
+         * time.
+         *
+         * The first column is the volume and the second column is the density.
+         * This data is only produced if the output is requested.
+         */
+        AnalysisData            volume_;
+
+        /*! \brief
+         * The selection to calculate the surface for.
+         *
+         * Selection::originalId() and Selection::mappedId() store the mapping
+         * from the positions to the columns of `residueArea_`.
+         * The selection is computed with SelectionOption::dynamicMask(), i.e.,
+         * even in the presence of a dynamic selection, the number of returned
+         * positions is fixed, and SelectionPosition::selected() is used.
+         */
+        Selection               surfaceSel_;
+        /*! \brief
+         * List of optional additional output groups.
+         *
+         * Each of these must be a subset of the `surfaceSel_`.
+         * Selection::originalId() and Selection::mappedId() store the mapping
+         * from the positions to the corresponsing positions in `surfaceSel_`.
+         */
+        SelectionList           outputSel_;
+
+        std::string             fnArea_;
+        std::string             fnAtomArea_;
+        std::string             fnResidueArea_;
+        std::string             fnDGSolv_;
+        std::string             fnVolume_;
+        std::string             fnConnolly_;
+
+        double                  solsize_;
+        int                     ndots_;
+        //double                  minarea_;
+        double                  dgsDefault_;
+        bool                    bIncludeSolute_;
+
+        t_topology             *top_;
+        //! Combined VdW and probe radii for each atom in the calculation group.
+        std::vector<real>       radii_;
+        /*! \brief
+         * Solvation free energy coefficients for each atom in the calculation
+         * group.
+         *
+         * Empty if the free energy output has not been requested.
+         */
+        std::vector<real>       dgsFactor_;
+
+        // Copy and assign disallowed by base.
+};
+
+Sasa::Sasa()
+    : TrajectoryAnalysisModule(SasaInfo::name, SasaInfo::shortDescription),
+      solsize_(0.14), ndots_(24), dgsDefault_(0), bIncludeSolute_(true), top_(NULL)
+{
+    //minarea_ = 0.5;
+    registerAnalysisDataset(&area_, "area");
+    registerAnalysisDataset(&atomArea_, "atomarea");
+    registerAnalysisDataset(&residueArea_, "resarea");
+    registerAnalysisDataset(&dgSolv_, "dgsolv");
+    registerAnalysisDataset(&volume_, "volume");
+}
+
+void
+Sasa::initOptions(Options *options, TrajectoryAnalysisSettings *settings)
+{
+    static const char *const desc[] = {
+        "[THISMODULE] computes solvent accessible surface areas.",
+        "See Eisenhaber F, Lijnzaad P, Argos P, Sander C, & Scharf M",
+        "(1995) J. Comput. Chem. 16, 273-284 for the algorithm used.",
+        "With [TT]-q[tt], the Connolly surface can be generated as well",
+        "in a [TT].pdb[tt] file where the nodes are represented as atoms",
+        "and the edges connecting the nearest nodes as CONECT records.",
+        "[TT]-odg[tt] allows for estimation of solvation free energies",
+        "from per-atom solvation energies per exposed surface area.[PAR]",
+
+        "The program requires a selection for the surface calculation to be",
+        "specified with [TT]-surface[tt]. This should always consist of all",
+        "non-solvent atoms in the system. The area of this group is always",
+        "calculated. Optionally, [TT]-output[tt] can specify additional",
+        "selections, which should be subsets of the calculation group.",
+        "The solvent-accessible areas for these groups are also extracted",
+        "from the full surface.[PAR]",
+
+        "The average and standard deviation of the area over the trajectory",
+        "can be calculated per residue and atom (options [TT]-or[tt] and",
+        "[TT]-oa[tt]).[PAR]",
+        //"In combination with the latter option an [TT].itp[tt] file can be",
+        //"generated (option [TT]-i[tt])",
+        //"which can be used to restrain surface atoms.[PAR]",
+
+        "With the [TT]-tv[tt] option the total volume and density of the",
+        "molecule can be computed.",
+        "Please consider whether the normal probe radius is appropriate",
+        "in this case or whether you would rather use, e.g., 0. It is good",
+        "to keep in mind that the results for volume and density are very",
+        "approximate. For example, in ice Ih, one can easily fit water molecules in the",
+        "pores which would yield a volume that is too low, and surface area and density",
+        "that are both too high."
+    };
+
+    options->setDescription(concatenateStrings(desc));
+
+    options->addOption(FileNameOption("o").filetype(eftPlot).outputFile().required()
+                           .store(&fnArea_).defaultBasename("area")
+                           .description("Total area as a function of time"));
+    options->addOption(FileNameOption("odg").filetype(eftPlot).outputFile()
+                           .store(&fnDGSolv_).defaultBasename("dgsolv")
+                           .description("Estimated solvation free energy as a function of time"));
+    options->addOption(FileNameOption("or").filetype(eftPlot).outputFile()
+                           .store(&fnResidueArea_).defaultBasename("resarea")
+                           .description("Average area per residue"));
+    options->addOption(FileNameOption("oa").filetype(eftPlot).outputFile()
+                           .store(&fnAtomArea_).defaultBasename("atomarea")
+                           .description("Average area per atom"));
+    options->addOption(FileNameOption("tv").filetype(eftPlot).outputFile()
+                           .store(&fnVolume_).defaultBasename("volume")
+                           .description("Total volume and density as a function of time"));
+    options->addOption(FileNameOption("q").filetype(eftPDB).outputFile()
+                           .store(&fnConnolly_).defaultBasename("connolly")
+                           .description("PDB file for Connolly surface"));
+    //options->addOption(FileNameOption("i").filetype(eftITP).outputFile()
+    //                       .store(&fnRestraints_).defaultBasename("surfat")
+    //                       .description("Topology file for position restraings on surface atoms"));
+
+
+    options->addOption(DoubleOption("probe").store(&solsize_)
+                           .description("Radius of the solvent probe (nm)"));
+    options->addOption(IntegerOption("ndots").store(&ndots_)
+                           .description("Number of dots per sphere, more dots means more accuracy"));
+    //options->addOption(DoubleOption("minarea").store(&minarea_)
+    //                       .description("The minimum area (nm^2) to count an atom as a surface atom when writing a position restraint file (see help)"));
+    options->addOption(BooleanOption("prot").store(&bIncludeSolute_)
+                           .description("Output the protein to the Connolly [TT].pdb[tt] file too"));
+    options->addOption(DoubleOption("dgs").store(&dgsDefault_)
+                           .description("Default value for solvation free energy per area (kJ/mol/nm^2)"));
+
+    // Selections must select atoms for the VdW radii lookup to work.
+    // The calculation group uses dynamicMask() so that the coordinates
+    // match a static array of VdW radii.
+    options->addOption(SelectionOption("surface").store(&surfaceSel_)
+                           .required().onlyAtoms().dynamicMask()
+                           .description("Surface calculation selection"));
+    options->addOption(SelectionOption("output").storeVector(&outputSel_)
+                           .onlyAtoms().multiValue()
+                           .description("Output selection(s)"));
+
+    // Atom names etc. are required for the VdW radii lookup.
+    settings->setFlag(TrajectoryAnalysisSettings::efRequireTop);
+}
+
+void
+Sasa::initAnalysis(const TrajectoryAnalysisSettings &settings,
+                   const TopologyInformation        &top)
+{
+    const t_atoms &atoms = top.topology()->atoms;
+    top_ = top.topology();
+
+    //bITP   = opt2bSet("-i", nfile, fnm);
+    const bool bResAt =
+        !fnResidueArea_.empty() || !fnAtomArea_.empty(); // || bITP;
+    const bool bDGsol = !fnDGSolv_.empty();
+
+    if (solsize_ < 0)
+    {
+        solsize_ = 1e-3;
+        fprintf(stderr, "Probe size too small, setting it to %g\n", solsize_);
+    }
+    if (ndots_ < 20)
+    {
+        ndots_ = 20;
+        fprintf(stderr, "Ndots too small, setting it to %d\n", ndots_);
+    }
+
+    please_cite(stderr, "Eisenhaber95");
+    //if ((top.ePBC() != epbcXYZ) || (TRICLINIC(fr.box)))
+    //{
+    //    fprintf(stderr, "\n\nWARNING: non-rectangular boxes may give erroneous results or crashes.\n"
+    //            "Analysis based on vacuum simulations (with the possibility of evaporation)\n"
+    //            "will certainly crash the analysis.\n\n");
+    //}
+
+    if (bDGsol)
+    {
+        if (!top.hasFullTopology())
+        {
+            GMX_THROW(InconsistentInputError("Cannot compute Delta G of solvation without a tpr file"));
+        }
+        else
+        {
+            if (strcmp(*(atoms.atomtype[0]), "?") == 0)
+            {
+                GMX_THROW(InconsistentInputError("Your input tpr file is too old (does not contain atom types). Cannot not compute Delta G of solvation"));
+            }
+            else
+            {
+                printf("Free energy of solvation predictions:\n");
+                please_cite(stdout, "Eisenberg86a");
+            }
+        }
+    }
+
+    // Now compute atomic radii including solvent probe size.
+    // Also, fetch solvation free energy coefficients and
+    // compute the residue indices that map the calculation atoms
+    // to the columns of residueArea_.
+    radii_.reserve(surfaceSel_.posCount());
+    if (bDGsol)
+    {
+        dgsFactor_.reserve(surfaceSel_.posCount());
+    }
+
+    // TODO: Not exception-safe, but nice solution would be to have a C++
+    // atom properties class...
+    gmx_atomprop_t     aps = gmx_atomprop_init();
+
+    ConstArrayRef<int> atomIndices = surfaceSel_.atomIndices();
+    int                prevResind  = atoms.atom[atomIndices[0]].resind;
+    int                resCount    = 0;
+    int                ndefault    = 0;
+    for (int i = 0; i < surfaceSel_.posCount(); i++)
+    {
+        const int ii     = atomIndices[i];
+        const int resind = atoms.atom[ii].resind;
+        if (resind != prevResind)
+        {
+            ++resCount;
+            prevResind = resind;
+        }
+        surfaceSel_.setOriginalId(i, resCount);
+        real      radius;
+        if (!gmx_atomprop_query(aps, epropVDW,
+                                *(atoms.resinfo[resind].name),
+                                *(atoms.atomname[ii]), &radius))
+        {
+            ndefault++;
+        }
+        radii_.push_back(radius + solsize_);
+        if (bDGsol)
+        {
+            real dgsFactor;
+            if (!gmx_atomprop_query(aps, epropDGsol,
+                                    *(atoms.resinfo[resind].name),
+                                    *(atoms.atomtype[ii]), &dgsFactor))
+            {
+                dgsFactor = dgsDefault_;
+            }
+            dgsFactor_.push_back(dgsFactor);
+        }
+    }
+    if (ndefault > 0)
+    {
+        fprintf(stderr, "WARNING: could not find a Van der Waals radius for %d atoms\n", ndefault);
+    }
+    gmx_atomprop_destroy(aps);
+
+    // The loop above doesn't count the last residue.
+    ++resCount;
+
+    // Pre-compute mapping from the output groups to the calculation group,
+    // and store it in the selection ID map for easy lookup.
+    for (size_t g = 0; g < outputSel_.size(); ++g)
+    {
+        ConstArrayRef<int> outputIndices = outputSel_[g].atomIndices();
+        for (int i = 0, j = 0; i < outputSel_[g].posCount(); ++i)
+        {
+            while (j < surfaceSel_.posCount() && outputIndices[i] > atomIndices[j])
+            {
+                ++j;
+            }
+            if (j == surfaceSel_.posCount() || outputIndices[i] != atomIndices[j])
+            {
+                GMX_THROW(InconsistentInputError("Output selection is not a subset of the input selection"));
+            }
+            outputSel_[g].setOriginalId(i, j);
+        }
+    }
+
+    // Initialize all the output data objects and initialize the output plotters.
+
+    area_.setColumnCount(0, 1 + outputSel_.size());
+    {
+        AnalysisDataPlotModulePointer plotm(
+                new AnalysisDataPlotModule(settings.plotSettings()));
+        plotm->setFileName(fnArea_);
+        plotm->setTitle("Solvent Accessible Surface");
+        plotm->setXAxisIsTime();
+        plotm->setYLabel("Area (nm\\S2\\N)");
+        plotm->appendLegend("Total");
+        for (size_t i = 0; i < outputSel_.size(); ++i)
+        {
+            plotm->appendLegend(outputSel_[i].name());
+        }
+        area_.addModule(plotm);
+    }
+
+    if (bResAt)
+    {
+        atomArea_.setDataSetCount(1 + outputSel_.size());
+        residueArea_.setDataSetCount(1 + outputSel_.size());
+        for (size_t i = 0; i <= outputSel_.size(); ++i)
+        {
+            atomArea_.setColumnCount(i, surfaceSel_.posCount());
+            residueArea_.setColumnCount(i, resCount);
+        }
+        {
+            AnalysisDataAverageModulePointer avem(new AnalysisDataAverageModule);
+            for (int i = 0; i < surfaceSel_.posCount(); ++i)
+            {
+                avem->setXAxisValue(i, surfaceSel_.position(i).atomIndices()[0] + 1);
+            }
+            atomArea_.addModule(avem);
+            if (!fnAtomArea_.empty())
+            {
+                AnalysisDataPlotModulePointer plotm(
+                        new AnalysisDataPlotModule(settings.plotSettings()));
+                plotm->setFileName(fnAtomArea_);
+                plotm->setTitle("Area per residue over the trajectory");
+                plotm->setXLabel("Atom");
+                plotm->setXFormat(8, 0);
+                plotm->setYLabel("Area (nm\\S2\\N)");
+                plotm->setErrorsAsSeparateColumn(true);
+                plotm->appendLegend("Average (nm\\S2\\N)");
+                plotm->appendLegend("Standard deviation (nm\\S2\\N)");
+                avem->addModule(plotm);
+            }
+        }
+        {
+            AnalysisDataAverageModulePointer avem(new AnalysisDataAverageModule);
+            for (int i = 0; i < surfaceSel_.posCount(); ++i)
+            {
+                const int atomIndex     = surfaceSel_.position(i).atomIndices()[0];
+                const int residueIndex  = atoms.atom[atomIndex].resind;
+                avem->setXAxisValue(i, atoms.resinfo[residueIndex].nr);
+            }
+            residueArea_.addModule(avem);
+            if (!fnResidueArea_.empty())
+            {
+                AnalysisDataPlotModulePointer plotm(
+                        new AnalysisDataPlotModule(settings.plotSettings()));
+                plotm->setFileName(fnResidueArea_);
+                plotm->setTitle("Area per atom over the trajectory");
+                plotm->setXLabel("Residue");
+                plotm->setXFormat(8, 0);
+                plotm->setYLabel("Area (nm\\S2\\N)");
+                plotm->setErrorsAsSeparateColumn(true);
+                plotm->appendLegend("Average (nm\\S2\\N)");
+                plotm->appendLegend("Standard deviation (nm\\S2\\N)");
+                avem->addModule(plotm);
+            }
+        }
+    }
+
+    if (!fnDGSolv_.empty())
+    {
+        dgSolv_.setColumnCount(0, 1 + outputSel_.size());
+        AnalysisDataPlotModulePointer plotm(
+                new AnalysisDataPlotModule(settings.plotSettings()));
+        plotm->setFileName(fnDGSolv_);
+        plotm->setTitle("Free Energy of Solvation");
+        plotm->setXAxisIsTime();
+        plotm->setYLabel("D Gsolv");
+        plotm->appendLegend("Total");
+        for (size_t i = 0; i < outputSel_.size(); ++i)
+        {
+            plotm->appendLegend(outputSel_[i].name());
+        }
+        dgSolv_.addModule(plotm);
+    }
+
+    if (!fnVolume_.empty())
+    {
+        volume_.setColumnCount(0, 2);
+        AnalysisDataPlotModulePointer plotm(
+                new AnalysisDataPlotModule(settings.plotSettings()));
+        plotm->setFileName(fnVolume_);
+        plotm->setTitle("Volume and Density");
+        plotm->setXAxisIsTime();
+        plotm->appendLegend("Volume (nm\\S3\\N)");
+        plotm->appendLegend("Density (g/l)");
+        volume_.addModule(plotm);
+    }
+}
+
+/*! \brief
+ * Temporary memory for use within a single-frame calculation.
+ */
+class SasaModuleData : public TrajectoryAnalysisModuleData
+{
+    public:
+        /*! \brief
+         * Reserves memory for the frame-local data.
+         *
+         * `residueCount` will be zero if per-residue data is not being
+         * calculated.
+         */
+        SasaModuleData(TrajectoryAnalysisModule          *module,
+                       const AnalysisDataParallelOptions &opt,
+                       const SelectionCollection         &selections,
+                       int atomCount, int residueCount)
+            : TrajectoryAnalysisModuleData(module, opt, selections)
+        {
+            index_.reserve(atomCount);
+            // If the calculation group is not dynamic, pre-calculate
+            // the index, since it is not going to change.
+            for (int i = 0; i < atomCount; ++i)
+            {
+                index_.push_back(i);
+            }
+            atomAreas_.resize(atomCount);
+            res_a_.resize(residueCount);
+        }
+
+        virtual void finish() { finishDataHandles(); }
+
+        //! Indices of the calculation selection positions selected for the frame.
+        std::vector<int>        index_;
+        /*! \brief
+         * Atom areas for each calculation selection position for the frame.
+         *
+         * One entry for each position in the calculation group.
+         * Values for atoms not selected are set to zero.
+         */
+        std::vector<real>       atomAreas_;
+        /*! \brief
+         * Working array to accumulate areas for each residue.
+         *
+         * One entry for each distinct residue in the calculation group;
+         * indices are not directly residue numbers or residue indices.
+         *
+         * This vector is empty if residue area calculations are not being
+         * performed.
+         */
+        std::vector<real>       res_a_;
+};
+
+TrajectoryAnalysisModuleDataPointer Sasa::startFrames(
+        const AnalysisDataParallelOptions &opt,
+        const SelectionCollection         &selections)
+{
+    return TrajectoryAnalysisModuleDataPointer(
+            new SasaModuleData(this, opt, selections, surfaceSel_.posCount(),
+                               residueArea_.columnCount(0)));
+}
+
+/*! \brief
+ * Helper method to compute the areas for a single selection.
+ *
+ * \param[in]  surfaceSel     The calculation selection.
+ * \param[in]  sel            The selection to compute the areas for (can be
+ *     `surfaceSel` or one of the output selections).
+ * \param[in]  atomAreas      Atom areas for each position in `surfaceSel`.
+ * \param[in]  dgsFactor      Free energy coefficients for each position in
+ *     `surfaceSel`. If empty, free energies are not calculated.
+ * \param[out] totalAreaOut Total area of `sel` (sum of atom areas it selects).
+ * \param[out] dgsolvOut      Solvation free energy.
+ *     Will be zero of `dgsFactor` is empty.
+ * \param      atomAreaHandle Data handle to use for storing atom areas for `sel`.
+ * \param      resAreaHandle  Data handle to use for storing residue areas for `sel`.
+ * \param      resAreaWork    Work array for accumulating the residue areas.
+ *     If empty, atom and residue areas are not calculated.
+ *
+ * `atomAreaHandle` and `resAreaHandle` are not used if `resAreaWork` is empty.
+ */
+void computeAreas(const Selection &surfaceSel, const Selection &sel,
+                  const std::vector<real> &atomAreas,
+                  const std::vector<real> &dgsFactor,
+                  real *totalAreaOut, real *dgsolvOut,
+                  AnalysisDataHandle atomAreaHandle,
+                  AnalysisDataHandle resAreaHandle,
+                  std::vector<real> *resAreaWork)
+{
+    const bool bResAt    = !resAreaWork->empty();
+    const bool bDGsolv   = !dgsFactor.empty();
+    real       totalArea = 0;
+    real       dgsolv    = 0;
+
+    if (bResAt)
+    {
+        std::fill(resAreaWork->begin(), resAreaWork->end(),
+                  static_cast<real>(0.0));
+    }
+    for (int i = 0; i < sel.posCount(); ++i)
+    {
+        // Get the index of the atom in the calculation group.
+        // For the output groups, the mapping has been precalculated in
+        // initAnalysis().
+        const int  ii = (sel != surfaceSel ? sel.position(i).mappedId() : i);
+        if (!surfaceSel.position(ii).selected())
+        {
+            // For the calculation group, skip unselected atoms.
+            if (sel == surfaceSel)
+            {
+                continue;
+            }
+            GMX_THROW(InconsistentInputError("Output selection is not a subset of the surface selection"));
+        }
+        // Get the internal index of the matching residue.
+        // These have been precalculated in initAnalysis().
+        const int  ri       = surfaceSel.position(ii).mappedId();
+        const real atomArea = atomAreas[ii];
+        totalArea += atomArea;
+        if (bResAt)
+        {
+            atomAreaHandle.setPoint(ii, atomArea);
+            (*resAreaWork)[ri] += atomArea;
+        }
+        if (bDGsolv)
+        {
+            dgsolv += atomArea * dgsFactor[ii];
+        }
+    }
+    if (bResAt)
+    {
+        for (size_t i = 0; i < (*resAreaWork).size(); ++i)
+        {
+            resAreaHandle.setPoint(i, (*resAreaWork)[i]);
+        }
+    }
+    *totalAreaOut = totalArea;
+    *dgsolvOut    = dgsolv;
+}
+
+void
+Sasa::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
+                   TrajectoryAnalysisModuleData *pdata)
+{
+    AnalysisDataHandle   ah         = pdata->dataHandle(area_);
+    AnalysisDataHandle   dgh        = pdata->dataHandle(dgSolv_);
+    AnalysisDataHandle   aah        = pdata->dataHandle(atomArea_);
+    AnalysisDataHandle   rah        = pdata->dataHandle(residueArea_);
+    AnalysisDataHandle   vh         = pdata->dataHandle(volume_);
+    const Selection     &surfaceSel = pdata->parallelSelection(surfaceSel_);
+    const SelectionList &outputSel  = pdata->parallelSelections(outputSel_);
+    SasaModuleData      &frameData  = *static_cast<SasaModuleData *>(pdata);
+
+    const bool           bResAt    = !frameData.res_a_.empty();
+    const bool           bDGsol    = !dgsFactor_.empty();
+    const bool           bConnolly = (frnr == 0 && !fnConnolly_.empty());
+
+    // Update indices of selected atoms in the work array.
+    if (surfaceSel.isDynamic())
+    {
+        frameData.index_.clear();
+        for (int i = 0; i < surfaceSel.posCount(); ++i)
+        {
+            if (surfaceSel.position(i).selected())
+            {
+                frameData.index_.push_back(i);
+            }
+        }
+    }
+
+    // Determine what needs to be calculated.
+    int                  flag      = 0;
+    if (bResAt || bDGsol || !outputSel.empty())
+    {
+        flag |= FLAG_ATOM_AREA;
+    }
+    if (bConnolly)
+    {
+        flag |= FLAG_DOTS;
+    }
+    if (volume_.columnCount() > 0)
+    {
+        flag |= FLAG_VOLUME;
+    }
+
+    // Do the low-level calculation.
+    // totarea and totvolume receive the values for the calculation group.
+    // area array contains the per-atom areas for the selected positions.
+    // surfacedots contains nsurfacedots entries, and contains the actual
+    // points.
+    real  totarea, totvolume;
+    real *area = NULL, *surfacedots = NULL;
+    int   nsurfacedots;
+    int   retval = nsc_dclm_pbc(surfaceSel.coordinates().data(), &radii_[0],
+                                frameData.index_.size(), ndots_, flag, &totarea,
+                                &area, &totvolume, &surfacedots, &nsurfacedots,
+                                &frameData.index_[0],
+                                pbc != NULL ? pbc->ePBC : epbcNONE,
+                                pbc != NULL ? pbc->box : NULL);
+    // Unpack the atomwise areas into the frameData.atomAreas_ array for easier
+    // indexing in the case of dynamic surfaceSel.
+    if (area != NULL)
+    {
+        if (surfaceSel.isDynamic())
+        {
+            std::fill(frameData.atomAreas_.begin(), frameData.atomAreas_.end(),
+                      static_cast<real>(0.0));
+            for (size_t i = 0; i < frameData.index_.size(); ++i)
+            {
+                frameData.atomAreas_[frameData.index_[i]] = area[i];
+            }
+        }
+        else
+        {
+            std::copy(area, area + surfaceSel.posCount(),
+                      frameData.atomAreas_.begin());
+        }
+        sfree(area);
+    }
+    scoped_ptr_sfree dotsGuard(surfacedots);
+    if (retval != 0)
+    {
+        GMX_THROW(InternalError("nsc_dclm_pbc failed"));
+    }
+
+    if (bConnolly)
+    {
+        // This is somewhat nasty, as it modifies the atoms and symtab
+        // structures.  But since it is only used in the first frame, and no
+        // one else uses the topology after initialization, it may just work
+        // even with future parallelization.
+        connolly_plot(fnConnolly_.c_str(),
+                      nsurfacedots, surfacedots, fr.x, &top_->atoms,
+                      &top_->symtab, fr.ePBC, fr.box, bIncludeSolute_);
+    }
+
+    ah.startFrame(frnr, fr.time);
+    if (bResAt)
+    {
+        aah.startFrame(frnr, fr.time);
+        rah.startFrame(frnr, fr.time);
+    }
+    if (bDGsol)
+    {
+        dgh.startFrame(frnr, fr.time);
+    }
+
+    ah.setPoint(0, totarea);
+
+    real totalArea, dgsolv;
+    if (bResAt || bDGsol)
+    {
+        computeAreas(surfaceSel, surfaceSel, frameData.atomAreas_, dgsFactor_,
+                     &totalArea, &dgsolv, aah, rah, &frameData.res_a_);
+        if (bDGsol)
+        {
+            dgh.setPoint(0, dgsolv);
+        }
+    }
+    for (size_t g = 0; g < outputSel.size(); ++g)
+    {
+        if (bResAt)
+        {
+            aah.selectDataSet(g + 1);
+            rah.selectDataSet(g + 1);
+        }
+        computeAreas(surfaceSel, outputSel[g], frameData.atomAreas_, dgsFactor_,
+                     &totalArea, &dgsolv, aah, rah, &frameData.res_a_);
+        ah.setPoint(g + 1, totalArea);
+        if (bDGsol)
+        {
+            dgh.setPoint(g + 1, dgsolv);
+        }
+    }
+
+    ah.finishFrame();
+    if (bResAt)
+    {
+        aah.finishFrame();
+        rah.finishFrame();
+    }
+    if (bDGsol)
+    {
+        dgh.finishFrame();
+    }
+
+    if (vh.isValid())
+    {
+        real totmass = 0;
+        for (int i = 0; i < surfaceSel.posCount(); ++i)
+        {
+            totmass += surfaceSel.position(i).mass();
+        }
+        const real density = totmass*AMU/(totvolume*NANO*NANO*NANO);
+        vh.startFrame(frnr, fr.time);
+        vh.setPoint(0, totvolume);
+        vh.setPoint(1, density);
+        vh.finishFrame();
+    }
+}
+
+void
+Sasa::finishAnalysis(int /*nframes*/)
+{
+    //if (bITP)
+    //{
+    //    fp3 = ftp2FILE(efITP, nfile, fnm, "w");
+    //    fprintf(fp3, "[ position_restraints ]\n"
+    //            "#define FCX 1000\n"
+    //            "#define FCY 1000\n"
+    //            "#define FCZ 1000\n"
+    //            "; Atom  Type  fx   fy   fz\n");
+    //    for (i = 0; i < nx[0]; i++)
+    //    {
+    //        if (atom_area[i] > minarea)
+    //        {
+    //            fprintf(fp3, "%5d   1     FCX  FCX  FCZ\n", ii+1);
+    //        }
+    //    }
+    //    ffclose(fp3);
+    //}
+}
+
+void
+Sasa::writeOutput()
+{
+}
+
+//! \}
+
+}       // namespace
+
+const char SasaInfo::name[]             = "sasa";
+const char SasaInfo::shortDescription[] =
+    "Compute solvent accessible surface area";
+
+TrajectoryAnalysisModulePointer SasaInfo::create()
+{
+    return TrajectoryAnalysisModulePointer(new Sasa);
+}
+
+} // namespace analysismodules
+
+} // namespace gmx
diff --git a/src/gromacs/trajectoryanalysis/modules/sasa.h b/src/gromacs/trajectoryanalysis/modules/sasa.h
new file mode 100644 (file)
index 0000000..dcf7329
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2013,2014, 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.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * Declares trajectory analysis module for surface area calculations.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \ingroup module_trajectoryanalysis
+ */
+#ifndef GMX_TRAJECTORYANALYSIS_MODULES_SASA_H
+#define GMX_TRAJECTORYANALYSIS_MODULES_SASA_H
+
+#include "../analysismodule.h"
+
+namespace gmx
+{
+
+namespace analysismodules
+{
+
+class SasaInfo
+{
+    public:
+        static const char name[];
+        static const char shortDescription[];
+        static TrajectoryAnalysisModulePointer create();
+};
+
+} // namespace analysismodules
+
+} // namespace gmx
+
+#endif
index 913645d7caa58c92b04acddb299d667e836ef8f8..a752e3f12d571320fea103721be22e6b46000bdd 100644 (file)
@@ -37,6 +37,7 @@ gmx_add_unit_test(TrajectoryAnalysisUnitTests trajectoryanalysis-test
                   angle.cpp
                   distance.cpp
                   freevolume.cpp
+                  sasa.cpp
                   select.cpp
                   $<TARGET_OBJECTS:analysisdata-test-shared>)
 
diff --git a/src/gromacs/trajectoryanalysis/tests/lysozyme.gro b/src/gromacs/trajectoryanalysis/tests/lysozyme.gro
new file mode 100644 (file)
index 0000000..ef9e9dd
--- /dev/null
@@ -0,0 +1,158 @@
+First 10 residues from 1AKI
+  155
+    1LYS      N    1   3.536   2.234  -1.198
+    1LYS     H1    2   3.612   2.288  -1.236
+    1LYS     H2    3   3.470   2.214  -1.270
+    1LYS     H3    4   3.492   2.286  -1.125
+    1LYS     CA    5   3.589   2.107  -1.143
+    1LYS     HA    6   3.633   2.055  -1.216
+    1LYS     CB    7   3.687   2.144  -1.031
+    1LYS    HB1    8   3.763   2.195  -1.070
+    1LYS    HB2    9   3.639   2.201  -0.964
+    1LYS     CG   10   3.745   2.025  -0.956
+    1LYS    HG1   11   3.676   1.989  -0.894
+    1LYS    HG2   12   3.770   1.954  -1.023
+    1LYS     CD   13   3.869   2.065  -0.877
+    1LYS    HD1   14   3.945   2.083  -0.940
+    1LYS    HD2   15   3.849   2.147  -0.824
+    1LYS     CE   16   3.906   1.951  -0.784
+    1LYS    HE1   17   3.841   1.946  -0.708
+    1LYS    HE2   18   3.906   1.864  -0.833
+    1LYS     NZ   19   4.042   1.977  -0.730
+    1LYS    HZ1   20   4.069   1.903  -0.668
+    1LYS    HZ2   21   4.108   1.982  -0.806
+    1LYS    HZ3   22   4.042   2.064  -0.680
+    1LYS      C   23   3.474   2.026  -1.084
+    1LYS      O   24   3.395   2.081  -1.008
+    2VAL      N   25   3.474   1.896  -1.104
+    2VAL      H   26   3.536   1.860  -1.174
+    2VAL     CA   27   3.390   1.800  -1.033
+    2VAL     HA   28   3.317   1.852  -0.990
+    2VAL     CB   29   3.314   1.703  -1.123
+    2VAL     HB   30   3.386   1.652  -1.170
+    2VAL    CG1   31   3.225   1.608  -1.043
+    2VAL   HG11   32   3.177   1.547  -1.106
+    2VAL   HG12   33   3.282   1.555  -0.981
+    2VAL   HG13   34   3.158   1.661  -0.991
+    2VAL    CG2   35   3.229   1.771  -1.229
+    2VAL   HG21   36   3.183   1.702  -1.284
+    2VAL   HG22   37   3.162   1.830  -1.185
+    2VAL   HG23   38   3.288   1.827  -1.288
+    2VAL      C   39   3.480   1.731  -0.929
+    2VAL      O   40   3.576   1.661  -0.966
+    3PHE      N   41   3.449   1.755  -0.804
+    3PHE      H   42   3.375   1.819  -0.784
+    3PHE     CA   43   3.519   1.690  -0.692
+    3PHE     HA   44   3.615   1.697  -0.717
+    3PHE     CB   45   3.497   1.763  -0.559
+    3PHE    HB1   46   3.405   1.802  -0.558
+    3PHE    HB2   47   3.506   1.698  -0.484
+    3PHE     CG   48   3.594   1.874  -0.538
+    3PHE    CD1   49   3.567   2.005  -0.580
+    3PHE    HD1   50   3.481   2.025  -0.627
+    3PHE    CD2   51   3.700   1.856  -0.447
+    3PHE    HD2   52   3.713   1.766  -0.405
+    3PHE    CE1   53   3.658   2.108  -0.557
+    3PHE    HE1   54   3.648   2.195  -0.604
+    3PHE    CE2   55   3.787   1.959  -0.416
+    3PHE    HE2   56   3.866   1.942  -0.357
+    3PHE     CZ   57   3.764   2.087  -0.467
+    3PHE     HZ   58   3.822   2.164  -0.439
+    3PHE      C   59   3.474   1.544  -0.677
+    3PHE      O   60   3.352   1.516  -0.686
+    4GLY      N   61   3.572   1.464  -0.633
+    4GLY      H   62   3.667   1.495  -0.632
+    4GLY     CA   63   3.537   1.328  -0.587
+    4GLY    HA1   64   3.462   1.292  -0.643
+    4GLY    HA2   65   3.616   1.268  -0.594
+    4GLY      C   66   3.492   1.342  -0.442
+    4GLY      O   67   3.530   1.440  -0.378
+    5ARG      N   68   3.405   1.254  -0.397
+    5ARG      H   69   3.371   1.184  -0.460
+    5ARG     CA   70   3.356   1.254  -0.259
+    5ARG     HA   71   3.298   1.334  -0.252
+    5ARG     CB   72   3.276   1.126  -0.233
+    5ARG    HB1   73   3.200   1.122  -0.297
+    5ARG    HB2   74   3.336   1.047  -0.247
+    5ARG     CG   75   3.221   1.120  -0.092
+    5ARG    HG1   76   3.297   1.117  -0.027
+    5ARG    HG2   77   3.165   1.201  -0.075
+    5ARG     CD   78   3.138   1.000  -0.072
+    5ARG    HD1   79   3.104   0.999   0.022
+    5ARG    HD2   80   3.060   1.005  -0.135
+    5ARG     NE   81   3.206   0.875  -0.096
+    5ARG     HE   82   3.202   0.840  -0.189
+    5ARG     CZ   83   3.273   0.801  -0.010
+    5ARG    NH1   84   3.284   0.833   0.119
+    5ARG   HH11   85   3.239   0.916   0.153
+    5ARG   HH12   86   3.336   0.775   0.181
+    5ARG    NH2   87   3.325   0.684  -0.053
+    5ARG   HH21   88   3.311   0.655  -0.147
+    5ARG   HH22   89   3.376   0.626   0.010
+    5ARG      C   90   3.467   1.273  -0.156
+    5ARG      O   91   3.467   1.365  -0.070
+    6CYS      N   92   3.567   1.185  -0.161
+    6CYS      H   93   3.567   1.116  -0.233
+    6CYS     CA   94   3.678   1.187  -0.065
+    6CYS     HA   95   3.631   1.202   0.022
+    6CYS     CB   96   3.749   1.053  -0.062
+    6CYS    HB1   97   3.770   1.034  -0.158
+    6CYS    HB2   98   3.834   1.072  -0.013
+    6CYS     SG   99   3.654   0.920   0.014
+    6CYS      C  100   3.775   1.305  -0.078
+    6CYS      O  101   3.815   1.361   0.026
+    7GLU      N  102   3.786   1.348  -0.202
+    7GLU      H  103   3.740   1.300  -0.276
+    7GLU     CA  104   3.868   1.469  -0.231
+    7GLU     HA  105   3.960   1.455  -0.193
+    7GLU     CB  106   3.878   1.485  -0.382
+    7GLU    HB1  107   3.923   1.402  -0.417
+    7GLU    HB2  108   3.785   1.489  -0.417
+    7GLU     CG  109   3.954   1.605  -0.438
+    7GLU    HG1  110   3.913   1.687  -0.399
+    7GLU    HG2  111   4.049   1.598  -0.407
+    7GLU     CD  112   3.958   1.624  -0.587
+    7GLU    OE1  113   3.867   1.564  -0.649
+    7GLU    OE2  114   4.042   1.695  -0.638
+    7GLU      C  115   3.805   1.593  -0.166
+    7GLU      O  116   3.874   1.673  -0.101
+    8LEU      N  117   3.674   1.605  -0.182
+    8LEU      H  118   3.626   1.535  -0.235
+    8LEU     CA  119   3.596   1.716  -0.125
+    8LEU     HA  120   3.640   1.801  -0.156
+    8LEU     CB  121   3.453   1.717  -0.181
+    8LEU    HB1  122   3.457   1.722  -0.281
+    8LEU    HB2  123   3.406   1.633  -0.153
+    8LEU     CG  124   3.372   1.835  -0.131
+    8LEU     HG  125   3.378   1.842  -0.031
+    8LEU    CD1  126   3.430   1.966  -0.184
+    8LEU   HD11  127   3.376   2.043  -0.150
+    8LEU   HD12  128   3.524   1.975  -0.153
+    8LEU   HD13  129   3.427   1.965  -0.284
+    8LEU    CD2  130   3.225   1.814  -0.160
+    8LEU   HD21  131   3.172   1.893  -0.126
+    8LEU   HD22  132   3.211   1.805  -0.258
+    8LEU   HD23  133   3.193   1.731  -0.114
+    8LEU      C  134   3.605   1.713   0.027
+    8LEU      O  135   3.616   1.817   0.092
+    9ALA      N  136   3.575   1.598   0.083
+    9ALA      H  137   3.546   1.522   0.024
+    9ALA     CA  138   3.584   1.576   0.228
+    9ALA     HA  139   3.508   1.626   0.269
+    9ALA     CB  140   3.566   1.429   0.262
+    9ALA    HB1  141   3.572   1.416   0.361
+    9ALA    HB2  142   3.476   1.398   0.230
+    9ALA    HB3  143   3.637   1.375   0.218
+    9ALA      C  144   3.714   1.631   0.284
+    9ALA      O  145   3.715   1.698   0.390
+   10ALA      N  146   3.827   1.598   0.220
+   10ALA      H  147   3.820   1.539   0.140
+   10ALA     CA  148   3.961   1.643   0.262
+   10ALA     HA  149   3.969   1.619   0.358
+   10ALA     CB  150   4.071   1.571   0.184
+   10ALA    HB1  151   4.160   1.603   0.215
+   10ALA    HB2  152   4.064   1.472   0.201
+   10ALA    HB3  153   4.060   1.589   0.086
+   10ALA      C  154   3.974   1.794   0.246
+   10ALA      O  155   4.019   1.850   0.347
+   5.90620   6.84510   3.05170
diff --git a/src/gromacs/trajectoryanalysis/tests/refdata/SasaModuleTest_BasicTest.xml b/src/gromacs/trajectoryanalysis/tests/refdata/SasaModuleTest_BasicTest.xml
new file mode 100644 (file)
index 0000000..91f8305
--- /dev/null
@@ -0,0 +1,1157 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <String Name="CommandLine">sasa -surface all -output 'name N CA C O H'</String>
+  <OutputData Name="Data">
+    <AnalysisData Name="area">
+      <DataFrame Name="Frame0">
+        <Real Name="X">0</Real>
+        <DataValues>
+          <Int Name="Count">2</Int>
+          <DataValue>
+            <Real Name="Value">11.879942829725929</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">2.2198340537623622</Real>
+          </DataValue>
+        </DataValues>
+      </DataFrame>
+    </AnalysisData>
+    <AnalysisData Name="atomarea">
+      <DataFrame Name="Frame0">
+        <Real Name="X">0</Real>
+        <DataValues>
+          <Int Name="Count">155</Int>
+          <Int Name="DataSet">0</Int>
+          <DataValue>
+            <Real Name="Value">0.034174637584831476</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.2389181213055038</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.2389181213055038</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1674154725098001</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.075476763502494812</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.034174637584831476</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.075476763502494812</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.034174637584831476</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.2389181213055038</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10252391275449443</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.03348309450196002</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.40212385965949349</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.03348309450196002</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13393237800784008</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10044928350588006</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15095352700498962</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.075476763502494812</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.30134785051764018</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.40179713402352024</Real>
+          </DataValue>
+        </DataValues>
+        <DataValues>
+          <Int Name="Count">155</Int>
+          <Int Name="DataSet">1</Int>
+          <DataValue>
+            <Real Name="Value">0.034174637584831476</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1674154725098001</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.075476763502494812</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.03348309450196002</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.03348309450196002</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10044928350588006</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.30134785051764018</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.40179713402352024</Real>
+          </DataValue>
+        </DataValues>
+      </DataFrame>
+    </AnalysisData>
+    <AnalysisData Name="resarea">
+      <DataFrame Name="Frame0">
+        <Real Name="X">0</Real>
+        <DataValues>
+          <Int Name="Count">10</Int>
+          <Int Name="DataSet">0</Int>
+          <DataValue>
+            <Real Name="Value">2.0779707251005344</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1.5688265482010961</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.95548398966280002</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.39403425857649987</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1.9788063529899724</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.78071090715829228</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.81812256327356647</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1.2125306713758435</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.85466085663114266</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1.238795956756181</Real>
+          </DataValue>
+        </DataValues>
+        <DataValues>
+          <Int Name="Count">10</Int>
+          <Int Name="DataSet">1</Int>
+          <DataValue>
+            <Real Name="Value">0.23507320459659159</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.30708439870309512</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.25824677010671504</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.075476763502494812</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.16621538411612879</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.060029552424793776</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10044928350588006</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.30134785051764018</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.51501227927726245</Real>
+          </DataValue>
+        </DataValues>
+      </DataFrame>
+    </AnalysisData>
+    <AnalysisData Name="volume">
+      <DataFrame Name="Frame0">
+        <Real Name="X">0</Real>
+        <DataValues>
+          <Int Name="Count">2</Int>
+          <DataValue>
+            <Real Name="Value">2.7441690613360836</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">698.86027894441133</Real>
+          </DataValue>
+        </DataValues>
+      </DataFrame>
+    </AnalysisData>
+  </OutputData>
+</ReferenceData>
diff --git a/src/gromacs/trajectoryanalysis/tests/refdata/SasaModuleTest_HandlesDynamicCalculationGroup.xml b/src/gromacs/trajectoryanalysis/tests/refdata/SasaModuleTest_HandlesDynamicCalculationGroup.xml
new file mode 100644 (file)
index 0000000..37fa6a7
--- /dev/null
@@ -0,0 +1,1228 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <String Name="CommandLine">sasa -surface 'y &gt; 1.5' -output 'y &gt; 1.5 and z &gt; 0'</String>
+  <OutputData Name="Data">
+    <AnalysisData Name="area">
+      <DataFrame Name="Frame0">
+        <Real Name="X">0</Real>
+        <DataValues>
+          <Int Name="Count">2</Int>
+          <DataValue>
+            <Real Name="Value">9.4969238506609042</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">2.3761644165939706</Real>
+          </DataValue>
+        </DataValues>
+      </DataFrame>
+    </AnalysisData>
+    <AnalysisData Name="atomarea">
+      <DataFrame Name="Frame0">
+        <Real Name="X">0</Real>
+        <DataValues>
+          <Int Name="Count">155</Int>
+          <Int Name="DataSet">0</Int>
+          <DataValue>
+            <Real Name="Value">0.034174637584831476</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.2389181213055038</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.2389181213055038</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.18869190875623704</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.26786475601568016</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15095352700498962</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10044928350588006</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15095352700498962</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.22643029050748442</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.30134785051764018</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.034174637584831476</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.26416867225873186</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.40179713402352024</Real>
+          </DataValue>
+        </DataValues>
+        <DataValues>
+          <Int Name="Count">155</Int>
+          <Int Name="DataSet">1</Int>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.22643029050748442</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.30134785051764018</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.034174637584831476</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.26416867225873186</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.40179713402352024</Real>
+          </DataValue>
+        </DataValues>
+      </DataFrame>
+    </AnalysisData>
+    <AnalysisData Name="resarea">
+      <DataFrame Name="Frame0">
+        <Real Name="X">0</Real>
+        <DataValues>
+          <Int Name="Count">10</Int>
+          <Int Name="DataSet">0</Int>
+          <DataValue>
+            <Real Name="Value">2.0779707251005344</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1.5688265482010961</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1.2068868001736697</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1.0165251349220497</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1.4514487926813473</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.85752755992754337</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1.3177382896546672</Real>
+          </DataValue>
+        </DataValues>
+        <DataValues>
+          <Int Name="Count">10</Int>
+          <Int Name="DataSet">1</Int>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.85752755992754337</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1.3177382896546672</Real>
+          </DataValue>
+        </DataValues>
+      </DataFrame>
+    </AnalysisData>
+  </OutputData>
+</ReferenceData>
diff --git a/src/gromacs/trajectoryanalysis/tests/refdata/SasaModuleTest_HandlesDynamicOutputGroup.xml b/src/gromacs/trajectoryanalysis/tests/refdata/SasaModuleTest_HandlesDynamicOutputGroup.xml
new file mode 100644 (file)
index 0000000..f209a71
--- /dev/null
@@ -0,0 +1,1090 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <String Name="CommandLine">sasa -surface all -output 'y &gt; 1.5'</String>
+  <OutputData Name="Data">
+    <AnalysisData Name="area">
+      <DataFrame Name="Frame0">
+        <Real Name="X">0</Real>
+        <DataValues>
+          <Int Name="Count">2</Int>
+          <DataValue>
+            <Real Name="Value">11.879942829725929</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">7.9341601835821569</Real>
+          </DataValue>
+        </DataValues>
+      </DataFrame>
+    </AnalysisData>
+    <AnalysisData Name="atomarea">
+      <DataFrame Name="Frame0">
+        <Real Name="X">0</Real>
+        <DataValues>
+          <Int Name="Count">155</Int>
+          <Int Name="DataSet">0</Int>
+          <DataValue>
+            <Real Name="Value">0.034174637584831476</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.2389181213055038</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.2389181213055038</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1674154725098001</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.075476763502494812</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.034174637584831476</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.075476763502494812</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.034174637584831476</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.2389181213055038</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10252391275449443</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.03348309450196002</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.40212385965949349</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.03348309450196002</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13393237800784008</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10044928350588006</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15095352700498962</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.075476763502494812</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.30134785051764018</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.40179713402352024</Real>
+          </DataValue>
+        </DataValues>
+        <DataValues>
+          <Int Name="Count">155</Int>
+          <Int Name="DataSet">1</Int>
+          <DataValue>
+            <Real Name="Value">0.034174637584831476</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.2389181213055038</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.079639373768501276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.2389181213055038</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10618583169133503</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.21237166338267005</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1674154725098001</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13393237800784008</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.10044928350588006</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.037738381751247406</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.026546457922833756</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15095352700498962</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.13273228961416877</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.20089856701176012</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.30134785051764018</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.15927874753700255</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.1858252054598363</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+            <Bool Name="Present">false</Bool>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.053092915845667513</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.11321514525374221</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.40179713402352024</Real>
+          </DataValue>
+        </DataValues>
+      </DataFrame>
+    </AnalysisData>
+    <AnalysisData Name="resarea">
+      <DataFrame Name="Frame0">
+        <Real Name="X">0</Real>
+        <DataValues>
+          <Int Name="Count">10</Int>
+          <Int Name="DataSet">0</Int>
+          <DataValue>
+            <Real Name="Value">2.0779707251005344</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1.5688265482010961</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.95548398966280002</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.39403425857649987</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1.9788063529899724</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.78071090715829228</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.81812256327356647</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1.2125306713758435</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.85466085663114266</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1.238795956756181</Real>
+          </DataValue>
+        </DataValues>
+        <DataValues>
+          <Int Name="Count">10</Int>
+          <Int Name="DataSet">1</Int>
+          <DataValue>
+            <Real Name="Value">2.0779707251005344</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1.5688265482010961</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.95548398966280002</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.63229735781373031</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1.2125306713758435</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0.46062659805464273</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1.026424293373511</Real>
+          </DataValue>
+        </DataValues>
+      </DataFrame>
+    </AnalysisData>
+  </OutputData>
+</ReferenceData>
diff --git a/src/gromacs/trajectoryanalysis/tests/refdata/SasaModuleTest_WritesConnollySurfaceWithSolute.xml b/src/gromacs/trajectoryanalysis/tests/refdata/SasaModuleTest_WritesConnollySurfaceWithSolute.xml
new file mode 100644 (file)
index 0000000..3294dd0
--- /dev/null
@@ -0,0 +1,215 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <String Name="CommandLine">sasa -surface 'atomnr 1'</String>
+  <OutputData Name="Data">
+    <AnalysisData Name="area">
+      <DataFrame Name="Frame0">
+        <Real Name="X">0</Real>
+        <DataValues>
+          <Int Name="Count">1</Int>
+          <DataValue>
+            <Real Name="Value">1.0935884027146072</Real>
+          </DataValue>
+        </DataValues>
+      </DataFrame>
+    </AnalysisData>
+  </OutputData>
+  <OutputFiles Name="Files">
+    <String Name="-q"><![CDATA[
+TITLE     Connolly Dot Surface Generated by gmx sasa
+REMARK    THIS IS A SIMULATION BOX
+CRYST1   59.062   68.451   30.517  90.00  90.00  90.00 P 1           1
+MODEL        1
+ATOM      1  N   LYS     1      35.360  22.340 -11.980  1.00  0.00            
+ATOM      2  H1  LYS     1      36.120  22.880 -12.360  1.00  0.00            
+ATOM      3  H2  LYS     1      34.700  22.140 -12.700  1.00  0.00            
+ATOM      4  H3  LYS     1      34.920  22.860 -11.250  1.00  0.00            
+ATOM      5  CA  LYS     1      35.890  21.070 -11.430  1.00  0.00            
+ATOM      6  HA  LYS     1      36.330  20.550 -12.160  1.00  0.00            
+ATOM      7  CB  LYS     1      36.870  21.440 -10.310  1.00  0.00            
+ATOM      8  HB1 LYS     1      37.630  21.950 -10.700  1.00  0.00            
+ATOM      9  HB2 LYS     1      36.390  22.010  -9.640  1.00  0.00            
+ATOM     10  CG  LYS     1      37.450  20.250  -9.560  1.00  0.00            
+ATOM     11  HG1 LYS     1      36.760  19.890  -8.940  1.00  0.00            
+ATOM     12  HG2 LYS     1      37.700  19.540 -10.230  1.00  0.00            
+ATOM     13  CD  LYS     1      38.690  20.650  -8.770  1.00  0.00            
+ATOM     14  HD1 LYS     1      39.450  20.830  -9.400  1.00  0.00            
+ATOM     15  HD2 LYS     1      38.490  21.470  -8.240  1.00  0.00            
+ATOM     16  CE  LYS     1      39.060  19.510  -7.840  1.00  0.00            
+ATOM     17  HE1 LYS     1      38.410  19.460  -7.080  1.00  0.00            
+ATOM     18  HE2 LYS     1      39.060  18.640  -8.330  1.00  0.00            
+ATOM     19  NZ  LYS     1      40.420  19.770  -7.300  1.00  0.00            
+ATOM     20  HZ1 LYS     1      40.690  19.030  -6.680  1.00  0.00            
+ATOM     21  HZ2 LYS     1      41.080  19.820  -8.060  1.00  0.00            
+ATOM     22  HZ3 LYS     1      40.420  20.640  -6.800  1.00  0.00            
+ATOM     23  C   LYS     1      34.740  20.260 -10.840  1.00  0.00            
+ATOM     24  O   LYS     1      33.950  20.810 -10.080  1.00  0.00            
+ATOM     25  N   VAL     2      34.740  18.960 -11.040  1.00  0.00            
+ATOM     26  H   VAL     2      35.360  18.600 -11.740  1.00  0.00            
+ATOM     27  CA  VAL     2      33.900  18.000 -10.330  1.00  0.00            
+ATOM     28  HA  VAL     2      33.170  18.520  -9.900  1.00  0.00            
+ATOM     29  CB  VAL     2      33.140  17.030 -11.230  1.00  0.00            
+ATOM     30  HB  VAL     2      33.860  16.520 -11.700  1.00  0.00            
+ATOM     31  CG1 VAL     2      32.250  16.080 -10.430  1.00  0.00            
+ATOM     32 1HG1 VAL     2      31.770  15.470 -11.060  1.00  0.00            
+ATOM     33 2HG1 VAL     2      32.820  15.550  -9.810  1.00  0.00            
+ATOM     34 3HG1 VAL     2      31.580  16.610  -9.910  1.00  0.00            
+ATOM     35  CG2 VAL     2      32.290  17.710 -12.290  1.00  0.00            
+ATOM     36 1HG2 VAL     2      31.830  17.020 -12.840  1.00  0.00            
+ATOM     37 2HG2 VAL     2      31.620  18.300 -11.850  1.00  0.00            
+ATOM     38 3HG2 VAL     2      32.880  18.270 -12.880  1.00  0.00            
+ATOM     39  C   VAL     2      34.800  17.310  -9.290  1.00  0.00            
+ATOM     40  O   VAL     2      35.760  16.610  -9.660  1.00  0.00            
+ATOM     41  N   PHE     3      34.490  17.550  -8.040  1.00  0.00            
+ATOM     42  H   PHE     3      33.750  18.190  -7.840  1.00  0.00            
+ATOM     43  CA  PHE     3      35.190  16.900  -6.920  1.00  0.00            
+ATOM     44  HA  PHE     3      36.150  16.970  -7.170  1.00  0.00            
+ATOM     45  CB  PHE     3      34.970  17.630  -5.590  1.00  0.00            
+ATOM     46  HB1 PHE     3      34.050  18.020  -5.580  1.00  0.00            
+ATOM     47  HB2 PHE     3      35.060  16.980  -4.840  1.00  0.00            
+ATOM     48  CG  PHE     3      35.940  18.740  -5.380  1.00  0.00            
+ATOM     49  CD1 PHE     3      35.670  20.050  -5.800  1.00  0.00            
+ATOM     50  HD1 PHE     3      34.810  20.250  -6.270  1.00  0.00            
+ATOM     51  CD2 PHE     3      37.000  18.560  -4.470  1.00  0.00            
+ATOM     52  HD2 PHE     3      37.130  17.660  -4.050  1.00  0.00            
+ATOM     53  CE1 PHE     3      36.580  21.080  -5.570  1.00  0.00            
+ATOM     54  HE1 PHE     3      36.480  21.950  -6.040  1.00  0.00            
+ATOM     55  CE2 PHE     3      37.870  19.590  -4.160  1.00  0.00            
+ATOM     56  HE2 PHE     3      38.660  19.420  -3.570  1.00  0.00            
+ATOM     57  CZ  PHE     3      37.640  20.870  -4.670  1.00  0.00            
+ATOM     58  HZ  PHE     3      38.220  21.640  -4.390  1.00  0.00            
+ATOM     59  C   PHE     3      34.740  15.440  -6.770  1.00  0.00            
+ATOM     60  O   PHE     3      33.520  15.160  -6.860  1.00  0.00            
+ATOM     61  N   GLY     4      35.720  14.640  -6.330  1.00  0.00            
+ATOM     62  H   GLY     4      36.670  14.950  -6.320  1.00  0.00            
+ATOM     63  CA  GLY     4      35.370  13.280  -5.870  1.00  0.00            
+ATOM     64  HA1 GLY     4      34.620  12.920  -6.430  1.00  0.00            
+ATOM     65  HA2 GLY     4      36.160  12.680  -5.940  1.00  0.00            
+ATOM     66  C   GLY     4      34.920  13.420  -4.420  1.00  0.00            
+ATOM     67  O   GLY     4      35.300  14.400  -3.780  1.00  0.00            
+ATOM     68  N   ARG     5      34.050  12.540  -3.970  1.00  0.00            
+ATOM     69  H   ARG     5      33.710  11.840  -4.600  1.00  0.00            
+ATOM     70  CA  ARG     5      33.560  12.540  -2.590  1.00  0.00            
+ATOM     71  HA  ARG     5      32.980  13.340  -2.520  1.00  0.00            
+ATOM     72  CB  ARG     5      32.760  11.260  -2.330  1.00  0.00            
+ATOM     73  HB1 ARG     5      32.000  11.220  -2.970  1.00  0.00            
+ATOM     74  HB2 ARG     5      33.360  10.470  -2.470  1.00  0.00            
+ATOM     75  CG  ARG     5      32.210  11.200  -0.920  1.00  0.00            
+ATOM     76  HG1 ARG     5      32.970  11.170  -0.270  1.00  0.00            
+ATOM     77  HG2 ARG     5      31.650  12.010  -0.750  1.00  0.00            
+ATOM     78  CD  ARG     5      31.380  10.000  -0.720  1.00  0.00            
+ATOM     79  HD1 ARG     5      31.040   9.990   0.220  1.00  0.00            
+ATOM     80  HD2 ARG     5      30.600  10.050  -1.350  1.00  0.00            
+ATOM     81  NE  ARG     5      32.060   8.750  -0.960  1.00  0.00            
+ATOM     82  HE  ARG     5      32.020   8.400  -1.890  1.00  0.00            
+ATOM     83  CZ  ARG     5      32.730   8.010  -0.100  1.00  0.00            
+ATOM     84  NH1 ARG     5      32.840   8.330   1.190  1.00  0.00            
+ATOM     85 1HH1 ARG     5      32.390   9.160   1.530  1.00  0.00            
+ATOM     86 2HH1 ARG     5      33.360   7.750   1.810  1.00  0.00            
+ATOM     87  NH2 ARG     5      33.250   6.840  -0.530  1.00  0.00            
+ATOM     88 1HH2 ARG     5      33.110   6.550  -1.470  1.00  0.00            
+ATOM     89 2HH2 ARG     5      33.760   6.260   0.100  1.00  0.00            
+ATOM     90  C   ARG     5      34.670  12.730  -1.560  1.00  0.00            
+ATOM     91  O   ARG     5      34.670  13.650  -0.700  1.00  0.00            
+ATOM     92  N   CYS     6      35.670  11.850  -1.610  1.00  0.00            
+ATOM     93  H   CYS     6      35.670  11.160  -2.330  1.00  0.00            
+ATOM     94  CA  CYS     6      36.780  11.870  -0.650  1.00  0.00            
+ATOM     95  HA  CYS     6      36.310  12.020   0.220  1.00  0.00            
+ATOM     96  CB  CYS     6      37.490  10.530  -0.620  1.00  0.00            
+ATOM     97  HB1 CYS     6      37.700  10.340  -1.580  1.00  0.00            
+ATOM     98  HB2 CYS     6      38.340  10.720  -0.130  1.00  0.00            
+ATOM     99  SG  CYS     6      36.540   9.200   0.140  1.00  0.00            
+ATOM    100  C   CYS     6      37.750  13.050  -0.780  1.00  0.00            
+ATOM    101  O   CYS     6      38.150  13.610   0.260  1.00  0.00            
+ATOM    102  N   GLU     7      37.860  13.480  -2.020  1.00  0.00            
+ATOM    103  H   GLU     7      37.400  13.000  -2.760  1.00  0.00            
+ATOM    104  CA  GLU     7      38.680  14.690  -2.310  1.00  0.00            
+ATOM    105  HA  GLU     7      39.600  14.550  -1.930  1.00  0.00            
+ATOM    106  CB  GLU     7      38.780  14.850  -3.820  1.00  0.00            
+ATOM    107  HB1 GLU     7      39.230  14.020  -4.170  1.00  0.00            
+ATOM    108  HB2 GLU     7      37.850  14.890  -4.170  1.00  0.00            
+ATOM    109  CG  GLU     7      39.540  16.050  -4.380  1.00  0.00            
+ATOM    110  HG1 GLU     7      39.130  16.870  -3.990  1.00  0.00            
+ATOM    111  HG2 GLU     7      40.490  15.980  -4.070  1.00  0.00            
+ATOM    112  CD  GLU     7      39.580  16.240  -5.870  1.00  0.00            
+ATOM    113  OE1 GLU     7      38.670  15.640  -6.490  1.00  0.00            
+ATOM    114  OE2 GLU     7      40.420  16.950  -6.380  1.00  0.00            
+ATOM    115  C   GLU     7      38.050  15.930  -1.660  1.00  0.00            
+ATOM    116  O   GLU     7      38.740  16.730  -1.010  1.00  0.00            
+ATOM    117  N   LEU     8      36.740  16.050  -1.820  1.00  0.00            
+ATOM    118  H   LEU     8      36.260  15.350  -2.350  1.00  0.00            
+ATOM    119  CA  LEU     8      35.960  17.160  -1.250  1.00  0.00            
+ATOM    120  HA  LEU     8      36.400  18.010  -1.560  1.00  0.00            
+ATOM    121  CB  LEU     8      34.530  17.170  -1.810  1.00  0.00            
+ATOM    122  HB1 LEU     8      34.570  17.220  -2.810  1.00  0.00            
+ATOM    123  HB2 LEU     8      34.060  16.330  -1.530  1.00  0.00            
+ATOM    124  CG  LEU     8      33.720  18.350  -1.310  1.00  0.00            
+ATOM    125  HG  LEU     8      33.780  18.420  -0.310  1.00  0.00            
+ATOM    126  CD1 LEU     8      34.300  19.660  -1.840  1.00  0.00            
+ATOM    127 1HD1 LEU     8      33.760  20.430  -1.500  1.00  0.00            
+ATOM    128 2HD1 LEU     8      35.240  19.750  -1.530  1.00  0.00            
+ATOM    129 3HD1 LEU     8      34.270  19.650  -2.840  1.00  0.00            
+ATOM    130  CD2 LEU     8      32.250  18.140  -1.600  1.00  0.00            
+ATOM    131 1HD2 LEU     8      31.720  18.930  -1.260  1.00  0.00            
+ATOM    132 2HD2 LEU     8      32.110  18.050  -2.580  1.00  0.00            
+ATOM    133 3HD2 LEU     8      31.930  17.310  -1.140  1.00  0.00            
+ATOM    134  C   LEU     8      36.050  17.130   0.270  1.00  0.00            
+ATOM    135  O   LEU     8      36.160  18.170   0.920  1.00  0.00            
+ATOM    136  N   ALA     9      35.750  15.980   0.830  1.00  0.00            
+ATOM    137  H   ALA     9      35.460  15.220   0.240  1.00  0.00            
+ATOM    138  CA  ALA     9      35.840  15.760   2.280  1.00  0.00            
+ATOM    139  HA  ALA     9      35.080  16.260   2.690  1.00  0.00            
+ATOM    140  CB  ALA     9      35.660  14.290   2.620  1.00  0.00            
+ATOM    141  HB1 ALA     9      35.720  14.160   3.610  1.00  0.00            
+ATOM    142  HB2 ALA     9      34.760  13.980   2.300  1.00  0.00            
+ATOM    143  HB3 ALA     9      36.370  13.750   2.180  1.00  0.00            
+ATOM    144  C   ALA     9      37.140  16.310   2.840  1.00  0.00            
+ATOM    145  O   ALA     9      37.150  16.980   3.900  1.00  0.00            
+ATOM    146  N   ALA    10      38.270  15.980   2.200  1.00  0.00            
+ATOM    147  H   ALA    10      38.200  15.390   1.400  1.00  0.00            
+ATOM    148  CA  ALA    10      39.610  16.430   2.620  1.00  0.00            
+ATOM    149  HA  ALA    10      39.690  16.190   3.580  1.00  0.00            
+ATOM    150  CB  ALA    10      40.710  15.710   1.840  1.00  0.00            
+ATOM    151  HB1 ALA    10      41.600  16.030   2.150  1.00  0.00            
+ATOM    152  HB2 ALA    10      40.640  14.720   2.010  1.00  0.00            
+ATOM    153  HB3 ALA    10      40.600  15.890   0.860  1.00  0.00            
+ATOM    154  C   ALA    10      39.740  17.940   2.460  1.00  0.00            
+ATOM    155  O   ALA    10      40.190  18.500   3.470  1.00  0.00            
+ATOM    156  DOT DOT    11      33.016  20.637 -12.533  1.00  0.00            
+ATOM    157  DOT DOT    11      33.225  20.789 -10.661  1.00  0.00            
+ATOM    158  DOT DOT    11      32.462  22.340 -11.427  1.00  0.00            
+ATOM    159  DOT DOT    11      33.569  22.340  -9.636  1.00  0.00            
+ATOM    160  DOT DOT    11      32.721  22.340 -13.299  1.00  0.00            
+ATOM    161  DOT DOT    11      33.016  24.043 -12.533  1.00  0.00            
+ATOM    162  DOT DOT    11      33.225  23.891 -10.661  1.00  0.00            
+ATOM    163  DOT DOT    11      34.545  19.831 -13.299  1.00  0.00            
+ATOM    164  DOT DOT    11      34.465  19.584 -11.427  1.00  0.00            
+ATOM    165  DOT DOT    11      34.807  20.637  -9.636  1.00  0.00            
+ATOM    166  DOT DOT    11      33.911  21.287 -14.324  1.00  0.00            
+ATOM    167  DOT DOT    11      33.911  23.393 -14.324  1.00  0.00            
+ATOM    168  DOT DOT    11      34.545  24.849 -13.299  1.00  0.00            
+ATOM    169  DOT DOT    11      34.465  25.096 -11.427  1.00  0.00            
+ATOM    170  DOT DOT    11      34.807  24.043  -9.636  1.00  0.00            
+ATOM    171  DOT DOT    11      35.913  20.637 -14.324  1.00  0.00            
+ATOM    172  DOT DOT    11      36.255  19.584 -12.533  1.00  0.00            
+ATOM    173  DOT DOT    11      36.175  19.831 -10.661  1.00  0.00            
+ATOM    174  DOT DOT    11      36.809  21.287  -9.636  1.00  0.00            
+ATOM    175  DOT DOT    11      35.360  22.340 -14.930  1.00  0.00            
+ATOM    176  DOT DOT    11      36.809  23.393  -9.636  1.00  0.00            
+ATOM    177  DOT DOT    11      35.360  22.340  -9.030  1.00  0.00            
+ATOM    178  DOT DOT    11      35.913  24.043 -14.324  1.00  0.00            
+ATOM    179  DOT DOT    11      36.255  25.096 -12.533  1.00  0.00            
+ATOM    180  DOT DOT    11      36.175  24.849 -10.661  1.00  0.00            
+ATOM    181  DOT DOT    11      37.495  20.789 -13.299  1.00  0.00            
+ATOM    182  DOT DOT    11      37.704  20.637 -11.427  1.00  0.00            
+ATOM    183  DOT DOT    11      37.151  22.340 -14.324  1.00  0.00            
+ATOM    184  DOT DOT    11      38.258  22.340 -12.533  1.00  0.00            
+ATOM    185  DOT DOT    11      37.999  22.340 -10.661  1.00  0.00            
+ATOM    186  DOT DOT    11      37.495  23.891 -13.299  1.00  0.00            
+ATOM    187  DOT DOT    11      37.704  24.043 -11.427  1.00  0.00            
+TER
+ENDMDL
+]]></String>
+  </OutputFiles>
+</ReferenceData>
diff --git a/src/gromacs/trajectoryanalysis/tests/sasa.cpp b/src/gromacs/trajectoryanalysis/tests/sasa.cpp
new file mode 100644 (file)
index 0000000..1295979
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2014, 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.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * Tests for functionality of the "sasa" trajectory analysis module.
+ *
+ * These tests test the basic functionality of the tool itself, but currently
+ * the following are missing:
+ *  - Tests related to -odg output.  This would require a full tpr file, and
+ *    some investigation on what kind of tpr it should be to produce reasonable
+ *    output.
+ *  - Tests for the X axes in the area per atom/residue plots.  These could be
+ *    added once better X axes are implemented.
+ *  - Tests for XVG labels.  This is a limitation of the current testing
+ *    framework.
+ *
+ * The actual surface area algorithm should be tested separately with a more
+ * extensive set of data, but those fit better as a separate set of unit tests.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \ingroup module_trajectoryanalysis
+ */
+#include <gtest/gtest.h>
+
+#include "gromacs/trajectoryanalysis/modules/sasa.h"
+
+#include "testutils/cmdlinetest.h"
+#include "testutils/testasserts.h"
+
+#include "moduletest.h"
+
+namespace
+{
+
+using gmx::test::CommandLine;
+
+/********************************************************************
+ * Tests for gmx::analysismodules::Sas.
+ */
+
+//! Test fixture for the select analysis module.
+typedef gmx::test::TrajectoryAnalysisModuleTestFixture<gmx::analysismodules::SasaInfo>
+    SasaModuleTest;
+
+TEST_F(SasaModuleTest, BasicTest)
+{
+    const char *const cmdline[] = {
+        "sasa",
+        "-surface", "all",
+        "-output", "name N CA C O H"
+    };
+    setTopology("lysozyme.gro");
+    setOutputFileNoTest("-o", "xvg");
+    setOutputFileNoTest("-or", "xvg");
+    setOutputFileNoTest("-oa", "xvg");
+    setOutputFileNoTest("-tv", "xvg");
+    excludeDataset("dgsolv");
+    setDatasetTolerance("area", gmx::test::ulpTolerance(8));
+    setDatasetTolerance("volume", gmx::test::ulpTolerance(8));
+    runTest(CommandLine(cmdline));
+}
+
+TEST_F(SasaModuleTest, WritesConnollySurfaceWithSolute)
+{
+    const char *const cmdline[] = {
+        "sasa",
+        "-surface", "atomnr 1"
+    };
+    setTopology("lysozyme.gro");
+    setOutputFileNoTest("-o", "xvg");
+    setOutputFile("-q", "connolly.pdb");
+    includeDataset("area");
+    runTest(CommandLine(cmdline));
+}
+
+// The CONECT records written to the output make this very difficult to test
+// without parsing the output file, since by construction, there are a lot of
+// dot pairs that are at exactly the same distance from each other in exact
+// arithmetic, and depending on rounding etc., different pairs get picked into
+// the output for single and double precision.
+#if 0
+TEST_F(SasaModuleTest, WritesConnollySurfaceWithoutSolute)
+{
+    const char *const cmdline[] = {
+        "sasa",
+        "-surface", "atomnr 1",
+        "-noprot"
+    };
+    setTopology("lysozyme.gro");
+    setOutputFileNoTest("-o", "xvg");
+    setOutputFile("-q", "connolly.pdb");
+    includeDataset("area");
+    runTest(CommandLine(cmdline));
+}
+#endif
+
+TEST_F(SasaModuleTest, HandlesDynamicOutputGroup)
+{
+    const char *const cmdline[] = {
+        "sasa",
+        "-surface", "all",
+        "-output", "y > 1.5"
+    };
+    setTopology("lysozyme.gro");
+    setOutputFileNoTest("-o", "xvg");
+    setOutputFileNoTest("-or", "xvg");
+    setOutputFileNoTest("-oa", "xvg");
+    excludeDataset("volume");
+    excludeDataset("dgsolv");
+    setDatasetTolerance("area", gmx::test::ulpTolerance(8));
+    runTest(CommandLine(cmdline));
+}
+
+TEST_F(SasaModuleTest, HandlesDynamicCalculationGroup)
+{
+    const char *const cmdline[] = {
+        "sasa",
+        "-surface", "y > 1.5",
+        "-output", "y > 1.5 and z > 0"
+    };
+    setTopology("lysozyme.gro");
+    setOutputFileNoTest("-o", "xvg");
+    setOutputFileNoTest("-or", "xvg");
+    setOutputFileNoTest("-oa", "xvg");
+    excludeDataset("volume");
+    excludeDataset("dgsolv");
+    setDatasetTolerance("area", gmx::test::ulpTolerance(8));
+    runTest(CommandLine(cmdline));
+}
+
+} // namespace
index e032cde9af498292fa24f246485ae9525131cc9e..3abc47c6c9526630b5bf6a916dc554b60c0a5e29 100644 (file)
@@ -207,6 +207,7 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager)
                    "Calculate free energy difference estimates through Bennett's acceptance ratio");
     registerObsoleteTool(manager, "bond");
     registerObsoleteTool(manager, "dist");
+    registerObsoleteTool(manager, "sas");
     registerObsoleteTool(manager, "sgangle");
 
     registerModule(manager, &gmx_bundle, "bundle",
@@ -306,8 +307,6 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager)
                    "Compute salt bridges");
     registerModule(manager, &gmx_sans, "sans",
                    "Compute small angle neutron scattering spectra");
-    registerModule(manager, &gmx_sas, "sas",
-                   "Compute solvent accessible surface area");
     registerModule(manager, &gmx_saxs, "saxs",
                    "Compute small angle X-ray scattering spectra");
     registerModule(manager, &gmx_sham, "sham",
@@ -449,7 +448,6 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager)
         group.addModule("principal");
         group.addModule("rdf");
         group.addModule("saltbr");
-        group.addModule("sas");
         group.addModule("sorient");
         group.addModule("spol");
     }