/// <summary> /// Calculate the accesible volume. /// </summary> /// <param name="L">Linker length</param> /// <param name="W">Linker width (diameter)</param> /// <param name="R">Dye radius</param> /// <param name="atom_i">Atom number in xyz arrays (not the original number in the pdb file)</param> public void Calculate1R(Double L, Double W, Double R, Int32 atom_i) { // grid Double dg1 = Math.Min(L * _avGrid.GridSize, W * _avGrid.GridSize); Double dg2 = Math.Min(R * 2.0 * _avGrid.GridSize, dg1); Double dg = Math.Max(dg2, _avGrid.MinGridSize); Double x0 = mol.XLocal[atom_i], y0 = mol.YLocal[atom_i], z0 = mol.ZLocal[atom_i]; Double dx, dy, dz; Int32 npm = (Int32)Math.Floor(L / dg); Int32 ng = 2 * npm + 1, ng3 = ng * ng * ng, n; Int32 offset; Double[] xg = new Double[ng]; Double[] yg = new Double[ng]; Double[] zg = new Double[ng]; for (Int32 i = -npm; i <= npm; i++) { n = i + npm; xg[n] = i * dg; yg[n] = i * dg; zg[n] = i * dg; } _density = new Byte[ng3]; n = FpsNativeWrapper.AvCalculate1R(L, W, R, atom_i, dg, mol.XLocal, mol.YLocal, mol.ZLocal, mol.vdWR, mol.NAtoms, AtomData.vdWRMax, _avGrid.LinkerInitialSphere, _avGrid.LinkSearchNodes, _density); // saves _r = new Vector3[n]; Double rn = 1.0 / (Double)n; n = 0; dx = 0.0; dy = 0.0; dz = 0.0; x0 += mol.CM.X; y0 += mol.CM.Y; z0 += mol.CM.Z; for (Int32 ix = -npm; ix <= npm; ix++) { offset = ng * (ng * (ix + npm)) + npm; for (Int32 iy = -npm; iy <= npm; iy++) { for (Int32 iz = -npm; iz <= npm; iz++) { if (_density[iz + offset] > 0) { _r[n].X = xg[ix + npm] + x0; dx += _r[n].X; _r[n].Y = yg[iy + npm] + y0; dy += _r[n].Y; _r[n].Z = zg[iz + npm] + z0; dz += _r[n++].Z; } } offset += ng; } } // other saves _rmp.X = dx * rn; _rmp.Y = dy * rn; _rmp.Z = dz * rn; _xGrid.Min = xg[0] + x0; _yGrid.Min = yg[0] + y0; _zGrid.Min = zg[0] + z0; _xGrid.NNodes = ng; _yGrid.NNodes = ng; _zGrid.NNodes = ng; _xGrid.Step = dg; _yGrid.Step = dg; _zGrid.Step = dg; }