Ejemplo n.º 1
0
def smooth(input_vmfile, rough_vmfile, output_vmfile, combo_smooth=True,
           grid_only=True, strict_layers=True, extrapolate_grid=True,
           ngrid=None, dz0=None, zuniform=None, top_layer=0,
           bottom_layer=None, damping=0.1, first_derivative_smoothing=0.1,
           second_derivative_smoothing=0.5, slowness_scale=0.02,
           slowness_jump_scale=0.005, reflector_depth_scale=2.0,
           slowness_reference_scale=0.2,
           vscale_pow=2, matrix_terms=2, penalty_terms=2,
           reflector_depth_weight=0.5, slowness_jump_weight=10,
           aspect_ratio=1.0, target_chi_squared=1.0):
    """
    Smooth a VM model.

    .. note:: This is a wrapper for the Fortran program ``vm_smooth_model``

    :param input_vmfile: Filename of the VM-format slowness model to that was
        used as input to the inversion that produced ``rough_vmfile``.
    :param rough_vmfile: Filename of the VM-format slowness model result from
        the inversion.
    :param output_vmfile: Filename of the smoothed, output VM-format slowness
        model.
    """
    # Set default inversion grid parameters
    if None in [ngrid, dz0, zuniform, bottom_layer]:
        vm = readVM(input_vmfile)
    if ngrid is None:
        ngrid = (vm.nx, vm.ny, vm.nz)
    if dz0 is None:
        dz0 = vm.dz
    if zuniform is None:
        zuniform = vm.r2[2]
    if bottom_layer is None:
        bottom_layer = vm.nr
    # Setup input
    sh = '#!/bin/bash\n'
    sh += '#\n'
    sh += '{:} << eof\n'.format(SMOOTHING_PROGRAM)
    sh += '{:} {:}\n'.format(python2fortran_bool(combo_smooth),
                             python2fortran_bool(grid_only))
    sh += '{:} {:}\n'.format(python2fortran_bool(strict_layers),
                             python2fortran_bool(extrapolate_grid))
    sh += '{:}\n'.format(input_vmfile)
    sh += '{:} {:} {:}\n'.format(ngrid[0], ngrid[1], ngrid[2])
    sh += '{:} {:}\n'.format(dz0, zuniform)
    sh += '{:}\n'.format(rough_vmfile)
    sh += '{:} {:}\n'.format(top_layer, bottom_layer)
    sh += '{:} {:} {:}\n'.format(damping, first_derivative_smoothing,
                                 second_derivative_smoothing)
    sh += '{:} {:} {:}\n'.format(slowness_scale, slowness_jump_scale,
                                 reflector_depth_scale)
    sh += '{:} {:} {:} {:}\n'.format(slowness_reference_scale,
        vscale_pow, matrix_terms, penalty_terms)
    sh += '{:} {:}\n'.format(reflector_depth_weight, slowness_jump_weight)
    sh += '{:}\n'.format(aspect_ratio)
    sh += '{:}\n'.format(target_chi_squared)
    sh += '{:}\n'.format(output_vmfile)
    # Run the script
    subprocess.call(sh, shell=True)
Ejemplo n.º 2
0
def invert(input_vmfile, rayfile, output_vmfile, smooth_result=True,
           target_chi_squared=1.0, damping=0.1,
           first_derivative_smoothing=0.1, second_derivative_smoothing=0.5,
           ngrid=None, dz0=None, zuniform=None,
           slowness_scale=0.02, slowness_jump_scale=0.005,
           reflector_depth_scale=2.0,
           top_layer=0, bottom_layer=None,
           station_correction=True,
           station_correction_scale=0.04, station_correction_weight=0.0,
           station_correction_file=None,
           headwaves=True, strict_layers=True, extrapolate_grid=True,
           ray_skip_interval=1, horizontal_ray_extension=1,
           vertical_ray_extension=0.2, slowness_reference_scale=0.2,
           vscale_pow=2, matrix_terms=2, penalty_terms=2,
           reflector_depth_weight=0.5, slowness_jump_weight=10,
           aspect_ratio=1.0,
           diagnostic_directory='inverse', combo_smooth=True,
           grid_only=True):
    """
    Wrapper for running the VM Tomography inversion program.

    :param input_vmfile: Filename of the VM-format slowness model to use as
        the starting model for the inversion.
    :param rayfile: Filename of the rayfan file with rays traced through
        ``vmfile``.
    :param output_vmfile: Filename of the VM-format slowness model to write
        the inversion result to.
    :param smooth_result: Bool. Determines whether or not to smooth the
        inversion result. Default is True.
    :param target_chi_squared: Optional. Target chi^2 value, a value that
        measures how well the inversion result fits the data. Default is
        ``1.0`` (i.e., the best fit that can be achieved within error).
    :param damping: Optional. Weight for model perturbation damping. A
        negative value causes damping to be turned off. Default is ``0.1``.
    :param first_derivative_smoothing: Optional. Weight for the penalty on
        first derivative model smoothness. A negative value causes this term
        to be ignored. Default is ``0.1``.
    :param second_derivative_smoothing: Optional. Weight for the penalty on
        second derivative model smoothness. A negative value causes this term
        to be ignored. Default is ``0.5``.
    :param ngrid: Optional. Tuple with grid sizes ``(nx, ny, nz)`` for the
        inversion grid. Default is to use the model grid sizes.
    :param dz0: Optional. Vertical grid spacing at the top of the inversion
        grid. Default is to use the model grid spacing.
    :param zuniform: Optional. Depth below which the inversion grid spacing
        increases linearly. Default is set this depth to the maximum depth
        in the input model (i.e., inversion grid spacing is constant).
    :param slowness_scale: Optional. Scale factor for slowness (1/velocity)
        changes. Default is ``0.02``.
    :param slowness_jump_scale: Optional. Scale factor for slowness jump
        changes. Default is ``0.005``.
    :param reflector_depth_scale: Optional. Scale factor for changes to
        reflector depths. Default is ``2.0``.
    :param top_layer: Optional. The index of the top-most layer to include in
        the inversion. Default is ``0`` (i.e., the top-most layer in the
        model).
    :param bottom_layer: Optional. The index of the bottom-most layer to
        include in the model. Default is the index of the bottom-most layer
        in the model.
    :param station_correction: Optional. Determines whether or not to include
        station static corrections in the inversion. Default is True.
    :param station_correction_scale: Optional. Scale factor for station
        static corrections. Default is 0.04.
    :param station_correction_weight: Optional. Weight for station correction
        terms. A value of zero forces station corrections to be enforced.
        Default is ``0.0``.
    :param station_correction_file: Optional. Filename for output file with
        station static corrections. Default is
        ``<ouput model>.station_statics.dat``.
    :param headwaves: Optional. Determines whether or not to include
        include headwaves in the calculation of Frechet derivatives. Default
        is True.
    :param strict_layers: Optional. Default is True.
    :param extrapolate_grid: Optional. Default is True.
    :param ray_skip_interval: Optional. Skip interval for raypaths to include
        in the inversion. 1=use all rays, n=use every n-th ray. Default is 1.
    :param horizontal_ray_extension: Optional. Horizontal distance over
        which to extend model sensitivity. Units are the same as the model's
        distance units. Default is ``1.``.
    :param vertical_ray_extension: Optional. Vertical distance over which to
        extend model sensitivity. Units are the same as the model's distance
        units. Default is ``0.2``.
    :param slowness_reference_scale: Optional. Scaling factor for the
        reference slowness model. Default is ``0.2``.
    :param vscale_pow: Optional. ????. Default is ``2``.
    :param matrix_terms: Optional. ????. Default is ``2``.
    :param penalty_terms: Optional. ????. Default is ``2``.
    :param reflector_depth_weight: Optional. Relative strength
        regularization of interface depths. Default is ``0.5``.
    :param aspect_ratio: Optional. Aspect ratio of smoothing constraints
        (i.e,  amplification of horizontal versus vertical derivatives
        constraints). Default is ``1.0`` (i.e., no bias).
    :param slowness_jump_weight: Optional. Relative strength regularization of
        slowness jumps. Default is ``10.0``.
    :param diagnostic_directory: Optional. Directory to store diagnositic
        files in. Default is to create a new directory ``'inverse'`` within
        the current working directory, if it does not already exist.
    """
    # Set default inversion grid parameters
    if None in [ngrid, dz0, zuniform, bottom_layer]:
        vm = readVM(input_vmfile)
    if ngrid is None:
        ngrid = (vm.nx, vm.ny, vm.nz)
    if dz0 is None:
        dz0 = vm.dz
    if zuniform is None:
        zuniform = vm.r2[2]
    if bottom_layer is None:
        bottom_layer = vm.nr
    # station statics file
    if station_correction_file is None:
        station_correction_file = output_vmfile.split('.vm')[0]\
                + '.station_statics.dat'
    # Diagnostic files
    if not os.path.isdir(diagnostic_directory):
        os.mkdir(diagnostic_directory)
    frechet_matrix = diagnostic_directory + os.path.sep \
            + 'frechet_matrix.bin'
    sl1_file = diagnostic_directory + os.path.sep + 'sl.dat'
    sl2_file = diagnostic_directory + os.path.sep + 'sl.ext.dat'
    rf1_file = diagnostic_directory + os.path.sep + 'rf.dat'
    rf2_file = diagnostic_directory + os.path.sep + 'rf.ext.dat'
    jp1_file = diagnostic_directory + os.path.sep + 'jp.dat'
    jp2_file = diagnostic_directory + os.path.sep + 'jp.ext.dat'
    dws_sl_file = diagnostic_directory + os.path.sep + 'dws.sl.dat'
    dws_rf_file = diagnostic_directory + os.path.sep + 'dws.rf.dat'
    dws_jp_file = diagnostic_directory + os.path.sep + 'dws.jp.dat'
    nlr_file = diagnostic_directory + os.path.sep + 'nlr.dat'
    inz_file = diagnostic_directory + os.path.sep + 'inz.dat'
    anz_file = diagnostic_directory + os.path.sep + 'anz.dat'
    sol_file = diagnostic_directory + os.path.sep + 'sol.dat'
    vecm_file = diagnostic_directory + os.path.sep + 'vecm.bin'
    # Build run script
    sh = '#!/bin/bash\n'
    sh += '#\n'
    sh += '{:} << eof\n'.format(INVERSION_PROGRAM)
    sh += '{:} {:} {:} {:}\n'\
        .format(python2fortran_bool(USE_NEW_FRECHET_DERIVATIVE_CALCULATION),
        python2fortran_bool(USE_COMBINATION_SMOOTHNESS),
        python2fortran_bool(station_correction),
        bool2int(PRINT_FORTRAN_DEBUG))
    sh += '{:}\n'.format(python2fortran_bool(headwaves))
    sh += '{:} {:}\n'.format(python2fortran_bool(strict_layers),
                             python2fortran_bool(extrapolate_grid))
    sh += '{:}\n'.format(input_vmfile)
    sh += '{:} {:} {:}\n'.format(ngrid[0], ngrid[1], ngrid[2])
    sh += '{:} {:}\n'.format(dz0, zuniform)
    sh += '{:} {:}\n'.format(top_layer, bottom_layer)
    sh += '{:}\n'.format(rayfile)
    sh += '{:}\n'.format(frechet_matrix)
    sh += '{:}\n'.format(ray_skip_interval)
    sh += '{:} {:}\n'.format(horizontal_ray_extension, vertical_ray_extension)
    sh += '{:}\n'.format(sl1_file)
    sh += '{:}\n'.format(sl2_file)
    sh += '{:}\n'.format(rf1_file)
    sh += '{:}\n'.format(rf2_file)
    sh += '{:}\n'.format(jp1_file)
    sh += '{:}\n'.format(jp2_file)
    sh += '{:} {:} {:}\n'.format(damping, first_derivative_smoothing,
                                 second_derivative_smoothing)
    sh += '{:}\n'.format(station_correction_weight)
    sh += '{:} {:} {:} {:}\n'.format(slowness_scale, slowness_jump_scale,
        reflector_depth_scale, station_correction_scale)
    sh += '{:} {:} {:} {:}\n'.format(slowness_reference_scale,
        vscale_pow, matrix_terms, penalty_terms)
    sh += '{:} {:}\n'.format(reflector_depth_weight, slowness_jump_weight)
    sh += '{:}\n'.format(aspect_ratio)
    sh += '{:}\n'.format(dws_sl_file)
    sh += '{:}\n'.format(dws_rf_file)
    sh += '{:}\n'.format(dws_jp_file)
    sh += '{:}\n'.format(nlr_file)
    sh += '{:}\n'.format(inz_file)
    sh += '{:}\n'.format(anz_file)
    sh += '{:}\n'.format(sol_file)
    sh += '{:}\n'.format(target_chi_squared)
    sh += '{:}\n'.format(station_correction_file)
    sh += '{:}\n'.format(output_vmfile)
    sh += 'eof'
    # Run the inversion script
    subprocess.call(sh, shell=True)
    # Optional smoothing
    if smooth_result:
        smooth(input_vmfile, output_vmfile, output_vmfile,
               combo_smooth=combo_smooth,
               grid_only=grid_only, strict_layers=strict_layers,
               extrapolate_grid=extrapolate_grid, ngrid=ngrid,
               dz0=dz0, zuniform=zuniform, top_layer=top_layer,
               bottom_layer=bottom_layer, damping=damping,
               first_derivative_smoothing=first_derivative_smoothing,
               second_derivative_smoothing=second_derivative_smoothing,
               slowness_scale=slowness_scale,
               slowness_jump_scale=slowness_jump_scale,
               reflector_depth_scale=reflector_depth_scale,
               slowness_reference_scale=slowness_reference_scale,
               vscale_pow=vscale_pow, matrix_terms=matrix_terms,
               penalty_terms=penalty_terms,
               reflector_depth_weight=reflector_depth_weight,
               slowness_jump_weight=slowness_jump_weight,
               aspect_ratio=aspect_ratio,
               target_chi_squared=target_chi_squared)
    # Clean up hard-coded files
    if os.path.isfile('vecm.bin'):
        os.rename('vecm.bin', vecm_file)