Example #1
0
int gmx_make_ndx(int argc, char *argv[])
{
    const char     *desc[] = {
        "Index groups are necessary for almost every GROMACS program.",
        "All these programs can generate default index groups. You ONLY",
        "have to use [THISMODULE] when you need SPECIAL index groups.",
        "There is a default index group for the whole system, 9 default",
        "index groups for proteins, and a default index group",
        "is generated for every other residue name.",
        "",
        "When no index file is supplied, also [THISMODULE] will generate the",
        "default groups.",
        "With the index editor you can select on atom, residue and chain names",
        "and numbers.",
        "When a run input file is supplied you can also select on atom type.",
        "You can use boolean operations, you can split groups",
        "into chains, residues or atoms. You can delete and rename groups.",
        "Type 'h' in the editor for more details.",
        "",
        "The atom numbering in the editor and the index file starts at 1.",
        "",
        "The [TT]-twin[tt] switch duplicates all index groups with an offset of",
        "[TT]-natoms[tt], which is useful for Computational Electrophysiology",
        "double-layer membrane setups.",
        "",
        "See also [gmx-select] [TT]-on[tt], which provides an alternative way",
        "for constructing index groups.  It covers nearly all of [THISMODULE]",
        "functionality, and in many cases much more."
    };

    static int      natoms     = 0;
    static gmx_bool bVerbose   = FALSE;
    static gmx_bool bDuplicate = FALSE;
    t_pargs         pa[]       = {
        { "-natoms",  FALSE, etINT, {&natoms},
          "set number of atoms (default: read from coordinate or index file)" },
        { "-twin",     FALSE, etBOOL, {&bDuplicate},
          "Duplicate all index groups with an offset of -natoms" },
        { "-verbose", FALSE, etBOOL, {&bVerbose},
          "HIDDENVerbose output" }
    };
#define NPA asize(pa)

    gmx_output_env_t *oenv;
    const char       *stxfile;
    const char       *ndxoutfile;
    gmx_bool          bNatoms;
    int               j;
    t_atoms          *atoms;
    rvec             *x, *v;
    int               ePBC;
    matrix            box;
    t_blocka         *block, *block2;
    char            **gnames, **gnames2;
    t_filenm          fnm[] = {
        { efSTX, "-f", nullptr,     ffOPTRD  },
        { efNDX, "-n", nullptr,     ffOPTRDMULT },
        { efNDX, "-o", nullptr,     ffWRITE }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, 0, NFILE, fnm, NPA, pa, asize(desc), desc,
                           0, nullptr, &oenv))
    {
        return 0;
    }

    stxfile = ftp2fn_null(efSTX, NFILE, fnm);
    gmx::ArrayRef<const std::string> ndxInFiles = opt2fnsIfOptionSet("-n", NFILE, fnm);
    ndxoutfile = opt2fn("-o", NFILE, fnm);
    bNatoms    = opt2parg_bSet("-natoms", NPA, pa);

    if (!stxfile && ndxInFiles.empty())
    {
        gmx_fatal(FARGS, "No input files (structure or index)");
    }

    if (stxfile)
    {
        t_topology *top;
        snew(top, 1);
        fprintf(stderr, "\nReading structure file\n");
        read_tps_conf(stxfile, top, &ePBC, &x, &v, box, FALSE);
        atoms = &top->atoms;
        if (atoms->pdbinfo == nullptr)
        {
            snew(atoms->pdbinfo, atoms->nr);
        }
        natoms  = atoms->nr;
        bNatoms = TRUE;
    }
    else
    {
        atoms = nullptr;
        x     = nullptr;
    }

    /* read input file(s) */
    block  = new_blocka();
    gnames = nullptr;
    printf("Going to read %td old index file(s)\n", ndxInFiles.size());
    if (!ndxInFiles.empty())
    {
        for (const std::string &ndxInFile : ndxInFiles)
        {
            block2 = init_index(ndxInFile.c_str(), &gnames2);
            srenew(gnames, block->nr+block2->nr);
            for (j = 0; j < block2->nr; j++)
            {
                gnames[block->nr+j] = gnames2[j];
            }
            sfree(gnames2);
            merge_blocks(block, block2);
            sfree(block2->a);
            sfree(block2->index);
/*       done_block(block2); */
            sfree(block2);
        }
    }
    else
    {
        snew(gnames, 1);
        analyse(atoms, block, &gnames, FALSE, TRUE);
    }

    if (!bNatoms)
    {
        natoms = block2natoms(block);
        printf("Counted atom numbers up to %d in index file\n", natoms);
    }

    edit_index(natoms, atoms, x, block, &gnames, bVerbose);

    write_index(ndxoutfile, block, gnames, bDuplicate, natoms);

    return 0;
}
Example #2
0
int gmx_spatial(int argc, char *argv[])
{
    const char       *desc[] = {
        "[THISMODULE] calculates the spatial distribution function and",
        "outputs it in a form that can be read by VMD as Gaussian98 cube format.",
        "For a system of 32,000 atoms and a 50 ns trajectory, the SDF can be generated",
        "in about 30 minutes, with most of the time dedicated to the two runs through",
        "[TT]trjconv[tt] that are required to center everything properly.",
        "This also takes a whole bunch of space (3 copies of the trajectory file).",
        "Still, the pictures are pretty and very informative when the fitted selection is properly made.",
        "3-4 atoms in a widely mobile group (like a free amino acid in solution) works",
        "well, or select the protein backbone in a stable folded structure to get the SDF",
        "of solvent and look at the time-averaged solvation shell.",
        "It is also possible using this program to generate the SDF based on some arbitrary",
        "Cartesian coordinate. To do that, simply omit the preliminary [gmx-trjconv] steps.",
        "",
        "Usage:",
        "",
        "1. Use [gmx-make_ndx] to create a group containing the atoms around which you want the SDF",
        "2. [TT]gmx trjconv -s a.tpr -f a.tng -o b.tng -boxcenter tric -ur compact -pbc none[tt]",
        "3. [TT]gmx trjconv -s a.tpr -f b.tng -o c.tng -fit rot+trans[tt]",
        "4. run [THISMODULE] on the [TT]c.tng[tt] output of step #3.",
        "5. Load [TT]grid.cube[tt] into VMD and view as an isosurface.",
        "",
        "[BB]Note[bb] that systems such as micelles will require [TT]gmx trjconv -pbc cluster[tt] between steps 1 and 2.",
        "",
        "Warnings",
        "^^^^^^^^",
        "",
        "The SDF will be generated for a cube that contains all bins that have some non-zero occupancy.",
        "However, the preparatory [TT]-fit rot+trans[tt] option to [gmx-trjconv] implies that your system will be rotating",
        "and translating in space (in order that the selected group does not). Therefore the values that are",
        "returned will only be valid for some region around your central group/coordinate that has full overlap",
        "with system volume throughout the entire translated/rotated system over the course of the trajectory.",
        "It is up to the user to ensure that this is the case.",
        "",
        "Risky options",
        "^^^^^^^^^^^^^",
        "",
        "To reduce the amount of space and time required, you can output only the coords",
        "that are going to be used in the first and subsequent run through [gmx-trjconv].",
        "However, be sure to set the [TT]-nab[tt] option to a sufficiently high value since",
        "memory is allocated for cube bins based on the initial coordinates and the [TT]-nab[tt]",
        "option value."
    };
    const char       *bugs[] = {
        "When the allocated memory is not large enough, a segmentation fault may occur. This is usually detected "
        "and the program is halted prior to the fault while displaying a warning message suggesting the use of the [TT]-nab[tt] (Number of Additional Bins) "
        "option. However, the program does not detect all such events. If you encounter a segmentation fault, run it again "
        "with an increased [TT]-nab[tt] value."
    };

    static gmx_bool   bPBC         = FALSE;
    static int        iIGNOREOUTER = -1;   /*Positive values may help if the surface is spikey */
    static gmx_bool   bCUTDOWN     = TRUE;
    static real       rBINWIDTH    = 0.05; /* nm */
    static gmx_bool   bCALCDIV     = TRUE;
    static int        iNAB         = 4;

    t_pargs           pa[] = {
        { "-pbc",      FALSE, etBOOL, {&bPBC},
          "Use periodic boundary conditions for computing distances" },
        { "-div",      FALSE, etBOOL, {&bCALCDIV},
          "Calculate and apply the divisor for bin occupancies based on atoms/minimal cube size. Set as TRUE for visualization and as FALSE ([TT]-nodiv[tt]) to get accurate counts per frame" },
        { "-ign",      FALSE, etINT, {&iIGNOREOUTER},
          "Do not display this number of outer cubes (positive values may reduce boundary speckles; -1 ensures outer surface is visible)" },
        /*    { "-cut",      bCUTDOWN, etBOOL, {&bCUTDOWN},*/
        /*      "Display a total cube that is of minimal size" }, */
        { "-bin",      FALSE, etREAL, {&rBINWIDTH},
          "Width of the bins (nm)" },
        { "-nab",      FALSE, etINT, {&iNAB},
          "Number of additional bins to ensure proper memory allocation" }
    };

    double            MINBIN[3];
    double            MAXBIN[3];
    t_topology        top;
    int               ePBC;
    t_trxframe        fr;
    rvec             *xtop;
    matrix            box, box_pbc;
    t_trxstatus      *status;
    int               flags = TRX_READ_X;
    t_pbc             pbc;
    t_atoms          *atoms;
    int               natoms;
    char             *grpnm, *grpnmp;
    int              *index, *indexp;
    int               i, nidx, nidxp;
    int               v;
    int               j, k;
    int            ***bin = NULL;
    int               nbin[3];
    FILE             *flp;
    int               x, y, z, minx, miny, minz, maxx, maxy, maxz;
    int               numfr, numcu;
    int               tot, maxval, minval;
    double            norm;
    gmx_output_env_t *oenv;
    gmx_rmpbc_t       gpbc = NULL;

    t_filenm          fnm[] = {
        { efTPS,  NULL,  NULL, ffREAD }, /* this is for the topology */
        { efTRX, "-f", NULL, ffREAD },   /* and this for the trajectory */
        { efNDX, NULL, NULL, ffOPTRD }
    };

#define NFILE asize(fnm)

    /* This is the routine responsible for adding default options,
     * calling the X/motif interface, etc. */
    if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv))
    {
        return 0;
    }

    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtop, NULL, box, TRUE);
    sfree(xtop);

    atoms = &(top.atoms);
    printf("Select group to generate SDF:\n");
    get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &nidx, &index, &grpnm);
    printf("Select group to output coords (e.g. solute):\n");
    get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &nidxp, &indexp, &grpnmp);

    /* The first time we read data is a little special */
    natoms = read_first_frame(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &fr, flags);

    /* Memory Allocation */
    MINBIN[XX] = MAXBIN[XX] = fr.x[0][XX];
    MINBIN[YY] = MAXBIN[YY] = fr.x[0][YY];
    MINBIN[ZZ] = MAXBIN[ZZ] = fr.x[0][ZZ];
    for (i = 1; i < top.atoms.nr; ++i)
    {
        if (fr.x[i][XX] < MINBIN[XX])
        {
            MINBIN[XX] = fr.x[i][XX];
        }
        if (fr.x[i][XX] > MAXBIN[XX])
        {
            MAXBIN[XX] = fr.x[i][XX];
        }
        if (fr.x[i][YY] < MINBIN[YY])
        {
            MINBIN[YY] = fr.x[i][YY];
        }
        if (fr.x[i][YY] > MAXBIN[YY])
        {
            MAXBIN[YY] = fr.x[i][YY];
        }
        if (fr.x[i][ZZ] < MINBIN[ZZ])
        {
            MINBIN[ZZ] = fr.x[i][ZZ];
        }
        if (fr.x[i][ZZ] > MAXBIN[ZZ])
        {
            MAXBIN[ZZ] = fr.x[i][ZZ];
        }
    }
    for (i = ZZ; i >= XX; --i)
    {
        MAXBIN[i]  = (std::ceil((MAXBIN[i]-MINBIN[i])/rBINWIDTH)+iNAB)*rBINWIDTH+MINBIN[i];
        MINBIN[i] -= iNAB*rBINWIDTH;
        nbin[i]    = static_cast<int>(std::ceil((MAXBIN[i]-MINBIN[i])/rBINWIDTH));
    }
    snew(bin, nbin[XX]);
    for (i = 0; i < nbin[XX]; ++i)
    {
        snew(bin[i], nbin[YY]);
        for (j = 0; j < nbin[YY]; ++j)
        {
            snew(bin[i][j], nbin[ZZ]);
        }
    }
    copy_mat(box, box_pbc);
    numfr = 0;
    minx  = miny = minz = 999;
    maxx  = maxy = maxz = 0;

    if (bPBC)
    {
        gpbc = gmx_rmpbc_init(&top.idef, ePBC, natoms);
    }
    /* This is the main loop over frames */
    do
    {
        /* Must init pbc every step because of pressure coupling */

        copy_mat(box, box_pbc);
        if (bPBC)
        {
            gmx_rmpbc_trxfr(gpbc, &fr);
            set_pbc(&pbc, ePBC, box_pbc);
        }

        for (i = 0; i < nidx; i++)
        {
            if (fr.x[index[i]][XX] < MINBIN[XX] || fr.x[index[i]][XX] > MAXBIN[XX] ||
                fr.x[index[i]][YY] < MINBIN[YY] || fr.x[index[i]][YY] > MAXBIN[YY] ||
                fr.x[index[i]][ZZ] < MINBIN[ZZ] || fr.x[index[i]][ZZ] > MAXBIN[ZZ])
            {
                printf("There was an item outside of the allocated memory. Increase the value given with the -nab option.\n");
                printf("Memory was allocated for [%f,%f,%f]\tto\t[%f,%f,%f]\n", MINBIN[XX], MINBIN[YY], MINBIN[ZZ], MAXBIN[XX], MAXBIN[YY], MAXBIN[ZZ]);
                printf("Memory was required for [%f,%f,%f]\n", fr.x[index[i]][XX], fr.x[index[i]][YY], fr.x[index[i]][ZZ]);
                exit(1);
            }
            x = static_cast<int>(std::ceil((fr.x[index[i]][XX]-MINBIN[XX])/rBINWIDTH));
            y = static_cast<int>(std::ceil((fr.x[index[i]][YY]-MINBIN[YY])/rBINWIDTH));
            z = static_cast<int>(std::ceil((fr.x[index[i]][ZZ]-MINBIN[ZZ])/rBINWIDTH));
            ++bin[x][y][z];
            if (x < minx)
            {
                minx = x;
            }
            if (x > maxx)
            {
                maxx = x;
            }
            if (y < miny)
            {
                miny = y;
            }
            if (y > maxy)
            {
                maxy = y;
            }
            if (z < minz)
            {
                minz = z;
            }
            if (z > maxz)
            {
                maxz = z;
            }
        }
        numfr++;
        /* printf("%f\t%f\t%f\n",box[XX][XX],box[YY][YY],box[ZZ][ZZ]); */

    }
    while (read_next_frame(oenv, status, &fr));

    if (bPBC)
    {
        gmx_rmpbc_done(gpbc);
    }

    if (!bCUTDOWN)
    {
        minx = miny = minz = 0;
        maxx = nbin[XX];
        maxy = nbin[YY];
        maxz = nbin[ZZ];
    }

    /* OUTPUT */
    flp = gmx_ffopen("grid.cube", "w");
    fprintf(flp, "Spatial Distribution Function\n");
    fprintf(flp, "test\n");
    fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", nidxp, (MINBIN[XX]+(minx+iIGNOREOUTER)*rBINWIDTH)*10./bohr, (MINBIN[YY]+(miny+iIGNOREOUTER)*rBINWIDTH)*10./bohr, (MINBIN[ZZ]+(minz+iIGNOREOUTER)*rBINWIDTH)*10./bohr);
    fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxx-minx+1-(2*iIGNOREOUTER), rBINWIDTH*10./bohr, 0., 0.);
    fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxy-miny+1-(2*iIGNOREOUTER), 0., rBINWIDTH*10./bohr, 0.);
    fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxz-minz+1-(2*iIGNOREOUTER), 0., 0., rBINWIDTH*10./bohr);
    for (i = 0; i < nidxp; i++)
    {
        v = 2;
        if (*(top.atoms.atomname[indexp[i]][0]) == 'C')
        {
            v = 6;
        }
        if (*(top.atoms.atomname[indexp[i]][0]) == 'N')
        {
            v = 7;
        }
        if (*(top.atoms.atomname[indexp[i]][0]) == 'O')
        {
            v = 8;
        }
        if (*(top.atoms.atomname[indexp[i]][0]) == 'H')
        {
            v = 1;
        }
        if (*(top.atoms.atomname[indexp[i]][0]) == 'S')
        {
            v = 16;
        }
        fprintf(flp, "%5d%12.6f%12.6f%12.6f%12.6f\n", v, 0., fr.x[indexp[i]][XX]*10.0/bohr, fr.x[indexp[i]][YY]*10.0/bohr, fr.x[indexp[i]][ZZ]*10.0/bohr);
    }

    tot = 0;
    for (k = 0; k < nbin[XX]; k++)
    {
        if (!(k < minx || k > maxx))
        {
            continue;
        }
        for (j = 0; j < nbin[YY]; j++)
        {
            if (!(j < miny || j > maxy))
            {
                continue;
            }
            for (i = 0; i < nbin[ZZ]; i++)
            {
                if (!(i < minz || i > maxz))
                {
                    continue;
                }
                if (bin[k][j][i] != 0)
                {
                    printf("A bin was not empty when it should have been empty. Programming error.\n");
                    printf("bin[%d][%d][%d] was = %d\n", k, j, i, bin[k][j][i]);
                    exit(1);
                }
            }
        }
    }

    minval = 999;
    maxval = 0;
    for (k = 0; k < nbin[XX]; k++)
    {
        if (k < minx+iIGNOREOUTER || k > maxx-iIGNOREOUTER)
        {
            continue;
        }
        for (j = 0; j < nbin[YY]; j++)
        {
            if (j < miny+iIGNOREOUTER || j > maxy-iIGNOREOUTER)
            {
                continue;
            }
            for (i = 0; i < nbin[ZZ]; i++)
            {
                if (i < minz+iIGNOREOUTER || i > maxz-iIGNOREOUTER)
                {
                    continue;
                }
                tot += bin[k][j][i];
                if (bin[k][j][i] > maxval)
                {
                    maxval = bin[k][j][i];
                }
                if (bin[k][j][i] < minval)
                {
                    minval = bin[k][j][i];
                }
            }
        }
    }

    numcu = (maxx-minx+1-(2*iIGNOREOUTER))*(maxy-miny+1-(2*iIGNOREOUTER))*(maxz-minz+1-(2*iIGNOREOUTER));
    if (bCALCDIV)
    {
        norm = static_cast<double>(numcu*numfr)/tot;
    }
    else
    {
        norm = 1.0;
    }

    for (k = 0; k < nbin[XX]; k++)
    {
        if (k < minx+iIGNOREOUTER || k > maxx-iIGNOREOUTER)
        {
            continue;
        }
        for (j = 0; j < nbin[YY]; j++)
        {
            if (j < miny+iIGNOREOUTER || j > maxy-iIGNOREOUTER)
            {
                continue;
            }
            for (i = 0; i < nbin[ZZ]; i++)
            {
                if (i < minz+iIGNOREOUTER || i > maxz-iIGNOREOUTER)
                {
                    continue;
                }
                fprintf(flp, "%12.6f ", static_cast<double>(norm*bin[k][j][i])/numfr);
            }
            fprintf(flp, "\n");
        }
        fprintf(flp, "\n");
    }
    gmx_ffclose(flp);

    if (bCALCDIV)
    {
        printf("Counts per frame in all %d cubes divided by %le\n", numcu, 1.0/norm);
        printf("Normalized data: average %le, min %le, max %le\n", 1.0, minval*norm/numfr, maxval*norm/numfr);
    }
    else
    {
        printf("grid.cube contains counts per frame in all %d cubes\n", numcu);
        printf("Raw data: average %le, min %le, max %le\n", 1.0/norm, static_cast<double>(minval)/numfr, static_cast<double>(maxval)/numfr);
    }

    return 0;
}
Example #3
0
int gmx_pme_error(int argc,char *argv[])
{
    const char *desc[] = {
            "g_pme_error estimates the error of the electrostatic forces",
            "if using the SPME algorithm. The flag [TT]-tune[tt] will determine",
            "the splitting parameter such that the error is equally",
            "distributed over the real and reciprocal space part.",
            "As a part of the error stems from self interaction of the particles "
            "and is computationally very demanding a good a approximation is possible",
            "if just a fraction of the particles is used to calculate the average",
            "of this error by using the flag [TT]-self[tt].[PAR]",
    };

    int        repeats=2;
    real       fs=0.0;             /* 0 indicates: not set by the user */

    real        user_beta=-1.0;
    real        fracself=-1.0;
    
    
    t_perf      **perfdata;
    t_inputinfo info;
    t_state     state;     /* The state from the tpr input file */
    gmx_mtop_t  mtop;      /* The topology from the tpr input file */
    t_inputrec  *ir=NULL;  /* The inputrec from the tpr file */
    FILE        *fp=NULL;
    t_commrec   *cr;
    unsigned long PCA_Flags;
    gmx_bool        bTUNE=FALSE;


    static t_filenm fnm[] = {
      /* g_tune_pme */
      { efTPX, "-s",     NULL,    ffREAD },
      { efOUT, "-o",    "error",  ffWRITE },
      { efTPX, "-so",   "tuned",  ffOPTWR }
    };


    output_env_t oenv=NULL;

    t_pargs pa[] = {
      /***********************/
      /* g_tune_pme options: */
      /***********************/
        { "-beta",     FALSE, etREAL, {&user_beta},
            "If positive, overwrite ewald_beta from tpr file with this value" },
        { "-tune",     FALSE, etBOOL, {&bTUNE},
            "If flag is set the splitting parameter will be tuned to distribute the error equally in real and rec. space" },
        { "-self",     FALSE, etREAL, {&fracself},
            "If positive, determine selfinteraction error just over this fraction (default=1.0)" }
    };

    
#define NFILE asize(fnm)
    
    cr = init_par(&argc,&argv);
    
    if (MASTER(cr))
      CopyRight(stderr,argv[0]);
    
    PCA_Flags = PCA_NOEXIT_ON_ARGS;
    PCA_Flags |= (MASTER(cr) ? 0 : PCA_QUIET);
    
    parse_common_args(&argc,argv,PCA_Flags,
                      NFILE,fnm,asize(pa),pa,asize(desc),desc,
                      0,NULL,&oenv);        

    if (!bTUNE)
        bTUNE = opt2bSet("-so",NFILE,fnm);

    info.n_entries = 1;
    
    /* Allocate memory for the inputinfo struct: */
    create_info(&info);
    info.fourier_sp[0] = fs;
    
    /* Read in the tpr file and open logfile for reading */
    if (MASTER(cr))
    {
        snew(ir,1);
        read_tpr_file(opt2fn("-s",NFILE,fnm), &info, &state, &mtop, ir, user_beta,fracself);

        fp=fopen(opt2fn("-o",NFILE,fnm),"w");
    }
    
    /* Check consistency if the user provided fourierspacing */
    if (fs > 0 && MASTER(cr))
    {
        /* Recalculate the grid dimensions using fourierspacing from user input */
        info.nkx[0] = 0;
        info.nky[0] = 0;
        info.nkz[0] = 0;
        calc_grid(stdout,state.box,info.fourier_sp[0],&(info.nkx[0]),&(info.nky[0]),&(info.nkz[0]));
        if ( (ir->nkx != info.nkx[0]) || (ir->nky != info.nky[0]) || (ir->nkz != info.nkz[0]) )
            gmx_fatal(FARGS, "Wrong fourierspacing %f nm, input file grid = %d x %d x %d, computed grid = %d x %d x %d", 
                      fs,ir->nkx,ir->nky,ir->nkz,info.nkx[0],info.nky[0],info.nkz[0]);
    }
    
    /* Estimate (S)PME force error */

    /* Determine the volume of the simulation box */
    if (MASTER(cr))
    {
        info.volume = det(state.box);
        calc_recipbox(state.box,info.recipbox);
        info.natoms = mtop.natoms;
        info.bTUNE  = bTUNE;
    }   

    if (PAR(cr))
        bcast_info(&info, cr);
    
    /* Get an error estimate of the input tpr file */
    estimate_PME_error(&info, &state, &mtop, fp, cr);
    
    if (MASTER(cr))
    {
        ir->ewald_rtol=info.ewald_rtol[0];
        write_tpx_state(opt2fn("-so",NFILE,fnm),ir,&state,&mtop);
        please_cite(fp,"Wang2010");
        fclose(fp);
    }
    
    if (gmx_parallel_env_initialized())
    {
        gmx_finalize();
    }
    
    return 0;
}
Example #4
0
int gmx_sorient(int argc, char *argv[])
{
    t_topology        top;
    int               ePBC = -1;
    t_trxstatus      *status;
    int               natoms;
    real              t;
    rvec             *xtop, *x;
    matrix            box;

    FILE             *fp;
    int               i, p, sa0, sa1, sa2, n, ntot, nf, m, *hist1, *hist2, *histn, nbin1, nbin2, nrbin;
    real             *histi1, *histi2, invbw, invrbw;
    double            sum1, sum2;
    int              *isize, nrefgrp, nrefat;
    int             **index;
    char            **grpname;
    real              inp, outp, nav, normfac, rmin2, rmax2, rcut, rcut2, r2, r;
    real              c1, c2;
    char              str[STRLEN];
    gmx_bool          bTPS;
    rvec              xref, dx, dxh1, dxh2, outer;
    gmx_rmpbc_t       gpbc = NULL;
    t_pbc             pbc;
    const char       *legr[] = {
        "<cos(\\8q\\4\\s1\\N)>",
        "<3cos\\S2\\N(\\8q\\4\\s2\\N)-1>"
    };
    const char       *legc[] = {
        "cos(\\8q\\4\\s1\\N)",
        "3cos\\S2\\N(\\8q\\4\\s2\\N)-1"
    };

    const char       *desc[] = {
        "[THISMODULE] analyzes solvent orientation around solutes.",
        "It calculates two angles between the vector from one or more",
        "reference positions to the first atom of each solvent molecule:",
        "",
        " * [GRK]theta[grk][SUB]1[sub]: the angle with the vector from the first atom of the solvent",
        "   molecule to the midpoint between atoms 2 and 3.",
        " * [GRK]theta[grk][SUB]2[sub]: the angle with the normal of the solvent plane, defined by the",
        "   same three atoms, or, when the option [TT]-v23[tt] is set, ",
        "   the angle with the vector between atoms 2 and 3.",
        "",
        "The reference can be a set of atoms or",
        "the center of mass of a set of atoms. The group of solvent atoms should",
        "consist of 3 atoms per solvent molecule.",
        "Only solvent molecules between [TT]-rmin[tt] and [TT]-rmax[tt] are",
        "considered for [TT]-o[tt] and [TT]-no[tt] each frame.[PAR]",
        "[TT]-o[tt]: distribtion of [MATH][COS][GRK]theta[grk][SUB]1[sub][cos][math] for rmin<=r<=rmax.[PAR]",
        "[TT]-no[tt]: distribution of [MATH][COS][GRK]theta[grk][SUB]2[sub][cos][math] for rmin<=r<=rmax.[PAR]",
        "[TT]-ro[tt]: [MATH][CHEVRON][COS][GRK]theta[grk][SUB]1[sub][cos][chevron][math] and [MATH][CHEVRON]3[COS]^2[GRK]theta[grk][SUB]2[sub][cos]-1[chevron][math] as a function of the",
        "distance.[PAR]",
        "[TT]-co[tt]: the sum over all solvent molecules within distance r",
        "of [MATH][COS][GRK]theta[grk][SUB]1[sub][cos][math] and [MATH]3[COS]^2([GRK]theta[grk][SUB]2[sub])-1[cos][math] as a function of r.[PAR]",
        "[TT]-rc[tt]: the distribution of the solvent molecules as a function of r"
    };

    gmx_output_env_t *oenv;
    static gmx_bool   bCom = FALSE, bVec23 = FALSE, bPBC = FALSE;
    static real       rmin = 0.0, rmax = 0.5, binwidth = 0.02, rbinw = 0.02;
    t_pargs           pa[] = {
        {   "-com",  FALSE, etBOOL,  {&bCom},
            "Use the center of mass as the reference postion"
        },
        {   "-v23",  FALSE, etBOOL,  {&bVec23},
            "Use the vector between atoms 2 and 3"
        },
        { "-rmin",  FALSE, etREAL, {&rmin}, "Minimum distance (nm)" },
        { "-rmax",  FALSE, etREAL, {&rmax}, "Maximum distance (nm)" },
        { "-cbin",  FALSE, etREAL, {&binwidth}, "Binwidth for the cosine" },
        { "-rbin",  FALSE, etREAL, {&rbinw}, "Binwidth for r (nm)" },
        { "-pbc",   FALSE, etBOOL, {&bPBC}, "Check PBC for the center of mass calculation. Only necessary when your reference group consists of several molecules." }
    };

    t_filenm          fnm[] = {
        { efTRX, NULL,  NULL,  ffREAD },
        { efTPS, NULL,  NULL,  ffREAD },
        { efNDX, NULL,  NULL,  ffOPTRD },
        { efXVG, NULL,  "sori",   ffWRITE },
        { efXVG, "-no", "snor",   ffWRITE },
        { efXVG, "-ro", "sord",   ffWRITE },
        { efXVG, "-co", "scum",   ffWRITE },
        { efXVG, "-rc", "scount", ffWRITE }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    bTPS = (opt2bSet("-s", NFILE, fnm) || !opt2bSet("-n", NFILE, fnm) || bCom);
    if (bTPS)
    {
        read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtop, NULL, box,
                      bCom);
    }

    /* get index groups */
    printf("Select a group of reference particles and a solvent group:\n");
    snew(grpname, 2);
    snew(index, 2);
    snew(isize, 2);
    if (bTPS)
    {
        get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 2, isize, index, grpname);
    }
    else
    {
        get_index(NULL, ftp2fn(efNDX, NFILE, fnm), 2, isize, index, grpname);
    }

    if (bCom)
    {
        nrefgrp = 1;
        nrefat  = isize[0];
    }
    else
    {
        nrefgrp = isize[0];
        nrefat  = 1;
    }

    if (isize[1] % 3)
    {
        gmx_fatal(FARGS, "The number of solvent atoms (%d) is not a multiple of 3",
                  isize[1]);
    }

    /* initialize reading trajectory:                         */
    natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);

    rmin2 = sqr(rmin);
    rmax2 = sqr(rmax);
    rcut  = 0.99*std::sqrt(max_cutoff2(guess_ePBC(box), box));
    if (rcut == 0)
    {
        rcut = 10*rmax;
    }
    rcut2 = sqr(rcut);

    invbw = 1/binwidth;
    nbin1 = 1+static_cast<int>(2*invbw + 0.5);
    nbin2 = 1+static_cast<int>(invbw + 0.5);

    invrbw = 1/rbinw;

    snew(hist1, nbin1);
    snew(hist2, nbin2);
    nrbin = 1+static_cast<int>(rcut/rbinw);
    if (nrbin == 0)
    {
        nrbin = 1;
    }
    snew(histi1, nrbin);
    snew(histi2, nrbin);
    snew(histn, nrbin);

    ntot = 0;
    nf   = 0;
    sum1 = 0;
    sum2 = 0;

    if (bTPS)
    {
        /* make molecules whole again */
        gpbc = gmx_rmpbc_init(&top.idef, ePBC, natoms);
    }
    /* start analysis of trajectory */
    do
    {
        if (bTPS)
        {
            /* make molecules whole again */
            gmx_rmpbc(gpbc, natoms, box, x);
        }

        set_pbc(&pbc, ePBC, box);
        n    = 0;
        inp  = 0;
        for (p = 0; (p < nrefgrp); p++)
        {
            if (bCom)
            {
                calc_com_pbc(nrefat, &top, x, &pbc, index[0], xref, bPBC);
            }
            else
            {
                copy_rvec(x[index[0][p]], xref);
            }

            for (m = 0; m < isize[1]; m += 3)
            {
                sa0 = index[1][m];
                sa1 = index[1][m+1];
                sa2 = index[1][m+2];
                range_check(sa0, 0, natoms);
                range_check(sa1, 0, natoms);
                range_check(sa2, 0, natoms);
                pbc_dx(&pbc, x[sa0], xref, dx);
                r2  = norm2(dx);
                if (r2 < rcut2)
                {
                    r = std::sqrt(r2);
                    if (!bVec23)
                    {
                        /* Determine the normal to the plain */
                        rvec_sub(x[sa1], x[sa0], dxh1);
                        rvec_sub(x[sa2], x[sa0], dxh2);
                        rvec_inc(dxh1, dxh2);
                        svmul(1/r, dx, dx);
                        unitv(dxh1, dxh1);
                        inp = iprod(dx, dxh1);
                        cprod(dxh1, dxh2, outer);
                        unitv(outer, outer);
                        outp = iprod(dx, outer);
                    }
                    else
                    {
                        /* Use the vector between the 2nd and 3rd atom */
                        rvec_sub(x[sa2], x[sa1], dxh2);
                        unitv(dxh2, dxh2);
                        outp = iprod(dx, dxh2)/r;
                    }
                    {
                        int ii = static_cast<int>(invrbw*r);
                        range_check(ii, 0, nrbin);
                        histi1[ii] += inp;
                        histi2[ii] += 3*sqr(outp) - 1;
                        histn[ii]++;
                    }
                    if ((r2 >= rmin2) && (r2 < rmax2))
                    {
                        int ii1 = static_cast<int>(invbw*(inp + 1));
                        int ii2 = static_cast<int>(invbw*std::abs(outp));

                        range_check(ii1, 0, nbin1);
                        range_check(ii2, 0, nbin2);
                        hist1[ii1]++;
                        hist2[ii2]++;
                        sum1 += inp;
                        sum2 += outp;
                        n++;
                    }
                }
            }
        }
        ntot += n;
        nf++;

    }
    while (read_next_x(oenv, status, &t, x, box));

    /* clean up */
    sfree(x);
    close_trj(status);
    gmx_rmpbc_done(gpbc);

    /* Add the bin for the exact maximum to the previous bin */
    hist1[nbin1-1] += hist1[nbin1];
    hist2[nbin2-1] += hist2[nbin2];

    nav     = static_cast<real>(ntot)/(nrefgrp*nf);
    normfac = invbw/ntot;

    fprintf(stderr,  "Average nr of molecules between %g and %g nm: %.1f\n",
            rmin, rmax, nav);
    if (ntot > 0)
    {
        sum1 /= ntot;
        sum2 /= ntot;
        fprintf(stderr, "Average cos(theta1)     between %g and %g nm: %6.3f\n",
                rmin, rmax, sum1);
        fprintf(stderr, "Average 3cos2(theta2)-1 between %g and %g nm: %6.3f\n",
                rmin, rmax, sum2);
    }

    sprintf(str, "Solvent orientation between %g and %g nm", rmin, rmax);
    fp = xvgropen(opt2fn("-o", NFILE, fnm), str, "cos(\\8q\\4\\s1\\N)", "", oenv);
    if (output_env_get_print_xvgr_codes(oenv))
    {
        fprintf(fp, "@ subtitle \"average shell size %.1f molecules\"\n", nav);
    }
    for (i = 0; i < nbin1; i++)
    {
        fprintf(fp, "%g %g\n", (i+0.5)*binwidth-1, 2*normfac*hist1[i]);
    }
    xvgrclose(fp);

    sprintf(str, "Solvent normal orientation between %g and %g nm", rmin, rmax);
    fp = xvgropen(opt2fn("-no", NFILE, fnm), str, "cos(\\8q\\4\\s2\\N)", "", oenv);
    if (output_env_get_print_xvgr_codes(oenv))
    {
        fprintf(fp, "@ subtitle \"average shell size %.1f molecules\"\n", nav);
    }
    for (i = 0; i < nbin2; i++)
    {
        fprintf(fp, "%g %g\n", (i+0.5)*binwidth, normfac*hist2[i]);
    }
    xvgrclose(fp);


    sprintf(str, "Solvent orientation");
    fp = xvgropen(opt2fn("-ro", NFILE, fnm), str, "r (nm)", "", oenv);
    if (output_env_get_print_xvgr_codes(oenv))
    {
        fprintf(fp, "@ subtitle \"as a function of distance\"\n");
    }
    xvgr_legend(fp, 2, legr, oenv);
    for (i = 0; i < nrbin; i++)
    {
        fprintf(fp, "%g %g %g\n", (i+0.5)*rbinw,
                histn[i] ? histi1[i]/histn[i] : 0,
                histn[i] ? histi2[i]/histn[i] : 0);
    }
    xvgrclose(fp);

    sprintf(str, "Cumulative solvent orientation");
    fp = xvgropen(opt2fn("-co", NFILE, fnm), str, "r (nm)", "", oenv);
    if (output_env_get_print_xvgr_codes(oenv))
    {
        fprintf(fp, "@ subtitle \"as a function of distance\"\n");
    }
    xvgr_legend(fp, 2, legc, oenv);
    normfac = 1.0/(nrefgrp*nf);
    c1      = 0;
    c2      = 0;
    fprintf(fp, "%g %g %g\n", 0.0, c1, c2);
    for (i = 0; i < nrbin; i++)
    {
        c1 += histi1[i]*normfac;
        c2 += histi2[i]*normfac;
        fprintf(fp, "%g %g %g\n", (i+1)*rbinw, c1, c2);
    }
    xvgrclose(fp);

    sprintf(str, "Solvent distribution");
    fp = xvgropen(opt2fn("-rc", NFILE, fnm), str, "r (nm)", "molecules/nm", oenv);
    if (output_env_get_print_xvgr_codes(oenv))
    {
        fprintf(fp, "@ subtitle \"as a function of distance\"\n");
    }
    normfac = 1.0/(rbinw*nf);
    for (i = 0; i < nrbin; i++)
    {
        fprintf(fp, "%g %g\n", (i+0.5)*rbinw, histn[i]*normfac);
    }
    xvgrclose(fp);

    do_view(oenv, opt2fn("-o", NFILE, fnm), NULL);
    do_view(oenv, opt2fn("-no", NFILE, fnm), NULL);
    do_view(oenv, opt2fn("-ro", NFILE, fnm), "-nxy");
    do_view(oenv, opt2fn("-co", NFILE, fnm), "-nxy");

    return 0;
}
Example #5
0
int gmx_dielectric(int argc, char *argv[])
{
    const char  *desc[] = {
        "[THISMODULE] calculates frequency dependent dielectric constants",
        "from the autocorrelation function of the total dipole moment in",
        "your simulation. This ACF can be generated by [gmx-dipoles].",
        "The functional forms of the available functions are:[PAR]",
        "One parameter:    y = [EXP]-a[SUB]1[sub] x[exp],[BR]",
        "Two parameters:   y = a[SUB]2[sub] [EXP]-a[SUB]1[sub] x[exp],[BR]",
        "Three parameters: y = a[SUB]2[sub] [EXP]-a[SUB]1[sub] x[exp] + (1 - a[SUB]2[sub]) [EXP]-a[SUB]3[sub] x[exp].[BR]",
        "Start values for the fit procedure can be given on the command line.",
        "It is also possible to fix parameters at their start value, use [TT]-fix[tt]",
        "with the number of the parameter you want to fix.",
        "[PAR]",
        "Three output files are generated, the first contains the ACF,",
        "an exponential fit to it with 1, 2 or 3 parameters, and the",
        "numerical derivative of the combination data/fit.",
        "The second file contains the real and imaginary parts of the",
        "frequency-dependent dielectric constant, the last gives a plot",
        "known as the Cole-Cole plot, in which the imaginary",
        "component is plotted as a function of the real component.",
        "For a pure exponential relaxation (Debye relaxation) the latter",
        "plot should be one half of a circle."
    };
    t_filenm     fnm[] = {
        { efXVG, "-f", "dipcorr", ffREAD  },
        { efXVG, "-d", "deriv",  ffWRITE },
        { efXVG, "-o", "epsw",   ffWRITE },
        { efXVG, "-c", "cole",   ffWRITE }
    };
#define NFILE asize(fnm)
    output_env_t oenv;
    int          i, j, nx, ny, nxtail, eFitFn, nfitparm;
    real         dt, integral, fitintegral, fac, rffac;
    double      *fitparms;
    double     **yd;
    real       **y;
    const char  *legend[] = { "Correlation", "Std. Dev.", "Fit", "Combined", "Derivative" };
    static int   fix      = 0, bX = 1, nsmooth = 3;
    static real  tendInt  = 5.0, tbegin = 5.0, tend = 500.0;
    static real  A        = 0.5, tau1 = 10.0, tau2 = 1.0, eps0 = 80, epsRF = 78.5, tail = 500.0;
    real         lambda;
    t_pargs      pa[] = {
        { "-x1",  FALSE, etBOOL, {&bX},
          "use first column as [IT]x[it]-axis rather than first data set" },
        { "-eint", FALSE, etREAL, {&tendInt},
          "Time to end the integration of the data and start to use the fit"},
        { "-bfit", FALSE, etREAL, {&tbegin},
          "Begin time of fit" },
        { "-efit", FALSE, etREAL, {&tend},
          "End time of fit" },
        { "-tail", FALSE, etREAL, {&tail},
          "Length of function including data and tail from fit" },
        { "-A", FALSE, etREAL, {&A},
          "Start value for fit parameter A" },
        { "-tau1", FALSE, etREAL, {&tau1},
          "Start value for fit parameter [GRK]tau[grk]1" },
        { "-tau2", FALSE, etREAL, {&tau2},
          "Start value for fit parameter [GRK]tau[grk]2" },
        { "-eps0", FALSE, etREAL, {&eps0},
          "[GRK]epsilon[grk]0 of your liquid" },
        { "-epsRF", FALSE, etREAL, {&epsRF},
          "[GRK]epsilon[grk] of the reaction field used in your simulation. A value of 0 means infinity." },
        { "-fix", FALSE, etINT,  {&fix},
          "Fix parameters at their start values, A (2), tau1 (1), or tau2 (4)" },
        { "-ffn",    FALSE, etENUM, {s_ffn},
          "Fit function" },
        { "-nsmooth", FALSE, etINT, {&nsmooth},
          "Number of points for smoothing" }
    };

    if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }
    please_cite(stdout, "Spoel98a");
    printf("WARNING: non-polarizable models can never yield an infinite\n"
           "dielectric constant that is different from 1. This is incorrect\n"
           "in the reference given above (Spoel98a).\n\n");


    nx     = read_xvg(opt2fn("-f", NFILE, fnm), &yd, &ny);
    dt     = yd[0][1] - yd[0][0];
    nxtail = min(tail/dt, nx);

    printf("Read data set containing %d colums and %d rows\n", ny, nx);
    printf("Assuming (from data) that timestep is %g, nxtail = %d\n",
           dt, nxtail);
    snew(y, 6);
    for (i = 0; (i < ny); i++)
    {
        snew(y[i], max(nx, nxtail));
    }
    for (i = 0; (i < nx); i++)
    {
        y[0][i] = yd[0][i];
        for (j = 1; (j < ny); j++)
        {
            y[j][i] = yd[j][i];
        }
    }
    if (nxtail > nx)
    {
        for (i = nx; (i < nxtail); i++)
        {
            y[0][i] = dt*i+y[0][0];
            for (j = 1; (j < ny); j++)
            {
                y[j][i] = 0.0;
            }
        }
        nx = nxtail;
    }


    /* We have read a file WITHOUT standard deviations, so we make our own... */
    if (ny == 2)
    {
        printf("Creating standard deviation numbers ...\n");
        srenew(y, 3);
        snew(y[2], nx);

        fac = 1.0/((real)nx);
        for (i = 0; (i < nx); i++)
        {
            y[2][i] = fac;
        }
    }

    eFitFn   = sffn2effn(s_ffn);
    nfitparm = effnNparams(eFitFn);
    snew(fitparms, 4);
    fitparms[0] = tau1;
    if (nfitparm > 1)
    {
        fitparms[1] = A;
    }
    if (nfitparm > 2)
    {
        fitparms[2] = tau2;
    }


    snew(y[3], nx);
    snew(y[4], nx);
    snew(y[5], nx);

    integral = print_and_integrate(NULL, calc_nbegin(nx, y[0], tbegin),
                                   dt, y[1], NULL, 1);
    integral += do_lmfit(nx, y[1], y[2], dt, y[0], tbegin, tend,
                         oenv, TRUE, eFitFn, fitparms, fix);
    for (i = 0; i < nx; i++)
    {
        y[3][i] = fit_function(eFitFn, fitparms, y[0][i]);
    }

    if (epsRF == 0)
    {
        /* This means infinity! */
        lambda = 0;
        rffac  = 1;
    }
    else
    {
        lambda = (eps0 - 1.0)/(2*epsRF - 1.0);
        rffac  = (2*epsRF+eps0)/(2*epsRF+1);
    }
    printf("DATA INTEGRAL: %5.1f, tauD(old) = %5.1f ps, "
           "tau_slope = %5.1f, tau_slope,D = %5.1f ps\n",
           integral, integral*rffac, fitparms[0], fitparms[0]*rffac);

    printf("tau_D from tau1 = %8.3g , eps(Infty) = %8.3f\n",
           fitparms[0]*(1 + fitparms[1]*lambda),
           1 + ((1 - fitparms[1])*(eps0 - 1))/(1 + fitparms[1]*lambda));

    fitintegral = numerical_deriv(nx, y[0], y[1], y[3], y[4], y[5], tendInt, nsmooth);
    printf("FIT INTEGRAL (tau_M): %5.1f, tau_D = %5.1f\n",
           fitintegral, fitintegral*rffac);

    /* Now we have the negative gradient of <Phi(0) Phi(t)> */
    write_xvg(opt2fn("-d", NFILE, fnm), "Data", nx-1, 6, y, legend, oenv);

    /* Do FFT and analysis */
    do_four(opt2fn("-o", NFILE, fnm), opt2fn("-c", NFILE, fnm),
            nx-1, y[0], y[5], eps0, epsRF, oenv);

    do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy");
    do_view(oenv, opt2fn("-c", NFILE, fnm), NULL);
    do_view(oenv, opt2fn("-d", NFILE, fnm), "-nxy");

    return 0;
}
Example #6
0
int gmx_mindist(int argc, char *argv[])
{
    const char     *desc[] = {
        "[THISMODULE] computes the distance between one group and a number of",
        "other groups. Both the minimum distance",
        "(between any pair of atoms from the respective groups)",
        "and the number of contacts within a given",
        "distance are written to two separate output files.",
        "With the [TT]-group[tt] option a contact of an atom in another group",
        "with multiple atoms in the first group is counted as one contact",
        "instead of as multiple contacts.",
        "With [TT]-or[tt], minimum distances to each residue in the first",
        "group are determined and plotted as a function of residue number.[PAR]",
        "With option [TT]-pi[tt] the minimum distance of a group to its",
        "periodic image is plotted. This is useful for checking if a protein",
        "has seen its periodic image during a simulation. Only one shift in",
        "each direction is considered, giving a total of 26 shifts.",
        "It also plots the maximum distance within the group and the lengths",
        "of the three box vectors.[PAR]",
        "Also [gmx-distance] calculates distances."
    };
    const char     *bugs[] = {
        "The [TT]-pi[tt] option is very slow."
    };

    static gmx_bool bMat             = FALSE, bPI = FALSE, bSplit = FALSE, bMax = FALSE, bPBC = TRUE;
    static gmx_bool bGroup           = FALSE;
    static real     rcutoff          = 0.6;
    static int      ng               = 1;
    static gmx_bool bEachResEachTime = FALSE, bPrintResName = FALSE;
    t_pargs         pa[]             = {
        { "-matrix", FALSE, etBOOL, {&bMat},
          "Calculate half a matrix of group-group distances" },
        { "-max",    FALSE, etBOOL, {&bMax},
          "Calculate *maximum* distance instead of minimum" },
        { "-d",      FALSE, etREAL, {&rcutoff},
          "Distance for contacts" },
        { "-group",      FALSE, etBOOL, {&bGroup},
          "Count contacts with multiple atoms in the first group as one" },
        { "-pi",     FALSE, etBOOL, {&bPI},
          "Calculate minimum distance with periodic images" },
        { "-split",  FALSE, etBOOL, {&bSplit},
          "Split graph where time is zero" },
        { "-ng",       FALSE, etINT, {&ng},
          "Number of secondary groups to compute distance to a central group" },
        { "-pbc",    FALSE, etBOOL, {&bPBC},
          "Take periodic boundary conditions into account" },
        { "-respertime",  FALSE, etBOOL, {&bEachResEachTime},
          "When writing per-residue distances, write distance for each time point" },
        { "-printresname",  FALSE, etBOOL, {&bPrintResName},
          "Write residue names" }
    };
    output_env_t    oenv;
    t_topology     *top  = NULL;
    int             ePBC = -1;
    char            title[256];
    real            t;
    rvec           *x;
    matrix          box;
    gmx_bool        bTop = FALSE;

    FILE           *atm;
    int             i, j, nres = 0;
    const char     *trxfnm, *tpsfnm, *ndxfnm, *distfnm, *numfnm, *atmfnm, *oxfnm, *resfnm;
    char          **grpname;
    int            *gnx;
    atom_id       **index, *residues = NULL;
    t_filenm        fnm[] = {
        { efTRX, "-f",  NULL,      ffREAD },
        { efTPS,  NULL, NULL,      ffOPTRD },
        { efNDX,  NULL, NULL,      ffOPTRD },
        { efXVG, "-od", "mindist",  ffWRITE },
        { efXVG, "-on", "numcont",  ffOPTWR },
        { efOUT, "-o", "atm-pair", ffOPTWR },
        { efTRO, "-ox", "mindist",  ffOPTWR },
        { efXVG, "-or", "mindistres", ffOPTWR }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv,
                           PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT | PCA_BE_NICE,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    trxfnm  = ftp2fn(efTRX, NFILE, fnm);
    ndxfnm  = ftp2fn_null(efNDX, NFILE, fnm);
    distfnm = opt2fn("-od", NFILE, fnm);
    numfnm  = opt2fn_null("-on", NFILE, fnm);
    atmfnm  = ftp2fn_null(efOUT, NFILE, fnm);
    oxfnm   = opt2fn_null("-ox", NFILE, fnm);
    resfnm  = opt2fn_null("-or", NFILE, fnm);
    if (bPI || resfnm != NULL)
    {
        /* We need a tps file */
        tpsfnm = ftp2fn(efTPS, NFILE, fnm);
    }
    else
    {
        tpsfnm = ftp2fn_null(efTPS, NFILE, fnm);
    }

    if (!tpsfnm && !ndxfnm)
    {
        gmx_fatal(FARGS, "You have to specify either the index file or a tpr file");
    }

    if (bPI)
    {
        ng = 1;
        fprintf(stderr, "Choose a group for distance calculation\n");
    }
    else if (!bMat)
    {
        ng++;
    }

    snew(gnx, ng);
    snew(index, ng);
    snew(grpname, ng);

    if (tpsfnm || resfnm || !ndxfnm)
    {
        snew(top, 1);
        bTop = read_tps_conf(tpsfnm, title, top, &ePBC, &x, NULL, box, FALSE);
        if (bPI && !bTop)
        {
            printf("\nWARNING: Without a run input file a trajectory with broken molecules will not give the correct periodic image distance\n\n");
        }
    }
    get_index(top ? &(top->atoms) : NULL, ndxfnm, ng, gnx, index, grpname);

    if (bMat && (ng == 1))
    {
        ng = gnx[0];
        printf("Special case: making distance matrix between all atoms in group %s\n",
               grpname[0]);
        srenew(gnx, ng);
        srenew(index, ng);
        srenew(grpname, ng);
        for (i = 1; (i < ng); i++)
        {
            gnx[i]      = 1;
            grpname[i]  = grpname[0];
            snew(index[i], 1);
            index[i][0] = index[0][i];
        }
        gnx[0] = 1;
    }

    if (resfnm)
    {
        nres = find_residues(top ? &(top->atoms) : NULL,
                             gnx[0], index[0], &residues);
        if (debug)
        {
            dump_res(debug, nres, residues, index[0]);
        }
    }

    if (bPI)
    {
        periodic_mindist_plot(trxfnm, distfnm, top, ePBC, gnx[0], index[0], bSplit, oenv);
    }
    else
    {
        dist_plot(trxfnm, atmfnm, distfnm, numfnm, resfnm, oxfnm,
                  rcutoff, bMat, top ? &(top->atoms) : NULL,
                  ng, index, gnx, grpname, bSplit, !bMax, nres, residues, bPBC, ePBC,
                  bGroup, bEachResEachTime, bPrintResName, oenv);
    }

    do_view(oenv, distfnm, "-nxy");
    if (!bPI)
    {
        do_view(oenv, numfnm, "-nxy");
    }

    return 0;
}
Example #7
0
int gmx_spol(int argc, char *argv[])
{
    t_topology  *top;
    t_inputrec  *ir;
    t_atom      *atom;
    char         title[STRLEN];
    t_trxstatus *status;
    int          nrefat, natoms, nf, ntot;
    real         t;
    rvec        *xtop, *x, xref, trial, dx = {0}, dip, dir;
    matrix       box;

    FILE        *fp;
    int         *isize, nrefgrp;
    atom_id    **index, *molindex;
    char       **grpname;
    real         rmin2, rmax2, rcut, rcut2, rdx2 = 0, rtry2, qav, q, dip2, invbw;
    int          nbin, i, m, mol, a0, a1, a, d;
    double       sdip, sdip2, sinp, sdinp, nmol;
    int         *hist;
    t_pbc        pbc;
    gmx_rmpbc_t  gpbc = NULL;


    const char     *desc[] = {
        "[THISMODULE] analyzes dipoles around a solute; it is especially useful",
        "for polarizable water. A group of reference atoms, or a center",
        "of mass reference (option [TT]-com[tt]) and a group of solvent",
        "atoms is required. The program splits the group of solvent atoms",
        "into molecules. For each solvent molecule the distance to the",
        "closest atom in reference group or to the COM is determined.",
        "A cumulative distribution of these distances is plotted.",
        "For each distance between [TT]-rmin[tt] and [TT]-rmax[tt]",
        "the inner product of the distance vector",
        "and the dipole of the solvent molecule is determined.",
        "For solvent molecules with net charge (ions), the net charge of the ion",
        "is subtracted evenly from all atoms in the selection of each ion.",
        "The average of these dipole components is printed.",
        "The same is done for the polarization, where the average dipole is",
        "subtracted from the instantaneous dipole. The magnitude of the average",
        "dipole is set with the option [TT]-dip[tt], the direction is defined",
        "by the vector from the first atom in the selected solvent group",
        "to the midpoint between the second and the third atom."
    };

    output_env_t    oenv;
    static gmx_bool bCom   = FALSE, bPBC = FALSE;
    static int      srefat = 1;
    static real     rmin   = 0.0, rmax = 0.32, refdip = 0, bw = 0.01;
    t_pargs         pa[]   = {
        { "-com",  FALSE, etBOOL,  {&bCom},
          "Use the center of mass as the reference postion" },
        { "-refat",  FALSE, etINT, {&srefat},
          "The reference atom of the solvent molecule" },
        { "-rmin",  FALSE, etREAL, {&rmin}, "Maximum distance (nm)" },
        { "-rmax",  FALSE, etREAL, {&rmax}, "Maximum distance (nm)" },
        { "-dip",   FALSE, etREAL, {&refdip}, "The average dipole (D)" },
        { "-bw",    FALSE, etREAL, {&bw}, "The bin width" }
    };

    t_filenm        fnm[] = {
        { efTRX, NULL,  NULL,  ffREAD },
        { efTPR, NULL,  NULL,  ffREAD },
        { efNDX, NULL,  NULL,  ffOPTRD },
        { efXVG, NULL,  "scdist",  ffWRITE }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    snew(top, 1);
    snew(ir, 1);
    read_tpx_top(ftp2fn(efTPR, NFILE, fnm),
                 ir, box, &natoms, NULL, NULL, NULL, top);

    /* get index groups */
    printf("Select a group of reference particles and a solvent group:\n");
    snew(grpname, 2);
    snew(index, 2);
    snew(isize, 2);
    get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm), 2, isize, index, grpname);

    if (bCom)
    {
        nrefgrp = 1;
        nrefat  = isize[0];
    }
    else
    {
        nrefgrp = isize[0];
        nrefat  = 1;
    }

    spol_atom2molindex(&(isize[1]), index[1], &(top->mols));
    srefat--;

    /* initialize reading trajectory:                         */
    natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);

    rcut  = 0.99*sqrt(max_cutoff2(ir->ePBC, box));
    if (rcut == 0)
    {
        rcut = 10*rmax;
    }
    rcut2 = sqr(rcut);
    invbw = 1/bw;
    nbin  = (int)(rcut*invbw)+2;
    snew(hist, nbin);

    rmin2 = sqr(rmin);
    rmax2 = sqr(rmax);

    nf    = 0;
    ntot  = 0;
    sdip  = 0;
    sdip2 = 0;
    sinp  = 0;
    sdinp = 0;

    molindex = top->mols.index;
    atom     = top->atoms.atom;

    gpbc = gmx_rmpbc_init(&top->idef, ir->ePBC, natoms);

    /* start analysis of trajectory */
    do
    {
        /* make molecules whole again */
        gmx_rmpbc(gpbc, natoms, box, x);

        set_pbc(&pbc, ir->ePBC, box);
        if (bCom)
        {
            calc_com_pbc(nrefat, top, x, &pbc, index[0], xref, ir->ePBC);
        }

        for (m = 0; m < isize[1]; m++)
        {
            mol = index[1][m];
            a0  = molindex[mol];
            a1  = molindex[mol+1];
            for (i = 0; i < nrefgrp; i++)
            {
                pbc_dx(&pbc, x[a0+srefat], bCom ? xref : x[index[0][i]], trial);
                rtry2 = norm2(trial);
                if (i == 0 || rtry2 < rdx2)
                {
                    copy_rvec(trial, dx);
                    rdx2 = rtry2;
                }
            }
            if (rdx2 < rcut2)
            {
                hist[(int)(sqrt(rdx2)*invbw)+1]++;
            }
            if (rdx2 >= rmin2 && rdx2 < rmax2)
            {
                unitv(dx, dx);
                clear_rvec(dip);
                qav = 0;
                for (a = a0; a < a1; a++)
                {
                    qav += atom[a].q;
                }
                qav /= (a1 - a0);
                for (a = a0; a < a1; a++)
                {
                    q = atom[a].q - qav;
                    for (d = 0; d < DIM; d++)
                    {
                        dip[d] += q*x[a][d];
                    }
                }
                for (d = 0; d < DIM; d++)
                {
                    dir[d] = -x[a0][d];
                }
                for (a = a0+1; a < a0+3; a++)
                {
                    for (d = 0; d < DIM; d++)
                    {
                        dir[d] += 0.5*x[a][d];
                    }
                }
                unitv(dir, dir);

                svmul(ENM2DEBYE, dip, dip);
                dip2   = norm2(dip);
                sdip  += sqrt(dip2);
                sdip2 += dip2;
                for (d = 0; d < DIM; d++)
                {
                    sinp  += dx[d]*dip[d];
                    sdinp += dx[d]*(dip[d] - refdip*dir[d]);
                }

                ntot++;
            }
        }
        nf++;

    }
    while (read_next_x(oenv, status, &t, x, box));

    gmx_rmpbc_done(gpbc);

    /* clean up */
    sfree(x);
    close_trj(status);

    fprintf(stderr, "Average number of molecules within %g nm is %.1f\n",
            rmax, (real)ntot/(real)nf);
    if (ntot > 0)
    {
        sdip  /= ntot;
        sdip2 /= ntot;
        sinp  /= ntot;
        sdinp /= ntot;
        fprintf(stderr, "Average dipole:                               %f (D), std.dev. %f\n",
                sdip, sqrt(sdip2-sqr(sdip)));
        fprintf(stderr, "Average radial component of the dipole:       %f (D)\n",
                sinp);
        fprintf(stderr, "Average radial component of the polarization: %f (D)\n",
                sdinp);
    }

    fp = xvgropen(opt2fn("-o", NFILE, fnm),
                  "Cumulative solvent distribution", "r (nm)", "molecules", oenv);
    nmol = 0;
    for (i = 0; i <= nbin; i++)
    {
        nmol += hist[i];
        fprintf(fp, "%g %g\n", i*bw, nmol/nf);
    }
    xvgrclose(fp);

    do_view(oenv, opt2fn("-o", NFILE, fnm), NULL);

    return 0;
}
Example #8
0
int gmx_trjorder(int argc, char *argv[])
{
    const char       *desc[] = {
        "[THISMODULE] orders molecules according to the smallest distance",
        "to atoms in a reference group",
        "or on z-coordinate (with option [TT]-z[tt]).",
        "With distance ordering, it will ask for a group of reference",
        "atoms and a group of molecules. For each frame of the trajectory",
        "the selected molecules will be reordered according to the shortest",
        "distance between atom number [TT]-da[tt] in the molecule and all the",
        "atoms in the reference group. The center of mass of the molecules can",
        "be used instead of a reference atom by setting [TT]-da[tt] to 0.",
        "All atoms in the trajectory are written",
        "to the output trajectory.[PAR]",
        "[THISMODULE] can be useful for e.g. analyzing the n waters closest to a",
        "protein.",
        "In that case the reference group would be the protein and the group",
        "of molecules would consist of all the water atoms. When an index group",
        "of the first n waters is made, the ordered trajectory can be used",
        "with any GROMACS program to analyze the n closest waters.",
        "[PAR]",
        "If the output file is a [REF].pdb[ref] file, the distance to the reference target",
        "will be stored in the B-factor field in order to color with e.g. Rasmol.",
        "[PAR]",
        "With option [TT]-nshell[tt] the number of molecules within a shell",
        "of radius [TT]-r[tt] around the reference group are printed."
    };
    static int        na   = 3, ref_a = 1;
    static real       rcut = 0;
    static gmx_bool   bCOM = FALSE, bZ = FALSE;
    t_pargs           pa[] = {
        { "-na", FALSE, etINT,  {&na},
          "Number of atoms in a molecule" },
        { "-da", FALSE, etINT,  {&ref_a},
          "Atom used for the distance calculation, 0 is COM" },
        { "-com", FALSE, etBOOL, {&bCOM},
          "Use the distance to the center of mass of the reference group" },
        { "-r",  FALSE, etREAL, {&rcut},
          "Cutoff used for the distance calculation when computing the number of molecules in a shell around e.g. a protein" },
        { "-z", FALSE, etBOOL, {&bZ},
          "Order molecules on z-coordinate" }
    };
    FILE             *fp;
    t_trxstatus      *out;
    t_trxstatus      *status;
    gmx_bool          bNShell, bPDBout;
    t_topology        top;
    int               ePBC;
    rvec             *x, *xsol, xcom, dx;
    matrix            box;
    t_pbc             pbc;
    gmx_rmpbc_t       gpbc;
    real              t, totmass, mass, rcut2 = 0, n2;
    int               natoms, nwat, ncut;
    char            **grpname;
    int               i, j, d, *isize, isize_ref = 0, isize_sol;
    int               sa, sr, *swi, **index, *ind_ref = NULL, *ind_sol;
    gmx_output_env_t *oenv;
    t_filenm          fnm[] = {
        { efTRX, "-f", NULL, ffREAD  },
        { efTPS, NULL, NULL, ffREAD  },
        { efNDX, NULL, NULL, ffOPTRD },
        { efTRO, "-o", "ordered", ffOPTWR },
        { efXVG, "-nshell", "nshell", ffOPTWR }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_CAN_TIME,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &x, NULL, box, TRUE);
    sfree(x);

    /* get index groups */
    printf("Select %sa group of molecules to be ordered:\n",
           bZ ? "" : "a group of reference atoms and ");
    snew(grpname, 2);
    snew(index, 2);
    snew(isize, 2);
    get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), bZ ? 1 : 2,
              isize, index, grpname);

    if (!bZ)
    {
        isize_ref = isize[0];
        isize_sol = isize[1];
        ind_ref   = index[0];
        ind_sol   = index[1];
    }
    else
    {
        isize_sol = isize[0];
        ind_sol   = index[0];
    }

    natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);
    if (natoms > top.atoms.nr)
    {
        gmx_fatal(FARGS, "Number of atoms in the run input file is larger than in the trjactory");
    }
    for (i = 0; (i < 2); i++)
    {
        for (j = 0; (j < isize[i]); j++)
        {
            if (index[i][j] > natoms)
            {
                gmx_fatal(FARGS, "An atom number in group %s is larger than the number of atoms in the trajectory");
            }
        }
    }

    if ((isize_sol % na) != 0)
    {
        gmx_fatal(FARGS, "Number of atoms in the molecule group (%d) is not a multiple of na (%d)",
                  isize[1], na);
    }

    nwat = isize_sol/na;
    if (ref_a > na)
    {
        gmx_fatal(FARGS, "The reference atom can not be larger than the number of atoms in a molecule");
    }
    ref_a--;
    snew(xsol, nwat);
    snew(order, nwat);
    snew(swi, natoms);
    for (i = 0; (i < natoms); i++)
    {
        swi[i] = i;
    }

    out     = NULL;
    fp      = NULL;
    bNShell = ((opt2bSet("-nshell", NFILE, fnm)) ||
               (opt2parg_bSet("-r", asize(pa), pa)));
    bPDBout = FALSE;
    if (bNShell)
    {
        rcut2   = rcut*rcut;
        fp      = xvgropen(opt2fn("-nshell", NFILE, fnm), "Number of molecules",
                           "Time (ps)", "N", oenv);
        printf("Will compute the number of molecules within a radius of %g\n",
               rcut);
    }
    if (!bNShell || opt2bSet("-o", NFILE, fnm))
    {
        bPDBout = (fn2ftp(opt2fn("-o", NFILE, fnm)) == efPDB);
        if (bPDBout && !top.atoms.pdbinfo)
        {
            fprintf(stderr, "Creating pdbfino records\n");
            snew(top.atoms.pdbinfo, top.atoms.nr);
        }
        out = open_trx(opt2fn("-o", NFILE, fnm), "w");
    }
    gpbc = gmx_rmpbc_init(&top.idef, ePBC, natoms);
    do
    {
        gmx_rmpbc(gpbc, natoms, box, x);
        set_pbc(&pbc, ePBC, box);

        if (ref_a == -1)
        {
            /* Calculate the COM of all solvent molecules */
            for (i = 0; i < nwat; i++)
            {
                totmass = 0;
                clear_rvec(xsol[i]);
                for (j = 0; j < na; j++)
                {
                    sa       = ind_sol[i*na+j];
                    mass     = top.atoms.atom[sa].m;
                    totmass += mass;
                    for (d = 0; d < DIM; d++)
                    {
                        xsol[i][d] += mass*x[sa][d];
                    }
                }
                svmul(1.0/totmass, xsol[i], xsol[i]);
            }
        }
        else
        {
            /* Copy the reference atom of all solvent molecules */
            for (i = 0; i < nwat; i++)
            {
                copy_rvec(x[ind_sol[i*na+ref_a]], xsol[i]);
            }
        }

        if (bZ)
        {
            for (i = 0; (i < nwat); i++)
            {
                sa           = ind_sol[na*i];
                order[i].i   = sa;
                order[i].d2  = xsol[i][ZZ];
            }
        }
        else if (bCOM)
        {
            totmass = 0;
            clear_rvec(xcom);
            for (i = 0; i < isize_ref; i++)
            {
                mass     = top.atoms.atom[ind_ref[i]].m;
                totmass += mass;
                for (j = 0; j < DIM; j++)
                {
                    xcom[j] += mass*x[ind_ref[i]][j];
                }
            }
            svmul(1/totmass, xcom, xcom);
            for (i = 0; (i < nwat); i++)
            {
                sa = ind_sol[na*i];
                pbc_dx(&pbc, xcom, xsol[i], dx);
                order[i].i   = sa;
                order[i].d2  = norm2(dx);
            }
        }
        else
        {
            /* Set distance to first atom */
            for (i = 0; (i < nwat); i++)
            {
                sa = ind_sol[na*i];
                pbc_dx(&pbc, x[ind_ref[0]], xsol[i], dx);
                order[i].i   = sa;
                order[i].d2  = norm2(dx);
            }
            for (j = 1; (j < isize_ref); j++)
            {
                sr = ind_ref[j];
                for (i = 0; (i < nwat); i++)
                {
                    pbc_dx(&pbc, x[sr], xsol[i], dx);
                    n2 = norm2(dx);
                    if (n2 < order[i].d2)
                    {
                        order[i].d2  = n2;
                    }
                }
            }
        }

        if (bNShell)
        {
            ncut = 0;
            for (i = 0; (i < nwat); i++)
            {
                if (order[i].d2 <= rcut2)
                {
                    ncut++;
                }
            }
            fprintf(fp, "%10.3f  %8d\n", t, ncut);
        }
        if (out)
        {
            qsort(order, nwat, sizeof(*order), ocomp);
            for (i = 0; (i < nwat); i++)
            {
                for (j = 0; (j < na); j++)
                {
                    swi[ind_sol[na*i]+j] = order[i].i+j;
                }
            }

            /* Store the distance as the B-factor */
            if (bPDBout)
            {
                for (i = 0; (i < nwat); i++)
                {
                    for (j = 0; (j < na); j++)
                    {
                        top.atoms.pdbinfo[order[i].i+j].bfac = std::sqrt(order[i].d2);
                    }
                }
            }
            write_trx(out, natoms, swi, &top.atoms, 0, t, box, x, NULL, NULL);
        }
    }
    while (read_next_x(oenv, status, &t, x, box));
    close_trj(status);
    if (out)
    {
        close_trx(out);
    }
    if (fp)
    {
        xvgrclose(fp);
    }
    gmx_rmpbc_done(gpbc);

    return 0;
}
Example #9
0
int gmx_velacc(int argc,char *argv[])
{
    const char *desc[] = {
        "[TT]g_velacc[tt] computes the velocity autocorrelation function.",
        "When the [TT]-m[tt] option is used, the momentum autocorrelation",
        "function is calculated.[PAR]",
        "With option [TT]-mol[tt] the velocity autocorrelation function of",
        "molecules is calculated. In this case the index group should consist",
        "of molecule numbers instead of atom numbers.[PAR]",
        "Be sure that your trajectory contains frames with velocity information",
        "(i.e. [TT]nstvout[tt] was set in your original [TT].mdp[tt] file),",
        "and that the time interval between data collection points is",
        "much shorter than the time scale of the autocorrelation."
    };
  
    static gmx_bool bMass=FALSE,bMol=FALSE,bRecip=TRUE;
    t_pargs pa[] = {
        { "-m", FALSE, etBOOL, {&bMass},
          "Calculate the momentum autocorrelation function" },
        { "-recip", FALSE, etBOOL, {&bRecip},
          "Use cm^-1 on X-axis instead of 1/ps for spectra." },
        { "-mol", FALSE, etBOOL, {&bMol},
          "Calculate the velocity acf of molecules" }
    };

    t_topology top;
    int        ePBC=-1;
    t_trxframe fr;
    matrix     box;
    gmx_bool       bTPS=FALSE,bTop=FALSE;
    int        gnx;
    atom_id    *index;
    char       *grpname;
    char       title[256];
    /* t0, t1 are the beginning and end time respectively. 
     * dt is the time step, mass is temp variable for atomic mass.
     */
    real       t0,t1,dt,mass;
    t_trxstatus *status;
    int        counter,n_alloc,i,j,counter_dim,k,l;
    rvec       mv_mol;
    /* Array for the correlation function */
    real       **c1;
    real             *normm=NULL;
    output_env_t oenv;
  
#define NHISTO 360
    
    t_filenm  fnm[] = {
        { efTRN, "-f",    NULL,   ffREAD  },
        { efTPS, NULL,    NULL,   ffOPTRD }, 
        { efNDX, NULL,    NULL,   ffOPTRD },
        { efXVG, "-o",    "vac",  ffWRITE },
        { efXVG, "-os",   "spectrum", ffOPTWR }
    };
#define NFILE asize(fnm)
    int     npargs;
    t_pargs *ppa;

    npargs = asize(pa);
    ppa    = add_acf_pargs(&npargs,pa);
    parse_common_args(&argc,argv,PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE,
                      NFILE,fnm,npargs,ppa,asize(desc),desc,0,NULL,&oenv);

    if (bMol || bMass) {
        bTPS = ftp2bSet(efTPS,NFILE,fnm) || !ftp2bSet(efNDX,NFILE,fnm);
    }

    if (bTPS) {
        bTop=read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,NULL,NULL,box,
                           TRUE);
        get_index(&top.atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&gnx,&index,&grpname);
    } else
        rd_index(ftp2fn(efNDX,NFILE,fnm),1,&gnx,&index,&grpname);

    if (bMol) {
        if (!bTop)
            gmx_fatal(FARGS,"Need a topology to determine the molecules");
        snew(normm,top.atoms.nr);
        precalc(top,normm);
        index_atom2mol(&gnx,index,&top.mols);
    }
  
    /* Correlation stuff */
    snew(c1,gnx);
    for(i=0; (i<gnx); i++)
        c1[i]=NULL;
  
    read_first_frame(oenv,&status,ftp2fn(efTRN,NFILE,fnm),&fr,TRX_NEED_V);
    t0=fr.time;
      
    n_alloc=0;
    counter=0;
    do {
        if (counter >= n_alloc) {
            n_alloc+=100;
            for(i=0; i<gnx; i++)
                srenew(c1[i],DIM*n_alloc);
        }
        counter_dim=DIM*counter;
        if (bMol)
            for(i=0; i<gnx; i++) {
                clear_rvec(mv_mol);
                k=top.mols.index[index[i]];
                l=top.mols.index[index[i]+1];
                for(j=k; j<l; j++) {
                    if (bMass)
                        mass = top.atoms.atom[j].m;
                    else
                        mass = normm[j];
                    mv_mol[XX] += mass*fr.v[j][XX];
                    mv_mol[YY] += mass*fr.v[j][YY];
                    mv_mol[ZZ] += mass*fr.v[j][ZZ];
                }
                c1[i][counter_dim+XX]=mv_mol[XX];
                c1[i][counter_dim+YY]=mv_mol[YY];
                c1[i][counter_dim+ZZ]=mv_mol[ZZ];
            }
        else
            for(i=0; i<gnx; i++) {
                if (bMass)
                    mass = top.atoms.atom[index[i]].m;
                else
                    mass = 1;
                c1[i][counter_dim+XX]=mass*fr.v[index[i]][XX];
                c1[i][counter_dim+YY]=mass*fr.v[index[i]][YY];
                c1[i][counter_dim+ZZ]=mass*fr.v[index[i]][ZZ];
            }

        t1=fr.time;

        counter ++;
    } while (read_next_frame(oenv,status,&fr));
  
    close_trj(status);

    if (counter >= 4)
    {
      /* Compute time step between frames */
      dt = (t1-t0)/(counter-1);
      do_autocorr(opt2fn("-o",NFILE,fnm), oenv,
		  bMass ? 
		  "Momentum Autocorrelation Function" :
		  "Velocity Autocorrelation Function",
		  counter,gnx,c1,dt,eacVector,TRUE);

      do_view(oenv,opt2fn("-o",NFILE,fnm),"-nxy");

      if (opt2bSet("-os",NFILE,fnm)) {
        calc_spectrum(counter/2,(real *) (c1[0]),(t1-t0)/2,opt2fn("-os",NFILE,fnm),
                      oenv,bRecip);
        do_view(oenv,opt2fn("-os",NFILE,fnm),"-nxy");
      }
    }
    else {
      fprintf(stderr,"Not enough frames in trajectory - no output generated.\n");
    }

    thanx(stderr);

    return 0;
}
Example #10
0
int gmx_dih(int argc,char *argv[])
{
  const char *desc[] = {
    "g_dih can do two things. The default is to analyze dihedral transitions",
    "by merely computing all the dihedral angles defined in your topology",
    "for the whole trajectory. When a dihedral flips over to another minimum",
    "an angle/time plot is made.[PAR]",
    "The opther option is to discretize the dihedral space into a number of",
    "bins, and group each conformation in dihedral space in the",
    "appropriate bin. The output is then given as a number of dihedral",
    "conformations sorted according to occupancy."
  };
  static int  mult = -1;
  static gmx_bool bSA  = FALSE;
  t_pargs pa[] = {
    { "-sa", FALSE, etBOOL, {&bSA},
      "Perform cluster analysis in dihedral space instead of analysing dihedral transitions." },
    { "-mult", FALSE, etINT, {&mult},
      "mulitiplicity for dihedral angles (by default read from topology)" }
  };
  FILE       *out;
  t_xrama    *xr;
  t_topology *top;
  real       **dih,*time;
  real       dd;
  int        i,nframes,maxframes=1000;
  output_env_t oenv;
  t_filenm   fnm[] = {
    { efTRX, "-f", NULL, ffREAD },
    { efTPX, NULL, NULL, ffREAD },
    { efOUT, NULL, NULL, ffWRITE }
  };
#define NFILE asize(fnm)

  CopyRight(stderr,argv[0]);
  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);
  
  if (mult != -1)
    fprintf(stderr,"Using %d for dihedral multiplicity rather than topology values\n",mult);
    
  snew(xr,1);
  init_rama(oenv,ftp2fn(efTRX,NFILE,fnm),
	    ftp2fn(efTPX,NFILE,fnm),xr,3);
  top=read_top(ftp2fn(efTPX,NFILE,fnm),NULL);
	       
  /* Brute force malloc, may be too big... */
  snew(dih,xr->ndih);
  for(i=0; (i<xr->ndih); i++)
    snew(dih[i],maxframes);
  snew(time,maxframes);

  fprintf(stderr,"\n");
  nframes = 0;
  while (new_data(xr)) {
    for(i=0; (i<xr->ndih); i++) {
      dd=xr->dih[i].ang*RAD2DEG;
      while (dd < 0)
	dd+=360;
      while (dd > 360)
	dd-=360;
      dih[i][nframes]=dd;
    }
    time[nframes]=xr->t;
    nframes++;
    if (nframes > maxframes) {
      maxframes += 1000;
      for(i=0; (i<xr->ndih); i++)
	srenew(dih[i],maxframes);
      srenew(time,maxframes);
    }
  } 

  fprintf(stderr,"\nCalculated all dihedrals, now analysing...\n");

  out=ftp2FILE(efOUT,NFILE,fnm,"w");

  if (bSA) {
    /* Cluster and structure analysis */
    ana_cluster(out,xr,dih,time,top,nframes,mult);
  }
  else {
    /* Analyse transitions... */
    ana_trans(out,xr,dih,time,top,nframes,oenv);
  }
  ffclose(out);
    
  thanx(stderr);
    
  return 0;
}
Example #11
0
int gmx_xpm2ps(int argc, char *argv[])
{
    const char     *desc[] = {
        "[THISMODULE] makes a beautiful color plot of an XPixelMap file.",
        "Labels and axis can be displayed, when they are supplied",
        "in the correct matrix format.",
        "Matrix data may be generated by programs such as [gmx-do_dssp], [gmx-rms] or",
        "[gmx-mdmat].[PAR]",
        "Parameters are set in the [TT].m2p[tt] file optionally supplied with",
        "[TT]-di[tt]. Reasonable defaults are provided. Settings for the [IT]y[it]-axis",
        "default to those for the [IT]x[it]-axis. Font names have a defaulting hierarchy:",
        "titlefont -> legendfont; titlefont -> (xfont -> yfont -> ytickfont)",
        "-> xtickfont, e.g. setting titlefont sets all fonts, setting xfont",
        "sets yfont, ytickfont and xtickfont.[PAR]",
        "When no [TT].m2p[tt] file is supplied, many settings are taken from",
        "command line options. The most important option is [TT]-size[tt],",
        "which sets the size of the whole matrix in postscript units.",
        "This option can be overridden with the [TT]-bx[tt] and [TT]-by[tt]",
        "options (and the corresponding parameters in the [TT].m2p[tt] file),",
        "which set the size of a single matrix element.[PAR]",
        "With [TT]-f2[tt] a second matrix file can be supplied. Both matrix",
        "files will be read simultaneously and the upper left half of the",
        "first one ([TT]-f[tt]) is plotted together with the lower right",
        "half of the second one ([TT]-f2[tt]). The diagonal will contain",
        "values from the matrix file selected with [TT]-diag[tt].",
        "Plotting of the diagonal values can be suppressed altogether by",
        "setting [TT]-diag[tt] to [TT]none[tt].",
        "In this case, a new color map will be generated with",
        "a red gradient for negative numbers and a blue for positive.",
        "If the color coding and legend labels of both matrices are identical,",
        "only one legend will be displayed, else two separate legends are",
        "displayed.",
        "With [TT]-combine[tt], an alternative operation can be selected",
        "to combine the matrices. The output range is automatically set",
        "to the actual range of the combined matrix. This can be overridden",
        "with [TT]-cmin[tt] and [TT]-cmax[tt].[PAR]",
        "[TT]-title[tt] can be set to [TT]none[tt] to suppress the title, or to",
        "[TT]ylabel[tt] to show the title in the Y-label position (alongside",
        "the [IT]y[it]-axis).[PAR]",
        "With the [TT]-rainbow[tt] option, dull grayscale matrices can be turned",
        "into attractive color pictures.[PAR]",
        "Merged or rainbowed matrices can be written to an XPixelMap file with",
        "the [TT]-xpm[tt] option."
    };

    output_env_t    oenv;
    const char     *fn, *epsfile = NULL, *xpmfile = NULL;
    int             i, nmat, nmat2, etitle, elegend, ediag, erainbow, ecombine;
    t_matrix       *mat = NULL, *mat2 = NULL;
    gmx_bool        bTitle, bTitleOnce, bDiag, bFirstDiag, bGrad;
    static gmx_bool bFrame = TRUE, bZeroLine = FALSE, bYonce = FALSE, bAdd = FALSE;
    static real     size   = 400, boxx = 0, boxy = 0, cmin = 0, cmax = 0;
    static rvec     grad   = {0, 0, 0};
    enum                    {
        etSel, etTop, etOnce, etYlabel, etNone, etNR
    };
    const char *title[]   = { NULL, "top", "once", "ylabel", "none", NULL };
    /* MUST correspond to enum elXxx as defined at top of file */
    const char *legend[]  = { NULL, "both", "first", "second", "none", NULL };
    enum                    {
        edSel, edFirst, edSecond, edNone, edNR
    };
    const char *diag[]    = { NULL, "first", "second", "none", NULL };
    enum                    {
        erSel, erNo, erBlue, erRed, erNR
    };
    const char *rainbow[] = { NULL, "no", "blue", "red", NULL };
    /* MUST correspond to enum ecXxx as defined at top of file */
    const char *combine[] = {
        NULL, "halves", "add", "sub", "mult", "div", NULL
    };
    static int  skip = 1, mapoffset = 0;
    t_pargs     pa[] = {
        { "-frame",   FALSE, etBOOL, {&bFrame},
          "Display frame, ticks, labels, title and legend" },
        { "-title",   FALSE, etENUM, {title},   "Show title at" },
        { "-yonce",   FALSE, etBOOL, {&bYonce}, "Show y-label only once" },
        { "-legend",  FALSE, etENUM, {legend},  "Show legend" },
        { "-diag",    FALSE, etENUM, {diag},    "Diagonal" },
        { "-size",    FALSE, etREAL, {&size},
          "Horizontal size of the matrix in ps units" },
        { "-bx",      FALSE, etREAL, {&boxx},
          "Element x-size, overrides [TT]-size[tt] (also y-size when [TT]-by[tt] is not set)" },
        { "-by",      FALSE, etREAL, {&boxy},   "Element y-size" },
        { "-rainbow", FALSE, etENUM, {rainbow},
          "Rainbow colors, convert white to" },
        { "-gradient", FALSE, etRVEC, {grad},
          "Re-scale colormap to a smooth gradient from white {1,1,1} to {r,g,b}" },
        { "-skip",    FALSE, etINT,  {&skip},
          "only write out every nr-th row and column" },
        { "-zeroline", FALSE, etBOOL, {&bZeroLine},
          "insert line in [TT].xpm[tt] matrix where axis label is zero"},
        { "-legoffset", FALSE, etINT, {&mapoffset},
          "Skip first N colors from [TT].xpm[tt] file for the legend" },
        { "-combine", FALSE, etENUM, {combine}, "Combine two matrices" },
        { "-cmin",    FALSE, etREAL, {&cmin}, "Minimum for combination output" },
        { "-cmax",    FALSE, etREAL, {&cmax}, "Maximum for combination output" }
    };
#define NPA asize(pa)
    t_filenm    fnm[] = {
        { efXPM, "-f",  NULL,      ffREAD },
        { efXPM, "-f2", "root2",   ffOPTRD },
        { efM2P, "-di", NULL,      ffLIBOPTRD },
        { efM2P, "-do", "out",     ffOPTWR },
        { efEPS, "-o",  NULL,      ffOPTWR },
        { efXPM, "-xpm", NULL,      ffOPTWR }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_CAN_VIEW,
                           NFILE, fnm, NPA, pa,
                           asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    etitle   = nenum(title);
    elegend  = nenum(legend);
    ediag    = nenum(diag);
    erainbow = nenum(rainbow);
    ecombine = nenum(combine);
    bGrad    = opt2parg_bSet("-gradient", NPA, pa);
    for (i = 0; i < DIM; i++)
    {
        if (grad[i] < 0 || grad[i] > 1)
        {
            gmx_fatal(FARGS, "RGB value %g out of range (0.0-1.0)", grad[i]);
        }
    }
    if (!bFrame)
    {
        etitle  = etNone;
        elegend = elNone;
    }

    epsfile = ftp2fn_null(efEPS, NFILE, fnm);
    xpmfile = opt2fn_null("-xpm", NFILE, fnm);
    if (epsfile == NULL && xpmfile == NULL)
    {
        if (ecombine != ecHalves)
        {
            xpmfile = opt2fn("-xpm", NFILE, fnm);
        }
        else
        {
            epsfile = ftp2fn(efEPS, NFILE, fnm);
        }
    }
    if (ecombine != ecHalves && epsfile)
    {
        fprintf(stderr,
                "WARNING: can only write result of arithmetic combination "
                "of two matrices to .xpm file\n"
                "         file %s will not be written\n", epsfile);
        epsfile = NULL;
    }

    bDiag      = ediag != edNone;
    bFirstDiag = ediag != edSecond;

    fn   = opt2fn("-f", NFILE, fnm);
    nmat = read_xpm_matrix(fn, &mat);
    fprintf(stderr, "There %s %d matri%s in %s\n", (nmat > 1) ? "are" : "is", nmat, (nmat > 1) ? "ces" : "x", fn);
    fn = opt2fn_null("-f2", NFILE, fnm);
    if (fn)
    {
        nmat2 = read_xpm_matrix(fn, &mat2);
        fprintf(stderr, "There %s %d matri%s in %s\n", (nmat2 > 1) ? "are" : "is", nmat2, (nmat2 > 1) ? "ces" : "x", fn);
        if (nmat != nmat2)
        {
            fprintf(stderr, "Different number of matrices, using the smallest number.\n");
            nmat = nmat2 = min(nmat, nmat2);
        }
    }
    else
    {
        if (ecombine != ecHalves)
        {
            fprintf(stderr,
                    "WARNING: arithmetic matrix combination selected (-combine), "
                    "but no second matrix (-f2) supplied\n"
                    "         no matrix combination will be performed\n");
        }
        ecombine = 0;
        nmat2    = 0;
    }
    bTitle     = etitle == etTop;
    bTitleOnce = etitle == etOnce;
    if (etitle == etYlabel)
    {
        for (i = 0; (i < nmat); i++)
        {
            strcpy(mat[i].label_y, mat[i].title);
            if (mat2)
            {
                strcpy(mat2[i].label_y, mat2[i].title);
            }
        }
    }
    if (bGrad)
    {
        gradient_mat(grad, nmat, mat);
        if (mat2)
        {
            gradient_mat(grad, nmat2, mat2);
        }
    }
    if (erainbow != erNo)
    {
        rainbow_mat(erainbow == erBlue, nmat, mat);
        if (mat2)
        {
            rainbow_mat(erainbow == erBlue, nmat2, mat2);
        }
    }

    if ((mat2 == NULL) && (elegend != elNone))
    {
        elegend = elFirst;
    }

    if (ecombine && ecombine != ecHalves)
    {
        write_combined_matrix(ecombine, xpmfile, nmat, mat, mat2,
                              opt2parg_bSet("-cmin", NPA, pa) ? &cmin : NULL,
                              opt2parg_bSet("-cmax", NPA, pa) ? &cmax : NULL);
    }
    else
    {
        do_mat(nmat, mat, mat2, bFrame, bZeroLine, bDiag, bFirstDiag,
               bTitle, bTitleOnce, bYonce,
               elegend, size, boxx, boxy, epsfile, xpmfile,
               opt2fn_null("-di", NFILE, fnm), opt2fn_null("-do", NFILE, fnm), skip,
               mapoffset);
    }

    view_all(oenv, NFILE, fnm);

    return 0;
}
int main(int argc, char *argv[]) {
    const char *desc[] = {
        "g_ensemble_comp evaluates the difference between two conformational ensembles, R and R'.",
        "Quanitification is in terms of a true metric that satisfies the conditions set forth by the zeroth law of thermodynamics.",
        "The quantification metric eta=1-|Overlap|=|R'|-|Overlap|=DeltaR is normalized, that is, 0<=eta<1,",
        "and takes up a value closer to unity as the difference between the ensembles increases.",
        "For two Gaussian distributions with identical standard deviations of 0.5 A,",
        "eta=0.68 represents a geometric center deviation of 1 A.\n",
        "The two ensembles are provided as two trajectory files specified by the -f1 and -f2 options (supported formats=xtc,trr,pdb).",
        "We recommend that frames numbers in the trajectory files are in the range 2500-5000.",
        "While the speed of the algorithm decreases with increase in ensemble size,", 
        "the numerical accuracy of the calculation reduces with decrease in ensemble size,",
        "and a small number of frames may not provide a good representation of the ensemble.",
        "Note that if you are not interested in eta to reflect changes in whole molecule translation/rotation,",
        "then these degress of freedom need to be removed prior to ensemble comparison.",
        "For most cases, this can be accomplished by fitting all conformations",
        "in the two ensembles on to one single representative structure, such as the x-ray structure",
        "For this, we recommend the use of trjconv with the -fit rot+trans option.\n"
        "By default, differences (eta) are estimated for all atoms, but comparisons can be done for a smaller specific group of atoms,",
        "which can be selected from index files -n1 and -n2. ",
        "The average eta can also be calculated for each residue specified in a structure file given by -res (.pdb and .gro are supported).\n",
        "Overlaps are estimated by training a support vector machine in a pre-defined Hilbert space specified by",
        "the width of the RDF Kernel (gamma=0.4) and",
        "the maximum value that can be taken up by the Lagrange multiplier (C=100.0).", 
        "The values of C and gamma can be changed with -c and -g,",
        "but such changes may increase mean absolute error (MAE=3.26%) of the method.\n",
        "If g_ensemble_comp was built with OPENMP, you can set the number of threads to use with -nthreads X,\n",
        "where X is the number of threads to use. The default behavior is to use the maximum number of cores available.\n\n",
        "Methodoligical details and example applications can be found in\n",
        "Leighty and Varma, JCTC, 2013, 9: 868-875.\n",
        "Varma, Botlani and Leighty, Proteins, 2014, 82: 3241-3254.\n",
        "Dutta, Botlani and Varma, JPC B, 2014, 118: 14795-14807.\n"
    };
    const char *fnames[eNUMFILES];
    output_env_t oenv = NULL;
    real gamma = GAMMA, c = COST;
    int nthreads = -1;

    /* eta values */
    real *eta;
    int natoms;

    init_log("eta.log", argv[0]);

    t_filenm fnm[] = {
        {efTRX, "-f1", "traj1.xtc", ffREAD},
        {efTRX, "-f2", "traj2.xtc", ffREAD},
        {efNDX, "-n1", "index1.ndx", ffOPTRD},
        {efNDX, "-n2", "index2.ndx", ffOPTRD},
        {efSTX, "-res", "res.pdb", ffOPTRD},
        {efDAT, "-eta_atom", "eta_atom.dat", ffWRITE},
        {efDAT, "-eta_res", "eta_res.dat", ffWRITE}
    };

    t_pargs pa[] = {
        {"-g", FALSE, etREAL, {&gamma}, "RBD Kernel width (default=0.4)"},
        {"-c", FALSE, etREAL, {&c}, "Max value of Lagrange multiplier (default=100)"},
        {"-nthreads", FALSE, etINT, {&nthreads}, "set the number of parallel threads to use (default is max available)"}
    };

    parse_common_args(&argc, argv, 0, eNUMFILES, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv);

    fnames[eTRAJ1] = opt2fn("-f1", eNUMFILES, fnm);
    fnames[eTRAJ2] = opt2fn("-f2", eNUMFILES, fnm);
    fnames[eNDX1] = opt2fn_null("-n1", eNUMFILES, fnm);
    fnames[eNDX2] = opt2fn_null("-n2", eNUMFILES, fnm);
    fnames[eRES1] = opt2fn_null("-res", eNUMFILES, fnm);
    fnames[eETA_ATOM] = opt2fn("-eta_atom", eNUMFILES, fnm);
    fnames[eETA_RES] = opt2fn("-eta_res", eNUMFILES, fnm);

    ensemble_comp(fnames, gamma, c, &eta, &natoms, nthreads, &oenv);

    save_eta(eta, natoms, fnames[eETA_ATOM]);

    if(fnames[eRES1] != NULL) {
        eta_res_t eta_res;

        calc_eta_res(fnames[eRES1], eta, natoms, &eta_res);
        save_eta_res(&eta_res, fnames[eETA_RES]);

        free_eta_res(&eta_res);
    }

    sfree(eta);

    print_log("%s completed successfully.\n", argv[0]);
    close_log();

    return 0;
}
Example #13
0
int gmx_dist(int argc,char *argv[])
{
  const char *desc[] = {
    "[TT]g_dist[tt] can calculate the distance between the centers of mass of two",
    "groups of atoms as a function of time. The total distance and its",
    "[IT]x[it]-, [IT]y[it]-, and [IT]z[it]-components are plotted.[PAR]",
    "Or when [TT]-dist[tt] is set, print all the atoms in group 2 that are",
    "closer than a certain distance to the center of mass of group 1.[PAR]",
    "With options [TT]-lt[tt] and [TT]-dist[tt] the number of contacts",
    "of all atoms in group 2 that are closer than a certain distance",
    "to the center of mass of group 1 are plotted as a function of the time",
    "that the contact was continously present.[PAR]",
    "Other programs that calculate distances are [TT]g_mindist[tt]",
    "and [TT]g_bond[tt]."
  };
  
  t_topology *top=NULL;
  int  ePBC;
  real t,t0,cut2,dist2;
  rvec *x=NULL,*v=NULL,dx;
  matrix box;
  t_trxstatus *status;
  int natoms;

  int g,d,i,j,res,teller=0;
  atom_id aid;

  int     ngrps;     /* the number of index groups */
  atom_id **index,max;   /* the index for the atom numbers */
  int     *isize;    /* the size of each group */
  char    **grpname; /* the name of each group */
  rvec    *com;
  real    *mass;
  FILE    *fp=NULL,*fplt=NULL;
  gmx_bool    bCutoff,bPrintDist,bLifeTime;
  t_pbc   *pbc;
  int     *contact_time=NULL,*ccount=NULL,ccount_nalloc=0,sum;
  char    buf[STRLEN];
  output_env_t oenv;
  gmx_rmpbc_t  gpbc=NULL;
  
  const char *leg[4] = { "|d|","d\\sx\\N","d\\sy\\N","d\\sz\\N" };

  static real cut=0;
  
  static t_pargs pa[] = {
    { "-dist",      FALSE, etREAL, {&cut},
      "Print all atoms in group 2 closer than dist to the center of mass of group 1" }
  };
#define NPA asize(pa)

  t_filenm fnm[] = {
    { efTRX, "-f", NULL, ffREAD },
    { efTPX, NULL, NULL, ffREAD },
    { efNDX, NULL, NULL, ffOPTRD },
    { efXVG, NULL, "dist", ffOPTWR },
    { efXVG, "-lt", "lifetime", ffOPTWR },
  };
#define NFILE asize(fnm)


  CopyRight(stderr,argv[0]);

  parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_BE_NICE,
		    NFILE,fnm,NPA,pa,asize(desc),desc,0,NULL,&oenv);
  
  bCutoff = opt2parg_bSet("-dist",NPA,pa);
  cut2 = cut*cut;
  bLifeTime = opt2bSet("-lt",NFILE,fnm);
  bPrintDist = (bCutoff && !bLifeTime);
  
  top=read_top(ftp2fn(efTPX,NFILE,fnm),&ePBC);
  
  /* read index files */
  ngrps = 2;
  snew(com,ngrps);
  snew(grpname,ngrps);
  snew(index,ngrps);
  snew(isize,ngrps);
  get_index(&top->atoms,ftp2fn(efNDX,NFILE,fnm),ngrps,isize,index,grpname);
  
  /* calculate mass */
  max=0;
  snew(mass,ngrps);
  for(g=0;(g<ngrps);g++) {
    mass[g]=0;
    for(i=0;(i<isize[g]);i++) {
      if (index[g][i]>max)
	max=index[g][i];
      if (index[g][i] >= top->atoms.nr)
	gmx_fatal(FARGS,"Atom number %d, item %d of group %d, is larger than number of atoms in the topolgy (%d)\n",index[g][i]+1,i+1,g+1,top->atoms.nr+1);
      mass[g]+=top->atoms.atom[index[g][i]].m;
    }
  }

  natoms=read_first_x(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box);
  t0 = t;

  if (max>=natoms)
    gmx_fatal(FARGS,"Atom number %d in an index group is larger than number of atoms in the trajectory (%d)\n",(int)max+1,natoms);

  if (!bCutoff) {
    /* open output file */
    fp = xvgropen(ftp2fn(efXVG,NFILE,fnm),
		  "Distance","Time (ps)","Distance (nm)",oenv);
    xvgr_legend(fp,4,leg,oenv);
  } else {
    ngrps = 1;
    if (bLifeTime)
      snew(contact_time,isize[1]);
  }
  if (ePBC != epbcNONE)
    snew(pbc,1);
  else
    pbc = NULL;
    
  gpbc = gmx_rmpbc_init(&top->idef,ePBC,natoms,box);
  do {
    /* initialisation for correct distance calculations */
    if (pbc) {
      set_pbc(pbc,ePBC,box);
      /* make molecules whole again */
      gmx_rmpbc(gpbc,natoms,box,x);
    }
    /* calculate center of masses */
    for(g=0;(g<ngrps);g++) {
      if (isize[g] == 1) {
	copy_rvec(x[index[g][0]],com[g]);
      } else {
	for(d=0;(d<DIM);d++) {
	  com[g][d]=0;
	  for(i=0;(i<isize[g]);i++) {
	    com[g][d] += x[index[g][i]][d] * top->atoms.atom[index[g][i]].m;
	  }
	  com[g][d] /= mass[g];
	}
      }
    }
    
    if (!bCutoff) {
      /* write to output */
      fprintf(fp,"%12.7f ",t);
      for(g=0;(g<ngrps/2);g++) {
	if (pbc)
	  pbc_dx(pbc,com[2*g],com[2*g+1],dx);
	else
	  rvec_sub(com[2*g],com[2*g+1],dx);
	
	fprintf(fp,"%12.7f %12.7f %12.7f %12.7f",
		norm(dx),dx[XX],dx[YY],dx[ZZ]);
      }
      fprintf(fp,"\n");
    } else {
      for(i=0;(i<isize[1]);i++) { 
	j=index[1][i];
	if (pbc)
	  pbc_dx(pbc,x[j],com[0],dx);
	else
	  rvec_sub(x[j],com[0],dx);
	
	dist2 = norm2(dx);
	if (dist2<cut2) {
	  if (bPrintDist) {
	    res=top->atoms.atom[j].resind;
	    fprintf(stdout,"\rt: %g  %d %s %d %s  %g (nm)\n",
		    t,top->atoms.resinfo[res].nr,*top->atoms.resinfo[res].name,
		    j+1,*top->atoms.atomname[j],sqrt(dist2));
	  }
	  if (bLifeTime)
	    contact_time[i]++;
	} else {
	  if (bLifeTime) {
	    if (contact_time[i]) {
	      add_contact_time(&ccount,&ccount_nalloc,contact_time[i]-1);
	      contact_time[i] = 0;
	    }
	  }
	}
      }
    }
    
    teller++;
  } while (read_next_x(oenv,status,&t,natoms,x,box));
  gmx_rmpbc_done(gpbc);

  if (!bCutoff)
    ffclose(fp);

  close_trj(status);
  
  if (bCutoff && bLifeTime) {
    /* Add the contacts still present in the last frame */
    for(i=0; i<isize[1]; i++)
      if (contact_time[i])
	add_contact_time(&ccount,&ccount_nalloc,contact_time[i]-1);

    sprintf(buf,"%s - %s within %g nm",
	    grpname[0],grpname[1],cut);
    fp = xvgropen(opt2fn("-lt",NFILE,fnm),
		  buf,"Time (ps)","Number of contacts",oenv);
    for(i=0; i<min(ccount_nalloc,teller-1); i++) {
      /* Account for all subintervals of longer intervals */
      sum = 0;
      for(j=i; j<ccount_nalloc; j++)
	sum += (j-i+1)*ccount[j];

      fprintf(fp,"%10.3f %10.3f\n",i*(t-t0)/(teller-1),sum/(double)(teller-i));
    }
    ffclose(fp);
  }
  
  thanx(stderr);
  return 0;
}
int gmx_morph(int argc,char *argv[])
{
  char *desc[] = {
    "g_morph does a linear interpolation of conformations in order to",
    "create intermediates. Of course these are completely unphysical, but",
    "that you may try to justify yourself. Output is in the form of a ",
    "generic trajectory. The number of intermediates can be controlled with",
    "the -ninterm flag. The first and last flag correspond to the way of",
    "interpolating: 0 corresponds to input structure 1 while",
    "1 corresponds to input strucutre 2.",
    "If you specify first < 0 or last > 1 extrapolation will be",
    "on the path from input structure x1 to x2. In general the coordinates",
    "of the intermediate x(i) out of N total intermidates correspond to:[PAR]",
    "x(i) = x1 + (first+(i/(N-1))*(last-first))*(x2-x1)[PAR]",
    "Finally the RMSD with respect to both input structures can be computed",
    "if explicitly selected (-or option). In that case an index file may be",
    "read to select what group RMS is computed from."
  };
  t_filenm fnm[] = {
    { efSTX, "-f1", "conf1",  ffREAD },
    { efSTX, "-f2", "conf2",  ffREAD },
    { efTRO, "-o",  "interm", ffWRITE },
    { efXVG, "-or", "rms-interm", ffOPTWR },
    { efNDX, "-n",  "index",  ffOPTRD }
  };
#define NFILE asize(fnm)
  static  int  ninterm = 11;
  static  real first   = 0.0;
  static  real last    = 1.0;
  static  bool bFit    = TRUE;
  t_pargs pa [] = {
    { "-ninterm", FALSE, etINT,  {&ninterm},
      "Number of intermediates" },
    { "-first",   FALSE, etREAL, {&first},
      "Corresponds to first generated structure (0 is input x0, see above)" },
    { "-last",    FALSE, etREAL, {&last},
      "Corresponds to last generated structure (1 is input x1, see above)" },
    { "-fit",     FALSE, etBOOL, {&bFit},
      "Do a least squares fit of the second to the first structure before interpolating" }
  };
  char     *leg[] = { "Ref = 1\\Sst\\N conf", "Ref = 2\\Snd\\N conf" };
  FILE     *fp=NULL;
  int      i,isize,is_lsq,status,nat1,nat2;
  atom_id  *index,*index_lsq,*index_all,*dummy;
  t_atoms  atoms;
  rvec     *x1,*x2,*xx,*v;
  matrix   box;
  real     rms1,rms2,fac,*mass;
  char     title[STRLEN],*grpname;
  bool     bRMS;
  
  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_CAN_VIEW,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,
		    0,NULL);
  get_stx_coordnum (opt2fn("-f1",NFILE,fnm),&nat1);
  get_stx_coordnum (opt2fn("-f2",NFILE,fnm),&nat2);
  if (nat1 != nat2)
    gmx_fatal(FARGS,"Number of atoms in first structure is %d, in second %d",
		nat1,nat2);
  
  init_t_atoms(&atoms,nat1,TRUE);
  snew(x1,nat1);
  snew(x2,nat1);
  snew(xx,nat1);
  snew(v,nat1);
  
  read_stx_conf(opt2fn("-f1",NFILE,fnm),title,&atoms,x1,v,NULL,box);
  read_stx_conf(opt2fn("-f2",NFILE,fnm),title,&atoms,x2,v,NULL,box);

  snew(mass,nat1);
  snew(index_all,nat1);
  for(i=0; (i<nat1); i++) {
    mass[i] = 1;
    index_all[i] = i;
  }
  if (bFit) {
    printf("Select group for LSQ superposition:\n");
    get_index(&atoms,opt2fn_null("-n",NFILE,fnm),1,&is_lsq,&index_lsq,
	      &grpname);
    reset_x(is_lsq,index_lsq,nat1,index_all,x1,mass);
    reset_x(is_lsq,index_lsq,nat1,index_all,x2,mass);
    do_fit(nat1,mass,x1,x2);
  }
  
  bRMS = opt2bSet("-or",NFILE,fnm);
  if (bRMS) {
    fp = xvgropen(opt2fn("-or",NFILE,fnm),"RMSD","Conf","(nm)");
    xvgr_legend(fp,asize(leg),leg);
    printf("Select group for RMSD calculation:\n");
    get_index(&atoms,opt2fn_null("-n",NFILE,fnm),1,&isize,&index,&grpname);
    printf("You selected group %s, containing %d atoms\n",grpname,isize);
    rms1 = rmsdev_ind(isize,index,mass,x1,x2);  
    fprintf(stderr,"RMSD between input conformations is %g nm\n",rms1);
  }
  
  snew(dummy,nat1);
  for(i=0; (i<nat1); i++)
    dummy[i] = i;
  status = open_trx(ftp2fn(efTRX,NFILE,fnm),"w");
  
  for(i=0; (i<ninterm); i++) {
    fac = dointerp(nat1,x1,x2,xx,i,ninterm,first,last);
    write_trx(status,nat1,dummy,&atoms,i,fac,box,xx,NULL);
    if (bRMS) {
      rms1 = rmsdev_ind(isize,index,mass,x1,xx);
      rms2 = rmsdev_ind(isize,index,mass,x2,xx);
      fprintf(fp,"%10g  %10g  %10g\n",fac,rms1,rms2);
    }
  }
  
  close_trx(status); 
  
  if (bRMS) {
    fclose(fp);
    do_view(opt2fn("-or",NFILE,fnm),"-nxy");
  }
  
  thanx(stderr);

  return 0;
}
int gmx_order(int argc, char *argv[])
{
    const char        *desc[] = {
        "[THISMODULE] computes the order parameter per atom for carbon tails. For atom i the",
        "vector i-1, i+1 is used together with an axis. ",
        "The index file should contain only the groups to be used for calculations,",
        "with each group of equivalent carbons along the relevant acyl chain in its own",
        "group. There should not be any generic groups (like System, Protein) in the index",
        "file to avoid confusing the program (this is not relevant to tetrahedral order",
        "parameters however, which only work for water anyway).[PAR]",
        "[THISMODULE] can also give all",
        "diagonal elements of the order tensor and even calculate the deuterium",
        "order parameter Scd (default). If the option [TT]-szonly[tt] is given, only one",
        "order tensor component (specified by the [TT]-d[tt] option) is given and the",
        "order parameter per slice is calculated as well. If [TT]-szonly[tt] is not",
        "selected, all diagonal elements and the deuterium order parameter is",
        "given.[PAR]"
        "The tetrahedrality order parameters can be determined",
        "around an atom. Both angle an distance order parameters are calculated. See",
        "P.-L. Chau and A.J. Hardwick, Mol. Phys., 93, (1998), 511-518.",
        "for more details.[BR]",
        ""
    };

    static int         nslices       = 1;     /* nr of slices defined       */
    static gmx_bool    bSzonly       = FALSE; /* True if only Sz is wanted  */
    static gmx_bool    bUnsat        = FALSE; /* True if carbons are unsat. */
    static const char *normal_axis[] = { NULL, "z", "x", "y", NULL };
    static gmx_bool    permolecule   = FALSE; /*compute on a per-molecule basis */
    static gmx_bool    radial        = FALSE; /*compute a radial membrane normal */
    static gmx_bool    distcalc      = FALSE; /*calculate distance from a reference group */
    t_pargs            pa[]          = {
        { "-d",      FALSE, etENUM, {normal_axis},
          "Direction of the normal on the membrane" },
        { "-sl",     FALSE, etINT, {&nslices},
          "Calculate order parameter as function of box length, dividing the box"
          " into this number of slices." },
        { "-szonly", FALSE, etBOOL, {&bSzonly},
          "Only give Sz element of order tensor. (axis can be specified with [TT]-d[tt])" },
        { "-unsat",  FALSE, etBOOL, {&bUnsat},
          "Calculate order parameters for unsaturated carbons. Note that this can"
          "not be mixed with normal order parameters." },
        { "-permolecule", FALSE, etBOOL, {&permolecule},
          "Compute per-molecule Scd order parameters" },
        { "-radial", FALSE, etBOOL, {&radial},
          "Compute a radial membrane normal" },
        { "-calcdist", FALSE, etBOOL, {&distcalc},
          "Compute distance from a reference" },
    };

    rvec              *order;                         /* order par. for each atom   */
    real             **slOrder;                       /* same, per slice            */
    real               slWidth = 0.0;                 /* width of a slice           */
    char             **grpname;                       /* groupnames                 */
    int                ngrps,                         /* nr. of groups              */
                       i,
                       axis = 0;                      /* normal axis                */
    t_topology   *top;                                /* topology         */
    int           ePBC;
    atom_id      *index,                              /* indices for a              */
    *a;                                               /* atom numbers in each group */
    t_blocka     *block;                              /* data from index file       */
    t_filenm      fnm[] = {                           /* files for g_order    */
        { efTRX, "-f", NULL,  ffREAD },               /* trajectory file              */
        { efNDX, "-n", NULL,  ffREAD },               /* index file           */
        { efNDX, "-nr", NULL,  ffREAD },              /* index for radial axis calculation	  */
        { efTPX, NULL, NULL,  ffREAD },               /* topology file                */
        { efXVG, "-o", "order", ffWRITE },            /* xvgr output file     */
        { efXVG, "-od", "deuter", ffWRITE },          /* xvgr output file           */
        { efPDB, "-ob", NULL, ffWRITE },              /* write Scd as B factors to PDB if permolecule           */
        { efXVG, "-os", "sliced", ffWRITE },          /* xvgr output file           */
        { efXVG, "-Sg", "sg-ang", ffOPTWR },          /* xvgr output file           */
        { efXVG, "-Sk", "sk-dist", ffOPTWR },         /* xvgr output file           */
        { efXVG, "-Sgsl", "sg-ang-slice", ffOPTWR },  /* xvgr output file           */
        { efXVG, "-Sksl", "sk-dist-slice", ffOPTWR }, /* xvgr output file           */
    };
    gmx_bool      bSliced = FALSE;                    /* True if box is sliced      */
#define NFILE asize(fnm)
    real        **distvals = NULL;
    const char   *sgfnm, *skfnm, *ndxfnm, *tpsfnm, *trxfnm;
    output_env_t  oenv;

    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 (nslices < 1)
    {
        gmx_fatal(FARGS, "Can not have nslices < 1");
    }
    sgfnm  = opt2fn_null("-Sg", NFILE, fnm);
    skfnm  = opt2fn_null("-Sk", NFILE, fnm);
    ndxfnm = opt2fn_null("-n", NFILE, fnm);
    tpsfnm = ftp2fn(efTPX, NFILE, fnm);
    trxfnm = ftp2fn(efTRX, NFILE, fnm);

    /* Calculate axis */
    if (strcmp(normal_axis[0], "x") == 0)
    {
        axis = XX;
    }
    else if (strcmp(normal_axis[0], "y") == 0)
    {
        axis = YY;
    }
    else if (strcmp(normal_axis[0], "z") == 0)
    {
        axis = ZZ;
    }
    else
    {
        gmx_fatal(FARGS, "Invalid axis, use x, y or z");
    }

    switch (axis)
    {
        case 0:
            fprintf(stderr, "Taking x axis as normal to the membrane\n");
            break;
        case 1:
            fprintf(stderr, "Taking y axis as normal to the membrane\n");
            break;
        case 2:
            fprintf(stderr, "Taking z axis as normal to the membrane\n");
            break;
    }

    /* tetraheder order parameter */
    if (skfnm || sgfnm)
    {
        /* If either of theoptions is set we compute both */
        sgfnm = opt2fn("-Sg", NFILE, fnm);
        skfnm = opt2fn("-Sk", NFILE, fnm);
        calc_tetra_order_parm(ndxfnm, tpsfnm, trxfnm, sgfnm, skfnm, nslices, axis,
                              opt2fn("-Sgsl", NFILE, fnm), opt2fn("-Sksl", NFILE, fnm),
                              oenv);
        /* view xvgr files */
        do_view(oenv, opt2fn("-Sg", NFILE, fnm), NULL);
        do_view(oenv, opt2fn("-Sk", NFILE, fnm), NULL);
        if (nslices > 1)
        {
            do_view(oenv, opt2fn("-Sgsl", NFILE, fnm), NULL);
            do_view(oenv, opt2fn("-Sksl", NFILE, fnm), NULL);
        }
    }
    else
    {
        /* tail order parameter */

        if (nslices > 1)
        {
            bSliced = TRUE;
            fprintf(stderr, "Dividing box in %d slices.\n\n", nslices);
        }

        if (bSzonly)
        {
            fprintf(stderr, "Only calculating Sz\n");
        }
        if (bUnsat)
        {
            fprintf(stderr, "Taking carbons as unsaturated!\n");
        }

        top = read_top(ftp2fn(efTPX, NFILE, fnm), &ePBC); /* read topology file */

        block = init_index(ftp2fn(efNDX, NFILE, fnm), &grpname);
        index = block->index;                   /* get indices from t_block block */
        a     = block->a;                       /* see block.h                    */
        ngrps = block->nr;

        if (permolecule)
        {
            nslices = index[1] - index[0]; /*I think this assumes contiguous lipids in topology*/
            fprintf(stderr, "Calculating Scd order parameters for each of %d molecules\n", nslices);
        }

        if (radial)
        {
            fprintf(stderr, "Calculating radial distances\n");
            if (!permolecule)
            {
                gmx_fatal(FARGS, "Cannot yet output radial distances without permolecule\n");
            }
        }

        /* show atomtypes, to check if index file is correct */
        print_types(index, a, ngrps, grpname, top);

        calc_order(ftp2fn(efTRX, NFILE, fnm), index, a, &order,
                   &slOrder, &slWidth, nslices, bSliced, bUnsat,
                   top, ePBC, ngrps, axis, permolecule, radial, distcalc, opt2fn_null("-nr", NFILE, fnm), &distvals, oenv);

        if (radial)
        {
            ngrps--; /*don't print the last group--was used for
                               center-of-mass determination*/

        }
        order_plot(order, slOrder, opt2fn("-o", NFILE, fnm), opt2fn("-os", NFILE, fnm),
                   opt2fn("-od", NFILE, fnm), ngrps, nslices, slWidth, bSzonly, permolecule, distvals, oenv);

        if (opt2bSet("-ob", NFILE, fnm))
        {
            if (!permolecule)
            {
                fprintf(stderr,
                        "Won't write B-factors with averaged order parameters; use -permolecule\n");
            }
            else
            {
                write_bfactors(fnm, NFILE, index, a, nslices, ngrps, slOrder, top, distvals, oenv);
            }
        }


        do_view(oenv, opt2fn("-o", NFILE, fnm), NULL);  /* view xvgr file */
        do_view(oenv, opt2fn("-os", NFILE, fnm), NULL); /* view xvgr file */
        do_view(oenv, opt2fn("-od", NFILE, fnm), NULL); /* view xvgr file */
    }

    if (distvals != NULL)
    {
        for (i = 0; i < nslices; ++i)
        {
            sfree(distvals[i]);
        }
        sfree(distvals);
    }

    return 0;
}
Example #16
0
int gmx_potential(int argc, char *argv[])
{
    const char        *desc[] = {
        "[THISMODULE] computes the electrostatical potential across the box. The potential is",
        "calculated by first summing the charges per slice and then integrating",
        "twice of this charge distribution. Periodic boundaries are not taken",
        "into account. Reference of potential is taken to be the left side of",
        "the box. It is also possible to calculate the potential in spherical",
        "coordinates as function of r by calculating a charge distribution in",
        "spherical slices and twice integrating them. epsilon_r is taken as 1,",
        "but 2 is more appropriate in many cases."
    };
    output_env_t       oenv;
    static int         axis       = 2;       /* normal to memb. default z  */
    static const char *axtitle    = "Z";
    static int         nslices    = 10;      /* nr of slices defined       */
    static int         ngrps      = 1;
    static gmx_bool    bSpherical = FALSE;   /* default is bilayer types   */
    static real        fudge_z    = 0;       /* translate coordinates      */
    static gmx_bool    bCorrect   = 0;
    t_pargs            pa []      = {
        { "-d",   FALSE, etSTR, {&axtitle},
          "Take the normal on the membrane in direction X, Y or Z." },
        { "-sl",  FALSE, etINT, {&nslices},
          "Calculate potential as function of boxlength, dividing the box"
          " in this number of slices." },
        { "-cb",  FALSE, etINT, {&cb},
          "Discard this number of  first slices of box for integration" },
        { "-ce",  FALSE, etINT, {&ce},
          "Discard this number of last slices of box for integration" },
        { "-tz",  FALSE, etREAL, {&fudge_z},
          "Translate all coordinates by this distance in the direction of the box" },
        { "-spherical", FALSE, etBOOL, {&bSpherical},
          "Calculate spherical thingie" },
        { "-ng",       FALSE, etINT, {&ngrps},
          "Number of groups to consider" },
        { "-correct",  FALSE, etBOOL, {&bCorrect},
          "Assume net zero charge of groups to improve accuracy" }
    };
    const char        *bugs[] = {
        "Discarding slices for integration should not be necessary."
    };

    double           **potential,              /* potential per slice        */
    **charge,                                  /* total charge per slice     */
    **field,                                   /* field per slice            */
                       slWidth;                /* width of one slice         */
    char      **grpname;                       /* groupnames                 */
    int        *ngx;                           /* sizes of groups            */
    t_topology *top;                           /* topology        */
    int         ePBC;
    atom_id   **index;                         /* indices for all groups     */
    t_filenm    fnm[] = {                      /* files for g_order       */
        { efTRX, "-f", NULL,  ffREAD },        /* trajectory file             */
        { efNDX, NULL, NULL,  ffREAD },        /* index file          */
        { efTPX, NULL, NULL,  ffREAD },        /* topology file               */
        { efXVG, "-o", "potential", ffWRITE }, /* xvgr output file    */
        { efXVG, "-oc", "charge", ffWRITE },   /* xvgr output file    */
        { efXVG, "-of", "field", ffWRITE },    /* xvgr output file    */
    };

#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, asize(bugs), bugs,
                           &oenv))
    {
        return 0;
    }

    /* Calculate axis */
    axis = toupper(axtitle[0]) - 'X';

    top = read_top(ftp2fn(efTPX, NFILE, fnm), &ePBC); /* read topology file */

    snew(grpname, ngrps);
    snew(index, ngrps);
    snew(ngx, ngrps);

    rd_index(ftp2fn(efNDX, NFILE, fnm), ngrps, ngx, index, grpname);


    calc_potential(ftp2fn(efTRX, NFILE, fnm), index, ngx,
                   &potential, &charge, &field,
                   &nslices, top, ePBC, axis, ngrps, &slWidth, fudge_z,
                   bSpherical, bCorrect, oenv);

    plot_potential(potential, charge, field, opt2fn("-o", NFILE, fnm),
                   opt2fn("-oc", NFILE, fnm), opt2fn("-of", NFILE, fnm),
                   nslices, ngrps, (const char**)grpname, slWidth, oenv);

    do_view(oenv, opt2fn("-o", NFILE, fnm), NULL);  /* view xvgr file */
    do_view(oenv, opt2fn("-oc", NFILE, fnm), NULL); /* view xvgr file */
    do_view(oenv, opt2fn("-of", NFILE, fnm), NULL); /* view xvgr file */

    return 0;
}
Example #17
0
int gmx_filter(int argc,char *argv[])
{
  const char *desc[] = {
    "[TT]g_filter[tt] performs frequency filtering on a trajectory.",
    "The filter shape is cos([GRK]pi[grk] t/A) + 1 from -A to +A, where A is given",
    "by the option [TT]-nf[tt] times the time step in the input trajectory.",
    "This filter reduces fluctuations with period A by 85%, with period",
    "2*A by 50% and with period 3*A by 17% for low-pass filtering.",
    "Both a low-pass and high-pass filtered trajectory can be written.[PAR]",

    "Option [TT]-ol[tt] writes a low-pass filtered trajectory.",
    "A frame is written every [TT]-nf[tt] input frames.",
    "This ratio of filter length and output interval ensures a good",
    "suppression of aliasing of high-frequency motion, which is useful for",
    "making smooth movies. Also averages of properties which are linear",
    "in the coordinates are preserved, since all input frames are weighted",
    "equally in the output.",
    "When all frames are needed, use the [TT]-all[tt] option.[PAR]",

    "Option [TT]-oh[tt] writes a high-pass filtered trajectory.",
    "The high-pass filtered coordinates are added to the coordinates",
    "from the structure file. When using high-pass filtering use [TT]-fit[tt]",
    "or make sure you use a trajectory that has been fitted on",
    "the coordinates in the structure file."
  };
  
  static int nf=10;
  static gmx_bool bNoJump = TRUE,bFit = FALSE,bLowAll = FALSE;
  t_pargs pa[] = {
    { "-nf", FALSE, etINT, {&nf},
      "Sets the filter length as well as the output interval for low-pass filtering" },
    { "-all", FALSE, etBOOL, {&bLowAll},
      "Write all low-pass filtered frames" },
    { "-nojump", FALSE, etBOOL, {&bNoJump},
      "Remove jumps of atoms across the box" },
    { "-fit", FALSE, etBOOL, {&bFit},
      "Fit all frames to a reference structure" }
  };
  const char *topfile,*lowfile,*highfile;
  gmx_bool       bTop=FALSE;
  t_topology top;
  int        ePBC=-1;
  rvec       *xtop;
  matrix     topbox,*box,boxf;
  char       title[256],*grpname;
  int        isize;
  atom_id    *index;
  real       *w_rls=NULL;
  t_trxstatus *in;
  t_trxstatus *outl,*outh;
  int        nffr,i,fr,nat,j,d,m;
  atom_id    *ind;
  real       flen,*filt,sum,*t;
  rvec       xcmtop,xcm,**x,*ptr,*xf,*xn,*xp,hbox;
  output_env_t oenv;
  gmx_rmpbc_t  gpbc=NULL;

#define NLEG asize(leg)
  t_filenm fnm[] = { 
    { efTRX, "-f", NULL, ffREAD  }, 
    { efTPS, NULL, NULL, ffOPTRD },
    { efNDX, NULL, NULL, ffOPTRD },
    { efTRO, "-ol", "lowpass",  ffOPTWR }, 
    { efTRO, "-oh", "highpass", ffOPTWR } 
  }; 
#define NFILE asize(fnm) 

  parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_BE_NICE,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv); 

  highfile = opt2fn_null("-oh",NFILE,fnm);
  if (highfile) {
    topfile = ftp2fn(efTPS,NFILE,fnm);
    lowfile = opt2fn_null("-ol",NFILE,fnm);
  } else {
    topfile = ftp2fn_null(efTPS,NFILE,fnm);
    lowfile = opt2fn("-ol",NFILE,fnm);
  }
  if (topfile) {
    bTop = read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,
			 &xtop,NULL,topbox,TRUE);
    if (bTop) {
      gpbc = gmx_rmpbc_init(&top.idef,ePBC,top.atoms.nr,topbox);
      gmx_rmpbc(gpbc,top.atoms.nr,topbox,xtop);
    }
  }

  clear_rvec(xcmtop);
  if (bFit) {
    fprintf(stderr,"Select group for least squares fit\n");
    get_index(&top.atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&isize,&index,&grpname);
    /* Set the weight */
    snew(w_rls,top.atoms.nr);
    for(i=0; i<isize; i++) 
      w_rls[index[i]] = top.atoms.atom[index[i]].m;
    calc_xcm(xtop,isize,index,top.atoms.atom,xcmtop,FALSE);
    for(j=0; j<top.atoms.nr; j++)
      rvec_dec(xtop[j],xcmtop);
  }

  /* The actual filter length flen can actually be any real number */
  flen = 2*nf;
  /* nffr is the number of frames that we filter over */
  nffr = 2*nf - 1;
  snew(filt,nffr);
  sum = 0;
  for(i=0; i<nffr; i++) {
    filt[i] = cos(2*M_PI*(i - nf + 1)/(real)flen) + 1;
    sum += filt[i];
  }
  fprintf(stdout,"filter weights:");
  for(i=0; i<nffr; i++) {
    filt[i] /= sum;
    fprintf(stdout," %5.3f",filt[i]);
  }
  fprintf(stdout,"\n");
  
  snew(t,nffr);
  snew(x,nffr);
  snew(box,nffr);

  nat = read_first_x(oenv,&in,opt2fn("-f",NFILE,fnm),
		     &(t[nffr - 1]),&(x[nffr - 1]),box[nffr - 1]);
  snew(ind,nat);
  for(i=0; i<nat; i++)
    ind[i] = i;
  /* x[nffr - 1] was already allocated by read_first_x */
  for(i=0; i<nffr-1; i++)
    snew(x[i],nat);
  snew(xf,nat);
  if (lowfile)
    outl = open_trx(lowfile,"w");
  else
    outl = 0;
  if (highfile)
    outh = open_trx(highfile,"w");
  else
    outh = 0;

  fr = 0;
  do {
    xn = x[nffr - 1];
    if (bNoJump && fr > 0) {
      xp = x[nffr - 2];
      for(j=0; j<nat; j++)
	for(d=0; d<DIM; d++)
	  hbox[d] = 0.5*box[nffr - 1][d][d];
      for(i=0; i<nat; i++)
	for(m=DIM-1; m>=0; m--)
	  if (hbox[m] > 0) {
	    while (xn[i][m] - xp[i][m] <= -hbox[m])
	      for(d=0; d<=m; d++)
		xn[i][d] += box[nffr - 1][m][d];
	    while (xn[i][m] - xp[i][m] > hbox[m])
	      for(d=0; d<=m; d++)
		xn[i][d] -= box[nffr - 1][m][d];
	  }
    }
    if (bTop) {
      gmx_rmpbc(gpbc,nat,box[nffr - 1],xn);
    }
    if (bFit) {
      calc_xcm(xn,isize,index,top.atoms.atom,xcm,FALSE);
      for(j=0; j<nat; j++)
	rvec_dec(xn[j],xcm);
      do_fit(nat,w_rls,xtop,xn);
      for(j=0; j<nat; j++)
	rvec_inc(xn[j],xcmtop);
    }
    if (fr >= nffr && (outh || bLowAll || fr % nf == nf - 1)) {
      /* Lowpass filtering */
      for(j=0; j<nat; j++)
	clear_rvec(xf[j]);
      clear_mat(boxf);
      for(i=0; i<nffr; i++) {
	for(j=0; j<nat; j++)
	  for(d=0; d<DIM; d++)
	    xf[j][d] += filt[i]*x[i][j][d];
	for(j=0; j<DIM; j++)
	  for(d=0; d<DIM; d++)
	    boxf[j][d] += filt[i]*box[i][j][d];
      }
      if (outl && (bLowAll || fr % nf == nf - 1))
	write_trx(outl,nat,ind,topfile ? &(top.atoms) : NULL,
		  0,t[nf - 1],bFit ? topbox : boxf,xf,NULL,NULL);
      if (outh) {
	/* Highpass filtering */
	for(j=0; j<nat; j++)
	  for(d=0; d<DIM; d++)
	    xf[j][d] = xtop[j][d] + x[nf - 1][j][d] - xf[j][d];
	if (bFit)
	  for(j=0; j<nat; j++)
	    rvec_inc(xf[j],xcmtop);
	for(j=0; j<DIM; j++)
	  for(d=0; d<DIM; d++)
	    boxf[j][d] = topbox[j][d] + box[nf - 1][j][d] - boxf[j][d];
	write_trx(outh,nat,ind,topfile ? &(top.atoms) : NULL,
		  0,t[nf - 1],bFit ? topbox : boxf,xf,NULL,NULL);
      }
    }
    /* Cycle all the pointer and the box by one */
    ptr = x[0];
    for(i=0; i<nffr-1; i++) {
      t[i] = t[i+1];
      x[i] = x[i+1];
      copy_mat(box[i+1],box[i]);
    }
    x[nffr - 1] = ptr;
    fr++;
  } while (read_next_x(oenv,in,&(t[nffr - 1]),nat,x[nffr - 1],box[nffr - 1]));
  
  if (bTop)
    gmx_rmpbc_done(gpbc);

  if (outh)
    close_trx(outh);
  if (outl)
    close_trx(outl);
  close_trx(in);
  
  return 0;
}
Example #18
0
int gmx_rmsdist(int argc, char *argv[])
{
    const char     *desc[] = {
        "[THISMODULE] computes the root mean square deviation of atom distances,",
        "which has the advantage that no fit is needed like in standard RMS",
        "deviation as computed by [gmx-rms].",
        "The reference structure is taken from the structure file.",
        "The RMSD at time t is calculated as the RMS",
        "of the differences in distance between atom-pairs in the reference",
        "structure and the structure at time t.[PAR]",
        "[THISMODULE] can also produce matrices of the rms distances, rms distances",
        "scaled with the mean distance and the mean distances and matrices with",
        "NMR averaged distances (1/r^3 and 1/r^6 averaging). Finally, lists",
        "of atom pairs with 1/r^3 and 1/r^6 averaged distance below the",
        "maximum distance ([TT]-max[tt], which will default to 0.6 in this case)",
        "can be generated, by default averaging over equivalent hydrogens",
        "(all triplets of hydrogens named \\*[123]). Additionally a list of",
        "equivalent atoms can be supplied ([TT]-equiv[tt]), each line containing",
        "a set of equivalent atoms specified as residue number and name and",
        "atom name; e.g.:[PAR]",
        "[TT]HB* 3 SER  HB1 3 SER  HB2[tt][PAR]",
        "Residue and atom names must exactly match those in the structure",
        "file, including case. Specifying non-sequential atoms is undefined."

    };

    int             i, teller;
    real            t;

    t_topology      top;
    int             ePBC;
    t_atoms        *atoms;
    matrix          box;
    rvec           *x;
    FILE           *fp;

    t_trxstatus    *status;
    int             isize, gnr = 0;
    atom_id        *index, *noe_index;
    char           *grpname;
    real          **d_r, **d, **dtot, **dtot2, **mean, **rms, **rmsc, *resnr;
    real          **dtot1_3 = NULL, **dtot1_6 = NULL;
    real            rmsnow, meanmax, rmsmax, rmscmax;
    real            max1_3, max1_6;
    t_noe_gr       *noe_gr = NULL;
    t_noe         **noe    = NULL;
    t_rgb           rlo, rhi;
    gmx_bool        bRMS, bScale, bMean, bNOE, bNMR3, bNMR6, bNMR;

    static int      nlevels  = 40;
    static real     scalemax = -1.0;
    static gmx_bool bSumH    = TRUE;
    static gmx_bool bPBC     = TRUE;
    output_env_t    oenv;

    t_pargs         pa[] = {
        { "-nlevels",   FALSE, etINT,  {&nlevels},
          "Discretize RMS in this number of levels" },
        { "-max",   FALSE, etREAL, {&scalemax},
          "Maximum level in matrices" },
        { "-sumh",  FALSE, etBOOL, {&bSumH},
          "Average distance over equivalent hydrogens" },
        { "-pbc",   FALSE, etBOOL, {&bPBC},
          "Use periodic boundary conditions when computing distances" }
    };
    t_filenm        fnm[] = {
        { efTRX, "-f",   NULL,       ffREAD },
        { efTPS, NULL,   NULL,       ffREAD },
        { efNDX, NULL,   NULL,       ffOPTRD },
        { efDAT, "-equiv", "equiv",   ffOPTRD },
        { efXVG, NULL,   "distrmsd", ffWRITE },
        { efXPM, "-rms", "rmsdist",  ffOPTWR },
        { efXPM, "-scl", "rmsscale", ffOPTWR },
        { efXPM, "-mean", "rmsmean",  ffOPTWR },
        { efXPM, "-nmr3", "nmr3",     ffOPTWR },
        { efXPM, "-nmr6", "nmr6",     ffOPTWR },
        { efDAT, "-noe", "noe",     ffOPTWR },
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    bRMS   = opt2bSet("-rms", NFILE, fnm);
    bScale = opt2bSet("-scl", NFILE, fnm);
    bMean  = opt2bSet("-mean", NFILE, fnm);
    bNOE   = opt2bSet("-noe", NFILE, fnm);
    bNMR3  = opt2bSet("-nmr3", NFILE, fnm);
    bNMR6  = opt2bSet("-nmr6", NFILE, fnm);
    bNMR   = bNMR3 || bNMR6 || bNOE;

    max1_3 = 0;
    max1_6 = 0;

    /* check input */
    if (bNOE && scalemax < 0)
    {
        scalemax = 0.6;
        fprintf(stderr, "WARNING: using -noe without -max "
                "makes no sense, setting -max to %g\n\n", scalemax);
    }

    /* get topology and index */
    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &x, NULL, box, FALSE);

    if (!bPBC)
    {
        ePBC = epbcNONE;
    }
    atoms = &(top.atoms);

    get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, &grpname);

    /* initialize arrays */
    snew(d, isize);
    snew(dtot, isize);
    snew(dtot2, isize);
    if (bNMR)
    {
        snew(dtot1_3, isize);
        snew(dtot1_6, isize);
    }
    snew(mean, isize);
    snew(rms, isize);
    snew(rmsc, isize);
    snew(d_r, isize);
    snew(resnr, isize);
    for (i = 0; (i < isize); i++)
    {
        snew(d[i], isize);
        snew(dtot[i], isize);
        snew(dtot2[i], isize);
        if (bNMR)
        {
            snew(dtot1_3[i], isize);
            snew(dtot1_6[i], isize);
        }
        snew(mean[i], isize);
        snew(rms[i], isize);
        snew(rmsc[i], isize);
        snew(d_r[i], isize);
        resnr[i] = i+1;
    }

    /*set box type*/
    calc_dist(isize, index, x, ePBC, box, d_r);
    sfree(x);

    /*open output files*/
    fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "RMS Deviation", "Time (ps)", "RMSD (nm)",
                  oenv);
    if (output_env_get_print_xvgr_codes(oenv))
    {
        fprintf(fp, "@ subtitle \"of distances between %s atoms\"\n", grpname);
    }

    /*do a first step*/
    read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);
    teller = 0;

    do
    {
        calc_dist_tot(isize, index, x, ePBC, box, d, dtot, dtot2, bNMR, dtot1_3, dtot1_6);

        rmsnow = rms_diff(isize, d, d_r);
        fprintf(fp, "%g  %g\n", t, rmsnow);
        teller++;
    }
    while (read_next_x(oenv, status, &t, x, box));
    fprintf(stderr, "\n");

    xvgrclose(fp);

    close_trj(status);

    calc_rms(isize, teller, dtot, dtot2, rms, &rmsmax, rmsc, &rmscmax, mean, &meanmax);
    fprintf(stderr, "rmsmax = %g, rmscmax = %g\n", rmsmax, rmscmax);

    if (bNMR)
    {
        calc_nmr(isize, teller, dtot1_3, dtot1_6, &max1_3, &max1_6);
    }

    if (scalemax > -1.0)
    {
        rmsmax  = scalemax;
        rmscmax = scalemax;
        meanmax = scalemax;
        max1_3  = scalemax;
        max1_6  = scalemax;
    }

    if (bNOE)
    {
        /* make list of noe atom groups */
        snew(noe_index, isize+1);
        snew(noe_gr, isize);
        gnr = analyze_noe_equivalent(opt2fn_null("-equiv", NFILE, fnm),
                                     atoms, isize, index, bSumH, noe_index, noe_gr);
        fprintf(stdout, "Found %d non-equivalent atom-groups in %d atoms\n",
                gnr, isize);
        /* make half matrix of of noe-group distances from atom distances */
        snew(noe, gnr);
        for (i = 0; i < gnr; i++)
        {
            snew(noe[i], gnr);
        }
        calc_noe(isize, noe_index, dtot1_3, dtot1_6, gnr, noe);
    }

    rlo.r = 1.0, rlo.g = 1.0, rlo.b = 1.0;
    rhi.r = 0.0, rhi.g = 0.0, rhi.b = 0.0;

    if (bRMS)
    {
        write_xpm(opt2FILE("-rms", NFILE, fnm, "w"), 0,
                  "RMS of distance", "RMS (nm)", "Atom Index", "Atom Index",
                  isize, isize, resnr, resnr, rms, 0.0, rmsmax, rlo, rhi, &nlevels);
    }

    if (bScale)
    {
        write_xpm(opt2FILE("-scl", NFILE, fnm, "w"), 0,
                  "Relative RMS", "RMS", "Atom Index", "Atom Index",
                  isize, isize, resnr, resnr, rmsc, 0.0, rmscmax, rlo, rhi, &nlevels);
    }

    if (bMean)
    {
        write_xpm(opt2FILE("-mean", NFILE, fnm, "w"), 0,
                  "Mean Distance", "Distance (nm)", "Atom Index", "Atom Index",
                  isize, isize, resnr, resnr, mean, 0.0, meanmax, rlo, rhi, &nlevels);
    }

    if (bNMR3)
    {
        write_xpm(opt2FILE("-nmr3", NFILE, fnm, "w"), 0, "1/r^3 averaged distances",
                  "Distance (nm)", "Atom Index", "Atom Index",
                  isize, isize, resnr, resnr, dtot1_3, 0.0, max1_3, rlo, rhi, &nlevels);
    }
    if (bNMR6)
    {
        write_xpm(opt2FILE("-nmr6", NFILE, fnm, "w"), 0, "1/r^6 averaged distances",
                  "Distance (nm)", "Atom Index", "Atom Index",
                  isize, isize, resnr, resnr, dtot1_6, 0.0, max1_6, rlo, rhi, &nlevels);
    }

    if (bNOE)
    {
        write_noe(opt2FILE("-noe", NFILE, fnm, "w"), gnr, noe, noe_gr, scalemax);
    }

    do_view(oenv, ftp2fn(efXVG, NFILE, fnm), NULL);

    return 0;
}
Example #19
0
int main(int argc,char *argv[])
{
  int       mmm[] = { 8, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36, 40,
		      45, 48, 50, 54, 60, 64, 72, 75, 80, 81, 90, 100 };
  int       nnn[] = { 24, 32, 48, 60, 72, 84, 96 };
#define NNN asize(nnn)
  FILE      *fp,*fplog;
  int       *niter;
  int       i,j,n,nit,ntot,n3,rsize;
  double    t,nflop,start;
  double    *rt,*ct;
  t_fftgrid *g;
  t_commrec *cr;
  static gmx_bool bReproducible = FALSE;
  static int  nnode    = 1;
  static int  nitfac  = 1;
  t_pargs pa[] = {
    { "-reproducible",   FALSE, etBOOL, {&bReproducible}, 
      "Request binary reproducible results" },
    { "-np",    FALSE, etINT, {&nnode},
      "Number of NODEs" },
    { "-itfac", FALSE, etINT, {&nitfac},
      "Multiply number of iterations by this" }
  };
  static t_filenm fnm[] = {
    { efLOG, "-g", "fft",      ffWRITE },
    { efXVG, "-o", "fft",      ffWRITE }
  };
#define NFILE asize(fnm)
  
  cr = init_par(&argc,&argv);
  if (MASTER(cr))
    CopyRight(stdout,argv[0]);
  parse_common_args(&argc,argv, PCA_CAN_SET_DEFFNM,
		    NFILE,fnm,asize(pa),pa,0,NULL,0,NULL);
  gmx_log_open(ftp2fn(efLOG,NFILE,fnm),cr,1,0,&fplog);

  snew(niter,NNN);
  snew(ct,NNN);
  snew(rt,NNN);
  rsize = sizeof(real);
  for(i=0; (i<NNN); i++) {
    n  = nnn[i];
    if (n < 16)
      niter[i] = 50;
    else if (n < 26)
      niter[i] = 20;
    else if (n < 51)
      niter[i] = 10;
    else
      niter[i] = 5;
    niter[i] *= nitfac;
    nit = niter[i];
    
    if (MASTER(cr))
      fprintf(stderr,"\r3D FFT (%s precision) %3d^3, niter %3d     ",
	      (rsize == 8) ? "Double" : "Single",n,nit);
    
    g  = mk_fftgrid(n,n,n,NULL,NULL,cr,bReproducible);

    if (PAR(cr))
      start = time(NULL);
    else
      start_time();
    for(j=0; (j<nit); j++) {
      gmxfft3D(g,GMX_FFT_REAL_TO_COMPLEX,cr);
      gmxfft3D(g,GMX_FFT_COMPLEX_TO_REAL,cr);
    }
    if (PAR(cr)) 
      rt[i] = time(NULL)-start;
    else {
      update_time();
      rt[i] = node_time();
    }
    done_fftgrid(g);
    sfree(g);
  }
  if (MASTER(cr)) {
    fprintf(stderr,"\n");
    fp=xvgropen(ftp2fn(efXVG,NFILE,fnm),
		"FFT timings","n^3","t (s)");
    for(i=0; (i<NNN); i++) {
      n3 = 2*niter[i]*nnn[i]*nnn[i]*nnn[i];
      fprintf(fp,"%10d  %10g\n",nnn[i],rt[i]/(2*niter[i]));
    }
    gmx_fio_fclose(fp);
  }
  return 0;
}
Example #20
0
int gmx_current(int argc, char *argv[])
{

    static int             nshift  = 1000;
    static real            temp    = 300.0;
    static real            trust   = 0.25;
    static real            eps_rf  = 0.0;
    static gmx_bool        bNoJump = TRUE;
    static real            bfit    = 100.0;
    static real            bvit    = 0.5;
    static real            efit    = 400.0;
    static real            evit    = 5.0;
    t_pargs                pa[]    = {
        { "-sh", FALSE, etINT, {&nshift},
          "Shift of the frames for averaging the correlation functions and the mean-square displacement."},
        { "-nojump", FALSE, etBOOL, {&bNoJump},
          "Removes jumps of atoms across the box."},
        { "-eps", FALSE, etREAL, {&eps_rf},
          "Dielectric constant of the surrounding medium. The value zero corresponds to infinity (tin-foil boundary conditions)."},
        { "-bfit", FALSE, etREAL, {&bfit},
          "Begin of the fit of the straight line to the MSD of the translational fraction of the dipole moment."},
        { "-efit", FALSE, etREAL, {&efit},
          "End of the fit of the straight line to the MSD of the translational fraction of the dipole moment."},
        { "-bvit", FALSE, etREAL, {&bvit},
          "Begin of the fit of the current autocorrelation function to a*t^b."},
        { "-evit", FALSE, etREAL, {&evit},
          "End of the fit of the current autocorrelation function to a*t^b."},
        { "-tr", FALSE, etREAL, {&trust},
          "Fraction of the trajectory taken into account for the integral."},
        { "-temp", FALSE, etREAL, {&temp},
          "Temperature for calculating epsilon."}
    };

    output_env_t           oenv;
    t_topology             top;
    char                   title[STRLEN];
    char                 **grpname = NULL;
    const char            *indexfn;
    t_trxframe             fr;
    real                  *mass2 = NULL;
    rvec                  *xtop, *vtop;
    matrix                 box;
    atom_id               *index0;
    int                   *indexm = NULL;
    int                    isize;
    t_trxstatus           *status;
    int                    flags = 0;
    gmx_bool               bTop;
    gmx_bool               bNEU;
    gmx_bool               bACF;
    gmx_bool               bINT;
    int                    ePBC = -1;
    int                    natoms;
    int                    nmols;
    int                    i, j, k = 0, l;
    int                    step;
    real                   t;
    real                   lambda;
    real                  *qmol;
    FILE                  *outf   = NULL;
    FILE                  *outi   = NULL;
    FILE                  *tfile  = NULL;
    FILE                  *mcor   = NULL;
    FILE                  *fmj    = NULL;
    FILE                  *fmd    = NULL;
    FILE                  *fmjdsp = NULL;
    FILE                  *fcur   = NULL;
    t_filenm               fnm[]  = {
        { efTPS,  NULL,  NULL, ffREAD }, /* this is for the topology */
        { efNDX, NULL, NULL, ffOPTRD },
        { efTRX, "-f", NULL, ffREAD },   /* and this for the trajectory */
        { efXVG, "-o", "current.xvg", ffWRITE },
        { efXVG, "-caf", "caf.xvg", ffOPTWR },
        { efXVG, "-dsp", "dsp.xvg", ffWRITE },
        { efXVG, "-md", "md.xvg", ffWRITE },
        { efXVG, "-mj", "mj.xvg", ffWRITE},
        { efXVG, "-mc", "mc.xvg", ffOPTWR }
    };

#define NFILE asize(fnm)


    const char *desc[] = {
        "[TT]g_current[tt] is a tool for calculating the current autocorrelation function, the correlation",
        "of the rotational and translational dipole moment of the system, and the resulting static",
        "dielectric constant. To obtain a reasonable result, the index group has to be neutral.",
        "Furthermore, the routine is capable of extracting the static conductivity from the current ",
        "autocorrelation function, if velocities are given. Additionally, an Einstein-Helfand fit ",
        "can be used to obtain the static conductivity."
        "[PAR]",
        "The flag [TT]-caf[tt] is for the output of the current autocorrelation function and [TT]-mc[tt] writes the",
        "correlation of the rotational and translational part of the dipole moment in the corresponding",
        "file. However, this option is only available for trajectories containing velocities.",
        "Options [TT]-sh[tt] and [TT]-tr[tt] are responsible for the averaging and integration of the",
        "autocorrelation functions. Since averaging proceeds by shifting the starting point",
        "through the trajectory, the shift can be modified with [TT]-sh[tt] to enable the choice of uncorrelated",
        "starting points. Towards the end, statistical inaccuracy grows and integrating the",
        "correlation function only yields reliable values until a certain point, depending on",
        "the number of frames. The option [TT]-tr[tt] controls the region of the integral taken into account",
        "for calculating the static dielectric constant.",
        "[PAR]",
        "Option [TT]-temp[tt] sets the temperature required for the computation of the static dielectric constant.",
        "[PAR]",
        "Option [TT]-eps[tt] controls the dielectric constant of the surrounding medium for simulations using",
        "a Reaction Field or dipole corrections of the Ewald summation ([TT]-eps[tt]=0 corresponds to",
        "tin-foil boundary conditions).",
        "[PAR]",
        "[TT]-[no]nojump[tt] unfolds the coordinates to allow free diffusion. This is required to get a continuous",
        "translational dipole moment, required for the Einstein-Helfand fit. The results from the fit allow",
        "the determination of the dielectric constant for system of charged molecules. However, it is also possible to extract",
        "the dielectric constant from the fluctuations of the total dipole moment in folded coordinates. But this",
        "option has to be used with care, since only very short time spans fulfill the approximation that the density",
        "of the molecules is approximately constant and the averages are already converged. To be on the safe side,",
        "the dielectric constant should be calculated with the help of the Einstein-Helfand method for",
        "the translational part of the dielectric constant."
    };


    /* At first the arguments will be parsed and the system information processed */
    parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW,
                      NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv);

    bACF = opt2bSet("-caf", NFILE, fnm);
    bINT = opt2bSet("-mc", NFILE, fnm);

    bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), title, &top, &ePBC, &xtop, &vtop, box, TRUE);



    sfree(xtop);
    sfree(vtop);
    indexfn = ftp2fn_null(efNDX, NFILE, fnm);
    snew(grpname, 1);

    get_index(&(top.atoms), indexfn, 1, &isize, &index0, grpname);

    flags = flags | TRX_READ_X | TRX_READ_V;

    read_first_frame(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &fr, flags);

    snew(mass2, top.atoms.nr);
    snew(qmol, top.atoms.nr);

    bNEU = precalc(top, mass2, qmol);


    snew(indexm, isize);

    for (i = 0; i < isize; i++)
    {
        indexm[i] = index0[i];
    }

    nmols = isize;


    index_atom2mol(&nmols, indexm, &top.mols);

    if (fr.bV)
    {
        if (bACF)
        {
            outf = xvgropen(opt2fn("-caf", NFILE, fnm),
                            "Current autocorrelation function", output_env_get_xvgr_tlabel(oenv),
                            "ACF (e nm/ps)\\S2", oenv);
            fprintf(outf, "# time\t acf\t average \t std.dev\n");
        }
        fcur = xvgropen(opt2fn("-o", NFILE, fnm),
                        "Current", output_env_get_xvgr_tlabel(oenv), "J(t) (e nm/ps)", oenv);
        fprintf(fcur, "# time\t Jx\t Jy \t J_z \n");
        if (bINT)
        {
            mcor = xvgropen(opt2fn("-mc", NFILE, fnm),
                            "M\\sD\\N - current  autocorrelation function",
                            output_env_get_xvgr_tlabel(oenv),
                            "< M\\sD\\N (0)\\c7\\CJ(t) >  (e nm/ps)\\S2", oenv);
            fprintf(mcor, "# time\t M_D(0) J(t) acf \t Integral acf\n");
        }
    }

    fmj = xvgropen(opt2fn("-mj", NFILE, fnm),
                   "Averaged translational part of M", output_env_get_xvgr_tlabel(oenv),
                   "< M\\sJ\\N > (enm)", oenv);
    fprintf(fmj, "# time\t x\t y \t z \t average of M_J^2 \t std.dev\n");
    fmd = xvgropen(opt2fn("-md", NFILE, fnm),
                   "Averaged rotational part of M", output_env_get_xvgr_tlabel(oenv),
                   "< M\\sD\\N > (enm)", oenv);
    fprintf(fmd, "# time\t x\t y \t z \t average of M_D^2 \t std.dev\n");

    fmjdsp = xvgropen(opt2fn("-dsp", NFILE, fnm),
                      "MSD of the squared translational dipole moment M",
                      output_env_get_xvgr_tlabel(oenv),
                      "<|M\\sJ\\N(t)-M\\sJ\\N(0)|\\S2\\N > / 6.0*V*k\\sB\\N*T / Sm\\S-1\\Nps\\S-1\\N",
                      oenv);


    /* System information is read and prepared, dielectric() processes the frames
     * and calculates the requested quantities */

    dielectric(fmj, fmd, outf, fcur, mcor, fmjdsp, bNoJump, bACF, bINT, ePBC, top, fr,
               temp, trust, bfit, efit, bvit, evit, status, isize, nmols, nshift,
               index0, indexm, mass2, qmol, eps_rf, oenv);

    ffclose(fmj);
    ffclose(fmd);
    ffclose(fmjdsp);
    if (bACF)
    {
        ffclose(outf);
    }
    if (bINT)
    {
        ffclose(mcor);
    }

    thanx(stderr);

    return 0;
}
Example #21
0
int main(int argc,char *argv[])
{
  static char *desc[] = {
    "compnl compares two neighborlists as generated by [TT]mdrun[tt]",
    "in the log file, when the environment variable DUMPNL is set to",
    "a number larger than 0. compnl is mainly used for debugging the",
    "mdrun internals and not for end-users."
  };
  FILE    *in,*out;
  int     i,j,nmiss,mod;
  char    **fn,title[256];
  int     ***mat,nnb;
  real    mb;
  bool    bConf;
  rvec    *x = NULL;
  rvec    dx;
  matrix  box;
  t_atoms atoms;
  t_pbc   pbc;
  
  t_filenm fnm[] = {
    { efLOG, "-f1", NULL, ffREAD },
    { efLOG, "-f2", NULL, ffREAD },
    { efOUT, "-o",  "compnl", ffWRITE },
    { efSTX, "-c",  NULL, ffOPTRD }
  };
#define NFILE asize(fnm)
  static int natoms=648;
  static bool bSymm=TRUE;
  static t_pargs pa[] = {
    { "-nat",  FALSE, etINT, { &natoms }, "Number of atoms" },
    { "-symm", FALSE, etBOOL,{ &bSymm  }, "Symmetrize the matrices" },
  };

  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,0,NFILE,fnm,asize(pa),pa,
		    asize(desc),desc,0,NULL);

  bConf = (opt2bSet("-c",NFILE,fnm));
  if (bConf) {
    get_stx_coordnum (opt2fn("-c",NFILE,fnm),&natoms);
    init_t_atoms(&atoms,natoms,FALSE);
    snew(x,natoms);
    read_stx_conf(opt2fn("-c",NFILE,fnm),title,&atoms,x,NULL,box);
    set_pbc(&pbc,box);
  }
  snew(fn,2);
  fn[0] = opt2fn("-f1",NFILE,fnm);
  fn[1] = opt2fn("-f2",NFILE,fnm);
  
  snew(mat,2);  
  out = gmx_fio_fopen(ftp2fn(efOUT,NFILE,fnm),"w");
  mb  = sizeof(int)*sqr(natoms/1024.0);
  for(i=0; (i<2); i++) {
    in = gmx_fio_fopen(fn[i],"r");
    fprintf(stderr,"Reading %s\n",fn[i]);
    fprintf(out,   "Reading %s\n",fn[i]);
    fprintf(stderr,"Going to allocate %.0f Mb of memory\n",mb);
    fprintf(out,   "Going to allocate %.0f Mb of memory\n",mb);
    snew(mat[i],natoms);
    for(j=0; (j<natoms); j++) 
      snew(mat[i][j],natoms);
    nnb = read_nblist(in,out,mat[i],natoms,bSymm);
    gmx_fio_fclose(in);
    fprintf(stderr,"Interaction matrix %d has %d entries\n",i,nnb);
    fprintf(out,   "Interaction matrix %d has %d entries\n",i,nnb);
  }
  fprintf(stderr,"Comparing Interaction Matrices\n");
  mod=1;
  nmiss = 0;
  for(i=0; (i<natoms); i+=mod) {
    for(j=0; (j<natoms); j+=mod) {
      if (mat[0][i][j] != mat[1][i][j]) {
	fprintf(out,"i: %5d, j: %5d, shift[%s]: %3d, shift[%s]: %3d",
		i,j,fn[0],mat[0][i][j]-1,fn[1],mat[1][i][j]-1);
	if (bConf) {
	  pbc_dx(&pbc,x[i],x[j],dx);
	  fprintf(out," dist: %8.3f\n",norm(dx));
	}
	else
	  fprintf(out,"\n");
	nmiss++;
      }
    }
  }
  fprintf(out,"There were %d mismatches\n",nmiss);
  fprintf(out,"Done.\n");
  gmx_fio_fclose(out);
  fprintf(stderr,"There were %d mismatches\n",nmiss);
  fprintf(stderr,"Finished\n");
  
  thanx(stdout);
  
  return 0;
}
Example #22
0
int gmx_editconf(int argc, char *argv[])
{
    const char     *desc[] =
    {
        "[THISMODULE] converts generic structure format to [REF].gro[ref], [TT].g96[tt]",
        "or [REF].pdb[ref].",
        "[PAR]",
        "The box can be modified with options [TT]-box[tt], [TT]-d[tt] and",
        "[TT]-angles[tt]. Both [TT]-box[tt] and [TT]-d[tt]",
        "will center the system in the box, unless [TT]-noc[tt] is used.",
        "The [TT]-center[tt] option can be used to shift the geometric center",
        "of the system from the default of (x/2, y/2, z/2) implied by [TT]-c[tt]",
        "to some other value.",
        "[PAR]",
        "Option [TT]-bt[tt] determines the box type: [TT]triclinic[tt] is a",
        "triclinic box, [TT]cubic[tt] is a rectangular box with all sides equal",
        "[TT]dodecahedron[tt] represents a rhombic dodecahedron and",
        "[TT]octahedron[tt] is a truncated octahedron.",
        "The last two are special cases of a triclinic box.",
        "The length of the three box vectors of the truncated octahedron is the",
        "shortest distance between two opposite hexagons.",
        "Relative to a cubic box with some periodic image distance, the volume of a ",
        "dodecahedron with this same periodic distance is 0.71 times that of the cube, ",
        "and that of a truncated octahedron is 0.77 times.",
        "[PAR]",
        "Option [TT]-box[tt] requires only",
        "one value for a cubic, rhombic dodecahedral, or truncated octahedral box.",
        "[PAR]",
        "With [TT]-d[tt] and a [TT]triclinic[tt] box the size of the system in the [IT]x[it]-, [IT]y[it]-,",
        "and [IT]z[it]-directions is used. With [TT]-d[tt] and [TT]cubic[tt],",
        "[TT]dodecahedron[tt] or [TT]octahedron[tt] boxes, the dimensions are set",
        "to the diameter of the system (largest distance between atoms) plus twice",
        "the specified distance.",
        "[PAR]",
        "Option [TT]-angles[tt] is only meaningful with option [TT]-box[tt] and",
        "a triclinic box and cannot be used with option [TT]-d[tt].",
        "[PAR]",
        "When [TT]-n[tt] or [TT]-ndef[tt] is set, a group",
        "can be selected for calculating the size and the geometric center,",
        "otherwise the whole system is used.",
        "[PAR]",
        "[TT]-rotate[tt] rotates the coordinates and velocities.",
        "[PAR]",
        "[TT]-princ[tt] aligns the principal axes of the system along the",
        "coordinate axes, with the longest axis aligned with the [IT]x[it]-axis. ",
        "This may allow you to decrease the box volume,",
        "but beware that molecules can rotate significantly in a nanosecond.",
        "[PAR]",
        "Scaling is applied before any of the other operations are",
        "performed. Boxes and coordinates can be scaled to give a certain density (option",
        "[TT]-density[tt]). Note that this may be inaccurate in case a [REF].gro[ref]",
        "file is given as input. A special feature of the scaling option is that when the",
        "factor -1 is given in one dimension, one obtains a mirror image,",
        "mirrored in one of the planes. When one uses -1 in three dimensions, ",
        "a point-mirror image is obtained.[PAR]",
        "Groups are selected after all operations have been applied.[PAR]",
        "Periodicity can be removed in a crude manner.",
        "It is important that the box vectors at the bottom of your input file",
        "are correct when the periodicity is to be removed.",
        "[PAR]",
        "When writing [REF].pdb[ref] files, B-factors can be",
        "added with the [TT]-bf[tt] option. B-factors are read",
        "from a file with with following format: first line states number of",
        "entries in the file, next lines state an index",
        "followed by a B-factor. The B-factors will be attached per residue",
        "unless the number of B-factors is larger than the number of the residues or unless the",
        "[TT]-atom[tt] option is set. Obviously, any type of numeric data can",
        "be added instead of B-factors. [TT]-legend[tt] will produce",
        "a row of CA atoms with B-factors ranging from the minimum to the",
        "maximum value found, effectively making a legend for viewing.",
        "[PAR]",
        "With the option [TT]-mead[tt] a special [REF].pdb[ref] ([REF].pqr[ref])",
        "file for the MEAD electrostatics",
        "program (Poisson-Boltzmann solver) can be made. A further prerequisite",
        "is that the input file is a run input file.",
        "The B-factor field is then filled with the Van der Waals radius",
        "of the atoms while the occupancy field will hold the charge.",
        "[PAR]",
        "The option [TT]-grasp[tt] is similar, but it puts the charges in the B-factor",
        "and the radius in the occupancy.",
        "[PAR]",
        "Option [TT]-align[tt] allows alignment",
        "of the principal axis of a specified group against the given vector, ",
        "with an optional center of rotation specified by [TT]-aligncenter[tt].",
        "[PAR]",
        "Finally, with option [TT]-label[tt], [TT]editconf[tt] can add a chain identifier",
        "to a [REF].pdb[ref] file, which can be useful for analysis with e.g. Rasmol.",
        "[PAR]",
        "To convert a truncated octrahedron file produced by a package which uses",
        "a cubic box with the corners cut off (such as GROMOS), use::",
        "",
        "  gmx editconf -f in -rotate 0 45 35.264 -bt o -box veclen -o out",
        "",
        "where [TT]veclen[tt] is the size of the cubic box times [SQRT]3[sqrt]/2."
    };
    const char     *bugs[] =
    {
        "For complex molecules, the periodicity removal routine may break down, "
        "in that case you can use [gmx-trjconv]."
    };
    static real     dist    = 0.0;
    static gmx_bool bNDEF   = FALSE, bRMPBC = FALSE, bCenter = FALSE, bReadVDW =
        FALSE, bCONECT      = FALSE;
    static gmx_bool peratom = FALSE, bLegend = FALSE, bOrient = FALSE, bMead =
        FALSE, bGrasp       = FALSE, bSig56 = FALSE;
    static rvec     scale   =
    { 1, 1, 1 }, newbox     =
    { 0, 0, 0 }, newang     =
    { 90, 90, 90 };
    static real rho          = 1000.0, rvdw = 0.12;
    static rvec center       =
    { 0, 0, 0 }, translation =
    { 0, 0, 0 }, rotangles   =
    { 0, 0, 0 }, aligncenter =
    { 0, 0, 0 }, targetvec   =
    { 0, 0, 0 };
    static const char *btype[] =
    { nullptr, "triclinic", "cubic", "dodecahedron", "octahedron", nullptr },
    *label             = "A";
    static rvec visbox =
    { 0, 0, 0 };
    static int  resnr_start = -1;
    t_pargs
                pa[] =
    {
        { "-ndef", FALSE, etBOOL,
          { &bNDEF }, "Choose output from default index groups" },
        { "-visbox", FALSE, etRVEC,
          { visbox },
          "HIDDENVisualize a grid of boxes, -1 visualizes the 14 box images" },
        { "-bt", FALSE, etENUM,
          { btype }, "Box type for [TT]-box[tt] and [TT]-d[tt]" },
        { "-box", FALSE, etRVEC,
          { newbox }, "Box vector lengths (a,b,c)" },
        { "-angles", FALSE, etRVEC,
          { newang }, "Angles between the box vectors (bc,ac,ab)" },
        { "-d", FALSE, etREAL,
          { &dist }, "Distance between the solute and the box" },
        { "-c", FALSE, etBOOL,
          { &bCenter },
          "Center molecule in box (implied by [TT]-box[tt] and [TT]-d[tt])" },
        { "-center", FALSE, etRVEC,
          { center }, "Shift the geometrical center to (x,y,z)" },
        { "-aligncenter", FALSE, etRVEC,
          { aligncenter }, "Center of rotation for alignment" },
        { "-align", FALSE, etRVEC,
          { targetvec },
          "Align to target vector" },
        { "-translate", FALSE, etRVEC,
          { translation }, "Translation" },
        { "-rotate", FALSE, etRVEC,
          { rotangles },
          "Rotation around the X, Y and Z axes in degrees" },
        { "-princ", FALSE, etBOOL,
          { &bOrient },
          "Orient molecule(s) along their principal axes" },
        { "-scale", FALSE, etRVEC,
          { scale }, "Scaling factor" },
        { "-density", FALSE, etREAL,
          { &rho },
          "Density (g/L) of the output box achieved by scaling" },
        { "-pbc", FALSE, etBOOL,
          { &bRMPBC },
          "Remove the periodicity (make molecule whole again)" },
        { "-resnr", FALSE, etINT,
          { &resnr_start },
          " Renumber residues starting from resnr" },
        { "-grasp", FALSE, etBOOL,
          { &bGrasp },
          "Store the charge of the atom in the B-factor field and the radius of the atom in the occupancy field" },
        {
            "-rvdw", FALSE, etREAL,
            { &rvdw },
            "Default Van der Waals radius (in nm) if one can not be found in the database or if no parameters are present in the topology file"
        },
        { "-sig56", FALSE, etBOOL,
          { &bSig56 },
          "Use rmin/2 (minimum in the Van der Waals potential) rather than [GRK]sigma[grk]/2 " },
        {
            "-vdwread", FALSE, etBOOL,
            { &bReadVDW },
            "Read the Van der Waals radii from the file [TT]vdwradii.dat[tt] rather than computing the radii based on the force field"
        },
        { "-atom", FALSE, etBOOL,
          { &peratom }, "Force B-factor attachment per atom" },
        { "-legend", FALSE, etBOOL,
          { &bLegend }, "Make B-factor legend" },
        { "-label", FALSE, etSTR,
          { &label }, "Add chain label for all residues" },
        {
            "-conect", FALSE, etBOOL,
            { &bCONECT },
            "Add CONECT records to a [REF].pdb[ref] file when written. Can only be done when a topology is present"
        }
    };
#define NPA asize(pa)

    FILE             *out;
    const char       *infile, *outfile;
    int               outftp, inftp, natom, i, j, n_bfac, itype, ntype;
    double           *bfac    = nullptr, c6, c12;
    int              *bfac_nr = nullptr;
    t_topology       *top     = nullptr;
    char             *grpname, *sgrpname, *agrpname;
    int               isize, ssize, numAlignmentAtoms;
    int              *index, *sindex, *aindex;
    rvec             *x, *v, gc, rmin, rmax, size;
    int               ePBC;
    matrix            box, rotmatrix, trans;
    rvec              princd, tmpvec;
    gmx_bool          bIndex, bSetSize, bSetAng, bDist, bSetCenter, bAlign;
    gmx_bool          bHaveV, bScale, bRho, bTranslate, bRotate, bCalcGeom, bCalcDiam;
    real              diam = 0, mass = 0, d, vdw;
    gmx_atomprop_t    aps;
    gmx_conect        conect;
    gmx_output_env_t *oenv;
    t_filenm          fnm[] =
    {
        { efSTX, "-f", nullptr, ffREAD },
        { efNDX, "-n", nullptr, ffOPTRD },
        { efSTO, nullptr, nullptr, ffOPTWR },
        { efPQR, "-mead", "mead", ffOPTWR },
        { efDAT, "-bf", "bfact", ffOPTRD }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, NFILE, fnm, NPA, pa,
                           asize(desc), desc, asize(bugs), bugs, &oenv))
    {
        return 0;
    }

    bIndex     = opt2bSet("-n", NFILE, fnm) || bNDEF;
    bMead      = opt2bSet("-mead", NFILE, fnm);
    bSetSize   = opt2parg_bSet("-box", NPA, pa);
    bSetAng    = opt2parg_bSet("-angles", NPA, pa);
    bSetCenter = opt2parg_bSet("-center", NPA, pa);
    bDist      = opt2parg_bSet("-d", NPA, pa);
    bAlign     = opt2parg_bSet("-align", NPA, pa);
    /* Only automatically turn on centering without -noc */
    if ((bDist || bSetSize || bSetCenter) && !opt2parg_bSet("-c", NPA, pa))
    {
        bCenter = TRUE;
    }
    bScale     = opt2parg_bSet("-scale", NPA, pa);
    bRho       = opt2parg_bSet("-density", NPA, pa);
    bTranslate = opt2parg_bSet("-translate", NPA, pa);
    bRotate    = opt2parg_bSet("-rotate", NPA, pa);
    if (bScale && bRho)
    {
        fprintf(stderr, "WARNING: setting -density overrides -scale\n");
    }
    bScale    = bScale || bRho;
    bCalcGeom = bCenter || bRotate || bOrient || bScale;

    GMX_RELEASE_ASSERT(btype[0] != nullptr, "Option setting inconsistency; btype[0] is NULL");

    bCalcDiam = (btype[0][0] == 'c' || btype[0][0] == 'd' || btype[0][0] == 'o');

    infile = ftp2fn(efSTX, NFILE, fnm);
    if (bMead)
    {
        outfile = ftp2fn(efPQR, NFILE, fnm);
    }
    else
    {
        outfile = ftp2fn(efSTO, NFILE, fnm);
    }
    outftp = fn2ftp(outfile);
    inftp  = fn2ftp(infile);

    aps = gmx_atomprop_init();

    if (bMead && bGrasp)
    {
        printf("Incompatible options -mead and -grasp. Turning off -grasp\n");
        bGrasp = FALSE;
    }
    if (bGrasp && (outftp != efPDB))
    {
        gmx_fatal(FARGS, "Output file should be a .pdb file"
                  " when using the -grasp option\n");
    }
    if ((bMead || bGrasp) && (fn2ftp(infile) != efTPR))
    {
        gmx_fatal(FARGS, "Input file should be a .tpr file"
                  " when using the -mead option\n");
    }

    t_topology *top_tmp;
    snew(top_tmp, 1);
    read_tps_conf(infile, top_tmp, &ePBC, &x, &v, box, FALSE);
    t_atoms  &atoms = top_tmp->atoms;
    natom = atoms.nr;
    if (atoms.pdbinfo == nullptr)
    {
        snew(atoms.pdbinfo, atoms.nr);
    }
    atoms.havePdbInfo = TRUE;

    if (fn2ftp(infile) == efPDB)
    {
        get_pdb_atomnumber(&atoms, aps);
    }
    printf("Read %d atoms\n", atoms.nr);

    /* Get the element numbers if available in a pdb file */
    if (fn2ftp(infile) == efPDB)
    {
        get_pdb_atomnumber(&atoms, aps);
    }

    if (ePBC != epbcNONE)
    {
        real vol = det(box);
        printf("Volume: %g nm^3, corresponds to roughly %d electrons\n",
               vol, 100*(static_cast<int>(vol*4.5)));
    }

    if (bMead || bGrasp || bCONECT)
    {
        top = read_top(infile, nullptr);
    }

    if (bMead || bGrasp)
    {
        if (atoms.nr != top->atoms.nr)
        {
            gmx_fatal(FARGS, "Atom numbers don't match (%d vs. %d)", atoms.nr, top->atoms.nr);
        }
        snew(atoms.pdbinfo, top->atoms.nr);
        ntype = top->idef.atnr;
        for (i = 0; (i < atoms.nr); i++)
        {
            /* Determine the Van der Waals radius from the force field */
            if (bReadVDW)
            {
                if (!gmx_atomprop_query(aps, epropVDW,
                                        *top->atoms.resinfo[top->atoms.atom[i].resind].name,
                                        *top->atoms.atomname[i], &vdw))
                {
                    vdw = rvdw;
                }
            }
            else
            {
                itype = top->atoms.atom[i].type;
                c12   = top->idef.iparams[itype*ntype+itype].lj.c12;
                c6    = top->idef.iparams[itype*ntype+itype].lj.c6;
                if ((c6 != 0) && (c12 != 0))
                {
                    real sig6;
                    if (bSig56)
                    {
                        sig6 = 2*c12/c6;
                    }
                    else
                    {
                        sig6 = c12/c6;
                    }
                    vdw   = 0.5*gmx::sixthroot(sig6);
                }
                else
                {
                    vdw = rvdw;
                }
            }
            /* Factor of 10 for nm -> Angstroms */
            vdw *= 10;

            if (bMead)
            {
                atoms.pdbinfo[i].occup = top->atoms.atom[i].q;
                atoms.pdbinfo[i].bfac  = vdw;
            }
            else
            {
                atoms.pdbinfo[i].occup = vdw;
                atoms.pdbinfo[i].bfac  = top->atoms.atom[i].q;
            }
        }
    }
    bHaveV = FALSE;
    for (i = 0; (i < natom) && !bHaveV; i++)
    {
        for (j = 0; (j < DIM) && !bHaveV; j++)
        {
            bHaveV = bHaveV || (v[i][j] != 0);
        }
    }
    printf("%selocities found\n", bHaveV ? "V" : "No v");

    if (visbox[0] > 0)
    {
        if (bIndex)
        {
            gmx_fatal(FARGS, "Sorry, can not visualize box with index groups");
        }
        if (outftp != efPDB)
        {
            gmx_fatal(FARGS, "Sorry, can only visualize box with a pdb file");
        }
    }
    else if (visbox[0] == -1)
    {
        visualize_images("images.pdb", ePBC, box);
    }

    /* remove pbc */
    if (bRMPBC)
    {
        rm_gropbc(&atoms, x, box);
    }

    if (bCalcGeom)
    {
        if (bIndex)
        {
            fprintf(stderr, "\nSelect a group for determining the system size:\n");
            get_index(&atoms, ftp2fn_null(efNDX, NFILE, fnm),
                      1, &ssize, &sindex, &sgrpname);
        }
        else
        {
            ssize  = atoms.nr;
            sindex = nullptr;
        }
        diam = calc_geom(ssize, sindex, x, gc, rmin, rmax, bCalcDiam);
        rvec_sub(rmax, rmin, size);
        printf("    system size :%7.3f%7.3f%7.3f (nm)\n",
               size[XX], size[YY], size[ZZ]);
        if (bCalcDiam)
        {
            printf("    diameter    :%7.3f               (nm)\n", diam);
        }
        printf("    center      :%7.3f%7.3f%7.3f (nm)\n", gc[XX], gc[YY], gc[ZZ]);
        printf("    box vectors :%7.3f%7.3f%7.3f (nm)\n",
               norm(box[XX]), norm(box[YY]), norm(box[ZZ]));
        printf("    box angles  :%7.2f%7.2f%7.2f (degrees)\n",
               norm2(box[ZZ]) == 0 ? 0 :
               RAD2DEG*gmx_angle(box[YY], box[ZZ]),
               norm2(box[ZZ]) == 0 ? 0 :
               RAD2DEG*gmx_angle(box[XX], box[ZZ]),
               norm2(box[YY]) == 0 ? 0 :
               RAD2DEG*gmx_angle(box[XX], box[YY]));
        printf("    box volume  :%7.2f               (nm^3)\n", det(box));
    }

    if (bRho || bOrient || bAlign)
    {
        mass = calc_mass(&atoms, !fn2bTPX(infile), aps);
    }

    if (bOrient)
    {
        int     *index;
        char    *grpnames;

        /* Get a group for principal component analysis */
        fprintf(stderr, "\nSelect group for the determining the orientation\n");
        get_index(&atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, &grpnames);

        /* Orient the principal axes along the coordinate axes */
        orient_princ(&atoms, isize, index, natom, x, bHaveV ? v : nullptr, nullptr);
        sfree(index);
        sfree(grpnames);
    }

    if (bScale)
    {
        /* scale coordinates and box */
        if (bRho)
        {
            /* Compute scaling constant */
            real vol, dens;

            vol  = det(box);
            dens = (mass*AMU)/(vol*NANO*NANO*NANO);
            fprintf(stderr, "Volume  of input %g (nm^3)\n", vol);
            fprintf(stderr, "Mass    of input %g (a.m.u.)\n", mass);
            fprintf(stderr, "Density of input %g (g/l)\n", dens);
            if (vol == 0 || mass == 0)
            {
                gmx_fatal(FARGS, "Cannot scale density with "
                          "zero mass (%g) or volume (%g)\n", mass, vol);
            }

            scale[XX] = scale[YY] = scale[ZZ] = std::cbrt(dens/rho);
            fprintf(stderr, "Scaling all box vectors by %g\n", scale[XX]);
        }
        scale_conf(atoms.nr, x, box, scale);
    }

    if (bAlign)
    {
        if (bIndex)
        {
            fprintf(stderr, "\nSelect a group that you want to align:\n");
            get_index(&atoms, ftp2fn_null(efNDX, NFILE, fnm),
                      1, &numAlignmentAtoms, &aindex, &agrpname);
        }
        else
        {
            numAlignmentAtoms = atoms.nr;
            snew(aindex, numAlignmentAtoms);
            for (i = 0; i < numAlignmentAtoms; i++)
            {
                aindex[i] = i;
            }
        }
        printf("Aligning %d atoms (out of %d) to %g %g %g, center of rotation %g %g %g\n", numAlignmentAtoms, natom,
               targetvec[XX], targetvec[YY], targetvec[ZZ],
               aligncenter[XX], aligncenter[YY], aligncenter[ZZ]);
        /*subtract out pivot point*/
        for (i = 0; i < numAlignmentAtoms; i++)
        {
            rvec_dec(x[aindex[i]], aligncenter);
        }
        /*now determine transform and rotate*/
        /*will this work?*/
        principal_comp(numAlignmentAtoms, aindex, atoms.atom, x, trans, princd);

        unitv(targetvec, targetvec);
        printf("Using %g %g %g as principal axis\n", trans[0][2], trans[1][2], trans[2][2]);
        tmpvec[XX] = trans[0][2]; tmpvec[YY] = trans[1][2]; tmpvec[ZZ] = trans[2][2];
        calc_rotmatrix(tmpvec, targetvec, rotmatrix);
        /* rotmatrix finished */

        for (i = 0; i < numAlignmentAtoms; ++i)
        {
            mvmul(rotmatrix, x[aindex[i]], tmpvec);
            copy_rvec(tmpvec, x[aindex[i]]);
        }

        /*add pivot point back*/
        for (i = 0; i < numAlignmentAtoms; i++)
        {
            rvec_inc(x[aindex[i]], aligncenter);
        }
        if (!bIndex)
        {
            sfree(aindex);
        }
    }

    if (bTranslate)
    {
        if (bIndex)
        {
            fprintf(stderr, "\nSelect a group that you want to translate:\n");
            get_index(&atoms, ftp2fn_null(efNDX, NFILE, fnm),
                      1, &ssize, &sindex, &sgrpname);
        }
        else
        {
            ssize  = atoms.nr;
            sindex = nullptr;
        }
        printf("Translating %d atoms (out of %d) by %g %g %g nm\n", ssize, natom,
               translation[XX], translation[YY], translation[ZZ]);
        if (sindex)
        {
            for (i = 0; i < ssize; i++)
            {
                rvec_inc(x[sindex[i]], translation);
            }
        }
        else
        {
            for (i = 0; i < natom; i++)
            {
                rvec_inc(x[i], translation);
            }
        }
    }
    if (bRotate)
    {
        /* Rotate */
        printf("Rotating %g, %g, %g degrees around the X, Y and Z axis respectively\n", rotangles[XX], rotangles[YY], rotangles[ZZ]);
        for (i = 0; i < DIM; i++)
        {
            rotangles[i] *= DEG2RAD;
        }
        rotate_conf(natom, x, v, rotangles[XX], rotangles[YY], rotangles[ZZ]);
    }

    if (bCalcGeom)
    {
        /* recalc geometrical center and max and min coordinates and size */
        calc_geom(ssize, sindex, x, gc, rmin, rmax, FALSE);
        rvec_sub(rmax, rmin, size);
        if (bScale || bOrient || bRotate)
        {
            printf("new system size : %6.3f %6.3f %6.3f\n",
                   size[XX], size[YY], size[ZZ]);
        }
    }

    if ((btype[0] != nullptr) && (bSetSize || bDist || (btype[0][0] == 't' && bSetAng)))
    {
        ePBC = epbcXYZ;
        if (!(bSetSize || bDist))
        {
            for (i = 0; i < DIM; i++)
            {
                newbox[i] = norm(box[i]);
            }
        }
        clear_mat(box);
        /* calculate new boxsize */
        switch (btype[0][0])
        {
            case 't':
                if (bDist)
                {
                    for (i = 0; i < DIM; i++)
                    {
                        newbox[i] = size[i]+2*dist;
                    }
                }
                if (!bSetAng)
                {
                    box[XX][XX] = newbox[XX];
                    box[YY][YY] = newbox[YY];
                    box[ZZ][ZZ] = newbox[ZZ];
                }
                else
                {
                    matrix_convert(box, newbox, newang);
                }
                break;
            case 'c':
            case 'd':
            case 'o':
                if (bSetSize)
                {
                    d = newbox[0];
                }
                else
                {
                    d = diam+2*dist;
                }
                if (btype[0][0] == 'c')
                {
                    for (i = 0; i < DIM; i++)
                    {
                        box[i][i] = d;
                    }
                }
                else if (btype[0][0] == 'd')
                {
                    box[XX][XX] = d;
                    box[YY][YY] = d;
                    box[ZZ][XX] = d/2;
                    box[ZZ][YY] = d/2;
                    box[ZZ][ZZ] = d*std::sqrt(2.0)/2.0;
                }
                else
                {
                    box[XX][XX] = d;
                    box[YY][XX] = d/3;
                    box[YY][YY] = d*std::sqrt(2.0)*2.0/3.0;
                    box[ZZ][XX] = -d/3;
                    box[ZZ][YY] = d*std::sqrt(2.0)/3.0;
                    box[ZZ][ZZ] = d*std::sqrt(6.0)/3.0;
                }
                break;
        }
    }

    /* calculate new coords for geometrical center */
    if (!bSetCenter)
    {
        calc_box_center(ecenterDEF, box, center);
    }

    /* center molecule on 'center' */
    if (bCenter)
    {
        center_conf(natom, x, center, gc);
    }

    /* print some */
    if (bCalcGeom)
    {
        calc_geom(ssize, sindex, x, gc, rmin, rmax, FALSE);
        printf("new center      :%7.3f%7.3f%7.3f (nm)\n", gc[XX], gc[YY], gc[ZZ]);
    }
    if (bOrient || bScale || bDist || bSetSize)
    {
        printf("new box vectors :%7.3f%7.3f%7.3f (nm)\n",
               norm(box[XX]), norm(box[YY]), norm(box[ZZ]));
        printf("new box angles  :%7.2f%7.2f%7.2f (degrees)\n",
               norm2(box[ZZ]) == 0 ? 0 :
               RAD2DEG*gmx_angle(box[YY], box[ZZ]),
               norm2(box[ZZ]) == 0 ? 0 :
               RAD2DEG*gmx_angle(box[XX], box[ZZ]),
               norm2(box[YY]) == 0 ? 0 :
               RAD2DEG*gmx_angle(box[XX], box[YY]));
        printf("new box volume  :%7.2f               (nm^3)\n", det(box));
    }

    if (check_box(epbcXYZ, box))
    {
        printf("\nWARNING: %s\n"
               "See the GROMACS manual for a description of the requirements that\n"
               "must be satisfied by descriptions of simulation cells.\n",
               check_box(epbcXYZ, box));
    }

    if (bDist && btype[0][0] == 't')
    {
        if (TRICLINIC(box))
        {
            printf("\nWARNING: Your box is triclinic with non-orthogonal axes. In this case, the\n"
                   "distance from the solute to a box surface along the corresponding normal\n"
                   "vector might be somewhat smaller than your specified value %f.\n"
                   "You can check the actual value with g_mindist -pi\n", dist);
        }
        else if (!opt2parg_bSet("-bt", NPA, pa))
        {
            printf("\nWARNING: No boxtype specified - distance condition applied in each dimension.\n"
                   "If the molecule rotates the actual distance will be smaller. You might want\n"
                   "to use a cubic box instead, or why not try a dodecahedron today?\n");
        }
    }
    if (bCONECT && (outftp == efPDB) && (inftp == efTPR))
    {
        conect = gmx_conect_generate(top);
    }
    else
    {
        conect = nullptr;
    }

    if (bIndex)
    {
        fprintf(stderr, "\nSelect a group for output:\n");
        get_index(&atoms, opt2fn_null("-n", NFILE, fnm),
                  1, &isize, &index, &grpname);

        if (resnr_start >= 0)
        {
            renum_resnr(&atoms, isize, index, resnr_start);
        }

        if (opt2parg_bSet("-label", NPA, pa))
        {
            for (i = 0; (i < atoms.nr); i++)
            {
                atoms.resinfo[atoms.atom[i].resind].chainid = label[0];
            }
        }

        if (opt2bSet("-bf", NFILE, fnm) || bLegend)
        {
            gmx_fatal(FARGS, "Sorry, cannot do bfactors with an index group.");
        }

        if (outftp == efPDB)
        {
            out = gmx_ffopen(outfile, "w");
            write_pdbfile_indexed(out, *top_tmp->name, &atoms, x, ePBC, box, ' ', 1, isize, index, conect, TRUE, FALSE);
            gmx_ffclose(out);
        }
        else
        {
            write_sto_conf_indexed(outfile, *top_tmp->name, &atoms, x, bHaveV ? v : nullptr, ePBC, box, isize, index);
        }
    }
    else
    {
        if (resnr_start >= 0)
        {
            renum_resnr(&atoms, atoms.nr, nullptr, resnr_start);
        }

        if ((outftp == efPDB) || (outftp == efPQR))
        {
            out = gmx_ffopen(outfile, "w");
            if (bMead)
            {
                fprintf(out, "REMARK    "
                        "The B-factors in this file hold atomic radii\n");
                fprintf(out, "REMARK    "
                        "The occupancy in this file hold atomic charges\n");
            }
            else if (bGrasp)
            {
                fprintf(out, "GRASP PDB FILE\nFORMAT NUMBER=1\n");
                fprintf(out, "REMARK    "
                        "The B-factors in this file hold atomic charges\n");
                fprintf(out, "REMARK    "
                        "The occupancy in this file hold atomic radii\n");
            }
            else if (opt2bSet("-bf", NFILE, fnm))
            {
                read_bfac(opt2fn("-bf", NFILE, fnm), &n_bfac, &bfac, &bfac_nr);
                set_pdb_conf_bfac(atoms.nr, atoms.nres, &atoms,
                                  n_bfac, bfac, bfac_nr, peratom);
            }
            if (opt2parg_bSet("-label", NPA, pa))
            {
                for (i = 0; (i < atoms.nr); i++)
                {
                    atoms.resinfo[atoms.atom[i].resind].chainid = label[0];
                }
            }
            /* Need to bypass the regular write_pdbfile because I don't want to change
             * all instances to include the boolean flag for writing out PQR files.
             */
            int *index;
            snew(index, atoms.nr);
            for (int i = 0; i < atoms.nr; i++)
            {
                index[i] = i;
            }
            write_pdbfile_indexed(out, *top_tmp->name, &atoms, x, ePBC, box, ' ', -1, atoms.nr, index, conect,
                                  TRUE, outftp == efPQR);
            sfree(index);
            if (bLegend)
            {
                pdb_legend(out, atoms.nr, atoms.nres, &atoms, x);
            }
            if (visbox[0] > 0)
            {
                visualize_box(out, bLegend ? atoms.nr+12 : atoms.nr,
                              bLegend ? atoms.nres = 12 : atoms.nres, box, visbox);
            }
            gmx_ffclose(out);
        }
        else
        {
            write_sto_conf(outfile, *top_tmp->name, &atoms, x, bHaveV ? v : nullptr, ePBC, box);
        }
    }
    gmx_atomprop_destroy(aps);

    do_view(oenv, outfile, nullptr);

    return 0;
}
Example #23
0
int gmx_sdf(int argc,char *argv[])
{
  static char *desc[] = {
    "g_sdf calculates the spatial distribution function (SDF) of a set of atoms",
    "within a coordinate system defined by three atoms. There is single body, ",
    "two body and three body SDF implemented (select with option -mode). ",
    "In the single body case the local coordinate system is defined by using",
    "a triple of atoms from one single molecule, for the two and three body case",
    "the configurations are dynamically searched complexes of two or three",
    "molecules (or residues) meeting certain distance consitions (see below).[PAR]",
    "The program needs a trajectory, a GROMACS run input file and an index ",
    "file to work. ",
    "You have to setup 4 groups in the index file before using g_sdf: [PAR]",
    "The first three groups are used to define the SDF coordinate system.",
    "The programm will dynamically generate the atom tripels according to ",
    "the selected -mode: ", 
    "In -mode 1 the triples will be just the 1st, 2nd, 3rd, ... atoms from ",
    "groups 1, 2 and 3. Hence the nth entries in groups 1, 2 and 3 must be from the",
    "same residue. In -mode 2 the triples will be 1st, 2nd, 3rd, ... atoms from",
    "groups 1 and 2 (with the nth entries in groups 1 and 2 having the same res-id).",
    "For each pair from groups 1 and 2  group 3 is searched for an atom meeting the",
    "distance conditions set with -triangle and -dtri relative to atoms 1 and 2. In",
    "-mode 3 for each atom in group 1 group 2 is searched for an atom meeting the",
    "distance condition and if a pair is found group 3 is searched for an atom",
    "meeting the further conditions. The triple will only be used if all three atoms",
    "have different res-id's.[PAR]",
    "The local coordinate system is always defined using the following scheme:",
    "Atom 1 will be used as the point of origin for the SDF. "
    "Atom 1 and 2 will define the principle axis (Z) of the coordinate system.",
    "The other two axis will be defined inplane (Y) and normal (X) to the plane through",
    "Atoms 1, 2 and 3. "
    "The fourth group",
    "contains the atoms for which the SDF will be evaluated.[PAR]",
    "For -mode 2 and 3 you have to define the distance conditions for the ",
    "2 resp. 3 molecule complexes to be searched for using -triangle and -dtri.[PAR]",
    "The SDF will be sampled in cartesian coordinates.",
    "Use '-grid x y z' to define the size of the SDF grid around the ",
    "reference molecule. ",
    "The Volume of the SDF grid will be V=x*y*z (nm^3). "
    "Use -bin to set the binwidth for grid.[PAR]",
    "The output will be a binary 3D-grid file (gom_plt.dat) in the .plt format that can be be",
    "read directly by gOpenMol. ",
    "The option -r will generate a .gro file with the reference molecule(s) transfered to",
    "the SDF coordinate system. Load this file into gOpenMol and display the",
    "SDF as a contour plot (see http://www.csc.fi/gopenmol/index.phtml for ",
    "further documentation). [PAR]",
    "For further information about SDF's have a look at: A. Vishnyakov, JPC A, 105,",
    "2001, 1702 and the references cited within."
  };
  static bool bRef=FALSE;
  static int mode=1;
  static rvec triangle={0.0,0.0,0.0};
  static rvec dtri={0.03,0.03,0.03};
  static rvec cutoff={1,1,1};
  static real binwidth=0.05;
  t_pargs pa[] = {
    { "-mode",     FALSE, etINT, {&mode},
      "SDF in [1,2,3] particle mode"},
    { "-triangle", FALSE, etRVEC, {&triangle},
      "r(1,3), r(2,3), r(1,2)"},
    { "-dtri",     FALSE, etRVEC, {&dtri},
      "dr(1,3), dr(2,3), dr(1,2)"},
    { "-bin",      FALSE, etREAL, {&binwidth},
      "Binwidth for the 3D-grid (nm)" },
    { "-grid",      FALSE, etRVEC, {&cutoff},
      "Size of the 3D-grid (nm,nm,nm)"}
  };
#define NPA asize(pa)
  char       *fnTPS,*fnNDX,*fnREF;
  
  t_filenm   fnm[] = {
    { efTRX, "-f",  NULL,     ffREAD },
    { efNDX, NULL,  NULL,     ffREAD },
    { efTPS, NULL,  NULL,     ffOPTRD },
    { efDAT, "-o",  "gom_plt",     ffWRITE },
    { efSTO, "-r",  "refmol",  ffOPTWR },
  };
#define NFILE asize(fnm)
  
  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_BE_NICE,
                    NFILE,fnm,NPA,pa,asize(desc),desc,0,NULL);


  fnTPS = ftp2fn_null(efTPS,NFILE,fnm);
  fnNDX = ftp2fn_null(efNDX,NFILE,fnm);
  fnREF = opt2fn_null("-r",NFILE,fnm);
  bRef  = opt2bSet("-r",NFILE,fnm);


  
  if (!fnNDX)
    gmx_fatal(FARGS,"No index file specified\n"
                "             Nothing to do!");


  if (!fnTPS)
    gmx_fatal(FARGS,"No topology file specified\n"
                "             Nothing to do!");


  if ( bRef && fn2ftp(fnREF) != efGRO)
    {
      fprintf(stderr,"\nOnly GROMACS format is supported for reference structures.\n");
      fprintf(stderr,"Option -r will be ignored!\n");
      bRef = FALSE;
    }


  if (mode < 1 || mode > 3)
    gmx_fatal(FARGS,"Wrong -mode selection. Chose 1-, 2- oder 3-praticle mode.\n");


  do_sdf(fnNDX,fnTPS,ftp2fn(efTRX,NFILE,fnm),opt2fn("-o",NFILE,fnm),
         fnREF,bRef,cutoff,binwidth,mode,triangle,dtri);


  thanx(stderr);
  
  return 0;
}
Example #24
0
int main(int argc,char *argv[])
{
  static char *desc[] = {
    "mk_angndx makes an index file for calculation of",
    "angle distributions etc. It uses a run input file ([TT].tpx[tt]) for the",
    "definitions of the angles, dihedrals etc."
  };
  static char *opt[] = { NULL, "angle", "dihedral", "improper", "ryckaert-bellemans", NULL };
  static bool bH=TRUE;
  t_pargs pa[] = {
    { "-type", FALSE, etENUM, {opt},
      "Type of angle" },
    { "-hyd", FALSE, etBOOL, {&bH},
      "Include angles with atoms with mass < 1.5" }
  };
  
  FILE       *out;
  t_topology *top;
  int        i,j,ntype;
  int        nft=0,*ft,mult=0;
  int        **index;
  int        *ft_ind;
  int        *nr;
  char       **grpnames;
  t_filenm fnm[] = {
    { efTPX, NULL, NULL, ffREAD  },
    { efNDX, NULL, "angle", ffWRITE }
  };
#define NFILE asize(fnm)

  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,0,NFILE,fnm,asize(pa),pa,
		    asize(desc),desc,0,NULL);


  ft = select_ftype(opt[0],&nft,&mult);

  top = read_top(ftp2fn(efTPX,NFILE,fnm),NULL);

  ntype = calc_ntype(nft,ft,&(top->idef));
  snew(grpnames,ntype);
  snew(ft_ind,top->idef.ntypes);
  fill_ft_ind(nft,ft,&top->idef,ft_ind,grpnames);
  
  snew(nr,ntype);
  snew(index,ntype);
  fill_ang(nft,ft,mult,nr,index,ft_ind,top,!bH);
  
  out=ftp2FILE(efNDX,NFILE,fnm,"w");
  for(i=0; (i<ntype); i++) {
    if (nr[i] > 0) {
      fprintf(out,"[ %s ]\n",grpnames[i]);
      for(j=0; (j<nr[i]*mult); j++) {
	fprintf(out," %5d",index[i][j]+1);
	if ((j % 12) == 11)
	  fprintf(out,"\n");
      }
      fprintf(out,"\n");
    }
  }
  fclose(out);
  
  thanx(stderr);
  
  return 0;
}
Example #25
0
int gmx_enemat(int argc, char *argv[])
{
    const char     *desc[] = {
        "[TT]g_enemat[tt] extracts an energy matrix from the energy file ([TT]-f[tt]).",
        "With [TT]-groups[tt] a file must be supplied with on each",
        "line a group of atoms to be used. For these groups matrix of",
        "interaction energies will be extracted from the energy file",
        "by looking for energy groups with names corresponding to pairs",
        "of groups of atoms, e.g. if your [TT]-groups[tt] file contains:[BR]",
        "[TT]2[tt][BR]",
        "[TT]Protein[tt][BR]",
        "[TT]SOL[tt][BR]",
        "then energy groups with names like 'Coul-SR:Protein-SOL' and ",
        "'LJ:Protein-SOL' are expected in the energy file (although",
        "[TT]g_enemat[tt] is most useful if many groups are analyzed",
        "simultaneously). Matrices for different energy types are written",
        "out separately, as controlled by the",
        "[TT]-[no]coul[tt], [TT]-[no]coulr[tt], [TT]-[no]coul14[tt], ",
        "[TT]-[no]lj[tt], [TT]-[no]lj14[tt], ",
        "[TT]-[no]bham[tt] and [TT]-[no]free[tt] options.",
        "Finally, the total interaction energy energy per group can be ",
        "calculated ([TT]-etot[tt]).[PAR]",

        "An approximation of the free energy can be calculated using:",
        "[MATH]E[SUB]free[sub] = E[SUB]0[sub] + kT [LOG][CHEVRON][EXP](E-E[SUB]0[sub])/kT[exp][chevron][log][math], where '[MATH][CHEVRON][chevron][math]'",
        "stands for time-average. A file with reference free energies",
        "can be supplied to calculate the free energy difference",
        "with some reference state. Group names (e.g. residue names)",
        "in the reference file should correspond to the group names",
        "as used in the [TT]-groups[tt] file, but a appended number",
        "(e.g. residue number) in the [TT]-groups[tt] will be ignored",
        "in the comparison."
    };
    static gmx_bool bSum      = FALSE;
    static gmx_bool bMeanEmtx = TRUE;
    static int      skip      = 0, nlevels = 20;
    static real     cutmax    = 1e20, cutmin = -1e20, reftemp = 300.0;
    static gmx_bool bCoulSR   = TRUE, bCoulLR = FALSE, bCoul14 = FALSE;
    static gmx_bool bLJSR     = TRUE, bLJLR = FALSE, bLJ14 = FALSE, bBhamSR = FALSE, bBhamLR = FALSE,
                    bFree     = TRUE;
    t_pargs         pa[]      = {
        { "-sum",  FALSE, etBOOL, {&bSum},
          "Sum the energy terms selected rather than display them all" },
        { "-skip", FALSE, etINT,  {&skip},
          "Skip number of frames between data points" },
        { "-mean", FALSE, etBOOL, {&bMeanEmtx},
          "with [TT]-groups[tt] extracts matrix of mean energies instead of "
          "matrix for each timestep" },
        { "-nlevels", FALSE, etINT, {&nlevels}, "number of levels for matrix colors"},
        { "-max", FALSE, etREAL, {&cutmax}, "max value for energies"},
        { "-min", FALSE, etREAL, {&cutmin}, "min value for energies"},
        { "-coulsr", FALSE, etBOOL, {&bCoulSR}, "extract Coulomb SR energies"},
        { "-coullr", FALSE, etBOOL, {&bCoulLR}, "extract Coulomb LR energies"},
        { "-coul14", FALSE, etBOOL, {&bCoul14}, "extract Coulomb 1-4 energies"},
        { "-ljsr", FALSE, etBOOL, {&bLJSR}, "extract Lennard-Jones SR energies"},
        { "-ljlr", FALSE, etBOOL, {&bLJLR}, "extract Lennard-Jones LR energies"},
        { "-lj14", FALSE, etBOOL, {&bLJ14}, "extract Lennard-Jones 1-4 energies"},
        { "-bhamsr", FALSE, etBOOL, {&bBhamSR}, "extract Buckingham SR energies"},
        { "-bhamlr", FALSE, etBOOL, {&bBhamLR}, "extract Buckingham LR energies"},
        { "-free", FALSE, etBOOL, {&bFree}, "calculate free energy"},
        { "-temp", FALSE, etREAL, {&reftemp},
          "reference temperature for free energy calculation"}
    };
    /* We will define egSP more energy-groups:
       egTotal (total energy) */
#define egTotal egNR
#define egSP 1
    gmx_bool       egrp_use[egNR+egSP];
    ener_file_t    in;
    FILE          *out;
    int            timecheck = 0;
    gmx_enxnm_t   *enm       = NULL;
    t_enxframe    *fr;
    int            teller = 0;
    real           sum;
    gmx_bool       bCont, bRef;
    gmx_bool       bCutmax, bCutmin;
    real         **eneset, *time = NULL;
    int           *set, i, j, k, prevk, m = 0, n, nre, nset, nenergy;
    char         **groups = NULL;
    char           groupname[255], fn[255];
    int            ngroups;
    t_rgb          rlo, rhi, rmid;
    real           emax, emid, emin;
    real        ***emat, **etot, *groupnr;
    double         beta, expE, **e, *eaver, *efree = NULL, edum;
    char           label[234];
    char         **ereflines, **erefres = NULL;
    real          *eref  = NULL, *edif = NULL;
    int            neref = 0;
    output_env_t   oenv;

    t_filenm       fnm[] = {
        { efEDR, "-f", NULL, ffOPTRD },
        { efDAT, "-groups", "groups.dat", ffREAD },
        { efDAT, "-eref",   "eref.dat", ffOPTRD },
        { efXPM, "-emat",   "emat", ffWRITE },
        { efXVG, "-etot",   "energy", ffWRITE }
    };
#define NFILE asize(fnm)

    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);

    egrp_use[egCOULSR] = bCoulSR;
    egrp_use[egLJSR]   = bLJSR;
    egrp_use[egBHAMSR] = bBhamSR;
    egrp_use[egCOULLR] = bCoulLR;
    egrp_use[egLJLR]   = bLJLR;
    egrp_use[egBHAMLR] = bBhamLR;
    egrp_use[egCOUL14] = bCoul14;
    egrp_use[egLJ14]   = bLJ14;
    egrp_use[egTotal]  = TRUE;

    bRef = opt2bSet("-eref", NFILE, fnm);
    in   = open_enx(ftp2fn(efEDR, NFILE, fnm), "r");
    do_enxnms(in, &nre, &enm);

    if (nre == 0)
    {
        gmx_fatal(FARGS, "No energies!\n");
    }

    bCutmax = opt2parg_bSet("-max", asize(pa), pa);
    bCutmin = opt2parg_bSet("-min", asize(pa), pa);

    nenergy = 0;

    /* Read groupnames from input file and construct selection of
       energy groups from it*/

    fprintf(stderr, "Will read groupnames from inputfile\n");
    ngroups = get_lines(opt2fn("-groups", NFILE, fnm), &groups);
    fprintf(stderr, "Read %d groups\n", ngroups);
    snew(set, sqr(ngroups)*egNR/2);
    n     = 0;
    prevk = 0;
    for (i = 0; (i < ngroups); i++)
    {
        fprintf(stderr, "\rgroup %d", i);
        for (j = i; (j < ngroups); j++)
        {
            for (m = 0; (m < egNR); m++)
            {
                if (egrp_use[m])
                {
                    sprintf(groupname, "%s:%s-%s", egrp_nm[m], groups[i], groups[j]);
#ifdef DEBUG
                    fprintf(stderr, "\r%-15s %5d", groupname, n);
#endif
                    for (k = prevk; (k < prevk+nre); k++)
                    {
                        if (strcmp(enm[k%nre].name, groupname) == 0)
                        {
                            set[n++] = k;
                            break;
                        }
                    }
                    if (k == prevk+nre)
                    {
                        fprintf(stderr, "WARNING! could not find group %s (%d,%d)"
                                "in energy file\n", groupname, i, j);
                    }
                    else
                    {
                        prevk = k;
                    }
                }
            }
        }
    }
    fprintf(stderr, "\n");
    nset = n;
    snew(eneset, nset+1);
    fprintf(stderr, "Will select half-matrix of energies with %d elements\n", n);

    /* Start reading energy frames */
    snew(fr, 1);
    do
    {
        do
        {
            bCont = do_enx(in, fr);
            if (bCont)
            {
                timecheck = check_times(fr->t);
            }
        }
        while (bCont && (timecheck < 0));

        if (timecheck == 0)
        {
#define DONTSKIP(cnt) (skip) ? ((cnt % skip) == 0) : TRUE

            if (bCont)
            {
                fprintf(stderr, "\rRead frame: %d, Time: %.3f", teller, fr->t);

                if ((nenergy % 1000) == 0)
                {
                    srenew(time, nenergy+1000);
                    for (i = 0; (i <= nset); i++)
                    {
                        srenew(eneset[i], nenergy+1000);
                    }
                }
                time[nenergy] = fr->t;
                sum           = 0;
                for (i = 0; (i < nset); i++)
                {
                    eneset[i][nenergy] = fr->ener[set[i]].e;
                    sum               += fr->ener[set[i]].e;
                }
                if (bSum)
                {
                    eneset[nset][nenergy] = sum;
                }
                nenergy++;
            }
            teller++;
        }
    }
    while (bCont && (timecheck == 0));

    fprintf(stderr, "\n");

    fprintf(stderr, "Will build energy half-matrix of %d groups, %d elements, "
            "over %d frames\n", ngroups, nset, nenergy);

    snew(emat, egNR+egSP);
    for (j = 0; (j < egNR+egSP); j++)
    {
        if (egrp_use[m])
        {
            snew(emat[j], ngroups);
            for (i = 0; (i < ngroups); i++)
            {
                snew(emat[j][i], ngroups);
            }
        }
    }
    snew(groupnr, ngroups);
    for (i = 0; (i < ngroups); i++)
    {
        groupnr[i] = i+1;
    }
    rlo.r  = 1.0, rlo.g  = 0.0, rlo.b  = 0.0;
    rmid.r = 1.0, rmid.g = 1.0, rmid.b = 1.0;
    rhi.r  = 0.0, rhi.g  = 0.0, rhi.b  = 1.0;
    if (bMeanEmtx)
    {
        snew(e, ngroups);
        for (i = 0; (i < ngroups); i++)
        {
            snew(e[i], nenergy);
        }
        n = 0;
        for (i = 0; (i < ngroups); i++)
        {
            for (j = i; (j < ngroups); j++)
            {
                for (m = 0; (m < egNR); m++)
                {
                    if (egrp_use[m])
                    {
                        for (k = 0; (k < nenergy); k++)
                        {
                            emat[m][i][j] += eneset[n][k];
                            e[i][k]       += eneset[n][k]; /* *0.5; */
                            e[j][k]       += eneset[n][k]; /* *0.5; */
                        }
                        n++;
                        emat[egTotal][i][j] += emat[m][i][j];
                        emat[m][i][j]       /= nenergy;
                        emat[m][j][i]        = emat[m][i][j];
                    }
                }
                emat[egTotal][i][j] /= nenergy;
                emat[egTotal][j][i]  = emat[egTotal][i][j];
            }
        }
        if (bFree)
        {
            if (bRef)
            {
                fprintf(stderr, "Will read reference energies from inputfile\n");
                neref = get_lines(opt2fn("-eref", NFILE, fnm), &ereflines);
                fprintf(stderr, "Read %d reference energies\n", neref);
                snew(eref, neref);
                snew(erefres, neref);
                for (i = 0; (i < neref); i++)
                {
                    snew(erefres[i], 5);
                    sscanf(ereflines[i], "%s %lf", erefres[i], &edum);
                    eref[i] = edum;
                }
            }
            snew(eaver, ngroups);
            for (i = 0; (i < ngroups); i++)
            {
                for (k = 0; (k < nenergy); k++)
                {
                    eaver[i] += e[i][k];
                }
                eaver[i] /= nenergy;
            }
            beta = 1.0/(BOLTZ*reftemp);
            snew(efree, ngroups);
            snew(edif, ngroups);
            for (i = 0; (i < ngroups); i++)
            {
                expE = 0;
                for (k = 0; (k < nenergy); k++)
                {
                    expE += exp(beta*(e[i][k]-eaver[i]));
                }
                efree[i] = log(expE/nenergy)/beta + eaver[i];
                if (bRef)
                {
                    n = search_str2(neref, erefres, groups[i]);
                    if (n != -1)
                    {
                        edif[i] = efree[i]-eref[n];
                    }
                    else
                    {
                        edif[i] = efree[i];
                        fprintf(stderr, "WARNING: group %s not found "
                                "in reference energies.\n", groups[i]);
                    }
                }
                else
                {
                    edif[i] = 0;
                }
            }
        }

        emid             = 0.0; /*(emin+emax)*0.5;*/
        egrp_nm[egTotal] = "total";
        for (m = 0; (m < egNR+egSP); m++)
        {
            if (egrp_use[m])
            {
                emin = 1e10;
                emax = -1e10;
                for (i = 0; (i < ngroups); i++)
                {
                    for (j = i; (j < ngroups); j++)
                    {
                        if (emat[m][i][j] > emax)
                        {
                            emax = emat[m][i][j];
                        }
                        else if (emat[m][i][j] < emin)
                        {
                            emin = emat[m][i][j];
                        }
                    }
                }
                if (emax == emin)
                {
                    fprintf(stderr, "Matrix of %s energy is uniform at %f "
                            "(will not produce output).\n", egrp_nm[m], emax);
                }
                else
                {
                    fprintf(stderr, "Matrix of %s energy ranges from %f to %f\n",
                            egrp_nm[m], emin, emax);
                    if ((bCutmax) || (emax > cutmax))
                    {
                        emax = cutmax;
                    }
                    if ((bCutmin) || (emin < cutmin))
                    {
                        emin = cutmin;
                    }
                    if ((emax == cutmax) || (emin == cutmin))
                    {
                        fprintf(stderr, "Energy range adjusted: %f to %f\n", emin, emax);
                    }

                    sprintf(fn, "%s%s", egrp_nm[m], ftp2fn(efXPM, NFILE, fnm));
                    sprintf(label, "%s Interaction Energies", egrp_nm[m]);
                    out = ffopen(fn, "w");
                    if (emin >= emid)
                    {
                        write_xpm(out, 0, label, "Energy (kJ/mol)",
                                  "Residue Index", "Residue Index",
                                  ngroups, ngroups, groupnr, groupnr, emat[m],
                                  emid, emax, rmid, rhi, &nlevels);
                    }
                    else if (emax <= emid)
                    {
                        write_xpm(out, 0, label, "Energy (kJ/mol)",
                                  "Residue Index", "Residue Index",
                                  ngroups, ngroups, groupnr, groupnr, emat[m],
                                  emin, emid, rlo, rmid, &nlevels);
                    }
                    else
                    {
                        write_xpm3(out, 0, label, "Energy (kJ/mol)",
                                   "Residue Index", "Residue Index",
                                   ngroups, ngroups, groupnr, groupnr, emat[m],
                                   emin, emid, emax, rlo, rmid, rhi, &nlevels);
                    }
                    ffclose(out);
                }
            }
        }
        snew(etot, egNR+egSP);
        for (m = 0; (m < egNR+egSP); m++)
        {
            snew(etot[m], ngroups);
            for (i = 0; (i < ngroups); i++)
            {
                for (j = 0; (j < ngroups); j++)
                {
                    etot[m][i] += emat[m][i][j];
                }
            }
        }

        out = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Mean Energy", "Residue", "kJ/mol",
                       oenv);
        xvgr_legend(out, 0, NULL, oenv);
        j = 0;
        for (m = 0; (m < egNR+egSP); m++)
        {
            if (egrp_use[m])
            {
                fprintf(out, "@ legend string %d \"%s\"\n", j++, egrp_nm[m]);
            }
        }
        if (bFree)
        {
            fprintf(out, "@ legend string %d \"%s\"\n", j++, "Free");
        }
        if (bFree)
        {
            fprintf(out, "@ legend string %d \"%s\"\n", j++, "Diff");
        }
        fprintf(out, "@TYPE xy\n");
        fprintf(out, "#%3s", "grp");
        for (m = 0; (m < egNR+egSP); m++)
        {
            if (egrp_use[m])
            {
                fprintf(out, " %9s", egrp_nm[m]);
            }
        }
        if (bFree)
        {
            fprintf(out, " %9s", "Free");
        }
        if (bFree)
        {
            fprintf(out, " %9s", "Diff");
        }
        fprintf(out, "\n");
        for (i = 0; (i < ngroups); i++)
        {
            fprintf(out, "%3.0f", groupnr[i]);
            for (m = 0; (m < egNR+egSP); m++)
            {
                if (egrp_use[m])
                {
                    fprintf(out, " %9.5g", etot[m][i]);
                }
            }
            if (bFree)
            {
                fprintf(out, " %9.5g", efree[i]);
            }
            if (bRef)
            {
                fprintf(out, " %9.5g", edif[i]);
            }
            fprintf(out, "\n");
        }
        ffclose(out);
    }
    else
    {
        fprintf(stderr, "While typing at your keyboard, suddenly...\n"
                "...nothing happens.\nWARNING: Not Implemented Yet\n");
/*
    out=ftp2FILE(efMAT,NFILE,fnm,"w");
    n=0;
    emin=emax=0.0;
    for (k=0; (k<nenergy); k++) {
      for (i=0; (i<ngroups); i++)
    for (j=i+1; (j<ngroups); j++)
      emat[i][j]=eneset[n][k];
      sprintf(label,"t=%.0f ps",time[k]);
      write_matrix(out,ngroups,1,ngroups,groupnr,emat,label,emin,emax,nlevels);
      n++;
    }
    ffclose(out);
 */
    }
    close_enx(in);

    thanx(stderr);

    return 0;
}
Example #26
0
int main (int argc, char *argv[])
{
  static const char *desc[] = {
    "The gromacs preprocessor",
    "reads a molecular topology file, checks the validity of the",
    "file, expands the topology from a molecular description to an atomic",
    "description. The topology file contains information about",
    "molecule types and the number of molecules, the preprocessor",
    "copies each molecule as needed. ",
    "There is no limitation on the number of molecule types. ",
    "Bonds and bond-angles can be converted into constraints, separately",
    "for hydrogens and heavy atoms.",
    "Then a coordinate file is read and velocities can be generated",
    "from a Maxwellian distribution if requested.",
    "grompp also reads parameters for the mdrun ",
    "(eg. number of MD steps, time step, cut-off), and others such as",
    "NEMD parameters, which are corrected so that the net acceleration",
    "is zero.",
    "Eventually a binary file is produced that can serve as the sole input",
    "file for the MD program.[PAR]",
    
    "grompp uses the atom names from the topology file. The atom names",
    "in the coordinate file (option [TT]-c[tt]) are only read to generate",
    "warnings when they do not match the atom names in the topology.",
    "Note that the atom names are irrelevant for the simulation as",
    "only the atom types are used for generating interaction parameters.[PAR]",

    "grompp calls a preprocessor to resolve includes, macros ",
    "etcetera. By default we use the cpp in your path. To specify a "
    "different macro-preprocessor (e.g. m4) or alternative location",

    "you can put a line in your parameter file specifying the path",
    "to that program. Specifying [TT]-pp[tt] will get the pre-processed",
    "topology file written out.[PAR]",
    
    "If your system does not have a c-preprocessor, you can still",
    "use grompp, but you do not have access to the features ",
    "from the cpp. Command line options to the c-preprocessor can be given",
    "in the [TT].mdp[tt] file. See your local manual (man cpp).[PAR]",
    
    "When using position restraints a file with restraint coordinates",
    "can be supplied with [TT]-r[tt], otherwise restraining will be done",
    "with respect to the conformation from the [TT]-c[tt] option.",
    "For free energy calculation the the coordinates for the B topology",
    "can be supplied with [TT]-rb[tt], otherwise they will be equal to",
    "those of the A topology.[PAR]",
    
    "Starting coordinates can be read from trajectory with [TT]-t[tt].",
    "The last frame with coordinates and velocities will be read,",
    "unless the [TT]-time[tt] option is used.",
    "Note that these velocities will not be used when [TT]gen_vel = yes[tt]",
    "in your [TT].mdp[tt] file. An energy file can be supplied with",
    "[TT]-e[tt] to have exact restarts when using pressure and/or",
    "Nose-Hoover temperature coupling. For an exact restart do not forget",
    "to turn off velocity generation and turn on unconstrained starting",
    "when constraints are present in the system.",
    "If you want to continue a crashed run, it is",
    "easier to use [TT]tpbconv[tt].[PAR]",

    "Using the [TT]-morse[tt] option grompp can convert the harmonic bonds",
    "in your topology to morse potentials. This makes it possible to break",
    "bonds. For this option to work you need an extra file in your $GMXLIB",
    "with dissociation energy. Use the -debug option to get more information",
    "on the workings of this option (look for MORSE in the grompp.log file",
    "using less or something like that).[PAR]",
    
    "By default all bonded interactions which have constant energy due to",
    "virtual site constructions will be removed. If this constant energy is",
    "not zero, this will result in a shift in the total energy. All bonded",
    "interactions can be kept by turning off [TT]-rmvsbds[tt]. Additionally,",
    "all constraints for distances which will be constant anyway because",
    "of virtual site constructions will be removed. If any constraints remain",
    "which involve virtual sites, a fatal error will result.[PAR]"
    
    "To verify your run input file, please make notice of all warnings",
    "on the screen, and correct where necessary. Do also look at the contents",
    "of the [TT]mdout.mdp[tt] file, this contains comment lines, as well as",
    "the input that [TT]grompp[tt] has read. If in doubt you can start grompp",
    "with the [TT]-debug[tt] option which will give you more information",
    "in a file called grompp.log (along with real debug info). Finally, you",
    "can see the contents of the run input file with the [TT]gmxdump[tt]",
    "program."
  };
  t_gromppopts *opts;
  gmx_mtop_t   *sys;
  int          nmi;
  t_molinfo    *mi;
  gpp_atomtype_t atype;
  t_inputrec   *ir;
  int          natoms,nvsite,comb,mt;
  t_params     *plist;
  t_state      state;
  matrix       box;
  real         max_spacing,fudgeQQ;
  double       reppow;
  char         fn[STRLEN],fnB[STRLEN],*mdparin;
  int          nerror,ntype;
  bool         bNeedVel,bGenVel;
  bool         have_radius,have_vol,have_surftens,have_gb_radius,have_S_hct;
  bool         have_atomnumber;
  int		   n12,n13,n14;
  t_params     *gb_plist = NULL;
  gmx_genborn_t *born = NULL;

  t_filenm fnm[] = {
    { efMDP, NULL,  NULL,        ffOPTRD },
    { efMDP, "-po", "mdout",     ffWRITE },
    { efSTX, "-c",  NULL,        ffREAD  },
    { efSTX, "-r",  NULL,        ffOPTRD },
    { efSTX, "-rb", NULL,        ffOPTRD },
    { efNDX, NULL,  NULL,        ffOPTRD },
    { efTOP, NULL,  NULL,        ffREAD  },
    { efTOP, "-pp", "processed", ffOPTWR },
    { efTPX, "-o",  NULL,        ffWRITE },
    { efTRN, "-t",  NULL,        ffOPTRD },
    { efEDR, "-e",  NULL,        ffOPTRD }
  };
#define NFILE asize(fnm)

  /* Command line options */
  static bool bVerbose=TRUE,bRenum=TRUE;
  static bool bRmVSBds=TRUE,bZero=FALSE;
  static int  i,maxwarn=0;
  static real fr_time=-1;
  t_pargs pa[] = {
    { "-v",       FALSE, etBOOL, {&bVerbose},
      "Be loud and noisy" },
    { "-time",    FALSE, etREAL, {&fr_time},
      "Take frame at or first after this time." },
    { "-rmvsbds",FALSE, etBOOL, {&bRmVSBds},
      "Remove constant bonded interactions with virtual sites" },
    { "-maxwarn", FALSE, etINT,  {&maxwarn},
      "Number of allowed warnings during input processing" },
    { "-zero",    FALSE, etBOOL, {&bZero},
      "Set parameters for bonded interactions without defaults to zero instead of generating an error" },
    { "-renum",   FALSE, etBOOL, {&bRenum},
      "Renumber atomtypes and minimize number of atomtypes" }
  };
  
  CopyRight(stdout,argv[0]);
  
  /* Initiate some variables */
  nerror=0;
  snew(ir,1);
  snew(opts,1);
  init_ir(ir,opts);
  
  /* Parse the command line */
  parse_common_args(&argc,argv,0,NFILE,fnm,asize(pa),pa,
		    asize(desc),desc,0,NULL);
  
  init_warning(maxwarn);
  
  /* PARAMETER file processing */
  mdparin = opt2fn("-f",NFILE,fnm);
  set_warning_line(mdparin,-1);    
  get_ir(mdparin,opt2fn("-po",NFILE,fnm),ir,opts,&nerror);
  
  if (bVerbose) 
    fprintf(stderr,"checking input for internal consistency...\n");
  check_ir(mdparin,ir,opts,&nerror);

  if (ir->ld_seed == -1) {
    ir->ld_seed = make_seed();
    fprintf(stderr,"Setting the LD random seed to %d\n",ir->ld_seed);
  }

  bNeedVel = EI_STATE_VELOCITY(ir->eI);
  bGenVel  = (bNeedVel && opts->bGenVel);

  snew(plist,F_NRE);
  init_plist(plist);
  snew(sys,1);
  atype = init_atomtype();
  if (debug)
    pr_symtab(debug,0,"Just opened",&sys->symtab);
    
  strcpy(fn,ftp2fn(efTOP,NFILE,fnm));
  if (!gmx_fexist(fn)) 
    gmx_fatal(FARGS,"%s does not exist",fn);
  new_status(fn,opt2fn_null("-pp",NFILE,fnm),opt2fn("-c",NFILE,fnm),
	     opts,ir,bZero,bGenVel,bVerbose,&state,
	     atype,sys,&nmi,&mi,plist,&comb,&reppow,&fudgeQQ,
	     opts->bMorse,
	     &nerror);
  
  if (debug)
    pr_symtab(debug,0,"After new_status",&sys->symtab);
  
  if (count_constraints(sys,mi) && (ir->eConstrAlg == econtSHAKE)) {
    if (ir->eI == eiCG || ir->eI == eiLBFGS) {
      fprintf(stderr,
	      "ERROR: Can not do %s with %s, use %s\n",
	      EI(ir->eI),econstr_names[econtSHAKE],econstr_names[econtLINCS]);
      nerror++;
    }
    if (ir->bPeriodicMols) {
      fprintf(stderr,
	      "ERROR: can not do periodic molecules with %s, use %s\n",
	      econstr_names[econtSHAKE],econstr_names[econtLINCS]);
      nerror++;
    }
  }

  /* If we are doing GBSA, check that we got the parameters we need                                                            
   * This checking is to see if there are GBSA paratmeters for all                                                             
   * atoms in the force field. To go around this for testing purposes                                                          
   * comment out the nerror++ counter temporarliy                                                                              
   */
  have_radius=have_vol=have_surftens=have_gb_radius=have_S_hct=TRUE;
  for(i=0;i<get_atomtype_ntypes(atype);i++) {
    have_radius=have_radius       && (get_atomtype_radius(i,atype) > 0);
    have_vol=have_vol             && (get_atomtype_vol(i,atype) > 0);
    have_surftens=have_surftens   && (get_atomtype_surftens(i,atype) > 0);
    have_gb_radius=have_gb_radius && (get_atomtype_gb_radius(i,atype) > 0);
    have_S_hct=have_S_hct         && (get_atomtype_S_hct(i,atype) > 0);
  }
  if(!have_radius && ir->implicit_solvent==eisGBSA) {
    fprintf(stderr,"Can't do GB electrostatics; the forcefield is missing values for\n"
	    "atomtype radii, or they might be zero\n.");
    /* nerror++; */
  }
  /*
  if(!have_surftens && ir->implicit_solvent!=eisNO) {
    fprintf(stderr,"Can't do implicit solvent; the forcefield is missing values\n"
	    " for atomtype surface tension\n.");
    nerror++;                                                                                                                
  }
  */
  
  /* If we are doing QM/MM, check that we got the atom numbers */
  have_atomnumber = TRUE;
  for (i=0; i<get_atomtype_ntypes(atype); i++) {
    have_atomnumber = have_atomnumber && (get_atomtype_atomnumber(i,atype) >= 0);
  }
  if (!have_atomnumber && ir->bQMMM)
  {
    fprintf(stderr,"\n"
            "It appears as if you are trying to run a QM/MM calculation, but the force\n"
            "field you are using does not contain atom numbers fields. This is an\n"
            "optional field (introduced in Gromacs 3.3) for general runs, but mandatory\n"
            "for QM/MM. The good news is that it is easy to add - put the atom number as\n"
            "an integer just before the mass column in ffXXXnb.itp.\n"
            "NB: United atoms have the same atom numbers as normal ones.\n\n"); 
    nerror++;
  }

  if (nerror) {
    print_warn_num(FALSE);
    
    gmx_fatal(FARGS,"There were %d error(s) processing your input",nerror);
  }
  if (opt2bSet("-r",NFILE,fnm))
    sprintf(fn,"%s",opt2fn("-r",NFILE,fnm));
  else
    sprintf(fn,"%s",opt2fn("-c",NFILE,fnm));
  if (opt2bSet("-rb",NFILE,fnm))
    sprintf(fnB,"%s",opt2fn("-rb",NFILE,fnm));
  else
    strcpy(fnB,fn);

  if (nint_ftype(sys,mi,F_POSRES) > 0) {
    if (bVerbose) {
      fprintf(stderr,"Reading position restraint coords from %s",fn);
      if (strcmp(fn,fnB) == 0) {
	fprintf(stderr,"\n");
      } else {
	fprintf(stderr," and %s\n",fnB);
	if (ir->efep != efepNO && ir->n_flambda > 0) {
	  fprintf(stderr,"ERROR: can not change the position restraint reference coordinates with lambda togther with foreign lambda calculation.\n");
	  nerror++;
	}
      }
    }
    gen_posres(sys,mi,fn,fnB,
	       ir->refcoord_scaling,ir->ePBC,
	       ir->posres_com,ir->posres_comB);
  }
		
  nvsite = 0;
  /* set parameters for virtual site construction (not for vsiten) */
  for(mt=0; mt<sys->nmoltype; mt++) {
    nvsite +=
      set_vsites(bVerbose, &sys->moltype[mt].atoms, atype, mi[mt].plist);
  }
  /* now throw away all obsolete bonds, angles and dihedrals: */
  /* note: constraints are ALWAYS removed */
  if (nvsite) {
    for(mt=0; mt<sys->nmoltype; mt++) {
      clean_vsite_bondeds(mi[mt].plist,sys->moltype[mt].atoms.nr,bRmVSBds);
    }
  }
  
	/* If we are using CMAP, setup the pre-interpolation grid */
	if(plist->ncmap>0)
	{
		init_cmap_grid(&sys->cmap_grid, plist->nc, plist->grid_spacing);
		setup_cmap(plist->grid_spacing, plist->nc, plist->cmap,&sys->cmap_grid);
	}
	
  set_wall_atomtype(atype,opts,ir);
  if (bRenum) {
    renum_atype(plist, sys, ir->wall_atomtype, atype, bVerbose);
    ntype = get_atomtype_ntypes(atype);
  }
  
	/* PELA: Copy the atomtype data to the topology atomtype list */
	copy_atomtype_atomtypes(atype,&(sys->atomtypes));

	if (debug)
    pr_symtab(debug,0,"After renum_atype",&sys->symtab);

  if (bVerbose) 
    fprintf(stderr,"converting bonded parameters...\n");
	
  ntype = get_atomtype_ntypes(atype);
  convert_params(ntype, plist, mi, comb, reppow, fudgeQQ, sys);
  	
	if(ir->implicit_solvent)
	{
		printf("Constructing Generalized Born topology...\n");

		/* Check for -normvsbds switch to grompp, necessary for gb together with vsites */
		if(bRmVSBds && nvsite)
		{
			fprintf(stderr, "ERROR: Must use -normvsbds switch to grompp when doing Generalized Born\n"
					"together with virtual sites\n");
			nerror++;
		}
		
		if (nerror)
		{
			print_warn_num(FALSE);
			gmx_fatal(FARGS,"There were %d error(s) processing your input",nerror);
		}
		
		generate_gb_topology(sys,mi);
	}
	
  if (debug)
    pr_symtab(debug,0,"After convert_params",&sys->symtab);

  /* set ptype to VSite for virtual sites */
  for(mt=0; mt<sys->nmoltype; mt++) {
    set_vsites_ptype(FALSE,&sys->moltype[mt]);
  }
  if (debug) {
    pr_symtab(debug,0,"After virtual sites",&sys->symtab);
  }
  /* Check velocity for virtual sites and shells */
  if (bGenVel) {
    check_vel(sys,state.v);
  }
    
  /* check masses */
  check_mol(sys);
  
  for(i=0; i<sys->nmoltype; i++) {
    check_cg_sizes(ftp2fn(efTOP,NFILE,fnm),&sys->moltype[i].cgs);
  }

  check_warning_error(FARGS);
	
  if (bVerbose) 
    fprintf(stderr,"initialising group options...\n");
  do_index(mdparin,ftp2fn_null(efNDX,NFILE,fnm),
	   sys,bVerbose,ir,
	   bGenVel ? state.v : NULL);
	
  /* Init the temperature coupling state */
  init_gtc_state(&state,ir->opts.ngtc);

  if (bVerbose)
    fprintf(stderr,"Checking consistency between energy and charge groups...\n");
  check_eg_vs_cg(sys);
  
  if (debug)
    pr_symtab(debug,0,"After index",&sys->symtab);
  triple_check(mdparin,ir,sys,&nerror);
  close_symtab(&sys->symtab);
  if (debug)
    pr_symtab(debug,0,"After close",&sys->symtab);

  /* make exclusions between QM atoms */
  if (ir->bQMMM) {
    generate_qmexcl(sys,ir);
  }

  if (ftp2bSet(efTRN,NFILE,fnm)) {
    if (bVerbose)
      fprintf(stderr,"getting data from old trajectory ...\n");
    cont_status(ftp2fn(efTRN,NFILE,fnm),ftp2fn_null(efEDR,NFILE,fnm),
		bNeedVel,bGenVel,fr_time,ir,&state,sys);
  }

  if (ir->ePBC==epbcXY && ir->nwall!=2)
    clear_rvec(state.box[ZZ]);
  
  if (EEL_FULL(ir->coulombtype)) {
    /* Calculate the optimal grid dimensions */
    copy_mat(state.box,box);
    if (ir->ePBC==epbcXY && ir->nwall==2)
      svmul(ir->wall_ewald_zfac,box[ZZ],box[ZZ]);
    max_spacing = calc_grid(stdout,box,opts->fourierspacing,
			    &(ir->nkx),&(ir->nky),&(ir->nkz),1);
    if ((ir->coulombtype == eelPPPM) && (max_spacing > 0.1)) {
      set_warning_line(mdparin,-1);
      sprintf(warn_buf,"Grid spacing larger then 0.1 while using PPPM.");
      warning_note(NULL);
    }
  }

  if (ir->ePull != epullNO)
    set_pull_init(ir,sys,state.x,state.box,opts->pull_start);

  /*  reset_multinr(sys); */
  
  if (EEL_PME(ir->coulombtype)) {
    float ratio = pme_load_estimate(sys,ir,state.box);
    fprintf(stderr,"Estimate for the relative computational load of the PME mesh part: %.2f\n",ratio);
    if (ratio > 0.5)
      warning_note("The optimal PME mesh load for parallel simulations is below 0.5\n"
		   "and for highly parallel simulations between 0.25 and 0.33,\n"
		   "for higher performance, increase the cut-off and the PME grid spacing");
  }

  {
    double cio = compute_io(ir,sys->natoms,&sys->groups,F_NRE,1);
    sprintf(warn_buf,"This run will generate roughly %.0f Mb of data",cio);
    if (cio > 2000) {
      set_warning_line(mdparin,-1);
      warning_note(NULL);
    } else {
      printf("%s\n",warn_buf);
    }
  }
	
  if (bVerbose) 
    fprintf(stderr,"writing run input file...\n");

  print_warn_num(TRUE);
  state.lambda = ir->init_lambda;
  write_tpx_state(ftp2fn(efTPX,NFILE,fnm),ir,&state,sys);
  
  thanx(stderr);
  
  return 0;
}
Example #27
0
int gmx_densorder(int argc, char *argv[])
{
    static const char *desc[] = {
        "[THISMODULE] reduces a two-phase density distribution",
        "along an axis, computed over a MD trajectory,",
        "to 2D surfaces fluctuating in time, by a fit to",
        "a functional profile for interfacial densities.",
        "A time-averaged spatial representation of the",
        "interfaces can be output with the option [TT]-tavg[tt]."
    };

    /* Extra arguments - but note how you always get the begin/end
     * options when running the program, without mentioning them here!
     */

    gmx_output_env_t  *oenv;
    t_topology        *top;
    char             **grpname;
    int                ePBC, *ngx;
    static real        binw      = 0.2;
    static real        binwz     = 0.05;
    static real        dens1     = 0.00;
    static real        dens2     = 1000.00;
    static int         ftorder   = 0;
    static int         nsttblock = 100;
    static int         axis      = 2;
    static const char *axtitle   = "Z";
    int              **index; /* Index list for single group*/
    int                xslices, yslices, zslices, tblock;
    static gmx_bool    bGraph   = FALSE;
    static gmx_bool    bCenter  = FALSE;
    static gmx_bool    bFourier = FALSE;
    static gmx_bool    bRawOut  = FALSE;
    static gmx_bool    bOut     = FALSE;
    static gmx_bool    b1d      = FALSE;
    static int         nlevels  = 100;
    /*Densitymap - Densmap[t][x][y][z]*/
    real           ****Densmap = NULL;
    /* Surfaces surf[t][surf_x,surf_y]*/
    t_interf        ***surf1, ***surf2;

    static const char *meth[] = {NULL, "bisect", "functional", NULL};
    int                eMeth;

    char             **graphfiles, **rawfiles, **spectra; /* Filenames for xpm-surface maps, rawdata and powerspectra */
    int                nfxpm = -1, nfraw, nfspect;        /* # files for interface maps and spectra = # interfaces */

    t_pargs            pa[] = {
        { "-1d", FALSE, etBOOL, {&b1d},
          "Pseudo-1d interface geometry"},
        { "-bw", FALSE, etREAL, {&binw},
          "Binwidth of density distribution tangential to interface"},
        { "-bwn", FALSE, etREAL, {&binwz},
          "Binwidth of density distribution normal to interface"},
        { "-order", FALSE, etINT, {&ftorder},
          "Order of Gaussian filter, order 0 equates to NO filtering"},
        {"-axis", FALSE, etSTR, {&axtitle},
         "Axis Direction - X, Y or Z"},
        {"-method", FALSE, etENUM, {meth},
         "Interface location method"},
        {"-d1", FALSE, etREAL, {&dens1},
         "Bulk density phase 1 (at small z)"},
        {"-d2", FALSE, etREAL, {&dens2},
         "Bulk density phase 2 (at large z)"},
        { "-tblock", FALSE, etINT, {&nsttblock},
          "Number of frames in one time-block average"},
        { "-nlevel", FALSE, etINT, {&nlevels},
          "Number of Height levels in 2D - XPixMaps"}
    };


    t_filenm fnm[] = {
        { efTPR, "-s",  NULL, ffREAD },               /* this is for the topology */
        { efTRX, "-f", NULL, ffREAD },                /* and this for the trajectory */
        { efNDX, "-n", NULL, ffREAD},                 /* this is to select groups */
        { efDAT, "-o", "Density4D", ffOPTWR},         /* This is for outputting the entire 4D densityfield in binary format */
        { efOUT, "-or", NULL, ffOPTWRMULT},           /* This is for writing out the entire information in the t_interf arrays */
        { efXPM, "-og", "interface", ffOPTWRMULT},    /* This is for writing out the interface meshes - one xpm-file per tblock*/
        { efOUT, "-Spect", "intfspect", ffOPTWRMULT}, /* This is for the trajectory averaged Fourier-spectra*/
    };

#define NFILE asize(fnm)

    /* This is the routine responsible for adding default options,
     * calling the X/motif interface, etc. */
    if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }


    eMeth    = nenum(meth);
    bFourier = opt2bSet("-Spect", NFILE, fnm);
    bRawOut  = opt2bSet("-or", NFILE, fnm);
    bGraph   = opt2bSet("-og", NFILE, fnm);
    bOut     = opt2bSet("-o", NFILE, fnm);
    top      = read_top(ftp2fn(efTPR, NFILE, fnm), &ePBC);
    snew(grpname, 1);
    snew(index, 1);
    snew(ngx, 1);

/* Calculate axis */
    axis = toupper(axtitle[0]) - 'X';

    get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, ngx, index, grpname);

    density_in_time(ftp2fn(efTRX, NFILE, fnm), index, ngx, binw, binwz, nsttblock, &Densmap, &xslices, &yslices, &zslices, &tblock, top, ePBC, axis, bCenter, b1d, oenv);

    if (ftorder > 0)
    {
        filterdensmap(Densmap, xslices, yslices, zslices, tblock, 2*ftorder+1);
    }

    if (bOut)
    {
        outputfield(opt2fn("-o", NFILE, fnm), Densmap, xslices, yslices, zslices, tblock);
    }

    interfaces_txy(Densmap, xslices, yslices, zslices, tblock, binwz, eMeth, dens1, dens2, &surf1, &surf2, oenv);

    if (bGraph)
    {

        /*Output surface-xpms*/
        nfxpm = opt2fns(&graphfiles, "-og", NFILE, fnm);
        if (nfxpm != 2)
        {
            gmx_fatal(FARGS, "No or not correct number (2) of output-files: %d", nfxpm);
        }
        writesurftoxpms(surf1, surf2, tblock, xslices, yslices, zslices, binw, binwz, graphfiles, zslices);
    }





/*Output raw-data*/
    if (bRawOut)
    {
        nfraw = opt2fns(&rawfiles, "-or", NFILE, fnm);
        if (nfraw != 2)
        {
            gmx_fatal(FARGS, "No or not correct number (2) of output-files: %d", nfxpm);
        }
        writeraw(surf1, surf2, tblock, xslices, yslices, rawfiles, oenv);
    }



    if (bFourier)
    {
        nfspect = opt2fns(&spectra, "-Spect", NFILE, fnm);
        if (nfspect != 2)
        {
            gmx_fatal(FARGS, "No or not correct number (2) of output-file-series: %d",
                      nfspect);
        }
        powerspectavg_intf(surf1, surf2, tblock, xslices, yslices, spectra);
    }

    sfree(Densmap);
    if (bGraph || bFourier || bRawOut)
    {
        sfree(surf1);
        sfree(surf2);
    }

    return 0;
}
Example #28
0
int gmx_insert_molecules(int argc, char *argv[])
{
    const char *desc[] = {
        "[THISMODULE] inserts [TT]-nmol[tt] copies of the system specified in",
        "the [TT]-ci[tt] input file. The insertions take place either into",
        "vacant space in the solute conformation given with [TT]-f[tt], or",
        "into an empty box given by [TT]-box[tt]. Specifying both [TT]-f[tt]",
        "and [TT]-box[tt] behaves like [TT]-f[tt], but places a new box",
        "around the solute before insertions. Any velocities present are",
        "discarded.[PAR]",

        "By default, the insertion positions are random (with initial seed",
        "specified by [TT]-seed[tt]). The program iterates until [TT]-nmol[tt]",
        "molecules have been inserted in the box. Molecules are not inserted",
        "where the distance between any existing atom and any atom of the",
        "inserted molecule is less than the sum based on the van der Waals",
        "radii of both atoms. A database ([TT]vdwradii.dat[tt]) of van der",
        "Waals radii is read by the program, and the resulting radii scaled",
        "by [TT]-scale[tt]. If radii are not found in the database, those"
        "atoms are assigned the (pre-scaled) distance [TT]-radius[tt].[PAR]",

        "A total of [TT]-nmol[tt] * [TT]-try[tt] insertion attempts are made",
        "before giving up. Increase [TT]-try[tt] if you have several small",
        "holes to fill. Option [TT]-rot[tt] specifies whether the insertion",
        "molecules are randomly oriented before insertion attempts.[PAR]",

        "Alternatively, the molecules can be inserted only at positions defined in",
        "positions.dat ([TT]-ip[tt]). That file should have 3 columns (x,y,z),",
        "that give the displacements compared to the input molecule position",
        "([TT]-ci[tt]). Hence, if that file should contain the absolute",
        "positions, the molecule must be centered on (0,0,0) before using",
        "[THISMODULE] (e.g. from [gmx-editconf] [TT]-center[tt]).",
        "Comments in that file starting with # are ignored. Option [TT]-dr[tt]",
        "defines the maximally allowed displacements during insertial trials.",
        "[TT]-try[tt] and [TT]-rot[tt] work as in the default mode (see above).",
        "[PAR]",
    };

    /* parameter data */
    real          *exclusionDistances       = NULL;
    real          *exclusionDistances_insrt = NULL;

    /* protein configuration data */
    char          *title = NULL;
    t_atoms       *atoms, *atoms_insrt;
    rvec          *x    = NULL, *x_insrt = NULL;
    int            ePBC = -1;
    matrix         box;

    t_filenm       fnm[] = {
        { efSTX, "-f", "protein", ffOPTRD },
        { efSTX, "-ci", "insert",  ffREAD},
        { efDAT, "-ip", "positions",  ffOPTRD},
        { efSTO, NULL,  NULL,      ffWRITE},
    };
#define NFILE asize(fnm)

    static int      nmol_ins               = 0, nmol_try = 10, seed = 1997;
    static real     defaultDistance        = 0.105, scaleFactor = 0.57;
    static rvec     new_box                = {0.0, 0.0, 0.0}, deltaR = {0.0, 0.0, 0.0};
    output_env_t    oenv;
    const char     *enum_rot_string[] = {NULL, "xyz", "z", "none", NULL};
    t_pargs         pa[]              = {
        { "-box",    FALSE, etRVEC, {new_box},
          "Box size (in nm)" },
        { "-nmol",   FALSE, etINT, {&nmol_ins},
          "Number of extra molecules to insert" },
        { "-try",    FALSE, etINT, {&nmol_try},
          "Try inserting [TT]-nmol[tt] times [TT]-try[tt] times" },
        { "-seed",   FALSE, etINT, {&seed},
          "Random generator seed"},
        { "-radius",   FALSE, etREAL, {&defaultDistance},
          "Default van der Waals distance"},
        { "-scale", FALSE, etREAL, {&scaleFactor},
          "Scale factor to multiply Van der Waals radii from the database in share/gromacs/top/vdwradii.dat. The default value of 0.57 yields density close to 1000 g/l for proteins in water." },
        { "-dr",    FALSE, etRVEC, {deltaR},
          "Allowed displacement in x/y/z from positions in [TT]-ip[tt] file" },
        { "-rot", FALSE,  etENUM, {enum_rot_string},
          "rotate inserted molecules randomly" }
    };

    if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa,
                           asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    const bool        bProt    = opt2bSet("-f", NFILE, fnm);
    const bool        bBox     = opt2parg_bSet("-box", asize(pa), pa);
    const char *const posfn    = opt2fn_null("-ip", NFILE, fnm);
    const int         enum_rot = nenum(enum_rot_string);

    /* check input */
    if (nmol_ins <= 0 && !opt2bSet("-ip", NFILE, fnm))
    {
        gmx_fatal(FARGS, "Either -nmol must be larger than 0, "
                  "or positions must be given with -ip");
    }
    if (!bProt && !bBox)
    {
        gmx_fatal(FARGS, "When no solute (-f) is specified, "
                  "a box size (-box) must be specified");
    }

    gmx_atomprop_t aps = gmx_atomprop_init();

    snew(atoms, 1);
    init_t_atoms(atoms, 0, FALSE);
    if (bProt)
    {
        /* Generate a solute configuration */
        const char *conf_prot = opt2fn("-f", NFILE, fnm);
        title                 = readConformation(conf_prot, atoms, &x, NULL,
                                                 &ePBC, box);
        exclusionDistances = makeExclusionDistances(atoms, aps, defaultDistance, scaleFactor);
        if (atoms->nr == 0)
        {
            fprintf(stderr, "Note: no atoms in %s\n", conf_prot);
            sfree(title);
            title = NULL;
        }
    }
    if (bBox)
    {
        ePBC = epbcXYZ;
        clear_mat(box);
        box[XX][XX] = new_box[XX];
        box[YY][YY] = new_box[YY];
        box[ZZ][ZZ] = new_box[ZZ];
    }
    if (det(box) == 0)
    {
        gmx_fatal(FARGS, "Undefined solute box.\nCreate one with gmx editconf "
                  "or give explicit -box command line option");
    }
    snew(atoms_insrt, 1);
    init_t_atoms(atoms_insrt, 0, FALSE);
    {
        int         ePBC_dummy;
        matrix      box_dummy;
        const char *conf_insrt = opt2fn("-ci", NFILE, fnm);
        char       *title_ins
            = readConformation(conf_insrt, atoms_insrt, &x_insrt, NULL,
                               &ePBC_dummy, box_dummy);
        if (atoms_insrt->nr == 0)
        {
            gmx_fatal(FARGS, "No molecule in %s, please check your input", conf_insrt);
        }
        if (title == NULL)
        {
            title = title_ins;
        }
        else
        {
            sfree(title_ins);
        }
        if (posfn == NULL)
        {
            center_molecule(atoms_insrt->nr, x_insrt);
        }
        exclusionDistances_insrt = makeExclusionDistances(atoms_insrt, aps, defaultDistance, scaleFactor);
    }

    gmx_atomprop_destroy(aps);

    /* add nmol_ins molecules of atoms_ins
       in random orientation at random place */
    insert_mols(nmol_ins, nmol_try, seed,
                atoms, &x, &exclusionDistances,
                atoms_insrt, x_insrt, exclusionDistances_insrt,
                ePBC, box, posfn, deltaR, enum_rot);

    /* write new configuration to file confout */
    const char *confout = ftp2fn(efSTO, NFILE, fnm);
    fprintf(stderr, "Writing generated configuration to %s\n", confout);
    write_sto_conf(confout, title, atoms, x, NULL, ePBC, box);

    /* print size of generated configuration */
    fprintf(stderr, "\nOutput configuration contains %d atoms in %d residues\n",
            atoms->nr, atoms->nres);

    sfree(exclusionDistances);
    sfree(exclusionDistances_insrt);
    sfree(x);
    done_atom(atoms);
    done_atom(atoms_insrt);
    sfree(atoms);
    sfree(atoms_insrt);
    sfree(title);

    return 0;
}
int gmx_dipoles(int argc,char *argv[])
{
    const char *desc[] = {
        "[TT]g_dipoles[tt] computes the total dipole plus fluctuations of a simulation",
        "system. From this you can compute e.g. the dielectric constant for",
        "low-dielectric media.",
        "For molecules with a net charge, the net charge is subtracted at",
        "center of mass of the molecule.[PAR]",
        "The file [TT]Mtot.xvg[tt] contains the total dipole moment of a frame, the",
        "components as well as the norm of the vector.",
        "The file [TT]aver.xvg[tt] contains < |Mu|^2 > and |< Mu >|^2 during the",
        "simulation.",
        "The file [TT]dipdist.xvg[tt] contains the distribution of dipole moments during",
        "the simulation",
        "The value of [TT]-mumax[tt] is used as the highest value in the distribution graph.[PAR]",
        "Furthermore, the dipole autocorrelation function will be computed when",
        "option [TT]-corr[tt] is used. The output file name is given with the [TT]-c[tt]",
        "option.",
        "The correlation functions can be averaged over all molecules",
        "([TT]mol[tt]), plotted per molecule separately ([TT]molsep[tt])",
        "or it can be computed over the total dipole moment of the simulation box",
        "([TT]total[tt]).[PAR]",
        "Option [TT]-g[tt] produces a plot of the distance dependent Kirkwood",
        "G-factor, as well as the average cosine of the angle between the dipoles",
        "as a function of the distance. The plot also includes gOO and hOO",
        "according to Nymand & Linse, J. Chem. Phys. 112 (2000) pp 6386-6395. In the same plot, ",
        "we also include the energy per scale computed by taking the inner product of",
        "the dipoles divided by the distance to the third power.[PAR]",
        "[PAR]",
        "EXAMPLES[PAR]",
        "[TT]g_dipoles -corr mol -P 1 -o dip_sqr -mu 2.273 -mumax 5.0[tt][PAR]",
        "This will calculate the autocorrelation function of the molecular",
        "dipoles using a first order Legendre polynomial of the angle of the",
        "dipole vector and itself a time t later. For this calculation 1001",
        "frames will be used. Further, the dielectric constant will be calculated",
        "using an [GRK]epsilon[grk]RF of infinity (default), temperature of 300 K (default) and",
        "an average dipole moment of the molecule of 2.273 (SPC). For the",
        "distribution function a maximum of 5.0 will be used."
    };
    real mu_max=5, mu_aver=-1,rcmax=0;
    real epsilonRF=0.0, temp=300;
    gmx_bool bAverCorr=FALSE,bMolCorr=FALSE,bPairs=TRUE,bPhi=FALSE;
    const char *corrtype[]={NULL, "none", "mol", "molsep", "total", NULL};
    const char *axtitle="Z";
    int  nslices = 10;      /* nr of slices defined       */
    int  skip=0,nFA=0,nFB=0,ncos=1;
    int  nlevels=20,ndegrees=90;
    output_env_t oenv;
    t_pargs pa[] = {
        { "-mu",       FALSE, etREAL, {&mu_aver},
          "dipole of a single molecule (in Debye)" },
        { "-mumax",    FALSE, etREAL, {&mu_max},
          "max dipole in Debye (for histogram)" },
        { "-epsilonRF",FALSE, etREAL, {&epsilonRF},
          "epsilon of the reaction field used during the simulation, needed for dielectric constant calculation. WARNING: 0.0 means infinity (default)" },
        { "-skip",     FALSE, etINT, {&skip},
          "Skip steps in the output (but not in the computations)" },
        { "-temp",     FALSE, etREAL, {&temp},
          "Average temperature of the simulation (needed for dielectric constant calculation)" },
        { "-corr",     FALSE, etENUM, {corrtype},
          "Correlation function to calculate" },
        { "-pairs",    FALSE, etBOOL, {&bPairs},
          "Calculate |cos [GRK]theta[grk]| between all pairs of molecules. May be slow" },
        { "-ncos",     FALSE, etINT, {&ncos},
          "Must be 1 or 2. Determines whether the <cos> is computed between all molecules in one group, or between molecules in two different groups. This turns on the [TT]-gkr[tt] flag." }, 
        { "-axis",     FALSE, etSTR, {&axtitle}, 
          "Take the normal on the computational box in direction X, Y or Z." },
        { "-sl",       FALSE, etINT, {&nslices},
          "Divide the box in #nr slices." },
        { "-gkratom",  FALSE, etINT, {&nFA},
          "Use the n-th atom of a molecule (starting from 1) to calculate the distance between molecules rather than the center of charge (when 0) in the calculation of distance dependent Kirkwood factors" },
        { "-gkratom2", FALSE, etINT, {&nFB},
          "Same as previous option in case ncos = 2, i.e. dipole interaction between two groups of molecules" },
        { "-rcmax",    FALSE, etREAL, {&rcmax},
          "Maximum distance to use in the dipole orientation distribution (with ncos == 2). If zero, a criterion based on the box length will be used." },
        { "-phi",      FALSE, etBOOL, {&bPhi},
          "Plot the 'torsion angle' defined as the rotation of the two dipole vectors around the distance vector between the two molecules in the [TT].xpm[tt] file from the [TT]-cmap[tt] option. By default the cosine of the angle between the dipoles is plotted." },
        { "-nlevels",  FALSE, etINT, {&nlevels},
          "Number of colors in the cmap output" },
        { "-ndegrees", FALSE, etINT, {&ndegrees},
          "Number of divisions on the [IT]y[it]-axis in the cmap output (for 180 degrees)" }
    };
    int          *gnx;
    int          nFF[2];
    atom_id      **grpindex;
    char         **grpname=NULL;
    gmx_bool     bCorr,bQuad,bGkr,bMU,bSlab;  
    t_filenm fnm[] = {
        { efEDR, "-en", NULL,         ffOPTRD },
        { efTRX, "-f", NULL,           ffREAD },
        { efTPX, NULL, NULL,           ffREAD },
        { efNDX, NULL, NULL,           ffOPTRD },
        { efXVG, "-o",   "Mtot",       ffWRITE },
        { efXVG, "-eps", "epsilon",    ffWRITE },
        { efXVG, "-a",   "aver",       ffWRITE },
        { efXVG, "-d",   "dipdist",    ffWRITE },
        { efXVG, "-c",   "dipcorr",    ffOPTWR },
        { efXVG, "-g",   "gkr",        ffOPTWR },
        { efXVG, "-adip","adip",       ffOPTWR },
        { efXVG, "-dip3d", "dip3d",    ffOPTWR },
        { efXVG, "-cos", "cosaver",    ffOPTWR },
        { efXPM, "-cmap","cmap",       ffOPTWR },
        { efXVG, "-q",   "quadrupole", ffOPTWR },
        { efXVG, "-slab","slab",       ffOPTWR }
    };
#define NFILE asize(fnm)
    int     npargs;
    t_pargs *ppa;
    t_topology *top;
    int     ePBC;
    int     k,natoms;
    matrix  box;
  
    CopyRight(stderr,argv[0]);
    npargs = asize(pa);
    ppa    = add_acf_pargs(&npargs,pa);
    parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_BE_NICE,
                      NFILE,fnm,npargs,ppa,asize(desc),desc,0,NULL,&oenv);

    printf("Using %g as mu_max and %g as the dipole moment.\n", 
           mu_max,mu_aver);
    if (epsilonRF == 0.0)
        printf("WARNING: EpsilonRF = 0.0, this really means EpsilonRF = infinity\n");

    bMU   = opt2bSet("-en",NFILE,fnm);
    if (bMU)
        gmx_fatal(FARGS,"Due to new ways of treating molecules in GROMACS the total dipole in the energy file may be incorrect, because molecules can be split over periodic boundary conditions before computing the dipole. Please use your trajectory file.");
    bQuad = opt2bSet("-q",NFILE,fnm);
    bGkr  = opt2bSet("-g",NFILE,fnm);
    if (opt2parg_bSet("-ncos",asize(pa),pa)) {
        if ((ncos != 1) && (ncos != 2)) 
            gmx_fatal(FARGS,"ncos has to be either 1 or 2");
        bGkr = TRUE;
    }
    bSlab = (opt2bSet("-slab",NFILE,fnm) || opt2parg_bSet("-sl",asize(pa),pa) ||
             opt2parg_bSet("-axis",asize(pa),pa));
    if (bMU) {
        bAverCorr = TRUE;
        if (bQuad) {
            printf("WARNING: Can not determine quadrupoles from energy file\n");
            bQuad = FALSE;
        }
        if (bGkr) {
            printf("WARNING: Can not determine Gk(r) from energy file\n");
            bGkr  = FALSE;
            ncos = 1;
        }
        if (mu_aver == -1) 
            printf("WARNING: Can not calculate Gk and gk, since you did\n"
                   "         not enter a valid dipole for the molecules\n");
    }

    snew(top,1);
    ePBC = read_tpx_top(ftp2fn(efTPX,NFILE,fnm),NULL,box,
                        &natoms,NULL,NULL,NULL,top);
  
    snew(gnx,ncos);
    snew(grpname,ncos);
    snew(grpindex,ncos);
    get_index(&top->atoms,ftp2fn_null(efNDX,NFILE,fnm),
              ncos,gnx,grpindex,grpname);
    for(k=0; (k<ncos); k++) 
    {
        dipole_atom2molindex(&gnx[k],grpindex[k],&(top->mols));
        neutralize_mols(gnx[k],grpindex[k],&(top->mols),top->atoms.atom);
    }
    nFF[0] = nFA;
    nFF[1] = nFB;
    do_dip(top,ePBC,det(box),ftp2fn(efTRX,NFILE,fnm),
           opt2fn("-o",NFILE,fnm),opt2fn("-eps",NFILE,fnm),
           opt2fn("-a",NFILE,fnm),opt2fn("-d",NFILE,fnm),
           opt2fn_null("-cos",NFILE,fnm),
           opt2fn_null("-dip3d",NFILE,fnm),opt2fn_null("-adip",NFILE,fnm),
           bPairs,corrtype[0],
           opt2fn("-c",NFILE,fnm),
           bGkr,    opt2fn("-g",NFILE,fnm),
           bPhi,    &nlevels,  ndegrees,
           ncos,
           opt2fn("-cmap",NFILE,fnm),rcmax,
           bQuad,   opt2fn("-q",NFILE,fnm),
           bMU,     opt2fn("-en",NFILE,fnm),
           gnx,grpindex,mu_max,mu_aver,epsilonRF,temp,nFF,skip,
           bSlab,nslices,axtitle,opt2fn("-slab",NFILE,fnm),oenv);
  
    do_view(oenv,opt2fn("-o",NFILE,fnm),"-autoscale xy -nxy");
    do_view(oenv,opt2fn("-eps",NFILE,fnm),"-autoscale xy -nxy");
    do_view(oenv,opt2fn("-a",NFILE,fnm),"-autoscale xy -nxy");
    do_view(oenv,opt2fn("-d",NFILE,fnm),"-autoscale xy");
    do_view(oenv,opt2fn("-c",NFILE,fnm),"-autoscale xy");

    thanx(stderr);
  
    return 0;
}
Example #30
0
int gmx_rotmat(int argc, char *argv[])
{
    const char       *desc[] = {
        "[THISMODULE] plots the rotation matrix required for least squares fitting",
        "a conformation onto the reference conformation provided with",
        "[TT]-s[tt]. Translation is removed before fitting.",
        "The output are the three vectors that give the new directions",
        "of the x, y and z directions of the reference conformation,",
        "for example: (zx,zy,zz) is the orientation of the reference",
        "z-axis in the trajectory frame.",
        "[PAR]",
        "This tool is useful for, for instance,",
        "determining the orientation of a molecule",
        "at an interface, possibly on a trajectory produced with",
        "[TT]gmx trjconv -fit rotxy+transxy[tt] to remove the rotation",
        "in the [IT]x-y[it] plane.",
        "[PAR]",
        "Option [TT]-ref[tt] determines a reference structure for fitting,",
        "instead of using the structure from [TT]-s[tt]. The structure with",
        "the lowest sum of RMSD's to all other structures is used.",
        "Since the computational cost of this procedure grows with",
        "the square of the number of frames, the [TT]-skip[tt] option",
        "can be useful. A full fit or only a fit in the [IT]x-y[it] plane can",
        "be performed.",
        "[PAR]",
        "Option [TT]-fitxy[tt] fits in the [IT]x-y[it] plane before determining",
        "the rotation matrix."
    };
    const char       *reffit[] =
    { NULL, "none", "xyz", "xy", NULL };
    static int        skip   = 1;
    static gmx_bool   bFitXY = FALSE, bMW = TRUE;
    t_pargs           pa[]   = {
        { "-ref", FALSE, etENUM, {reffit},
          "Determine the optimal reference structure" },
        { "-skip", FALSE, etINT, {&skip},
          "Use every nr-th frame for [TT]-ref[tt]" },
        { "-fitxy", FALSE, etBOOL, {&bFitXY},
          "Fit the x/y rotation before determining the rotation" },
        { "-mw", FALSE, etBOOL, {&bMW},
          "Use mass weighted fitting" }
    };
    FILE             *out;
    t_trxstatus      *status;
    t_topology        top;
    int               ePBC;
    rvec             *x_ref, *x;
    matrix            box, R;
    real              t;
    int               natoms, i;
    char             *grpname;
    int               gnx;
    gmx_rmpbc_t       gpbc = NULL;
    int              *index;
    gmx_output_env_t *oenv;
    real             *w_rls;
    const char       *leg[]  = { "xx", "xy", "xz", "yx", "yy", "yz", "zx", "zy", "zz" };
#define NLEG asize(leg)
    t_filenm          fnm[] = {
        { efTRX, "-f",   NULL,       ffREAD },
        { efTPS, NULL,   NULL,       ffREAD },
        { efNDX, NULL,   NULL,       ffOPTRD },
        { efXVG, NULL,   "rotmat",   ffWRITE }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &x_ref, NULL, box, bMW);

    gpbc = gmx_rmpbc_init(&top.idef, ePBC, top.atoms.nr);

    gmx_rmpbc(gpbc, top.atoms.nr, box, x_ref);

    get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &gnx, &index, &grpname);

    GMX_RELEASE_ASSERT(reffit[0] != NULL, "Options inconsistency; reffit[0] is NULL");
    if (reffit[0][0] != 'n')
    {
        get_refx(oenv, ftp2fn(efTRX, NFILE, fnm), reffit[0][2] == 'z' ? 3 : 2, skip,
                 gnx, index, bMW, &top, ePBC, x_ref);
    }

    natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);

    snew(w_rls, natoms);
    for (i = 0; i < gnx; i++)
    {
        if (index[i] >= natoms)
        {
            gmx_fatal(FARGS, "Atom index (%d) is larger than the number of atoms in the trajecory (%d)", index[i]+1, natoms);
        }
        w_rls[index[i]] = (bMW ? top.atoms.atom[index[i]].m : 1.0);
    }

    if (reffit[0][0] == 'n')
    {
        reset_x(gnx, index, natoms, NULL, x_ref, w_rls);
    }

    out = xvgropen(ftp2fn(efXVG, NFILE, fnm),
                   "Fit matrix", "Time (ps)", "", oenv);
    xvgr_legend(out, NLEG, leg, oenv);

    do
    {
        gmx_rmpbc(gpbc, natoms, box, x);

        reset_x(gnx, index, natoms, NULL, x, w_rls);

        if (bFitXY)
        {
            do_fit_ndim(2, natoms, w_rls, x_ref, x);
        }

        calc_fit_R(DIM, natoms, w_rls, x_ref, x, R);

        fprintf(out,
                "%7g %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f\n",
                t,
                R[XX][XX], R[XX][YY], R[XX][ZZ],
                R[YY][XX], R[YY][YY], R[YY][ZZ],
                R[ZZ][XX], R[ZZ][YY], R[ZZ][ZZ]);
    }
    while (read_next_x(oenv, status, &t, x, box));

    gmx_rmpbc_done(gpbc);

    close_trj(status);

    xvgrclose(out);

    do_view(oenv, ftp2fn(efXVG, NFILE, fnm), "-nxy");

    return 0;
}