Exemplo n.º 1
0
class EnhancedSacPzResponse(Object):
    codes = Tuple.T(4, String.T())
    tmin = Timestamp.T(optional=True)
    tmax = Timestamp.T(optional=True)
    lat = Float.T()
    lon = Float.T()
    elevation = Float.T()
    depth = Float.T()
    dip = Float.T()
    azimuth = Float.T()
    input_unit = String.T()
    output_unit = String.T()
    response = trace.PoleZeroResponse.T()

    def spans(self, *args):
        if len(args) == 0:
            return True
        elif len(args) == 1:
            return ((self.tmin is None or
                     self.tmin <= args[0]) and
                    (self.tmax is None or
                     args[0] <= self.tmax))

        elif len(args) == 2:
            return ((self.tmin is None or
                     args[1] >= self.tmin) and
                    (self.tmax is None or
                     self.tmax >= args[0]))
Exemplo n.º 2
0
class SourceGenerator(LocationGenerator):

    nevents = Int.T(default=2)
    avoid_water = Bool.T(
        default=False, help='Avoid sources offshore under the ocean / lakes.')

    radius = Float.T(default=10 * km)

    time_min = Timestamp.T(default=util.str_to_time('2017-01-01 00:00:00'))
    time_max = Timestamp.T(default=util.str_to_time('2017-01-03 00:00:00'))

    magnitude_min = Float.T(default=4.0)
    magnitude_max = Float.T(default=0.0)
    b_value = Float.T(optional=True,
                      help='Gutenberg Richter magnitude distribution.')

    def __init__(self, *args, **kwargs):
        super(SourceGenerator, self).__init__(*args, **kwargs)
        if self.b_value and self.magnitude_max:
            raise Exception('b_value and magnitude_max are mutually exclusive')

    def draw_magnitude(self, rstate):
        if self.b_value is None:
            return rstate.uniform(self.magnitude_min, self.magnitude_max)
        else:
            return moment_tensor.rand_to_gutenberg_richter(
                rstate.rand(), self.b_value, magnitude_min=self.magnitude_min)

    def get_sources(self):
        sources = []
        for ievent in range(self.nevents):
            src = self.get_source(ievent)
            src.name = 'scenario_ev%03d' % (ievent + 1)
            sources.append(src)

        return sources

    def dump_data(self, path):
        fn_sources = op.join(path, 'sources.yml')
        with open(fn_sources, 'w') as f:
            for src in self.get_sources():
                f.write(src.dump())

        fn_events = op.join(path, 'events.txt')
        with open(fn_events, 'w') as f:
            for isrc, src in enumerate(self.get_sources()):
                f.write(src.pyrocko_event().dump())

        return [fn_events, fn_sources]

    def add_map_artists(self, automap):
        pass
Exemplo n.º 3
0
class Equipment(Object):
    resource_id = String.T(optional=True, xmlstyle='attribute')
    type = String.T(optional=True, xmltagname='Type')
    description = Unicode.T(optional=True, xmltagname='Description')
    manufacturer = Unicode.T(optional=True, xmltagname='Manufacturer')
    vendor = Unicode.T(optional=True, xmltagname='Vendor')
    model = Unicode.T(optional=True, xmltagname='Model')
    serial_number = String.T(optional=True, xmltagname='SerialNumber')
    installation_date = Timestamp.T(optional=True,
                                    xmltagname='InstallationDate')
    removal_date = DummyAwareOptionalTimestamp.T(optional=True,
                                                 xmltagname='RemovalDate')
    calibration_date_list = List.T(Timestamp.T(xmltagname='CalibrationDate'))
Exemplo n.º 4
0
class StaticTarget(meta.MultiLocation):
    '''
    A computation request for a spatial multi-location target of
    static/geodetic quantities.
    '''
    quantity = meta.QuantityType.T(
        optional=True,
        default='displacement',
        help='Measurement quantity type, for now only `displacement` is'
             'supported.')

    interpolation = InterpolationMethod.T(
        default='nearest_neighbor',
        help='Interpolation method between Green\'s functions. Supported are'
             ' ``nearest_neighbor`` and ``multilinear``')

    tsnapshot = Timestamp.T(
        optional=True,
        help='time of the desired snapshot in [s], '
             'If not given, the first sample is taken. If the desired sample'
             ' exceeds the length of the Green\'s function store,'
             ' the last sample is taken.')

    store_id = meta.StringID.T(
        optional=True,
        help='ID of Green\'s function store to use for the computation. '
             'If not given, the processor may use a system default.')

    def base_key(self):
        return (self.store_id,
                self.coords5.shape,
                self.quantity,
                self.tsnapshot,
                self.interpolation)

    @property
    def ntargets(self):
        ''' Number of targets held by instance. '''
        return self.ncoords

    def get_targets(self):
        ''' Discretizes the multilocation target into a list of
        :class:`Target:`

        :returns: :class:`Target`
        :rtype: list
        '''
        targets = []
        for i in xrange(self.ntargets):
            targets.append(
                Target(
                    lat=self.coords5[i, 0],
                    lon=self.coords5[i, 1],
                    north_shift=self.coords5[i, 2],
                    east_shift=self.coords5[i, 3],
                    elevation=self.coords5[i, 4]))
        return targets

    def post_process(self, engine, source, statics):
        return meta.StaticResult(result=statics)
Exemplo n.º 5
0
class Station(BaseNode):
    '''This type represents a Station epoch. It is common to only have
    a single station epoch with the station's creation and termination
    dates as the epoch start and end dates.'''

    latitude = Latitude.T(xmltagname='Latitude')
    longitude = Longitude.T(xmltagname='Longitude')
    elevation = Distance.T(xmltagname='Elevation')
    site = Site.T(optional=True, xmltagname='Site')
    vault = Unicode.T(optional=True, xmltagname='Vault')
    geology = Unicode.T(optional=True, xmltagname='Geology')
    equipment_list = List.T(Equipment.T(xmltagname='Equipment'))
    operator_list = List.T(Operator.T(xmltagname='Operator'))
    creation_date = Timestamp.T(optional=True, xmltagname='CreationDate')
    termination_date = DummyAwareOptionalTimestamp.T(
        optional=True, xmltagname='TerminationDate')
    total_number_channels = Counter.T(optional=True,
                                      xmltagname='TotalNumberChannels')
    selected_number_channels = Counter.T(optional=True,
                                         xmltagname='SelectedNumberChannels')
    external_reference_list = List.T(
        ExternalReference.T(xmltagname='ExternalReference'))
    channel_list = List.T(Channel.T(xmltagname='Channel'))

    @property
    def position_values(self):
        lat = self.latitude.value
        lon = self.longitude.value
        elevation = value_or_none(self.elevation)
        return lat, lon, elevation
Exemplo n.º 6
0
class DirContext(Object):
    path = String.T()
    mtime = Timestamp.T()
    entries = DirContextEntry.T()

    def get_entry(self, fn):
        path = os.path.abspath(fn)
        for entry in self.entries:
            if entry.path == path:
                return entry

        raise Exception('entry not found')

    def iter_entries(self, fn, step=1):
        current = self.get_entry(fn)
        by_ifile = dict(
            (entry.ifile, entry) for entry in self.entries
            if entry.tstart == current.tstart)

        icurrent = current.ifile
        while True:
            icurrent += step
            try:
                yield by_ifile[icurrent]

            except KeyError:
                break
Exemplo n.º 7
0
class CreationInfo(Object):
    agency_id = AgencyID.T(optional=True, xmltagname='agencyID')
    agency_uri = ResourceReference.T(optional=True, xmltagname='agencyURI')
    author = Author.T(optional=True)
    author_uri = ResourceReference.T(optional=True, xmltagname='authorURI')
    creation_time = Timestamp.T(optional=True)
    version = Version.T(optional=True)
Exemplo n.º 8
0
class Meta(Object):
    """Meta configuration for ``Scene``."""

    scene_title = String.T(default="Unnamed Scene", help="Scene title")
    scene_id = String.T(default="None", help="Scene identification")
    satellite_name = String.T(
        default="Undefined Mission", help="Satellite mission name"
    )
    wavelength = Float.T(optional=True, help="Wavelength in [m]")
    orbital_node = StringChoice.T(
        choices=["Ascending", "Descending", "Undefined"],
        default="Undefined",
        help="Orbital direction, ascending/descending",
    )
    time_master = Timestamp.T(
        default=1481116161.930574, help="Timestamp for master acquisition"
    )
    time_slave = Timestamp.T(
        default=1482239325.482, help="Timestamp for slave acquisition"
    )
    extra = Dict.T(default={}, help="Extra header information")
    filename = String.T(optional=True)

    def __init__(self, *args, **kwargs):
        self.old_import = False

        mapping = {"orbit_direction": "orbital_node"}

        for old, new in mapping.items():
            if old in kwargs.keys():
                kwargs[new] = kwargs.pop(old, None)
                self.old_import = True

        Object.__init__(self, *args, **kwargs)

    @property
    def time_separation(self):
        """
        :getter: Absolute time difference between ``time_master``
                 and ``time_slave``
        :type: timedelta
        """
        return dt.fromtimestamp(self.time_slave) - dt.fromtimestamp(self.time_master)
Exemplo n.º 9
0
class Comment(Object):
    '''Container for a comment or log entry. Corresponds to SEED
    blockettes 31, 51 and 59.'''

    id = Counter.T(optional=True, xmlstyle='attribute')
    value = Unicode.T(xmltagname='Value')
    begin_effective_time = Timestamp.T(optional=True,
                                       xmltagname='BeginEffectiveTime')
    end_effective_time = DummyAwareOptionalTimestamp.T(
        optional=True, xmltagname='EndEffectiveTime')
    author_list = List.T(Person.T(xmltagname='Author'))
Exemplo n.º 10
0
class SourceGenerator(LocationGenerator):

    nevents = Int.T(default=2)
    avoid_water = Bool.T(
        default=False,
        help='Avoid sources offshore under the ocean / lakes.')

    radius = Float.T(
        default=10*km)

    time_min = Timestamp.T(default=util.str_to_time('2017-01-01 00:00:00'))
    time_max = Timestamp.T(default=util.str_to_time('2017-01-03 00:00:00'))

    magnitude_min = Float.T(default=4.0)
    magnitude_max = Float.T(default=7.0)

    def get_sources(self):
        sources = []
        for ievent in range(self.nevents):
            sources.append(self.get_source(ievent))

        return sources

    def dump_data(self, path):
        fn_sources = op.join(path, 'sources.yml')
        with open(fn_sources, 'w') as f:
            for src in self.get_sources():
                f.write(src.dump())

        fn_events = op.join(path, 'events.txt')
        with open(fn_events, 'w') as f:
            for src in self.get_sources():
                f.write(src.pyrocko_event().dump())

        return [fn_events, fn_sources]

    def add_map_artists(self, automap):
        pass
Exemplo n.º 11
0
class Detection(Object):
    id = String.T()
    time = Timestamp.T()
    location = geo.Point.T()
    ifm = Float.T()

    def get_event(self):
        lat, lon = geo.point_coords(self.location, system='latlon')

        event = model.Event(lat=lat,
                            lon=lon,
                            depth=self.location.z,
                            time=self.time,
                            name='%s (%g)' % (self.id, self.ifm))

        return event
Exemplo n.º 12
0
class WaveformMisfitResult(gf.Result, MisfitResult):
    '''Carries the observations for a target and corresponding synthetics.

    A number of different waveform  or phase representations are possible.
    '''
    processed_obs = Trace.T(optional=True)
    processed_syn = Trace.T(optional=True)
    filtered_obs = Trace.T(optional=True)
    filtered_syn = Trace.T(optional=True)
    spectrum_obs = TraceSpectrum.T(optional=True)
    spectrum_syn = TraceSpectrum.T(optional=True)

    taper = trace.Taper.T(optional=True)
    tobs_shift = Float.T(optional=True)
    tsyn_pick = Timestamp.T(optional=True)
    tshift = Float.T(optional=True)
    cc = Trace.T(optional=True)

    piggyback_subresults = List.T(WaveformPiggybackSubresult.T())
Exemplo n.º 13
0
class BaseNode(Object):
    '''A base node type for derivation from: Network, Station and
    Channel types.'''

    code = String.T(xmlstyle='attribute')
    start_date = Timestamp.T(optional=True, xmlstyle='attribute')
    end_date = DummyAwareOptionalTimestamp.T(optional=True,
                                             xmlstyle='attribute')
    restricted_status = RestrictedStatus.T(optional=True, xmlstyle='attribute')
    alternate_code = String.T(optional=True, xmlstyle='attribute')
    historical_code = String.T(optional=True, xmlstyle='attribute')
    description = Unicode.T(optional=True, xmltagname='Description')
    comment_list = List.T(Comment.T(xmltagname='Comment'))

    def spans(self, *args):
        if len(args) == 0:
            return True
        elif len(args) == 1:
            return ((self.start_date is None or self.start_date <= args[0])
                    and (self.end_date is None or args[0] <= self.end_date))

        elif len(args) == 2:
            return ((self.start_date is None or args[1] >= self.start_date)
                    and (self.end_date is None or self.end_date >= args[0]))
Exemplo n.º 14
0
class Target(meta.Receiver):
    '''
    A seismogram computation request for a single component, including
    its post-processing parmeters.
    '''

    quantity = meta.QuantityType.T(
        optional=True,
        help='Measurement quantity type (e.g. "displacement", "pressure", ...)'
             'If not given, it is guessed from the channel code.'
             'Beware: If velocity is requested, the velocity is not directly'
             'retrieved. Instead a numpy.diff is run on the retrieved'
             'displacements, with lower accuracy. For high accuracy we'
             'recommend using the Pyrocko object DifferentiationResponse.')

    codes = Tuple.T(
        4, String.T(), default=('', 'STA', '', 'Z'),
        help='network, station, location and channel codes to be set on '
             'the response trace.')

    elevation = Float.T(
        default=0.0,
        help='station surface elevation in [m]')

    store_id = meta.StringID.T(
        optional=True,
        help='ID of Green\'s function store to use for the computation. '
             'If not given, the processor may use a system default.')

    sample_rate = Float.T(
        optional=True,
        help='sample rate to produce. '
             'If not given the GF store\'s default sample rate is used. '
             'GF store specific restrictions may apply.')

    interpolation = meta.InterpolationMethod.T(
        default='nearest_neighbor',
        help='Interpolation method between Green\'s functions. Supported are'
             ' ``nearest_neighbor`` and ``multilinear``')

    optimization = OptimizationMethod.T(
        default='enable',
        optional=True,
        help='disable/enable optimizations in weight-delay-and-sum operation')

    tmin = Timestamp.T(
        optional=True,
        help='time of first sample to request in [s]. '
             'If not given, it is determined from the Green\'s functions.')

    tmax = Timestamp.T(
        optional=True,
        help='time of last sample to request in [s]. '
             'If not given, it is determined from the Green\'s functions.')

    azimuth = Float.T(
        optional=True,
        help='azimuth of sensor component in [deg], clockwise from north. '
             'If not given, it is guessed from the channel code.')

    dip = Float.T(
        optional=True,
        help='dip of sensor component in [deg], '
             'measured downward from horizontal. '
             'If not given, it is guessed from the channel code.')

    filter = Filter.T(
        optional=True,
        help='frequency response filter.')

    def base_key(self):
        return (self.store_id, self.sample_rate, self.interpolation,
                self.optimization,
                self.tmin, self.tmax,
                self.elevation, self.depth, self.north_shift, self.east_shift,
                self.lat, self.lon)

    def effective_quantity(self):
        if self.quantity is not None:
            return self.quantity

        # guess from channel code
        cha = self.codes[-1].upper()
        if len(cha) == 3:
            # use most common SEED conventions here, however units have to be
            # guessed, because they are not uniquely defined by the conventions
            if cha[-2] in 'HL':  # high gain, low gain seismometer
                return 'velocity'
            if cha[-2] == 'N':   # accelerometer
                return 'acceleration'
            if cha[-2] == 'D':   # hydrophone, barometer, ...
                return 'pressure'
            if cha[-2] == 'A':   # tiltmeter
                return 'tilt'
        elif len(cha) == 2:
            if cha[-2] == 'U':
                return 'displacement'
            if cha[-2] == 'V':
                return 'velocity'
        elif len(cha) == 1:
            if cha in 'NEZ':
                return 'displacement'
            if cha == 'P':
                return 'pressure'

        raise BadTarget('cannot guess measurement quantity type from channel '
                        'code "%s"' % cha)

    def receiver(self, store):
        rec = meta.Receiver(**dict(meta.Receiver.T.inamevals(self)))
        return rec

    def component_code(self):
        cha = self.codes[-1].upper()
        if cha:
            return cha[-1]
        else:
            return ' '

    def effective_azimuth(self):
        if self.azimuth is not None:
            return self.azimuth
        elif self.component_code() in 'NEZ':
            return {'N': 0., 'E': 90., 'Z': 0.}[self.component_code()]

        raise BadTarget('cannot determine sensor component azimuth for '
                        '%s.%s.%s.%s' % self.codes)

    def effective_dip(self):
        if self.dip is not None:
            return self.dip
        elif self.component_code() in 'NEZ':
            return {'N': 0., 'E': 0., 'Z': -90.}[self.component_code()]

        raise BadTarget('cannot determine sensor component dip')

    def get_sin_cos_factors(self):
        azi = self.effective_azimuth()
        dip = self.effective_dip()
        sa = math.sin(azi*d2r)
        ca = math.cos(azi*d2r)
        sd = math.sin(dip*d2r)
        cd = math.cos(dip*d2r)
        return sa, ca, sd, cd

    def get_factor(self):
        return 1.0

    def post_process(self, engine, source, tr):
        return meta.Result(trace=tr)
Exemplo n.º 15
0
class FDSNStationXML(Object):
    '''Top-level type for Station XML. Required field are Source
    (network ID of the institution sending the message) and one or
    more Network containers or one or more Station containers.'''

    schema_version = Float.T(default=1.0, xmlstyle='attribute')
    source = String.T(xmltagname='Source')
    sender = String.T(optional=True, xmltagname='Sender')
    module = String.T(optional=True, xmltagname='Module')
    module_uri = String.T(optional=True, xmltagname='ModuleURI')
    created = Timestamp.T(xmltagname='Created')
    network_list = List.T(Network.T(xmltagname='Network'))

    xmltagname = 'FDSNStationXML'

    def get_pyrocko_stations(self,
                             nslcs=None,
                             nsls=None,
                             time=None,
                             timespan=None,
                             inconsistencies='warn'):

        assert inconsistencies in ('raise', 'warn')

        if nslcs is not None:
            nslcs = set(nslcs)

        if nsls is not None:
            nsls = set(nsls)

        tt = ()
        if time is not None:
            tt = (time, )
        elif timespan is not None:
            tt = timespan

        pstations = []
        for network in self.network_list:
            if not network.spans(*tt):
                continue

            for station in network.station_list:
                if not station.spans(*tt):
                    continue

                if station.channel_list:
                    loc_to_channels = {}
                    for channel in station.channel_list:
                        if not channel.spans(*tt):
                            continue

                        loc = channel.location_code.strip()
                        if loc not in loc_to_channels:
                            loc_to_channels[loc] = []

                        loc_to_channels[loc].append(channel)

                    for loc in sorted(loc_to_channels.keys()):
                        channels = loc_to_channels[loc]
                        if nslcs is not None:
                            channels = [
                                channel for channel in channels
                                if (network.code, station.code, loc,
                                    channel.code) in nslcs
                            ]

                        if not channels:
                            continue

                        nsl = network.code, station.code, loc
                        if nsls is not None and nsl not in nsls:
                            continue

                        pstations.append(
                            pyrocko_station_from_channels(
                                nsl, channels,
                                inconsistencies=inconsistencies))
                else:
                    pstations.append(
                        model.Station(network.code,
                                      station.code,
                                      '*',
                                      lat=station.latitude.value,
                                      lon=station.longitude.value,
                                      elevation=value_or_none(
                                          station.elevation),
                                      name=station.description or ''))

        return pstations

    @classmethod
    def from_pyrocko_stations(cls, pyrocko_stations):
        ''' Generate :py:class:`FDSNStationXML` from list of
        :py:class;`pyrocko.model.Station` instances.

        :param pyrocko_stations: list of
            :py:class;`pyrocko.model.Station` instances.
        '''
        from collections import defaultdict
        network_dict = defaultdict(list)
        for s in pyrocko_stations:
            network, station, location = s.nsl()
            channel_list = []
            for c in s.channels:
                channel_list.append(
                    Channel(location_code=location,
                            code=c.name,
                            latitude=Latitude(value=s.lat),
                            longitude=Longitude(value=s.lon),
                            elevation=Distance(value=s.elevation),
                            depth=Distance(value=s.depth),
                            azimuth=Azimuth(value=c.azimuth),
                            dip=Dip(value=c.dip)))

            network_dict[network].append(
                Station(code=station,
                        latitude=Latitude(value=s.lat),
                        longitude=Longitude(value=s.lon),
                        elevation=Distance(value=s.elevation),
                        channel_list=channel_list))

        timestamp = time.time()
        network_list = []
        for k, station_list in network_dict.items():

            network_list.append(
                Network(code=k,
                        station_list=station_list,
                        total_number_stations=len(station_list)))

        sxml = FDSNStationXML(source='from pyrocko stations list',
                              created=timestamp,
                              network_list=network_list)

        sxml.validate()
        return sxml

    def iter_network_stations(self,
                              net=None,
                              sta=None,
                              time=None,
                              timespan=None):

        tt = ()
        if time is not None:
            tt = (time, )
        elif timespan is not None:
            tt = timespan

        for network in self.network_list:
            if not network.spans(*tt) or (net is not None
                                          and network.code != net):
                continue

            for station in network.station_list:
                if not station.spans(*tt) or (sta is not None
                                              and station.code != sta):
                    continue

                yield (network, station)

    def iter_network_station_channels(self,
                                      net=None,
                                      sta=None,
                                      loc=None,
                                      cha=None,
                                      time=None,
                                      timespan=None):

        if loc is not None:
            loc = loc.strip()

        tt = ()
        if time is not None:
            tt = (time, )
        elif timespan is not None:
            tt = timespan

        for network in self.network_list:
            if not network.spans(*tt) or (net is not None
                                          and network.code != net):
                continue

            for station in network.station_list:
                if not station.spans(*tt) or (sta is not None
                                              and station.code != sta):
                    continue

                if station.channel_list:
                    for channel in station.channel_list:
                        if (not channel.spans(*tt)
                                or (cha is not None and channel.code != cha)
                                or (loc is not None
                                    and channel.location_code.strip() != loc)):
                            continue

                        yield (network, station, channel)

    def get_channel_groups(self,
                           net=None,
                           sta=None,
                           loc=None,
                           cha=None,
                           time=None,
                           timespan=None):

        groups = {}
        for network, station, channel in self.iter_network_station_channels(
                net, sta, loc, cha, time=time, timespan=timespan):

            net = network.code
            sta = station.code
            cha = channel.code
            loc = channel.location_code.strip()
            if len(cha) == 3:
                bic = cha[:2]  # band and intrument code according to SEED
            elif len(cha) == 1:
                bic = ''
            else:
                bic = cha

            if channel.response and \
                    channel.response.instrument_sensitivity and \
                    channel.response.instrument_sensitivity.input_units:

                unit = channel.response.instrument_sensitivity.input_units.name
            else:
                unit = None

            bic = (bic, unit)

            k = net, sta, loc
            if k not in groups:
                groups[k] = {}

            if bic not in groups[k]:
                groups[k][bic] = []

            groups[k][bic].append(channel)

        for nsl, bic_to_channels in groups.iteritems():
            bad_bics = []
            for bic, channels in bic_to_channels.iteritems():
                sample_rates = []
                for channel in channels:
                    sample_rates.append(channel.sample_rate.value)

                if not same(sample_rates):
                    scs = ','.join(channel.code for channel in channels)
                    srs = ', '.join('%e' % x for x in sample_rates)
                    err = 'ignoring channels with inconsistent sampling ' + \
                          'rates (%s.%s.%s.%s: %s)' % (nsl + (scs, srs))

                    logger.warn(err)
                    bad_bics.append(bic)

            for bic in bad_bics:
                del bic_to_channels[bic]

        return groups

    def choose_channels(self,
                        target_sample_rate=None,
                        priority_band_code=['H', 'B', 'M', 'L', 'V', 'E', 'S'],
                        priority_units=['M/S', 'M/S**2'],
                        priority_instrument_code=['H', 'L'],
                        time=None,
                        timespan=None):

        nslcs = {}
        for nsl, bic_to_channels in self.get_channel_groups(
                time=time, timespan=timespan).iteritems():

            useful_bics = []
            for bic, channels in bic_to_channels.iteritems():
                rate = channels[0].sample_rate.value

                if target_sample_rate is not None and \
                        rate < target_sample_rate*0.99999:
                    continue

                if len(bic[0]) == 2:
                    if bic[0][0] not in priority_band_code:
                        continue

                    if bic[0][1] not in priority_instrument_code:
                        continue

                unit = bic[1]

                prio_unit = len(priority_units)
                try:
                    prio_unit = priority_units.index(unit)
                except ValueError:
                    pass

                prio_inst = len(priority_instrument_code)
                prio_band = len(priority_band_code)
                if len(channels[0].code) == 3:
                    try:
                        prio_inst = priority_instrument_code.index(
                            channels[0].code[1])
                    except ValueError:
                        pass

                    try:
                        prio_band = priority_band_code.index(
                            channels[0].code[0])
                    except ValueError:
                        pass

                if target_sample_rate is None:
                    rate = -rate

                useful_bics.append((-len(channels), prio_band, rate, prio_unit,
                                    prio_inst, bic))

            useful_bics.sort()

            for _, _, rate, _, _, bic in useful_bics:
                channels = sorted(bic_to_channels[bic])
                if channels:
                    for channel in channels:
                        nslcs[nsl + (channel.code, )] = channel

                    break

        return nslcs

    def get_pyrocko_response(self,
                             nslc,
                             time=None,
                             timespan=None,
                             fake_input_units=None):

        net, sta, loc, cha = nslc
        resps = []
        for _, _, channel in self.iter_network_station_channels(
                net, sta, loc, cha, time=time, timespan=timespan):
            resp = channel.response
            if resp:
                resps.append(
                    resp.get_pyrocko_response(
                        nslc, fake_input_units=fake_input_units))

        if not resps:
            raise NoResponseInformation('%s.%s.%s.%s' % nslc)
        elif len(resps) > 1:
            raise MultipleResponseInformation('%s.%s.%s.%s' % nslc)

        return resps[0]

    @property
    def n_code_list(self):
        return sorted(set(x.code for x in self.network_list))

    @property
    def ns_code_list(self):
        nss = set()
        for network in self.network_list:
            for station in network.station_list:
                nss.add((network.code, station.code))

        return sorted(nss)

    @property
    def nsl_code_list(self):
        nsls = set()
        for network in self.network_list:
            for station in network.station_list:
                for channel in station.channel_list:
                    nsls.add(
                        (network.code, station.code, channel.location_code))

        return sorted(nsls)

    @property
    def nslc_code_list(self):
        nslcs = set()
        for network in self.network_list:
            for station in network.station_list:
                for channel in station.channel_list:
                    nslcs.add((network.code, station.code,
                               channel.location_code, channel.code))

        return sorted(nslcs)

    def summary(self):
        l = [
            'number of n codes: %i' % len(self.n_code_list),
            'number of ns codes: %i' % len(self.ns_code_list),
            'number of nsl codes: %i' % len(self.nsl_code_list),
            'number of nslc codes: %i' % len(self.nslc_code_list)
        ]

        return '\n'.join(l)
Exemplo n.º 16
0
class ScenarioCollectionItem(Object):
    scenario_id = gf.StringID.T()
    time_created = Timestamp.T()

    def __init__(self, **kwargs):
        Object.__init__(self, **kwargs)
        self._path = None
        self._pile = None
        self._engine = None
        self._scenes = None

    def set_base_path(self, path):
        self._path = path

    def get_base_path(self):
        if self._path is None:
            raise EnvironmentError('Base path not set!')
        return self._path

    def init_modelling(self, engine):
        self._engine = engine

    def get_path(self, *entry):
        return op.join(*((self._path, ) + entry))

    def get_generator(self):
        generator = guts.load(filename=self.get_path('generator.yaml'))
        generator.init_modelling(self._engine)
        return generator

    def get_time_range(self):
        return self.get_generator().get_time_range()

    def have_waveforms(self, tmin, tmax):
        p = self.get_waveform_pile()
        trs_have = p.all(tmin=tmin, tmax=tmax, load_data=False, degap=False)

        return any(tr.data_len() > 0 for tr in trs_have)

    def get_waveform_pile(self):
        self.ensure_data()

        if self._pile is None:
            path_waveforms = self.get_path('waveforms')
            util.ensuredir(path_waveforms)
            fns = util.select_files([path_waveforms], show_progress=False)

            self._pile = pile.Pile()
            if fns:
                self._pile.load_files(fns,
                                      fileformat='mseed',
                                      show_progress=False)

        return self._pile

    def get_insar_scenes(self):
        from kite import Scene
        if self._scenes is None:
            self._scenes = []
            path_insar = self.get_path('insar')
            util.ensuredir(path_insar)

            fns = util.select_files([path_insar],
                                    regex='\\.(npz)$',
                                    show_progress=False)
            for f in fns:
                self._scenes.append(Scene.load(f))

        return self._scenes

    def get_gnss_campaigns(self):
        return self.get_generator().get_gnss_campaigns()

    def make_map(self, path_pdf):
        draw_scenario_gmt(self.get_generator(), path_pdf)

    def get_map(self, format='pdf'):
        path_pdf = self.get_path('map.pdf')

        if not op.exists(path_pdf):
            self.make_map(path_pdf)

        path = self.get_path('map.%s' % format)

        outdated = op.exists(path) and mtime(path) < mtime(path_pdf)
        if not op.exists(path) or outdated:
            gmtpy.convert_graph(path_pdf, path)

        return path

    def ensure_data(self, tmin=None, tmax=None, overwrite=False):
        return self.get_generator().dump_data(self.get_path(), tmin, tmax,
                                              overwrite)

    def ensure_waveforms(self, tmin=None, tmax=None, overwrite=False):
        self.ensure_data(tmin, tmax, overwrite)
        return self.get_waveform_pile()

    def ensure_insar_scenes(self, tmin=None, tmax=None, overwrite=False):
        self.ensure_data(tmin, tmax, overwrite)
        return self.get_insar_scenes()

    def get_archive(self):
        self.ensure_data()

        path_tar = self.get_path('archive.tar')
        if not op.exists(path_tar):
            path_base = self.get_path()
            path_waveforms = self.get_path('waveforms')
            self.ensure_data()

            fns = util.select_files([path_waveforms], show_progress=False)

            f = tarfile.TarFile(path_tar, 'w')
            for fn in fns:
                fna = fn[len(path_base) + 1:]
                f.add(fn, fna)

            f.close()

        return path_tar
Exemplo n.º 17
0
class Event(Object):
    '''Seismic event representation

    :param lat: latitude of hypocenter (default 0.0)
    :param lon: longitude of hypocenter (default 0.0)
    :param time: origin time as float in seconds after '1970-01-01 00:00:00
    :param name: event identifier as string (optional)
    :param depth: source depth (optional)
    :param magnitude: magnitude of event (optional)
    :param region: source region (optional)
    :param catalog: name of catalog that lists this event (optional)
    :param moment_tensor: moment tensor as
        :py:class:`moment_tensor.MomentTensor` instance (optional)
    :param duration: source duration as float (optional)
    '''

    lat = Float.T(default=0.0)
    lon = Float.T(default=0.0)
    time = Timestamp.T(default=util.str_to_time('1970-01-01 00:00:00'))
    name = String.T(default='', optional=True)
    depth = Float.T(optional=True)
    magnitude = Float.T(optional=True)
    magnitude_type = String.T(optional=True)
    region = Unicode.T(optional=True)
    catalog = String.T(optional=True)
    moment_tensor = moment_tensor.MomentTensor.T(optional=True)
    duration = Float.T(optional=True)

    def __init__(self,
                 lat=0.,
                 lon=0.,
                 time=0.,
                 name='',
                 depth=None,
                 magnitude=None,
                 magnitude_type=None,
                 region=None,
                 load=None,
                 loadf=None,
                 catalog=None,
                 moment_tensor=None,
                 duration=None):

        vals = None
        if load is not None:
            vals = Event.oldload(load)
        elif loadf is not None:
            vals = Event.oldloadf(loadf)

        if vals:
            lat, lon, time, name, depth, magnitude, magnitude_type, region, \
                catalog, moment_tensor, duration = vals

        Object.__init__(self,
                        lat=lat,
                        lon=lon,
                        time=time,
                        name=name,
                        depth=depth,
                        magnitude=magnitude,
                        magnitude_type=magnitude_type,
                        region=region,
                        catalog=catalog,
                        moment_tensor=moment_tensor,
                        duration=duration)

    def time_as_string(self):
        return util.time_to_str(self.time)

    def set_name(self, name):
        self.name = name

    def olddump(self, filename):
        file = open(filename, 'w')
        self.olddumpf(file)
        file.close()

    def olddumpf(self, file):
        file.write('name = %s\n' % self.name)
        file.write('time = %s\n' % util.time_to_str(self.time))
        if self.lat is not None:
            file.write('latitude = %.12g\n' % self.lat)
        if self.lon is not None:
            file.write('longitude = %.12g\n' % self.lon)
        if self.magnitude is not None:
            file.write('magnitude = %g\n' % self.magnitude)
            file.write('moment = %g\n' %
                       moment_tensor.magnitude_to_moment(self.magnitude))
        if self.magnitude_type is not None:
            file.write('magnitude_type = %s\n' % self.magnitude_type)
        if self.depth is not None:
            file.write('depth = %.10g\n' % self.depth)
        if self.region is not None:
            file.write('region = %s\n' % self.region)
        if self.catalog is not None:
            file.write('catalog = %s\n' % self.catalog)
        if self.moment_tensor is not None:
            m = self.moment_tensor.m()
            sdr1, sdr2 = self.moment_tensor.both_strike_dip_rake()
            file.write(
                ('mnn = %g\nmee = %g\nmdd = %g\nmne = %g\nmnd = %g\nmed = %g\n'
                 'strike1 = %g\ndip1 = %g\nrake1 = %g\n'
                 'strike2 = %g\ndip2 = %g\nrake2 = %g\n') %
                ((m[0, 0], m[1, 1], m[2, 2], m[0, 1], m[0, 2], m[1, 2]) +
                 sdr1 + sdr2))

        if self.duration is not None:
            file.write('duration = %g\n' % self.duration)

    @staticmethod
    def unique(events,
               deltat=10.,
               group_cmp=(lambda a, b: cmp(a.catalog, b.catalog))):
        groups = Event.grouped(events, deltat)

        events = []
        for group in groups:
            if group:
                group.sort(group_cmp)
                events.append(group[-1])

        return events

    @staticmethod
    def grouped(events, deltat=10.):
        events = list(events)
        groups = []
        for ia, a in enumerate(events):
            groups.append([])
            haveit = False
            for ib, b in enumerate(events[:ia]):
                if abs(b.time - a.time) < deltat:
                    groups[ib].append(a)
                    haveit = True
                    break

            if not haveit:
                groups[ia].append(a)

        groups = [g for g in groups if g]
        groups.sort(key=lambda g: sum(e.time for e in g) // len(g))
        return groups

    @staticmethod
    def dump_catalog(events, filename=None, stream=None):
        if filename is not None:
            file = open(filename, 'w')
        else:
            file = stream
        try:
            i = 0
            for ev in events:

                ev.olddumpf(file)

                file.write('--------------------------------------------\n')
                i += 1

        finally:
            if filename is not None:
                file.close()

    @staticmethod
    def oldload(filename):
        with open(filename, 'r') as file:
            return Event.oldloadf(file)

    @staticmethod
    def oldloadf(file):
        d = {}
        try:
            for line in file:
                if line.lstrip().startswith('#'):
                    continue

                toks = line.split(' = ', 1)
                if len(toks) == 2:
                    k, v = toks[0].strip(), toks[1].strip()
                    if k in ('name', 'region', 'catalog', 'magnitude_type'):
                        d[k] = v
                    if k in (('latitude longitude magnitude depth duration '
                              'mnn mee mdd mne mnd med strike1 dip1 rake1 '
                              'strike2 dip2 rake2 duration').split()):
                        d[k] = float(v)
                    if k == 'time':
                        d[k] = util.str_to_time(v)

                if line.startswith('---'):
                    d['have_separator'] = True
                    break

        except Exception as e:
            raise FileParseError(e)

        if not d:
            raise EOF()

        if 'have_separator' in d and len(d) == 1:
            raise EmptyEvent()

        mt = None
        m6 = [d[x] for x in 'mnn mee mdd mne mnd med'.split() if x in d]
        if len(m6) == 6:
            mt = moment_tensor.MomentTensor(m=moment_tensor.symmat6(*m6))
        else:
            sdr = [d[x] for x in 'strike1 dip1 rake1'.split() if x in d]
            if len(sdr) == 3:
                moment = 1.0
                if 'moment' in d:
                    moment = d['moment']
                elif 'magnitude' in d:
                    moment = moment_tensor.magnitude_to_moment(d['magnitude'])

                mt = moment_tensor.MomentTensor(strike=sdr[0],
                                                dip=sdr[1],
                                                rake=sdr[2],
                                                scalar_moment=moment)

        return (d.get('latitude', 0.0), d.get('longitude', 0.0),
                d.get('time', 0.0), d.get('name', ''), d.get('depth', None),
                d.get('magnitude', None), d.get('magnitude_type',
                                                None), d.get('region', None),
                d.get('catalog', None), mt, d.get('duration', None))

    @staticmethod
    def load_catalog(filename):

        file = open(filename, 'r')

        try:
            while True:
                try:
                    ev = Event(loadf=file)
                    yield ev
                except EmptyEvent:
                    pass

        except EOF:
            pass

        file.close()

    def get_hash(self):
        e = self
        if isinstance(e.time, util.hpfloat):
            stime = util.time_to_str(e.time, format='%Y-%m-%d %H:%M:%S.6FRAC')
        else:
            stime = util.time_to_str(e.time, format='%Y-%m-%d %H:%M:%S.3FRAC')

        s = float_or_none_to_str

        return ehash(', '.join(
            (stime, s(e.lat), s(e.lon), s(e.depth), s(e.magnitude),
             str(e.catalog), str(e.name), str(e.region))))

    def human_str(self):
        s = [
            'Latitude [deg]: %g' % self.lat,
            'Longitude [deg]: %g' % self.lon,
            'Time [UTC]: %s' % util.time_to_str(self.time)
        ]

        if self.name:
            s.append('Name: %s' % self.name)

        if self.depth is not None:
            s.append('Depth [km]: %g' % (self.depth / 1000.))

        if self.magnitude is not None:
            s.append('Magnitude [%s]: %3.1f' %
                     (self.magnitude_type or 'M?', self.magnitude))

        if self.region:
            s.append('Region: %s' % self.region)

        if self.catalog:
            s.append('Catalog: %s' % self.catalog)

        if self.moment_tensor:
            s.append(str(self.moment_tensor))

        return '\n'.join(s)
Exemplo n.º 18
0
class Config(HasPaths):

    stations_path = Path.T(optional=True,
                           help='stations file in Pyrocko format')

    stations_stationxml_path = Path.T(
        optional=True, help='stations file in StationXML format')

    receivers = List.T(receiver.Receiver.T(),
                       help='receiver coordinates if not read from file')

    data_paths = List.T(Path.T(),
                        help='list of directories paths to search for data')

    events_path = Path.T(
        optional=True,
        help='limit processing to time windows around given events')

    event_time_window_factor = Float.T(
        default=2.,
        help='controls length of time windows for event-wise processing')

    blacklist = List.T(
        String.T(),
        help='codes in the form NET.STA.LOC of receivers to be excluded')

    whitelist = List.T(
        String.T(),
        help='codes in the form NET.STA.LOC of receivers to be included')

    distance_max = Float.T(optional=True,
                           help='receiver maximum distance from grid')

    tmin = Timestamp.T(optional=True,
                       help='beginning of time interval to be processed')

    tmax = Timestamp.T(optional=True,
                       help='end of time interval to be processed')

    run_path = Path.T(optional=True, help='output is saved to this directory')

    save_figures = Bool.T(default=False,
                          help='flag to activate saving of detection figures')

    grid = grid.Grid.T(
        optional=True,
        help='definition of search grid, if not given, a default grid is '
        'chosen')

    autogrid_radius_factor = Float.T(
        default=1.5,
        help='size factor to use when automatically choosing a grid size')

    autogrid_density_factor = Float.T(
        default=10.0,
        help='grid density factor used when automatically choosing a grid '
        'spacing')

    image_function_contributions = List.T(ifc.IFC.T(),
                                          help='image function contributions')

    sharpness_normalization = Bool.T(
        default=True,
        help='whether to divide image function frames by their mean value')

    ifc_count_normalization = Bool.T(
        default=False,
        help='whether to divide image function by number of contributors')

    detector_threshold = Float.T(default=70.,
                                 help='threshold on detector function')

    detector_tpeaksearch = Float.T(optional=True,
                                   help='search time span for peak detection')

    fill_incomplete_with_zeros = Bool.T(
        default=True,
        help='fill incomplete trace time windows with zeros '
        '(and let edge effects ruin your day)')

    earthmodels = List.T(Earthmodel.T(),
                         help='list of earthmodels usable in shifters')

    tabulated_phases = List.T(
        TPDef.T(), help='list of tabulated phase definitions usable shifters')

    cache_path = Path.T(
        default='lassie_phases.cache',
        help='directory where lassie stores tabulated phases etc.')

    stacking_blocksize = Int.T(
        optional=True,
        help='enable chunked stacking to reduce memory usage. Setting this to '
        'e.g. 64 will use ngridpoints * 64 * 8 bytes of memory to hold '
        'the stacking results, instead of computing the whole processing '
        'time window in one shot. Setting this to a very small number '
        'may lead to bad performance. If this is enabled together with '
        'plotting, the cutout of the image function seen in the map '
        'image must be stacked again just for plotting (redundantly and '
        'memory greedy) because it may intersect more than one '
        'processing chunk.')

    def __init__(self, *args, **kwargs):
        HasPaths.__init__(self, *args, **kwargs)
        self._receivers = None
        self._grid = None
        self._events = None
        self._config_name = 'untitled'

    def setup_image_function_contributions(self):
        '''
        Post-init setup of image function contributors.
        '''
        for ifc_ in self.image_function_contributions:
            ifc_.setup(self)

    def set_config_name(self, config_name):
        self._config_name = config_name

    def expand_path(self, path):
        def extra(path):
            return expand_template(path, dict(config_name=self._config_name))

        return HasPaths.expand_path(self, path, extra=extra)

    def get_events_path(self):
        run_path = self.expand_path(self.run_path)
        return op.join(run_path, 'events.list')

    def get_ifm_dir_path(self):
        run_path = self.expand_path(self.run_path)
        return op.join(run_path, 'ifm')

    def get_ifm_path_template(self):
        return op.join(self.get_ifm_dir_path(),
                       '%(station)s_%(tmin_ms)s.mseed')

    def get_detections_path(self):
        run_path = self.expand_path(self.run_path)
        return op.join(run_path, 'detections.list')

    def get_figures_path_template(self):
        run_path = self.expand_path(self.run_path)
        return op.join(run_path, 'figures', '%(id)s.%(format)s')

    def get_receivers(self):
        '''Aggregate receivers from different sources.'''

        fp = self.expand_path

        if self._receivers is None:
            self._receivers = list(self.receivers)
            if self.stations_path:
                for station in model.load_stations(fp(self.stations_path)):
                    self._receivers.append(
                        receiver.Receiver(codes=station.nsl(),
                                          lat=station.lat,
                                          lon=station.lon,
                                          z=station.depth))

            if self.stations_stationxml_path:
                sx = stationxml.load_xml(
                    filename=fp(self.stations_stationxml_path))
                for station in sx.get_pyrocko_stations():
                    self._receivers.append(
                        receiver.Receiver(codes=station.nsl(),
                                          lat=station.lat,
                                          lon=station.lon,
                                          z=station.depth))

        return self._receivers

    def get_events(self):
        if self.events_path is None:
            return None

        if self._events is None:
            self._events = model.load_events(self.expand_path(
                self.events_path))

        return self._events

    def get_grid(self):
        '''Get grid or make default grid.'''

        self.setup_image_function_contributions()

        if self._grid is None:

            if not self.grid:
                receivers = self.get_receivers()

                fsmooth_max = max(ifc.get_fsmooth()
                                  for ifc in self.image_function_contributions)

                vmin = min(ifc.shifter.get_vmin()
                           for ifc in self.image_function_contributions)

                spacing = vmin / fsmooth_max / self.autogrid_density_factor

                lat0, lon0, north, east, depth = geo.bounding_box_square(
                    *geo.points_coords(receivers),
                    scale=self.autogrid_radius_factor)

                self._grid = grid.Carthesian3DGrid(lat=lat0,
                                                   lon=lon0,
                                                   xmin=north[0],
                                                   xmax=north[1],
                                                   dx=spacing,
                                                   ymin=east[0],
                                                   ymax=east[1],
                                                   dy=spacing,
                                                   zmin=depth[0],
                                                   zmax=depth[1],
                                                   dz=spacing)

                logger.info('automatic grid:\n%s' % self._grid)

            else:
                self._grid = self.grid

            self._grid.update()

        return self._grid
Exemplo n.º 19
0
class DirContextEntry(Object):
    path = String.T()
    tstart = Timestamp.T()
    ifile = Int.T()
Exemplo n.º 20
0
class SourceGenerator(LocationGenerator):

    nevents = Int.T(default=2)
    avoid_water = Bool.T(
        default=False, help='Avoid sources offshore under the ocean / lakes.')

    time_min = Timestamp.T(default=util.str_to_time('2017-01-01 00:00:00'))
    time_max = Timestamp.T(default=util.str_to_time('2017-01-03 00:00:00'))

    magnitude_min = Float.T(default=4.0, help='minimum moment magnitude')
    magnitude_max = Float.T(
        optional=True,
        help='if set, maximum moment magnitude for a uniform distribution. '
        'If set to ``None``, magnitudes are drawn using a '
        'Gutenberg-Richter distribution, see :gattr:`b_value`.')
    b_value = Float.T(
        optional=True,
        help='b-value for Gutenberg-Richter magnitude distribution. If unset, '
        'a value of 1 is assumed.')

    def __init__(self, *args, **kwargs):
        super(SourceGenerator, self).__init__(*args, **kwargs)
        if self.b_value is not None and self.magnitude_max is not None:
            raise ScenarioError(
                '%s: b_value and magnitude_max are mutually exclusive.' %
                self.__class__.__name__)

    def draw_magnitude(self, rstate):
        if self.b_value is None and self.magnitude_max is None:
            b_value = 1.0
        else:
            b_value = self.b_value

        if b_value is None:
            return rstate.uniform(self.magnitude_min, self.magnitude_max)
        else:
            return moment_tensor.rand_to_gutenberg_richter(
                rstate.rand(), b_value, magnitude_min=self.magnitude_min)

    def get_sources(self):
        sources = []
        for ievent in range(self.nevents):
            src = self.get_source(ievent)
            src.name = 'scenario_ev%03d' % (ievent + 1)
            sources.append(src)

        return sources

    def ensure_data(self, path):
        fn_sources = op.join(path, 'sources.yml')
        if not op.exists(fn_sources):
            with open(fn_sources, 'w') as f:
                for src in self.get_sources():
                    f.write(src.dump())

        fn_events = op.join(path, 'events.txt')
        if not op.exists(fn_events):
            with open(fn_events, 'w') as f:
                for isrc, src in enumerate(self.get_sources()):
                    f.write(src.pyrocko_event().dump())

    def add_map_artists(self, automap):
        pass
Exemplo n.º 21
0
class ScenePatch(Object):
    lat_center = Float.T(help='Center latitude anchor.')
    lon_center = Float.T(help='center longitude anchor.')
    time_master = Timestamp.T(help='Timestamp of the master.')
    time_slave = Timestamp.T(help='Timestamp of the slave.')
    inclination = Float.T(
        help='Orbital inclination towards the equatorial plane [deg].')
    apogee = Float.T(help='Apogee of the satellite in [m].')
    swath_width = Float.T(default=250 * km, help='Swath width in [m].')
    track_length = Float.T(help='Track length in [m].')
    incident_angle = Float.T(help='Ground incident angle in [deg].')
    resolution = Tuple.T(help='Resolution of raster in east x north [px].')
    orbital_node = StringChoice.T(['Ascending', 'Descending'],
                                  help='Orbit heading.')
    mask_water = Bool.T(default=True, help='Mask water bodies.')

    class SatelliteGeneratorTarget(gf.SatelliteTarget):
        def __init__(self, scene_patch, *args, **kwargs):
            gf.SatelliteTarget.__init__(self, *args, **kwargs)

            self.scene_patch = scene_patch

        def post_process(self, *args, **kwargs):
            resp = gf.SatelliteTarget.post_process(self, *args, **kwargs)

            from kite import Scene
            from kite.scene import SceneConfig, FrameConfig, Meta

            patch = self.scene_patch

            grid, _ = patch.get_grid()

            displacement = num.empty_like(grid)
            displacement.fill(num.nan)
            displacement[patch.get_mask()] = resp.result['displacement.los']

            theta, phi = patch.get_incident_angles()

            llLat, llLon = patch.get_ll_anchor()
            urLat, urLon = patch.get_ur_anchor()
            dLon = num.abs(llLon - urLon) / patch.resolution[0]
            dLat = num.abs(llLat - urLat) / patch.resolution[1]

            scene_config = SceneConfig(meta=Meta(
                scene_title='Pyrocko Scenario Generator - {orbit} ({time})'.
                format(orbit=self.scene_patch.orbital_node,
                       time=datetime.now()),
                orbital_node=patch.orbital_node,
                scene_id='pyrocko_scenario_%s' % self.scene_patch.orbital_node,
                satellite_name='Sentinel-1 (Scenario)'),
                                       frame=FrameConfig(llLat=float(llLat),
                                                         llLon=float(llLon),
                                                         dN=float(dLat),
                                                         dE=float(dLon),
                                                         spacing='degree'))

            scene = Scene(displacement=displacement,
                          theta=theta,
                          phi=phi,
                          config=scene_config)

            resp.scene = scene

            return resp

    def __init__(self, *args, **kwargs):
        Object.__init__(self, *args, **kwargs)
        self._mask_water = None

    @property
    def width(self):
        track_shift = num.abs(
            num.cos(self.inclination * d2r) * self.track_length)

        return self.swath_width + track_shift

    def get_ll_anchor(self):
        return od.ne_to_latlon(self.lat_center, self.lon_center,
                               -self.track_length / 2, -self.width / 2)

    def get_ur_anchor(self):
        return od.ne_to_latlon(self.lat_center, self.lon_center,
                               self.track_length / 2, self.width / 2)

    def get_ul_anchor(self):
        return od.ne_to_latlon(self.lat_center, self.lon_center,
                               self.track_length / 2, -self.width / 2)

    def get_lr_anchor(self):
        return od.ne_to_latlon(self.lat_center, self.lon_center,
                               -self.track_length / 2, self.width / 2)

    def get_corner_coordinates(self):
        inc = self.inclination

        llLat, llLon = self.get_ll_anchor()
        urLat, urLon = self.get_ur_anchor()

        if self.orbital_node == 'Ascending':

            ulLat, ulLon = od.ne_to_latlon(
                self.lat_center, self.lon_center, self.track_length / 2,
                -num.tan(inc * d2r) * self.width / 2)
            lrLat, lrLon = od.ne_to_latlon(self.lat_center, self.lon_center,
                                           -self.track_length / 2,
                                           num.tan(inc * d2r) * self.width / 2)

        elif self.orbital_node == 'Descending':
            urLat, urLon = od.ne_to_latlon(self.lat_center, self.lon_center,
                                           self.track_length / 2,
                                           num.tan(inc * d2r) * self.width / 2)
            llLat, llLon = od.ne_to_latlon(
                self.lat_center, self.lon_center, -self.track_length / 2,
                -num.tan(inc * d2r) * self.width / 2)

        return ((llLat, llLon), (ulLat, ulLon), (urLat, urLon), (lrLat, lrLon))

    def get_grid(self):
        '''Return relative positions of scatterer.

        :param track: Acquisition track, from `'asc'` or `'dsc'`.
        :type track: string
        '''
        easts = num.linspace(0, self.width, self.resolution[0])
        norths = num.linspace(0, self.track_length, self.resolution[1])

        return num.meshgrid(easts, norths)

    def get_mask_track(self):
        east_shifts, north_shifts = self.get_grid()
        norths = north_shifts[:, 0]
        track = num.abs(num.cos(self.inclination * d2r)) * norths

        track_mask = num.logical_and(
            east_shifts > track[:, num.newaxis], east_shifts <
            (track + self.swath_width)[:, num.newaxis])

        if self.orbital_node == 'Ascending':
            track_mask = num.fliplr(track_mask)

        return track_mask

    def get_mask_water(self):
        if self._mask_water is None:
            east_shifts, north_shifts = self.get_grid()

            east_shifts -= east_shifts[0, -1] / 2
            north_shifts -= north_shifts[-1, -1] / 2

            latlon = od.ne_to_latlon(self.lat_center, self.lon_center,
                                     north_shifts.ravel(), east_shifts.ravel())
            points = num.array(latlon).T
            self._mask_water = get_gsshg().get_land_mask(points)\
                .reshape(*east_shifts.shape)

        return self._mask_water

    def get_mask(self):
        mask_track = self.get_mask_track()
        if self.mask_water:
            mask_water = self.get_mask_water()
            return num.logical_and(mask_track, mask_water)
        return mask_track

    def get_incident_angles(self):
        # theta: elevation angle towards satellite from horizon in radians.
        # phi:  Horizontal angle towards satellite' :abbr:`line of sight (LOS)`
        #       in [rad] from East.
        east_shifts, _ = self.get_grid()

        phi = num.empty_like(east_shifts)
        theta = num.empty_like(east_shifts)

        east_shifts += num.tan(self.incident_angle * d2r) * self.apogee
        theta = num.arctan(east_shifts / self.apogee)

        if self.orbital_node == 'Ascending':
            phi.fill(self.inclination * d2r + num.pi / 2)
        elif self.orbital_node == 'Descending':
            phi.fill(2 * num.pi - (self.inclination * d2r + 3 / 2 * num.pi))
            theta = num.fliplr(theta)
        else:
            raise AttributeError('Orbital node %s not defined!' %
                                 self.orbital_node)

        return theta, phi

    def get_target(self):
        gE, gN = self.get_grid()
        mask = self.get_mask()

        east_shifts = gE[mask].ravel()
        north_shifts = gN[mask].ravel()
        llLat, llLon = self.get_ll_anchor()

        ncoords = east_shifts.size

        theta, phi = self.get_incident_angles()

        theta = theta[mask].ravel()
        phi = phi[mask].ravel()

        if ncoords == 0:
            logger.warning('InSAR taget has no valid points,'
                           ' maybe it\'s all water?')
            return

        return self.SatelliteGeneratorTarget(scene_patch=self,
                                             lats=num_full(ncoords,
                                                           fill_value=llLat),
                                             lons=num_full(ncoords,
                                                           fill_value=llLon),
                                             east_shifts=east_shifts,
                                             north_shifts=north_shifts,
                                             theta=theta,
                                             phi=phi)
Exemplo n.º 22
0
class TimeQuantity(Object):
    value = Timestamp.T()
    uncertainty = Float.T(optional=True)
    lower_uncertainty = Float.T(optional=True)
    upper_uncertainty = Float.T(optional=True)
    confidence_level = Float.T(optional=True)
Exemplo n.º 23
0
 class A(Object):
     x = Choice.T(optional=True, choices=[Timestamp.T(), Int.T()])
Exemplo n.º 24
0
class TimeWindow(Object):
    begin = Float.T()
    end = Float.T()
    reference = Timestamp.T()