Beispiel #1
0
static void rotate_x(int natom,rvec xin[],real angle,rvec xout[],
		     gmx_bool bZ,gmx_bool bUpsideDown,real dz)
{
  int i;
  matrix mat;
  
  angle *= DEG2RAD;
  clear_mat(mat);
  if (bZ) {
    mat[XX][XX] = cos(angle);
    mat[XX][YY] = sin(angle);
    mat[YY][XX] = -sin(angle);
    mat[YY][YY] = cos(angle);
    mat[ZZ][ZZ] = 1;
  }
  else {
    mat[XX][XX] = 1;
    mat[YY][YY] = cos(angle);
    mat[YY][ZZ] = sin(angle);
    mat[ZZ][YY] = -sin(angle);
    mat[ZZ][ZZ] = cos(angle);
  }
    
  for(i=0; (i<natom); i++) {
    mvmul(mat,xin[i],xout[i]);
    if (bUpsideDown)
      xout[i][ZZ] *= -1;
    xout[i][ZZ] += dz;
  }
}
Beispiel #2
0
msym_error_t findPermutation(msym_symmetry_operation_t *sop, int l, double (*v[l])[3], msym_thresholds_t *t, msym_permutation_t *perm){
    msym_error_t ret = MSYM_SUCCESS;
    double m[3][3];
    symmetryOperationMatrix(sop, m);
    
    perm->p = malloc(sizeof(int[l]));
    memset(perm->p, -1, sizeof(int[l])); //TODO: 2s complement
    perm->p_length = l;
    
    for(int i = 0; i < l;i++){
        int j;
        double r[3];
        mvmul(*v[i], m, r);
        for(j = 0;j < l;j++){
            if(vequal(r, *v[j],t->permutation)){
                perm->p[i] = j;
                break;
            }
        }
        if(j == l) {
            char buf[16];
            symmetryOperationName(sop, sizeof(buf), buf);
            msymSetErrorDetails("Unable to determine permutation for symmetry operation %s",buf);
            ret = MSYM_PERMUTATION_ERROR;
            goto err;
        }
    }
    if(MSYM_SUCCESS != (ret = setPermutationCycles(perm))) goto err;
    
    return ret;
    
err:
    free(perm->p);
    return ret;
}
Beispiel #3
0
PyObject *apply_rotation( PyObject *self, PyObject *args)
{
  PyObject *Rotation;
  PyObject *py_v;
  real phi;
  if(!PyArg_ParseTuple(args,"OOd",&Rotation,&py_v, &phi))
    return NULL;

  PyObject *rm1 = PyObject_GetAttrString(Rotation,"m1");
  PyObject *rm2 = PyObject_GetAttrString(Rotation,"m2");

  matrix m1, m2;
  PyObject2matrix(rm1, m1);
  PyObject2matrix(rm2, m2);
  rvec v, v2;

  PyObject *py_v2 = PyObject_GetAttrString(Rotation,"v2");

  Pyvec2rvec(py_v, v);
  Pyvec2rvec(py_v2, v2);

  rvec vec;
  rvec_sub(v, v2, vec );

  rvec b, d, a, c, e;
  mvmul(m1, vec, b);
  mvmul(m2, vec, d);
  real cc = cos(phi);
  svmul( cc, vec, a);
  svmul( -cc, b, c);
  svmul( sin(phi), d, e);

  clear_rvec( vec );
  rvec_add( a, b, vec);
  rvec_add( vec, c, vec );
  rvec_add( vec, e, vec );
  
  clear_rvec(v);
  rvec_add( v2, vec, v);
  return Py_BuildValue("[ddd]", v[XX], v[YY], v[ZZ] );
 }
Beispiel #4
0
int gmx_editconf(int argc, char *argv[])
{
    const char
        *desc[] =
            {
                "editconf converts generic structure format to [TT].gro[tt], [TT].g96[tt]",
                "or [TT].pdb[tt].",
                "[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.",
                "The volume of a dodecahedron is 0.71 and that of a truncated octahedron",
                "is 0.77 of that of a cubic box with the same periodic image distance.",
                "[PAR]",
                "Option [TT]-box[tt] requires only",
                "one value for a cubic box, dodecahedron and a truncated octahedron.",
                "[PAR]",
                "With [TT]-d[tt] and a [TT]triclinic[tt] box the size of the system in the x, y",
                "and z 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 can not 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, 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 gro",
                "file is given as input. A special feature of the scaling option, when the",
                "factor -1 is given in one dimension, one obtains a mirror image,",
                "mirrored in one of the plains, 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 sizes at the bottom of your input file",
                "are correct when the periodicity is to be removed.",
                "[PAR]",
                "When writing [TT].pdb[tt] 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 -mead a special pdb (pqr) 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 -grasp 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] editconf can add a chain identifier",
                "to a pdb 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:[BR]",
                "[TT]editconf -f <in> -rotate 0 45 35.264 -bt o -box <veclen> -o <out>[tt][BR]",
                "where [TT]veclen[tt] is the size of the cubic box times sqrt(3)/2." };
    const char *bugs[] =
        {
            "For complex molecules, the periodicity removal routine may break down, ",
                "in that case you can use trjconv." };
    static real dist = 0.0, rbox = 0.0, to_diam = 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 };
    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 -box and -d" },
                    { "-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 -box and -d)" },
                    { "-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)" },
                    { "-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, etREAL,
                        { &bSig56 },
                        "Use rmin/2 (minimum in the Van der Waals potential) rather than sigma/2 " },
                    {
                        "-vdwread", FALSE, etBOOL,
                        { &bReadVDW },
                        "Read the Van der Waals radii from the file vdwradii.dat 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 pdb file when written. Can only be done when a topology is present" } };
#define NPA asize(pa)

    FILE *out;
    const char *infile, *outfile;
    char title[STRLEN];
    int outftp, inftp, natom, i, j, n_bfac, itype, ntype;
    double *bfac = NULL, c6, c12;
    int *bfac_nr = NULL;
    t_topology *top = NULL;
    t_atoms atoms;
    char *grpname, *sgrpname, *agrpname;
    int isize, ssize, tsize, asize;
    atom_id *index, *sindex, *tindex, *aindex;
    rvec *x, *v, gc, min, max, size;
    int ePBC;
    matrix box,rotmatrix,trans;
	rvec princd,tmpvec;
    gmx_bool bIndex, bSetSize, bSetAng, bCubic, bDist, bSetCenter, bAlign;
    gmx_bool bHaveV, bScale, bRho, bTranslate, bRotate, bCalcGeom, bCalcDiam;
    real xs, ys, zs, xcent, ycent, zcent, 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)

    CopyRight(stderr, argv[0]);
    parse_common_args(&argc, argv, PCA_CAN_VIEW, NFILE, fnm, NPA, pa,
                      asize(desc), desc, asize(bugs), bugs, &oenv);

    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;
    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) ||
                (fn2ftp(infile) == efTPA) ||
                (fn2ftp(infile) == efTPB)))
        gmx_fatal(FARGS,"Input file should be a .tp[abr] file"
            " when using the -mead option\n");

        get_stx_coordnum(infile,&natom);
        init_t_atoms(&atoms,natom,TRUE);
        snew(x,natom);
        snew(v,natom);
        read_stx_conf(infile,title,&atoms,x,v,&ePBC,box);
        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*((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*pow(sig6,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,min,max,bCalcDiam);
        rvec_sub(max, min, 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*acos(cos_angle_no_table(box[YY],box[ZZ])),
        norm2(box[ZZ])==0 ? 0 :
        RAD2DEG*acos(cos_angle_no_table(box[XX],box[ZZ])),
        norm2(box[YY])==0 ? 0 :
        RAD2DEG*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] = pow(dens/rho,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,min,max,FALSE);
        rvec_sub(max, min, size);
        if (bScale || bOrient || bRotate)
            printf("new system size : %6.3f %6.3f %6.3f\n",
                   size[XX],size[YY],size[ZZ]);
    }

    if (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*sqrt(2)/2;
            } else {
                box[XX][XX] = d;
                box[YY][XX] = d/3;
                box[YY][YY] = d*sqrt(2)*2/3;
                box[ZZ][XX] = -d/3;
                box[ZZ][YY] = d*sqrt(2)/3;
                box[ZZ][ZZ] = d*sqrt(6)/3;
            }
            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, min, max, 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*acos(cos_angle_no_table(box[YY],box[ZZ])),
        norm2(box[ZZ])==0 ? 0 :
        RAD2DEG*acos(cos_angle_no_table(box[XX],box[ZZ])),
        norm2(box[YY])==0 ? 0 :
        RAD2DEG*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",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
        {
            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 (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=ffopen(outfile,"w");
            write_pdbfile_indexed(out,title,&atoms,x,ePBC,box,' ',1,isize,index,conect,TRUE);
            ffclose(out);
        }
        else
        {
            write_sto_conf_indexed(outfile,title,&atoms,x,bHaveV?v:NULL,ePBC,box,isize,index); 
        }
    }
    else {
        if ((outftp == efPDB) || (outftp == efPQR)) {
            out=ffopen(outfile,"w");
            if (bMead) {
                set_pdb_wide_format(TRUE);
                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,title,&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);
            ffclose(out);
        }
        else
            write_sto_conf(outfile,title,&atoms,x,bHaveV?v:NULL,ePBC,box); 
    }
    gmx_atomprop_destroy(aps);

    do_view(oenv,outfile,NULL);

    thanx(stderr);

    return 0;
}
Beispiel #5
0
static void do_sdf(char *fnNDX,char *fnTPS,char *fnTRX, char *fnSDF, 
                   char *fnREF, bool bRef, rvec cutoff, real binwidth,
                   int mode, rvec triangle, rvec dtri)
{
  FILE       *fp;
  int        status;
  int        ng,natoms,i,j,k,l,X,Y,Z,lc,dest;
  ivec       nbin;
  int        ***count;
  /* real       ***sdf; */
  real       sdf,min_sdf=1e10,max_sdf=0;
  char       **grpname;
  int        *isize;
  int        isize_cg=0;
  int        isize_ref=3;
  int        ref_resind[3];
  int        nrefmol=0,refc=0;
  atom_id    **index;
  atom_id    *index_cg=NULL;
  atom_id    *index_ref=NULL;
  real       t,boxmin,hbox,normfac;
  real       invbinw;
  rvec       tri_upper,tri_lower;
  rvec       *x,xcog,dx,*x_i1,xi,*x_refmol;
  matrix     box;
  matrix     rot; /* rotation matrix := unit vectors for the molecule frame */
  rvec       k_mol,i1_mol,i2_mol,dx_mol;
  real       delta;
  atom_id    ix,jx;
  t_topology top;
  int        ePBC=-1;
  t_pbc      pbc;
  bool       bTop=FALSE,bRefDone=FALSE,bInGroup=FALSE;
  char       title[STRLEN];


  /* Read Topology */
  if (fnTPS) {
    bTop=read_tps_conf(fnTPS,title,&top,&ePBC,&x,NULL,box,TRUE);
  }
  


  if ( !bTop ) {
    fprintf(stderr,"\nNeed tpr-file to make a reference structure.\n");
    fprintf(stderr,"Option -r will be ignored!\n");
    bRef = FALSE;
  }


  /* Allocate memory for 4 groups, 3 dummy groups and a group for the ref 
structure if needed */
  ng = 4;
  snew(grpname,ng);
  /* the dummy groups are used to dynamically store triples of atoms */
  /* for molecular coordinate systems */
  if ( bRef )
    {
      snew(isize,ng+4);
      snew(index,ng+4);
    }
  else 
    {
      snew(isize,ng+3);
      snew(index,ng+3);
    }


  /* Read the index groups */
  fprintf(stderr,"\nSelect the 3 reference groups and the SDF group:\n");
  if (fnTPS)
    get_index(&top.atoms,fnNDX,ng,isize,index,grpname);
  else
    rd_index(fnNDX,ng,isize,index,grpname);


  isize[NDX_REF1]=isize[G_REF1];
  for (i=NDX_REF1; i<=NDX_REF3; i++)
    snew(index[i],isize[NDX_REF1]);


  /* Read first frame and check it */
  natoms=read_first_x(&status,fnTRX,&t,&x,box);
  if ( !natoms )
    gmx_fatal(FARGS,"Could not read coordinates from statusfile!\n");


  /* check with topology */
  if (fnTPS)
    if ( natoms > top.atoms.nr )
      gmx_fatal(FARGS,"Trajectory (%d atoms) does not match topology (%d atoms)!\n",
                  natoms,top.atoms.nr);


  /* check with index groups */
  for (i=0; i<ng; i++)
    for (j=0; j<isize[i]; j++)
      if ( index[i][j] >= natoms )
        gmx_fatal(FARGS,"Atom index (%d) in index group %s (%d atoms) larger "
                    "than number of atoms in trajectory (%d atoms)!\n",
                    index[i][j],grpname[i],isize[i],natoms);


  /* check reference groups */
  if ( mode == 1 )
    {
      if ( isize[G_REF1] != isize[G_REF2] || isize[G_REF1] != isize[G_REF3] || 
           isize[G_REF2] != isize[G_REF3] )
        gmx_fatal(FARGS,"For single particle SDF, all reference groups"
                    "must have the same size.\n");


      /* for single particle SDF dynamic triples are not needed */
      /* so we build them right here */


      /* copy all triples from G_REFx to NDX_REFx */    
      for (i=0; i<isize[G_REF1]; i++)
        {
          /* check if all three atoms come from the same molecule */
          for (j=G_REF1; j<=G_REF3; j++)
            ref_resind[j] = top.atoms.atom[index[j][i]].resind;


          if ( ref_resind[G_REF1] != ref_resind[G_REF2] ||
                 ref_resind[G_REF2] != ref_resind[G_REF3] ||
                 ref_resind[G_REF3] != ref_resind[G_REF1] )
              {
                fprintf(stderr,"\nWarning: reference triple (%d) will be skipped.\n",i);
                fprintf(stderr,  "         resnr[1]: %d, resnr[2]: %d, resnr[3]: %d\n",
                        ref_resind[G_REF1],ref_resind[G_REF2], ref_resind[G_REF3]);
                isize[NDX_REF1]--;
                for (j=NDX_REF1; j<=NDX_REF3; j++)
                  srenew(index[j],isize[NDX_REF1]);
                continue;
              }
          else
            /* check if all entries are unique*/
            if ( index[G_REF1][i] == index[G_REF2][i] ||
                 index[G_REF2][i] == index[G_REF3][i] ||
                 index[G_REF3][i] == index[G_REF1][i] )
              {
                fprintf(stderr,"Warning: reference triple (%d) will be skipped.\n",i);
                fprintf(stderr,  "         index[1]: %d, index[2]: %d, index[3]: %d\n",
                        index[G_REF1][i],index[G_REF2][i],index[G_REF3][i]);    
                isize[NDX_REF1]--;
                for (j=NDX_REF1; j<=NDX_REF3; j++)
                  srenew(index[j],isize[NDX_REF1]);
                continue;
              }
            else /* everythings fine, copy that one */
              for (j=G_REF1; j<=G_REF3; j++)
                index[j+4][i] = index[j][i];
        }
    }
  else if ( mode == 2 )
    {
      if ( isize[G_REF1] != isize[G_REF2] )
        gmx_fatal(FARGS,"For two particle SDF, reference groups 1 and 2"
                    "must have the same size.\n");


      for (i=0; i<isize[G_REF1]; i++)
        {
          /* check consistency for atoms 1 and 2 */
          for (j=G_REF1; j<=G_REF2; j++)
            ref_resind[j] = top.atoms.atom[index[j][i]].resind;


          if ( ref_resind[G_REF1] != ref_resind[G_REF2] ||
               index[G_REF1][i] == index[G_REF2][i] )
            {
              if ( ref_resind[G_REF1] != ref_resind[G_REF2] )
                {
                  fprintf(stderr,"\nWarning: bond (%d) not from one molecule."
                          "Will not be used for SDF.\n",i);
                  fprintf(stderr,  "         resnr[1]: %d, resnr[2]: %d\n",
                          ref_resind[G_REF1],ref_resind[G_REF2]);
                }
              else
                {
                  fprintf(stderr,"\nWarning: atom1 and atom2 are identical."
                          "Bond (%d) will not be used for SDF.\n",i);
                  fprintf(stderr,  "         index[1]: %d, index[2]: %d\n",
                          index[G_REF1][i],index[G_REF2][i]);
                }
              for (j=NDX_REF1; j<=NDX_REF2; j++)
                {
                  for (k=i; k<isize[G_REF1]-1; k++)
                    index[j][k]=index[j][k+1];
                  isize[j]--;
                  srenew(index[j],isize[j]);
                }
            }
        }
    }


  /* Read Atoms for refmol group */
  if ( bRef )
    {
      snew(index[G_REFMOL],1);


      for (i=G_REF1; i<=G_REF3; i++)
        ref_resind[i] = top.atoms.atom[index[i][0]].resind;


      for (i=0; i<natoms; i++)
        {
          if (  ref_resind[G_REF1] == top.atoms.atom[i].resind ||
                ref_resind[G_REF2] == top.atoms.atom[i].resind ||
                ref_resind[G_REF3] == top.atoms.atom[i].resind )
            nrefmol++;
        }
      srenew(index[G_REFMOL],nrefmol);
      isize[G_REFMOL] = nrefmol;
      nrefmol = 0;


      for (i=0; i<natoms; i++)
        {
          if (  ref_resind[G_REF1] == top.atoms.atom[i].resind ||
                ref_resind[G_REF2] == top.atoms.atom[i].resind ||
                ref_resind[G_REF3] == top.atoms.atom[i].resind )
            {
              index[G_REFMOL][nrefmol] = i;
              nrefmol++;
            }
        }
    }


  /* initialize some stuff */
  boxmin = min( norm(box[XX]), min( norm(box[YY]), norm(box[ZZ]) ) );
  hbox   = boxmin / 2.0;


  for (i=0; i<DIM; i++)
    {
      cutoff[i] = cutoff[i] / 2;
      nbin[i]   = (int)(2 * cutoff[i] / binwidth) + 1;
      invbinw = 1.0 / binwidth;
      tri_upper[i] = triangle[i] + dtri[i];
      tri_upper[i] = sqr(tri_upper[i]);
      tri_lower[i] = triangle[i] - dtri[i];
      tri_lower[i] = sqr(tri_lower[i]);
    }


  /* Allocate the array's for sdf */
  snew(count,nbin[0]+1);
  for(i=0; i<nbin[0]+1; i++) 
    {
      snew(count[i],nbin[1]+1);
      for (j=0; j<nbin[1]+1; j++) 
        snew(count[i][j],nbin[2]+1);
    }


  /* Allocate space for the coordinates */
  snew(x_i1,isize[G_SDF]);
  snew(x_refmol,isize[G_REFMOL]);
  for (i=0; i<isize[G_REFMOL]; i++)
    for (j=XX; j<=ZZ; j++)
      x_refmol[i][j] = 0;


  normfac = 0;


  do {
    /* Must init pbc every step because of pressure coupling */
    set_pbc(&pbc,ePBC,box);
    rm_pbc(&top.idef,ePBC,natoms,box,x,x);


    /* Dynamically build the ref tripels */
    if ( mode == 2 )
      {
        isize[NDX_REF1]=0;
        for (j=NDX_REF1; j<=NDX_REF3; j++)
          srenew(index[j],isize[NDX_REF1]+1);


        /* consistancy of G_REF[1,2] has already been check */
        /* hence we can look for the third atom right away */


        for (i=0; i<isize[G_REF1]; i++)
          {
            for (j=0; j<isize[G_REF3]; j++)
              {
                /* Avoid expensive stuff if possible */
                if ( top.atoms.atom[index[G_REF1][i]].resind != 
                     top.atoms.atom[index[G_REF3][j]].resind &&
                     index[G_REF1][i] != index[G_REF3][j] &&
                     index[G_REF2][i] != index[G_REF3][j] )
                  {
                    pbc_dx(&pbc,x[index[G_REF1][i]],x[index[G_REF3][j]],dx);
                    delta = norm2(dx);
                    if ( delta < tri_upper[G_REF1] &&
                         delta > tri_lower[G_REF1] )
                      {
                        pbc_dx(&pbc,x[index[G_REF2][i]],x[index[G_REF3][j]],dx);
                        delta = norm2(dx);
                        if ( delta < tri_upper[G_REF2] &&
                             delta > tri_lower[G_REF2] )
                          {
                            /* found triple */
                            index[NDX_REF1][isize[NDX_REF1]]=index[G_REF1][i];
                            index[NDX_REF2][isize[NDX_REF1]]=index[G_REF2][i];
                            index[NDX_REF3][isize[NDX_REF1]]=index[G_REF3][j];


                            /* resize groups */
                            isize[NDX_REF1]++;
                            for (k=NDX_REF1; k<=NDX_REF3; k++)
                              srenew(index[k],isize[NDX_REF1]+1);
                          }
                      }
                  }
              }
          }
      }
    else if ( mode ==3 )
      {
        isize[NDX_REF1]=0;
        for (j=NDX_REF1; j<=NDX_REF3; j++)
          srenew(index[j],isize[NDX_REF1]+1);

        /* consistancy will be checked while searching */


        for (i=0; i<isize[G_REF1]; i++)
          {
            for (j=0; j<isize[G_REF2]; j++)
              {
                /* Avoid expensive stuff if possible */
                if ( top.atoms.atom[index[G_REF1][i]].resind != 
                     top.atoms.atom[index[G_REF2][j]].resind &&
                     index[G_REF1][i] != index[G_REF2][j] )
                  {
                    pbc_dx(&pbc,x[index[G_REF1][i]],x[index[G_REF2][j]],dx);
                    delta = norm2(dx);
                    if ( delta < tri_upper[G_REF3] &&
                         delta > tri_lower[G_REF3] )
                      {
                        for (k=0; k<isize[G_REF3]; k++)
                          {
                            if ( top.atoms.atom[index[G_REF1][i]].resind != 
                                 top.atoms.atom[index[G_REF3][k]].resind &&
                                 top.atoms.atom[index[G_REF2][j]].resind != 
                                 top.atoms.atom[index[G_REF3][k]].resind &&
                                 index[G_REF1][i] != index[G_REF3][k] &&
                                 index[G_REF2][j] != index[G_REF3][k])
                              {
                                pbc_dx(&pbc,x[index[G_REF1][i]],x[index[G_REF3][k]],dx);
                                delta = norm2(dx);
                                if ( delta < tri_upper[G_REF1] &&
                                     delta > tri_lower[G_REF1] )
                                  {
                                    pbc_dx(&pbc,x[index[G_REF2][j]],x[index[G_REF3][k]],dx);
                                    delta = norm2(dx);
                                    if ( delta < tri_upper[G_REF2] &&
                                         delta > tri_lower[G_REF2] )
                                      {
                                        /* found triple */
                                        index[NDX_REF1][isize[NDX_REF1]]=index[G_REF1][i];
                                        index[NDX_REF2][isize[NDX_REF1]]=index[G_REF2][j];
                                        index[NDX_REF3][isize[NDX_REF1]]=index[G_REF3][k];
                                    
                                        /* resize groups */
                                        isize[NDX_REF1]++;
                                        for (l=NDX_REF1; l<=NDX_REF3; l++)
                                          srenew(index[l],isize[NDX_REF1]+1);
                                      }
                                  }
                              }
                          }
                      }
                  }
              }
          }
      }
 
    for (i=0; i<isize[NDX_REF1]; i++)
      {
        /* setup the molecular coordinate system (i',j',k') */
        /* because the coodinate system of the box forms a unit matrix */
        /* (i',j',k') is identical with the rotation matrix */
        clear_mat(rot);


        /* k' = unitv(r(atom0) - r(atom1)) */
        pbc_dx(&pbc,x[index[NDX_REF1][i]],x[index[NDX_REF2][i]],k_mol);
        unitv(k_mol,rot[2]);
        
        /* i' = unitv(k' x (r(atom2) - r(atom1))) */
        pbc_dx(&pbc,x[index[NDX_REF3][i]],x[index[NDX_REF2][i]],i1_mol);
        cprod(i1_mol,rot[2],i2_mol);
        unitv(i2_mol,rot[0]);
      
        /* j' = k' x i' */
        cprod(rot[2],rot[0],rot[1]);


        /* set the point of reference */
        if ( mode == 2 )
          copy_rvec(x[index[NDX_REF3][i]],xi);
        else
          copy_rvec(x[index[NDX_REF1][i]],xi);


        /* make the reference */
        if ( bRef )
          {
            for (j=0; j<isize[G_REFMOL]; j++)
              {
                pbc_dx(&pbc,xi,x[index[G_REFMOL][j]],dx);
                mvmul(rot,dx,dx_mol);
                rvec_inc(x_refmol[j],dx_mol);
                for(k=XX; k<=ZZ; k++)
                   x_refmol[j][k] = x_refmol[j][k] / 2;
              }
          }


        /* Copy the indexed coordinates to a continuous array */
        for(j=0; j<isize[G_SDF]; j++)
          copy_rvec(x[index[G_SDF][j]],x_i1[j]);
        
        /* count the SDF */
        for(j=0; j<isize[G_SDF]; j++) 
          {
            /* Exclude peaks from the reference set */
            bInGroup=FALSE;
            for (k=NDX_REF1; k<=NDX_REF3; k++)
              if ( index[G_SDF][j] == index[k][i] )
                bInGroup=TRUE;


            if ( !bInGroup )
              {
                pbc_dx(&pbc,xi,x_i1[j],dx);
            
                /* transfer dx to the molecular coordinate system */
                mvmul(rot,dx,dx_mol);


                /* check cutoff's and count */
                if ( dx_mol[XX] > -cutoff[XX] && dx_mol[XX] < cutoff[XX] )
                  if ( dx_mol[YY] > -cutoff[YY] && dx_mol[YY] < cutoff[YY] )
                    if ( dx_mol[ZZ] > -cutoff[ZZ] && dx_mol[ZZ] < cutoff[ZZ] )
                      {
                        X = (int)(floor(dx_mol[XX]*invbinw)) + (nbin[XX]-1)/2 
+1;
                        Y = (int)(floor(dx_mol[YY]*invbinw)) + (nbin[YY]-1)/2 
+1;
                        Z = (int)(floor(dx_mol[ZZ]*invbinw)) + (nbin[ZZ]-1)/2 
+1;
                        count[X][Y][Z]++;
                        normfac++;
                      }
              }
          }
      }
  } while (read_next_x(status,&t,natoms,x,box));
  fprintf(stderr,"\n");
  
  close_trj(status);
  
  sfree(x);


  /* write the reference strcture*/
  if ( bRef )
    {
      fp=ffopen(fnREF,"w"); 
      fprintf(fp,"%s\n",title);
      fprintf(fp,"  %d\n",isize[G_REFMOL]);


      for (i=0; i<isize[G_REFMOL]; i++)
        fprintf(fp,"%5d%5s%5s%5d%8.3f%8.3f%8.3f\n",
                top.atoms.resinfo[top.atoms.atom[index[G_REFMOL][i]].resind].nr,
                *(top.atoms.resinfo[top.atoms.atom[index[G_REFMOL][i]].resind].name),
                *(top.atoms.atomname[index[G_REFMOL][i]]),i+1,
                -1*x_refmol[i][XX],-1*x_refmol[i][YY],-1*x_refmol[i][ZZ]);
      /* Inserted -1* on the line above three times */
      fprintf(fp,"   10.00000   10.00000   10.00000\n");
      ffclose(fp);
      fprintf(stderr,"\nWrote reference structure. (%d Atoms)\n",isize[G_REFMOL]);
    }


  /* Calculate the mean probability density */
  fprintf(stderr,"\nNumber of configuations used for SDF: %d\n",(int)normfac);


  normfac = nbin[0]*nbin[1]*nbin[2] / normfac;


  fprintf(stderr,"\nMean probability density: %f\n",1/normfac);


  /* normalize the SDF and write output */
  /* see http://www.csc.fi/gopenmol/index.phtml for documentation */
  fp=ffopen(fnSDF,"wb"); 


  /* rank */
  i_write(fp,3);


  /* Type of surface */
  i_write(fp,42);


  /* Zdim, Ydim, Xdim */
  for (i=ZZ; i>=XX; i--)
    i_write(fp,nbin[i]);


  /* [Z,Y,X][min,max] (box corners in Angstroem)*/
  for (i=ZZ; i>=XX; i--)
    {
      f_write(fp,-cutoff[i]*10);
      f_write(fp,cutoff[i]*10);
    }


/* Original Code
  for (i=1; i<nbin[2]+1; i++)
    for (j=1; j<nbin[1]+1; j++)
      for (k=1; k<nbin[0]+1; k++) 
        {
          sdf = normfac * count[k][j][i];
          if ( sdf < min_sdf ) min_sdf = sdf;
          if ( sdf > max_sdf ) max_sdf = sdf;
          f_write(fp,sdf);
        }*/
/* Changed Code to Mirror SDF to correct coordinates */
  for (i=nbin[2]; i>0; i--)
    for (j=nbin[1]; j>0; j--)
      for (k=nbin[0]; k>0; k--)
        {
          sdf = normfac * count[k][j][i];
          if ( sdf < min_sdf ) min_sdf = sdf;
          if ( sdf > max_sdf ) max_sdf = sdf;
          f_write(fp,sdf);
        }

  fprintf(stderr,"\nMin: %f Max: %f\n",min_sdf,max_sdf);


  ffclose(fp); 


  /* Give back the mem */
  for(i=0; i<nbin[0]+1; i++)
    {
      for (j=0; j<nbin[1]+1; j++)
        {
          sfree(count[i][j]);
        }
      sfree(count[i]);
    }
  sfree(count);
}
void settle_proj(FILE *fp,int nsettle, t_iatom iatoms[],rvec x[],
		 real dOH,real dHH,real invmO,real invmH,
		 rvec *der,rvec *derp,
		 bool bCalcVir,tensor rmdder)
{
  /* Settle for projection out constraint components
   * of derivatives of the coordinates.
   * Berk Hess 2008-1-10
   */

  /* Initialized data */
  static bool bFirst=TRUE;
  static real imO,imH,invdOH,invdHH;
  static matrix invmat;

  real imOn,imHn;
  matrix mat;
  int i,m,m2,ow1,hw2,hw3;
  rvec roh2,roh3,rhh,dc,fc;

  if (bFirst) {
    if (fp)
      fprintf(fp,"Going to use settle for derivatives (%d waters)\n",nsettle);

    imO = invmO;
    imH = invmH;
    /* We normalize the inverse masses with imO for the matrix inversion.
     * so we can keep using masses of almost zero for frozen particles,
     * without running out of the float range in m_inv.
     */
    imOn = 1;
    imHn = imH/imO;

    /* Construct the constraint coupling matrix */
    mat[0][0] = imOn + imHn;
    mat[0][1] = imOn*(1 - 0.5*dHH*dHH/(dOH*dOH));
    mat[0][2] = imHn*0.5*dHH/dOH;
    mat[1][1] = mat[0][0];
    mat[1][2] = mat[0][2];
    mat[2][2] = imHn + imHn;
    mat[1][0] = mat[0][1];
    mat[2][0] = mat[0][2];
    mat[2][1] = mat[1][2];

    m_inv(mat,invmat);

    msmul(invmat,1/imO,invmat);

    invdOH = 1/dOH;
    invdHH = 1/dHH;

    bFirst = FALSE;
  }

#ifdef PRAGMAS
#pragma ivdep
#endif
  for (i=0; i<nsettle; i++) {
    ow1 = iatoms[i*2+1];
    hw2 = ow1 + 1;
    hw3 = ow1 + 2;
    
    for(m=0; m<DIM; m++)
      roh2[m] = (x[ow1][m] - x[hw2][m])*invdOH;
    for(m=0; m<DIM; m++)
      roh3[m] = (x[ow1][m] - x[hw3][m])*invdOH;
    for(m=0; m<DIM; m++)
      rhh [m] = (x[hw2][m] - x[hw3][m])*invdHH;
    /* 18 flops */

    /* Determine the projections of der on the bonds */
    clear_rvec(dc);
    for(m=0; m<DIM; m++)
      dc[0] += (der[ow1][m] - der[hw2][m])*roh2[m];
    for(m=0; m<DIM; m++)
      dc[1] += (der[ow1][m] - der[hw3][m])*roh3[m];
    for(m=0; m<DIM; m++)
      dc[2] += (der[hw2][m] - der[hw3][m])*rhh [m];
    /* 27 flops */

    /* Determine the correction for the three bonds */
    mvmul(invmat,dc,fc);
    /* 15 flops */

    /* Subtract the corrections from derp */
    for(m=0; m<DIM; m++) {
      derp[ow1][m] -= imO*( fc[0]*roh2[m] + fc[1]*roh3[m]);
      derp[hw2][m] -= imH*(-fc[0]*roh2[m] + fc[2]*rhh [m]);
      derp[hw3][m] -= imH*(-fc[1]*roh3[m] - fc[2]*rhh [m]);
    }
    /* 45 flops */

    if (bCalcVir) {
      /* Determining r x m der is easy,
       * since fc contains the mass weighted corrections for der.
       */
      for(m=0; m<DIM; m++) {
	for(m2=0; m2<DIM; m2++) {
	  rmdder[m][m2] +=
	    dOH*roh2[m]*roh2[m2]*fc[0] +
	    dOH*roh3[m]*roh3[m2]*fc[1] +
	    dHH*rhh [m]*rhh [m2]*fc[2];
	}
      }
    }
  }
}
Beispiel #7
0
real orires(int nfa,const t_iatom forceatoms[],const t_iparams ip[],
            const rvec x[],rvec f[],rvec fshift[],
            const t_pbc *pbc,const t_graph *g,
            real lambda,real *dvdlambda,
            const t_mdatoms *md,t_fcdata *fcd,
            int *global_atom_index,int ftype,gmx_mc_move *mc_move)
{
    atom_id      ai,aj;
    int          fa,d,i,type,ex,power,ki=CENTRAL;
    ivec         dt;
    real         r2,invr,invr2,fc,smooth_fc,dev,devins,pfac;
    rvec         r,Sr,fij;
    real         vtot;
    const t_oriresdata *od;
    bool         bTAV;
    
    vtot = 0;
    od = &(fcd->orires);
    
    if (od->fc != 0)
    {
        bTAV = (od->edt != 0);

        smooth_fc = od->fc;
        if (bTAV)
        {
            /* Smoothly switch on the restraining when time averaging is used */
            smooth_fc *= (1.0 - od->exp_min_t_tau);
        }
        
        d = 0;
        for(fa=0; fa<nfa; fa+=3)
        {
            type  = forceatoms[fa];
            ai    = forceatoms[fa+1];
            aj    = forceatoms[fa+2];
            if (pbc)
            {
                ki = pbc_dx_aiuc(pbc,x[ai],x[aj],r);
            }
            else
            {
                rvec_sub(x[ai],x[aj],r);
            }
            r2    = norm2(r);
            invr  = invsqrt(r2);
            invr2 = invr*invr;
            ex    = ip[type].orires.ex;
            power = ip[type].orires.power;
            fc    = smooth_fc*ip[type].orires.kfac;
            dev   = od->otav[d] - ip[type].orires.obs;
            
            /* NOTE:
             * there is no real potential when time averaging is applied
             */
            vtot += 0.5*fc*sqr(dev);
            
            if (bTAV)
            {
                /* Calculate the force as the sqrt of tav times instantaneous */
                devins = od->oins[d] - ip[type].orires.obs;
                if (dev*devins <= 0)
                {
                    dev = 0;
                }
                else
                {
                    dev = sqrt(dev*devins);
                    if (devins < 0)
                    {
                        dev = -dev;
                    }
                }
            }
            
            pfac  = fc*ip[type].orires.c*invr2;
            for(i=0; i<power; i++)
            {
                pfac *= invr;
            }
            mvmul(od->S[ex],r,Sr);
            for(i=0; i<DIM; i++)
            {
                fij[i] =
                    -pfac*dev*(4*Sr[i] - 2*(2+power)*invr2*iprod(Sr,r)*r[i]);
            }
            
            if (g)
            {
                ivec_sub(SHIFT_IVEC(g,ai),SHIFT_IVEC(g,aj),dt);
                ki=IVEC2IS(dt);
            }
            
            for(i=0; i<DIM; i++)
            {
                f[ai][i]           += fij[i];
                f[aj][i]           -= fij[i];
                fshift[ki][i]      += fij[i];
                fshift[CENTRAL][i] -= fij[i];
            }
            d++;
        }
    }
    
    return vtot;
    
    /* Approx. 80*nfa/3 flops */
}
Beispiel #8
0
real calc_orires_dev(const gmx_multisim_t *ms,
                     int nfa,const t_iatom forceatoms[],const t_iparams ip[],
                     const t_mdatoms *md,const rvec x[],const t_pbc *pbc,
                     t_fcdata *fcd,history_t *hist)
{
    int          fa,d,i,j,type,ex,nref;
    real         edt,edt1,invn,pfac,r2,invr,corrfac,weight,wsv2,sw,dev;
    tensor       *S,R,TMP;
    rvec5        *Dinsl,*Dins,*Dtav,*rhs;
    real         *mref,***T;
    double       mtot;
    rvec         *xref,*xtmp,com,r_unrot,r;
    t_oriresdata *od;
    bool         bTAV;
    const real   two_thr=2.0/3.0;
    
    od = &(fcd->orires);

    if (od->nr == 0)
    {
        /* This means that this is not the master node */
        gmx_fatal(FARGS,"Orientation restraints are only supported on the master node, use less processors");
    }
    
    bTAV = (od->edt != 0);
    edt  = od->edt;
    edt1 = od->edt1;
    S    = od->S;
    Dinsl= od->Dinsl;
    Dins = od->Dins;
    Dtav = od->Dtav;
    T    = od->TMP;
    rhs  = od->tmp;
    nref = od->nref;
    mref = od->mref;
    xref = od->xref;
    xtmp = od->xtmp;
    
    if (bTAV)
    {
        od->exp_min_t_tau = hist->orire_initf*edt;
        
        /* Correction factor to correct for the lack of history
         * at short times.
         */
        corrfac = 1.0/(1.0 - od->exp_min_t_tau);
    }
    else
    {
        corrfac = 1.0;
    }

    if (ms)
    {
        invn = 1.0/ms->nsim;
    }
    else
    {
        invn = 1.0;
    }
    
    clear_rvec(com);
    mtot = 0;
    j=0;
    for(i=0; i<md->nr; i++)
    {
        if (md->cORF[i] == 0)
        {
            copy_rvec(x[i],xtmp[j]);
            mref[j] = md->massT[i];
            for(d=0; d<DIM; d++)
            {
                com[d] += mref[j]*xref[j][d];
            }
            mtot += mref[j];
            j++;
        }
    }
    svmul(1.0/mtot,com,com);
    for(j=0; j<nref; j++)
    {
        rvec_dec(xtmp[j],com);
    }
    /* Calculate the rotation matrix to rotate x to the reference orientation */
    calc_fit_R(DIM,nref,mref,xref,xtmp,R);
    copy_mat(R,od->R);
    
    d = 0;
    for(fa=0; fa<nfa; fa+=3)
    {
        type = forceatoms[fa];
        if (pbc)
        {
            pbc_dx_aiuc(pbc,x[forceatoms[fa+1]],x[forceatoms[fa+2]],r_unrot);
        }
        else
        {
            rvec_sub(x[forceatoms[fa+1]],x[forceatoms[fa+2]],r_unrot);
        }
        mvmul(R,r_unrot,r);
        r2   = norm2(r);
        invr = invsqrt(r2);
        /* Calculate the prefactor for the D tensor, this includes the factor 3! */
        pfac = ip[type].orires.c*invr*invr*3;
        for(i=0; i<ip[type].orires.power; i++)
        {
            pfac *= invr;
        }
        Dinsl[d][0] = pfac*(2*r[0]*r[0] + r[1]*r[1] - r2);
        Dinsl[d][1] = pfac*(2*r[0]*r[1]);
        Dinsl[d][2] = pfac*(2*r[0]*r[2]);
        Dinsl[d][3] = pfac*(2*r[1]*r[1] + r[0]*r[0] - r2);
        Dinsl[d][4] = pfac*(2*r[1]*r[2]);
        
        if (ms)
        {
            for(i=0; i<5; i++)
            {
                Dins[d][i] = Dinsl[d][i]*invn;
            }
        }

        d++;
    }
  
    if (ms)
    {
        gmx_sum_sim(5*od->nr,Dins[0],ms);
    }
   
    /* Calculate the order tensor S for each experiment via optimization */
    for(ex=0; ex<od->nex; ex++)
    {
        for(i=0; i<5; i++)
        {
            rhs[ex][i] = 0;
            for(j=0; j<=i; j++)
            {
                T[ex][i][j] = 0;
            }
        }
    }
    d = 0;
    for(fa=0; fa<nfa; fa+=3)
    {
        if (bTAV)
        {
            /* Here we update Dtav in t_fcdata using the data in history_t.
             * Thus the results stay correct when this routine
             * is called multiple times.
             */
            for(i=0; i<5; i++)
            {
                Dtav[d][i] = edt*hist->orire_Dtav[d*5+i] + edt1*Dins[d][i];
            }
        }
        
        type   = forceatoms[fa];
        ex     = ip[type].orires.ex;
        weight = ip[type].orires.kfac;
        /* Calculate the vector rhs and half the matrix T for the 5 equations */
        for(i=0; i<5; i++) {
            rhs[ex][i] += Dtav[d][i]*ip[type].orires.obs*weight;
            for(j=0; j<=i; j++)
            {
                T[ex][i][j] += Dtav[d][i]*Dtav[d][j]*weight;
            }
        }
        d++;
    }
    /* Now we have all the data we can calculate S */
    for(ex=0; ex<od->nex; ex++)
    {
        /* Correct corrfac and copy one half of T to the other half */
        for(i=0; i<5; i++)
        {
            rhs[ex][i]  *= corrfac;
            T[ex][i][i] *= sqr(corrfac);
            for(j=0; j<i; j++)
            {
                T[ex][i][j] *= sqr(corrfac);
                T[ex][j][i]  = T[ex][i][j];
            }
        }
        m_inv_gen(T[ex],5,T[ex]);
        /* Calculate the orientation tensor S for this experiment */
        S[ex][0][0] = 0;
        S[ex][0][1] = 0;
        S[ex][0][2] = 0;
        S[ex][1][1] = 0;
        S[ex][1][2] = 0;
        for(i=0; i<5; i++)
        {
            S[ex][0][0] += 1.5*T[ex][0][i]*rhs[ex][i];
            S[ex][0][1] += 1.5*T[ex][1][i]*rhs[ex][i];
            S[ex][0][2] += 1.5*T[ex][2][i]*rhs[ex][i];
            S[ex][1][1] += 1.5*T[ex][3][i]*rhs[ex][i];
            S[ex][1][2] += 1.5*T[ex][4][i]*rhs[ex][i];
        }
        S[ex][1][0] = S[ex][0][1];
        S[ex][2][0] = S[ex][0][2];
        S[ex][2][1] = S[ex][1][2];
        S[ex][2][2] = -S[ex][0][0] - S[ex][1][1];
    }
    
    wsv2 = 0;
    sw   = 0;
    
    d = 0;
    for(fa=0; fa<nfa; fa+=3)
    {
        type = forceatoms[fa];
        ex = ip[type].orires.ex;
        
        od->otav[d] = two_thr*
            corrfac*(S[ex][0][0]*Dtav[d][0] + S[ex][0][1]*Dtav[d][1] +
                     S[ex][0][2]*Dtav[d][2] + S[ex][1][1]*Dtav[d][3] +
                     S[ex][1][2]*Dtav[d][4]);
        if (bTAV)
        {
            od->oins[d] = two_thr*(S[ex][0][0]*Dins[d][0] + S[ex][0][1]*Dins[d][1] +
                                   S[ex][0][2]*Dins[d][2] + S[ex][1][1]*Dins[d][3] +
                                   S[ex][1][2]*Dins[d][4]);
        }
        if (ms)
        {
            /* When ensemble averaging is used recalculate the local orientation
             * for output to the energy file.
             */
            od->oinsl[d] = two_thr*
                (S[ex][0][0]*Dinsl[d][0] + S[ex][0][1]*Dinsl[d][1] +
                 S[ex][0][2]*Dinsl[d][2] + S[ex][1][1]*Dinsl[d][3] +
                 S[ex][1][2]*Dinsl[d][4]);
        }
        
        dev = od->otav[d] - ip[type].orires.obs;
        
        wsv2 += ip[type].orires.kfac*sqr(dev);
        sw   += ip[type].orires.kfac;
        
        d++;
    }
    od->rmsdev = sqrt(wsv2/sw);
    
    /* Rotate the S matrices back, so we get the correct grad(tr(S D)) */
    for(ex=0; ex<od->nex; ex++)
    {
        tmmul(R,S[ex],TMP);
        mmul(TMP,R,S[ex]);
    }
    
    return od->rmsdev;
    
    /* Approx. 120*nfa/3 flops */
}
Beispiel #9
0
void check_cm_grp(FILE *fp, t_vcm *vcm, t_inputrec *ir, real Temp_Max)
{
    int    m, g;
    real   ekcm, ekrot, tm, tm_1, Temp_cm;
    rvec   jcm;
    tensor Icm;

    /* First analyse the total results */
    if (vcm->mode != ecmNO)
    {
        for (g = 0; (g < vcm->nr); g++)
        {
            tm = vcm->group_mass[g];
            if (tm != 0)
            {
                tm_1 = 1.0/tm;
                svmul(tm_1, vcm->group_p[g], vcm->group_v[g]);
            }
            /* Else it's zero anyway! */
        }
        if (vcm->mode == ecmANGULAR)
        {
            for (g = 0; (g < vcm->nr); g++)
            {
                tm = vcm->group_mass[g];
                if (tm != 0)
                {
                    tm_1 = 1.0/tm;

                    /* Compute center of mass for this group */
                    for (m = 0; (m < DIM); m++)
                    {
                        vcm->group_x[g][m] *= tm_1;
                    }

                    /* Subtract the center of mass contribution to the
                     * angular momentum
                     */
                    cprod(vcm->group_x[g], vcm->group_v[g], jcm);
                    for (m = 0; (m < DIM); m++)
                    {
                        vcm->group_j[g][m] -= tm*jcm[m];
                    }

                    /* Subtract the center of mass contribution from the inertia
                     * tensor (this is not as trivial as it seems, but due to
                     * some cancellation we can still do it, even in parallel).
                     */
                    clear_mat(Icm);
                    update_tensor(vcm->group_x[g], tm, Icm);
                    m_sub(vcm->group_i[g], Icm, vcm->group_i[g]);

                    /* Compute angular velocity, using matrix operation
                     * Since J = I w
                     * we have
                     * w = I^-1 J
                     */
                    get_minv(vcm->group_i[g], Icm);
                    mvmul(Icm, vcm->group_j[g], vcm->group_w[g]);
                }
                /* Else it's zero anyway! */
            }
        }
    }
    for (g = 0; (g < vcm->nr); g++)
    {
        ekcm    = 0;
        if (vcm->group_mass[g] != 0 && vcm->group_ndf[g] > 0)
        {
            for (m = 0; m < vcm->ndim; m++)
            {
                ekcm += sqr(vcm->group_v[g][m]);
            }
            ekcm   *= 0.5*vcm->group_mass[g];
            Temp_cm = 2*ekcm/vcm->group_ndf[g];

            if ((Temp_cm > Temp_Max) && fp)
            {
                fprintf(fp, "Large VCM(group %s): %12.5f, %12.5f, %12.5f, Temp-cm: %12.5e\n",
                        vcm->group_name[g], vcm->group_v[g][XX],
                        vcm->group_v[g][YY], vcm->group_v[g][ZZ], Temp_cm);
            }

            if (vcm->mode == ecmANGULAR)
            {
                ekrot = 0.5*iprod(vcm->group_j[g], vcm->group_w[g]);
                if ((ekrot > 1) && fp && !EI_RANDOM(ir->eI))
                {
                    /* if we have an integrator that may not conserve momenta, skip */
                    tm    = vcm->group_mass[g];
                    fprintf(fp, "Group %s with mass %12.5e, Ekrot %12.5e Det(I) = %12.5e\n",
                            vcm->group_name[g], tm, ekrot, det(vcm->group_i[g]));
                    fprintf(fp, "  COM: %12.5f  %12.5f  %12.5f\n",
                            vcm->group_x[g][XX], vcm->group_x[g][YY], vcm->group_x[g][ZZ]);
                    fprintf(fp, "  P:   %12.5f  %12.5f  %12.5f\n",
                            vcm->group_p[g][XX], vcm->group_p[g][YY], vcm->group_p[g][ZZ]);
                    fprintf(fp, "  V:   %12.5f  %12.5f  %12.5f\n",
                            vcm->group_v[g][XX], vcm->group_v[g][YY], vcm->group_v[g][ZZ]);
                    fprintf(fp, "  J:   %12.5f  %12.5f  %12.5f\n",
                            vcm->group_j[g][XX], vcm->group_j[g][YY], vcm->group_j[g][ZZ]);
                    fprintf(fp, "  w:   %12.5f  %12.5f  %12.5f\n",
                            vcm->group_w[g][XX], vcm->group_w[g][YY], vcm->group_w[g][ZZ]);
                    pr_rvecs(fp, 0, "Inertia tensor", vcm->group_i[g], DIM);
                }
            }
        }
    }
}
int gmx_helixorient(int argc, char *argv[])
{
    const char       *desc[] = {
        "[THISMODULE] calculates the coordinates and direction of the average",
        "axis inside an alpha helix, and the direction/vectors of both the",
        "C[GRK]alpha[grk] and (optionally) a sidechain atom relative to the axis.[PAR]",
        "As input, you need to specify an index group with C[GRK]alpha[grk] atoms",
        "corresponding to an [GRK]alpha[grk]-helix of continuous residues. Sidechain",
        "directions require a second index group of the same size, containing",
        "the heavy atom in each residue that should represent the sidechain.[PAR]",
        "[BB]Note[bb] that this program does not do any fitting of structures.[PAR]",
        "We need four C[GRK]alpha[grk] coordinates to define the local direction of the helix",
        "axis.[PAR]",
        "The tilt/rotation is calculated from Euler rotations, where we define",
        "the helix axis as the local [IT]x[it]-axis, the residues/C[GRK]alpha[grk] vector as [IT]y[it], and the",
        "[IT]z[it]-axis from their cross product. We use the Euler Y-Z-X rotation, meaning",
        "we first tilt the helix axis (1) around and (2) orthogonal to the residues",
        "vector, and finally apply the (3) rotation around it. For debugging or other",
        "purposes, we also write out the actual Euler rotation angles as [TT]theta[1-3].xvg[tt]"
    };

    t_topology       *top = NULL;
    real              t;
    rvec             *x = NULL;
    matrix            box;
    t_trxstatus      *status;
    int               natoms;
    real              theta1, theta2, theta3;

    int               i, j, teller = 0;
    int               iCA, iSC;
    int              *ind_CA;
    int              *ind_SC;
    char             *gn_CA;
    char             *gn_SC;
    rvec              v1, v2;
    rvec             *x_CA, *x_SC;
    rvec             *r12;
    rvec             *r23;
    rvec             *r34;
    rvec             *diff13;
    rvec             *diff24;
    rvec             *helixaxis;
    rvec             *residuehelixaxis;
    rvec             *residueorigin;
    rvec             *residuevector;
    rvec             *sidechainvector;

    rvec             *residuehelixaxis_t0;
    rvec             *residuevector_t0;
    rvec             *axis3_t0;
    rvec             *residuehelixaxis_tlast;
    rvec             *residuevector_tlast;
    rvec             *axis3_tlast;
    rvec              refaxes[3], newaxes[3];
    rvec              unitaxes[3];
    rvec              rot_refaxes[3], rot_newaxes[3];

    real              tilt, rotation;
    rvec             *axis3;
    real             *twist, *residuetwist;
    real             *radius, *residueradius;
    real             *rise, *residuerise;
    real             *residuebending;

    real              tmp;
    real              weight[3];
    t_pbc             pbc;
    matrix            A;

    FILE             *fpaxis, *fpcenter, *fptilt, *fprotation;
    FILE             *fpradius, *fprise, *fptwist;
    FILE             *fptheta1, *fptheta2, *fptheta3;
    FILE             *fpbending;
    int               ePBC;

    gmx_output_env_t *oenv;
    gmx_rmpbc_t       gpbc = NULL;

    static  gmx_bool  bSC          = FALSE;
    static gmx_bool   bIncremental = FALSE;

    static t_pargs    pa[] = {
        { "-sidechain",      FALSE, etBOOL, {&bSC},
          "Calculate sidechain directions relative to helix axis too." },
        { "-incremental",        FALSE, etBOOL, {&bIncremental},
          "Calculate incremental rather than total rotation/tilt." },
    };
#define NPA asize(pa)

    t_filenm fnm[] = {
        { efTPR, NULL, NULL, ffREAD },
        { efTRX, "-f", NULL, ffREAD },
        { efNDX, NULL, NULL, ffOPTRD },
        { efDAT, "-oaxis",    "helixaxis", ffWRITE },
        { efDAT, "-ocenter",  "center", ffWRITE },
        { efXVG, "-orise",    "rise", ffWRITE },
        { efXVG, "-oradius",  "radius", ffWRITE },
        { efXVG, "-otwist",   "twist", ffWRITE },
        { efXVG, "-obending", "bending", ffWRITE },
        { efXVG, "-otilt",    "tilt", ffWRITE },
        { efXVG, "-orot",     "rotation", ffWRITE }
    };
#define NFILE asize(fnm)

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

    top = read_top(ftp2fn(efTPR, NFILE, fnm), &ePBC);

    for (i = 0; i < 3; i++)
    {
        weight[i] = 1.0;
    }

    /* read index files */
    printf("Select a group of Calpha atoms corresponding to a single continuous helix:\n");
    get_index(&(top->atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &iCA, &ind_CA, &gn_CA);
    snew(x_CA, iCA);
    snew(x_SC, iCA); /* sic! */

    snew(r12, iCA-3);
    snew(r23, iCA-3);
    snew(r34, iCA-3);
    snew(diff13, iCA-3);
    snew(diff24, iCA-3);
    snew(helixaxis, iCA-3);
    snew(twist, iCA);
    snew(residuetwist, iCA);
    snew(radius, iCA);
    snew(residueradius, iCA);
    snew(rise, iCA);
    snew(residuerise, iCA);
    snew(residueorigin, iCA);
    snew(residuehelixaxis, iCA);
    snew(residuevector, iCA);
    snew(sidechainvector, iCA);
    snew(residuebending, iCA);
    snew(residuehelixaxis_t0, iCA);
    snew(residuevector_t0, iCA);
    snew(axis3_t0, iCA);
    snew(residuehelixaxis_tlast, iCA);
    snew(residuevector_tlast, iCA);
    snew(axis3_tlast, iCA);
    snew(axis3, iCA);

    if (bSC)
    {
        printf("Select a group of atoms defining the sidechain direction (1/residue):\n");
        get_index(&(top->atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &iSC, &ind_SC, &gn_SC);
        if (iSC != iCA)
        {
            gmx_fatal(FARGS, "Number of sidechain atoms (%d) != number of CA atoms (%d)", iSC, iCA);
        }

    }

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

    fpaxis    = gmx_ffopen(opt2fn("-oaxis", NFILE, fnm), "w");
    fpcenter  = gmx_ffopen(opt2fn("-ocenter", NFILE, fnm), "w");
    fprise    = gmx_ffopen(opt2fn("-orise", NFILE, fnm), "w");
    fpradius  = gmx_ffopen(opt2fn("-oradius", NFILE, fnm), "w");
    fptwist   = gmx_ffopen(opt2fn("-otwist", NFILE, fnm), "w");
    fpbending = gmx_ffopen(opt2fn("-obending", NFILE, fnm), "w");

    fptheta1 = gmx_ffopen("theta1.xvg", "w");
    fptheta2 = gmx_ffopen("theta2.xvg", "w");
    fptheta3 = gmx_ffopen("theta3.xvg", "w");

    if (bIncremental)
    {
        fptilt = xvgropen(opt2fn("-otilt", NFILE, fnm),
                          "Incremental local helix tilt", "Time(ps)", "Tilt (degrees)",
                          oenv);
        fprotation = xvgropen(opt2fn("-orot", NFILE, fnm),
                              "Incremental local helix rotation", "Time(ps)",
                              "Rotation (degrees)", oenv);
    }
    else
    {
        fptilt = xvgropen(opt2fn("-otilt", NFILE, fnm),
                          "Cumulative local helix tilt", "Time(ps)", "Tilt (degrees)", oenv);
        fprotation = xvgropen(opt2fn("-orot", NFILE, fnm),
                              "Cumulative local helix rotation", "Time(ps)",
                              "Rotation (degrees)", oenv);
    }

    clear_rvecs(3, unitaxes);
    unitaxes[0][0] = 1;
    unitaxes[1][1] = 1;
    unitaxes[2][2] = 1;

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

    do
    {
        /* initialisation for correct distance calculations */
        set_pbc(&pbc, ePBC, box);
        /* make molecules whole again */
        gmx_rmpbc(gpbc, natoms, box, x);

        /* copy coords to our smaller arrays */
        for (i = 0; i < iCA; i++)
        {
            copy_rvec(x[ind_CA[i]], x_CA[i]);
            if (bSC)
            {
                copy_rvec(x[ind_SC[i]], x_SC[i]);
            }
        }

        for (i = 0; i < iCA-3; i++)
        {
            rvec_sub(x_CA[i+1], x_CA[i], r12[i]);
            rvec_sub(x_CA[i+2], x_CA[i+1], r23[i]);
            rvec_sub(x_CA[i+3], x_CA[i+2], r34[i]);
            rvec_sub(r12[i], r23[i], diff13[i]);
            rvec_sub(r23[i], r34[i], diff24[i]);
            /* calculate helix axis */
            cprod(diff13[i], diff24[i], helixaxis[i]);
            svmul(1.0/norm(helixaxis[i]), helixaxis[i], helixaxis[i]);

            tmp       = cos_angle(diff13[i], diff24[i]);
            twist[i]  = 180.0/M_PI * std::acos( tmp );
            radius[i] = std::sqrt( norm(diff13[i])*norm(diff24[i]) ) / (2.0* (1.0-tmp) );
            rise[i]   = std::abs(iprod(r23[i], helixaxis[i]));

            svmul(radius[i]/norm(diff13[i]), diff13[i], v1);
            svmul(radius[i]/norm(diff24[i]), diff24[i], v2);

            rvec_sub(x_CA[i+1], v1, residueorigin[i+1]);
            rvec_sub(x_CA[i+2], v2, residueorigin[i+2]);
        }
        residueradius[0] = residuetwist[0] = residuerise[0] = 0;

        residueradius[1] = radius[0];
        residuetwist[1]  = twist[0];
        residuerise[1]   = rise[0];

        residuebending[0] = residuebending[1] = 0;
        for (i = 2; i < iCA-2; i++)
        {
            residueradius[i]  = 0.5*(radius[i-2]+radius[i-1]);
            residuetwist[i]   = 0.5*(twist[i-2]+twist[i-1]);
            residuerise[i]    = 0.5*(rise[i-2]+rise[i-1]);
            residuebending[i] = 180.0/M_PI*std::acos( cos_angle(helixaxis[i-2], helixaxis[i-1]) );
        }
        residueradius[iCA-2]  = radius[iCA-4];
        residuetwist[iCA-2]   = twist[iCA-4];
        residuerise[iCA-2]    = rise[iCA-4];
        residueradius[iCA-1]  = residuetwist[iCA-1] = residuerise[iCA-1] = 0;
        residuebending[iCA-2] = residuebending[iCA-1] = 0;

        clear_rvec(residueorigin[0]);
        clear_rvec(residueorigin[iCA-1]);

        /* average helix axes to define them on the residues.
         * Just extrapolate second first/list atom.
         */
        copy_rvec(helixaxis[0], residuehelixaxis[0]);
        copy_rvec(helixaxis[0], residuehelixaxis[1]);

        for (i = 2; i < iCA-2; i++)
        {
            rvec_add(helixaxis[i-2], helixaxis[i-1], residuehelixaxis[i]);
            svmul(0.5, residuehelixaxis[i], residuehelixaxis[i]);
        }
        copy_rvec(helixaxis[iCA-4], residuehelixaxis[iCA-2]);
        copy_rvec(helixaxis[iCA-4], residuehelixaxis[iCA-1]);

        /* Normalize the axis */
        for (i = 0; i < iCA; i++)
        {
            svmul(1.0/norm(residuehelixaxis[i]), residuehelixaxis[i], residuehelixaxis[i]);
        }

        /* calculate vector from origin to residue CA */
        fprintf(fpaxis, "%15.12g  ", t);
        fprintf(fpcenter, "%15.12g  ", t);
        fprintf(fprise, "%15.12g  ", t);
        fprintf(fpradius, "%15.12g  ", t);
        fprintf(fptwist, "%15.12g  ", t);
        fprintf(fpbending, "%15.12g  ", t);

        for (i = 0; i < iCA; i++)
        {
            if (i == 0 || i == iCA-1)
            {
                fprintf(fpaxis, "%15.12g %15.12g %15.12g       ", 0.0, 0.0, 0.0);
                fprintf(fpcenter, "%15.12g %15.12g %15.12g       ", 0.0, 0.0, 0.0);
                fprintf(fprise, "%15.12g  ", 0.0);
                fprintf(fpradius, "%15.12g  ", 0.0);
                fprintf(fptwist, "%15.12g  ", 0.0);
                fprintf(fpbending, "%15.12g  ", 0.0);
            }
            else
            {
                rvec_sub( bSC ? x_SC[i] : x_CA[i], residueorigin[i], residuevector[i]);
                svmul(1.0/norm(residuevector[i]), residuevector[i], residuevector[i]);
                cprod(residuehelixaxis[i], residuevector[i], axis3[i]);
                fprintf(fpaxis, "%15.12g %15.12g %15.12g       ", residuehelixaxis[i][0], residuehelixaxis[i][1], residuehelixaxis[i][2]);
                fprintf(fpcenter, "%15.12g %15.12g %15.12g       ", residueorigin[i][0], residueorigin[i][1], residueorigin[i][2]);

                fprintf(fprise, "%15.12g  ", residuerise[i]);
                fprintf(fpradius, "%15.12g  ", residueradius[i]);
                fprintf(fptwist, "%15.12g  ", residuetwist[i]);
                fprintf(fpbending, "%15.12g  ", residuebending[i]);
            }
        }
        fprintf(fprise, "\n");
        fprintf(fpradius, "\n");
        fprintf(fpaxis, "\n");
        fprintf(fpcenter, "\n");
        fprintf(fptwist, "\n");
        fprintf(fpbending, "\n");

        if (teller == 0)
        {
            for (i = 0; i < iCA; i++)
            {
                copy_rvec(residuehelixaxis[i], residuehelixaxis_t0[i]);
                copy_rvec(residuevector[i], residuevector_t0[i]);
                copy_rvec(axis3[i], axis3_t0[i]);
            }
        }
        else
        {
            fprintf(fptilt, "%15.12g       ", t);
            fprintf(fprotation, "%15.12g       ", t);
            fprintf(fptheta1, "%15.12g      ", t);
            fprintf(fptheta2, "%15.12g      ", t);
            fprintf(fptheta3, "%15.12g      ", t);

            for (i = 0; i < iCA; i++)
            {
                if (i == 0 || i == iCA-1)
                {
                    tilt = rotation = 0;
                }
                else
                {
                    if (!bIncremental)
                    {
                        /* Total rotation & tilt */
                        copy_rvec(residuehelixaxis_t0[i], refaxes[0]);
                        copy_rvec(residuevector_t0[i], refaxes[1]);
                        copy_rvec(axis3_t0[i], refaxes[2]);
                    }
                    else
                    {
                        /* Rotation/tilt since last step */
                        copy_rvec(residuehelixaxis_tlast[i], refaxes[0]);
                        copy_rvec(residuevector_tlast[i], refaxes[1]);
                        copy_rvec(axis3_tlast[i], refaxes[2]);
                    }
                    copy_rvec(residuehelixaxis[i], newaxes[0]);
                    copy_rvec(residuevector[i], newaxes[1]);
                    copy_rvec(axis3[i], newaxes[2]);

                    /* rotate reference frame onto unit axes */
                    calc_fit_R(3, 3, weight, unitaxes, refaxes, A);
                    for (j = 0; j < 3; j++)
                    {
                        mvmul(A, refaxes[j], rot_refaxes[j]);
                        mvmul(A, newaxes[j], rot_newaxes[j]);
                    }

                    /* Determine local rotation matrix A */
                    calc_fit_R(3, 3, weight, rot_newaxes, rot_refaxes, A);
                    /* Calculate euler angles, from rotation order y-z-x, where
                     * x is helixaxis, y residuevector, and z axis3.
                     *
                     * A contains rotation column vectors.
                     */

                    theta1 = 180.0/M_PI*std::atan2(A[0][2], A[0][0]);
                    theta2 = 180.0/M_PI*std::asin(-A[0][1]);
                    theta3 = 180.0/M_PI*std::atan2(A[2][1], A[1][1]);

                    tilt     = std::sqrt(theta1*theta1+theta2*theta2);
                    rotation = theta3;
                    fprintf(fptheta1, "%15.12g  ", theta1);
                    fprintf(fptheta2, "%15.12g  ", theta2);
                    fprintf(fptheta3, "%15.12g  ", theta3);

                }
                fprintf(fptilt, "%15.12g  ", tilt);
                fprintf(fprotation, "%15.12g  ", rotation);
            }
            fprintf(fptilt, "\n");
            fprintf(fprotation, "\n");
            fprintf(fptheta1, "\n");
            fprintf(fptheta2, "\n");
            fprintf(fptheta3, "\n");
        }

        for (i = 0; i < iCA; i++)
        {
            copy_rvec(residuehelixaxis[i], residuehelixaxis_tlast[i]);
            copy_rvec(residuevector[i], residuevector_tlast[i]);
            copy_rvec(axis3[i], axis3_tlast[i]);
        }

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

    gmx_rmpbc_done(gpbc);

    gmx_ffclose(fpaxis);
    gmx_ffclose(fpcenter);
    xvgrclose(fptilt);
    xvgrclose(fprotation);
    gmx_ffclose(fprise);
    gmx_ffclose(fpradius);
    gmx_ffclose(fptwist);
    gmx_ffclose(fpbending);
    gmx_ffclose(fptheta1);
    gmx_ffclose(fptheta2);
    gmx_ffclose(fptheta3);

    close_trj(status);

    return 0;
}
Beispiel #11
0
void settle_proj(gmx_settledata_t settled, int econq,
                 int nsettle, t_iatom iatoms[],
                 const t_pbc *pbc,
                 rvec x[],
                 rvec *der, rvec *derp,
                 int calcvir_atom_end, tensor vir_r_m_dder)
{
    /* Settle for projection out constraint components
     * of derivatives of the coordinates.
     * Berk Hess 2008-1-10
     */

    settleparam_t *p;
    real           imO, imH, dOH, dHH, invdOH, invdHH;
    matrix         invmat;
    int            i, m, m2, ow1, hw2, hw3;
    rvec           roh2, roh3, rhh, dc, fc;

    calcvir_atom_end *= DIM;

    if (econq == econqForce)
    {
        p = &settled->mass1;
    }
    else
    {
        p = &settled->massw;
    }
    imO    = p->imO;
    imH    = p->imH;
    copy_mat(p->invmat, invmat);
    dOH    = p->dOH;
    dHH    = p->dHH;
    invdOH = p->invdOH;
    invdHH = p->invdHH;

#ifdef PRAGMAS
#pragma ivdep
#endif

    for (i = 0; i < nsettle; i++)
    {
        ow1 = iatoms[i*4+1];
        hw2 = iatoms[i*4+2];
        hw3 = iatoms[i*4+3];

        if (pbc == NULL)
        {
            rvec_sub(x[ow1], x[hw2], roh2);
            rvec_sub(x[ow1], x[hw3], roh3);
            rvec_sub(x[hw2], x[hw3], rhh);
        }
        else
        {
            pbc_dx_aiuc(pbc, x[ow1], x[hw2], roh2);
            pbc_dx_aiuc(pbc, x[ow1], x[hw3], roh3);
            pbc_dx_aiuc(pbc, x[hw2], x[hw3], rhh);
        }
        svmul(invdOH, roh2, roh2);
        svmul(invdOH, roh3, roh3);
        svmul(invdHH, rhh, rhh);
        /* 18 flops */

        /* Determine the projections of der on the bonds */
        clear_rvec(dc);
        for (m = 0; m < DIM; m++)
        {
            dc[0] += (der[ow1][m] - der[hw2][m])*roh2[m];
            dc[1] += (der[ow1][m] - der[hw3][m])*roh3[m];
            dc[2] += (der[hw2][m] - der[hw3][m])*rhh [m];
        }
        /* 27 flops */

        /* Determine the correction for the three bonds */
        mvmul(invmat, dc, fc);
        /* 15 flops */

        /* Subtract the corrections from derp */
        for (m = 0; m < DIM; m++)
        {
            derp[ow1][m] -= imO*( fc[0]*roh2[m] + fc[1]*roh3[m]);
            derp[hw2][m] -= imH*(-fc[0]*roh2[m] + fc[2]*rhh [m]);
            derp[hw3][m] -= imH*(-fc[1]*roh3[m] - fc[2]*rhh [m]);
        }

        /* 45 flops */

        if (ow1 < calcvir_atom_end)
        {
            /* Determining r \dot m der is easy,
             * since fc contains the mass weighted corrections for der.
             */

            for (m = 0; m < DIM; m++)
            {
                for (m2 = 0; m2 < DIM; m2++)
                {
                    vir_r_m_dder[m][m2] +=
                        dOH*roh2[m]*roh2[m2]*fc[0] +
                        dOH*roh3[m]*roh3[m2]*fc[1] +
                        dHH*rhh [m]*rhh [m2]*fc[2];
                }
            }
        }
    }
}
int nsc_dclm_pbc(const rvec *coords, real *radius, int nat,
                 int  densit, int mode,
                 real *value_of_area, real **at_area,
                 real *value_of_vol,
                 real **lidots, int *nu_dots,
                 atom_id index[], int ePBC, matrix box)
{
    int         iat, i, ii, iii, ix, iy, iz, ixe, ixs, iye, iys, ize, izs, i_ac;
    int         jat, j, jj, jjj, jx, jy, jz;
    int         distribution;
    int         l;
    int         maxnei, nnei, last, maxdots = 0;
    int        *wkdot = NULL, *wkbox = NULL, *wkat1 = NULL, *wkatm = NULL;
    Neighb     *wknb, *ctnb;
    int         iii1, iii2, iiat, lfnr = 0, i_at, j_at;
    real        dx, dy, dz, dd, ai, aisq, ajsq, aj, as, a;
    real        xi, yi, zi, xs = 0., ys = 0., zs = 0.;
    real        dotarea, area, vol = 0.;
    real       *xus, *dots = NULL, *atom_area = NULL;
    int         nxbox, nybox, nzbox, nxy, nxyz;
    real        xmin = 0, ymin = 0, zmin = 0, xmax, ymax, zmax, ra2max, d;
    const real *pco;
    /* Added DvdS 2006-07-19 */
    t_pbc       pbc;
    rvec        ddx, *x = NULL;
    int         iat_xx, jat_xx;

    distribution = unsp_type(densit);
    if (distribution != -last_unsp || last_cubus != 4 ||
        (densit != last_densit && densit != last_n_dot))
    {
        if (make_unsp(densit, (-distribution), &n_dot, 4))
        {
            return 1;
        }
    }
    xus = xpunsp;

    dotarea = FOURPI/(real) n_dot;
    area    = 0.;

    if (debug)
    {
        fprintf(debug, "nsc_dclm: n_dot=%5d %9.3f\n", n_dot, dotarea);
    }

    /* start with neighbour list */
    /* calculate neighbour list with the box algorithm */
    if (nat == 0)
    {
        WARNING("nsc_dclm: no surface atoms selected");
        return 1;
    }
    if (mode & FLAG_VOLUME)
    {
        vol = 0.;
    }
    if (mode & FLAG_DOTS)
    {
        maxdots = (3*n_dot*nat)/10;
        /* should be set to NULL on first user call */
        if (dots == NULL)
        {
            snew(dots, maxdots);
        }
        else
        {
            srenew(dots, maxdots);
        }

        lfnr = 0;
    }
    if (mode & FLAG_ATOM_AREA)
    {
        /* should be set to NULL on first user call */
        if (atom_area == NULL)
        {
            snew(atom_area, nat);
        }
        else
        {
            srenew(atom_area, nat);
        }
    }

    /* Compute minimum size for grid cells */
    ra2max = radius[index[0]];
    for (iat_xx = 1; (iat_xx < nat); iat_xx++)
    {
        iat    = index[iat_xx];
        ra2max = max(ra2max, radius[iat]);
    }
    ra2max = 2*ra2max;

    /* Added DvdS 2006-07-19 */
    /* Updated 2008-10-09 */
    if (box)
    {
        set_pbc(&pbc, ePBC, box);
        snew(x, nat);
        for (i = 0; (i < nat); i++)
        {
            iat  = index[0];
            copy_rvec(coords[iat], x[i]);
        }
        put_atoms_in_triclinic_unitcell(ecenterTRIC, box, nat, x);
        nxbox = max(1, floor(norm(box[XX])/ra2max));
        nybox = max(1, floor(norm(box[YY])/ra2max));
        nzbox = max(1, floor(norm(box[ZZ])/ra2max));
        if (debug)
        {
            fprintf(debug, "nbox = %d, %d, %d\n", nxbox, nybox, nzbox);
        }
    }
    else
    {
        /* dimensions of atomic set, cell edge is 2*ra_max */
        iat    = index[0];
        xmin   = coords[iat][XX]; xmax = xmin; xs = xmin;
        ymin   = coords[iat][YY]; ymax = ymin; ys = ymin;
        zmin   = coords[iat][ZZ]; zmax = zmin; zs = zmin;

        for (iat_xx = 1; (iat_xx < nat); iat_xx++)
        {
            iat  = index[iat_xx];
            pco  = coords[iat];
            xmin = min(xmin, *pco);     xmax = max(xmax, *pco);
            ymin = min(ymin, *(pco+1)); ymax = max(ymax, *(pco+1));
            zmin = min(zmin, *(pco+2)); zmax = max(zmax, *(pco+2));
            xs   = xs+ *pco; ys = ys+ *(pco+1); zs = zs+ *(pco+2);
        }
        xs = xs/ (real) nat;
        ys = ys/ (real) nat;
        zs = zs/ (real) nat;
        if (debug)
        {
            fprintf(debug, "nsc_dclm: n_dot=%5d ra2max=%9.3f %9.3f\n", n_dot, ra2max, dotarea);
        }

        d    = xmax-xmin; nxbox = (int) max(ceil(d/ra2max), 1.);
        d    = (((real)nxbox)*ra2max-d)/2.;
        xmin = xmin-d; xmax = xmax+d;
        d    = ymax-ymin; nybox = (int) max(ceil(d/ra2max), 1.);
        d    = (((real)nybox)*ra2max-d)/2.;
        ymin = ymin-d; ymax = ymax+d;
        d    = zmax-zmin; nzbox = (int) max(ceil(d/ra2max), 1.);
        d    = (((real)nzbox)*ra2max-d)/2.;
        zmin = zmin-d; zmax = zmax+d;
    }
    /* Help variables */
    nxy  = nxbox*nybox;
    nxyz = nxy*nzbox;

    /* box number of atoms */
    snew(wkatm, nat);
    snew(wkat1, nat);
    snew(wkdot, n_dot);
    snew(wkbox, nxyz+1);

    if (box)
    {
        matrix box_1;
        rvec   x_1;
        int    ix, iy, iz, m;
        m_inv(box, box_1);
        for (i = 0; (i < nat); i++)
        {
            mvmul(box_1, x[i], x_1);
            ix = ((int)floor(x_1[XX]*nxbox) + 2*nxbox) % nxbox;
            iy = ((int)floor(x_1[YY]*nybox) + 2*nybox) % nybox;
            iz = ((int)floor(x_1[ZZ]*nzbox) + 2*nzbox) % nzbox;
            j  =  ix + iy*nxbox + iz*nxbox*nybox;
            if (debug)
            {
                fprintf(debug, "Atom %d cell index %d. x = (%8.3f,%8.3f,%8.3f) fc = (%8.3f,%8.3f,%8.3f)\n",
                        i, j, x[i][XX], x[i][YY], x[i][ZZ], x_1[XX], x_1[YY], x_1[ZZ]);
            }
            range_check(j, 0, nxyz);
            wkat1[i] = j;
            wkbox[j]++;
        }
    }
    else
    {
        /* Put the atoms in their boxes */
        for (iat_xx = 0; (iat_xx < nat); iat_xx++)
        {
            iat           = index[iat_xx];
            pco           = coords[iat];
            i             = (int) max(floor((pco[XX]-xmin)/ra2max), 0);
            i             = min(i, nxbox-1);
            j             = (int) max(floor((pco[YY]-ymin)/ra2max), 0);
            j             = min(j, nybox-1);
            l             = (int) max(floor((pco[ZZ]-zmin)/ra2max), 0);
            l             = min(l, nzbox-1);
            i             = i+j*nxbox+l*nxy;
            wkat1[iat_xx] = i;
            wkbox[i]++;
        }
    }

    /* sorting of atoms in accordance with box numbers */
    j = wkbox[0];
    for (i = 1; i < nxyz; i++)
    {
        j = max(wkbox[i], j);
    }
    for (i = 1; i <= nxyz; i++)
    {
        wkbox[i] += wkbox[i-1];
    }

    /* maxnei = (int) floor(ra2max*ra2max*ra2max*0.5); */
    maxnei = min(nat, 27*j);
    snew(wknb, maxnei);
    for (iat_xx = 0; iat_xx < nat; iat_xx++)
    {
        iat = index[iat_xx];
        range_check(wkat1[iat_xx], 0, nxyz);
        wkatm[--wkbox[wkat1[iat_xx]]] = iat_xx;
        if (debug)
        {
            fprintf(debug, "atom %5d on place %5d\n", iat, wkbox[wkat1[iat_xx]]);
        }
    }

    if (debug)
    {
        fprintf(debug, "nsc_dclm: n_dot=%5d ra2max=%9.3f %9.3f\n",
                n_dot, ra2max, dotarea);
        fprintf(debug, "neighbour list calculated/box(xyz):%d %d %d\n",
                nxbox, nybox, nzbox);

        for (i = 0; i < nxyz; i++)
        {
            fprintf(debug, "box %6d : atoms %4d-%4d    %5d\n",
                    i, wkbox[i], wkbox[i+1]-1, wkbox[i+1]-wkbox[i]);
        }
        for (i = 0; i < nat; i++)
        {
            fprintf(debug, "list place %5d by atom %7d\n", i, index[wkatm[i]]);
        }
    }

    /* calculate surface for all atoms, step cube-wise */
    for (iz = 0; iz < nzbox; iz++)
    {
        iii = iz*nxy;
        if (box)
        {
            izs = iz-1;
            ize = min(iz+2, izs+nzbox);
        }
        else
        {
            izs = max(iz-1, 0);
            ize = min(iz+2, nzbox);
        }
        for (iy = 0; iy < nybox; iy++)
        {
            ii = iy*nxbox+iii;
            if (box)
            {
                iys = iy-1;
                iye = min(iy+2, iys+nybox);
            }
            else
            {
                iys = max(iy-1, 0);
                iye = min(iy+2, nybox);
            }
            for (ix = 0; ix < nxbox; ix++)
            {
                i    = ii+ix;
                iii1 = wkbox[i];
                iii2 = wkbox[i+1];
                if (iii1 >= iii2)
                {
                    continue;
                }
                if (box)
                {
                    ixs = ix-1;
                    ixe = min(ix+2, ixs+nxbox);
                }
                else
                {
                    ixs = max(ix-1, 0);
                    ixe = min(ix+2, nxbox);
                }
                iiat = 0;
                /* make intermediate atom list */
                for (jz = izs; jz < ize; jz++)
                {
                    jjj = ((jz+nzbox) % nzbox)*nxy;
                    for (jy = iys; jy < iye; jy++)
                    {
                        jj = ((jy+nybox) % nybox)*nxbox+jjj;
                        for (jx = ixs; jx < ixe; jx++)
                        {
                            j = jj+((jx+nxbox) % nxbox);
                            for (jat = wkbox[j]; jat < wkbox[j+1]; jat++)
                            {
                                range_check(wkatm[jat], 0, nat);
                                range_check(iiat, 0, nat);
                                wkat1[iiat] = wkatm[jat];
                                iiat++;
                            } /* end of cycle "jat" */
                        }     /* end of cycle "jx" */
                    }         /* end of cycle "jy" */
                }             /* end of cycle "jz" */
                for (iat = iii1; iat < iii2; iat++)
                {
                    i_at = index[wkatm[iat]];
                    ai   = radius[i_at];
                    aisq = ai*ai;
                    pco  = coords[i_at];
                    xi   = pco[XX]; yi = pco[YY]; zi = pco[ZZ];
                    for (i = 0; i < n_dot; i++)
                    {
                        wkdot[i] = 0;
                    }

                    ctnb = wknb; nnei = 0;
                    for (j = 0; j < iiat; j++)
                    {
                        j_at = index[wkat1[j]];
                        if (j_at == i_at)
                        {
                            continue;
                        }

                        aj   = radius[j_at];
                        ajsq = aj*aj;
                        pco  = coords[j_at];

                        /* Added DvdS 2006-07-19 */
                        if (box)
                        {
                            /*rvec xxi;

                               xxi[XX] = xi;
                               xxi[YY] = yi;
                               xxi[ZZ] = zi;
                               pbc_dx(&pbc,pco,xxi,ddx);*/
                            pbc_dx(&pbc, coords[j_at], coords[i_at], ddx);
                            dx = ddx[XX];
                            dy = ddx[YY];
                            dz = ddx[ZZ];
                        }
                        else
                        {
                            dx = pco[XX]-xi;
                            dy = pco[YY]-yi;
                            dz = pco[ZZ]-zi;
                        }
                        dd = dx*dx+dy*dy+dz*dz;
                        as = ai+aj;
                        if (dd > as*as)
                        {
                            continue;
                        }
                        nnei++;
                        ctnb->x   = dx;
                        ctnb->y   = dy;
                        ctnb->z   = dz;
                        ctnb->dot = (dd+aisq-ajsq)/(2.*ai); /* reference dot product */
                        ctnb++;
                    }

                    /* check points on accessibility */
                    if (nnei)
                    {
                        last = 0; i_ac = 0;
                        for (l = 0; l < n_dot; l++)
                        {
                            if (xus[3*l]*(wknb+last)->x+
                                xus[1+3*l]*(wknb+last)->y+
                                xus[2+3*l]*(wknb+last)->z <= (wknb+last)->dot)
                            {
                                for (j = 0; j < nnei; j++)
                                {
                                    if (xus[3*l]*(wknb+j)->x+xus[1+3*l]*(wknb+j)->y+
                                        xus[2+3*l]*(wknb+j)->z > (wknb+j)->dot)
                                    {
                                        last = j;
                                        break;
                                    }
                                }
                                if (j >= nnei)
                                {
                                    i_ac++;
                                    wkdot[l] = 1;
                                }
                            } /* end of cycle j */
                        }     /* end of cycle l */
                    }
                    else
                    {
                        i_ac  = n_dot;
                        for (l = 0; l < n_dot; l++)
                        {
                            wkdot[l] = 1;
                        }
                    }

                    if (debug)
                    {
                        fprintf(debug, "i_ac=%d, dotarea=%8.3f, aisq=%8.3f\n",
                                i_ac, dotarea, aisq);
                    }

                    a    = aisq*dotarea* (real) i_ac;
                    area = area + a;
                    if (mode & FLAG_ATOM_AREA)
                    {
                        range_check(wkatm[iat], 0, nat);
                        atom_area[wkatm[iat]] = a;
                    }
                    if (mode & FLAG_DOTS)
                    {
                        for (l = 0; l < n_dot; l++)
                        {
                            if (wkdot[l])
                            {
                                lfnr++;
                                if (maxdots <= 3*lfnr+1)
                                {
                                    maxdots = maxdots+n_dot*3;
                                    srenew(dots, maxdots);
                                }
                                dots[3*lfnr-3] = ai*xus[3*l]+xi;
                                dots[3*lfnr-2] = ai*xus[1+3*l]+yi;
                                dots[3*lfnr-1] = ai*xus[2+3*l]+zi;
                            }
                        }
                    }
                    if (mode & FLAG_VOLUME)
                    {
                        dx = 0.; dy = 0.; dz = 0.;
                        for (l = 0; l < n_dot; l++)
                        {
                            if (wkdot[l])
                            {
                                dx = dx+xus[3*l];
                                dy = dy+xus[1+3*l];
                                dz = dz+xus[2+3*l];
                            }
                        }
                        vol = vol+aisq*(dx*(xi-xs)+dy*(yi-ys)+dz*(zi-zs)+ai* (real) i_ac);
                    }

                } /* end of cycle "iat" */
            }     /* end of cycle "ix" */
        }         /* end of cycle "iy" */
    }             /* end of cycle "iz" */

    sfree(wkatm);
    sfree(wkat1);
    sfree(wkdot);
    sfree(wkbox);
    sfree(wknb);
    if (box)
    {
        sfree(x);
    }
    if (mode & FLAG_VOLUME)
    {
        vol           = vol*FOURPI/(3.* (real) n_dot);
        *value_of_vol = vol;
    }
    if (mode & FLAG_DOTS)
    {
        *nu_dots = lfnr;
        *lidots  = dots;
    }
    if (mode & FLAG_ATOM_AREA)
    {
        *at_area = atom_area;
    }
    *value_of_area = area;

    if (debug)
    {
        fprintf(debug, "area=%8.3f\n", area);
    }

    return 0;
}
Beispiel #13
0
void settle_proj(FILE *fp,
                 gmx_settledata_t settled,int econq,
                 int nsettle, t_iatom iatoms[],rvec x[],
                 rvec *der,rvec *derp,
                 gmx_bool bCalcVir,tensor rmdder,t_vetavars *vetavar)
{
    /* Settle for projection out constraint components
     * of derivatives of the coordinates.
     * Berk Hess 2008-1-10
     */
    
    settleparam_t *p;
    real   imO,imH,dOH,dHH,invdOH,invdHH;
    matrix invmat;
    int    i,m,m2,ow1,hw2,hw3;
    rvec   roh2,roh3,rhh,dc,fc,fcv;
    rvec   derm[3],derpm[3];
    real   invvscale,vscale_nhc,veta;
    real   kfacOH,kfacHH;

    if (econq == econqForce)
    {
        p = &settled->mass1;
    }
    else
    {
        p = &settled->massw;
    }
    imO    = p->imO;
    imH    = p->imH;
    copy_mat(p->invmat,invmat);
    dOH    = p->dOH;
    dHH    = p->dHH;
    invdOH = p->invdOH;
    invdHH = p->invdHH;
    
    veta = vetavar->veta;     
    vscale_nhc = vetavar->vscale_nhc[0]; /* assume the first temperature control group. */

#ifdef PRAGMAS
#pragma ivdep
#endif
    
    for (i=0; i<nsettle; i++)
    {
        ow1 = iatoms[i*2+1];
        hw2 = ow1 + 1;
        hw3 = ow1 + 2;


        for(m=0; m<DIM; m++)
        {
            /* in the velocity case, these are the velocities, so we 
               need to modify with the pressure control velocities! */
            
            derm[0][m]  = vscale_nhc*der[ow1][m] + veta*x[ow1][m];
            derm[1][m]  = vscale_nhc*der[hw2][m] + veta*x[hw2][m];
            derm[2][m]  = vscale_nhc*der[hw3][m] + veta*x[hw3][m];
            
        }
        /* 27 flops */
        
        for(m=0; m<DIM; m++)
        {
            roh2[m] = (x[ow1][m] - x[hw2][m])*invdOH;
            roh3[m] = (x[ow1][m] - x[hw3][m])*invdOH;
            rhh [m] = (x[hw2][m] - x[hw3][m])*invdHH;
        }
        /* 18 flops */
        
        /* Determine the projections of der(modified) on the bonds */
        clear_rvec(dc);
        for(m=0; m<DIM; m++)
        {
            dc[0] += (derm[0][m] - derm[1][m])*roh2[m];
            dc[1] += (derm[0][m] - derm[2][m])*roh3[m];
            dc[2] += (derm[1][m] - derm[2][m])*rhh [m];
        }
        /* 27 flops */
        
        /* Determine the correction for the three bonds */
        mvmul(invmat,dc,fc);
        /* 15 flops */
        
        /* divide velocity by vscale_nhc for determining constrained velocities, since they 
           have not yet been multiplied */
        svmul(1.0/vscale_nhc,fc,fcv);
        /* 7? flops */
        
        /* Subtract the corrections from derp */
        for(m=0; m<DIM; m++)
        {
            derp[ow1][m] -= imO*( fcv[0]*roh2[m] + fcv[1]*roh3[m]);
            derp[hw2][m] -= imH*(-fcv[0]*roh2[m] + fcv[2]*rhh [m]);
            derp[hw3][m] -= imH*(-fcv[1]*roh3[m] - fcv[2]*rhh [m]);
        }
        
        /* 45 flops */

        if (bCalcVir)
        {
            /* Determining r \dot m der is easy,
             * since fc contains the mass weighted corrections for der.
             */
            
            for(m=0; m<DIM; m++)
            {
                for(m2=0; m2<DIM; m2++)
                {
                    rmdder[m][m2] +=
                        dOH*roh2[m]*roh2[m2]*fcv[0] +
                        dOH*roh3[m]*roh3[m2]*fcv[1] +
                        dHH*rhh [m]*rhh [m2]*fcv[2]; 
                }
            }
        }
    }
    /* conrect rmdder, which will be used to calcualate the virial; we need to use 
       the unscaled multipliers in the virial */
    msmul(rmdder,1.0/vetavar->vscale,rmdder);
}
Beispiel #14
0
real orires(int nfa,t_iatom forceatoms[],t_iparams ip[],
	    rvec x[],rvec f[],t_forcerec *fr,t_graph *g,
	    matrix box,real lambda,real *dvdlambda,
	    t_mdatoms *md,int ngrp,real egnb[],real egcoul[],
	    t_fcdata *fcd)
{
  atom_id      ai,aj;
  int          fa,d,i,type,ex,power,ki;
  ivec         dt;
  real         r2,invr,invr2,fc,smooth_fc,dev,devins,pfac;
  rvec         r,Sr,fij;
  real         vtot;
  t_oriresdata *od;
  bool         bTAV;

  vtot = 0;
  od = &(fcd->orires);

  if (fabs(od->fc) > GMX_REAL_MIN) {
    bTAV = (fabs(od->edt) > GMX_REAL_MIN);
    
    /* Smoothly switch on the restraining when time averaging is used */
    smooth_fc = od->fc*(1.0 - od->exp_min_t_tau);
    
    d = 0;
    for(fa=0; fa<nfa; fa+=3) {
      type  = forceatoms[fa];
      ai    = forceatoms[fa+1];
      aj    = forceatoms[fa+2];
      rvec_sub(x[ai],x[aj],r);
      r2    = norm2(r);
      invr  = invsqrt(r2);
      invr2 = invr*invr;
      ex    = ip[type].orires.ex;
      power = ip[type].orires.pow;
      fc    = smooth_fc*ip[type].orires.kfac;
      dev   = od->otav[d] - ip[type].orires.obs;
      
      /* NOTE: there is no real potential when time averaging is applied */
      vtot += 0.5*fc*sqr(dev);
      
      if (bTAV) {
	/* Calculate the force as the sqrt of tav times instantaneous */
	devins = od->oins[d] - ip[type].orires.obs;
	if (dev*devins <= 0)
	  dev = 0;
	else {
	  dev = sqrt(dev*devins);
	  if (devins < 0)
	    dev = -dev;
	}
      }
      
      pfac  = fc*ip[type].orires.c*invr2;
      for(i=0; i<power; i++)
	pfac *= invr;
      mvmul(od->S[ex],r,Sr);
      for(i=0; i<DIM; i++)
	fij[i] = -pfac*dev*(4*Sr[i] - 2*(2+power)*invr2*iprod(Sr,r)*r[i]);
      
      ivec_sub(SHIFT_IVEC(g,ai),SHIFT_IVEC(g,aj),dt);
      ki=IVEC2IS(dt);
      
      for(i=0; i<DIM; i++) {
	f[ai][i]               += fij[i];
	f[aj][i]               -= fij[i];
	fr->fshift[ki][i]      += fij[i];
	fr->fshift[CENTRAL][i] -= fij[i];
      }
      d++;
    }
  }
  
  return vtot;
  
  /* Approx. 80*nfa/3 flops */
}
Beispiel #15
0
real calc_orires_dev(t_commrec *mcr,
		     int nfa,t_iatom forceatoms[],t_iparams ip[],
		     t_mdatoms *md,rvec x[],t_fcdata *fcd)
{
  int          fa,d,i,j,type,ex,nref;
  real         edt,edt1,invn,pfac,r2,invr,corrfac,weight,wsv2,sw,dev;
  tensor       *S,R,TMP;
  rvec5        *Dinsl,*Dins,*Dtav,*rhs;
  real         *mref,***T;
  rvec         *xref,*xtmp,com,r_unrot,r;
  t_oriresdata *od;
  bool         bTAV;
  static real  two_thr=2.0/3.0;

  od = &(fcd->orires);

  bTAV = (fabs(od->edt)>GMX_REAL_MIN);
  edt  = od->edt;
  edt1 = od->edt1;
  S    = od->S;
  Dinsl= od->Dinsl;
  Dins = od->Dins;
  Dtav = od->Dtav;
  T    = od->TMP;
  rhs  = od->tmp;
  nref = od->nref;
  mref = od->mref;
  xref = od->xref;
  xtmp = od->xtmp;
  
  od->exp_min_t_tau *= edt;

  if (mcr)
    invn = 1.0/mcr->nnodes;
  else
    invn = 1.0;

  j=0;
  for(i=0; i<md->nr; i++)
    if (md->cORF[i] == 0) {
      copy_rvec(x[i],xtmp[j]);
      for(d=0; d<DIM; d++)
	com[d] += mref[j]*xref[j][d];
      j++;
    }
  svmul(od->invmref,com,com);
  for(j=0; j<nref; j++)
    rvec_dec(xtmp[j],com);
  /* Calculate the rotation matrix to rotate x to the reference orientation */
  calc_fit_R(nref,mref,xref,xtmp,R);
  copy_mat(R,od->R);

  d = 0;
  for(fa=0; fa<nfa; fa+=3) {
    type = forceatoms[fa];
    rvec_sub(x[forceatoms[fa+1]],x[forceatoms[fa+2]],r_unrot);
    mvmul(R,r_unrot,r);
    r2   = norm2(r);
    invr = invsqrt(r2);
    /* Calculate the prefactor for the D tensor, this includes the factor 3! */
    pfac = ip[type].orires.c*invr*invr*3;
    for(i=0; i<ip[type].orires.pow; i++)
      pfac *= invr;
    Dinsl[d][0] = pfac*(2*r[0]*r[0] + r[1]*r[1] - r2);
    Dinsl[d][1] = pfac*(2*r[0]*r[1]);
    Dinsl[d][2] = pfac*(2*r[0]*r[2]);
    Dinsl[d][3] = pfac*(2*r[1]*r[1] + r[0]*r[0] - r2);
    Dinsl[d][4] = pfac*(2*r[1]*r[2]);

    if (mcr)
      for(i=0; i<5; i++)
	Dins[d][i] = Dinsl[d][i]*invn;
    
    d++;
  }
  
  if (mcr)
    gmx_sum(5*od->nr,Dins[0],mcr);
  
  /* Correction factor to correct for the lack of history for short times */
  corrfac = 1.0/(1.0-od->exp_min_t_tau);
  
  /* Calculate the order tensor S for each experiment via optimization */
  for(ex=0; ex<od->nex; ex++)
    for(i=0; i<5; i++) {
      rhs[ex][i] = 0;
      for(j=0; j<=i; j++)
	T[ex][i][j] = 0;
    }
  d = 0;
  for(fa=0; fa<nfa; fa+=3) {
    if (bTAV)
      for(i=0; i<5; i++)
	Dtav[d][i] = edt*Dtav[d][i] + edt1*Dins[d][i];

    type   = forceatoms[fa];
    ex     = ip[type].orires.ex;
    weight = ip[type].orires.kfac;
    /* Calculate the vector rhs and half the matrix T for the 5 equations */
    for(i=0; i<5; i++) {
      rhs[ex][i] += Dtav[d][i]*ip[type].orires.obs*weight;
      for(j=0; j<=i; j++)
	T[ex][i][j] += Dtav[d][i]*Dtav[d][j]*weight;
    }
    d++;
  }
  /* Now we have all the data we can calculate S */
  for(ex=0; ex<od->nex; ex++) {
    /* Correct corrfac and copy one half of T to the other half */
    for(i=0; i<5; i++) {
      rhs[ex][i]  *= corrfac;
      T[ex][i][i] *= sqr(corrfac);
      for(j=0; j<i; j++) {
	T[ex][i][j] *= sqr(corrfac);
	T[ex][j][i]  = T[ex][i][j];
      }
    }
    m_inv_gen(T[ex],5,T[ex]);
    /* Calculate the orientation tensor S for this experiment */
    S[ex][0][0] = 0;
    S[ex][0][1] = 0;
    S[ex][0][2] = 0;
    S[ex][1][1] = 0;
    S[ex][1][2] = 0;
    for(i=0; i<5; i++) {
      S[ex][0][0] += 1.5*T[ex][0][i]*rhs[ex][i];
      S[ex][0][1] += 1.5*T[ex][1][i]*rhs[ex][i];
      S[ex][0][2] += 1.5*T[ex][2][i]*rhs[ex][i];
      S[ex][1][1] += 1.5*T[ex][3][i]*rhs[ex][i];
      S[ex][1][2] += 1.5*T[ex][4][i]*rhs[ex][i];
    }
    S[ex][1][0] = S[ex][0][1];
    S[ex][2][0] = S[ex][0][2];
    S[ex][2][1] = S[ex][1][2];
    S[ex][2][2] = -S[ex][0][0] - S[ex][1][1];
  }
  
  wsv2 = 0;
  sw   = 0;
  
  d = 0;
  for(fa=0; fa<nfa; fa+=3) {
    type = forceatoms[fa];
    ex = ip[type].orires.ex;

    od->otav[d] = two_thr*
      corrfac*(S[ex][0][0]*Dtav[d][0] + S[ex][0][1]*Dtav[d][1] +
	       S[ex][0][2]*Dtav[d][2] + S[ex][1][1]*Dtav[d][3] +
	       S[ex][1][2]*Dtav[d][4]);
    if (bTAV)
      od->oins[d] = two_thr*(S[ex][0][0]*Dins[d][0] + S[ex][0][1]*Dins[d][1] +
			     S[ex][0][2]*Dins[d][2] + S[ex][1][1]*Dins[d][3] +
			     S[ex][1][2]*Dins[d][4]);
    if (mcr)
      /* When ensemble averaging is used recalculate the local orientation
       * for output to the energy file.
       */
      od->oinsl[d] = two_thr*
	(S[ex][0][0]*Dinsl[d][0] + S[ex][0][1]*Dinsl[d][1] +
	 S[ex][0][2]*Dinsl[d][2] + S[ex][1][1]*Dinsl[d][3] +
	 S[ex][1][2]*Dinsl[d][4]);
    
    dev = od->otav[d] - ip[type].orires.obs;
    
    wsv2 += ip[type].orires.kfac*sqr(dev);
    sw   += ip[type].orires.kfac;
    
    d++;
  }
  od->rmsdev = sqrt(wsv2/sw);
  
  /* Rotate the S matrices back, so we get the correct grad(tr(S D)) */
  for(ex=0; ex<od->nex; ex++) {
    tmmul(R,S[ex],TMP);
    mmul(TMP,R,S[ex]);
  }

  return od->rmsdev;
  
  /* Approx. 120*nfa/3 flops */
}