📄 s_wiener_filter.m
字号:
function filter=s_wiener_filter(from,to,varargin)% Function computes the filter that matches (filters that match) the first% input data set to the second input data set.%% Written by: E. R.: October 2001% Last updated: August 3, 2006: bug fix%% filter=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 length of "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 as output.% 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.% No default unless "from" and "to" are one-trace datasets;% in this case {'option','tracewise'} % 'flength' filter length in ms; no default.% 'window1' window on the first input data set which should be used% Default: {'window1',from.first,from.last}% 'window2' window on the second input data set that should be matched % Default: {'window1',to.first,to.last}% '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". To suppress % cresting this header set {'header',[]}% 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% corresponding 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.% Check input dataif ~istype(from,'seismic') | ~istype(to,'seismic') error(' The first two input data sets must be seismic structures.')endntr1=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 parametersparam.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 argumentsparam=assign_input(param,varargin);if isempty(param.option) if size(from.traces,2) == 1 & size(to.traces,2) == 1 param.option='tracewise'; else error('Parameter "option" must be specified.') endendif isempty(param.option) error('Parameter "option" must be specified.')endif 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);endif strcmp(param.scale,'yes') scaling=logical(1);else scaling=logical(0);endta1=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),')'])endif 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 alert(' ... 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 endfilter.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),')'])endif 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')endfilter.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); endelse error(' Not yet implemented')endfilter.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);% ----------------------------------------------- otherwiseerror([' Unknown option "',param.option,'"'])end % End of switch blockfilter.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 fieldif 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 + -