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