def test_point_mutate(self): # Modify coordinates p = Point(3.0, 4.0) p.coords = (2.0, 1.0) self.assertEqual(p.__geo_interface__, { 'type': 'Point', 'coordinates': (2.0, 1.0) }) # Alternate method p.coords = ((0.0, 0.0), ) self.assertEqual(p.__geo_interface__, { 'type': 'Point', 'coordinates': (0.0, 0.0) })
def test_point_immutable(): p = Point(3.0, 4.0) with pytest.raises(AttributeError): p.coords = (2.0, 1.0) with pytest.raises(TypeError): p.coords[0] = (2.0, 1.0)
def test_point_empty_mutate(self): # Check that we can set coordinates of a null geometry p_null = Point() p_null.coords = (1, 2) self.assertEqual(p_null.coords[:], [(1.0, 2.0)]) # Passing > 3 arguments to Point is erroneous with self.assertRaises(TypeError): Point(1.0, 2.0, 3.0, 4.0)
def seed_neurons(self, neurons=None, container=None, on_area=None, xmin=None, xmax=None, ymin=None, ymax=None, soma_radius=0, unit=None, return_quantity=None): ''' Return the positions of the neurons inside the :class:`Shape`. Parameters ---------- neurons : int, optional (default: None) Number of neurons to seed. This argument is considered only if the :class:`Shape` has no `parent`, otherwise, a position is generated for each neuron in `parent`. container : :class:`Shape`, optional (default: None) Subshape acting like a mask, in which the neurons must be contained. The resulting area where the neurons are generated is the :func:`~shapely.Shape.intersection` between of the current shape and the `container`. on_area : str or list, optional (default: None) Area(s) where the seeded neurons should be. xmin : double, optional (default: lowest abscissa of the Shape) Limit the area where neurons will be seeded to the region on the right of `xmin`. xmax : double, optional (default: highest abscissa of the Shape) Limit the area where neurons will be seeded to the region on the left of `xmax`. ymin : double, optional (default: lowest ordinate of the Shape) Limit the area where neurons will be seeded to the region on the upper side of `ymin`. ymax : double, optional (default: highest ordinate of the Shape) Limit the area where neurons will be seeded to the region on the lower side of `ymax`. unit : string (default: None) Unit in which the positions of the neurons will be returned, among 'um', 'mm', 'cm', 'dm', 'm'. return_quantity : bool, optional (default: False) Whether the positions should be returned as ``pint.Quantity`` objects (requires Pint). .. versionchanged:: 0.5 Accepts `pint` units and `return_quantity` argument. Note ---- If both `container` and `on_area` are provided, the intersection of the two is used. Returns ------- positions : array of double with shape (N, 2) or `pint.Quantity` if `return_quantity` is `True`. ''' return_quantity = (self._return_quantity if return_quantity is None else return_quantity) if return_quantity: unit = self._unit if unit is None else unit if not _unit_support: raise RuntimeError("`return_quantity` requested but Pint is " "not available. Please install it first.") if _unit_support: from .units import Q_ if isinstance(xmin, Q_): xmin = xmin.m_as(unit) if isinstance(xmax, Q_): xmax = xmax.m_as(unit) if isinstance(ymin, Q_): ymin = ymin.m_as(unit) if isinstance(ymax, Q_): ymax = ymax.m_as(unit) if isinstance(soma_radius, Q_): soma_radius = soma_radius.m_as(unit) positions = None if neurons is None and self._parent is not None: neurons = self._parent.node_nb() if neurons is None: raise ValueError("`neurons` cannot be None if `parent` is None.") if on_area is not None: if not hasattr(on_area, '__iter__'): on_area = [on_area] min_x, min_y, max_x, max_y = self.bounds custom_shape = (container is not None) if container is None and on_area is None: # set min/max if xmin is None: xmin = -np.inf if ymin is None: ymin = -np.inf if xmax is None: xmax = np.inf if ymax is None: ymax = np.inf min_x = max(xmin, min_x) # smaller that Shape max x assert min_x <= self.bounds[2], "`min_x` must be inside Shape." min_y = max(ymin, min_y) # smaller that Shape max y assert min_y <= self.bounds[3], "`min_y` must be inside Shape." max_x = min(xmax, max_x) # larger that Shape min x assert max_x >= self.bounds[0], "`max_x` must be inside Shape." max_y = min(ymax, max_y) # larger that Shape min y assert max_y >= self.bounds[1], "`max_y` must be inside Shape." # remaining tests if self._geom_type == "Rectangle": xx = uniform(min_x + soma_radius, max_x - soma_radius, size=neurons) yy = uniform(min_y + soma_radius, max_y - soma_radius, size=neurons) positions = np.vstack((xx, yy)).T elif (self._geom_type == "Disk" and (xmin, ymin, xmax, ymax) == self.bounds): theta = uniform(0, 2 * np.pi, size=neurons) # take some precaution to stay inside the shape r = (self.radius - soma_radius) *\ np.sqrt(uniform(0, 0.99, size=neurons)) positions = np.vstack((r * np.cos(theta) + self.centroid[0], r * np.sin(theta) + self.centroid[1])).T else: custom_shape = True container = Polygon([(min_x, min_y), (min_x, max_y), (max_x, max_y), (max_x, min_y)]) elif on_area is not None: custom_shape = True area_shape = Polygon() for area in on_area: area_shape = area_shape.union(self._areas[area]) if container is not None: container = container.intersection(area_shape) else: container = area_shape assert container.area > 0, "`container` and `on_area` have " +\ "empty intersection." # enter here only if Polygon or `container` is not None if custom_shape: seed_area = self.intersection(container) area_buffer = seed_area.buffer(-soma_radius) if not area_buffer.is_empty: seed_area = area_buffer assert not seed_area.is_empty, "Empty area for seeding, check " +\ "your `container` and min/max values." if not isinstance(seed_area, (Polygon, MultiPolygon)): raise ValueError("Invalid boundary value for seed region; " "check that the min/max values you requested " "are inside the shape.") if _opengl_support: triangles = [] if isinstance(seed_area, MultiPolygon): for g in seed_area.geoms: triangles.extend((Polygon(v) for v in triangulate(g))) else: triangles = [Polygon(v) for v in triangulate(seed_area)] positions = rnd_pts_in_tr(triangles, neurons) else: logger.warning("Random point generation can be very slow " "without advanced triangulation methods. " "Please install PyOpenGL for faster seeding " "inside complex shapes.") points = [] p = Point() while len(points) < neurons: new_x = uniform(min_x, max_x, neurons - len(points)) new_y = uniform(min_y, max_y, neurons - len(points)) for x, y in zip(new_x, new_y): p.coords = (x, y) if seed_area.contains(p): points.append((x, y)) positions = np.array(points) if unit is not None and unit != self._unit: positions *= conversion_magnitude(unit, self._unit) if _unit_support and return_quantity: from .units import Q_ return positions * Q_("um" if unit is None else unit) return positions
def test_point(self): # Test 2D points p = Point(1.0, 2.0) self.assertEqual(p.x, 1.0) self.assertEqual(p.y, 2.0) self.assertEqual(p.coords[:], [(1.0, 2.0)]) self.assertEqual(str(p), p.wkt) self.assertFalse(p.has_z) with self.assertRaises(DimensionError): p.z # Check 3D p = Point(1.0, 2.0, 3.0) self.assertEqual(p.coords[:], [(1.0, 2.0, 3.0)]) self.assertEqual(str(p), p.wkt) self.assertTrue(p.has_z) self.assertEqual(p.z, 3.0) # From coordinate sequence p = Point((3.0, 4.0)) self.assertEqual(p.coords[:], [(3.0, 4.0)]) # From another point q = Point(p) self.assertEqual(q.coords[:], [(3.0, 4.0)]) # Coordinate access self.assertEqual(p.x, 3.0) self.assertEqual(p.y, 4.0) self.assertEqual(tuple(p.coords), ((3.0, 4.0), )) self.assertEqual(p.coords[0], (3.0, 4.0)) with self.assertRaises(IndexError): # index out of range p.coords[1] # Bounds self.assertEqual(p.bounds, (3.0, 4.0, 3.0, 4.0)) # Geo interface self.assertEqual(p.__geo_interface__, { 'type': 'Point', 'coordinates': (3.0, 4.0) }) # Modify coordinates p.coords = (2.0, 1.0) self.assertEqual(p.__geo_interface__, { 'type': 'Point', 'coordinates': (2.0, 1.0) }) # Alternate method p.coords = ((0.0, 0.0), ) self.assertEqual(p.__geo_interface__, { 'type': 'Point', 'coordinates': (0.0, 0.0) }) # Adapt a coordinate list to a point coords = [3.0, 4.0] pa = asPoint(coords) self.assertEqual(pa.coords[0], (3.0, 4.0)) self.assertEqual(pa.distance(p), 5.0) # Move the coordinates and watch the distance change coords[0] = 1.0 self.assertEqual(pa.coords[0], (1.0, 4.0)) self.assertAlmostEqual(pa.distance(p), 4.123105625617661) # Test Non-operability of Null geometry p_null = Point() self.assertEqual(p_null.wkt, 'GEOMETRYCOLLECTION EMPTY') self.assertEqual(p_null.coords[:], []) self.assertEqual(p_null.area, 0.0) # Check that we can set coordinates of a null geometry p_null.coords = (1, 2) self.assertEqual(p_null.coords[:], [(1.0, 2.0)]) # Passing > 3 arguments to Point is erroneous with self.assertRaises(TypeError): Point(1.0, 2.0, 3.0, 4.0)
def test_point(self): # Test 2D points p = Point(1.0, 2.0) self.assertEqual(p.x, 1.0) self.assertEqual(p.y, 2.0) self.assertEqual(p.coords[:], [(1.0, 2.0)]) self.assertEqual(str(p), p.wkt) self.assertFalse(p.has_z) with self.assertRaises(DimensionError): p.z # Check 3D p = Point(1.0, 2.0, 3.0) self.assertEqual(p.coords[:], [(1.0, 2.0, 3.0)]) self.assertEqual(str(p), p.wkt) self.assertTrue(p.has_z) self.assertEqual(p.z, 3.0) # From coordinate sequence p = Point((3.0, 4.0)) self.assertEqual(p.coords[:], [(3.0, 4.0)]) # From another point q = Point(p) self.assertEqual(q.coords[:], [(3.0, 4.0)]) # Coordinate access self.assertEqual(p.x, 3.0) self.assertEqual(p.y, 4.0) self.assertEqual(tuple(p.coords), ((3.0, 4.0),)) self.assertEqual(p.coords[0], (3.0, 4.0)) with self.assertRaises(IndexError): # index out of range p.coords[1] # Bounds self.assertEqual(p.bounds, (3.0, 4.0, 3.0, 4.0)) # Geo interface self.assertEqual(p.__geo_interface__, {'type': 'Point', 'coordinates': (3.0, 4.0)}) # Modify coordinates p.coords = (2.0, 1.0) self.assertEqual(p.__geo_interface__, {'type': 'Point', 'coordinates': (2.0, 1.0)}) # Alternate method p.coords = ((0.0, 0.0),) self.assertEqual(p.__geo_interface__, {'type': 'Point', 'coordinates': (0.0, 0.0)}) # Adapt a coordinate list to a point coords = [3.0, 4.0] pa = asPoint(coords) self.assertEqual(pa.coords[0], (3.0, 4.0)) self.assertEqual(pa.distance(p), 5.0) # Move the coordinates and watch the distance change coords[0] = 1.0 self.assertEqual(pa.coords[0], (1.0, 4.0)) self.assertAlmostEqual(pa.distance(p), 4.123105625617661) # Test Non-operability of Null geometry p_null = Point() self.assertEqual(p_null.wkt, 'GEOMETRYCOLLECTION EMPTY') self.assertEqual(p_null.coords[:], []) self.assertEqual(p_null.area, 0.0) # Check that we can set coordinates of a null geometry p_null.coords = (1, 2) self.assertEqual(p_null.coords[:], [(1.0, 2.0)]) # Passing > 3 arguments to Point is erroneous with self.assertRaises(TypeError): Point(1.0, 2.0, 3.0, 4.0)
def test_point_mutability_deprecated(): p = Point(3.0, 4.0) with pytest.warns(ShapelyDeprecationWarning, match="Setting"): p.coords = (2.0, 1.0)