📄 s_wavextra.m
字号:
function [wavelet,aux]=s_wavextra(seismic,refl,varargin)% Function extracts wavelet from seismic data using a log-derived % reflectivity sequence% Written by E. R., May 6, 2000% Last update: July 23, 2005: New definitions and defaults for 'logshifts',% 'logwindow', and 'wavshifts'%% [wavelet,aux]=s_wavextra(seismic,refl,varargin)% INPUT% seismic seismic traces in the vicinity of the well% refl seismic structure representing the reflection coefficient sequence% seismic and refl must have the same sample interval% varargin one or more cell arrays; the first element of each cell array is a keyword,% the other elements are parameters. Presently, keywords are:% 'downstep' step size (in seismic time units - usually ms) by which log and % seismic move down to compute a new wavelet.% Default: {'downstep',20}% 'headers' Header to copy from seismic to wavelets. % Default: {'headers','*'} meaning all headers% 'header_null' No-data value to use for missing header values.% Default: {'header_null',NaN} % 'wlength' wavelet length. Default 60 ms% 'logshifts' vector of global shifts of the reflection coefficient% sequence vs the seismic that are to be used (to account% for a possible error in the time to the top of the log,% bad check shot data). It can be one value or a vector. % A wavelet is computed for each shift.% Default: {'logshifts',0}% 'logwindow' length of log segment matched to seismic. Recommended: % logwindow >= 5*wlength% Default: {'logwindow',refl.last-refl.first} i.e. the % whole reflection coefficient series% 'null' Null value to use; Default: {'null',NaN}% 'print' Controls printed output showing progress of wavelet estimation; % no output if set to 0. Default: {'print',1}% 'scale' scale wavelets so that synthetic has about the same % amplitude level as the seismic (counteract noise in data)% Default: {'scale','yes'}% 'sp_constraint' Controls use of spectrum constraints, representing % the ratio of Frobenius norm of spectrum constraint to % Frobenius norm of convolution matrix. If set to zero % spectrum constraint is not used. % Default: {'sp_constraint',0)% 'dc_constraint' Constraint on the DC component of the wavelet% Default: {'dc_constraint',0}% 'wavshifts' vector of shifts of seismic data with respect to the% reflection coefficients. It can be one value or a vector. % It is intended to allow small changes in % shifts for any value of 'logshifts'. Only the best wavelet % found for any of the shifts is output% Default: {'wavshifts',0}% 'wnoise' White noise (ratio of to maximum reflection coefficient)% Default: {'wnoise',0.1}% % OUTPUT% wavelet wavelet(s) extracted from the seismic data. A number of headers are added to this% data set to capture the following information about the wavelet.% wstart start time of window over which wavelet is estimated% cc_wavelet correlation coefficient for this wavelet and for this particular% trace, window, and value of "logshifts"% cc_max maximum correlation coefficient for this particular trace and % value of "logshift" (common for all wavelets derived from the same % seismic trace and the same value of "logshift")% cc_median median correlation coefficient for this particular trace and% value of "logshift" (common for all wavelets derived from the same % seismic trace and the same value of "logshift")% swstart start of seismic window used% rwstart start of log window used% aux structure with additional information% aux.logsegments number of log segments used (==> number of% wavelets per trace% aux.logshifts number of bulk logshifts used (see keyword 'logshifts')%% EXAMPLES wavelets=s_wavextra(seismic,refl,{'logshifts',-40,4,32})global ABORTEDABORTED=logical(1);% Set defaults for input parametersparam.downstep=20;param.headers='*';param.header_null=NaN;param.wlength=60;param.logshifts=0;param.logwindow=refl.last-refl.first;param.null=NaN;param.print=1;param.sp_constraint=0.0;param.dc_constraint=0.0;param.scale='yes';param.wavshifts=0;param.wnoise=0.1;% Decode input argumentsparam=assign_input(param,varargin); % Read input parameters% Check input parametersif param.logwindow > refl.last-refl.first param.logwindow=refl.last-refl.first;endif strcmp(param.scale,'yes') scaling=logical(1);else scaling=logical(0);endif iscell(param.wavshifts) % Legacy code param.wavshifts=cell2mat(param.wavshifts);endtemp(1)=round(param.wavshifts(1)/seismic.step);temp(3)=round(param.wavshifts(end)/seismic.step);increment=max(fix(temp(3)-temp(1))/length(param.wavshifts),1);temp(2)=increment;param.wavshifts=temp*seismic.step;% Convert times to samplesnsampw=round(param.wlength/seismic.step)+1; % Number of samples of waveletnlogwindow=round(param.logwindow/seismic.step)+1; % Number of samples of log windowndownstep=round(param.downstep/seismic.step); % Number of samples to step down for next windownsampr=length(refl.traces); % Number of samples of reflection coefficient[nsamp,ntr]=size(seismic.traces);% Checking of input parametersif abs(seismic.step - refl.step) > 1.06*eps*seismic.step error([' Seismic and reflection coefficients have different sample intervals: ', ... num2str([seismic.step,refl.step])])endtemp=(seismic.first-refl.first)/seismic.step;if abs(round(temp)-temp) > 1.0e6*eps disp(' Start time of seismic and reflection coefficients differ by a non-integer') disp(' multiple of the sample interval') error(' Abnormal termination')end if 0if iscell(param.logshifts) % Legacy parameters logshifts=param.logshifts{1}:param.logshifts{2}:param.logshifts{3};else logshifts=param.logshifts; if isempty(logshifts) error(' Empty array of log shifts supplied') endend end%temp(1)=round(param.logshifts(1)/seismic.step);%temp(3)=round(param.logshifts(end)/seismic.step);%temp(2)=max(fix(temp(end)-temp(1))/length(param.logshifts),1);%logshifts=temp*seismic.step;first=round(param.logshifts(1)/seismic.step);last=round(param.logshifts(end)/seismic.step);step=max(fix(temp(end)-temp(1))/length(param.logshifts),1);logshifts=(first:step:last)*seismic.step;% Prepare for newly created headersheader_info=[ ... {'cc_wavelet','n/a','Cross-correlation of synthetic and seismic'}; ... {'cc_max','n/a','Maximum correlation for this trace and shift'}; ... {'cc_median','n/a','Median correlation for this trace and shift'}; ... {'swstart','ms','Start of seismic window used'}; ... {'rwstart','ms','Start of reflection coefficient window used'}];% Select seismic headers to copy to wavelet and append header_infoif isfield(seismic,'headers') if ~iscell(param.headers) param.headers={param.headers}; end if length(param.headers) == 1 & strcmp(param.headers{1},'*') param.headers=seismic.header_info(:,1); end [index,ier]=mnemonics_match(seismic.header_info(:,1),param.headers); if ier error(' Abnormal termination') end seismic_headers=seismic.headers(index,:); header_info=[header_info;seismic.header_info(index,:)];endnheaders=size(header_info,1); % Reserve room for arraysnlogsegments=fix((nsampr-nlogwindow)/ndownstep)+1; % Number of log windowsnwavelets=ntr*nlogsegments*length(logshifts);shifts=NaN*zeros(nwavelets,1);% cc_wavelets=param.header_null*zeros(nwavelets,1);wavelets=zeros(nsampw,nwavelets);headers=param.header_null*zeros(nheaders,nwavelets);iawav=1; iewav=ntr;nseiswindow=round((param.logwindow-param.wlength+ ... param.wavshifts(end)-param.wavshifts(1))/seismic.step); % Correctionif param.print disp(['S_WAVEXTRA uses ',num2str(nlogsegments),' log segment(s) and ', ... num2str(length(logshifts)),' log shift(s)'])endaux.logsegments=nlogsegments;aux.logshifts=logshifts;nulls=0;% Create constraint matrixif param.sp_constraint ~= 0 % Create spectral constraint matrix temp=s_select(seismic,{'times',refl.first,refl.last}); spc=spectral_constraints(sum(correlate(temp.traces,temp.traces),2),nsampw); clear temp spc=spc/norm(spc,'fro'); if param.dc_constraint ~= 0 % Add DC constraint matrix spc(1,:)=spc(1,:)*(1+abs(param.dc_constraint/param.sp_constraint)); end constraint=param.sp_constraint;elseif param.dc_constraint ~= 0 % Create DC constraint matrix spc=ones(1,nsampw)/sqrt(nsampw); constraint=param.dc_constraint;else constraint=0; spc=[]; endif iscell(param.wavshifts) increment=round(param.wavshifts{2}/seismic.step);else increment=round(param.wavshifts(2)/seismic.step);endik=0; % keyboardfor lshift=logshifts ik=ik+1; disp([' Shift: ',num2str(lshift),' (',num2str(ik),' of ',num2str(length(logshifts)),')']) seismic_ta=refl.first+lshift+param.wavshifts(1)+param.wlength*0.5; ia0=round((seismic_ta-seismic.first)/seismic.step); ia=ia0+1; iawav0=iawav; ie=ia+nseiswindow; ia=max(1,ia); ia_refl=1; ie_refl=nlogwindow; % for ii=1:nlogsegments if ia > 0 & ie <= nsamp s1=refl.traces(ia_refl:ie_refl,:); s2=seismic.traces(ia:ie,:); [filters,cc,shift,scale]=mfilter_t2d(s1,s2, ... nsampw,param.wnoise,increment,constraint,spc); if scaling wavelets(:,iawav:iewav)=filters*spdiags(scale,0,length(scale),length(scale)); else wavelets(:,iawav:iewav)=filters; end headers(1,iawav:iewav)=cc(:)'; headers(4,iawav:iewav)=seismic.first+((ia-1)+shift(:)')*seismic.step; headers(5,iawav:iewav)=refl.first+ia_refl+refl.step; shifts(iawav:iewav)=shift+ia0; else % Not enough seismic data for a requested shift nulls=1; end if exist('seismic_headers','var') headers(6:end,iawav:iewav)=seismic_headers; % Store seimic headers end ia_refl=ia_refl+ndownstep; ie_refl=ie_refl+ndownstep; ia=ia+ndownstep; ie=ie+ndownstep; iawav=iawav+ntr; iewav=iewav+ntr; end% Compute maximum and median correlation coefficient for each trace temp=reshape(headers(1,iawav0:iewav-ntr),ntr,nlogsegments); temp_max=max(temp,[],2); if nulls temp_median=NaN*zeros(size(temp,1),1); for ll=1:size(temp,1) idx=find(~isnan(temp(ll,:))); if ~isempty(idx) temp_median(ll)=median(temp(ll,idx)); end end else temp_median=median(temp,2); end headers(2,iawav0:iewav-ntr)= ... reshape(temp_max(:,ones(nlogsegments,1)),1,nlogsegments*ntr); headers(3,iawav0:iewav-ntr)= ... reshape(temp_median(:,ones(nlogsegments,1)),1,nlogsegments*ntr);endidx=find(~isnan(shifts))';min_shift=min(shifts(idx));shifts(idx)=shifts(idx)-min_shift;max_shift=max(shifts(idx)); trywavelet.type='seismic';wavelet.tag='wavelet';wavelet.name='';wavelet.traces=param.null*zeros(nsampw+max_shift,nwavelets); catchdisp(' Not enough space in MATLAB to store all requires wavelets') %keyboard endfor ii=idx wavelet.traces(shifts(ii)+1:shifts(ii)+nsampw,ii)=wavelets(:,ii);endwavelet.first=seismic.first-refl.first+(min_shift-nsampw)*seismic.step;wavelet.last=wavelet.first+(nsampw+max_shift-1)*seismic.step;wavelet.step=seismic.step;wavelet.units=seismic.units;if (nulls | max_shift > 0) & isnan(param.null) wavelet.null=NaN;endif isfield(wavelet,'headers') wavelet.headers=[wavelet.headers;headers]; wavelet.header_info=[wavelet.header_info;header_info];else wavelet.headers=headers; wavelet.header_info=header_info;endif isfield(seismic,'history') & isfield(refl,'history') wavelet.history=seismic.history; wavelet=s_history(wavelet,'append',' '); wavelet=s_history(wavelet,'merge',refl.history);endABORTED=logical(0);%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function matrix=spectral_constraints(ac,ncol)% Function creates a matrix which imposes a spectral constraint on on the solution % of a linear system of equations% INPUT% ac autocorrelation of a function with the desired spectral shape% ac must be symmetric and have at least ncol samples; % the number of samples is odd% ncol number of columns/rows of the spectral constraint matrix% % OUTPUT% matrix constraint matrix% matrix=spectral_constraints(ac,ncol)nac=length(ac);nc=(nac+1)/2;if mod(ncol,2) ncolh=(ncol-1)/2; fac=fft(ac(nc-ncolh:nc+ncolh)); fac=sqrt(sqrt(abs(fac))); fac=1./(fac+0.01*max(fac)); tempm=fac(1:ncolh+1,ones(1,ncol)).*ftmatrix(ncolh+1,ncol); matrix=[real(tempm);imag(tempm(2:end,:))];else ncolh=ncol/2-1; fac=fft(ac(nc-ncolh:nc+ncolh),ncol); fac=sqrt(sqrt(abs(fac))); fac=1./(fac+0.01*max(fac)); tempm=fac(1:ncolh+2,ones(1,ncol)).*ftmatrix(ncolh+2,ncol); matrix=[real(tempm);imag(tempm(2:end-1,:))];end% matrix=matrix/norm(matrix,'fro');
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -