示例#1
0
文件: topio.c 项目: andersx/gmx-debug
int
find_gb_bondlength(t_params *plist,int ai,int aj, real *length)
{
    int i,j,a1,a2;
    
    int found=0;
    int status;
    
    for(i=0;i<F_NRE && !found;i++)
    {
        if(IS_CHEMBOND(i))
        {
            for(j=0;j<plist[i].nr; j++)
            {
                a1=plist[i].param[j].a[0];
                a2=plist[i].param[j].a[1];
                
                if( (a1==ai && a2==aj) || (a1==aj && a2==ai))
                {
                    /* Equilibrium bond distance */
                    *length=plist[i].param[j].c[0];
                    found=1;
                }
            }
        }
    }
    status = !found;
    
    return status;
}
示例#2
0
void gmx_tng_add_mtop(tng_trajectory_t  tng,
                      const gmx_mtop_t *mtop)
{
    int                  i, j;
    const t_ilist       *ilist;
    tng_bond_t           tngBond;

    if (!mtop)
    {
        /* No topology information available to add. */
        return;
    }

    for (int molIt = 0; molIt < mtop->nmolblock; molIt++)
    {
        tng_molecule_t       tngMol  = NULL;
        const gmx_moltype_t *molType =
            &mtop->moltype[mtop->molblock[molIt].type];

        /* Add a molecule to the TNG trajectory with the same name as the
         * current molecule. */
        addTngMoleculeFromTopology(tng,
                                   *(molType->name),
                                   &molType->atoms,
                                   mtop->molblock[molIt].nmol,
                                   &tngMol);

        /* Bonds have to be deduced from interactions (constraints etc). Different
         * interactions have different sets of parameters. */
        /* Constraints are specified using two atoms */
        for (i = 0; i < F_NRE; i++)
        {
            if (IS_CHEMBOND(i))
            {
                ilist = &molType->ilist[i];
                if (ilist)
                {
                    j = 1;
                    while (j < ilist->nr)
                    {
                        tng_molecule_bond_add(tng, tngMol, ilist->iatoms[j], ilist->iatoms[j+1], &tngBond);
                        j += 3;
                    }
                }
            }
        }
        /* Settle is described using three atoms */
        ilist = &molType->ilist[F_SETTLE];
        if (ilist)
        {
            j = 1;
            while (j < ilist->nr)
            {
                tng_molecule_bond_add(tng, tngMol, ilist->iatoms[j], ilist->iatoms[j+1], &tngBond);
                tng_molecule_bond_add(tng, tngMol, ilist->iatoms[j], ilist->iatoms[j+2], &tngBond);
                j += 4;
            }
        }
    }
}
示例#3
0
static void add_bpl(t_manager *man,t_idef *idef,bool bB[])
{
  int ftype;

  for(ftype=0; ftype<F_NRE; ftype++)
    if (IS_CHEMBOND(ftype) || ftype==F_SETTLE)
      add_bonds(man,idef->functype,&idef->il[ftype],bB);
}
示例#4
0
static void add_bonds(t_manager *man, t_functype func[],
                      t_ilist *b, bool bB[])
{
    bool        *bH = man->bHydro;
    t_iatom     *ia;
    t_iatom      type, ai, aj, ak;
    int          i, delta, ftype;

#ifdef DEBUG
    std::fprintf(stderr, "Going to make bonds from an ilist with %d entries\n", b->nr);
#endif
    ia = b->iatoms;
    for (i = 0; (i < b->nr); )
    {
        type  = ia[0];
        ai    = ia[1];
        ftype = func[type];
        delta = interaction_function[ftype].nratoms;

        if (ftype == F_SETTLE)
        {
            aj     = ia[2];
            ak     = ia[3];
            bB[ai] = bB[aj] = bB[ak] = true;
            add_object(man, eOHBond, ai, aj);
            add_object(man, eOHBond, ai, ak);
        }
        else if (IS_CHEMBOND(ftype))
        {
            aj = ia[2];
#ifdef DEBUG
            std::fprintf(stderr, "Adding bond from %d to %d\n", ai, aj);
#endif
            bB[ai] = bB[aj] = true;
            if (!(bH[ai] == bH[aj]))
            {
                add_object(man, eOHBond, ai, aj);
            }
            else if (!bH[ai] && !bH[aj])
            {
                add_object(man, eOBond, ai, aj);
            }
        }
#ifdef DEBUG
        std::fprintf(stderr, "Type: %5d, delta: %5d\n", type, delta);
#endif
        ia += delta+1;
        i  += delta+1;
    }
}
示例#5
0
void gen_nnb(t_nextnb *nnb, t_params plist[])
{
    sortable *s;
    int       i, nrbonds, nrf;

    nrbonds = 0;
    for (i = 0; (i < F_NRE); i++)
    {
        if (IS_CHEMBOND(i))
        {
            /* we need every bond twice (bidirectional) */
            nrbonds += 2*plist[i].nr;
        }
    }

    snew(s, nrbonds);

    nrf = 0;
    for (i = 0; (i < F_NRE); i++)
    {
        if (IS_CHEMBOND(i))
        {
            add_b(&plist[i], &nrf, s);
        }
    }

    /* now sort the bonds */
    prints("gen_excl before qsort", nrbonds, s);
    if (nrbonds > 1)
    {
        qsort((void *) s, nrbonds, (size_t)sizeof(sortable), bond_sort);
        prints("gen_excl after qsort", nrbonds, s);
    }

    do_gen(nrbonds, s, nnb);
    sfree(s);
}
示例#6
0
文件: pdbio.c 项目: andersx/gmx-debug
gmx_conect gmx_conect_generate(t_topology *top)
{
  int f,i;
  gmx_conect gc;
  
  /* Fill the conect records */
  gc  = gmx_conect_init();

  for(f=0; (f<F_NRE); f++) {
    if (IS_CHEMBOND(f))
      for(i=0; (i<top->idef.il[f].nr); i+=interaction_function[f].nratoms+1) {
	gmx_conect_add(gc,top->idef.il[f].iatoms[i+1],
		       top->idef.il[f].iatoms[i+2]);
    }
  }
  return gc;
}
示例#7
0
int gmx_rms(int argc, char *argv[])
{
    const char     *desc[] =
    {
        "[THISMODULE] compares two structures by computing the root mean square",
        "deviation (RMSD), the size-independent [GRK]rho[grk] similarity parameter",
        "([TT]rho[tt]) or the scaled [GRK]rho[grk] ([TT]rhosc[tt]), ",
        "see Maiorov & Crippen, Proteins [BB]22[bb], 273 (1995).",
        "This is selected by [TT]-what[tt].[PAR]"

        "Each structure from a trajectory ([TT]-f[tt]) is compared to a",
        "reference structure. The reference structure",
        "is taken from the structure file ([TT]-s[tt]).[PAR]",

        "With option [TT]-mir[tt] also a comparison with the mirror image of",
        "the reference structure is calculated.",
        "This is useful as a reference for 'significant' values, see",
        "Maiorov & Crippen, Proteins [BB]22[bb], 273 (1995).[PAR]",

        "Option [TT]-prev[tt] produces the comparison with a previous frame",
        "the specified number of frames ago.[PAR]",

        "Option [TT]-m[tt] produces a matrix in [TT].xpm[tt] format of",
        "comparison values of each structure in the trajectory with respect to",
        "each other structure. This file can be visualized with for instance",
        "[TT]xv[tt] and can be converted to postscript with [gmx-xpm2ps].[PAR]",

        "Option [TT]-fit[tt] controls the least-squares fitting of",
        "the structures on top of each other: complete fit (rotation and",
        "translation), translation only, or no fitting at all.[PAR]",

        "Option [TT]-mw[tt] controls whether mass weighting is done or not.",
        "If you select the option (default) and ",
        "supply a valid [TT].tpr[tt] file masses will be taken from there, ",
        "otherwise the masses will be deduced from the [TT]atommass.dat[tt] file in",
        "[TT]GMXLIB[tt]. This is fine for proteins, but not",
        "necessarily for other molecules. A default mass of 12.011 amu (carbon)",
        "is assigned to unknown atoms. You can check whether this happend by",
        "turning on the [TT]-debug[tt] flag and inspecting the log file.[PAR]",

        "With [TT]-f2[tt], the 'other structures' are taken from a second",
        "trajectory, this generates a comparison matrix of one trajectory",
        "versus the other.[PAR]",

        "Option [TT]-bin[tt] does a binary dump of the comparison matrix.[PAR]",

        "Option [TT]-bm[tt] produces a matrix of average bond angle deviations",
        "analogously to the [TT]-m[tt] option. Only bonds between atoms in the",
        "comparison group are considered."
    };
    static gmx_bool bPBC              = TRUE, bFitAll = TRUE, bSplit = FALSE;
    static gmx_bool bDeltaLog         = FALSE;
    static int      prev              = 0, freq = 1, freq2 = 1, nlevels = 80, avl = 0;
    static real     rmsd_user_max     = -1, rmsd_user_min = -1, bond_user_max = -1,
                    bond_user_min     = -1, delta_maxy = 0.0;
    /* strings and things for selecting difference method */
    enum
    {
        ewSel, ewRMSD, ewRho, ewRhoSc, ewNR
    };
    int         ewhat;
    const char *what[ewNR + 1] =
    { NULL, "rmsd", "rho", "rhosc", NULL };
    const char *whatname[ewNR] =
    { NULL, "RMSD", "Rho", "Rho sc" };
    const char *whatlabel[ewNR] =
    { NULL, "RMSD (nm)", "Rho", "Rho sc" };
    const char *whatxvgname[ewNR] =
    { NULL, "RMSD", "\\8r\\4", "\\8r\\4\\ssc\\N" };
    const char *whatxvglabel[ewNR] =
    { NULL, "RMSD (nm)", "\\8r\\4", "\\8r\\4\\ssc\\N" };
    /* strings and things for fitting methods */
    enum
    {
        efSel, efFit, efReset, efNone, efNR
    };
    int             efit;
    const char     *fit[efNR + 1] =
    { NULL, "rot+trans", "translation", "none", NULL };
    const char     *fitgraphlabel[efNR + 1] =
    { NULL, "lsq fit", "translational fit", "no fit" };
    static int      nrms          = 1;
    static gmx_bool bMassWeighted = TRUE;
    t_pargs         pa[]          =
    {
        { "-what", FALSE, etENUM,
          { what }, "Structural difference measure" },
        { "-pbc", FALSE, etBOOL,
          { &bPBC }, "PBC check" },
        { "-fit", FALSE, etENUM,
          { fit }, "Fit to reference structure" },
        { "-prev", FALSE, etINT,
          { &prev }, "Compare with previous frame" },
        { "-split", FALSE, etBOOL,
          { &bSplit }, "Split graph where time is zero" },
        { "-fitall", FALSE, etBOOL,
          { &bFitAll }, "HIDDENFit all pairs of structures in matrix" },
        { "-skip", FALSE, etINT,
          { &freq }, "Only write every nr-th frame to matrix" },
        { "-skip2", FALSE, etINT,
          { &freq2 }, "Only write every nr-th frame to matrix" },
        { "-max", FALSE, etREAL,
          { &rmsd_user_max }, "Maximum level in comparison matrix" },
        { "-min", FALSE, etREAL,
          { &rmsd_user_min }, "Minimum level in comparison matrix" },
        { "-bmax", FALSE, etREAL,
          { &bond_user_max }, "Maximum level in bond angle matrix" },
        { "-bmin", FALSE, etREAL,
          { &bond_user_min }, "Minimum level in bond angle matrix" },
        { "-mw", FALSE, etBOOL,
          { &bMassWeighted }, "Use mass weighting for superposition" },
        { "-nlevels", FALSE, etINT,
          { &nlevels }, "Number of levels in the matrices" },
        { "-ng", FALSE, etINT,
          { &nrms }, "Number of groups to compute RMS between" },
        { "-dlog", FALSE, etBOOL,
          { &bDeltaLog },
          "HIDDENUse a log x-axis in the delta t matrix" },
        { "-dmax", FALSE, etREAL,
          { &delta_maxy }, "HIDDENMaximum level in delta matrix" },
        { "-aver", FALSE, etINT,
          { &avl },
          "HIDDENAverage over this distance in the RMSD matrix" }
    };
    int             natoms_trx, natoms_trx2, natoms;
    int             i, j, k, m, teller, teller2, tel_mat, tel_mat2;
#define NFRAME 5000
    int             maxframe = NFRAME, maxframe2 = NFRAME;
    real            t, *w_rls, *w_rms, *w_rls_m = NULL, *w_rms_m = NULL;
    gmx_bool        bNorm, bAv, bFreq2, bFile2, bMat, bBond, bDelta, bMirror, bMass;
    gmx_bool        bFit, bReset;
    t_topology      top;
    int             ePBC;
    t_iatom        *iatom = NULL;

    matrix          box;
    rvec           *x, *xp, *xm = NULL, **mat_x = NULL, **mat_x2, *mat_x2_j = NULL, vec1,
                    vec2;
    t_trxstatus    *status;
    char            buf[256], buf2[256];
    int             ncons = 0;
    FILE           *fp;
    real            rlstot = 0, **rls, **rlsm = NULL, *time, *time2, *rlsnorm = NULL,
    **rmsd_mat             = NULL, **bond_mat = NULL, *axis, *axis2, *del_xaxis,
    *del_yaxis, rmsd_max, rmsd_min, rmsd_avg, bond_max, bond_min, ang;
    real       **rmsdav_mat = NULL, av_tot, weight, weight_tot;
    real       **delta      = NULL, delta_max, delta_scalex = 0, delta_scaley = 0,
    *delta_tot;
    int          delta_xsize = 0, del_lev = 100, mx, my, abs_my;
    gmx_bool     bA1, bA2, bPrev, bTop, *bInMat = NULL;
    int          ifit, *irms, ibond = 0, *ind_bond1 = NULL, *ind_bond2 = NULL, n_ind_m =
        0;
    atom_id     *ind_fit, **ind_rms, *ind_m = NULL, *rev_ind_m = NULL, *ind_rms_m =
        NULL;
    char        *gn_fit, **gn_rms;
    t_rgb        rlo, rhi;
    output_env_t oenv;
    gmx_rmpbc_t  gpbc = NULL;

    t_filenm     fnm[] =
    {
        { efTPS, NULL, NULL, ffREAD },
        { efTRX, "-f", NULL, ffREAD },
        { efTRX, "-f2", NULL, ffOPTRD },
        { efNDX, NULL, NULL, ffOPTRD },
        { efXVG, NULL, "rmsd", ffWRITE },
        { efXVG, "-mir", "rmsdmir", ffOPTWR },
        { efXVG, "-a", "avgrp", ffOPTWR },
        { efXVG, "-dist", "rmsd-dist", ffOPTWR },
        { efXPM, "-m", "rmsd", ffOPTWR },
        { efDAT, "-bin", "rmsd", ffOPTWR },
        { efXPM, "-bm", "bond", ffOPTWR }
    };
#define NFILE asize(fnm)

    if (!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))
    {
        return 0;
    }
    /* parse enumerated options: */
    ewhat = nenum(what);
    if (ewhat == ewRho || ewhat == ewRhoSc)
    {
        please_cite(stdout, "Maiorov95");
    }
    efit   = nenum(fit);
    bFit   = efit == efFit;
    bReset = efit == efReset;
    if (bFit)
    {
        bReset = TRUE; /* for fit, reset *must* be set */
    }
    else
    {
        bFitAll = FALSE;
    }

    /* mark active cmdline options */
    bMirror = opt2bSet("-mir", NFILE, fnm); /* calc RMSD vs mirror of ref. */
    bFile2  = opt2bSet("-f2", NFILE, fnm);
    bMat    = opt2bSet("-m", NFILE, fnm);
    bBond   = opt2bSet("-bm", NFILE, fnm);
    bDelta  = (delta_maxy > 0); /* calculate rmsd vs delta t matrix from *
                                 *	your RMSD matrix (hidden option       */
    bNorm   = opt2bSet("-a", NFILE, fnm);
    bFreq2  = opt2parg_bSet("-skip2", asize(pa), pa);
    if (freq <= 0)
    {
        fprintf(stderr, "The number of frames to skip is <= 0. "
                "Writing out all frames.\n\n");
        freq = 1;
    }
    if (!bFreq2)
    {
        freq2 = freq;
    }
    else if (bFile2 && freq2 <= 0)
    {
        fprintf(stderr,
                "The number of frames to skip in second trajectory is <= 0.\n"
                "  Writing out all frames.\n\n");
        freq2 = 1;
    }

    bPrev = (prev > 0);
    if (bPrev)
    {
        prev = abs(prev);
        if (freq != 1)
        {
            fprintf(stderr, "WARNING: option -skip also applies to -prev\n");
        }
    }

    if (bFile2 && !bMat && !bBond)
    {
        fprintf(
                stderr,
                "WARNING: second trajectory (-f2) useless when not calculating matrix (-m/-bm),\n"
                "         will not read from %s\n", opt2fn("-f2", NFILE,
                                                           fnm));
        bFile2 = FALSE;
    }

    if (bDelta)
    {
        bMat = TRUE;
        if (bFile2)
        {
            fprintf(stderr,
                    "WARNING: second trajectory (-f2) useless when making delta matrix,\n"
                    "         will not read from %s\n", opt2fn("-f2",
                                                               NFILE, fnm));
            bFile2 = FALSE;
        }
    }

    bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), buf, &top, &ePBC, &xp,
                         NULL, box, TRUE);
    snew(w_rls, top.atoms.nr);
    snew(w_rms, top.atoms.nr);

    if (!bTop && bBond)
    {
        fprintf(stderr,
                "WARNING: Need a run input file for bond angle matrix,\n"
                "         will not calculate bond angle matrix.\n");
        bBond = FALSE;
    }

    if (bReset)
    {
        fprintf(stderr, "Select group for %s fit\n", bFit ? "least squares"
                : "translational");
        get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &ifit,
                  &ind_fit, &gn_fit);
    }
    else
    {
        ifit = 0;
    }

    if (bReset)
    {
        if (bFit && ifit < 3)
        {
            gmx_fatal(FARGS, "Need >= 3 points to fit!\n" );
        }

        bMass = FALSE;
        for (i = 0; i < ifit; i++)
        {
            if (bMassWeighted)
            {
                w_rls[ind_fit[i]] = top.atoms.atom[ind_fit[i]].m;
            }
            else
            {
                w_rls[ind_fit[i]] = 1;
            }
            bMass = bMass || (top.atoms.atom[ind_fit[i]].m != 0);
        }
        if (!bMass)
        {
            fprintf(stderr, "All masses in the fit group are 0, using masses of 1\n");
            for (i = 0; i < ifit; i++)
            {
                w_rls[ind_fit[i]] = 1;
            }
        }
    }

    if (bMat || bBond)
    {
        nrms = 1;
    }

    snew(gn_rms, nrms);
    snew(ind_rms, nrms);
    snew(irms, nrms);

    fprintf(stderr, "Select group%s for %s calculation\n",
            (nrms > 1) ? "s" : "", whatname[ewhat]);
    get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm),
              nrms, irms, ind_rms, gn_rms);

    if (bNorm)
    {
        snew(rlsnorm, irms[0]);
    }
    snew(rls, nrms);
    for (j = 0; j < nrms; j++)
    {
        snew(rls[j], maxframe);
    }
    if (bMirror)
    {
        snew(rlsm, nrms);
        for (j = 0; j < nrms; j++)
        {
            snew(rlsm[j], maxframe);
        }
    }
    snew(time, maxframe);
    for (j = 0; j < nrms; j++)
    {
        bMass = FALSE;
        for (i = 0; i < irms[j]; i++)
        {
            if (bMassWeighted)
            {
                w_rms[ind_rms[j][i]] = top.atoms.atom[ind_rms[j][i]].m;
            }
            else
            {
                w_rms[ind_rms[j][i]] = 1.0;
            }
            bMass = bMass || (top.atoms.atom[ind_rms[j][i]].m != 0);
        }
        if (!bMass)
        {
            fprintf(stderr, "All masses in group %d are 0, using masses of 1\n", j);
            for (i = 0; i < irms[j]; i++)
            {
                w_rms[ind_rms[j][i]] = 1;
            }
        }
    }
    /* Prepare reference frame */
    if (bPBC)
    {
        gpbc = gmx_rmpbc_init(&top.idef, ePBC, top.atoms.nr);
        gmx_rmpbc(gpbc, top.atoms.nr, box, xp);
    }
    if (bReset)
    {
        reset_x(ifit, ind_fit, top.atoms.nr, NULL, xp, w_rls);
    }
    if (bMirror)
    {
        /* generate reference structure mirror image: */
        snew(xm, top.atoms.nr);
        for (i = 0; i < top.atoms.nr; i++)
        {
            copy_rvec(xp[i], xm[i]);
            xm[i][XX] = -xm[i][XX];
        }
    }
    if (ewhat == ewRhoSc)
    {
        norm_princ(&top.atoms, ifit, ind_fit, top.atoms.nr, xp);
    }

    /* read first frame */
    natoms_trx = read_first_x(oenv, &status, opt2fn("-f", NFILE, fnm), &t, &x, box);
    if (natoms_trx != top.atoms.nr)
    {
        fprintf(stderr,
                "\nWARNING: topology has %d atoms, whereas trajectory has %d\n",
                top.atoms.nr, natoms_trx);
    }
    natoms = min(top.atoms.nr, natoms_trx);
    if (bMat || bBond || bPrev)
    {
        snew(mat_x, NFRAME);

        if (bPrev)
        {
            /* With -prev we use all atoms for simplicity */
            n_ind_m = natoms;
        }
        else
        {
            /* Check which atoms we need (fit/rms) */
            snew(bInMat, natoms);
            for (i = 0; i < ifit; i++)
            {
                bInMat[ind_fit[i]] = TRUE;
            }
            n_ind_m = ifit;
            for (i = 0; i < irms[0]; i++)
            {
                if (!bInMat[ind_rms[0][i]])
                {
                    bInMat[ind_rms[0][i]] = TRUE;
                    n_ind_m++;
                }
            }
        }
        /* Make an index of needed atoms */
        snew(ind_m, n_ind_m);
        snew(rev_ind_m, natoms);
        j = 0;
        for (i = 0; i < natoms; i++)
        {
            if (bPrev || bInMat[i])
            {
                ind_m[j]     = i;
                rev_ind_m[i] = j;
                j++;
            }
        }
        snew(w_rls_m, n_ind_m);
        snew(ind_rms_m, irms[0]);
        snew(w_rms_m, n_ind_m);
        for (i = 0; i < ifit; i++)
        {
            w_rls_m[rev_ind_m[ind_fit[i]]] = w_rls[ind_fit[i]];
        }
        for (i = 0; i < irms[0]; i++)
        {
            ind_rms_m[i]          = rev_ind_m[ind_rms[0][i]];
            w_rms_m[ind_rms_m[i]] = w_rms[ind_rms[0][i]];
        }
        sfree(bInMat);
    }

    if (bBond)
    {
        ncons = 0;
        for (k = 0; k < F_NRE; k++)
        {
            if (IS_CHEMBOND(k))
            {
                iatom  = top.idef.il[k].iatoms;
                ncons += top.idef.il[k].nr/3;
            }
        }
        fprintf(stderr, "Found %d bonds in topology\n", ncons);
        snew(ind_bond1, ncons);
        snew(ind_bond2, ncons);
        ibond = 0;
        for (k = 0; k < F_NRE; k++)
        {
            if (IS_CHEMBOND(k))
            {
                iatom = top.idef.il[k].iatoms;
                ncons = top.idef.il[k].nr/3;
                for (i = 0; i < ncons; i++)
                {
                    bA1 = FALSE;
                    bA2 = FALSE;
                    for (j = 0; j < irms[0]; j++)
                    {
                        if (iatom[3*i+1] == ind_rms[0][j])
                        {
                            bA1 = TRUE;
                        }
                        if (iatom[3*i+2] == ind_rms[0][j])
                        {
                            bA2 = TRUE;
                        }
                    }
                    if (bA1 && bA2)
                    {
                        ind_bond1[ibond] = rev_ind_m[iatom[3*i+1]];
                        ind_bond2[ibond] = rev_ind_m[iatom[3*i+2]];
                        ibond++;
                    }
                }
            }
        }
        fprintf(stderr, "Using %d bonds for bond angle matrix\n", ibond);
        if (ibond == 0)
        {
            gmx_fatal(FARGS, "0 bonds found");
        }
    }

    /* start looping over frames: */
    tel_mat = 0;
    teller  = 0;
    do
    {
        if (bPBC)
        {
            gmx_rmpbc(gpbc, natoms, box, x);
        }

        if (bReset)
        {
            reset_x(ifit, ind_fit, natoms, NULL, x, w_rls);
        }
        if (ewhat == ewRhoSc)
        {
            norm_princ(&top.atoms, ifit, ind_fit, natoms, x);
        }

        if (bFit)
        {
            /*do the least squares fit to original structure*/
            do_fit(natoms, w_rls, xp, x);
        }

        if (teller % freq == 0)
        {
            /* keep frame for matrix calculation */
            if (bMat || bBond || bPrev)
            {
                if (tel_mat >= NFRAME)
                {
                    srenew(mat_x, tel_mat+1);
                }
                snew(mat_x[tel_mat], n_ind_m);
                for (i = 0; i < n_ind_m; i++)
                {
                    copy_rvec(x[ind_m[i]], mat_x[tel_mat][i]);
                }
            }
            tel_mat++;
        }

        /*calculate energy of root_least_squares*/
        if (bPrev)
        {
            j = tel_mat-prev-1;
            if (j < 0)
            {
                j = 0;
            }
            for (i = 0; i < n_ind_m; i++)
            {
                copy_rvec(mat_x[j][i], xp[ind_m[i]]);
            }
            if (bReset)
            {
                reset_x(ifit, ind_fit, natoms, NULL, xp, w_rls);
            }
            if (bFit)
            {
                do_fit(natoms, w_rls, x, xp);
            }
        }
        for (j = 0; (j < nrms); j++)
        {
            rls[j][teller] =
                calc_similar_ind(ewhat != ewRMSD, irms[j], ind_rms[j], w_rms, x, xp);
        }
        if (bNorm)
        {
            for (j = 0; (j < irms[0]); j++)
            {
                rlsnorm[j] +=
                    calc_similar_ind(ewhat != ewRMSD, 1, &(ind_rms[0][j]), w_rms, x, xp);
            }
        }

        if (bMirror)
        {
            if (bFit)
            {
                /*do the least squares fit to mirror of original structure*/
                do_fit(natoms, w_rls, xm, x);
            }

            for (j = 0; j < nrms; j++)
            {
                rlsm[j][teller] =
                    calc_similar_ind(ewhat != ewRMSD, irms[j], ind_rms[j], w_rms, x, xm);
            }
        }
        time[teller] = output_env_conv_time(oenv, t);

        teller++;
        if (teller >= maxframe)
        {
            maxframe += NFRAME;
            srenew(time, maxframe);
            for (j = 0; (j < nrms); j++)
            {
                srenew(rls[j], maxframe);
            }
            if (bMirror)
            {
                for (j = 0; (j < nrms); j++)
                {
                    srenew(rlsm[j], maxframe);
                }
            }
        }
    }
    while (read_next_x(oenv, status, &t, x, box));
    close_trj(status);

    if (bFile2)
    {
        snew(time2, maxframe2);

        fprintf(stderr, "\nWill read second trajectory file\n");
        snew(mat_x2, NFRAME);
        natoms_trx2 =
            read_first_x(oenv, &status, opt2fn("-f2", NFILE, fnm), &t, &x, box);
        if (natoms_trx2 != natoms_trx)
        {
            gmx_fatal(FARGS,
                      "Second trajectory (%d atoms) does not match the first one"
                      " (%d atoms)", natoms_trx2, natoms_trx);
        }
        tel_mat2 = 0;
        teller2  = 0;
        do
        {
            if (bPBC)
            {
                gmx_rmpbc(gpbc, natoms, box, x);
            }

            if (bReset)
            {
                reset_x(ifit, ind_fit, natoms, NULL, x, w_rls);
            }
            if (ewhat == ewRhoSc)
            {
                norm_princ(&top.atoms, ifit, ind_fit, natoms, x);
            }

            if (bFit)
            {
                /*do the least squares fit to original structure*/
                do_fit(natoms, w_rls, xp, x);
            }

            if (teller2 % freq2 == 0)
            {
                /* keep frame for matrix calculation */
                if (bMat)
                {
                    if (tel_mat2 >= NFRAME)
                    {
                        srenew(mat_x2, tel_mat2+1);
                    }
                    snew(mat_x2[tel_mat2], n_ind_m);
                    for (i = 0; i < n_ind_m; i++)
                    {
                        copy_rvec(x[ind_m[i]], mat_x2[tel_mat2][i]);
                    }
                }
                tel_mat2++;
            }

            time2[teller2] = output_env_conv_time(oenv, t);

            teller2++;
            if (teller2 >= maxframe2)
            {
                maxframe2 += NFRAME;
                srenew(time2, maxframe2);
            }
        }
        while (read_next_x(oenv, status, &t, x, box));
        close_trj(status);
    }
    else
    {
        mat_x2   = mat_x;
        time2    = time;
        tel_mat2 = tel_mat;
        freq2    = freq;
    }
    gmx_rmpbc_done(gpbc);

    if (bMat || bBond)
    {
        /* calculate RMS matrix */
        fprintf(stderr, "\n");
        if (bMat)
        {
            fprintf(stderr, "Building %s matrix, %dx%d elements\n",
                    whatname[ewhat], tel_mat, tel_mat2);
            snew(rmsd_mat, tel_mat);
        }
        if (bBond)
        {
            fprintf(stderr, "Building bond angle matrix, %dx%d elements\n",
                    tel_mat, tel_mat2);
            snew(bond_mat, tel_mat);
        }
        snew(axis, tel_mat);
        snew(axis2, tel_mat2);
        rmsd_max = 0;
        if (bFile2)
        {
            rmsd_min = 1e10;
        }
        else
        {
            rmsd_min = 0;
        }
        rmsd_avg = 0;
        bond_max = 0;
        bond_min = 1e10;
        for (j = 0; j < tel_mat2; j++)
        {
            axis2[j] = time2[freq2*j];
        }
        if (bDelta)
        {
            if (bDeltaLog)
            {
                delta_scalex = 8.0/log(2.0);
                delta_xsize  = (int)(log(tel_mat/2)*delta_scalex+0.5)+1;
            }
            else
            {
                delta_xsize = tel_mat/2;
            }
            delta_scaley = 1.0/delta_maxy;
            snew(delta, delta_xsize);
            for (j = 0; j < delta_xsize; j++)
            {
                snew(delta[j], del_lev+1);
            }
            if (avl > 0)
            {
                snew(rmsdav_mat, tel_mat);
                for (j = 0; j < tel_mat; j++)
                {
                    snew(rmsdav_mat[j], tel_mat);
                }
            }
        }

        if (bFitAll)
        {
            snew(mat_x2_j, natoms);
        }
        for (i = 0; i < tel_mat; i++)
        {
            axis[i] = time[freq*i];
            fprintf(stderr, "\r element %5d; time %5.2f  ", i, axis[i]);
            if (bMat)
            {
                snew(rmsd_mat[i], tel_mat2);
            }
            if (bBond)
            {
                snew(bond_mat[i], tel_mat2);
            }
            for (j = 0; j < tel_mat2; j++)
            {
                if (bFitAll)
                {
                    for (k = 0; k < n_ind_m; k++)
                    {
                        copy_rvec(mat_x2[j][k], mat_x2_j[k]);
                    }
                    do_fit(n_ind_m, w_rls_m, mat_x[i], mat_x2_j);
                }
                else
                {
                    mat_x2_j = mat_x2[j];
                }
                if (bMat)
                {
                    if (bFile2 || (i < j))
                    {
                        rmsd_mat[i][j] =
                            calc_similar_ind(ewhat != ewRMSD, irms[0], ind_rms_m,
                                             w_rms_m, mat_x[i], mat_x2_j);
                        if (rmsd_mat[i][j] > rmsd_max)
                        {
                            rmsd_max = rmsd_mat[i][j];
                        }
                        if (rmsd_mat[i][j] < rmsd_min)
                        {
                            rmsd_min = rmsd_mat[i][j];
                        }
                        rmsd_avg += rmsd_mat[i][j];
                    }
                    else
                    {
                        rmsd_mat[i][j] = rmsd_mat[j][i];
                    }
                }
                if (bBond)
                {
                    if (bFile2 || (i <= j))
                    {
                        ang = 0.0;
                        for (m = 0; m < ibond; m++)
                        {
                            rvec_sub(mat_x[i][ind_bond1[m]], mat_x[i][ind_bond2[m]], vec1);
                            rvec_sub(mat_x2_j[ind_bond1[m]], mat_x2_j[ind_bond2[m]], vec2);
                            ang += acos(cos_angle(vec1, vec2));
                        }
                        bond_mat[i][j] = ang*180.0/(M_PI*ibond);
                        if (bond_mat[i][j] > bond_max)
                        {
                            bond_max = bond_mat[i][j];
                        }
                        if (bond_mat[i][j] < bond_min)
                        {
                            bond_min = bond_mat[i][j];
                        }
                    }
                    else
                    {
                        bond_mat[i][j] = bond_mat[j][i];
                    }
                }
            }
        }
        if (bFile2)
        {
            rmsd_avg /= tel_mat*tel_mat2;
        }
        else
        {
            rmsd_avg /= tel_mat*(tel_mat - 1)/2;
        }
        if (bMat && (avl > 0))
        {
            rmsd_max = 0.0;
            rmsd_min = 0.0;
            rmsd_avg = 0.0;
            for (j = 0; j < tel_mat-1; j++)
            {
                for (i = j+1; i < tel_mat; i++)
                {
                    av_tot     = 0;
                    weight_tot = 0;
                    for (my = -avl; my <= avl; my++)
                    {
                        if ((j+my >= 0) && (j+my < tel_mat))
                        {
                            abs_my = abs(my);
                            for (mx = -avl; mx <= avl; mx++)
                            {
                                if ((i+mx >= 0) && (i+mx < tel_mat))
                                {
                                    weight      = (real)(avl+1-max(abs(mx), abs_my));
                                    av_tot     += weight*rmsd_mat[i+mx][j+my];
                                    weight_tot += weight;
                                }
                            }
                        }
                    }
                    rmsdav_mat[i][j] = av_tot/weight_tot;
                    rmsdav_mat[j][i] = rmsdav_mat[i][j];
                    if (rmsdav_mat[i][j] > rmsd_max)
                    {
                        rmsd_max = rmsdav_mat[i][j];
                    }
                }
            }
            rmsd_mat = rmsdav_mat;
        }

        if (bMat)
        {
            fprintf(stderr, "\n%s: Min %f, Max %f, Avg %f\n",
                    whatname[ewhat], rmsd_min, rmsd_max, rmsd_avg);
            rlo.r = 1; rlo.g = 1; rlo.b = 1;
            rhi.r = 0; rhi.g = 0; rhi.b = 0;
            if (rmsd_user_max != -1)
            {
                rmsd_max = rmsd_user_max;
            }
            if (rmsd_user_min != -1)
            {
                rmsd_min = rmsd_user_min;
            }
            if ((rmsd_user_max !=  -1) || (rmsd_user_min != -1))
            {
                fprintf(stderr, "Min and Max value set to resp. %f and %f\n",
                        rmsd_min, rmsd_max);
            }
            sprintf(buf, "%s %s matrix", gn_rms[0], whatname[ewhat]);
            write_xpm(opt2FILE("-m", NFILE, fnm, "w"), 0, buf, whatlabel[ewhat],
                      output_env_get_time_label(oenv), output_env_get_time_label(oenv), tel_mat, tel_mat2,
                      axis, axis2, rmsd_mat, rmsd_min, rmsd_max, rlo, rhi, &nlevels);
            /* Print the distribution of RMSD values */
            if (opt2bSet("-dist", NFILE, fnm))
            {
                low_rmsd_dist(opt2fn("-dist", NFILE, fnm), rmsd_max, tel_mat, rmsd_mat, oenv);
            }

            if (bDelta)
            {
                snew(delta_tot, delta_xsize);
                for (j = 0; j < tel_mat-1; j++)
                {
                    for (i = j+1; i < tel_mat; i++)
                    {
                        mx = i-j;
                        if (mx < tel_mat/2)
                        {
                            if (bDeltaLog)
                            {
                                mx = (int)(log(mx)*delta_scalex+0.5);
                            }
                            my             = (int)(rmsd_mat[i][j]*delta_scaley*del_lev+0.5);
                            delta_tot[mx] += 1.0;
                            if ((rmsd_mat[i][j] >= 0) && (rmsd_mat[i][j] <= delta_maxy))
                            {
                                delta[mx][my] += 1.0;
                            }
                        }
                    }
                }
                delta_max = 0;
                for (i = 0; i < delta_xsize; i++)
                {
                    if (delta_tot[i] > 0.0)
                    {
                        delta_tot[i] = 1.0/delta_tot[i];
                        for (j = 0; j <= del_lev; j++)
                        {
                            delta[i][j] *= delta_tot[i];
                            if (delta[i][j] > delta_max)
                            {
                                delta_max = delta[i][j];
                            }
                        }
                    }
                }
                fprintf(stderr, "Maximum in delta matrix: %f\n", delta_max);
                snew(del_xaxis, delta_xsize);
                snew(del_yaxis, del_lev+1);
                for (i = 0; i < delta_xsize; i++)
                {
                    del_xaxis[i] = axis[i]-axis[0];
                }
                for (i = 0; i < del_lev+1; i++)
                {
                    del_yaxis[i] = delta_maxy*i/del_lev;
                }
                sprintf(buf, "%s %s vs. delta t", gn_rms[0], whatname[ewhat]);
                fp = gmx_ffopen("delta.xpm", "w");
                write_xpm(fp, 0, buf, "density", output_env_get_time_label(oenv), whatlabel[ewhat],
                          delta_xsize, del_lev+1, del_xaxis, del_yaxis,
                          delta, 0.0, delta_max, rlo, rhi, &nlevels);
                gmx_ffclose(fp);
            }
            if (opt2bSet("-bin", NFILE, fnm))
            {
                /* NB: File must be binary if we use fwrite */
                fp = ftp2FILE(efDAT, NFILE, fnm, "wb");
                for (i = 0; i < tel_mat; i++)
                {
                    if (fwrite(rmsd_mat[i], sizeof(**rmsd_mat), tel_mat2, fp) != tel_mat2)
                    {
                        gmx_fatal(FARGS, "Error writing to output file");
                    }
                }
                gmx_ffclose(fp);
            }
        }
        if (bBond)
        {
            fprintf(stderr, "\nMin. angle: %f, Max. angle: %f\n", bond_min, bond_max);
            if (bond_user_max != -1)
            {
                bond_max = bond_user_max;
            }
            if (bond_user_min != -1)
            {
                bond_min = bond_user_min;
            }
            if ((bond_user_max !=  -1) || (bond_user_min != -1))
            {
                fprintf(stderr, "Bond angle Min and Max set to:\n"
                        "Min. angle: %f, Max. angle: %f\n", bond_min, bond_max);
            }
            rlo.r = 1; rlo.g = 1; rlo.b = 1;
            rhi.r = 0; rhi.g = 0; rhi.b = 0;
            sprintf(buf, "%s av. bond angle deviation", gn_rms[0]);
            write_xpm(opt2FILE("-bm", NFILE, fnm, "w"), 0, buf, "degrees",
                      output_env_get_time_label(oenv), output_env_get_time_label(oenv), tel_mat, tel_mat2,
                      axis, axis2, bond_mat, bond_min, bond_max, rlo, rhi, &nlevels);
        }
    }

    bAv = opt2bSet("-a", NFILE, fnm);

    /* Write the RMSD's to file */
    if (!bPrev)
    {
        sprintf(buf, "%s", whatxvgname[ewhat]);
    }
    else
    {
        sprintf(buf, "%s with frame %g %s ago", whatxvgname[ewhat],
                time[prev*freq]-time[0], output_env_get_time_label(oenv));
    }
    fp = xvgropen(opt2fn("-o", NFILE, fnm), buf, output_env_get_xvgr_tlabel(oenv),
                  whatxvglabel[ewhat], oenv);
    if (output_env_get_print_xvgr_codes(oenv))
    {
        fprintf(fp, "@ subtitle \"%s%s after %s%s%s\"\n",
                (nrms == 1) ? "" : "of ", gn_rms[0], fitgraphlabel[efit],
                bFit     ? " to " : "", bFit ? gn_fit : "");
    }
    if (nrms != 1)
    {
        xvgr_legend(fp, nrms, (const char**)gn_rms, oenv);
    }
    for (i = 0; (i < teller); i++)
    {
        if (bSplit && i > 0 &&
            abs(time[bPrev ? freq*i : i]/output_env_get_time_factor(oenv)) < 1e-5)
        {
            fprintf(fp, "&\n");
        }
        fprintf(fp, "%12.7f", time[bPrev ? freq*i : i]);
        for (j = 0; (j < nrms); j++)
        {
            fprintf(fp, " %12.7f", rls[j][i]);
            if (bAv)
            {
                rlstot += rls[j][i];
            }
        }
        fprintf(fp, "\n");
    }
    gmx_ffclose(fp);

    if (bMirror)
    {
        /* Write the mirror RMSD's to file */
        sprintf(buf, "%s with Mirror", whatxvgname[ewhat]);
        sprintf(buf2, "Mirror %s", whatxvglabel[ewhat]);
        fp = xvgropen(opt2fn("-mir", NFILE, fnm), buf, output_env_get_xvgr_tlabel(oenv),
                      buf2, oenv);
        if (nrms == 1)
        {
            if (output_env_get_print_xvgr_codes(oenv))
            {
                fprintf(fp, "@ subtitle \"of %s after lsq fit to mirror of %s\"\n",
                        gn_rms[0], gn_fit);
            }
        }
        else
        {
            if (output_env_get_print_xvgr_codes(oenv))
            {
                fprintf(fp, "@ subtitle \"after lsq fit to mirror %s\"\n", gn_fit);
            }
            xvgr_legend(fp, nrms, (const char**)gn_rms, oenv);
        }
        for (i = 0; (i < teller); i++)
        {
            if (bSplit && i > 0 && abs(time[i]) < 1e-5)
            {
                fprintf(fp, "&\n");
            }
            fprintf(fp, "%12.7f", time[i]);
            for (j = 0; (j < nrms); j++)
            {
                fprintf(fp, " %12.7f", rlsm[j][i]);
            }
            fprintf(fp, "\n");
        }
        gmx_ffclose(fp);
    }

    if (bAv)
    {
        sprintf(buf, "Average %s", whatxvgname[ewhat]);
        sprintf(buf2, "Average %s", whatxvglabel[ewhat]);
        fp = xvgropen(opt2fn("-a", NFILE, fnm), buf, "Residue", buf2, oenv);
        for (j = 0; (j < nrms); j++)
        {
            fprintf(fp, "%10d  %10g\n", j, rlstot/teller);
        }
        gmx_ffclose(fp);
    }

    if (bNorm)
    {
        fp = xvgropen("aver.xvg", gn_rms[0], "Residue", whatxvglabel[ewhat], oenv);
        for (j = 0; (j < irms[0]); j++)
        {
            fprintf(fp, "%10d  %10g\n", j, rlsnorm[j]/teller);
        }
        gmx_ffclose(fp);
    }
    do_view(oenv, opt2fn_null("-a", NFILE, fnm), "-graphtype bar");
    do_view(oenv, opt2fn("-o", NFILE, fnm), NULL);
    do_view(oenv, opt2fn_null("-mir", NFILE, fnm), NULL);
    do_view(oenv, opt2fn_null("-m", NFILE, fnm), NULL);
    do_view(oenv, opt2fn_null("-bm", NFILE, fnm), NULL);
    do_view(oenv, opt2fn_null("-dist", NFILE, fnm), NULL);

    return 0;
}
示例#8
0
/* Create a TNG molecule representing the selection groups
 * to write */
static void add_selection_groups(tng_trajectory_t  tng,
                                 const gmx_mtop_t *mtop)
{
    const gmx_moltype_t     *molType;
    const t_atoms           *atoms;
    const t_atom            *at;
    const t_resinfo         *resInfo;
    const t_ilist           *ilist;
    int                      nAtoms      = 0, i = 0, j, molIt, atomIt, nameIndex;
    int                      atom_offset = 0;
    tng_molecule_t           mol, iterMol;
    tng_chain_t              chain;
    tng_residue_t            res;
    tng_atom_t               atom;
    tng_bond_t               tngBond;
    gmx_int64_t              nMols;
    char                    *groupName;

    /* The name of the TNG molecule containing the selection group is the
     * same as the name of the selection group. */
    nameIndex = *mtop->groups.grps[egcCompressedX].nm_ind;
    groupName = *mtop->groups.grpname[nameIndex];

    tng_molecule_alloc(tng, &mol);
    tng_molecule_name_set(tng, mol, groupName);
    tng_molecule_chain_add(tng, mol, "", &chain);
    for (molIt = 0; molIt < mtop->nmoltype; molIt++)
    {
        molType = &mtop->moltype[mtop->molblock[molIt].type];

        atoms = &molType->atoms;

        for (j = 0; j < mtop->molblock[molIt].nmol; j++)
        {
            bool bAtomsAdded = FALSE;
            for (atomIt = 0; atomIt < atoms->nr; atomIt++, i++)
            {
                char *res_name;
                int   res_id;

                if (ggrpnr(&mtop->groups, egcCompressedX, i) != 0)
                {
                    continue;
                }
                at = &atoms->atom[atomIt];
                if (atoms->nres > 0)
                {
                    resInfo = &atoms->resinfo[at->resind];
                    /* FIXME: When TNG supports both residue index and residue
                     * number the latter should be used. */
                    res_name = *resInfo->name;
                    res_id   = at->resind + 1;
                }
                else
                {
                    res_name = (char *)"";
                    res_id   = 0;
                }
                if (tng_chain_residue_find(tng, chain, res_name, res_id, &res)
                    != TNG_SUCCESS)
                {
                    /* Since there is ONE chain for selection groups do not keep the
                     * original residue IDs - otherwise there might be conflicts. */
                    tng_chain_residue_add(tng, chain, res_name, &res);
                }
                tng_residue_atom_w_id_add(tng, res, *(atoms->atomname[atomIt]),
                                          *(atoms->atomtype[atomIt]),
                                          atom_offset + atomIt, &atom);
                nAtoms++;
                bAtomsAdded = TRUE;
            }
            /* Add bonds. */
            if (bAtomsAdded)
            {
                for (int k = 0; k < F_NRE; k++)
                {
                    if (IS_CHEMBOND(k))
                    {
                        ilist = &molType->ilist[k];
                        if (ilist)
                        {
                            int l = 1;
                            while (l < ilist->nr)
                            {
                                int atom1, atom2;
                                atom1 = ilist->iatoms[l] + atom_offset;
                                atom2 = ilist->iatoms[l+1] + atom_offset;
                                if (ggrpnr(&mtop->groups, egcCompressedX, atom1) == 0 &&
                                    ggrpnr(&mtop->groups, egcCompressedX, atom2) == 0)
                                {
                                    tng_molecule_bond_add(tng, mol, ilist->iatoms[l],
                                                          ilist->iatoms[l+1], &tngBond);
                                }
                                l += 3;
                            }
                        }
                    }
                }
                /* Settle is described using three atoms */
                ilist = &molType->ilist[F_SETTLE];
                if (ilist)
                {
                    int l = 1;
                    while (l < ilist->nr)
                    {
                        int atom1, atom2, atom3;
                        atom1 = ilist->iatoms[l] + atom_offset;
                        atom2 = ilist->iatoms[l+1] + atom_offset;
                        atom3 = ilist->iatoms[l+2] + atom_offset;
                        if (ggrpnr(&mtop->groups, egcCompressedX, atom1) == 0)
                        {
                            if (ggrpnr(&mtop->groups, egcCompressedX, atom2) == 0)
                            {
                                tng_molecule_bond_add(tng, mol, atom1,
                                                      atom2, &tngBond);
                            }
                            if (ggrpnr(&mtop->groups, egcCompressedX, atom3) == 0)
                            {
                                tng_molecule_bond_add(tng, mol, atom1,
                                                      atom3, &tngBond);
                            }
                        }
                        l += 4;
                    }
                }
            }
            atom_offset += atoms->nr;
        }
    }
    if (nAtoms != i)
    {
        tng_molecule_existing_add(tng, &mol);
        tng_molecule_cnt_set(tng, mol, 1);
        tng_num_molecule_types_get(tng, &nMols);
        for (gmx_int64_t k = 0; k < nMols; k++)
        {
            tng_molecule_of_index_get(tng, k, &iterMol);
            if (iterMol == mol)
            {
                continue;
            }
            tng_molecule_cnt_set(tng, iterMol, 0);
        }
    }
    else
    {
        tng_molecule_free(tng, &mol);
    }
}
示例#9
0
文件: topio.c 项目: andersx/gmx-debug
static void generate_qmexcl_moltype(gmx_moltype_t *molt,unsigned char *grpnr,
				    t_inputrec *ir)
{
  /* This routine expects molt->ilist to be of size F_NRE and ordered. */

  /* generates the exclusions between the individual QM atoms, as
   * these interactions should be handled by the QM subroutines and
   * not by the gromacs routines 
   */
  int
    i,j,l,k=0,jmax,qm_max=0,qm_nr=0,nratoms=0,link_nr=0,link_max=0;
  atom_id 
    *qm_arr=NULL,*link_arr=NULL,a1,a2,a3,a4,ftype=0;
  t_blocka
    qmexcl;
  t_block2
    qmexcl2;
  gmx_bool 
    *bQMMM,*blink,bexcl;

  /* First we search and select the QM atoms in an qm_arr array that
   * we use to create the exclusions.
   *
   * we take the possibility into account that a user has defined more
   * than one QM group:
   *
   * for that we also need to do this an ugly work-about just in case
   * the QM group contains the entire system...  
   */
  fprintf(stderr,"excluding classical QM-QM interactions...\n");

  jmax = ir->opts.ngQM;

  /* we first search for all the QM atoms and put them in an array 
   */
  for(j=0;j<jmax;j++){
    for(i=0;i<molt->atoms.nr;i++){
      if(qm_nr>=qm_max){
	qm_max += 100;
	srenew(qm_arr,qm_max);
      }
      if ((grpnr ? grpnr[i] : 0) == j){
	qm_arr[qm_nr++] = i;
      }
    }
  }  
  /* bQMMM[..] is an array containin TRUE/FALSE for atoms that are
   * QM/not QM. We first set all elements to false. Afterwards we use
   * the qm_arr to change the elements corresponding to the QM atoms
   * to TRUE.  
   */
  snew(bQMMM,molt->atoms.nr);
  for (i=0;i<molt->atoms.nr;i++)
    bQMMM[i]=FALSE;
  for (i=0;i<qm_nr;i++)
    bQMMM[qm_arr[i]]=TRUE;
  
  /* We remove all bonded interactions (i.e. bonds,
   * angles, dihedrals, 1-4's), involving the QM atoms. The way they
   * are removed is as follows: if the interaction invloves 2 atoms,
   * it is removed if both atoms are QMatoms. If it involves 3 atoms,
   * it is removed if at least two of the atoms are QM atoms, if the
   * interaction involves 4 atoms, it is removed if there are at least
   * 2 QM atoms.  Since this routine is called once before any forces
   * are computed, the top->idef.il[N].iatom[] array (see idef.h) can
   * be rewritten at this poitn without any problem. 25-9-2002 */
  
  /* first check weter we already have CONNBONDS: */
  if (molt->ilist[F_CONNBONDS].nr != 0){
    fprintf(stderr,"nr. of CONNBONDS present already: %d\n",
	    molt->ilist[F_CONNBONDS].nr/3);
    ftype = molt->ilist[F_CONNBONDS].iatoms[0];
    k = molt->ilist[F_CONNBONDS].nr;
  }
  /* now we delete all bonded interactions, except the ones describing
   * a chemical bond. These are converted to CONNBONDS
   */
  for (i=0;i<F_LJ;i++){
    if(i==F_CONNBONDS)
      continue;
    nratoms = interaction_function[i].nratoms;
    j = 0;
    while (j<molt->ilist[i].nr){
      bexcl = FALSE;
      switch (nratoms){
      case 2:
	a1 = molt->ilist[i].iatoms[j+1];
	a2 = molt->ilist[i].iatoms[j+2];
	bexcl = (bQMMM[a1] && bQMMM[a2]);
	/* a bonded beteen two QM atoms will be copied to the
  	 * CONNBONDS list, for reasons mentioned above 
	 */
	if(bexcl && i<F_ANGLES){
	  srenew(molt->ilist[F_CONNBONDS].iatoms,k+3);
	  molt->ilist[F_CONNBONDS].nr         += 3; 
	  molt->ilist[F_CONNBONDS].iatoms[k++] = ftype;
	  molt->ilist[F_CONNBONDS].iatoms[k++] = a1;
	  molt->ilist[F_CONNBONDS].iatoms[k++] = a2;
	}
	break;
      case 3:
	a1 = molt->ilist[i].iatoms[j+1];
	a2 = molt->ilist[i].iatoms[j+2];
	a3 = molt->ilist[i].iatoms[j+3];
	bexcl = ((bQMMM[a1] && bQMMM[a2]) ||
		 (bQMMM[a1] && bQMMM[a3]) ||
		 (bQMMM[a2] && bQMMM[a3]));
	break;
      case 4:
	a1 = molt->ilist[i].iatoms[j+1];
	a2 = molt->ilist[i].iatoms[j+2];
	a3 = molt->ilist[i].iatoms[j+3];
	a4 = molt->ilist[i].iatoms[j+4];
	bexcl = ((bQMMM[a1] && bQMMM[a2] && bQMMM[a3]) ||
		 (bQMMM[a1] && bQMMM[a2] && bQMMM[a4]) ||
		 (bQMMM[a1] && bQMMM[a3] && bQMMM[a4]) ||
		 (bQMMM[a2] && bQMMM[a3] && bQMMM[a4]));
	break;
      default:
	gmx_fatal(FARGS,"no such bonded interactions with %d atoms\n",nratoms);
      }
      if (bexcl){
	/* since the interaction involves QM atoms, these should be
         * removed from the MM ilist 
	 */
	molt->ilist[i].nr -= (nratoms+1);
	for (l=j;l<molt->ilist[i].nr;l++)
	  molt->ilist[i].iatoms[l] = molt->ilist[i].iatoms[l+(nratoms+1)];  
      } else {
	j += nratoms+1; /* the +1 is for the functype */
      }
    }
  }
  /* Now, we search for atoms bonded to a QM atom because we also want
   * to exclude their nonbonded interactions with the QM atoms. The
   * reason for this is that this interaction is accounted for in the
   * linkatoms interaction with the QMatoms and would be counted
   * twice.  */
 
  for(i=0;i<F_NRE;i++){
    if(IS_CHEMBOND(i)){
      j=0;
      while(j<molt->ilist[i].nr){
	a1 = molt->ilist[i].iatoms[j+1];
	a2 = molt->ilist[i].iatoms[j+2];
	if((bQMMM[a1] && !bQMMM[a2])||(!bQMMM[a1] && bQMMM[a2])){
	  if(link_nr>=link_max){
	    link_max += 10;
	    srenew(link_arr,link_max);
	  }
	  if(bQMMM[a1]){
	    link_arr[link_nr++] = a2;
	  } else {
	    link_arr[link_nr++] = a1;
	  }
	}
	j+=3;
      }
    }
  }   
  snew(blink,molt->atoms.nr);   
  for (i=0;i<molt->atoms.nr;i++)
    blink[i]=FALSE;
  for (i=0;i<link_nr;i++)
    blink[link_arr[i]]=TRUE;
  /* creating the exclusion block for the QM atoms. Each QM atom has
   * as excluded elements all the other QMatoms (and itself).
   */
  qmexcl.nr = molt->atoms.nr;
  qmexcl.nra = qm_nr*(qm_nr+link_nr)+link_nr*qm_nr; 
  snew(qmexcl.index,qmexcl.nr+1);
  snew(qmexcl.a,qmexcl.nra);
  j=0;
  for(i=0;i<qmexcl.nr;i++){
    qmexcl.index[i]=j;
    if(bQMMM[i]){
      for(k=0;k<qm_nr;k++){
	qmexcl.a[k+j] = qm_arr[k];
      }
      for(k=0;k<link_nr;k++){
	qmexcl.a[qm_nr+k+j] = link_arr[k];
      }
      j+=(qm_nr+link_nr);
    }
    if(blink[i]){
      for(k=0;k<qm_nr;k++){
	qmexcl.a[k+j] = qm_arr[k];
      }
      j+=qm_nr;
    }
  }
  qmexcl.index[qmexcl.nr]=j;
  
  /* and merging with the exclusions already present in sys.
   */

  init_block2(&qmexcl2,molt->atoms.nr);
  b_to_b2(&qmexcl, &qmexcl2);
  merge_excl(&(molt->excls),&qmexcl2);
  done_block2(&qmexcl2);

  /* Finally, we also need to get rid of the pair interactions of the
   * classical atom bonded to the boundary QM atoms with the QMatoms,
   * as this interaction is already accounted for by the QM, so also
   * here we run the risk of double counting! We proceed in a similar
   * way as we did above for the other bonded interactions: */
  for (i=F_LJ14;i<F_COUL14;i++){
    nratoms = interaction_function[i].nratoms;
    j = 0;
    while (j<molt->ilist[i].nr){
      bexcl = FALSE;
      a1 = molt->ilist[i].iatoms[j+1];
      a2 = molt->ilist[i].iatoms[j+2];
      bexcl = ((bQMMM[a1] && bQMMM[a2])||
	       (blink[a1] && bQMMM[a2])||
	       (bQMMM[a1] && blink[a2]));
      if (bexcl){
	/* since the interaction involves QM atoms, these should be
         * removed from the MM ilist 
	 */
	molt->ilist[i].nr -= (nratoms+1);
	for (k=j;k<molt->ilist[i].nr;k++)
	  molt->ilist[i].iatoms[k] = molt->ilist[i].iatoms[k+(nratoms+1)];  
      } else {
	j += nratoms+1; /* the +1 is for the functype */
      }
    }
  }  
  
  free(qm_arr);  
  free(bQMMM);
  free(link_arr);
  free(blink);
} /* generate_qmexcl */ 
示例#10
0
static void clean_vsite_bonds(t_params *plist, t_pindex pindex[], 
			    int cftype, int vsite_type[])
{
  int      ftype,i,j,parnr,k,l,m,n,nvsite,nOut,kept_i,vsnral,vsitetype;
  int      nconverted,nremoved;
  atom_id  atom,oatom,constr,at1,at2;
  atom_id  vsiteatoms[MAXATOMLIST];
  gmx_bool     bKeep,bRemove,bUsed,bPresent,bThisFD,bThisOUT,bAllFD,bFirstTwo;
  t_params *ps;

  if (cftype == F_CONNBONDS)
    return;
  
  ps = &(plist[cftype]);
  vsnral=0;
  kept_i=0;
  nconverted=0;
  nremoved=0;
  nOut=0;
  for(i=0; (i<ps->nr); i++) { /* for all bonds in the plist */
    bKeep=FALSE;
    bRemove=FALSE;
    bAllFD=TRUE;
    /* check if all virtual sites are constructed from the same atoms */
    nvsite=0;
    if(debug) 
      fprintf(debug,"constr %u %u:",ps->param[i].AI+1,ps->param[i].AJ+1);
    for(k=0; (k<2) && !bKeep && !bRemove; k++) { 
      /* for all atoms in the bond */
      atom = ps->param[i].a[k];
      if (vsite_type[atom]!=NOTSET) {
	if(debug) {
	  fprintf(debug," d%d[%d: %d %d %d]",k,atom+1,
		  plist[pindex[atom].ftype].param[pindex[atom].parnr].AJ+1,
		  plist[pindex[atom].ftype].param[pindex[atom].parnr].AK+1,
		  plist[pindex[atom].ftype].param[pindex[atom].parnr].AL+1);
	}
	nvsite++;
	bThisFD = ( (pindex[atom].ftype == F_VSITE3FD ) ||
                (pindex[atom].ftype == F_VSITE3FAD) ||
                (pindex[atom].ftype == F_VSITE4FD ) ||
                (pindex[atom].ftype == F_VSITE4FDN ) );
	bThisOUT= ( (pindex[atom].ftype == F_VSITE3OUT) &&
		    (interaction_function[cftype].flags & IF_CONSTRAINT) );
	bAllFD = bAllFD && bThisFD;
	if (bThisFD || bThisOUT) {
	  if(debug)fprintf(debug," %s",bThisOUT?"out":"fd");
	  oatom = ps->param[i].a[1-k]; /* the other atom */
	  if ( vsite_type[oatom]==NOTSET &&
	       oatom==plist[pindex[atom].ftype].param[pindex[atom].parnr].AJ ){
	    /* if the other atom isn't a vsite, and it is AI */
	    bRemove=TRUE;
	    if (bThisOUT)
	      nOut++;
	    if(debug)fprintf(debug," D-AI");
	  }
	}
	if (!bRemove) {
	  if (nvsite==1) {
	    /* if this is the first vsite we encounter then
	       store construction atoms */
	    vsnral=NRAL(pindex[atom].ftype)-1;
	    for(m=0; (m<vsnral); m++)
	      vsiteatoms[m]=
		plist[pindex[atom].ftype].param[pindex[atom].parnr].a[m+1];
	  } else {
	    /* if it is not the first then
	       check if this vsite is constructed from the same atoms */
	    if (vsnral == NRAL(pindex[atom].ftype)-1 )
	      for(m=0; (m<vsnral) && !bKeep; m++) {
		bPresent=FALSE;
		constr=
		  plist[pindex[atom].ftype].param[pindex[atom].parnr].a[m+1];
		for(n=0; (n<vsnral) && !bPresent; n++)
		  if (constr == vsiteatoms[n])
		    bPresent=TRUE;
		if (!bPresent) {
		  bKeep=TRUE;
		  if(debug)fprintf(debug," !present");
		}
	      }
	    else {
	      bKeep=TRUE;
	      if(debug)fprintf(debug," !same#at");
	    }
	  }
	}
      }
    }
    
    if (bRemove) 
      bKeep=FALSE;
    else {
      /* if we have no virtual sites in this bond, keep it */
      if (nvsite==0) {
	if (debug)fprintf(debug," no vsite");
	bKeep=TRUE;
      }
    
      /* check if all non-vsite atoms are used in construction: */
      bFirstTwo=TRUE;
      for(k=0; (k<2) && !bKeep; k++) { /* for all atoms in the bond */
	atom = ps->param[i].a[k];
	if (vsite_type[atom]==NOTSET) {
	  bUsed=FALSE;
	  for(m=0; (m<vsnral) && !bUsed; m++)
	    if (atom == vsiteatoms[m]) {
	      bUsed=TRUE;
	      bFirstTwo = bFirstTwo && m<2;
	    }
	  if (!bUsed) {
	    bKeep=TRUE;
	    if(debug)fprintf(debug," !used");
	  }
	}
      }
      
      if ( ! ( bAllFD && bFirstTwo ) )
	/* check if all constructing atoms are constrained together */
	for (m=0; m<vsnral && !bKeep; m++) { /* all constr. atoms */
	  at1 = vsiteatoms[m];
	  at2 = vsiteatoms[(m+1) % vsnral];
	  bPresent=FALSE;
	  for (ftype=0; ftype<F_NRE; ftype++)
	    if ( interaction_function[ftype].flags & IF_CONSTRAINT )
	      for (j=0; (j<plist[ftype].nr) && !bPresent; j++)
		/* all constraints until one matches */
		bPresent = ( ( (plist[ftype].param[j].AI == at1) &&
			       (plist[ftype].param[j].AJ == at2) ) || 
			     ( (plist[ftype].param[j].AI == at2) &&
			       (plist[ftype].param[j].AJ == at1) ) );
	  if (!bPresent) {
	    bKeep=TRUE;
	    if(debug)fprintf(debug," !bonded");
	  }
	}
    }
    
    if ( bKeep ) {
      if(debug)fprintf(debug," keeping");
      /* now copy the bond to the new array */
      memcpy(&(ps->param[kept_i]),
	     &(ps->param[i]),(size_t)sizeof(ps->param[0]));
      kept_i++;
    } else if (IS_CHEMBOND(cftype)) {
      srenew(plist[F_CONNBONDS].param,plist[F_CONNBONDS].nr+1);
      memcpy(&(plist[F_CONNBONDS].param[plist[F_CONNBONDS].nr]),
	     &(ps->param[i]),(size_t)sizeof(plist[F_CONNBONDS].param[0]));
      plist[F_CONNBONDS].nr++;
      nconverted++;
    } else
      nremoved++;
    if(debug)fprintf(debug,"\n");
  }
  
  if (nremoved)
    fprintf(stderr,"Removed   %4d %15ss with virtual sites, %5d left\n",
	    nremoved, interaction_function[cftype].longname, kept_i);
  if (nconverted)
    fprintf(stderr,"Converted %4d %15ss with virtual sites to connections, %5d left\n",
	    nconverted, interaction_function[cftype].longname, kept_i);
  if (nOut)
    fprintf(stderr,"Warning: removed %d %ss with vsite with %s construction\n"
	    "         This vsite construction does not guarantee constant "
	    "bond-length\n"
	    "         If the constructions were generated by pdb2gmx ignore "
	    "this warning\n",
	    nOut, interaction_function[cftype].longname, 
	    interaction_function[F_VSITE3OUT].longname );
  ps->nr=kept_i;
}