📄 s_wiener_filter.m
字号:
function [filter,cc_max]=s_wiener_filter(from,to,varargin)
% Function computes filter that matches the first input data set to the
% second input data set
% Written by: E. R.:
% Last updated: August 4, 2004: handle case when first data set is longer than
% the second data set + the length of the filter;
% bug fix for filter start time
%
% [filter,cc_max]=s_wiener_filter(from,to,varargin)
% INPUT
% from, to seismic data sets to be matched.
% Depending on the options used the two data sets may
% need to have the same number of traces
% If the lengthof "to" + the filter length is less than the
% length of "to" a filter is computed for a number of shifts
% equal to "length ("to") - length ("from") - length('filter");
% the best-matching filter is chosen
% samples of "from"
% varargin one or more cell arrays; the first element of each cell
% array is a keyword,the other elements are parameters.
% Presently, keywords are:
% 'method' defines the method/algorithm to be used to compute
% the filter. Presently,the following algorithms are available:
% 'sridge' simple ridge regression
%
% 'option' specifies which type of filter to compute. Presently,
% the following options are available:
% 'tracewise' compute filters (one filter for each input/output trace pair)
% which convert traces in the first input dataset into the
% corresponding traces of the second seismic structure input. This
% requires that the the two seismic structures have the same number of
% traces (ntr1=ntr2). The number of filters output is equal to ntr1, the
% number of traces in the input data sets.
% 'dataset' Compute a single filter that converts every trace
% in the first input dataset into the corresponding trace
% of the second seismic input dataset. This requires
% that the the two seismic structures have the same number
% of traces (ntr1=ntr2).
% 'all' Compute ntr1*ntr2 individual filters which match each
% trace of the first input dataset to each trace
% of the second input data set.
% 'flength' filter length in ms; no default.
% 'window1' window on the first input data set which should be used
% Default: the whole time range.
% 'window2' window on the second input data set that should be matched
% Default: the whole time range.
% 'null' Null value to use for filter coefficients that do not exist
% Only important if there is more than one filter and if
% filters are shifted relative to one another. Default: null=0.
% 'header" As part of the filter calculation the crosscorrelation
% of the filtered first input data set, i.e. filter*from,
% and second data set, to, is computed.
% 'header' defines the header name used to store
% these crosscorrelations for option "tracewise".
% Default: {'header','param_cc'}
% 'wnoise' fraction of "white noise" to add
% Default: {'wnoise',0.01}
% OUTPUT
% filter filter in form of a seismic structure. Filter has either one trace (a single
% filter matching corresponding traces), or as many traces as there are traces
% in from or to. In this case there is one filter for each pair of
% corrsponding input traces. Finally there can be ntr1*ntr2 filters matching
% trace of the first input data set to each trace of the second input data set.
% In this case the first ntr2 filters match the first trace of the first input
% data set to the ntr2 traces of the second data set, the second ntr2 filters
% match the second trace of the first input data set to the second data set, etc.
% cc_max Cross correlations between filter*from and to.
% Check input data
if ~strcmp(from.type,'seismic') | ~strcmp(to.type,'seismic')
error(' The first two input data sets must be seismic structures')
end
ntr1=size(from.traces,2);
ntr2=size(to.traces,2);
if from.step~= to.step
error([' The two input data sets must have the same sample interval (', ...
num2str(from.step),' differs from ',num2str(to.step),')'])
end
% Set default values for input parameters
param.increment=from.step;
param.flength=[];
%param.method='sridge';
param.null=0;
param.option=[];
param.stepout=[];
param.scale='yes';
% param.type=1;
param.window1={from.first,from.last};
param.window2={to.first,to.last};
param.header='param_cc';
param.wnoise=0.01;
% Replace defaults by actual input arguments
param=assign_input(param,varargin);
if isempty(param.option)
error('Parameter "option" must be specified.')
end
if isempty(param.flength)
error(' Parameter "flength" has no default; must be specified')
else
nf=round(param.flength/from.step)+1;
% nf2=round((nf+1)/2);
end
if strcmp(param.scale,'yes')
scaling=logical(1);
else
scaling=logical(0);
end
ta1=max([param.window1{1},from.first]);
te1=min([param.window1{2},from.last]);
ta2=max([param.window2{1},to.first]);
te2=min([param.window2{2},to.last]);
ia1=round((ta1-from.first)/from.step)+1;
ie1=round((te1-from.first)/from.step)+1;
ia2=round((ta2-to.first)/to.step)+1;
ie2=round((te2-to.first)/to.step)+1;
n1=ie1-ia1+1;
n2=ie2-ia2+1;
if isempty(param.stepout)
param.stepout=param.flength/10;
end
incr=max(1,round(param.stepout/from.step));
filter.type='seismic';
filter.tag='wavelet';
filter.name='filter';
% Compute Wiener filter.
switch param.option
case 'tracewise'
if ntr1 ~= ntr2
error([' The two input data sets must have the same number of traces (', ...
num2str(ntr1),' differs from ',num2str(ntr2),')'])
end
if n2 >= n1-nf % Number of samples of target >= number of samples of original
% data set - filter coefficients
[filt,cc_max,shifts]=mfilter_t2t(from.traces(ia1:ie1,:), ...
to.traces(ia2:ie2,:),nf,param.wnoise,incr);
min_shift=min(shifts);
dshift=(shifts-min_shift);
max_shift=max(dshift);
if max_shift > 0 & isnan(param.null)
filter.null=NaN;
filter.traces=NaN*ones(nf+max_shift,ntr1);
else
filter.traces=param.null*ones(nf+max_shift,ntr1);
end
for ii=1:ntr1
filter.traces(1+dshift(ii):dshift(ii)+nf,ii)=filt(:,ii);
end
else
warning(' ... not yet sufficiently tested for multi-trace filters')
nshifts=n1-nf-n2;
ia10=ia1-1;
ie10=ia10+n2+nf-2;
cc=zeros(nshifts,ntr1);
filters=zeros(nshifts,ntr1,nf);
for ii=1:nshifts
[filt,cc_max,shifts]=mfilter_t2t(from.traces((ia10:ie10)+ii,:), ...
to.traces(ia2:ie2,:),nf,param.wnoise,incr);
filters(ii,:,:)=filt';
cc(ii,:)=cc_max;
end
[cc_max,idx]=max(cc);
idx1=idx+(0:nshifts:(ntr1-1)*nshifts);
shifts=2-idx;
filters=reshape(filters,[],nf);
filters=filters(idx1,:)';
min_shift=min(shifts);
dshift=(shifts-min_shift);
max_shift=max(dshift);
if max_shift > 0 & isnan(param.null)
filter.null=NaN;
filter.traces=NaN*ones(nf+max_shift,ntr1);
else
filter.traces=param.null*ones(nf+max_shift,ntr1);
end
for ii=1:ntr1
filter.traces(1+dshift(ii):dshift(ii)+nf,ii)=filters(:,ii);
end
end
filter.step=from.step;
%filter.first=to.first-from.first-(nf-nf2-min_shift)*filter.step;
%filter.first=to.first-from.first-(nf-min_shift)*filter.step;
filter.first=ta2-ta1-(nf-min_shift)*filter.step;
filter.last=filter.first+(nf+max_shift-1)*filter.step;
if isfield(from,'headers')
filter.headers=from.headers;
filter.header_info=from.header_info;
end
% -----------------------------------------------
case 'dataset'
if ntr1 ~= ntr2
error([' The two input data sets must have the same number of traces (', ...
num2str(ntr1),' differs from ',num2str(ntr2),')'])
end
if n2 >= n1-nf
[filt,cc_max,shifts]=mfilter_d2d(from.traces(ia1:ie1,:), ...
to.traces(ia2:ie2,:),nf,param.wnoise,incr);
filter.traces=filt;
else
error(' Second data set too short (< length of "from" + filter length); not yet implemented')
end
filter.step=from.step;
filter.first=ta2-ta1-(nf-shifts)*filter.step;
filter.last=filter.first+(nf-1)*filter.step;
% -----------------------------------------------
case 'all'
ntr12=ntr1*ntr2;
filters=zeros(nf,ntr12);
cc_max=zeros(ntr12,1);
shifts=zeros(ntr12,1);
if n2 >= n1-nf
for ii=1:ntr1
[filt,cc_m,shift,scale]=mfilter_t2d(from.traces(ia1:ie1,ii), ...
to.traces(ia2:ie2,:),nf,param.wnoise,incr,0);
if scaling
% filters(:,(ii-1)*ntr2+1:ii*ntr2)=filt*spdiags(scale,0, ...
% length(scale),length(scale));
filters(:,(ii-1)*ntr2+1:ii*ntr2)=mvt(filt,scale);
else
filters(:,(ii-1)*ntr2+1:ii*ntr2)=filt;
end
cc_max((ii-1)*ntr2+1:ii*ntr2)=cc_m;
shifts((ii-1)*ntr2+1:ii*ntr2)=shift;
end
min_shift=min(shifts);
dshift=(shifts-min_shift);
max_shift=max(dshift);
if max_shift > 0 & isnan(param.null)
filter.null=NaN;
filter.traces=NaN*ones(nf+max_shift,ntr1*ntr2);
else
filter.traces=param.null*ones(nf+max_shift,ntr1*ntr2);
end
for ii=1:ntr12
filter.traces(1+dshift(ii):dshift(ii)+nf,ii)=filters(:,ii);
end
else
error(' Not yet implemented')
end
filter.step=from.step;
% filter.first=to.first-from.first-(nf-nf2-min_shift)*filter.step;
filter.first=to.first-from.first-(nf-min_shift)*filter.step;
filter.last=filter.first+(nf+max_shift-1)*filter.step;
cc_max=reshape(cc_max,ntr2,ntr1);
% -----------------------------------------------
otherwise
error([' Unknown option ',option])
end
filter.units=from.units;
if ~isempty(param.header) & ~strcmpi(param.option,'dataset')
filter=s_header(filter,'add',param.header,cc_max(:)','n/a', ...
'Coefficient of correlation');
end
% Append history field
if isfield(from,'history') & isfield(to,'history')
filter.history=from.history;
htext=param.option;
filter=s_history(filter,'append',htext);
filter=s_history(filter,'merge',to.history);
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -