Exemplo n.º 1
0
    def atom_surface(self, atom: Atom, ref: Surface, prad: float) -> Surface:
        """Create a new surface from the points that do fall on the reference
        surface.

        :param atom: Atom from which surface will be constructed.
        :return: Returns surface generated from the atom.

        .. note:: Although this seems like a candidate for a static method, the
        `accessable_outside_inflated_venderwalls_rad` method of this class
        *is* called from this function, and therefore must be a regular method.

        """

        arad = atom.radius
        apos = atom.position
        atomID = atom.id
        surf: Surface

        if arad < Constants.very_small_eps:
            return Surface(prad, 0)

        rad = arad + prad

        # Possibly merge these two loops?
        npoints = 0
        pos = Coordinate()
        for i in range(ref.npoints):
            pos.x = rad(ref.xs[i]) + apos.x
            pos.y = rad(ref.ys[i]) + apos.y
            pos.z = rad(ref.zs[i]) + apos.z

            # need to implement
            if self.accessable_outside_inflated_venderwalls_rad(
                pos, prad, atomID
            ):
                npoints += 1
                ref.is_on_surf[i] = True
            else:
                ref.is_on_surf[i] = False

        surf = Surface(prad, npoints)
        for i in range(ref.npoints):
            if ref.coords[i].is_on_surf:
                surf.coords.append((rad * ref.coords[i] + apos))
                surf.coords[-1].is_on_surf = True

        surf.area = (
            4.0
            * math.pi
            * rad
            * rad
            * float(surf.npoints)
            / float(ref.npoints)
        )

        return surf
Exemplo n.º 2
0
 def test_property_set(self):
     sut = Coordinate(0, 0, 0)
     assert sut.x == 0
     assert sut.y == 0
     assert sut.z == 0
     sut.x = 1
     sut.y = 2
     sut.z = 3
     assert sut.x == 1
     assert sut.y == 2
     assert sut.z == 3
Exemplo n.º 3
0
    def value(self, pt: Coordinate[float]) -> float:
        """Get potential value (from mesh or approximation) at a point

        :note: Previously returned by pointer, using return code as an error
               code.
                This has been replaced by returning the value and raising an
                exception on error.

        :param   x    : Coordinate at which to evaluate potential
        :returns      : value of grid
        """

        if self.data is None:
            raise RuntimeError("No data available.")

        ret_value = float(0)

        tmp = Coordinate(
            (pt.x - self.mins.x) / self.spaces.x,
            (pt.y - self.mins.y) / self.spaces.y,
            (pt.z - self.mins.z) / self.spaces.z,
        )

        hi = Coordinate(int(math.ceil(tmp.x)), int(math.ceil(tmp.y)),
                        int(math.ceil(tmp.z)))
        lo = Coordinate(
            int(math.floor(tmp.x)),
            int(math.floor(tmp.y)),
            int(math.floor(tmp.z)),
        )

        hi.x = (self.dims.x -
                1 if abs(pt.x - self.maxs.x) < Constants.epsilon else hi.x)
        hi.y = (self.dims.y -
                1 if abs(pt.y - self.maxs.y) < Constants.epsilon else hi.y)
        hi.z = (self.dims.z -
                1 if abs(pt.z - self.maxs.z) < Constants.epsilon else hi.z)

        lo.x = 0 if abs(pt.x - self.mins.x) < Constants.eps else lo.x
        lo.y = 0 if abs(pt.y - self.mins.y) < Constants.eps else lo.y
        lo.z = 0 if abs(pt.z - self.mins.z) < Constants.eps else lo.z

        if hi < self.dims:
            dx, dy, dz = tmp.x - lo.x, tmp.y - lo.y, tmp.z - lo.z
            ret_value = list()
            ret_value.append(float(dx * dy * dz * self.data[hi.x, hi.y, hi.z]))
            ret_value.append(
                float(dx * (1.0 - dy) * dz * self.data[hi.x, lo.y, hi.z]))
            ret_value.append(
                float(dx * dy * (1.0 - dz) * self.data[hi.x, hi.y, lo.z]))
            ret_value.append(
                float(dx * (1.0 - dy) * (1.0 - dz) *
                      self.data[hi.x, lo.y, lo.z]))
            ret_value.append(
                float((1.0 - dx) * dy * dz * self.data[lo.x, hi.y, hi.z]))
            ret_value.append(
                float((1.0 - dx) * (1.0 - dy) * dz *
                      self.data[lo.x, lo.y, hi.z]))
            ret_value.append(
                float((1.0 - dx) * dy * (1.0 - dz) *
                      self.data[lo.x, hi.y, lo.z]))
            ret_value.append(
                float((1.0 - dx) * (1.0 - dy) * (1.0 - dz) *
                      self.data[lo.x, lo.y, lo.z]))

            ret_value = sum(ret_value)

            if ret_value == math.nan:
                # TODO: Add a more descriptive error
                raise RuntimeError(
                    "Value routine failed to converge with the following "
                    "coordinates:\n"
                    f"\tLow: {lo}\n"
                    f"\tHigh: {hi}\n"
                    f"\tCoordinate: {pt}\n")

        return ret_value