Changeset 976
- Timestamp:
- Mar 1, 2005, 12:16:51 PM (20 years ago)
- Location:
- inundation/ga/storm_surge/pyvolution
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
inundation/ga/storm_surge/pyvolution/general_mesh.py
r849 r976 48 48 """ 49 49 50 def __init__(self, coordinates, triangles ):50 def __init__(self, coordinates, triangles, origin = None): 51 51 """ 52 52 Build triangles from x,y coordinates (sequence of 2-tuples or 53 53 Mx2 Numeric array of floats) and triangles (sequence of 3-tuples 54 54 or Nx3 Numeric array of non-negative integers). 55 56 origin is a 3-tuple consisting of UTM zone, easting and northing. 57 If specified coordinates are assumed to be relative to this origin. 55 58 """ 56 59 … … 59 62 self.triangles = array(triangles).astype(Int) 60 63 self.coordinates = array(coordinates) 64 65 self.origin = origin 61 66 62 67 #Input checks -
inundation/ga/storm_surge/pyvolution/least_squares.py
r968 r976 59 59 def fit_to_mesh_file(mesh_file, point_file, mesh_output_file, 60 60 alpha=DEFAULT_ALPHA, verbose= False, 61 expand_search = False): 61 expand_search = False, 62 origin = None, 63 mesh_origin=None): 62 64 """ 63 65 Given a mesh file (tsh) and a point attribute file (xya), fit 64 66 point attributes to the mesh and write a mesh file with the 65 67 results. 68 69 If origin is not None it is assumed to be 70 a 5-tuple with geo referenced 71 UTM coordinates (zone, easting, northing, false_easting, false_northing) 72 73 mesh_origin is the same but refers to the input tsh file. 74 FIXME: When that format contains it own origin, this parameter can go. 66 75 """ 76 67 77 from load_mesh.loadASCII import mesh_file_to_mesh_dictionary, \ 68 78 load_points_file, export_triangulation_file, \ 69 79 concatinate_attributelist 80 70 81 # load in the .tsh file 71 82 mesh_dict = mesh_file_to_mesh_dictionary(mesh_file) … … 78 89 79 90 # load in the .xya file 91 #FIXME (Ole): Maybe data origin should be extracted here 80 92 try: 81 93 point_dict = load_points_file(point_file,delimiter = ',') … … 84 96 point_coordinates = point_dict['pointlist'] 85 97 title_list,point_attributes = concatinate_attributelist(point_dict['attributelist']) 86 if verbose:print "points file loaded" 98 if verbose: print "points file loaded" 99 100 101 87 102 if verbose:print "fitting to mesh" 88 103 f = fit_to_mesh(vertex_coordinates, … … 216 231 verbose = False, 217 232 expand_search = True, 218 max_points_per_cell = 30): 233 max_points_per_cell = 30, 234 mesh_origin = None, 235 data_origin = None): 219 236 220 237 … … 236 253 237 254 alpha: Smoothing parameter 255 256 data_origin and mesh_origin are 3-tuples consisting of 257 UTM zone, easting and northing. If specified 258 point coordinates and vertex coordinates are assumed to be 259 relative to their respective origins. 238 260 239 261 """ 240 262 241 263 #Convert input to Numeric arrays 264 triangles = array(triangles).astype(Int) 242 265 vertex_coordinates = array(vertex_coordinates).astype(Float) 243 triangles = array(triangles).astype(Int) 244 266 245 267 #Build underlying mesh 246 268 if verbose: print 'Building mesh' 247 self.mesh = General_mesh(vertex_coordinates, triangles) 269 self.mesh = General_mesh(vertex_coordinates, triangles, 270 origin = mesh_origin) 271 self.data_origin = data_origin 248 272 249 273 #Smoothing parameter … … 254 278 verbose = verbose, 255 279 expand_search = expand_search, 256 max_points_per_cell = max_points_per_cell) 257 258 259 def set_point_coordinates(self, point_coordinates): 280 max_points_per_cell =\ 281 max_points_per_cell, 282 data_origin = data_origin) 283 284 285 def set_point_coordinates(self, point_coordinates, 286 data_origin = None): 260 287 """ 261 288 A public interface to setting the point co-ordinates. 262 289 """ 263 self.build_coefficient_matrix_B(point_coordinates )290 self.build_coefficient_matrix_B(point_coordinates, data_origin) 264 291 265 292 def build_coefficient_matrix_B(self, point_coordinates=None, 266 293 verbose = False, expand_search = True, 267 max_points_per_cell=30): 294 max_points_per_cell=30, 295 data_origin = None): 268 296 """Build final coefficient matrix""" 269 297 … … 273 301 self.build_smoothing_matrix_D() 274 302 275 if point_coordinates: 303 if point_coordinates is not None: 304 276 305 if verbose: print 'Building interpolation matrix' 277 306 self.build_interpolation_matrix_A(point_coordinates, 278 307 verbose = verbose, 279 308 expand_search = expand_search, 280 max_points_per_cell = max_points_per_cell) 309 max_points_per_cell =\ 310 max_points_per_cell, 311 data_origin = data_origin) 281 312 282 313 if self.alpha <> 0: … … 290 321 def build_interpolation_matrix_A(self, point_coordinates, 291 322 verbose = False, expand_search = True, 292 max_points_per_cell=30): 323 max_points_per_cell=30, 324 data_origin = None): 293 325 """Build n x m interpolation matrix, where 294 326 n is the number of data points and … … 296 328 297 329 This algorithm uses a quad tree data structure for fast binning of data points 330 origin is a 3-tuple consisting of UTM zone, easting and northing. 331 If specified coordinates are assumed to be relative to this origin. 332 333 This one will override any data_origin that may be specified in 334 interpolation instance 335 298 336 """ 299 337 300 338 from quad import build_quadtree 301 302 #Convert input to Numeric arrays 339 340 if data_origin is None: 341 data_origin = self.data_origin #Use the one from 342 #interpolation instance 343 344 #Convert input to Numeric arrays just in case. 303 345 point_coordinates = array(point_coordinates).astype(Float) 346 347 348 #Shift data points to same origin as mesh (if specified) 349 mesh_origin = self.mesh.origin 350 if point_coordinates is not None: 351 if data_origin is not None: 352 if mesh_origin is not None: 353 354 #Transformation: 355 # 356 #Let x_0 be the reference point of the point coordinates 357 #and xi_0 the reference point of the mesh. 358 # 359 #A point coordinate (x + x_0) is then made relative 360 #to xi_0 by 361 # 362 # x_new = x + x_0 - xi_0 363 # 364 #and similarly for eta 365 366 x_offset = data_origin[1] - mesh_origin[1] 367 y_offset = data_origin[2] - mesh_origin[2] 368 else: #Shift back to a zero origin 369 x_offset = data_origin[1] 370 y_offset = data_origin[2] 371 372 point_coordinates[:,0] += x_offset 373 point_coordinates[:,1] += y_offset 374 else: 375 if mesh_origin is not None: 376 #Use mesh origin for data points 377 point_coordinates[:,0] -= mesh_origin[1] 378 point_coordinates[:,1] -= mesh_origin[2] 379 380 381 382 304 383 305 384 #Build n x m interpolation matrix … … 307 386 n = point_coordinates.shape[0] #Nbr of data points 308 387 388 if verbose: print 'Number of datapoints: %d' %n 389 if verbose: print 'Number of basis functions: %d' %m 309 390 310 391 #FIXME (Ole): We should use CSR here since mat-mat mult is now OK. … … 322 403 #For each data_coordinate point 323 404 324 #if verbose: print 'Doing %d of %d' %(i, n)405 if verbose and i%((n+10)/10)==0: print 'Doing %d of %d' %(i, n) 325 406 326 407 x = point_coordinates[i] … … 656 737 #Build n x m interpolation matrix 657 738 m = self.mesh.coordinates.shape[0] #Number of vertices 658 n = z.shape[1] #Number of data points739 n = z.shape[1] #Number of data points 659 740 660 741 f = zeros((m,n), Float) #Resulting columns -
inundation/ga/storm_surge/pyvolution/test_least_squares.py
r969 r976 878 878 879 879 880 def test_fit_and_interpolation_with_different_origins(self): 881 """Fit a surface to one set of points. Then interpolate that surface 882 using another set of points. 883 This test tests situtaion where points and mesh belong to a different 884 coordinate system as defined by origin. 885 """ 886 from mesh import Mesh 887 888 #Setup mesh used to represent fitted function 889 a = [0.0, 0.0] 890 b = [0.0, 2.0] 891 c = [2.0, 0.0] 892 d = [0.0, 4.0] 893 e = [2.0, 2.0] 894 f = [4.0, 0.0] 895 896 points = [a, b, c, d, e, f] 897 #bac, bce, ecf, dbe, daf, dae 898 triangles = [[1,0,2], [1,2,4], [4,2,5], [3,1,4]] 899 900 #Datapoints to fit from 901 data_points1 = [[ 0.66666667, 0.66666667], 902 [ 1.33333333, 1.33333333], 903 [ 2.66666667, 0.66666667], 904 [ 0.66666667, 2.66666667], 905 [ 0.0, 1.0], 906 [ 0.0, 3.0], 907 [ 1.0, 0.0], 908 [ 1.0, 1.0], 909 [ 1.0, 2.0], 910 [ 1.0, 3.0], 911 [ 2.0, 1.0], 912 [ 3.0, 0.0], 913 [ 3.0, 1.0]] 914 915 916 #First check that things are OK when using same origin 917 mesh_origin = (56, 290000, 618000) #zone, easting, northing 918 data_origin = (56, 290000, 618000) #zone, easting, northing 919 920 921 #Fit surface to mesh 922 interp = Interpolation(points, triangles, data_points1, 923 alpha=0.0, 924 data_origin = data_origin, 925 mesh_origin = mesh_origin) 926 927 z = linear_function(data_points1) #Example z-values 928 f = interp.fit(z) #Fitted values at vertices 929 930 931 #New datapoints where interpolated values are sought 932 data_points2 = [[ 0.0, 0.0], 933 [ 0.5, 0.5], 934 [ 0.7, 0.7], 935 [ 1.0, 0.5], 936 [ 2.0, 0.4], 937 [ 2.8, 1.2]] 938 939 940 #Build new A matrix based on new points 941 interp.build_interpolation_matrix_A(data_points2) 942 943 #Interpolate using fitted surface 944 z1 = interp.interpolate(f) 945 946 #Desired result 947 answer = linear_function(data_points2) 948 assert allclose(z1, answer) 949 950 951 ############################################## 952 953 #Then check situtaion where points are relative to a different 954 #origin (same zone, though, until we figure that out (FIXME)) 955 956 mesh_origin = (56, 290000, 618000) #zone, easting, northing 957 data_origin = (56, 10000, 10000) #zone, easting, northing 958 959 #Shift datapoints according to new origin 960 961 for k in range(len(data_points1)): 962 data_points1[k][0] += mesh_origin[1] - data_origin[1] 963 data_points1[k][1] += mesh_origin[2] - data_origin[2] 964 965 for k in range(len(data_points2)): 966 data_points2[k][0] += mesh_origin[1] - data_origin[1] 967 data_points2[k][1] += mesh_origin[2] - data_origin[2] 968 969 970 971 #Fit surface to mesh 972 interp = Interpolation(points, triangles, data_points1, 973 alpha=0.0, 974 data_origin = data_origin, 975 mesh_origin = mesh_origin) 976 977 f1 = interp.fit(z) #Fitted values at vertices (using same z as before) 978 979 assert allclose(f,f1), 'Fit should have been unaltered' 980 981 982 #Build new A matrix based on new points 983 interp.build_interpolation_matrix_A(data_points2) 984 985 #Interpolate using fitted surface 986 z1 = interp.interpolate(f) 987 assert allclose(z1, answer) 988 989 880 990 881 991 def test_fit_to_mesh_file(self):
Note: See TracChangeset
for help on using the changeset viewer.