def test_deg_km_accuracy(self): c = quakelib.Conversion(quakelib.LatLonDepth(0, 0)) # Check that 360 * length of 1 longitude degree is equal to the circumference of the equator # Confirm accuracy is within 1 meter one_deg_len = c.convert2xyz(quakelib.LatLonDepth(0, 1)).mag() self.assertAlmostEqual(one_deg_len * 360.0 / 1000, 40075.016, 2) # Check that 4 * length of 90 degree vertical arc is equal to the polar circumference # Confirm accuracy is within 1 meter ninety_deg_len = c.convert2xyz(quakelib.LatLonDepth(90, 0)).mag() self.assertAlmostEqual(ninety_deg_len * 4.0 / 1000, 40007.860, 2) # Check that inverse of conversion results in the same value for base_lat in range(-90, 91, 5): for base_lon in range(-180, 180, 5): base_pt = quakelib.LatLonDepth(base_lat, base_lon) conv = quakelib.Conversion(base_pt) test_lat = math.fmod(base_lat + random.uniform(-45, 45), 90) test_lon = math.fmod(base_lon + random.uniform(-45, 45), 180) test_pt = quakelib.LatLonDepth(test_lat, test_lon) new_xyz = conv.convert2xyz(test_pt) rev_pt = conv.convert2LatLon(new_xyz) # Ensure accuracy to within 1e-7 degrees (~1 cm) self.assertAlmostEqual(test_lat, rev_pt.lat(), 7) self.assertAlmostEqual(test_lon, rev_pt.lon(), 7)
def test_unit_conversion(self): c = quakelib.Conversion() self.assertEqual(c.deg2rad(c.rad2deg(1)), 1) self.assertEqual(c.year2sec(c.sec2year(1)), 1) self.assertEqual(c.m2km(c.km2m(1)), 1) self.assertEqual(c.sqkm2sqm(c.sqm2sqkm(1)), 1) self.assertEqual(c.pascal2bar(c.bar2pascal(1)), 1)
def test_unit_conversion(self): c = quakelib.Conversion() self.assertEqual(c.deg2rad(c.rad2deg(1)), 1) self.assertAlmostEqual( c.year2sec(c.sec2year(1)), 1 ) # changed to almostEqual since 32-bit floating point can't maintain enough precision self.assertEqual(c.m2km(c.km2m(1)), 1) self.assertEqual(c.sqkm2sqm(c.sqm2sqkm(1)), 1) self.assertEqual(c.pascal2bar(c.bar2pascal(1)), 1)
def __init__(self, min_lat, max_lat, min_lon, max_lon, base_lat, base_lon, padding, map_res, map_proj): # These are constrained this way so we can plot on 1024x780 for the # animations max_map_width = 690.0 max_map_height = 658.0 #max_map_width = 309.0 #max_map_height = 309.0 # A conversion instance for doing the lat-lon to x-y conversions self.convert = quakelib.Conversion(base_lat, base_lon) # Calculate the lat-lon range based on the min-max and the padding lon_range = max_lon - min_lon lat_range = max_lat - min_lat max_range = max((lon_range, lat_range)) self.min_lon = min_lon - lon_range * padding self.min_lat = min_lat - lat_range * padding self.max_lon = max_lon + lon_range * padding self.max_lat = max_lat + lat_range * padding # We need a map instance to calculate the aspect ratio map = Basemap(llcrnrlon=self.min_lon, llcrnrlat=self.min_lat, urcrnrlon=self.max_lon, urcrnrlat=self.max_lat, lat_0=(self.max_lat + self.min_lat) / 2.0, lon_0=(self.max_lon + self.min_lon) / 2.0, resolution=map_res, projection=map_proj, suppress_ticks=True) # Using the aspect ratio (h/w) to find the actual map width and height # in pixels if map.aspect > max_map_height / max_map_width: map_height = max_map_height map_width = max_map_height / map.aspect else: map_width = max_map_width map_height = max_map_width * map.aspect #print map.aspect, map_width, map_height, max_map_height/max_map_width self.lons_1d = np.linspace(self.min_lon, self.max_lon, int(map_width)) self.lats_1d = np.linspace(self.min_lat, self.max_lat, int(map_height)) _lons_1d = quakelib.FloatList() _lats_1d = quakelib.FloatList() for lon in self.lons_1d: _lons_1d.append(lon) for lat in self.lats_1d: _lats_1d.append(lat) self.field_1d = self.convert.convertArray2xyz(_lats_1d, _lons_1d)
def calculate_model_extents(self): #----------------------------------------------------------------------- # get info from the original file #----------------------------------------------------------------------- block_info_table = self.file.root.block_info_table #----------------------------------------------------------------------- # calculate the model extents #----------------------------------------------------------------------- print 'Calculating model extents' start_time = time.time() sys_max_z = -sys.float_info.max sys_min_z = sys.float_info.max sys_max_x = -sys.float_info.max sys_min_x = sys.float_info.max sys_max_y = -sys.float_info.max sys_min_y = sys.float_info.max for block in block_info_table: min_x = min((block['m_x_pt1'], block['m_x_pt2'], block['m_x_pt3'], block['m_x_pt4'])) max_x = max((block['m_x_pt1'], block['m_x_pt2'], block['m_x_pt3'], block['m_x_pt4'])) min_y = min((block['m_y_pt1'], block['m_y_pt2'], block['m_y_pt3'], block['m_y_pt4'])) max_y = max((block['m_y_pt1'], block['m_y_pt2'], block['m_y_pt3'], block['m_y_pt4'])) min_z = min((block['m_z_pt1'], block['m_z_pt2'], block['m_z_pt3'], block['m_z_pt4'])) max_z = max((block['m_z_pt1'], block['m_z_pt2'], block['m_z_pt3'], block['m_z_pt4'])) if min_x < sys_min_x: sys_min_x = min_x if max_x > sys_max_x: sys_max_x = max_x if min_y < sys_min_y: sys_min_y = min_y if max_y > sys_max_y: sys_max_y = max_y if min_z < sys_min_z: sys_min_z = min_z if max_z > sys_max_z: sys_max_z = max_z base_lat_lon_table = self.file.root.base_lat_lon conv = quakelib.Conversion(base_lat_lon_table[0], base_lat_lon_table[1]) ne_corner = conv.convert2LatLon( quakelib.Vec3(sys_max_x, sys_max_y, 0.0)) sw_corner = conv.convert2LatLon( quakelib.Vec3(sys_min_x, sys_min_y, 0.0)) self.file.close() print 'Done! {} seconds'.format(time.time() - start_time) print 'Creating new tables' table_start_time = time.time() self.file = tables.open_file(self.file_path, 'a') desc = { 'min_x': tables.Float64Col(dflt=0.0), 'max_x': tables.Float64Col(dflt=0.0), 'min_y': tables.Float64Col(dflt=0.0), 'max_y': tables.Float64Col(dflt=0.0), 'min_z': tables.Float64Col(dflt=0.0), 'max_z': tables.Float64Col(dflt=0.0), 'min_lat': tables.Float64Col(dflt=0.0), 'max_lat': tables.Float64Col(dflt=0.0), 'min_lon': tables.Float64Col(dflt=0.0), 'max_lon': tables.Float64Col(dflt=0.0) } model_extents = self.file.create_table('/', 'model_extents', desc, 'Model Extents') model_extents.row.append() model_extents.flush() model_extents.cols.min_x[0] = sys_min_x model_extents.cols.max_x[0] = sys_max_x model_extents.cols.min_y[0] = sys_min_y model_extents.cols.max_y[0] = sys_max_y model_extents.cols.min_z[0] = sys_min_z model_extents.cols.max_z[0] = sys_max_z model_extents.cols.min_lat[0] = sw_corner.lat() model_extents.cols.max_lat[0] = ne_corner.lat() model_extents.cols.min_lon[0] = sw_corner.lon() model_extents.cols.max_lon[0] = ne_corner.lon() print 'Done! {} seconds'.format(time.time() - table_start_time) #----------------------------------------------------------------------- # close the file and reopen it with the new table #----------------------------------------------------------------------- self.file.close() self.file = tables.open_file(self.file_path) print 'Total time {} seconds'.format(time.time() - start_time)