Ejemplo n.º 1
0
def generateStationTestData(sta):

    time_range = (UTCDateTime(TIME_RANGE[0]), UTCDateTime(TIME_RANGE[1]))

    client = Client("IRIS")
    inv = client.get_stations(network=NETWORK,
                              station=sta,
                              channel=CHANNEL,
                              starttime=time_range[0],
                              endtime=time_range[1],
                              level='channel')
    print(inv)

    traces = client.get_waveforms(network=NETWORK,
                                  station=sta,
                                  channel=CHANNEL,
                                  location='*',
                                  starttime=time_range[0],
                                  endtime=time_range[1])
    print(traces)

    outfile = 'test_data_' + sta + '.h5'
    asdf_out = pyasdf.ASDFDataSet(outfile, mode='w')
    asdf_out.add_stationxml(inv)
    asdf_out.add_waveforms(traces, TAG)

    print("Saved data to " + outfile)
Ejemplo n.º 2
0
    def queryByBBoxInterval(self, outputFileName, bbox, timeinterval, chan='*Z', bbpadding=2,
                            event_id=None, verbose=False):
        """ Time interval is a tuple (starttime,endtime)
        """
        assert len(timeinterval) == 2, "timeinterval must be a tuple of ascending timestamps. len=" + str(
            len(timeinterval)) + " " + str(timeinterval)

        query_ds = pyasdf.ASDFDataSet(outputFileName)

        client = Client(self._client)
        ref_inv = client.get_stations(network=self._network,
                                      starttime=UTCDateTime(timeinterval[0]),
                                      endtime=UTCDateTime(timeinterval[1]),
                                      minlongitude=bbox[0] - bbpadding,
                                      maxlongitude=bbox[1] + bbpadding,
                                      minlatitude=bbox[2] - bbpadding,
                                      maxlatitude=bbox[3] + bbpadding,
                                      level='channel')

        if verbose:
            print(ref_inv)

        ref_st = Stream()

        # go through inventory and request timeseries data
        for net in ref_inv:
            for stn in net:
                stime = UTCDateTime(timeinterval[0])
                etime = UTCDateTime(timeinterval[1])
                step = 3600*24*10
                while stime + step < etime:
                    try:
                        ref_st = client.get_waveforms(network=net.code, station=stn.code,
                                                      channel=chan, location='*',
                                                      starttime=stime,
                                                      endtime=stime+step)
                        print ref_st
                        self.ref_stations.append(net.code + '.' + stn.code)
                        st_inv = ref_inv.select(station=stn.code, channel=chan)
                        
                        query_ds.add_stationxml(st_inv)
                        for tr in ref_st:
                            query_ds.add_waveforms(tr, "reference_station")
                    except FDSNException:
                        print('Data not available from Reference Station: ' + stn.code)
                    # end try
                    stime += step
                #wend
        # end for

        #tr.write(os.path.join(os.path.dirname(outputFileName), tr.id + ".MSEED"),
        #         format="MSEED") # Don't write miniseed
        if verbose:
            print("Wrote Reference Waveforms to ASDF file: " + outputFileName)
            print('\nWaveform data query completed.')

        metaOutputFileName = os.path.join(os.path.dirname(outputFileName),
                                          'meta.%s.xml'%(os.path.basename(outputFileName)))
        ref_inv.write(metaOutputFileName, format="STATIONXML")
        del query_ds
Ejemplo n.º 3
0
def getXmlFromIRIS(network=None):
    if network is None:
        return
    client = Client("IRIS")
    # Use level=response to get channel information...
    # ...which holds the location code necessary for station referencing
    inv = client.get_stations(network=network, level='response')
    inv.write('./' + network + '.xml', format='stationxml', validate=True)
Ejemplo n.º 4
0
 def get_stations(self, startdate=None, enddate=None,  network=None, station=None, location=None, channel=None,
         minlatitude=None, maxlatitude=None, minlongitude=None, maxlongitude=None, latitude=None, longitude=None, minradius=None, maxradius=None):
     """Get station inventory from IRIS server
     =======================================================================================================
     Input Parameters:
     startdate, enddata  - start/end date for searching
     network             - Select one or more network codes.
                             Can be SEED network codes or data center defined codes.
                                 Multiple codes are comma-separated (e.g. "IU,TA").
     station             - Select one or more SEED station codes.
                             Multiple codes are comma-separated (e.g. "ANMO,PFO").
     location            - Select one or more SEED location identifiers.
                             Multiple identifiers are comma-separated (e.g. "00,01").
                             As a special case ?--? (two dashes) will be translated to a string of two space
                             characters to match blank location IDs.
     channel             - Select one or more SEED channel codes.
                             Multiple codes are comma-separated (e.g. "BHZ,HHZ").             
     minlatitude         - Limit to events with a latitude larger than the specified minimum.
     maxlatitude         - Limit to events with a latitude smaller than the specified maximum.
     minlongitude        - Limit to events with a longitude larger than the specified minimum.
     maxlongitude        - Limit to events with a longitude smaller than the specified maximum.
     latitude            - Specify the latitude to be used for a radius search.
     longitude           - Specify the longitude to the used for a radius search.
     minradius           - Limit to events within the specified minimum number of degrees from the
                             geographic point defined by the latitude and longitude parameters.
     maxradius           - Limit to events within the specified maximum number of degrees from the
                             geographic point defined by the latitude and longitude parameters.
     =======================================================================================================
     """
     try: starttime      = obspy.core.utcdatetime.UTCDateTime(startdate)
     except: starttime   = None
     try: endtime        = obspy.core.utcdatetime.UTCDateTime(enddate)
     except: endtime     = None
     client  = Client('IRIS')
     inv     = client.get_stations(network=network, station=station, starttime=starttime, endtime=endtime, channel=channel, 
                 minlatitude=minlatitude, maxlatitude=maxlatitude, minlongitude=minlongitude, maxlongitude=maxlongitude,
                     latitude=latitude, longitude=longitude, minradius=minradius, maxradius=maxradius, level='channel')
     self.add_stationxml(inv)
     try: self.inv       += inv
     except: self.inv    = inv
     return 
Ejemplo n.º 5
0
                #Many (perhaps most) of the picks have no assigned channel.
                #use the iris client's ability to parse lists of channels to get
                #an appropriate waveform.

                #compute back-azimuth
                stalong=float(pick[4].strip())
                stalat=float(pick[5].strip())

                baz=distaz(evlat,evlong,stalat,stalong)[2]

                #get appropriate N/E waveforms to rotate

                #TODO convert this try/except block to use the IRIS client
                try:
                    #search for N/1 channel with high-frequency response
                    inv=irisclient.get_stations(starttime=starttime,endtime=endtime,station=st,level="channel",channel="BHN,BH1,HHN,HH1,SHN,SH1")
                    #find appropriate channels in the inventory (ASDF returns list, not inventory type)
                    chan=inv.get_contents()['channels'][0].split('.')

                    stream=irisclient.get_waveforms(chan[0],chan[1],chan[2],chan[3],starttime,endtime)
                    wf1=stream[0]
                    if wf1.stats['channel'][-1] == '1':
                        wf2=irisclient.get_waveforms(chan[0],chan[1],chan[2],chan[3][0:-1]+'2',starttime,endtime)[0]
                        wfz=irisclient.get_waveforms(chan[0],chan[1],chan[2],chan[3][0:-1]+'Z',starttime,endtime)[0]

                        stream=Stream(traces=[wfz,wf1,wf2])
                        #get an inventory including the Z and E/2 channels
                        IRISinv=irisclient.get_stations(starttime=starttime,endtime=endtime,station=st,level="channel")
                        stream=stream.rotate(method="->ZNE",inventory=IRISinv)
                        
                    else:
Ejemplo n.º 6
0
from obspy import UTCDateTime
import os

starttime = UTCDateTime("2012-10-01T01:00:00")
endtime = UTCDateTime("2012-10-02T01:00:00")

output_file = "/g/data/ha3/US_test.h5"

temp_sta = "249A"
perm_sta = "255A"

client = Client("IRIS")

ref_inv = client.get_stations(network="TA",
                              station=perm_sta,
                              channel="BHZ",
                              starttime=starttime,
                              endtime=endtime,
                              level='channel')

print(ref_inv)

temp_inv = client.get_stations(network="TA",
                               station=temp_sta,
                               channel="BHZ",
                               starttime=starttime,
                               endtime=endtime,
                               level='channel')

print(temp_inv)

# get waveforms
Ejemplo n.º 7
0
import matplotlib.animation as animation
Writer = animation.writers['pillow']
writer = Writer(fps=20, metadata=dict(artist='Me'), bitrate=1800)

sta = 'R32B'
loc = '00'
net = 'N4'
chan = 'HHZ'

stime = UTCDateTime('2019-08-16 12:59:10')
etime = stime + 120

client = Client()
inv = client.get_stations(network=net,
                          station=sta,
                          starttime=stime,
                          endtime=etime,
                          channel=chan,
                          level="response")
st = Stream()
st += client.get_waveforms(net, sta, loc, chan, stime, etime)

st.detrend('constant')
st.merge(fill_value=0)
st.attach_response(inv)
st.remove_response(output="DISP")
#st.rotate(method="->ZNE",inventory=inv)
st.filter("bandpass", freqmin=.5, freqmax=5)
tr = st[0]
t = np.linspace(0, (tr.stats.npts - 1) / tr.stats.sampling_rate,
                num=tr.stats.npts)
Ejemplo n.º 8
0
 def read_TA_lst(self, infname, startdate=None, enddate=None,  startbefore=None, startafter=None, endbefore=None, endafter=None, location=None, channel=None,\
         includerestricted=False, minlatitude=None, maxlatitude=None, minlongitude=None, maxlongitude=None, \
         latitude=None, longitude=None, minradius=None, maxradius=None):
     """Get station inventory from IRIS server
     =======================================================================================================
     Input Parameters:
     startdate, enddata  - start/end date for searching
     network             - Select one or more network codes.
                             Can be SEED network codes or data center defined codes.
                                 Multiple codes are comma-separated (e.g. "IU,TA").
     station             - Select one or more SEED station codes.
                             Multiple codes are comma-separated (e.g. "ANMO,PFO").
     location            - Select one or more SEED location identifiers.
                             Multiple identifiers are comma-separated (e.g. "00,01").
                             As a special case ?--? (two dashes) will be translated to a string of two space
                             characters to match blank location IDs.
     channel             - Select one or more SEED channel codes.
                             Multiple codes are comma-separated (e.g. "BHZ,HHZ").
     includerestricted   - default is False
     minlatitude         - Limit to events with a latitude larger than the specified minimum.
     maxlatitude         - Limit to events with a latitude smaller than the specified maximum.
     minlongitude        - Limit to events with a longitude larger than the specified minimum.
     maxlongitude        - Limit to events with a longitude smaller than the specified maximum.
     latitude            - Specify the latitude to be used for a radius search.
     longitude           - Specify the longitude to the used for a radius search.
     minradius           - Limit to events within the specified minimum number of degrees from the
                             geographic point defined by the latitude and longitude parameters.
     maxradius           - Limit to events within the specified maximum number of degrees from the
                             geographic point defined by the latitude and longitude parameters.
     =======================================================================================================
     """
     try:
         starttime = obspy.core.utcdatetime.UTCDateTime(startdate)
     except:
         starttime = None
     try:
         endtime = obspy.core.utcdatetime.UTCDateTime(enddate)
     except:
         endtime = None
     try:
         startbefore = obspy.core.utcdatetime.UTCDateTime(startbefore)
     except:
         startbefore = None
     try:
         startafter = obspy.core.utcdatetime.UTCDateTime(startafter)
     except:
         startafter = None
     try:
         endbefore = obspy.core.utcdatetime.UTCDateTime(endbefore)
     except:
         endbefore = None
     try:
         endafter = obspy.core.utcdatetime.UTCDateTime(endafter)
     except:
         endafter = None
     client = Client('IRIS')
     init_flag = True
     with open(infname, 'rb') as fio:
         for line in fio.readlines():
             network = line.split()[1]
             station = line.split()[2]
             if network == 'NET':
                 continue
             # print network, station
             if init_flag:
                 try:
                     inv     = client.get_stations(network=network, station=station, starttime=starttime, endtime=endtime, startbefore=startbefore, startafter=startafter,\
                                 endbefore=endbefore, endafter=endafter, channel=channel, minlatitude=minlatitude, maxlatitude=maxlatitude, \
                                     minlongitude=minlongitude, maxlongitude=maxlongitude, latitude=latitude, longitude=longitude, minradius=minradius, \
                                         maxradius=maxradius, level='channel', includerestricted=includerestricted)
                 except:
                     print('No station inv: ', line)
                     continue
                 init_flag = False
                 continue
             try:
                 inv     += client.get_stations(network=network, station=station, starttime=starttime, endtime=endtime, startbefore=startbefore, startafter=startafter,\
                             endbefore=endbefore, endafter=endafter, channel=channel, minlatitude=minlatitude, maxlatitude=maxlatitude, \
                                 minlongitude=minlongitude, maxlongitude=maxlongitude, latitude=latitude, longitude=longitude, minradius=minradius, \
                                     maxradius=maxradius, level='channel', includerestricted=includerestricted)
             except:
                 print('No station inv: ', line)
                 continue
     self.add_stationxml(inv)
     try:
         self.inv += inv
     except:
         self.inv = inv
     return
Ejemplo n.º 9
0
            )
            service = fdsn

        for i, pick in enumerate(picks):
            # get waveform data
            _st = service.get_waveforms(
                pick.waveform_id['network_code'],
                pick.waveform_id['station_code'],
                pick.waveform_id['location_code'] or '',
                pick.waveform_id['channel_code'][:2] + '?', starttime, endtime)

            # get station metadata
            _inv = fdsn.get_stations(
                starttime=starttime,
                endtime=endtime,
                network=pick.waveform_id['network_code'],
                station=pick.waveform_id['station_code'],
                location=pick.waveform_id['location_code'] or '',
                channel=pick.waveform_id['channel_code'][:2] + '?',
                level="channel")

            # Rotating streams when necessary while trimming to the same length all of them
            _st = _st.rotate(method="->ZNE",
                             inventory=_inv,
                             components=('ZNE'))

            # append stream to streams and inventory to inventories
            if i == 0:
                st = _st
                inv = _inv
            else:
                st += _st
Ejemplo n.º 10
0
class Downloader:

    def __init__(self,df,station,outdir):

        self.station = station
        self.data = df
        self.out = outdir
        # self.summary = [] # list to hold all tr_ids
        # print(self.data)
#           Resets indexing of DataFrame

        # print('{}/{}_downloaded_streams.txt'.format(outdir,outdir.split('/')[-1]))
        try:
            #print('Make /Users/ja17375/Shear_Wave_Splitting/Data/SAC_files/{}'.format(station))
            os.mkdir('{}/{}'.format(self.out,station))
        except FileExistsError:
            print('It already exists, Hooray! Less work for me!')

            # pass
    #   Made

        #self.outfile = open('/Users/ja17375/Shear_Wave_Splitting/Data/SAC_files/{}/{}_downloaded_streams_Jacks_Split.txt'.format(station,station),'w+')

        self.attempts = 0 #Counter for how many attempted downloads there were
        self.fdsnx = 0 #Counter for how many attempts hit a FDSNNoDataException
        self.dwn = 0 #Counter for how many events were downloaded
        self.ex = 0 #Counter for how many event already exist in filesystem and therefore werent downloaded
        self.ts = 0 #Counter for events who;s traces are too short.
        self.fdsnclient_evt = Client('IRIS') # Serparate client for events (hopefully to get round the "no event avialbel bug")
        self.fdsnclient = Client('IRIS')
#       Download Station Data

    def download_station_data(self):
        """
        Download or read important station data and make sure it is right
        """
        try:
            stat =  self.fdsnclient.get_stations(channel='BH?',station='{}'.format(self.station))
            self.network = stat.networks[0].code
            self.stla = stat.networks[0].stations[0].latitude
            self.stlo = stat.networks[0].stations[0].longitude
            # print(self.network)
            return True
        except FDSNNoDataException:
            return False

    def set_event_data(self,i,sep):
        """
        Function to download event information so we can get mroe accurate start times
        """
        self.evla = self.data.EVLA[i]
        self.evlo = self.data.EVLO[i]
        if sep is False:

            self.date = self.data.DATE[i]
            if 'TIME' in self.data.columns:
                self.time = self.data.TIME[i]
            else:
                self.time = '0000'

            datetime = str(self.date) + "T" + self.time #Combined date and time inputs for converstion t UTCDateTime object
            self.start = obspy.core.UTCDateTime(datetime)

            try:
                if 'TIME' in self.data.columns:
                    end = self.start + 60
                    print('Search starts {} , ends at {}'.format(self.start,end))
                    cat = self.fdsnclient_evt.get_events(starttime=self.start,endtime=self.start+86400 ,latitude=self.evla,longitude=self.evlo,maxradius=0.25,minmag=5.5) #Get event in order to get more accurate event times.
                    # self.time = '{:02d}{:02d}{:02d}'.format(cat[0].origins[0].time.hour,cat[0].origins[0].time.minute,cat[0].origins[0].time.second)
                else:
                    # No Time so we need to search over the whole day
                    end = self.start + 86400

                    print('Search starts {} , ends at {}'.format(self.start,end))
                    cat = self.fdsnclient_evt.get_events(starttime=self.start,endtime=self.start+86400 ,latitude=self.evla,longitude=self.evlo,maxradius=0.25,minmag=5.5) #Get event in order to get more accurate event times.
                if len(cat) > 1:
                    print("WARNING: MORE THAN ONE EVENT OCCURS WITHIN 5km Search!!")
                    print('Selecting Event with the largest magnitude')
                    # Select biggest magnitude
                    max_mag = max([cat[j].magnitudes[0].mag for j in [i for i,c in enumerate(cat)]])
                    cat = cat.filter('magnitude >= {}'.format(max_mag))
                    print(cat)

                self.time = '{:02d}{:02d}{:02d}'.format(cat[0].origins[0].time.hour,cat[0].origins[0].time.minute,cat[0].origins[0].time.second)
                self.start.minute = cat[0].origins[0].time.minute
                self.start.hour = cat[0].origins[0].time.hour
                print(self.time)

                self.start.second = cat[0].origins[0].time.second

                # Lines commented out as they are only needed if TIME is prvoided as hhmm (For Deng's events there is
                # no TIME provided so we just have to used the event time downloaded)
                # if self.start.minute != cat[0].origins[0].time.minute:
                #     self.time = self.time[:2] + str(cat[0].origins[0].time.minute) # Time is hhmm so we subtract the old minute value and add the new one

                dep = cat[0].origins[0].depth
                if dep is not None:
                    self.evdp = dep/1000.0 # divide by 1000 to convert depth to [km[]
                else:
                    self.evdp = 10.0 #Hard code depth to 10.0 km if evdp cannot be found
            except FDSNNoDataException:
                print("No Event Data Available")
                self.evdp = 0
            except FDSNException:
                print("FDSNException for get_events")
                # pass
        elif sep is True:
            self.start = obspy.core.UTCDateTime('{}'.format(self.data.DATE[i])) #iso8601=True
            self.date = '{:04d}{:03d}'.format(self.start.year,self.start.julday)
            self.time = '{:02d}{:02d}{:02d}'.format(self.start.hour,self.start.minute,self.start.second)
            self.evdp = self.data.EVDP[i]

    def download_traces(self,ch):
        """
        Function that downloads the traces for a given event and station
        """
        # if len(self.time) is 6:
        print('Start: {}. self.time: {}'.format(self.start,self.time))
        tr_id = "{}/{}/{}_{}_{}_{}.sac".format(self.out,self.station,self.station,self.date,self.time,ch)
        # elif len(self.time) is 4:
            # tr_id = "{}/{}/{}_{}_{}{}_{}.sac".format(self.out,self.station,self.station,self.date,self.time,self.start.second,ch)
        # print("Looking for :", tr_id)


        if ch == 'BHE':
            self.attempts += 1 # Counts the number of traces that downloads are attempted for

        if os.path.isfile(tr_id) == True:
            print("{} exists. It was not downloaded".format(tr_id)) # File does not exist

            if ch == 'BHE':
                out_id = '_'.join(tr_id.split('_')[0:-1])
                self.outfile.write('{}_\n'.format(out_id))
                # self.summary.append(out_id)
                self.ex += 1
        else:
            # print("It doesnt exists. Download attempted")
            st = obspy.core.stream.Stream() # Initialises our stream variable

            if self.network is 'BK':
                download_client = obspy.clients.fdsn.Client('NCEDC')
            else:
                download_client = obspy.clients.fdsn.Client('IRIS')
            try:
                st = download_client.get_waveforms(self.network,self.station,'??',ch,self.start,self.start + 3000,attach_response=True)
                # print(st)
                if len(st) > 3:
                    print("WARNING: More than three traces downloaded for event ", tr_id)
                elif len(st) < 3:
                    self.ts += 1

                dist_client = iris.Client() # Creates client to calculate event - station distance
                print('STLA {} STLO {} EVLA {} EVLO {}'.format(self.stla,self.stlo,self.evla,self.evlo))
                self.d = dist_client.distaz(stalat=self.stla,stalon=self.stlo,evtlat=self.evla,evtlon=self.evlo)
                print('Source-Reciever distance is {}'.format(self.d['distance']))
                if (self.d['distance'] >= 85.0) or (self.d['distance'] >=145.0):
                
                        if st[0].stats.endtime - st[0].stats.starttime >= 2000:
                            # print('Record length is {}, which is ok'.format(st[0].stats.endtime - st[0].stats.starttime))
                            self.write_st(st,tr_id)

                            if ch == 'BHE':
                                self.dwn += 1
                                out_id = '_'.join(tr_id.split('_')[0:-1])
                                self.outfile.write('{}_\n'.format(out_id))
                                # self.summary.append(out_id)

                        else:
                            print('Record length is {}, which is too short'.format(st[0].stats.endtime - st[0].stats.starttime))
                            if ch == 'BHE':
                                self.ts += 1
                else:
                    print("Source Reciever Distance is too small")
                    if ch == 'BHE':
                        self.ts += 1
            except FDSNException:
                print('No Data Exception??')
                if ch == 'BHE':
                    self.fdsnx += 1

    def write_st(self,st,tr_id):
        """

        """
        # print('Writing {}'.format(tr_id))
        st[0].write('holder.sac', format='SAC',) # Writes traces as SAC files
        #st.plot()
        st_2 = obspy.core.read('holder.sac')
        #sac = AttribDict() # Creates a dictionary sacd to contain all the header information I want.
        ## Set origin times
        st_2[0].stats.sac.nzyear = self.start.year
        st_2[0].stats.sac.nzjday = self.start.julday
        st_2[0].stats.sac.nzhour = self.start.hour
        st_2[0].stats.sac.nzmin = self.start.minute
        st_2[0].stats.sac.nzsec = self.start.second
        st_2[0].stats.sac.nzmsec = self.start.microsecond
        ## Station Paramters
        st_2[0].stats.sac.stla = self.stla
        st_2[0].stats.sac.stlo = self.stlo
        ## Event Paramters
        st_2[0].stats.sac.evla = self.evla#cat[0].origins[0].latitude # Event latitude
        st_2[0].stats.sac.evlo = self.evlo#cat[0].origins[0].longitude # Event longitude
        st_2[0].stats.sac.evdp = self.evdp#cat[0].origins[0].depth/1000 # Event depth
        st_2[0].stats.sac.kstnm = '{:>8}'.format(self.station)
        # print('stla = {}, stlo = {}, evla = {}, evlo = {}'.format(stla,stlo,evla,evlo))


        st_2[0].stats.sac.gcarc = self.d['distance'] # d.values returns the values from dictionary d produced by distaz. list converts this to a list attribute which can then be indexed to extract the great cricle distance in degrees
        st_2[0].stats.sac.dist = self.d['distancemeters']/1000 # Distnace in kilometers
        st_2[0].stats.sac.baz = self.d['backazimuth'] # Backzimuth (Reciever - SOurce)
        st_2[0].stats.sac.az = self.d['azimuth'] # Azimuth (Source - Receiver)
        st_2[0].write(tr_id, format='SAC',byteorder=1)
Ejemplo n.º 11
0
 def __init__(self, stream):
     self.stream = stream
     client = Client("IRIS")
     self.inv = client.get_stations(network=stream.traces[0].stats.network,
                                    station=stream.traces[0].stats.station,
                                    level='response')
def fdsnws2geomag():
    '''Convert fdsnws query to geomagnetic data file'''
    parser = argparse.ArgumentParser(
        description=
        'Query the FDSN webservice and convert the geomagnetic data standards')
    parser.add_argument('--url',
                        default=DEFAULT_FDNWS,
                        help='FDSN-WS URL (default: %s)' % DEFAULT_FDNWS)
    parser.add_argument('--format',
                        choices=['internet', 'iaga2002', 'imfv122'],
                        default='iaga2002',
                        help="Output format (default: iaga2002)")
    parser.add_argument('--output',
                        default=sys.stdout,
                        help='Output file (default: stdout).')
    # query specific parameters
    parser.add_argument('--date',
                        default=DEFAULT_DATE,
                        help='Date of the request (default: %s)' %
                        DEFAULT_DATE)
    parser.add_argument('--network',
                        default=DEFAULT_NETWORK,
                        help='Network code (default: DEFAULT_NETWORK)')
    parser.add_argument('--station', required=True, help='Station code')
    parser.add_argument(
        '--location',
        nargs='+',
        default=DEFAULT_LOCATIONS,
        help=
        'Data type + source (data type = R - raw, D - definitive, source = 0,1,2,3..., default: %s)'
        % DEFAULT_LOCATIONS)
    parser.add_argument('--channel',
                        nargs='+',
                        default=DEFAULT_CHANNELS,
                        help='FDSN compliant channel query (default: %s)' %
                        ",".join(DEFAULT_CHANNELS))
    parser.add_argument('-v',
                        '--verbose',
                        action='store_true',
                        help='Verbosity')
    args = parser.parse_args()

    # Set the logging level
    logging.basicConfig(
        format='%(asctime)s.%(msecs)03d %(levelname)s \
            %(module)s %(funcName)s: %(message)s',
        datefmt="%Y-%m-%d %H:%M:%S",
        level=logging.INFO if args.verbose else logging.WARNING)

    # Convert date to starttime and endtime
    reftime = UTCDateTime(args.date)
    starttime = UTCDateTime(
        reftime.datetime.replace(hour=0, minute=0, second=0, microsecond=0))
    endtime = UTCDateTime(
        reftime.datetime.replace(hour=23,
                                 minute=59,
                                 second=59,
                                 microsecond=999999))

    # Create a handler client
    logging.info("Connecting to %s", args.url)
    client = Client(args.url)
    logging.info("Requesting data for %s.%s.%s.%s from %s to %s", args.network,
                 args.station, ",".join(args.location), ",".join(args.channel),
                 starttime.isoformat(), endtime.isoformat())
    stream = Stream(
        client.get_waveforms(args.network, args.station,
                             ",".join(args.location), ",".join(args.channel),
                             starttime, endtime))
    logging.info("Found stream: %s", str(stream.__str__(extended=True)))
    # Load optional inventory information
    inventory = client.get_stations(network=args.network, station=args.station)

    # Handle if no data was found
    if not stream:
        logging.warning("No data found")
        return 1

    # Before sending the raw data for writing, we need to trim the response
    # from the FDSNWS query to are actual request time.  We also merge by
    # location.
    logging.info("Writing informtion to %s", str(args.output))
    # Correct the endtime with delta of the first trace
    endtime = UTCDateTime(reftime.datetime) + 86400 - stream[0].stats.delta
    stream.merge_by_location().trim(starttime,
                                    endtime).write(args.output,
                                                   format=args.format,
                                                   inventory=inventory)
def fdsnws2directory():
    '''
    Much like the fdsnws2geomag but is purely design to get the data from the FDSN-WS
    and add it according to the structure found on geomagnetic daqs servers.

    These structure vary depending on the source but can be customized by input argument.

    Filename for each can not be customized since these following strict naming convention.

    The convention can be found in the pygeomag/data/formats directory.
    '''
    parser = argparse.ArgumentParser(
        description=
        'Query the FDSN webservice and convert the geomagnetic data standards')
    parser.add_argument('--url',
                        default=DEFAULT_FDNWS,
                        help='FDSN-WS URL (default: %s)' % DEFAULT_FDNWS)
    parser.add_argument('--format',
                        choices=['iaga2002', 'imfv122'],
                        default='iaga2002',
                        help="Output format (default: iaga2002)")
    parser.add_argument(
        '--directory',
        default=DEFAULT_DIRECTORY,
        help=
        'Output directory with optional datetime parameter as accept by python datetime (default: %s).'
        % DEFAULT_DIRECTORY)
    # query specific parameters
    parser.add_argument('--date',
                        default=DEFAULT_DATE,
                        help='Date of the request (default: %s)' %
                        DEFAULT_DATE)
    parser.add_argument('--network',
                        default=DEFAULT_NETWORK,
                        help='Network code (default: DEFAULT_NETWORK)')
    parser.add_argument('--station',
                        default='*',
                        help='Station code (default: *)')
    parser.add_argument(
        '--location',
        nargs='+',
        default=DEFAULT_LOCATIONS,
        help=
        'Data type + source (data type = R - raw, D - definitive, source = 0,1,2,3..., default: %s)'
        % DEFAULT_LOCATIONS)
    parser.add_argument('--channel',
                        nargs='+',
                        default=DEFAULT_CHANNELS,
                        help='FDSN compliant channel query (default: %s)' %
                        "," % DEFAULT_CHANNELS)
    parser.add_argument('-v',
                        '--verbose',
                        action='store_true',
                        help='Verbosity')
    args = parser.parse_args()

    # Set the logging level
    logging.basicConfig(
        format='%(asctime)s.%(msecs)03d %(levelname)s \
            %(module)s %(funcName)s: %(message)s',
        datefmt="%Y-%m-%d %H:%M:%S",
        level=logging.INFO if args.verbose else logging.WARNING)

    # Convert date to starttime and endtime
    reftime = UTCDateTime(args.date)
    starttime = UTCDateTime(
        reftime.datetime.replace(hour=0, minute=0, second=0, microsecond=0))
    endtime = UTCDateTime(
        reftime.datetime.replace(hour=23,
                                 minute=59,
                                 second=59,
                                 microsecond=999999))

    # Create a handler client
    logging.info("Connecting to %s", args.url)
    client = Client(args.url)
    logging.info("Requesting data for %s.%s.%s.%s from %s to %s", args.network,
                 args.station, ",".join(args.location), ",".join(args.channel),
                 starttime.isoformat(), endtime.isoformat())
    stream = Stream(
        client.get_waveforms(args.network, args.station,
                             ",".join(args.location), ",".join(args.channel),
                             starttime, endtime))
    logging.info("Found stream: %s", str(stream.__str__(extended=True)))
    # Load optional inventory information
    inventory = client.get_stations(network=args.network, station=args.station)

    # Handle if no data was found
    if not stream:
        logging.warning("No data found")
        return 1

    # Before sending the raw data for writing, we need to trim the response
    # from the FDSNWS query to are actual request time.  We also merge by
    # location.
    # Correct the endtime with delta of the first trace
    endtime = UTCDateTime(reftime.datetime) + 86400 - stream[0].stats.delta
    stream = stream.merge_by_location().trim(starttime, endtime)

    # Loop through the list of stream and generate the unique list of station
    # codes.  We know the network code is constant and its a single sampling rate
    # request.
    stations = set([trace.stats.station for trace in stream])

    # Convert the directory format string to a full path
    directory = starttime.strftime(args.directory)
    logging.info("Creating directory %s if does not exist", directory)
    pathlib.Path(directory).mkdir(parents=True, exist_ok=True)

    for station in stations:
        # Extract the station I need
        extract = stream.select(station=station)
        # Generate its filename (depends on the format)
        if args.format in ['iaga2002']:
            filename = pygeomag.data.formats.iaga2002.get_filename(
                extract[0].stats)
        elif args.format in ['imfv122']:
            filename = pygeomag.data.formats.imfv122.get_filename(
                extract[0].stats)
        else:
            raise ValueError(
                "Unable to generate filename for unhandled format %s" %
                args.format)
        filename = os.path.join(directory, filename)
        logging.info("Writing magnetic data to %s", filename)
        extract.write(filename, format=args.format, inventory=inventory)
Ejemplo n.º 14
0
ax = fig.add_subplot(1, 1, 1)
ax.plot(tr_Z.times("matplotlib"), tr_Z.data, "k-")
ax.xaxis_date()
fig.autofmt_xdate()
plt.ylabel('counts')
plt.title('Raw Data')
fig.tight_layout()
plt.show()
fig.savefig('1_raw.png')   

# downloading the instrument response of the station from IRIS
client = Client("IRIS")
inventory = client.get_stations(network=dataset.attrs['network_code'],
                                station=dataset.attrs['receiver_code'],
                                starttime=UTCDateTime(dataset.attrs['trace_start_time']),
                                endtime=UTCDateTime(dataset.attrs['trace_start_time']) + 60,
                                loc="*", 
                                channel="*",
                                level="response")  
# exploring the downloaded response file   
print(inventory)
inventory[0].plot_response(min_freq=1E-4) 


# converting into displacement
st = make_stream(dataset)
st = st.remove_response(inventory=inventory, output="DISP", plot=False)
tr_Z = st[2]
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(tr_Z.times("matplotlib"), tr_Z.data, "k-")
Ejemplo n.º 15
0
mpl.rc('font', serif='Times')
mpl.rc('text', usetex=True)
mpl.rc('font', size=18)

debug = True
sta = 'COR'
chans = '00'
presloc = '30'
net = "IU"
stime = UTCDateTime('2019-121T00:00:00.0')
etime = stime + 3. * 24. * 60. * 60.

client = Client()
inv = client.get_stations(network="IU",
                          station=sta,
                          starttime=stime,
                          endtime=etime,
                          channel="LH*",
                          level='response')

if debug:
    print(inv)

ctime = stime
st = Stream()

#while ctime <= etime:
#    string = '/tr1/telemetry_days/IU_' + sta + '/' + str(ctime.year) + '/' + \
#                str(ctime.year) + '_' + str(ctime.julday).zfill(3) + '/*'
#    st += read(string + chans + '_LH*')
#    st += read(string + presloc + '_LDO*')
#    ctime += 24.*60.*60.
Ejemplo n.º 16
0
    def create_SG2K_initiate(self, event, quake_df):

        # Launch the custom station/component selection dialog
        sel_dlg = selectionDialog(parent=self,
                                  sta_list=self.station_list,
                                  chan_list=self.channel_codes)
        if sel_dlg.exec_():
            select_sta, select_comp = sel_dlg.getSelected()

            # specify output directory for miniSEED files
            temp_seed_out = os.path.join(os.path.dirname(self.cat_filename),
                                         event)

            # create directory
            if os.path.exists(temp_seed_out):
                shutil.rmtree(temp_seed_out)
            os.mkdir(temp_seed_out)

            query_time = UTCDateTime(quake_df['qtime'] - (10 * 60)).timestamp

            trace_starttime = UTCDateTime(quake_df['qtime'] - (5 * 60))
            trace_endtime = UTCDateTime(quake_df['qtime'] + (15 * 60))

            # Create a Stream object to put data into
            # st = Stream()
            # Create a dictionary to put traces into (keys are tr_ids)
            st_dict = defaultdict(list)

            print('---------------------------------------')
            print('Finding Data for Earthquake: ' + event)

            if os.path.splitext(self.db_filename)[1] == ".db":
                # run SQL query
                for matched_entry in self.session.query(Waveforms). \
                        filter(or_(and_(Waveforms.starttime <= query_time, query_time < Waveforms.endtime),
                                   and_(query_time <= Waveforms.starttime, Waveforms.starttime < query_time + 30 * 60)),
                               Waveforms.station.in_(select_sta),
                               Waveforms.component.in_(select_comp)):
                    print(matched_entry.ASDF_tag)

                    # read in the data to obspy
                    temp_st = read(
                        os.path.join(matched_entry.path,
                                     matched_entry.waveform_basename))

                    # modify network header
                    temp_tr = temp_st[0]
                    temp_tr.stats.network = matched_entry.new_network

                    # st.append(temp_tr)
                    st_dict[temp_tr.get_id()].append(temp_tr)

            if os.path.splitext(self.db_filename)[1] == ".json":
                # run python dictionary query
                for key, matched_entry in self.network_dict.iteritems():
                    if ((matched_entry['starttime'] <= query_time < matched_entry['endtime']) \
                                or (
                                query_time <= matched_entry['starttime'] and matched_entry['starttime'] < query_time + (
                            30 * 60))) \
                            and ((matched_entry['station'] in select_sta) and (
                                matched_entry['component'] in select_comp)):
                        print(matched_entry['ASDF_tag']
                              )  #, os.path.join(matched_entry['path'], key))

                        # read in the data to obspy
                        temp_st = read(os.path.join(matched_entry['path'],
                                                    key))

                        # modify network header
                        temp_tr = temp_st[0]
                        temp_tr.stats.network = matched_entry['new_network']

                        # trim trace to start and endtime
                        temp_tr.trim(starttime=trace_starttime,
                                     endtime=trace_endtime)

                        # st.append(temp_tr)
                        st_dict[temp_tr.get_id()].append(temp_tr)

            # free memory
            temp_st = None
            temp_tr = None

            if not len(st_dict) == 0:
                # .__nonzero__():

                print('')
                print('Merging Traces from %s Stations....' % len(st_dict))
                # Attempt to merge all traces with matching ID'S (same keys in dict) in place
                # st.merge()

                for key in st_dict.keys():
                    if len(st_dict[key]) > 1:
                        temp_st = Stream(traces=st_dict[key])
                        # merge in place
                        # print('\tMerging %s in Stream:' % temp_st.count())
                        temp_st.merge()
                        # assign trace back to dictionary key if there is data
                        if temp_st.__nonzero__():
                            print("Station {0} has {1} Seconds of data".format(
                                key, temp_st[0].stats.endtime -
                                temp_st[0].stats.starttime))
                            st_dict[key] = temp_st[0]
                        elif not temp_st.__nonzero__():
                            print("No Data for: %s" % key)
                            # no data for station delete key
                            del st_dict[key]
                            continue
                    elif len(st_dict[key]) == 1:
                        print("Station {0} has {1} Seconds of data".format(
                            key, st_dict[key][0].stats.endtime -
                            st_dict[key][0].stats.starttime))
                        st_dict[key] = st_dict[key][0]
                    elif len(st_dict[key]) == 0:
                        # no data for station delete key
                        print("No Data for: %s" % key)
                        del st_dict[key]

                print(
                    '\nTrimming Traces to 20 mins around earthquake time....')

                # now trim the st object to 5 mins
                # before query time and 15 minutes afterwards

                for key in st_dict.keys():

                    st_dict[key] = st_dict[key].trim(starttime=trace_starttime,
                                                     endtime=trace_endtime,
                                                     pad=True,
                                                     fill_value=0)

                # st.trim(starttime=trace_starttime, endtime=trace_endtime, pad=True, fill_value=0)

                try:
                    # write traces into temporary directory
                    # for tr in st:
                    for key in st_dict.keys():
                        if type(st_dict[key]) == Stream:
                            #there is a problem with network codes (two stations named the same)
                            #ignore it for now
                            continue
                        st_dict[key].write(os.path.join(
                            temp_seed_out, st_dict[key].get_id() + ".MSEED"),
                                           format="MSEED")
                    print("\nWrote Temporary MiniSEED data to: " +
                          temp_seed_out)
                    print('')
                except:
                    print("Something Went Wrong!")

            else:
                print("No Data for Earthquake!")

            # free memory
            st_dict = None

            # Now requesting reference station data from IRIS if desired
            if self.ref_radioButton.isChecked():
                ref_dir = os.path.join(temp_seed_out, 'ref_data')

                # create ref directory
                if os.path.exists(ref_dir):
                    shutil.rmtree(ref_dir)
                os.mkdir(ref_dir)

                # request stations that are close to the selected stations

                # first use the coords lists to get a bounding box for array
                def calc_bounding_box(x, y):
                    min_x, max_x = (min(x), max(x))
                    min_y, max_y = (min(y), max(y))

                    return (min_x, max_x, min_y, max_y)

                bb = calc_bounding_box(self.station_coords[0],
                                       self.station_coords[1])

                # request data for near earthquake time up to 5 degrees from bounding box of array
                print(
                    '\nRequesting Waveform Data from Nearby Permanent Network Stations....'
                )

                client = Client("IRIS")
                self.ref_inv = client.get_stations(
                    network="AU",
                    starttime=UTCDateTime(quake_df['qtime'] - (5 * 60)),
                    endtime=UTCDateTime(quake_df['qtime'] + (15 * 60)),
                    minlongitude=bb[0] - 2,
                    maxlongitude=bb[1] + 2,
                    minlatitude=bb[2] - 2,
                    maxlatitude=bb[3] + 2,
                    level='channel')

                print(self.ref_inv)

                ref_st = Stream()

                # go through inventory and request timeseries data
                for net in self.ref_inv:
                    for stn in net:
                        try:
                            ref_st += client.get_waveforms(
                                network=net.code,
                                station=stn.code,
                                channel='*',
                                location='*',
                                starttime=UTCDateTime(quake_df['qtime'] -
                                                      (5 * 60)),
                                endtime=UTCDateTime(quake_df['qtime'] +
                                                    (15 * 60)))
                        except FDSNException:
                            print(
                                'No Data for Earthquake from Reference Station: '
                                + stn.code)

                        else:
                            # plot the reference stations
                            js_call = "addRefStation('{station_id}', {latitude}, {longitude});" \
                                .format(station_id=stn.code, latitude=stn.latitude,
                                        longitude=stn.longitude)
                            self.web_view.page().mainFrame(
                            ).evaluateJavaScript(js_call)

                try:
                    # write ref traces into temporary directory
                    for tr in ref_st:
                        tr.write(os.path.join(ref_dir, tr.id + ".MSEED"),
                                 format="MSEED")
                    print("Wrote Reference MiniSEED data to: " + ref_dir)
                    print('\nEarthquake Data Query Done!!!')
                except:
                    print("Something Went Wrong Writing Reference Data!")

                self.ref_inv.write(os.path.join(ref_dir, "ref_metadata.xml"),
                                   format="STATIONXML")