def _parse_component_data(self, wfid, proc_data):
        """
        Parses the information for each component
        """
        filter_params = {
            'Type': proc_data['comp_ordered.filter_type'],
            'Order': proc_data['comp_ordered.filter_order'],
            'Passes': get_int(
                proc_data['comp_ordered.filter_number_of_passes']),
            'NRoll': get_int(proc_data['comp_ordered.nroll']),
            'High-Cut': get_float(proc_data['comp_ordered.high_cut_freq']),
            'Low-Cut': get_float(proc_data['comp_ordered.low_cut_freq'])}

        intensity_measures = {
            # All m - convert to cm
            'PGA': get_float(proc_data['comp_ordered.pga']),
            'PGV': get_float(proc_data['comp_ordered.pgv']),
            'PGD': get_float(proc_data['comp_ordered.pgd'])
            }

        for imkey in intensity_measures.keys():
            if intensity_measures[imkey]:
                intensity_measures[imkey] = 100.0 * intensity_measures[imkey]
            
        comp = Component(wfid,
            proc_data['comp_ordered.orientation'],
            ims=intensity_measures,
            longest_period=None,
            waveform_filter=filter_params,
            baseline=proc_data['comp_ordered.baseline_correction'])
        return comp
    def _parse_site_data(self, metadata):
        """
        Parses the site metadata. Coordinates in western hemisphere
        are returned as negative values.
        """
        try:
            altitude = get_float(metadata["ALTITUD (msnm)"])
        except:
            altitude = 0

        site = RecordSite(
            "|".join([metadata["INSTITUCION RESPONSABLE"],
                    metadata["CLAVE DE LA ESTACION"]]),
            metadata["CLAVE DE LA ESTACION"],
            metadata["NOMBRE DE LA ESTACION"],
            -get_float(metadata["COORDENADAS DE LA ESTACION"].split(" ")[3]),
            get_float(metadata["COORDENADAS DE LA ESTACION"].split(" ")[0]),
            altitude)

        if "UNAM" in metadata["INSTITUCION RESPONSABLE"]:
            site.network_code = "UNAM"
        elif "CICESE" in metadata["INSTITUCION RESPONSABLE"]:
            site.network_code = "CICESE"
        else:
            site.network_code = "unknown"

        try:
            site.morphology = metadata["TIPO DE SUELO"]
        except:
            site.morphology = None

        site.instrument_type = metadata["MODELO DEL ACELEROGRAFO"]

        return site
 def _parse_record(self, metadata):
     """
     Parses the record information and returns an instance of the
     :class: smtk.sm_database.GroundMotionRecord
     """
     # Waveform ID
     wfid = metadata["Record Sequence Number"]
     # Event information
     event = self._parse_event_data(metadata)
     # Site information
     site = self._parse_site_data(metadata)
     # Distance Information
     distances = self._parse_distance_data(event, site, metadata)
     # Components
     x_comp, y_comp, vertical = self._parse_processing_data(wfid, metadata)
     # Return record metadata
     lup = get_float(metadata["Lowest Usable Freq - Ave. Component (Hz)"])
     if lup:
         lup = 1. / lup
     sup = get_float(metadata["Maximum Usable Freq - Ave. Component (Hz)"])
     if sup:
         sup = 1. / sup
     return GroundMotionRecord(wfid,
         [metadata["File Name (Horizontal 1)"],
          metadata["File Name (Horizontal 2)"],
          metadata["File Name (Vertical)"]],
         event,
         distances,
         site,
         x_comp,
         y_comp,
         longest_period=lup,
         shortest_period=sup)
    def _parse_focal_mechanism(self, eq_id, eq_name, metadata):
        """
        Parses the focal mechanism returning an instance of FocalMechanism
        """
        nodal_planes = GCMTNodalPlanes()
        nodal_planes.nodal_plane_1 = {
            'strike': get_float(metadata['event.strike1']),
            'dip': get_float(metadata['event.dip1']),
            'rake': get_float(metadata['event.slip1'])
            }
        nodal_planes.nodal_plane_2 = {
            'strike': get_float(metadata['event.strike2']),
            'dip': get_float(metadata['event.dip2']),
            'rake': get_float(metadata['event.slip2'])
            }

        principal_axes = GCMTPrincipalAxes()
        principal_axes.t_axes = {
            'eigenvalue': None,
            'plunge': get_float(metadata['event.t_axes_plg']),
            'azimuth': get_float(metadata['event.t_axes_az'])}
        principal_axes.p_axes = {
            'eigenvalue': None,
            'plunge': get_float(metadata['event.p_axes_plg']),
            'azimuth': get_float(metadata['event.p_axes_az'])}
        principal_axes.b_axes = {
            'eigenvalue': None,
            'plunge': None,
            'azimuth': None}

        return FocalMechanism(eq_id, eq_name, nodal_planes, principal_axes,
            mechanism_type=metadata['event.fault_mechanism.name'])
Example #5
0
    def _parse_site_data(self, metadata):
        """
        Parses the site metadata
        """
        try:
            altitude = get_float(metadata["ALTITUD (msnm)"])
        except:
            altitude = 0

        site = RecordSite(
            "|".join([
                metadata["INSTITUCION RESPONSABLE"],
                metadata["CLAVE DE LA ESTACION"]
            ]), metadata["CLAVE DE LA ESTACION"],
            metadata["NOMBRE DE LA ESTACION"],
            get_float(metadata["COORDENADAS DE LA ESTACION"].split(" ")[3]),
            get_float(metadata["COORDENADAS DE LA ESTACION"].split(" ")[0]),
            altitude)

        if "UNAM" in metadata["INSTITUCION RESPONSABLE"]:
            site.network_code = "UNAM"
        elif "CICESE" in metadata["INSTITUCION RESPONSABLE"]:
            site.network_code = "CICESE"
        else:
            site.network_code = "unknown"

        try:
            site.morphology = metadata["TIPO DE SUELO"]
        except:
            site.morphology = None

        site.instrument_type = metadata["MODELO DEL ACELEROGRAFO"]

        return site
Example #6
0
    def _parse_distance_data(self, metadata, file_str, eqk):
        """
        Parses the event metadata to return an instance of the :class:
        smtk.sm_database.RecordDistance
        """

        epi_lon = get_float(
            metadata["COORDENADAS DEL EPICENTRO"].split(" ")[3])
        epi_lat = get_float(
            metadata["COORDENADAS DEL EPICENTRO"].split(" ")[0])
        sta_lon = get_float(
            metadata["COORDENADAS DE LA ESTACION"].split(" ")[3])
        sta_lat = get_float(
            metadata["COORDENADAS DE LA ESTACION"].split(" ")[0])

        p = Point(longitude=epi_lon, latitude=epi_lat)
        repi = p.distance(Point(longitude=sta_lon, latitude=sta_lat))

        # No hypocentral distance in file - calculate from event
        rhypo = sqrt(repi**2. + eqk.depth**2.)

        azimuth = Point(epi_lon, epi_lat,
                        eqk.depth).azimuth(Point(sta_lon, sta_lat))

        dists = RecordDistance(repi, rhypo)
        dists.azimuth = azimuth
        return dists
Example #7
0
 def _parse_record(self, metadata):
     """
     Parses the record information and returns an instance of the
     :class: smtk.sm_database.GroundMotionRecord
     """
     # Waveform ID
     wfid = metadata["Record Sequence Number"]
     # Event information
     event = self._parse_event_data(metadata)
     # Site information
     site = self._parse_site_data(metadata)
     # Distance Information
     distances = self._parse_distance_data(event, site, metadata)
     # Components
     x_comp, y_comp, vertical = self._parse_processing_data(wfid, metadata)
     # Return record metadata
     lup = get_float(metadata["Lowest Usable Freq - Ave. Component (Hz)"])
     if lup:
         lup = 1. / lup
     sup = get_float(metadata["Maximum Usable Freq - Ave. Component (Hz)"])
     if sup:
         sup = 1. / sup
     return GroundMotionRecord(wfid,
         [metadata["File Name (Horizontal 1)"],
          metadata["File Name (Horizontal 2)"],
          metadata["File Name (Vertical)"]],
         event,
         distances,
         site,
         x_comp,
         y_comp,
         longest_period=lup,
         shortest_period=sup)
Example #8
0
    def _get_focal_mechanism(self, eq_id, eq_name, metadata):
        """
        Returns the focal mechanism information as an instance of the
        :class: smtk.sigma_database.FocalMechanism 
        """
        nodal_planes = GCMTNodalPlanes()
        strike = get_float(metadata["Strike (deg)"])
        if strike is None:
            strike = 0.0
        dip = get_float(metadata["Dip (deg)"])
        if dip is None:
            dip = 90.0
        nodal_planes.nodal_plane_1 = {
            "strike": strike,
            "dip": dip,
            "rake": get_float(metadata["Rake Angle (deg)"])
        }

        nodal_planes.nodal_plane2 = {"strike": None, "dip": None, "rake": None}
        principal_axes = GCMTPrincipalAxes()
        return FocalMechanism(
            eq_id,
            eq_name,
            nodal_planes,
            principal_axes,
            mechanism_type=metadata["Mechanism Based on Rake Angle"])
    def _parse_distance_data(self, metadata, file_str, eqk):
        """
        Parses the event metadata to return an instance of the :class:
        smtk.sm_database.RecordDistance. Coordinates in western hemisphere
        are converted to negative values.
        """

        epi_lon = -get_float(
            metadata["COORDENADAS DEL EPICENTRO"].split(" ")[3])
        epi_lat = get_float(
            metadata["COORDENADAS DEL EPICENTRO"].split(" ")[0])
        sta_lon = -get_float(
            metadata["COORDENADAS DE LA ESTACION"].split(" ")[3])
        sta_lat = get_float(
            metadata["COORDENADAS DE LA ESTACION"].split(" ")[0])

        p = Point(longitude=epi_lon, latitude=epi_lat)
        repi = p.distance(Point(longitude=sta_lon, latitude=sta_lat))

        # No hypocentral distance in file - calculate from event
        rhypo = sqrt(repi ** 2. + eqk.depth ** 2.)

        azimuth = Point(epi_lon, epi_lat, eqk.depth).azimuth(
            Point(sta_lon, sta_lat))

        dists = RecordDistance(repi, rhypo)
        dists.azimuth = azimuth
        return dists
    def _parse_rupture(self, eq_id, eq_name, magnitude, metadata):
        """

        """
        return Rupture(eq_id, eq_name, magnitude,
                       get_float(metadata['event.fault_rupture_length']),
                       get_float(metadata['event.fault_rupture_width']),
                       get_float(metadata['event.fault_rupture_depth']))
    def _parse_rupture(self, eq_id, metadata):
        """

        """
        return Rupture(eq_id,
                       get_float(metadata['event.fault_rupture_length']),
                       get_float(metadata['event.fault_rupture_width']),
                       get_float(metadata['event.fault_rupture_depth']))
 def _parse_distance_data(self, metadata):
     """
     Parses the distance data
     """
     return RecordDistance(get_float(metadata['distance_repi']),
                           get_float(metadata['distance_rhyp']),
                           rjb = get_float(metadata['distance_rjb']),
                           rrup = get_float(metadata['distance_rrup']),
                           r_x = None,
                           flag = get_int(metadata['distance_flag']))
Example #13
0
    def _parse_event_data(self, metadata):
        """
        Read in the distance related metadata and return an instance of the
        :class: smtk.sm_database.Earthquake

        """
        metadata["MODY"] = metadata["MODY"].zfill(4)
        metadata["HRMN"] = metadata["HRMN"].zfill(4)
        # Date and Time
        year = get_int(metadata["YEAR"])
        month = get_int(metadata["MODY"][:2])
        day = get_int(metadata["MODY"][2:])
        hour = get_int(metadata["HRMN"][:2])
        minute = get_int(metadata["HRMN"][2:])
        eq_datetime = datetime(year, month, day, hour, minute)
        # Event ID and Name
        eq_id = metadata["EQID"]
        eq_name = metadata["Earthquake Name"]
        # Focal Mechanism
        focal_mechanism = self._get_focal_mechanism(eq_id, eq_name, metadata)
        focal_mechanism.scalar_moment = get_float(metadata["Mo (dyne.cm)"]) *\
            1E-7
        # Read magnitude
        pref_mag = Magnitude(get_float(metadata["Earthquake Magnitude"]),
                             metadata["Magnitude Type"],
                             sigma=get_float(metadata["Uncertainty"]))
        # Create Earthquake Class
        eqk = Earthquake(eq_id, eq_name, eq_datetime,
                         get_float(metadata["Hypocenter Longitude (deg)"]),
                         get_float(metadata["Hypocenter Latitude (deg)"]),
                         get_float(metadata["Hypocenter Depth (km)"]),
                         pref_mag, focal_mechanism, metadata["Country"])
        hypo_loc = (0.5, 0.7)  # Hypocentre Location
        msr = WC1994()
        # Warning rake set to 0.0 in scaling relationship
        area = msr.get_median_area(pref_mag.value, 0.0)
        aspect_ratio = 1.5  # Assumed Fixed
        width_model = np.sqrt(area / aspect_ratio)
        length_model = aspect_ratio * width_model
        ztor_model = eqk.depth - width_model / 2.
        if ztor_model < 0:
            ztor_model = 0.0

        length = get_float(metadata["Fault Rupture Length (km)"])
        if length is None:
            length = length_model
        width = get_float(metadata["Fault Rupture Width (km)"])
        if width is None:
            width = width_model
        ztor = get_float(metadata["Depth to Top Of Fault Rupture Model"])
        if ztor is None:
            ztor = ztor_model
        # Rupture
        eqk.rupture = Rupture(eq_id, eq_name, pref_mag, length, width, ztor)
        #    get_float(metadata["Fault Rupture Length (km)"]),
        #    get_float(metadata["Fault Rupture Width (km)"]),
        #    get_float(metadata["Depth to Top Of Fault Rupture Model"]))
        eqk.rupture.get_area()
        return eqk
  def _build_spectra_hdf5_from_row(self, output_file, row, periods,
                                   scalar_fields, spectra_fields, component,
                                   damping, units):
      """
 
      """
      fle = h5py.File(output_file, "w-")
      ts_grp = fle.create_group("Time Series")
      ims_grp = fle.create_group("IMS")
      h_grp = ims_grp.create_group("H")
      scalar_grp = h_grp.create_group("Scalar")
      # Create Scalar values
      for f_attr, imt in scalar_fields:
          dset = scalar_grp.create_dataset(imt, (1,), dtype="f")
          dset.attrs["Component"] = component
          input_units = re.search('\((.*?)\)', f_attr).group(1)
          if imt == "PGA":
              # Convert acceleration from reported units to cm/s/s
              dset.attrs["Units"] = "cm/s/s"
              dset[:] = utils.convert_accel_units(get_float(row[f_attr]),
                                                  input_units)
          else:
              # For other values take direct from spreadsheet
              # Units should be given in parenthesis from fieldname 
              dset.attrs["Units"] = input_units
              dset[:] = get_float(row[f_attr])
              
      spectra_grp = h_grp.create_group("Spectra")
      rsp_grp = spectra_grp.create_group("Response")
      # Setup periods dataset
      per_dset = rsp_grp.create_dataset("Periods",
                                        (len(periods),),
                                        dtype="f")
      per_dset.attrs["High Period"] = np.max(periods)
      per_dset.attrs["Low Period"] = np.min(periods)
      per_dset.attrs["Number Periods"] = len(periods)
      per_dset[:] = periods
      # Get response spectra
      spectra = np.array([get_float(row[f_attr])
                          for f_attr in spectra_fields])
      acc_grp = rsp_grp.create_group("Acceleration")
      comp_grp = acc_grp.create_group(component)
      spectra_dset = comp_grp.create_dataset("damping_{:s}".format(damping),
                                             (len(spectra),),
                                             dtype="f")
      spectra_dset.attrs["Units"] = "cm/s/s"
      spectra_dset[:] = utils.convert_accel_units(spectra, units)
      fle.close()
 def parse_metadata(self, metadata, file_str):
     """
     Parses the metadata dictionary
     """
     # Waveform id
     wfid = metadata['waveform_sourceid']
     # Get event information
     event = self._parse_event_data(metadata)
     # Get distance information
     distances = self._parse_distance_data(metadata)
     # Get site data
     site = self._parse_site_data(metadata)
     # Get processing data
     x_comp, y_comp, z_comp = self._parse_processing_data(wfid, metadata)
     # Create and return record
     rec_file = os.path.join(file_str + "/" + file_str)
                             
     return GroundMotionRecord(wfid,
         [rec_file + self.XCOMP_STR, 
          rec_file + self.YCOMP_STR,
          rec_file + self.ZCOMP_STR],
         event,
         distances,
         site,
         x_comp,
         y_comp,
         vertical=z_comp,
         ims=None,
         longest_period=get_float(metadata['up4horiz_components']),
         spectra_file=[rec_file + self.XSPEC_STR,
                       rec_file + self.YSPEC_STR,
                       rec_file + self.ZSPEC_STR])
Example #16
0
    def _build_spectra_hdf5_from_row(self, output_file, row, periods,
                                     scalar_fields, spectra_fields, component,
                                     damping, units):
        """
   
        """
        fle = h5py.File(output_file, "w-")
        ts_grp = fle.create_group("Time Series")
        ims_grp = fle.create_group("IMS")
        h_grp = ims_grp.create_group("H")
        scalar_grp = h_grp.create_group("Scalar")
        # Create Scalar values
        for f_attr, imt in scalar_fields:
            dset = scalar_grp.create_dataset(imt, (1, ), dtype="f")
            dset.attrs["Component"] = component
            input_units = re.search('\((.*?)\)', f_attr).group(1)
            if imt == "PGA":
                # Convert acceleration from reported units to cm/s/s
                dset.attrs["Units"] = "cm/s/s"
                dset[:] = utils.convert_accel_units(get_float(row[f_attr]),
                                                    input_units)
            else:
                # For other values take direct from spreadsheet
                # Units should be given in parenthesis from fieldname
                dset.attrs["Units"] = input_units
                dset[:] = get_float(row[f_attr])

        spectra_grp = h_grp.create_group("Spectra")
        rsp_grp = spectra_grp.create_group("Response")
        # Setup periods dataset
        per_dset = rsp_grp.create_dataset("Periods", (len(periods), ),
                                          dtype="f")
        per_dset.attrs["High Period"] = np.max(periods)
        per_dset.attrs["Low Period"] = np.min(periods)
        per_dset.attrs["Number Periods"] = len(periods)
        per_dset[:] = periods
        # Get response spectra
        spectra = np.array(
            [get_float(row[f_attr]) for f_attr in spectra_fields])
        acc_grp = rsp_grp.create_group("Acceleration")
        comp_grp = acc_grp.create_group(component)
        spectra_dset = comp_grp.create_dataset("damping_{:s}".format(damping),
                                               (len(spectra), ),
                                               dtype="f")
        spectra_dset.attrs["Units"] = "cm/s/s"
        spectra_dset[:] = utils.convert_accel_units(spectra, units)
        fle.close()
 def _parse_site_data(self, metadata):
     """
     Returns the site data as an instance of the :class:
     smtk.sm_database.RecordSite
     """
     site = RecordSite(metadata["Station Sequence Number"],
                       metadata["Station ID  No."],
                       metadata["Station ID  No."],
                       get_float(metadata["Station Longitude"]),
                       get_float(metadata["Station Latitude"]),
                       0.0, # Elevation data not given
                       get_float(metadata["Preferred Vs30 (m/s)"]),
                       network_code=metadata["Owner"])
     site.nehrp = metadata["Preferred NEHRP Based on Vs30"]
     site.vs30_measured_type = metadata["Measured/Inferred Class"]
     if site.vs30_measured_type in ["0", "5"]:
         site.vs30_measured = True
     else:
         site.vs30_measured = False
     site.vs30_uncertainty = get_float(
         metadata["Sigma of Vs30 (in natural log Units)"])
     site.z1pt0 = get_float(metadata["Z1 (m)"])
     site.z1pt5 = get_float(metadata["Z1.5 (m)"])
     site.z2pt5 = get_float(metadata["Z2.5 (m)"])
     # Implement default values for z1pt0 and z2pt5
     if site.z1pt0 is None:
         site.z1pt0 = rcfg.vs30_to_z1pt0_as08(site.vs30)
     if site.z2pt5 is None:
         site.z2pt5 = rcfg.z1pt0_to_z2pt5(site.z1pt0)
     site.arc_location = metadata["Forearc/Backarc for subduction events"]
     site.instrument_type = metadata["Type of Recording"]
     return site
    def _parse_event_data(self, metadata):
        """
        """
        # Get datetime
        if len(metadata['event.datetime']) > 20:
            eq_datetime = datetime.strptime(metadata['event.datetime'],
                                        "%Y-%m-%d %H:%M:%S.%f")
        else:
            eq_datetime = datetime.strptime(metadata['event.datetime'],
                                        "%Y-%m-%d %H:%M:%S")
        # Event ID and Name
        if metadata['event.unid']:
            eq_id = metadata['event.unid']
        else:
            eq_id = eq_datetime.isoformat()
        
        eq_name = metadata['event.name']
        
        # Get focal mechanism
        focal_mech = self._parse_focal_mechanism(eq_id, eq_name, metadata)

        # Get preferred magnitude
        pref_mag = Magnitude(get_float(metadata['event.pref_mag']),
                             metadata['event.pref_mag_type'])
        # Get magnitude list
        mag_list = []
        for kstr in ['0', '1', '2', '3', '4']:
            mag_list.append(Magnitude(
                get_float(metadata['event.magnitudes/' + kstr + '.value']),
                metadata['event.magnitudes/' + kstr + '.magtype']))

        eqk = Earthquake(eq_id, eq_name, eq_datetime,
            get_float(metadata['event.longitude']),
            get_float(metadata['event.latitude']),
            get_float(metadata['event.focaldepth']),
            pref_mag,
            focal_mech,
            metadata['event.country.name'])
        eqk.magnitude_list = mag_list
        # Get Rupture data
        eqk.rupture = self._parse_rupture(eq_id, eq_name, pref_mag, metadata)
        return eqk
    def _get_focal_mechanism(self, eq_id, eq_name, metadata):
        """
        Returns the focal mechanism information as an instance of the
        :class: smtk.sigma_database.FocalMechanism 
        """
        nodal_planes = GCMTNodalPlanes()
        strike = get_float(metadata["Strike (deg)"])
        if strike is None:
            strike = 0.0
        dip = get_float(metadata["Dip (deg)"])
        if dip is None:
            dip = 90.0
        nodal_planes.nodal_plane_1 = {
            "strike": strike,
            "dip": dip,
            "rake": get_float(metadata["Rake Angle (deg)"])}

        nodal_planes.nodal_plane2 = {"strike": None,
                                     "dip": None,
                                     "rake": None}
        principal_axes = GCMTPrincipalAxes()
        return FocalMechanism(eq_id, eq_name, nodal_planes, principal_axes,
            mechanism_type=metadata["Mechanism Based on Rake Angle"])
 def _parse_site_data(self, metadata):
     """
     Parse the site data
     """
     site = RecordSite(
         metadata['station.oid'],
         metadata['station.name'],
         metadata['station.code'],
         get_float(metadata['station.longitude']),
         get_float(metadata['station.latitude']),
         get_float(metadata['station.altitude']),
         vs30=get_float(metadata['station.vs30']),
         vs30_measured=get_int(metadata['station.vs30_measured']),
         network_code=metadata['station.agency.name'],
         country=metadata['station.country.name'])
     site.vs30_measured_type = metadata['station.vs30_measured_type']
     site.instrument_type = metadata['recording_type']
     site.digitiser = metadata['digitalizer']
     site.building_structure = metadata['station.building_struct.name']
     site.number_floors = get_int(metadata['station.number_of_floor'])
     site.floor = metadata['station.installed_on_floor']
     site.ec8 = metadata['station.ec8']
     return site
Example #21
0
    def _parse_distance_data(self, event, site, metadata):
        """
        Read in the distance related metadata and return an instance of the
        :class: smtk.sm_database.RecordDistance
        """
        # Compute various distance metrics
        # Add calculation of Repi, Rhypo from event and station localizations (latitudes, longitudes, depth, elevation)?
        target_site = Mesh(np.array([site.longitude]),
                           np.array([site.latitude]), np.array([0.0]))
        # Warning ratio fixed to 1.5
        ratio = 1.5
        surface_modeled = rcfg.create_planar_surface(
            Point(event.longitude, event.latitude, event.depth),
            event.mechanism.nodal_planes.nodal_plane_1['strike'],
            event.mechanism.nodal_planes.nodal_plane_1['dip'],
            event.rupture.area, ratio)
        hypocenter = rcfg.get_hypocentre_on_planar_surface(
            surface_modeled, event.rupture.hypo_loc)
        # Rhypo
        Rhypo = get_float(metadata["HypD (km)"])
        if Rhypo is None:
            Rhypo = hypocenter.distance_to_mesh(target_site)
        # Repi
        Repi = get_float(metadata["EpiD (km)"])
        if Repi is None:
            Repi = hypocenter.distance_to_mesh(target_site, with_depths=False)
        # Rrup
        Rrup = get_float(metadata["Campbell R Dist. (km)"])
        if Rrup is None:
            Rrup = surface_modeled.get_min_distance(target_site)
        # Rjb
        Rjb = get_float(metadata["Joyner-Boore Dist. (km)"])
        if Rjb is None:
            Rjb = surface_modeled.get_joyner_boore_distance(target_site)
        # Need to check if Rx and Ry0 are consistant with the other metrics
        # when those are coming from the flatfile?
        # Rx
        Rx = surface_modeled.get_rx_distance(target_site)
        # Ry0
        Ry0 = surface_modeled.get_ry0_distance(target_site)

        distance = RecordDistance(repi=float(Repi),
                                  rhypo=float(Rhypo),
                                  rjb=float(Rjb),
                                  rrup=float(Rrup),
                                  r_x=float(Rx),
                                  ry0=float(Ry0))
        distance.azimuth = get_float(metadata["Source to Site Azimuth (deg)"])
        distance.hanging_wall = get_float(metadata["FW/HW Indicator"])
        #        distance = RecordDistance(
        #            get_float(metadata["EpiD (km)"]),
        #            get_float(metadata["HypD (km)"]),
        #            get_float(metadata["Joyner-Boore Dist. (km)"]),
        #            get_float(metadata["Campbell R Dist. (km)"]))
        #        distance.azimuth = get_float(metadata["Source to Site Azimuth (deg)"])
        #        distance.hanging_wall = get_float(metadata["FW/HW Indicator"])
        return distance
 def _parse_distance_data(self, event, site, metadata):
     """
     Read in the distance related metadata and return an instance of the
     :class: smtk.sm_database.RecordDistance
     """
     # Compute various distance metrics
     # Add calculation of Repi, Rhypo from event and station localizations 
     # (latitudes, longitudes, depth, elevation)?
     target_site = Mesh(np.array([site.longitude]),
                        np.array([site.latitude]),
                        np.array([-site.altitude / 1000.0]))
     # Warning ratio fixed to 1.5
     ratio=1.5
     surface_modeled = rcfg.create_planar_surface(
         Point(event.longitude, event.latitude, event.depth),
         event.mechanism.nodal_planes.nodal_plane_1['strike'],
         event.mechanism.nodal_planes.nodal_plane_1['dip'],
         event.rupture.area,
         ratio)
     hypocenter = rcfg.get_hypocentre_on_planar_surface(
         surface_modeled,
         event.rupture.hypo_loc)
     
     # Rhypo
     Rhypo = get_float(metadata["Hypocentral Distance (km)"])
     if Rhypo is None:
         Rhypo = hypocenter.distance_to_mesh(target_site)
     # Repi
     Repi = get_float(metadata["Epicentral Distance (km)"])
     if Repi is None:
         Repi= hypocenter.distance_to_mesh(target_site, with_depths=False)
     # Rrup
     Rrup = get_float(metadata["Rupture Distance (km)"])
     if Rrup is None:
         Rrup = surface_modeled.get_min_distance(target_site)
     # Rjb
     Rjb = get_float(metadata["Joyner-Boore Distance (km)"])
     if Rjb is None:
         Rjb = surface_modeled.get_joyner_boore_distance(target_site)
     # Need to check if Rx and Ry0 are consistant with the other metrics
     # when those are coming from the flatfile?
     # Rx
     Rx = surface_modeled.get_rx_distance(target_site)
     # Ry0
     Ry0 = surface_modeled.get_ry0_distance(target_site)
     
     distance = RecordDistance(
         repi = float(Repi),
         rhypo = float(Rhypo),
         rjb = float(Rjb),
         rrup = float(Rrup),
         r_x = float(Rx),
         ry0 = float(Ry0))
     distance.azimuth = get_float(metadata["Source to Site Azimuth (deg)"])
     distance.hanging_wall = get_float(metadata["FW/HW Indicator"])
     return distance
 def _sanitise(self, row, reader):
     """
     If all of the strong motion values are negative the record is null
     and should be removed
     """
     iml_vals = []
     for fname in reader.fieldnames:
         if fname.startswith("SA(") or fname in SCALAR_LIST:
             # Ground motion value
             iml = get_float(row[fname])
             if iml:
                 iml_vals.append(iml)
             else:
                 iml_vals.append(-999.0)
     # If all ground motion values are negative then the record is null
     # return false
     if np.all(np.array(iml_vals) < 0.0):
         return False
     else:
         return True
Example #24
0
 def _sanitise(self, row, reader):
     """
     If all of the strong motion values are negative the record is null
     and should be removed
     """
     iml_vals = []
     for fname in reader.fieldnames:
         if fname.startswith("SA(") or fname in SCALAR_LIST:
             # Ground motion value
             iml = get_float(row[fname])
             if iml:
                 iml_vals.append(iml)
             else:
                 iml_vals.append(-999.0)
     # If all ground motion values are negative then the record is null
     # return false
     if np.all(np.array(iml_vals) < 0.0):
         return False
     else:
         return True
Example #25
0
 def _parse_site_data(self, metadata):
     """
     Returns the site data as an instance of the :class:
     smtk.sm_database.RecordSite
     """
     site = RecordSite(
         self._get_site_id(metadata["Station ID"]),
         metadata["Station ID"],
         metadata["Station Code"],
         get_float(metadata["Station Longitude (deg positive E)"]),
         get_float(metadata["Station Latitude (deg positive N)"]),
         get_float(metadata["Station Elevation (m)"]),
         get_float(metadata["Preferred Vs30 (m/s)"]),
         site_class=metadata[
             'Site Class (Hard Rock; Rock; Stiff Soil; Soft Soil)'],
         network_code=None,  # not provided
     )
     # network_code=metadata["Owner"])
     site.nehrp = metadata["Preferred NEHRP Based on Vs30"]
     site.vs30_measured_type = metadata["Measured(1)/Inferred(2) Class"]
     if metadata["Measured(1)/Inferred(2) Class"] == "1":
         site.vs30_measured = True
     else:
         site.vs30_measured = False
     site.vs30_uncertainty = get_float(
         metadata["Sigma of Vs30 (in natural log Units)"])
     site.z1pt0 = get_float(metadata["Z1 (m)"])
     site.z1pt5 = None
     # site.z1pt5 = get_float(metadata["Z1.5 (m)"])
     site.z2pt5 = get_float(metadata["Z2.5 (m)"])
     # Implement default values for z1pt0 and z2pt5
     if site.z1pt0 is None:
         site.z1pt0 = rcfg.vs30_to_z1pt0_as08(site.vs30)
     if site.z2pt5 is None:
         site.z2pt5 = rcfg.z1pt0_to_z2pt5(site.z1pt0)
     else:
         # Need to convert z2pt5 from m to km
         site.z2pt5 = site.z2pt5 / 1000.0
     if "Backarc" in metadata["Forearc/Backarc for subduction events"]:
         site.backarc = True
     site.instrument_type = metadata["Digital (D)/Analog (A) Recording"]
     return site
Example #26
0
 def _parse_site_data(self, metadata):
     """
     Returns the site data as an instance of the :class:
     smtk.sm_database.RecordSite
     """
     site = RecordSite(
         self._get_site_id(metadata["Station ID"]),
         metadata["Station ID"],
         metadata["Station Code"],
         get_float(metadata["Station Longitude (deg positive E)"]),
         get_float(metadata["Station Latitude (deg positive N)"]),
         get_float(metadata["Station Elevation (m)"]),
         get_float(metadata["Preferred Vs30 (m/s)"]),
         site_class=metadata['Site Class (Hard Rock; Rock; Stiff Soil; Soft Soil)'],
         network_code=None, # not provided
         )
         # network_code=metadata["Owner"])
     site.nehrp = metadata["Preferred NEHRP Based on Vs30"]
     site.vs30_measured_type = metadata["Measured(1)/Inferred(2) Class"]
     if metadata["Measured(1)/Inferred(2) Class"] == "1":
         site.vs30_measured = True
     else:
         site.vs30_measured = False
     site.vs30_uncertainty = get_float(
         metadata["Sigma of Vs30 (in natural log Units)"])
     site.z1pt0 = get_float(metadata["Z1 (m)"])
     site.z1pt5 = None
     # site.z1pt5 = get_float(metadata["Z1.5 (m)"])
     site.z2pt5 = get_float(metadata["Z2.5 (m)"])
     # Implement default values for z1pt0 and z2pt5
     if site.z1pt0 is None:
         site.z1pt0 = rcfg.vs30_to_z1pt0_as08(site.vs30)
     if site.z2pt5 is None:
         site.z2pt5 = rcfg.z1pt0_to_z2pt5(site.z1pt0)        
     else:
         # Need to convert z2pt5 from m to km
         site.z2pt5 = site.z2pt5/1000.0
     if "Backarc" in metadata["Forearc/Backarc for subduction events"]:
         site.backarc = True
     site.instrument_type = metadata["Digital (D)/Analog (A) Recording"]
     return site
Example #27
0
    def _parse_processing_data(self, wfid, metadata):
        """
        Parses the information for each component
        """
        filter_params1 = {
            'Type': FILTER_TYPE[metadata["Type of Filter"]],
            'Order': None,
            'Passes': get_int(metadata['npass']),
            'NRoll': get_int(metadata['nroll']),
            'High-Cut': get_float(metadata["LP-H1 (Hz)"]),
            'Low-Cut': get_float(metadata["HP-H1 (Hz)"])
        }

        filter_params2 = {
            'Type': FILTER_TYPE[metadata["Type of Filter"]],
            'Order': None,
            'Passes': get_int(metadata['npass']),
            'NRoll': get_int(metadata['nroll']),
            'High-Cut': get_float(metadata["LP-H2 (Hz)"]),
            'Low-Cut': get_float(metadata["HP-H2 (Hz)"])
        }
        intensity_measures = {
            # All m - convert to cm
            'PGA': None,
            'PGV': None,
            'PGD': None
        }

        lup1 = 1. / get_float(metadata["Lowest Usable Freq - H1 (Hz)"])
        lup2 = 1. / get_float(metadata["Lowest Usable Freq - H2 (Hz)"])
        xcomp = Component(wfid,
                          "1",
                          ims=intensity_measures,
                          longest_period=lup1,
                          waveform_filter=filter_params1,
                          units=metadata["Unit"])
        ycomp = Component(wfid,
                          "2",
                          ims=intensity_measures,
                          longest_period=lup2,
                          waveform_filter=filter_params2,
                          units=metadata["Unit"])
        return xcomp, ycomp, None
    def _parse_processing_data(self, wfid, metadata):
        """
        Parses the information for each component
        """
        filter_params1 = {
            'Type': FILTER_TYPE[metadata["Type of Filter"]] ,
            'Order': None,
            'Passes': get_int(metadata['npass']),
            'NRoll': get_int(metadata['nroll']),
            'High-Cut': get_float(metadata["LP-H1 (Hz)"]),
            'Low-Cut': get_float(metadata["HP-H1 (Hz)"])}

        filter_params2 = {
            'Type': FILTER_TYPE[metadata["Type of Filter"]] ,
            'Order': None,
            'Passes': get_int(metadata['npass']),
            'NRoll': get_int(metadata['nroll']),
            'High-Cut': get_float(metadata["LP-H2 (Hz)"]),
            'Low-Cut': get_float(metadata["HP-H2 (Hz)"])}
        intensity_measures = {
            # All m - convert to cm
            'PGA': None,
            'PGV': None,
            'PGD': None
            }

        lup1 = 1. / get_float(metadata["Lowest Usable Freq - H1 (Hz)"])
        lup2 = 1. / get_float(metadata["Lowest Usable Freq - H2 (Hz)"])
        xcomp = Component(wfid, "1",
            ims=intensity_measures,
            longest_period=lup1,
            waveform_filter=filter_params1,
            units=metadata["Unit"])
        ycomp = Component(wfid, "2",
            ims=intensity_measures,
            longest_period=lup2,
            waveform_filter=filter_params2,
            units=metadata["Unit"]) 
        return xcomp, ycomp, None
Example #29
0
    def _parse_distance_data(self, event, site, metadata):
        """
        Read in the distance related metadata and return an instance of the
        :class: smtk.sm_database.RecordDistance
        """
        # Compute various distance metrics
        # Add calculation of Repi, Rhypo from event and station localizations
        # (latitudes, longitudes, depth, elevation)?
        target_site = Mesh(np.array([site.longitude]),
                           np.array([site.latitude]),
                           np.array([-site.altitude / 1000.0]))
        # Warning ratio fixed to 1.5
        ratio = 1.5
        if not event.rupture.area:
            event.rupture.area = WC1994().get_median_area(
                event.magnitude.value, None)
        surface_modeled = rcfg.create_planar_surface(
            Point(event.longitude, event.latitude, event.depth),
            event.mechanism.nodal_planes.nodal_plane_1['strike'],
            event.mechanism.nodal_planes.nodal_plane_1['dip'],
            event.rupture.area, ratio)
        hypocenter = rcfg.get_hypocentre_on_planar_surface(
            surface_modeled, event.rupture.hypo_loc)
        try:
            surface_modeled._create_mesh()
        except:
            dip = surface_modeled.get_dip()
            dip_dir = (surface_modeled.get_strike() - 90.) % 360.
            ztor = surface_modeled.top_left.depth
            d_x = ztor * np.tan(np.radians(90.0 - dip))
            top_left_surface = surface_modeled.top_left.point_at(
                d_x, -ztor, dip_dir)
            top_left_surface.depth = 0.
            top_right_surface = surface_modeled.top_right.point_at(
                d_x, -ztor, dip_dir)
            top_right_surface.depth = 0.
            surface_modeled = SimpleFaultSurface.from_fault_data(
                Line([top_left_surface,
                      top_right_surface]), surface_modeled.top_left.depth,
                surface_modeled.bottom_left.depth, surface_modeled.get_dip(),
                1.0)

        # Rhypo
        Rhypo, Repi, Rrup, Rjb, Ry0 = tuple(
            map(get_positive_float, [
                metadata[key] for key in [
                    "Hypocentral Distance (km)", "Epicentral Distance (km)",
                    "Rupture Distance (km)", "Joyner-Boore Distance (km)",
                    "Ry0 (km)"
                ]
            ]))
        Rx = get_float(metadata["Rx (km)"])  # Rx can be negative

        #Rhypo = get_float(metadata["Hypocentral Distance (km)"])
        if Rhypo is None or Rhypo < 0.0:
            Rhypo = hypocenter.distance_to_mesh(target_site)
        # Repi
        #Repi = get_float(metadata["Epicentral Distance (km)"])
        if Repi is None or Repi < 0.0:
            Repi = hypocenter.distance_to_mesh(target_site, with_depths=False)
        # Rrup
        #Rrup = get_float(metadata["Rupture Distance (km)"])
        if Rrup is None or Rrup < 0.0:
            Rrup = surface_modeled.get_min_distance(target_site)[0]
        # Rjb
        #Rjb = get_float(metadata["Joyner-Boore Distance (km)"])
        if Rjb is None or Rjb < 0.0:
            Rjb = surface_modeled.get_joyner_boore_distance(target_site)[0]
        # Need to check if Rx and Ry0 are consistant with the other metrics
        # when those are coming from the flatfile?
        # Rx
        #Rx = get_float(metadata["Rx (km)"])
        if Rx is None or Rx < 0.0:
            Rx = surface_modeled.get_rx_distance(target_site)[0]
        # Ry0
        Ry0 = get_float(metadata["Ry0 (km)"])
        if Ry0 is None or Ry0 < 0.0:
            Ry0 = surface_modeled.get_ry0_distance(target_site)[0]

        distance = RecordDistance(repi=Repi,
                                  rhypo=Rhypo,
                                  rjb=Rjb,
                                  rrup=Rrup,
                                  r_x=Rx,
                                  ry0=Ry0)
        distance.azimuth = get_float(metadata["Source to Site Azimuth (deg)"])
        #distance.hanging_wall = get_float(metadata["FW/HW Indicator"])
        if metadata["FW/HW Indicator"] == "HW":
            distance.hanging_wall = True
        elif metadata["FW/HW Indicator"] == "FW":
            distance.hanging_wall = False
        else:
            pass

        return distance

        return
    def _parse_time_history(self, ifile, component2parse):
        """
        Parses the time history and returns the time history of the specified
        component. All 3 components are provided in every ASA file. Note that
        components are defined with various names, and are not always
        given in the same order
        """

        # The components are definied using the following names
        comp_names = {'X': ['ENE', 'N90E', 'N90E;', 'N90W', 'N90W;',
                            'S90E', 'S90W', 'E--W', 'S9OE'],
                      'Y': ['ENN', 'N00E', 'N00E;', 'NOOE;', 'N00W',
                            'NOOW;', 'S00E', 'S00W', 'N--S', 'NOOE'],
                      'V': ['ENZ', 'V', 'V;+', '+V', 'Z', 'VERT']}

        # Read component names, which are given on line 107
        o = open(ifile, "r", encoding='iso-8859-1')
        r = o.readlines()
        components = list(r[107].split())

        # Check if any component names are repeated
        if any(components.count(x) > 1 for x in components):
            raise ValueError(
                "Some components %s in record %s have the same name"
                % (components, ifile))
        # Check if more than 3 components are given
        if len(components) > 3:
            raise ValueError(
                "More than 3 components %s in record %s"
                % (components, ifile))

        # Get acceleration data from correct column
        column = None
        for i in comp_names[component2parse]:
            if i == components[0]:
                column = 0
                try:
                    accel = np.genfromtxt(ifile, skip_header=109,
                        usecols=column, delimiter='', encoding='iso-8859-1')
                except:
                    raise ValueError(
                        "Check %s has 3 equal length time-series columns"
                        % ifile)
                break
            elif i == components[1]:
                column = 1
                try:
                    accel = np.genfromtxt(ifile, skip_header=109,
                        usecols=column, delimiter='', encoding='iso-8859-1')
                except:
                    raise ValueError(
                        "Check %s has 3 equal length time-series columns"
                        % ifile)
                break
            elif i == components[2]:
                column = 2
                try:
                    accel = np.genfromtxt(ifile, skip_header=109,
                        usecols=column, delimiter='', encoding='iso-8859-1')
                except:
                    raise ValueError(
                        "Check %s has 3 equal length time-series columns"
                        % ifile)
                break
        if column is None:
                raise ValueError(
                    "None of the components %s were found to be \n\
                    the %s component of file %s" %
                    (components, component2parse, ifile))

        # Build the metadata dictionary again
        metadata = _get_metadata_from_file(ifile)

        # Get units
        units_provided = metadata["UNIDADES DE LOS DATOS"]
        units = units_provided[units_provided.find("(") + 1:
                               units_provided.find(")")]

        # Get time step, naming is not consistent so allow for variation
        for i in metadata:
            if 'INTERVALO DE MUESTREO, C1' in i:
                self.time_step = get_float(metadata[i].split("/")[1])

        # Get number of time steps, use len(accel) because
        # sometimes "NUM. TOTAL DE MUESTRAS, C1-C6" is wrong
        self.number_steps = len(accel)

        output = {
            "Acceleration": convert_accel_units(accel, self.units),
            "Time": get_time_vector(self.time_step, self.number_steps),
            "Time-step": self.time_step,
            "Number Steps": self.number_steps,
            "Units": self.units,
            "PGA": max(abs(accel)),
            "PGD": None
        }

        return output
Example #31
0
    def _parse_time_history(self, ifile, component2parse):
        """
        Parses the time history and returns the time history of the specified
        component. All 3 components are provided in every ASA file. Note that
        components are defined with various names, and are not always
        given in the same order
        """

        # The components are definied using the following names
        comp_names = {
            'X':
            ['N90E', 'N90E;', 'N90W', 'N90W;', 'S90E', 'S90W', 'E--W', 'S9OE'],
            'Y':
            ['N00E', 'N00E;', 'N00W', 'N00W;', 'S00E', 'S00W', 'N--S', 'NOOE'],
            'V': ['V', 'V;+', '+V', 'Z', 'VERT']
        }

        # Read component names, which are given on line 107
        o = open(ifile, "r")
        r = o.readlines()
        components = list(r[107].split())

        # Check if any component names are repeated
        if any(components.count(x) > 1 for x in components):
            raise ValueError(
                "Some components %s in record %s have the same name" %
                (components, ifile))
        # Check if more than 3 components are given
        if len(components) > 3:
            raise ValueError("More than 3 components %s in record %s" %
                             (components, ifile))

        # Get acceleration data from correct column
        column = None
        for i in comp_names[component2parse]:
            if i == components[0]:
                column = 0
                try:
                    accel = np.genfromtxt(ifile,
                                          skip_header=109,
                                          usecols=column,
                                          delimiter='')
                except:
                    raise ValueError(
                        "Check %s has 3 equal length time-series columns" %
                        ifile)
                break
            elif i == components[1]:
                column = 1
                try:
                    accel = np.genfromtxt(ifile,
                                          skip_header=109,
                                          usecols=column,
                                          delimiter='')
                except:
                    raise ValueError(
                        "Check %s has 3 equal length time-series columns" %
                        ifile)
                break
            elif i == components[2]:
                column = 2
                try:
                    accel = np.genfromtxt(ifile,
                                          skip_header=109,
                                          usecols=column,
                                          delimiter='')
                except:
                    raise ValueError(
                        "Check %s has 3 equal length time-series columns" %
                        ifile)
                break
        if column is None:
            raise ValueError("None of the components %s were found to be \n\
                    the %s component of file %s" %
                             (components, component2parse, ifile))

        # Build the metadata dictionary again
        metadata = _get_metadata_from_file(ifile)

        # Get units
        units_provided = metadata["UNIDADES DE LOS DATOS"]
        units = units_provided[units_provided.find("(") +
                               1:units_provided.find(")")]

        # Get time step, naming is not consistent so allow for variation
        for i in metadata:
            if 'INTERVALO DE MUESTREO, C1' in i:
                self.time_step = get_float(metadata[i].split("/")[1])

        # Get number of time steps, use len(accel) because
        # sometimes "NUM. TOTAL DE MUESTRAS, C1-C6" is wrong
        self.number_steps = len(accel)

        output = {
            "Acceleration": convert_accel_units(accel, self.units),
            "Time": get_time_vector(self.time_step, self.number_steps),
            "Time-step": self.time_step,
            "Number Steps": self.number_steps,
            "Units": self.units,
            "PGA": max(abs(accel)),
            "PGD": None
        }

        return output
    def _parse_processing_data(self, wfid, metadata):
        """
        Parses the information for each component
        """
        if metadata["Type of Filter"]:
            filter_params1 = {
                'Type': FILTER_TYPE[metadata["Type of Filter"]],
                'Order': None,
                'Passes': get_positive_int(metadata['npass']),
                'NRoll': get_positive_int(metadata['nroll']),
                'High-Cut': get_positive_float(metadata["LP-H1 (Hz)"]),
                'Low-Cut': get_positive_float(metadata["HP-H1 (Hz)"])}

            filter_params2 = {
                'Type': FILTER_TYPE[metadata["Type of Filter"]],
                'Order': None,
                'Passes': get_positive_int(metadata['npass']),
                'NRoll': get_positive_int(metadata['nroll']),
                'High-Cut': get_positive_float(metadata["LP-H2 (Hz)"]),
                'Low-Cut': get_positive_float(metadata["HP-H2 (Hz)"])}
        else:
            filter_params1, filter_params2 = None, None

        intensity_measures = {
            # All m - convert to cm
            'PGA': None,
            'PGV': None,
            'PGD': None
            }
        luf1 = get_float(metadata["Lowest Usable Freq - H1 (Hz)"])
        if luf1 and luf1 > 0.0:
           lup1 = 1. / luf1
        else:
           lup1 = None
        luf2 = get_float(metadata["Lowest Usable Freq - H2 (Hz)"])
        if luf2 and luf2 > 0.0:
            lup2 = 1. / luf2
        else:
            lup2 = None
        xcomp = Component(wfid, "1",
            ims=intensity_measures,
            longest_period=lup1,
            waveform_filter=filter_params1,
            units=metadata["Unit (cm/s/s; m/s/s; g)"])

        ycomp = Component(wfid, "2",
            ims=intensity_measures,
            longest_period=lup2,
            waveform_filter=filter_params2,
            units=metadata["Unit (cm/s/s; m/s/s; g)"])
        
        luf3 = get_float(metadata["Lowest Usable Freq - V (Hz)"])
        if luf3 and luf3 > 0.0:
            filter_params3 = {
                'Type': FILTER_TYPE[metadata["Type of Filter"]],
                'Order': None,
                'Passes': get_int(metadata['npass']),
                'NRoll': get_int(metadata['nroll']),
                'High-Cut': get_float(metadata["LP-V (Hz)"]),
                'Low-Cut': get_float(metadata["HP-V (Hz)"])}
            lup3 = 1. / luf3
            zcomp = Component(wfid, "V",
                ims=intensity_measures,
                longest_period=lup3,
                waveform_filter=filter_params3,
                units=metadata["Unit (cm/s/s; m/s/s; g)"])
            return xcomp, ycomp, zcomp
        else:
            return xcomp, ycomp, None
Example #33
0
    def _parse_event(self, metadata, file_str):
        """
        Parses the event metadata to return an instance of the :class:
        smtk.sm_database.Earthquake
        """

        months = {
            'ENERO': 1,
            'FEBRERO': 2,
            'MARZO': 3,
            'ABRIL': 4,
            'MAYO': 5,
            'JUNIO': 6,
            'JULIO': 7,
            'AGOSTO': 8,
            'SEPTIEMBRE': 9,
            'OCTUBURE': 10,
            'NOVIEMBRE': 11,
            'DICIEMBRE': 12
        }

        # Date and time
        try:  # UNAM DATES
            year, month, day = (
                get_int(metadata["FECHA DEL SISMO [GMT]"].split("/")[0]),
                get_int(metadata["FECHA DEL SISMO [GMT]"].split("/")[1]),
                get_int(metadata["FECHA DEL SISMO [GMT]"].split("/")[2]))
        except:  # CICESE DATES
            year, month, day = (
                get_int(metadata["FECHA DEL SISMO (GMT)"][-4:]),
                months[metadata["FECHA DEL SISMO (GMT)"].split()[2]],
                get_int(metadata["FECHA DEL SISMO (GMT)"][:2]))

        # Get event time, naming is not consistent (e.g. 07.1, 00, 17,1)
        for i in metadata:
            if 'HORA EPICENTRO (GMT)' in i:
                hour, minute, second = (
                    get_int(metadata[i].split(":")[0]),
                    get_int(metadata[i].split(":")[1]),
                    int(
                        float(metadata[i].split(":")[2].replace(
                            "0", "", 1).replace(",", "."))))

        try:
            eq_datetime = datetime(year, month, day, hour, minute, second)
        except:
            raise ValueError("Record %s is missing event time" % file_str)

        # Event ID - No EVID, so use the date and time of the event
        eq_id = str(eq_datetime).replace(" ", "_")

        # Event Name
        eq_name = None

        # Get magnitudes, below are the different types given in ASA files
        moment_mag = None
        surface_mag = None
        body_mag = None
        c_mag = None
        l_mag = None
        e_mag = None
        a_mag = None
        m_mag = None

        mag_list = []
        mag = metadata["MAGNITUD(ES)"].split("/")
        for i in range(0, len(mag)):
            if mag[i][0:2] == "":
                continue
            if mag[i][0:2] == "Mw":
                m_w = get_float(mag[i][3:])
                moment_mag = Magnitude(m_w, "Mw")
                mag_list.append(moment_mag)
            if mag[i][0:2] == "Ms":
                m_s = get_float(mag[i][3:])
                surface_mag = Magnitude(m_s, "Ms")
                mag_list.append(surface_mag)
            if mag[i][0:2] == "Mb":
                m_b = get_float(mag[i][3:])
                body_mag = Magnitude(m_b, "Mb")
                mag_list.append(body_mag)
            if mag[i][0:2] == "Mc":
                m = get_float(mag[i][3:])
                c_mag = Magnitude(m, "Mc")
                mag_list.append(c_mag)
            if mag[i][0:2] == "Ml":
                m = get_float(mag[i][3:])
                l_mag = Magnitude(m, "Ml")
                mag_list.append(l_mag)
            if mag[i][0:2] == "Me" or mag[i][0:2] == "ME":
                m = get_float(mag[i][3:])
                e_mag = Magnitude(m, "Me")
                mag_list.append(e_mag)
            if mag[i][0:2] == "Ma":
                m = get_float(mag[i][3:])
                a_mag = Magnitude(m, "Ma")
                mag_list.append(a_mag)
            if mag[i][0:2] == "M=":
                m = get_float(mag[i][2:])
                m_mag = Magnitude(m, "M")
                mag_list.append(m_mag)

        # magnitude hierarchy for defining pref_mag
        if moment_mag is not None:
            pref_mag = moment_mag
        elif surface_mag is not None:
            pref_mag = surface_mag
        elif body_mag is not None:
            pref_mag = body_mag
        elif c_mag is not None:
            pref_mag = c_mag
        elif l_mag is not None:
            pref_mag = l_mag
        elif e_mag is not None:
            pref_mag = e_mag
        elif a_mag is not None:
            pref_mag = a_mag
        elif m_mag is not None:
            pref_mag = m_mag
        else:
            raise ValueError("Record %s has no magnitude!" % file_str)

        # Get focal mechanism data (not given in ASA file)
        foc_mech = FocalMechanism(eq_id,
                                  eq_name,
                                  None,
                                  None,
                                  mechanism_type=None)

        # Get depths, naming is not consistent so allow for variation
        for i in metadata:
            if 'PROFUNDIDAD ' in i:
                # assume <5km = 5km
                evtdepth = get_float(re.sub('[ <>]', '', metadata[i]))
        if evtdepth is None:
            raise ValueError("Record %s is missing event depth" % file_str)

        # Build event
        eqk = Earthquake(
            eq_id, eq_name, eq_datetime,
            get_float(metadata["COORDENADAS DEL EPICENTRO"].split(" ")[3]),
            get_float(metadata["COORDENADAS DEL EPICENTRO"].split(" ")[0]),
            evtdepth, pref_mag, foc_mech)

        eqk.magnitude_list = mag_list

        return eqk
    def _parse_distance_data(self, event, site, metadata):
        """
        Read in the distance related metadata and return an instance of the
        :class: smtk.sm_database.RecordDistance
        """
        # Compute various distance metrics
        # Add calculation of Repi, Rhypo from event and station localizations 
        # (latitudes, longitudes, depth, elevation)?
        target_site = Mesh(np.array([site.longitude]),
                           np.array([site.latitude]),
                           np.array([-site.altitude / 1000.0]))
        # Warning ratio fixed to 1.5
        ratio=1.5
        if not event.rupture.area:
            event.rupture.area = WC1994().get_median_area(event.magnitude.value,
                                                          None)
        surface_modeled = rcfg.create_planar_surface(
            Point(event.longitude, event.latitude, event.depth),
            event.mechanism.nodal_planes.nodal_plane_1['strike'],
            event.mechanism.nodal_planes.nodal_plane_1['dip'],
            event.rupture.area,
            ratio)
        hypocenter = rcfg.get_hypocentre_on_planar_surface(
            surface_modeled,
            event.rupture.hypo_loc)
        try:
            surface_modeled._create_mesh()
        except:
            dip = surface_modeled.get_dip()
            dip_dir = (surface_modeled.get_strike() - 90.) % 360.
            ztor = surface_modeled.top_left.depth
            d_x = ztor * np.tan(np.radians(90.0 - dip))
            top_left_surface = surface_modeled.top_left.point_at(d_x,
                                                                 -ztor,
                                                                 dip_dir)
            top_left_surface.depth = 0.
            top_right_surface = surface_modeled.top_right.point_at(d_x,
                                                                   -ztor,
                                                                   dip_dir)
            top_right_surface.depth = 0.
            surface_modeled = SimpleFaultSurface.from_fault_data(
                Line([top_left_surface, top_right_surface]),
                surface_modeled.top_left.depth,
                surface_modeled.bottom_left.depth,
                surface_modeled.get_dip(),
                1.0)
        
        # Rhypo
        Rhypo, Repi, Rrup, Rjb, Ry0 = tuple(map(
            get_positive_float, [metadata[key] for key in [
                "Hypocentral Distance (km)", "Epicentral Distance (km)",
                "Rupture Distance (km)", "Joyner-Boore Distance (km)",
                "Ry0 (km)"]]))
        Rx = get_float(metadata["Rx (km)"]) # Rx can be negative

        #Rhypo = get_float(metadata["Hypocentral Distance (km)"])
        if Rhypo is None or Rhypo < 0.0:
            Rhypo = hypocenter.distance_to_mesh(target_site)
        # Repi
        #Repi = get_float(metadata["Epicentral Distance (km)"])
        if Repi is None or Repi < 0.0:
            Repi= hypocenter.distance_to_mesh(target_site, with_depths=False)
        # Rrup
        #Rrup = get_float(metadata["Rupture Distance (km)"])
        if Rrup is None or Rrup < 0.0:
            Rrup = surface_modeled.get_min_distance(target_site)[0]
        # Rjb
        #Rjb = get_float(metadata["Joyner-Boore Distance (km)"])
        if Rjb is None or Rjb < 0.0:
            Rjb = surface_modeled.get_joyner_boore_distance(
                target_site)[0]
        # Need to check if Rx and Ry0 are consistant with the other metrics
        # when those are coming from the flatfile?
        # Rx
        #Rx = get_float(metadata["Rx (km)"])
        if Rx is None or Rx < 0.0:
            Rx = surface_modeled.get_rx_distance(target_site)[0]
        # Ry0
        Ry0 = get_float(metadata["Ry0 (km)"])
        if Ry0 is None or Ry0 < 0.0:
            Ry0 = surface_modeled.get_ry0_distance(target_site)[0]
        
        distance = RecordDistance(
            repi = Repi,
            rhypo = Rhypo,
            rjb = Rjb,
            rrup = Rrup,
            r_x = Rx,
            ry0 = Ry0)
        distance.azimuth = get_float(metadata["Source to Site Azimuth (deg)"])
        #distance.hanging_wall = get_float(metadata["FW/HW Indicator"])
        if metadata["FW/HW Indicator"] == "HW":
            distance.hanging_wall = True
        elif metadata["FW/HW Indicator"] == "FW":
            distance.hanging_wall = False
        else:
            pass
        
        return distance
    
        return
 def _parse_distance_data(self, event, site, metadata):
     """
     Read in the distance related metadata and return an instance of the
     :class: smtk.sm_database.RecordDistance
     """
     # Compute various distance metrics
     # Add calculation of Repi, Rhypo from event and station localizations 
     # (latitudes, longitudes, depth, elevation)?
     target_site = Mesh(np.array([site.longitude]),
                        np.array([site.latitude]),
                        np.array([-site.altitude / 1000.0]))
     # Warning ratio fixed to 1.5
     ratio=1.5
     surface_modeled = rcfg.create_planar_surface(
         Point(event.longitude, event.latitude, event.depth),
         event.mechanism.nodal_planes.nodal_plane_1['strike'],
         event.mechanism.nodal_planes.nodal_plane_1['dip'],
         event.rupture.area,
         ratio)
     hypocenter = rcfg.get_hypocentre_on_planar_surface(
         surface_modeled,
         event.rupture.hypo_loc)
     try:
         surface_modeled._create_mesh()
     except:
         dip = surface_modeled.get_dip()
         dip_dir = (surface_modeled.get_strike() - 90.) % 360.
         ztor = surface_modeled.top_left.depth
         d_x = ztor * np.tan(np.radians(90.0 - dip))
         top_left_surface = surface_modeled.top_left.point_at(d_x,
                                                              -ztor,
                                                              dip_dir)
         top_left_surface.depth = 0.
         top_right_surface = surface_modeled.top_right.point_at(d_x,
                                                                -ztor,
                                                                dip_dir)
         top_right_surface.depth = 0.
         surface_modeled = SimpleFaultSurface.from_fault_data(
             Line([top_left_surface, top_right_surface]),
             surface_modeled.top_left.depth,
             surface_modeled.bottom_left.depth,
             surface_modeled.get_dip(),
             1.0)
         
     # Rhypo
     Rhypo = get_float(metadata["Hypocentral Distance (km)"])
     if Rhypo is None:
         Rhypo = hypocenter.distance_to_mesh(target_site)
     # Repi
     Repi = get_float(metadata["Epicentral Distance (km)"])
     if Repi is None:
         Repi= hypocenter.distance_to_mesh(target_site, with_depths=False)
     # Rrup
     Rrup = get_float(metadata["Rupture Distance (km)"])
     if Rrup is None:
         Rrup = surface_modeled.get_min_distance(target_site)
     # Rjb
     Rjb = get_float(metadata["Joyner-Boore Distance (km)"])
     if Rjb is None:
         Rjb = surface_modeled.get_joyner_boore_distance(target_site)
     # Rcdpp
     Rcdpp = get_float(metadata["Rcdpp"])
     if Rcdpp is None:
         Rcdpp = surface_modeled.get_cdppvalue(target_site)
     # Need to check if Rx and Ry0 are consistant with the other metrics
     # when those are coming from the flatfile?
     # Rx
     Rx = surface_modeled.get_rx_distance(target_site)
     # Ry0
     Ry0 = surface_modeled.get_ry0_distance(target_site)
     
     distance = RecordDistance(
         repi = float(Repi),
         rhypo = float(Rhypo),
         rjb = float(Rjb),
         rrup = float(Rrup),
         r_x = float(Rx),
         ry0 = float(Ry0),
         rcdpp = float(Rcdpp) )
     distance.azimuth = get_float(metadata["Source to Site Azimuth (deg)"])
     #distance.hanging_wall = get_float(metadata["FW/HW Indicator"])
     if metadata["FW/HW Indicator"] == "HW":
         distance.hanging_wall = True
     elif metadata["FW/HW Indicator"] == "FW":
         distance.hanging_wall = False
     else:
         pass
     
     return distance
Example #36
0
    def _parse_processing_data(self, wfid, metadata):
        """
        Parses the information for each component
        """
        if metadata["Type of Filter"]:
            filter_params1 = {
                'Type': FILTER_TYPE[metadata["Type of Filter"]],
                'Order': None,
                'Passes': get_positive_int(metadata['npass']),
                'NRoll': get_positive_int(metadata['nroll']),
                'High-Cut': get_positive_float(metadata["LP-H1 (Hz)"]),
                'Low-Cut': get_positive_float(metadata["HP-H1 (Hz)"])}

            filter_params2 = {
                'Type': FILTER_TYPE[metadata["Type of Filter"]],
                'Order': None,
                'Passes': get_positive_int(metadata['npass']),
                'NRoll': get_positive_int(metadata['nroll']),
                'High-Cut': get_positive_float(metadata["LP-H2 (Hz)"]),
                'Low-Cut': get_positive_float(metadata["HP-H2 (Hz)"])}
        else:
            filter_params1, filter_params2 = None, None

        intensity_measures = {
            # All m - convert to cm
            'PGA': None,
            'PGV': None,
            'PGD': None
            }
        luf1 = get_float(metadata["Lowest Usable Freq - H1 (Hz)"])
        if luf1 and luf1 > 0.0:
           lup1 = 1. / luf1
        else:
           lup1 = None
        luf2 = get_float(metadata["Lowest Usable Freq - H2 (Hz)"])
        if luf2 and luf2 > 0.0:
            lup2 = 1. / luf2
        else:
            lup2 = None
        xcomp = Component(wfid, "1",
            ims=intensity_measures,
            longest_period=lup1,
            waveform_filter=filter_params1,
            units=metadata["Unit (cm/s/s; m/s/s; g)"])

        ycomp = Component(wfid, "2",
            ims=intensity_measures,
            longest_period=lup2,
            waveform_filter=filter_params2,
            units=metadata["Unit (cm/s/s; m/s/s; g)"])
        
        luf3 = get_float(metadata["Lowest Usable Freq - V (Hz)"])
        if luf3 and luf3 > 0.0:
            filter_params3 = {
                'Type': FILTER_TYPE[metadata["Type of Filter"]],
                'Order': None,
                'Passes': get_int(metadata['npass']),
                'NRoll': get_int(metadata['nroll']),
                'High-Cut': get_float(metadata["LP-V (Hz)"]),
                'Low-Cut': get_float(metadata["HP-V (Hz)"])}
            lup3 = 1. / luf3
            zcomp = Component(wfid, "V",
                ims=intensity_measures,
                longest_period=lup3,
                waveform_filter=filter_params3,
                units=metadata["Unit (cm/s/s; m/s/s; g)"])
            return xcomp, ycomp, zcomp
        else:
            return xcomp, ycomp, None
Example #37
0
    def _get_focal_mechanism(self, eq_id, eq_name, metadata):
        """
        Returns the focal mechanism information as an instance of the
        :class: smtk.sigma_database.FocalMechanism
        """
        nodal_planes = GCMTNodalPlanes()
        # By default nodal plane 1 is assumed to be the fault plane in smtk.
        # Depending on parameter fault_plane import correct angles in nodal
        # planes 1 and 2 (1 being the fault plane)
        if metadata['Fault Plane (1; 2; X)'] == '1':
            nodal_planes.nodal_plane_1 = {
                "strike": get_float(metadata['Nodal Plane 1 Strike (deg)']),
                "dip": get_float(metadata['Nodal Plane 1 Dip (deg)']),
                "rake": get_float(metadata['Nodal Plane 1 Rake Angle (deg)'])}

            nodal_planes.nodal_plane_2 = {
                "strike": get_float(metadata['Nodal Plane 2 Strike (deg)']),
                "dip": get_float(metadata['Nodal Plane 2 Dip (deg)']),
                "rake": get_float(metadata['Nodal Plane 2 Rake Angle (deg)'])}
        elif metadata['Fault Plane (1; 2; X)'] == '2':
            nodal_planes.nodal_plane_1 = {
                "strike": get_float(metadata['Nodal Plane 2 Strike (deg)']),
                "dip": get_float(metadata['Nodal Plane 2 Dip (deg)']),
                "rake": get_float(metadata['Nodal Plane 2 Rake Angle (deg)'])}

            nodal_planes.nodal_plane_2 = {
                "strike": get_float(metadata['Nodal Plane 1 Strike (deg)']),
                "dip": get_float(metadata['Nodal Plane 1 Dip (deg)']),
                "rake": get_float(metadata['Nodal Plane 1 Rake Angle (deg)'])}
        elif metadata['Fault Plane (1; 2; X)'] == 'X':
            # Check if values for strike or dip are given otherwise set 
            # strike=0 and dip=90 and fill strike and dip for fault plane 1
            # What can we do for rake?
            strike = get_float(metadata['Nodal Plane 1 Strike (deg)'])
            if strike is None:
                strike = get_float(metadata['Nodal Plane 2 Strike (deg)'])
            if strike is None:
                strike = 0.0
            dip = get_float(metadata['Nodal Plane 1 Dip (deg)'])
            if dip is None:
                dip = get_float(metadata['Nodal Plane 2 Dip (deg)'])
            if dip is None:
                dip = 90.0
            nodal_planes.nodal_plane_1 = {"strike": strike,
                                 "dip": dip,
                                 "rake": None}
            nodal_planes.nodal_plane_2 = {"strike": None,
                                 "dip": None,
                                 "rake": None}

        nodal_planes = self._check_mechanism(nodal_planes)
        principal_axes = GCMTPrincipalAxes()
        mech_type =\
            NEW_MECHANISM_TYPE[metadata["Style-of-Faulting (S; R; N; U)"]]
        return FocalMechanism(eq_id, eq_name, nodal_planes, principal_axes,
            mechanism_type=mech_type)
Example #38
0
    def _parse_event_data(self, metadata):
        """
        Read in the distance related metadata and return an instance of the
        :class: smtk.sm_database.Earthquake

        """
        data_fields = ['Month', 'Day', 'Hour', 'Minute', 'Second']
        for f in data_fields:
            metadata[f] = metadata[f].zfill(2)

        # Date and Time
        year, month, day, hour, minute, second = self._validate_datetime(
            metadata)
        #year = get_int(metadata["Year"])
        #month = get_int(metadata["Month"])
        #day = get_int(metadata["Day"])
        #hour = get_int(metadata["Hour"])
        #minute = get_int(metadata["Minute"])
        #second = get_int(metadata["Second"])
        eq_datetime = datetime(year, month, day, hour, minute, second)
        # Event ID and Name
        eq_id = metadata["EQID"]
        eq_name = metadata["Earthquake Name"]
        # Focal Mechanism
        focal_mechanism = self._get_focal_mechanism(eq_id, eq_name, metadata)
        
        focal_mechanism.scalar_moment = get_float(metadata["Mo (dyne.cm)"]) *\
            1E-7
        # Read magnitude
        pref_mag = Magnitude(get_float(metadata["Magnitude"]),
                             metadata["Magnitude type"],
                             sigma=get_float(metadata["Magnitude uncertainty"]))
        # Create Earthquake Class
        eqk = Earthquake(eq_id, eq_name, eq_datetime,
            get_float(metadata["Epicenter Longitude (deg; positive E)"]),
            get_float(metadata["Epicenter Latitude (deg; positive N)"]),
            get_float(metadata["Hypocenter Depth (km)"]),
            pref_mag,
            focal_mechanism,
            metadata["Country"])

        # hypocenter location
        f1 = get_float(metadata[
            "Along-strike Hypocenter location " +
            "on the fault (fraction between 0 and 1)"])
        f2 = get_float(metadata[
            "Along-width Hypocenter location " +
            "on the fault (fraction between 0 and 1)"])
        if f1 is None or f2 is None:
            hypo_loc = (0.5, 0.7)
        else:
            hypo_loc = (f1, f2)

        eqk.tectonic_region = metadata["Tectonic environment (Crustal; Inslab; Interface; Stable; Geothermal; Volcanic; Oceanic_crust)"]
        if (eqk.tectonic_region == "Stable" or
            eqk.tectonic_region == "Crustal" or
            eqk.tectonic_region == "Oceanic_crust"):
            msr=WC1994()
        elif eqk.tectonic_region == "Inslab":
            msr=StrasserIntraslab()
        elif eqk.tectonic_region == "Interface":
            msr=StrasserInterface()

        # Warning rake set to 0.0 in scaling relationship - applies only
        # to WC1994
        area = msr.get_median_area(pref_mag.value, 0.0)
        aspect_ratio = 1.5
        width_model = np.sqrt(area / aspect_ratio)
        length_model = aspect_ratio * width_model
        ztor_model = eqk.depth - width_model / 2.
        if ztor_model < 0:
            ztor_model = 0.0

        length = get_positive_float(metadata["Fault Rupture Length (km)"])
        if length is None:
            length = length_model
        width = get_positive_float(metadata["Fault Rupture Width (km)"])
        if width is None:
            width = width_model
        ztor = get_float(metadata["Depth to Top Of Fault Rupture Model"])
        if ztor is None:
            ztor=ztor_model

        # Rupture
        eqk.rupture = Rupture(eq_id,
                              eq_name,
                              pref_mag,
                              length,
                              width,
                              ztor,
                              hypo_loc=hypo_loc)
#            get_float(metadata["Fault Rupture Length (km)"]),
#            get_float(metadata["Fault Rupture Width (km)"]),
#            get_float(metadata["Depth to Top Of Fault Rupture Model"]),
#            hypo_loc=hypo_loc)
        eqk.rupture.get_area()
        return eqk
    def _parse_event_data(self, metadata):
        """
        Read in the distance related metadata and return an instance of the
        :class: smtk.sm_database.Earthquake

        """
        data_fields = ['Month', 'Day', 'Hour', 'Minute', 'Second']
        for f in data_fields:
            metadata[f] = metadata[f].zfill(2)

        # Date and Time
        year = get_int(metadata["Year"])
        month = get_int(metadata["Month"])
        day = get_int(metadata["Day"])
        hour = get_int(metadata["Hour"])
        minute = get_int(metadata["Minute"])
        second = get_int(metadata["Second"])
        eq_datetime = datetime(year, month, day, hour, minute, second)
        # Event ID and Name
        eq_id = metadata["EQID"]
        eq_name = metadata["Earthquake Name"]
        # Focal Mechanism
        focal_mechanism = self._get_focal_mechanism(eq_id, eq_name, metadata)
        
        focal_mechanism.scalar_moment = get_float(metadata["Mo (dyne.cm)"]) *\
            1E-7
        # Read magnitude
        pref_mag = Magnitude(get_float(metadata["Magnitude"]),
                             metadata["Magnitude type"],
                             sigma=get_float(metadata["Magnitude uncertainty"]))
        # Create Earthquake Class
        eqk = Earthquake(eq_id, eq_name, eq_datetime,
            get_float(metadata["Epicenter Longitude (deg; positive E)"]),
            get_float(metadata["Epicenter Latitude (deg; positive N)"]),
            get_float(metadata["Hypocenter Depth (km)"]),
            pref_mag,
            focal_mechanism,
            metadata["Country"])

        # hypocenter location
        f1 = get_float(metadata[
            "Along-strike Hypocenter location " +
            "on the fault (fraction between 0 and 1)"])
        f2 = get_float(metadata[
            "Along-width Hypocenter location " +
            "on the fault (fraction between 0 and 1)"])
        if f1 is None or f2 is None:
            hypo_loc = (0.5, 0.7)
        else:
            hypo_loc = (f1, f2)

        evt_tectonic_region = metadata["Tectonic environment (Crustal; Inslab; Interface; Stable; Geothermal; Volcanic; Oceanic_crust)"]
        if evt_tectonic_region == "Stable" or evt_tectonic_region == "Crustal":
            msr=WC1994()
        elif evt_tectonic_region == "Inslab":
            msr=StrasserIntraslab()
        elif evt_tectonic_region == "Interface":
            msr=StrasserInterface()

        # Warning rake set to 0.0 in scaling relationship - applies only
        # to WC1994
        area = msr.get_median_area(pref_mag.value, 0.0)
        aspect_ratio = 1.5
        width_model = np.sqrt(area / aspect_ratio)
        length_model = aspect_ratio * width_model
        ztor_model = eqk.depth - width_model / 2.
        if ztor_model < 0:
            ztor_model = 0.0

        length = get_float(metadata["Fault Rupture Length (km)"])
        if length is None:
            length = length_model
        width = get_float(metadata["Fault Rupture Width (km)"])
        if width is None:
            width = width_model
        ztor = get_float(metadata["Depth to Top Of Fault Rupture Model"])
        if ztor is None:
            ztor=ztor_model

        # Rupture
        eqk.rupture = Rupture(eq_id,
                              length,
                              width,
                              ztor,
                              hypo_loc=hypo_loc)
#            get_float(metadata["Fault Rupture Length (km)"]),
#            get_float(metadata["Fault Rupture Width (km)"]),
#            get_float(metadata["Depth to Top Of Fault Rupture Model"]),
#            hypo_loc=hypo_loc)
        eqk.rupture.get_area()
        return eqk
    def _get_focal_mechanism(self, eq_id, eq_name, metadata):
        """
        Returns the focal mechanism information as an instance of the
        :class: smtk.sigma_database.FocalMechanism
        """
        nodal_planes = GCMTNodalPlanes()
        # By default nodal plane 1 is assumed to be the fault plane in smtk.
        # Depending on parameter fault_plane import correct angles in nodal
        # planes 1 and 2 (1 being the fault plane)
        if metadata['Fault Plane (1; 2; X)'] == '1':
            nodal_planes.nodal_plane_1 = {
                "strike": get_float(metadata['Nodal Plane 1 Strike (deg)']),
                "dip": get_float(metadata['Nodal Plane 1 Dip (deg)']),
                "rake": get_float(metadata['Nodal Plane 1 Rake Angle (deg)'])}

            nodal_planes.nodal_plane_2 = {
                "strike": get_float(metadata['Nodal Plane 2 Strike (deg)']),
                "dip": get_float(metadata['Nodal Plane 2 Dip (deg)']),
                "rake": get_float(metadata['Nodal Plane 2 Rake Angle (deg)'])}
        elif metadata['Fault Plane (1; 2; X)'] == '2':
            nodal_planes.nodal_plane_1 = {
                "strike": get_float(metadata['Nodal Plane 2 Strike (deg)']),
                "dip": get_float(metadata['Nodal Plane 2 Dip (deg)']),
                "rake": get_float(metadata['Nodal Plane 2 Rake Angle (deg)'])}

            nodal_planes.nodal_plane_2 = {
                "strike": get_float(metadata['Nodal Plane 1 Strike (deg)']),
                "dip": get_float(metadata['Nodal Plane 1 Dip (deg)']),
                "rake": get_float(metadata['Nodal Plane 1 Rake Angle (deg)'])}
        elif metadata['Fault Plane (1; 2; X)'] == 'X':
            # Check if values for strike or dip are given otherwise set 
            # strike=0 and dip=90 and fill strike and dip for fault plane 1
            # What can we do for rake?
            strike = get_float(metadata['Nodal Plane 1 Strike (deg)'])
            if strike is None:
                strike = get_float(metadata['Nodal Plane 2 Strike (deg)'])
            if strike is None:
                strike = 0.0
            dip = get_float(metadata['Nodal Plane 1 Dip (deg)'])
            if dip is None:
                dip = get_float(metadata['Nodal Plane 2 Dip (deg)'])
            if dip is None:
                dip = 90.0
            nodal_planes.nodal_plane_1 = {"strike": strike,
                                 "dip": dip,
                                 "rake": None}
            nodal_planes.nodal_plane_2 = {"strike": None,
                                 "dip": None,
                                 "rake": None}

        principal_axes = GCMTPrincipalAxes()
        mech_type =\
            NEW_MECHANISM_TYPE[metadata["Style-of-Faulting (S; R; N; U)"]]
        return FocalMechanism(eq_id, eq_name, nodal_planes, principal_axes,
            mechanism_type=mech_type)
    def _parse_event(self, metadata, file_str):
        """
        Parses the event metadata to return an instance of the :class:
        smtk.sm_database.Earthquake. Coordinates in western hemisphere
        are returned as negative values.
        """

        months = {'ENERO': 1, 'FEBRERO': 2, 'MARZO': 3, 'ABRIL': 4, 'MAYO': 5,
                 'JUNIO': 6, 'JULIO': 7, 'AGOSTO': 8, 'SEPTIEMBRE': 9,
                 'OCTUBURE': 10, 'NOVIEMBRE': 11, 'DICIEMBRE': 12}

        months_abrev = {'ENE': 1, 'FEB': 2, 'MAR': 3, 'ABR': 4, 'MAY': 5,
                 'JUN': 6, 'JUL': 7, 'AGO': 8, 'SEP': 9,
                 'OCT': 10, 'NOV': 11, 'DIC': 12}

        # Date and time
        if 'CICESE' in metadata["INSTITUCION RESPONSABLE"]:
            year, month, day = (
                get_int(metadata["FECHA DEL SISMO (GMT)"][-4:]),
                months[metadata["FECHA DEL SISMO (GMT)"].split()[2]],
                get_int(metadata["FECHA DEL SISMO (GMT)"][:2]))
        elif 'CIRES' in metadata["INSTITUCION RESPONSABLE"]:
            year, month, day = (
                get_int('20'+metadata["FECHA DEL SISMO (GMT)"][-2:]),
                months_abrev[metadata["FECHA DEL SISMO (GMT)"].split('/')[1]],
                get_int(metadata["FECHA DEL SISMO (GMT)"][:2]))
        # UNAM data, which is not always indicated in "INSTITUCION RESPONSABLE"
        else:
            year, month, day = (
                get_int(metadata["FECHA DEL SISMO [GMT]"].split("/")[0]),
                get_int(metadata["FECHA DEL SISMO [GMT]"].split("/")[1]),
                get_int(metadata["FECHA DEL SISMO [GMT]"].split("/")[2]))

        # Get event time, naming is not consistent (e.g. 07.1, 00, 17,1)
        for i in metadata:
            if 'HORA EPICENTRO (GMT)' in i:
                hour, minute, second = (get_int(metadata[i].split(":")[0]),
                                        get_int(metadata[i].split(":")[1]),
                                        int(float(metadata[i].split(":")[2].
                                            replace("0", "", 1).
                                            replace(",", "."))))
        try:
            eq_datetime = datetime(year, month, day, hour, minute, second)
        except:
            raise ValueError("Record %s is missing event time" % file_str)

        # Event ID - No EVID, so use the date and time of the event
        eq_id = str(eq_datetime).replace(" ", "_")

        # Event Name
        eq_name = None

        # Get magnitudes, below are the different types given in ASA files
        moment_mag = None
        surface_mag = None
        body_mag = None
        c_mag = None
        l_mag = None
        e_mag = None
        a_mag = None
        m_mag = None

        mag_list = []
        mag = metadata["MAGNITUD(ES)"].split("/")
        for i in range(0, len(mag)):
            if mag[i][0:2] == "":
                continue
            if mag[i][0:2] == "Mw":
                m_w = get_float(mag[i][3:])
                moment_mag = Magnitude(m_w, "Mw")
                mag_list.append(moment_mag)
            if mag[i][0:2] == "Ms":
                m_s = get_float(mag[i][3:])
                surface_mag = Magnitude(m_s, "Ms")
                mag_list.append(surface_mag)
            if mag[i][0:2] == "Mb":
                m_b = get_float(mag[i][3:])
                body_mag = Magnitude(m_b, "Mb")
                mag_list.append(body_mag)
            if mag[i][0:2] == "Mc":
                m = get_float(mag[i][3:])
                c_mag = Magnitude(m, "Mc")
                mag_list.append(c_mag)
            if mag[i][0:2] == "Ml":
                m = get_float(mag[i][3:])
                l_mag = Magnitude(m, "Ml")
                mag_list.append(l_mag)
            if mag[i][0:2] == "Me" or mag[i][0:2] == "ME":
                m = get_float(mag[i][3:])
                e_mag = Magnitude(m, "Me")
                mag_list.append(e_mag)
            if mag[i][0:2] == "Ma":
                m = get_float(mag[i][3:])
                a_mag = Magnitude(m, "Ma")
                mag_list.append(a_mag)
            if mag[i][0:2] == "M=":
                m = get_float(mag[i][2:])
                m_mag = Magnitude(m, "M")
                mag_list.append(m_mag)

        # magnitude hierarchy for defining pref_mag
        if moment_mag is not None:
            pref_mag = moment_mag
        elif surface_mag is not None:
            pref_mag = surface_mag
        elif body_mag is not None:
            pref_mag = body_mag
        elif c_mag is not None:
            pref_mag = c_mag
        elif l_mag is not None:
            pref_mag = l_mag
        elif e_mag is not None:
            pref_mag = e_mag
        elif a_mag is not None:
            pref_mag = a_mag
        elif m_mag is not None:
            pref_mag = m_mag
        else:
            raise ValueError("Record %s has no magnitude!" % file_str)

        # Get focal mechanism data (not given in ASA file)
        foc_mech = FocalMechanism(eq_id,
                                  eq_name,
                                  None,
                                  None,
                                  mechanism_type=None)

        # Get depths, naming is not consistent so allow for variation
        for i in metadata:
                if 'PROFUNDIDAD ' in i:
                    # assume <5km = 5km
                    evtdepth = get_float(re.sub('[ <>]', '', metadata[i]))
        if evtdepth is None:
            raise ValueError("Record %s is missing event depth" % file_str)

        # Build event
        eqk = Earthquake(
            eq_id,
            eq_name,
            eq_datetime,
            -get_float(metadata["COORDENADAS DEL EPICENTRO"].split(" ")[3]),
            get_float(metadata["COORDENADAS DEL EPICENTRO"].split(" ")[0]),
            evtdepth,
            pref_mag,
            foc_mech)

        eqk.magnitude_list = mag_list

        return eqk
Example #42
0
 def _parse_distance_data(self, event, site, metadata):
     """
     Read in the distance related metadata and return an instance of the
     :class: smtk.sm_database.RecordDistance
     """
     # Compute various distance metrics
     # Add calculation of Repi, Rhypo from event and station localizations 
     # (latitudes, longitudes, depth, elevation)?
     target_site = Mesh(np.array([site.longitude]),
                        np.array([site.latitude]),
                        np.array([-site.altitude / 1000.0]))
     # Warning ratio fixed to 1.5
     ratio=1.5
     surface_modeled = rcfg.create_planar_surface(
         Point(event.longitude, event.latitude, event.depth),
         event.mechanism.nodal_planes.nodal_plane_1['strike'],
         event.mechanism.nodal_planes.nodal_plane_1['dip'],
         event.rupture.area,
         ratio)
     hypocenter = rcfg.get_hypocentre_on_planar_surface(
         surface_modeled,
         event.rupture.hypo_loc)
     try:
         surface_modeled._create_mesh()
     except:
         dip = surface_modeled.get_dip()
         dip_dir = (surface_modeled.get_strike() - 90.) % 360.
         ztor = surface_modeled.top_left.depth
         d_x = ztor * np.tan(np.radians(90.0 - dip))
         top_left_surface = surface_modeled.top_left.point_at(d_x,
                                                              -ztor,
                                                              dip_dir)
         top_left_surface.depth = 0.
         top_right_surface = surface_modeled.top_right.point_at(d_x,
                                                                -ztor,
                                                                dip_dir)
         top_right_surface.depth = 0.
         surface_modeled = SimpleFaultSurface.from_fault_data(
             Line([top_left_surface, top_right_surface]),
             surface_modeled.top_left.depth,
             surface_modeled.bottom_left.depth,
             surface_modeled.get_dip(),
             1.0)
         
     # Rhypo
     Rhypo = get_float(metadata["Hypocentral Distance (km)"])
     if Rhypo is None:
         Rhypo = hypocenter.distance_to_mesh(target_site)
     # Repi
     Repi = get_float(metadata["Epicentral Distance (km)"])
     if Repi is None:
         Repi= hypocenter.distance_to_mesh(target_site, with_depths=False)
     # Rrup
     Rrup = get_float(metadata["Rupture Distance (km)"])
     if Rrup is None:
         Rrup = surface_modeled.get_min_distance(target_site)
     # Rjb
     Rjb = get_float(metadata["Joyner-Boore Distance (km)"])
     if Rjb is None:
         Rjb = surface_modeled.get_joyner_boore_distance(target_site)
     # Rcdpp
     Rcdpp = get_float(metadata["Rcdpp"])
     if Rcdpp is None:
         Rcdpp = surface_modeled.get_cdppvalue(target_site)
     # Need to check if Rx and Ry0 are consistant with the other metrics
     # when those are coming from the flatfile?
     # Rx
     Rx = surface_modeled.get_rx_distance(target_site)
     # Ry0
     Ry0 = surface_modeled.get_ry0_distance(target_site)
     
     distance = RecordDistance(
         repi = float(Repi),
         rhypo = float(Rhypo),
         rjb = float(Rjb),
         rrup = float(Rrup),
         r_x = float(Rx),
         ry0 = float(Ry0),
         rcdpp = float(Rcdpp) )
     distance.azimuth = get_float(metadata["Source to Site Azimuth (deg)"])
     #distance.hanging_wall = get_float(metadata["FW/HW Indicator"])
     if metadata["FW/HW Indicator"] == "HW":
         distance.hanging_wall = True
     elif metadata["FW/HW Indicator"] == "FW":
         distance.hanging_wall = False
     else:
         pass
     
     return distance
    def _parse_event_data(self, metadata):
        """
        Read in the distance related metadata and return an instance of the
        :class: smtk.sm_database.Earthquake

        """
        metadata["MODY"] = metadata["MODY"].zfill(4)
        metadata["HRMN"] = metadata["HRMN"].zfill(4)
        # Date and Time
        year = get_int(metadata["YEAR"])
        month = get_int(metadata["MODY"][:2])
        day = get_int(metadata["MODY"][2:])
        hour = get_int(metadata["HRMN"][:2])
        minute = get_int(metadata["HRMN"][2:])
        eq_datetime = datetime(year, month, day, hour, minute)
        # Event ID and Name
        eq_id = metadata["EQID"]
        eq_name = metadata["Earthquake Name"]
        # Focal Mechanism
        focal_mechanism = self._get_focal_mechanism(eq_id, eq_name, metadata)
        focal_mechanism.scalar_moment = get_float(metadata["Mo (dyne.cm)"]) *\
            1E-7
        # Read magnitude
        pref_mag = Magnitude(get_float(metadata["Earthquake Magnitude"]),
                             metadata["Magnitude Type"],
                             sigma=get_float(metadata["Uncertainty"]))
        # Create Earthquake Class
        eqk = Earthquake(eq_id, eq_name, eq_datetime,
            get_float(metadata["Hypocenter Longitude (deg)"]),
            get_float(metadata["Hypocenter Latitude (deg)"]),
            get_float(metadata["Hypocenter Depth (km)"]),
            pref_mag,
            focal_mechanism,
            metadata["Country"])
        hypo_loc = (0.5, 0.7)   # Hypocentre Location
        msr=WC1994()
        # Warning rake set to 0.0 in scaling relationship
        area = msr.get_median_area(pref_mag.value,0.0)
        aspect_ratio = 1.5 # Assumed Fixed
        width_model = np.sqrt(area / aspect_ratio)
        length_model = aspect_ratio * width_model
        ztor_model = eqk.depth - width_model / 2.
        if ztor_model < 0:
            ztor_model = 0.0

        length = get_float(metadata["Fault Rupture Length (km)"])
        if length is None:
            length = length_model
        width = get_float(metadata["Fault Rupture Width (km)"])
        if width is None:
            width = width_model
        ztor = get_float(metadata["Depth to Top Of Fault Rupture Model"])
        if ztor is None:
            ztor=ztor_model  
        # Rupture
        eqk.rupture = Rupture(eq_id,
                              eq_name,
                              pref_mag,
                              length,
                              width,
                              ztor)
        #    get_float(metadata["Fault Rupture Length (km)"]),
        #    get_float(metadata["Fault Rupture Width (km)"]),
        #    get_float(metadata["Depth to Top Of Fault Rupture Model"]))
        eqk.rupture.get_area()
        return eqk