Each phase
structure has 3 members related to phase identification:
Each phase
structure has three members weighting:
In order for a particular type of phase to be used it must be present
in two arrays of structures initialised at the top of of two different functions:
phase_map initialised in function
id_pha
If a phase code is missing from the phase_map array then any arrival with
that operator code will have phase
set to "" and so will end up with a weight_factor
of 0 and not contribute to the solution.
struct phase_map_rec phase_map[2] = {
{"p" , "P" },
{"P" , "P" },
}
Would set phase
to "P" if rep_phase
for an arrival were either "p" or "P". Arrivals with all other phase
codes would have phase
set to "".
Unless the no_reid_phase instruction has been given by the operator
id_pha
also calls a function (e.g. id_jb) to check that an arrival's phase code is consistent with the earth model
being used, the distance between the station and the source, and the source
depth. In the example above this would mean that even an arrival with
rep_phase
"P" would have
phase
set to "" if
delta
were too great for the P travel time tables being used. In practice
a "P" could also be reidentified as "Pg" at certain values of
delta
and source depth but it is an error for the phase identifying function to
assign a value to
phase
not present on the right side of the phase_map array.
phase_weight initialised in function
get_weight_factor
An arrival with a value of phase
that is not present in the phase_weight array will be given a
weight_factor
of 0 and not contribute to the solution. If it has a non null
phase
it will still have a residual calculated for it at the end of the solution
process, after final convergence has been reached.
If an arrival has a value of phase
that is present in the phase_weight array then the
weight_factor
it will be given depends on the distance between the station where it was
recorded and the current solution,
delta. This is why weight_factor
is recalculated every iteration.
struct phase_weight_rec phase_weight[2] = {
{ "P", 0, 20, 1 },
{ "P", 20, 100, 0.5 },
}
Would weight local P arrivals fully while weighting down teleseismic P.
A P arrival from a source more than 100 degrees away would not get a weight
and neither would any other type of arrival.
Two constants weighting1
and weighting2
can be set in config.txt
for a particular run of the iscloc program. weighting1
must equal a name that corresponds to an existing weighting function (although
one of the functions provided is no_weight
which just multiplies the weight_factor
of each phase by 1 to get its weight). weighting2
may or may not be set. If it is set then if convergence is reached
the weighting function in use will be changed to that corresponding to
weighting2
and iteration reinitiated using the result of the first convergence as a
starting point.
weighting1 = huber
weighting2 = buland
If these lines were present in config.txt
then a solution would first be attempted using Huber-t weighting as implemented
in the function huber_weight. If convergence were reached then further iterations would be made
using the function buland_weight
until final convergence was reached (or failed to be reached). The
weighting function currently in use is stored as
weighting_type
in the solution
structure. If weighting2
is set then weighting_type
will be reset by the function change_weighting
after the first convergence.
The three weighting functions provided so far and the corresponding names
that would need to be added to config.txt are:
huber_weight
(huber)
buland_weight
(buland)
no_weight
(none)
To use another function it would be necessary to add an else if block to
the function calc_weight
and provide a new function with the correct input arguments. For example:
#
include "iscloc.h"
int new_weight (struct sol_rec *sp, struct pha_rec p[])
{