def test_ucvm_select_right_models_for_query(self): """ Tests that given a desired set of properties, UCVM picks the correct models to query (for example if we are querying a depth model by elevation, we need to get the DEM). """ self.assertEqual( UCVM.get_models_for_query("1d.depth", ["velocity"]), { 0: {0: "1d"} } ) self.assertEqual( UCVM.get_models_for_query("1d", ["velocity"]), { 0: {0: "1d"} } ) self.assertEqual( UCVM.get_models_for_query("1d.elevation", ["velocity"]), { 0: {0: "usgs-noaa", 1: "1d"} } ) self.assertEqual( UCVM.get_models_for_query("usgs-noaa.1d.vs30-calc.elevation", ["velocity", "elevation", "vs30"]), { 0: {0: "usgs-noaa", 1: "1d", 2: "vs30-calc"} } )
def test_cvms4_basic_depth(self): """ Tests UCVM's basic query capabilities with CVM-S4 using depth. This tests that a known point within the model returns the correct material properties and also that a known point outside of the model returns the SCEC 1D background material properties. Returns: None """ self._test_start("test for UCVM query by depth") sd_test = [SeismicData(Point(-118, 34, 0))] self.assertTrue(UCVM.query(sd_test, "cvms4", ["velocity"])) assert_velocity_properties( self, sd_test[0], VelocityProperties(696.491, 213, 1974.976, None, None, "cvms4", "cvms4", "cvms4", None, None)) sd_test = [SeismicData(Point(-130, 40, 0))] self.assertTrue(UCVM.query(sd_test, "cvms4", ["velocity"])) assert_velocity_properties( self, sd_test[0], VelocityProperties(5000, 2886.751, 2654.5, None, None, "cvms4", "cvms4", "cvms4", None, None)) self._test_end()
def test_cvmh_query_gtl(self): """ Tests the CVM-H query capabilities both with the GTL and without. Returns: None """ self._test_start("test for CVM-H query using GTL") sd_test = [SeismicData(Point(-118, 34, 0))] self.assertTrue(UCVM.query(sd_test, "cvmh1510[gtl]")) assert_velocity_properties( self, sd_test[0], VelocityProperties(824.177, 195, 1084.062, None, None, "cvmh1510", "cvmh1510", "cvmh1510", None, None)) sd_test = [SeismicData(Point(-118, 34, 0))] self.assertTrue(UCVM.query(sd_test, "cvmh1510")) # No 1D means None for everything. assert_velocity_properties( self, sd_test[0], VelocityProperties(2484.3879, 969.2999, 2088.316, None, None, "cvmh1510", "cvmh1510", "cvmh1510", None, None)) self._test_end()
def test_cvms4_basic_depth(self): """ Tests UCVM's basic query capabilities with CVM-S4 using depth. This tests that a known point within the model returns the correct material properties and also that a known point outside of the model returns the SCEC 1D background material properties. Returns: None """ self._test_start("test for UCVM query by depth") sd_test = [SeismicData(Point(-118, 34, 0))] self.assertTrue(UCVM.query(sd_test, "cvms4", ["velocity"])) assert_velocity_properties( self, sd_test[0], VelocityProperties(696.491, 213, 1974.976, None, None, "cvms4", "cvms4", "cvms4", None, None) ) sd_test = [SeismicData(Point(-130, 40, 0))] self.assertTrue(UCVM.query(sd_test, "cvms4", ["velocity"])) assert_velocity_properties( self, sd_test[0], VelocityProperties(5000, 2886.751, 2654.5, None, None, "cvms4", "cvms4", "cvms4", None, None) ) self._test_end()
def test_cvms4_basic_elevation(self): """ Tests UCVM's query capabilities with CVM-S4 but using elevation. The tests are the same as with test_cvms4_basic_depth. Returns: None """ self._test_start("test for UCVM query by elevation") sd_test = [SeismicData(Point(-118, 34, 0, UCVM_ELEVATION))] self.assertTrue( UCVM.query(sd_test, "cvms4.usgs-noaa.elevation", ["velocity", "elevation"])) assert_velocity_properties( self, sd_test[0], VelocityProperties(2677.1596, 725.390, 2287.7236, None, None, "cvms4", "cvms4", "cvms4", None, None)) sd_test = [SeismicData(Point(-130, 40, 0, UCVM_ELEVATION))] self.assertTrue( UCVM.query(sd_test, "cvms4.usgs-noaa.elevation", ["velocity", "elevation"])) # This is above sea level so it should be None for everything. assert_velocity_properties( self, sd_test[0], VelocityProperties(None, None, None, None, None, None, None, None, None, None)) self._test_end()
def test_cvms4_basic_elevation(self): """ Tests UCVM's query capabilities with CVM-S4 but using elevation. The tests are the same as with test_cvms4_basic_depth. Returns: None """ self._test_start("test for UCVM query by elevation") sd_test = [SeismicData(Point(-118, 34, 0, UCVM_ELEVATION))] self.assertTrue(UCVM.query(sd_test, "cvms4.usgs-noaa.elevation", ["velocity", "elevation"])) assert_velocity_properties( self, sd_test[0], VelocityProperties(2677.1596, 725.390, 2287.7236, None, None, "cvms4", "cvms4", "cvms4", None, None) ) sd_test = [SeismicData(Point(-130, 40, 0, UCVM_ELEVATION))] self.assertTrue(UCVM.query(sd_test, "cvms4.usgs-noaa.elevation", ["velocity", "elevation"])) # This is above sea level so it should be None for everything. assert_velocity_properties( self, sd_test[0], VelocityProperties(None, None, None, None, None, None, None, None, None, None) ) self._test_end()
def test_cvmh_query_1d_background(self): """ Tests the CVM-H query capabilities both with the 1D background model and without. Returns: None """ self._test_start("test for CVM-H query with 1D model") sd_test = [SeismicData(Point(-122.0322, 37.3230, 0))] self.assertTrue(UCVM.query(sd_test, "cvmh1510[1d]")) assert_velocity_properties( self, sd_test[0], VelocityProperties(5000.0, 2886.7514, 2654.5, None, None, "cvmh1510", "cvmh1510", "cvmh1510", None, None)) sd_test = [SeismicData(Point(-122.0322, 37.3230, 0))] self.assertTrue(UCVM.query(sd_test, "cvmh1510")) # No 1D means None for everything. assert_velocity_properties( self, sd_test[0], VelocityProperties(None, None, None, None, None, None, None, None, None, None)) self._test_end()
def vpvs_ratio_test(_: unittest.TestCase): granularity = 0.001 depth_spacing = 10000 counter = 0 sd_array = UCVM.create_max_seismicdata_array() for x_val in \ custom_range(float(target.corners["bl"]["e"]), float(target.corners["tr"]["e"]) + granularity, granularity): for y_val in \ custom_range(float(target.corners["bl"]["n"]), float(target.corners["tr"]["n"]) + granularity, granularity): for z_val in custom_range(0, target.max_depth + depth_spacing, depth_spacing): sd_array[counter].original_point = Point(x_val, y_val, z_val) sd_array[counter].converted_point = Point(x_val, y_val, z_val) if counter == len(sd_array) - 1: UCVM.query(sd_array, name, ["velocity"]) _test_vpvs_ratio(sd_array) counter = 0 else: counter += 1 _test_vpvs_ratio(sd_array[0:counter])
def test_bayarea_basic_elevation(self): """ Tests the Bay Area query capabilities using elevation. This uses the model's DEM, not the UCVM DEM. Returns: None """ self._test_start("test for Bay Area query by elevation") sd_test = [SeismicData(Point(-122.0322, 37.3230, 0, UCVM_ELEVATION))] self.assertTrue(UCVM.query(sd_test, "bayarea.elevation")) assert_velocity_properties( self, sd_test[0], VelocityProperties(1700.0, 390.0, 1990.0, 44.0, 22.0, "bayarea", "bayarea", "bayarea", "bayarea", "bayarea") ) sd_test = [SeismicData(Point(-130, 40, 0, UCVM_ELEVATION))] self.assertTrue(UCVM.query(sd_test, "bayarea.elevation", ["velocity", "elevation"])) # This is above sea level so it should be None for everything. assert_velocity_properties( self, sd_test[0], VelocityProperties(None, None, None, None, None, None, None, None, None, None) ) self._test_end()
def test_bayarea_basic_elevation(self): """ Tests the Bay Area query capabilities using elevation. This uses the model's DEM, not the UCVM DEM. Returns: None """ self._test_start("test for Bay Area query by elevation") sd_test = [SeismicData(Point(-122.0322, 37.3230, 0, UCVM_ELEVATION))] self.assertTrue(UCVM.query(sd_test, "bayarea.elevation")) assert_velocity_properties( self, sd_test[0], VelocityProperties(1700.0, 390.0, 1990.0, 44.0, 22.0, "bayarea", "bayarea", "bayarea", "bayarea", "bayarea")) sd_test = [SeismicData(Point(-130, 40, 0, UCVM_ELEVATION))] self.assertTrue( UCVM.query(sd_test, "bayarea.elevation", ["velocity", "elevation"])) # This is above sea level so it should be None for everything. assert_velocity_properties( self, sd_test[0], VelocityProperties(None, None, None, None, None, None, None, None, None, None)) self._test_end()
def test_cvmh_query_gtl(self): """ Tests the CVM-H query capabilities both with the GTL and without. Returns: None """ self._test_start("test for CVM-H query using GTL") sd_test = [SeismicData(Point(-118, 34, 0))] self.assertTrue(UCVM.query(sd_test, "cvmh1510[gtl]")) assert_velocity_properties( self, sd_test[0], VelocityProperties(824.177, 195, 1084.062, None, None, "cvmh1510", "cvmh1510", "cvmh1510", None, None) ) sd_test = [SeismicData(Point(-118, 34, 0))] self.assertTrue(UCVM.query(sd_test, "cvmh1510")) # No 1D means None for everything. assert_velocity_properties( self, sd_test[0], VelocityProperties(2484.3879, 969.2999, 2088.316, None, None, "cvmh1510", "cvmh1510", "cvmh1510", None, None) ) self._test_end()
def test_cvmh_query_1d_background(self): """ Tests the CVM-H query capabilities both with the 1D background model and without. Returns: None """ self._test_start("test for CVM-H query with 1D model") sd_test = [SeismicData(Point(-122.0322, 37.3230, 0))] self.assertTrue(UCVM.query(sd_test, "cvmh1510[1d]")) assert_velocity_properties( self, sd_test[0], VelocityProperties(5000.0, 2886.7514, 2654.5, None, None, "cvmh1510", "cvmh1510", "cvmh1510", None, None) ) sd_test = [SeismicData(Point(-122.0322, 37.3230, 0))] self.assertTrue(UCVM.query(sd_test, "cvmh1510")) # No 1D means None for everything. assert_velocity_properties( self, sd_test[0], VelocityProperties(None, None, None, None, None, None, None, None, None, None) ) self._test_end()
def vpvs_ratio_test(_: unittest.TestCase): granularity = 0.001 depth_spacing = 10000 counter = 0 sd_array = UCVM.create_max_seismicdata_array() for x_val in \ custom_range(float(target.corners["bl"]["e"]), float(target.corners["tr"]["e"]) + granularity, granularity): for y_val in \ custom_range(float(target.corners["bl"]["n"]), float(target.corners["tr"]["n"]) + granularity, granularity): for z_val in custom_range(0, target.max_depth + depth_spacing, depth_spacing): sd_array[counter].original_point = Point( x_val, y_val, z_val) sd_array[counter].converted_point = Point( x_val, y_val, z_val) if counter == len(sd_array) - 1: UCVM.query(sd_array, name, ["velocity"]) _test_vpvs_ratio(sd_array) counter = 0 else: counter += 1 _test_vpvs_ratio(sd_array[0:counter])
def test_ucvm_get_model_type(self): """ Tests that given a model, it correctly identifies the model type. Because we cannot guarantee that any operators will be installed on the user's system, we don't test for this. """ self.assertEqual(UCVM.get_model_type("1d"), "velocity") self.assertEqual(UCVM.get_model_type("usgs-noaa"), "elevation") self.assertEqual(UCVM.get_model_type("wills-wald-2006"), "vs30")
def extract(self): proj = pyproj.Proj(proj='utm', zone=11, ellps='WGS84') x1, y1 = proj(self.start_point.x_value, self.start_point.y_value) x2, y2 = proj(self.end_point.x_value, self.end_point.y_value) num_prof = int( math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) / self.cross_section_properties.width_spacing ) for j in range(int(self.start_point.z_value), int(self.end_point.z_value) + (1 if self.end_point.depth_elev == UCVM_DEPTH else -1), int(self.cross_section_properties.height_spacing)): for i in range(0, num_prof + 1): x = x1 + i * (x2 - x1) / float(num_prof) y = y1 + i * (y2 - y1) / float(num_prof) lon, lat = proj(x, y, inverse=True) self.sd_array.append( SeismicData(Point(lon, lat, j, int(self.start_point.depth_elev))) ) UCVM.query(self.sd_array, self.cvms, ["elevation", "velocity"]) num_x = num_prof + 1 num_y = int(math.ceil(self.end_point.z_value - self.start_point.z_value) / self.cross_section_properties.height_spacing) self.extracted_data = np.arange(num_x * num_y * 6, dtype=float).reshape(num_y, num_x * 6) for y in range(int(num_y)): for x in range(int(num_x)): x_val = x * 6 if self.sd_array[y * num_x + x].velocity_properties is not None: vp_val = self.sd_array[y * num_x + x].velocity_properties.vp vs_val = self.sd_array[y * num_x + x].velocity_properties.vs density_val = self.sd_array[y * num_x + x].velocity_properties.density qp_val = self.sd_array[y * num_x + x].velocity_properties.qp qs_val = self.sd_array[y * num_x + x].velocity_properties.qs else: vp_val = None vs_val = None density_val = None qp_val = None qs_val = None self.extracted_data[y][x_val] = vp_val if vp_val is not None else -1 self.extracted_data[y][x_val + 1] = vs_val if vs_val is not None else -1 self.extracted_data[y][x_val + 2] = density_val if density_val is not None else -1 self.extracted_data[y][x_val + 3] = qp_val if qp_val is not None else -1 self.extracted_data[y][x_val + 4] = qs_val if qs_val is not None else -1 if self.sd_array[y * num_x + x].elevation_properties is not None: self.extracted_data[y][x_val + 5] = \ self.sd_array[y * num_x + x].elevation_properties.elevation else: self.extracted_data[y][x_val + 5] = -1
def test_cvmh_query_by_elevation(self): """ Tests the CVM-H query capabilities using the model's DEM. Returns: None """ self._test_start("test for CVM-H query using elevation") sd_test = [SeismicData(Point(-118, 34, 0, UCVM_ELEVATION))] self.assertTrue(UCVM.query(sd_test, "cvmh1510[gt].elevation")) assert_velocity_properties( self, sd_test[0], VelocityProperties(2495.1269, 978.5577, 2091.678, None, None, "cvmh1510", "cvmh1510", "cvmh1510", None, None) ) sd_test = [SeismicData(Point(-118, 34, 0))] self.assertTrue(UCVM.query(sd_test, "cvmh1510[gtl]")) # Query by depth. assert_velocity_properties( self, sd_test[0], VelocityProperties(824.177, 195, 1084.062, None, None, "cvmh1510", "cvmh1510", "cvmh1510", None, None) ) # Checks to see that the material properties returned at 266.690277 elevation at -118, 34 equal the # material properties returned at 0m depth (i.e. that CVM-H is using its own DEM correctly). sd_test = [SeismicData(Point(-118, 34, 266.690277099609, UCVM_ELEVATION))] self.assertTrue(UCVM.query(sd_test, "cvmh1510[gtl].elevation")) assert_velocity_properties( self, sd_test[0], VelocityProperties(824.177, 195, 1084.062, None, None, "cvmh1510", "cvmh1510", "cvmh1510", None, None) ) # Check to see that "air" returns nothing (there's a bug in vx that will return 1000 for density in air). sd_test = [SeismicData(Point(-118, 34, 1000, UCVM_ELEVATION))] self.assertTrue(UCVM.query(sd_test, "cvmh1510.elevation")) assert_velocity_properties( self, sd_test[0], VelocityProperties(None, None, None, None, None, None, None, None, None, None) ) self._test_end()
def test_ucvm_returns_nothing_for_elevation_in_air(self): """ Tests that querying a point in air with a model that is queryable by depth returns N/A for material properties across the board. """ s = SeismicData(Point(-118, 34, 1000, UCVM_ELEVATION)) UCVM.query([s], "1d[SCEC].elevation") self.assertIsNone(s.velocity_properties.vp) self.assertIsNone(s.velocity_properties.vs) self.assertIsNone(s.velocity_properties.density)
def test_ucvm_print_version(self): """ Tests that the replacements are done correctly when printing UCVM's version info. """ f = StringIO() with redirect_stdout(f): UCVM.print_version() out = f.getvalue() self.assertIn("17.3.0", out) self.assertIn("2017", out) self.assertIn("LICENSE", out)
def test_onedimensional_bbp_depth(self) -> None: """ Tests the 1D model for basic depth query. Returns: Nothing """ self._test_start("1D BBP format test") UCVM.query(self.data["depth"], "1d[CyberShake_BBP_LA_Basin]", ["velocity"]) assert_velocity_properties( self, self.data["depth"][0], VelocityProperties( 1700, 450, 2000, 45.0, 22.5, "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)" )) assert_velocity_properties( self, self.data["depth"][1], VelocityProperties( 1850, 900, 2100, 90.0, 45, "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)" )) assert_velocity_properties( self, self.data["depth"][2], VelocityProperties( 1900, 950, 2100, 95.0, 47.5, "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)" )) assert_velocity_properties( self, self.data["depth"][3], VelocityProperties( 7800, 4500, 3200, 450.0, 225.0, "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)" )) self._test_end()
def test_ucvm_get_model_instance(self): """ Tests that UCVM can retrieve a model instance correctly. Also tests to ensure that providing a bad model to this raises the correct error. """ self.assertEqual(UCVM.get_model_instance("1d").get_metadata()["id"], "1d") stdout = sys.stdout sys.stdout = None with self.assertRaises(UCVMError): UCVM.get_model_instance("bob") sys.stdout = stdout
def test_onedimensional_bbp_depth(self) -> None: """ Tests the 1D model for basic depth query. Returns: Nothing """ self._test_start("1D BBP format test") UCVM.query(self.data["depth"], "1d[CyberShake_BBP_LA_Basin]", ["velocity"]) assert_velocity_properties( self, self.data["depth"][0], VelocityProperties(1700, 450, 2000, 45.0, 22.5, "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)") ) assert_velocity_properties( self, self.data["depth"][1], VelocityProperties(1850, 900, 2100, 90.0, 45, "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)") ) assert_velocity_properties( self, self.data["depth"][2], VelocityProperties(1900, 950, 2100, 95.0, 47.5, "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)") ) assert_velocity_properties( self, self.data["depth"][3], VelocityProperties(7800, 4500, 3200, 450.0, 225.0, "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)", "cybershake la basin linearly interpolated with 1km moho (interpolated)") ) self._test_end()
def test_ucvm_load_models(self): """ Test that UCVM can load all the installed models without error. """ installed_models = UCVM.get_list_of_installed_models() for key in installed_models: for model in installed_models[key]: m_py = UCVM.get_model_instance(model["id"]) self.assertEqual(m_py.get_metadata()["name"], model["name"]) self.assertEqual(UCVM.instantiated_models[model["id"]].get_metadata()["name"], model["name"])
def test_ucvm_raises_error_on_negative_depth(self): """ Tests that you cannot pass a negative depth to UCVM. We test this two ways. First, you cannot pass a negative depth to a newly-constructed SeismicData object set to be depth. Second, if we modify the z_value after, we should get an error on query complaining about negative depth. """ with self.assertRaises(ValueError): SeismicData(Point(-118, 34, -500)) s = SeismicData(Point(-118, 34, 0)) s.original_point.z_value = -500 with self.assertRaises(ValueError): UCVM.query([s], "1d[SCEC]")
def test_cvmh_query_by_elevation(self): """ Tests the CVM-H query capabilities using the model's DEM. Returns: None """ self._test_start("test for CVM-H query using elevation") sd_test = [SeismicData(Point(-118, 34, 0, UCVM_ELEVATION))] self.assertTrue(UCVM.query(sd_test, "cvmh1510[gt].elevation")) assert_velocity_properties( self, sd_test[0], VelocityProperties(2495.1269, 978.5577, 2091.678, None, None, "cvmh1510", "cvmh1510", "cvmh1510", None, None)) sd_test = [SeismicData(Point(-118, 34, 0))] self.assertTrue(UCVM.query(sd_test, "cvmh1510[gtl]")) # Query by depth. assert_velocity_properties( self, sd_test[0], VelocityProperties(824.177, 195, 1084.062, None, None, "cvmh1510", "cvmh1510", "cvmh1510", None, None)) # Checks to see that the material properties returned at 266.690277 elevation at -118, 34 equal the # material properties returned at 0m depth (i.e. that CVM-H is using its own DEM correctly). sd_test = [ SeismicData(Point(-118, 34, 266.690277099609, UCVM_ELEVATION)) ] self.assertTrue(UCVM.query(sd_test, "cvmh1510[gtl].elevation")) assert_velocity_properties( self, sd_test[0], VelocityProperties(824.177, 195, 1084.062, None, None, "cvmh1510", "cvmh1510", "cvmh1510", None, None)) # Check to see that "air" returns nothing (there's a bug in vx that will return 1000 for density in air). sd_test = [SeismicData(Point(-118, 34, 1000, UCVM_ELEVATION))] self.assertTrue(UCVM.query(sd_test, "cvmh1510.elevation")) assert_velocity_properties( self, sd_test[0], VelocityProperties(None, None, None, None, None, None, None, None, None, None)) self._test_end()
def _add_corner_and_depth_information(): target.corners = { "bl": { "e": None, "n": None }, "tr": { "e": None, "n": None } } target.max_depth = 0 for _, model_dict in UCVM.parse_model_string(name).items(): for _, model in model_dict.items(): model_cpy = model.split(";")[0] if UCVM.get_model_type(model_cpy) == "velocity": coverage = UCVM.get_model_instance( model_cpy).get_metadata()["coverage"] if "depth" in coverage and float( coverage["depth"]) > target.max_depth: target.max_depth = float(coverage["depth"]) elif "depth" not in coverage and 50000 < target.max_depth: target.max_depth = 50000 if coverage["bottom_left"]["e"] is not None and \ (target.corners["bl"]["e"] is None or float(coverage["bottom_left"]["e"]) < target.corners["bl"]["e"]): target.corners["bl"]["e"] = float( coverage["bottom_left"]["e"]) if coverage["bottom_left"]["n"] is not None and \ (target.corners["bl"]["n"] is None or float(coverage["bottom_left"]["n"]) < target.corners["bl"]["n"]): target.corners["bl"]["n"] = float( coverage["bottom_left"]["n"]) if coverage["top_right"]["e"] is not None and \ (target.corners["tr"]["e"] is None or float(coverage["top_right"]["e"]) > target.corners["tr"]["e"]): target.corners["tr"]["e"] = float( coverage["top_right"]["e"]) if coverage["top_right"]["n"] is not None and \ (target.corners["tr"]["n"] is None or float(coverage["top_right"]["n"]) > target.corners["tr"]["n"]): target.corners["tr"]["n"] = float( coverage["top_right"]["n"]) break if target.max_depth == 0: target.max_depth = 50000
def test_cvms426_add_1d_model(self): """ Tests that we can add a 1D background model to CVM-S4.26 using tiling. This is a generic verification just to ensure that tiling works on the user's computer as we expect them to use it with this model. Returns: None """ self._test_start("CVM-S4.26 tiling with 1D model works") sd_test = [ SeismicData(Point(-118, 34, 0)), SeismicData(Point(-125, 40, 0)) ] self.assertTrue(UCVM.query(sd_test, "cvms426;1d[SCEC]", ["velocity"])) self.assertAlmostEqual(sd_test[0].velocity_properties.vp, 1860.9648, 4) self.assertAlmostEqual(sd_test[0].velocity_properties.vs, 909.3662, 4) self.assertAlmostEqual(sd_test[0].velocity_properties.density, 2050.1179, 4) self.assertEqual(sd_test[0].velocity_properties.vp_source, "cvms426") self.assertAlmostEqual(sd_test[1].velocity_properties.vp, 5000, 4) self.assertAlmostEqual(sd_test[1].velocity_properties.vs, 2886.7513, 4) self.assertAlmostEqual(sd_test[1].velocity_properties.density, 2654.5000, 4) self.assertEqual(sd_test[1].velocity_properties.vp_source, "scec 1d (interpolated)") self._test_end()
def test_cca06_add_1d_model(self): """ Tests that we can add a 1D background model to CCA06 using tiling. This is a generic verification just to ensure that tiling works on the user's computer as we expect them to use it with this model. Returns: None """ self._test_start("CCA06 tiling with 1D model works") sd_test = [ SeismicData(Point(-120.65, 35.64, 0)), SeismicData(Point(-125, 40, 0)) ] self.assertTrue(UCVM.query(sd_test, "cca06;1d[SCEC]", ["velocity"])) self.assertAlmostEqual(sd_test[0].velocity_properties.vp, 5076.7466, 4) self.assertAlmostEqual(sd_test[0].velocity_properties.vs, 2838.2566, 4) self.assertAlmostEqual(sd_test[0].velocity_properties.density, 2493.9988, 4) self.assertEqual(sd_test[0].velocity_properties.vp_source, "cca06") self.assertAlmostEqual(sd_test[1].velocity_properties.vp, 5000, 4) self.assertAlmostEqual(sd_test[1].velocity_properties.vs, 2886.7513, 4) self.assertAlmostEqual(sd_test[1].velocity_properties.density, 2654.5000, 4) self.assertEqual(sd_test[1].velocity_properties.vp_source, "scec 1d (interpolated)") self._test_end()
def test_etopo1_basic(self): """ Tests that the USGS/NOAA map delivers the expected ETOPO1 data at certain latitudes and longitudes around the world. Returns: None """ self._test_start("test for correct ETOPO1 data") sd_test = [ SeismicData(Point(-122.65, 49.21667, 0)), SeismicData(Point(-114.0833, 51.05, 0)) ] self.assertTrue(UCVM.query(sd_test, "usgs-noaa", ["elevation"])) self.assertAlmostEqual(sd_test[0].elevation_properties.elevation, 19.994, 3) self.assertEqual(sd_test[0].elevation_properties.elevation_source, "usgs-noaa") self.assertAlmostEqual(sd_test[1].elevation_properties.elevation, 1051.015, 3) self.assertEqual(sd_test[1].elevation_properties.elevation_source, "usgs-noaa") self._test_end()
def test_ucvm_query_with_test_velocity_model(self): """ Test that UCVM can query using the test velocity model and return correct material properties. """ UCVM.instantiated_models["testvelocitymodel"] = test_model.TestVelocityModel() data_1 = [ SeismicData(Point(-118, 34, 0)) ] UCVM.query(data_1, "testvelocitymodel", ["velocity"], { 0: {0: "testvelocitymodel"} }) self.assertEqual(data_1[0].velocity_properties.vp, 34 + (-118)) self.assertEqual(data_1[0].velocity_properties.vs, 34 - (-118)) self.assertEqual(data_1[0].velocity_properties.density, (34 + (-118)) / 2) self.assertEqual(data_1[0].velocity_properties.qp, (34 - (-118)) / 4) self.assertEqual(data_1[0].velocity_properties.qs, (34 + (-118)) / 4)
def test_ucvm_same_points_depth_or_elevation(self): """ Tests that querying by elevation using the UCVM built-in DEM works. Model-specific DEMs are compared within their respective model test codes. """ # The elevation at -118, 34 is 288.997m. We use that for the elevation test. s = SeismicData(Point(-118, 34, 0)) UCVM.query([s], "1d[SCEC]") velocity_properties_by_depth = s.velocity_properties s = SeismicData(Point(-118, 34, 288.99689, UCVM_ELEVATION)) UCVM.query([s], "1d[SCEC]") velocity_properties_by_elevation = s.velocity_properties self.assertEqual(velocity_properties_by_depth.vs, velocity_properties_by_elevation.vs) self.assertEqual(velocity_properties_by_depth.vp, velocity_properties_by_elevation.vp) self.assertEqual(velocity_properties_by_depth.density, velocity_properties_by_elevation.density)
def test_fails_incorrect_lat_lon_bounds(self): """ Tests that the USGS/NOAA map does not return heights for latitudes and longitudes that fall outside of the possible ranges. Returns: None """ self._test_start("test for out-of-bounds lat, lon") sd_test = [ SeismicData(Point(200, 34, 0)), SeismicData(Point(-118, 340, 0)) ] self.assertTrue(UCVM.query(sd_test, "usgs-noaa", ["elevation"])) self.assertEqual(sd_test[0].elevation_properties.elevation, None) self.assertEqual(sd_test[0].elevation_properties.elevation_source, None) self.assertEqual(sd_test[1].elevation_properties.elevation, None) self.assertEqual(sd_test[1].elevation_properties.elevation_source, None) self._test_end()
def test_nationalmap_basic(self): """ Tests that the USGS/NOAA map delivers the expected National Map data at certain latitudes and longitudes around the world. Returns: None """ self._test_start("test for correct National Map data") sd_test = [ SeismicData(Point(-118, 34, 0)), SeismicData(Point(-119, 35, 0)) ] self.assertTrue(UCVM.query(sd_test, "usgs-noaa", ["elevation"])) self.assertAlmostEqual(sd_test[0].elevation_properties.elevation, 287.997, 3) self.assertEqual(sd_test[0].elevation_properties.elevation_source, "usgs-noaa") self.assertAlmostEqual(sd_test[1].elevation_properties.elevation, 466.993, 3) self.assertEqual(sd_test[1].elevation_properties.elevation_source, "usgs-noaa") self._test_end()
def mesh_extract_single(information: dict, slices: str=None, interval: str=None, **kwargs) -> bool: """ Given a dictionary containing the relevant parameters for the extraction, extract the material properties for a single process. Args: information (dict): The dictionary containing the metadata defining the extraction. Returns: True, when successful. It will raise an error if the extraction is not successful. """ internal_mesh = InternalMesh(information) if slices is not None: internal_mesh.do_slices(slices) elif interval is not None: internal_mesh.do_interval(interval) sd_array = UCVM.create_max_seismicdata_array(min(internal_mesh.total_size, 250000), 1) print("\nThere are a total of " + humanize.intcomma(internal_mesh.total_size) + " grid points " "to extract.\nWe can extract " + humanize.intcomma(len(sd_array)) + " points at once.\n" "\nStarting extraction...\n") information["minimums"]["vp"] = float(information["minimums"]["vp"]) information["minimums"]["vs"] = float(information["minimums"]["vs"]) if internal_mesh.format == "awp": _mesh_extract_single_awp(sd_array, information, internal_mesh, slices, interval) elif internal_mesh.format == "rwg": _mesh_extract_single_rwg(sd_array, information, internal_mesh) print("\nExtraction done.") return True
def extract(self): num_points = int(math.ceil((self.profile_properties.depth - self.profile_point.z_value) / self.profile_properties.spacing)) + 1 self.sd_array = UCVM.create_max_seismicdata_array(num_points) for i in range(0, num_points): self.sd_array[i].original_point.x_value = self.profile_point.x_value self.sd_array[i].original_point.y_value = self.profile_point.y_value if self.profile_point.depth_elev == UCVM_DEPTH: self.sd_array[i].original_point.z_value = \ self.profile_point.z_value + (i * self.profile_properties.spacing) else: self.sd_array[i].original_point.depth_elev = UCVM_ELEVATION self.sd_array[i].original_point.z_value = \ self.profile_point.z_value - (i * self.profile_properties.spacing) UCVM.query(self.sd_array, self.cvms)
def _query(self, data: List[SeismicData], **kwargs) -> bool: """ This is the method that all models override. It handles querying the velocity model and filling in the SeismicData structures. Args: points (:obj:`list` of :obj:`SeismicData`): List of SeismicData objects containing the points. These are to be populated with :obj:`Vs30Properties`: Returns: True on success, false if there is an error. """ for datum in data: if datum.model_string is not None: query_points = [ SeismicData( Point(datum.original_point.x_value, datum.original_point.y_value, z, UCVM_DEPTH, datum.original_point.metadata, datum.original_point.projection)) for z in range(0, 30) ] for point in query_points: point.set_elevation_data(datum.elevation_properties) UCVM.query(query_points, datum.model_string, ["velocity"]) if query_points[0].velocity_properties.vs is None or \ query_points[0].velocity_properties.vs == 0: datum.vs30_properties = Vs30Properties(None, None) continue avg_slowness = 0 for point in query_points: avg_slowness += 1.0 / float(point.velocity_properties.vs) datum.vs30_properties = Vs30Properties( 1.0 / (avg_slowness / len(query_points)), self._public_metadata["id"]) else: datum.vs30_properties = Vs30Properties(None, None) return True
def test_cvms426_random_points(self): """ Tests the CVM-S4.26 velocity model at 10 random points selected from the model. These points were picked with a random number generator. Returns: None """ self._test_start("CVM-S4.26 points versus text model test") test_data = \ """ 90 754 10 -118.737022 32.944866 5571.414 3057.374 2792.542 724 627 15 -116.004835 34.763130 6383.228 3702.753 2863.826 449 125 19 -114.943019 32.340362 6094.292 3597.746 2817.387 924 1011 21 -116.896018 36.574456 5872.374 3248.397 2874.105 664 1416 22 -119.570398 36.833491 6357.490 3675.896 2882.698 385 1027 39 -118.869259 34.753449 6344.310 3578.079 2856.254 100 1496 43 -121.846471 35.058333 7403.315 4269.781 3034.174 689 567 48 -115.882460 34.466751 6493.230 3719.698 2909.571 361 850 49 -118.208090 34.163152 6771.910 3571.393 2953.548 444 723 53 -117.391091 34.083565 6937.791 4099.394 2912.123 736 901 56 -117.105324 35.607358 6727.089 3885.899 2943.158 949 1062 56 -117.023118 36.809121 6649.673 3770.664 2931.769 396 1061 69 -118.975273 34.888717 7781.172 4487.968 3095.297 558 1513 84 -120.364910 36.732035 7862.731 4538.450 3107.515 961 534 87 -114.765700 35.290399 7873.649 4544.644 3108.936 722 73 90 -113.767296 33.102653 7892.802 4558.516 3110.357 142 309 96 -116.744822 31.837443 7945.724 4599.341 3113.200 847 4 99 -113.043306 33.310262 7914.255 4569.352 3114.621 670 240 99 -114.620776 33.430007 7919.039 4574.102 3114.621 177 1240 100 -120.485602 34.623764 7869.447 4529.999 3115.094 """ points = [] for point in test_data.split("\n"): if point.strip() == "": continue point = point.split() points.append( (float(point[3]), float(point[4]), (int(point[2]) - 1) * 500, float(point[5]), float(point[6]), float(point[7])) ) sd_test = [SeismicData(Point(p[0], p[1], p[2])) for p in points] self.assertTrue(UCVM.query(sd_test, "cvms426", ["velocity"])) epsilon = 0.00001 for i in range(len(sd_test)): self.assertGreater(sd_test[i].velocity_properties.vp / points[i][3], 1 - epsilon) self.assertLess(sd_test[i].velocity_properties.vp / points[i][3], 1 + epsilon) self.assertGreater(sd_test[i].velocity_properties.vs / points[i][4], 1 - epsilon) self.assertLess(sd_test[i].velocity_properties.vs / points[i][4], 1 + epsilon) self.assertGreater(sd_test[i].velocity_properties.density / points[i][5], 1 - epsilon) self.assertLess(sd_test[i].velocity_properties.density / points[i][5], 1 + epsilon) self._test_end()
def _add_corner_and_depth_information(): target.corners = { "bl": { "e": None, "n": None }, "tr": { "e": None, "n": None } } target.max_depth = 0 for _, model_dict in UCVM.parse_model_string(name).items(): for _, model in model_dict.items(): model_cpy = model.split(";")[0] if UCVM.get_model_type(model_cpy) == "velocity": coverage = UCVM.get_model_instance(model_cpy).get_metadata()["coverage"] if "depth" in coverage and float(coverage["depth"]) > target.max_depth: target.max_depth = float(coverage["depth"]) elif "depth" not in coverage and 50000 < target.max_depth: target.max_depth = 50000 if coverage["bottom_left"]["e"] is not None and \ (target.corners["bl"]["e"] is None or float(coverage["bottom_left"]["e"]) < target.corners["bl"]["e"]): target.corners["bl"]["e"] = float(coverage["bottom_left"]["e"]) if coverage["bottom_left"]["n"] is not None and \ (target.corners["bl"]["n"] is None or float(coverage["bottom_left"]["n"]) < target.corners["bl"]["n"]): target.corners["bl"]["n"] = float(coverage["bottom_left"]["n"]) if coverage["top_right"]["e"] is not None and \ (target.corners["tr"]["e"] is None or float(coverage["top_right"]["e"]) > target.corners["tr"]["e"]): target.corners["tr"]["e"] = float(coverage["top_right"]["e"]) if coverage["top_right"]["n"] is not None and \ (target.corners["tr"]["n"] is None or float(coverage["top_right"]["n"]) > target.corners["tr"]["n"]): target.corners["tr"]["n"] = float(coverage["top_right"]["n"]) break if target.max_depth == 0: target.max_depth = 50000
def test_ucvm_raises_error_on_bad_model_combinations(self): """ Tests that UCVM errors out gracefully when a bad model name is called. """ data_1 = [ SeismicData(Point(-118, 34, 0)) ] stdout = sys.stdout sys.stdout = None with self.assertRaises(UCVMError): UCVM.query(data_1, "nonexistantvelocitymodel") with self.assertRaises(UCVMError): UCVM.query(data_1, None) with self.assertRaises(UCVMError): UCVM.query(data_1, "") with self.assertRaises(UCVMError): UCVM.query(data_1, "34[]34") with self.assertRaises(UCVMError): UCVM.query(data_1, "cvms426 vs30-calc") sys.stdout = stdout
def make_suite() -> unittest.TestSuite: suite = unittest.TestSuite() models = UCVM.get_list_of_installed_models() for key in models: for model in models[key]: path = os.path.join(UCVM.get_model_instance(model["id"]).model_location, "test_" + model["id"] + ".py") if os.path.exists(path): new_class = __import__("ucvm.models." + model["id"] + ".test_" + model["id"], fromlist=model["class"] + "Test") suite.addTest( unittest.makeSuite(getattr(new_class, model["class"] + "Test"), "test_") ) if key == "velocity": add_acceptance_test_methods(UCVMModelAcceptanceTest, model["id"]) suite.addTest(unittest.makeSuite(UCVMModelAcceptanceTest, "test_")) return suite
def test_ucvm_get_list_of_installed_models(self): """ Tests that we can retrieve the list of installed models. This helps verify that there are no permission problems reading the model XML file for example. """ models = UCVM.get_list_of_installed_models() self.assertTrue("velocity" in models) self.assertTrue(len(models["velocity"]) >= 1) self.assertTrue("elevation" in models) self.assertTrue(len(models["elevation"]) >= 1) self.assertTrue("vs30" in models) self.assertTrue(len(models["vs30"]) >= 1)
def make_suite() -> unittest.TestSuite: suite = unittest.TestSuite() models = UCVM.get_list_of_installed_models() for key in models: for model in models[key]: path = os.path.join( UCVM.get_model_instance(model["id"]).model_location, "test_" + model["id"] + ".py") if os.path.exists(path): new_class = __import__("ucvm.models." + model["id"] + ".test_" + model["id"], fromlist=model["class"] + "Test") suite.addTest( unittest.makeSuite( getattr(new_class, model["class"] + "Test"), "test_")) if key == "velocity": add_acceptance_test_methods(UCVMModelAcceptanceTest, model["id"]) suite.addTest(unittest.makeSuite(UCVMModelAcceptanceTest, "test_")) return suite
def test_falls_to_etopo_in_ocean(self): """ Tests that in the ocean - where the USGS map has no data - we fall back to the ETOPO1 map which has the bathymetry data in it. Returns: None """ self._test_start("test for ocean using ETOPO1 data") sd_test = [SeismicData(Point(-118.2, 33.5, 0))] self.assertTrue(UCVM.query(sd_test, "usgs-noaa", ["elevation"])) self.assertLess(sd_test[0].elevation_properties.elevation, 0) self.assertEqual(sd_test[0].elevation_properties.elevation_source, "usgs-noaa") self._test_end()
def _run_and_verify_commands(self, command, test_cases): for _, case_data in test_cases.items(): if case_data["requiresmodel"] != "": if not UCVM.is_model_installed(case_data["requiresmodel"]): print("\tModel " + case_data["requiresmodel"] + " is not installed. Skipping test.", file=sys.stderr) continue print("\tRunning test for " + case_data["name"] + ".", file=sys.stderr) p = Popen(["python3.5", "./ucvm/bin/" + command] + case_data["parameters"].split(), stdout=PIPE, stdin=PIPE, stderr=PIPE) p.stdin.write(str(case_data["input"]).encode("UTF-8")) streams = p.communicate() str_out = streams[0].decode("utf-8") str_err = streams[1].decode("utf-8") self.assertTrue(str(case_data["stdout"]) == str(str_out)) if case_data["stderr"] != "": self.assertIn(case_data["stderr"], str_err) else: self.assertEqual(case_data["stderr"], str_err)
def test_fails_incorrect_lat_lon_bounds(self): """ Tests that the USGS/NOAA map does not return heights for latitudes and longitudes that fall outside of the possible ranges. Returns: None """ self._test_start("test for out-of-bounds lat, lon") sd_test = [SeismicData(Point(200, 34, 0)), SeismicData(Point(-118, 340, 0))] self.assertTrue(UCVM.query(sd_test, "usgs-noaa", ["elevation"])) self.assertEqual(sd_test[0].elevation_properties.elevation, None) self.assertEqual(sd_test[0].elevation_properties.elevation_source, None) self.assertEqual(sd_test[1].elevation_properties.elevation, None) self.assertEqual(sd_test[1].elevation_properties.elevation_source, None) self._test_end()
def etree_extract_mpi(information: dict, rows: str=None, interval: str=None) -> bool: from mpi4py import MPI comm = MPI.COMM_WORLD rank = comm.Get_rank() size = comm.Get_size() stats = _calculate_etree_stats( information, int(information["properties"]["columns"]), int(information["properties"]["rows"]) ) start_rc = [1, 1] end_rc = [int(information["properties"]["rows"]), int(information["properties"]["columns"])] if rows is not None: if "-" in rows: parts = rows.split("-") start_rc = [int(parts[0]), 1] end_rc = [int(parts[1]), int(information["properties"]["columns"])] else: start_rc = [int(rows), 1] end_rc = [int(rows), int(information["properties"]["columns"])] elif interval is not None: if "-" in interval: parts = interval.split("-") parts1 = parts[0].split(",") start_rc = [int(parts1[0]), int(parts1[1])] parts2 = parts[1].split(",") end_rc = [int(parts2[0]), int(parts2[1])] else: interval = interval.split(",") start_rc = [int(interval[0]), int(interval[1])] end_rc = [int(interval[0]), int(interval[1])] if rank == 0: schema = "float Vp; float Vs; float density;".encode("ASCII") path = (os.path.join(information["out_dir"], information["etree_name"] + ".e")).encode("ASCII") if sys.byteorder == "little" and sys.platform != "darwin": if start_rc[0] == 1 and start_rc[1] == 1: ep = UCVMCCommon.c_etree_open(path, 578) else: ep = UCVMCCommon.c_etree_open(path, 2) else: if start_rc[0] == 1 and start_rc[1] == 1: ep = UCVMCCommon.c_etree_open(path, 1538) else: ep = UCVMCCommon.c_etree_open(path, 2) UCVMCCommon.c_etree_registerschema(ep, schema) rcs_to_extract = [] current_rc = start_rc while not (current_rc[0] == end_rc[0] and current_rc[1] == end_rc[1] + 1): if current_rc[1] > int(information["properties"]["columns"]): current_rc[0] += 1 current_rc[1] = 1 rcs_to_extract.append((current_rc[0], current_rc[1])) current_rc[1] += 1 total_extracted = 0 is_done = [False for _ in range(size - 1)] while True: data = comm.recv(source=MPI.ANY_SOURCE) if data["code"] == "start": if len(rcs_to_extract) > 0: comm.send(rcs_to_extract.pop(0), dest=data["source"]) else: comm.send("done", dest=data["source"]) is_done[data["source"] - 1] = True elif data["code"] == "write": print("[Node %d] Writing data from node %d to file." % (rank, data["source"]), flush=True) _etree_writer(ep, data["data"][0], data["data"][1], data["data"][2]) total_extracted += data["data"][2] print("[Node %d] Data written successfully!" % rank, flush=True) elif data["code"] == "new": if len(rcs_to_extract) > 0: comm.send(rcs_to_extract.pop(0), dest=data["source"]) else: comm.send("done", dest=data["source"]) is_done[data["source"] - 1] = True print("[Node %d] Writing data from node %d to file." % (rank, data["source"]), flush=True) _etree_writer(ep, data["data"][0], data["data"][1], data["data"][2]) total_extracted += data["data"][2] print("[Node %d] Data written successfully!" % rank, flush=True) if False not in is_done: break metadata_string = ("Title:%s Author:%s Date:%s %u %s %f %f %f %f %f %f %u %u %u" % ( str(information["author"]["title"]).replace(" ", "_"), str(information["author"]["person"]).replace(" ", "_"), str(information["author"]["date"]).replace(" ", "_"), 3, "Vp(float);Vs(float);density(float)", float(information["corners"]["bl"]["y"]), float(information["corners"]["bl"]["x"]), float(information["dimensions"]["x"]), float(information["dimensions"]["y"]), 0, float(information["dimensions"]["z"]), int(stats["max_ticks"]["width"]), int(stats["max_ticks"]["height"]), int(stats["max_ticks"]["depth"]) )).encode("ASCII") print("[Node %d] Total number of octants extracted: %d." % (rank, total_extracted), flush=True) UCVMCCommon.c_etree_setappmeta(ep, metadata_string) UCVMCCommon.c_etree_close(ep) else: done = False print("[Node %d] Maximum points per section is %d." % (rank, stats["max_points"]), flush=True) sd_array = UCVM.create_max_seismicdata_array(stats["max_points"], 1) count = 0 comm.send({"source": rank, "data": "", "code": "start"}, dest=0) while not done: row_col = comm.recv(source=0) if row_col == "done": break print("[Node %d] Received instruction to extract column (%d, %d)." % (rank, row_col[0], row_col[1]), flush=True) data = _extract_mpi(rank, sd_array, information, stats, row_col[1] - 1, row_col[0] - 1) count += data[2] print("[Node %d] Finished extracting column (%d, %d)" % (rank, row_col[0], row_col[1])) comm.send({"source": rank, "data": data, "code": "new"}, dest=0) print("[Node %d] Finished extracting %d octants." % (rank, count), flush=True) return True
def run_acceptance_test(test_case: unittest.TestCase, model_id: str, props_to_test: list = None) -> bool: """ Runs the acceptance test for the given model id. :param test_case: The unittest case. :param model_id: The model ID to run the test for. :return: True if successful, false or exception if not. """ npy_test_file = os.path.join(UCVM_MODELS_DIRECTORY, model_id, "test_" + model_id + ".npy") ucvm_model_file = os.path.join(UCVM_MODELS_DIRECTORY, model_id, "ucvm_model.xml") spacing = 0.05 depth = 5000 bottom_corner = {"e": 0, "n": 0} if not os.path.exists(npy_test_file) or not os.path.exists( ucvm_model_file): return False with open(ucvm_model_file, "r") as fd: ucvm_model = xmltodict.parse(fd.read()) bottom_corner["e"] = \ float(ucvm_model["root"]["information"]["coverage"]["bottom-left"]["e"]) bottom_corner["n"] = \ float(ucvm_model["root"]["information"]["coverage"]["bottom-left"]["n"]) model_type = ucvm_model["root"]["information"]["type"] arr = np.load(npy_test_file) nums = {"x": len(arr), "y": len(arr[0]), "z": len(arr[0][0])} sd_array = [ SeismicData() for _ in range(nums["x"] * nums["y"] * nums["z"]) ] counter = 0 for z in range(nums["z"]): for y in range(nums["y"]): for x in range(nums["x"]): sd_array[counter].original_point = Point( bottom_corner["e"] + spacing * x, bottom_corner["n"] + spacing * y, 0 + depth * z) counter += 1 UCVM.query(sd_array, model_id, [model_type]) if props_to_test is None or len(props_to_test) == 0: props_to_test = ["vp", "vs", "density"] counter = 0 epsilon = 0.006 for z in range(nums["z"]): for y in range(nums["y"]): for x in range(nums["x"]): if arr[x][y][z][0] <= 0 and sd_array[counter].velocity_properties.vp is None or \ arr[x][y][z][1] <= 0 and sd_array[counter].velocity_properties.vs is None or \ arr[x][y][z][2] <= 0 and sd_array[counter].velocity_properties.density is None: counter += 1 continue # This is to account for a floating point rounding issue in the CVM-S4.26 test which has the new UCVM # thinking that the corner is in bounds and the old version thinking it's out of bounds. This version # thinks the point is 1534.999999999 where as the old version thinks it's exactly 1535. This also fixes # a difference whereby the old CVM-S5 extended below 50000km but the new one does not. if (sd_array[counter].original_point.x_value == -116 and sd_array[counter].original_point.y_value == 30.45 and model_id == "cvms426") or \ (sd_array[counter].original_point.z_value == 50000 and model_id == "cvms426"): counter += 1 continue if "vp" in props_to_test: test_case.assertGreater( sd_array[counter].velocity_properties.vp / arr[x][y][z][0], 1 - epsilon) test_case.assertLess( sd_array[counter].velocity_properties.vp / arr[x][y][z][0], 1 + epsilon) if "vs" in props_to_test: test_case.assertGreater( sd_array[counter].velocity_properties.vs / arr[x][y][z][1], 1 - epsilon) test_case.assertLess( sd_array[counter].velocity_properties.vs / arr[x][y][z][1], 1 + epsilon) if "density" in props_to_test: test_case.assertGreater( sd_array[counter].velocity_properties.density / arr[x][y][z][2], 1 - epsilon) test_case.assertLess( sd_array[counter].velocity_properties.density / arr[x][y][z][2], 1 + epsilon) counter += 1 return True
def _mesh_extract_mpi_awp(sd_array: List[SeismicData], information: dict, im: InternalMesh, start_end: tuple) -> bool: """ Extract an AWP mesh using MPI. Internal method. Args: Returns: True, if successful. Raises an error if not successful. """ from mpi4py import MPI comm = MPI.COMM_WORLD rank = comm.Get_rank() file_out = os.path.join(information["out_dir"], information["mesh_name"]) + ".awp" im_iter = AWPInternalMeshIterator(im, start_end[0], start_end[1], len(sd_array), sd_array) progress = start_end[0] sqrt2 = math.sqrt(2) fh = MPI.File.Open(MPI.COMM_WORLD, file_out, amode=MPI.MODE_WRONLY | MPI.MODE_CREATE) while progress < im_iter.end_point: count = next(im_iter) UCVM.query(sd_array[0:count], information["cvm_list"], ["velocity"]) fl_array = [] for s in sd_array[0:count]: if s.velocity_properties is not None and s.velocity_properties.vs is not None and \ s.velocity_properties.vs < information["minimums"]["vs"]: s.set_velocity_data( VelocityProperties( information["minimums"]["vp"], information["minimums"]["vs"], s.velocity_properties.density, s.velocity_properties.qp, s.velocity_properties.qs, s.velocity_properties.vp_source, s.velocity_properties.vs_source, s.velocity_properties.density_source, s.velocity_properties.qp_source, s.velocity_properties.qs_source ) ) fl_array.append(s.velocity_properties.vp) fl_array.append(s.velocity_properties.vs) fl_array.append(s.velocity_properties.density) if s.velocity_properties is None or s.velocity_properties.vp is None or \ s.velocity_properties.vs is None or s.velocity_properties.density is None: print("[Node %d] Attention! %.3f, %.3f, %.3f has no material properties." % ( rank, s.original_point.x_value, s.original_point.y_value, s.original_point.z_value ), flush=True) if s.velocity_properties is not None and s.velocity_properties.vp is not None and \ s.velocity_properties.vs is not None and s.velocity_properties.vp / s.velocity_properties.vs < sqrt2: print("[Node %d] Warning: %.3f, %.3f, %.3f has a Vp/Vs ratio of less than sqrt(2)." % ( rank, s.original_point.x_value, s.original_point.y_value, s.original_point.z_value ), flush=True) s = struct.pack('f' * len(fl_array), *fl_array) fh.Write_at(progress * 12, s) fh.Sync() progress += count print("[Node %d] %-4.2f" % (rank, ((progress - start_end[0]) / (start_end[1] - start_end[0])) * 100.0) + "% complete. Wrote " + humanize.intcomma(count) + " more grid points.", flush=True) comm.Barrier() fh.Close() if rank == 0: print("\n[Node " + str(rank) + "] Extraction job fully complete.") # print("\n[Node " + str(rank) + "] Expected file size is " + im.get_grid_file_size()["display"] + ". " + # "Actual size is " + humanize.naturalsize(os.path.getsize(os.path.join(file_out)), gnu=False) + ".", # flush=True) # if im.get_grid_file_size()["real"] == os.path.getsize(file_out): # print("Generated file size matches the expected file size.") # else: # print("ERROR! File sizes DO NOT MATCH!") return True
def _mesh_extract_single_rwg(sd_array: List[SeismicData], information: dict, im: InternalMesh) -> bool: """ Takes an InternalMesh object, the mesh information file, and the iterator, and generates, using one core only, the mesh in RWG format. Args: information (dict): The mesh information dictionary (from the XML config file). im (InternalMesh): The internal representation of the RWG mesh. Returns: Nothing """ file_out_vp = information["mesh_name"] + ".rwgvp" file_out_vs = information["mesh_name"] + ".rwgvs" file_out_dn = information["mesh_name"] + ".rwgdn" im_iter = RWGInternalMeshIterator(im, 0, im.total_size, len(sd_array), sd_array) progress = 0 with open(os.path.join(information["out_dir"], file_out_vp), "wb") as fd_vp, \ open(os.path.join(information["out_dir"], file_out_vs), "wb") as fd_vs, \ open(os.path.join(information["out_dir"], file_out_dn), "wb") as fd_dn: while progress < im_iter.end_point: count = next(im_iter) progress += count UCVM.query(sd_array[0:count], information["cvm_list"], ["velocity"], None) vp_array = [] vs_array = [] dn_array = [] for s in sd_array[0:count]: if s.velocity_properties is not None and s.velocity_properties.vs is not None and \ s.velocity_properties.vs < information["minimums"]["vs"]: s.set_velocity_data( VelocityProperties( information["minimums"]["vp"], information["minimums"]["vs"], s.velocity_properties.density, s.velocity_properties.qp, s.velocity_properties.qs, s.velocity_properties.vp_source, s.velocity_properties.vs_source, s.velocity_properties.density_source, s.velocity_properties.qp_source, s.velocity_properties.qs_source ) ) vp_array.append(s.velocity_properties.vp / 1000) vs_array.append(s.velocity_properties.vs / 1000) dn_array.append(s.velocity_properties.density / 1000) if s.velocity_properties.vp is None: print("Attention! %.3f, %.3f, %.3f has no material properties." % ( s.original_point.x_value, s.original_point.y_value, s.original_point.z_value )) if s.velocity_properties is not None and s.velocity_properties.vp is not None and \ s.velocity_properties.vs is not None and s.velocity_properties.vp / s.velocity_properties.vs < 1.45: print("Warning: %.3f, %.3f, %.3f has a Vp/Vs ratio of less than 1.45." % ( s.original_point.x_value, s.original_point.y_value, s.original_point.z_value )) s = struct.pack('f' * len(vp_array), *vp_array) fd_vp.write(s) s = struct.pack('f' * len(vs_array), *vs_array) fd_vs.write(s) s = struct.pack('f' * len(dn_array), *dn_array) fd_dn.write(s) print("%-4.2f" % ((progress / im_iter.end_point) * 100.0) + "% complete. Wrote " + humanize.intcomma(count) + " more grid points.") print("\nExpected file size is " + im.get_grid_file_size()["display"] + ". " + "Actual size is " + humanize.naturalsize(os.path.getsize( os.path.join(information["out_dir"], file_out_vp)), gnu=False) + ".") if im.get_grid_file_size()["real"] == \ os.path.getsize(os.path.join(information["out_dir"], file_out_vp)) and \ im.get_grid_file_size()["real"] == \ os.path.getsize(os.path.join(information["out_dir"], file_out_vs)) and \ im.get_grid_file_size()["real"] == \ os.path.getsize(os.path.join(information["out_dir"], file_out_dn)): print("Generated file size matches the expected file size.") else: print("ERROR! File sizes DO NOT MATCH!") return True
def _mesh_extract_single_awp(sd_array: List[SeismicData], information: dict, im: InternalMesh, slices: str=None, interval: str=None) -> bool: """ Takes an InternalMesh object, the mesh information file, and the iterator, and generates, using one core only, the mesh in AWP-ODC format. Args: information (dict): The mesh information dictionary (from the XML config file). im (InternalMesh): The internal representation of the AWP mesh. im_iter (AWPInternalMeshIterator): The internal mesh iterator that was generated from im. Returns: Nothing """ file_out = information["mesh_name"] + ".awp" start_point = 0 end_point = im.total_size if slices is not None: if "-" in slices: parts = slices.split("-") start_point = (int(parts[0]) - 1) * im.slice_size end_point = (int(parts[1])) * im.slice_size else: start_point = (int(slices) - 1) * im.slice_size end_point = int(slices) * im.slice_size elif interval is not None: if "-" in interval: parts = interval.split("-") start_point = (int(parts[0]) / 100) * im.full_size end_point = (int(parts[1]) / 100) * im.full_size else: raise ValueError("Interval must be a range (e.g. 0-10 which means generate the first 10% of the mesh).") im_iter = AWPInternalMeshIterator(im, start_point, end_point, len(sd_array), sd_array) progress = start_point progress = 0 sqrt2 = math.sqrt(2) with open(os.path.join(information["out_dir"], file_out), "ab+") as fd: while progress < im.total_size: count = next(im_iter) UCVM.query(sd_array[0:count], information["cvm_list"], ["velocity"]) fl_array = [] for s in sd_array[0:count]: if s.velocity_properties is not None and s.velocity_properties.vs is not None and \ s.velocity_properties.vs < information["minimums"]["vs"]: s.set_velocity_data( VelocityProperties( information["minimums"]["vp"], information["minimums"]["vs"], s.velocity_properties.density, s.velocity_properties.qp, s.velocity_properties.qs, s.velocity_properties.vp_source, s.velocity_properties.vs_source, s.velocity_properties.density_source, s.velocity_properties.qp_source, s.velocity_properties.qs_source ) ) fl_array.append(s.velocity_properties.vp) fl_array.append(s.velocity_properties.vs) fl_array.append(s.velocity_properties.density) if s.velocity_properties is None or s.velocity_properties.vp is None or \ s.velocity_properties.vs is None or s.velocity_properties.density is None: print("Attention! %.3f, %.3f, %.3f has no material properties." % ( s.original_point.x_value, s.original_point.y_value, s.original_point.z_value )) if s.velocity_properties is not None and s.velocity_properties.vp is not None and \ s.velocity_properties.vs is not None and s.velocity_properties.vp / s.velocity_properties.vs < sqrt2: print("Warning: %.3f, %.3f, %.3f has a Vp/Vs ratio of less than sqrt(2)." % ( s.original_point.x_value, s.original_point.y_value, s.original_point.z_value )) s = struct.pack('f' * len(fl_array), *fl_array) fd.seek(progress * 12) fd.write(s) progress += count print("%-4.2f" % ((progress / (im_iter.end_point - start_point)) * 100.0) + "% complete. Wrote " + humanize.intcomma(count) + " more grid points.") print("\nExpected file size is " + im.get_grid_file_size()["display"] + ". " + "Actual size is " + humanize.naturalsize(os.path.getsize( os.path.join(information["out_dir"], file_out)), gnu=False) + ".") if im.get_grid_file_size()["real"] == \ os.path.getsize(os.path.join(information["out_dir"], file_out)): print("Generated file size matches the expected file size.") else: print("ERROR! File sizes DO NOT MATCH!") return True
def _query(self, data: List[SeismicData], **kwargs) -> bool: """ This is the method that all models override. It handles retrieving the queried models' properties and adjusting the SeismicData structures as need be. Args: points (:obj:`list` of :obj:`SeismicData`): List of SeismicData objects containing the points queried. These are to be adjusted if needed. Returns: True on success, false if there is an error. """ ely_coefficients = {"a": 1 / 2, "b": 2 / 3, "c": 3 / 2} depth = 350 zmin = 0 for datum in data: if datum.velocity_properties is None or \ datum.velocity_properties.vs is None or datum.velocity_properties.vs == 0 or \ datum.velocity_properties.vp is None or datum.velocity_properties.vp == 0 or \ datum.velocity_properties.density is None or datum.velocity_properties.density == 0 or \ datum.vs30_properties is None or datum.vs30_properties.vs30 == 0 or datum.vs30_properties.vs30 is None: continue if datum.converted_point.z_value < zmin: new_vs = ely_coefficients["a"] * datum.vs30_properties.vs30 new_vp = ely_coefficients["a"] * calculate_scaled_vp(new_vs) new_dn = calculate_nafe_drake_density(new_vp) datum.set_velocity_data( VelocityProperties(new_vp, new_vs, new_dn, datum.velocity_properties.qp, datum.velocity_properties.qs, new_sources["vp"], new_sources["vs"], new_sources["dn"], datum.velocity_properties.qp_source, datum.velocity_properties.qs_source)) elif datum.converted_point.z_value < depth: datum_ely = [ SeismicData( Point(datum.converted_point.x_value, datum.converted_point.y_value, depth, UCVM_DEPTH, datum.converted_point.projection)) ] UCVM.query( datum_ely, datum.model_string.replace(".elevation", "").replace(".elygtl", ""), ["velocity"]) new_vs = datum_ely[0].velocity_properties.vs new_vp = datum_ely[0].velocity_properties.vp new_dn = datum_ely[0].velocity_properties.density new_sources = { "vp": datum_ely[0].velocity_properties.vp_source, "vs": datum_ely[0].velocity_properties.vs_source, "dn": datum_ely[0].velocity_properties.density_source } z = (datum.converted_point.z_value - zmin) / (depth - zmin) f = z - math.pow(z, 2.0) g = math.pow(z, 2.0) + 2 * math.pow(z, 0.5) - (3 * z) new_vs = (z + ely_coefficients["b"] * f) * new_vs + \ (ely_coefficients["a"] - ely_coefficients["a"] * z + ely_coefficients["c"] * g) * datum.vs30_properties.vs30 new_vp = (z + ely_coefficients["b"] * f) * new_vp + \ (ely_coefficients["a"] - ely_coefficients["a"] * z + ely_coefficients["c"] * g) * \ calculate_scaled_vp(datum.vs30_properties.vs30) new_dn = calculate_nafe_drake_density(new_vp) for key, item in new_sources.items(): new_sources[key] = \ ", ".join([x.strip() for x in new_sources[key].split(",")]) + ", Ely GTL" datum.set_velocity_data( VelocityProperties(new_vp, new_vs, new_dn, datum.velocity_properties.qp, datum.velocity_properties.qs, new_sources["vp"], new_sources["vs"], new_sources["dn"], datum.velocity_properties.qp_source, datum.velocity_properties.qs_source)) return True
def extract(self): proj = pyproj.Proj(proj='utm', zone=11, ellps='WGS84') x1, y1 = proj(self.start_point.x_value, self.start_point.y_value) x2, y2 = proj(self.end_point.x_value, self.end_point.y_value) num_prof = int( math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) / self.cross_section_properties.width_spacing) for j in range( int(self.start_point.z_value), int(self.end_point.z_value) + (1 if self.end_point.depth_elev == UCVM_DEPTH else -1), int(self.cross_section_properties.height_spacing)): for i in range(0, num_prof + 1): x = x1 + i * (x2 - x1) / float(num_prof) y = y1 + i * (y2 - y1) / float(num_prof) lon, lat = proj(x, y, inverse=True) self.sd_array.append( SeismicData( Point(lon, lat, j, int(self.start_point.depth_elev)))) UCVM.query(self.sd_array, self.cvms, ["elevation", "velocity"]) num_x = num_prof + 1 num_y = int( math.ceil(self.end_point.z_value - self.start_point.z_value) / self.cross_section_properties.height_spacing) self.extracted_data = np.arange(num_x * num_y * 6, dtype=float).reshape(num_y, num_x * 6) for y in range(int(num_y)): for x in range(int(num_x)): x_val = x * 6 if self.sd_array[y * num_x + x].velocity_properties is not None: vp_val = self.sd_array[y * num_x + x].velocity_properties.vp vs_val = self.sd_array[y * num_x + x].velocity_properties.vs density_val = self.sd_array[y * num_x + x].velocity_properties.density qp_val = self.sd_array[y * num_x + x].velocity_properties.qp qs_val = self.sd_array[y * num_x + x].velocity_properties.qs else: vp_val = None vs_val = None density_val = None qp_val = None qs_val = None self.extracted_data[y][ x_val] = vp_val if vp_val is not None else -1 self.extracted_data[y][ x_val + 1] = vs_val if vs_val is not None else -1 self.extracted_data[y][ x_val + 2] = density_val if density_val is not None else -1 self.extracted_data[y][ x_val + 3] = qp_val if qp_val is not None else -1 self.extracted_data[y][ x_val + 4] = qs_val if qs_val is not None else -1 if self.sd_array[y * num_x + x].elevation_properties is not None: self.extracted_data[y][x_val + 5] = \ self.sd_array[y * num_x + x].elevation_properties.elevation else: self.extracted_data[y][x_val + 5] = -1
def test_cca06_random_points(self): """ Tests the CCA06 velocity model at 10 random points selected from the model. These points were picked with a random number generator. Returns: None """ self._test_start("CCA06 points versus text model test") test_data = \ """ 438 254 5 -118.887875 35.478906 4895.436 2667.120 2435.278 46 796 5 -122.422779 36.382854 2429.266 1417.205 2241.661 335 108 8 -118.879781 34.674750 5172.307 2793.584 2480.476 566 730 13 -119.865852 37.552742 6236.374 3768.482 2791.083 951 7 19 -115.790940 35.880222 5989.860 3398.884 2668.398 963 7 27 -115.735974 35.910148 6137.117 3460.438 2692.684 954 887 31 -118.588744 39.145429 6179.948 3394.584 2665.174 234 495 49 -120.580990 35.813587 6534.183 3684.867 2791.827 447 679 49 -120.236755 37.050627 6946.152 4085.203 3005.396 339 616 55 -120.513406 36.533256 6727.385 3888.453 2922.629 987 167 58 -116.119090 36.566131 6582.264 3690.730 2803.978 139 137 66 -119.834750 34.261905 8074.908 4733.310 3348.805 532 82 68 -117.920905 35.092949 7987.021 4711.226 3343.804 968 586 68 -117.534766 38.072441 7602.601 4214.103 3079.460 574 40 72 -117.600991 35.046711 7739.257 4522.150 3249.446 369 337 75 -119.463563 35.600098 7765.333 4526.807 3250.931 156 149 90 -119.798850 34.350777 7970.437 4622.248 3294.685 226 496 92 -120.619796 35.795691 7765.998 4442.617 3200.752 5 522 96 -121.679680 35.290345 7905.824 4564.610 3270.179 778 154 97 -117.036585 35.990024 7867.409 4607.975 3291.877 """ points = [] for point in test_data.split("\n"): if point.strip() == "": continue point = point.split() points.append( (float(point[3]), float(point[4]), (int(point[2]) - 1) * 500, float(point[5]), float(point[6]), float(point[7]))) sd_test = [SeismicData(Point(p[0], p[1], p[2])) for p in points] self.assertTrue(UCVM.query(sd_test, "cca06", ["velocity"])) epsilon = 0.00001 for i in range(len(sd_test)): self.assertGreater( sd_test[i].velocity_properties.vp / points[i][3], 1 - epsilon) self.assertLess(sd_test[i].velocity_properties.vp / points[i][3], 1 + epsilon) self.assertGreater( sd_test[i].velocity_properties.vs / points[i][4], 1 - epsilon) self.assertLess(sd_test[i].velocity_properties.vs / points[i][4], 1 + epsilon) self.assertGreater( sd_test[i].velocity_properties.density / points[i][5], 1 - epsilon) self.assertLess( sd_test[i].velocity_properties.density / points[i][5], 1 + epsilon) self._test_end()
def extract(self): init_array = [SeismicData() for _ in range(0, 250000)] im = InternalMesh.from_parameters( self.origin, { "num_x": self.slice_properties.num_x, "num_y": self.slice_properties.num_y, "num_z": 1, "rotation": self.slice_properties.rotation, "spacing": self.slice_properties.spacing, "projection": self.origin.projection }, self.cvms, "") im_iterator = AWPInternalMeshIterator(im, 0, im.total_size, len(init_array), init_array) print("Beginning extraction...") counter = 0 total_counter = 0 num_queried = next(im_iterator) while num_queried > 0: if self.extras["plot"]["property"] == "elevation": UCVM.query(init_array[0:num_queried], self.cvms, ["elevation"]) for sd_prop in init_array[0:num_queried]: self.extracted_data[ counter] = sd_prop.elevation_properties.elevation counter += 1 elif self.extras["plot"]["property"] == "vs30": UCVM.query(init_array[0:num_queried], self.cvms, ["vs30", "elevation", "velocity"]) for sd_prop in init_array[0:num_queried]: self.extracted_data[counter] = sd_prop.vs30_properties.vs30 counter += 1 elif self.extras["plot"]["property"] == "z10" or self.extras[ "plot"]["property"] == "z25": if "z-calc" not in self.cvms: self.cvms += ".z-calc" UCVM.query(init_array[0:num_queried], self.cvms, ["velocity"]) for sd_prop in init_array[0:num_queried]: if sd_prop.z_properties is not None: self.extracted_data[counter] = sd_prop.z_properties.z10 self.extracted_data[counter + 1] = sd_prop.z_properties.z25 else: self.extracted_data[counter] = None self.extracted_data[counter + 1] = None counter += 2 else: UCVM.query(init_array[0:num_queried], self.cvms, ["elevation", "velocity"]) for sd_prop in init_array[0:num_queried]: self.extracted_data[ counter] = sd_prop.velocity_properties.vp self.extracted_data[counter + 1] = sd_prop.velocity_properties.vs self.extracted_data[ counter + 2] = sd_prop.velocity_properties.density self.extracted_data[counter + 3] = sd_prop.velocity_properties.qp self.extracted_data[counter + 4] = sd_prop.velocity_properties.qs self.extracted_data[ counter + 5] = sd_prop.elevation_properties.elevation counter += 6 total_counter += num_queried print("\t%.2f%% extracted." % ((total_counter / im.total_size) * 100)) try: num_queried = next(im_iterator) except StopIteration: break print("Done extracting %d points." % im.total_size)
def plot(self, basic: bool = False): if self.needs_extraction: self.extract() else: # Read in the already extracted data. with open(self.extras["save_file"], "rb") as fd: self.extracted_data = np.load(fd) init_array = UCVM.create_max_seismicdata_array(self.QUERY_AT_ONCE, 1) lons = np.zeros(self.slice_properties.num_x * self.slice_properties.num_y, dtype=float).reshape(self.slice_properties.num_y, self.slice_properties.num_x) lats = np.zeros(self.slice_properties.num_x * self.slice_properties.num_y, dtype=float).reshape(self.slice_properties.num_y, self.slice_properties.num_x) data = np.zeros(self.slice_properties.num_x * self.slice_properties.num_y, dtype=float).reshape(self.slice_properties.num_y, self.slice_properties.num_x) topography = None if "features" in self.extras["plot"] and \ "topography" in self.extras["plot"]["features"] and \ str(self.extras["plot"]["features"]["topography"]).lower().strip() == "yes": topography = np.zeros( self.slice_properties.num_x * self.slice_properties.num_y, dtype="<f8").reshape(self.slice_properties.num_y, self.slice_properties.num_x) if str(self.extras["plot"]["property"]).lower().strip() == "vp": position = 0 self.bounds = [ 0, 0.35, 0.70, 1.00, 1.35, 1.70, 2.55, 3.40, 4.25, 5.10, 5.95, 6.80, 7.65, 8.50 ] self.ticks = [ 0, 0.85, 1.70, 2.55, 3.40, 4.25, 5.10, 5.95, 6.80, 7.65, 8.50 ] self.plot_cbar_label = "Vp (km/s)" elif str(self.extras["plot"]["property"]).lower().strip() == "vs": position = 1 self.bounds = [ 0, 0.20, 0.40, 0.60, 0.80, 1.00, 1.50, 2.00, 2.50, 3.00, 3.50, 4.00, 4.50, 5.00 ] self.ticks = [ 0, 0.50, 1.00, 1.50, 2.00, 2.50, 3.00, 3.50, 4.00, 4.50, 5.00 ] self.plot_cbar_label = "Vs (km/s)" elif str(self.extras["plot"]["property"]).lower().strip() == "density": position = 2 self.bounds = [ 0, 0.20, 0.40, 0.60, 0.80, 1.00, 1.50, 2.00, 2.50, 3.00, 3.50, 4.00, 4.50, 5.00 ] self.ticks = [ 0, 0.50, 1.00, 1.50, 2.00, 2.50, 3.00, 3.50, 4.00, 4.50, 5.00 ] self.plot_cbar_label = "Density (kg/m^3)" elif str(self.extras["plot"]["property"]).lower().strip() == "qp": position = 3 elif str(self.extras["plot"]["property"]).lower().strip() == "qs": position = 4 elif str(self.extras["plot"] ["property"]).lower().strip() == "elevation": position = 0 self.bounds = [-4, -3, -2, -1, 0, 1, 2, 3, 4] self.ticks = [-4, -3, -2, -1, 0, 1, 2, 3, 4] self.plot_cbar_label = "Elevation (km)" elif str(self.extras["plot"]["property"]).lower().strip() == "vs30": position = 0 self.bounds = [ 0, 0.20, 0.40, 0.60, 0.80, 1.00, 1.50, 2.00, 2.50, 3.00, 3.50, 4.00, 4.50, 5.00 ] self.ticks = [ 0, 0.50, 1.00, 1.50, 2.00, 2.50, 3.00, 3.50, 4.00, 4.50, 5.00 ] self.plot_cbar_label = "Vs (km/s)" elif str(self.extras["plot"]["property"]).lower().strip() == "z10": position = 0 self.bounds = [ 0, 1.00, 2.00, 3.00, 4.00, 5.00, 6.00, 7.00, 8.00, 9.00, 10.00 ] self.ticks = self.bounds self.plot_cbar_label = "Depth (km)" elif str(self.extras["plot"]["property"]).lower().strip() == "z25": position = 1 self.bounds = [ 0, 1.00, 2.00, 3.00, 4.00, 5.00, 6.00, 7.00, 8.00, 9.00, 10.00 ] self.ticks = self.bounds self.plot_cbar_label = "Depth (km)" else: position = 0 im = InternalMesh.from_parameters( self.origin, { "num_x": self.slice_properties.num_x, "num_y": self.slice_properties.num_y, "num_z": 1, "rotation": self.slice_properties.rotation, "spacing": self.slice_properties.spacing, "projection": self.origin.projection }, self.cvms, "") im_iterator = AWPInternalMeshIterator(im, 0, im.total_size, len(init_array), init_array) num_queried = next(im_iterator) i = 0 j = 0 while num_queried > 0: for datum in init_array[0:num_queried]: new_pt = datum.original_point.convert_to_projection( UCVM_DEFAULT_PROJECTION) lons[j][i] = new_pt.x_value lats[j][i] = new_pt.y_value if str(self.extras["plot"]["property"]).lower().strip() == "elevation" or \ str(self.extras["plot"]["property"]).lower().strip() == "vs30": data[j][i] = self.extracted_data[ j * self.slice_properties.num_x + i] / 1000 elif str(self.extras["plot"]["property"]).lower().strip() == "z10" or \ str(self.extras["plot"]["property"]).lower().strip() == "z25": data[j][i] = self.extracted_data[( (j * self.slice_properties.num_x) + i) * 2 + position] / 1000 else: data[j][i] = self.extracted_data[( (j * self.slice_properties.num_x) + i) * 6 + position] / 1000 if topography is not None: topography[j][i] = self.extracted_data[( (j * self.slice_properties.num_x) + i) * 6 + 5] / 1000 i += 1 if i == self.slice_properties.num_x: i = 0 j += 1 try: num_queried = next(im_iterator) except StopIteration: break # Ok, now that we have the 2D array of lons, lats, and data, let's call on our inherited # classes show_plot function to actually show the plot. return super(HorizontalSlice, self).show_plot(lons, lats, data, True, topography=topography, basic=basic)