Esempio n. 1
0
int
gmx_select(int argc, char *argv[])
{
    const char *desc[] = {
        "g_select writes out basic data about dynamic selections.",
        "It can be used for some simple analyses, or the output can",
        "be combined with output from other programs and/or external",
        "analysis programs to calculate more complex things.",
        "Any combination of the output options is possible, but note",
        "that [TT]-om[tt] only operates on the first selection.[PAR]",
        "With [TT]-os[tt], calculates the number of positions in each",
        "selection for each frame. With [TT]-norm[tt], the output is",
        "between 0 and 1 and describes the fraction from the maximum",
        "number of positions (e.g., for selection 'resname RA and x < 5'",
        "the maximum number of positions is the number of atoms in",
        "RA residues). With [TT]-cfnorm[tt], the output is divided",
        "by the fraction covered by the selection.",
        "[TT]-norm[tt] and [TT]-cfnorm[tt] can be specified independently",
        "of one another.[PAR]",
        "With [TT]-oc[tt], the fraction covered by each selection is",
        "written out as a function of time.[PAR]",
        "With [TT]-oi[tt], the selected atoms/residues/molecules are",
        "written out as a function of time. In the output, the first",
        "column contains the frame time, the second contains the number",
        "of positions, followed by the atom/residue/molecule numbers.",
        "If more than one selection is specified, the size of the second",
        "group immediately follows the last number of the first group",
        "and so on. With [TT]-dump[tt], the frame time and the number",
        "of positions is omitted from the output. In this case, only one",
        "selection can be given.[PAR]",
        "With [TT]-om[tt], a mask is printed for the first selection",
        "as a function of time. Each line in the output corresponds to",
        "one frame, and contains either 0/1 for each atom/residue/molecule",
        "possibly selected. 1 stands for the atom/residue/molecule being",
        "selected for the current frame, 0 for not selected.",
        "With [TT]-dump[tt], the frame time is omitted from the output.",
    };

    bool                bDump     = FALSE;
    bool                bFracNorm = FALSE;
    bool                bTotNorm  = FALSE;
    t_pargs             pa[] = {
        {"-dump",   FALSE, etBOOL, {&bDump},
         "Do not print the frame time (-om, -oi) or the index size (-oi)"},
        {"-norm",   FALSE, etBOOL, {&bTotNorm},
         "Normalize by total number of positions with -os"},
        {"-cfnorm", FALSE, etBOOL, {&bFracNorm},
         "Normalize by covered fraction with -os"},
    };

    t_filenm            fnm[] = {
        {efXVG, "-os", "size.xvg",  ffOPTWR},
        {efXVG, "-oc", "cfrac.xvg", ffOPTWR},
        {efDAT, "-oi", "index.dat", ffOPTWR},
        {efDAT, "-om", "mask.dat",  ffOPTWR},
    };
#define NFILE asize(fnm)

    gmx_ana_traj_t       *trj;
    t_topology           *top;
    int                   ngrps;
    gmx_ana_selection_t **sel;
    char                **grpnames;
    t_dsdata              d;
    char                 *fnSize, *fnFrac, *fnIndex, *fnMask;
    int                   g;
    int                   rc;

    CopyRight(stderr, argv[0]);
    gmx_ana_traj_create(&trj, 0);
    gmx_ana_set_nanagrps(trj, -1);
    parse_trjana_args(trj, &argc, argv, 0,
                      NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL);
    gmx_ana_get_nanagrps(trj, &ngrps);
    gmx_ana_get_anagrps(trj, &sel);
    gmx_ana_init_coverfrac(trj, CFRAC_SOLIDANGLE);

    /* Get output file names */
    fnSize  = opt2fn_null("-os", NFILE, fnm);
    fnFrac  = opt2fn_null("-oc", NFILE, fnm);
    fnIndex = opt2fn_null("-oi", NFILE, fnm);
    fnMask  = opt2fn_null("-om", NFILE, fnm);
    /* Write out sizes if nothing specified */
    if (!fnFrac && !fnIndex && !fnMask)
    {
        fnSize = opt2fn("-os", NFILE, fnm);
    }

    if (bDump && ngrps > 1)
    {
        gmx_fatal(FARGS, "Only one index group allowed with -dump");
    }
    if (fnMask && ngrps > 1)
    {
        fprintf(stderr, "warning: the mask (-om) will only be written for the first group\n");
    }
    if (fnMask && !sel[0]->bDynamic)
    {
        fprintf(stderr, "warning: will not write the mask (-om) for a static selection\n");
        fnMask = NULL;
    }

    /* Initialize reference calculation for masks */
    if (fnMask)
    {
        gmx_ana_get_topology(trj, FALSE, &top, NULL);
        snew(d.mmap, 1);
        gmx_ana_indexmap_init(d.mmap, sel[0]->g, top, sel[0]->p.m.type);
    }

    /* Initialize calculation data */
    d.bDump     = bDump;
    d.bFracNorm = bFracNorm;
    snew(d.size,  ngrps);
    for (g = 0; g < ngrps; ++g)
    {
        d.size[g] = bTotNorm ? sel[g]->p.nr : 1;
    }

    /* Open output files */
    d.sfp = d.cfp = d.ifp = d.mfp = NULL;
    gmx_ana_get_grpnames(trj, &grpnames);
    if (fnSize)
    {
        d.sfp = xvgropen(fnSize, "Selection size", "Time (ps)", "Number");
        xvgr_selections(d.sfp, trj);
        xvgr_legend(d.sfp, ngrps, grpnames);
    }
    if (fnFrac)
    {
        d.cfp = xvgropen(fnFrac, "Covered fraction", "Time (ps)", "Fraction");
        xvgr_selections(d.cfp, trj);
        xvgr_legend(d.cfp, ngrps, grpnames);
    }
    if (fnIndex)
    {
        d.ifp = ffopen(fnIndex, "w");
        xvgr_selections(d.ifp, trj);
    }
    if (fnMask)
    {
        d.mfp = ffopen(fnMask, "w");
        xvgr_selections(d.mfp, trj);
    }

    /* Do the analysis and write out results */
    gmx_ana_do(trj, 0, &print_data, &d);

    /* Close the files */
    if (d.sfp)
    {
        fclose(d.sfp);
    }
    if (d.cfp)
    {
        fclose(d.cfp);
    }
    if (d.ifp)
    {
        fclose(d.ifp);
    }
    if (d.mfp)
    {
        fclose(d.mfp);
    }

    thanx(stderr);

    return 0;
}
Esempio n. 2
0
int gmx_gmx2pqr(int argc, char *argv[])
{
    const char *desc[] = {
        "\tThis convert from gromacs to APBS pqr files.",
        "Use the -a1 flag for the start of the bond vector",
        "and the -a2 flag for the end of the bond vector.",
        "\n\tUse the -exclude flag to specify atoms which you",
        "would like to know the speficic contribution to the",
        "electrostatic field at the bond midpoint, or would",
        "like to exclude from the field calculation.",
        "Use the -site flag to add dummy atoms like those used",
        "by the Cho group {Choi, J. H.; Oh, K. I.; Lee, H.; Lee,",
        "C.; Cho, M.; Nitrile and thiocyanate IR",
        "probes: Quantum chemistry calculation studies and",
        "multivariate least-square fitting analysis; J. Phys.",
        "Chem. 2008}.  By default, both -site and -exclude flag",
        "will include the atoms indicated by -a1 and -a2.",
        "\n\tUse the -select flag to specify which atoms you",
        "want to include in the .pqr file and all calculations.",
        "For example, '(not resname SOL and not name Na) or",
        "resname SOL and same residue as within 0.5 of resname",
        "CNC and (name NE or name CD or name CB or name SG)",
        "would give protein and water near the heavy backbone",
        "atoms of any cyanocysteine residues. By default, when",
        "the -exclude flag is used, potentials will be reported",
        "in two group--water (resname HOH or resname SOL) and",
        "non-water contributions."
        "\n"
    };
    /* Command-line arguments */
    int             a1 = 0; // initialized for error checking
    int             a2 = 0;
    real            pdie = 1;
    real            delta = 0.010; // nm
    real            ring_dist = 0.07; // nm
    static char     *exclude = NULL;
    static char     *site = NULL;
    bool            bVerbose = false; // 0=false, 1=true
    bool            dopqr = true;
    
    t_pargs         pa[] = {
        { "-a1", TRUE, etINT,
            {&a1}, "Starting atom for bond vector--ie: CD in CNC"},
        { "-a2", TRUE, etINT,
            {&a2}, "Ending atom for bond vector--ie: NE in CNC"},
        { "-site", TRUE, etSTR,
            {&site}, "Atoms to be included as sites for the electrostatic model used by the Cho group.  Atoms pass by -a1 and -a2 are added to this group automatically.  Note that the whole selection string will need to be quoted so that your shell will pass it in as a string."},
        { "-exclude", TRUE, etSTR,
            {&exclude}, "Specific atoms to exclude from the field calculations.  Atoms pass by -a1 and -a2 are added to this group automatically.  Note that the whole selection string will need to be quoted so that your shell will pass it in as a string."},
        { "-pdie", TRUE, etREAL,
            {&pdie}, "Protein dielectric constant"},
        { "-delta", TRUE, etREAL,
            {&delta}, "(nm) Spacing between dummy atoms at the bond midpoint"},
        { "-dopqr", TRUE, etBOOL,
            {&dopqr}, "Write out a .pqr file.  Default: True"},
        { "-v", FALSE, etBOOL,
            {&bVerbose}, "Be slightly more verbose"}
    };
    
    t_filenm        fnm[] = {
         { efDAT, "-d", "/Users/ritchie/Utilities/apbs/AMBER.DAT", ffREAD }
        ,{ efPQR, "-o", NULL, ffWRITE }
        ,{ efXVG, "-of", "coulomb_field", ffWRITE }
        ,{ efDAT, "-bw", "bw.dat", ffOPTWR}
        ,{ efXVG, "-or", "coulomb_field_per_residue", ffOPTWR}
        //,{ efNDX, NULL, NULL, ffREAD }
    };
    
#define NFILE asize(fnm)
    
    gmx_ana_traj_t      *trj;
    t_topology          *top;
    output_env_t        oenv;
    //t_dsdata            d;
    //t_analysisdata d;
    t_analysisdata      d;
    int                 ngrps;
    gmx_ana_selection_t **sel;
    int                 g;
    int                 rc;
    
    CopyRight(stderr, argv[0]);
    
    gmx_ana_traj_create(&trj, ANA_REQUIRE_TOP);
    gmx_ana_set_nanagrps(trj, -1);
    parse_trjana_args(trj, &argc, argv, 0,
                      NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL,
                      &oenv);
    gmx_ana_get_topology(trj, FALSE, &top, NULL);

    gmx_ana_get_nanagrps(trj, &ngrps);
    gmx_ana_get_anagrps(trj, &sel);
    gmx_ana_init_coverfrac(trj, CFRAC_SOLIDANGLE);
    
    /* Get output file names */
    const char          *datname, *framepqr;
    datname = opt2fn("-d", NFILE, fnm);
    framepqr = opt2fn("-o", NFILE, fnm);
    
    /* open xvg file */
    d.fp = xvgropen(opt2fn("-of", NFILE, fnm), "Coulomb field for each frame", "Frame Number", "Field[kbt/eA]", oenv);
    std::vector<std::string> legend;
    legend.push_back("frame");
    legend.push_back("total_field");
    /* I'm also going to make a helpful string for my bw_wham script */
    std::stringstream bw_wham_string;
    bw_wham_string << "-d coulomb_all_atoms -u kbt/eA ";
    
    /* Check for optional field per residue output call */
    if ( opt2fn("-or", NFILE, fnm) ) {
        d.fpr = xvgropen(opt2fn("-or", NFILE, fnm), "Coulomb Field for each frame for each residue", "Frame Number", "Field[kbt/eA]", oenv);
    }
    
    /* Make sure -a1 and -a2 are included and increment by -1 to match internal numbering */
    if ( a1<1 || a2<1 ) {
        gmx_fatal(FARGS, "\nAtom numbers -a1 and -a2 defining the bond vector must be specified\n");
    }
    a1--; a2--;
    
    /* If any, get the atom numbers for the excluded atoms */
    std::vector<int> exclude_ndx;
    if (exclude) {
        int n;
        std::stringstream excluded_line(exclude);
        while ( excluded_line >> n ) {
            exclude_ndx.push_back(n-1);
        }
        exclude_ndx.push_back(a1);
        exclude_ndx.push_back(a2);
        fprintf(stderr,"\nWill calculate and remove field contributions due to atoms: ");
        for (int i=0; i<(int)exclude_ndx.size(); i++) {
            fprintf(stderr,"%i%s ",exclude_ndx[i]+1,*top->atoms.atomname[exclude_ndx[i]]);
            /* Add the excluded atoms to the xvg legend */
            std::stringstream key;
            key << exclude_ndx[i]+1 << *top->atoms.atomname[exclude_ndx[i]] << "_field";
            legend.push_back(key.str());
            bw_wham_string << "-d coulomb_" << *top->atoms.atomname[exclude_ndx[i]] << " -u kbt/eA ";
        }
    }
    /* Add entries to the xvg legend */
    legend.push_back("F-except");
    bw_wham_string << "-d coulomb_minus_ch2scn -u kbt/eA ";

    char xyz[] = "XYZ";
    /* midpoint field vector components */
    for (int i=0;i<3;i++){
        std::stringstream key;
        key << "MID" << xyz[i];
        legend.push_back(key.str());
        bw_wham_string << "-d coulomb_midpoint_" << xyz[i] << " -u kbt/eA ";
    }
    /* -a1 field vector components */
    for (int i=0;i<3;i++){
        std::stringstream key;
        key << *top->atoms.atomname[a1] << xyz[i];
        legend.push_back(key.str());
        bw_wham_string << "-d coulomb_" << *top->atoms.atomname[a1] << "_" << xyz[i] << " -u kbt/eA ";
    }
    /* -a2 field vector components */
    for (int i=0;i<3;i++){
        std::stringstream key;
        key << *top->atoms.atomname[a2] << xyz[i];
        legend.push_back(key.str());
        bw_wham_string << "-d coulomb_" << *top->atoms.atomname[a2] << "_" << xyz[i] << " -u kbt/eA ";
    }
    
    /* If any, get the atom numbers for the Cho site atoms */
    std::vector<int> site_ndx;
    if (site) {
        int n;
        std::stringstream site_line(site);
        while (site_line >> n ) {
            site_ndx.push_back(n-1);
        }
        site_ndx.push_back(a1);
        site_ndx.push_back(a2);
        fprintf(stderr,"\nWill calculate the electrostatic potential at sites on the following atoms: ");
        for (int i=0; i<(int)site_ndx.size(); i++) {
            fprintf(stderr,"%i%s ",site_ndx[i]+1,*top->atoms.atomname[site_ndx[i]]);
            /* Add the sites to the xvg legend */
            std::stringstream pkey, wkey;
            pkey << "protein_p" << i;
            legend.push_back(pkey.str());
            bw_wham_string << "-d coulomb_" << pkey.str() << " -u kbt/e ";
            wkey << "water_p" << i;
            legend.push_back(wkey.str());
            bw_wham_string << "-d coulomb_" << wkey.str() << " -u kbt/e ";
        }
        /* Add entries for each of the 8 sites on each -a1 and -a2 and the site straight out
           from the bond */
        for (int i=0; i<17; i++) {
            std::stringstream pkey, wkey;
            pkey << "protein_p" << i+(int)site_ndx.size();
            legend.push_back(pkey.str());
            bw_wham_string << "-d coulomb_" << pkey.str() << " -u kbt/e ";
            wkey << "water_p" << i+(int)site_ndx.size();
            legend.push_back(wkey.str());
            bw_wham_string << "-d coulomb_" << wkey.str() << " -u kbt/e ";
        }
    }
    
    /* convert the legend to a char array and include it in the xvg file */
    int nlegend_items = legend.size();
    char **flegend = new char* [nlegend_items];
    for (int i=0; i<nlegend_items; i++) {
        flegend[i] = new char [sizeof(legend[i].c_str())];
        strcpy(flegend[i],legend[i].c_str());
    }
    xvgr_legend(d.fp, nlegend_items, (const char**)flegend, oenv);
    
    /* Make sure that -a1, -a2, -exclude, and -site atoms exist in the trajectory */
    if (a1<0 || a1>top->atoms.nr){
        gmx_fatal(FARGS, "\nError: Atom -a1 is %d, which is outside of the range 0 to %d\n",a1+1,top->atoms.nr+1);
    }
    if (a2<0 || a2>top->atoms.nr){
        gmx_fatal(FARGS, "\nError: Atom -a2 is %d, which is outside of the range 0 to %d\n",a2+1,top->atoms.nr+1);
    }
    for (int i=0; i<(int)exclude_ndx.size(); i++){
        if (exclude_ndx[i]<0 || exclude_ndx[i]>top->atoms.nr){
            gmx_fatal(FARGS, "\nError: Excluded atom %d, %d, which is outside of the range 0 to %d\n",i,exclude_ndx[i]+1,top->atoms.nr+1);
        }
    }
    for (int i=0; i<(int)site_ndx.size(); i++){
        if (site_ndx[i]<0 || site_ndx[i]>top->atoms.nr){
            gmx_fatal(FARGS, "\nError: Cho site atom %d, %d, which is outside of the range 0 to %d\n",i,site_ndx[i]+1,top->atoms.nr+1);
        }
    }
    
    /* If asked for, print out the bw_wham_string to a file */
    if (opt2bSet("-bw", NFILE, fnm)) {
        fprintf(stderr,"\nWriting flags for bw_wham to %s",opt2fn("-bw", NFILE, fnm));
        std::ofstream bwfile;
        bwfile.open(opt2fn("-bw", NFILE, fnm));
        bwfile << bw_wham_string.str() << std::endl;
        bwfile.close();
    }
    
    /* Parse through the DAT file to make the gmx->dat mapping */
    read_DAT(datname, d.amber, bVerbose);

    /* Pass variables to structure for analysis */
    d.a1 = a1;
    d.a2 = a2;
    d.rpdie = 1./pdie;
    d.delta = delta * 0.5;
    d.ring_dist = ring_dist;
    d.site_ndx = site_ndx;
    d.exclude_ndx = exclude_ndx;
    d.framen = 0;
    d.pqr = framepqr;
    d.dopqr = dopqr;
    d.bVerbose = bVerbose;
    /* Parse through the frames */
    gmx_ana_do(trj, 0, &analyze_frame, &d);
    ffclose(d.fp);
}