Exemplo n.º 1
0
 def test_get_coordinates(self):
     """
     Test extracting coordinates
     """
     expected = {u'latitude': 47.737166999999999,
                 u'longitude': 12.795714,
                 u'elevation': 860.0,
                 u'local_depth': 0.0}
     channels = [Channel(code='EHZ',
                         location_code='',
                         start_date=UTCDateTime('2007-01-01'),
                         latitude=47.737166999999999,
                         longitude=12.795714,
                         elevation=860.0,
                         depth=0.0)]
     stations = [Station(code='RJOB',
                         latitude=0.0,
                         longitude=0.0,
                         elevation=0.0,
                         channels=channels)]
     networks = [Network('BW', stations=stations)]
     inv = Inventory(networks=networks, source='TEST')
     # 1
     coordinates = inv.get_coordinates('BW.RJOB..EHZ',
                                       UTCDateTime('2010-01-01T12:00'))
     self.assertEqual(sorted(coordinates.items()), sorted(expected.items()))
     # 2 - without datetime
     coordinates = inv.get_coordinates('BW.RJOB..EHZ')
     self.assertEqual(sorted(coordinates.items()), sorted(expected.items()))
     # 3 - unknown SEED ID should raise exception
     self.assertRaises(Exception, inv.get_coordinates, 'BW.RJOB..XXX')
Exemplo n.º 2
0
    def test_get_response(self):
        response_n1_s1 = Response('RESPN1S1')
        response_n1_s2 = Response('RESPN1S2')
        response_n2_s1 = Response('RESPN2S1')
        channels_n1_s1 = [Channel(code='BHZ',
                                  location_code='',
                                  latitude=0.0,
                                  longitude=0.0,
                                  elevation=0.0,
                                  depth=0.0,
                                  response=response_n1_s1)]
        channels_n1_s2 = [Channel(code='BHZ',
                                  location_code='',
                                  latitude=0.0,
                                  longitude=0.0,
                                  elevation=0.0,
                                  depth=0.0,
                                  response=response_n1_s2)]
        channels_n2_s1 = [Channel(code='BHZ',
                                  location_code='',
                                  latitude=0.0,
                                  longitude=0.0,
                                  elevation=0.0,
                                  depth=0.0,
                                  response=response_n2_s1)]
        stations_1 = [Station(code='N1S1',
                              latitude=0.0,
                              longitude=0.0,
                              elevation=0.0,
                              channels=channels_n1_s1),
                      Station(code='N1S2',
                              latitude=0.0,
                              longitude=0.0,
                              elevation=0.0,
                              channels=channels_n1_s2)]
        stations_2 = [Station(code='N2S1',
                              latitude=0.0,
                              longitude=0.0,
                              elevation=0.0,
                              channels=channels_n2_s1)]
        networks = [Network('N1', stations=stations_1),
                    Network('N2', stations=stations_2)]
        inv = Inventory(networks=networks, source='TEST')

        response = inv.get_response('N1.N1S1..BHZ',
                                    UTCDateTime('2010-01-01T12:00'))
        self.assertEqual(response, response_n1_s1)
        response = inv.get_response('N1.N1S2..BHZ',
                                    UTCDateTime('2010-01-01T12:00'))
        self.assertEqual(response, response_n1_s2)
        response = inv.get_response('N2.N2S1..BHZ',
                                    UTCDateTime('2010-01-01T12:00'))
        self.assertEqual(response, response_n2_s1)
Exemplo n.º 3
0
    def test_inventory_can_be_initialized_with_no_arguments(self):
        """
        Source and networks need not be specified.
        """
        inv = Inventory()
        self.assertEqual(inv.networks, [])
        self.assertEqual(inv.source, "ObsPy %s" % obspy.__version__)

        # Should also be serializable.
        with io.BytesIO() as buf:
            # This actually would not be a valid StationXML file but there
            # might be uses for this.
            inv.write(buf, format="stationxml")
            buf.seek(0, 0)
            inv2 = read_inventory(buf)

        self.assertEqual(inv, inv2)
Exemplo n.º 4
0
    def test_writing_module_tags(self):
        """
        Tests the writing of ObsPy related tags.
        """
        net = Network(code="UL")
        inv = Inventory(networks=[net], source="BLU")

        file_buffer = io.BytesIO()
        inv.write(file_buffer, format="StationXML", validate=True)
        file_buffer.seek(0, 0)
        lines = file_buffer.read().decode().splitlines()
        module_line = [_i.strip() for _i in lines if _i.strip().startswith(
            "<Module>")][0]
        self.assertTrue(fnmatch.fnmatch(module_line,
                                        "<Module>ObsPy *</Module>"))
        module_uri_line = [_i.strip() for _i in lines if _i.strip().startswith(
            "<ModuleURI>")][0]
        self.assertEqual(module_uri_line,
                         "<ModuleURI>https://www.obspy.org</ModuleURI>")
Exemplo n.º 5
0
def split_inventory_by_network(obspy_inv, output_folder, validate=False):
    """Export a station XML file per network for each network in given obspy Inventory.

    :param obspy_inv: Obspy Inventory containing the networks to export to file.
    :type obspy_inv: obspy.core.inventory.inventory.Inventory
    :param output_folder: Folder in which to output the per-network XML files. Will be created if doesn't yet exist.
    :type output_folder: str or pathlib.Path
    :param validate: Whether to validate the station data on write, defaults to False
    :type validate: bool, optional
    """
    pathlib.Path(output_folder).mkdir(exist_ok=True)

    if show_progress:
        pbar = tqdm.tqdm(total=len(obspy_inv.networks), ascii=True)
        std_print = pbar.write
    else:
        std_print = print

    # Since duplicate network codes can occur, we ensure that output file names are unique by keeping an instance
    # count for the occurrences of each network, and appending this to the file name.
    network_count = defaultdict(int)
    for network in obspy_inv:
        if show_progress:
            pbar.update()
            pbar.set_description("Network {}".format(network.code))
        net_inv = Inventory(networks=[network], source=obspy_inv.source)
        fname = "network_{}_{}.xml".format(network.code,
                                           network_count[network.code])
        network_count[network.code] += 1
        try:
            net_inv.write(os.path.join(output_folder, fname),
                          format="stationxml",
                          validate=validate)
        except Exception as e:
            std_print(str(e))
            std_print(
                "FAILED writing file {0} for network {1}, continuing".format(
                    fname, network.code))
            continue
    if show_progress:
        pbar.close()
Exemplo n.º 6
0
def save_network_local_plots(df, plot_folder, progressor=None, include_stations_list=True):
    """
    Save visual map plot per network, saved to file netcode.png.

    :param df: Dataframe of station records to save.
    :type df: pandas.DataFrame conforming to seismic.inventory.table_format.TABLE_SCHEMA
    :param plot_folder: Name of output folder
    :type plot_folder: str
    :param progressor: Progress bar functor to receive progress updates, defaults to None
    :type progressor: Callable object receiving incremental update on progress, optional
    :param include_stations_list: If True, also export stationtxt file alongside each png file, defaults to True
    :type include_stations_list: bool, optional
    """
    dest_path = os.path.join(plot_folder, "networks")
    pathlib.Path(dest_path).mkdir(parents=True, exist_ok=True)
    failed = []
    for netcode, data in df.groupby('NetworkCode'):
        net = dataframe_to_network(netcode, data, no_instruments)
        plot_fname = os.path.join(dest_path, netcode + ".png")
        try:
            fig = net.plot(projection="local", resolution="l", outfile=plot_fname, continent_fill_color="#e0e0e0",
                           water_fill_color="#d0d0ff", color="#c08080")
            plt.close(fig)
        except Exception:
            failed.append(netcode)
        # end try

        if include_stations_list:
            inv = Inventory(networks=[net], source='EHB')
            inv_fname = os.path.join(dest_path, netcode + ".txt")
            inv.write(inv_fname, format="stationtxt")

        if progressor:
            progressor(len(data))
    # end for

    if failed:
        print("FAILED plotting on the following networks:")
        print("\n".join(failed))
    else:
        print("SUCCESS!")
Exemplo n.º 7
0
    def test_writing_module_tags(self):
        """
        Tests the writing of ObsPy related tags.
        """
        net = Network(code="UL")
        inv = Inventory(networks=[net], source="BLU")

        file_buffer = io.BytesIO()
        inv.write(file_buffer, format="StationXML", validate=True)
        file_buffer.seek(0, 0)
        lines = file_buffer.read().decode().splitlines()
        module_line = [
            _i.strip() for _i in lines if _i.strip().startswith("<Module>")
        ][0]
        self.assertTrue(
            fnmatch.fnmatch(module_line, "<Module>ObsPy *</Module>"))
        module_uri_line = [
            _i.strip() for _i in lines if _i.strip().startswith("<ModuleURI>")
        ][0]
        self.assertEqual(module_uri_line,
                         "<ModuleURI>https://www.obspy.org</ModuleURI>")
Exemplo n.º 8
0
    def test_empty_network_code(self):
        """
        Tests that an empty sring is acceptabble.
        """
        # An empty string is allowed.
        n = Network(code="")
        self.assertEqual(n.code, "")

        # But None is not allowed.
        with self.assertRaises(ValueError) as e:
            Network(code=None)
        self.assertEqual(e.exception.args[0], "A code is required")

        # Should still serialize to something.
        inv = Inventory(networks=[n])
        with io.BytesIO() as buf:
            inv.write(buf, format="stationxml", validate=True)
            buf.seek(0, 0)
            inv2 = read_inventory(buf)

        self.assertEqual(inv, inv2)
Exemplo n.º 9
0
    def test_empty_network_code(self):
        """
        Tests that an empty sring is acceptabble.
        """
        # An empty string is allowed.
        n = Network(code="")
        self.assertEqual(n.code, "")

        # But None is not allowed.
        with self.assertRaises(ValueError) as e:
            Network(code=None)
        self.assertEqual(e.exception.args[0], "A code is required")

        # Should still serialize to something.
        inv = Inventory(networks=[n])
        with io.BytesIO() as buf:
            inv.write(buf, format="stationxml", validate=True)
            buf.seek(0, 0)
            inv2 = read_inventory(buf)

        self.assertEqual(inv, inv2)
Exemplo n.º 10
0
def dataless2stationXml(datalessFileName, xmlFileName):
    # Read the dataless seed file
    sp = Parser(datalessFileName)

    # Collect all potential unit abbreviations
    units = {}
    #genAbbrev={}
    for entry in sp.abbreviations:
        if entry.name == 'Units Abbreviations':
            units[entry.unit_lookup_code] = entry.unit_name
    #    elif entry.name=='Generic Abbreviation':
    #        genAbbrev[entry.abbreviation_lookup_code]=entry.abbreviation_description

    # Make a look-up dictionary for the transfer functions
    transFuncs = {
        'A': 'LAPLACE (RADIANS/SECOND)',
        'B': 'ANALOG (HERTZ)',
        'C': 'COMPOSITE',
        'D': 'DIGITAL (Z-TRANSFORM)'
    }

    # Collect each of the stations objects
    stations = []
    staNetCodes = []
    for stationBlock in sp.stations:
        station, staNetCode = getStation(stationBlock, units, transFuncs)
        stations.append(station)
        staNetCodes.append(staNetCode)

    # For each of the unique networks codes, collect the stations which relate to it
    networks = []
    staNetCodes = np.array(staNetCodes)
    unqNets = np.unique(staNetCodes)
    for aNet in unqNets:
        netStas = [stations[arg] for arg in np.where(staNetCodes == aNet)[0]]
        networks.append(Network(aNet, stations=netStas))

    # Finally turn this into an inventory and save
    inv = Inventory(networks, 'Lazylyst')
    inv.write(xmlFileName, format='stationxml', validate=True)
Exemplo n.º 11
0
 def test_get_orientation(self):
     """
     Test extracting orientation
     """
     expected = {u'azimuth': 90.0,
                 u'dip': 0.0}
     channels = [Channel(code='EHZ',
                         location_code='',
                         start_date=UTCDateTime('2007-01-01'),
                         latitude=47.737166999999999,
                         longitude=12.795714,
                         elevation=860.0,
                         depth=0.0,
                         azimuth=90.0,
                         dip=0.0)]
     stations = [Station(code='RJOB',
                         latitude=0.0,
                         longitude=0.0,
                         elevation=0.0,
                         channels=channels)]
     networks = [Network('BW', stations=stations)]
     inv = Inventory(networks=networks, source='TEST')
     # 1
     orientation = inv.get_orientation('BW.RJOB..EHZ',
                                       UTCDateTime('2010-01-01T12:00'))
     assert sorted(orientation.items()) == sorted(expected.items())
     # 2 - without datetime
     orientation = inv.get_orientation('BW.RJOB..EHZ')
     assert sorted(orientation.items()) == sorted(expected.items())
     # 3 - unknown SEED ID should raise exception
     with pytest.raises(Exception):
         inv.get_orientation('BW.RJOB..XXX')
Exemplo n.º 12
0
def staCsv2Xml(staCsvPath, staXmlPath, source='Lazylyst'):
    # Load the csv file
    info = np.genfromtxt(staCsvPath, delimiter=',', dtype=str)
    # For each network...
    networks = []
    unqNets = np.unique(info[:, 5])
    for net in unqNets:
        netInfo = info[np.where(info[:, 5] == net)]
        # ...gather its stations
        stations = []
        for entry in netInfo:
            stations.append(
                Station(entry[0],
                        entry[1],
                        entry[2],
                        entry[3],
                        site=Site(''),
                        creation_date=UTCDateTime(1970, 1, 1)))
        networks.append(Network(net, stations=stations))
    # Generate the inventory object, and save it as a station XML
    inv = Inventory(networks=networks, source=source)
    inv.write(staXmlPath, format='stationxml', validate=True)
Exemplo n.º 13
0
 def test_get_coordinates(self):
     """
     Test extracting coordinates
     """
     expected = {
         u'latitude': 47.737166999999999,
         u'longitude': 12.795714,
         u'elevation': 860.0,
         u'local_depth': 0.0
     }
     channels = [
         Channel(code='EHZ',
                 location_code='',
                 start_date=UTCDateTime('2007-01-01'),
                 latitude=47.737166999999999,
                 longitude=12.795714,
                 elevation=860.0,
                 depth=0.0)
     ]
     stations = [
         Station(code='RJOB',
                 latitude=0.0,
                 longitude=0.0,
                 elevation=0.0,
                 channels=channels)
     ]
     networks = [Network('BW', stations=stations)]
     inv = Inventory(networks=networks, source='TEST')
     # 1
     coordinates = inv.get_coordinates('BW.RJOB..EHZ',
                                       UTCDateTime('2010-01-01T12:00'))
     self.assertEqual(sorted(coordinates.items()), sorted(expected.items()))
     # 2 - without datetime
     coordinates = inv.get_coordinates('BW.RJOB..EHZ')
     self.assertEqual(sorted(coordinates.items()), sorted(expected.items()))
     # 3 - unknown SEED ID should raise exception
     self.assertRaises(Exception, inv.get_coordinates, 'BW.RJOB..XXX')
Exemplo n.º 14
0
def get_inventory_from_xml(ddir):
    '''
    Return combined inventory multiple xml files 
    (created by mass downloader)
    '''

    from obspy.core.inventory import Inventory

    inventory = Inventory(networks=[], source='ObsPy 1.0.3')
    #inventory = Inventory()

    for xmlfile in glob.iglob(ddir + '/*.xml'):
        stninv = obspy.read_inventory(xmlfile)
        inventory.networks.append(stninv[0])
        #inventory.__add__(stninv)

    return inventory
Exemplo n.º 15
0
def array_csvtoinventory(fh):
    """
    Takes a ph5 array csv file and converts it
    to an obspy inventory object
    :type file
    :param fh
    :return: :class obspy.core.inventory
    """
    net = [Network('XX')]
    net[0].extra = AttribDict({"channel_num": 1})
    created = UTCDateTime.now()
    csv_inventory = Inventory(networks=net,
                              source="",
                              sender="",
                              created=created,
                              module="",
                              module_uri="")
    return csv_inventory
Exemplo n.º 16
0
def create_simple_inventory(network, station, latitude=None, longitude=None,
                            elevation=None, depth=None, start_date=None,
                            end_date=None, location_code="S3",
                            channel_code="MX"):
    """
    Create simple inventory with only location information,
    for ZNE component, especially usefull for synthetic data
    """
    azi_dict = {"MXZ": 0.0,  "MXN": 0.0, "MXE": 90.0}
    dip_dict = {"MXZ": 90.0, "MXN": 0.0, "MXE": 0.0}
    channel_list = []

    if start_date is None:
        start_date = UTCDateTime(0)

    # specfem default channel code is MX
    for _comp in ["Z", "E", "N"]:
        _chan_code = "%s%s" % (channel_code, _comp)
        chan = Channel(_chan_code, location_code, latitude=latitude,
                       longitude=longitude, elevation=elevation,
                       depth=depth, azimuth=azi_dict[_chan_code],
                       dip=dip_dict[_chan_code], start_date=start_date,
                       end_date=end_date)
        channel_list.append(chan)

    site = Site("N/A")
    sta = Station(station, latitude=latitude, longitude=longitude,
                  elevation=elevation, channels=channel_list, site=site,
                  creation_date=start_date, total_number_of_channels=3,
                  selected_number_of_channels=3)

    nw = Network(network, stations=[sta, ], total_number_of_stations=1,
                 selected_number_of_stations=1)

    inv = Inventory([nw, ], source="SPECFEM3D_GLOBE", sender="Princeton",
                    created=UTCDateTime.now())

    return inv
Exemplo n.º 17
0
def dataless_parser(dfiles,subset,debug=0):
    print('Using: ',subset,' please')
    inv=Inventory()
    for i in dfiles: # loop through dataless files
        p=Parser()
        if (debug):
            print('reading',i)
        try:
            p.read(i)
        except Exception as e:
            print(e)
        invtmp=d2inv(p)
        if len(invtmp._networks) > 1:
            print('More than 1 net in: ',i,len(invtmp._networks))
        else:
            nettmp=invtmp._networks[0].select(location='0K')
        if len(inv) == 0:
            inv._networks.append(nettmp)
        else:
            sta=nettmp[0].select(location='01')
           # 
            inv._networks[0]._stations.append(sta)
    return inv
Exemplo n.º 18
0
def select_stations(inventory, station_list):
    """
    Select station within an Inventory according to a list.

    Parameters
    ----------
    inventory : obspy.Inventory
        The inventory.
    station_list : TYPE
        The station list.

    Returns
    -------
    obspy.Inventory
        An inventory only containing stations in station_list.

    """
    if station_list is None:
        return inventory
    network, = inventory
    stations = [station for station in network if station.code in station_list]
    network = Network(code='YV', stations=stations)
    inventory = Inventory(networks=[network], source='')
    return inventory
Exemplo n.º 19
0
def stats2inv(stats, resp=None, filexml=None, locs=None):

    # We'll first create all the various objects. These strongly follow the
    # hierarchy of StationXML files.
    inv = Inventory(networks=[], source="japan_from_resp")

    if locs is None:
        net = Network(
            # This is the network code according to the SEED standard.
            code=stats.network,
            # A list of stations. We'll add one later.
            stations=[],
            description="Marine created from SAC and resp files",
            # Start-and end dates are optional.
            start_date=stats.starttime)

        sta = Station(
            # This is the station code according to the SEED standard.
            code=stats.station,
            latitude=stats.sac["stla"],
            longitude=stats.sac["stlo"],
            elevation=stats.sac["stel"],
            creation_date=stats.starttime,
            site=Site(name="First station"))

        cha = Channel(
            # This is the channel code according to the SEED standard.
            code=stats.channel,
            # This is the location code according to the SEED standard.
            location_code=stats.location,
            # Note that these coordinates can differ from the station coordinates.
            latitude=stats.sac["stla"],
            longitude=stats.sac["stlo"],
            elevation=stats.sac["stel"],
            depth=-stats.sac["stel"],
            azimuth=stats.sac["cmpaz"],
            dip=stats.sac["cmpinc"],
            sample_rate=stats.sampling_rate)

    else:
        ista = locs[locs['station'] == stats.station].index.values.astype(
            'int64')[0]

        net = Network(
            # This is the network code according to the SEED standard.
            code=locs.iloc[ista]["network"],
            # A list of stations. We'll add one later.
            stations=[],
            description="Marine created from SAC and resp files",
            # Start-and end dates are optional.
            start_date=stats.starttime)

        sta = Station(
            # This is the station code according to the SEED standard.
            code=locs.iloc[ista]["station"],
            latitude=locs.iloc[ista]["latitude"],
            longitude=locs.iloc[ista]["longitude"],
            elevation=locs.iloc[ista]["elevation"],
            creation_date=stats.starttime,
            site=Site(name="First station"))
        cha = Channel(
            # This is the channel code according to the SEED standard.
            code=stats.channel,
            # This is the location code according to the SEED standard.
            location_code=stats.location,
            # Note that these coordinates can differ from the station coordinates.
            latitude=locs.iloc[ista]["latitude"],
            longitude=locs.iloc[ista]["longitude"],
            elevation=locs.iloc[ista]["elevation"],
            depth=-locs.iloc[ista]["elevation"],
            azimuth=0,
            dip=0,
            sample_rate=stats.sampling_rate)

    response = obspy.core.inventory.response.Response()
    if resp is not None:
        print('i dont have the response')
    # By default this accesses the NRL online. Offline copies of the NRL can
    # also be used instead
    # nrl = NRL()
    # The contents of the NRL can be explored interactively in a Python prompt,
    # see API documentation of NRL submodule:
    # http://docs.obspy.org/packages/obspy.clients.nrl.html
    # Here we assume that the end point of data logger and sensor are already
    # known:
    #response = nrl.get_response( # doctest: +SKIP
    #    sensor_keys=['Streckeisen', 'STS-1', '360 seconds'],
    #    datalogger_keys=['REF TEK', 'RT 130 & 130-SMA', '1', '200'])

    # Now tie it all together.
    cha.response = response
    sta.channels.append(cha)
    net.stations.append(sta)
    inv.networks.append(net)

    # And finally write it to a StationXML file. We also force a validation against
    # the StationXML schema to ensure it produces a valid StationXML file.
    #
    # Note that it is also possible to serialize to any of the other inventory
    # output formats ObsPy supports.
    if filexml is not None:
        inv.write(filexml, format="stationxml", validate=True)

    return inv
Exemplo n.º 20
0
def get_inventory():
    # We'll first create all the various objects. These strongly follow the
    # hierarchy of StationXML files.
    inv = Inventory(
        # We'll add networks later.
        networks=[],
        # The source should be the id whoever create the file.
        source="ObsPy-Tutorial")

    net = Network(
        # This is the network code according to the SEED standard.
        code="US",
        # A list of stations. We'll add one later.
        stations=[],
        description="A test stations.",
        # Start-and end dates are optional.
        start_date=UTCDateTime(2016, 1, 2))

    sta = Station(
        # This is the station code according to the SEED standard.
        code="ABCD",
        latitude=1.0,
        longitude=2.0,
        elevation=345.0,
        creation_date=UTCDateTime(2016, 1, 2),
        site=Site(name="First station"))

    cha1 = Channel(
        # This is the channel code according to the SEED standard.
        code="HN1",
        # This is the location code according to the SEED standard.
        location_code="11",
        # Note that these coordinates can differ from the station coordinates.
        latitude=1.0,
        longitude=2.0,
        elevation=345.0,
        depth=10.0,
        azimuth=0.0,
        dip=-90.0,
        sample_rate=1)
    cha2 = Channel(
        # This is the channel code according to the SEED standard.
        code="HN2",
        # This is the location code according to the SEED standard.
        location_code="11",
        # Note that these coordinates can differ from the station coordinates.
        latitude=1.0,
        longitude=2.0,
        elevation=345.0,
        depth=10.0,
        azimuth=90.0,
        dip=-90.0,
        sample_rate=1)
    cha3 = Channel(
        # This is the channel code according to the SEED standard.
        code="HNZ",
        # This is the location code according to the SEED standard.
        location_code="11",
        # Note that these coordinates can differ from the station coordinates.
        latitude=1.0,
        longitude=2.0,
        elevation=345.0,
        depth=10.0,
        azimuth=0.0,
        dip=-90.0,
        sample_rate=1)

    # Now tie it all together.
    sta.channels.append(cha1)
    sta.channels.append(cha2)
    sta.channels.append(cha3)
    net.stations.append(sta)
    inv.networks.append(net)

    return inv
Exemplo n.º 21
0
    def modify_invenory(self,
                        gps_clock_corr_csv=None,
                        orient_corr_json=None,
                        equipment_csv=None):
        """
        Modify the existing station XML files to include new metadata:
        - add equipment sensor digitizer
        - add extra metadata: GPS correction
        - add extra metadata: Orientation correction
        Args:

        Returns: the final station_xml file modified with new metadata: inv2_xml_file

        """

        # Construct a new inventory object of networks.
        # This will use new obspy version and new attributes:
        inv2 = Inventory(
            # We'll add networks later.
            networks=[],
            # The source should be the id whoever create the file.
            source="Geoscience Australia EFTF AusArray PST")

        # output dir for modified station inventory xml files
        out_dir = self.output_dir  # "/home/fzhang/tmpdir"

        net, sta, csv_data = get_csv_correction_data(gps_clock_corr_csv)
        net_sta, oricorr_json_data = get_orientation_corr(orient_corr_json)
        my_equip_obj = EquipmentExtractor(csvfile=equipment_csv)

        big_inv = self.inv_obj

        for a_net in big_inv.networks:

            print("The number of station-nodes in the network =",
                  len(a_net.stations))

            for a_sta in a_net.stations:
                # print(a_net.code, a_sta.code)  # this contains 328 pairs, but they are NOT unique, station code may repeat.

                a_inv = big_inv.select(
                    network=a_net.code,
                    station=a_sta.code)  # .copy appears to have no effect here

                # print (a_sta.code, " stations has %s channels"%len(a_sta))

                _sensors = my_equip_obj.get_sensors(a_net.code, a_sta.code)
                if len(_sensors) > 0:
                    sensor_desc = _sensors[0].get("Description")
                    sensor_sernumb = _sensors[0].get("SerNumber")
                else:
                    print("%s %s  No sensors !" % (a_net.code, a_sta.code))
                    # sensor_desc = "NA Sensor for (%s,%s)" % (a_net.code, a_sta.code)
                    sensor_desc = "Nanometrics Trillium Compact 120s"
                    sensor_sernumb = "N/A"

                _digitizers = my_equip_obj.get_digitizer(
                    a_net.code, a_sta.code)
                if len(_digitizers) > 0:
                    dig_desc = _digitizers[0].get("Description")
                    dig_sernumb = _digitizers[0].get("SerNumber")
                else:
                    print("%s %s  No digitizers !" % (a_net.code, a_sta.code))
                    #dig_desc = "NA Digitizer for (%s,%s)" % (a_net.code, a_sta.code)
                    dig_desc = "Guralp Minimus"
                    dig_sernumb = "N/A"

                # modify station metadata
                my_sensor = obspy.core.inventory.util.Equipment(
                    type="Sensor",
                    description=sensor_desc,
                    serial_number=sensor_sernumb)

                # my_digitizer = obspy.core.inventory.util.Equipment(type="Digitizer", description="Guralp Minimus",serial_number="MIN-A456")
                my_digitizer = obspy.core.inventory.util.Equipment(
                    type="Digitizer",
                    description=dig_desc,
                    serial_number=dig_sernumb)

                a_sta.equipments = [my_sensor, my_digitizer]

                # get station start_ end_date and split csv_data
                start_dt = a_sta.start_date
                end_dt = a_sta.end_date

                ajson = StationMetadataExtra(a_net.code,
                                             a_sta.code,
                                             start_datetime=start_dt,
                                             end_datetime=end_dt)

                # generate/format extra metadata from inputs
                mpdf = ajson.add_gps_correction_from_csv(csv_data)

                # updated the ajson object with more metadata, such as orientation corr
                ajson.add_orientation_correction(oricorr_json_data)

                ajson.write_metadata2json(
                    os.path.join(
                        out_dir, "%s.%s_%s_extra_metadata.json" %
                        (a_net.code, a_sta.code, str(start_dt))))

                # Now, ready to write the ajson obj into new xml file
                mformat = "JSON"

                my_tag = AttribDict()
                my_tag.namespace = GA_NameSpace

                my_tag.value = ajson.make_json_string(
                )  # store all the extra metadata into a json string.

                a_sta.extra = AttribDict()
                a_sta.extra.GAMetadata = my_tag

                # prepare to write out a modified xml file
                stationxml_with_extra = '%s.%s_station_metadata_%s.xml' % (
                    a_net.code, a_sta.code, mformat)

                if out_dir is not None and os.path.isdir(out_dir):
                    stationxml_with_extra = os.path.join(
                        out_dir, stationxml_with_extra)

                a_inv.write(stationxml_with_extra,
                            format='STATIONXML',
                            nsmap={'GeoscienceAustralia': GA_NameSpace})

            # Problem:
            # sta_file_name2 = "%s_%s_station2.xml"%(a_net.code, a_sta.code)
            # # OA_CE28 was written 3-times!!!!!! due to multiple (OA,CE28)-station-nodes
            # There will be 119 xml files written in this loop of 328 items. However, the final results missed 119 equipments!!
            # outxml2 = os.path.join(OUTPUT_DIR, sta_file_name2)
            #
            # inv2.networks = a_inv.networks
            #
            # inv2.write(outxml2,format="stationxml", validate=True) # nsmap={'GeoscienceAustralia': GA_NameSpace})

            # After the modification of ALL the station objects,
            # write the big inventory in new object inv2
            inv2.networks = []
            inv2.networks.append(a_net)
            inv2_xml_file = os.path.join(out_dir,
                                         a_net.code + "_stations2.xml")
            inv2.write(inv2_xml_file,
                       format="stationxml",
                       nsmap={'GeoscienceAustralia': GA_NameSpace},
                       validate=True)  # every Station got equipment

            # Add responses:
            resp_obj = read_response()
            self.add_response_into_stationxml(inv2, resp_obj)

            # and the original write out again to check what has been modified?
            post_orig = os.path.join(out_dir,
                                     a_net.code + "_stations_post_orig.xml")
            big_inv.write(post_orig,
                          format="stationxml",
                          nsmap={'GeoscienceAustralia': GA_NameSpace},
                          validate=True)  # also has the Sensors etc

            return inv2_xml_file
Exemplo n.º 22
0
    def test_write_stationtxt(self):
        """
        Test writing stationtxt at channel level
        """
        # Manually create a test Inventory object.
        resp_1 = Response(
            instrument_sensitivity=InstrumentSensitivity(
                frequency=0.02, input_units="M/S", output_units=None,
                value=8.48507E8))
        resp_2 = Response(
            instrument_sensitivity=InstrumentSensitivity(
                frequency=1.0, input_units="M/S**2",
                output_units=None, value=53435.4))
        resp_3 = Response(
            instrument_sensitivity=InstrumentSensitivity(
                frequency=0.03, input_units="M/S",
                output_units=None, value=6.27252E8))
        test_inv = Inventory(source=None, networks=[
            Network(
                code="IU",
                start_date=obspy.UTCDateTime("1988-01-01T00:00:00"),
                end_date=obspy.UTCDateTime("2500-12-31T23:59:59"),
                total_number_of_stations=1,
                description="Global Seismograph Network (GSN - IRIS/USGS)",
                stations=[
                    Station(
                        code="ANMO",
                        latitude=34.9459,
                        longitude=-106.4572,
                        elevation=1850.0,
                        channels=[
                            Channel(
                                code="BCI", location_code="",
                                latitude=34.9459,
                                longitude=-106.4572,
                                elevation=1850.0,
                                depth=100.0,
                                azimuth=0.0,
                                dip=0.0,
                                sample_rate=0.0,
                                sensor=Equipment(
                                    type="Geotech KS-36000-I Borehole "
                                         "Seismometer"),
                                start_date=obspy.UTCDateTime(
                                    "1989-08-29T00:00:00"),
                                end_date=obspy.UTCDateTime(
                                    "1995-02-01T00:00:00"),
                                response=resp_1),
                            Channel(
                                code="LNZ", location_code="20",
                                latitude=34.9459,
                                longitude=-106.4572,
                                elevation=1820.7,
                                depth=0.0,
                                azimuth=0.0,
                                dip=-90.0,
                                sample_rate=0.0,
                                sensor=Equipment(
                                    type="Titan Accelerometer"),
                                start_date=obspy.UTCDateTime(
                                    "2013-06-20T16:30:00"),
                                response=resp_2),
                        ]),
                ]),
            Network(
                code="6E",
                start_date=obspy.UTCDateTime("2013-01-01T00:00:00"),
                end_date=obspy.UTCDateTime("2016-12-31T23:59:59"),
                total_number_of_stations=1,
                description="Wabash Valley Seismic Zone",
                stations=[
                    Station(
                        code="SH01",
                        latitude=37.7457,
                        longitude=-88.1368,
                        elevation=126.0,
                        channels=[
                            Channel(
                                code="LOG", location_code="",
                                latitude=37.7457,
                                longitude=-88.1368,
                                elevation=126.0,
                                depth=0.0,
                                azimuth=0.0,
                                dip=0.0,
                                sample_rate=0.0,
                                sensor=Equipment(
                                    type="Reftek 130 Datalogger"),
                                start_date=obspy.UTCDateTime(
                                    "2013-11-23T00:00:00"),
                                end_date=obspy.UTCDateTime(
                                    "2016-12-31T23:59:59"),
                                response=resp_3)
                        ]),
                ])
        ])

        # CHANNEL level test
        stio = io.StringIO()
        test_inv.write(stio, format="STATIONTXT", level="CHANNEL")
        # check contents
        content = stio.getvalue()
        expected = [("Network|Station|Location|Channel|Latitude|Longitude|"
                     "Elevation|Depth|Azimuth|Dip|SensorDescription|Scale|"
                     "ScaleFreq|ScaleUnits|SampleRate|StartTime|EndTime"),
                    ("IU|ANMO||BCI|34.9459|-106.4572|1850.0|100.0|0.0|"
                     "0.0|Geotech KS-36000-I Borehole Seismometer|"
                     "848507000.0|0.02|M/S|0.0|1989-08-29T00:00:00|"
                     "1995-02-01T00:00:00"),
                    ("IU|ANMO|20|LNZ|34.9459|-106.4572|1820.7|0.0|0.0|"
                     "-90.0|Titan Accelerometer|53435.4|1.0|M/S**2|0.0|"
                     "2013-06-20T16:30:00|"),
                    ("6E|SH01||LOG|37.7457|-88.1368|126.0|0.0|0.0|0.0|"
                     "Reftek 130 Datalogger|627252000.0|0.03|M/S|0.0|"
                     "2013-11-23T00:00:00|2016-12-31T23:59:59"),
                    ]
        num_lines_written = 0
        for line in expected:
            self.assertIn(line, content)
            num_lines_written = num_lines_written + 1
        # assert that the number of lines written equals
        # the number of lines expected
        self.assertEqual(num_lines_written, len(expected))

        # STATION level test
        stio = io.StringIO()
        test_inv.write(stio, format="STATIONTXT", level="STATION")
        # check contents
        content = stio.getvalue()
        expected = [("Network|Station|Latitude|Longitude|"
                     "Elevation|SiteName|StartTime|EndTime"),
                    ("IU|ANMO|34.9459|-106.4572|1850.0||"),
                    ("6E|SH01|37.7457|-88.1368|126.0||"),
                    ]
        num_lines_written = 0
        for line in expected:
            self.assertIn(line, content)
            num_lines_written = num_lines_written + 1
        # assert that the number of lines written equals
        # the number of lines expected
        self.assertEqual(num_lines_written, len(expected))

        # NETWORK level test
        stio = io.StringIO()
        test_inv.write(stio, format="STATIONTXT", level="NETWORK")
        # check contents
        content = stio.getvalue()
        expected = [("Network|Description|StartTime|EndTime|TotalStations"),
                    ("IU|Global Seismograph Network (GSN - IRIS/USGS)|"
                     "1988-01-01T00:00:00|2500-12-31T23:59:59|1"),
                    ("6E|Wabash Valley Seismic Zone|"
                     "2013-01-01T00:00:00|2016-12-31T23:59:59|1"),
                    ]
        num_lines_written = 0
        for line in expected:
            self.assertIn(line, content)
            num_lines_written = num_lines_written + 1
        # assert that the number of lines written equals
        # the number of lines expected
        self.assertEqual(num_lines_written, len(expected))
Exemplo n.º 23
0
def read_fdsn_station_text_file(path_or_file_object):
    """
    Function reading a FDSN station text file to an inventory object.

    :param path_or_file_object: File name or file like object.
    """
    def _read(obj):
        r = unicode_csv_reader(obj, delimiter=native_str("|"))
        header = next(r)
        header[0] = header[0].lstrip("#")
        header = [_i.strip().lower() for _i in header]
        # IRIS currently has a wrong header name. Just map it.
        header = [
            _i.replace("instrument", "sensordescription") for _i in header
        ]

        all_lines = []
        for line in r:
            # Skip comment lines.
            if line[0].startswith("#"):
                continue
            all_lines.append([_i.strip() for _i in line])
        return {"header": tuple(header), "content": all_lines}

    # Enable reading from files and buffers opened in binary mode.
    if (hasattr(path_or_file_object, "mode") and
            "b" in path_or_file_object.mode) or \
            isinstance(path_or_file_object, io.BytesIO):
        buf = io.StringIO(path_or_file_object.read().decode("utf-8"))
        buf.seek(0, 0)
        path_or_file_object = buf

    if hasattr(path_or_file_object, "read"):
        content = _read(path_or_file_object)
    else:
        with open(path_or_file_object, "rt", newline="",
                  encoding="utf8") as fh:
            content = _read(fh)

    # Figure out the type.
    if content["header"] == network_components:
        level = "network"
        filetypes = network_types
    elif content["header"] == station_components:
        level = "station"
        filetypes = station_types
    elif content["header"] == channel_components:
        level = "channel"
        filetypes = channel_types
    else:
        raise ValueError("Unknown type of header.")

    content = content["content"]
    converted_content = []
    # Convert all types.
    for line in content:
        converted_content.append(
            [v_type(value) for value, v_type in zip(line, filetypes)])

    # Now convert to an inventory object.
    inv = Inventory(networks=[], source=None)

    if level == "network":
        for net in converted_content:
            network = Network(code=net[0],
                              description=net[1],
                              start_date=net[2],
                              end_date=net[3],
                              total_number_of_stations=net[4])
            inv.networks.append(network)
    elif level == "station":
        networks = collections.OrderedDict()
        for sta in converted_content:
            site = Site(name=sta[5])
            station = Station(code=sta[1],
                              latitude=sta[2],
                              longitude=sta[3],
                              elevation=sta[4],
                              site=site,
                              start_date=sta[6],
                              end_date=sta[7])
            if sta[0] not in networks:
                networks[sta[0]] = []
            networks[sta[0]].append(station)
        for network_code, stations in networks.items():
            net = Network(code=network_code, stations=stations)
            inv.networks.append(net)
    elif level == "channel":
        networks = collections.OrderedDict()
        stations = collections.OrderedDict()

        for channel in converted_content:
            net, sta, loc, chan, lat, lng, ele, dep, azi, dip, inst, scale, \
                scale_freq, scale_units, s_r, st, et = channel

            if net not in networks:
                networks[net] = Network(code=net)

            if (net, sta) not in stations:
                station = Station(code=sta,
                                  latitude=lat,
                                  longitude=lng,
                                  elevation=ele)
                networks[net].stations.append(station)
                stations[(net, sta)] = station

            sensor = Equipment(type=inst)
            if scale is not None and scale_freq is not None:
                resp = Response(instrument_sensitivity=InstrumentSensitivity(
                    value=scale,
                    frequency=scale_freq,
                    input_units=scale_units,
                    output_units=None))
            else:
                resp = None
            try:
                channel = Channel(code=chan,
                                  location_code=loc,
                                  latitude=lat,
                                  longitude=lng,
                                  elevation=ele,
                                  depth=dep,
                                  azimuth=azi,
                                  dip=dip,
                                  sensor=sensor,
                                  sample_rate=s_r,
                                  start_date=st,
                                  end_date=et,
                                  response=resp)
            except Exception as e:
                warnings.warn(
                    "Failed to parse channel %s.%s.%s.%s due to: %s" %
                    (net, sta, loc, chan, str(e)), UserWarning)
                continue
            stations[(net, sta)].channels.append(channel)
        inv.networks.extend(list(networks.values()))
    else:
        # Cannot really happen - just a safety measure.
        raise NotImplementedError("Unknown level: %s" % str(level))
    return inv
Exemplo n.º 24
0
def surf_4100_to_inv(location_file, response_inv, plot=False):
    """
    Combine the xyz Homestake locations and MMF calibration responses into
    an Inventory object for the 4100L
    """
    converter = SURF_converter()
    sta_df = pd.read_csv(location_file)
    inv = Inventory()
    serial_map = {'GMF1': '21010', 'GMF2': '21015', 'GMF3': '21027'}
    inv.networks = [Network(code='CB')]
    for _, row in sta_df.iterrows():
        print(row)
        sta_code = row['Sensor name']
        # Station location
        # Convert from SURF coords to lat lon, but keep local for actual use
        lon, lat, elev = converter.to_lonlat(
            (row['x_ft'] * 0.3048, row['y_ft'] * 0.3048, row['z_ft'] * 0.3048))
        print(lon, lat, elev)
        # Just leave as zero here and convert HMC feet elevation to m
        depth = 0.0
        # Save HMC coords to custom attributes of Station and Channel
        extra = AttribDict({
            'hmc_east': {
                'value': row['x_ft'],
                'namespace': 'smi:local/hmc'
            },
            'hmc_north': {
                'value': row['y_ft'],
                'namespace': 'smi:local/hmc'
            },
            'hmc_elev': {
                'value': row['z_ft'] * 0.3048,
                'namespace': 'smi:local/hmc'
            }
        })
        if sta_code.startswith('TS'):
            # Hydrophone or CASSM, wet well
            if 'SS' in sta_code:
                # Cassm (Y for unspecified instrument)
                chan_code = 'XY1'
                chans = [
                    Channel(code=chan_code,
                            location_code='',
                            latitude=lat,
                            longitude=lon,
                            elevation=elev,
                            depth=depth,
                            response=Response())
                ]
            else:
                # Hydrophone (D), Downhole (H) per SEED manual
                chan_code = 'XDH'
                chans = [
                    Channel(code=chan_code,
                            location_code='',
                            latitude=lat,
                            longitude=lon,
                            elevation=elev,
                            depth=depth,
                            response=Response())
                ]
        elif 'S' in sta_code:
            # Grouted CASSM
            chan_code = 'XY1'
            chans = [
                Channel(code=chan_code,
                        location_code='',
                        latitude=lat,
                        longitude=lon,
                        elevation=elev,
                        depth=depth,
                        response=Response())
            ]
        else:
            # Grouted accelerometer
            chans = []
            try:
                serial = serial_map[sta_code]
            except KeyError:
                serial = '9999'
            for chan_code in ['XNX', 'XNY', 'XNZ']:
                # Set samp_rate to 40 kHz so that Nyquist is below max shake f
                chan = Channel(code=chan_code,
                               location_code='',
                               latitude=lat,
                               longitude=lon,
                               elevation=elev,
                               depth=0.,
                               sample_rate=40000.,
                               sensor=Equipment(
                                   type='IEPE Accelerometer',
                                   description='Piezoelectric accelerometer',
                                   manufacturer='MMF',
                                   model='KS943B.100',
                                   serial_number=serial))
                # Apply exact response for the three tested sensors,
                # ...otherwise use the average
                avg_resp = response_inv.select(
                    station='AVG', channel=chan_code)[0][0][0].response
                chan.response = avg_resp
                chans.append(chan)
        sta = Station(code=sta_code,
                      latitude=chans[0].latitude,
                      longitude=chans[0].longitude,
                      elevation=chans[0].elevation,
                      channels=chans)
        sta.extra = extra
        inv[0].stations.append(sta)
    return inv
Exemplo n.º 25
0
# vim:fenc=utf-8
#
#
"""


20210627 -- cralvizuri <*****@*****.**>
"""
import glob
import obspy
from obspy.core.inventory import Inventory

ddir = '20210224100557024/mass_downloader/stations'
ddir = 'testxml'
#stninv=None

inventory = Inventory(networks=[], source='ObsPy 1.0')
for xmlfile in glob.iglob(ddir + '/*.xml'):
    try:
        stninv = obspy.read_inventory(xmlfile)
        inventory.networks.append(stninv[0])
    except:
        print('ERROR. unable to append file', xmlfile)
    #    #continue        # TEST 1. 2021-05-17 17:31 USE CONTINUE. DOESNT WORK.
    #    #stninv = []     # TEST 2. 2021-05-18 TEST2. DOESNT WORK
    #    #stninv = []     # TEST 3 apply both? set null in case it's needed further down (where?). But continue ?? DOESNT WORK
    #    #continue
    ##inventory.__add__(stninv)

#return inventory
Exemplo n.º 26
0
    def getInventory(self):
        """
        Extract an ObsPy inventory object from a Stream read in by gmprocess
        tools.
        """
        networks = [trace.stats.network for trace in self]
        if len(set(networks)) > 1:
            raise Exception(
                "Input stream has stations from multiple networks.")

        # We'll first create all the various objects. These strongly follow the
        # hierarchy of StationXML files.
        source = ''
        if 'standard' in self[0].stats and 'source' in self[0].stats.standard:
            source = self[0].stats.standard.source
        inv = Inventory(
            # We'll add networks later.
            networks=[],
            # The source should be the id whoever create the file.
            source=source)

        net = Network(
            # This is the network code according to the SEED standard.
            code=networks[0],
            # A list of stations. We'll add one later.
            stations=[],
            description="source",
            # Start-and end dates are optional.
        )
        channels = []
        for trace in self:
            logging.debug('trace: %s' % trace)
            channel = _channel_from_stats(trace.stats)
            channels.append(channel)

        subdict = {}
        for k in UNUSED_STANDARD_PARAMS:
            if k in self[0].stats.standard:
                subdict[k] = self[0].stats.standard[k]

        format_specific = {}
        if 'format_specific' in self[0].stats:
            format_specific = dict(self[0].stats.format_specific)

        big_dict = {'standard': subdict,
                    'format_specific': format_specific}
        try:
            jsonstr = json.dumps(big_dict)
        except Exception as e:
            raise GMProcessException('Exception in json.dumps: %s' % e)
        sta = Station(
            # This is the station code according to the SEED standard.
            code=self[0].stats.station,
            latitude=self[0].stats.coordinates.latitude,
            elevation=self[0].stats.coordinates.elevation,
            longitude=self[0].stats.coordinates.longitude,
            channels=channels,
            site=Site(name=self[0].stats.standard.station_name),
            description=jsonstr,
            creation_date=UTCDateTime(1970, 1, 1),  # this is bogus
            total_number_of_channels=len(self))

        net.stations.append(sta)
        inv.networks.append(net)

        return inv
Exemplo n.º 27
0
def main(argv):
    '''@package isc2stnxml
       It gathers station information from all STN files provided in ISC and Engdahl catalogues assigning correct network code.
       When proper network code can not be identified the program just guess it, sorry...
    '''
    inv = read_inventory("IRIS-ALL.xml")

    # unknown stations in Indonesia are usually installed by Potsdam and we assume they have network name GE
    default_net = 'GE'
    ehb1 = read_eng('BMG.STN')
    ehb2 = read_eng('ISC.STN')
    ehb = np.unique(np.vstack((ehb1, ehb2)), axis=0)

    isc1 = read_isc('ehb.stn')
    isc2 = read_isc('iscehb.stn')
    isc = np.unique(np.vstack((isc1, isc2)), axis=0)

    catalogue = []
    our_xml = Inventory(networks=[], source='EHB')

    for i in xrange(ehb.shape[0]):
        filed = False
        xml = False
        stn_found = isc[isc[:, 0] == ehb[i, 0], :]
        min_dist = 10e10
        if stn_found.shape[0] > 0:
            if stn_found.shape[0] > 1:
                for j in xrange(stn_found.shape[0]):
                    dist = locations2degrees(np.float(stn_found[j, 2]),
                                             np.float(stn_found[j, 3]),
                                             np.float(ehb[i, 1]),
                                             np.float(ehb[i, 2]))
                    if dist < min_dist:
                        min_dist = dist
                        record = stn_found[j, :]
            else:
                min_dist = locations2degrees(np.float(stn_found[0, 2]),
                                             np.float(stn_found[0, 3]),
                                             np.float(ehb[i, 1]),
                                             np.float(ehb[i, 2]))
                record = stn_found[0, :]

#                Now we try to find the same station in XML file
#                if min_dist > 1. or stn_found.shape[0]==0:

        xstn_found = inv.select(station=ehb[i, 0], channel="*HZ")

        if len(stn_found) == 0 and len(xstn_found) == 0:
            # we filed to find station anywhere and assign dummy values
            record = [
                ehb[i, 0], default_net, ehb[i, 1], ehb[i, 2], ehb[i, 3], 'Z',
                '1964-1-1 00:00:00', '2599-12-31 23:59:59'
            ]
            min_dist = 0.
            filed = True
        else:
            # if station is found somehwere we try to iterate and see if XML has data giving it preference through adding extra value to min_dist found in ISC
            if len(xstn_found) > 0:
                #                        print "----------",len(xstn_found)
                #                        print xstn_found[0][0].latitude
                min_dist = min_dist + 0.1
                for j in xrange(len(xstn_found)):
                    dist = locations2degrees(xstn_found[j][0].latitude,
                                             xstn_found[j][0].longitude,
                                             np.float(ehb[i, 1]),
                                             np.float(ehb[i, 2]))
                    if min_dist > dist:
                        min_dist = dist
                        record = xstn_found[j]
                        #                                print record
                        xml = True

# last defence if stations have been done but distance between declared and found locations are more than 1 degree
        if min_dist > 1:
            record = [
                ehb[i, 0], default_net, ehb[i, 1], ehb[i, 2], ehb[i, 3], 'Z',
                '1964-1-1 00:00:00', '2599-12-31 23:59:59'
            ]
            filed = True
        if xml:
            #our_xml.networks.append(record)
            xml = False

        else:
            if filed:

                if len(record[7]) < 5:
                    record[7] = '2599-12-31 23:59:59'
                catalogue.append(record)

            else:

                stn_found = isc[(isc[:, 0] == record[0]) &
                                (isc[:, 1] == record[1]), :]

                for k in xrange(stn_found.shape[0]):
                    net = Network(code=stn_found[k, 1],
                                  stations=[],
                                  description=' ')
                    if len(stn_found[k, 7]) < 5:
                        stn_found[k, 7] = '2599-12-31 23:59:59'
                    catalogue.append(stn_found[k, :])

    stn_found = np.unique(np.array(catalogue), axis=0)
    if len(stn_found[stn_found == '']) > 0 or len(
            stn_found[stn_found == ' ']) > 0:
        print "Some elements are empty, check the list"

    # we composed our inventory. However some stations from ISC list can be left behind. We check if some stations in ISC are forgotten
    lost = []
    for j in xrange(isc.shape[0]):
        # is there any common station name?
        common_st = stn_found[isc[j, 0] == stn_found[:, 0]]
        if common_st.shape[0] > 0:
            # is network code the same?
            common_net = common_st[common_st[:, 1] == isc[j, 1]]
            if common_net.shape[0] < 1:
                # ok we found forgotten one, check the XML
                if len(inv.select(station=isc[j, 0], network=isc[j, 1])) <= 0:
                    # Bingo...
                    lost.append(isc[j, :])
        else:
            if len(inv.select(station=isc[j, 0], network=isc[j, 1])) <= 0:
                # Bingo...
                lost.append(isc[j, :])

    stn_found = np.vstack((stn_found, np.array(lost)))

    for k in xrange(stn_found.shape[0]):

        net = Network(code=stn_found[k, 1], stations=[], description=' ')
        if len(stn_found[k, 7]) < 5:
            stn_found[k, 7] = '2599-12-31 23:59:59'
        catalogue.append(stn_found[k, :])
        sta=Station(code=stn_found[k,0],creation_date=utcdatetime.UTCDateTime(stn_found[k,6]), \
        termination_date=utcdatetime.UTCDateTime(stn_found[k,7]), \
        site=Site(name=' '), \
        latitude=np.float(stn_found[k,2]), \
        longitude=np.float(stn_found[k,3]), \
        elevation=np.float(stn_found[k,4]))

        cha=Channel(code=stn_found[k,5], \
        depth=0., \
        azimuth=0., \
        dip=-90., \
        location_code='', \
        latitude=np.float(stn_found[k,2]), \
        longitude=np.float(stn_found[k,3]), \
        elevation=np.float(stn_found[k,4]))

        sta.channels.append(cha)
        net.stations.append(sta)
        our_xml.networks.append(net)


#             print 'np',stn_found[k,:]

    our_xml.write("station.xml", format="stationxml", validate=True)
    our_xml.write("station.txt", format="stationtxt")
Exemplo n.º 28
0
Created on Mon Jun 10 14:43:36 2019

@author: jpeacock
"""

import obspy
from obspy.core.inventory import Inventory, Network, Station, Channel, Site
from obspy.core.inventory.util import Equipment
import pandas as pd

survey_csv = r"c:\Users\jpeacock\Documents\imush\Archive\survey_summary.csv"
survey_df = pd.read_csv(survey_csv)

# We'll first create all the various objects. These strongly follow the
# hierarchy of StationXML files.
inv = Inventory(networks=[], source="MT Test")

net = Network(
    code="MT",
    # A list of stations. We'll add one later.
    stations=[],
    description="Test stations.",
    # Start-and end dates are optional.
    start_date=obspy.UTCDateTime(2016, 1, 2))
inv.networks.append(net)

for row, station_df in survey_df.iterrows():
    sta = Station(code=station_df['siteID'],
                  latitude=station_df['lat'],
                  longitude=station_df['lon'],
                  elevation=station_df['nm_elev'],
Exemplo n.º 29
0
def MMF_calibration_to_response(directory, plot=False):
    """
    Take directory of MMF calibration spreadsheets and convert to Obspy
    inventory object
    """
    inv = Inventory(networks=[Network(code='MMF')])
    lat = Latitude(0.)
    lon = Longitude(0.)
    chan_map = {
        'Tabellenblatt3': 'X',
        'Tabellenblatt4': 'Y',
        'Tabellenblatt5': 'Z'
    }
    calibs = glob('{}/*.xls'.format(directory))
    avg_amp = {'XNZ': [], 'XNY': [], 'XNX': []}
    avg_phase = {'XNZ': [], 'XNY': [], 'XNX': []}
    avg_sensitivity = {'XNZ': [], 'XNY': [], 'XNX': []}
    avg_freq = []
    for c in calibs:
        serial = c.split()[-2]
        sta = Station(code=serial[1:],
                      latitude=lat,
                      longitude=lon,
                      elevation=0.)
        # Tables slightly shifted for each channel due to comments
        dict_xyz = pd.read_excel(c,
                                 sheet_name=['Tabellenblatt3'],
                                 header=14,
                                 usecols=list(np.arange(4, 14)),
                                 nrows=37)
        dict_xyz.update(
            pd.read_excel(c,
                          sheet_name=['Tabellenblatt4'],
                          header=14,
                          usecols=list(np.arange(5, 15)),
                          nrows=37))
        dict_xyz.update(
            pd.read_excel(c,
                          sheet_name=['Tabellenblatt5'],
                          header=13,
                          usecols=list(np.arange(9, 20)),
                          nrows=37))
        # Get array of sensitivities at 80 Hz for X, Y, Z
        sens = pd.read_excel(c,
                             sheet_name=['Tabellenblatt2'],
                             header=84,
                             usecols=[27],
                             nrows=3)['Tabellenblatt2'].values.squeeze()
        # mV/m/s**2 to V/m/s**2
        sens_dict = {
            'Tabellenblatt3': float(sens[0].replace(',', '.')) * 1e-3,
            'Tabellenblatt4': float(sens[1].replace(',', '.')) * 1e-3,
            'Tabellenblatt5': float(sens[2].replace(',', '.')) * 1e-3
        }
        # Resp for each channel
        for nm, df in dict_xyz.items():
            # Dummy channel
            chan_code = 'XN{}'.format(chan_map[nm])
            # Set samp_rate to 40 kHz so that Nyquist is below max shake freq
            chan = Channel(code=chan_code,
                           location_code='',
                           latitude=lat,
                           longitude=lon,
                           elevation=0.,
                           depth=0.,
                           sample_rate=40000.,
                           sensor=Equipment(
                               type='IEPE Accelerometer',
                               description='Piezoelectric accelerometer',
                               manufacturer='MMF',
                               model='KS943B.100',
                               serial_number=serial))
            values = df[['[Hz]', '[m/s²]', '[°]']].values
            # Add to dict for average channel estimate later
            avg_amp[chan_code].append(values[:, 1])
            avg_phase[chan_code].append(values[:, 2])
            avg_sensitivity[chan_code].append(float(sens_dict[nm]))
            avg_freq = values[:, 0]
            response_elements = [
                ResponseListElement(frequency=values[i][0],
                                    amplitude=values[i][1],
                                    phase=values[i][2])
                for i in range(values.shape[0])
            ]
            # Add a value at zero to avoid deconvolution errors
            response_elements.insert(
                0,
                ResponseListElement(frequency=0.,
                                    amplitude=values[0][1],
                                    phase=values[0][2]))
            resp_stage = ResponseListResponseStage(
                response_list_elements=response_elements,
                stage_gain=1,
                stage_gain_frequency=80.,
                input_units='M/S**2',
                output_units='V',
                stage_sequence_number=1)
            sensitivity = InstrumentSensitivity(value=float(sens_dict[nm]),
                                                frequency=80.,
                                                input_units='M/S**2',
                                                output_units='V',
                                                frequency_range_start=5,
                                                frequency_range_end=15850,
                                                frequency_range_db_variation=3)
            response = Response(instrument_sensitivity=sensitivity,
                                response_stages=[resp_stage])
            chan.response = response
            sta.channels.append(chan)
            # chan.response.plot(min_freq=2.4, sampling_rate=40000.)
        inv[0].stations.append(sta)
    # Now make an 'average' channel for the other sensors
    avg_sta = Station(code='AVG', latitude=lat, longitude=lon, elevation=0.)
    for c in ['XNX', 'XNY', 'XNZ']:
        chan = Channel(code=c,
                       location_code='',
                       latitude=lat,
                       longitude=lon,
                       elevation=0.,
                       depth=0.,
                       sample_rate=40000.,
                       sensor=Equipment(
                           type='IEPE Accelerometer',
                           description='Piezoelectric accelerometer',
                           manufacturer='MMF',
                           model='KS943B.100',
                           serial_number='9999'))
        amp = np.array(avg_amp[c]).mean(axis=0)
        pha = np.array(avg_phase[c]).mean(axis=0)
        response_elements = [
            ResponseListElement(frequency=avg_freq[i],
                                amplitude=amp[i],
                                phase=pha[i]) for i in range(avg_freq.size)
        ]
        # Add a value at zero to avoid deconvolution errors
        response_elements.insert(
            0, ResponseListElement(frequency=0.,
                                   amplitude=amp[0],
                                   phase=pha[0]))
        resp_stage = ResponseListResponseStage(
            response_list_elements=response_elements,
            stage_gain=1,
            stage_gain_frequency=80.,
            input_units='M/S**2',
            output_units='V',
            stage_sequence_number=1)
        sensitivity = InstrumentSensitivity(value=np.array(
            avg_sensitivity[c]).mean(),
                                            frequency=80.,
                                            input_units='M/S**2',
                                            output_units='V',
                                            frequency_range_start=5,
                                            frequency_range_end=15850,
                                            frequency_range_db_variation=3)
        response = Response(instrument_sensitivity=sensitivity,
                            response_stages=[resp_stage])
        chan.response = response
        avg_sta.channels.append(chan)
    inv[0].stations.append(avg_sta)
    if plot:
        inv.plot_response(min_freq=2.4, plot_degrees=True)
    return inv
Exemplo n.º 30
0
def fsb_to_inv(path, orientations=False, debug=0):
    """
    Take excel file of sensor locations and build an Inventory

    :param path: Path to excel spreadsheet
    :param orientations: False or dict of orientation info
    :param debug:
    :return:
    """
    inventory = Inventory()
    inventory.networks = [Network(code='FS')]
    converter = FSB_converter()
    sens_dict = read_fsb_asbuilt(path)
    # Assemble dictionary of {station: {channel: infoz}}
    # Create dict before, then build inventory from channel level upwards
    sta_dict = {}
    extra_dict = {}
    for sta, loc in sens_dict.items():
        # Station location
        # Convert from SURF coords to lat lon, but keep local for actual use
        lon, lat, elev = converter.to_lonlat((loc[0], loc[1], loc[2]))
        depth = 0.0  # Until we do any orientations?
        # Save HMC coords to custom attributes of Station and Channel
        extra = AttribDict({
            'ch1903_east': {
                'value': loc[0],
                'namespace': 'smi:local/hmc'
            },
            'ch1903_north': {
                'value': loc[1],
                'namespace': 'smi:local/hmc'
            },
            'ch1903_elev': {
                'value': loc[2],  # extra will preserve absolute elev
                'namespace': 'smi:local/hmc'
            }
        })
        # Not yet implemented; Pass orientations dict when we do
        if orientations:
            # TODO Something is real effed here. Answers are right though.
            dip_rad = np.arcsin(-orientations[sta]['Sz'])
            az_rad = np.arcsin(orientations[sta]['Sx'] / np.cos(dip_rad))
            dip = np.rad2deg(dip_rad)
            az = np.rad2deg(az_rad)
            # Force positive
            if az < 0:
                az += 360.
            # Correct
            if orientations[sta]['Sx'] < 0 and orientations[sta]['Sy'] < 0:
                az -= 270.
                az = 270. - az
            elif orientations[sta]['Sy'] < 0:
                az = 180 - az
            if debug > 0:
                print(
                    np.array((orientations[sta]['Sx'], orientations[sta]['Sy'],
                              orientations[sta]['Sz'])))
                print(az, dip)
        try:
            if orientations[sta]['Sensor'].endswith(('Z', 'X', 'Y')):
                chan = 'XN{}'.format(orientations[sta]['Sensor'][-1])
                # Geophones
                if orientations[sta]['Sensor'].startswith('G'):
                    no = orientations[sta]['Sensor'][-3]
                # Accelerometers
                else:
                    no = orientations[sta]['Sensor'].split('_')[1]
                sta_name = '{}{}'.format(orientations[sta]['Desc'], no)
                channel = Channel(code=chan,
                                  location_code='',
                                  latitude=lat,
                                  longitude=lon,
                                  elevation=elev,
                                  depth=depth,
                                  azimuth=az,
                                  dip=dip,
                                  response=Response())
                # channel.extra = extra
            elif orientations[sta]['Sensor'].startswith('Hydro'):
                chan = 'XN1'
                sta_name = '{}{}'.format(
                    orientations[sta]['Desc'],
                    orientations[sta]['Sensor'].split('-')[-1].zfill(2))
                channel = Channel(code=chan,
                                  location_code='',
                                  latitude=lat,
                                  longitude=lon,
                                  elevation=elev,
                                  depth=depth,
                                  response=Response())
        except TypeError as e:
            sta_name = sta
            if sta in fsb_accelerometers:
                channels = []
                for chan in ['XNZ', 'XNX', 'XNY']:
                    channels.append(
                        Channel(code=chan,
                                location_code='',
                                latitude=lat,
                                longitude=lon,
                                elevation=elev,
                                depth=depth,
                                response=Response()))
            else:
                channel = Channel(code='XN1',
                                  location_code='',
                                  latitude=lat,
                                  longitude=lon,
                                  elevation=elev,
                                  depth=depth,
                                  response=Response())
                channels = [channel]
        extra_dict[sta_name] = extra
        sta_dict[sta_name] = channels
    for nm, chans in sta_dict.items():
        station = Station(code=nm,
                          latitude=chans[0].latitude,
                          longitude=chans[0].longitude,
                          elevation=chans[0].elevation,
                          channels=chans)
        station.extra = extra_dict[nm]
        inventory[0].stations.append(station)
    return inventory
Exemplo n.º 31
0
# Import all the necessary packages.
from obspy.core.inventory import Inventory, Network, Station
import os
# Variables that you can modify.
source = 'dn_IMAGE-project'
input_file = 'station_info' 
# The input file should be in the same directory as this code and have the
# format : header
# PROJECT	SENSORCODE needs_correction(y/n) LATITUDE	LONGITUDE ELEVATION(m) SENSORTYPE
# ...
# We'll first create all the various objects. These strongly follow the
# hierarchy of StationXML files.
inv = Inventory(
                # We'll add networks later.
                networks=[],
                # The source should be the id whoever create the file.
                source=source)

net = Network(
              # This is the network code according to the SEED standard.
              code=".",
              # A list of stations. We'll add one later.
              stations=[],
              description = ("This inventory file is used for correcting the " +
                             "OBS clock errors. We will ignore the different" +
                             " networks present in our data and assume that " +
                             "they all belong to a single network. This " +
                             "facilitates the processing."))

with open(os.path.dirname(__file__) + '/' + input_file) as file:
Exemplo n.º 32
0
def main(argv):
    inv = read_inventory("IRIS-ALL.xml")
    # if os.path.exists("IRIS-ALL.pkl"): # doesn't work on CentOS for some reason
    #     with open('IRIS-ALL.pkl', 'rb') as f:
    #         import cPickle as pkl
    #         inv = pkl.load(f)
    # else:
    #     inv = read_inventory("IRIS-ALL.xml")
    #     with open('IRIS-ALL.pkl', 'wb') as f:
    #         import pickle as pkl
    #         pkl.dump(inv, f, pkl.HIGHEST_PROTOCOL)
    sensorDict, responseDict = extract_unique_sensors_responses(inv)
    print('\nFound {0} response objects with keys: {1}'.format(len(responseDict.keys()), responseDict.keys()))

    # unknown stations in Indonesia are usually installed by Potsdam and we assume they have network name GE
    default_net = 'GE'
    ehb1 = read_eng('BMG.STN')
    ehb2 = read_eng('ISC.STN')
    ehb = np.unique(np.vstack((ehb1, ehb2)), axis=0)

    isc1 = read_isc('ehb.stn')
    isc2 = read_isc('iscehb.stn')
    isc = np.unique(np.vstack((isc1, isc2)), axis=0)

    catalogue = []
    for i in xrange(ehb.shape[0]):
        filed = False
        xml = False
        stn_found = isc[isc[:, 0] == ehb[i, 0], :]
        min_dist = 10e10
        if stn_found.shape[0] > 0:
            if stn_found.shape[0] > 1:
                for j in xrange(stn_found.shape[0]):
                    dist = locations2degrees(np.float(stn_found[j, 2]), np.float(stn_found[j, 3]), np.float(ehb[i, 1]),
                                             np.float(ehb[i, 2]))
                    if dist < min_dist:
                        min_dist = dist
                        record = stn_found[j, :]
            else:
                min_dist = locations2degrees(np.float(stn_found[0, 2]), np.float(stn_found[0, 3]), np.float(ehb[i, 1]),
                                             np.float(ehb[i, 2]))
                record = stn_found[0, :]

            #                Now we try to find the same station in XML file
            #                if min_dist > 1. or stn_found.shape[0]==0:

        xstn_found = inv.select(station=ehb[i, 0], channel="*HZ")

        if len(stn_found) == 0 and len(xstn_found) == 0:
            # we filed to find station anywhere and assign dummy values
            record = [ehb[i, 0], default_net, ehb[i, 1], ehb[i, 2], ehb[i, 3], 'SHZ', '1964-1-1 00:00:00',
                      '2599-12-31 23:59:59']
            min_dist = 0.
            filed = True
        else:
            # if station is found somehwere we try to iterate and see if XML has data giving it preference through adding extra value to min_dist found in ISC
            if len(xstn_found) > 0:
                #                        print "----------",len(xstn_found)
                #                        print xstn_found[0][0].latitude
                min_dist = min_dist + 0.1
                for j in xrange(len(xstn_found)):
                    dist = locations2degrees(xstn_found[j][0].latitude, xstn_found[j][0].longitude, np.float(ehb[i, 1]),
                                             np.float(ehb[i, 2]))
                    if min_dist > dist:
                        min_dist = dist
                        record = xstn_found[j]
                        #                                print record
                        xml = True

                    # last defence if stations have been done but distance between declared and found locations are more than 1 degree
        if min_dist > 1:
            record = [ehb[i, 0], default_net, ehb[i, 1], ehb[i, 2], ehb[i, 3], 'SHZ', '1964-1-1 00:00:00',
                      '2599-12-31 23:59:59']
            filed = True
        if xml:
            xml = False

        else:
            if filed:

                if len(record[7]) < 5:
                    record[7] = '2599-12-31 23:59:59'
                catalogue.append(record)

            else:

                stn_found = isc[(isc[:, 0] == record[0]) & (isc[:, 1] == record[1]), :]

                for k in xrange(stn_found.shape[0]):
                    net = Network(code=stn_found[k, 1], stations=[], description=' ')
                    if len(stn_found[k, 7]) < 5:
                        stn_found[k, 7] = '2599-12-31 23:59:59'
                    catalogue.append(stn_found[k, :])

    stn_found = np.unique(np.array(catalogue), axis=0)
    if len(stn_found[stn_found == '']) > 0 or len(stn_found[stn_found == ' ']) > 0:
        print
        "Some elements are empty, check the list"

    # we composed our inventory. However some stations from ISC list can be left behind. We check if some stations in ISC are forgotten
    lost = []
    for j in xrange(isc.shape[0]):
        # is there any common station name?
        common_st = stn_found[isc[j, 0] == stn_found[:, 0]]
        if common_st.shape[0] > 0:
            # is network code the same?
            common_net = common_st[common_st[:, 1] == isc[j, 1]]
            if common_net.shape[0] < 1:
                # ok we found forgotten one, check the XML
                if len(inv.select(station=isc[j, 0], network=isc[j, 1])) <= 0:
                    # Bingo...
                    lost.append(isc[j, :])
        else:
            if len(inv.select(station=isc[j, 0], network=isc[j, 1])) <= 0:
                # Bingo...
                lost.append(isc[j, :])

    stn_found = np.vstack((stn_found, np.array(lost)))

    netDict = defaultdict(list)
    for k in xrange(stn_found.shape[0]):
        result = inv.select(network=stn_found[k, 1])
        if (len(result.networks)):
            net = result.networks[0]
            net.stations = []
        else:
            net = Network(code=stn_found[k, 1], stations=[], description=' ')

        # print stn_found[k, 1]

        if len(stn_found[k, 7]) < 5:
            stn_found[k, 7] = '2599-12-31 23:59:59'
        catalogue.append(stn_found[k, :])
        sta = Station(code=stn_found[k, 0], creation_date=utcdatetime.UTCDateTime(stn_found[k, 6]), \
                      termination_date=utcdatetime.UTCDateTime(stn_found[k, 7]), \
                      site=Site(name=' '), \
                      latitude=np.float(stn_found[k, 2]), \
                      longitude=np.float(stn_found[k, 3]), \
                      elevation=np.float(stn_found[k, 4]))

        if (stn_found[k, 5] in responseDict.keys()):
            r = responseDict[stn_found[k, 5]]

            cha = Channel(code=stn_found[k, 5], \
                          depth=0., \
                          azimuth=0., \
                          dip=-90., \
                          location_code='', \
                          latitude=np.float(stn_found[k, 2]), \
                          longitude=np.float(stn_found[k, 3]), \
                          elevation=np.float(stn_found[k, 4]), \
                          # sensor=sensorDict[stn_found[k,5]], \
                          response=r)

            sta.channels.append(cha)

            if (type(netDict[stn_found[k, 1]]) == Network):
                netDict[stn_found[k, 1]].stations.append(sta)
            else:
                net.stations.append(sta)
                netDict[stn_found[k, 1]] = net

            #                 print 'np',stn_found[k,:]
            # end if

    our_xml = Inventory(networks=netDict.values(), source='EHB')

    print 'Writing output files..'
    for inet, net in enumerate(our_xml.networks):
        currInv = Inventory(networks=[net], source='EHB')
        currInv.write("output/station.%d.xml" % (inet), format="stationxml", validate=True)

    # our_xml.write("station.xml",format="stationxml", validate=True)
    our_xml.write("station.txt", format="stationtxt")
Exemplo n.º 33
0
def check_stations(maxradius, SEARCH_TYPE, search_netstat, excl_net, excl_stat,
                   lat, lon, Year, Month, Day, Hour, Minute, Second):

    sta_lat = lat
    sta_lon = lon
    maxradius = maxradius / 111  # conversion from kn to degrees
    start_1 = (str(Year) + '-' + str(Month) + '-' + str(Day) + '-' +
               str(Hour) + '-' + str(Minute) + '-' + str(Second))
    UTCDateTime.DEFAULT_PRECISION = 0
    t0 = UTCDateTime(start_1)

    #################################
    # if only stations in Ireland
    if SEARCH_TYPE == 1:
        sta_lat = 53.522
        sta_lon = -8.744
        maxradius = 2.36

    ##############################
    # load inventories
    inv = Inventory(networks=[])

    if SEARCH_TYPE != 2:  # if no specific stations are specified
        # Raspberry Shake Network
        client = Client(base_url='https://fdsnws.raspberryshakedata.com/')
        try:
            inv += client.get_stations(longitude=sta_lon,
                                       latitude=sta_lat,
                                       maxradius=maxradius,
                                       starttime=t0,
                                       endtime=t0 + 60,
                                       channel="EHZ,SHZ",
                                       level="channel")
        except:
            print("No Raspberry Shake station data found")
            print('')
        # BGS network
        client = Client('http://eida.bgs.ac.uk')
        try:
            inv += client.get_stations(longitude=sta_lon,
                                       latitude=sta_lat,
                                       maxradius=maxradius,
                                       starttime=t0,
                                       endtime=t0 + 60,
                                       channel="HHZ",
                                       level="channel")
        except:
            print("No GB station data found")
            print('')
        # networks provided by GFZ service
        client = Client('GFZ')
        try:
            inv += client.get_stations(longitude=sta_lon,
                                       latitude=sta_lat,
                                       maxradius=maxradius,
                                       starttime=t0,
                                       endtime=t0 + 60,
                                       channel="HHZ",
                                       level="channel")
        except:
            print("No GFZ station data found")
            print('')

    if SEARCH_TYPE == 2:  # if specific stations are specified
        for stat in search_netstat:
            net = stat.split(".")[0]
            station = stat.split(".")[1]
            # Raspberry Shake Network
            if net == 'AM':
                client = Client(
                    base_url='https://fdsnws.raspberryshakedata.com/')
                try:
                    inv += client.get_stations(network=net,
                                               station=station,
                                               starttime=t0,
                                               endtime=t0 + 60,
                                               channel="EHZ,SHZ",
                                               level="channel")
                except:
                    print("No Raspberry Shake station data found")
                    print('')
            # BGS network
            if net == 'GB':
                client = Client('http://eida.bgs.ac.uk')
                try:
                    inv += client.get_stations(network=net,
                                               station=station,
                                               starttime=t0,
                                               endtime=t0 + 60,
                                               channel="HHZ",
                                               level="channel")
                except:
                    print("No GB station data found")
                    print('')
            # networks provided by GFZ service
            if net != 'AM' and net != 'GB':
                client = Client('GFZ')
                try:
                    inv += client.get_stations(network=net,
                                               station=station,
                                               starttime=t0,
                                               endtime=t0 + 60,
                                               channel="HHZ",
                                               level="channel")
                except:
                    print("No GFZ station data found")
                    print('')

    ########################################
    # populate station entries nslc (network station location channel)
    nslc = []
    for network in inv:
        for station in network:
            for channel in station:
                nslc.extend([
                    network.code + "." + station.code + "." +
                    channel.location_code + "." + channel.code
                ])

    # remove multiple entries:
    nslc = list(dict.fromkeys(nslc))

    print(
        'found data for these stations in provided search area and time frame:'
    )
    print(nslc)

    ###################################
    # exclude certain networks/stations

    excl_netstat = []
    for item in nslc:
        for ex_n in excl_net:
            if re.search(ex_n + '.+',
                         item):  # The .+ symbol is used in place of * symbol
                excl_netstat.append(item)
    for item in excl_netstat:
        nslc.remove(item)

    excl_netstat = []
    for item in nslc:
        for ex_s in excl_stat:
            if re.search('.+' + ex_s + '.+',
                         item):  # The .+ symbol is used in place of * symbol
                excl_netstat.append(item)
    for item in excl_netstat:
        nslc.remove(item)

    print('')
    print('new list after excluding networks and/or stations:')
    print(nslc)
    #print(inv)

    return nslc, t0, inv
Exemplo n.º 34
0
if exists(ASDF_out):
    delete_queary = query_yes_no("Remove Existing ASDF File?")
    if delete_queary == 'yes':
        # removing existing ASDF
        remove(ASDF_out)
    elif delete_queary == 'no':
        sys.exit(0)

# create the log file
ASDF_log_file = open(ASDF_log_out, 'w')

# Create/open the ASDF file
ds = pyasdf.ASDFDataSet(ASDF_out, compression="gzip-3")

# create empty inventory to add all inventories together
new_inv = Inventory(networks=[], source="Geoscience Australia AusArray")

# create the inventory object for the network
net_inv = Network(code=FDSNnetwork[:2])

# dictionary to keep end date/start date for each station
station_start_end_dict ={}

# dictionary to keep inventory for all stations (default dict)
station_inventory_dict = {}



# function to create the ASDF waveform ID tag
def make_ASDF_tag(tr, tag):
    # def make_ASDF_tag(ri, tag):
Exemplo n.º 35
0
    def test_get_response(self):
        response_n1_s1 = Response('RESPN1S1')
        response_n1_s2 = Response('RESPN1S2')
        response_n2_s1 = Response('RESPN2S1')
        channels_n1_s1 = [
            Channel(code='BHZ',
                    location_code='',
                    latitude=0.0,
                    longitude=0.0,
                    elevation=0.0,
                    depth=0.0,
                    response=response_n1_s1)
        ]
        channels_n1_s2 = [
            Channel(code='BHZ',
                    location_code='',
                    latitude=0.0,
                    longitude=0.0,
                    elevation=0.0,
                    depth=0.0,
                    response=response_n1_s2)
        ]
        channels_n2_s1 = [
            Channel(code='BHZ',
                    location_code='',
                    latitude=0.0,
                    longitude=0.0,
                    elevation=0.0,
                    depth=0.0,
                    response=response_n2_s1)
        ]
        stations_1 = [
            Station(code='N1S1',
                    latitude=0.0,
                    longitude=0.0,
                    elevation=0.0,
                    channels=channels_n1_s1),
            Station(code='N1S2',
                    latitude=0.0,
                    longitude=0.0,
                    elevation=0.0,
                    channels=channels_n1_s2)
        ]
        stations_2 = [
            Station(code='N2S1',
                    latitude=0.0,
                    longitude=0.0,
                    elevation=0.0,
                    channels=channels_n2_s1)
        ]
        networks = [
            Network('N1', stations=stations_1),
            Network('N2', stations=stations_2)
        ]
        inv = Inventory(networks=networks, source='TEST')

        response = inv.get_response('N1.N1S1..BHZ',
                                    UTCDateTime('2010-01-01T12:00'))
        self.assertEqual(response, response_n1_s1)
        response = inv.get_response('N1.N1S2..BHZ',
                                    UTCDateTime('2010-01-01T12:00'))
        self.assertEqual(response, response_n1_s2)
        response = inv.get_response('N2.N2S1..BHZ',
                                    UTCDateTime('2010-01-01T12:00'))
        self.assertEqual(response, response_n2_s1)
Exemplo n.º 36
0
def surf_stations_to_inv(excel_file, debug=0):
    """
    Take Petrs orientation excel file for the hydrophones/accelerometers
    and build an inventory for later use.
    :param excel_file: path to Petr's excel file (formatting hard-coded)
    :return: obspy.core.Inventory
    """
    # Call coordinate converter
    converter = SURF_converter()
    sta_df = pd.read_excel(excel_file,
                           skiprows=[0, 1, 2, 3],
                           header=1,
                           nrows=90)
    # Assemble dictionary of {station: {channel: infoz}}
    # Create dict before, then build inventory from channel level upwards
    sta_dict = {}
    extra_dict = {}
    for i, row in sta_df.iterrows():
        # Station location
        # Convert from SURF coords to lat lon, but keep local for actual use
        lon, lat, elev = converter.to_lonlat(
            (row['Easting(m)'], row['Northing(m)'], row['Elev(m)']))
        # Correct for arbitrary zero 'depth' of 130m
        elev -= 130
        # Already accounted for in the elevation but will include here as its
        # ...a required arg for Channel()
        depth = row['Depth (m)']
        # Save HMC coords to custom attributes of Station and Channel
        extra = AttribDict({
            'hmc_east': {
                'value': row['Easting(m)'],
                'namespace': 'smi:local/hmc'
            },
            'hmc_north': {
                'value': row['Northing(m)'],
                'namespace': 'smi:local/hmc'
            },
            'hmc_elev': {
                'value': row['Elev(m)'],  # extra will preserve absolute elev
                'namespace': 'smi:local/hmc'
            }
        })
        # Sort out azimuth and dip for this channel (if it exists)
        if not np.isnan(row['Sx']):
            # TODO Something is real effed here. Answers are right though.
            dip_rad = np.arcsin(-row['Sz'])
            az_rad = np.arcsin(row['Sx'] / np.cos(dip_rad))
            dip = np.rad2deg(dip_rad)
            az = np.rad2deg(az_rad)
            # Force positive
            if az < 0:
                az += 360.
            # Correct
            if row['Sx'] < 0 and row['Sy'] < 0:
                az -= 270.
                az = 270. - az
            elif row['Sy'] < 0:
                az = 180 - az
            if debug > 0:
                print(np.array((row['Sx'], row['Sy'], row['Sz'])))
                print(az, dip)
        if row['Sensor'].endswith(('Z', 'X', 'Y')):
            chan = 'XN{}'.format(row['Sensor'][-1])
            # Geophones
            if row['Sensor'].startswith('G'):
                continue
            # Accelerometers
            else:
                no = row['Sensor'].split('_')[1]
            sta_name = '{}{}'.format(row['Desc'], no)
            if sta_name in ['OB14', 'OT17', 'PDT2', 'PDT5', 'PSB8', 'PST11']:
                # These are geode stations only, skip
                continue
            channel = Channel(code=chan,
                              location_code='',
                              latitude=lat,
                              longitude=lon,
                              elevation=elev,
                              depth=depth,
                              azimuth=az,
                              dip=dip,
                              response=Response())
            # channel.extra = extra
        elif row['Sensor'].startswith('Hydro'):
            chan = 'XN1'
            sta_name = '{}{}'.format(row['Desc'],
                                     row['Sensor'].split('-')[-1].zfill(2))
            channel = Channel(code=chan,
                              location_code='',
                              latitude=lat,
                              longitude=lon,
                              elevation=elev,
                              depth=depth,
                              response=Response())
        extra_dict[sta_name] = extra
        # channel.extra = extra
        if sta_name in sta_dict.keys():
            sta_dict[sta_name].append(channel)
        else:
            sta_dict[sta_name] = [channel]
    # Now loop station dict to create inventory
    stas = []
    for nm, chans in sta_dict.items():
        station = Station(code=nm,
                          latitude=chans[0].latitude,
                          longitude=chans[0].longitude,
                          elevation=chans[0].elevation,
                          channels=chans)
        station.extra = extra_dict[nm]
        stas.append(station)
    # Build inventory
    inventory = Inventory(networks=[Network(code='SV', stations=stas)],
                          source='SURF')
    return inventory