Beispiel #1
0
class SectionPlotConfig(PlotConfig):

    size_cm = Tuple.T(2, Float.T(), default=(20., 20.))

    margins_em = Tuple.T(4, Float.T(), default=(7., 5., 7., 5.))

    separator_em = Float.T(default=1.0)
Beispiel #2
0
class QSeisConfig(Object):

    qseis_version = String.T(default='2006')
    time_region = Tuple.T(2,
                          Timing.T(),
                          default=(Timing('-10'), Timing('+890')))

    cut = Tuple.T(2, Timing.T(), optional=True)
    fade = Tuple.T(4, Timing.T(), optional=True)
    relevel_with_fade_in = Bool.T(default=False)

    sw_algorithm = Int.T(default=0)
    slowness_window = Tuple.T(4, Float.T(default=0.0))
    wavenumber_sampling = Float.T(default=2.5)
    aliasing_suppression_factor = Float.T(default=0.1)

    filter_surface_effects = Int.T(default=0)
    filter_shallow_paths = Int.T(default=0)
    filter_shallow_paths_depth = Float.T(default=0.0)
    propagation_filters = List.T(QSeisPropagationFilter.T())
    receiver_filter = QSeisPoleZeroFilter.T(optional=True)

    sw_flat_earth_transform = Int.T(default=0)

    gradient_resolution_vp = Float.T(default=0.0)
    gradient_resolution_vs = Float.T(default=0.0)
    gradient_resolution_density = Float.T(default=0.0)

    wavelet_duration_samples = Float.T(default=0.0)
    wavelet_type = Int.T(default=2)
    user_wavelet_samples = List.T(Float.T())

    def items(self):
        return dict(self.T.inamevals(self))
Beispiel #3
0
class AhfullKiwiTestSetupEntry(Object):
    vp = Float.T()
    vs = Float.T()
    density = Float.T()
    x = Tuple.T(3, Float.T())
    f = Tuple.T(3, Float.T())
    m6 = Tuple.T(6, Float.T())
    tau = Float.T()
    deltat = Float.T()
Beispiel #4
0
class AhfullgreenConfig(Object):

    time_region = Tuple.T(2,
                          gf.Timing.T(),
                          default=(gf.Timing('-10'), gf.Timing('+890')))

    cut = Tuple.T(2, gf.Timing.T(), optional=True)
    fade = Tuple.T(4, gf.Timing.T(), optional=True)

    def items(self):
        return dict(self.T.inamevals(self))
Beispiel #5
0
class CPT(Object):
    color_below = Tuple.T(3, Float.T(), optional=True)
    color_above = Tuple.T(3, Float.T(), optional=True)
    color_nan = Tuple.T(3, Float.T(), optional=True)
    levels = List.T(CPTLevel.T())

    def scale(self, vmin, vmax):
        vmin_old, vmax_old = self.levels[0].vmin, self.levels[-1].vmax
        for level in self.levels:
            level.vmin = (level.vmin - vmin_old) / (vmax_old - vmin_old) * \
                (vmax - vmin) + vmin
            level.vmax = (level.vmax - vmin_old) / (vmax_old - vmin_old) * \
                (vmax - vmin) + vmin
Beispiel #6
0
class QSSPConfig(Object):
    qssp_version = String.T(default='2010beta')
    time_region = Tuple.T(2, gf.Timing.T(), default=(
        gf.Timing('-10'), gf.Timing('+890')))

    frequency_max = Float.T(optional=True)
    slowness_max = Float.T(default=0.4)
    antialiasing_factor = Float.T(default=0.1)

    # only available in 2017:
    switch_turning_point_filter = Int.T(default=0)
    max_pene_d1 = Float.T(default=2891.5)
    max_pene_d2 = Float.T(default=6371.0)
    earth_radius = Float.T(default=6371.0)
    switch_free_surf_reflection = Int.T(default=1)

    lowpass_order = Int.T(default=0, optional=True)
    lowpass_corner = Float.T(default=1.0, optional=True)

    bandpass_order = Int.T(default=0, optional=True)
    bandpass_corner_low = Float.T(default=1.0, optional=True)
    bandpass_corner_high = Float.T(default=1.0, optional=True)

    output_slowness_min = Float.T(default=0.0, optional=True)
    output_slowness_max = Float.T(optional=True)

    spheroidal_modes = Bool.T(default=True)
    toroidal_modes = Bool.T(default=True)

    # only available in 2010beta:
    cutoff_harmonic_degree_sd = Int.T(optional=True, default=0)

    cutoff_harmonic_degree_min = Int.T(default=0)
    cutoff_harmonic_degree_max = Int.T(default=25000)

    crit_frequency_sge = Float.T(default=0.0)
    crit_harmonic_degree_sge = Int.T(default=0)

    include_physical_dispersion = Bool.T(default=False)

    source_patch_radius = Float.T(default=0.0)

    cut = Tuple.T(2, gf.Timing.T(), optional=True)

    fade = Tuple.T(4, gf.Timing.T(), optional=True)
    relevel_with_fade_in = Bool.T(default=False)
    nonzero_fade_in = Bool.T(default=False)
    nonzero_fade_out = Bool.T(default=False)

    def items(self):
        return dict(self.T.inamevals(self))
Beispiel #7
0
class CPT(Object):
    color_below = Tuple.T(3, Float.T(), optional=True)
    color_above = Tuple.T(3, Float.T(), optional=True)
    color_nan = Tuple.T(3, Float.T(), optional=True)
    levels = List.T(CPTLevel.T())

    def scale(self, vmin, vmax):
        vmin_old, vmax_old = self.levels[0].vmin, self.levels[-1].vmax
        for level in self.levels:
            level.vmin = (level.vmin - vmin_old) / (vmax_old - vmin_old) * \
                (vmax - vmin) + vmin
            level.vmax = (level.vmax - vmin_old) / (vmax_old - vmin_old) * \
                (vmax - vmin) + vmin

    def discretize(self, nlevels):
        colors = []
        vals = []
        for level in self.levels:
            vals.append(level.vmin)
            vals.append(level.vmax)
            colors.append(level.color_min)
            colors.append(level.color_max)

        r, g, b = num.array(colors, dtype=num.float).T
        vals = num.array(vals, dtype=num.float)

        vmin, vmax = self.levels[0].vmin, self.levels[-1].vmax
        x = num.linspace(vmin, vmax, nlevels + 1)
        rd = num.interp(x, vals, r)
        gd = num.interp(x, vals, g)
        bd = num.interp(x, vals, b)

        levels = []
        for ilevel in range(nlevels):
            color = (float(0.5 * (rd[ilevel] + rd[ilevel + 1])),
                     float(0.5 * (gd[ilevel] + gd[ilevel + 1])),
                     float(0.5 * (bd[ilevel] + bd[ilevel + 1])))

            levels.append(
                CPTLevel(vmin=x[ilevel],
                         vmax=x[ilevel + 1],
                         color_min=color,
                         color_max=color))

        cpt = CPT(color_below=self.color_below,
                  color_above=self.color_above,
                  color_nan=self.color_nan,
                  levels=levels)

        return cpt
Beispiel #8
0
class GFConfig(Object):
    """
    Base config for GreensFunction calculation parameters.
    """
    store_superdir = String.T(
        default='./',
        help='Absolute path to the directory where Greens Function'
        ' stores are located')
    reference_model_idx = Int.T(
        default=0,
        help='Index to velocity model to use for the optimization.'
        ' 0 - reference, 1..n - model of variations')
    n_variations = Tuple.T(
        2,
        Int.T(),
        default=(0, 1),
        help='Start and end index to vary input velocity model. '
        'Important for the calculation of the model prediction covariance'
        ' matrix with respect to uncertainties in the velocity model.')
    earth_model_name = String.T(
        default='ak135-f-average.m',
        help='Name of the reference earthmodel, see '
        'pyrocko.cake.builtin_models() for alternatives.')
    nworkers = Int.T(
        default=1, help='Number of processors to use for calculating the GFs')
Beispiel #9
0
class PlotGroup(Object):
    name = StringID.T(
        help='group name')
    section = StringID.T(
        optional=True,
        help='group\'s section path, e.g. results.waveforms')
    title = Unicode.T(
        optional=True,
        help='group\'s title')
    description = Unicode.T(
        optional=True,
        help='group description')
    formats = List.T(
        PlotFormat.T(),
        help='plot format')
    variant = StringID.T(
        help='variant of the group')
    feather_icon = String.T(
        default='bar-chart-2',
        help='Feather icon for the HTML report.')
    size_cm = Tuple.T(2, Float.T())
    items = List.T(PlotItem.T())
    attributes = Dict.T(StringID.T(), List.T(String.T()))

    def filename_image(self, item, format):
        return '%s.%s.%s.%s' % (
            self.name,
            self.variant,
            item.name,
            format.extension)
Beispiel #10
0
class TimingConfig(Object):
    timing_test = Bool.T()
    bandpass = Tuple.T(3, Float.T())
    time_wdw = List.T()
    cc_thresh = Float.T()
    search_locations = Bool.T()
    debug_mode = Bool.T(default=False)
Beispiel #11
0
class GFConfig(Object):
    """
    Base config for GreensFunction calculation parameters.
    """
    store_superdir = String.T(
        default='./',
        help='Absolute path to the directory where Greens Function'
        ' stores are located')
    reference_model_idx = Int.T(
        default=0,
        help='Index to velocity model to use for the optimization.'
        ' 0 - reference, 1..n - model of variations')
    n_variations = Tuple.T(
        2,
        Int.T(),
        default=(0, 1),
        help='Start and end index to vary input velocity model. '
        'Important for the calculation of the model prediction covariance'
        ' matrix with respect to uncertainties in the velocity model.')
    error_depth = Float.T(
        default=0.1,
        help='3sigma [%/100] error in velocity model layer depth, '
        'translates to interval for varying the velocity model')
    error_velocities = Float.T(
        default=0.1,
        help='3sigma [%/100] in velocity model layer wave-velocities, '
        'translates to interval for varying the velocity model')
    depth_limit_variation = Float.T(
        default=600.,
        help='Depth limit [km] for varying the velocity model. Below that '
        'depth the velocity model is not varied based on the errors '
        'defined above!')
Beispiel #12
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]))
Beispiel #13
0
 class X(Object):
     a = Type.T()
     b = Type.T(optional=True)
     c = Type.T(default=sample)
     d = List.T(Type.T())
     e = Tuple.T(1, Type.T())
     xmltagname = 'x'
Beispiel #14
0
class QSeis2dConfig(Object):
    '''
    Combined config object for QSeisS and QSeisR.

    This config object should contain all settings which cannot be derived from
    the backend-independant Pyrocko GF Store config.
    '''

    qseis_s_config = QSeisSConfig.T(default=QSeisSConfig.D())
    qseis_r_config = QSeisRConfig.T(default=QSeisRConfig.D())

    time_region = Tuple.T(2, Timing.T(), default=default_time_region)
    cut = Tuple.T(2, Timing.T(), optional=True)
    fade = Tuple.T(4, Timing.T(), optional=True)
    relevel_with_fade_in = Bool.T(default=False)

    gf_directory = String.T('qseis2d_green')
Beispiel #15
0
class RestDownRotConfig(Object):
    # Restitution
    rest_data = Bool.T()
    freqlim = Tuple.T(4, Float.T())

    # Downsampling & Rotate NE --> RT
    rotate_data = Bool.T()
    deltat_down = Float.T(default=2.0)
Beispiel #16
0
class MapParameters(Object):
    width = Float.T(help="width of map", optional=True, default=16)
    height = Float.T(help="heigth of map", optional=True, default=16)
    lat = Float.T(help="center latitude")
    lon = Float.T(help="center longitude")
    radius = Float.T(help="radius of map")
    outfn = String.T(help="output filename", optional=True, default="map.png")
    stations = List.T(model.Station.T(), optional=True)
    station_label_mapping = List.T(String.T(), optional=True)
    station_colors = Dict.T(String.T(), String.T(), optional=True)
    events = List.T(model.Event.T(), optional=True)
    show_topo = Bool.T(optional=True, default=True)
    show_grid = Bool.T(optional=True, default=True)
    color_wet = Tuple.T(3, Int.T(), default=(200, 200, 200))
    color_dry = Tuple.T(3, Int.T(), default=(253, 253, 253))

    @classmethod
    def process_args(cls, *args, **kwargs):
        return cls(**kwargs)
Beispiel #17
0
class SeismicGFLibraryConfig(GFLibaryConfig):
    """
    Config for the linear Seismic GF Library for dumping and loading.
    """
    wave_config = WaveformFitConfig.T(default=WaveformFitConfig.D())
    starttime_sampling = Float.T(default=0.5)
    duration_sampling = Float.T(default=0.5)
    starttime_min = Float.T(default=0.)
    duration_min = Float.T(default=0.1)
    dimensions = Tuple.T(5, Int.T(), default=(0, 0, 0, 0, 0))
Beispiel #18
0
class OrientConfig(Object):
    # orientations
    orient_rayl = Bool.T()
    bandpass = Tuple.T(3, Float.T())
    start_before_ev = Float.T()
    stop_after_ev = Float.T()
    plot_heatmap = Bool.T()
    ccmin = Float.T(optional=True)
    plot_distr = Bool.T()
    plot_orient_map_fromfile = Bool.T()
    plot_angles_vs_events = Bool.T(default=False)
    orient_map_label = List.T(optional=True)
    debug_mode = Bool.T(default=False)
Beispiel #19
0
class PsCmpConfig(Object):

    pscmp_version = String.T(default='2008a')
    # scatter, profile or array
    observation = PsCmpObservation.T(default=PsCmpScatter.D())

    pscmp_outdir = String.T(default='./')
    psgrn_outdir = String.T(default='./psgrn_functions/')

    los_vector = Tuple.T(3, Float.T(), optional=True)

    times_snapshots = List.T(Float.T(), optional=True)

    rectangular_source_patches = List.T(default=PsCmpRectangularSource.D())
Beispiel #20
0
class PyrockoConfig(ConfigBase):
    cache_dir = PathWithPlaceholders.T(
        default=os.path.join(pyrocko_dir_tmpl, 'cache'))
    earthradius = Float.T(default=6371.*1000.)
    gf_store_dirs = List.T(PathWithPlaceholders.T())
    gf_store_superdirs = List.T(PathWithPlaceholders.T())
    topo_dir = PathWithPlaceholders.T(
        default=os.path.join(pyrocko_dir_tmpl, 'topo'))
    geonames_dir = PathWithPlaceholders.T(
        default=os.path.join(pyrocko_dir_tmpl, 'geonames'))
    leapseconds_path = PathWithPlaceholders.T(
        default=os.path.join(pyrocko_dir_tmpl, 'leap-seconds.list'))
    leapseconds_url = String.T(
        default='http://www.ietf.org/timezones/data/leap-seconds.list')
    earthdata_credentials = Tuple.T(2, String.T(), optional=True)
Beispiel #21
0
class PlotConfig(Object):
    name = 'undefined'
    variant = String.T(default='default',
                       help='Variant of the plot (if applicable)')
    formats = List.T(PlotFormat.T(),
                     default=[PNG()],
                     help='Format of the plot')
    size_cm = Tuple.T(2, Float.T(), help='size of the plot')
    font_size = Float.T(default=10., help='font size')

    @property
    def size_inch(self):
        return self.size_cm[0] / inch, self.size_cm[1] / inch

    def make(self, environ):
        pass
Beispiel #22
0
class WaveformFitConfig(Object):
    """
    Config for specific parameters that are applied to post-process
    a specific type of waveform and calculate the misfit.
    """
    include = Bool.T(default=True,
                     help='Flag to include waveform into optimization.')
    name = String.T('any_P')
    channels = List.T(String.T(), default=['Z'])
    filterer = Filter.T(default=Filter.D())
    distances = Tuple.T(2, Float.T(), default=(30., 90.))
    interpolation = StringChoice.T(choices=['nearest_neighbor', 'multilinear'],
                                   default='multilinear',
                                   help='GF interpolation sceme')
    arrival_taper = trace.Taper.T(
        default=ArrivalTaper.D(),
        help='Taper a,b/c,d time [s] before/after wave arrival')
Beispiel #23
0
class ParallelTemperingConfig(SamplerParameters):

    n_samples = Int.T(
        default=int(1e5),
        help='Number of samples of the posterior distribution.'
        ' Only the samples of processors that sample from the posterior'
        ' (beta=1) are kept.')
    n_chains = Int.T(
        default=2,
        help='Number of PT chains to sample in parallel.'
        ' A number < 2 will raise an Error, as this is the minimum'
        ' amount of chains needed. ')
    swap_interval = Tuple.T(
        2,
        Int.T(),
        default=(100, 300),
        help='Interval for uniform random integer that is drawn to determine'
        ' the length of MarkovChains on each worker. When chain is'
        ' completed the last sample is returned for swapping state'
        ' between chains. Consequently, lower number will result in'
        ' more state swapping.')
    beta_tune_interval = Int.T(
        default=int(5e3),
        help='Sample interval of master chain after which the chain swap'
        ' acceptance is evaluated. High acceptance will result in'
        ' closer spaced betas and vice versa.')
    n_chains_posterior = Int.T(
        default=1,
        help='Number of chains that sample from the posterior at beat=1.')
    resample = Bool.T(
        default=False,
        help='If "true" the testvalue of the priors is taken as seed for'
        ' all Markov Chains.')
    thin = Int.T(
        default=3,
        help='Thinning parameter of the sampled trace. Every "thin"th sample'
        ' is taken.')
    burn = Float.T(
        default=0.5,
        help='Burn-in parameter between 0. and 1. to discard fraction of'
        ' samples from the beginning of the chain.')
Beispiel #24
0
class TalpaConfig(Object):
    show_cursor = Bool.T(default=True)

    default_gf_dir = String.T(default="")  # noqa

    nvectors = Int.T(default=200,
                     help="Number of horizontal displacement vectors to show")

    vector_color = Tuple.T(
        default=(0, 0, 0, 100),
        help="Color of the displacement arrows, RGBA (0, 0, 0, 100)",
    )

    vector_relative_length = Int.T(default=100,
                                   help="Relative length of the arrow.")

    vector_pen_thickness = Float.T(default=1.0,
                                   help="Thickness of the arrows.")

    view_north = Bool.T(default=True,
                        help="Show the north view of displacement.")

    view_east = Bool.T(default=True,
                       help="Show the east view of displacement.")

    view_down = Bool.T(default=True,
                       help="Show the down view of displacement.")

    view_los = Bool.T(default=True, help="Show the los view of displacement.")

    def __init__(self, *args, **kwargs):
        class QConfig(QtCore.QObject):
            updated = QtCore.pyqtSignal()

        Object.__init__(self, *args, **kwargs)
        self.qconfig = QConfig()

    def saveConfig(self):
        self.regularize()
        self.dump(filename=config_file)
        self.qconfig.updated.emit()
Beispiel #25
0
class SeismicConfig(Object):
    """
    Config for seismic data optimization related parameters.
    """

    datadir = String.T(default='./')
    blacklist = List.T(String.T(),
                       default=['placeholder'],
                       help='Station name for station to be thrown out.')
    distances = Tuple.T(2, Float.T(), default=(30., 90.))
    channels = List.T(String.T(), default=['Z', 'T'])
    calc_data_cov = Bool.T(
        default=True,
        help='Flag for calculating the data covariance matrix based on the'
        ' pre P arrival data trace noise.')
    arrival_taper = trace.Taper.T(
        default=ArrivalTaper.D(),
        help='Taper a,b/c,d time [s] before/after wave arrival')
    filterer = Filter.T(default=Filter.D())
    targets = List.T(TeleseismicTarget.T(), optional=True)
    gf_config = SeismicGFConfig.T(default=SeismicGFConfig.D())
Beispiel #26
0
class TalpaConfig(Object):
    show_cursor = Bool.T(default=True)

    default_gf_dir = String.T(default='')  # noqa

    nvectors = Int.T(default=200,
                     help='Number of horizontal displacement vectors to show')

    vector_color = Tuple.T(
        default=(0, 0, 0, 100),
        help='Color of displacement arrow, RGBA (0, 0 ,0 , 100)')

    class QConfig(QtCore.QObject):
        updated = QtCore.Signal()

    qconfig = QConfig()

    def saveConfig(self):
        self.regularize()
        self.dump(filename=config_file)
        self.qconfig.updated.emit()
Beispiel #27
0
class QSeisSConfig(Object):

    qseiss_version = String.T(default='2014')

    calc_slowness_window = Int.T(default=1)
    slowness_window = Tuple.T(4, optional=True)
    wavenumber_sampling = Float.T(default=2.5)
    aliasing_suppression_factor = Float.T(default=0.01)

    filter_shallow_paths = Int.T(default=0)
    filter_shallow_paths_depth = Float.T(default=0.0)
    propagation_filters = List.T(QSeisSPropagationFilter.T())

    sw_flat_earth_transform = Int.T(default=0)

    gradient_resolution_vp = Float.T(default=0.0)
    gradient_resolution_vs = Float.T(default=0.0)
    gradient_resolution_density = Float.T(default=0.0)

    def items(self):
        return dict(self.T.inamevals(self))
Beispiel #28
0
class KiteSceneTarget(SatelliteTarget):

    shape = Tuple.T(2,
                    Int.T(),
                    optional=False,
                    help='Shape of the displacement vectors.')

    def __init__(self, scene, **kwargs):
        size = scene.displacement.size

        if scene.frame.spacing == 'meter':
            lats = num_full(size, scene.frame.llLat)
            lons = num_full(size, scene.frame.llLon)
            north_shifts = scene.frame.gridN.data.flatten()
            east_shifts = scene.frame.gridE.data.flatten()

        elif scene.frame.spacing == 'degree':
            lats = scene.frame.gridN.data.flatten() + scene.frame.llLat
            lons = scene.frame.gridE.data.flatten() + scene.frame.llLon
            north_shifts = num.zeros(size)
            east_shifts = num.zeros(size)

        self.scene = scene

        super(KiteSceneTarget, self).__init__(lats=lats,
                                              lons=lons,
                                              north_shifts=north_shifts,
                                              east_shifts=east_shifts,
                                              theta=scene.theta.flatten(),
                                              phi=scene.phi.flatten(),
                                              shape=scene.shape,
                                              **kwargs)

    def post_process(self, engine, source, statics):
        res = meta.KiteSceneResult(result=statics,
                                   theta=self.theta,
                                   phi=self.phi,
                                   shape=self.scene.shape)
        res.config = self.scene.config
        return res
Beispiel #29
0
class ShakemapPlot(PlotConfig):
    '''
    Illustration of the solution distribution of decomposed moment tensor.
    '''

    name = 'shakemap'
    size_cm = Tuple.T(2, Float.T(), default=(17.5, 17.5 * (3. / 4.)))

    def make(self, environ):
        cm = environ.get_plot_collection_manager()
        mpl_init(fontsize=self.font_size)
        cm.create_group_mpl(self,
                            self.draw_figures(history),
                            title=u'shakemap',
                            section='shakemap',
                            feather_icon='box',
                            description=u'''
Shakemap
''')

    def draw_figures(self):
        item = PlotItem(name='gf_shakemap')
        return [[item]]
Beispiel #30
0
class GNSSTargetMisfitPlot(PlotConfig):
    ''' Maps showing horizontal surface displacements
        of a GNSS campaign and model '''

    name = 'gnss'

    size_cm = Tuple.T(2,
                      Float.T(),
                      default=(30., 30.),
                      help='width and length of the figure in cm')
    show_topo = Bool.T(default=False, help='show topography')
    show_grid = Bool.T(default=True, help='show the lat/lon grid')
    show_rivers = Bool.T(default=True, help='show rivers on the map')
    radius = Float.T(optional=True,
                     help='radius of the map around campaign center lat/lon')

    def make(self, environ):
        cm = environ.get_plot_collection_manager()
        history = environ.get_history(subset='harvest')
        optimiser = environ.get_optimiser()
        ds = environ.get_dataset()

        environ.setup_modelling()

        cm.create_group_automap(self,
                                self.draw_gnss_fits(ds, history, optimiser),
                                title=u'GNSS Displacements',
                                section='fits',
                                feather_icon='map',
                                description=u'''
Maps showing station positions and statiom names of the GNSS targets.

Arrows the observed surface displacements (black arrows) and synthetic
displacements (red arrows). The top plot shows the horizontal displacements and
the bottom plot the vertical displacements. The grey filled box shows the
surface projection of the modelled source, with the thick-lined edge marking
the upper fault edge.
''')

    def draw_gnss_fits(self, ds, history, optimiser, vertical=False):
        problem = history.problem

        gnss_targets = problem.gnss_targets
        for target in gnss_targets:
            target.set_dataset(ds)

        xbest = history.get_best_model()
        source = history.get_best_source()

        results = problem.evaluate(xbest,
                                   result_mode='full',
                                   targets=gnss_targets)

        def plot_gnss(gnss_target, result, ifig, vertical=False):
            campaign = gnss_target.campaign
            item = PlotItem(
                name='fig_%i' % ifig,
                attributes={'targets': gnss_target.path},
                title=u'Static GNSS Surface Displacements - Campaign %s' %
                campaign.name,
                description=u'''
Static surface displacement from GNSS campaign %s (black vectors) and
displacements derived from best model (red).
''' % campaign.name)

            event = source.pyrocko_event()
            locations = campaign.stations + [event]

            lat, lon = od.geographic_midpoint_locations(locations)

            if self.radius is None:
                coords = num.array([loc.effective_latlon for loc in locations])
                radius = od.distance_accurate50m_numpy(lat[num.newaxis],
                                                       lon[num.newaxis],
                                                       coords[:, 0].max(),
                                                       coords[:, 1]).max()
                radius *= 1.1

            if radius < 30. * km:
                logger.warn('Radius of GNSS campaign %s too small, defaulting'
                            ' to 30 km' % campaign.name)
                radius = 30 * km

            model_camp = gnss.GNSSCampaign(stations=copy.deepcopy(
                campaign.stations),
                                           name='grond model')
            for ista, sta in enumerate(model_camp.stations):
                sta.north.shift = result.statics_syn['displacement.n'][ista]
                sta.north.sigma = 0.

                sta.east.shift = result.statics_syn['displacement.e'][ista]
                sta.east.sigma = 0.

                if sta.up:
                    sta.up.shift = -result.statics_syn['displacement.d'][ista]
                    sta.up.sigma = 0.

            m = automap.Map(width=self.size_cm[0],
                            height=self.size_cm[1],
                            lat=lat,
                            lon=lon,
                            radius=radius,
                            show_topo=self.show_topo,
                            show_grid=self.show_grid,
                            show_rivers=self.show_rivers,
                            color_wet=(216, 242, 254),
                            color_dry=(238, 236, 230))

            all_stations = campaign.stations + model_camp.stations
            offset_scale = num.zeros(len(all_stations))

            for ista, sta in enumerate(all_stations):
                for comp in sta.components.values():
                    offset_scale[ista] += comp.shift
            offset_scale = num.sqrt(offset_scale**2).max()

            m.add_gnss_campaign(campaign,
                                psxy_style={
                                    'G': 'black',
                                    'W': '0.8p,black',
                                },
                                offset_scale=offset_scale,
                                vertical=vertical)

            m.add_gnss_campaign(model_camp,
                                psxy_style={
                                    'G': 'red',
                                    'W': '0.8p,red',
                                    't': 30,
                                },
                                offset_scale=offset_scale,
                                vertical=vertical,
                                labels=False)

            if isinstance(problem, CMTProblem) \
                    or isinstance(problem, VLVDProblem):
                from pyrocko import moment_tensor
                from pyrocko.plot import gmtpy

                mt = event.moment_tensor.m_up_south_east()
                ev_lat, ev_lon = event.effective_latlon

                xx = num.trace(mt) / 3.
                mc = num.matrix([[xx, 0., 0.], [0., xx, 0.], [0., 0., xx]])
                mc = mt - mc
                mc = mc / event.moment_tensor.scalar_moment() * \
                    moment_tensor.magnitude_to_moment(5.0)
                m6 = tuple(moment_tensor.to6(mc))
                symbol_size = 20.
                m.gmt.psmeca(S='%s%g' % ('d', symbol_size / gmtpy.cm),
                             in_rows=[(ev_lon, ev_lat, 10) + m6 + (1, 0, 0)],
                             M=True,
                             *m.jxyr)

            elif isinstance(problem, RectangularProblem):
                m.gmt.psxy(in_rows=source.outline(cs='lonlat'),
                           L='+p2p,black',
                           W='1p,black',
                           G='black',
                           t=60,
                           *m.jxyr)

            elif isinstance(problem, VolumePointProblem):
                ev_lat, ev_lon = event.effective_latlon
                dV = abs(source.volume_change)
                sphere_radius = num.cbrt(dV / (4. / 3. * num.pi))

                volcanic_circle = [ev_lon, ev_lat, '%fe' % sphere_radius]
                m.gmt.psxy(S='E-',
                           in_rows=[volcanic_circle],
                           W='1p,black',
                           G='orange3',
                           *m.jxyr)

            return (item, m)

        ifig = 0
        for vertical in (False, True):
            for gnss_target, result in zip(problem.gnss_targets, results):
                yield plot_gnss(gnss_target, result, ifig, vertical)
                ifig += 1