コード例 #1
0
ファイル: resid_gmx2pqr.cpp プロジェクト: awritchie/my_gmx
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);
}
コード例 #2
0
ファイル: convert_tpr.cpp プロジェクト: tanigawa/gromacs
int gmx_convert_tpr(int argc, char *argv[])
{
    const char       *desc[] = {
        "[THISMODULE] can edit run input files in four ways.[PAR]",
        "[BB]1.[bb] by modifying the number of steps in a run input file",
        "with options [TT]-extend[tt], [TT]-until[tt] or [TT]-nsteps[tt]",
        "(nsteps=-1 means unlimited number of steps)[PAR]",
        "[BB]2.[bb] (OBSOLETE) by creating a run input file",
        "for a continuation run when your simulation has crashed due to e.g.",
        "a full disk, or by making a continuation run input file.",
        "This option is obsolete, since mdrun now writes and reads",
        "checkpoint files.",
        "[BB]Note[bb] that a frame with coordinates and velocities is needed.",
        "When pressure and/or Nose-Hoover temperature coupling is used",
        "an energy file can be supplied to get an exact continuation",
        "of the original run.[PAR]",
        "[BB]3.[bb] by creating a [REF].tpx[ref] file for a subset of your original",
        "tpx file, which is useful when you want to remove the solvent from",
        "your [REF].tpx[ref] file, or when you want to make e.g. a pure C[GRK]alpha[grk] [REF].tpx[ref] file.",
        "Note that you may need to use [TT]-nsteps -1[tt] (or similar) to get",
        "this to work.",
        "[BB]WARNING: this [REF].tpx[ref] file is not fully functional[bb].[PAR]",
        "[BB]4.[bb] by setting the charges of a specified group",
        "to zero. This is useful when doing free energy estimates",
        "using the LIE (Linear Interaction Energy) method."
    };

    const char       *top_fn, *frame_fn;
    struct t_fileio  *fp;
    ener_file_t       fp_ener = NULL;
    gmx_trr_header_t  head;
    int               i;
    gmx_int64_t       nsteps_req, run_step, frame;
    double            run_t, state_t;
    gmx_bool          bOK, bNsteps, bExtend, bUntil, bTime, bTraj;
    gmx_bool          bFrame, bUse, bSel, bNeedEner, bReadEner, bScanEner, bFepState;
    gmx_mtop_t        mtop;
    t_atoms           atoms;
    t_inputrec       *ir;
    t_state           state;
    rvec             *newx = NULL, *newv = NULL, *tmpx, *tmpv;
    matrix            newbox;
    int               gnx;
    char             *grpname;
    atom_id          *index = NULL;
    int               nre;
    gmx_enxnm_t      *enm     = NULL;
    t_enxframe       *fr_ener = NULL;
    char              buf[200], buf2[200];
    gmx_output_env_t *oenv;
    t_filenm          fnm[] = {
        { efTPR, NULL,  NULL,    ffREAD  },
        { efTRN, "-f",  NULL,    ffOPTRD },
        { efEDR, "-e",  NULL,    ffOPTRD },
        { efNDX, NULL,  NULL,    ffOPTRD },
        { efTPR, "-o",  "tprout", ffWRITE }
    };
#define NFILE asize(fnm)

    /* Command line options */
    static int      nsteps_req_int = 0;
    static real     start_t        = -1.0, extend_t = 0.0, until_t = 0.0;
    static int      init_fep_state = 0;
    static gmx_bool bContinuation  = TRUE, bZeroQ = FALSE, bVel = TRUE;
    static t_pargs  pa[]           = {
        { "-extend",        FALSE, etREAL, {&extend_t},
          "Extend runtime by this amount (ps)" },
        { "-until",         FALSE, etREAL, {&until_t},
          "Extend runtime until this ending time (ps)" },
        { "-nsteps",        FALSE, etINT,  {&nsteps_req_int},
          "Change the number of steps" },
        { "-time",          FALSE, etREAL, {&start_t},
          "Continue from frame at this time (ps) instead of the last frame" },
        { "-zeroq",         FALSE, etBOOL, {&bZeroQ},
          "Set the charges of a group (from the index) to zero" },
        { "-vel",           FALSE, etBOOL, {&bVel},
          "Require velocities from trajectory" },
        { "-cont",          FALSE, etBOOL, {&bContinuation},
          "For exact continuation, the constraints should not be applied before the first step" },
        { "-init_fep_state", FALSE, etINT, {&init_fep_state},
          "fep state to initialize from" },
    };

    /* Parse the command line */
    if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa,
                           asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    /* Convert int to gmx_int64_t */
    nsteps_req = nsteps_req_int;
    bNsteps    = opt2parg_bSet("-nsteps", asize(pa), pa);
    bExtend    = opt2parg_bSet("-extend", asize(pa), pa);
    bUntil     = opt2parg_bSet("-until", asize(pa), pa);
    bFepState  = opt2parg_bSet("-init_fep_state", asize(pa), pa);
    bTime      = opt2parg_bSet("-time", asize(pa), pa);
    bTraj      = (opt2bSet("-f", NFILE, fnm) || bTime);

    top_fn = ftp2fn(efTPR, NFILE, fnm);
    fprintf(stderr, "Reading toplogy and stuff from %s\n", top_fn);

    snew(ir, 1);
    read_tpx_state(top_fn, ir, &state, &mtop);
    run_step = ir->init_step;
    run_t    = ir->init_step*ir->delta_t + ir->init_t;

    if (!EI_STATE_VELOCITY(ir->eI))
    {
        bVel = FALSE;
    }

    if (bTraj)
    {
        fprintf(stderr, "\n"
                "NOTE: Reading the state from trajectory is an obsolete feature of gmx convert-tpr.\n"
                "      Continuation should be done by loading a checkpoint file with mdrun -cpi\n"
                "      This guarantees that all state variables are transferred.\n"
                "      gmx convert-tpr is now only useful for increasing nsteps,\n"
                "      but even that can often be avoided by using mdrun -maxh\n"
                "\n");

        if (ir->bContinuation != bContinuation)
        {
            fprintf(stderr, "Modifying ir->bContinuation to %s\n",
                    bool_names[bContinuation]);
        }
        ir->bContinuation = bContinuation;


        bNeedEner = (ir->epc == epcPARRINELLORAHMAN || ir->etc == etcNOSEHOOVER);
        bReadEner = (bNeedEner && ftp2bSet(efEDR, NFILE, fnm));
        bScanEner = (bReadEner && !bTime);

        if (ir->epc != epcNO || EI_SD(ir->eI) || ir->eI == eiBD)
        {
            fprintf(stderr, "NOTE: The simulation uses pressure coupling and/or stochastic dynamics.\n"
                    "gmx convert-tpr can not provide binary identical continuation.\n"
                    "If you want that, supply a checkpoint file to mdrun\n\n");
        }

        if (EI_SD(ir->eI) || ir->eI == eiBD)
        {
            fprintf(stderr, "\nChanging ld-seed from %" GMX_PRId64 " ", ir->ld_seed);
            ir->ld_seed = (gmx_int64_t)gmx_rng_make_seed();
            fprintf(stderr, "to %" GMX_PRId64 "\n\n", ir->ld_seed);
        }

        frame_fn = ftp2fn(efTRN, NFILE, fnm);

        if (fn2ftp(frame_fn) == efCPT)
        {
            int sim_part;

            fprintf(stderr,
                    "\nREADING STATE FROM CHECKPOINT %s...\n\n",
                    frame_fn);

            read_checkpoint_state(frame_fn, &sim_part,
                                  &run_step, &run_t, &state);
        }
        else
        {
            fprintf(stderr,
                    "\nREADING COORDS, VELS AND BOX FROM TRAJECTORY %s...\n\n",
                    frame_fn);

            fp = gmx_trr_open(frame_fn, "r");
            if (bScanEner)
            {
                fp_ener = open_enx(ftp2fn(efEDR, NFILE, fnm), "r");
                do_enxnms(fp_ener, &nre, &enm);
                snew(fr_ener, 1);
                fr_ener->t = -1e-12;
            }

            /* Now scan until the last set of x and v (step == 0)
             * or the ones at step step.
             */
            bFrame = TRUE;
            frame  = 0;
            while (bFrame)
            {
                bFrame = gmx_trr_read_frame_header(fp, &head, &bOK);
                if (bOK && frame == 0)
                {
                    if (mtop.natoms != head.natoms)
                    {
                        gmx_fatal(FARGS, "Number of atoms in Topology (%d) "
                                  "is not the same as in Trajectory (%d)\n",
                                  mtop.natoms, head.natoms);
                    }
                    snew(newx, head.natoms);
                    snew(newv, head.natoms);
                }
                bFrame = bFrame && bOK;
                if (bFrame)
                {
                    bOK = gmx_trr_read_frame_data(fp, &head, newbox, newx, newv, NULL);
                }
                bFrame = bFrame && bOK;
                bUse   = FALSE;
                if (bFrame &&
                    (head.x_size) && (head.v_size || !bVel))
                {
                    bUse = TRUE;
                    if (bScanEner)
                    {
                        /* Read until the energy time is >= the trajectory time */
                        while (fr_ener->t < head.t && do_enx(fp_ener, fr_ener))
                        {
                            ;
                        }
                        bUse = (fr_ener->t == head.t);
                    }
                    if (bUse)
                    {
                        tmpx                  = newx;
                        newx                  = state.x;
                        state.x               = tmpx;
                        tmpv                  = newv;
                        newv                  = state.v;
                        state.v               = tmpv;
                        run_t                 = head.t;
                        run_step              = head.step;
                        state.fep_state       = head.fep_state;
                        state.lambda[efptFEP] = head.lambda;
                        copy_mat(newbox, state.box);
                    }
                }
                if (bFrame || !bOK)
                {
                    sprintf(buf, "\r%s %s frame %s%s: step %s%s time %s",
                            "%s", "%s", "%6", GMX_PRId64, "%6", GMX_PRId64, " %8.3f");
                    fprintf(stderr, buf,
                            bUse ? "Read   " : "Skipped", ftp2ext(fn2ftp(frame_fn)),
                            frame, head.step, head.t);
                    frame++;
                    if (bTime && (head.t >= start_t))
                    {
                        bFrame = FALSE;
                    }
                }
            }
            if (bScanEner)
            {
                close_enx(fp_ener);
                free_enxframe(fr_ener);
                free_enxnms(nre, enm);
            }
            gmx_trr_close(fp);
            fprintf(stderr, "\n");

            if (!bOK)
            {
                fprintf(stderr, "%s frame %s (step %s, time %g) is incomplete\n",
                        ftp2ext(fn2ftp(frame_fn)), gmx_step_str(frame-1, buf2),
                        gmx_step_str(head.step, buf), head.t);
            }
            fprintf(stderr, "\nUsing frame of step %s time %g\n",
                    gmx_step_str(run_step, buf), run_t);

            if (bNeedEner)
            {
                if (bReadEner)
                {
                    get_enx_state(ftp2fn(efEDR, NFILE, fnm), run_t, &mtop.groups, ir, &state);
                }
                else
                {
                    fprintf(stderr, "\nWARNING: The simulation uses %s temperature and/or %s pressure coupling,\n"
                            "         the continuation will only be exact when an energy file is supplied\n\n",
                            ETCOUPLTYPE(etcNOSEHOOVER),
                            EPCOUPLTYPE(epcPARRINELLORAHMAN));
                }
            }
            if (bFepState)
            {
                ir->fepvals->init_fep_state = init_fep_state;
            }
        }
    }

    if (bNsteps)
    {
        fprintf(stderr, "Setting nsteps to %s\n", gmx_step_str(nsteps_req, buf));
        ir->nsteps = nsteps_req;
    }
    else
    {
        /* Determine total number of steps remaining */
        if (bExtend)
        {
            ir->nsteps = ir->nsteps - (run_step - ir->init_step) + (gmx_int64_t)(extend_t/ir->delta_t + 0.5);
            printf("Extending remaining runtime of by %g ps (now %s steps)\n",
                   extend_t, gmx_step_str(ir->nsteps, buf));
        }
        else if (bUntil)
        {
            printf("nsteps = %s, run_step = %s, current_t = %g, until = %g\n",
                   gmx_step_str(ir->nsteps, buf),
                   gmx_step_str(run_step, buf2),
                   run_t, until_t);
            ir->nsteps = (gmx_int64_t)((until_t - run_t)/ir->delta_t + 0.5);
            printf("Extending remaining runtime until %g ps (now %s steps)\n",
                   until_t, gmx_step_str(ir->nsteps, buf));
        }
        else
        {
            ir->nsteps -= run_step - ir->init_step;
            /* Print message */
            printf("%s steps (%g ps) remaining from first run.\n",
                   gmx_step_str(ir->nsteps, buf), ir->nsteps*ir->delta_t);
        }
    }

    if (bNsteps || bZeroQ || (ir->nsteps > 0))
    {
        ir->init_step = run_step;

        if (ftp2bSet(efNDX, NFILE, fnm) ||
            !(bNsteps || bExtend || bUntil || bTraj))
        {
            atoms = gmx_mtop_global_atoms(&mtop);
            get_index(&atoms, ftp2fn_null(efNDX, NFILE, fnm), 1,
                      &gnx, &index, &grpname);
            if (!bZeroQ)
            {
                bSel = (gnx != state.natoms);
                for (i = 0; ((i < gnx) && (!bSel)); i++)
                {
                    bSel = (i != index[i]);
                }
            }
            else
            {
                bSel = FALSE;
            }
            if (bSel)
            {
                fprintf(stderr, "Will write subset %s of original tpx containing %d "
                        "atoms\n", grpname, gnx);
                reduce_topology_x(gnx, index, &mtop, state.x, state.v);
                state.natoms = gnx;
            }
            else if (bZeroQ)
            {
                zeroq(index, &mtop);
                fprintf(stderr, "Zero-ing charges for group %s\n", grpname);
            }
            else
            {
                fprintf(stderr, "Will write full tpx file (no selection)\n");
            }
        }

        state_t = ir->init_t + ir->init_step*ir->delta_t;
        sprintf(buf,   "Writing statusfile with starting step %s%s and length %s%s steps...\n", "%10", GMX_PRId64, "%10", GMX_PRId64);
        fprintf(stderr, buf, ir->init_step, ir->nsteps);
        fprintf(stderr, "                                 time %10.3f and length %10.3f ps\n",
                state_t, ir->nsteps*ir->delta_t);
        write_tpx_state(opt2fn("-o", NFILE, fnm), ir, &state, &mtop);
    }
    else
    {
        printf("You've simulated long enough. Not writing tpr file\n");
    }

    return 0;
}
コード例 #3
0
void sas_plot(int nfile,t_filenm fnm[],real solsize,int ndots,
	      real qcut,gmx_bool bSave,real minarea,gmx_bool bPBC,
	      real dgs_default,gmx_bool bFindex, const output_env_t oenv)
{
  FILE         *fp,*fp2,*fp3=NULL,*vp;
  const char   *flegend[] = { "Hydrophobic", "Hydrophilic", 
			      "Total", "D Gsolv" };
  const char   *vlegend[] = { "Volume (nm\\S3\\N)", "Density (g/l)" };
  const char   *or_and_oa_legend[] = { "Average (nm\\S2\\N)", "Standard deviation (nm\\S2\\N)" };
  const char   *vfile;
  real         t;
  gmx_atomprop_t aps=NULL;
  gmx_rmpbc_t  gpbc=NULL;
  t_trxstatus  *status;
  int          ndefault;
  int          i,j,ii,nfr,natoms,flag,nsurfacedots,res;
  rvec         *xtop,*x;
  matrix       topbox,box;
  t_topology   top;
  char         title[STRLEN];
  int          ePBC;
  gmx_bool         bTop;
  t_atoms      *atoms;
  gmx_bool         *bOut,*bPhobic;
  gmx_bool         bConnelly;
  gmx_bool         bResAt,bITP,bDGsol;
  real         *radius,*dgs_factor=NULL,*area=NULL,*surfacedots=NULL;
  real         at_area,*atom_area=NULL,*atom_area2=NULL;
  real         *res_a=NULL,*res_area=NULL,*res_area2=NULL;
  real         totarea,totvolume,totmass=0,density,harea,tarea,fluc2;
  atom_id      **index,*findex;
  int          *nx,nphobic,npcheck,retval;
  char         **grpname,*fgrpname;
  real         dgsolv;

  bITP   = opt2bSet("-i",nfile,fnm);
  bResAt = opt2bSet("-or",nfile,fnm) || opt2bSet("-oa",nfile,fnm) || bITP;

  bTop = read_tps_conf(ftp2fn(efTPS,nfile,fnm),title,&top,&ePBC,
		       &xtop,NULL,topbox,FALSE);
  atoms = &(top.atoms);
  
  if (!bTop) {
    fprintf(stderr,"No tpr file, will not compute Delta G of solvation\n");
    bDGsol = FALSE;
  } else {
    bDGsol = strcmp(*(atoms->atomtype[0]),"?") != 0;
    if (!bDGsol) {
      fprintf(stderr,"Warning: your tpr file is too old, will not compute "
	      "Delta G of solvation\n");
    } else {
      printf("In case you use free energy of solvation predictions:\n");
      please_cite(stdout,"Eisenberg86a");
    }
  }

  aps = gmx_atomprop_init();
  
  if ((natoms=read_first_x(oenv,&status,ftp2fn(efTRX,nfile,fnm),
			   &t,&x,box))==0)
    gmx_fatal(FARGS,"Could not read coordinates from statusfile\n");

  if ((ePBC != epbcXYZ) || (TRICLINIC(box))) {
    fprintf(stderr,"\n\nWARNING: non-rectangular boxes may give erroneous results or crashes.\n"
	    "Analysis based on vacuum simulations (with the possibility of evaporation)\n" 
	    "will certainly crash the analysis.\n\n");
  }
  snew(nx,2);
  snew(index,2);
  snew(grpname,2);
  fprintf(stderr,"Select a group for calculation of surface and a group for output:\n");
  get_index(atoms,ftp2fn_null(efNDX,nfile,fnm),2,nx,index,grpname);

  if (bFindex) {
    fprintf(stderr,"Select a group of hydrophobic atoms:\n");
    get_index(atoms,ftp2fn_null(efNDX,nfile,fnm),1,&nphobic,&findex,&fgrpname);
  }
  snew(bOut,natoms);
  for(i=0; i<nx[1]; i++)
    bOut[index[1][i]] = TRUE;

  /* Now compute atomic readii including solvent probe size */
  snew(radius,natoms);
  snew(bPhobic,nx[0]);
  if (bResAt) {
    snew(atom_area,nx[0]);
    snew(atom_area2,nx[0]);
    snew(res_a,atoms->nres);
    snew(res_area,atoms->nres);
    snew(res_area2,atoms->nres);
  }
  if (bDGsol)
    snew(dgs_factor,nx[0]);

  /* Get a Van der Waals radius for each atom */
  ndefault = 0;
  for(i=0; (i<natoms); i++) {
    if (!gmx_atomprop_query(aps,epropVDW,
			    *(atoms->resinfo[atoms->atom[i].resind].name),
			    *(atoms->atomname[i]),&radius[i]))
      ndefault++;
    /* radius[i] = calc_radius(*(top->atoms.atomname[i])); */
    radius[i] += solsize;
  }
  if (ndefault > 0)
    fprintf(stderr,"WARNING: could not find a Van der Waals radius for %d atoms\n",ndefault);
  /* Determine which atom is counted as hydrophobic */
  if (bFindex) {
    npcheck = 0;
    for(i=0; (i<nx[0]); i++) {
      ii = index[0][i];
      for(j=0; (j<nphobic); j++) {
	if (findex[j] == ii) {
	  bPhobic[i] = TRUE;
	  if (bOut[ii])
	    npcheck++;
	}
      }
    }
    if (npcheck != nphobic)
      gmx_fatal(FARGS,"Consistency check failed: not all %d atoms in the hydrophobic index\n"
		  "found in the normal index selection (%d atoms)",nphobic,npcheck);
  }
  else
    nphobic = 0;
    
  for(i=0; (i<nx[0]); i++) {
    ii = index[0][i];
    if (!bFindex) {
      bPhobic[i] = fabs(atoms->atom[ii].q) <= qcut;
      if (bPhobic[i] && bOut[ii])
	nphobic++;
    }
    if (bDGsol)
      if (!gmx_atomprop_query(aps,epropDGsol,
			      *(atoms->resinfo[atoms->atom[ii].resind].name),
			      *(atoms->atomtype[ii]),&(dgs_factor[i])))
	dgs_factor[i] = dgs_default;
    if (debug)
      fprintf(debug,"Atom %5d %5s-%5s: q= %6.3f, r= %6.3f, dgsol= %6.3f, hydrophobic= %s\n",
	      ii+1,*(atoms->resinfo[atoms->atom[ii].resind].name),
	      *(atoms->atomname[ii]),
	      atoms->atom[ii].q,radius[ii]-solsize,dgs_factor[i],
	      BOOL(bPhobic[i]));
  }
  fprintf(stderr,"%d out of %d atoms were classified as hydrophobic\n",
	  nphobic,nx[1]);
  
  fp=xvgropen(opt2fn("-o",nfile,fnm),"Solvent Accessible Surface","Time (ps)",
	      "Area (nm\\S2\\N)",oenv);
  xvgr_legend(fp,asize(flegend) - (bDGsol ? 0 : 1),flegend,oenv);
  vfile = opt2fn_null("-tv",nfile,fnm);
  if (vfile) {
    if (!bTop) {
      gmx_fatal(FARGS,"Need a tpr file for option -tv");
    }
    vp=xvgropen(vfile,"Volume and Density","Time (ps)","",oenv);
    xvgr_legend(vp,asize(vlegend),vlegend,oenv);
    totmass  = 0;
    ndefault = 0;
    for(i=0; (i<nx[0]); i++) {
      real mm;
      ii = index[0][i];
      /*
      if (!query_atomprop(atomprop,epropMass,
			  *(top->atoms.resname[top->atoms.atom[ii].resnr]),
			  *(top->atoms.atomname[ii]),&mm))
	ndefault++;
      totmass += mm;
      */
      totmass += atoms->atom[ii].m;
    }
    if (ndefault)
      fprintf(stderr,"WARNING: Using %d default masses for density calculation, which most likely are inaccurate\n",ndefault);
  }
  else
    vp = NULL;
    
  gmx_atomprop_destroy(aps);

  if (bPBC)
    gpbc = gmx_rmpbc_init(&top.idef,ePBC,natoms,box);
  
  nfr=0;
  do {
    if (bPBC)
      gmx_rmpbc(gpbc,natoms,box,x);
    
    bConnelly = (nfr==0 && opt2bSet("-q",nfile,fnm));
    if (bConnelly) {
      if (!bTop)
	gmx_fatal(FARGS,"Need a tpr file for Connelly plot");
      flag = FLAG_ATOM_AREA | FLAG_DOTS;
    } else {
      flag = FLAG_ATOM_AREA;
    }
    if (vp) {
      flag = flag | FLAG_VOLUME;
    }
      
    if (debug)
      write_sto_conf("check.pdb","pbc check",atoms,x,NULL,ePBC,box);

    retval = nsc_dclm_pbc(x,radius,nx[0],ndots,flag,&totarea,
			  &area,&totvolume,&surfacedots,&nsurfacedots,
			  index[0],ePBC,bPBC ? box : NULL);
    if (retval)
      gmx_fatal(FARGS,"Something wrong in nsc_dclm_pbc");
    
    if (bConnelly)
      connelly_plot(ftp2fn(efPDB,nfile,fnm),
		    nsurfacedots,surfacedots,x,atoms,
		    &(top.symtab),ePBC,box,bSave);
    harea  = 0; 
    tarea  = 0;
    dgsolv = 0;
    if (bResAt)
      for(i=0; i<atoms->nres; i++)
	res_a[i] = 0;
    for(i=0; (i<nx[0]); i++) {
      ii = index[0][i];
      if (bOut[ii]) {
	at_area = area[i];
	if (bResAt) {
	  atom_area[i] += at_area;
	  atom_area2[i] += sqr(at_area);
	  res_a[atoms->atom[ii].resind] += at_area;
	}
	tarea += at_area;
	if (bDGsol)
	  dgsolv += at_area*dgs_factor[i];
	if (bPhobic[i])
	  harea += at_area;
      }
    }
    if (bResAt)
      for(i=0; i<atoms->nres; i++) {
	res_area[i] += res_a[i];
	res_area2[i] += sqr(res_a[i]);
      }
    fprintf(fp,"%10g  %10g  %10g  %10g",t,harea,tarea-harea,tarea);
    if (bDGsol)
      fprintf(fp,"  %10g\n",dgsolv);
    else
      fprintf(fp,"\n");
    
    /* Print volume */
    if (vp) {
      density = totmass*AMU/(totvolume*NANO*NANO*NANO);
      fprintf(vp,"%12.5e  %12.5e  %12.5e\n",t,totvolume,density);
    }
    if (area) {
      sfree(area);
      area = NULL;
    }
    if (surfacedots) {
      sfree(surfacedots);
      surfacedots = NULL;
    }
    nfr++;
  } while (read_next_x(oenv,status,&t,natoms,x,box));

  if (bPBC)  
    gmx_rmpbc_done(gpbc);

  fprintf(stderr,"\n");
  close_trj(status);
  ffclose(fp);
  if (vp)
    ffclose(vp);
    
  /* if necessary, print areas per atom to file too: */
  if (bResAt) {
    for(i=0; i<atoms->nres; i++) {
      res_area[i] /= nfr;
      res_area2[i] /= nfr;
    }
    for(i=0; i<nx[0]; i++) {
      atom_area[i] /= nfr;
      atom_area2[i] /= nfr;
    }
    fprintf(stderr,"Printing out areas per atom\n");
    fp  = xvgropen(opt2fn("-or",nfile,fnm),"Area per residue over the trajectory","Residue",
		   "Area (nm\\S2\\N)",oenv);
    xvgr_legend(fp, asize(or_and_oa_legend),or_and_oa_legend,oenv);
    fp2 = xvgropen(opt2fn("-oa",nfile,fnm),"Area per atom over the trajectory","Atom #",
		   "Area (nm\\S2\\N)",oenv);
    xvgr_legend(fp2, asize(or_and_oa_legend),or_and_oa_legend,oenv);
    if (bITP) {
      fp3 = ftp2FILE(efITP,nfile,fnm,"w");
      fprintf(fp3,"[ position_restraints ]\n"
	      "#define FCX 1000\n"
	      "#define FCY 1000\n"
	      "#define FCZ 1000\n"
	      "; Atom  Type  fx   fy   fz\n");
    }
    for(i=0; i<nx[0]; i++) {
      ii = index[0][i];
      res = atoms->atom[ii].resind;
      if (i==nx[0]-1 || res!=atoms->atom[index[0][i+1]].resind) {
	fluc2 = res_area2[res]-sqr(res_area[res]);
	if (fluc2 < 0)
	  fluc2 = 0;
	fprintf(fp,"%10d  %10g %10g\n",
		atoms->resinfo[res].nr,res_area[res],sqrt(fluc2));
      }
      fluc2 = atom_area2[i]-sqr(atom_area[i]);
      if (fluc2 < 0)
	fluc2 = 0;
      fprintf(fp2,"%d %g %g\n",index[0][i]+1,atom_area[i],sqrt(fluc2));
      if (bITP && (atom_area[i] > minarea))
	fprintf(fp3,"%5d   1     FCX  FCX  FCZ\n",ii+1);
    }
    if (bITP)
      ffclose(fp3);
    ffclose(fp);
  }

    /* Be a good citizen, keep our memory free! */
    sfree(x);
    sfree(nx);
    for(i=0;i<2;i++)
    {
        sfree(index[i]);
        sfree(grpname[i]);
    }
    sfree(bOut);
    sfree(radius);
    sfree(bPhobic);
    
    if(bResAt)
    {
        sfree(atom_area);
        sfree(atom_area2);
        sfree(res_a);
        sfree(res_area);
        sfree(res_area2);
    }
    if(bDGsol)
    {
        sfree(dgs_factor);
    }
}
コード例 #4
0
ファイル: gmx_make_edi.c プロジェクト: drmaruyama/gromacs
int gmx_make_edi(int argc, char *argv[])
{

    static const char *desc[] = {
        "[THISMODULE] generates an essential dynamics (ED) sampling input file to be used with [TT]mdrun[tt]",
        "based on eigenvectors of a covariance matrix ([gmx-covar]) or from a",
        "normal modes analysis ([gmx-nmeig]).",
        "ED sampling can be used to manipulate the position along collective coordinates",
        "(eigenvectors) of (biological) macromolecules during a simulation. Particularly,",
        "it may be used to enhance the sampling efficiency of MD simulations by stimulating",
        "the system to explore new regions along these collective coordinates. A number",
        "of different algorithms are implemented to drive the system along the eigenvectors",
        "([TT]-linfix[tt], [TT]-linacc[tt], [TT]-radfix[tt], [TT]-radacc[tt], [TT]-radcon[tt]),",
        "to keep the position along a certain (set of) coordinate(s) fixed ([TT]-linfix[tt]),",
        "or to only monitor the projections of the positions onto",
        "these coordinates ([TT]-mon[tt]).[PAR]",
        "References:[BR]",
        "A. Amadei, A.B.M. Linssen, B.L. de Groot, D.M.F. van Aalten and ",
        "H.J.C. Berendsen; An efficient method for sampling the essential subspace ",
        "of proteins., J. Biomol. Struct. Dyn. 13:615-626 (1996)[BR]",
        "B.L. de Groot, A. Amadei, D.M.F. van Aalten and H.J.C. Berendsen; ",
        "Towards an exhaustive sampling of the configurational spaces of the ",
        "two forms of the peptide hormone guanylin,",
        "J. Biomol. Struct. Dyn. 13 : 741-751 (1996)[BR]",
        "B.L. de Groot, A.Amadei, R.M. Scheek, N.A.J. van Nuland and H.J.C. Berendsen; ",
        "An extended sampling of the configurational space of HPr from E. coli",
        "Proteins: Struct. Funct. Gen. 26: 314-322 (1996)",
        "[PAR]You will be prompted for one or more index groups that correspond to the eigenvectors,",
        "reference structure, target positions, etc.[PAR]",

        "[TT]-mon[tt]: monitor projections of the coordinates onto selected eigenvectors.[PAR]",
        "[TT]-linfix[tt]: perform fixed-step linear expansion along selected eigenvectors.[PAR]",
        "[TT]-linacc[tt]: perform acceptance linear expansion along selected eigenvectors.",
        "(steps in the desired directions will be accepted, others will be rejected).[PAR]",
        "[TT]-radfix[tt]: perform fixed-step radius expansion along selected eigenvectors.[PAR]",
        "[TT]-radacc[tt]: perform acceptance radius expansion along selected eigenvectors.",
        "(steps in the desired direction will be accepted, others will be rejected).",
        "[BB]Note:[bb] by default the starting MD structure will be taken as origin of the first",
        "expansion cycle for radius expansion. If [TT]-ori[tt] is specified, you will be able",
        "to read in a structure file that defines an external origin.[PAR]",
        "[TT]-radcon[tt]: perform acceptance radius contraction along selected eigenvectors",
        "towards a target structure specified with [TT]-tar[tt].[PAR]",
        "NOTE: each eigenvector can be selected only once. [PAR]",
        "[TT]-outfrq[tt]: frequency (in steps) of writing out projections etc. to [TT].xvg[tt] file[PAR]",
        "[TT]-slope[tt]: minimal slope in acceptance radius expansion. A new expansion",
        "cycle will be started if the spontaneous increase of the radius (in nm/step)",
        "is less than the value specified.[PAR]",
        "[TT]-maxedsteps[tt]: maximum number of steps per cycle in radius expansion",
        "before a new cycle is started.[PAR]",
        "Note on the parallel implementation: since ED sampling is a 'global' thing",
        "(collective coordinates etc.), at least on the 'protein' side, ED sampling",
        "is not very parallel-friendly from an implementation point of view. Because",
        "parallel ED requires some extra communication, expect the performance to be",
        "lower as in a free MD simulation, especially on a large number of nodes and/or",
        "when the ED group contains a lot of atoms. [PAR]",
        "Please also note that if your ED group contains more than a single protein,",
        "then the [TT].tpr[tt] file must contain the correct PBC representation of the ED group.",
        "Take a look on the initial RMSD from the reference structure, which is printed",
        "out at the start of the simulation; if this is much higher than expected, one",
        "of the ED molecules might be shifted by a box vector. [PAR]",
        "All ED-related output of [TT]mdrun[tt] (specify with [TT]-eo[tt]) is written to a [TT].xvg[tt] file",
        "as a function of time in intervals of OUTFRQ steps.[PAR]",
        "[BB]Note[bb] that you can impose multiple ED constraints and flooding potentials in",
        "a single simulation (on different molecules) if several [TT].edi[tt] files were concatenated",
        "first. The constraints are applied in the order they appear in the [TT].edi[tt] file. ",
        "Depending on what was specified in the [TT].edi[tt] input file, the output file contains for each ED dataset[PAR]",
        "[TT]*[tt] the RMSD of the fitted molecule to the reference structure (for atoms involved in fitting prior to calculating the ED constraints)[BR]",
        "[TT]*[tt] projections of the positions onto selected eigenvectors[BR]",
        "[PAR][PAR]",
        "FLOODING:[PAR]",
        "with [TT]-flood[tt], you can specify which eigenvectors are used to compute a flooding potential,",
        "which will lead to extra forces expelling the structure out of the region described",
        "by the covariance matrix. If you switch -restrain the potential is inverted and the structure",
        "is kept in that region.",
        "[PAR]",
        "The origin is normally the average structure stored in the [TT]eigvec.trr[tt] file.",
        "It can be changed with [TT]-ori[tt] to an arbitrary position in configuration space.",
        "With [TT]-tau[tt], [TT]-deltaF0[tt], and [TT]-Eflnull[tt] you control the flooding behaviour.",
        "Efl is the flooding strength, it is updated according to the rule of adaptive flooding.",
        "Tau is the time constant of adaptive flooding, high [GRK]tau[grk] means slow adaption (i.e. growth). ",
        "DeltaF0 is the flooding strength you want to reach after tau ps of simulation.",
        "To use constant Efl set [TT]-tau[tt] to zero.",
        "[PAR]",
        "[TT]-alpha[tt] is a fudge parameter to control the width of the flooding potential. A value of 2 has been found",
        "to give good results for most standard cases in flooding of proteins.",
        "[GRK]alpha[grk] basically accounts for incomplete sampling, if you sampled further the width of the ensemble would",
        "increase, this is mimicked by [GRK]alpha[grk] > 1.",
        "For restraining, [GRK]alpha[grk] < 1 can give you smaller width in the restraining potential.",
        "[PAR]",
        "RESTART and FLOODING:",
        "If you want to restart a crashed flooding simulation please find the values deltaF and Efl in",
        "the output file and manually put them into the [TT].edi[tt] file under DELTA_F0 and EFL_NULL."
    };

    /* Save all the params in this struct and then save it in an edi file.
     * ignoring fields nmass,massnrs,mass,tmass,nfit,fitnrs,edo
     */
    static t_edipar edi_params;

    enum  {
        evStepNr = evRADFIX + 1
    };
    static const char* evSelections[evNr]      = {NULL, NULL, NULL, NULL, NULL, NULL};
    static const char* evOptions[evNr]         = {"-linfix", "-linacc", "-flood", "-radfix", "-radacc", "-radcon", "-mon"};
    static const char* evParams[evStepNr]      = {NULL, NULL};
    static const char* evStepOptions[evStepNr] = {"-linstep", "-accdir", "-not_used", "-radstep"};
    static const char* ConstForceStr;
    static real      * evStepList[evStepNr];
    static real        radstep  = 0.0;
    static real        deltaF0  = 150;
    static real        deltaF   = 0;
    static real        tau      = .1;
    static real        constEfl = 0.0;
    static real        alpha    = 1;
    static int         eqSteps  = 0;
    static int       * listen[evNr];
    static real        T         = 300.0;
    const real         kB        = 2.5 / 300.0; /* k_boltzmann in MD units */
    static gmx_bool    bRestrain = FALSE;
    static gmx_bool    bHesse    = FALSE;
    static gmx_bool    bHarmonic = FALSE;
    t_pargs            pa[]      = {
        { "-mon", FALSE, etSTR, {&evSelections[evMON]},
          "Indices of eigenvectors for projections of x (e.g. 1,2-5,9) or 1-100:10 means 1 11 21 31 ... 91" },
        { "-linfix", FALSE, etSTR, {&evSelections[0]},
          "Indices of eigenvectors for fixed increment linear sampling" },
        { "-linacc", FALSE, etSTR, {&evSelections[1]},
          "Indices of eigenvectors for acceptance linear sampling" },
        { "-radfix", FALSE, etSTR, {&evSelections[3]},
          "Indices of eigenvectors for fixed increment radius expansion" },
        { "-radacc", FALSE, etSTR, {&evSelections[4]},
          "Indices of eigenvectors for acceptance radius expansion" },
        { "-radcon", FALSE, etSTR, {&evSelections[5]},
          "Indices of eigenvectors for acceptance radius contraction" },
        { "-flood",  FALSE, etSTR, {&evSelections[2]},
          "Indices of eigenvectors for flooding"},
        { "-outfrq", FALSE, etINT, {&edi_params.outfrq},
          "Freqency (in steps) of writing output in [TT].xvg[tt] file" },
        { "-slope", FALSE, etREAL, { &edi_params.slope},
          "Minimal slope in acceptance radius expansion"},
        { "-linstep", FALSE, etSTR, {&evParams[0]},
          "Stepsizes (nm/step) for fixed increment linear sampling (put in quotes! \"1.0 2.3 5.1 -3.1\")"},
        { "-accdir", FALSE, etSTR, {&evParams[1]},
          "Directions for acceptance linear sampling - only sign counts! (put in quotes! \"-1 +1 -1.1\")"},
        { "-radstep", FALSE, etREAL, {&radstep},
          "Stepsize (nm/step) for fixed increment radius expansion"},
        { "-maxedsteps", FALSE, etINT, {&edi_params.maxedsteps},
          "Maximum number of steps per cycle" },
        { "-eqsteps", FALSE, etINT, {&eqSteps},
          "Number of steps to run without any perturbations "},
        { "-deltaF0", FALSE, etREAL, {&deltaF0},
          "Target destabilization energy for flooding"},
        { "-deltaF", FALSE, etREAL, {&deltaF},
          "Start deltaF with this parameter - default 0, nonzero values only needed for restart"},
        { "-tau", FALSE, etREAL, {&tau},
          "Coupling constant for adaption of flooding strength according to deltaF0, 0 = infinity i.e. constant flooding strength"},
        { "-Eflnull", FALSE, etREAL, {&constEfl},
          "The starting value of the flooding strength. The flooding strength is updated "
          "according to the adaptive flooding scheme. For a constant flooding strength use [TT]-tau[tt] 0. "},
        { "-T", FALSE, etREAL, {&T},
          "T is temperature, the value is needed if you want to do flooding "},
        { "-alpha", FALSE, etREAL, {&alpha},
          "Scale width of gaussian flooding potential with alpha^2 "},
        { "-restrain", FALSE, etBOOL, {&bRestrain},
          "Use the flooding potential with inverted sign -> effects as quasiharmonic restraining potential"},
        { "-hessian", FALSE, etBOOL, {&bHesse},
          "The eigenvectors and eigenvalues are from a Hessian matrix"},
        { "-harmonic", FALSE, etBOOL, {&bHarmonic},
          "The eigenvalues are interpreted as spring constant"},
        { "-constF", FALSE, etSTR, {&ConstForceStr},
          "Constant force flooding: manually set the forces for the eigenvectors selected with -flood "
          "(put in quotes! \"1.0 2.3 5.1 -3.1\"). No other flooding parameters are needed when specifying the forces directly."}
    };
#define NPA asize(pa)

    rvec        *xref1;
    int          nvec1, *eignr1 = NULL;
    rvec        *xav1, **eigvec1 = NULL;
    t_atoms     *atoms = NULL;
    int          nav; /* Number of atoms in the average structure */
    char        *grpname;
    const char  *indexfile;
    int          i;
    atom_id     *index, *ifit;
    int          nfit;           /* Number of atoms in the reference/fit structure */
    int          ev_class;       /* parameter _class i.e. evMON, evRADFIX etc. */
    int          nvecs;
    real        *eigval1 = NULL; /* in V3.3 this is parameter of read_eigenvectors */

    const char  *EdiFile;
    const char  *TargetFile;
    const char  *OriginFile;
    const char  *EigvecFile;

    output_env_t oenv;

    /*to read topology file*/
    t_topology  top;
    int         ePBC;
    char        title[STRLEN];
    matrix      topbox;
    rvec       *xtop;
    gmx_bool    bTop, bFit1;

    t_filenm    fnm[] = {
        { efTRN, "-f",    "eigenvec",    ffREAD  },
        { efXVG, "-eig",  "eigenval",    ffOPTRD },
        { efTPS, NULL,    NULL,          ffREAD },
        { efNDX, NULL,    NULL,  ffOPTRD },
        { efSTX, "-tar", "target", ffOPTRD},
        { efSTX, "-ori", "origin", ffOPTRD},
        { efEDI, "-o", "sam", ffWRITE }
    };
#define NFILE asize(fnm)
    edi_params.outfrq = 100; edi_params.slope = 0.0; edi_params.maxedsteps = 0;
    if (!parse_common_args(&argc, argv, 0,
                           NFILE, fnm, NPA, pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    indexfile       = ftp2fn_null(efNDX, NFILE, fnm);
    EdiFile         = ftp2fn(efEDI, NFILE, fnm);
    TargetFile      = opt2fn_null("-tar", NFILE, fnm);
    OriginFile      = opt2fn_null("-ori", NFILE, fnm);


    for (ev_class = 0; ev_class < evNr; ++ev_class)
    {
        if (opt2parg_bSet(evOptions[ev_class], NPA, pa))
        {
            /*get list of eigenvectors*/
            nvecs = sscan_list(&(listen[ev_class]), opt2parg_str(evOptions[ev_class], NPA, pa), evOptions[ev_class]);
            if (ev_class < evStepNr-2)
            {
                /*if apropriate get list of stepsizes for these eigenvectors*/
                if (opt2parg_bSet(evStepOptions[ev_class], NPA, pa))
                {
                    evStepList[ev_class] =
                        scan_vecparams(opt2parg_str(evStepOptions[ev_class], NPA, pa), evStepOptions[ev_class], nvecs);
                }
                else   /*if list is not given fill with zeros */
                {
                    snew(evStepList[ev_class], nvecs);
                    for (i = 0; i < nvecs; i++)
                    {
                        evStepList[ev_class][i] = 0.0;
                    }
                }
            }
            else if (ev_class == evRADFIX)
            {
                snew(evStepList[ev_class], nvecs);
                for (i = 0; i < nvecs; i++)
                {
                    evStepList[ev_class][i] = radstep;
                }
            }
            else if (ev_class == evFLOOD)
            {
                snew(evStepList[ev_class], nvecs);

                /* Are we doing constant force flooding? In that case, we read in
                 * the fproj values from the command line */
                if (opt2parg_bSet("-constF", NPA, pa))
                {
                    evStepList[ev_class] = scan_vecparams(opt2parg_str("-constF", NPA, pa), "-constF", nvecs);
                }
            }
            else
            {
            };   /*to avoid ambiguity   */
        }
        else     /* if there are no eigenvectors for this option set list to zero */
        {
            listen[ev_class] = NULL;
            snew(listen[ev_class], 1);
            listen[ev_class][0] = 0;
        }
    }

    /* print the interpreted list of eigenvectors - to give some feedback*/
    for (ev_class = 0; ev_class < evNr; ++ev_class)
    {
        printf("Eigenvector list %7s consists of the indices: ", evOptions[ev_class]);
        i = 0;
        while (listen[ev_class][i])
        {
            printf("%d ", listen[ev_class][i++]);
        }
        printf("\n");
    }

    EigvecFile = NULL;
    EigvecFile = opt2fn("-f", NFILE, fnm);

    /*read eigenvectors from eigvec.trr*/
    read_eigenvectors(EigvecFile, &nav, &bFit1,
                      &xref1, &edi_params.fitmas, &xav1, &edi_params.pcamas, &nvec1, &eignr1, &eigvec1, &eigval1);

    bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm),
                         title, &top, &ePBC, &xtop, NULL, topbox, 0);
    atoms = &top.atoms;


    printf("\nSelect an index group of %d elements that corresponds to the eigenvectors\n", nav);
    get_index(atoms, indexfile, 1, &i, &index, &grpname); /*if indexfile != NULL parameter 'atoms' is ignored */
    if (i != nav)
    {
        gmx_fatal(FARGS, "you selected a group with %d elements instead of %d",
                  i, nav);
    }
    printf("\n");


    if (xref1 == NULL)
    {
        if (bFit1)
        {
            /* if g_covar used different coordinate groups to fit and to do the PCA */
            printf("\nNote: the structure in %s should be the same\n"
                   "      as the one used for the fit in g_covar\n", ftp2fn(efTPS, NFILE, fnm));
            printf("\nSelect the index group that was used for the least squares fit in g_covar\n");
        }
        else
        {
            printf("\nNote: Apparently no fitting was done in g_covar.\n"
                   "      However, you need to select a reference group for fitting in mdrun\n");
        }
        get_index(atoms, indexfile, 1, &nfit, &ifit, &grpname);
        snew(xref1, nfit);
        for (i = 0; i < nfit; i++)
        {
            copy_rvec(xtop[ifit[i]], xref1[i]);
        }
    }
    else
    {
        nfit = nav;
        ifit = index;
    }

    if (opt2parg_bSet("-constF", NPA, pa))
    {
        /* Constant force flooding is special: Most of the normal flooding
         * options are not needed. */
        edi_params.flood.bConstForce = TRUE;
    }
    else
    {
        /* For normal flooding read eigenvalues and store them in evSteplist[evFLOOD] */

        if (listen[evFLOOD][0] != 0)
        {
            read_eigenvalues(listen[evFLOOD], opt2fn("-eig", NFILE, fnm), evStepList[evFLOOD], bHesse, kB*T);
        }

        edi_params.flood.tau       = tau;
        edi_params.flood.deltaF0   = deltaF0;
        edi_params.flood.deltaF    = deltaF;
        edi_params.presteps        = eqSteps;
        edi_params.flood.kT        = kB*T;
        edi_params.flood.bHarmonic = bHarmonic;
        if (bRestrain)
        {
            /* Trick: invert sign of Efl and alpha2 then this will give the same sign in the exponential and inverted sign outside */
            edi_params.flood.constEfl = -constEfl;
            edi_params.flood.alpha2   = -sqr(alpha);
        }
        else
        {
            edi_params.flood.constEfl = constEfl;
            edi_params.flood.alpha2   = sqr(alpha);
        }
    }

    edi_params.ned = nav;

    /*number of system atoms  */
    edi_params.nini = atoms->nr;


    /*store reference and average structure in edi_params*/
    make_t_edx(&edi_params.sref, nfit, xref1, ifit );
    make_t_edx(&edi_params.sav, nav, xav1, index);


    /* Store target positions in edi_params */
    if (opt2bSet("-tar", NFILE, fnm))
    {
        if (0 != listen[evFLOOD][0])
        {
            fprintf(stderr, "\nNote: Providing a TARGET structure has no effect when using flooding.\n"
                    "      You may want to use -ori to define the flooding potential center.\n\n");
        }
        get_structure(atoms, indexfile, TargetFile, &edi_params.star, nfit, ifit, nav, index);
    }
    else
    {
        make_t_edx(&edi_params.star, 0, NULL, index);
    }

    /* Store origin positions */
    if (opt2bSet("-ori", NFILE, fnm))
    {
        get_structure(atoms, indexfile, OriginFile, &edi_params.sori, nfit, ifit, nav, index);
    }
    else
    {
        make_t_edx(&edi_params.sori, 0, NULL, index);
    }

    /* Write edi-file */
    write_the_whole_thing(gmx_ffopen(EdiFile, "w"), &edi_params, eigvec1, nvec1, listen, evStepList);

    return 0;
}
コード例 #5
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;
}
コード例 #6
0
ファイル: gmx_spol.cpp プロジェクト: carryer123/gromacs
int gmx_spol(int argc, char *argv[])
{
    t_topology  *top;
    t_inputrec  *ir;
    t_atom      *atom;
    t_trxstatus *status;
    int          nrefat, natoms, nf, ntot;
    real         t;
    rvec        *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;
    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*std::sqrt(max_cutoff2(ir->ePBC, box));
    if (rcut == 0)
    {
        rcut = 10*rmax;
    }
    rcut2 = sqr(rcut);
    invbw = 1/bw;
    nbin  = static_cast<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[static_cast<int>(std::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  += std::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, static_cast<real>(ntot)/nf);
    if (ntot > 0)
    {
        sdip  /= ntot;
        sdip2 /= ntot;
        sinp  /= ntot;
        sdinp /= ntot;
        fprintf(stderr, "Average dipole:                               %f (D), std.dev. %f\n",
                sdip, std::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;
}
コード例 #7
0
int gmx_genconf(int argc, char *argv[])
{
    const char     *desc[] = {
        "[THISMODULE] multiplies a given coordinate file by simply stacking them",
        "on top of each other, like a small child playing with wooden blocks.",
        "The program makes a grid of [IT]user-defined[it]",
        "proportions ([TT]-nbox[tt]), ",
        "and interspaces the grid point with an extra space [TT]-dist[tt].[PAR]",
        "When option [TT]-rot[tt] is used the program does not check for overlap",
        "between molecules on grid points. It is recommended to make the box in",
        "the input file at least as big as the coordinates + ",
        "van der Waals radius.[PAR]",
        "If the optional trajectory file is given, conformations are not",
        "generated, but read from this file and translated appropriately to",
        "build the grid."

    };
    const char     *bugs[] = {
        "The program should allow for random displacement of lattice points."
    };

    int             vol;
    t_atoms        *atoms;      /* list with all atoms */
    char            title[STRLEN];
    rvec           *x, *xx, *v; /* coordinates? */
    real            t;
    vec4           *xrot, *vrot;
    int             ePBC;
    matrix          box, boxx; /* box length matrix */
    rvec            shift;
    int             natoms;    /* number of atoms in one molecule  */
    int             nres;      /* number of molecules? */
    int             i, j, k, l, m, ndx, nrdx, nx, ny, nz;
    t_trxstatus    *status;
    gmx_bool        bTRX;
    output_env_t    oenv;
    gmx_rng_t       rng;

    t_filenm        fnm[] = {
        { efSTX, "-f", "conf", ffREAD  },
        { efSTO, "-o", "out",  ffWRITE },
        { efTRX, "-trj", NULL,  ffOPTRD }
    };
#define NFILE asize(fnm)
    static rvec     nrbox    = {1, 1, 1};
    static int      seed     = 0;    /* seed for random number generator */
    static int      nmolat   = 3;
    static int      nblock   = 1;
    static gmx_bool bShuffle = FALSE;
    static gmx_bool bSort    = FALSE;
    static gmx_bool bRandom  = FALSE;           /* False: no random rotations */
    static gmx_bool bRenum   = TRUE;            /* renumber residues */
    static rvec     dist     = {0, 0, 0};       /* space added between molecules ? */
    static rvec     max_rot  = {180, 180, 180}; /* maximum rotation */
    t_pargs         pa[]     = {
        { "-nbox",   FALSE, etRVEC, {nrbox},   "Number of boxes" },
        { "-dist",   FALSE, etRVEC, {dist},    "Distance between boxes" },
        { "-seed",   FALSE, etINT,  {&seed},
          "Random generator seed, if 0 generated from the time" },
        { "-rot",    FALSE, etBOOL, {&bRandom}, "Randomly rotate conformations" },
        { "-shuffle", FALSE, etBOOL, {&bShuffle}, "Random shuffling of molecules" },
        { "-sort",   FALSE, etBOOL, {&bSort},   "Sort molecules on X coord" },
        { "-block",  FALSE, etINT,  {&nblock},
          "Divide the box in blocks on this number of cpus" },
        { "-nmolat", FALSE, etINT,  {&nmolat},
          "Number of atoms per molecule, assumed to start from 0. "
          "If you set this wrong, it will screw up your system!" },
        { "-maxrot", FALSE, etRVEC, {max_rot}, "Maximum random rotation" },
        { "-renumber", FALSE, etBOOL, {&bRenum},  "Renumber residues" }
    };

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

    if (seed == 0)
    {
        rng = gmx_rng_init(gmx_rng_make_seed());
    }
    else
    {
        rng = gmx_rng_init(seed);
    }

    bTRX = ftp2bSet(efTRX, NFILE, fnm);
    nx   = (int)(nrbox[XX]+0.5);
    ny   = (int)(nrbox[YY]+0.5);
    nz   = (int)(nrbox[ZZ]+0.5);

    if ((nx <= 0) || (ny <= 0) || (nz <= 0))
    {
        gmx_fatal(FARGS, "Number of boxes (-nbox) should be larger than zero");
    }
    if ((nmolat <= 0) && bShuffle)
    {
        gmx_fatal(FARGS, "Can not shuffle if the molecules only have %d atoms",
                  nmolat);
    }

    vol = nx*ny*nz; /* calculate volume in grid points (= nr. molecules) */

    get_stx_coordnum(opt2fn("-f", NFILE, fnm), &natoms);
    snew(atoms, 1);
    /* make space for all the atoms */
    init_t_atoms(atoms, natoms*vol, FALSE);
    snew(x, natoms*vol);           /* get space for coordinates of all atoms */
    snew(xrot, natoms);            /* get space for rotation matrix? */
    snew(v, natoms*vol);           /* velocities. not really needed? */
    snew(vrot, natoms);
    /* set atoms->nr to the number in one box *
     * to avoid complaints in read_stx_conf   *
     */
    atoms->nr = natoms;
    read_stx_conf(opt2fn("-f", NFILE, fnm), title, atoms, x, v, &ePBC, box);

    nres = atoms->nres;            /* nr of residues in one element? */

    if (bTRX)
    {
        if (!read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &xx, boxx))
        {
            gmx_fatal(FARGS, "No atoms in trajectory %s", ftp2fn(efTRX, NFILE, fnm));
        }
    }
    else
    {
        snew(xx, natoms);
        for (i = 0; i < natoms; i++)
        {
            copy_rvec(x[i], xx[i]);
        }
    }


    for (k = 0; (k < nz); k++)     /* loop over all gridpositions    */
    {
        shift[ZZ] = k*(dist[ZZ]+box[ZZ][ZZ]);

        for (j = 0; (j < ny); j++)
        {
            shift[YY] = j*(dist[YY]+box[YY][YY])+k*box[ZZ][YY];

            for (i = 0; (i < nx); i++)
            {
                shift[XX] = i*(dist[XX]+box[XX][XX])+j*box[YY][XX]+k*box[ZZ][XX];

                ndx  = (i*ny*nz+j*nz+k)*natoms;
                nrdx = (i*ny*nz+j*nz+k)*nres;

                /* Random rotation on input coords */
                if (bRandom)
                {
                    rand_rot(natoms, xx, v, xrot, vrot, rng, max_rot);
                }

                for (l = 0; (l < natoms); l++)
                {
                    for (m = 0; (m < DIM); m++)
                    {
                        if (bRandom)
                        {
                            x[ndx+l][m] = xrot[l][m];
                            v[ndx+l][m] = vrot[l][m];
                        }
                        else
                        {
                            x[ndx+l][m] = xx[l][m];
                            v[ndx+l][m] = v[l][m];
                        }
                    }
                    if (ePBC == epbcSCREW && i % 2 == 1)
                    {
                        /* Rotate around x axis */
                        for (m = YY; m <= ZZ; m++)
                        {
                            x[ndx+l][m] = box[YY][m] + box[ZZ][m] - x[ndx+l][m];
                            v[ndx+l][m] = -v[ndx+l][m];
                        }
                    }
                    for (m = 0; (m < DIM); m++)
                    {
                        x[ndx+l][m] += shift[m];
                    }
                    atoms->atom[ndx+l].resind = nrdx + atoms->atom[l].resind;
                    atoms->atomname[ndx+l]    = atoms->atomname[l];
                }

                for (l = 0; (l < nres); l++)
                {
                    atoms->resinfo[nrdx+l] = atoms->resinfo[l];
                    if (bRenum)
                    {
                        atoms->resinfo[nrdx+l].nr += nrdx;
                    }
                }
                if (bTRX)
                {
                    if (!read_next_x(oenv, status, &t, xx, boxx) &&
                        ((i+1)*(j+1)*(k+1) < vol))
                    {
                        gmx_fatal(FARGS, "Not enough frames in trajectory");
                    }
                }
            }
        }
    }
    if (bTRX)
    {
        close_trj(status);
    }

    /* make box bigger */
    for (m = 0; (m < DIM); m++)
    {
        box[m][m] += dist[m];
    }
    svmul(nx, box[XX], box[XX]);
    svmul(ny, box[YY], box[YY]);
    svmul(nz, box[ZZ], box[ZZ]);
    if (ePBC == epbcSCREW && nx % 2 == 0)
    {
        /* With an even number of boxes in x we can forgot about the screw */
        ePBC = epbcXYZ;
    }

    /* move_x(natoms*vol,x,box); */          /* put atoms in box? */

    atoms->nr   *= vol;
    atoms->nres *= vol;

    /*depending on how you look at it, this is either a nasty hack or the way it should work*/
    if (bRenum)
    {
        for (i = 0; i < atoms->nres; i++)
        {
            atoms->resinfo[i].nr = i+1;
        }
    }


    if (bShuffle)
    {
        randwater(0, atoms->nr/nmolat, nmolat, x, v, rng);
    }
    else if (bSort)
    {
        sortwater(0, atoms->nr/nmolat, nmolat, x, v);
    }
    else if (opt2parg_bSet("-block", asize(pa), pa))
    {
        mkcompact(0, atoms->nr/nmolat, nmolat, x, v, nblock, box);
    }
    gmx_rng_destroy(rng);

    write_sto_conf(opt2fn("-o", NFILE, fnm), title, atoms, x, v, ePBC, box);

    return 0;
}
コード例 #8
0
int gmx_genbox(int argc,char *argv[])
{
  const char *desc[] = {
    "[TT]genbox[tt] can do one of 3 things:[PAR]",
    
    "1) Generate a box of solvent. Specify [TT]-cs[tt] and [TT]-box[tt]. Or specify [TT]-cs[tt] and",
    "[TT]-cp[tt] with a structure file with a box, but without atoms.[PAR]",
    
    "2) Solvate a solute configuration, e.g. a protein, in a bath of solvent ",
    "molecules. Specify [TT]-cp[tt] (solute) and [TT]-cs[tt] (solvent). ",
    "The box specified in the solute coordinate file ([TT]-cp[tt]) is used,",
    "unless [TT]-box[tt] is set.",
    "If you want the solute to be centered in the box,",
    "the program [TT]editconf[tt] has sophisticated options",
    "to change the box dimensions and center the solute.",
    "Solvent molecules are removed from the box where the ",
    "distance between any atom of the solute molecule(s) and any atom of ",
    "the solvent molecule is less than the sum of 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 atoms not in the database are ",
    "assigned a default distance [TT]-vdwd[tt].",
    "Note that this option will also influence the distances between",
    "solvent molecules if they contain atoms that are not in the database.",
    "[PAR]",
    
    "3) Insert a number ([TT]-nmol[tt]) of extra molecules ([TT]-ci[tt]) ",
    "at random positions.",
    "The program iterates until [TT]nmol[tt] molecules",
    "have been inserted in the box. To test whether an insertion is ",
    "successful the same van der Waals criterium is used as for removal of ",
    "solvent molecules. When no appropriately-sized ",
    "holes (holes that can hold an extra molecule) are available, the ",
    "program tries for [TT]-nmol[tt] * [TT]-try[tt] times before giving up. ",
    "Increase [TT]-try[tt] if you have several small holes to fill.[PAR]",

    "If you need to do more than one of the above operations, it can be",
    "best to call [TT]genbox[tt] separately for each operation, so that",
    "you are sure of the order in which the operations occur.[PAR]",

    "The default solvent is Simple Point Charge water (SPC), with coordinates ",
    "from [TT]$GMXLIB/spc216.gro[tt]. These coordinates can also be used",
    "for other 3-site water models, since a short equibilibration will remove",
    "the small differences between the models.",
    "Other solvents are also supported, as well as mixed solvents. The",
    "only restriction to solvent types is that a solvent molecule consists",
    "of exactly one residue. The residue information in the coordinate",
    "files is used, and should therefore be more or less consistent.",
    "In practice this means that two subsequent solvent molecules in the ",
    "solvent coordinate file should have different residue number.",
    "The box of solute is built by stacking the coordinates read from",
    "the coordinate file. This means that these coordinates should be ",
    "equlibrated in periodic boundary conditions to ensure a good",
    "alignment of molecules on the stacking interfaces.",
    "The [TT]-maxsol[tt] option simply adds only the first [TT]-maxsol[tt]",
    "solvent molecules and leaves out the rest would have fit into the box.",
    "[PAR]",
    
    "The program can optionally rotate the solute molecule to align the",
    "longest molecule axis along a box edge. This way the amount of solvent",
    "molecules necessary is reduced.",
    "It should be kept in mind that this only works for",
    "short simulations, as e.g. an alpha-helical peptide in solution can ",
    "rotate over 90 degrees, within 500 ps. In general it is therefore ",
    "better to make a more or less cubic box.[PAR]",
    
    "Setting [TT]-shell[tt] larger than zero will place a layer of water of",
    "the specified thickness (nm) around the solute. Hint: it is a good",
    "idea to put the protein in the center of a box first (using [TT]editconf[tt]).",
    "[PAR]",
    
    "Finally, [TT]genbox[tt] will optionally remove lines from your topology file in ",
    "which a number of solvent molecules is already added, and adds a ",
    "line with the total number of solvent molecules in your coordinate file."
  };

  const char *bugs[] = {
    "Molecules must be whole in the initial configurations.",
  };
  
  /* parameter data */
  gmx_bool bSol,bProt,bBox;
  const char *conf_prot,*confout;
  int  bInsert;
  real *r;
  char *title_ins;
  gmx_atomprop_t aps;
  
  /* protein configuration data */
  char    *title=NULL;
  t_atoms atoms;
  rvec    *x,*v=NULL;
  int     ePBC=-1;
  matrix  box;
  t_pbc   pbc;
    
  /* other data types */
  int  atoms_added,residues_added;
  
  t_filenm fnm[] = {
    { efSTX, "-cp", "protein", ffOPTRD },
    { efSTX, "-cs", "spc216",  ffLIBOPTRD},
    { efSTX, "-ci", "insert",  ffOPTRD},
    { efSTO, NULL,  NULL,      ffWRITE},
    { efTOP, NULL,  NULL,      ffOPTRW},
  };
#define NFILE asize(fnm)
  
  static int nmol_ins=0,nmol_try=10,seed=1997;
  static real r_distance=0.105,r_shell=0;
  static rvec new_box={0.0,0.0,0.0};
  static gmx_bool bReadV=FALSE;
  static int  max_sol = 0;
  output_env_t oenv;
  t_pargs pa[] = {
    { "-box",    FALSE, etRVEC, {new_box},   
      "box size" },
    { "-nmol",   FALSE, etINT , {&nmol_ins},  
      "no 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"},
    { "-vdwd",   FALSE, etREAL, {&r_distance},
      "default vdwaals distance"},
    { "-shell",  FALSE, etREAL, {&r_shell},
      "thickness of optional water layer around solute" },
    { "-maxsol", FALSE, etINT,  {&max_sol},
      "maximum number of solvent molecules to add if they fit in the box. If zero (default) this is ignored" },
    { "-vel",    FALSE, etBOOL, {&bReadV},
      "keep velocities from input solute and solvent" }
  };

  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv, PCA_BE_NICE,NFILE,fnm,asize(pa),pa,
		    asize(desc),desc,asize(bugs),bugs,&oenv);
  
  bInsert   = opt2bSet("-ci",NFILE,fnm) && (nmol_ins > 0);
  bSol      = opt2bSet("-cs",NFILE,fnm);
  bProt     = opt2bSet("-cp",NFILE,fnm);
  bBox      = opt2parg_bSet("-box",asize(pa),pa);
     
  /* check input */
  if (bInsert && nmol_ins<=0)
    gmx_fatal(FARGS,"When specifying inserted molecules (-ci), "
		"-nmol must be larger than 0");
  if (!bProt && !bBox)
    gmx_fatal(FARGS,"When no solute (-cp) is specified, "
		"a box size (-box) must be specified");

  aps = gmx_atomprop_init();
  
  if (bProt) {
    /*generate a solute configuration */
    conf_prot = opt2fn("-cp",NFILE,fnm);
    title = read_prot(conf_prot,&atoms,&x,bReadV?&v:NULL,&r,&ePBC,box,
		      aps,r_distance);
    if (bReadV && !v)
      fprintf(stderr,"Note: no velocities found\n");
    if (atoms.nr == 0) {
      fprintf(stderr,"Note: no atoms in %s\n",conf_prot);
      bProt = FALSE;
    }
  } 
  if (!bProt) {
    atoms.nr=0;
    atoms.nres=0;
    atoms.resinfo=NULL;
    atoms.atomname=NULL;
    atoms.atom=NULL;
    atoms.pdbinfo=NULL;
    x=NULL;
    r=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 editconf "
		"or give explicit -box command line option");
  
  /* add nmol_ins molecules of atoms_ins 
     in random orientation at random place */
  if (bInsert) 
    title_ins = insert_mols(opt2fn("-ci",NFILE,fnm),nmol_ins,nmol_try,seed,
			    &atoms,&x,&r,ePBC,box,aps,r_distance,r_shell,
                            oenv);
  else
    title_ins = strdup("Generated by genbox");
  
  /* add solvent */
  if (bSol)
    add_solv(opt2fn("-cs",NFILE,fnm),&atoms,&x,v?&v:NULL,&r,ePBC,box,
	     aps,r_distance,&atoms_added,&residues_added,r_shell,max_sol,
             oenv);
	     
  /* write new configuration 1 to file confout */
  confout = ftp2fn(efSTO,NFILE,fnm);
  fprintf(stderr,"Writing generated configuration to %s\n",confout);
  if (bProt) {
    write_sto_conf(confout,title,&atoms,x,v,ePBC,box);
    /* print box sizes and box type to stderr */
    fprintf(stderr,"%s\n",title);  
  } else 
    write_sto_conf(confout,title_ins,&atoms,x,v,ePBC,box);
  
  /* print size of generated configuration */
  fprintf(stderr,"\nOutput configuration contains %d atoms in %d residues\n",
	  atoms.nr,atoms.nres);
  update_top(&atoms,box,NFILE,fnm,aps);
	  
  gmx_atomprop_destroy(aps);
  
  thanx(stderr);
  
  return 0;
}
コード例 #9
0
int gmx_analyze(int argc,char *argv[])
{
  static char *desc[] = {
    "g_analyze reads an ascii file and analyzes data sets.",
    "A line in the input file may start with a time",
    "(see option [TT]-time[tt]) and any number of y values may follow.",
    "Multiple sets can also be",
    "read when they are seperated by & (option [TT]-n[tt]),",
    "in this case only one y value is read from each line.",
    "All lines starting with # and @ are skipped.",
    "All analyses can also be done for the derivative of a set",
    "(option [TT]-d[tt]).[PAR]",

    "All options, except for [TT]-av[tt] and [TT]-power[tt] assume that the",
    "points are equidistant in time.[PAR]",

    "g_analyze always shows the average and standard deviation of each",
    "set. For each set it also shows the relative deviation of the third",
    "and forth cumulant from those of a Gaussian distribution with the same",
    "standard deviation.[PAR]",

    "Option [TT]-ac[tt] produces the autocorrelation function(s).[PAR]",
    
    "Option [TT]-cc[tt] plots the resemblance of set i with a cosine of",
    "i/2 periods. The formula is:[BR]"
    "2 (int0-T y(t) cos(i pi t) dt)^2 / int0-T y(t) y(t) dt[BR]",
    "This is useful for principal components obtained from covariance",
    "analysis, since the principal components of random diffusion are",
    "pure cosines.[PAR]",
    
    "Option [TT]-msd[tt] produces the mean square displacement(s).[PAR]",
    
    "Option [TT]-dist[tt] produces distribution plot(s).[PAR]",
    
    "Option [TT]-av[tt] produces the average over the sets.",
    "Error bars can be added with the option [TT]-errbar[tt].",
    "The errorbars can represent the standard deviation, the error",
    "(assuming the points are independent) or the interval containing",
    "90% of the points, by discarding 5% of the points at the top and",
    "the bottom.[PAR]",
    
    "Option [TT]-ee[tt] produces error estimates using block averaging.",
    "A set is divided in a number of blocks and averages are calculated for",
    "each block. The error for the total average is calculated from",
    "the variance between averages of the m blocks B_i as follows:",
    "error^2 = Sum (B_i - <B>)^2 / (m*(m-1)).",
    "These errors are plotted as a function of the block size.",
    "Also an analytical block average curve is plotted, assuming",
    "that the autocorrelation is a sum of two exponentials.",
    "The analytical curve for the block average is:[BR]",
    "f(t) = sigma sqrt(2/T (  a   (tau1 ((exp(-t/tau1) - 1) tau1/t + 1)) +[BR]",
    "                       (1-a) (tau2 ((exp(-t/tau2) - 1) tau2/t + 1)))),[BR]"
    "where T is the total time.",
    "a, tau1 and tau2 are obtained by fitting f^2(t) to error^2.",
    "When the actual block average is very close to the analytical curve,",
    "the error is sigma*sqrt(2/T (a tau1 + (1-a) tau2)).",
    "The complete derivation is given in",
    "B. Hess, J. Chem. Phys. 116:209-217, 2002.[PAR]",

    "Option [TT]-filter[tt] prints the RMS high-frequency fluctuation",
    "of each set and over all sets with respect to a filtered average.",
    "The filter is proportional to cos(pi t/len) where t goes from -len/2",
    "to len/2. len is supplied with the option [TT]-filter[tt].",
    "This filter reduces oscillations with period len/2 and len by a factor",
    "of 0.79 and 0.33 respectively.[PAR]",

    "Option [TT]-g[tt] fits the data to the function given with option",
    "[TT]-fitfn[tt].[PAR]",
    
    "Option [TT]-power[tt] fits the data to b t^a, which is accomplished",
    "by fitting to a t + b on log-log scale. All points after the first",
    "zero or negative value are ignored.[PAR]"
    
    "Option [TT]-luzar[tt] performs a Luzar & Chandler kinetics analysis",
    "on output from [TT]g_hbond[tt]. The input file can be taken directly",
    "from [TT]g_hbond -ac[tt], and then the same result should be produced."
  };
  static real tb=-1,te=-1,frac=0.5,filtlen=0,binwidth=0.1,aver_start=0;
  static bool bHaveT=TRUE,bDer=FALSE,bSubAv=TRUE,bAverCorr=FALSE,bXYdy=FALSE;
  static bool bEESEF=FALSE,bEENLC=FALSE,bEeFitAc=FALSE,bPower=FALSE;
  static bool bIntegrate=FALSE,bRegression=FALSE,bLuzar=FALSE,bLuzarError=FALSE; 
  static int  nsets_in=1,d=1,nb_min=4,resol=10;
  static real temp=298.15,fit_start=1,smooth_tail_start=-1;
  
  /* must correspond to enum avbar* declared at beginning of file */
  static char *avbar_opt[avbarNR+1] = { 
    NULL, "none", "stddev", "error", "90", NULL
  };

  t_pargs pa[] = {
    { "-time",    FALSE, etBOOL, {&bHaveT},
      "Expect a time in the input" },
    { "-b",       FALSE, etREAL, {&tb},
      "First time to read from set" },
    { "-e",       FALSE, etREAL, {&te},
      "Last time to read from set" },
    { "-n",       FALSE, etINT, {&nsets_in},
      "Read # sets seperated by &" },
    { "-d",       FALSE, etBOOL, {&bDer},
	"Use the derivative" },
    { "-dp",      FALSE, etINT, {&d}, 
      "HIDDENThe derivative is the difference over # points" },
    { "-bw",      FALSE, etREAL, {&binwidth},
      "Binwidth for the distribution" },
    { "-errbar",  FALSE, etENUM, {avbar_opt},
      "Error bars for -av" },
    { "-integrate",FALSE,etBOOL, {&bIntegrate},
      "Integrate data function(s) numerically using trapezium rule" },
    { "-aver_start",FALSE, etREAL, {&aver_start},
      "Start averaging the integral from here" },
    { "-xydy",    FALSE, etBOOL, {&bXYdy},
      "Interpret second data set as error in the y values for integrating" },
    { "-regression",FALSE,etBOOL,{&bRegression},
      "Perform a linear regression analysis on the data" },
    { "-luzar",   FALSE, etBOOL, {&bLuzar},
      "Do a Luzar and Chandler analysis on a correlation function and related as produced by g_hbond. When in addition the -xydy flag is given the second and fourth column will be interpreted as errors in c(t) and n(t)." },
    { "-temp",    FALSE, etREAL, {&temp},
      "Temperature for the Luzar hydrogen bonding kinetics analysis" },
    { "-fitstart", FALSE, etREAL, {&fit_start},
      "Time (ps) from which to start fitting the correlation functions in order to obtain the forward and backward rate constants for HB breaking and formation" }, 
    { "-smooth",FALSE, etREAL, {&smooth_tail_start},
      "If >= 0, the tail of the ACF will be smoothed by fitting it to an exponential function: y = A exp(-x/tau)" },
    { "-nbmin",   FALSE, etINT, {&nb_min},
      "HIDDENMinimum number of blocks for block averaging" },
    { "-resol", FALSE, etINT, {&resol},
      "HIDDENResolution for the block averaging, block size increases with"
    " a factor 2^(1/#)" },
    { "-eeexpfit", FALSE, etBOOL, {&bEESEF},
      "HIDDENAlways use a single exponential fit for the error estimate" },
    { "-eenlc", FALSE, etBOOL, {&bEENLC},
      "HIDDENAllow a negative long-time correlation" },
    { "-eefitac", FALSE, etBOOL, {&bEeFitAc},
      "HIDDENAlso plot analytical block average using a autocorrelation fit" },
    { "-filter",  FALSE, etREAL, {&filtlen},
      "Print the high-frequency fluctuation after filtering with a cosine filter of length #" },
    { "-power", FALSE, etBOOL, {&bPower},
      "Fit data to: b t^a" },
    { "-subav", FALSE, etBOOL, {&bSubAv},
      "Subtract the average before autocorrelating" },
    { "-oneacf", FALSE, etBOOL, {&bAverCorr},
      "Calculate one ACF over all sets" }
  };
#define NPA asize(pa)

  FILE     *out,*out_fit;
  int      n,nlast,s,nset,i,j=0;
  real     **val,*t,dt,tot,error;
  double   *av,*sig,cum1,cum2,cum3,cum4,db;
  char     *acfile,*msdfile,*ccfile,*distfile,*avfile,*eefile,*fitfile;
  
  t_filenm fnm[] = { 
    { efXVG, "-f",    "graph",    ffREAD   },
    { efXVG, "-ac",   "autocorr", ffOPTWR  },
    { efXVG, "-msd",  "msd",      ffOPTWR  },
    { efXVG, "-cc",   "coscont",  ffOPTWR  },
    { efXVG, "-dist", "distr",    ffOPTWR  },
    { efXVG, "-av",   "average",  ffOPTWR  },
    { efXVG, "-ee",   "errest",   ffOPTWR  },
    { efLOG, "-g",    "fitlog",   ffOPTWR  }
  }; 
#define NFILE asize(fnm) 

  int     npargs;
  t_pargs *ppa;

  npargs = asize(pa); 
  ppa    = add_acf_pargs(&npargs,pa);
  
  CopyRight(stderr,argv[0]); 
  parse_common_args(&argc,argv,PCA_CAN_VIEW,
		    NFILE,fnm,npargs,ppa,asize(desc),desc,0,NULL); 

  acfile   = opt2fn_null("-ac",NFILE,fnm);
  msdfile  = opt2fn_null("-msd",NFILE,fnm);
  ccfile   = opt2fn_null("-cc",NFILE,fnm);
  distfile = opt2fn_null("-dist",NFILE,fnm);
  avfile   = opt2fn_null("-av",NFILE,fnm);
  eefile   = opt2fn_null("-ee",NFILE,fnm);
  if (opt2parg_bSet("-fitfn",npargs,ppa)) 
    fitfile  = opt2fn("-g",NFILE,fnm);
  else
    fitfile  = opt2fn_null("-g",NFILE,fnm);
    
  val=read_xvg_time(opt2fn("-f",NFILE,fnm),bHaveT,
		    opt2parg_bSet("-b",npargs,ppa),tb,
		    opt2parg_bSet("-e",npargs,ppa),te,
		    nsets_in,&nset,&n,&dt,&t);
  printf("Read %d sets of %d points, dt = %g\n\n",nset,n,dt);
  
  if (bDer) {
    printf("Calculating the derivative as (f[i+%d]-f[i])/(%d*dt)\n\n",
	    d,d);
    n -= d;
    for(s=0; s<nset; s++)
      for(i=0; (i<n); i++)
	val[s][i] = (val[s][i+d]-val[s][i])/(d*dt);
  }
  if (bIntegrate) {
    real sum,stddev;
    printf("Calculating the integral using the trapezium rule\n");
    
    if (bXYdy) {
      sum = evaluate_integral(n,t,val[0],val[1],aver_start,&stddev);
      printf("Integral %10.3f +/- %10.5f\n",sum,stddev);
    }
    else {
      for(s=0; s<nset; s++) {
	sum = evaluate_integral(n,t,val[s],NULL,aver_start,&stddev);
	printf("Integral %d  %10.5f  +/- %10.5f\n",s+1,sum,stddev);
      }
    }
  }
  if (fitfile) {
    out_fit = ffopen(fitfile,"w");
    if (bXYdy && nset>=2) {
      do_fit(out_fit,0,TRUE,n,t,val,npargs,ppa);
    } else {
      for(s=0; s<nset; s++)
	do_fit(out_fit,s,FALSE,n,t,val,npargs,ppa);
    }
    fclose(out_fit);
  }

  printf("                                      std. dev.    relative deviation of\n");
  printf("                       standard       ---------   cumulants from those of\n");
  printf("set      average       deviation      sqrt(n-1)   a Gaussian distribition\n");
  printf("                                                      cum. 3   cum. 4\n");
  snew(av,nset);
  snew(sig,nset);
  for(s=0; (s<nset); s++) {
    cum1 = 0;
    cum2 = 0;
    cum3 = 0;
    cum4 = 0;
    for(i=0; (i<n); i++)
      cum1 += val[s][i];
    cum1 /= n;
    for(i=0; (i<n); i++) {
      db = val[s][i]-cum1;
      cum2 += db*db;
      cum3 += db*db*db;
      cum4 += db*db*db*db;
    }
    cum2  /= n;
    cum3  /= n;
    cum4  /= n;
    av[s]  = cum1;
    sig[s] = sqrt(cum2);
    if (n > 1)
      error = sqrt(cum2/(n-1));
    else
      error = 0;
    printf("SS%d  %13.6e   %12.6e   %12.6e      %6.3f   %6.3f\n",
	   s+1,av[s],sig[s],error,
	   sig[s] ? cum3/(sig[s]*sig[s]*sig[s]*sqrt(8/M_PI)) : 0,
	   sig[s] ? cum4/(sig[s]*sig[s]*sig[s]*sig[s]*3)-1 : 0); 
  }
  printf("\n");

  if (filtlen)
    filter(filtlen,n,nset,val,dt);
  
  if (msdfile) {
    out=xvgropen(msdfile,"Mean square displacement",
		 "time","MSD (nm\\S2\\N)");
    nlast = (int)(n*frac);
    for(s=0; s<nset; s++) {
      for(j=0; j<=nlast; j++) {
	if (j % 100 == 0)
	  fprintf(stderr,"\r%d",j);
	tot=0;
	for(i=0; i<n-j; i++)
	  tot += sqr(val[s][i]-val[s][i+j]); 
	tot /= (real)(n-j);
	fprintf(out," %g %8g\n",dt*j,tot);
      }
      if (s<nset-1)
	fprintf(out,"&\n");
    }
    fclose(out);
    fprintf(stderr,"\r%d, time=%g\n",j-1,(j-1)*dt);
  }
  if (ccfile)
    plot_coscont(ccfile,n,nset,val);
  
  if (distfile)
    histogram(distfile,binwidth,n,nset,val);
  if (avfile)
    average(avfile,nenum(avbar_opt),n,nset,val,t);
  if (eefile)
    estimate_error(eefile,nb_min,resol,n,nset,av,sig,val,dt,
		   bEeFitAc,bEESEF,bEENLC);
  if (bPower)
    power_fit(n,nset,val,t);
  if (acfile) {
    if (bSubAv) 
      for(s=0; s<nset; s++)
	for(i=0; i<n; i++)
	  val[s][i] -= av[s];
    do_autocorr(acfile,"Autocorrelation",n,nset,val,dt,
		eacNormal,bAverCorr);
  }
  if (bRegression)
    regression_analysis(n,bXYdy,t,val);

  if (bLuzar) 
    luzar_correl(n,t,nset,val,temp,bXYdy,fit_start,smooth_tail_start);
    
  view_all(NFILE, fnm);
  
  thanx(stderr);

  return 0;
}
コード例 #10
0
int gmx_dos(int argc,char *argv[])
{
    const char *desc[] = {
        "[TT]g_dos[tt] computes the Density of States from a simulations.",
        "In order for this to be meaningful the velocities must be saved",
        "in the trajecotry with sufficiently high frequency such as to cover",
        "all vibrations. For flexible systems that would be around a few fs",
        "between saving. Properties based on the DoS are printed on the",
        "standard output."
    };
    const char *bugs[] = {
        "This program needs a lot of memory: total usage equals the number of atoms times 3 times number of frames times 4 (or 8 when run in double precision)."
    };
    FILE       *fp,*fplog;
    t_topology top;
    int        ePBC=-1;
    t_trxframe fr;
    matrix     box;
    int        gnx;
    char       title[256];
    real       t0,t1,m;
    t_trxstatus *status;
    int        nV,nframes,n_alloc,i,j,k,l,fftcode,Nmol,Natom;
    double     rho,dt,V2sum,Vsum,V,tmass,dostot,dos2,dosabs;
    real       **c1,**dos,mi,beta,bfac,*nu,*tt,stddev,c1j;
    output_env_t oenv;
    gmx_fft_t  fft;
    double     cP,S,A,E,DiffCoeff,Delta,f,y,z,sigHS,Shs,Sig,DoS0,recip_fac;
    double     wCdiff,wSdiff,wAdiff,wEdiff;

    static     gmx_bool bVerbose=TRUE,bAbsolute=FALSE,bNormalize=FALSE;
    static     gmx_bool bRecip=FALSE,bDump=FALSE;
    static     real Temp=298.15,toler=1e-6;
    t_pargs pa[] = {
        {   "-v", FALSE, etBOOL, {&bVerbose},
            "Be loud and noisy."
        },
        {   "-recip", FALSE, etBOOL, {&bRecip},
            "Use cm^-1 on X-axis instead of 1/ps for DoS plots."
        },
        {   "-abs", FALSE, etBOOL, {&bAbsolute},
            "Use the absolute value of the Fourier transform of the VACF as the Density of States. Default is to use the real component only"
        },
        {   "-normdos", FALSE, etBOOL, {&bNormalize},
            "Normalize the DoS such that it adds up to 3N. This is a hack that should not be necessary."
        },
        {   "-T", FALSE, etREAL, {&Temp},
            "Temperature in the simulation"
        },
        {   "-toler", FALSE, etREAL, {&toler},
            "[HIDDEN]Tolerance when computing the fluidicity using bisection algorithm"
        },
        {   "-dump", FALSE, etBOOL, {&bDump},
            "[HIDDEN]Dump the y/fy plot corresponding to Fig. 2 inLin2003a and the and the weighting functions corresponding to Fig. 1 in Berens1983a."
        }
    };

    t_filenm  fnm[] = {
        { efTRN, "-f",    NULL,    ffREAD  },
        { efTPX, "-s",    NULL,    ffREAD  },
        { efNDX, NULL,    NULL,    ffOPTRD },
        { efXVG, "-vacf", "vacf",  ffWRITE },
        { efXVG, "-mvacf","mvacf", ffWRITE },
        { efXVG, "-dos",  "dos",   ffWRITE },
        { efLOG, "-g",    "dos",   ffWRITE },
    };
#define NFILE asize(fnm)
    int     npargs;
    t_pargs *ppa;
    const char *DoSlegend[] = {
        "DoS(v)", "DoS(v)[Solid]", "DoS(v)[Diff]"
    };

    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,
                      asize(bugs),bugs,&oenv);

    beta = 1/(Temp*BOLTZ);
    if (bDump)
    {
        printf("Dumping reference figures. Thanks for your patience.\n");
        dump_fy(oenv,toler);
        dump_w(oenv,beta);
        exit(0);
    }

    fplog = gmx_fio_fopen(ftp2fn(efLOG,NFILE,fnm),"w");
    fprintf(fplog,"Doing density of states analysis based on trajectory.\n");
    please_cite(fplog,"Pascal2011a");
    please_cite(fplog,"Caleman2011b");

    read_tps_conf(ftp2fn(efTPX,NFILE,fnm),title,&top,&ePBC,NULL,NULL,box,
                  TRUE);
    V = det(box);
    tmass = 0;
    for(i=0; (i<top.atoms.nr); i++)
        tmass += top.atoms.atom[i].m;

    Natom = top.atoms.nr;
    Nmol = top.mols.nr;
    gnx = Natom*DIM;

    /* 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;
    nframes=0;
    Vsum = V2sum = 0;
    nV = 0;
    do {
        if (fr.bBox)
        {
            V = det(fr.box);
            V2sum += V*V;
            Vsum += V;
            nV++;
        }
        if (nframes >= n_alloc)
        {
            n_alloc+=100;
            for(i=0; i<gnx; i++)
                srenew(c1[i],n_alloc);
        }
        for(i=0; i<gnx; i+=DIM)
        {
            c1[i+XX][nframes] = fr.v[i/DIM][XX];
            c1[i+YY][nframes] = fr.v[i/DIM][YY];
            c1[i+ZZ][nframes] = fr.v[i/DIM][ZZ];
        }

        t1=fr.time;

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

    close_trj(status);

    dt = (t1-t0)/(nframes-1);
    if (nV > 0)
    {
        V = Vsum/nV;
    }
    if (bVerbose)
        printf("Going to do %d fourier transforms of length %d. Hang on.\n",
               gnx,nframes);
    low_do_autocorr(NULL,oenv,NULL,nframes,gnx,nframes,c1,dt,eacNormal,0,FALSE,
                    FALSE,FALSE,-1,-1,0,0);
    snew(dos,DOS_NR);
    for(j=0; (j<DOS_NR); j++)
        snew(dos[j],nframes+4);

    if (bVerbose)
        printf("Going to merge the ACFs into the mass-weighted and plain ACF\n");
    for(i=0; (i<gnx); i+=DIM)
    {
        mi = top.atoms.atom[i/DIM].m;
        for(j=0; (j<nframes/2); j++)
        {
            c1j = (c1[i+XX][j] + c1[i+YY][j] + c1[i+ZZ][j]);
            dos[VACF][j]  += c1j/Natom;
            dos[MVACF][j] += mi*c1j;
        }
    }
    fp = xvgropen(opt2fn("-vacf",NFILE,fnm),"Velocity ACF",
                  "Time (ps)","C(t)",oenv);
    snew(tt,nframes/2);
    for(j=0; (j<nframes/2); j++)
    {
        tt[j] = j*dt;
        fprintf(fp,"%10g  %10g\n",tt[j],dos[VACF][j]);
    }
    xvgrclose(fp);
    fp = xvgropen(opt2fn("-mvacf",NFILE,fnm),"Mass-weighted velocity ACF",
                  "Time (ps)","C(t)",oenv);
    for(j=0; (j<nframes/2); j++)
    {
        fprintf(fp,"%10g  %10g\n",tt[j],dos[MVACF][j]);
    }
    xvgrclose(fp);

    if ((fftcode = gmx_fft_init_1d_real(&fft,nframes/2,
                                        GMX_FFT_FLAG_NONE)) != 0)
    {
        gmx_fatal(FARGS,"gmx_fft_init_1d_real returned %d",fftcode);
    }
    if ((fftcode = gmx_fft_1d_real(fft,GMX_FFT_REAL_TO_COMPLEX,
                                   (void *)dos[MVACF],(void *)dos[DOS])) != 0)
    {
        gmx_fatal(FARGS,"gmx_fft_1d_real returned %d",fftcode);
    }

    /* First compute the DoS */
    /* Magic factor of 8 included now. */
    bfac = 8*dt*beta/2;
    dos2 = 0;
    snew(nu,nframes/4);
    for(j=0; (j<nframes/4); j++)
    {
        nu[j] = 2*j/(t1-t0);
        dos2 += sqr(dos[DOS][2*j]) + sqr(dos[DOS][2*j+1]);
        if (bAbsolute)
            dos[DOS][j] = bfac*sqrt(sqr(dos[DOS][2*j]) + sqr(dos[DOS][2*j+1]));
        else
            dos[DOS][j] = bfac*dos[DOS][2*j];
    }
    /* Normalize it */
    dostot = evaluate_integral(nframes/4,nu,dos[DOS],NULL,nframes/4,&stddev);
    if (bNormalize)
    {
        for(j=0; (j<nframes/4); j++)
            dos[DOS][j] *= 3*Natom/dostot;
    }

    /* Now analyze it */
    DoS0 = dos[DOS][0];

    /* Note this eqn. is incorrect in Pascal2011a! */
    Delta = ((2*DoS0/(9*Natom))*sqrt(M_PI*BOLTZ*Temp*Natom/tmass)*
             pow((Natom/V),1.0/3.0)*pow(6/M_PI,2.0/3.0));
    f = calc_fluidicity(Delta,toler);
    y = calc_y(f,Delta,toler);
    z = calc_compress(y);
    Sig = BOLTZ*(5.0/2.0+log(2*M_PI*BOLTZ*Temp/(sqr(PLANCK))*V/(f*Natom)));
    Shs = Sig+calc_Shs(f,y);
    rho = (tmass*AMU)/(V*NANO*NANO*NANO);
    sigHS = pow(6*y*V/(M_PI*Natom),1.0/3.0);

    fprintf(fplog,"System = \"%s\"\n",title);
    fprintf(fplog,"Nmol = %d\n",Nmol);
    fprintf(fplog,"Natom = %d\n",Natom);
    fprintf(fplog,"dt = %g ps\n",dt);
    fprintf(fplog,"tmass = %g amu\n",tmass);
    fprintf(fplog,"V = %g nm^3\n",V);
    fprintf(fplog,"rho = %g g/l\n",rho);
    fprintf(fplog,"T = %g K\n",Temp);
    fprintf(fplog,"beta = %g mol/kJ\n",beta);

    fprintf(fplog,"\nDoS parameters\n");
    fprintf(fplog,"Delta = %g\n",Delta);
    fprintf(fplog,"fluidicity = %g\n",f);
    fprintf(fplog,"hard sphere packing fraction = %g\n",y);
    fprintf(fplog,"hard sphere compressibility = %g\n",z);
    fprintf(fplog,"ideal gas entropy = %g\n",Sig);
    fprintf(fplog,"hard sphere entropy = %g\n",Shs);
    fprintf(fplog,"sigma_HS = %g nm\n",sigHS);
    fprintf(fplog,"DoS0 = %g\n",DoS0);
    fprintf(fplog,"Dos2 = %g\n",dos2);
    fprintf(fplog,"DoSTot = %g\n",dostot);

    /* Now compute solid (2) and diffusive (3) components */
    fp = xvgropen(opt2fn("-dos",NFILE,fnm),"Density of states",
                  bRecip ? "E (cm\\S-1\\N)" : "\\f{12}n\\f{4} (1/ps)",
                  "\\f{4}S(\\f{12}n\\f{4})",oenv);
    xvgr_legend(fp,asize(DoSlegend),DoSlegend,oenv);
    recip_fac = bRecip ? (1e7/SPEED_OF_LIGHT) : 1.0;
    for(j=0; (j<nframes/4); j++)
    {
        dos[DOS_DIFF][j] = DoS0/(1+sqr(DoS0*M_PI*nu[j]/(6*f*Natom)));
        dos[DOS_SOLID][j] = dos[DOS][j]-dos[DOS_DIFF][j];
        fprintf(fp,"%10g  %10g  %10g  %10g\n",
                recip_fac*nu[j],
                dos[DOS][j]/recip_fac,
                dos[DOS_SOLID][j]/recip_fac,
                dos[DOS_DIFF][j]/recip_fac);
    }
    xvgrclose(fp);

    /* Finally analyze the results! */
    wCdiff = 0.5;
    wSdiff = Shs/(3*BOLTZ); /* Is this correct? */
    wEdiff = 0.5;
    wAdiff = wEdiff-wSdiff;
    for(j=0; (j<nframes/4); j++)
    {
        dos[DOS_CP][j] = (dos[DOS_DIFF][j]*wCdiff +
                          dos[DOS_SOLID][j]*wCsolid(nu[j],beta));
        dos[DOS_S][j]  = (dos[DOS_DIFF][j]*wSdiff +
                          dos[DOS_SOLID][j]*wSsolid(nu[j],beta));
        dos[DOS_A][j]  = (dos[DOS_DIFF][j]*wAdiff +
                          dos[DOS_SOLID][j]*wAsolid(nu[j],beta));
        dos[DOS_E][j]  = (dos[DOS_DIFF][j]*wEdiff +
                          dos[DOS_SOLID][j]*wEsolid(nu[j],beta));
    }
    DiffCoeff = evaluate_integral(nframes/2,tt,dos[VACF],NULL,nframes/2,&stddev);
    DiffCoeff = 1000*DiffCoeff/3.0;
    fprintf(fplog,"Diffusion coefficient from VACF %g 10^-5 cm^2/s\n",
            DiffCoeff);
    fprintf(fplog,"Diffusion coefficient from DoS %g 10^-5 cm^2/s\n",
            1000*DoS0/(12*tmass*beta));

    cP = BOLTZ * evaluate_integral(nframes/4,nu,dos[DOS_CP],NULL,
                                   nframes/4,&stddev);
    fprintf(fplog,"Heat capacity %g J/mol K\n",1000*cP/Nmol);

    /*
    S  = BOLTZ * evaluate_integral(nframes/4,nu,dos[DOS_S],NULL,
                                   nframes/4,&stddev);
    fprintf(fplog,"Entropy %g J/mol K\n",1000*S/Nmol);
    A  = BOLTZ * evaluate_integral(nframes/4,nu,dos[DOS_A],NULL,
                                   nframes/4,&stddev);
    fprintf(fplog,"Helmholtz energy %g kJ/mol\n",A/Nmol);
    E  = BOLTZ * evaluate_integral(nframes/4,nu,dos[DOS_E],NULL,
                                   nframes/4,&stddev);
    fprintf(fplog,"Internal energy %g kJ/mol\n",E/Nmol);
    */
    fprintf(fplog,"\nArrivederci!\n");
    gmx_fio_fclose(fplog);

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

    thanx(stderr);

    return 0;
}
コード例 #11
0
ファイル: gmx_sham.c プロジェクト: yuduy/gromacs
int gmx_sham(int argc, char *argv[])
{
    const char        *desc[] = {
        "[THISMODULE] makes multi-dimensional free-energy, enthalpy and entropy plots.",
        "[THISMODULE] reads one or more [TT].xvg[tt] files and analyzes data sets.",
        "The basic purpose of [THISMODULE] is to plot Gibbs free energy landscapes",
        "(option [TT]-ls[tt])",
        "by Bolzmann inverting multi-dimensional histograms (option [TT]-lp[tt]),",
        "but it can also",
        "make enthalpy (option [TT]-lsh[tt]) and entropy (option [TT]-lss[tt])",
        "plots. The histograms can be made for any quantities the user supplies.",
        "A line in the input file may start with a time",
        "(see option [TT]-time[tt]) and any number of [IT]y[it]-values may follow.",
        "Multiple sets can also be",
        "read when they are separated by & (option [TT]-n[tt]),",
        "in this case only one [IT]y[it]-value is read from each line.",
        "All lines starting with # and @ are skipped.",
        "[PAR]",
        "Option [TT]-ge[tt] can be used to supply a file with free energies",
        "when the ensemble is not a Boltzmann ensemble, but needs to be biased",
        "by this free energy. One free energy value is required for each",
        "(multi-dimensional) data point in the [TT]-f[tt] input.",
        "[PAR]",
        "Option [TT]-ene[tt] can be used to supply a file with energies.",
        "These energies are used as a weighting function in the single",
        "histogram analysis method by Kumar et al. When temperatures",
        "are supplied (as a second column in the file), an experimental",
        "weighting scheme is applied. In addition the vales",
        "are used for making enthalpy and entropy plots.",
        "[PAR]",
        "With option [TT]-dim[tt], dimensions can be gives for distances.",
        "When a distance is 2- or 3-dimensional, the circumference or surface",
        "sampled by two particles increases with increasing distance.",
        "Depending on what one would like to show, one can choose to correct",
        "the histogram and free-energy for this volume effect.",
        "The probability is normalized by r and r^2 for dimensions of 2 and 3, ",
        "respectively.",
        "A value of -1 is used to indicate an angle in degrees between two",
        "vectors: a sin(angle) normalization will be applied.",
        "[BB]Note[bb] that for angles between vectors the inner-product or cosine",
        "is the natural quantity to use, as it will produce bins of the same",
        "volume."
    };
    static real        tb        = -1, te = -1, frac = 0.5, filtlen = 0;
    static gmx_bool    bHaveT    = TRUE, bDer = FALSE, bSubAv = TRUE, bAverCorr = FALSE, bXYdy = FALSE;
    static gmx_bool    bEESEF    = FALSE, bEENLC = FALSE, bEeFitAc = FALSE, bPower = FALSE;
    static gmx_bool    bShamEner = TRUE, bSham = TRUE;
    static real        Tref      = 298.15, pmin = 0, ttol = 0, pmax = 0, gmax = 0, emin = 0, emax = 0;
    static rvec        nrdim     = {1, 1, 1};
    static rvec        nrbox     = {32, 32, 32};
    static rvec        xmin      = {0, 0, 0}, xmax = {1, 1, 1};
    static int         nsets_in  = 1, nb_min = 4, resol = 10, nlevels = 25;
    t_pargs            pa[]      = {
        { "-time",    FALSE, etBOOL, {&bHaveT},
          "Expect a time in the input" },
        { "-b",       FALSE, etREAL, {&tb},
          "First time to read from set" },
        { "-e",       FALSE, etREAL, {&te},
          "Last time to read from set" },
        { "-ttol",     FALSE, etREAL, {&ttol},
          "Tolerance on time in appropriate units (usually ps)" },
        { "-n",       FALSE, etINT, {&nsets_in},
          "Read this number of sets separated by lines containing only an ampersand" },
        { "-d",       FALSE, etBOOL, {&bDer},
          "Use the derivative" },
        { "-sham",    FALSE, etBOOL, {&bSham},
          "Turn off energy weighting even if energies are given" },
        { "-tsham",   FALSE, etREAL, {&Tref},
          "Temperature for single histogram analysis" },
        { "-pmin",    FALSE, etREAL, {&pmin},
          "Minimum probability. Anything lower than this will be set to zero" },
        { "-dim",     FALSE, etRVEC, {nrdim},
          "Dimensions for distances, used for volume correction (max 3 values, dimensions > 3 will get the same value as the last)" },
        { "-ngrid",   FALSE, etRVEC, {nrbox},
          "Number of bins for energy landscapes (max 3 values, dimensions > 3 will get the same value as the last)" },
        { "-xmin",    FALSE, etRVEC, {xmin},
          "Minimum for the axes in energy landscape (see above for > 3 dimensions)" },
        { "-xmax",    FALSE, etRVEC, {xmax},
          "Maximum for the axes in energy landscape (see above for > 3 dimensions)" },
        { "-pmax",    FALSE, etREAL, {&pmax},
          "Maximum probability in output, default is calculate" },
        { "-gmax",    FALSE, etREAL, {&gmax},
          "Maximum free energy in output, default is calculate" },
        { "-emin",    FALSE, etREAL, {&emin},
          "Minimum enthalpy in output, default is calculate" },
        { "-emax",    FALSE, etREAL, {&emax},
          "Maximum enthalpy in output, default is calculate" },
        { "-nlevels", FALSE, etINT,  {&nlevels},
          "Number of levels for energy landscape" },
    };
#define NPA asize(pa)

    FILE           *out;
    int             n, e_n, nlast, s, nset, e_nset, d_nset, i, j = 0, *idim, *ibox;
    real          **val, **et_val, *t, *e_t, e_dt, d_dt, dt, tot, error;
    real           *rmin, *rmax;
    double         *av, *sig, cum1, cum2, cum3, cum4, db;
    const char     *fn_ge, *fn_ene;
    output_env_t    oenv;
    gmx_int64_t     num_grid_points;

    t_filenm        fnm[] = {
        { efXVG, "-f",    "graph",    ffREAD   },
        { efXVG, "-ge",   "gibbs",    ffOPTRD  },
        { efXVG, "-ene",  "esham",    ffOPTRD  },
        { efXVG, "-dist", "ener",     ffOPTWR  },
        { efXVG, "-histo", "edist",    ffOPTWR  },
        { efNDX, "-bin",  "bindex",   ffOPTWR  },
        { efXPM, "-lp",   "prob",     ffOPTWR  },
        { efXPM, "-ls",   "gibbs",    ffOPTWR  },
        { efXPM, "-lsh",  "enthalpy", ffOPTWR  },
        { efXPM, "-lss",  "entropy",  ffOPTWR  },
        { efPDB, "-ls3",  "gibbs3",   ffOPTWR  },
        { efLOG, "-g",    "shamlog",  ffOPTWR  }
    };
#define NFILE asize(fnm)

    int     npargs;

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

    val = read_xvg_time(opt2fn("-f", NFILE, fnm), bHaveT,
                        opt2parg_bSet("-b", npargs, pa), tb-ttol,
                        opt2parg_bSet("-e", npargs, pa), te+ttol,
                        nsets_in, &nset, &n, &dt, &t);
    printf("Read %d sets of %d points, dt = %g\n\n", nset, n, dt);

    fn_ge  = opt2fn_null("-ge", NFILE, fnm);
    fn_ene = opt2fn_null("-ene", NFILE, fnm);

    if (fn_ge && fn_ene)
    {
        gmx_fatal(FARGS, "Can not do free energy and energy corrections at the same time");
    }

    if (fn_ge || fn_ene)
    {
        et_val = read_xvg_time(fn_ge ? fn_ge : fn_ene, bHaveT,
                               opt2parg_bSet("-b", npargs, pa), tb-ttol,
                               opt2parg_bSet("-e", npargs, pa), te+ttol,
                               1, &e_nset, &e_n, &e_dt, &e_t);
        if (fn_ge)
        {
            if (e_nset != 1)
            {
                gmx_fatal(FARGS, "Can only handle one free energy component in %s",
                          fn_ge);
            }
        }
        else
        {
            if (e_nset != 1 && e_nset != 2)
            {
                gmx_fatal(FARGS, "Can only handle one energy component or one energy and one T in %s",
                          fn_ene);
            }
        }
        if (e_n != n)
        {
            gmx_fatal(FARGS, "Number of energies (%d) does not match number of entries (%d) in %s", e_n, n, opt2fn("-f", NFILE, fnm));
        }
    }
    else
    {
        et_val = NULL;
    }

    if (fn_ene && et_val)
    {
        ehisto(opt2fn("-histo", NFILE, fnm), e_n, et_val, oenv);
    }

    snew(idim, max(3, nset));
    snew(ibox, max(3, nset));
    snew(rmin, max(3, nset));
    snew(rmax, max(3, nset));
    for (i = 0; (i < min(3, nset)); i++)
    {
        idim[i] = nrdim[i];
        ibox[i] = nrbox[i];
        rmin[i] = xmin[i];
        rmax[i] = xmax[i];
    }
    for (; (i < nset); i++)
    {
        idim[i] = nrdim[2];
        ibox[i] = nrbox[2];
        rmin[i] = xmin[2];
        rmax[i] = xmax[2];
    }

    /* Check that the grid size is manageable. */
    num_grid_points = ibox[0];
    for (i = 1; i < nset; i++)
    {
        gmx_int64_t result;
        if (!check_int_multiply_for_overflow(num_grid_points, ibox[i], &result))
        {
            gmx_fatal(FARGS,
                      "The number of dimensions and grid points is too large for this tool.\n");
        }
        num_grid_points = result;
    }
    /* The number of grid points fits in a gmx_int64_t. */

    do_sham(opt2fn("-dist", NFILE, fnm), opt2fn("-bin", NFILE, fnm),
            opt2fn("-lp", NFILE, fnm),
            opt2fn("-ls", NFILE, fnm), opt2fn("-lsh", NFILE, fnm),
            opt2fn("-lss", NFILE, fnm),
            opt2fn("-ls3", NFILE, fnm), opt2fn("-g", NFILE, fnm),
            n, nset, val, fn_ge != NULL, e_nset, et_val, Tref,
            pmax, gmax,
            opt2parg_bSet("-emin", NPA, pa) ? &emin : NULL,
            opt2parg_bSet("-emax", NPA, pa) ? &emax : NULL,
            nlevels, pmin,
            idim, ibox,
            opt2parg_bSet("-xmin", NPA, pa), rmin,
            opt2parg_bSet("-xmax", NPA, pa), rmax);

    return 0;
}
コード例 #12
0
int gmx_nmens(int argc,char *argv[])
{
  static char *desc[] = {
    "[TT]g_nmens[tt] generates an ensemble around an average structure",
    "in a subspace which is defined by a set of normal modes (eigenvectors).",
    "The eigenvectors are assumed to be mass-weighted.",
    "The position along each eigenvector is randomly taken from a Gaussian",
    "distribution with variance kT/eigenvalue.[PAR]",
    "By default the starting eigenvector is set to 7, since the first six",
    "normal modes are the translational and rotational degrees of freedom." 
  };
  static int  nstruct=100,first=7,last=-1,seed=-1;
  static real temp=300.0;
  t_pargs pa[] = {
    { "-temp",  FALSE, etREAL, {&temp}, 
      "Temperature in Kelvin" },
    { "-seed", FALSE, etINT, {&seed},     
      "Random seed, -1 generates a seed from time and pid" },
    { "-num", FALSE, etINT, {&nstruct},     
      "Number of structures to generate" },
    { "-first", FALSE, etINT, {&first},     
      "First eigenvector to use (-1 is select)" },
    { "-last",  FALSE, etINT, {&last}, 
      "Last eigenvector to use (-1 is till the last)" }
  };
#define NPA asize(pa)
  
  int        out;
  int        status,trjout;
  t_topology top;
  int        ePBC;
  t_atoms    *atoms;
  rvec       *xtop,*xref,*xav,*xout1,*xout2;
  bool       bDMR,bDMA,bFit;
  int        nvec,*eignr=NULL;
  rvec       **eigvec=NULL;
  matrix     box;
  real       *eigval,totmass,*invsqrtm,t,disp;
  int        natoms,neigval;
  char       *grpname,*indexfile,title[STRLEN];
  int        i,j,d,s,v;
  int        nout,*iout,noutvec,*outvec;
  atom_id    *index;
  real       rfac,invfr,rhalf,jr;
  int *      eigvalnr;
  
  unsigned long      jran;
  const unsigned long im = 0xffff;
  const unsigned long ia = 1093;
  const unsigned long ic = 18257;

  t_filenm fnm[] = { 
    { efTRN, "-v",    "eigenvec",    ffREAD  },
    { efXVG, "-e",    "eigenval",    ffREAD  },
    { efTPS, NULL,    NULL,          ffREAD },
    { efNDX, NULL,    NULL,          ffOPTRD },
    { efTRO, "-o",    "ensemble",    ffWRITE }
  }; 
#define NFILE asize(fnm) 

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

  indexfile=ftp2fn_null(efNDX,NFILE,fnm);

  read_eigenvectors(opt2fn("-v",NFILE,fnm),&natoms,&bFit,
		    &xref,&bDMR,&xav,&bDMA,&nvec,&eignr,&eigvec,&eigval);

  read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&xtop,NULL,box,bDMA);
  atoms=&top.atoms;

  printf("\nSelect an index group of %d elements that corresponds to the eigenvectors\n",natoms);
  get_index(atoms,indexfile,1,&i,&index,&grpname);
  if (i!=natoms)
    gmx_fatal(FARGS,"you selected a group with %d elements instead of %d",
		i,natoms);
  printf("\n");
  
  snew(invsqrtm,natoms);
  if (bDMA) {
    for(i=0; (i<natoms); i++)
      invsqrtm[i] = invsqrt(atoms->atom[index[i]].m);
  } else {
    for(i=0; (i<natoms); i++)
      invsqrtm[i]=1.0;
  }
  
  if (last==-1)
      last=natoms*DIM;
  if (first>-1) 
  {
      /* make an index from first to last */
      nout=last-first+1;
      snew(iout,nout);
      for(i=0; i<nout; i++)
          iout[i]=first-1+i;
  }
  else 
  {
      printf("Select eigenvectors for output, end your selection with 0\n");
      nout=-1;
      iout=NULL;
      do {
          nout++;
          srenew(iout,nout+1);
          if(1 != scanf("%d",&iout[nout]))
	  {
	      gmx_fatal(FARGS,"Error reading user input");
	  }
          iout[nout]--;
      } while (iout[nout]>=0);
      printf("\n");
  }
  
  /* make an index of the eigenvectors which are present */
  snew(outvec,nout);
  noutvec=0;
  for(i=0; i<nout; i++)
  {
      j=0;
      while ((j<nvec) && (eignr[j]!=iout[i]))
          j++;
      if ((j<nvec) && (eignr[j]==iout[i]))
      {
          outvec[noutvec] = j;
          iout[noutvec] = iout[i];
          noutvec++;
      }
  }
  
  fprintf(stderr,"%d eigenvectors selected for output\n",noutvec);

  if (seed == -1)
    seed = make_seed();
  fprintf(stderr,"Using seed %d and a temperature of %g K\n",seed,temp);

  snew(xout1,natoms);
  snew(xout2,atoms->nr);
  out=open_trx(ftp2fn(efTRO,NFILE,fnm),"w");
  jran = (unsigned long)((real)im*rando(&seed));
  for(s=0; s<nstruct; s++) {
    for(i=0; i<natoms; i++)
      copy_rvec(xav[i],xout1[i]);
    for(j=0; j<noutvec; j++) {
      v = outvec[j];
      /* (r-0.5) n times:  var_n = n * var_1 = n/12
	 n=4:  var_n = 1/3, so multiply with 3 */
      
      rfac  = sqrt(3.0 * BOLTZ*temp/eigval[iout[j]]);
      rhalf = 2.0*rfac; 
      rfac  = rfac/(real)im;

      jran = (jran*ia+ic) & im;
      jr = (real)jran;
      jran = (jran*ia+ic) & im;
      jr += (real)jran;
      jran = (jran*ia+ic) & im;
      jr += (real)jran;
      jran = (jran*ia+ic) & im;
      jr += (real)jran;
      disp = rfac * jr - rhalf;
      
      for(i=0; i<natoms; i++)
          for(d=0; d<DIM; d++)
              xout1[i][d] += disp*eigvec[v][i][d]*invsqrtm[i];
    }
    for(i=0; i<natoms; i++)
        copy_rvec(xout1[i],xout2[index[i]]);
    t = s+1;
    write_trx(out,natoms,index,atoms,0,t,box,xout2,NULL);
    fprintf(stderr,"\rGenerated %d structures",s+1);
  }
  fprintf(stderr,"\n");
  close_trx(out);
  
  return 0;
}
コード例 #13
0
ファイル: gmx_angle.cpp プロジェクト: friforever/gromacs
int gmx_g_angle(int argc, char *argv[])
{
    static const char *desc[] = {
        "[THISMODULE] computes the angle distribution for a number of angles",
        "or dihedrals.[PAR]",
        "With option [TT]-ov[tt], you can plot the average angle of",
        "a group of angles as a function of time. With the [TT]-all[tt] option,",
        "the first graph is the average and the rest are the individual angles.[PAR]",
        "With the [TT]-of[tt] option, [THISMODULE] also calculates the fraction of trans",
        "dihedrals (only for dihedrals) as function of time, but this is",
        "probably only fun for a select few.[PAR]",
        "With option [TT]-oc[tt], a dihedral correlation function is calculated.[PAR]",
        "It should be noted that the index file must contain",
        "atom triplets for angles or atom quadruplets for dihedrals.",
        "If this is not the case, the program will crash.[PAR]",
        "With option [TT]-or[tt], a trajectory file is dumped containing cos and",
        "sin of selected dihedral angles, which subsequently can be used as",
        "input for a principal components analysis using [gmx-covar].[PAR]",
        "Option [TT]-ot[tt] plots when transitions occur between",
        "dihedral rotamers of multiplicity 3 and [TT]-oh[tt]",
        "records a histogram of the times between such transitions,",
        "assuming the input trajectory frames are equally spaced in time."
    };
    static const char *opt[]    = { nullptr, "angle", "dihedral", "improper", "ryckaert-bellemans", nullptr };
    static gmx_bool    bALL     = FALSE, bChandler = FALSE, bAverCorr = FALSE, bPBC = TRUE;
    static real        binwidth = 1;
    t_pargs            pa[]     = {
        { "-type", FALSE, etENUM, {opt},
          "Type of angle to analyse" },
        { "-all",    FALSE,  etBOOL, {&bALL},
          "Plot all angles separately in the averages file, in the order of appearance in the index file." },
        { "-binwidth", FALSE, etREAL, {&binwidth},
          "binwidth (degrees) for calculating the distribution" },
        { "-periodic", FALSE, etBOOL, {&bPBC},
          "Print dihedral angles modulo 360 degrees" },
        { "-chandler", FALSE,  etBOOL, {&bChandler},
          "Use Chandler correlation function (N[trans] = 1, N[gauche] = 0) rather than cosine correlation function. Trans is defined as phi < -60 or phi > 60." },
        { "-avercorr", FALSE,  etBOOL, {&bAverCorr},
          "Average the correlation functions for the individual angles/dihedrals" }
    };
    static const char *bugs[] = {
        "Counting transitions only works for dihedrals with multiplicity 3"
    };

    FILE              *out;
    real               dt;
    int                isize;
    int               *index;
    char              *grpname;
    real               maxang, S2, norm_fac, maxstat;
    unsigned long      mode;
    int                nframes, maxangstat, mult, *angstat;
    int                i, j, nangles, first, last;
    gmx_bool           bAver, bRb, bPeriodic,
                       bFrac,               /* calculate fraction too?  */
                       bTrans,              /* worry about transtions too? */
                       bCorr;               /* correlation function ? */
    real              aver, aver2, aversig; /* fraction trans dihedrals */
    double            tfrac = 0;
    char              title[256];
    real            **dih = nullptr; /* mega array with all dih. angles at all times*/
    real             *time, *trans_frac, *aver_angle;
    t_filenm          fnm[] = {
        { efTRX, "-f", nullptr,  ffREAD  },
        { efNDX, nullptr, "angle",  ffREAD  },
        { efXVG, "-od", "angdist",  ffWRITE },
        { efXVG, "-ov", "angaver",  ffOPTWR },
        { efXVG, "-of", "dihfrac",  ffOPTWR },
        { efXVG, "-ot", "dihtrans", ffOPTWR },
        { efXVG, "-oh", "trhisto",  ffOPTWR },
        { efXVG, "-oc", "dihcorr",  ffOPTWR },
        { efTRR, "-or", nullptr,       ffOPTWR }
    };
#define NFILE asize(fnm)
    int               npargs;
    t_pargs          *ppa;
    gmx_output_env_t *oenv;

    npargs = asize(pa);
    ppa    = add_acf_pargs(&npargs, pa);
    if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME,
                           NFILE, fnm, npargs, ppa, asize(desc), desc, asize(bugs), bugs,
                           &oenv))
    {
        sfree(ppa);
        return 0;
    }

    mult   = 4;
    maxang = 360.0;
    bRb    = FALSE;

    GMX_RELEASE_ASSERT(opt[0] != nullptr, "Internal option inconsistency; opt[0]==NULL after processing");

    switch (opt[0][0])
    {
        case 'a':
            mult   = 3;
            maxang = 180.0;
            break;
        case 'd':
            break;
        case 'i':
            break;
        case 'r':
            bRb = TRUE;
            break;
    }

    if (opt2bSet("-or", NFILE, fnm))
    {
        if (mult != 4)
        {
            gmx_fatal(FARGS, "Can not combine angles with trr dump");
        }
        else
        {
            please_cite(stdout, "Mu2005a");
        }
    }

    /* Calculate bin size */
    maxangstat = gmx::roundToInt(maxang/binwidth);
    binwidth   = maxang/maxangstat;

    rd_index(ftp2fn(efNDX, NFILE, fnm), 1, &isize, &index, &grpname);
    nangles = isize/mult;
    if ((isize % mult) != 0)
    {
        gmx_fatal(FARGS, "number of index elements not multiple of %d, "
                  "these can not be %s\n",
                  mult, (mult == 3) ? "angle triplets" : "dihedral quadruplets");
    }


    /* Check whether specific analysis has to be performed */
    bCorr  = opt2bSet("-oc", NFILE, fnm);
    bAver  = opt2bSet("-ov", NFILE, fnm);
    bTrans = opt2bSet("-ot", NFILE, fnm);
    bFrac  = opt2bSet("-of", NFILE, fnm);
    if (bTrans && opt[0][0] != 'd')
    {
        fprintf(stderr, "Option -ot should only accompany -type dihedral. Disabling -ot.\n");
        bTrans = FALSE;
    }

    if (bChandler && !bCorr)
    {
        bCorr = TRUE;
    }

    if (bFrac && !bRb)
    {
        fprintf(stderr, "Warning:"
                " calculating fractions as defined in this program\n"
                "makes sense for Ryckaert Bellemans dihs. only. Ignoring -of\n\n");
        bFrac = FALSE;
    }

    if ( (bTrans || bFrac || bCorr) && mult == 3)
    {
        gmx_fatal(FARGS, "Can only do transition, fraction or correlation\n"
                  "on dihedrals. Select -d\n");
    }

    /*
     * We need to know the nr of frames so we can allocate memory for an array
     * with all dihedral angles at all timesteps. Works for me.
     */
    if (bTrans || bCorr  || bALL || opt2bSet("-or", NFILE, fnm))
    {
        snew(dih, nangles);
    }

    snew(angstat, maxangstat);

    read_ang_dih(ftp2fn(efTRX, NFILE, fnm), (mult == 3),
                 bALL || bCorr || bTrans || opt2bSet("-or", NFILE, fnm),
                 bRb, bPBC, maxangstat, angstat,
                 &nframes, &time, isize, index, &trans_frac, &aver_angle, dih,
                 oenv);

    dt = (time[nframes-1]-time[0])/(nframes-1);

    if (bAver)
    {
        sprintf(title, "Average Angle: %s", grpname);
        out = xvgropen(opt2fn("-ov", NFILE, fnm),
                       title, "Time (ps)", "Angle (degrees)", oenv);
        for (i = 0; (i < nframes); i++)
        {
            fprintf(out, "%10.5f  %8.3f", time[i], aver_angle[i]*RAD2DEG);
            if (bALL)
            {
                for (j = 0; (j < nangles); j++)
                {
                    if (bPBC)
                    {
                        real dd = dih[j][i];
                        fprintf(out, "  %8.3f", std::atan2(std::sin(dd), std::cos(dd))*RAD2DEG);
                    }
                    else
                    {
                        fprintf(out, "  %8.3f", dih[j][i]*RAD2DEG);
                    }
                }
            }
            fprintf(out, "\n");
        }
        xvgrclose(out);
    }
    if (opt2bSet("-or", NFILE, fnm))
    {
        dump_dih_trr(nframes, nangles, dih, opt2fn("-or", NFILE, fnm), time);
    }

    if (bFrac)
    {
        sprintf(title, "Trans fraction: %s", grpname);
        out = xvgropen(opt2fn("-of", NFILE, fnm),
                       title, "Time (ps)", "Fraction", oenv);
        tfrac = 0.0;
        for (i = 0; (i < nframes); i++)
        {
            fprintf(out, "%10.5f  %10.3f\n", time[i], trans_frac[i]);
            tfrac += trans_frac[i];
        }
        xvgrclose(out);

        tfrac /= nframes;
        fprintf(stderr, "Average trans fraction: %g\n", tfrac);
    }
    sfree(trans_frac);

    if (bTrans)
    {
        ana_dih_trans(opt2fn("-ot", NFILE, fnm), opt2fn("-oh", NFILE, fnm),
                      dih, nframes, nangles, grpname, time, bRb, oenv);
    }

    if (bCorr)
    {
        /* Autocorrelation function */
        if (nframes < 2)
        {
            fprintf(stderr, "Not enough frames for correlation function\n");
        }
        else
        {

            if (bChandler)
            {
                real     dval, sixty = DEG2RAD*60;
                gmx_bool bTest;

                for (i = 0; (i < nangles); i++)
                {
                    for (j = 0; (j < nframes); j++)
                    {
                        dval = dih[i][j];
                        if (bRb)
                        {
                            bTest = (dval > -sixty) && (dval < sixty);
                        }
                        else
                        {
                            bTest = (dval < -sixty) || (dval > sixty);
                        }
                        if (bTest)
                        {
                            dih[i][j] = dval-tfrac;
                        }
                        else
                        {
                            dih[i][j] = -tfrac;
                        }
                    }
                }
            }
            if (bChandler)
            {
                mode = eacNormal;
            }
            else
            {
                mode = eacCos;
            }
            do_autocorr(opt2fn("-oc", NFILE, fnm), oenv,
                        "Dihedral Autocorrelation Function",
                        nframes, nangles, dih, dt, mode, bAverCorr);
        }
    }


    /* Determine the non-zero part of the distribution */
    for (first = 0; (first < maxangstat-1) && (angstat[first+1] == 0); first++)
    {
        ;
    }
    for (last = maxangstat-1; (last > 0) && (angstat[last-1] == 0); last--)
    {
        ;
    }

    aver = aver2 = 0;
    for (i = 0; (i < nframes); i++)
    {
        aver  += RAD2DEG*aver_angle[i];
        aver2 += gmx::square(RAD2DEG*aver_angle[i]);
    }
    aver   /= nframes;
    aver2  /= nframes;
    aversig = std::sqrt(aver2-gmx::square(aver));
    printf("Found points in the range from %d to %d (max %d)\n",
           first, last, maxangstat);
    printf(" < angle >  = %g\n", aver);
    printf("< angle^2 > = %g\n", aver2);
    printf("Std. Dev.   = %g\n", aversig);

    if (mult == 3)
    {
        sprintf(title, "Angle Distribution: %s", grpname);
    }
    else
    {
        sprintf(title, "Dihedral Distribution: %s", grpname);

        calc_distribution_props(maxangstat, angstat, -180.0, 0, nullptr, &S2);
        fprintf(stderr, "Order parameter S^2 = %g\n", S2);
    }

    bPeriodic = (mult == 4) && (first == 0) && (last == maxangstat-1);

    out = xvgropen(opt2fn("-od", NFILE, fnm), title, "Degrees", "", oenv);
    if (output_env_get_print_xvgr_codes(oenv))
    {
        fprintf(out, "@    subtitle \"average angle: %g\\So\\N\"\n", aver);
    }
    norm_fac = 1.0/(nangles*nframes*binwidth);
    if (bPeriodic)
    {
        maxstat = 0;
        for (i = first; (i <= last); i++)
        {
            maxstat = std::max(maxstat, angstat[i]*norm_fac);
        }
        if (output_env_get_print_xvgr_codes(oenv))
        {
            fprintf(out, "@with g0\n");
            fprintf(out, "@    world xmin -180\n");
            fprintf(out, "@    world xmax  180\n");
            fprintf(out, "@    world ymin 0\n");
            fprintf(out, "@    world ymax %g\n", maxstat*1.05);
            fprintf(out, "@    xaxis  tick major 60\n");
            fprintf(out, "@    xaxis  tick minor 30\n");
            fprintf(out, "@    yaxis  tick major 0.005\n");
            fprintf(out, "@    yaxis  tick minor 0.0025\n");
        }
    }
    for (i = first; (i <= last); i++)
    {
        fprintf(out, "%10g  %10f\n", i*binwidth+180.0-maxang, angstat[i]*norm_fac);
    }
    if (bPeriodic)
    {
        /* print first bin again as last one */
        fprintf(out, "%10g  %10f\n", 180.0, angstat[0]*norm_fac);
    }

    xvgrclose(out);

    do_view(oenv, opt2fn("-od", NFILE, fnm), "-nxy");
    if (bAver)
    {
        do_view(oenv, opt2fn("-ov", NFILE, fnm), "-nxy");
    }

    return 0;
}
コード例 #14
0
ファイル: gmx_dyndom.cpp プロジェクト: carryer123/gromacs
int gmx_dyndom(int argc, char *argv[])
{
    const char  *desc[] = {
        "[THISMODULE] reads a [REF].pdb[ref] file output from DynDom",
        "(http://www.cmp.uea.ac.uk/dyndom/).",
        "It reads the coordinates, the coordinates of the rotation axis,",
        "and an index file containing the domains.",
        "Furthermore, it takes the first and last atom of the arrow file",
        "as command line arguments (head and tail) and",
        "finally it takes the translation vector (given in DynDom info file)",
        "and the angle of rotation (also as command line arguments). If the angle",
        "determined by DynDom is given, one should be able to recover the",
        "second structure used for generating the DynDom output.",
        "Because of limited numerical accuracy this should be verified by",
        "computing an all-atom RMSD (using [gmx-confrms]) rather than by file",
        "comparison (using diff).[PAR]",
        "The purpose of this program is to interpolate and extrapolate the",
        "rotation as found by DynDom. As a result unphysical structures with",
        "long or short bonds, or overlapping atoms may be produced. Visual",
        "inspection, and energy minimization may be necessary to",
        "validate the structure."
    };
    static real  trans0 = 0;
    static rvec  head   = { 0, 0, 0 };
    static rvec  tail   = { 0, 0, 0 };
    static real  angle0 = 0, angle1 = 0, maxangle = 0;
    static int   label  = 0, nframes = 11;
    t_pargs      pa[]   = {
        { "-firstangle",    FALSE, etREAL, {&angle0},
          "Angle of rotation about rotation vector" },
        { "-lastangle",    FALSE, etREAL, {&angle1},
          "Angle of rotation about rotation vector" },
        { "-nframe",   FALSE, etINT,  {&nframes},
          "Number of steps on the pathway" },
        { "-maxangle", FALSE, etREAL, {&maxangle},
          "DymDom dtermined angle of rotation about rotation vector" },
        { "-trans",    FALSE, etREAL, {&trans0},
          "Translation (Angstrom) along rotation vector (see DynDom info file)" },
        { "-head",     FALSE, etRVEC, {head},
          "First atom of the arrow vector" },
        { "-tail",     FALSE, etRVEC, {tail},
          "Last atom of the arrow vector" }
    };
    int          i, j, natoms, isize;
    t_trxstatus *status;
    atom_id     *index = NULL, *index_all;
    char         title[256], *grpname;
    t_atoms      atoms;
    real         angle, trans;
    rvec        *x, *v, *xout, *vout;
    matrix       box;
    output_env_t oenv;

    t_filenm     fnm[] = {
        { efPDB, "-f", "dyndom",  ffREAD },
        { efTRO, "-o", "rotated", ffWRITE },
        { efNDX, "-n", "domains", ffREAD }
    };
#define NFILE asize(fnm)

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

    if (maxangle == 0)
    {
        gmx_fatal(FARGS, "maxangle not given");
    }

    get_stx_coordnum (opt2fn("-f", NFILE, fnm), &natoms);
    init_t_atoms(&atoms, natoms, TRUE);
    snew(x, natoms);
    snew(v, natoms);
    read_stx_conf(opt2fn("-f", NFILE, fnm), title, &atoms, x, v, NULL, box);
    snew(xout, natoms);
    snew(vout, natoms);

    printf("Select group to rotate:\n");
    rd_index(ftp2fn(efNDX, NFILE, fnm), 1, &isize, &index, &grpname);
    printf("Going to rotate %s containg %d atoms\n", grpname, isize);

    snew(index_all, atoms.nr);
    for (i = 0; (i < atoms.nr); i++)
    {
        index_all[i] = i;
    }

    status = open_trx(opt2fn("-o", NFILE, fnm), "w");

    label = 'A';
    for (i = 0; (i < nframes); i++, label++)
    {
        angle = angle0 + (i*(angle1-angle0))/(nframes-1);
        trans = trans0*0.1*angle/maxangle;
        printf("Frame: %2d (label %c), angle: %8.3f deg., trans: %8.3f nm\n",
               i, label, angle, trans);
        rot_conf(&atoms, x, v, trans, angle, head, tail, isize, index, xout, vout);

        if (label > 'Z')
        {
            label -= 26;
        }
        for (j = 0; (j < atoms.nr); j++)
        {
            atoms.resinfo[atoms.atom[j].resind].chainid = label;
        }

        write_trx(status, atoms.nr, index_all, &atoms, i, angle, box, xout, vout, NULL);
    }
    close_trx(status);

    return 0;
}
コード例 #15
0
int gmx_morph(int argc, char *argv[])
{
    const char      *desc[] = {
        "[THISMODULE] 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 [TT]-ninterm[tt] flag. The first and last flag correspond to the way of",
        "interpolating: 0 corresponds to input structure 1 while",
        "1 corresponds to input structure 2.",
        "If you specify [TT]-first[tt] < 0 or [TT]-last[tt] > 1 extrapolation will be",
        "on the path from input structure x[SUB]1[sub] to x[SUB]2[sub]. In general, the coordinates",
        "of the intermediate x(i) out of N total intermediates correspond to:[PAR]",
        "x(i) = x[SUB]1[sub] + (first+(i/(N-1))*(last-first))*(x[SUB]2[sub]-x[SUB]1[sub])[PAR]",
        "Finally the RMSD with respect to both input structures can be computed",
        "if explicitly selected ([TT]-or[tt] option). In that case, an index file may be",
        "read to select the group from which the RMS is computed."
    };
    t_filenm         fnm[] = {
        { efSTX, "-f1", "conf1",  ffREAD },
        { efSTX, "-f2", "conf2",  ffREAD },
        { efTRX, "-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  gmx_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 x[SUB]1[sub], see above)" },
        { "-last",    FALSE, etREAL, {&last},
          "Corresponds to last generated structure (1 is input x[SUB]2[sub], see above)" },
        { "-fit",     FALSE, etBOOL, {&bFit},
          "Do a least squares fit of the second to the first structure before interpolating" }
    };
    const char      *leg[] = { "Ref = 1\\Sst\\N conf", "Ref = 2\\Snd\\N conf" };
    FILE            *fp    = NULL;
    int              i, isize, is_lsq, nat1, nat2;
    t_trxstatus     *status;
    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;
    gmx_bool         bRMS;
    output_env_t     oenv;

    if (!parse_common_args(&argc, argv, PCA_CAN_VIEW,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc,
                           0, NULL, &oenv))
    {
        return 0;
    }
    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)", oenv);
        xvgr_legend(fp, asize(leg), leg, oenv);
        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, 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)
    {
        gmx_ffclose(fp);
        do_view(oenv, opt2fn("-or", NFILE, fnm), "-nxy");
    }

    return 0;
}
コード例 #16
0
int gmx_clustsize(int argc,char *argv[])
{
  static char *desc[] = {
    "This program computes the size distributions of molecular/atomic clusters in",
    "the gas phase. The output is given in the form of a XPM file.",
    "The total number of clusters is written to a XVG file.[PAR]",
    "When the [TT]-mol[tt] option is given clusters will be made out of",
    "molecules rather than atoms, which allows clustering of large molecules.",
    "In this case an index file would still contain atom numbers",
    "or your calculcation will die with a SEGV.[PAR]",
    "When velocities are present in your trajectory, the temperature of",
    "the largest cluster will be printed in a separate xvg file assuming",
    "that the particles are free to move. If you are using constraints,",
    "please correct the temperature. For instance water simulated with SHAKE",
    "or SETTLE will yield a temperature that is 1.5 times too low. You can",
    "compensate for this with the -ndf option. Remember to take the removal",
    "of center of mass motion into account.[PAR]",
    "The [TT]-mc[tt] option will produce an index file containing the",
    "atom numbers of the largest cluster."
  };
  
  static real cutoff   = 0.35;
  static int  nskip    = 0;
  static int  nlevels  = 20;
  static int  ndf      = -1;
  static bool bMol     = FALSE;
  static bool bPBC     = TRUE;
  static rvec rlo      = { 1.0, 1.0, 0.0 };
  static rvec rhi      = { 0.0, 0.0, 1.0 };
  t_pargs pa[] = {
    { "-cut",      FALSE, etREAL, {&cutoff},
      "Largest distance (nm) to be considered in a cluster" },
    { "-mol",      FALSE, etBOOL, {&bMol},
      "Cluster molecules rather than atoms (needs tpr file)" },
    { "-pbc",      FALSE, etBOOL, {&bPBC},
      "Use periodic boundary conditions" },
    { "-nskip",    FALSE, etINT,  {&nskip},
      "Number of frames to skip between writing" },
    { "-nlevels",  FALSE, etINT,  {&nlevels},
      "Number of levels of grey in xpm output" },
    { "-ndf",      FALSE, etINT,  {&ndf},
      "Number of degrees of freedom of the entire system for temperature calculation. If not set the number of atoms times three is used." },
    { "-rgblo",    FALSE, etRVEC, {rlo},
      "RGB values for the color of the lowest occupied cluster size" },
    { "-rgbhi",    FALSE, etRVEC, {rhi},
      "RGB values for the color of the highest occupied cluster size" }
  };
#define NPA asize(pa)
  char       *fnNDX,*fnTPR;
  bool       bSQ,bRDF;
  t_rgb      rgblo,rgbhi;
  
  t_filenm   fnm[] = {
    { efTRX, "-f",  NULL,         ffREAD  },
    { efTPR, NULL,  NULL,         ffOPTRD },
    { efNDX, NULL,  NULL,         ffOPTRD },
    { efXPM, "-o", "csize",       ffWRITE },
    { efXPM, "-ow","csizew",      ffWRITE },
    { efXVG, "-nc","nclust",      ffWRITE },
    { efXVG, "-mc","maxclust",    ffWRITE },
    { efXVG, "-ac","avclust",     ffWRITE },
    { efXVG, "-hc","histo-clust", ffWRITE },
    { efXVG, "-temp","temp",     ffOPTWR },
    { efNDX, "-mcn", "maxclust", ffOPTWR }
  };
#define NFILE asize(fnm)
  
  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT | PCA_BE_NICE,
		    NFILE,fnm,NPA,pa,asize(desc),desc,0,NULL);

  fnNDX = ftp2fn_null(efNDX,NFILE,fnm);
  rgblo.r = rlo[XX],rgblo.g = rlo[YY],rgblo.b = rlo[ZZ];
  rgbhi.r = rhi[XX],rgbhi.g = rhi[YY],rgbhi.b = rhi[ZZ];
    
  fnTPR = ftp2fn_null(efTPR,NFILE,fnm);
  if (bMol && !fnTPR)
    gmx_fatal(FARGS,"You need a tpr file for the -mol option");
    
  clust_size(fnNDX,ftp2fn(efTRX,NFILE,fnm),opt2fn("-o",NFILE,fnm),
	     opt2fn("-ow",NFILE,fnm),
	     opt2fn("-nc",NFILE,fnm),opt2fn("-ac",NFILE,fnm),
	     opt2fn("-mc",NFILE,fnm),opt2fn("-hc",NFILE,fnm),
	     opt2fn("-temp",NFILE,fnm),opt2fn("-mcn",NFILE,fnm),
	     bMol,bPBC,fnTPR,
	     cutoff,nskip,nlevels,rgblo,rgbhi,ndf);

  thanx(stderr);
  
  return 0;
}
コード例 #17
0
ファイル: gmx_principal.c プロジェクト: pslacerda/gromacs
int gmx_principal(int argc, char *argv[])
{
    const char     *desc[] = {
        "[TT]g_principal[tt] calculates the three principal axes of inertia for a group",
        "of atoms.",
    };
    static gmx_bool foo = FALSE;

    t_pargs         pa[] = {
        { "-foo",      FALSE, etBOOL, {&foo}, "Dummy option to avoid empty array" }
    };
    t_trxstatus    *status;
    t_topology      top;
    int             ePBC;
    real            t;
    rvec      *     x;

    int             natoms;
    char           *grpname, title[256];
    int             i, j, m, gnx, nam, mol;
    atom_id        *index;
    rvec            a1, a2, a3, moi;
    FILE      *     axis1;
    FILE      *     axis2;
    FILE      *     axis3;
    FILE      *     fmoi;
    matrix          axes, box;
    output_env_t    oenv;
    gmx_rmpbc_t     gpbc = NULL;


    t_filenm fnm[] = {
        { efTRX, "-f",   NULL,       ffREAD },
        { efTPS, NULL,   NULL,       ffREAD },
        { efNDX, NULL,   NULL,       ffOPTRD },
        { efDAT, "-a1",  "axis1",    ffWRITE },
        { efDAT, "-a2",  "axis2",    ffWRITE },
        { efDAT, "-a3",  "axis3",    ffWRITE },
        { efDAT, "-om",  "moi",      ffWRITE }
    };
#define NFILE asize(fnm)

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

    axis1 = ffopen(opt2fn("-a1", NFILE, fnm), "w");
    axis2 = ffopen(opt2fn("-a2", NFILE, fnm), "w");
    axis3 = ffopen(opt2fn("-a3", NFILE, fnm), "w");
    fmoi  = ffopen(opt2fn("-om", NFILE, fnm), "w");

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

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

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

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

        calc_principal_axes(&top, x, index, gnx, axes, moi);

        fprintf(axis1, "%15.10f     %15.10f  %15.10f  %15.10f\n", t, axes[XX][XX], axes[YY][XX], axes[ZZ][XX]);
        fprintf(axis2, "%15.10f     %15.10f  %15.10f  %15.10f\n", t, axes[XX][YY], axes[YY][YY], axes[ZZ][YY]);
        fprintf(axis3, "%15.10f     %15.10f  %15.10f  %15.10f\n", t, axes[XX][ZZ], axes[YY][ZZ], axes[ZZ][ZZ]);
        fprintf(fmoi,  "%15.10f     %15.10f  %15.10f  %15.10f\n", t, moi[XX], moi[YY], moi[ZZ]);
    }
    while (read_next_x(oenv, status, &t, x, box));

    gmx_rmpbc_done(gpbc);


    close_trj(status);
    ffclose(axis1);
    ffclose(axis2);
    ffclose(axis3);
    ffclose(fmoi);

    return 0;
}
コード例 #18
0
ファイル: gmx_trjcat.cpp プロジェクト: kmtu/gromacs
int gmx_trjcat(int argc, char *argv[])
{
    const char     *desc[] =
    {
        "[THISMODULE] concatenates several input trajectory files in sorted order. ",
        "In case of double time frames the one in the later file is used. ",
        "By specifying [TT]-settime[tt] you will be asked for the start time ",
        "of each file. The input files are taken from the command line, ",
        "such that a command like [TT]gmx trjcat -f *.trr -o fixed.trr[tt] should do ",
        "the trick. Using [TT]-cat[tt], you can simply paste several files ",
        "together without removal of frames with identical time stamps.[PAR]",
        "One important option is inferred when the output file is amongst the",
        "input files. In that case that particular file will be appended to",
        "which implies you do not need to store double the amount of data.",
        "Obviously the file to append to has to be the one with lowest starting",
        "time since one can only append at the end of a file.[PAR]",
        "If the [TT]-demux[tt] option is given, the N trajectories that are",
        "read, are written in another order as specified in the [REF].xvg[ref] file.",
        "The [REF].xvg[ref] file should contain something like::",
        "",
        "    0  0  1  2  3  4  5",
        "    2  1  0  2  3  5  4",
        "",
        "The first number is the time, and subsequent numbers point to",
        "trajectory indices.",
        "The frames corresponding to the numbers present at the first line",
        "are collected into the output trajectory. If the number of frames in",
        "the trajectory does not match that in the [REF].xvg[ref] file then the program",
        "tries to be smart. Beware."
    };
    static gmx_bool bCat            = FALSE;
    static gmx_bool bSort           = TRUE;
    static gmx_bool bKeepLast       = FALSE;
    static gmx_bool bKeepLastAppend = FALSE;
    static gmx_bool bOverwrite      = FALSE;
    static gmx_bool bSetTime        = FALSE;
    static gmx_bool bDeMux;
    static real     begin = -1;
    static real     end   = -1;
    static real     dt    = 0;

    t_pargs
        pa[] =
    {
        { "-b", FALSE, etTIME,
          { &begin }, "First time to use (%t)" },
        { "-e", FALSE, etTIME,
          { &end }, "Last time to use (%t)" },
        { "-dt", FALSE, etTIME,
          { &dt }, "Only write frame when t MOD dt = first time (%t)" },
        { "-settime", FALSE, etBOOL,
          { &bSetTime }, "Change starting time interactively" },
        { "-sort", FALSE, etBOOL,
          { &bSort }, "Sort trajectory files (not frames)" },
        { "-keeplast", FALSE, etBOOL,
          { &bKeepLast }, "Keep overlapping frames at end of trajectory" },
        { "-overwrite", FALSE, etBOOL,
          { &bOverwrite }, "Overwrite overlapping frames during appending" },
        { "-cat", FALSE, etBOOL,
          { &bCat }, "Do not discard double time frames" }
    };
#define npargs asize(pa)
    int               ftpin, i, frame, frame_out;
    t_trxstatus      *status, *trxout = NULL;
    real              t_corr;
    t_trxframe        fr, frout;
    char            **fnms, **fnms_out, *out_file;
    int               n_append;
    gmx_bool          bNewFile, bIndex, bWrite;
    int               nfile_in, nfile_out, *cont_type;
    real             *readtime, *timest, *settime;
    real              first_time  = 0, lasttime, last_ok_t = -1, timestep;
    gmx_bool          lastTimeSet = FALSE;
    real              last_frame_time, searchtime;
    int               isize = 0, j;
    int              *index = NULL, imax;
    char             *grpname;
    real            **val = NULL, *t = NULL, dt_remd;
    int               n, nset, ftpout = -1, prevEndStep = 0, filetype;
    gmx_off_t         fpos;
    gmx_output_env_t *oenv;
    t_filenm          fnm[] =
    {
        { efTRX, "-f", NULL, ffRDMULT },
        { efTRO, "-o", NULL, ffWRMULT },
        { efNDX, "-n", "index", ffOPTRD },
        { efXVG, "-demux", "remd", ffOPTRD }
    };

#define NFILE asize(fnm)

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

    bIndex = ftp2bSet(efNDX, NFILE, fnm);
    bDeMux = ftp2bSet(efXVG, NFILE, fnm);
    bSort  = bSort && !bDeMux;

    imax = -1;
    if (bIndex)
    {
        printf("Select group for output\n");
        rd_index(ftp2fn(efNDX, NFILE, fnm), 1, &isize, &index, &grpname);
        /* scan index */
        imax = index[0];
        for (i = 1; i < isize; i++)
        {
            imax = std::max(imax, index[i]);
        }
    }
    if (bDeMux)
    {
        nset    = 0;
        dt_remd = 0;
        val     = read_xvg_time(opt2fn("-demux", NFILE, fnm), TRUE,
                                opt2parg_bSet("-b", npargs, pa), begin,
                                opt2parg_bSet("-e", npargs, pa), end, 1, &nset, &n,
                                &dt_remd, &t);
        printf("Read %d sets of %d points, dt = %g\n\n", nset, n, dt_remd);
        if (debug)
        {
            fprintf(debug, "Dump of replica_index.xvg\n");
            for (i = 0; (i < n); i++)
            {
                fprintf(debug, "%10g", t[i]);
                for (j = 0; (j < nset); j++)
                {
                    fprintf(debug, "  %3d", static_cast<int>(std::round(val[j][i])));
                }
                fprintf(debug, "\n");
            }
        }
    }

    nfile_in = opt2fns(&fnms, "-f", NFILE, fnm);
    if (!nfile_in)
    {
        gmx_fatal(FARGS, "No input files!" );
    }

    if (bDeMux && (nfile_in != nset))
    {
        gmx_fatal(FARGS, "You have specified %d files and %d entries in the demux table", nfile_in, nset);
    }

    ftpin = fn2ftp(fnms[0]);

    for (i = 1; i < nfile_in; i++)
    {
        if (ftpin != fn2ftp(fnms[i]))
        {
            gmx_fatal(FARGS, "All input files must be of the same format");
        }
    }

    nfile_out = opt2fns(&fnms_out, "-o", NFILE, fnm);
    if (!nfile_out)
    {
        gmx_fatal(FARGS, "No output files!");
    }
    if ((nfile_out > 1) && !bDeMux)
    {
        gmx_fatal(FARGS, "Don't know what to do with more than 1 output file if  not demultiplexing");
    }
    else if (bDeMux && (nfile_out != nset) && (nfile_out != 1))
    {
        gmx_fatal(FARGS, "Number of output files should be 1 or %d (#input files), not %d", nset, nfile_out);
    }
    if (bDeMux)
    {
        if (nfile_out != nset)
        {
            char *buf = gmx_strdup(fnms_out[0]);
            snew(fnms_out, nset);
            for (i = 0; (i < nset); i++)
            {
                snew(fnms_out[i], std::strlen(buf)+32);
                sprintf(fnms_out[i], "%d_%s", i, buf);
            }
            sfree(buf);
        }
        do_demux(nfile_in, fnms, fnms_out, n, val, t, dt_remd, isize, index, dt, oenv);
    }
    else
    {
        snew(readtime, nfile_in+1);
        snew(timest, nfile_in+1);
        scan_trj_files(fnms, nfile_in, readtime, timest, imax, oenv);

        snew(settime, nfile_in+1);
        snew(cont_type, nfile_in+1);
        edit_files(fnms, nfile_in, readtime, timest, settime, cont_type, bSetTime, bSort,
                   oenv);

        /* Check whether the output file is amongst the input files
         * This has to be done after sorting etc.
         */
        out_file = fnms_out[0];
        ftpout   = fn2ftp(out_file);
        n_append = -1;
        for (i = 0; ((i < nfile_in) && (n_append == -1)); i++)
        {
            if (std::strcmp(fnms[i], out_file) == 0)
            {
                n_append = i;
            }
        }
        if (n_append == 0)
        {
            fprintf(stderr, "Will append to %s rather than creating a new file\n",
                    out_file);
        }
        else if (n_append != -1)
        {
            gmx_fatal(FARGS, "Can only append to the first file which is %s (not %s)",
                      fnms[0], out_file);
        }

        /* Not checking input format, could be dangerous :-) */
        /* Not checking output format, equally dangerous :-) */

        frame     = -1;
        frame_out = -1;
        /* the default is not to change the time at all,
         * but this is overridden by the edit_files routine
         */
        t_corr = 0;

        if (n_append == -1)
        {
            if (ftpout == efTNG)
            {
                if (ftpout != ftpin)
                {
                    gmx_fatal(FARGS, "When writing TNG the input file format must also be TNG");
                }
                if (bIndex)
                {
                    trjtools_gmx_prepare_tng_writing(out_file, 'w', NULL, &trxout,
                                                     fnms[0], isize, NULL, index, grpname);
                }
                else
                {
                    trjtools_gmx_prepare_tng_writing(out_file, 'w', NULL, &trxout,
                                                     fnms[0], -1, NULL, NULL, NULL);
                }
            }
            else
            {
                trxout = open_trx(out_file, "w");
            }
            std::memset(&frout, 0, sizeof(frout));
        }
        else
        {
            t_fileio *stfio;

            if (!read_first_frame(oenv, &status, out_file, &fr, FLAGS))
            {
                gmx_fatal(FARGS, "Reading first frame from %s", out_file);
            }

            stfio = trx_get_fileio(status);
            if (!bKeepLast && !bOverwrite)
            {
                fprintf(stderr, "\n\nWARNING: Appending without -overwrite implies -keeplast "
                        "between the first two files. \n"
                        "If the trajectories have an overlap and have not been written binary \n"
                        "reproducible this will produce an incorrect trajectory!\n\n");

                filetype = gmx_fio_getftp(stfio);
                /* Fails if last frame is incomplete
                 * We can't do anything about it without overwriting
                 * */
                if (filetype == efXTC || filetype == efTNG)
                {
                    lasttime = trx_get_time_of_final_frame(status);
                    fr.time  = lasttime;
                }
                else
                {
                    while (read_next_frame(oenv, status, &fr))
                    {
                        ;
                    }
                    lasttime = fr.time;
                }
                lastTimeSet     = TRUE;
                bKeepLastAppend = TRUE;
                close_trj(status);
                trxout = open_trx(out_file, "a");
            }
            else if (bOverwrite)
            {
                if (gmx_fio_getftp(stfio) != efXTC)
                {
                    gmx_fatal(FARGS, "Overwrite only supported for XTC." );
                }
                last_frame_time = trx_get_time_of_final_frame(status);

                /* xtc_seek_time broken for trajectories containing only 1 or 2 frames
                 *     or when seek time = 0 */
                if (nfile_in > 1 && settime[1] < last_frame_time+timest[0]*0.5)
                {
                    /* Jump to one time-frame before the start of next
                     *  trajectory file */
                    searchtime = settime[1]-timest[0]*1.25;
                }
                else
                {
                    searchtime = last_frame_time;
                }
                if (xtc_seek_time(stfio, searchtime, fr.natoms, TRUE))
                {
                    gmx_fatal(FARGS, "Error seeking to append position.");
                }
                read_next_frame(oenv, status, &fr);
                if (std::abs(searchtime - fr.time) > timest[0]*0.5)
                {
                    gmx_fatal(FARGS, "Error seeking: attempted to seek to %f but got %f.",
                              searchtime, fr.time);
                }
                lasttime    = fr.time;
                lastTimeSet = TRUE;
                fpos        = gmx_fio_ftell(stfio);
                close_trj(status);
                trxout = open_trx(out_file, "r+");
                if (gmx_fio_seek(trx_get_fileio(trxout), fpos))
                {
                    gmx_fatal(FARGS, "Error seeking to append position.");
                }
            }
            if (lastTimeSet)
            {
                printf("\n Will append after %f \n", lasttime);
            }
            frout = fr;
        }
        /* Lets stitch up some files */
        timestep = timest[0];
        for (i = n_append+1; (i < nfile_in); i++)
        {
            /* Open next file */

            /* set the next time from the last frame in previous file */
            if (i > 0)
            {
                /* When writing TNG the step determine which frame to write. Use an
                 * offset to be able to increase steps properly when changing files. */
                if (ftpout == efTNG)
                {
                    prevEndStep = frout.step;
                }

                if (frame_out >= 0)
                {
                    if (cont_type[i] == TIME_CONTINUE)
                    {
                        begin        = frout.time;
                        begin       += 0.5*timestep;
                        settime[i]   = frout.time;
                        cont_type[i] = TIME_EXPLICIT;
                    }
                    else if (cont_type[i] == TIME_LAST)
                    {
                        begin  = frout.time;
                        begin += 0.5*timestep;
                    }
                    /* Or, if the time in the next part should be changed by the
                     * same amount, start at half a timestep from the last time
                     * so we dont repeat frames.
                     */
                    /* I don't understand the comment above, but for all the cases
                     * I tried the code seems to work properly. B. Hess 2008-4-2.
                     */
                }
                /* Or, if time is set explicitly, we check for overlap/gap */
                if (cont_type[i] == TIME_EXPLICIT)
                {
                    if ( ( i < nfile_in ) &&
                         ( frout.time < settime[i]-1.5*timestep ) )
                    {
                        fprintf(stderr, "WARNING: Frames around t=%f %s have a different "
                                "spacing than the rest,\n"
                                "might be a gap or overlap that couldn't be corrected "
                                "automatically.\n", output_env_conv_time(oenv, frout.time),
                                output_env_get_time_unit(oenv));
                    }
                }
            }

            /* if we don't have a timestep in the current file, use the old one */
            if (timest[i] != 0)
            {
                timestep = timest[i];
            }
            read_first_frame(oenv, &status, fnms[i], &fr, FLAGS);
            if (!fr.bTime)
            {
                fr.time = 0;
                fprintf(stderr, "\nWARNING: Couldn't find a time in the frame.\n");
            }

            if (cont_type[i] == TIME_EXPLICIT)
            {
                t_corr = settime[i]-fr.time;
            }
            /* t_corr is the amount we want to change the time.
             * If the user has chosen not to change the time for
             * this part of the trajectory t_corr remains at
             * the value it had in the last part, changing this
             * by the same amount.
             * If no value was given for the first trajectory part
             * we let the time start at zero, see the edit_files routine.
             */

            bNewFile = TRUE;

            if (!lastTimeSet)
            {
                lasttime    = 0;
                lastTimeSet = true;
            }
            printf("\n");
            printf("lasttime %g\n", lasttime);

            do
            {
                /* copy the input frame to the output frame */
                frout = fr;
                /* set the new time by adding the correct calculated above */
                frout.time += t_corr;
                if (ftpout == efTNG)
                {
                    frout.step += prevEndStep;
                }
                /* quit if we have reached the end of what should be written */
                if ((end > 0) && (frout.time > end+GMX_REAL_EPS))
                {
                    i = nfile_in;
                    break;
                }

                /* determine if we should write this frame (dt is handled elsewhere) */
                if (bCat) /* write all frames of all files */
                {
                    bWrite = TRUE;
                }
                else if (bKeepLast || (bKeepLastAppend && i == 1))
                /* write till last frame of this traj
                   and skip first frame(s) of next traj */
                {
                    bWrite = ( frout.time > lasttime+0.5*timestep );
                }
                else /* write till first frame of next traj */
                {
                    bWrite = ( frout.time < settime[i+1]-0.5*timestep );
                }

                if (bWrite && (frout.time >= begin) )
                {
                    frame++;
                    if (frame_out == -1)
                    {
                        first_time = frout.time;
                    }
                    lasttime    = frout.time;
                    lastTimeSet = TRUE;
                    if (dt == 0 || bRmod(frout.time, first_time, dt))
                    {
                        frame_out++;
                        last_ok_t = frout.time;
                        if (bNewFile)
                        {
                            fprintf(stderr, "\nContinue writing frames from %s t=%g %s, "
                                    "frame=%d      \n",
                                    fnms[i], output_env_conv_time(oenv, frout.time), output_env_get_time_unit(oenv),
                                    frame);
                            bNewFile = FALSE;
                        }

                        if (bIndex)
                        {
                            write_trxframe_indexed(trxout, &frout, isize, index,
                                                   NULL);
                        }
                        else
                        {
                            write_trxframe(trxout, &frout, NULL);
                        }
                        if ( ((frame % 10) == 0) || (frame < 10) )
                        {
                            fprintf(stderr, " ->  frame %6d time %8.3f %s     \r",
                                    frame_out, output_env_conv_time(oenv, frout.time), output_env_get_time_unit(oenv));
                            fflush(stderr);
                        }
                    }
                }
            }
            while (read_next_frame(oenv, status, &fr));

            close_trj(status);
        }
        if (trxout)
        {
            close_trx(trxout);
        }
        fprintf(stderr, "\nLast frame written was %d, time %f %s\n",
                frame, output_env_conv_time(oenv, last_ok_t), output_env_get_time_unit(oenv));
    }

    return 0;
}
コード例 #19
0
ファイル: gmx_dos.cpp プロジェクト: wangxubo0201/gromacs
int gmx_dos(int argc, char *argv[])
{
    const char         *desc[] = {
        "[THISMODULE] computes the Density of States from a simulations.",
        "In order for this to be meaningful the velocities must be saved",
        "in the trajecotry with sufficiently high frequency such as to cover",
        "all vibrations. For flexible systems that would be around a few fs",
        "between saving. Properties based on the DoS are printed on the",
        "standard output."
        "Note that the density of states is calculated from the mass-weighted",
        "autocorrelation, and by default only from the square of the real",
        "component rather than absolute value. This means the shape can differ",
        "substantially from the plain vibrational power spectrum you can",
        "calculate with gmx velacc."
    };
    const char         *bugs[] = {
        "This program needs a lot of memory: total usage equals the number of atoms times 3 times number of frames times 4 (or 8 when run in double precision)."
    };
    FILE               *fp, *fplog;
    t_topology          top;
    int                 ePBC = -1;
    t_trxframe          fr;
    matrix              box;
    int                 gnx;
    real                t0, t1;
    t_trxstatus        *status;
    int                 nV, nframes, n_alloc, i, j, fftcode, Nmol, Natom;
    double              rho, dt, Vsum, V, tmass, dostot, dos2;
    real              **c1, **dos, mi, beta, bfac, *nu, *tt, stddev, c1j;
    gmx_output_env_t   *oenv;
    gmx_fft_t           fft;
    double              cP, DiffCoeff, Delta, f, y, z, sigHS, Shs, Sig, DoS0, recip_fac;
    double              wCdiff, wSdiff, wAdiff, wEdiff;
    int                 grpNatoms;
    int                *index;
    char               *grpname;
    double              invNormalize;
    gmx_bool            normalizeAutocorrelation;

    static     gmx_bool bVerbose = TRUE, bAbsolute = FALSE, bNormalizeDos = FALSE;
    static     gmx_bool bRecip   = FALSE;
    static     real     Temp     = 298.15, toler = 1e-6;

    t_pargs             pa[]     = {
        {   "-v", FALSE, etBOOL, {&bVerbose},
            "Be loud and noisy."
        },
        {   "-recip", FALSE, etBOOL, {&bRecip},
            "Use cm^-1 on X-axis instead of 1/ps for DoS plots."
        },
        {   "-abs", FALSE, etBOOL, {&bAbsolute},
            "Use the absolute value of the Fourier transform of the VACF as the Density of States. Default is to use the real component only"
        },
        {   "-normdos", FALSE, etBOOL, {&bNormalizeDos},
            "Normalize the DoS such that it adds up to 3N. This should usually not be necessary."
        },
        {   "-T", FALSE, etREAL, {&Temp},
            "Temperature in the simulation"
        },
        {   "-toler", FALSE, etREAL, {&toler},
            "[HIDDEN]Tolerance when computing the fluidicity using bisection algorithm"
        }
    };

    t_filenm            fnm[] = {
        { efTRN, "-f",    NULL,    ffREAD  },
        { efTPR, "-s",    NULL,    ffREAD  },
        { efNDX, NULL,    NULL,    ffOPTRD },
        { efXVG, "-vacf", "vacf",  ffWRITE },
        { efXVG, "-mvacf", "mvacf", ffWRITE },
        { efXVG, "-dos",  "dos",   ffWRITE },
        { efLOG, "-g",    "dos",   ffWRITE },
    };
#define NFILE asize(fnm)
    int                 npargs;
    t_pargs            *ppa;
    const char         *DoSlegend[] = {
        "DoS(v)", "DoS(v)[Solid]", "DoS(v)[Diff]"
    };

    npargs = asize(pa);
    ppa    = add_acf_pargs(&npargs, pa);
    if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME,
                           NFILE, fnm, npargs, ppa, asize(desc), desc,
                           asize(bugs), bugs, &oenv))
    {
        return 0;
    }

    beta = 1/(Temp*BOLTZ);

    fplog = gmx_fio_fopen(ftp2fn(efLOG, NFILE, fnm), "w");
    fprintf(fplog, "Doing density of states analysis based on trajectory.\n");
    please_cite(fplog, "Pascal2011a");
    please_cite(fplog, "Caleman2011b");

    read_tps_conf(ftp2fn(efTPR, NFILE, fnm), &top, &ePBC, NULL, NULL, box, TRUE);

    /* Handle index groups */
    get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &grpNatoms, &index, &grpname);

    V     = det(box);
    tmass = 0;
    for (i = 0; i < grpNatoms; i++)
    {
        tmass += top.atoms.atom[index[i]].m;
    }

    Natom = grpNatoms;
    Nmol  = calcMoleculesInIndexGroup(&top.mols, top.atoms.nr, index, grpNatoms);
    gnx   = Natom*DIM;

    /* 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;
    nframes = 0;
    Vsum    = 0;
    nV      = 0;
    do
    {
        if (fr.bBox)
        {
            V      = det(fr.box);
            Vsum  += V;
            nV++;
        }
        if (nframes >= n_alloc)
        {
            n_alloc += 100;
            for (i = 0; i < gnx; i++)
            {
                srenew(c1[i], n_alloc);
            }
        }
        for (i = 0; i < gnx; i += DIM)
        {
            c1[i+XX][nframes] = fr.v[index[i/DIM]][XX];
            c1[i+YY][nframes] = fr.v[index[i/DIM]][YY];
            c1[i+ZZ][nframes] = fr.v[index[i/DIM]][ZZ];
        }

        t1 = fr.time;

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

    close_trj(status);

    dt = (t1-t0)/(nframes-1);
    if (nV > 0)
    {
        V = Vsum/nV;
    }
    if (bVerbose)
    {
        printf("Going to do %d fourier transforms of length %d. Hang on.\n",
               gnx, nframes);
    }
    /* Unfortunately the -normalize program option for the autocorrelation
     * function calculation is added as a hack with a static variable in the
     * autocorrelation.c source. That would work if we called the normal
     * do_autocorr(), but this routine overrides that by directly calling
     * the low-level functionality. That unfortunately leads to ignoring the
     * default value for the option (which is to normalize).
     * Since the absolute value seems to be important for the subsequent
     * analysis below, we detect the value directly from the option, calculate
     * the autocorrelation without normalization, and then apply the
     * normalization just to the autocorrelation output
     * (or not, if the user asked for a non-normalized autocorrelation).
     */
    normalizeAutocorrelation = opt2parg_bool("-normalize", npargs, ppa);

    /* Note that we always disable normalization here, regardless of user settings */
    low_do_autocorr(NULL, oenv, NULL, nframes, gnx, nframes, c1, dt, eacNormal, 0, FALSE,
                    FALSE, FALSE, -1, -1, 0);
    snew(dos, DOS_NR);
    for (j = 0; (j < DOS_NR); j++)
    {
        snew(dos[j], nframes+4);
    }

    if (bVerbose)
    {
        printf("Going to merge the ACFs into the mass-weighted and plain ACF\n");
    }
    for (i = 0; (i < gnx); i += DIM)
    {
        mi = top.atoms.atom[index[i/DIM]].m;
        for (j = 0; (j < nframes/2); j++)
        {
            c1j            = (c1[i+XX][j] + c1[i+YY][j] + c1[i+ZZ][j]);
            dos[VACF][j]  += c1j/Natom;
            dos[MVACF][j] += mi*c1j;
        }
    }

    fp = xvgropen(opt2fn("-vacf", NFILE, fnm), "Velocity autocorrelation function",
                  "Time (ps)", "C(t)", oenv);
    snew(tt, nframes/2);

    invNormalize = normalizeAutocorrelation ? 1.0/dos[VACF][0] : 1.0;

    for (j = 0; (j < nframes/2); j++)
    {
        tt[j] = j*dt;
        fprintf(fp, "%10g  %10g\n", tt[j], dos[VACF][j] * invNormalize);
    }
    xvgrclose(fp);

    fp = xvgropen(opt2fn("-mvacf", NFILE, fnm), "Mass-weighted velocity autocorrelation function",
                  "Time (ps)", "C(t)", oenv);

    invNormalize = normalizeAutocorrelation ? 1.0/dos[VACF][0] : 1.0;

    for (j = 0; (j < nframes/2); j++)
    {
        fprintf(fp, "%10g  %10g\n", tt[j], dos[MVACF][j] * invNormalize);
    }
    xvgrclose(fp);

    if ((fftcode = gmx_fft_init_1d_real(&fft, nframes/2,
                                        GMX_FFT_FLAG_NONE)) != 0)
    {
        gmx_fatal(FARGS, "gmx_fft_init_1d_real returned %d", fftcode);
    }
    if ((fftcode = gmx_fft_1d_real(fft, GMX_FFT_REAL_TO_COMPLEX,
                                   (void *)dos[MVACF], (void *)dos[DOS])) != 0)
    {
        gmx_fatal(FARGS, "gmx_fft_1d_real returned %d", fftcode);
    }

    /* First compute the DoS */
    /* Magic factor of 8 included now. */
    bfac = 8*dt*beta/2;
    dos2 = 0;
    snew(nu, nframes/4);
    for (j = 0; (j < nframes/4); j++)
    {
        nu[j] = 2*j/(t1-t0);
        dos2 += gmx::square(dos[DOS][2*j]) + gmx::square(dos[DOS][2*j+1]);
        if (bAbsolute)
        {
            dos[DOS][j] = bfac*std::hypot(dos[DOS][2*j], dos[DOS][2*j+1]);
        }
        else
        {
            dos[DOS][j] = bfac*dos[DOS][2*j];
        }
    }
    /* Normalize it */
    dostot = evaluate_integral(nframes/4, nu, dos[DOS], NULL, nframes/4, &stddev);
    if (bNormalizeDos)
    {
        for (j = 0; (j < nframes/4); j++)
        {
            dos[DOS][j] *= 3*Natom/dostot;
        }
    }

    /* Now analyze it */
    DoS0 = dos[DOS][0];

    /* Note this eqn. is incorrect in Pascal2011a! */
    Delta = ((2*DoS0/(9*Natom))*std::sqrt(M_PI*BOLTZ*Temp*Natom/tmass)*
             std::pow((Natom/V), 1.0/3.0)*std::pow(6.0/M_PI, 2.0/3.0));
    f     = calc_fluidicity(Delta, toler);
    y     = calc_y(f, Delta, toler);
    z     = calc_compress(y);
    Sig   = BOLTZ*(5.0/2.0+std::log(2*M_PI*BOLTZ*Temp/(gmx::square(PLANCK))*V/(f*Natom)));
    Shs   = Sig+calc_Shs(f, y);
    rho   = (tmass*AMU)/(V*NANO*NANO*NANO);
    sigHS = std::cbrt(6*y*V/(M_PI*Natom));

    fprintf(fplog, "System = \"%s\"\n", *top.name);
    fprintf(fplog, "Nmol = %d\n", Nmol);
    fprintf(fplog, "Natom = %d\n", Natom);
    fprintf(fplog, "dt = %g ps\n", dt);
    fprintf(fplog, "tmass = %g amu\n", tmass);
    fprintf(fplog, "V = %g nm^3\n", V);
    fprintf(fplog, "rho = %g g/l\n", rho);
    fprintf(fplog, "T = %g K\n", Temp);
    fprintf(fplog, "beta = %g mol/kJ\n", beta);

    fprintf(fplog, "\nDoS parameters\n");
    fprintf(fplog, "Delta = %g\n", Delta);
    fprintf(fplog, "fluidicity = %g\n", f);
    fprintf(fplog, "hard sphere packing fraction = %g\n", y);
    fprintf(fplog, "hard sphere compressibility = %g\n", z);
    fprintf(fplog, "ideal gas entropy = %g\n", Sig);
    fprintf(fplog, "hard sphere entropy = %g\n", Shs);
    fprintf(fplog, "sigma_HS = %g nm\n", sigHS);
    fprintf(fplog, "DoS0 = %g\n", DoS0);
    fprintf(fplog, "Dos2 = %g\n", dos2);
    fprintf(fplog, "DoSTot = %g\n", dostot);

    /* Now compute solid (2) and diffusive (3) components */
    fp = xvgropen(opt2fn("-dos", NFILE, fnm), "Density of states",
                  bRecip ? "E (cm\\S-1\\N)" : "\\f{12}n\\f{4} (1/ps)",
                  "\\f{4}S(\\f{12}n\\f{4})", oenv);
    xvgr_legend(fp, asize(DoSlegend), DoSlegend, oenv);
    recip_fac = bRecip ? (1e7/SPEED_OF_LIGHT) : 1.0;
    for (j = 0; (j < nframes/4); j++)
    {
        dos[DOS_DIFF][j]  = DoS0/(1+gmx::square(DoS0*M_PI*nu[j]/(6*f*Natom)));
        dos[DOS_SOLID][j] = dos[DOS][j]-dos[DOS_DIFF][j];
        fprintf(fp, "%10g  %10g  %10g  %10g\n",
                recip_fac*nu[j],
                dos[DOS][j]/recip_fac,
                dos[DOS_SOLID][j]/recip_fac,
                dos[DOS_DIFF][j]/recip_fac);
    }
    xvgrclose(fp);

    /* Finally analyze the results! */
    wCdiff = 0.5;
    wSdiff = Shs/(3*BOLTZ); /* Is this correct? */
    wEdiff = 0.5;
    wAdiff = wEdiff-wSdiff;
    for (j = 0; (j < nframes/4); j++)
    {
        dos[DOS_CP][j] = (dos[DOS_DIFF][j]*wCdiff +
                          dos[DOS_SOLID][j]*wCsolid(nu[j], beta));
        dos[DOS_S][j]  = (dos[DOS_DIFF][j]*wSdiff +
                          dos[DOS_SOLID][j]*wSsolid(nu[j], beta));
        dos[DOS_A][j]  = (dos[DOS_DIFF][j]*wAdiff +
                          dos[DOS_SOLID][j]*wAsolid(nu[j], beta));
        dos[DOS_E][j]  = (dos[DOS_DIFF][j]*wEdiff +
                          dos[DOS_SOLID][j]*wEsolid(nu[j], beta));
    }
    DiffCoeff = evaluate_integral(nframes/2, tt, dos[VACF], NULL, nframes/2, &stddev);
    DiffCoeff = 1000*DiffCoeff/3.0;
    fprintf(fplog, "Diffusion coefficient from VACF %g 10^-5 cm^2/s\n",
            DiffCoeff);
    fprintf(fplog, "Diffusion coefficient from DoS %g 10^-5 cm^2/s\n",
            1000*DoS0/(12*tmass*beta));

    cP = BOLTZ * evaluate_integral(nframes/4, nu, dos[DOS_CP], NULL,
                                   nframes/4, &stddev);
    fprintf(fplog, "Heat capacity %g J/mol K\n", 1000*cP/Nmol);
    fprintf(fplog, "\nArrivederci!\n");
    gmx_fio_fclose(fplog);

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

    return 0;
}
コード例 #20
0
ファイル: gmx_eneconv.c プロジェクト: dkarkoulis/gromacs
int gmx_eneconv(int argc, char *argv[])
{
    const char     *desc[] = {
        "With [IT]multiple files[it] specified for the [TT]-f[tt] option:[BR]",
        "Concatenates several energy files in sorted order.",
        "In the case of double time frames, the one",
        "in the later file is used. By specifying [TT]-settime[tt] you will be",
        "asked for the start time of each file. The input files are taken",
        "from the command line,",
        "such that the command [TT]gmx eneconv -f *.edr -o fixed.edr[tt] should do",
        "the trick. [PAR]",
        "With [IT]one file[it] specified for [TT]-f[tt]:[BR]",
        "Reads one energy file and writes another, applying the [TT]-dt[tt],",
        "[TT]-offset[tt], [TT]-t0[tt] and [TT]-settime[tt] options and",
        "converting to a different format if necessary (indicated by file",
        "extentions).[PAR]",
        "[TT]-settime[tt] is applied first, then [TT]-dt[tt]/[TT]-offset[tt]",
        "followed by [TT]-b[tt] and [TT]-e[tt] to select which frames to write."
    };
    const char     *bugs[] = {
        "When combining trajectories the sigma and E^2 (necessary for statistics) are not updated correctly. Only the actual energy is correct. One thus has to compute statistics in another way."
    };
    ener_file_t     in  = NULL, out = NULL;
    gmx_enxnm_t    *enm = NULL;
#if 0
    ener_file_t     in, out = NULL;
    gmx_enxnm_t    *enm = NULL;
#endif
    t_enxframe     *fr, *fro;
    gmx_int64_t     ee_sum_step = 0, ee_sum_nsteps, ee_sum_nsum;
    t_energy       *ee_sum;
    gmx_int64_t     lastfilestep, laststep, startstep, startstep_file = 0;
    int             noutfr;
    int             nre, nremax, this_nre, nfile, f, i, j, kkk, nset, *set = NULL;
    double          last_t;
    char          **fnms;
    real           *readtime, *settime, timestep, t1, tadjust;
    char            inputstring[STRLEN], *chptr, buf[22], buf2[22], buf3[22];
    gmx_bool        ok;
    int            *cont_type;
    gmx_bool        bNewFile, bFirst, bNewOutput;
    output_env_t    oenv;
    gmx_bool        warned_about_dh = FALSE;
    t_enxblock     *blocks          = NULL;
    int             nblocks         = 0;
    int             nblocks_alloc   = 0;

    t_filenm        fnm[] = {
        { efEDR, "-f", NULL,    ffRDMULT },
        { efEDR, "-o", "fixed", ffWRITE  },
    };

#define NFILE asize(fnm)
    gmx_bool         bWrite;
    static real      delta_t   = 0.0, toffset = 0, scalefac = 1;
    static gmx_bool  bSetTime  = FALSE;
    static gmx_bool  bSort     = TRUE, bError = TRUE;
    static real      begin     = -1;
    static real      end       = -1;
    gmx_bool         remove_dh = FALSE;

    t_pargs          pa[] = {
        { "-b",        FALSE, etREAL, {&begin},
          "First time to use"},
        { "-e",        FALSE, etREAL, {&end},
          "Last time to use"},
        { "-dt",       FALSE, etREAL, {&delta_t},
          "Only write out frame when t MOD dt = offset" },
        { "-offset",   FALSE, etREAL, {&toffset},
          "Time offset for [TT]-dt[tt] option" },
        { "-settime",  FALSE, etBOOL, {&bSetTime},
          "Change starting time interactively" },
        { "-sort",     FALSE, etBOOL, {&bSort},
          "Sort energy files (not frames)"},
        { "-rmdh",     FALSE, etBOOL, {&remove_dh},
          "Remove free energy block data" },
        { "-scalefac", FALSE, etREAL, {&scalefac},
          "Multiply energy component by this factor" },
        { "-error",    FALSE, etBOOL, {&bError},
          "Stop on errors in the file" }
    };

    if (!parse_common_args(&argc, argv, PCA_BE_NICE, NFILE, fnm, asize(pa),
                           pa, asize(desc), desc, asize(bugs), bugs, &oenv))
    {
        return 0;
    }
    tadjust  = 0;
    nremax   = 0;
    nset     = 0;
    timestep = 0.0;
    snew(fnms, argc);
    lastfilestep = 0;
    laststep     = startstep = 0;

    nfile = opt2fns(&fnms, "-f", NFILE, fnm);

    if (!nfile)
    {
        gmx_fatal(FARGS, "No input files!");
    }

    snew(settime, nfile+1);
    snew(readtime, nfile+1);
    snew(cont_type, nfile+1);

    nre = scan_ene_files(fnms, nfile, readtime, &timestep, &nremax);
    edit_files(fnms, nfile, readtime, settime, cont_type, bSetTime, bSort);

    ee_sum_nsteps = 0;
    ee_sum_nsum   = 0;
    snew(ee_sum, nremax);

    snew(fr, 1);
    snew(fro, 1);
    fro->t   = -1e20;
    fro->nre = nre;
    snew(fro->ener, nremax);

    noutfr = 0;
    bFirst = TRUE;

    last_t = fro->t;
    for (f = 0; f < nfile; f++)
    {
        bNewFile   = TRUE;
        bNewOutput = TRUE;
        in         = open_enx(fnms[f], "r");
        enm        = NULL;
        do_enxnms(in, &this_nre, &enm);
        if (f == 0)
        {
            if (scalefac != 1)
            {
                set = select_it(nre, enm, &nset);
            }

            /* write names to the output file */
            out = open_enx(opt2fn("-o", NFILE, fnm), "w");
            do_enxnms(out, &nre, &enm);
        }

        /* start reading from the next file */
        while ((fro->t <= (settime[f+1] + GMX_REAL_EPS)) &&
               do_enx(in, fr))
        {
            if (bNewFile)
            {
                startstep_file = fr->step;
                tadjust        = settime[f] - fr->t;
                if (cont_type[f+1] == TIME_LAST)
                {
                    settime[f+1]   = readtime[f+1]-readtime[f]+settime[f];
                    cont_type[f+1] = TIME_EXPLICIT;
                }
                bNewFile = FALSE;
            }

            if (tadjust + fr->t <= last_t)
            {
                /* Skip this frame, since we already have it / past it */
                if (debug)
                {
                    fprintf(debug, "fr->step %s, fr->t %.4f\n",
                            gmx_step_str(fr->step, buf), fr->t);
                    fprintf(debug, "tadjust %12.6e + fr->t %12.6e <= t %12.6e\n",
                            tadjust, fr->t, last_t);
                }
                continue;
            }

            fro->step = lastfilestep + fr->step - startstep_file;
            fro->t    = tadjust  + fr->t;

            bWrite = ((begin < 0 || (begin >= 0 && (fro->t >= begin-GMX_REAL_EPS))) &&
                      (end  < 0 || (end  >= 0 && (fro->t <= end  +GMX_REAL_EPS))) &&
                      (fro->t <= settime[f+1]+0.5*timestep));

            if (debug)
            {
                fprintf(debug,
                        "fr->step %s, fr->t %.4f, fro->step %s fro->t %.4f, w %d\n",
                        gmx_step_str(fr->step, buf), fr->t,
                        gmx_step_str(fro->step, buf2), fro->t, bWrite);
            }

            if (bError)
            {
                if ((end > 0) && (fro->t > end+GMX_REAL_EPS))
                {
                    f = nfile;
                    break;
                }
            }

            if (fro->t >= begin-GMX_REAL_EPS)
            {
                if (bFirst)
                {
                    bFirst    = FALSE;
                    startstep = fr->step;
                }
                if (bWrite)
                {
                    update_ee_sum(nre, &ee_sum_step, &ee_sum_nsteps, &ee_sum_nsum, ee_sum,
                                  fr, fro->step);
                }
            }

            /* determine if we should write it */
            if (bWrite && (delta_t == 0 || bRmod(fro->t, toffset, delta_t)))
            {
                laststep = fro->step;
                last_t   = fro->t;
                if (bNewOutput)
                {
                    bNewOutput = FALSE;
                    fprintf(stderr, "\nContinue writing frames from t=%g, step=%s\n",
                            fro->t, gmx_step_str(fro->step, buf));
                }

                /* Copy the energies */
                for (i = 0; i < nre; i++)
                {
                    fro->ener[i].e = fr->ener[i].e;
                }

                fro->nsteps = ee_sum_nsteps;
                fro->dt     = fr->dt;

                if (ee_sum_nsum <= 1)
                {
                    fro->nsum = 0;
                }
                else
                {
                    fro->nsum = gmx_int64_to_int(ee_sum_nsum,
                                                 "energy average summation");
                    /* Copy the energy sums */
                    for (i = 0; i < nre; i++)
                    {
                        fro->ener[i].esum = ee_sum[i].esum;
                        fro->ener[i].eav  = ee_sum[i].eav;
                    }
                }
                /* We wrote the energies, so reset the counts */
                ee_sum_nsteps = 0;
                ee_sum_nsum   = 0;

                if (scalefac != 1)
                {
                    for (kkk = 0; kkk < nset; kkk++)
                    {
                        fro->ener[set[kkk]].e    *= scalefac;
                        if (fro->nsum > 0)
                        {
                            fro->ener[set[kkk]].eav  *= scalefac*scalefac;
                            fro->ener[set[kkk]].esum *= scalefac;
                        }
                    }
                }
                /* Copy restraint stuff */
                /*fro->ndisre       = fr->ndisre;
                   fro->disre_rm3tav = fr->disre_rm3tav;
                   fro->disre_rt     = fr->disre_rt;*/
                fro->nblock       = fr->nblock;
                /*fro->nr           = fr->nr;*/
                fro->block        = fr->block;

                /* check if we have blocks with delta_h data and are throwing
                   away data */
                if (fro->nblock > 0)
                {
                    if (remove_dh)
                    {
                        int i;
                        if (!blocks || nblocks_alloc < fr->nblock)
                        {
                            /* we pre-allocate the blocks */
                            nblocks_alloc = fr->nblock;
                            snew(blocks, nblocks_alloc);
                        }
                        nblocks = 0; /* number of blocks so far */

                        for (i = 0; i < fr->nblock; i++)
                        {
                            if ( (fr->block[i].id != enxDHCOLL) &&
                                 (fr->block[i].id != enxDH) &&
                                 (fr->block[i].id != enxDHHIST) )
                            {
                                /* copy everything verbatim */
                                blocks[nblocks] = fr->block[i];
                                nblocks++;
                            }
                        }
                        /* now set the block pointer to the new blocks */
                        fro->nblock = nblocks;
                        fro->block  = blocks;
                    }
                    else if (delta_t > 0)
                    {
                        if (!warned_about_dh)
                        {
                            for (i = 0; i < fr->nblock; i++)
                            {
                                if (fr->block[i].id == enxDH ||
                                    fr->block[i].id == enxDHHIST)
                                {
                                    int size;
                                    if (fr->block[i].id == enxDH)
                                    {
                                        size = fr->block[i].sub[2].nr;
                                    }
                                    else
                                    {
                                        size = fr->nsteps;
                                    }
                                    if (size > 0)
                                    {
                                        printf("\nWARNING: %s contains delta H blocks or histograms for which\n"
                                               "         some data is thrown away on a block-by-block basis, where each block\n"
                                               "         contains up to %d samples.\n"
                                               "         This is almost certainly not what you want.\n"
                                               "         Use the -rmdh option to throw all delta H samples away.\n"
                                               "         Use g_energy -odh option to extract these samples.\n",
                                               fnms[f], size);
                                        warned_about_dh = TRUE;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }

                do_enx(out, fro);
                if (noutfr % 1000 == 0)
                {
                    fprintf(stderr, "Writing frame time %g    ", fro->t);
                }
                noutfr++;
            }
        }
        if (f == nfile)
        {
            f--;
        }
        printf("\nLast step written from %s: t %g, step %s\n",
               fnms[f], last_t, gmx_step_str(laststep, buf));
        lastfilestep = laststep;

        /* set the next time from the last in previous file */
        if (cont_type[f+1] == TIME_CONTINUE)
        {
            settime[f+1] = fro->t;
            /* in this case we have already written the last frame of
             * previous file, so update begin to avoid doubling it
             * with the start of the next file
             */
            begin = fro->t+0.5*timestep;
            /* cont_type[f+1]==TIME_EXPLICIT; */
        }

        if ((fro->t < end) && (f < nfile-1) &&
            (fro->t < settime[f+1]-1.5*timestep))
        {
            fprintf(stderr,
                    "\nWARNING: There might be a gap around t=%g\n", fro->t);
        }

        /* move energies to lastee */
        close_enx(in);
        free_enxnms(this_nre, enm);

        fprintf(stderr, "\n");
    }
    if (noutfr == 0)
    {
        fprintf(stderr, "No frames written.\n");
    }
    else
    {
        fprintf(stderr, "Last frame written was at step %s, time %f\n",
                gmx_step_str(fro->step, buf), fro->t);
        fprintf(stderr, "Wrote %d frames\n", noutfr);
    }

    return 0;
}
コード例 #21
0
ファイル: gmx_tcaf.cpp プロジェクト: rmcgibbo/gromacs
int gmx_tcaf(int argc, char *argv[])
{
    const char       *desc[] = {
        "[THISMODULE] computes tranverse current autocorrelations.",
        "These are used to estimate the shear viscosity, [GRK]eta[grk].",
        "For details see: Palmer, Phys. Rev. E 49 (1994) pp 359-366.[PAR]",
        "Transverse currents are calculated using the",
        "k-vectors (1,0,0) and (2,0,0) each also in the [IT]y[it]- and [IT]z[it]-direction,",
        "(1,1,0) and (1,-1,0) each also in the 2 other planes (these vectors",
        "are not independent) and (1,1,1) and the 3 other box diagonals (also",
        "not independent). For each k-vector the sine and cosine are used, in",
        "combination with the velocity in 2 perpendicular directions. This gives",
        "a total of 16*2*2=64 transverse currents. One autocorrelation is",
        "calculated fitted for each k-vector, which gives 16 TCAFs. Each of",
        "these TCAFs is fitted to [MATH]f(t) = [EXP]-v[exp]([COSH]Wv[cosh] + 1/W [SINH]Wv[sinh])[math],",
        "[MATH]v = -t/(2 [GRK]tau[grk])[math], [MATH]W = [SQRT]1 - 4 [GRK]tau[grk] [GRK]eta[grk]/[GRK]rho[grk] k^2[sqrt][math], which gives 16 values of [GRK]tau[grk]",
        "and [GRK]eta[grk]. The fit weights decay exponentially with time constant [MATH]w[math] (given with [TT]-wt[tt]) as [MATH][EXP]-t/w[exp][math], and the TCAF and",
        "fit are calculated up to time [MATH]5*w[math].",
        "The [GRK]eta[grk] values should be fitted to [MATH]1 - a [GRK]eta[grk](k) k^2[math], from which",
        "one can estimate the shear viscosity at k=0.[PAR]",
        "When the box is cubic, one can use the option [TT]-oc[tt], which",
        "averages the TCAFs over all k-vectors with the same length.",
        "This results in more accurate TCAFs.",
        "Both the cubic TCAFs and fits are written to [TT]-oc[tt]",
        "The cubic [GRK]eta[grk] estimates are also written to [TT]-ov[tt].[PAR]",
        "With option [TT]-mol[tt], the transverse current is determined of",
        "molecules instead of atoms. In this case, the index group should",
        "consist of molecule numbers instead of atom numbers.[PAR]",
        "The k-dependent viscosities in the [TT]-ov[tt] file should be",
        "fitted to [MATH][GRK]eta[grk](k) = [GRK]eta[grk][SUB]0[sub] (1 - a k^2)[math] to obtain the viscosity at",
        "infinite wavelength.[PAR]",
        "[BB]Note:[bb] make sure you write coordinates and velocities often enough.",
        "The initial, non-exponential, part of the autocorrelation function",
        "is very important for obtaining a good fit."
    };

    static gmx_bool   bMol = FALSE, bK34 = FALSE;
    static real       wt   = 5;
    t_pargs           pa[] = {
        { "-mol", FALSE, etBOOL, {&bMol},
          "Calculate TCAF of molecules" },
        { "-k34", FALSE, etBOOL, {&bK34},
          "Also use k=(3,0,0) and k=(4,0,0)" },
        { "-wt", FALSE, etREAL, {&wt},
          "Exponential decay time for the TCAF fit weights" }
    };

    t_topology        top;
    int               ePBC;
    t_trxframe        fr;
    matrix            box;
    gmx_bool          bTop;
    int               gnx;
    atom_id          *index, *atndx = NULL, at;
    char             *grpname;
    char              title[256];
    real              t0, t1, dt, m, mtot, sysmass, rho, sx, cx;
    t_trxstatus      *status;
    int               nframes, n_alloc, i, j, k, d;
    rvec              mv_mol, cm_mol, kfac[NK];
    int               nkc, nk, ntc;
    real            **tc;
    gmx_output_env_t *oenv;

#define NHISTO 360

    t_filenm  fnm[] = {
        { efTRN, "-f",    NULL,      ffREAD  },
        { efTPS, NULL,    NULL,      ffOPTRD },
        { efNDX, NULL,    NULL,      ffOPTRD },
        { efXVG, "-ot",  "transcur", ffOPTWR },
        { efXVG, "-oa",  "tcaf_all", ffWRITE },
        { efXVG, "-o",   "tcaf",     ffWRITE },
        { efXVG, "-of",  "tcaf_fit", ffWRITE },
        { efXVG, "-oc",  "tcaf_cub", ffOPTWR },
        { efXVG, "-ov",  "visc_k",   ffWRITE }
    };
#define NFILE asize(fnm)
    int       npargs;
    t_pargs  *ppa;

    npargs = asize(pa);
    ppa    = add_acf_pargs(&npargs, pa);

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

    bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, NULL, NULL, box,
                         TRUE);
    get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &gnx, &index, &grpname);

    if (bMol)
    {
        if (!bTop)
        {
            gmx_fatal(FARGS, "Need a topology to determine the molecules");
        }
        atndx = top.mols.index;
    }

    if (bK34)
    {
        nkc = NKC;
    }
    else
    {
        nkc = NKC0;
    }
    nk  = kset_c[nkc];
    ntc = nk*NPK;

    sprintf(title, "Velocity Autocorrelation Function for %s", grpname);

    sysmass = 0;
    for (i = 0; i < nk; i++)
    {
        if (iprod(v0[i], v1[i]) != 0)
        {
            gmx_fatal(FARGS, "DEATH HORROR: vectors not orthogonal");
        }
        if (iprod(v0[i], v2[i]) != 0)
        {
            gmx_fatal(FARGS, "DEATH HORROR: vectors not orthogonal");
        }
        if (iprod(v1[i], v2[i]) != 0)
        {
            gmx_fatal(FARGS, "DEATH HORROR: vectors not orthogonal");
        }
        unitv(v1[i], v1[i]);
        unitv(v2[i], v2[i]);
    }
    snew(tc, ntc);
    for (i = 0; i < top.atoms.nr; i++)
    {
        sysmass += top.atoms.atom[i].m;
    }

    read_first_frame(oenv, &status, ftp2fn(efTRN, NFILE, fnm), &fr,
                     TRX_NEED_X | TRX_NEED_V);
    t0 = fr.time;

    n_alloc = 0;
    nframes = 0;
    rho     = 0;

    do
    {

        if (nframes >= n_alloc)
        {
            n_alloc += 100;
            for (i = 0; i < ntc; i++)
            {
                srenew(tc[i], n_alloc);
            }
        }

        rho += 1/det(fr.box);
        for (k = 0; k < nk; k++)
        {
            for (d = 0; d < DIM; d++)
            {
                kfac[k][d] = 2*M_PI*v0[k][d]/fr.box[d][d];
            }
        }
        for (i = 0; i < ntc; i++)
        {
            tc[i][nframes] = 0;
        }

        for (i = 0; i < gnx; i++)
        {
            if (bMol)
            {
                clear_rvec(mv_mol);
                clear_rvec(cm_mol);
                mtot = 0;
                for (j = 0; j < atndx[index[i]+1] - atndx[index[i]]; j++)
                {
                    at          = atndx[index[i]] + j;
                    m           = top.atoms.atom[at].m;
                    mv_mol[XX] += m*fr.v[at][XX];
                    mv_mol[YY] += m*fr.v[at][YY];
                    mv_mol[ZZ] += m*fr.v[at][ZZ];
                    cm_mol[XX] += m*fr.x[at][XX];
                    cm_mol[YY] += m*fr.x[at][YY];
                    cm_mol[ZZ] += m*fr.x[at][ZZ];
                    mtot       += m;
                }
                svmul(1.0/mtot, cm_mol, cm_mol);
            }
            else
            {
                svmul(top.atoms.atom[index[i]].m, fr.v[index[i]], mv_mol);
            }

            if (!bMol)
            {
                copy_rvec(fr.x[index[i]], cm_mol);
            }
            j = 0;
            for (k = 0; k < nk; k++)
            {
                sx              = std::sin(iprod(kfac[k], cm_mol));
                cx              = std::cos(iprod(kfac[k], cm_mol));
                tc[j][nframes] += sx*iprod(v1[k], mv_mol);
                j++;
                tc[j][nframes] += cx*iprod(v1[k], mv_mol);
                j++;
                tc[j][nframes] += sx*iprod(v2[k], mv_mol);
                j++;
                tc[j][nframes] += cx*iprod(v2[k], mv_mol);
                j++;
            }
        }

        t1 = fr.time;
        nframes++;
    }
    while (read_next_frame(oenv, status, &fr));
    close_trj(status);

    dt = (t1-t0)/(nframes-1);

    rho *= sysmass/nframes*AMU/(NANO*NANO*NANO);
    fprintf(stdout, "Density = %g (kg/m^3)\n", rho);
    process_tcaf(nframes, dt, nkc, tc, kfac, rho, wt,
                 opt2fn_null("-ot", NFILE, fnm),
                 opt2fn("-oa", NFILE, fnm), opt2fn("-o", NFILE, fnm),
                 opt2fn("-of", NFILE, fnm), opt2fn_null("-oc", NFILE, fnm),
                 opt2fn("-ov", NFILE, fnm), oenv);

    return 0;
}
コード例 #22
0
ファイル: gmx_order.c プロジェクト: alwanderer/gromacs
int gmx_order(int argc, char *argv[])
{
    const char        *desc[] = {
        "Compute 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]",
        "The program 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;

    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 (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 */
    }

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

    return 0;
}
コード例 #23
0
int gmx_dielectric(int argc,char *argv[])
{
  const char *desc[] = {
    "[TT]g_dielectric[tt] calculates frequency dependent dielectric constants",
    "from the autocorrelation function of the total dipole moment in",
    "your simulation. This ACF can be generated by [TT]g_dipoles[tt].",
    "The functional forms of the available functions are:[PAR]",
    "One parameter:    y = Exp[-a1 x],[BR]",
    "Two parameters:   y = a2 Exp[-a1 x],[BR]",
    "Three parameters: y = a2 Exp[-a1 x] + (1 - a2) Exp[-a3 x].[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,*fitparms,fac,rffac;
  double **yd;
  real   **y;
  const char *legend[] = { "Correlation", "Std. Dev.", "Fit", "Combined", "Derivative" };
  static int fix=0,bFour = 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[] = {
    { "-fft", FALSE, etBOOL, {&bFour},
      "use fast fourier transform for correlation function" },
    { "-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" }
  };
  
  CopyRight(stderr,argv[0]);
  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);
  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 = nfp_ffn[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");
	    
  thanx(stderr);

  return 0;
}
コード例 #24
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.",
        "[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 an index is larger than the number of 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[] =
    { NULL, "triclinic", "cubic", "dodecahedron", "octahedron", NULL },
    *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 }, "Coordinates of geometrical center" },
        { "-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    = NULL, c6, c12;
    int           *bfac_nr = NULL;
    t_topology    *top     = NULL;
    char          *grpname, *sgrpname, *agrpname;
    int            isize, ssize, asize;
    atom_id       *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;
    output_env_t   oenv;
    t_filenm       fnm[] =
    {
        { efSTX, "-f", NULL, ffREAD },
        { efNDX, "-n", NULL, ffOPTRD },
        { efSTO, NULL, NULL, 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] != NULL, "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 == NULL)
    {
        snew(atoms.pdbinfo, atoms.nr);
    }
    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, NULL);
    }

    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*std::pow(sig6, static_cast<real>(1.0/6.0));
                }
                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 = NULL;
        }
        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*std::acos(cos_angle_no_table(box[YY], box[ZZ])),
               norm2(box[ZZ]) == 0 ? 0 :
               RAD2DEG*std::acos(cos_angle_no_table(box[XX], box[ZZ])),
               norm2(box[YY]) == 0 ? 0 :
               RAD2DEG*std::acos(cos_angle_no_table(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)
    {
        atom_id *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 : NULL, NULL);
        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::pow(dens/rho, static_cast<real>(1.0/3.0));
            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, &asize, &aindex, &agrpname);
        }
        else
        {
            asize = atoms.nr;
            snew(aindex, asize);
            for (i = 0; i < asize; i++)
            {
                aindex[i] = i;
            }
        }
        printf("Aligning %d atoms (out of %d) to %g %g %g, center of rotation %g %g %g\n", asize, natom,
               targetvec[XX], targetvec[YY], targetvec[ZZ],
               aligncenter[XX], aligncenter[YY], aligncenter[ZZ]);
        /*subtract out pivot point*/
        for (i = 0; i < asize; i++)
        {
            rvec_dec(x[aindex[i]], aligncenter);
        }
        /*now determine transform and rotate*/
        /*will this work?*/
        principal_comp(asize, 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 < asize; ++i)
        {
            mvmul(rotmatrix, x[aindex[i]], tmpvec);
            copy_rvec(tmpvec, x[aindex[i]]);
        }

        /*add pivot point back*/
        for (i = 0; i < asize; 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 = NULL;
        }
        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] != NULL) && (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*std::acos(cos_angle_no_table(box[YY], box[ZZ])),
               norm2(box[ZZ]) == 0 ? 0 :
               RAD2DEG*std::acos(cos_angle_no_table(box[XX], box[ZZ])),
               norm2(box[YY]) == 0 ? 0 :
               RAD2DEG*std::acos(cos_angle_no_table(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 = NULL;
    }

    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);
            gmx_ffclose(out);
        }
        else
        {
            write_sto_conf_indexed(outfile, *top_tmp->name, &atoms, x, bHaveV ? v : NULL, ePBC, box, isize, index);
        }
    }
    else
    {
        if (resnr_start >= 0)
        {
            renum_resnr(&atoms, atoms.nr, NULL, 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];
                }
            }
            write_pdbfile(out, *top_tmp->name, &atoms, x, ePBC, box, ' ', -1, conect, TRUE);
            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 : NULL, ePBC, box);
        }
    }
    gmx_atomprop_destroy(aps);

    do_view(oenv, outfile, NULL);

    return 0;
}
コード例 #25
0
ファイル: gmx_vanhove.c プロジェクト: alwanderer/gromacs
int gmx_vanhove(int argc, char *argv[])
{
    const char *desc[] = {
        "[TT]g_vanhove[tt] computes the Van Hove correlation function.",
        "The Van Hove G(r,t) is the probability that a particle that is at r[SUB]0[sub]",
        "at time zero can be found at position r[SUB]0[sub]+r at time t.",
        "[TT]g_vanhove[tt] determines G not for a vector r, but for the length of r.",
        "Thus it gives the probability that a particle moves a distance of r",
        "in time t.",
        "Jumps across the periodic boundaries are removed.",
        "Corrections are made for scaling due to isotropic",
        "or anisotropic pressure coupling.",
        "[PAR]",
        "With option [TT]-om[tt] the whole matrix can be written as a function",
        "of t and r or as a function of [SQRT]t[sqrt] and r (option [TT]-sqrt[tt]).",
        "[PAR]",
        "With option [TT]-or[tt] the Van Hove function is plotted for one",
        "or more values of t. Option [TT]-nr[tt] sets the number of times,",
        "option [TT]-fr[tt] the number spacing between the times.",
        "The binwidth is set with option [TT]-rbin[tt]. The number of bins",
        "is determined automatically.",
        "[PAR]",
        "With option [TT]-ot[tt] the integral up to a certain distance",
        "(option [TT]-rt[tt]) is plotted as a function of time.",
        "[PAR]",
        "For all frames that are read the coordinates of the selected particles",
        "are stored in memory. Therefore the program may use a lot of memory.",
        "For options [TT]-om[tt] and [TT]-ot[tt] the program may be slow.",
        "This is because the calculation scales as the number of frames times",
        "[TT]-fm[tt] or [TT]-ft[tt].",
        "Note that with the [TT]-dt[tt] option the memory usage and calculation",
        "time can be reduced."
    };
    static int  fmmax = 0, ftmax = 0, nlev = 81, nr = 1, fshift = 0;
    static real sbin  = 0, rmax = 2, rbin = 0.01, mmax = 0, rint = 0;
    t_pargs     pa[]  = {
        { "-sqrt",    FALSE, etREAL, {&sbin},
          "Use [SQRT]t[sqrt] on the matrix axis which binspacing # in [SQRT]ps[sqrt]" },
        { "-fm",      FALSE, etINT, {&fmmax},
          "Number of frames in the matrix, 0 is plot all" },
        { "-rmax",    FALSE, etREAL, {&rmax},
          "Maximum r in the matrix (nm)" },
        { "-rbin",    FALSE, etREAL, {&rbin},
          "Binwidth in the matrix and for [TT]-or[tt] (nm)" },
        { "-mmax",    FALSE, etREAL, {&mmax},
          "Maximum density in the matrix, 0 is calculate (1/nm)" },
        { "-nlevels", FALSE, etINT,  {&nlev},
          "Number of levels in the matrix" },
        { "-nr",      FALSE, etINT, {&nr},
          "Number of curves for the [TT]-or[tt] output" },
        { "-fr",      FALSE, etINT, {&fshift},
          "Frame spacing for the [TT]-or[tt] output" },
        { "-rt",      FALSE, etREAL, {&rint},
          "Integration limit for the [TT]-ot[tt] output (nm)" },
        { "-ft",      FALSE, etINT, {&ftmax},
          "Number of frames in the [TT]-ot[tt] output, 0 is plot all" }
    };
#define NPA asize(pa)

    t_filenm fnm[] = {
        { efTRX, NULL, NULL,  ffREAD },
        { efTPS, NULL, NULL,  ffREAD },
        { efNDX, NULL, NULL,  ffOPTRD },
        { efXPM, "-om", "vanhove", ffOPTWR },
        { efXVG, "-or", "vanhove_r", ffOPTWR },
        { efXVG, "-ot", "vanhove_t", ffOPTWR }
    };
#define NFILE asize(fnm)

    output_env_t oenv;
    const char  *matfile, *otfile, *orfile;
    char         title[256];
    t_topology   top;
    int          ePBC;
    matrix       boxtop, box, *sbox, avbox, corr;
    rvec        *xtop, *x, **sx;
    int          isize, nalloc, nallocn, natom;
    t_trxstatus *status;
    atom_id     *index;
    char        *grpname;
    int          nfr, f, ff, i, m, mat_nx = 0, nbin = 0, bin, mbin, fbin;
    real        *time, t, invbin = 0, rmax2 = 0, rint2 = 0, d2;
    real         invsbin = 0, matmax, normfac, dt, *tickx, *ticky;
    char         buf[STRLEN], **legend;
    real       **mat = NULL;
    int         *pt  = NULL, **pr = NULL, *mcount = NULL, *tcount = NULL, *rcount = NULL;
    FILE        *fp;
    t_rgb        rlo = {1, 1, 1}, rhi = {0, 0, 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);

    matfile = opt2fn_null("-om", NFILE, fnm);
    if (opt2parg_bSet("-fr", NPA, pa))
    {
        orfile  = opt2fn("-or", NFILE, fnm);
    }
    else
    {
        orfile  = opt2fn_null("-or", NFILE, fnm);
    }
    if (opt2parg_bSet("-rt", NPA, pa))
    {
        otfile  = opt2fn("-ot", NFILE, fnm);
    }
    else
    {
        otfile  = opt2fn_null("-ot", NFILE, fnm);
    }

    if (!matfile && !otfile && !orfile)
    {
        fprintf(stderr,
                "For output set one (or more) of the output file options\n");
        exit(0);
    }

    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), title, &top, &ePBC, &xtop, NULL, boxtop,
                  FALSE);
    get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, &grpname);

    nalloc = 0;
    time   = NULL;
    sbox   = NULL;
    sx     = NULL;
    clear_mat(avbox);

    natom = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);
    nfr   = 0;
    do
    {
        if (nfr >= nalloc)
        {
            nalloc += 100;
            srenew(time, nalloc);
            srenew(sbox, nalloc);
            srenew(sx, nalloc);
        }

        time[nfr] = t;
        copy_mat(box, sbox[nfr]);
        /* This assumes that the off-diagonal box elements
         * are not affected by jumps across the periodic boundaries.
         */
        m_add(avbox, box, avbox);
        snew(sx[nfr], isize);
        for (i = 0; i < isize; i++)
        {
            copy_rvec(x[index[i]], sx[nfr][i]);
        }

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

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

    fprintf(stderr, "Read %d frames\n", nfr);

    dt = (time[nfr-1] - time[0])/(nfr - 1);
    /* Some ugly rounding to get nice nice times in the output */
    dt = (int)(10000.0*dt + 0.5)/10000.0;

    invbin = 1.0/rbin;

    if (matfile)
    {
        if (fmmax <= 0 || fmmax >= nfr)
        {
            fmmax = nfr - 1;
        }
        snew(mcount, fmmax);
        nbin = (int)(rmax*invbin + 0.5);
        if (sbin == 0)
        {
            mat_nx = fmmax + 1;
        }
        else
        {
            invsbin = 1.0/sbin;
            mat_nx  = sqrt(fmmax*dt)*invsbin + 1;
        }
        snew(mat, mat_nx);
        for (f = 0; f < mat_nx; f++)
        {
            snew(mat[f], nbin);
        }
        rmax2 = sqr(nbin*rbin);
        /* Initialize time zero */
        mat[0][0]  = nfr*isize;
        mcount[0] += nfr;
    }
    else
    {
        fmmax = 0;
    }

    if (orfile)
    {
        snew(pr, nr);
        nalloc = 0;
        snew(rcount, nr);
    }

    if (otfile)
    {
        if (ftmax <= 0)
        {
            ftmax = nfr - 1;
        }
        snew(tcount, ftmax);
        snew(pt, nfr);
        rint2 = rint*rint;
        /* Initialize time zero */
        pt[0]      = nfr*isize;
        tcount[0] += nfr;
    }
    else
    {
        ftmax = 0;
    }

    msmul(avbox, 1.0/nfr, avbox);
    for (f = 0; f < nfr; f++)
    {
        if (f % 100 == 0)
        {
            fprintf(stderr, "\rProcessing frame %d", f);
        }
        /* Scale all the configuration to the average box */
        m_inv_ur0(sbox[f], corr);
        mmul_ur0(avbox, corr, corr);
        for (i = 0; i < isize; i++)
        {
            mvmul_ur0(corr, sx[f][i], sx[f][i]);
            if (f > 0)
            {
                /* Correct for periodic jumps */
                for (m = DIM-1; m >= 0; m--)
                {
                    while (sx[f][i][m] - sx[f-1][i][m] > 0.5*avbox[m][m])
                    {
                        rvec_dec(sx[f][i], avbox[m]);
                    }
                    while (sx[f][i][m] - sx[f-1][i][m] <= -0.5*avbox[m][m])
                    {
                        rvec_inc(sx[f][i], avbox[m]);
                    }
                }
            }
        }
        for (ff = 0; ff < f; ff++)
        {
            fbin = f - ff;
            if (fbin <= fmmax || fbin <= ftmax)
            {
                if (sbin == 0)
                {
                    mbin = fbin;
                }
                else
                {
                    mbin = (int)(sqrt(fbin*dt)*invsbin + 0.5);
                }
                for (i = 0; i < isize; i++)
                {
                    d2 = distance2(sx[f][i], sx[ff][i]);
                    if (mbin < mat_nx && d2 < rmax2)
                    {
                        bin = (int)(sqrt(d2)*invbin + 0.5);
                        if (bin < nbin)
                        {
                            mat[mbin][bin] += 1;
                        }
                    }
                    if (fbin <= ftmax && d2 <= rint2)
                    {
                        pt[fbin]++;
                    }
                }
                if (matfile)
                {
                    mcount[mbin]++;
                }
                if (otfile)
                {
                    tcount[fbin]++;
                }
            }
        }
        if (orfile)
        {
            for (fbin = 0; fbin < nr; fbin++)
            {
                ff = f - (fbin + 1)*fshift;
                if (ff >= 0)
                {
                    for (i = 0; i < isize; i++)
                    {
                        d2  = distance2(sx[f][i], sx[ff][i]);
                        bin = (int)(sqrt(d2)*invbin);
                        if (bin >= nalloc)
                        {
                            nallocn = 10*(bin/10) + 11;
                            for (m = 0; m < nr; m++)
                            {
                                srenew(pr[m], nallocn);
                                for (i = nalloc; i < nallocn; i++)
                                {
                                    pr[m][i] = 0;
                                }
                            }
                            nalloc = nallocn;
                        }
                        pr[fbin][bin]++;
                    }
                    rcount[fbin]++;
                }
            }
        }
    }
    fprintf(stderr, "\n");

    if (matfile)
    {
        matmax = 0;
        for (f = 0; f < mat_nx; f++)
        {
            normfac = 1.0/(mcount[f]*isize*rbin);
            for (i = 0; i < nbin; i++)
            {
                mat[f][i] *= normfac;
                if (mat[f][i] > matmax && (f != 0 || i != 0))
                {
                    matmax = mat[f][i];
                }
            }
        }
        fprintf(stdout, "Value at (0,0): %.3f, maximum of the rest %.3f\n",
                mat[0][0], matmax);
        if (mmax > 0)
        {
            matmax = mmax;
        }
        snew(tickx, mat_nx);
        for (f = 0; f < mat_nx; f++)
        {
            if (sbin == 0)
            {
                tickx[f] = f*dt;
            }
            else
            {
                tickx[f] = f*sbin;
            }
        }
        snew(ticky, nbin+1);
        for (i = 0; i <= nbin; i++)
        {
            ticky[i] = i*rbin;
        }
        fp = ffopen(matfile, "w");
        write_xpm(fp, MAT_SPATIAL_Y, "Van Hove function", "G (1/nm)",
                  sbin == 0 ? "time (ps)" : "sqrt(time) (ps^1/2)", "r (nm)",
                  mat_nx, nbin, tickx, ticky, mat, 0, matmax, rlo, rhi, &nlev);
        ffclose(fp);
    }

    if (orfile)
    {
        fp = xvgropen(orfile, "Van Hove function", "r (nm)", "G (nm\\S-1\\N)", oenv);
        fprintf(fp, "@ subtitle \"for particles in group %s\"\n", grpname);
        snew(legend, nr);
        for (fbin = 0; fbin < nr; fbin++)
        {
            sprintf(buf, "%g ps", (fbin + 1)*fshift*dt);
            legend[fbin] = strdup(buf);
        }
        xvgr_legend(fp, nr, (const char**)legend, oenv);
        for (i = 0; i < nalloc; i++)
        {
            fprintf(fp, "%g", i*rbin);
            for (fbin = 0; fbin < nr; fbin++)
            {
                fprintf(fp, " %g",
                        (real)pr[fbin][i]/(rcount[fbin]*isize*rbin*(i == 0 ? 0.5 : 1)));
            }
            fprintf(fp, "\n");
        }
        ffclose(fp);
    }

    if (otfile)
    {
        sprintf(buf, "Probability of moving less than %g nm", rint);
        fp = xvgropen(otfile, buf, "t (ps)", "", oenv);
        fprintf(fp, "@ subtitle \"for particles in group %s\"\n", grpname);
        for (f = 0; f <= ftmax; f++)
        {
            fprintf(fp, "%g %g\n", f*dt, (real)pt[f]/(tcount[f]*isize));
        }
        ffclose(fp);
    }

    do_view(oenv, matfile, NULL);
    do_view(oenv, orfile, NULL);
    do_view(oenv, otfile, NULL);

    thanx(stderr);

    return 0;
}
コード例 #26
0
ファイル: gmx_gyrate.c プロジェクト: alwanderer/gromacs
int gmx_gyrate(int argc, char *argv[])
{
    const char     *desc[] = {
        "[TT]g_gyrate[tt] computes the radius of gyration of a group of atoms",
        "and the radii of gyration about the [IT]x[it]-, [IT]y[it]- and [IT]z[it]-axes,",
        "as a function of time. The atoms are explicitly mass weighted.[PAR]",
        "With the [TT]-nmol[tt] option the radius of gyration will be calculated",
        "for multiple molecules by splitting the analysis group in equally",
        "sized parts.[PAR]",
        "With the option [TT]-nz[tt] 2D radii of gyration in the [IT]x-y[it] plane",
        "of slices along the [IT]z[it]-axis are calculated."
    };
    static int      nmol = 1, nz = 0;
    static gmx_bool bQ   = FALSE, bRot = FALSE, bMOI = FALSE;
    t_pargs         pa[] = {
        { "-nmol", FALSE, etINT, {&nmol},
          "The number of molecules to analyze" },
        { "-q", FALSE, etBOOL, {&bQ},
          "Use absolute value of the charge of an atom as weighting factor instead of mass" },
        { "-p", FALSE, etBOOL, {&bRot},
          "Calculate the radii of gyration about the principal axes." },
        { "-moi", FALSE, etBOOL, {&bMOI},
          "Calculate the moments of inertia (defined by the principal axes)." },
        { "-nz", FALSE, etINT, {&nz},
          "Calculate the 2D radii of gyration of this number of slices along the z-axis" },
    };
    FILE           *out;
    t_trxstatus    *status;
    t_topology      top;
    int             ePBC;
    rvec           *x, *x_s;
    rvec            xcm, gvec, gvec1;
    matrix          box, trans;
    gmx_bool        bACF;
    real          **moi_trans = NULL;
    int             max_moi   = 0, delta_moi = 100;
    rvec            d, d1; /* eigenvalues of inertia tensor */
    real            t, t0, tm, gyro;
    int             natoms;
    char           *grpname, title[256];
    int             i, j, m, gnx, nam, mol;
    atom_id        *index;
    output_env_t    oenv;
    gmx_rmpbc_t     gpbc   = NULL;
    const char     *leg[]  = { "Rg", "RgX", "RgY", "RgZ" };
    const char     *legI[] = { "Itot", "I1", "I2", "I3" };
#define NLEG asize(leg)
    t_filenm        fnm[] = {
        { efTRX, "-f",   NULL,       ffREAD },
        { efTPS, NULL,   NULL,       ffREAD },
        { efNDX, NULL,   NULL,       ffOPTRD },
        { efXVG, NULL,   "gyrate",   ffWRITE },
        { efXVG, "-acf", "moi-acf",  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_TIME | PCA_CAN_VIEW | PCA_BE_NICE,
                      NFILE, fnm, npargs, ppa, asize(desc), desc, 0, NULL, &oenv);
    bACF = opt2bSet("-acf", NFILE, fnm);
    if (bACF && nmol != 1)
    {
        gmx_fatal(FARGS, "Can only do acf with nmol=1");
    }
    bRot = bRot || bMOI || bACF;
    /*
       if (nz > 0)
       bMOI = TRUE;
     */
    if (bRot)
    {
        printf("Will rotate system along principal axes\n");
        snew(moi_trans, DIM);
    }
    if (bMOI)
    {
        printf("Will print moments of inertia\n");
        bQ = FALSE;
    }
    if (bQ)
    {
        printf("Will print radius normalised by charge\n");
    }

    read_tps_conf(ftp2fn(efTPS, NFILE, fnm), title, &top, &ePBC, &x, NULL, box, TRUE);
    get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &gnx, &index, &grpname);

    if (nmol > gnx || gnx % nmol != 0)
    {
        gmx_fatal(FARGS, "The number of atoms in the group (%d) is not a multiple of nmol (%d)", gnx, nmol);
    }
    nam = gnx/nmol;

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

    j  = 0;
    t0 = t;
    if (bQ)
    {
        out = xvgropen(ftp2fn(efXVG, NFILE, fnm),
                       "Radius of Charge", "Time (ps)", "Rg (nm)", oenv);
    }
    else if (bMOI)
    {
        out = xvgropen(ftp2fn(efXVG, NFILE, fnm),
                       "Moments of inertia", "Time (ps)", "I (a.m.u. nm\\S2\\N)", oenv);
    }
    else
    {
        out = xvgropen(ftp2fn(efXVG, NFILE, fnm),
                       "Radius of gyration", "Time (ps)", "Rg (nm)", oenv);
    }
    if (bMOI)
    {
        xvgr_legend(out, NLEG, legI, oenv);
    }
    else
    {
        if (bRot)
        {
            if (output_env_get_print_xvgr_codes(oenv))
            {
                fprintf(out, "@ subtitle \"Axes are principal component axes\"\n");
            }
        }
        xvgr_legend(out, NLEG, leg, oenv);
    }
    if (nz == 0)
    {
        gpbc = gmx_rmpbc_init(&top.idef, ePBC, natoms, box);
    }
    do
    {
        if (nz == 0)
        {
            gmx_rmpbc_copy(gpbc, natoms, box, x, x_s);
        }
        gyro = 0;
        clear_rvec(gvec);
        clear_rvec(d);
        for (mol = 0; mol < nmol; mol++)
        {
            tm    = sub_xcm(nz == 0 ? x_s : x, nam, index+mol*nam, top.atoms.atom, xcm, bQ);
            if (nz == 0)
            {
                gyro += calc_gyro(x_s, nam, index+mol*nam, top.atoms.atom,
                                  tm, gvec1, d1, bQ, bRot, bMOI, trans);
            }
            else
            {
                calc_gyro_z(x, box, nam, index+mol*nam, top.atoms.atom, nz, t, out);
            }
            rvec_inc(gvec, gvec1);
            rvec_inc(d, d1);
        }
        if (nmol > 0)
        {
            gyro /= nmol;
            svmul(1.0/nmol, gvec, gvec);
            svmul(1.0/nmol, d, d);
        }

        if (nz == 0)
        {
            if (bRot)
            {
                if (j >= max_moi)
                {
                    max_moi += delta_moi;
                    for (m = 0; (m < DIM); m++)
                    {
                        srenew(moi_trans[m], max_moi*DIM);
                    }
                }
                for (m = 0; (m < DIM); m++)
                {
                    copy_rvec(trans[m], moi_trans[m]+DIM*j);
                }
                fprintf(out, "%10g  %10g  %10g  %10g  %10g\n",
                        t, gyro, d[XX], d[YY], d[ZZ]);
            }
            else
            {
                fprintf(out, "%10g  %10g  %10g  %10g  %10g\n",
                        t, gyro, gvec[XX], gvec[YY], gvec[ZZ]);
            }
        }
        j++;
    }
    while (read_next_x(oenv, status, &t, natoms, x, box));
    close_trj(status);
    if (nz == 0)
    {
        gmx_rmpbc_done(gpbc);
    }

    ffclose(out);

    if (bACF)
    {
        int mode = eacVector;

        do_autocorr(opt2fn("-acf", NFILE, fnm), oenv,
                    "Moment of inertia vector ACF",
                    j, 3, moi_trans, (t-t0)/j, mode, FALSE);
        do_view(oenv, opt2fn("-acf", NFILE, fnm), "-nxy");
    }

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

    thanx(stderr);

    return 0;
}
コード例 #27
0
ファイル: gmx_sgangle.c プロジェクト: martinhoefling/gromacs
int gmx_sgangle(int argc,char *argv[])
{
  const char *desc[] = {
    "Compute the angle and distance between two groups. ",
    "The groups are defined by a number of atoms given in an index file and",
    "may be two or three atoms in size.",
    "If [TT]-one[tt] is set, only one group should be specified in the index",
    "file and the angle between this group at time 0 and t will be computed.",
    "The angles calculated depend on the order in which the atoms are ",
    "given. Giving, for instance, 5 6 will rotate the vector 5-6 with ",
    "180 degrees compared to giving 6 5. [PAR]If three atoms are given, ",
    "the normal on the plane spanned by those three atoms will be",
    "calculated, using the formula  P1P2 x P1P3.",
    "The cos of the angle is calculated, using the inproduct of the two",
    "normalized vectors.[PAR]",
    "Here is what some of the file options do:[BR]",
    "[TT]-oa[tt]: Angle between the two groups specified in the index file. If a group contains three atoms the normal to the plane defined by those three atoms will be used. If a group contains two atoms, the vector defined by those two atoms will be used.[BR]",
    "[TT]-od[tt]: Distance between two groups. Distance is taken from the center of one group to the center of the other group.[BR]",
    "[TT]-od1[tt]: If one plane and one vector is given, the distances for each of the atoms from the center of the plane is given separately.[BR]",
    "[TT]-od2[tt]: For two planes this option has no meaning."
  };

  output_env_t oenv;
  const char *fna, *fnd, *fnd1, *fnd2;		
  char *      grpname[2];          		/* name of the two groups */
  int       gnx[2];               		/* size of the two groups */
  t_topology *top;                		/* topology 		*/ 
  int       ePBC;
  atom_id   *index[2];            		
  static gmx_bool bOne = FALSE, bZ=FALSE;
  t_pargs pa[] = {
    { "-one", FALSE, etBOOL, {&bOne},
      "Only one group compute angle between vector at time zero and time t"},
    { "-z", FALSE, etBOOL, {&bZ},
        "Use the [IT]z[it]-axis as reference" }
  };
#define NPA asize(pa)

  t_filenm  fnm[] = {             		/* files for g_sgangle 	*/
    { efTRX, "-f", NULL,  ffREAD },    		/* trajectory file 	*/
    { efNDX, NULL, NULL,  ffREAD },    		/* index file 		*/
    { efTPX, NULL, NULL,  ffREAD },    		/* topology file 	*/
    { efXVG,"-oa","sg_angle",ffWRITE },		/* xvgr output file 	*/
    { efXVG, "-od","sg_dist",ffOPTWR }, 	/* xvgr output file 	*/
    { efXVG, "-od1", "sg_dist1",ffOPTWR }, 	/* xvgr output file 	*/
    { efXVG, "-od2", "sg_dist2",ffOPTWR } 	/* xvgr output file 	*/
  };

#define NFILE asize(fnm)

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

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

  fna = opt2fn("-oa",NFILE,fnm);
  fnd = opt2fn_null("-od",NFILE,fnm);
  fnd1 = opt2fn_null("-od1",NFILE,fnm);
  fnd2 = opt2fn_null("-od2",NFILE,fnm);
  
  /* read index file. */
  if(bOne) {
    rd_index(ftp2fn(efNDX,NFILE,fnm),1,gnx,index,grpname); 
    print_types(index[0],gnx[0],grpname[0],    
 		index[0],gnx[0],grpname[0],top); 

    sgangle_plot_single(ftp2fn(efTRX,NFILE,fnm), fna, fnd, fnd1, fnd2,
			index[0],gnx[0],grpname[0],
			index[0],gnx[0],grpname[0],
			top,ePBC,oenv);
  }  else {
    rd_index(ftp2fn(efNDX,NFILE,fnm),bZ ? 1 : 2,gnx,index,grpname);
    if (!bZ)
      print_types(index[0],gnx[0],grpname[0],
		index[1],gnx[1],grpname[1],top); 
    else {
      gnx[1] = 0;
      grpname[1] = strdup("Z-axis");
    }  
    sgangle_plot(ftp2fn(efTRX,NFILE,fnm), fna, fnd, fnd1, fnd2,
		 index[0],gnx[0],grpname[0],
		 index[1],gnx[1],grpname[1],
		 top,ePBC,oenv);
  }

  do_view(oenv,fna,"-nxy");     /* view xvgr file */
  do_view(oenv,fnd,"-nxy");     /* view xvgr file */
  do_view(oenv,fnd1,"-nxy");     /* view xvgr file */
  do_view(oenv,fnd2,"-nxy");     /* view xvgr file */

  thanx(stderr);
  return 0;
}
コード例 #28
0
int gmx_bond(int argc,char *argv[])
{
  static char *desc[] = {
    "g_bond makes a distribution of bond lengths. If all is well a",
    "gaussian distribution should be made when using a harmonic potential.",
    "bonds are read from a single group in the index file in order i1-j1",
    "i2-j2 thru in-jn.[PAR]",
    "[TT]-tol[tt] gives the half-width of the distribution as a fraction",
    "of the bondlength ([TT]-blen[tt]). That means, for a bond of 0.2",
    "a tol of 0.1 gives a distribution from 0.18 to 0.22.[PAR]",
    "Option [TT]-d[tt] plots all the distances as a function of time.",
    "This requires a structure file for the atom and residue names in",
    "the output. If however the option [TT]-averdist[tt] is given (as well",
    "or separately) the average bond length is plotted instead."
  };
  static char *bugs[] = {
    "It should be possible to get bond information from the topology."
  };
  static real blen=-1.0,tol=0.1;
  static bool bAver=TRUE,bAverDist=TRUE;
  t_pargs pa[] = {
    { "-blen", FALSE, etREAL, {&blen}, 
      "Bond length. By default length of first bond" },
    { "-tol",  FALSE, etREAL, {&tol}, 
      "Half width of distribution as fraction of blen" },
    { "-aver", FALSE, etBOOL, {&bAver},
      "Average bond length distributions" },
    { "-averdist", FALSE, etBOOL, {&bAverDist},
      "Average distances (turns on -d)" }
  };
  FILE      *fp;
  char      *grpname,*fdist;
  int       gnx;
  atom_id   *index;
  char      title[STRLEN];
  t_topology top;
  int       ePBC=-1;
  rvec      *x;
  matrix    box;

  t_filenm fnm[] = {
    { efTRX, "-f", NULL, ffREAD  },
    { efNDX, NULL, NULL, ffREAD  },
    { efTPS, NULL, NULL, ffOPTRD },
    { efXVG, "-o", "bonds", ffWRITE },
    { efLOG, NULL, "bonds", ffOPTWR },
    { efXVG, "-d", "distance", ffOPTWR }
  };
#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,asize(bugs),bugs);
  
  if (bAverDist)
    fdist = opt2fn("-d",NFILE,fnm);
  else {
    fdist = opt2fn_null("-d",NFILE,fnm);
    if (fdist)
      read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&x,NULL,box,
		    FALSE);
  }
  
  rd_index(ftp2fn(efNDX,NFILE,fnm),1,&gnx,&index,&grpname);
  if ( !even(gnx) )
    fprintf(stderr,"WARNING: odd number of atoms (%d) in group!\n",gnx);
  fprintf(stderr,"Will gather information on %d bonds\n",gnx/2);
  
  if (!bAver)
    fp = ftp2FILE(efLOG,NFILE,fnm,"w");
  else
    fp = NULL;
  
  do_bonds(fp,ftp2fn(efTRX,NFILE,fnm),opt2fn("-o",NFILE,fnm),fdist,gnx,index,
	   blen,tol,bAver,&top,ePBC,bAverDist);
  
  do_view(opt2fn("-o",NFILE,fnm),"-nxy");
  do_view(opt2fn_null("-d",NFILE,fnm),"-nxy");
  
  thanx(stderr);
  
  return 0;
}
コード例 #29
0
int gmx_sas(int argc,char *argv[])
{
  const char *desc[] = {
    "[TT]g_sas[tt] computes hydrophobic, hydrophilic and total solvent",
    "accessible surface area. See Eisenhaber F, Lijnzaad P, Argos P,",
    "Sander C, & Scharf M (1995) J. Comput. Chem. 16, 273-284.",
    "As a side effect, the Connolly surface can be generated as well in",
    "a [TT].pdb[tt] file where the nodes are represented as atoms and the",
    "vertice connecting the nearest nodes as CONECT records.",
    "The program will ask for a group for the surface calculation",
    "and a group for the output. The calculation group should always",
    "consists of all the non-solvent atoms in the system.",
    "The output group can be the whole or part of the calculation group.",
    "The average and standard deviation of the area over the trajectory can be plotted",
    "per residue and atom as well (options [TT]-or[tt] and [TT]-oa[tt]).",
    "In combination with the latter option an [TT].itp[tt] file can be",
    "generated (option [TT]-i[tt])",
    "which can be used to restrain surface atoms.[PAR]",

    "By default, periodic boundary conditions are taken into account,",
    "this can be turned off using the [TT]-nopbc[tt] option.[PAR]",

    "With the [TT]-tv[tt] option the total volume and density of the",
    "molecule can be computed.",
    "Please consider whether the normal probe radius is appropriate",
    "in this case or whether you would rather use e.g. 0. It is good",
    "to keep in mind that the results for volume and density are very",
    "approximate. For example, in ice Ih, one can easily fit water molecules in the",
    "pores which would yield a volume that is too low, and surface area and density",
    "that are both too high."
  };

  output_env_t oenv;
  static real solsize = 0.14;
  static int  ndots   = 24;
  static real qcut    = 0.2;
  static real minarea = 0.5, dgs_default=0;
  static gmx_bool bSave   = TRUE,bPBC=TRUE,bFindex=FALSE;
  t_pargs pa[] = {
    { "-probe", FALSE, etREAL, {&solsize},
      "Radius of the solvent probe (nm)" },
    { "-ndots",   FALSE, etINT,  {&ndots},
      "Number of dots per sphere, more dots means more accuracy" },
    { "-qmax",    FALSE, etREAL, {&qcut},
      "The maximum charge (e, absolute value) of a hydrophobic atom" },
    { "-f_index", FALSE, etBOOL, {&bFindex},
      "Determine from a group in the index file what are the hydrophobic atoms rather than from the charge" },
    { "-minarea", FALSE, etREAL, {&minarea},
      "The minimum area (nm^2) to count an atom as a surface atom when writing a position restraint file  (see help)" },
    { "-pbc",     FALSE, etBOOL, {&bPBC},
      "Take periodicity into account" },
    { "-prot",    FALSE, etBOOL, {&bSave},
      "Output the protein to the Connelly [TT].pdb[tt] file too" },
    { "-dgs",     FALSE, etREAL, {&dgs_default},
      "Default value for solvation free energy per area (kJ/mol/nm^2)" }
  };
  t_filenm  fnm[] = {
    { efTRX, "-f",   NULL,       ffREAD },
    { efTPS, "-s",   NULL,       ffREAD },
    { efXVG, "-o",   "area",     ffWRITE },
    { efXVG, "-or",  "resarea",  ffOPTWR },
    { efXVG, "-oa",  "atomarea", ffOPTWR },
    { efXVG, "-tv",  "volume",   ffOPTWR },
    { efPDB, "-q",   "connelly", ffOPTWR },
    { efNDX, "-n",   "index",    ffOPTRD },
    { efITP, "-i",   "surfat",   ffOPTWR }
  };
#define NFILE asize(fnm)

  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 (solsize < 0) {
    solsize=1e-3;
    fprintf(stderr,"Probe size too small, setting it to %g\n",solsize);
  }
  if (ndots < 20) {
    ndots = 20;
    fprintf(stderr,"Ndots too small, setting it to %d\n",ndots);
  }

  please_cite(stderr,"Eisenhaber95");
    
  sas_plot(NFILE,fnm,solsize,ndots,qcut,bSave,minarea,bPBC,dgs_default,bFindex,
          oenv);
  
  do_view(oenv,opt2fn("-o",NFILE,fnm),"-nxy");
  do_view(oenv,opt2fn_null("-or",NFILE,fnm),"-nxy");
  do_view(oenv,opt2fn_null("-oa",NFILE,fnm),"-nxy");

  thanx(stderr);
  
  return 0;
}
コード例 #30
0
ファイル: gmx_nmtraj.cpp プロジェクト: mpharrigan/gromacs
int gmx_nmtraj(int argc, char *argv[])
{
    const char *desc[] =
    {
        "[THISMODULE] generates an virtual trajectory from an eigenvector, ",
        "corresponding to a harmonic Cartesian oscillation around the average ",
        "structure. The eigenvectors should normally be mass-weighted, but you can ",
        "use non-weighted eigenvectors to generate orthogonal motions. ",
        "The output frames are written as a trajectory file covering an entire period, and ",
        "the first frame is the average structure. If you write the trajectory in (or convert to) ",
        "PDB format you can view it directly in PyMol and also render a photorealistic movie. ",
        "Motion amplitudes are calculated from the eigenvalues and a preset temperature, ",
        "assuming equipartition of the energy over all modes. To make the motion clearly visible ",
        "in PyMol you might want to amplify it by setting an unrealistically high temperature. ",
        "However, be aware that both the linear Cartesian displacements and mass weighting will ",
        "lead to serious structure deformation for high amplitudes - this is is simply a limitation ",
        "of the Cartesian normal mode model. By default the selected eigenvector is set to 7, since ",
        "the first six normal modes are the translational and rotational degrees of freedom."
    };

    static real        refamplitude = 0.25;
    static int         nframes      = 30;
    static real        temp         = 300.0;
    static const char *eignrvec     = "7";
    static const char *phasevec     = "0.0";

    t_pargs            pa[] =
    {
        { "-eignr",     FALSE, etSTR,  {&eignrvec}, "String of eigenvectors to use (first is 1)" },
        { "-phases",    FALSE, etSTR,  {&phasevec}, "String of phases (default is 0.0)" },
        { "-temp",      FALSE, etREAL, {&temp},      "Temperature (K)" },
        { "-amplitude", FALSE, etREAL, {&refamplitude}, "Amplitude for modes with eigenvalue<=0" },
        { "-nframes",   FALSE, etINT,  {&nframes},   "Number of frames to generate" }
    };

#define NPA asize(pa)

    t_trxstatus      *out;
    t_topology        top;
    int               ePBC;
    t_atoms          *atoms;
    rvec             *xtop, *xref, *xav, *xout;
    int               nvec, *eignr = NULL;
    rvec            **eigvec = NULL;
    matrix            box;
    int               natoms;
    int               i, j, k, kmode, d;
    gmx_bool          bDMR, bDMA, bFit;

    real        *     eigval;
    int        *      dummy;
    real        *     invsqrtm;
    real              fraction;
    int              *out_eigidx;
    rvec        *     this_eigvec;
    real              omega, Ekin, m, vel;
    int               nmodes, nphases;
    int              *imodes;
    real             *amplitude;
    real             *phases;
    const char       *p;
    char             *pe;
    output_env_t      oenv;

    t_filenm          fnm[] =
    {
        { efTPS, NULL,    NULL,          ffREAD },
        { efTRN, "-v",    "eigenvec",    ffREAD  },
        { efTRO, "-o",    "nmtraj",      ffWRITE }
    };

#define NFILE asize(fnm)

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

    read_eigenvectors(opt2fn("-v", NFILE, fnm), &natoms, &bFit,
                      &xref, &bDMR, &xav, &bDMA, &nvec, &eignr, &eigvec, &eigval);

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

    /* Find vectors and phases */

    /* first find number of args in string */
    nmodes = gmx::countWords(eignrvec);

    snew(imodes, nmodes);
    p = eignrvec;
    for (i = 0; i < nmodes; i++)
    {
        /* C indices start on 0 */
        imodes[i] = std::strtol(p, &pe, 10)-1;
        p         = pe;
    }

    /* Now read phases */
    nphases = gmx::countWords(phasevec);

    if (nphases > nmodes)
    {
        gmx_fatal(FARGS, "More phases than eigenvector indices specified.\n");
    }

    snew(phases, nmodes);
    p = phasevec;

    for (i = 0; i < nphases; i++)
    {
        phases[i] = strtod(p, &pe);
        p         = pe;
    }

    if (nmodes > nphases)
    {
        printf("Warning: Setting phase of last %d modes to zero...\n", nmodes-nphases);
    }

    for (i = nphases; i < nmodes; i++)
    {
        phases[i] = 0;
    }

    atoms = &top.atoms;

    if (atoms->nr != natoms)
    {
        gmx_fatal(FARGS, "Different number of atoms in topology and eigenvectors.\n");
    }

    snew(dummy, natoms);
    for (i = 0; i < natoms; i++)
    {
        dummy[i] = i;
    }

    /* Find the eigenvalue/vector to match our select one */
    snew(out_eigidx, nmodes);
    for (i = 0; i < nmodes; i++)
    {
        out_eigidx[i] = -1;
    }

    for (i = 0; i < nvec; i++)
    {
        for (j = 0; j < nmodes; j++)
        {
            if (imodes[j] == eignr[i])
            {
                out_eigidx[j] = i;
            }
        }
    }
    for (i = 0; i < nmodes; i++)
    {
        if (out_eigidx[i] == -1)
        {
            gmx_fatal(FARGS, "Could not find mode %d in eigenvector file.\n", imodes[i]);
        }
    }


    snew(invsqrtm, natoms);

    if (bDMA)
    {
        for (i = 0; (i < natoms); i++)
        {
            invsqrtm[i] = gmx_invsqrt(atoms->atom[i].m);
        }
    }
    else
    {
        for (i = 0; (i < natoms); i++)
        {
            invsqrtm[i] = 1.0;
        }
    }

    snew(xout, natoms);
    snew(amplitude, nmodes);

    printf("mode phases: %g %g\n", phases[0], phases[1]);

    for (i = 0; i < nmodes; i++)
    {
        kmode       = out_eigidx[i];
        this_eigvec = eigvec[kmode];

        if ( (kmode >= 6) && (eigval[kmode] > 0))
        {
            /* Derive amplitude from temperature and eigenvalue if we can */

            /* Convert eigenvalue to angular frequency, in units s^(-1) */
            omega = std::sqrt(eigval[kmode]*1.0E21/(AVOGADRO*AMU));
            /* Harmonic motion will be x=x0 + A*sin(omega*t)*eigenvec.
             * The velocity is thus:
             *
             * v = A*omega*cos(omega*t)*eigenvec.
             *
             * And the average kinetic energy the integral of mass*v*v/2 over a
             * period:
             *
             * (1/4)*mass*A*omega*eigenvec
             *
             * For t =2*pi*n, all energy will be kinetic, and v=A*omega*eigenvec.
             * The kinetic energy will be sum(0.5*mass*v*v) if we temporarily set A to 1,
             * and the average over a period half of this.
             */

            Ekin = 0;
            for (k = 0; k < natoms; k++)
            {
                m = atoms->atom[k].m;
                for (d = 0; d < DIM; d++)
                {
                    vel   = omega*this_eigvec[k][d];
                    Ekin += 0.5*0.5*m*vel*vel;
                }
            }

            /* Convert Ekin from amu*(nm/s)^2 to J, i.e., kg*(m/s)^2
             * This will also be proportional to A^2
             */
            Ekin *= AMU*1E-18;

            /* Set the amplitude so the energy is kT/2 */
            amplitude[i] = std::sqrt(0.5*BOLTZMANN*temp/Ekin);
        }
        else
        {
            amplitude[i] = refamplitude;
        }
    }

    out = open_trx(ftp2fn(efTRO, NFILE, fnm), "w");

    /* Write a sine oscillation around the average structure,
     * modulated by the eigenvector with selected amplitude.
     */

    for (i = 0; i < nframes; i++)
    {
        fraction = static_cast<real>(i)/nframes;
        for (j = 0; j < natoms; j++)
        {
            copy_rvec(xav[j], xout[j]);
        }

        for (k = 0; k < nmodes; k++)
        {
            kmode       = out_eigidx[k];
            this_eigvec = eigvec[kmode];

            for (j = 0; j < natoms; j++)
            {
                for (d = 0; d < DIM; d++)
                {
                    xout[j][d] += amplitude[k]*std::sin(2*M_PI*(fraction+phases[k]/360.0))*this_eigvec[j][d];
                }
            }
        }
        write_trx(out, natoms, dummy, atoms, i, static_cast<real>(i)/nframes, box, xout, NULL, NULL);
    }

    fprintf(stderr, "\n");
    close_trx(out);

    return 0;
}