1+ import matplotlib .path
12import numpy
23
34# CSEP Imports
5+ import numpy as np
6+ import pyproj
7+
48from csep .utils .time_utils import datetime_to_utc_epoch , epoch_time_to_utc_datetime
59from csep .utils import plots
610
@@ -142,6 +146,7 @@ def plot(self, show=False, plot_args=None):
142146 ax = plots .plot_number_test (self , show = show , plot_args = plot_args )
143147 return ax
144148
149+
145150class CatalogPseudolikelihoodTestResult (EvaluationResult ):
146151
147152 def __init__ (self , ** kwargs ):
@@ -158,6 +163,7 @@ def plot(self, show=False, plot_args=None):
158163 ax = plots .plot_likelihood_test (self , show = show , plot_args = plot_args )
159164 return ax
160165
166+
161167class CatalogMagnitudeTestResult (EvaluationResult ):
162168
163169 def __init__ (self , ** kwargs ):
@@ -172,6 +178,7 @@ def plot(self, show=False, plot_args=None):
172178 ax = plots .plot_magnitude_test (self , show = show , plot_args = plot_args )
173179 return ax
174180
181+
175182class CatalogSpatialTestResult (EvaluationResult ):
176183
177184 def __init__ (self , ** kwargs ):
@@ -190,6 +197,7 @@ def plot(self, show=False, plot_args=None):
190197 ax = plots .plot_spatial_test (self , show = show , plot_args = plot_args )
191198 return ax
192199
200+
193201class CalibrationTestResult (EvaluationResult ):
194202
195203 def __init__ (self , ** kwargs ):
@@ -206,6 +214,7 @@ def plot(self, show=False, axes=None, plot_args=None):
206214 ax = plots .plot_calibration_test (self , show = show , axes = axes , plot_args = plot_args )
207215 return ax
208216
217+
209218class EvaluationConfiguration :
210219 """
211220 Store information about the evaluation which will be used to store metadata about the evaluation.
@@ -282,4 +291,74 @@ def update_version(self, name, version, fnames):
282291 e ['fnames' ] = fnames
283292 found = True
284293 if not found :
285- self .evaluations .append ({'name' : name , 'version' : version , 'fnames' : fnames })
294+ self .evaluations .append ({'name' : name , 'version' : version , 'fnames' : fnames })
295+
296+
297+ class Polygon :
298+ """
299+ Represents polygons defined through a collection of vertices.
300+
301+ This polygon is assumed to be 2d, but could contain an arbitrary number of vertices. The path is treated as not being
302+ closed.
303+ """
304+ def __init__ (self , points ):
305+ # instance members
306+ self .points = points
307+ self .origin = self .points [0 ]
308+
309+ # https://matplotlib.org/3.1.1/api/path_api.html
310+ self .path = matplotlib .path .Path (self .points )
311+
312+ def __str__ (self ):
313+ return str (self .origin )
314+
315+ def contains (self , points ):
316+ """ Returns a bool array which is True if the path contains the corresponding point.
317+
318+ Args:
319+ points: 2d numpy array
320+
321+ """
322+ nd_points = np .array (points )
323+ if nd_points .ndim == 1 :
324+ nd_points = nd_points .reshape (1 ,- 1 )
325+ return self .path .contains_points (nd_points )
326+
327+ def centroid (self ):
328+ """ return the centroid of the polygon."""
329+ c0 , c1 = 0 , 0
330+ k = len (self .points )
331+ for p in self .points :
332+ c0 = c0 + p [0 ]
333+ c1 = c1 + p [1 ]
334+ return c0 / k , c1 / k
335+
336+ def get_xcoords (self ):
337+ return np .array (self .points )[:,0 ]
338+
339+ def get_ycoords (self ):
340+ return np .array (self .points )[:,1 ]
341+
342+ @classmethod
343+ def from_great_circle_radius (cls , centroid , radius , num_points = 10 ):
344+ """
345+ Generates a polygon object from a given radius and centroid location.
346+
347+ Args:
348+ centroid: (lon, lat)
349+ radius: should be in (meters)
350+ num_points: more points is higher resolution polygon
351+
352+ Returns:
353+ polygon
354+ """
355+ geod = pyproj .Geod (ellps = 'WGS84' )
356+ azim = np .linspace (0 , 360 , num_points )
357+ # create vectors with same length as azim for computations
358+ center_lons = np .ones (num_points ) * centroid [0 ]
359+ center_lats = np .ones (num_points ) * centroid [1 ]
360+ radius = np .ones (num_points ) * radius
361+ # get new lons and lats
362+ endlon , endlat , backaz = geod .fwd (center_lons , center_lats , azim , radius )
363+ # class method
364+ return cls (np .column_stack ([endlon , endlat ]))
0 commit comments