diff --git a/algorithms/angle_stks_from_gath/angle_stks_from_gath.m b/algorithms/angle_stks_from_gath/angle_stks_from_gath.m new file mode 100644 index 0000000..f69104d --- /dev/null +++ b/algorithms/angle_stks_from_gath/angle_stks_from_gath.m @@ -0,0 +1,211 @@ +function [] = angle_stks_from_gath(job_meta_path,i_block,startvol,volinc,endvol,angwidth,tottracerun) +% +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +%% Parameters +% would normaly convert all parameters to double, but keep i_block as string as being passed to +% other modules; it does happen at the bottom of this program for output +%i_block = str2double(i_block); +% +% angle trace data ranges to use, vol is an angle trace either as a +% seperate angle volume or as a angle trace in an angle gather +% number of the first angle trace/volume to read +startvol = str2double(startvol); +% angle trace/volume increment +volinc = str2double(volinc); +% number of the last angle trace/volume to read +%endvol = job_meta.nvols; +endvol = str2double(endvol); +angwidth = str2double(angwidth); + +% number of traces to run, put to zero to make it run all traces in the +% block, this is the default, this is also used to pass an inline (pkey +% number to use in testing has to be ilnnnn format +useselectemode = 0; + +origstart_vol = startvol; +orig_endvol = endvol; +ebdichdr = ['segy io']; + +if isempty(regexp(tottracerun,'il','once')) == 0 + useselectemode = 1; + requiredinline = str2double(regexprep(tottracerun,'il','')); + %requiredinline = str2double(strrep(tottracerun,'il','')); + tottracerun = 0; +else + tottracerun = str2double(tottracerun); +end +% tottracerun = 500; + + + + +% to reduce printout in compilied version turned all warning off +warning off all; + +% end of parameters +%##################################################################### +% +% total number of volumes to load +totalvol = length(startvol:volinc:endvol); +droptraces = 1; +% +% Load job meta information +job_meta = load(job_meta_path); +% +% if tottracerun == 0 +% ebdichdr = ['segy io']; +% if useselectemode == 1; +% testdiscpt = ['gathers_segy_io_',num2str(startvol),'_',num2str(volinc),'_',num2str(endvol)]; +% else +% testdiscpt = ['gathers_segy_io_',num2str(startvol),'_',num2str(volinc),'_',num2str(endvol)]; +% end +% else +% ebdichdr = ['segy io']; +% if useselectemode == 1; +% testdiscpt = ['gathers_segy_io_',num2str(startvol),'_',num2str(volinc),'_',num2str(endvol)]; +% else +% testdiscpt = ['gathers_segy_io_',num2str(startvol),'_',num2str(volinc),'_',num2str(endvol)]; +% end +% end + +% add the history of jobs run and this one to the curent ebcdic +if isfield(job_meta,'comm_history') + ebdichdr2 = job_meta.comm_history; + tmpebc = ebdichdr2{size(ebdichdr2,1),2}; +else + ebdichdr2{1,2} = ''; + tmpebc = ''; +end + +for ebcii = (size(ebdichdr2,1)-1):-1:1 + tmpebcc = regexp(ebdichdr2{ebcii,2},'/','split'); + tmpebc = [tmpebc tmpebcc{1} tmpebcc{end}]; +end +tmpebc = sprintf('%-3200.3200s',tmpebc); +clear tmpebcc ebdichdr2; +% +% Make ouput directories and create meta information +%fprintf('reading data for total volumes = %d\n',totalvol) +% +% read data to pick a water bottom on, this does not need to happen and then +% be ignored, should happen later after reading all the volumes +% + +% read all the data for this block +% node_segy_read(job_meta_path,vol_index,i_block) +[~, vol_traces, ilxl_read, offset_read] = node_segy_read(job_meta_path,'1',i_block); +% find the total number of offsets +offset = unique(offset_read); + + +if droptraces == 1 + % % reshape the gather array to the same 3d matrix as the angle volumes and + % drop as required + nsamps = size(vol_traces,1); + fold = length(offset); + vol_traces = reshape(vol_traces,nsamps,fold,[]); + % grab the actual angles from the gather to pick the correct indicies + startvol = find(offset == startvol,1); + endvol = find(offset == endvol,1); + + % resize the ilxl data + tmp_ilxlrd = ilxl_read(1:length(offset):end,:); + ilxl_read = tmp_ilxlrd; + clear tmp_ilxlrd; + + %resize the offset header - no need as stacking + %offset_read = offset_read(:,(startvol:volinc:endvol),:); + + % now loop round making however many angle gathers are requested + aidx = 1; + for kk = startvol:angwidth:endvol + % resize the traces data + vol_tracestmp = vol_traces(:,(kk:volinc:(kk+(angwidth-volinc))),:); + kdsb = zeros(size(vol_tracestmp,1),size(vol_tracestmp,3)); + for ii = 1:size(vol_tracestmp,3) + kds = vol_tracestmp(:,:,ii); + kdsb(:,ii) = sum((kds ~= 0),2); + end + % sum the gather and divide by live samples + %make logical of what is not zero and cumlatively sum it to get the fold + + angle_stk{aidx} = squeeze(sum(vol_tracestmp,2)) ./ kdsb; + angle_stk{aidx}(isnan(angle_stk{aidx})) = 0; + %figure(3); imagesc(angle_stk{aidx}); colormap(gray); + aidx = aidx +1; + clear kdsb + end +end + +i_block = str2double(i_block); + +%% Save results +aidx = 1; +for kk = origstart_vol:angwidth:orig_endvol + + + resultno = 1; + % Save outputs into correct structure to be written to SEGY. + results_out{resultno,1} = 'Meta data for output files'; + results_out{resultno,2}{1,1} = ilxl_read; + results_out{resultno,3} = 'is_gather'; % 1 is yes, 0 is no + results_out{resultno,2}{2,1} = uint32(zeros(size(angle_stk{aidx},2),1)); + %was written as uint32(zeros(ntraces,1)); + %results_out{resultno,2}{2,1} = offset_read'; + + ebcstrtowrite = sprintf('%-3200.3200s',[results_out{resultno,1} ' ' ebdichdr ' ' tmpebc]); + results_out{resultno,1} = ebcstrtowrite; + + resultno = resultno + 1; + + % correct file names added by SRW - 02/07/14 + +% if kk == startvol +% testdiscpt = ['gathers_segy_io_',num2str(origstart_vol),'_',num2str(volinc),'_',num2str(origstart_vol+angwidth)]; +% else + testdiscpt = ['angle_stk_range_',num2str(kk),'_',num2str((kk+(angwidth-volinc)))]; +% end + + results_out{resultno,1} = strcat(testdiscpt); + %results_out{2,2} = digi_intercept; + results_out{resultno,2} = angle_stk{aidx}; + results_out{resultno,3} = 0; + aidx = aidx +1; + + % check segy write functions - many different versions now! + if exist(strcat(job_meta.output_dir,'bg_angle_stks/'),'dir') == 0 + output_dir = strcat(job_meta.output_dir,'bg_angle_stks/'); + mkdir(output_dir); + else + output_dir = strcat(job_meta.output_dir,'bg_angle_stks/'); + end + + + node_segy_write(results_out,i_block,job_meta.s_rate/1000,output_dir) + +end + +end + + diff --git a/algorithms/angle_stks_from_gath/angle_stks_from_gath.m~ b/algorithms/angle_stks_from_gath/angle_stks_from_gath.m~ new file mode 100644 index 0000000..1379890 --- /dev/null +++ b/algorithms/angle_stks_from_gath/angle_stks_from_gath.m~ @@ -0,0 +1,191 @@ +function [] = angle_stks_from_gath(job_meta_path,i_block,startvol,volinc,endvol,angwidth,tottracerun) +% ------------------------------------------------------------------------- +% Authors: Charles Jones +% ------------------------------------------------------------------------- +%% Parameters +% would normaly convert all parameters to double, but keep i_block as string as being passed to +% other modules; it does happen at the bottom of this program for output +%i_block = str2double(i_block); +% +% angle trace data ranges to use, vol is an angle trace either as a +% seperate angle volume or as a angle trace in an angle gather +% number of the first angle trace/volume to read +startvol = str2double(startvol); +% angle trace/volume increment +volinc = str2double(volinc); +% number of the last angle trace/volume to read +%endvol = job_meta.nvols; +endvol = str2double(endvol); +angwidth = str2double(angwidth); + +% number of traces to run, put to zero to make it run all traces in the +% block, this is the default, this is also used to pass an inline (pkey +% number to use in testing has to be ilnnnn format +useselectemode = 0; + +origstart_vol = startvol; +orig_endvol = endvol; +ebdichdr = ['segy io']; + +if isempty(regexp(tottracerun,'il','once')) == 0 + useselectemode = 1; + requiredinline = str2double(regexprep(tottracerun,'il','')); + %requiredinline = str2double(strrep(tottracerun,'il','')); + tottracerun = 0; +else + tottracerun = str2double(tottracerun); +end +% tottracerun = 500; + + + + +% to reduce printout in compilied version turned all warning off +warning off all; + +% end of parameters +%##################################################################### +% +% total number of volumes to load +totalvol = length(startvol:volinc:endvol); +droptraces = 1; +% +% Load job meta information +job_meta = load(job_meta_path); +% +% if tottracerun == 0 +% ebdichdr = ['segy io']; +% if useselectemode == 1; +% testdiscpt = ['gathers_segy_io_',num2str(startvol),'_',num2str(volinc),'_',num2str(endvol)]; +% else +% testdiscpt = ['gathers_segy_io_',num2str(startvol),'_',num2str(volinc),'_',num2str(endvol)]; +% end +% else +% ebdichdr = ['segy io']; +% if useselectemode == 1; +% testdiscpt = ['gathers_segy_io_',num2str(startvol),'_',num2str(volinc),'_',num2str(endvol)]; +% else +% testdiscpt = ['gathers_segy_io_',num2str(startvol),'_',num2str(volinc),'_',num2str(endvol)]; +% end +% end + +% add the history of jobs run and this one to the curent ebcdic +if isfield(job_meta,'comm_history') + ebdichdr2 = job_meta.comm_history; + tmpebc = ebdichdr2{size(ebdichdr2,1),2}; +else + ebdichdr2{1,2} = ''; + tmpebc = ''; +end + +for ebcii = (size(ebdichdr2,1)-1):-1:1 + tmpebcc = regexp(ebdichdr2{ebcii,2},'/','split'); + tmpebc = [tmpebc tmpebcc{1} tmpebcc{end}]; +end +tmpebc = sprintf('%-3200.3200s',tmpebc); +clear tmpebcc ebdichdr2; +% +% Make ouput directories and create meta information +%fprintf('reading data for total volumes = %d\n',totalvol) +% +% read data to pick a water bottom on, this does not need to happen and then +% be ignored, should happen later after reading all the volumes +% + +% read all the data for this block +% node_segy_read(job_meta_path,vol_index,i_block) +[~, vol_traces, ilxl_read, offset_read] = node_segy_read(job_meta_path,'1',i_block); +% find the total number of offsets +offset = unique(offset_read); + + +if droptraces == 1 + % % reshape the gather array to the same 3d matrix as the angle volumes and + % drop as required + nsamps = size(vol_traces,1); + fold = length(offset); + vol_traces = reshape(vol_traces,nsamps,fold,[]); + % grab the actual angles from the gather to pick the correct indicies + startvol = find(offset == startvol,1); + endvol = find(offset == endvol,1); + + % resize the ilxl data + tmp_ilxlrd = ilxl_read(1:length(offset):end,:); + ilxl_read = tmp_ilxlrd; + clear tmp_ilxlrd; + + %resize the offset header - no need as stacking + %offset_read = offset_read(:,(startvol:volinc:endvol),:); + + % now loop round making however many angle gathers are requested + aidx = 1; + for kk = startvol:angwidth:endvol + % resize the traces data + vol_tracestmp = vol_traces(:,(kk:volinc:(kk+(angwidth-volinc))),:); + kdsb = zeros(size(vol_tracestmp,1),size(vol_tracestmp,3)); + for ii = 1:size(vol_tracestmp,3) + kds = vol_tracestmp(:,:,ii); + kdsb(:,ii) = sum((kds ~= 0),2); + end + % sum the gather and divide by live samples + %make logical of what is not zero and cumlatively sum it to get the fold + + angle_stk{aidx} = squeeze(sum(vol_tracestmp,2)) ./ kdsb; + angle_stk{aidx}(isnan(angle_stk{aidx})) = 0; + %figure(3); imagesc(angle_stk{aidx}); colormap(gray); + aidx = aidx +1; + clear kdsb + end +end + +i_block = str2double(i_block); + +%% Save results +aidx = 1; +for kk = origstart_vol:angwidth:orig_endvol + + + resultno = 1; + % Save outputs into correct structure to be written to SEGY. + results_out{resultno,1} = 'Meta data for output files'; + results_out{resultno,2}{1,1} = ilxl_read; + results_out{resultno,3} = 'is_gather'; % 1 is yes, 0 is no + results_out{resultno,2}{2,1} = uint32(zeros(size(angle_stk{aidx},2),1)); + %was written as uint32(zeros(ntraces,1)); + %results_out{resultno,2}{2,1} = offset_read'; + + ebcstrtowrite = sprintf('%-3200.3200s',[results_out{resultno,1} ' ' ebdichdr ' ' tmpebc]); + results_out{resultno,1} = ebcstrtowrite; + + resultno = resultno + 1; + + % correct file names added by SRW - 02/07/14 + +% if kk == startvol +% testdiscpt = ['gathers_segy_io_',num2str(origstart_vol),'_',num2str(volinc),'_',num2str(origstart_vol+angwidth)]; +% else + testdiscpt = ['angle_stk_range_',num2str(kk),'_',num2str((kk+(angwidth-volinc)))]; +% end + + results_out{resultno,1} = strcat(testdiscpt); + %results_out{2,2} = digi_intercept; + results_out{resultno,2} = angle_stk{aidx}; + results_out{resultno,3} = 0; + aidx = aidx +1; + + % check segy write functions - many different versions now! + if exist(strcat(job_meta.output_dir,'bg_angle_stks/'),'dir') == 0 + output_dir = strcat(job_meta.output_dir,'bg_angle_stks/'); + mkdir(output_dir); + else + output_dir = strcat(job_meta.output_dir,'bg_angle_stks/'); + end + + + node_segy_write(results_out,i_block,job_meta.s_rate/1000,output_dir) + +end + +end + + diff --git a/algorithms/bandpass_filter/bandpass_filter.m b/algorithms/bandpass_filter/bandpass_filter.m new file mode 100644 index 0000000..32d44a4 --- /dev/null +++ b/algorithms/bandpass_filter/bandpass_filter.m @@ -0,0 +1,82 @@ +function [o] = bandpass_filter(d,dt,f1,f2,f3,f4); +%BP_Filter: Apply a band-pass filter to a group of traces. +% +% [o] = bp_filter(d,dt,f1,f2,f3,f4); +% +% IN d: data (columns are traces) +% dt: sampling interval in sec +% f1: freq. in Hz +% f2: freq. in Hz +% f3: freq. in Hz +% f4: freq. in Hz +% +% ^ +% | ___________ +% | / \ Amplitude spectrum +% | / \ +% | / \ +% |------------------------> +% f1 f2 f3 f4 +% +% OUT o: output (columns are traces) +% +% Example: +% +% d=linear_events; +% dout = bp_filter(d,0.004,1,3,30,40); +% wigb([d,dout]); +% +% Copyright (C) 2008, Signal Analysis and Imaging Group +% For more information: http://www-geo.phys.ualberta.ca/saig/SeismicLab +% Author: M.D.Sacchi +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published +% by the Free Software Foundation, either version 3 of the License, or +% any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details: http://www.gnu.org/licenses/ +% +% modifications made to the tapers in freq and made to vectorise with +% bsxfun + + + [nt,nx] = size(d); % Calculate the size of the data + k = nextpow2(nt); % Calculate the smallest power of two greater than or equal to the total number of samples ina trace + nf = 4*(2^k); % Design Length of the filter + + i1 = floor(nf*f1*dt)+1; % Index of f1 in filter + i2 = floor(nf*f2*dt)+1; % Index of f2 in filter + i3 = floor(nf*f3*dt)+1; % Index of f3 in filter + i4 = floor(nf*f4*dt)+1; % Index of f4 in filter + + %up = (1:1:(i2-i1))/(i2-i1); % Design the filter taper ramp up + up = ((sin(linspace((-(pi*0.87)/2),((pi)/2),(i2-i1))')+1)/2)'; + %down = (i4-i3:-1:1)/(i4-i3); % Design the filter taper ramp down + down = ((sin(linspace(((pi)/2),(-(pi*0.87)/2),(i4-i3))')+1)/2)'; + aux = [zeros(1,i1), up, ones(1,i3-i2), down, zeros(1,nf/2+1-i4) ]; % Design the whole filter joining the bits + aux2 = fliplr(aux(1,2:nf/2)); % Flip the filter + + c = 0; % zero phase (could apply rotations as well) + F = ([aux,aux2]'); + Phase = (pi/180.)*[0.,-c*ones(1,nf/2-1),0.,c*ones(1,nf/2-1)]; % Phase spectrum + Transfer = F.*exp(-1i*Phase'); + + + D = fft(d,nf,1); + +% for k = 1:nx +% Do(:,k) = Transfer.*D(:,k); +% end + + Do(:,:) = bsxfun(@times,D(:,:),Transfer); + + + o = ifft(Do,nf,1); + + o = real(o(1:nt,:)); + + diff --git a/algorithms/int_grad_inv_proj/int_grad_inv_proj.m b/algorithms/int_grad_inv_proj/int_grad_inv_proj.m new file mode 100644 index 0000000..4b344e0 --- /dev/null +++ b/algorithms/int_grad_inv_proj/int_grad_inv_proj.m @@ -0,0 +1,980 @@ +function [] = int_grad_inv_proj(job_meta_path,i_block,startvol,volinc,endvol,tottracerun,maxzout,wavevar) +% +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% INT_GRAD_INV_PROJ: function to run Intercept Gradient Inversion using +% dynamic wavelet set. +% Inputs: +% job_mat_path = path of metadata .mat file. +% i_block = current block to be processed. +% startvol = number of the first angle trace/volume to read +% volinc = angle trace/volume increment +% endvol = number of the last angle trace/volume to read +% tottracerun = number of traces to output, 0 = all, and il1234 would +% only output inline 1234 +% maxzout = To be given in samples if this is initialized as 0 this will be +% converted to the maximum number of samples in the volume +% wavevar = Flag 1: for spatially varying wavelet, Flag 0: for +% spatially stationary wavelet + +% Outputs: +% digi_intercept SEGY files. +% digi_gradient SEGY files. +% digi_minimum_energy_eer_projection SEGY files. +% +% ------------------------------------------------------------------------- +%% Parameters +% would normaly convert all parameters to double, but keep i_block as string as being passed to +% other modules; it does happen at the bottom of this program for output +%i_block = str2double(i_block); +% +% angle trace data ranges to use, vol is an angle trace either as a +% seperate angle volume or as a angle trace in an angle gather + +startvol = str2double(startvol); % number of the first angle trace/volume to read +volinc = str2double(volinc); % angle trace/volume increment +%endvol = job_meta.nvols; +endvol = str2double(endvol); % number of the last angle trace/volume to read + +% number of traces to run, put to zero to make it run all traces in the +% block, this is the default, this is also used to pass an inline (pkey +% number to use in testing has to be ilnnnn format +useselectemode = 0; + +if isempty(regexp(tottracerun,'il','once')) == 0 + useselectemode = 1; + requiredinline = str2double(regexprep(tottracerun,'il','')); + %requiredinline = str2double(strrep(tottracerun,'il','')); + tottracerun = 0; +else + tottracerun = str2double(tottracerun); +end +% tottracerun = 500; +%maxzout = 8000; +maxzout = str2double(maxzout); + +output_std = 0; % do you want to calculate and output standard line fitting intercept and gradient and eer +plot_on = 0; % do you want interactive plots to pop up when running (just for debug) + +% do you want to have a background starting model, default 0 is all zeros, +% setting this to value 1 uses standard line fitting to make a background +% model; lsq seems to reach the same answer with any model , did try random +% numbers and no difference in result just more iterations required +background = 0; +needconf = 0; % do you want a confidence volume calculating and outputing, 0 = no , 1 = yes +noofreports = 20; % how many % progress reports do you want in the running of the job, 5 = 20% increment for reporting +chi_model_type = 'empirical'; % what is the chi model that you want for the eer... + % ...empirical is 19 degrees with 1 degree increase per km or second + +% Tikhonov regularisation weight, 1 = little smoothing, 10 = moderate, +% 100 = smooth, 1000 = very smooth +%wsmooth = 7000; uruguay gathers +%wsmooth = 10; tza angle gathers +%wsmooth = str2double(wsmooth); + +eer_weight = 0.1; % Weight for EER constraint between 0 and 1, value of 1 forces it much closer to the intercept values +iter = 300; % maximum number of iterations in the lsq solver - normally 300 +tol = 1e-3; % convergence tolerance in the lsq solver can move to tol = 5e-4 or 1e-4.....but larger value speeds it up as less iterations to run +%tol = 8e-4; +padding = 64; % water bottom pick padding +extrapad = 0; % extra padding to top of dataset, this many samples will get zeroed below the wb +%extrapad = (floor(extrapad/32))*32; +use_spatial_wavelets = wavevar; % FLag 1 for using spatial wavelets + +warning off all; % to reduce printout in compilied version turned all warning off + +relfreq = 6; % frequency to taper down below in hz, it is a sine taper so gentle ramp off, so can be a bit higher than expected, ie 6 cuts in at 4.5Hz +lowfreqtaperstart = 6; % Hz to start tapering the wavelet down from to 0 hz +wsmo_scal = 5; % scaler to make the weighting in the tikonov regularisation , normally set to 5 * the std dev of the amplitudes of the input data as measured + % in the wavelet estimation code + +% end of parameters +%% +% set initial variables +totalvol = length(startvol:volinc:endvol); % Total number of volumes to load +job_meta = load(job_meta_path); % Load job meta information +wsmooth = job_meta.stdev_smo(str2double(i_block))*wsmo_scal; % Get stdev for this block from the mat file +topfreq = 500000/job_meta.s_rate; +top3dpt = topfreq*0.72; +% +if tottracerun == 0 + eer_weight_out = num2str((eer_weight*1000)); + %eer_weight_out = regexprep(eer_weight_out, '0.', ''); + tol_out = num2str((tol*10000)); + %tol_out = regexprep(tol_out, '0.', ''); + + ebdichdr = ['digi parameters: wsmooth ',num2str(wsmooth),' eer_weight ',num2str(eer_weight_out),' tolr ',tol_out]; + if useselectemode == 1; + testdiscpt = ['_w_tolrt1e3__eer_weight_',num2str(eer_weight_out),'_il',num2str(requiredinline),'_range_',num2str(startvol),'_',num2str(volinc),'_',num2str(endvol)]; + else + testdiscpt = ['_w_range_',num2str(startvol),'_',num2str(volinc),'_',num2str(endvol)]; + end +else + eer_weight_out = num2str((eer_weight*1000)); + %eer_weight_out = regexprep(eer_weight_out, '0.', ''); + tol_out = num2str((tol*10000)); + %tol_out = regexprep(tol_out, '0.', ''); + testdiscpt = [date,'_w_tolrt1e3__eer_weight_',num2str(eer_weight_out),'_range_p',num2str(startvol),'_',num2str(volinc),'_',num2str(endvol)]; + ebdichdr = ['digi parameters: wsmooth ',num2str(wsmooth),' eer_weight ',num2str(eer_weight_out),' tolr ',tol_out]; +end + +% add the history of jobs run and this one to the curent ebcdic +if isfield(job_meta,'comm_history') + ebdichdr2 = job_meta.comm_history; + tmpebc = ebdichdr2{size(ebdichdr2,1),2}; +else + ebdichdr2{1,2} = ''; + tmpebc = ''; +end + +for ebcii = (size(ebdichdr2,1)-1):-1:1 + tmpebcc = regexp(ebdichdr2{ebcii,2},'/','split'); + tmpebc = [tmpebc tmpebcc{1} tmpebcc{end}]; +end +tmpebc = sprintf('%-3200.3200s',tmpebc); +clear tmpebcc ebdichdr2; + +fprintf('reading data for total volumes = %d\n',totalvol) % Make ouput directories and create meta information + +% set maxzout if set to 0 on the command line +if maxzout == 0 + maxzout = job_meta.n_samples{1}; % maxzout set yo maximum number of samples +end +%% +%========================================================================================================================== +% read data to find data to pick a water bottom on +vol_index_wb = 1; +if job_meta.is_gather == 0 + pick_wb_ind = ceil(job_meta.nvols*0.6667); + + [~, traces{vol_index_wb}, ilxl_read{vol_index_wb}] = node_segy_read(job_meta_path,num2str(pick_wb_ind),i_block); + % check to make sure it read something if not exit + if size(traces{vol_index_wb},1) == 1 && size(traces{vol_index_wb},2) == 1 + return + end + traces{vol_index_wb} = traces{vol_index_wb}(1:maxzout,:); + n_samples_fullz = job_meta.n_samples{1}; + job_meta.n_samples{1} = maxzout; +else + + + % find the water bottom on a few gathers and take the middle one t use + % as an offset plane to pick the water bottom on + + % read all the data for this block + % node_segy_read(job_meta_path,vol_index,i_block) + [~, vol_traces, ilxl_read{vol_index_wb}, offset_read] = node_segy_read(job_meta_path,'1',i_block); + vol_traces = vol_traces(1:maxzout,:); % truncate data to make z axis number + job_meta.n_samples{1} = maxzout; % Write max zout in job meta file + offset = unique(offset_read); % find the total number of offsets + %#############for lobster TRN limit offset to 40 and rerun for failed + %blocks################################################################### + + if isempty(vol_traces) == 1 && isempty(ilxl_read) == 1 && isempty(offset_read) == 1 + return + end + %juststack = 1; + %if juststack == 1 + traces{vol_index_wb} = zeros(size(vol_traces,1),size(vol_traces,2)/size(offset,2)); + for stki = 1:size(offset,2) + traces{vol_index_wb} = traces{vol_index_wb} + vol_traces(:,offset_read == offset(stki)); + end + + pick_wb_ind = job_meta.live_offset_avg; + +% % should reshape and sum instead of this terrible loop +% %else +% +% %read the middle 5 gathers in the input data to find the middle tkey(angle/offset) value of the water bottom +% %tracestest{vol_index_wb} = vol_traces(:,(floor(size(vol_traces,2)/2)-(length(offset)*2)):(floor(size(vol_traces,2)/2)+(length(offset)*2))); +% tracestest{vol_index_wb} = vol_traces(:,(floor(size(vol_traces,2)/2)-(length(offset)*2.5)+2):(floor(size(vol_traces,2)/2)+(length(offset)*2.5))); +% tmpoffread = offset_read((floor(size(vol_traces,2)/2)-(length(offset)*2.5)+2):(floor(size(vol_traces,2)/2)+(length(offset)*2.5))); +% %pick the water bottom +% %pick the water bottom +% [wb_idxcj] = water_bottom_picker(tracestest{vol_index_wb}(:,:),0); +% %filter the water bottom pick to make a difference in WB time for +% %traces that are not picking the wb +% filtw = [1 2 3 2 1]/9; +% wb_idxcjfilt = conv(wb_idxcj,filtw,'same'); +% % now make a blank array the size of the wb index array +% wb_idxcj2 = zeros(1,size(wb_idxcj,2)); +% %now find the difference between the values of the filtered and +% %unfiltered water bottom indexes, if there is a difference then it is +% %likely to not be the water bottom as it should be mostly flat on the +% %gathers +% wb_idx_diff_ck = abs((wb_idxcj./wb_idxcjfilt)-1); +% wb_idxcj2(wb_idx_diff_ck < 0.009) = wb_idxcj(wb_idx_diff_ck < 0.009); +% +% %now work out the index locations of the water bottom +% wb_idx_index = 1:1:size(wb_idxcj,2); +% %apply a logical index to the index array to give the index of where the wb is picked and less then 10 elsewhere +% wb_idx_index(ismember(wb_idxcj2,floor((min(wb_idxcj2((wb_idxcj2 > 10)))*0.9)):1:ceil((min(wb_idxcj2((wb_idxcj2 > 10)))*1.1)))); +% % select the angles with the wb on +% tmpwbangs = (tmpoffread(wb_idx_index(ismember(wb_idxcj2,floor((min(wb_idxcj2((wb_idxcj2 > 10)))*0.9)):1:ceil((min(wb_idxcj2((wb_idxcj2 > 10)))*1.1)))))); +% tmpangpickstd = ceil(std(double(tmpwbangs))); +% tmpangpick = floor(mean(tmpwbangs)); +% %tmpangpick = floor(mean(tmpoffread(wb_idx_index(ismember(wb_idxcj2,floor((min(wb_idxcj2((wb_idxcj2 > 10)))*0.9)):1:ceil((min(wb_idxcj2((wb_idxcj2 > 10)))*1.1))))))); +% pick_wb_ind = find(offset == tmpangpick); +% +% clear tracestest offset_read; +% +% +% % [wb_idxcj] = water_bottom_picker(traces{vol_index_wb}(:,:),0); +% % +% % %pick the water bottom +% % [wb_idxcj] = water_bottom_picker(tracestest{vol_index_wb}(:,:),0); +% % %filter the water bottom pick to make a difference in WB time for +% % %traces that are not picking the wb +% % filtw = [1 2 3 2 1]/9; +% % wb_idxcjfilt = conv(wb_idxcj,filtw,'same'); +% % % now make a blank array the size of the wb index array +% % wb_idxcj2 = zeros(1,size(wb_idxcj,2)); +% % %now find the difference between the values of the filtered and +% % %unfiltered water bottom indexes, if there is a difference then it is +% % %likely to not be the water bottom as it should be mostly flat on the +% % %gathers +% % wb_idx_diff_ck = abs((wb_idxcj./wb_idxcjfilt)-1); +% % wb_idxcj2(wb_idx_diff_ck < 0.005) = wb_idxcj(wb_idx_diff_ck < 0.005); +% % +% % %now work out the index locations of the water bottom +% % wb_idx_index = 1:1:size(wb_idxcj,2); +% % %apply a logical index to the index array to give the index of where the wb is picked and less then 10 elsewhere +% % wb_idx_index(wb_idxcj2 == min(wb_idxcj2((wb_idxcj2 > 10)))); +% % % calculate the gather index in each gather by removing the integer +% % % number of gathers from the index number and putting back to all being +% % % the same angle index in each gather ie 1-46,1-46,1-46 etc... and +% % % findingf the average value of all the indexes +% % pick_wb_ind = floor(mean(((wb_idx_index(wb_idxcj2 == min(wb_idxcj2((wb_idxcj2 > 10)))))/length(offset) - floor((wb_idx_index(wb_idxcj2 == min(wb_idxcj2((wb_idxcj2 > 10)))))/length(offset)))*length(offset))); +% % %read the offset plane from the input data gathers. +% % %traces{vol_index_wb} = vol_traces(:,offset_read == offset(pick_wb_ind)); + + + %end +end + + +% pkey_inc_mode = mode(job_meta.pkey_inc); +% skey_inc_mode = mode(job_meta.skey_inc); +% +% n_iline = (ilxl_read{vol_index_wb}(:,1)-min(ilxl_read{vol_index_wb}(:,1)))/pkey_inc_mode+1; +% n_xline = (ilxl_read{vol_index_wb}(:,2)-min(ilxl_read{vol_index_wb}(:,2)))/skey_inc_mode+1; +% skeyn = (max(ilxl_read{vol_index_wb}(:,2))-min(ilxl_read{vol_index_wb}(:,2)))/skey_inc_mode+1; +% pkeyn = (max(ilxl_read{vol_index_wb}(:,1))-min(ilxl_read{vol_index_wb}(:,1)))/pkey_inc_mode+1; +% lin_ind = ((n_iline-1).*skeyn)+n_xline; + +%========================================================================================================================== +% Pick water bottom or use a pre picked water bottom horizon +if isfield(job_meta, 'wb_path') + %wb_idx = dlmread(job_meta.wb_path,'delimiter','\t'); + wb_idx_in = dlmread(job_meta.wb_path); + wb_idx_in = sortrows(wb_idx_in,[1 2]); + % col 1 inline + % col 2 xline + % col 3 twt + [~,locations] = ismember(ilxl_read{1}(1:end,:),wb_idx_in(:,1:2),'rows'); + %wb_idx = zeros(size(traces{vol_index_wb},2),1); + zero_loc = locations ~= 0; + %wb_idx + zero_loc = wb_idx_in(locations(zero_loc),3); + xi = (1:size(traces{vol_index_wb},2))'; + x = xi(zero_loc)'; + wb_idx = interp1(x,wb_idx_in(locations(zero_loc),3),xi); + clear wb_idx_in + %min_il = min(ilxl_read{vol_index_wb}(:,1)); + %max_il = max(ilxl_read{vol_index_wb}(:,1)); + %min_xl = min(ilxl_read{vol_index_wb}(:,2)); + %max_xl = max(ilxl_read{vol_index_wb}(:,2)); + %wb_idx2 = wb_idx(wb_idx(:,1) >= min_il & wb_idx(:,1) <= max_il & wb_idx(:,2) >= min_xl & wb_idx(:,2) <= max_xl,:); + % wb_idx = wb_idx(wb_idx(:,1) >= min_il & wb_idx(:,1) <= (max_il+1) & wb_idx(:,2) >= min_xl & wb_idx(:,2) <= (max_xl+1),:); + % wb_idx(:,3) = wb_idx(:,3)./(job_meta.s_rate/1000); + wb_idx = (wb_idx./(job_meta.s_rate/1000))'; + + wb_idx = round(wb_idx-padding); + win_sub = bsxfun(@plus,wb_idx,(0:job_meta.n_samples{vol_index_wb}-max(wb_idx))'); + + win_ind = bsxfun(@plus,win_sub,(0:job_meta.n_samples{vol_index_wb}:... + job_meta.n_samples{vol_index_wb}*(size(traces{vol_index_wb},2)-1))); +else + [wb_idx] = water_bottom_picker(traces{vol_index_wb},padding); + wb_idx(wb_idx < 0) = 1; + win_sub = bsxfun(@plus,wb_idx,(0:job_meta.n_samples{vol_index_wb}-max(wb_idx))'); + + win_ind = bsxfun(@plus,win_sub,(0:job_meta.n_samples{vol_index_wb}:... + job_meta.n_samples{vol_index_wb}*(size(traces{vol_index_wb},2)-1))); + +end +%% +%========================================================================================================================== +% read in all the data and decimate as required (allready read in for gathers) +if job_meta.is_gather == 1 + % reshape the gather array to the same 3d matrix as the angle volumes + %vol_tracescjtmp = reshape(vol_traces,size(traces{vol_index_wb},1),length(offset),size(traces{vol_index_wb},2)); + %vol_traces = vol_tracescjtmp(:,(startvol:volinc:endvol),:); + %clear vol_tracescjtmp; + % this can just be vol_traces_cjtmp is not needed, just put in to check + % debug stages + vol_traces = reshape(vol_traces,size(traces{vol_index_wb},1),length(offset),size(traces{vol_index_wb},2)); + + % try applying a running average to the data to smooth out variations + % on the angle gathers + + filttraces = [1 1 1]/3; + %----- Finding the mute and discarding the points outside it by a mask---------------- + for ii = 1:1:size(vol_traces,3) + % mute the low amplitude areas + mask = low_amp_mute(vol_traces(:,:,ii)); + % apply a small smoother to reduce noise + vol_traces(:,:,ii) = conv2(1,filttraces,vol_traces(:,:,ii),'same'); + vol_traces(:,:,ii) = vol_traces(:,:,ii) .* mask; + %imagesc(vol_traces(:,:,ii)); + %colormap(gray); + %caxis([-500 500]); + end + + %drop the angles that are not needed + % note the 3 trace average above to allow 2:1 decimation with a bit of + % anti aliasing, not perfect but ... + vol_traces = vol_traces(:,(startvol:volinc:endvol),:); + + input_angles = double(offset(startvol:volinc:endvol)); + % resize the ilxl data to drop to stack fold + tmp_ilxlrd = ilxl_read{vol_index_wb}(1:length(offset):end,:); + ilxl_read{vol_index_wb} = tmp_ilxlrd; + clear tmp_ilxlrd; +else + % Load block for remaining angle traces + % initialise the data array + vol_traces = zeros(totalvol,n_samples_fullz,size(traces{vol_index_wb},2)); + + % if tottracerun == 0; + % vol_traces = zeros(totalvol,size(traces{vol_index_wb},1),size(traces{vol_index_wb},2)); + % else + % vol_traces = zeros(totalvol,size(traces{vol_index_wb},1),tottracerun); + % end + + vol_count = 1; + for i_vol = startvol:volinc:endvol + fprintf('reading data no of vol = %d\n',i_vol) + + % Read traces + %[~, traces{vol_count}, ~, ~] = node_segy_read(job_meta_path,num2str(i_vol),i_block); + [~, vol_traces(vol_count,:,:), ~, ~] = node_segy_read(job_meta_path,num2str(i_vol),i_block); + + % Flatten traces to water bottom + %traces{vol_count} = traces{vol_count}(win_ind); + %vol_traces(vol_count,:,:) = vol_traces(vol_count,win_ind); + % truncate the dataset if just running a test for a set number of + % traces + % if tottracerun ~= 0; + % % if vol_count == 1; + % % vol_traces = zeros(totalvol,size(traces{vol_count},1),tottracerun); + % % end + % %########################################################### + % % cj test edit resize the dataset temp to test with + % vol_traces(vol_count,:,:) = traces{vol_count}(:,1:tottracerun); + % traces{vol_count} = traces{vol_count}(:,1:tottracerun); + % end + + % keep a list of the angle values read in, this might need to change + % for angle gathers with on a single angle value; it needs to be + % assigned to both fields in the job meta file + input_angles(vol_count) = (job_meta.angle{i_vol}(2)+job_meta.angle{i_vol}(1))/2; + + if plot_on == 2 + figure(1) + subplot(1,totalvol,vol_count); imagesc(vol_traces(vol_count,:,:)); + end + + vol_count = vol_count + 1; + end + + % deal with zeros in the IGmatrix build rather than as a mask as + % already zeros, this is just to cover low amp noise + %----- Finding the mute and discarding the points outside it by a mask---------------- + for ii = 1:1:size(vol_traces,3) + % mute the low amplitude areas + mask = low_amp_mute(vol_traces(:,:,ii)'); + % apply a small smoother to reduce noise + %vol_traces(:,:,ii) = conv2(1,filttraces,vol_traces(:,:,ii),'same'); + vol_traces(:,:,ii) = vol_traces(:,:,ii) .* mask'; + + %imagesc(vol_traces(:,:,ii)); + %colormap(gray); + %caxis([-500 500]); + end + + % truncate data to make z axis number + vol_traces = vol_traces(:,1:maxzout,:); + job_meta.n_samples{1} = maxzout; +end +clear traces win_sub wb_idx; +%% +%========================================================================================================================== +% now flatten to the water bottom offset plane at a time +% +padding = padding + extrapad; +% +if job_meta.is_gather == 1 + for i_vol = 1:totalvol + tmp_vol = squeeze(vol_traces(:,i_vol,:)); + vol_traces(1:size(win_ind,1),i_vol,:) = tmp_vol(win_ind); + end + % resize the traces to drop the trailing blanks after the shift to the wb + vol_traces = vol_traces(1:size(win_ind,1),:,:); + % taper the top 25 samples to avoid wb reflection creating artifacts due to + % high amplitude + + % need to apply a taper that does not go to zero, make the wavelet try + % to match zero and does not work + %taper = single([ zeros(floor(padding-5),1)',linspace(0,1,20)])'; + %vol_traces(1:length(taper),:,:) = bsxfun(@times,vol_traces(1:length(taper),:,:),taper); + +else + for i_vol = 1:totalvol + tmp_vol = squeeze(vol_traces(i_vol,:,:)); + % flattern to water bottom + vol_traces(i_vol,1:size(win_ind,1),:) = tmp_vol(win_ind); + end + % resize the traces to drop the trailing blanks after the shift to the wb + vol_traces = vol_traces(:,1:size(win_ind,1),:); + % taper the top 25 samples to avoid wb reflection creating artifacts due to + % high amplitude + + % need to apply a taper that does not go to zero, make the wavelet try + % to match zero and does not work + %taper = single([ zeros(floor(padding-5),1)',linspace(0,1,20)]); + %vol_traces(:,1:length(taper),:) = bsxfun(@times,vol_traces(:,1:length(taper),:),taper); + +end + + +ns = size(win_ind,1); +ntraces = size(win_ind,2); +% +% inverse taper to apply to the results in the inversion +%taperrev = single([ zeros(floor(padding-5),1)',linspace(1,0,20)]); +taperrev = single([ zeros(floor(padding-5),1)',1./(linspace(0,1,20)),ones((ns-(padding+15)),1)']); +taperrev = [taperrev, taperrev]; +taperrev(isnan(taperrev)) = 0; +taperrev(isinf(taperrev)) = 0; +taperrev(taperrev> 10) = 10; +taperrev = taperrev'; +clear tmp_vol; +padding = padding - extrapad; + +% Test unflatten +% Unflatten data +% [ns,ntraces] = size(traces{1}); +% traces_unflat = [traces{1};zeros(job_meta.n_samples{vol_index_wb}-ns,ntraces)]; +% for kk = 1:length(wb_idx) +% traces_unflat(:,kk) = circshift(traces_unflat(:,kk),wb_idx(kk)); +% end +% +%========================================================================================================================== +%% +%---------Wavelets to be used------------------------------------- + +%Load wavelets set +if use_spatial_wavelets == '0' % Use single wavelet set + wavelets = load(strcat(job_meta.wav_directory,'all_wavelets_time.mat')); % This file gets made by wavelet_average.m +else % Use Spatially Varying Wavelet Sets + algo = '2'; % FLag for which algorithm to use for spatial wavelets + wavelet_dir_path = job_meta.wav_directory; % Wavelet Directory Path from job meta file + wavelets = load_wavelet_spatial(job_meta_path,wavelet_dir_path,i_block,algo); % Call function to smoothen wavelet spatially by various algorithms and load the wavelet for this block +end +%% +ns_wavelet = size(wavelets.all_wavelets_time{1},1)-1; % Number of samples in a wavelet? +hns_wavelet = floor(ns_wavelet/2); % Half of number of samples? + +%======================================= +%make a low freq taper for the wavelet to avoid blowing up noise + +taperlen = floor((lowfreqtaperstart/(500000/job_meta.s_rate))*hns_wavelet)+1; +taperst = (sin(linspace((-(pi*0.94)/2),((pi*0.8)/2),taperlen)')+1)/2; +%taperst(1:(end-2)) = taperst(1:(end-2)) ./ 10; +taperst= power(taperst,4); +taperend = flipud(taperst); +taperapply = [taperst;ones((ns_wavelet-(taperlen*2)),1);taperend]; + +%========================================== + +vol_count = 1; +%Loop though the different angle volumes +for i_vol = startvol:volinc:endvol + wavelet_z_grid = wavelets.all_wavelets_freq{i_vol}(1,:); + wavelet_z_grid = wavelet_z_grid + padding; + wavelet = wavelets.all_wavelets_freq{i_vol}(2:end,:); + wavelet(isnan(wavelet)) = 0; + % apply the low freq taper + wavelet = bsxfun(@times,wavelet,taperapply); + if plot_on == 1 + figure(2) + subplot(1,totalvol,vol_count); imagesc(wavelet); + figure(3) + subplot(1,totalvol,vol_count); plot(wavelet(:,10)); + end + start_interp = min(wavelet_z_grid);%-hns_wavelet; + end_interp = max(wavelet_z_grid);%+hns_wavelet; + wavelet_interp{vol_count} = interp1(wavelet_z_grid,wavelet',start_interp:1:end_interp,'linear'); + %wavelet_interp{vol_count} = interpolate_wavelets(wavelet_z_grid,wavelet,start_interp,end_interp); + wavelet_interp{vol_count} = circshift(ifft(wavelet_interp{vol_count}','symmetric'),floor(job_meta.ns_win/2)); + %wavelet_interp{i_vol} = wavelet_interp{i_vol}; + + if start_interp > 1; + % Pad with zeros or first wavelet + pad_size = start_interp-1; + wavelet_interp{vol_count} = [repmat(wavelet_interp{vol_count}(:,1),1,pad_size),... + wavelet_interp{vol_count}]; + end + if end_interp < ns; + % Pad with zeros or last wavelet + pad_size = ns-end_interp; + wavelet_interp{vol_count} = [wavelet_interp{vol_count},... + repmat(wavelet_interp{vol_count}(:,end),1,pad_size)]; + end + if floor(ns_wavelet/2) == ns_wavelet/2 + wavelet_interp{vol_count}(end+1,:) = wavelet_interp{vol_count}(end,:); + end + if plot_on == 1 + figure(4) + subplot(1,totalvol,vol_count); imagesc(wavelet_interp{vol_count}); + end + wavelet_interp{vol_count} = wavelet_interp{vol_count}(:,1:ns); + vol_count = vol_count + 1; +end +interp_wavelet_z_grid = 1:ns; +ns_wavelet = size(wavelet_interp{1},1); + +%========================================================================================================================== +% normalise the wavelets +if job_meta.is_gather == 0 + [~, wbliveidx] = min(abs((startvol:volinc:endvol)-pick_wb_ind)); + %wavelet_norm = wavelet_rms_norm(totalvol,wavelet_interp,interp_wavelet_z_grid,ceil(totalvol*0.6667)); + wavelet_norm = wavelet_rms_norm(totalvol,wavelet_interp,wbliveidx); +else + % need to store the water bottom live offset in the job_meta + %job_meta.livewb = 12; + %[~, wbliveidx] = min(abs(input_angles-job_meta.livewb)); + [~, wbliveidx] = min(abs((startvol:volinc:endvol)-pick_wb_ind)); + wavelet_norm = wavelet_rms_norm(totalvol,wavelet_interp,wbliveidx); +end + +clear wavelet_interp wavelets wavelet_z_grid interp_wavelet_z_grid wavelet ; + +for i_vol = 1:1:totalvol + wavelet_norm{i_vol}(isnan(wavelet_norm{i_vol})) = 0; +end + +if plot_on == 1 + figure(5) + waveletck = cell2mat(wavelet_norm); + imagesc(waveletck); + imagesc(waveletck(:,1000:ns:end)); + plot(sum(abs(waveletck(:,1600:ns:end)),1)); +end + + +%% +% start building the inversion operators +% Chi model +switch chi_model_type + case 'empirical' + chi = (job_meta.s_rate/1e6)*(0:1:ns-1)'.*-2 + 19; + + case 'raw' + + case 'bootstrap' + + otherwise + warning('Unexpected plot type. No plot created.'); +end + +% Build operator matrix +% Build blanking matrix used to ensure the convolution operator matrix is correct +IGblank = spdiags(ones(ns,2*hns_wavelet+1),(-hns_wavelet:hns_wavelet),ns,ns); +IGblank = repmat(IGblank,1+totalvol,2); + +% Tikhonov regularisation matrix % check tik order +%##smooth = spdiags([-wsmooth*ones(2*ns,1) wsmooth*ones(2*ns,1)],[-1 0],2*ns,2*ns); +%smooth = spdiags([-wsmooth*ones(2*ns,1) wsmooth*ones(2*ns,1)],[-1 0],ns,ns); + +smooth = spdiags([wsmooth*ones(2*ns,1) -2*wsmooth*ones(2*ns,1) wsmooth*ones(2*ns,1)],[-1 0 1],2*ns,2*ns); +%smooth = smooth.*0; +%cj edit +%smooth = spdiags([wsmooth*ones(2*ns,1) -2*wsmooth*ones(2*ns,1) wsmooth*ones(2*ns,1)],[-1 0 1],ns,ns); +%smooth2 = spdiags([wsmooth*10*ones(2*ns,1) -2*wsmooth*10*ones(2*ns,1) wsmooth*10*ones(2*ns,1)],[-1 0 1],ns,ns); +% smooth = [smooth, smooth]; + +% Extract the angle of the stack closest to the mean chi angle for this trace +% This is for the IG crossplot correlation constraint +theta = asind(sqrt(tand(mean(chi)))); +[~, angle_index] = min(abs(input_angles-theta)); + +IGmatrix = build_operator(totalvol,input_angles,ns_wavelet,wavelet_norm,ns,hns_wavelet,angle_index,chi,eer_weight,IGblank,smooth); + +clear wavelet_norm IGblank smooth ; + + +%% Inversion loop + +% Set first and last traces to loop over +first_iter = 1; +if tottracerun ~= 0; + ntraces = tottracerun; +end +last_iter = ntraces; + +% Begin inversion loop +tic +ava = zeros(2*ns,((last_iter - first_iter)+1),'single'); +%residcount = zeros(iter,(last_iter - first_iter)+1); +%cjmodel = rand(4100,1); +% +% make a taper to apply before any filterinf +tflen = 0.05; +%zeropad = 5; +up = ((sin(linspace((-(pi)/2),((pi)/2),round(tflen*ns))')+1)/2); +%down = flipud(up); +%outtaper = [up; ones(ns-(length(up)*2)-zeropad,1); down; zeros(zeropad,1); up; ones(ns-(length(up)*2)-zeropad,1); down; zeros(zeropad,1) ]; +down = ((sin(linspace(((pi)/2),(-(pi)/2),round((tflen*2)*ns))')+1)/2); +outtaper = [up; ones(ns-(length(up)+length(down)),1); down; up; ones(ns-(length(up)+length(down)),1); down ]; + + +% now loop round all the traces in the input and run the inversion we have +% added a parfor loop for testing but will not compile +for kk = first_iter:last_iter +%parfor kk = first_iter:last_iter +% for ii = 1:totalvol +% data(:,ii) = traces{ii}(:,kk); % Read the angle stack data for the inversion of this trace +% end + +if useselectemode == 0 + requiredinline = ilxl_read{vol_index_wb}(kk,1); +end + +if ilxl_read{vol_index_wb}(kk,1) == requiredinline; + + if job_meta.is_gather == 1 + data = vol_traces(:,:,kk); + else + data = vol_traces(:,:,kk)'; + end + data(isnan(data)) = 0; % Set NaNs to zero + + fold = sum(data ~= 0,2); % Get angle fold + + fmask = data == 0; + %fmask = low_amp_mute(trim_data); + + % filter the low freq out of the dataset + %[dataqc scaleused] = time_balence(data); + %figure(57); imagesc(data); colormap(gray); caxis([-10000 10000]); + %amp_spec_plot(data,job_meta.s_rate) + data = bandpass_filter(data,(job_meta.s_rate/1000000),0,relfreq,top3dpt,topfreq); + %amp_spec_plot(data,job_meta.s_rate) + %[dataqc scaleused] = time_balence(dataqc); + %figure(58); imagesc(data); colormap(gray); caxis([-10000 10000]); + data = data .* (1.-fmask); + %figure(59); imagesc(data); colormap(gray); + data_tmp = data(:); % Make temporary column vector from data + + %data_zeros = abs(data_tmp) < abs(mean(data_tmp)/range(data_tmp)); % Find zones where data is zero (due to mute angle mute functions) + data_zeros = data_tmp == 0; + data_zeros2 = data(:,wbliveidx) == 0; + % or close to zero + %data(reshape(data_zeros,[],totalvol)) = 0; + %data_zeros = logical([data_zeros;zeros(3*ns,1)]); + %data_zeros = logical([data_zeros;data_zeros2;zeros(2*ns,1)]); + data_zeros = logical([data_zeros;data_zeros2;data_zeros2;data_zeros2]); + + if plot_on == 1; + figure(6) + subplot(1,2,1); spy(IGmatrix) + end + IGiter = IGmatrix; + IGiter(data_zeros,:) = 0; % Set operator rows to zero if there are zeros in the data vector + + if plot_on == 1; + figure(6) + subplot(1,2,2); spy(IGiter) + end + + % Model intercept = [near], model gradient = [far-near]/[far_angle - near_angle] + if background == 1 || output_std == 1; + model_tmp = zeros(2,ns); + for ii = 1:ns + model_op = [ones(totalvol,1),sind(input_angles').*sind(input_angles')]; + model_zeros = data(ii,:) == 0; + model_op(model_zeros,:) = 0; + model_tmp(:,ii) = model_op\data(ii,:)'; + end + model_tmp = model_tmp'; + %[traces{1}(:,1) traces{2}(:,1) traces{3}(:,1) model_tmp]; + if output_std == 1; + Imodel(:,kk) = model_tmp(:,1)/norm(model_tmp(:,1)); %data(:,1)/norm(data(:,1)); + Gmodel(:,kk) = model_tmp(:,2)/norm(model_tmp(:,1)); %-Imodel./tand(chi); + model = [Imodel(:,kk);Gmodel(:,kk)]; + model(isnan(model)) = 0; + else + Imodel = model_tmp(:,1)/norm(model_tmp(:,1)); %data(:,1)/norm(data(:,1)); + Gmodel = model_tmp(:,2)/norm(model_tmp(:,1)); %-Imodel./tand(chi); + %model = [Imodel;Gmodel]; + model(isnan(model)) = 0; + end + end + % Set NaNs to zero + + % Make the data a column vector and add zeros on the end for the EER constraint and the Tikhonov regularisation + data = double([data(:);zeros(3*ns,1,'single')]); + %data = [data(:);zeros(2*ns,1)]; + % Do the inversion + if background == 1; + [ava_tmp,lsqflag,~,fiternotmp] = lsqr(IGiter,data,tol,iter,[],[],model); + ava(:,kk) = single(ava_tmp); + % try a different solving method? + ava(:,kk) = bsxfun(@times,cjava,taperrev); + else + %[ava(:,kk),~] = lsqr(IGiter,data,tol,iter,[],[],cjmodel); + %[ava_tmp,lsqflag,relres,fiternotmp,residvec] = lsqr(IGiter,data,tol,iter,[],[]); + [ava_tmp,lsqflag,~,fiternotmp] = lsqr(IGiter,data,tol,iter,[],[]); + %residcount(1:length(residvec),kk) = residvec; + %apply band pass filter to the output + ava_zeros = ava_tmp == 0; + % need to apply tapering to the data before the bandpass filter at + % the start of each cube + ava_tmp = ava_tmp.*outtaper; + ava_tmp = bandpass_filter(ava_tmp,(job_meta.s_rate/1000000),(relfreq/3),(relfreq+1),top3dpt,topfreq); + ava(:,kk) = ava_tmp .* (1.-ava_zeros); + ava(1,kk) = single(fiternotmp); + % left out the taper reverse to see if that just kept high + % amplitudes down + %ava(:,kk) = bsxfun(@times,ava_tmp,taperrev); + end + %[ava(:,kk),~] = lsqr(IGiter,data,1e-2,100,[],[],model); + + % mute out any hard zeros from the data + %ava([fold;fold]==0,kk)=0; + +% % apply band pass filter to the output +% ava_zeros = ava(:,kk) == 0; +% ava(:,kk) = bandpass_filter(ava(:,kk),(job_meta.s_rate/1000000),0,relfreq,top3dpt,topfreq); +% ava(:,kk) = ava(:,kk) .* (1.-ava_zeros); + + % Estimate the R^2 confidence in the result. This is the variance ratio: + % 1-[(sum(data-Gm)^2)/(sum(data-mean)^2)], where the inversion was + % solving data = Gm. + if needconf == 1; + data = reshape(data(1:ns*totalvol,:),[],totalvol); + digi_confidence(:,kk) = 1-(sum((data-reshape(IGiter(1:totalvol*ns,:)*ava(:,kk),[],totalvol)).^2,2)./sum(bsxfun(@minus,data,sum(data,2)./fold).^2,2)); + end + % Give a status report, add this to a log file + reportinc = round((last_iter-first_iter+1)/noofreports); + curtr = (kk-first_iter+1)/reportinc; + curtrresid = curtr - round(curtr); + if kk == first_iter; + fprintf('Completed 0 percent: trace %d of %d lsqflag was: %d it took: %d iterations\n',kk-first_iter+1,last_iter-first_iter+1,lsqflag,fiternotmp) + elseif (curtrresid == 0) + fprintf('Completed %5.2f percent: trace %d of %d lsqflag was: %d it took: %d iterations\n',((100/noofreports)*curtr),kk-first_iter+1,last_iter-first_iter+1,lsqflag,fiternotmp) + end +end +end +toc +%fprintf('Completed %8d traces: lsqflag was: %d last iteration no was: %d \n',(kk,lsqflag,fiternotmp); +clear IGiter IGmatrix; % remove the preconditioning matrices + +%% +% Save results +%digi_intercept = zeros(job_meta.n_samples{vol_index_wb},ntraces); +%digi_gradient = zeros(job_meta.n_samples{vol_index_wb},ntraces); + +%digi_intercept = [ava(1:ns,:);zeros(job_meta.n_samples{vol_index_wb}-ns,ntraces)]; +%digi_gradient = [ava(1+ns:end,:);zeros(job_meta.n_samples{vol_index_wb}-ns,ntraces)]; +%digi_minimum_energy_eer_projection = [bsxfun(@times,ava(1:ns,:),cosd(chi))+bsxfun(@times,ava(1+ns:end,:),sind(chi));zeros(job_meta.n_samples{vol_index_wb}-ns,ntraces)]; +%digi_minimum_energy_eer_projection = bsxfun(@times,ava(1:ns,:),cosd(chi))+bsxfun(@times,ava(1+ns:end,:),sind(chi)); + + +if needconf == 1; + digi_confidence(digi_confidence<0)=0; + digi_confidence(digi_confidence>1)=1; + digi_confidence(isnan(digi_confidence))=0; + digi_confidence = [digi_confidence;zeros(job_meta.n_samples{vol_index_wb}-ns,ntraces)]; +end +if output_std == 1; + std_intercept = [Imodel;zeros(job_meta.n_samples{vol_index_wb}-ns,ntraces)]; + std_gradient = [Gmodel;zeros(job_meta.n_samples{vol_index_wb}-ns,ntraces)]; + %calculate the mimum energy based on chi angle provided + std_minimum_energy_eer_projection = [bsxfun(@times,Imodel,cosd(chi))+bsxfun(@times,Gmodel,sind(chi));zeros(job_meta.n_samples{vol_index_wb}-ns,ntraces)]; +end + +% Old way to Unflatten data +%digi_intercept(win_ind(:,1:ntraces)) = ava(1:ns,:); +%digi_gradient(win_ind(:,1:ntraces)) = ava(1+ns:end,:); +%digi_minimum_energy_eer_projection = bsxfun(@times,digi_intercept,cosd(chi))+bsxfun(@times,digi_gradient,sind(chi)); +%digi_confidence(win_ind(:,1:ntraces)) = digi_confidence(1:ns,:); +% for kk = 1:ntraces +% %cj edit +% %for kk = 1:length(wb_idx) +% digi_intercept(:,kk) = circshift(digi_intercept(:,kk),wb_idx(kk)); +% digi_gradient(:,kk) = circshift(digi_gradient(:,kk),wb_idx(kk)); +% digi_minimum_energy_eer_projection(:,kk) = circshift(digi_minimum_energy_eer_projection(:,kk),wb_idx(kk)); +% digi_confidence(:,kk) = circshift(digi_confidence(:,kk),wb_idx(kk)); +% if output_std == 1; +% std_intercept(:,kk) = circshift(std_intercept(:,kk),wb_idx(kk)); +% std_gradient(:,kk) = circshift(std_gradient(:,kk),wb_idx(kk)); +% std_minimum_energy_eer_projection(:,kk) = circshift(std_minimum_energy_eer_projection(:,kk),wb_idx(kk)); +% end +% end + +resultno = 1; +% Save outputs into correct structure to be written to SEGY. +results_out{resultno,1} = 'Meta data for output files'; +results_out{resultno,2}{1,1} = ilxl_read{vol_index_wb}(1:ntraces,:); +%results_out{resultno,2}{2,1} = uint32(zeros(size(traces{vol_index_wb},2),1)); +results_out{resultno,2}{2,1} = uint32(zeros(ntraces,1)); + +ebcstrtowrite = sprintf('%-3200.3200s',[results_out{resultno,1} ' ' ebdichdr ' ' tmpebc]); +results_out{resultno,1} = ebcstrtowrite; + +resultno = resultno + 1; +clear ilxl_read; + +results_out{1,3} = 'is_gather'; % 1 is yes, 0 is no + +results_out{resultno,1} = strcat('digi_intercept',testdiscpt); +%results_out{2,2} = digi_intercept; +results_out{resultno,2} = zeros(job_meta.n_samples{vol_index_wb},ntraces); +% Unflatten data using the window index +results_out{resultno,2}(win_ind(:,1:ntraces)) = 1000.*ava(1:ns,:); +results_out{resultno,3} = 0; +resultno = resultno + 1; + +results_out{resultno,1} = strcat('digi_gradient',testdiscpt); +%results_out{3,2} = digi_gradient; +results_out{resultno,2} = zeros(job_meta.n_samples{vol_index_wb},ntraces); +% Unflatten data using the window index +results_out{resultno,2}(win_ind(:,1:ntraces)) = 1000.*ava(1+ns:end,:); +results_out{resultno,3} = 0; +resultno = resultno + 1; + +results_out{resultno,1} = strcat('digi_minimum_energy_eer_projection',testdiscpt); +%results_out{4,2} = digi_minimum_energy_eer_projection; +digi_minimum_energy_eer_projection = [bsxfun(@times,ava(1:ns,:),cosd(chi))+bsxfun(@times,ava(1+ns:end,:),sind(chi));zeros(job_meta.n_samples{vol_index_wb}-ns,ntraces)]; +results_out{resultno,2} = zeros(job_meta.n_samples{vol_index_wb},ntraces); +% Unflatten data using the window index +results_out{resultno,2}(win_ind(:,1:ntraces)) = 1000.*digi_minimum_energy_eer_projection(1:ns,:); +results_out{resultno,3} = 0; +resultno = resultno + 1; + +if needconf == 1; + results_out{resultno,1} = strcat('digi_confidence',testdiscpt); + %results_out{5,2} = digi_confidence; + digi_confidence = [digi_confidence;zeros(job_meta.n_samples{vol_index_wb}-ns,ntraces)]; + results_out{resultno,2} = zeros(job_meta.n_samples{vol_index_wb},ntraces); + % Unflatten data using the window index + results_out{resultno,2}(win_ind(:,1:ntraces)) = 1000.*digi_confidence(1:ns,:); + results_out{resultno,3} = 0; + resultno = resultno + 1; +end + +% output standard intercept and gradient result +if output_std == 1; + results_out{resultno,1} = strcat('std_intercept',testdiscpt); + results_out{resultno,2} = 1000.*std_intercept; + results_out{resultno,3} = 0; + resultno = resultno + 1; + + results_out{resultno,1} = strcat('std_gradient',testdiscpt); + results_out{resultno,2} = 1000.*std_gradient; + results_out{resultno,3} = 0; + resultno = resultno + 1; + + results_out{resultno,1} = strcat('std_minimum_energy_eer_projection',testdiscpt); + results_out{resultno,2} = 1000.*std_minimum_energy_eer_projection; + results_out{resultno,3} = 0; + resultno = resultno + 1; +end +%% +% segy write function +if exist(strcat(job_meta.output_dir,'digi_results/'),'dir') == 0 + output_dir = strcat(job_meta.output_dir,'digi_results/'); + mkdir(output_dir); +else + output_dir = strcat(job_meta.output_dir,'digi_results/'); +end + +i_block = str2double(i_block); +node_segy_write(results_out,i_block,job_meta.s_rate/1000,output_dir); + +end + +%% +function [IGmatrix] = build_operator(totalvol,input_angles,ns_wavelet,wavelet_tmp,ns,hns_wavelet,angle_index,chi,alpha,IGblank,smooth) + % Build operator for inversion + for ii = 1:totalvol + Iwavelet_interp(:,1+(ii-1)*ns_wavelet:ii*ns_wavelet) = wavelet_tmp{ii}'; + %Iwavelet_interp(:,1+(ii-1)*ns_wavelet:ii*ns_wavelet) = wavelet_tmp{ii}'*(cosd(input_angles(ii)).*cosd(input_angles(ii))); + Gwavelet_interp(:,1+(ii-1)*ns_wavelet:ii*ns_wavelet) = wavelet_tmp{ii}'*(sind(input_angles(ii)).*sind(input_angles(ii))); + %Iwavelet_interp(:,1+(ii-1)*ns_wavelet:ii*ns_wavelet) = interp1(wavelet_z_grid,wavelet_tmp{ii}',start_interp:1:end_interp,'linear','extrap'); + %Gwavelet_interp(:,1+(ii-1)*ns_wavelet:ii*ns_wavelet) = interp1(wavelet_z_grid,... + % wavelet_tmp{ii}'*(sind(input_angles(ii)).*sind(input_angles(ii))),start_interp:1:end_interp,'linear','extrap'); + end + + IGdiagnals = sort(reshape([(-hns_wavelet:hns_wavelet)',bsxfun(@plus,(-hns_wavelet:hns_wavelet)',(-ns:-ns:-ns*(totalvol-1)))],1,[]),'descend'); + + Imatrix = spdiags(Iwavelet_interp,IGdiagnals,ns*totalvol,ns); + Gmatrix = spdiags(Gwavelet_interp,IGdiagnals,ns*totalvol,ns); + + EERmatrix = alpha*[bsxfun(@times,Imatrix(1+ns*(angle_index-1):+ns*angle_index,:),cosd(chi)),bsxfun(@times,Imatrix(1+ns*(angle_index-1):+ns*angle_index,:),sind(chi))]; + + IGmatrix = [[Imatrix,Gmatrix;EERmatrix].*IGblank;smooth]; +end +% +% function wavelet_interp = interpolate_wavelets(wavelet_z_grid,wavelet,start_interp,end_interp) +% % start_interp = min(wavelet_z_grid)-mode(diff(wavelet_z_grid')); +% % end_interp = max(wavelet_z_grid)+mode(diff(wavelet_z_grid')); +% wavelet_interp = interp1(wavelet_z_grid,wavelet',start_interp:1:end_interp,'spline','extrap'); +% end +%% +function wavelet_norm = wavelet_rms_norm(totalvol,wavelet_interp,vol_index) + % Normalise the wavelets to have constant energy w.r.t. angle. The energy + % is set to that of the nearest angle wavelets. Wavelet energy still varies + % w.r.t. time. + norm_to = sum(abs(wavelet_interp{vol_index})); + for ii=1:totalvol + curwav = sum(abs(wavelet_interp{ii})); + ratio = norm_to./curwav; + wavelet_norm{ii} = bsxfun(@times,wavelet_interp{ii},ratio); + end +% A = cell2mat(wavelet_interp); +% %B = sqrt(sum(A.^2)); +% B = (sum(abs(A))); +% %B = sqrt(max(A.^2)); +% C = reshape(B',length(wavelet_z_grid),[]); +% D = C(:,vol_index); +% for ii=1:totalvol +% E = A(:,1+(ii-1)*length(wavelet_z_grid):ii*length(wavelet_z_grid)); +% F = bsxfun(@rdivide,bsxfun(@times,E,D'),sqrt(sum(E.^2))); +% F(isnan(F)) = 0; +% wavelet_norm{ii} = F; +% end +end diff --git a/algorithms/low_amp_mute/low_amp_mute.m b/algorithms/low_amp_mute/low_amp_mute.m new file mode 100644 index 0000000..76a30f9 --- /dev/null +++ b/algorithms/low_amp_mute/low_amp_mute.m @@ -0,0 +1,128 @@ +function [ mask ] = low_amp_mute( data_tmpb ) +% +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +%LOW_AMP_MUTE Summary of this function goes here +% Detailed explanation goes here + +%old route +%data_tmp = data_tmpb(:); +% Find zones where data is zero (due to mute angle mute functions) +% data_zeros = abs(data_tmp) < abs(mean(data_tmp)/range(data_tmp)); +% +% data_tmp = abs(vol_traces(:,:,ii)); +% data_tmp = data_tmp(:); +% mu3 = mean(data_tmp); % Data mean +% sigma3 = std(data_tmp); % Data standard deviation +% outliers = (data_tmp - mu3) > 2*sigma3; +% +% data_tmpb = vol_traces(:,:,ii); +% ================================================================== +% this applies a short vertical smoother to the data and then compares +% those values to the mean of each constant time, the mean is moothed over +% several time steps to get a bigger average, this give a %variation to the +% running mean + +filtw = [1 2 2 2 1]/8; +data_tmpb(isnan(data_tmpb)) = 0; +data_tmpb = abs(data_tmpb); +%data_tmpb(data_tmpb == 0) = NaN; +%cjkl = nanmean(abs(cjk),2); can get a better mean with nanmean, but low is +%good for this mute anyway +data_tmpa = conv2(filtw,1,data_tmpb,'same'); + +tmpmean = mean(data_tmpb,2); +cjk = repmat(tmpmean,1,size(data_tmpb,2)); +data_tmpb(bsxfun(@ge,data_tmpb,(tmpmean*1.5)) == 1) = cjk(bsxfun(@ge,data_tmpb,(tmpmean*1.5)) == 1); +finmean = mean(data_tmpb,2); + +filt_smo = ones(1,21)/21; +tmpmean_smo = conv(finmean,filt_smo,'same'); +finmean(finmean > tmpmean_smo) = tmpmean_smo(finmean > tmpmean_smo); +tmpd = bsxfun(@rdivide,data_tmpa,finmean); +% +% ================================================================== +% now apply a short vertival smoother and pick the point of low difference +%filtww = [1 2 3 2 1]/9; +tmpf = conv2(filtw,1,abs(tmpd),'same') > 0.05; + +%tmpe = conv2(filtww,1,abs(tmpd),'same'); +%data_tmpb(tmpe < 0.1) = 0; +%[FX,FY] = gradient(tmpd); +%imagesc(abs(FY)) +% percentage change from the pre filtered version +%tmpe = abs((data_tmpa ./ (abs(data_tmpb) - data_tmpa)) + 1); + +% ================================================================== +% +% low pick the left hand side and the right hand side mutes +[~,lhs] = max(single(tmpf')); +lhs(end+1:1:end+length(filt_smo)) = lhs(end); +lhs = conv(lhs,filt_smo,'same'); +lhs = floor(lhs(1:size(data_tmpb,1)))-1; +lhs(lhs < 0) = 0; + +[~,rhs] = max(single(tmpf(:,end:-1:1)')); +rhs = size(data_tmpb,2)-rhs; +rhs(end+1:1:end+length(filt_smo)) = rhs(end); +rhs = conv(rhs,filt_smo,'same'); +rhs = floor(rhs(1:size(data_tmpb,1))+0.5)+1; +rhs(rhs > size(tmpf,2)) = size(tmpf,2); + +% 2d filtering +%s = [1 2 1; 0 0 0; -1 -2 -1]; +%s = ones(5,5)/25; +%data_tmpa = conv2(data_tmpb,s,'same'); + +%outline = union(lhs, rhs, 'rows'); +%mask = 1:size(data_tmpb,1)*size(data_tmpb,2); +%mask = reshape(mask,size(data_tmpb,2),[])'; + +% ================================================================== +% now use the mutes to make a mask +% use expansion in a for loop +% mask = zeros(size(data_tmpb,1),size(data_tmpb,2),'single'); +% for ij = 1: size(data_tmpb,1) +% mask(ij,lhs(ij):rhs(ij)) = 1; +% end +% +% make the mask using bsxfun rather than a for loop +mask = ones(size(data_tmpb,1),size(data_tmpb,2),'single'); +mask = cumsum(mask,2); +mask(bsxfun(@ge,mask,lhs') == 0) = 0; +mask(bsxfun(@le,mask,rhs') == 0) = 0; +%mask(mask ~= 0) = 1; +% +% add in points for a blank data to the mask, ie the hard zeros round the +% edge +mask = data_tmpa .* mask; + +%make mask 0's and 1's +mask(mask ~= 0) = 1; + +% % apply the mutes to blank low amp data +% data_tmpb(reshape(data_zeros,[],size(data_tmpb,2))) = 0; +% data_tmpb = data_tmpb .* mask; + +end + diff --git a/algorithms/low_amp_mute/low_amp_mute.m~ b/algorithms/low_amp_mute/low_amp_mute.m~ new file mode 100644 index 0000000..0185dfb --- /dev/null +++ b/algorithms/low_amp_mute/low_amp_mute.m~ @@ -0,0 +1,105 @@ +function [ mask ] = low_amp_mute( data_tmpb ) +%LOW_AMP_MUTE Summary of this function goes here +% Detailed explanation goes here + +%old route +%data_tmp = data_tmpb(:); +% Find zones where data is zero (due to mute angle mute functions) +% data_zeros = abs(data_tmp) < abs(mean(data_tmp)/range(data_tmp)); +% +% data_tmp = abs(vol_traces(:,:,ii)); +% data_tmp = data_tmp(:); +% mu3 = mean(data_tmp); % Data mean +% sigma3 = std(data_tmp); % Data standard deviation +% outliers = (data_tmp - mu3) > 2*sigma3; +% +% data_tmpb = vol_traces(:,:,ii); +% ================================================================== +% this applies a short vertical smoother to the data and then compares +% those values to the mean of each constant time, the mean is moothed over +% several time steps to get a bigger average, this give a %variation to the +% running mean + +filtw = [1 2 2 2 1]/8; +data_tmpb(isnan(data_tmpb)) = 0; +data_tmpb = abs(data_tmpb); +%data_tmpb(data_tmpb == 0) = NaN; +%cjkl = nanmean(abs(cjk),2); can get a better mean with nanmean, but low is +%good for this mute anyway +data_tmpa = conv2(filtw,1,data_tmpb,'same'); + +tmpmean = mean(data_tmpb,2); +cjk = repmat(tmpmean,1,size(data_tmpb,2)); +data_tmpb(bsxfun(@ge,data_tmpb,(tmpmean*1.5)) == 1) = cjk(bsxfun(@ge,data_tmpb,(tmpmean*1.5)) == 1); +finmean = mean(data_tmpb,2); + +filt_smo = ones(1,21)/21; +tmpmean_smo = conv(finmean,filt_smo,'same'); +finmean(finmean > tmpmean_smo) = tmpmean_smo(finmean > tmpmean_smo); +tmpd = bsxfun(@rdivide,data_tmpa,finmean); +% +% ================================================================== +% now apply a short vertival smoother and pick the point of low difference +%filtww = [1 2 3 2 1]/9; +tmpf = conv2(filtw,1,abs(tmpd),'same') > 0.05; + +%tmpe = conv2(filtww,1,abs(tmpd),'same'); +%data_tmpb(tmpe < 0.1) = 0; +%[FX,FY] = gradient(tmpd); +%imagesc(abs(FY)) +% percentage change from the pre filtered version +%tmpe = abs((data_tmpa ./ (abs(data_tmpb) - data_tmpa)) + 1); + +% ================================================================== +% +% low pick the left hand side and the right hand side mutes +[~,lhs] = max(single(tmpf')); +lhs(end+1:1:end+length(filt_smo)) = lhs(end); +lhs = conv(lhs,filt_smo,'same'); +lhs = floor(lhs(1:size(data_tmpb,1)))-1; +lhs(lhs < 0) = 0; + +[~,rhs] = max(single(tmpf(:,end:-1:1)')); +rhs = size(data_tmpb,2)-rhs; +rhs(end+1:1:end+length(filt_smo)) = rhs(end); +rhs = conv(rhs,filt_smo,'same'); +rhs = floor(rhs(1:size(data_tmpb,1))+0.5)+1; +rhs(rhs > size(tmpf,2)) = size(tmpf,2); + +% 2d filtering +%s = [1 2 1; 0 0 0; -1 -2 -1]; +%s = ones(5,5)/25; +%data_tmpa = conv2(data_tmpb,s,'same'); + +%outline = union(lhs, rhs, 'rows'); +%mask = 1:size(data_tmpb,1)*size(data_tmpb,2); +%mask = reshape(mask,size(data_tmpb,2),[])'; + +% ================================================================== +% now use the mutes to make a mask +% use expansion in a for loop +% mask = zeros(size(data_tmpb,1),size(data_tmpb,2),'single'); +% for ij = 1: size(data_tmpb,1) +% mask(ij,lhs(ij):rhs(ij)) = 1; +% end +% +% make the mask using bsxfun rather than a for loop +mask = ones(size(data_tmpb,1),size(data_tmpb,2),'single'); +mask = cumsum(mask,2); +mask(bsxfun(@ge,mask,lhs') == 0) = 0; +mask(bsxfun(@le,mask,rhs') == 0) = 0; +%mask(mask ~= 0) = 1; +% +% add in points for a blank data to the mask, ie the hard zeros round the +% edge +mask = data_tmpa .* mask; + +%make mask 0's and 1's +mask(mask ~= 0) = 1; + +% % apply the mutes to blank low amp data +% data_tmpb(reshape(data_zeros,[],size(data_tmpb,2))) = 0; +% data_tmpb = data_tmpb .* mask; + +end + diff --git a/algorithms/median_filter/medfilt3.m b/algorithms/median_filter/medfilt3.m new file mode 100644 index 0000000..6acaa1f --- /dev/null +++ b/algorithms/median_filter/medfilt3.m @@ -0,0 +1,218 @@ +function B = medfilt3(A,siz,padopt,CHUNKFACTOR) + +%MEDFILT3 1-D, 2-D and 3-D median filtering. +% B = MEDFILT3(A,[M N P]) performs median filtering of the 3-D array A. +% Each output pixel contains the median value in the M-by-N-by-P +% neighborhood around the corresponding pixel in the input array. +% +% B = MEDFILT3(A,[M N]) performs median filtering of the matrix A. Each +% output pixel contains the median value in the M-by-N neighborhood +% around the corresponding pixel. +% +% B = MEDFILT3(A,M) performs median filtering of the vector A. Each +% output pixel contains the median value in the M neighborhood +% around the corresponding pixel. +% +% B = MEDFILT3(A) performs median filtering using a 3 or 3x3 or 3x3x3 +% neighborhood according to the size of A. +% +% B = MEDFILT3(A,...,PADOPT) pads array A using PADOPT option: +% +% String values for PADOPT (default = 'replicate'): +% 'circular' Pads with circular repetition of elements. +% 'replicate' Repeats border elements of A. (DEFAULT) +% 'symmetric' Pads array with mirror reflections of itself. +% +% If PADOPT is a scalar, A is padded with this scalar. +% +% Class Support +% ------------- +% Input array can be numeric or logical. The returned array is of class +% single or double. +% +% Notes +% ----- +% M, N and P must be odd integers. If not, they are incremented by 1. +% +% If NANMEDIAN exists (Statistics Toolbox is required), then MEDFILT3 +% treats NaNs as missing values. +% +% If you work with very large 3D arrays, an "Out of memory" error may +% appear. The chunk factor (CHUNKFACTOR, default value = 1) must be +% increased to reduce the size of the chunks. This will imply more +% iterations whose number is directly proportional to CHUNKFACTOR. Use +% the following syntax: MEDFILT3(A,[...],PADOPT,CHUNKFACTOR) +% +% Examples +% -------- +% %>> 1-D median filtering << +% t = linspace(0,2*pi,100); +% y = cos(t); +% I = round(rand(1,5)*99+1); +% y(I) = rand(size(I)); +% ys = medfilt3(y,5); +% plot(t,y,':',t,ys) +% +% %>> 2-D median filtering << +% % original image +% I = imread('eight.tif'); +% % noisy image +% J = I; +% rand('state',sum(100*clock)) +% J(rand(size(J))<0.01) = 255; +% J(rand(size(J))<0.01) = 0; +% % denoised image +% K = medfilt3(J); +% % figures +% figure +% subplot(121),imshow(J), subplot(122), imshow(K) +% +% %>> 3-D median filtering << +% rand('state',0) +% [x,y,z,V] = flow(50); +% noisyV = V + 0.1*double(rand(size(V))>0.95); +% clear V +% figure +% subplot(121) +% hpatch = patch(isosurface(x,y,z,noisyV,0)); +% isonormals(x,y,z,noisyV,hpatch) +% set(hpatch,'FaceColor','red','EdgeColor','none') +% daspect([1,4,4]), view([-65,20]), axis tight off +% camlight left; lighting phong +% subplot(122) +% %-------- +% denoisedV = medfilt3(noisyV,7); +% %-------- +% hpatch = patch(isosurface(x,y,z,denoisedV,0)); +% isonormals(x,y,z,denoisedV,hpatch) +% set(hpatch,'FaceColor','red','EdgeColor','none') +% daspect([1,4,4]), view([-65,20]), axis tight off +% camlight left; lighting phong +% +% See also MEDFILT1, MEDFILT2, HMF. +% +% -- Damien Garcia -- 2007/08, revised 2010/04 +% website: www.BiomeCardio.com + +%% Note: +% If you work with large 3D arrays, an "Out of memory" error may appear. +% The chunk factor thus must be increased to reduce the size of the chunks. +if nargin~=4 + CHUNKFACTOR = 1; +end +if CHUNKFACTOR<1, CHUNKFACTOR = 1; end + +%% Checking input arguments +if isscalar(A), B = A; return, end + +if ndims(A)>3 + error('A must be a 1-D, 2-D or 3-D array.') +end + +if all(isnan(A(:))), B = A; return, end + +sizA = size(A); +if nargin==1 + % default kernel size is 3 or 3x3 or 3x3x3 + if isvector(A) + siz = 3; + else + siz = 3*ones(1,numel(sizA)); + end + padopt = 'replicate'; +elseif nargin==2 + % default padding option is "replicate" + padopt = 'replicate'; +end + +%% Make SIZ a 3-element array +if numel(siz)==2 + siz = [siz 1]; +elseif isscalar(siz) + if sizA(1)==1 + siz = [1 siz 1]; + else + siz = [siz 1 1]; + end +end + +%% Chunks: the numerical process is split up in order to avoid large arrays +N = numel(A); +siz = ceil((siz-1)/2); +n = prod(siz*2+1); +if n==1, B = A; return, end +nchunk = (1:ceil(N/n/CHUNKFACTOR):N); +if nchunk(end)~=N, nchunk = [nchunk N]; end + +%% Change to double if needed +class0 = class(A); +if ~isa(A,'float') + A = double(A); +end + +%% Padding along specified direction +% If PADARRAY exists (Image Processing Toolbox), this function is used. +% Otherwise the array is padded with scalars. +B = A; +sizB = sizA; +try + A = padarray(A,siz,padopt); +catch + if ~isscalar(padopt) + padopt = 0; +% warning('MATLAB:medfilt3:InexistentPadarrayFunction',... +% ['PADARRAY function does not exist: '... +% 'only scalar padding option is available.\n'... +% 'If not specified, the scalar 0 is used as default.']); + end + A = ones(sizB+siz(1:ndims(B))*2)*padopt; + A(siz(1)+1:end-siz(1),siz(2)+1:end-siz(2),siz(3)+1:end-siz(3)) = B; +end +sizA = size(A); + +if numel(sizB)==2 + sizA = [sizA 1]; + sizB = [sizB 1]; +end + +%% Creating the index arrays (INT32) +inc = zeros([3 2*siz+1],'int32'); +siz = int32(siz); +[inc(1,:,:,:) inc(2,:,:,:) inc(3,:,:,:)] = ndgrid(... + [0:-1:-siz(1) 1:siz(1)],... + [0:-1:-siz(2) 1:siz(2)],... + [0:-1:-siz(3) 1:siz(3)]); +inc = reshape(inc,1,3,[]); + +I = zeros([sizB 3],'int32'); +sizB = int32(sizB); +[I(:,:,:,1) I(:,:,:,2) I(:,:,:,3)] = ndgrid(... + (1:sizB(1))+siz(1),... + (1:sizB(2))+siz(2),... + (1:sizB(3))+siz(3)); +I = reshape(I,[],3); + +%% Check if NANMEDIAN exists +existNaNmedian = exist('nanmedian','file'); + +%% Filtering + +for i = 1:length(nchunk)-1 + + Im = repmat(I(nchunk(i):nchunk(i+1),:),[1 1 n]); + Im = bsxfun(@plus,Im,inc); + + I0 = Im(:,1,:) +... + (Im(:,2,:)-1)*sizA(1) +... + (Im(:,3,:)-1)*sizA(1)*sizA(2); + I0 = squeeze(I0); + + if existNaNmedian + B(nchunk(i):nchunk(i+1)) = nanmedian(A(I0),2); + else + B(nchunk(i):nchunk(i+1)) = median(A(I0),2); + end +end +B = cast(B,class0); + \ No newline at end of file diff --git a/algorithms/median_filter/medfilt3nt.m b/algorithms/median_filter/medfilt3nt.m new file mode 100644 index 0000000..0a34aae --- /dev/null +++ b/algorithms/median_filter/medfilt3nt.m @@ -0,0 +1,218 @@ +function B = medfilt3nt(A,siz,padopt,CHUNKFACTOR) + +%MEDFILT3 1-D, 2-D and 3-D median filtering. +% B = MEDFILT3(A,[M N P]) performs median filtering of the 3-D array A. +% Each output pixel contains the median value in the M-by-N-by-P +% neighborhood around the corresponding pixel in the input array. +% +% B = MEDFILT3(A,[M N]) performs median filtering of the matrix A. Each +% output pixel contains the median value in the M-by-N neighborhood +% around the corresponding pixel. +% +% B = MEDFILT3(A,M) performs median filtering of the vector A. Each +% output pixel contains the median value in the M neighborhood +% around the corresponding pixel. +% +% B = MEDFILT3(A) performs median filtering using a 3 or 3x3 or 3x3x3 +% neighborhood according to the size of A. +% +% B = MEDFILT3(A,...,PADOPT) pads array A using PADOPT option: +% +% String values for PADOPT (default = 'replicate'): +% 'circular' Pads with circular repetition of elements. +% 'replicate' Repeats border elements of A. (DEFAULT) +% 'symmetric' Pads array with mirror reflections of itself. +% +% If PADOPT is a scalar, A is padded with this scalar. +% +% Class Support +% ------------- +% Input array can be numeric or logical. The returned array is of class +% single or double. +% +% Notes +% ----- +% M, N and P must be odd integers. If not, they are incremented by 1. +% +% If NANMEDIAN exists (Statistics Toolbox is required), then MEDFILT3 +% treats NaNs as missing values. +% +% If you work with very large 3D arrays, an "Out of memory" error may +% appear. The chunk factor (CHUNKFACTOR, default value = 1) must be +% increased to reduce the size of the chunks. This will imply more +% iterations whose number is directly proportional to CHUNKFACTOR. Use +% the following syntax: MEDFILT3(A,[...],PADOPT,CHUNKFACTOR) +% +% Examples +% -------- +% %>> 1-D median filtering << +% t = linspace(0,2*pi,100); +% y = cos(t); +% I = round(rand(1,5)*99+1); +% y(I) = rand(size(I)); +% ys = medfilt3(y,5); +% plot(t,y,':',t,ys) +% +% %>> 2-D median filtering << +% % original image +% I = imread('eight.tif'); +% % noisy image +% J = I; +% rand('state',sum(100*clock)) +% J(rand(size(J))<0.01) = 255; +% J(rand(size(J))<0.01) = 0; +% % denoised image +% K = medfilt3(J); +% % figures +% figure +% subplot(121),imshow(J), subplot(122), imshow(K) +% +% %>> 3-D median filtering << +% rand('state',0) +% [x,y,z,V] = flow(50); +% noisyV = V + 0.1*double(rand(size(V))>0.95); +% clear V +% figure +% subplot(121) +% hpatch = patch(isosurface(x,y,z,noisyV,0)); +% isonormals(x,y,z,noisyV,hpatch) +% set(hpatch,'FaceColor','red','EdgeColor','none') +% daspect([1,4,4]), view([-65,20]), axis tight off +% camlight left; lighting phong +% subplot(122) +% %-------- +% denoisedV = medfilt3(noisyV,7); +% %-------- +% hpatch = patch(isosurface(x,y,z,denoisedV,0)); +% isonormals(x,y,z,denoisedV,hpatch) +% set(hpatch,'FaceColor','red','EdgeColor','none') +% daspect([1,4,4]), view([-65,20]), axis tight off +% camlight left; lighting phong +% +% See also MEDFILT1, MEDFILT2, HMF. +% +% -- Damien Garcia -- 2007/08, revised 2010/04 +% website: www.BiomeCardio.com + +%% Note: +% If you work with large 3D arrays, an "Out of memory" error may appear. +% The chunk factor thus must be increased to reduce the size of the chunks. +if nargin~=4 + CHUNKFACTOR = 1; +end +if CHUNKFACTOR<1, CHUNKFACTOR = 1; end + +%% Checking input arguments +if isscalar(A), B = A; return, end + +if ndims(A)>3 + error('A must be a 1-D, 2-D or 3-D array.') +end + +if all(isnan(A(:))), B = A; return, end + +sizA = size(A); +if nargin==1 + % default kernel size is 3 or 3x3 or 3x3x3 + if isvector(A) + siz = 3; + else + siz = 3*ones(1,numel(sizA)); + end + padopt = 'replicate'; +elseif nargin==2 + % default padding option is "replicate" + padopt = 'replicate'; +end + +%% Make SIZ a 3-element array +if numel(siz)==2 + siz = [siz 1]; +elseif isscalar(siz) + if sizA(1)==1 + siz = [1 siz 1]; + else + siz = [siz 1 1]; + end +end + +%% Chunks: the numerical process is split up in order to avoid large arrays +N = numel(A); +siz = ceil((siz-1)/2); +n = prod(siz*2+1); +if n==1, B = A; return, end +nchunk = (1:ceil(N/n/CHUNKFACTOR):N); +if nchunk(end)~=N, nchunk = [nchunk N]; end + +%% Change to double if needed +class0 = class(A); +if ~isa(A,'float') + A = double(A); +end + +%% Padding along specified direction +% If PADARRAY exists (Image Processing Toolbox), this function is used. +% Otherwise the array is padded with scalars. +B = A; +sizB = sizA; +%try +% A = padarray(A,siz,padopt); +%catch + if ~isscalar(padopt) + padopt = 0; +% warning('MATLAB:medfilt3:InexistentPadarrayFunction',... +% ['PADARRAY function does not exist: '... +% 'only scalar padding option is available.\n'... +% 'If not specified, the scalar 0 is used as default.']); + end + A = ones(sizB+siz(1:ndims(B))*2)*padopt; + A(siz(1)+1:end-siz(1),siz(2)+1:end-siz(2),siz(3)+1:end-siz(3)) = B; +%end +sizA = size(A); + +if numel(sizB)==2 + sizA = [sizA 1]; + sizB = [sizB 1]; +end + +%% Creating the index arrays (INT32) +inc = zeros([3 2*siz+1],'int32'); +siz = int32(siz); +[inc(1,:,:,:) inc(2,:,:,:) inc(3,:,:,:)] = ndgrid(... + [0:-1:-siz(1) 1:siz(1)],... + [0:-1:-siz(2) 1:siz(2)],... + [0:-1:-siz(3) 1:siz(3)]); +inc = reshape(inc,1,3,[]); + +I = zeros([sizB 3],'int32'); +sizB = int32(sizB); +[I(:,:,:,1) I(:,:,:,2) I(:,:,:,3)] = ndgrid(... + (1:sizB(1))+siz(1),... + (1:sizB(2))+siz(2),... + (1:sizB(3))+siz(3)); +I = reshape(I,[],3); + +%% Check if NANMEDIAN exists +%existNaNmedian = exist('nanmedian','file'); + +%% Filtering + +for i = 1:length(nchunk)-1 + + Im = repmat(I(nchunk(i):nchunk(i+1),:),[1 1 n]); + Im = bsxfun(@plus,Im,inc); + + I0 = Im(:,1,:) +... + (Im(:,2,:)-1)*sizA(1) +... + (Im(:,3,:)-1)*sizA(1)*sizA(2); + I0 = squeeze(I0); + + %if existNaNmedian + % B(nchunk(i):nchunk(i+1)) = nanmedian(A(I0),2); + %else + B(nchunk(i):nchunk(i+1)) = median(A(I0),2); + %end +end +B = cast(B,class0); + \ No newline at end of file diff --git a/algorithms/purge_function.sh b/algorithms/purge_function.sh new file mode 100644 index 0000000..b32fa42 --- /dev/null +++ b/algorithms/purge_function.sh @@ -0,0 +1,31 @@ +#!/bin/sh +## ------------------ Disclaimer ------------------ +# +# BG Group plc or any of its respective subsidiaries, affiliates and +# associated companies (or by any of their respective officers, employees +# or agents) makes no representation or warranty, express or implied, in +# respect to the quality, accuracy or usefulness of this repository. The code +# is this repository is supplied with the explicit understanding and +# agreement of recipient that any action taken or expenditure made by +# recipient based on its examination, evaluation, interpretation or use is +# at its own risk and responsibility. +# +# No representation or warranty, express or implied, is or will be made in +# relation to the accuracy or completeness of the information in this +# repository and no responsibility or liability is or will be accepted by +# BG Group plc or any of its respective subsidiaries, affiliates and +# associated companies (or by any of their respective officers, employees +# or agents) in relation to it. +## ------------------ License ------------------ +# GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +## github +# https://github.com/AnalysePrestackSeismic/ +# script for execution of deployed applications +# +# Sets up the MCR environment for the current $ARCH and executes +# the specified command. +# +umask 002 +rm -rf /localcache/mcr_cache_umask_friendly/$1 + +exit diff --git a/algorithms/purge_function.sh~ b/algorithms/purge_function.sh~ new file mode 100644 index 0000000..add0b02 --- /dev/null +++ b/algorithms/purge_function.sh~ @@ -0,0 +1,10 @@ +#!/bin/sh +# script for execution of deployed applications +# +# Sets up the MCR environment for the current $ARCH and executes +# the specified command. +# +umask 002 +rm -rf /localcache/mcr_cache_umask_friendly/$1 + +exit \ No newline at end of file diff --git a/algorithms/time_balence/time_balence.m b/algorithms/time_balence/time_balence.m new file mode 100644 index 0000000..b9489dc --- /dev/null +++ b/algorithms/time_balence/time_balence.m @@ -0,0 +1,108 @@ +function [ trim_data_filt scalepos ] = time_balence( trim_data ) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% time_balence: function to scales a gather or setion from the envelope +% of the amplitudes to make the envelope tend to the value +/- 2000 +% Arguments: +% trim_data = a matrix containing a pre-stack seismic gather +% [rows: samples, cols: tertiary key] +% +% Outputs: +% trim_data_filt = scaled version of trim_data +% scalepos = amount of scaling applied for undo +% +% Writes to Disk: +% nothing + +filt_smo = ones(1,3)/3; +filttraces = [1 2 2 3 3 3 2 2 1]/19; + +% find the max of the data across the gather and smooth +td_max = max(trim_data,[],2); +td_max = conv(td_max,filttraces,'same'); + +% find the first and second derivatives of the max +max_1st_deriv = diff(td_max); +max_2nd_deriv = diff(td_max,2); + +% apply a signum filter to get samples at zero crossings and make only 1 +% and 0's +sign_1_deriv = sign(max_1st_deriv); +sign_1_deriv(sign_1_deriv == 0) = 1; + +% find the point where sign of 1st deriv changes +diffsign = diff(sign_1_deriv); + +% set the point to zro where second derivative is positive and pad, this +% finds the peaks in the max dataset +diffsign(sign(max_2nd_deriv) > 0) = 0; +diffsign = [1;diffsign]; + +%use the peaks logical to get the values and indexes to then interpolate to +%make and envelope which includes the signal, but preserves the wiggles in +%the dataset +itpsval = td_max(diffsign < 0); +itpslocs = single(1:size(trim_data,1))'; +itpslocsin = itpslocs(diffsign < 0); + +% interpolate to make the envelope only using fast linear interp +posenv = double(interp1q(itpslocsin,itpsval,itpslocs)); + +% now make the scaler to make envlope all fit the value 2000 +%scalepos = 2000 ./ posenv; +scalepos = bsxfun(@rdivide,2000,posenv); +scalepos(isnan(scalepos)) = 0; + +% apply a median filter to remove sudden jumps in scaling and the small +% averaging to make sure it is a smooth scalar +scalepos = medfilt3nt(scalepos,15,0); +scalepos = conv(scalepos,filt_smo,'same'); + + +%Apply the scaling to the input data +trim_data_filt = bsxfun(@times,scalepos,trim_data); + +% td_max = max(trim_data,[],2); +% td_max = conv(td_max,filt_smo,'same'); +% +% cjdiff2 = diff(td_max,2); +% cjdiff = diff(td_max); +% cjdiffb = sign(cjdiff); +% cjdiffb(cjdiffb == 0) = 1; +% diffsign = diff(sign(cjdiff)); +% cjdiff2sign = sign(cjdiff2); +% diffsign(cjdiff2sign > 0) = 0; +% diffsign = [1;diffsign]; +% %td_max(diffsign == 0) = 0; +% itpsval = td_max(diffsign < 0); +% itpslocs = single(1:size(trim_data,1))'; +% itpslocsin = itpslocs(diffsign < 0); +% posenv = double(interp1q(itpslocsin,itpsval,itpslocs)); +% %scalepos = 2000 ./ posenv; +% scalepos = bsxfun(@rdivide,2000,posenv); +% scalepos(isnan(scalepos)) = 0; +% scalepos = conv(scalepos,filttraces,'same'); +% scaltd = bsxfun(@times,scalepos,trim_data); + +end + diff --git a/algorithms/time_balence/time_balence.m~ b/algorithms/time_balence/time_balence.m~ new file mode 100644 index 0000000..2b8dff9 --- /dev/null +++ b/algorithms/time_balence/time_balence.m~ @@ -0,0 +1,108 @@ +function [ trim_data_filt scalepos ] = time_balence( trim_data ) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% time_balence: function to scales a gather or setion from the envelope +% of the amplitudes to make the envelope tend to the value +/- 2000 +% Arguments: +% trim_data = a matrix containing a pre-stack seismic gather +% [rows: samples, cols: tertiary key] +% +% Outputs: +% trim_data_filt = scaled version of trim_data +% scalepos = amount of scaling applied to allow undo +% +% Writes to Disk: +% nothing + +filt_smo = ones(1,3)/3; +filttraces = [1 2 2 3 3 3 2 2 1]/19; + +% find the max of the data across the gather and smooth +td_max = max(trim_data,[],2); +td_max = conv(td_max,filttraces,'same'); + +% find the first and second derivatives of the max +max_1st_deriv = diff(td_max); +max_2nd_deriv = diff(td_max,2); + +% apply a signum filter to get samples at zero crossings and make only 1 +% and 0's +sign_1_deriv = sign(max_1st_deriv); +sign_1_deriv(sign_1_deriv == 0) = 1; + +% find the point where sign of 1st deriv changes +diffsign = diff(sign_1_deriv); + +% set the point to zro where second derivative is positive and pad, this +% finds the peaks in the max dataset +diffsign(sign(max_2nd_deriv) > 0) = 0; +diffsign = [1;diffsign]; + +%use the peaks logical to get the values and indexes to then interpolate to +%make and envelope which includes the signal, but preserves the wiggles in +%the dataset +itpsval = td_max(diffsign < 0); +itpslocs = single(1:size(trim_data,1))'; +itpslocsin = itpslocs(diffsign < 0); + +% interpolate to make the envelope only using fast linear interp +posenv = double(interp1q(itpslocsin,itpsval,itpslocs)); + +% now make the scaler to make envlope all fit the value 2000 +%scalepos = 2000 ./ posenv; +scalepos = bsxfun(@rdivide,2000,posenv); +scalepos(isnan(scalepos)) = 0; + +% apply a median filter to remove sudden jumps in scaling and the small +% averaging to make sure it is a smooth scalar +scalepos = medfilt3nt(scalepos,15,0); +scalepos = conv(scalepos,filt_smo,'same'); + + +%Apply the scaling to the input data +trim_data_filt = bsxfun(@times,scalepos,trim_data); + +% td_max = max(trim_data,[],2); +% td_max = conv(td_max,filt_smo,'same'); +% +% cjdiff2 = diff(td_max,2); +% cjdiff = diff(td_max); +% cjdiffb = sign(cjdiff); +% cjdiffb(cjdiffb == 0) = 1; +% diffsign = diff(sign(cjdiff)); +% cjdiff2sign = sign(cjdiff2); +% diffsign(cjdiff2sign > 0) = 0; +% diffsign = [1;diffsign]; +% %td_max(diffsign == 0) = 0; +% itpsval = td_max(diffsign < 0); +% itpslocs = single(1:size(trim_data,1))'; +% itpslocsin = itpslocs(diffsign < 0); +% posenv = double(interp1q(itpslocsin,itpsval,itpslocs)); +% %scalepos = 2000 ./ posenv; +% scalepos = bsxfun(@rdivide,2000,posenv); +% scalepos(isnan(scalepos)) = 0; +% scalepos = conv(scalepos,filttraces,'same'); +% scaltd = bsxfun(@times,scalepos,trim_data); + +end + diff --git a/algorithms/time_balence/time_balence_stk.m b/algorithms/time_balence/time_balence_stk.m new file mode 100644 index 0000000..609bcc2 --- /dev/null +++ b/algorithms/time_balence/time_balence_stk.m @@ -0,0 +1,131 @@ +function trim_data_filt = time_balence_stk( trim_data ) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% time_balence: function to scales a section from the envelope +% of the amplitudes +% Arguments: +% trim_data = a matrix containing a seismic section +% [rows: samples, cols: secondary key] +% +% Outputs: +% trim_data_filt = scaled version of trim_data +% +% Writes to Disk: +% nothing + +filt_smo = ones(1,3)/3; +%filttraces = [1 2 2 3 3 3 2 2 1]/19; +trim_data_filt = trim_data; + +for ckk = 1:size(trim_data,2) + +% find the max of the data across the gather and smooth +td_max = trim_data(:,ckk); +%td_max = conv(td_max,filttraces,'same'); + +% find the first and second derivatives of the max +max_1st_deriv = diff(td_max); +max_2nd_deriv = diff(td_max,2); + +% apply a signum filter to get samples at zero crossings and make only 1 +% and 0's +sign_1_deriv = sign(max_1st_deriv); +sign_1_deriv(sign_1_deriv == 0) = 1; + +% find the point where sign of 1st deriv changes +diffsign = diff(sign_1_deriv); +mdiffsign = diffsign; + +% set the point to zero where second derivative is positive and pad, this +% finds the peaks in the max dataset +diffsign(sign(max_2nd_deriv) > 0) = 0; +diffsign = [1;diffsign]; + +% set the point to zero where second derivative is positive and pad, this +% finds the mins in the max dataset +mdiffsign(sign(max_2nd_deriv) <= 0) = 0; +mdiffsign = [1;mdiffsign]; + +%use the peaks logical to get the values and indexes to then interpolate to +%make and envelope which includes the signal, but preserves the wiggles in +%the dataset +itpsval = td_max(diffsign < 0); +itpslocs = single(1:size(trim_data,1))'; +itpslocsin = itpslocs(diffsign < 0); + +% interpolate to make the envelope only using fast linear interp +posenv = double(interp1q(itpslocsin,itpsval,itpslocs)); + + +%use the mins logical to get the values and indexes to then interpolate to +%make and envelope which includes the signal, but preserves the wiggles in +%the dataset +mitpsval = td_max(mdiffsign > 0); +mitpslocs = single(1:size(trim_data,1))'; +mitpslocsin = mitpslocs(mdiffsign > 0); + +% interpolate to make the min envelope only using fast linear interp +mposenv = double(interp1q(mitpslocsin,mitpsval,mitpslocs)); + +maxenv = max([abs(posenv) abs(mposenv)],[],2); + +% now make the scaler to make envlope all fit the value 2000 +scalepos = 2000 ./ maxenv; +%scalepos = bsxfun(@rdivide,2000,posenv); +scalepos(isnan(scalepos)) = 0; + +% apply a median filter to remove sudden jumps in scaling and the small +% averaging to make sure it is a smooth scalar +scalepos = medfilt3nt(scalepos,15,0); +scalepos = conv(scalepos,filt_smo,'same'); + + +%Apply the scaling to the input data +%trim_data_filt(ckk) = bsxfun(@times,scalepos,trim_data(ckk)); +trim_data_filt(:,ckk) = trim_data(:,ckk).*scalepos; + +end +% td_max = max(trim_data,[],2); +% td_max = conv(td_max,filt_smo,'same'); +% +% cjdiff2 = diff(td_max,2); +% cjdiff = diff(td_max); +% cjdiffb = sign(cjdiff); +% cjdiffb(cjdiffb == 0) = 1; +% diffsign = diff(sign(cjdiff)); +% cjdiff2sign = sign(cjdiff2); +% diffsign(cjdiff2sign > 0) = 0; +% diffsign = [1;diffsign]; +% %td_max(diffsign == 0) = 0; +% itpsval = td_max(diffsign < 0); +% itpslocs = single(1:size(trim_data,1))'; +% itpslocsin = itpslocs(diffsign < 0); +% posenv = double(interp1q(itpslocsin,itpsval,itpslocs)); +% %scalepos = 2000 ./ posenv; +% scalepos = bsxfun(@rdivide,2000,posenv); +% scalepos(isnan(scalepos)) = 0; +% scalepos = conv(scalepos,filttraces,'same'); +% scaltd = bsxfun(@times,scalepos,trim_data); + +end + diff --git a/algorithms/time_balence/time_balence_stk.m~ b/algorithms/time_balence/time_balence_stk.m~ new file mode 100644 index 0000000..a8df677 --- /dev/null +++ b/algorithms/time_balence/time_balence_stk.m~ @@ -0,0 +1,131 @@ +function trim_data_filt = time_balence_stk( trim_data ) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% time_balence: function to scales a gather or setion from the envelope +% of the amplitudes +% Arguments: +% trim_data = a matrix containing a pre-stack seismic gather +% [rows: samples, cols: tertiary key] +% +% Outputs: +% trim_data_filt = scaled version of trim_data +% +% Writes to Disk: +% nothing + +filt_smo = ones(1,3)/3; +%filttraces = [1 2 2 3 3 3 2 2 1]/19; +trim_data_filt = trim_data; + +for ckk = 1:size(trim_data,2) + +% find the max of the data across the gather and smooth +td_max = trim_data(:,ckk); +%td_max = conv(td_max,filttraces,'same'); + +% find the first and second derivatives of the max +max_1st_deriv = diff(td_max); +max_2nd_deriv = diff(td_max,2); + +% apply a signum filter to get samples at zero crossings and make only 1 +% and 0's +sign_1_deriv = sign(max_1st_deriv); +sign_1_deriv(sign_1_deriv == 0) = 1; + +% find the point where sign of 1st deriv changes +diffsign = diff(sign_1_deriv); +mdiffsign = diffsign; + +% set the point to zero where second derivative is positive and pad, this +% finds the peaks in the max dataset +diffsign(sign(max_2nd_deriv) > 0) = 0; +diffsign = [1;diffsign]; + +% set the point to zero where second derivative is positive and pad, this +% finds the mins in the max dataset +mdiffsign(sign(max_2nd_deriv) <= 0) = 0; +mdiffsign = [1;mdiffsign]; + +%use the peaks logical to get the values and indexes to then interpolate to +%make and envelope which includes the signal, but preserves the wiggles in +%the dataset +itpsval = td_max(diffsign < 0); +itpslocs = single(1:size(trim_data,1))'; +itpslocsin = itpslocs(diffsign < 0); + +% interpolate to make the envelope only using fast linear interp +posenv = double(interp1q(itpslocsin,itpsval,itpslocs)); + + +%use the mins logical to get the values and indexes to then interpolate to +%make and envelope which includes the signal, but preserves the wiggles in +%the dataset +mitpsval = td_max(mdiffsign > 0); +mitpslocs = single(1:size(trim_data,1))'; +mitpslocsin = mitpslocs(mdiffsign > 0); + +% interpolate to make the min envelope only using fast linear interp +mposenv = double(interp1q(mitpslocsin,mitpsval,mitpslocs)); + +maxenv = max([abs(posenv) abs(mposenv)],[],2); + +% now make the scaler to make envlope all fit the value 2000 +scalepos = 2000 ./ maxenv; +%scalepos = bsxfun(@rdivide,2000,posenv); +scalepos(isnan(scalepos)) = 0; + +% apply a median filter to remove sudden jumps in scaling and the small +% averaging to make sure it is a smooth scalar +scalepos = medfilt3nt(scalepos,15,0); +scalepos = conv(scalepos,filt_smo,'same'); + + +%Apply the scaling to the input data +%trim_data_filt(ckk) = bsxfun(@times,scalepos,trim_data(ckk)); +trim_data_filt(:,ckk) = trim_data(:,ckk).*scalepos; + +end +% td_max = max(trim_data,[],2); +% td_max = conv(td_max,filt_smo,'same'); +% +% cjdiff2 = diff(td_max,2); +% cjdiff = diff(td_max); +% cjdiffb = sign(cjdiff); +% cjdiffb(cjdiffb == 0) = 1; +% diffsign = diff(sign(cjdiff)); +% cjdiff2sign = sign(cjdiff2); +% diffsign(cjdiff2sign > 0) = 0; +% diffsign = [1;diffsign]; +% %td_max(diffsign == 0) = 0; +% itpsval = td_max(diffsign < 0); +% itpslocs = single(1:size(trim_data,1))'; +% itpslocsin = itpslocs(diffsign < 0); +% posenv = double(interp1q(itpslocsin,itpsval,itpslocs)); +% %scalepos = 2000 ./ posenv; +% scalepos = bsxfun(@rdivide,2000,posenv); +% scalepos(isnan(scalepos)) = 0; +% scalepos = conv(scalepos,filttraces,'same'); +% scaltd = bsxfun(@times,scalepos,trim_data); + +end + diff --git a/algorithms/trim_calculation/trim_calculation.m b/algorithms/trim_calculation/trim_calculation.m new file mode 100644 index 0000000..b50ce83 --- /dev/null +++ b/algorithms/trim_calculation/trim_calculation.m @@ -0,0 +1,733 @@ +function [] = trim_calculation(job_meta_path,i_block,startvolr,endvolr,shift,zsmooth,itmr,otmr,timbal,outputflatgathers) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +%% Function Description +% this works out and applies trim statics and keeps a sum of the statics +% for each z sample +% Input: +% job_meta_path: Path to job meta file +% i_block: The current Block Number +% startvol: The smallest angle trace to load to make the stack for stack alignment +% endvol: The largest angle trace to load to make the stack for stack alignment +% shift: Maximum allowable shift in samples ?? +% zsmooth : Smoother ?? Not used? +% itmr: Inner Trace Mute for the trim zone, this is what is output in prestack gathers +% otmr: Outer Trace Mute for the trim zone, this is what is output in prestack gathers +% timbal: Flag to balence the data to avoid any loud parts dominating any solution. Use '1' for yes, '0' for no +% outputflatgathers: Flag to output the prestack flatterned data. Use '1' for yes, '0' for no +% +% Output: +% Void Output +% +% Writes to Disk: +% Everything gets written in .../trimout/*. The written out items are: +% +% sort out parameters +smoothing_scaler = 8; % normally 10 +startvolr = str2double(startvolr); +endvolr = str2double(endvolr); +otmr = str2double(otmr); +itmr = str2double(itmr); +timbal = str2double(timbal); +shift = str2double(shift); +useselectemode = 0; +%outputflatgathers = 1; % 1 outputs the prestack flatterned data, 0 does not +outputflatgathers = str2double(outputflatgathers); + +outputgathershifts = 0; % 1 outputs the prestack shifts, 0 does not +% +if isempty(regexp(zsmooth,'il','once')) == 0 + useselectemode = 1; + requiredinline = str2double(regexprep(zsmooth,'il','')); + %requiredinline = str2double(strrep(tottracerun,'il','')); + zsmooth = 20; +else + zsmooth = str2double(zsmooth); +end + +% zsmooth = str2double(zsmooth); +%zsmooth2 = shift*2; +% if zsmooth2 < 7 +% zsmooth2 = 7; +% end +% shiftinc = 0.5; now set in the code from the new sample rate +plots = 0; +padding = 50; +% Wavelet estimation parameters +ns_win = 128; +hns_win = ns_win/2; +ns_overlap = 96; +totmaxshift = 5; +avg_vel = 2500; +% ============================================================================================================ +% load the job meta file containing more parameters +job_meta = load(job_meta_path); +sample_rate = (job_meta.s_rate/1000); +% add the history of jobs run and this one to the curent ebcdic +ebdichdr = ['trim statics ']; +if isfield(job_meta,'comm_history') + ebdichdr2 = job_meta.comm_history; + tmpebc = ebdichdr2{size(ebdichdr2,1),2}; +else + ebdichdr2{1,2} = ''; + tmpebc = ''; +end + +for ebcii = (size(ebdichdr2,1)-1):-1:1 + tmpebcc = regexp(ebdichdr2{ebcii,2},'/','split'); + tmpebc = [tmpebc tmpebcc{1} tmpebcc{end}]; +end +tmpebc = sprintf('%-3200.3200s',tmpebc); +clear tmpebcc ebdichdr2; +% +% ============================================================================================================ +% Read the data for this block + +% [~, traces, ilxl_read, offset_read] = node_segy_read(job_meta_path,'1',i_block); +% offset = unique(offset_read); +% traces = reshape(traces,size(traces,1),length(offset),[]); +% +% [n_samples,n_traces_gather,n_traces] = size(traces); + +[seismic, results_out{2,2}, results_out{1,2}{1,1}, offset_read] = node_segy_read(job_meta_path,'1',i_block); +offset = unique(offset_read); +results_out{2,2} = reshape(results_out{2,2},size(results_out{2,2},1),length(offset),[]); + +% put itmr and otmr into sequential trace numbers in the gather +itm = find(offset <= itmr,1,'last'); +otm = find(offset <= otmr,1,'last'); + +% put startvolr and endvolr into sequential trace numbers in the gather +startvol = find(offset <= startvolr,1,'last'); +endvol = find(offset <= endvolr,1,'last'); + + +% check to make sure it read something if not exit +if isempty(results_out{2,2}) == 1 && isempty(results_out{1,2}{1,1}) == 1 && isempty(offset_read) == 1 + return +end + +% drop data as required +% order is samples, angles, skeys +% results_out{2,2} = results_out{2,2}(1:maxzout,:,:); +% job_meta.n_samples{1} = maxzout; + +%results_out{1,2}{1,1} + +[n_samples,n_traces_gather,n_traces] = size(results_out{2,2}); +in_n_samples = n_samples; + +% apply any itm and otm to the gathers +sttrc = 2; +edtrc = n_traces_gather; +if itm > 0 + results_out{2,2}(:,1:itm,:) = 0; + edtrc = (n_traces_gather - itm); +end +if otm > 0 + results_out{2,2}(:,otm:end,:) = 0; + sttrc = (n_traces_gather - otm) + 2; +end +midtrc = startvol + floor((endvol - startvol)/2); +% ============================================================================================================ +% Make results meta information + +% for the pre-stack dataset +results_out{1,1} = 'Meta data for output files'; +%results_out{resultno,2}{1,1} = ilxl_read; +results_out{1,2}{2,1} = offset_read'; +ebcstrtowrite = sprintf('%-3200.3200s',[results_out{1,1} ' ' ebdichdr ' ' tmpebc]); +results_out{1,1} = ebcstrtowrite; +results_out{1,3} = 'is_gather'; % 1 is yes, 0 is no + + +% for the stack output +results_out2{1,1} = 'Meta data for output files'; +results_out2{1,2}{1,1} = results_out{1,2}{1,1}(1:n_traces_gather:end,:); +results_out2{1,2}{2,1} = int32(zeros(n_traces,1)); +%ebcstrtowrite = sprintf('%-3200.3200s',[results_out{resultno,1} ' ' ebdichdr ' ' tmpebc]); +results_out2{1,1} = ebcstrtowrite; +results_out2{1,3} = 'is_gather'; % 1 is yes, 0 is no + +output_dir = [job_meta.output_dir,'trimout/']; +% check to see if the directory exists +if exist(output_dir,'dir') == 0 + mkdir(output_dir); +end + + +% prestack output +filename = 'gaths'; +results_out{2,1} = strcat(filename,'_trim_data_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +%results_out{2,2} = zeros(n_samples,n_traces_gather,n_traces,'single'); +%commented out as written to above +results_out{2,3} = 1; + +if outputgathershifts == 1; + results_out{3,1} = strcat(filename,'_trim_shifts_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); + results_out{3,3} = 1; + results_out{3,2} = zeros(in_n_samples,n_traces_gather,n_traces,'single'); +end + + + +% stack result +filename2 = 'stack'; +results_out2{2,1} = strcat(filename2,'_trim_sum_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +results_out2{2,2} = zeros(in_n_samples,n_traces,'single'); +results_out2{3,1} = strcat(filename2,'_pretrim_guide_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +results_out2{3,2} = zeros(in_n_samples,n_traces,'single'); +%results_out2{4,1} = strcat(filename2,'_posttrim_no_resid_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +results_out2{4,1} = strcat(filename2,'_posttrim_guide_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +results_out2{4,2} = zeros(in_n_samples,n_traces,'single'); +results_out2{5,1} = strcat(filename2,'_posttrim_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +results_out2{5,2} = zeros(in_n_samples,n_traces,'single'); +results_out2{6,1} = strcat(filename2,'_pretrim_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +results_out2{6,2} = zeros(in_n_samples,n_traces,'single'); +results_out2{2,3} = 0; +results_out2{3,3} = 0; +results_out2{4,3} = 0; +results_out2{5,3} = 0; +results_out2{6,3} = 0; +% ======================================================================== +% flattern the data to the water bottom and make a stack of the data for +% freq analysis + +% stack to make something to pick wb on +stackin_freq = sum(results_out{2,2}(:,startvol:midtrc,:),2) ./ ((midtrc - startvol) +1) ; +% pick wb +%[wb_idx] = water_bottom_picker(stackin_freq,padding); +[wb_idx] = water_bottom_picker(squeeze(stackin_freq),padding); +wb_idx(wb_idx < 0) = 1; +% write out a wbpick +%ilxltoprint = results_out{1,2}{1,1}(1:length(offset):end,:); +% only write out the values that are not 1, so are picked +%dlmwrite(strcat(output_dir,'wbpick_',i_block,'.xyz'),[ilxltoprint((wb_idx ~= 1)',:),(int32(wb_idx(wb_idx ~= 1)+padding)'.*job_meta.s_rate)/1000],'delimiter', ' ', 'precision', '%-6d','newline', 'unix'); +% +win_sub = bsxfun(@plus,wb_idx,(0:n_samples-max(wb_idx))'); +win_ind = bsxfun(@plus,win_sub,(0:n_samples:n_samples*(n_traces-1))); +clear win_sub; +% make anew stack after flattening, make sure to blank it before +stackin_freq2 = stackin_freq(win_ind); +%stackin_freq2 = time_balence_stk(stackin_freq2); +[n_samples,~] = size(stackin_freq2); +clear win_ind stackin_freq; +% +% ======================================================================== +% find the dominant frequency of the data, take a subset of the data and +% average freqs down the trace +start_index = 1:ns_win-ns_overlap-1:n_samples-ns_win; +end_index = start_index+ns_win-1; +freq_axis = (1e6/job_meta.s_rate)/2*linspace(0,1,ns_win/2); +n_win = length(start_index); +peak_freq = zeros(n_win,2); +min_freq = zeros(n_win,2); +gathinc = ceil(n_traces/20); +% make taper to apply to signal before fft +taperlen = 16; +%taperst = linspace(0,1,taperlen)'; +taperst = (sin(linspace((-pi/2),(pi/2),taperlen)')+1)/2; +taperend = 1 - taperst; +taperapply = [taperst;ones((ns_win-(taperlen*2)),1);taperend]; +filt_smof = ones(1,9)/9; +% +for ii = 1:n_win + % Estimate wavelets and store meta information + % make a tmp array with the fft values in it + tmpfft = zeros(2,2); + tmpfft = abs(fft(bsxfun(@times,stackin_freq2(start_index(ii):end_index(ii),:),taperapply))); + avgfreq = sum(tmpfft,2,'double'); + avgfreqsmo = conv(avgfreq(1:hns_win),filt_smof,'same'); + %figure(12); plot(avgfreqsmo); + cja = (avgfreqsmo > max(avgfreqsmo)*0.75); + [~,rhs] = max(cja(end:-1:1)); + [~,lowf_idx] = max(cja(1:1:end)); + highf_idx = (hns_win - rhs) + 1; + %[~,idxf] = max(avgfreqsmo); + %peak_freq(ii,:) = [(start_index(ii)+hns_win) ((peak_freq(ii,2)+freq_axis(highf_idx)))]; + peak_freq(ii,:) = [(start_index(ii)+hns_win) max(peak_freq(ii,2),freq_axis(highf_idx))]; + min_freq(ii,:) = [(start_index(ii)+hns_win) max(min_freq(ii,2),freq_axis(lowf_idx))]; + mid_freq(ii,:) = [(start_index(ii)+hns_win) (min_freq(ii,2)+((peak_freq(ii,2) - min_freq(ii,2) )*0.65))]; +end +% +% ========================================================================= +%see if the code can resample the data down to calculate shifts at +resamp_rt = round(1000 /(max(mid_freq(:,2))*2)); +use_samp_drop = 0; +wb_n_samples = n_samples; +orig_sample_rate = sample_rate; +time = repmat((0:sample_rate:(n_samples-1)*sample_rate)',1,n_traces_gather); +if resamp_rt > (sample_rate * 1.8) + samp_drop = round(resamp_rt/(sample_rate*1.8) + 0.1); + sample_rate = sample_rate * samp_drop; + ufoff = 1000/(sample_rate*2); + ufon = ufoff*0.8; + n_samples = length(1:samp_drop:n_samples); + peak_freq((peak_freq(:,2) > ufoff),2) = ufoff; + totmaxshift = ceil(sample_rate/1.5); % was 2.5 and 3 before + use_samp_drop = 1; +end +time_sub = (0:sample_rate:(n_samples-1)*sample_rate); +% +% for jj = 1:gathinc:n_traces; +% freq_test = results_out{2,2}(:,sttrc:midtrc,jj); +% %freq_test = time_balence(freq_test); +% +% for ii = 1:n_win +% % Estimate wavelets and store meta information +% % make a tmp array with the fft values in it +% tmpfft = zeros(2,2); +% tmpfft = abs(fft(bsxfun(@times,freq_test(start_index(ii):end_index(ii),:),taperapply))); +% avgfreq = sum(tmpfft,2,'double'); +% avgfreqsmo = conv(avgfreq(1:hns_win),filt_smof,'same'); +% %figure(12); plot(avgfreqsmo); +% cja = (avgfreqsmo > max(avgfreqsmo)*0.75); +% [~,rhs] = max(cja(end:-1:1)); +% highf_idx = (hns_win - rhs) + 1; +% %[~,idxf] = max(avgfreqsmo); +% %peak_freq(ii,:) = [(start_index(ii)+hns_win) ((peak_freq(ii,2)+freq_axis(highf_idx)))]; +% peak_freq(ii,:) = [(start_index(ii)+hns_win) max(peak_freq(ii,2),freq_axis(highf_idx))]; +% end +% end +%peak_freq(:,2) = peak_freq(:,2)/n_win; +% +% ======================================================================== +% calculate the shift limits and the smoothing for the trim, currently +% the wavelength at the peak freq at 2000m/s divided by 30 +max_shift = [peak_freq(:,1) (avg_vel./(peak_freq(:,2)*42))]; +% smooth the shifts +%filt_smos = ones(1,3)/3; +%max_shift = conv(max_shift,filt_smos,'same'); +% ======================================================================== +% set the shift increment from the sample rate +shiftinc = sample_rate/30; % this leads to floating point rounding errors +%shiftincloc = floor((sample_rate*10000)/30); + + +max_shiftstk = max_shift; +max_shiftstk(:,2) = max_shiftstk(:,2).*4; % was 3 before this allows the residual to do more + +% clip the max shifts +max_shift((max_shift(:,2) > totmaxshift),2) = totmaxshift; +max_shiftstk((max_shiftstk(:,2) > totmaxshift),2) = (totmaxshift); + +% set the maxshift to an increment of shiftinc +max_shift(:,2) = floor(max_shift(:,2)./shiftinc)*shiftinc; +max_shiftstk(:,2) = floor(max_shiftstk(:,2)./shiftinc)*shiftinc; + +% calculate the length of the smoother, currently 10 times the shift value +freq_grid = [max_shift(:,1) floor(max_shift(:,2).*smoothing_scaler)]; + +%shift = max(max_shift(:,2)); +shift = max(max_shiftstk(:,2)); + +%totmaxshift = shift; +% find the max shift to calculate +% if totmaxshift >= shift +% totmaxshift = shift; +% else +% shift = totmaxshift; +% end + +% % clip the max shifts +% max_shift((max_shift(:,2) > totmaxshift),2) = totmaxshift; +% max_shiftstk((max_shiftstk(:,2) > totmaxshift),2) = (totmaxshift); % should multiple by 1.5 at some point, but need to update shift; + +totnumshifts = length(-shift:shiftinc:shift); + +%now make the time varying smoothing as a diagonal on a matrix S +%freq_grid2 = [30 11; 300 21; 900 31]; + +totalpts = max(freq_grid(:,2)); +for mm = 1:size(freq_grid,1) + freq_interp_grid(mm,:) = [zeros(1,(totalpts-freq_grid(mm,2))) , 0:(totalpts/freq_grid(mm,2)):totalpts , (totalpts-(totalpts/freq_grid(mm,2))):-(totalpts/freq_grid(mm,2)):0 , zeros(1,(totalpts-freq_grid(mm,2))) ]; + + %shift_interp_grid(mm,:) = [[zeros(1,round(shift/shiftinc-((max_shift(mm,2)/shiftinc)))) , ones(1,round(max_shift(mm,2)/shiftinc))],1,fliplr([zeros(1,round(shift/shiftinc-(max_shift(mm,2)/shiftinc))) , ones(1,round(max_shift(mm,2)/shiftinc))])]; + shift_interp_grid(mm,:) = [[zeros(1,round((round((shift/shiftinc)*10000) - round((max_shift(mm,2)/shiftinc)*10000))/10000)), ones(1,(round((max_shift(mm,2))/shiftinc)*10000)/10000)],1,fliplr([zeros(1,round((round((shift/shiftinc)*10000) - round((max_shift(mm,2)/shiftinc)*10000))/10000)), ones(1,(round((max_shift(mm,2))/shiftinc)*10000)/10000)])]; + + shift_interp_gridstk(mm,:) = [[zeros(1,round((round((shift/shiftinc)*10000) - round((max_shiftstk(mm,2)/shiftinc)*10000))/10000)), ones(1,(round((max_shiftstk(mm,2))/shiftinc)*10000)/10000)],1,fliplr([zeros(1,round((round((shift/shiftinc)*10000) - round((max_shiftstk(mm,2)/shiftinc)*10000))/10000)), ones(1,(round((max_shiftstk(mm,2))/shiftinc)*10000)/10000)])]; + + + %shift_interp_grid(mm,:) = [[zeros(1,round(shift/shiftinc-((max_shift(mm,2)/shiftinc)))) , ones(1,round(max_shift(mm,2)/shiftinc))],1,fliplr([zeros(1,round(shift/shiftinc-(max_shift(mm,2)/shiftinc))) , ones(1,round(max_shift(mm,2)/shiftinc))])]; + %shift_interp_gridstk(mm,:) = [[zeros(1,round(shift/shiftinc-((max_shiftstk(mm,2)/shiftinc)))) , ones(1,round((max_shiftstk(mm,2))/shiftinc))],1,fliplr([zeros(1,round(shift/shiftinc-((max_shiftstk(mm,2))/shiftinc))) , ones(1,round((max_shiftstk(mm,2))/shiftinc))])]; + %shift_interp_grid(mm,:) = [[zeros(1,(shift/shiftinc-(max_shift(mm,2)/shiftinc))) , ones(1,max_shift(mm,2)/shiftinc)],1,fliplr([zeros(1,(shift/shiftinc-(max_shift(mm,2)/shiftinc))) , ones(1,max_shift(mm,2)/shiftinc)])]; + %shift_interp_gridstk(mm,:) = [[zeros(1,(shift/shiftinc-((max_shiftstk(mm,2)/shiftinc)))) , ones(1,(max_shiftstk(mm,2))/shiftinc)],1,fliplr([zeros(1,(shift/shiftinc-((max_shiftstk(mm,2))/shiftinc))) , ones(1,(max_shiftstk(mm,2))/shiftinc)])]; +end +start_interp = 1; +end_interp = n_samples; +freq_zgrid = freq_grid(:,1); + +if freq_grid(1,1) > 1 + freq_zgrid = [1; freq_zgrid]; + freq_interp_grid = [ freq_interp_grid(1,:) ; freq_interp_grid]; + shift_interp_grid = [ shift_interp_grid(1,:) ; shift_interp_grid]; + shift_interp_gridstk = [ shift_interp_gridstk(1,:) ; shift_interp_gridstk]; +end +if freq_grid(end,1) < n_samples + freq_zgrid(end+1) = n_samples; + freq_interp_grid(end+1,:) = freq_interp_grid(end,:); + shift_interp_grid(end+1,:) = shift_interp_grid(end,:); + shift_interp_gridstk(end+1,:) = shift_interp_gridstk(end,:); +end + +%make the array to go down the diagonal as a smoother +diag_smo_interp = interp1(freq_zgrid,freq_interp_grid,start_interp:1:end_interp,'linear'); +S = (1/totalpts)*spdiags(diag_smo_interp,[(-totalpts:1:0),(1:1:totalpts)], n_samples,n_samples); + +% now make a smaller smoother +dropf = 3; +dropfsel = [(totalpts + 1) - ((length((totalpts + 1:dropf:(totalpts*2)+1)) -1)*dropf):dropf:totalpts, (totalpts + 1:dropf:(totalpts*2)+1)]; +%droprows = [(-round(totalpts/dropf):1:0),(1:1:round(totalpts/dropf))]; +droprows = [(-round((length(dropfsel) -1)/2):1:0),(1:1:round((length(dropfsel) -1)/2))]; +S2 = (1/totalpts)*spdiags(diag_smo_interp(:,dropfsel),droprows, n_samples,n_samples); + +diag_smo_interp3 = interp1(freq_zgrid,freq_interp_grid,start_interp:1:wb_n_samples,'linear'); +%S3 = (1/totalpts)*spdiags(diag_smo_interp3(:,dropfsel),droprows, wb_n_samples,wb_n_samples); +S3 = (1/totalpts)*spdiags(diag_smo_interp3,[(-totalpts:1:0),(1:1:totalpts)], wb_n_samples,wb_n_samples); + +% make a mask to apply to the shifts before picking the peak +shift_mask = interp1(freq_zgrid,shift_interp_grid,start_interp:1:end_interp,'linear'); + +shift_interp_gridstk = interp1(2:2:(totnumshifts*2),shift_interp_gridstk',1:((totnumshifts*2)+1),'linear'); +shift_interp_gridstk(isnan(shift_interp_gridstk)) = 0; +shift_maskstk = interp1(freq_zgrid,shift_interp_gridstk',start_interp:1:wb_n_samples,'linear'); +shift_mask(shift_mask<1) = 0; +shift_maskstk(shift_maskstk<1) = 0; +% ============================================================================================================ +% loop round the traces 3d array one gather at a time and do calculations +f_max = (1/sample_rate)*1000; +phase_shifts = bsxfun(@times,(-shift:shiftinc:shift),(1/1000).*2.*pi.*repmat((0:f_max/(n_samples-1):f_max)',1,1+2*round((shift/shiftinc)))); + +f_maxorig = (1/orig_sample_rate)*1000; +phase_shifts_orig = bsxfun(@times,(-shift:shiftinc:shift),(1/1000).*2.*pi.*repmat((0:f_maxorig/(wb_n_samples-1):f_maxorig)',1,1+2*round((shift/shiftinc)))); + +totnumshifts = length(-shift:shiftinc:shift); +%S = (1/zsmooth)*spdiags(repmat([(1:1:zsmooth),(zsmooth-1:-1:1)],n_samples,1),[(-zsmooth+1:1:0),(1:1:zsmooth-1)],n_samples,n_samples); +%S2 = (1/zsmooth2)*spdiags(repmat([(1:1:zsmooth2),(zsmooth2-1:-1:1)],n_samples,1),[(-zsmooth2+1:1:0),(1:1:zsmooth2-1)],n_samples,n_samples); +det_coef = zeros(n_samples,totnumshifts); +det_coefb = zeros(n_samples,totnumshifts); + +%filttraces = [1 2 3 3 3 3 3 3 3 2 1]/27; +filttraces = [1 2 3 3 2 1]/12; +filt_smo = [1 2 1]/4; +filt_smo2 = ones(1,5)/5; +idxshift = round((shift/shiftinc))+1; + +% initialise zeros in output +trim_shift = zeros(n_samples,n_traces_gather,'single'); +trim_shiftb = zeros(n_samples,n_traces_gather,'single'); +trim_shiftb_out = zeros(wb_n_samples,n_traces_gather,'single'); +wt_taperapply = [taperst;ones((wb_n_samples-(taperlen*2)),1);taperend]; +det_coef3 = zeros(wb_n_samples,length(2:2:totnumshifts) ); +norm_fold_b = zeros(wb_n_samples,1,'single'); +norm_fold = zeros(wb_n_samples,1,'single'); +% +for kk = 1:n_traces; +%for kk = 1:200; + if useselectemode == 0 + requiredinline = results_out{1,2}{1,1}(kk,1); + end + if results_out{1,2}{1,1}(kk,1) == requiredinline; + + + % get the input gather and apply shift to flattern to the water bottom + trim_data = results_out{2,2}(wb_idx(kk):(wb_idx(kk)+wb_n_samples-1),:,kk); + + % apply an automatic mute to remove low amp noise + fmask = low_amp_mute(trim_data); + trim_data = trim_data .* fmask; + + %drop samples if possible + if use_samp_drop == 1 + trim_data_filt = bsxfun(@times,trim_data,wt_taperapply); + trim_data_filt = bandpass_filter(trim_data_filt,(sample_rate/1000),0,0,ufon,ufoff); + trim_data_filt = trim_data_filt(1:samp_drop:end,:); + mask = fmask(1:samp_drop:end,:); + else + trim_data_filt = trim_data; + mask = fmask; + end + + % balence the data to avoid any loud parts dominating any solution + if timbal == 1 + trim_data_filtin = trim_data_filt; + [trim_data_filt scaleused] = time_balence(trim_data_filt); + end + + %trim_data = trim_data_filt; + %trim_data_filt = bandpass_filter(d,dt,f1,f2,f3,f4); + + if plots == 1; figure(101); imagesc(trim_data_filt); colormap(gray); caxis([-4000 4000]); end; + + % apply a small smoother to reduce noise + if itm > 0 + mask(:,1:itm) = 0; + trim_data_filt(:,1:itm) = repmat(trim_data_filt(:,(itm+1)),1,itm); + end + if otm > 0 + mask(:,otm:end) = 0; + trim_data_filt(:,otm:n_traces_gather) = repmat(trim_data_filt(:,(otm-1)),1,(n_traces_gather-otm)+1); + end + + % apply a small smoother to reduce noise + %trim_data_filt = medfilt3nt(trim_data_filt,[0 9],0); + trim_data_filt = conv2(filt_smo,filttraces,trim_data_filt,'same'); + + if plots == 1; figure(106); imagesc(trim_data_filt); colormap(gray); caxis([-4000 4000]); end; + + %apply mask to the filtered data to remove duplicated data + trim_data_filt = trim_data_filt .* mask; + + % flip the data to work from outside in + trim_data_filt = fliplr(trim_data_filt); + + for ii = sttrc:edtrc + t1 = double(trim_data_filt(:,ii-1)); + T1 = S*spdiags(t1,0,n_samples,n_samples); + T1b = S2*spdiags(t1,0,n_samples,n_samples); + + %t2 = double(trim_data_filt(:,ii)); + t2f = fft(double(trim_data_filt(:,ii))); + t2_shifts = ifft(bsxfun(@times,t2f,exp(1i*phase_shifts)),'symmetric'); + + for count = 1:totnumshifts + %T2 = S*spdiags(t2_shifts(:,count),0,n_samples,n_samples); + T2diag = spdiags(t2_shifts(:,count),0,n_samples,n_samples); + %sparse + T2 = S*T2diag; + T2b = S2*spdiags(t2_shifts(:,count),0,n_samples,n_samples); + det_coef(:,count) = ((T1*t2_shifts(:,count)).*(T2*t1))./((T1*t1).*(T2*t2_shifts(:,count))); + det_coefb(:,count) = ((T1b*t2_shifts(:,count)).*(T2b*t1))./((T1b*t1).*(T2b*t2_shifts(:,count))); + end + % add in a taper to zero out large shifts in the shallow before picking + % the max + det_coef = det_coef.*shift_mask; + %det_coefb = det_coefb.*shift_mask; + % cj edit took out the mask as it was making steps in the + % results + if plots == 1; figure(205); imagesc(det_coef); caxis([0.8 1]); end; + if plots == 1; figure(206); imagesc(det_coefb); caxis([0.8 1]); end; + %[~,idx] = max(det_coef'); + %trim_shift(:,ii-1) = idx'-shift-1; + [~,idx]= max(det_coef,[],2); + [~,idxb]= max(det_coefb,[],2); + + if plots == 1; figure; plot(idx,length(det_coef):-1:1); end; + if plots == 1; figure; plot(idxb,length(det_coef):-1:1); end; + + trim_shift(:,ii) = (idx-idxshift)*shiftinc; + trim_shiftb(:,ii) = (idxb-idxshift)*shiftinc; + %trim_shift(:,ii-1) = idx-shift-1; + + end + + maskb = [ones(n_samples,1,'single'),mask(:,1:(end -1))] .* [mask(:,2:end),ones(n_samples,1,'single')]; + trim_shift = [trim_shift(:,1),fliplr(trim_shift(:,2:end))].* maskb; + trim_shiftb = [trim_shiftb(:,1),fliplr(trim_shiftb(:,2:end))].* maskb; + %trim_shift = trim_shift .* maskb; + %trimfold = max(cumsum(maskb,2),[],2); + %figure; + if plots == 1; figure(91); imagesc(trim_shift); caxis([-5 5]); end; + if plots == 1; figure(90); imagesc(trim_shiftb); caxis([-5 5]); end; + %imagesc(trim_shiftb); + + %trim_sum = sum(abs(trim_shift(:,startvol:endvol)),2) ./ max(cumsum(maskb(:,startvol:endvol),2),[],2); + % trim_shiftcj = trim_shift; + %trim_datacj = trim_data; + + trim_shift = cumsum(trim_shift,2); + trim_shift = conv2(filt_smo2,filt_smo,trim_shift,'same'); + trim_shift = trim_shift .* mask; + %trim_shift(data==0) = 0; + % trim_sum = sum(trim_shift,2); + %n = length(trim_shift); + %trim_sum = sqrt((1/n)*sum((trim_shift.^2),2)); + + + % normalise the sum of the shifts for the fold in case we have + % difference in fold + norm_fold_b = max(cumsum(fmask(:,startvol:endvol),2),[],2); + norm_fold = max(cumsum(fmask(:,startvol:midtrc),2),[],2); + norm_fold_b(norm_fold_b == 0) = 1; + norm_fold(norm_fold == 0) = 1; + + %tf %stackin = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(maskb(:,startvol:endvol),2),[],2); + stackin = sum(trim_data(:,startvol:midtrc),2) ./ norm_fold; + stackinb = sum(trim_data(:,startvol:endvol),2) ./ norm_fold_b; + %stackin = sum(trim_data(:,startvol:midtrc),2) ./ max(cumsum(fmask(:,startvol:midtrc),2),[],2); + %stackinb = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(fmask(:,startvol:endvol),2),[],2); + + + %if plots == 2; ilplotin(:,kk) = stackin; end + ftrim_shift = interp1(time_sub,trim_shift,time(:,1),'linear',0); + ftrim_shiftb = interp1(time_sub,trim_shiftb,time(:,1),'linear',0); + + for ii = 1:n_traces_gather + trim_data(:,ii) = interp1(time(:,ii),trim_data(:,ii),time(:,ii)-ftrim_shift(:,ii),'linear',0); + %trim_data(:,ii) = interp1q(time(:,ii),trim_data(:,ii),time(:,ii)-trim_shift(:,ii)); + + %trim_datab(:,ii) = interp1(time(:,ii),trim_data(:,ii),time(:,ii)-trim_shift(:,ii),'spline',0); + trim_shiftb_out(:,ii) = interp1(time(:,ii),ftrim_shiftb(:,ii),time(:,ii)-ftrim_shift(:,ii),'linear',0); + end + + % % % cj test version of shifts ======================== + % zoom3 = 600; + % zoom4 = 1000; + % % figure(108); imagesc(trim_datacj(zoom3:zoom4,:)) ; colormap(gray); caxis([-50 50]); + % % trim_datacjb = trim_datacj; + % % trim_datacj = fliplr(trim_datacj); + % % trim_shiftcj = fliplr(trim_shift); + % % + % % % for ii = 2:n_traces_gather + % % % for jj = 1:ii + % % % trim_datacj(:,jj) = interp1(time(:,1),trim_datacj(:,jj),time(:,1)-trim_shiftcj(:,ii),'linear',0); + % % % end + % % % end + % % + % % for ii = 2:n_traces_gather + % % trim_datacj(:,1:ii) = interp1(time(:,1),trim_datacj(:,1:ii),time(:,ii)-trim_shiftcj(:,ii),'linear',0); + % % end + % % trim_datacj = fliplr(trim_datacj); + % % %trim_shiftcj = fliplr(trim_shiftcj); + % figure(109); imagesc(trim_datacj(zoom3:zoom4,:)) ; colormap(gray); caxis([-500000 500000]); + % figure(119); imagesc(trim_datacj) ; colormap(gray); caxis([-500000 500000]); + % % figure(110); imagesc(trim_datacjb(zoom3:zoom4,:) - trim_datacj(zoom3:zoom4,:) ) ; colormap(gray); caxis([-20 20]); + % % figure(112); imagesc(trim_datacjb(zoom3:zoom4,:) - trim_data(zoom3:zoom4,:) ) ; colormap(gray); caxis([-20 20]); + % figure(121); imagesc(trim_data(zoom3:zoom4,:)) ; colormap(gray); caxis([-500000 500000]); + % figure(111); imagesc(trim_data) ; colormap(gray); caxis([-500000 500000]); + % % =================================================== + + + if plots == 1; + figure(102); imagesc(time_balence(trim_data)); colormap(gray); caxis([-4000 4000]); + figure(103); imagesc(trim_data); colormap(gray); + end; + + % normalise the sum of the shifts for the fold in case we have + % difference in fold +% norm_fold_b = max(cumsum(fmask(:,startvol:endvol),2),[],2); +% norm_fold = max(cumsum(fmask(:,startvol:midtrc),2),[],2); +% norm_fold_b(norm_fold_b == 0) = 1; +% norm_fold(norm_fold == 0) = 1; + + %tf %trim_sum = sum(abs(trim_shiftb_out(:,startvol:endvol)),2) ./ max(cumsum(maskb(:,startvol:endvol),2),[],2); + trim_sum = sum(abs(trim_shiftb_out(:,startvol:endvol)),2) ./ norm_fold_b; + %trim_sum = sum(abs(trim_shiftb_out(:,startvol:endvol)),2) ./ max(cumsum(fmask(:,startvol:endvol),2),[],2); + %trim_sum = sum(abs(trim_shiftb_out(:,startvol:endvol)),2); + if plots == 1; figure(109); imagesc(trim_shiftb_out); caxis([-5 5]); end; + + %tf %stackout = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(maskb(:,startvol:endvol),2),[],2); + stackout = sum(trim_data(:,startvol:midtrc),2) ./ norm_fold; + %stackout = sum(trim_data(:,startvol:midtrc),2) ./ max(cumsum(fmask(:,startvol:midtrc),2),[],2); + %stackout = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(fmask(:,startvol:endvol),2),[],2); + + % ================================================================= + % now add a section to apply a residual trim static to the whole gather + % based on the mismatch between the stacks before and after trim and + % then repeat the final stack + + st1 = double(time_balence_stk(stackin)); + sT1 = S3*spdiags(st1,0,wb_n_samples,wb_n_samples); + + st2 = double(time_balence_stk(stackout)); + st2_shifts = ifft(bsxfun(@times,fft(st2),exp(1i*phase_shifts_orig)),'symmetric'); + % for count = 1:totnumshifts + % sT2 = S3*spdiags(st2_shifts(:,count),0,wb_n_samples,wb_n_samples); + % det_coef5(:,count) = ((sT1*st2_shifts(:,count)).*(sT2*st1))./((sT1*st1).*(sT2*st2_shifts(:,count))); + % + % end + + + countr = 1; + + for count = 2:2:totnumshifts + sT2 = S3*spdiags(st2_shifts(:,count),0,wb_n_samples,wb_n_samples); + det_coef3(:,countr) = ((sT1*st2_shifts(:,count)).*(sT2*st1))./((sT1*st1).*(sT2*st2_shifts(:,count))); + countr = countr +1; + end + det_coef3(isnan(det_coef3)) = 0; + det_coef4 = interp1(4:4:(totnumshifts*2),det_coef3',1:( ((totnumshifts-1)/2)*4 + 3 ),'spline'); + % add in a taper to zero out large shifts in the shallow before picking + % the max + det_coef4 = det_coef4'.*shift_maskstk; + [~,stkidx]= max(det_coef4,[],2); + stack_shift = (stkidx-(idxshift*2))*(shiftinc/2); + + trim_data(:,1:n_traces_gather) = interp1(time(:,1),trim_data(:,1:n_traces_gather),time(:,1)+stack_shift(:,1),'linear',0); + + + stackoutb = sum(trim_data(:,startvol:endvol),2) ./ norm_fold_b; + stackout = sum(trim_data(:,startvol:midtrc),2) ./ norm_fold; + %stackoutb = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(fmask(:,startvol:endvol),2),[],2); + %stackout = sum(trim_data(:,startvol:midtrc),2) ./ max(cumsum(fmask(:,startvol:midtrc),2),[],2); + % ================================================================= + + if plots == 2; ilplot(:,kk) = stackout; end + %ilplotb(:,kk) = stackoutb; + if outputgathershifts == 1; + results_out{3,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,:,kk) = ftrim_shift; + end + results_out{2,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,:,kk) = trim_data; + results_out2{2,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = trim_sum; + results_out2{3,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = stackin; + results_out2{4,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = stackout; + results_out2{5,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = stackoutb; + results_out2{6,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = stackinb; + + end +end + +if plots == 2; + zoom1 = 400; + zoom2 = 800; + %figure(102); imagesc((ilplotb(500:700,:) - ilplot(500:700,:))); colormap(gray); caxis([-100 100]) + %figure(101); imagesc(ilplotb(zoom1:zoom2,:)); colormap(gray); caxis([-200 200]) + figure(100); imagesc(ilplot(zoom1:zoom2,:)); colormap(gray); caxis([-200 200]) + figure(103); imagesc(ilplotin(zoom1:zoom2,:)); colormap(gray); caxis([-200 200]) + figure(102); imagesc((ilplotin(zoom1:zoom2,:) - ilplot(zoom1:zoom2,:))); colormap(gray); caxis([-100 100]) + %figure(104); imagesc((ilplotin(zoom1:zoom2,:) - ilplotb(zoom1:zoom2,:))); colormap(gray); caxis([-100 100]) + figure(105); imagesc(results_out2{2,2}(zoom1:zoom2,1:kk)) + if outputgathershifts == 1; + figure(107); imagesc(squeeze(results_out{3,2}(zoom1:zoom2,36,1:kk))) + end + figure(108); imagesc(reshape(results_out{2,2}(zoom1:zoom2,:,1:50:kk),(zoom2-zoom1+1),[])); colormap(gray); caxis([-100 100]); +end + +% need to reshape the 2 3d matricies into 2d ones as the segy write just wants samples * total traces +results_out{2,2} = reshape(results_out{2,2},in_n_samples,[]); +if outputgathershifts == 1; + results_out{3,2} = reshape(results_out{3,2},in_n_samples,[]); +end + + + + +i_block = str2double(i_block); +% write the pre-stack dataset +if outputflatgathers == 1; + node_segy_write(results_out,i_block, orig_sample_rate, output_dir) +end +% write the stack +node_segy_write(results_out2,i_block, orig_sample_rate, output_dir) + +end diff --git a/algorithms/trim_calculation/trim_calculation.m~ b/algorithms/trim_calculation/trim_calculation.m~ new file mode 100644 index 0000000..7a30244 --- /dev/null +++ b/algorithms/trim_calculation/trim_calculation.m~ @@ -0,0 +1,740 @@ +function [] = trim_calculation(job_meta_path,i_block,startvolr,endvolr,shift,zsmooth,itmr,otmr,timbal,outputflatgathers) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +%% Function Description +% this works out and applies trim statics and keeps a sum of the statics +% for each z sample +% Input: +% job_meta_path: Path to job meta file +% i_block: The current Block Number +% startvol: The smallest angle trace to load to make the stack for stack alignment +% endvol: The largest angle trace to load to make the stack for stack alignment +% shift: Maximum allowable shift in samples ?? +% zsmooth : Smoother ?? Not used? +% itmr: Inner Trace Mute for the trim zone, this is what is output in prestack gathers +% otmr: Outer Trace Mute for the trim zone, this is what is output in prestack gathers +% timbal: Flag to balence the data to avoid any loud parts dominating any solution. Use '1' for yes, '0' for no +% outputflatgathers: Flag to output the prestack flatterned data. Use '1' for yes, '0' for no +% +% Output: +% Void Output +% +% Writes to Disk: +% Everything gets written in .../trimout/*. The written out items are: +% +% +% +% +% +% +% ============================================================================================================ +%% +% sort out parameters +smoothing_scaler = 8; % normally 10 +startvolr = str2double(startvolr); +endvolr = str2double(endvolr); +otmr = str2double(otmr); +itmr = str2double(itmr); +timbal = str2double(timbal); +shift = str2double(shift); +useselectemode = 0; +%outputflatgathers = 1; % 1 outputs the prestack flatterned data, 0 does not +outputflatgathers = str2double(outputflatgathers); + +outputgathershifts = 0; % 1 outputs the prestack shifts, 0 does not +% +if isempty(regexp(zsmooth,'il','once')) == 0 + useselectemode = 1; + requiredinline = str2double(regexprep(zsmooth,'il','')); + %requiredinline = str2double(strrep(tottracerun,'il','')); + zsmooth = 20; +else + zsmooth = str2double(zsmooth); +end + +% zsmooth = str2double(zsmooth); +%zsmooth2 = shift*2; +% if zsmooth2 < 7 +% zsmooth2 = 7; +% end +% shiftinc = 0.5; now set in the code from the new sample rate +plots = 0; +padding = 50; +% Wavelet estimation parameters +ns_win = 128; +hns_win = ns_win/2; +ns_overlap = 96; +totmaxshift = 5; +avg_vel = 2500; +% ============================================================================================================ +% load the job meta file containing more parameters +job_meta = load(job_meta_path); +sample_rate = (job_meta.s_rate/1000); +% add the history of jobs run and this one to the curent ebcdic +ebdichdr = ['trim statics ']; +if isfield(job_meta,'comm_history') + ebdichdr2 = job_meta.comm_history; + tmpebc = ebdichdr2{size(ebdichdr2,1),2}; +else + ebdichdr2{1,2} = ''; + tmpebc = ''; +end + +for ebcii = (size(ebdichdr2,1)-1):-1:1 + tmpebcc = regexp(ebdichdr2{ebcii,2},'/','split'); + tmpebc = [tmpebc tmpebcc{1} tmpebcc{end}]; +end +tmpebc = sprintf('%-3200.3200s',tmpebc); +clear tmpebcc ebdichdr2; +% +% ============================================================================================================ +% Read the data for this block + +% [~, traces, ilxl_read, offset_read] = node_segy_read(job_meta_path,'1',i_block); +% offset = unique(offset_read); +% traces = reshape(traces,size(traces,1),length(offset),[]); +% +% [n_samples,n_traces_gather,n_traces] = size(traces); + +[seismic, results_out{2,2}, results_out{1,2}{1,1}, offset_read] = node_segy_read(job_meta_path,'1',i_block); +offset = unique(offset_read); +results_out{2,2} = reshape(results_out{2,2},size(results_out{2,2},1),length(offset),[]); + +% put itmr and otmr into sequential trace numbers in the gather +itm = find(offset <= itmr,1,'last'); +otm = find(offset <= otmr,1,'last'); + +% put startvolr and endvolr into sequential trace numbers in the gather +startvol = find(offset <= startvolr,1,'last'); +endvol = find(offset <= endvolr,1,'last'); + + +% check to make sure it read something if not exit +if isempty(results_out{2,2}) == 1 && isempty(results_out{1,2}{1,1}) == 1 && isempty(offset_read) == 1 + return +end + +% drop data as required +% order is samples, angles, skeys +% results_out{2,2} = results_out{2,2}(1:maxzout,:,:); +% job_meta.n_samples{1} = maxzout; + +%results_out{1,2}{1,1} + +[n_samples,n_traces_gather,n_traces] = size(results_out{2,2}); +in_n_samples = n_samples; + +% apply any itm and otm to the gathers +sttrc = 2; +edtrc = n_traces_gather; +if itm > 0 + results_out{2,2}(:,1:itm,:) = 0; + edtrc = (n_traces_gather - itm); +end +if otm > 0 + results_out{2,2}(:,otm:end,:) = 0; + sttrc = (n_traces_gather - otm) + 2; +end +midtrc = startvol + floor((endvol - startvol)/2); +% ============================================================================================================ +% Make results meta information + +% for the pre-stack dataset +results_out{1,1} = 'Meta data for output files'; +%results_out{resultno,2}{1,1} = ilxl_read; +results_out{1,2}{2,1} = offset_read'; +ebcstrtowrite = sprintf('%-3200.3200s',[results_out{1,1} ' ' ebdichdr ' ' tmpebc]); +results_out{1,1} = ebcstrtowrite; +results_out{1,3} = 'is_gather'; % 1 is yes, 0 is no + + +% for the stack output +results_out2{1,1} = 'Meta data for output files'; +results_out2{1,2}{1,1} = results_out{1,2}{1,1}(1:n_traces_gather:end,:); +results_out2{1,2}{2,1} = int32(zeros(n_traces,1)); +%ebcstrtowrite = sprintf('%-3200.3200s',[results_out{resultno,1} ' ' ebdichdr ' ' tmpebc]); +results_out2{1,1} = ebcstrtowrite; +results_out2{1,3} = 'is_gather'; % 1 is yes, 0 is no + +output_dir = [job_meta.output_dir,'trimout/']; +% check to see if the directory exists +if exist(output_dir,'dir') == 0 + mkdir(output_dir); +end + + +% prestack output +filename = 'gaths'; +results_out{2,1} = strcat(filename,'_trim_data_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +%results_out{2,2} = zeros(n_samples,n_traces_gather,n_traces,'single'); +%commented out as written to above +results_out{2,3} = 1; + +if outputgathershifts == 1; + results_out{3,1} = strcat(filename,'_trim_shifts_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); + results_out{3,3} = 1; + results_out{3,2} = zeros(in_n_samples,n_traces_gather,n_traces,'single'); +end + + + +% stack result +filename2 = 'stack'; +results_out2{2,1} = strcat(filename2,'_trim_sum_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +results_out2{2,2} = zeros(in_n_samples,n_traces,'single'); +results_out2{3,1} = strcat(filename2,'_pretrim_guide_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +results_out2{3,2} = zeros(in_n_samples,n_traces,'single'); +%results_out2{4,1} = strcat(filename2,'_posttrim_no_resid_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +results_out2{4,1} = strcat(filename2,'_posttrim_guide_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +results_out2{4,2} = zeros(in_n_samples,n_traces,'single'); +results_out2{5,1} = strcat(filename2,'_posttrim_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +results_out2{5,2} = zeros(in_n_samples,n_traces,'single'); +results_out2{6,1} = strcat(filename2,'_pretrim_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +results_out2{6,2} = zeros(in_n_samples,n_traces,'single'); +results_out2{2,3} = 0; +results_out2{3,3} = 0; +results_out2{4,3} = 0; +results_out2{5,3} = 0; +results_out2{6,3} = 0; +% ======================================================================== +% flattern the data to the water bottom and make a stack of the data for +% freq analysis + +% stack to make something to pick wb on +stackin_freq = sum(results_out{2,2}(:,startvol:midtrc,:),2) ./ ((midtrc - startvol) +1) ; +% pick wb +%[wb_idx] = water_bottom_picker(stackin_freq,padding); +[wb_idx] = water_bottom_picker(squeeze(stackin_freq),padding); +wb_idx(wb_idx < 0) = 1; +% write out a wbpick +%ilxltoprint = results_out{1,2}{1,1}(1:length(offset):end,:); +% only write out the values that are not 1, so are picked +%dlmwrite(strcat(output_dir,'wbpick_',i_block,'.xyz'),[ilxltoprint((wb_idx ~= 1)',:),(int32(wb_idx(wb_idx ~= 1)+padding)'.*job_meta.s_rate)/1000],'delimiter', ' ', 'precision', '%-6d','newline', 'unix'); +% +win_sub = bsxfun(@plus,wb_idx,(0:n_samples-max(wb_idx))'); +win_ind = bsxfun(@plus,win_sub,(0:n_samples:n_samples*(n_traces-1))); +clear win_sub; +% make anew stack after flattening, make sure to blank it before +stackin_freq2 = stackin_freq(win_ind); +%stackin_freq2 = time_balence_stk(stackin_freq2); +[n_samples,~] = size(stackin_freq2); +clear win_ind stackin_freq; +% +% ======================================================================== +% find the dominant frequency of the data, take a subset of the data and +% average freqs down the trace +start_index = 1:ns_win-ns_overlap-1:n_samples-ns_win; +end_index = start_index+ns_win-1; +freq_axis = (1e6/job_meta.s_rate)/2*linspace(0,1,ns_win/2); +n_win = length(start_index); +peak_freq = zeros(n_win,2); +min_freq = zeros(n_win,2); +gathinc = ceil(n_traces/20); +% make taper to apply to signal before fft +taperlen = 16; +%taperst = linspace(0,1,taperlen)'; +taperst = (sin(linspace((-pi/2),(pi/2),taperlen)')+1)/2; +taperend = 1 - taperst; +taperapply = [taperst;ones((ns_win-(taperlen*2)),1);taperend]; +filt_smof = ones(1,9)/9; +% +for ii = 1:n_win + % Estimate wavelets and store meta information + % make a tmp array with the fft values in it + tmpfft = zeros(2,2); + tmpfft = abs(fft(bsxfun(@times,stackin_freq2(start_index(ii):end_index(ii),:),taperapply))); + avgfreq = sum(tmpfft,2,'double'); + avgfreqsmo = conv(avgfreq(1:hns_win),filt_smof,'same'); + %figure(12); plot(avgfreqsmo); + cja = (avgfreqsmo > max(avgfreqsmo)*0.75); + [~,rhs] = max(cja(end:-1:1)); + [~,lowf_idx] = max(cja(1:1:end)); + highf_idx = (hns_win - rhs) + 1; + %[~,idxf] = max(avgfreqsmo); + %peak_freq(ii,:) = [(start_index(ii)+hns_win) ((peak_freq(ii,2)+freq_axis(highf_idx)))]; + peak_freq(ii,:) = [(start_index(ii)+hns_win) max(peak_freq(ii,2),freq_axis(highf_idx))]; + min_freq(ii,:) = [(start_index(ii)+hns_win) max(min_freq(ii,2),freq_axis(lowf_idx))]; + mid_freq(ii,:) = [(start_index(ii)+hns_win) (min_freq(ii,2)+((peak_freq(ii,2) - min_freq(ii,2) )*0.65))]; +end +% +% ========================================================================= +%see if the code can resample the data down to calculate shifts at +resamp_rt = round(1000 /(max(mid_freq(:,2))*2)); +use_samp_drop = 0; +wb_n_samples = n_samples; +orig_sample_rate = sample_rate; +time = repmat((0:sample_rate:(n_samples-1)*sample_rate)',1,n_traces_gather); +if resamp_rt > (sample_rate * 1.8) + samp_drop = round(resamp_rt/(sample_rate*1.8) + 0.1); + sample_rate = sample_rate * samp_drop; + ufoff = 1000/(sample_rate*2); + ufon = ufoff*0.8; + n_samples = length(1:samp_drop:n_samples); + peak_freq((peak_freq(:,2) > ufoff),2) = ufoff; + totmaxshift = ceil(sample_rate/1.5); % was 2.5 and 3 before + use_samp_drop = 1; +end +time_sub = (0:sample_rate:(n_samples-1)*sample_rate); +% +% for jj = 1:gathinc:n_traces; +% freq_test = results_out{2,2}(:,sttrc:midtrc,jj); +% %freq_test = time_balence(freq_test); +% +% for ii = 1:n_win +% % Estimate wavelets and store meta information +% % make a tmp array with the fft values in it +% tmpfft = zeros(2,2); +% tmpfft = abs(fft(bsxfun(@times,freq_test(start_index(ii):end_index(ii),:),taperapply))); +% avgfreq = sum(tmpfft,2,'double'); +% avgfreqsmo = conv(avgfreq(1:hns_win),filt_smof,'same'); +% %figure(12); plot(avgfreqsmo); +% cja = (avgfreqsmo > max(avgfreqsmo)*0.75); +% [~,rhs] = max(cja(end:-1:1)); +% highf_idx = (hns_win - rhs) + 1; +% %[~,idxf] = max(avgfreqsmo); +% %peak_freq(ii,:) = [(start_index(ii)+hns_win) ((peak_freq(ii,2)+freq_axis(highf_idx)))]; +% peak_freq(ii,:) = [(start_index(ii)+hns_win) max(peak_freq(ii,2),freq_axis(highf_idx))]; +% end +% end +%peak_freq(:,2) = peak_freq(:,2)/n_win; +% +% ======================================================================== +% calculate the shift limits and the smoothing for the trim, currently +% the wavelength at the peak freq at 2000m/s divided by 30 +max_shift = [peak_freq(:,1) (avg_vel./(peak_freq(:,2)*42))]; +% smooth the shifts +%filt_smos = ones(1,3)/3; +%max_shift = conv(max_shift,filt_smos,'same'); +% ======================================================================== +% set the shift increment from the sample rate +shiftinc = sample_rate/30; % this leads to floating point rounding errors +%shiftincloc = floor((sample_rate*10000)/30); + + +max_shiftstk = max_shift; +max_shiftstk(:,2) = max_shiftstk(:,2).*4; % was 3 before this allows the residual to do more + +% clip the max shifts +max_shift((max_shift(:,2) > totmaxshift),2) = totmaxshift; +max_shiftstk((max_shiftstk(:,2) > totmaxshift),2) = (totmaxshift); + +% set the maxshift to an increment of shiftinc +max_shift(:,2) = floor(max_shift(:,2)./shiftinc)*shiftinc; +max_shiftstk(:,2) = floor(max_shiftstk(:,2)./shiftinc)*shiftinc; + +% calculate the length of the smoother, currently 10 times the shift value +freq_grid = [max_shift(:,1) floor(max_shift(:,2).*smoothing_scaler)]; + +%shift = max(max_shift(:,2)); +shift = max(max_shiftstk(:,2)); + +%totmaxshift = shift; +% find the max shift to calculate +% if totmaxshift >= shift +% totmaxshift = shift; +% else +% shift = totmaxshift; +% end + +% % clip the max shifts +% max_shift((max_shift(:,2) > totmaxshift),2) = totmaxshift; +% max_shiftstk((max_shiftstk(:,2) > totmaxshift),2) = (totmaxshift); % should multiple by 1.5 at some point, but need to update shift; + +totnumshifts = length(-shift:shiftinc:shift); + +%now make the time varying smoothing as a diagonal on a matrix S +%freq_grid2 = [30 11; 300 21; 900 31]; + +totalpts = max(freq_grid(:,2)); +for mm = 1:size(freq_grid,1) + freq_interp_grid(mm,:) = [zeros(1,(totalpts-freq_grid(mm,2))) , 0:(totalpts/freq_grid(mm,2)):totalpts , (totalpts-(totalpts/freq_grid(mm,2))):-(totalpts/freq_grid(mm,2)):0 , zeros(1,(totalpts-freq_grid(mm,2))) ]; + + %shift_interp_grid(mm,:) = [[zeros(1,round(shift/shiftinc-((max_shift(mm,2)/shiftinc)))) , ones(1,round(max_shift(mm,2)/shiftinc))],1,fliplr([zeros(1,round(shift/shiftinc-(max_shift(mm,2)/shiftinc))) , ones(1,round(max_shift(mm,2)/shiftinc))])]; + shift_interp_grid(mm,:) = [[zeros(1,round((round((shift/shiftinc)*10000) - round((max_shift(mm,2)/shiftinc)*10000))/10000)), ones(1,(round((max_shift(mm,2))/shiftinc)*10000)/10000)],1,fliplr([zeros(1,round((round((shift/shiftinc)*10000) - round((max_shift(mm,2)/shiftinc)*10000))/10000)), ones(1,(round((max_shift(mm,2))/shiftinc)*10000)/10000)])]; + + shift_interp_gridstk(mm,:) = [[zeros(1,round((round((shift/shiftinc)*10000) - round((max_shiftstk(mm,2)/shiftinc)*10000))/10000)), ones(1,(round((max_shiftstk(mm,2))/shiftinc)*10000)/10000)],1,fliplr([zeros(1,round((round((shift/shiftinc)*10000) - round((max_shiftstk(mm,2)/shiftinc)*10000))/10000)), ones(1,(round((max_shiftstk(mm,2))/shiftinc)*10000)/10000)])]; + + + %shift_interp_grid(mm,:) = [[zeros(1,round(shift/shiftinc-((max_shift(mm,2)/shiftinc)))) , ones(1,round(max_shift(mm,2)/shiftinc))],1,fliplr([zeros(1,round(shift/shiftinc-(max_shift(mm,2)/shiftinc))) , ones(1,round(max_shift(mm,2)/shiftinc))])]; + %shift_interp_gridstk(mm,:) = [[zeros(1,round(shift/shiftinc-((max_shiftstk(mm,2)/shiftinc)))) , ones(1,round((max_shiftstk(mm,2))/shiftinc))],1,fliplr([zeros(1,round(shift/shiftinc-((max_shiftstk(mm,2))/shiftinc))) , ones(1,round((max_shiftstk(mm,2))/shiftinc))])]; + %shift_interp_grid(mm,:) = [[zeros(1,(shift/shiftinc-(max_shift(mm,2)/shiftinc))) , ones(1,max_shift(mm,2)/shiftinc)],1,fliplr([zeros(1,(shift/shiftinc-(max_shift(mm,2)/shiftinc))) , ones(1,max_shift(mm,2)/shiftinc)])]; + %shift_interp_gridstk(mm,:) = [[zeros(1,(shift/shiftinc-((max_shiftstk(mm,2)/shiftinc)))) , ones(1,(max_shiftstk(mm,2))/shiftinc)],1,fliplr([zeros(1,(shift/shiftinc-((max_shiftstk(mm,2))/shiftinc))) , ones(1,(max_shiftstk(mm,2))/shiftinc)])]; +end +start_interp = 1; +end_interp = n_samples; +freq_zgrid = freq_grid(:,1); + +if freq_grid(1,1) > 1 + freq_zgrid = [1; freq_zgrid]; + freq_interp_grid = [ freq_interp_grid(1,:) ; freq_interp_grid]; + shift_interp_grid = [ shift_interp_grid(1,:) ; shift_interp_grid]; + shift_interp_gridstk = [ shift_interp_gridstk(1,:) ; shift_interp_gridstk]; +end +if freq_grid(end,1) < n_samples + freq_zgrid(end+1) = n_samples; + freq_interp_grid(end+1,:) = freq_interp_grid(end,:); + shift_interp_grid(end+1,:) = shift_interp_grid(end,:); + shift_interp_gridstk(end+1,:) = shift_interp_gridstk(end,:); +end + +%make the array to go down the diagonal as a smoother +diag_smo_interp = interp1(freq_zgrid,freq_interp_grid,start_interp:1:end_interp,'linear'); +S = (1/totalpts)*spdiags(diag_smo_interp,[(-totalpts:1:0),(1:1:totalpts)], n_samples,n_samples); + +% now make a smaller smoother +dropf = 3; +dropfsel = [(totalpts + 1) - ((length((totalpts + 1:dropf:(totalpts*2)+1)) -1)*dropf):dropf:totalpts, (totalpts + 1:dropf:(totalpts*2)+1)]; +%droprows = [(-round(totalpts/dropf):1:0),(1:1:round(totalpts/dropf))]; +droprows = [(-round((length(dropfsel) -1)/2):1:0),(1:1:round((length(dropfsel) -1)/2))]; +S2 = (1/totalpts)*spdiags(diag_smo_interp(:,dropfsel),droprows, n_samples,n_samples); + +diag_smo_interp3 = interp1(freq_zgrid,freq_interp_grid,start_interp:1:wb_n_samples,'linear'); +%S3 = (1/totalpts)*spdiags(diag_smo_interp3(:,dropfsel),droprows, wb_n_samples,wb_n_samples); +S3 = (1/totalpts)*spdiags(diag_smo_interp3,[(-totalpts:1:0),(1:1:totalpts)], wb_n_samples,wb_n_samples); + +% make a mask to apply to the shifts before picking the peak +shift_mask = interp1(freq_zgrid,shift_interp_grid,start_interp:1:end_interp,'linear'); + +shift_interp_gridstk = interp1(2:2:(totnumshifts*2),shift_interp_gridstk',1:((totnumshifts*2)+1),'linear'); +shift_interp_gridstk(isnan(shift_interp_gridstk)) = 0; +shift_maskstk = interp1(freq_zgrid,shift_interp_gridstk',start_interp:1:wb_n_samples,'linear'); +shift_mask(shift_mask<1) = 0; +shift_maskstk(shift_maskstk<1) = 0; +% ============================================================================================================ +% loop round the traces 3d array one gather at a time and do calculations +f_max = (1/sample_rate)*1000; +phase_shifts = bsxfun(@times,(-shift:shiftinc:shift),(1/1000).*2.*pi.*repmat((0:f_max/(n_samples-1):f_max)',1,1+2*round((shift/shiftinc)))); + +f_maxorig = (1/orig_sample_rate)*1000; +phase_shifts_orig = bsxfun(@times,(-shift:shiftinc:shift),(1/1000).*2.*pi.*repmat((0:f_maxorig/(wb_n_samples-1):f_maxorig)',1,1+2*round((shift/shiftinc)))); + +totnumshifts = length(-shift:shiftinc:shift); +%S = (1/zsmooth)*spdiags(repmat([(1:1:zsmooth),(zsmooth-1:-1:1)],n_samples,1),[(-zsmooth+1:1:0),(1:1:zsmooth-1)],n_samples,n_samples); +%S2 = (1/zsmooth2)*spdiags(repmat([(1:1:zsmooth2),(zsmooth2-1:-1:1)],n_samples,1),[(-zsmooth2+1:1:0),(1:1:zsmooth2-1)],n_samples,n_samples); +det_coef = zeros(n_samples,totnumshifts); +det_coefb = zeros(n_samples,totnumshifts); + +%filttraces = [1 2 3 3 3 3 3 3 3 2 1]/27; +filttraces = [1 2 3 3 2 1]/12; +filt_smo = [1 2 1]/4; +filt_smo2 = ones(1,5)/5; +idxshift = round((shift/shiftinc))+1; + +% initialise zeros in output +trim_shift = zeros(n_samples,n_traces_gather,'single'); +trim_shiftb = zeros(n_samples,n_traces_gather,'single'); +trim_shiftb_out = zeros(wb_n_samples,n_traces_gather,'single'); +wt_taperapply = [taperst;ones((wb_n_samples-(taperlen*2)),1);taperend]; +det_coef3 = zeros(wb_n_samples,length(2:2:totnumshifts) ); +norm_fold_b = zeros(wb_n_samples,1,'single'); +norm_fold = zeros(wb_n_samples,1,'single'); +% +for kk = 1:n_traces; +%for kk = 1:200; + if useselectemode == 0 + requiredinline = results_out{1,2}{1,1}(kk,1); + end + if results_out{1,2}{1,1}(kk,1) == requiredinline; + + + % get the input gather and apply shift to flattern to the water bottom + trim_data = results_out{2,2}(wb_idx(kk):(wb_idx(kk)+wb_n_samples-1),:,kk); + + % apply an automatic mute to remove low amp noise + fmask = low_amp_mute(trim_data); + trim_data = trim_data .* fmask; + + %drop samples if possible + if use_samp_drop == 1 + trim_data_filt = bsxfun(@times,trim_data,wt_taperapply); + trim_data_filt = bandpass_filter(trim_data_filt,(sample_rate/1000),0,0,ufon,ufoff); + trim_data_filt = trim_data_filt(1:samp_drop:end,:); + mask = fmask(1:samp_drop:end,:); + else + trim_data_filt = trim_data; + mask = fmask; + end + + % balence the data to avoid any loud parts dominating any solution + if timbal == 1 + trim_data_filtin = trim_data_filt; + [trim_data_filt scaleused] = time_balence(trim_data_filt); + end + + %trim_data = trim_data_filt; + %trim_data_filt = bandpass_filter(d,dt,f1,f2,f3,f4); + + if plots == 1; figure(101); imagesc(trim_data_filt); colormap(gray); caxis([-4000 4000]); end; + + % apply a small smoother to reduce noise + if itm > 0 + mask(:,1:itm) = 0; + trim_data_filt(:,1:itm) = repmat(trim_data_filt(:,(itm+1)),1,itm); + end + if otm > 0 + mask(:,otm:end) = 0; + trim_data_filt(:,otm:n_traces_gather) = repmat(trim_data_filt(:,(otm-1)),1,(n_traces_gather-otm)+1); + end + + % apply a small smoother to reduce noise + %trim_data_filt = medfilt3nt(trim_data_filt,[0 9],0); + trim_data_filt = conv2(filt_smo,filttraces,trim_data_filt,'same'); + + if plots == 1; figure(106); imagesc(trim_data_filt); colormap(gray); caxis([-4000 4000]); end; + + %apply mask to the filtered data to remove duplicated data + trim_data_filt = trim_data_filt .* mask; + + % flip the data to work from outside in + trim_data_filt = fliplr(trim_data_filt); + + for ii = sttrc:edtrc + t1 = double(trim_data_filt(:,ii-1)); + T1 = S*spdiags(t1,0,n_samples,n_samples); + T1b = S2*spdiags(t1,0,n_samples,n_samples); + + %t2 = double(trim_data_filt(:,ii)); + t2f = fft(double(trim_data_filt(:,ii))); + t2_shifts = ifft(bsxfun(@times,t2f,exp(1i*phase_shifts)),'symmetric'); + + for count = 1:totnumshifts + %T2 = S*spdiags(t2_shifts(:,count),0,n_samples,n_samples); + T2diag = spdiags(t2_shifts(:,count),0,n_samples,n_samples); + %sparse + T2 = S*T2diag; + T2b = S2*spdiags(t2_shifts(:,count),0,n_samples,n_samples); + det_coef(:,count) = ((T1*t2_shifts(:,count)).*(T2*t1))./((T1*t1).*(T2*t2_shifts(:,count))); + det_coefb(:,count) = ((T1b*t2_shifts(:,count)).*(T2b*t1))./((T1b*t1).*(T2b*t2_shifts(:,count))); + end + % add in a taper to zero out large shifts in the shallow before picking + % the max + det_coef = det_coef.*shift_mask; + %det_coefb = det_coefb.*shift_mask; + % cj edit took out the mask as it was making steps in the + % results + if plots == 1; figure(205); imagesc(det_coef); caxis([0.8 1]); end; + if plots == 1; figure(206); imagesc(det_coefb); caxis([0.8 1]); end; + %[~,idx] = max(det_coef'); + %trim_shift(:,ii-1) = idx'-shift-1; + [~,idx]= max(det_coef,[],2); + [~,idxb]= max(det_coefb,[],2); + + if plots == 1; figure; plot(idx,length(det_coef):-1:1); end; + if plots == 1; figure; plot(idxb,length(det_coef):-1:1); end; + + trim_shift(:,ii) = (idx-idxshift)*shiftinc; + trim_shiftb(:,ii) = (idxb-idxshift)*shiftinc; + %trim_shift(:,ii-1) = idx-shift-1; + + end + + maskb = [ones(n_samples,1,'single'),mask(:,1:(end -1))] .* [mask(:,2:end),ones(n_samples,1,'single')]; + trim_shift = [trim_shift(:,1),fliplr(trim_shift(:,2:end))].* maskb; + trim_shiftb = [trim_shiftb(:,1),fliplr(trim_shiftb(:,2:end))].* maskb; + %trim_shift = trim_shift .* maskb; + %trimfold = max(cumsum(maskb,2),[],2); + %figure; + if plots == 1; figure(91); imagesc(trim_shift); caxis([-5 5]); end; + if plots == 1; figure(90); imagesc(trim_shiftb); caxis([-5 5]); end; + %imagesc(trim_shiftb); + + %trim_sum = sum(abs(trim_shift(:,startvol:endvol)),2) ./ max(cumsum(maskb(:,startvol:endvol),2),[],2); + % trim_shiftcj = trim_shift; + %trim_datacj = trim_data; + + trim_shift = cumsum(trim_shift,2); + trim_shift = conv2(filt_smo2,filt_smo,trim_shift,'same'); + trim_shift = trim_shift .* mask; + %trim_shift(data==0) = 0; + % trim_sum = sum(trim_shift,2); + %n = length(trim_shift); + %trim_sum = sqrt((1/n)*sum((trim_shift.^2),2)); + + + % normalise the sum of the shifts for the fold in case we have + % difference in fold + norm_fold_b = max(cumsum(fmask(:,startvol:endvol),2),[],2); + norm_fold = max(cumsum(fmask(:,startvol:midtrc),2),[],2); + norm_fold_b(norm_fold_b == 0) = 1; + norm_fold(norm_fold == 0) = 1; + + %tf %stackin = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(maskb(:,startvol:endvol),2),[],2); + stackin = sum(trim_data(:,startvol:midtrc),2) ./ norm_fold; + stackinb = sum(trim_data(:,startvol:endvol),2) ./ norm_fold_b; + %stackin = sum(trim_data(:,startvol:midtrc),2) ./ max(cumsum(fmask(:,startvol:midtrc),2),[],2); + %stackinb = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(fmask(:,startvol:endvol),2),[],2); + + + %if plots == 2; ilplotin(:,kk) = stackin; end + ftrim_shift = interp1(time_sub,trim_shift,time(:,1),'linear',0); + ftrim_shiftb = interp1(time_sub,trim_shiftb,time(:,1),'linear',0); + + for ii = 1:n_traces_gather + trim_data(:,ii) = interp1(time(:,ii),trim_data(:,ii),time(:,ii)-ftrim_shift(:,ii),'linear',0); + %trim_data(:,ii) = interp1q(time(:,ii),trim_data(:,ii),time(:,ii)-trim_shift(:,ii)); + + %trim_datab(:,ii) = interp1(time(:,ii),trim_data(:,ii),time(:,ii)-trim_shift(:,ii),'spline',0); + trim_shiftb_out(:,ii) = interp1(time(:,ii),ftrim_shiftb(:,ii),time(:,ii)-ftrim_shift(:,ii),'linear',0); + end + + % % % cj test version of shifts ======================== + % zoom3 = 600; + % zoom4 = 1000; + % % figure(108); imagesc(trim_datacj(zoom3:zoom4,:)) ; colormap(gray); caxis([-50 50]); + % % trim_datacjb = trim_datacj; + % % trim_datacj = fliplr(trim_datacj); + % % trim_shiftcj = fliplr(trim_shift); + % % + % % % for ii = 2:n_traces_gather + % % % for jj = 1:ii + % % % trim_datacj(:,jj) = interp1(time(:,1),trim_datacj(:,jj),time(:,1)-trim_shiftcj(:,ii),'linear',0); + % % % end + % % % end + % % + % % for ii = 2:n_traces_gather + % % trim_datacj(:,1:ii) = interp1(time(:,1),trim_datacj(:,1:ii),time(:,ii)-trim_shiftcj(:,ii),'linear',0); + % % end + % % trim_datacj = fliplr(trim_datacj); + % % %trim_shiftcj = fliplr(trim_shiftcj); + % figure(109); imagesc(trim_datacj(zoom3:zoom4,:)) ; colormap(gray); caxis([-500000 500000]); + % figure(119); imagesc(trim_datacj) ; colormap(gray); caxis([-500000 500000]); + % % figure(110); imagesc(trim_datacjb(zoom3:zoom4,:) - trim_datacj(zoom3:zoom4,:) ) ; colormap(gray); caxis([-20 20]); + % % figure(112); imagesc(trim_datacjb(zoom3:zoom4,:) - trim_data(zoom3:zoom4,:) ) ; colormap(gray); caxis([-20 20]); + % figure(121); imagesc(trim_data(zoom3:zoom4,:)) ; colormap(gray); caxis([-500000 500000]); + % figure(111); imagesc(trim_data) ; colormap(gray); caxis([-500000 500000]); + % % =================================================== + + + if plots == 1; + figure(102); imagesc(time_balence(trim_data)); colormap(gray); caxis([-4000 4000]); + figure(103); imagesc(trim_data); colormap(gray); + end; + + % normalise the sum of the shifts for the fold in case we have + % difference in fold +% norm_fold_b = max(cumsum(fmask(:,startvol:endvol),2),[],2); +% norm_fold = max(cumsum(fmask(:,startvol:midtrc),2),[],2); +% norm_fold_b(norm_fold_b == 0) = 1; +% norm_fold(norm_fold == 0) = 1; + + %tf %trim_sum = sum(abs(trim_shiftb_out(:,startvol:endvol)),2) ./ max(cumsum(maskb(:,startvol:endvol),2),[],2); + trim_sum = sum(abs(trim_shiftb_out(:,startvol:endvol)),2) ./ norm_fold_b; + %trim_sum = sum(abs(trim_shiftb_out(:,startvol:endvol)),2) ./ max(cumsum(fmask(:,startvol:endvol),2),[],2); + %trim_sum = sum(abs(trim_shiftb_out(:,startvol:endvol)),2); + if plots == 1; figure(109); imagesc(trim_shiftb_out); caxis([-5 5]); end; + + %tf %stackout = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(maskb(:,startvol:endvol),2),[],2); + stackout = sum(trim_data(:,startvol:midtrc),2) ./ norm_fold; + %stackout = sum(trim_data(:,startvol:midtrc),2) ./ max(cumsum(fmask(:,startvol:midtrc),2),[],2); + %stackout = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(fmask(:,startvol:endvol),2),[],2); + + % ================================================================= + % now add a section to apply a residual trim static to the whole gather + % based on the mismatch between the stacks before and after trim and + % then repeat the final stack + + st1 = double(time_balence_stk(stackin)); + sT1 = S3*spdiags(st1,0,wb_n_samples,wb_n_samples); + + st2 = double(time_balence_stk(stackout)); + st2_shifts = ifft(bsxfun(@times,fft(st2),exp(1i*phase_shifts_orig)),'symmetric'); + % for count = 1:totnumshifts + % sT2 = S3*spdiags(st2_shifts(:,count),0,wb_n_samples,wb_n_samples); + % det_coef5(:,count) = ((sT1*st2_shifts(:,count)).*(sT2*st1))./((sT1*st1).*(sT2*st2_shifts(:,count))); + % + % end + + + countr = 1; + + for count = 2:2:totnumshifts + sT2 = S3*spdiags(st2_shifts(:,count),0,wb_n_samples,wb_n_samples); + det_coef3(:,countr) = ((sT1*st2_shifts(:,count)).*(sT2*st1))./((sT1*st1).*(sT2*st2_shifts(:,count))); + countr = countr +1; + end + det_coef3(isnan(det_coef3)) = 0; + det_coef4 = interp1(4:4:(totnumshifts*2),det_coef3',1:( ((totnumshifts-1)/2)*4 + 3 ),'spline'); + % add in a taper to zero out large shifts in the shallow before picking + % the max + det_coef4 = det_coef4'.*shift_maskstk; + [~,stkidx]= max(det_coef4,[],2); + stack_shift = (stkidx-(idxshift*2))*(shiftinc/2); + + trim_data(:,1:n_traces_gather) = interp1(time(:,1),trim_data(:,1:n_traces_gather),time(:,1)+stack_shift(:,1),'linear',0); + + + stackoutb = sum(trim_data(:,startvol:endvol),2) ./ norm_fold_b; + stackout = sum(trim_data(:,startvol:midtrc),2) ./ norm_fold; + %stackoutb = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(fmask(:,startvol:endvol),2),[],2); + %stackout = sum(trim_data(:,startvol:midtrc),2) ./ max(cumsum(fmask(:,startvol:midtrc),2),[],2); + % ================================================================= + + if plots == 2; ilplot(:,kk) = stackout; end + %ilplotb(:,kk) = stackoutb; + if outputgathershifts == 1; + results_out{3,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,:,kk) = ftrim_shift; + end + results_out{2,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,:,kk) = trim_data; + results_out2{2,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = trim_sum; + results_out2{3,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = stackin; + results_out2{4,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = stackout; + results_out2{5,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = stackoutb; + results_out2{6,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = stackinb; + + end +end + +if plots == 2; + zoom1 = 400; + zoom2 = 800; + %figure(102); imagesc((ilplotb(500:700,:) - ilplot(500:700,:))); colormap(gray); caxis([-100 100]) + %figure(101); imagesc(ilplotb(zoom1:zoom2,:)); colormap(gray); caxis([-200 200]) + figure(100); imagesc(ilplot(zoom1:zoom2,:)); colormap(gray); caxis([-200 200]) + figure(103); imagesc(ilplotin(zoom1:zoom2,:)); colormap(gray); caxis([-200 200]) + figure(102); imagesc((ilplotin(zoom1:zoom2,:) - ilplot(zoom1:zoom2,:))); colormap(gray); caxis([-100 100]) + %figure(104); imagesc((ilplotin(zoom1:zoom2,:) - ilplotb(zoom1:zoom2,:))); colormap(gray); caxis([-100 100]) + figure(105); imagesc(results_out2{2,2}(zoom1:zoom2,1:kk)) + if outputgathershifts == 1; + figure(107); imagesc(squeeze(results_out{3,2}(zoom1:zoom2,36,1:kk))) + end + figure(108); imagesc(reshape(results_out{2,2}(zoom1:zoom2,:,1:50:kk),(zoom2-zoom1+1),[])); colormap(gray); caxis([-100 100]); +end + +% need to reshape the 2 3d matricies into 2d ones as the segy write just wants samples * total traces +results_out{2,2} = reshape(results_out{2,2},in_n_samples,[]); +if outputgathershifts == 1; + results_out{3,2} = reshape(results_out{3,2},in_n_samples,[]); +end + + + + +i_block = str2double(i_block); +% write the pre-stack dataset +if outputflatgathers == 1; + node_segy_write(results_out,i_block, orig_sample_rate, output_dir) +end +% write the stack +node_segy_write(results_out2,i_block, orig_sample_rate, output_dir) + +end diff --git a/algorithms/trim_calculation/trim_shifts_calculate.m b/algorithms/trim_calculation/trim_shifts_calculate.m new file mode 100644 index 0000000..851ee13 --- /dev/null +++ b/algorithms/trim_calculation/trim_shifts_calculate.m @@ -0,0 +1,725 @@ +function [out_traces stack_shifts stack_traces coeff_sum ] = trim_shifts_calculate(mode,job_meta,traces,timbal,shift_param) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% this works out and applies trim statics and keeps a sum of the statics +% for each z sample +% +% mode: 'calc' or 'apply' +% job_meta: meta data for the input gathers +% traces: input traces - should be cdp-sorted nmo-corrected muted gathers +% timbal: flag for time-balancing +% zsmooth: time/depth smoothing +% +% out_traces: traces with shifts applied or shifts +% out_shifts: traces with samples replaced by shift values +% xcor_coeffs: one trace per input gather with average xcor coefficient +% +% ============================================================================================================ +% sort out parameters +timbal = str2double(timbal); +shift_param = str2double(shift_param); +% ============================================================================================================ +% zsmooth parameter was not used + +% useselectemode = 0; +% if isempty(regexp(zsmooth,'il','once')) == 0 +% useselectemode = 1; +% requiredinline = str2double(regexprep(zsmooth,'il','')); +% %requiredinline = str2double(strrep(tottracerun,'il','')); +% zsmooth = 20; +% else +% zsmooth = str2double(zsmooth); +% end + +% zsmooth = str2double(zsmooth); +%zsmooth2 = shift*2; +% if zsmooth2 < 7 +% zsmooth2 = 7; +% end +% ============================================================================================================ + + +shiftinc = 0.2; +plots = 0; +padding = 50; +% Wavelet estimation parameters +ns_win = 128; +hns_win = ns_win/2; +ns_overlap = 96; +totmaxshift = 5; + +% ============================================================================================================ +% % load the job meta file containing more parameters +% job_meta = load(job_meta_path); +sample_rate = (job_meta.s_rate/1000); +% add the history of jobs run and this one to the curent ebcdic +% ebdichdr = ['trim statics ']; +% if isfield(job_meta,'comm_history') +% ebdichdr2 = job_meta.comm_history; +% tmpebc = ebdichdr2{size(ebdichdr2,1),2}; +% else +% ebdichdr2{1,2} = ''; +% tmpebc = ''; +% end +% +% for ebcii = (size(ebdichdr2,1)-1):-1:1 +% tmpebcc = regexp(ebdichdr2{ebcii,2},'/','split'); +% tmpebc = [tmpebc tmpebcc{1} tmpebcc{end}]; +% end +% tmpebc = sprintf('%-3200.3200s',tmpebc); +% clear tmpebcc ebdichdr2; +% % +% ============================================================================================================ +% Read the data for this block + +% [~, traces, ilxl_read, offset_read] = node_segy_read(job_meta_path,'1',i_block); +% offset = unique(offset_read); +% traces = reshape(traces,size(traces,1),length(offset),[]); +% +% [n_samples,n_traces_gather,n_traces] = size(traces); + +% [seismic, results_out{3,2}, results_out{1,2}{1,1}, offset_read] = node_segy_read(job_meta_path,'1',i_block); +% offset = unique(offset_read); +% results_out{3,2} = reshape(results_out{3,2},size(results_out{3,2},1),length(offset),[]); +% +% % check to make sure it read something if not exit +% if isempty(results_out{3,2}) == 1 && isempty(results_out{1,2}{1,1}) == 1 && isempty(offset_read) == 1 +% return +% end + +% drop data as required +% order is samples, angles, skeys +% results_out{3,2} = results_out{3,2}(1:maxzout,:,:); +% job_meta.n_samples{1} = maxzout; + +%results_out{1,2}{1,1} + +[n_samples,n_traces_gather,n_traces] = size(traces); +in_n_samples = n_samples; + +% apply any itm and otm to the gathers +% sttrc = 2; +% edtrc = n_traces_gather; +% if itm > 0 +% results_out{3,2}(:,1:itm,:) = 0; +% edtrc = (n_traces_gather - itm); +% end +% if otm > 0 +% results_out{3,2}(:,otm:end,:) = 0; +% sttrc = (n_traces_gather - otm) + 2; +% end +% midtrc = startvol + floor((endvol - startvol)/2); +% ============================================================================================================ +% % Make results meta information +% +% % for the pre-stack dataset +% results_out{1,1} = 'Meta data for output files'; +% %results_out{resultno,2}{1,1} = ilxl_read; +% results_out{1,2}{2,1} = offset_read'; +% ebcstrtowrite = sprintf('%-3200.3200s',[results_out{1,1} ' ' ebdichdr ' ' tmpebc]); +% results_out{1,1} = ebcstrtowrite; +% results_out{1,3} = 'is_gather'; % 1 is yes, 0 is no +% +% +% % for the stack output +% results_out2{1,1} = 'Meta data for output files'; +% results_out2{1,2}{1,1} = results_out{1,2}{1,1}(1:n_traces_gather:end,:); +% results_out2{1,2}{2,1} = uint32(zeros(n_traces,1)); +% %ebcstrtowrite = sprintf('%-3200.3200s',[results_out{resultno,1} ' ' ebdichdr ' ' tmpebc]); +% results_out2{1,1} = ebcstrtowrite; +% results_out2{1,3} = 'is_gather'; % 1 is yes, 0 is no +% +% output_dir = [job_meta.output_dir,'trimout/']; +% % check to see if the directory exists +% if exist(output_dir,'dir') == 0 +% mkdir(output_dir); +% end +% +% +% % prestack output +% filename = 'gaths'; +% results_out{2,1} = strcat(filename,'_trim_shifts_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +% results_out{3,1} = strcat(filename,'_trim_data_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +% results_out{2,3} = 1; +% results_out{3,3} = 1; +% results_out{2,2} = zeros(in_n_samples,n_traces_gather,n_traces,'single'); +% %results_out{3,2} = zeros(n_samples,n_traces_gather,n_traces,'single'); +% +% +% +% % stack result +% filename2 = 'stack'; +% results_out2{2,1} = strcat(filename2,'_trim_sum_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +% results_out2{2,2} = zeros(in_n_samples,n_traces,'single'); +% results_out2{3,1} = strcat(filename2,'_pretrim_guide_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +% results_out2{3,2} = zeros(in_n_samples,n_traces,'single'); +% %results_out2{4,1} = strcat(filename2,'_posttrim_no_resid_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +% results_out2{4,1} = strcat(filename2,'_posttrim_guide_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +% results_out2{4,2} = zeros(in_n_samples,n_traces,'single'); +% results_out2{5,1} = strcat(filename2,'_posttrim_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +% results_out2{5,2} = zeros(in_n_samples,n_traces,'single'); +% results_out2{6,1} = strcat(filename2,'_pretrim_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +% results_out2{6,2} = zeros(in_n_samples,n_traces,'single'); +% results_out2{2,3} = 0; +% results_out2{3,3} = 0; +% results_out2{4,3} = 0; +% results_out2{5,3} = 0; +% results_out2{6,3} = 0; +% ======================================================================== +% flattern the data to the water bottom and make a stack of the data for +% freq analysis + + +% % stack to make something to pick wb on +% stackin_freq = sum(results_out{3,2}(:,startvol:midtrc,:),2) ./ ((midtrc - startvol) +1) ; +% % pick wb +% %[wb_idx] = water_bottom_picker(stackin_freq,padding); +% [wb_idx] = water_bottom_picker(squeeze(stackin_freq),padding); +% wb_idx(wb_idx < 0) = 1; +% % write out a wbpick +% %ilxltoprint = results_out{1,2}{1,1}(1:length(offset):end,:); +% % only write out the values that are not 1, so are picked +% %dlmwrite(strcat(output_dir,'wbpick_',i_block,'.xyz'),[ilxltoprint((wb_idx ~= 1)',:),(int32(wb_idx(wb_idx ~= 1)+padding)'.*job_meta.s_rate)/1000],'delimiter', ' ', 'precision', '%-6d','newline', 'unix'); +% % +% win_sub = bsxfun(@plus,wb_idx,(0:n_samples-max(wb_idx))'); +% win_ind = bsxfun(@plus,win_sub,(0:n_samples:n_samples*(n_traces-1))); +% clear win_sub; +% % make anew stack after flattening, make sure to blank it before +% stackin_freq2 = stackin_freq(win_ind); +% %stackin_freq2 = time_balence_stk(stackin_freq2); +% [n_samples,~] = size(stackin_freq2); +clear win_ind stackin_freq; + +wb_idx=ones(n_traces); + +stack_fold = squeeze(max(1,sum(abs(traces)>0,2))); + +stackin_freq2 = squeeze(sum(traces,2))./(stack_fold/n_traces_gather); + +% find the dominant frequency of the data, take a subset of the data and +% +% returns window centre, low, high, weighted avg freq +% +% assign to arrays with same name as in previous code + +peak_freqs = peak_freq_calc(job_meta,stackin_freq2); + +min_freq = peak_freqs(:,[1 2]); +peak_freq = peak_freqs(:,[1 3]); +mid_freq = peak_freqs(:,[1 4]); + +peak_freq(:,2) = 90; +mid_freq(:,2) = 80; + + +% make taper to apply to signal before fft +taperlen = 16; + +taperst = (sin(linspace((-pi/2),(pi/2),taperlen)')+1)/2; +taperend = 1 - taperst; +% taperapply = [taperst;ones((ns_win-(taperlen*2)),1);taperend]; + +% ========================================================================= +%see if the code can resample the data down to calculate shifts at +resamp_rt = round(1000 /(max(mid_freq(:,2))*2)); +use_samp_drop = 0; +wb_n_samples = n_samples; +orig_sample_rate = sample_rate; +time = repmat((0:sample_rate:(n_samples-1)*sample_rate)',1,n_traces_gather); +if resamp_rt > (sample_rate * 1.8) + samp_drop = round(resamp_rt/(sample_rate * 1.8) + 0.1); + sample_rate = sample_rate * samp_drop; + ufoff = 1000/(sample_rate*2); + ufon = ufoff*0.8; + n_samples = length(1:samp_drop:n_samples); + peak_freq((peak_freq(:,2) > ufoff),2) = ufoff; + totmaxshift = ceil(sample_rate/2.5); % was 3 before + use_samp_drop = 1; +end + +time_sub = (0:sample_rate:(n_samples-1)*sample_rate); + +% +% for jj = 1:gathinc:n_traces; +% freq_test = results_out{3,2}(:,sttrc:midtrc,jj); +% %freq_test = time_balence(freq_test); +% +% for ii = 1:n_win +% % Estimate wavelets and store meta information +% % make a tmp array with the fft values in it +% tmpfft = zeros(2,2); +% tmpfft = abs(fft(bsxfun(@times,freq_test(start_index(ii):end_index(ii),:),taperapply))); +% avgfreq = sum(tmpfft,2,'double'); +% avgfreqsmo = conv(avgfreq(1:hns_win),filt_smof,'same'); +% %figure(12); plot(avgfreqsmo); +% cja = (avgfreqsmo > max(avgfreqsmo)*0.75); +% [~,rhs] = max(cja(end:-1:1)); +% highf_idx = (hns_win - rhs) + 1; +% %[~,idxf] = max(avgfreqsmo); +% %peak_freq(ii,:) = [(start_index(ii)+hns_win) ((peak_freq(ii,2)+freq_axis(highf_idx)))]; +% peak_freq(ii,:) = [(start_index(ii)+hns_win) max(peak_freq(ii,2),freq_axis(highf_idx))]; +% end +% end +%peak_freq(:,2) = peak_freq(:,2)/n_win; +% +% % ======================================================================== +% % calculate the shift limits and the smoothing for the trim, currently +% % the wavelength at the peak freq at 2000m/s divided by 30 +% % max_shift = [peak_freq(:,1) (2000./(peak_freq(:,2)*42))]; + +% max_shift = [peak_freq(:,1) (2000./(peak_freq(:,2)*13))]; + +max_shift = zeros(size(peak_freq)); + +max_shift(:,1) = peak_freq(:,1); +max_shift(:,2) = shift_param; + +% smooth the shifts +%filt_smos = ones(1,3)/3; +%max_shift = conv(max_shift,filt_smos,'same'); +max_shift(:,2) = floor(max_shift(:,2)./shiftinc)*shiftinc; +max_shiftstk = max_shift; +max_shiftstk(:,2) = max_shiftstk(:,2).*4; % was 3 before this allows the residual to do more + +% calculate the length of the smoother, currently 10 times the shift value +freq_grid = [max_shift(:,1) floor(max_shift(:,2).*10)]; + +shift = max(max_shift(:,2)); +% find the max shift to calculate +if totmaxshift >= shift + totmaxshift = shift; +else + shift = totmaxshift; +end + +% clip the max shifts +max_shift((max_shift(:,2) > totmaxshift),2) = totmaxshift; +max_shiftstk((max_shiftstk(:,2) > totmaxshift),2) = totmaxshift; + + +totnumshifts = length(-shift:shiftinc:shift); + +%now make the time varying smoothing as a diagonal on a matrix S +%freq_grid2 = [30 11; 300 21; 900 31]; + +totalpts = max(freq_grid(:,2)); +for mm = 1:size(freq_grid,1) + freq_interp_grid(mm,:) = [zeros(1,(totalpts-freq_grid(mm,2))) , 0:(totalpts/freq_grid(mm,2)):totalpts , (totalpts-(totalpts/freq_grid(mm,2))):-(totalpts/freq_grid(mm,2)):0 , zeros(1,(totalpts-freq_grid(mm,2))) ]; + shift_interp_grid(mm,:) = [[zeros(1,round(shift/shiftinc-((max_shift(mm,2)/shiftinc)))) , ones(1,round(max_shift(mm,2)/shiftinc))],1,fliplr([zeros(1,round(shift/shiftinc-(max_shift(mm,2)/shiftinc))) , ones(1,round(max_shift(mm,2)/shiftinc))])]; + shift_interp_gridstk(mm,:) = [[zeros(1,round(shift/shiftinc-((max_shiftstk(mm,2)/shiftinc)))) , ones(1,round((max_shiftstk(mm,2))/shiftinc))],1,fliplr([zeros(1,round(shift/shiftinc-((max_shiftstk(mm,2))/shiftinc))) , ones(1,round((max_shiftstk(mm,2))/shiftinc))])]; +end +start_interp = 1; +end_interp = n_samples; +freq_zgrid = freq_grid(:,1); + +if freq_grid(1,1) > 1 + freq_zgrid = [1; freq_zgrid]; + freq_interp_grid = [ freq_interp_grid(1,:) ; freq_interp_grid]; + shift_interp_grid = [ shift_interp_grid(1,:) ; shift_interp_grid]; + shift_interp_gridstk = [ shift_interp_gridstk(1,:) ; shift_interp_gridstk]; +end +if freq_grid(end,1) < n_samples + freq_zgrid(end+1) = n_samples; + freq_interp_grid(end+1,:) = freq_interp_grid(end,:); + shift_interp_grid(end+1,:) = shift_interp_grid(end,:); + shift_interp_gridstk(end+1,:) = shift_interp_gridstk(end,:); +end + +%make the array to go down the diagonal as a smoother +diag_smo_interp = interp1(freq_zgrid,freq_interp_grid,start_interp:1:end_interp,'linear'); +S = (1/totalpts)*spdiags(diag_smo_interp,[(-totalpts:1:0),(1:1:totalpts)], n_samples,n_samples); + +% now make a smaller smoother +dropf = 3; +dropfsel = [(totalpts + 1) - ((length((totalpts + 1:dropf:(totalpts*2)+1)) -1)*dropf):dropf:totalpts, (totalpts + 1:dropf:(totalpts*2)+1)]; +%droprows = [(-round(totalpts/dropf):1:0),(1:1:round(totalpts/dropf))]; +droprows = [(-round((length(dropfsel) -1)/2):1:0),(1:1:round((length(dropfsel) -1)/2))]; +S2 = (1/totalpts)*spdiags(diag_smo_interp(:,dropfsel),droprows, n_samples,n_samples); + +diag_smo_interp3 = interp1(freq_zgrid,freq_interp_grid,start_interp:1:wb_n_samples,'linear'); +%S3 = (1/totalpts)*spdiags(diag_smo_interp3(:,dropfsel),droprows, wb_n_samples,wb_n_samples); +S3 = (1/totalpts)*spdiags(diag_smo_interp3,[(-totalpts:1:0),(1:1:totalpts)], wb_n_samples,wb_n_samples); + +% make a mask to apply to the shifts before picking the peak +shift_mask = interp1(freq_zgrid,shift_interp_grid,start_interp:1:end_interp,'linear'); + +shift_interp_gridstk = interp1(2:2:(totnumshifts*2),shift_interp_gridstk',1:((totnumshifts*2)+1),'linear'); +shift_interp_gridstk(isnan(shift_interp_gridstk)) = 0; +shift_maskstk = interp1(freq_zgrid,shift_interp_gridstk',start_interp:1:wb_n_samples,'linear'); +shift_mask(shift_mask<1) = 0; +shift_maskstk(shift_maskstk<1) = 0; +% ============================================================================================================ +% loop round the traces 3d array one gather at a time and do calculations +f_max = (1/sample_rate)*1000; +phase_shifts = bsxfun(@times,(-shift:shiftinc:shift),(1/1000).*2.*pi.*repmat((0:f_max/(n_samples-1):f_max)',1,1+2*(shift/shiftinc))); + +f_maxorig = (1/orig_sample_rate)*1000; +phase_shifts_orig = bsxfun(@times,(-shift:shiftinc:shift),(1/1000).*2.*pi.*repmat((0:f_maxorig/(wb_n_samples-1):f_maxorig)',1,1+2*(shift/shiftinc))); + +totnumshifts = length(-shift:shiftinc:shift); +%S = (1/zsmooth)*spdiags(repmat([(1:1:zsmooth),(zsmooth-1:-1:1)],n_samples,1),[(-zsmooth+1:1:0),(1:1:zsmooth-1)],n_samples,n_samples); +%S2 = (1/zsmooth2)*spdiags(repmat([(1:1:zsmooth2),(zsmooth2-1:-1:1)],n_samples,1),[(-zsmooth2+1:1:0),(1:1:zsmooth2-1)],n_samples,n_samples); +det_coef = zeros(n_samples,totnumshifts); +det_coefb = zeros(n_samples,totnumshifts); + +%filttraces = [1 2 3 3 3 3 3 3 3 2 1]/27; +filttraces = [1 2 3 3 2 1]/12; +filt_smo = [1 2 1]/4; +filt_smo2 = ones(1,5)/5; +idxshift = (shift/shiftinc)+1; + +% initialise zeros in output +trim_shift = zeros(n_samples,n_traces_gather,'single'); +trim_shiftb = zeros(n_samples,n_traces_gather,'single'); +trim_shiftb_out = zeros(wb_n_samples,n_traces_gather,'single'); +wt_taperapply = [taperst;ones((wb_n_samples-(taperlen*2)),1);taperend]; +det_coef3 = zeros(wb_n_samples,length(2:2:totnumshifts) ); +norm_fold_b = zeros(wb_n_samples,1,'single'); +norm_fold = zeros(wb_n_samples,1,'single'); +out_traces = zeros(size(traces)); +coeff_sum = zeros(wb_n_samples,n_traces); + +% +for kk = 1:n_traces; + %for kk = 1:200; + % if useselectemode == 0 + % requiredinline = results_out{1,2}{1,1}(kk,1); + % end + % if results_out{1,2}{1,1}(kk,1) == requiredinline; + + + % get the input gather and apply shift to flattern to the water bottom + trim_data = traces(wb_idx(kk):(wb_idx(kk)+wb_n_samples-1),:,kk); + + % apply an automatic mute to remove low amp noise + fmask = low_amp_mute(trim_data); + trim_data = trim_data .* fmask; + + %drop samples if possible + if use_samp_drop == 1 + trim_data_filt = bsxfun(@times,trim_data,wt_taperapply); + trim_data_filt = bandpass_filter(trim_data_filt,(sample_rate/1000),0,0,ufon,ufoff); + trim_data_filt = trim_data_filt(1:samp_drop:end,:); + mask = fmask(1:samp_drop:end,:); + else + trim_data_filt = trim_data; + mask = fmask; + end + + % balence the data to avoid any loud parts dominating any solution + if timbal == 1 + trim_data_filtin = trim_data_filt; + [trim_data_filt scaleused] = time_balence(trim_data_filt); + end + + %trim_data = trim_data_filt; + %trim_data_filt = bandpass_filter(d,dt,f1,f2,f3,f4); + + if plots == 1; figure(101); imagesc(trim_data_filt); colormap(gray); caxis([-4000 4000]); end; + + % apply a small smoother to reduce noise + % if itm > 0 + itm=0; otm=n_traces_gather; + mask(:,1:itm) = 0; + trim_data_filt(:,1:itm) = repmat(trim_data_filt(:,(itm+1)),1,itm); + %end + %if otm > 0 + mask(:,otm:end) = 0; + trim_data_filt(:,otm:n_traces_gather) = repmat(trim_data_filt(:,(otm-1)),1,(n_traces_gather-otm)+1); + %end + + % apply a small smoother to reduce noise + %trim_data_filt = medfilt3nt(trim_data_filt,[0 9],0); +% trim_data_filt = conv2(filt_smo,filttraces,trim_data_filt,'same'); + + if plots == 1; figure(106); imagesc(trim_data_filt); colormap(gray); caxis([-4000 4000]); end; + + %apply mask to the filtered data to remove duplicated data + trim_data_filt = trim_data_filt .* mask; + + % flip the data to work from outside in + trim_data_filt = fliplr(trim_data_filt); + + %for ii = sttrc:edtrc + for ii = 2:n_traces_gather; + t1 = double(trim_data_filt(:,ii-1)); + T1 = S*spdiags(t1,0,n_samples,n_samples); + T1b = S2*spdiags(t1,0,n_samples,n_samples); + + %t2 = double(trim_data_filt(:,ii)); + t2f = fft(double(trim_data_filt(:,ii))); + t2_shifts = ifft(bsxfun(@times,t2f,exp(1i*phase_shifts)),'symmetric'); + + for count = 1:totnumshifts + %T2 = S*spdiags(t2_shifts(:,count),0,n_samples,n_samples); + T2diag = spdiags(t2_shifts(:,count),0,n_samples,n_samples); + %sparse + T2 = S*T2diag; + T2b = S2*spdiags(t2_shifts(:,count),0,n_samples,n_samples); + det_coef(:,count) = ((T1*t2_shifts(:,count)).*(T2*t1))./((T1*t1).*(T2*t2_shifts(:,count))); + det_coefb(:,count) = ((T1b*t2_shifts(:,count)).*(T2b*t1))./((T1b*t1).*(T2b*t2_shifts(:,count))); + end + % add in a taper to zero out large shifts in the shallow before picking + % the max + det_coef = det_coef.*shift_mask; + %det_coefb = det_coefb.*shift_mask; + % cj edit took out the mask as it was making steps in the + % results + + %[~,idx] = max(det_coef'); + %trim_shift(:,ii-1) = idx'-shift-1; + [~,idx]= max(det_coef,[],2); + [coeffb,idxb]= max(det_coefb,[],2); + + trim_shift(:,ii) = (idx-idxshift)*shiftinc; + trim_shiftb(:,ii) = (idxb-idxshift)*shiftinc; + trim_coeffb(:,ii) = coeffb; + %trim_shift(:,ii-1) = idx-shift-1; + + end + + maskb = [ones(n_samples,1,'single'),mask(:,1:(end -1))] .* [mask(:,2:end),ones(n_samples,1,'single')]; + trim_shift = [trim_shift(:,1),fliplr(trim_shift(:,2:end))].* maskb; + trim_shiftb = [trim_shiftb(:,1),fliplr(trim_shiftb(:,2:end))].* maskb; + trim_coeffb = [trim_coeffb(:,1),fliplr(trim_coeffb(:,2:end))].* maskb; + %trim_shift = trim_shift .* maskb; + %trimfold = max(cumsum(maskb,2),[],2); + %figure; + if plots == 1; figure(91); imagesc(trim_shift); caxis([-5 5]); end; + if plots == 1; figure(90); imagesc(trim_shiftb); caxis([-5 5]); end; + %imagesc(trim_shiftb); + + %trim_sum = sum(abs(trim_shift(:,startvol:endvol)),2) ./ max(cumsum(maskb(:,startvol:endvol),2),[],2); + % trim_shiftcj = trim_shift; + %trim_datacj = trim_data; + + trim_shift = cumsum(trim_shift,2); + trim_shift = conv2(filt_smo2,filt_smo,trim_shift,'same'); + trim_shift = trim_shift .* mask; + %trim_shift(data==0) = 0; + % trim_sum = sum(trim_shift,2); + %n = length(trim_shift); + %trim_sum = sqrt((1/n)*sum((trim_shift.^2),2)); + + + % % normalise the sum of the shifts for the fold in case we have + % % difference in fold + % norm_fold_b = max(cumsum(fmask(:,startvol:endvol),2),[],2); + % norm_fold = max(cumsum(fmask(:,startvol:midtrc),2),[],2); + % norm_fold_b(norm_fold_b == 0) = 1; + % norm_fold(norm_fold == 0) = 1; + + % %tf %stackin = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(maskb(:,startvol:endvol),2),[],2); + % stackin = sum(trim_data(:,startvol:midtrc),2) ./ norm_fold; + % stackinb = sum(trim_data(:,startvol:endvol),2) ./ norm_fold_b; + % %stackin = sum(trim_data(:,startvol:midtrc),2) ./ max(cumsum(fmask(:,startvol:midtrc),2),[],2); + % %stackinb = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(fmask(:,startvol:endvol),2),[],2); + + + %if plots == 2; ilplotin(:,kk) = stackin; end + ftrim_shift = interp1(time_sub,trim_shift,time(:,1),'linear',0); + ftrim_shiftb = interp1(time_sub,trim_shiftb,time(:,1),'linear',0); + ftrim_coeffb = interp1(time_sub,trim_coeffb,time(:,1),'linear',0); + maskpi = interp1(time_sub,mask,time(:,1),'linear',0); + + if strcmp(mode,'apply') + for ii = 1:n_traces_gather + out_traces(:,ii,kk) = interp1(time(:,ii),trim_data(:,ii),time(:,ii)-ftrim_shift(:,ii),'linear',0); + trim_coeffb_out(:,ii) = interp1(time(:,ii),ftrim_coeffb(:,ii),time(:,ii)-ftrim_shift(:,ii),'linear',0); + end + else + for ii = 1:n_traces_gather + trim_coeffb_out(:,ii) = interp1(time(:,ii),ftrim_coeffb(:,ii),time(:,ii)-ftrim_shift(:,ii),'linear',0); + out_traces(:,ii,kk) = interp1(time(:,ii),ftrim_shiftb(:,ii),time(:,ii)-ftrim_shift(:,ii),'linear',0); + end + + out_traces(:,1:n_traces_gather,kk) = cumsum(out_traces(:,1:n_traces_gather,kk),2); + out_traces(:,1:n_traces_gather,kk) = squeeze(out_traces(:,1:n_traces_gather,kk)) .* maskpi; + + + + + % pick xcorrelation peaks - these are times to pick velocities at + + % coeff_peaks_in = coeff_sum; + % coeff_peaks_out = zeros(size(coeff_peaks_in),1); + + + % while max(coeff_peaks_in)>0.95 + % + % [~,peak_idx] = max(coeff_peaks_in); + % coeff_peaks_out(peak_idx) = coeff_peaks_in(peak_idx); + % start_mask=max(peak_idx-50,1); + % end_mask=min(peak_idx+50,wb_n_samples); + % + % coeff_peaks_in(start_mask:end_mask) = 0; + % + % end + + end + trim_coeffb_out(trim_coeffb_out == 0) = NaN; % set zero to NaN for nanmean + + coeff_sum(:,kk) = nanmean(trim_coeffb_out,2); + coeff_sum(isnan(coeff_sum)) = 0; + + stack_traces = 0; + stack_shifts=0; + + + % % % % cj test version of shifts ======================== + % % zoom3 = 600; + % % zoom4 = 1000; + % % % figure(108); imagesc(trim_datacj(zoom3:zoom4,:)) ; colormap(gray); caxis([-50 50]); + % % % trim_datacjb = trim_datacj; + % % % trim_datacj = fliplr(trim_datacj); + % % % trim_shiftcj = fliplr(trim_shift); + % % % + % % % % for ii = 2:n_traces_gather + % % % % for jj = 1:ii + % % % % trim_datacj(:,jj) = interp1(time(:,1),trim_datacj(:,jj),time(:,1)-trim_shiftcj(:,ii),'linear',0); + % % % % end + % % % % end + % % % + % % % for ii = 2:n_traces_gather + % % % trim_datacj(:,1:ii) = interp1(time(:,1),trim_datacj(:,1:ii),time(:,ii)-trim_shiftcj(:,ii),'linear',0); + % % % end + % % % trim_datacj = fliplr(trim_datacj); + % % % %trim_shiftcj = fliplr(trim_shiftcj); + % % figure(109); imagesc(trim_datacj(zoom3:zoom4,:)) ; colormap(gray); caxis([-500000 500000]); + % % figure(119); imagesc(trim_datacj) ; colormap(gray); caxis([-500000 500000]); + % % % figure(110); imagesc(trim_datacjb(zoom3:zoom4,:) - trim_datacj(zoom3:zoom4,:) ) ; colormap(gray); caxis([-20 20]); + % % % figure(112); imagesc(trim_datacjb(zoom3:zoom4,:) - trim_data(zoom3:zoom4,:) ) ; colormap(gray); caxis([-20 20]); + % % figure(121); imagesc(trim_data(zoom3:zoom4,:)) ; colormap(gray); caxis([-500000 500000]); + % % figure(111); imagesc(trim_data) ; colormap(gray); caxis([-500000 500000]); + % % % =================================================== + % + % + % if plots == 1; + % figure(102); imagesc(time_balence(trim_data)); colormap(gray); caxis([-4000 4000]); + % figure(103); imagesc(trim_data); colormap(gray); + % end; + % + % % normalise the sum of the shifts for the fold in case we have + % % difference in fold + % % norm_fold_b = max(cumsum(fmask(:,startvol:endvol),2),[],2); + % % norm_fold = max(cumsum(fmask(:,startvol:midtrc),2),[],2); + % % norm_fold_b(norm_fold_b == 0) = 1; + % % norm_fold(norm_fold == 0) = 1; + % + % %tf %trim_sum = sum(abs(trim_shiftb_out(:,startvol:endvol)),2) ./ max(cumsum(maskb(:,startvol:endvol),2),[],2); + % trim_sum = sum(abs(trim_shiftb_out(:,startvol:endvol)),2) ./ norm_fold_b; + % %trim_sum = sum(abs(trim_shiftb_out(:,startvol:endvol)),2) ./ max(cumsum(fmask(:,startvol:endvol),2),[],2); + % %trim_sum = sum(abs(trim_shiftb_out(:,startvol:endvol)),2); + % if plots == 1; figure(109); imagesc(trim_shiftb_out); caxis([-5 5]); end; + % + % %tf %stackout = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(maskb(:,startvol:endvol),2),[],2); + % stackout = sum(trim_data(:,startvol:midtrc),2) ./ norm_fold; + % %stackout = sum(trim_data(:,startvol:midtrc),2) ./ max(cumsum(fmask(:,startvol:midtrc),2),[],2); + % %stackout = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(fmask(:,startvol:endvol),2),[],2); + % + % % ================================================================= + % % now add a section to apply a residual trim static to the whole gather + % % based on the mismatch between the stacks before and after trim and + % % then repeat the final stack + % + % st1 = double(time_balence_stk(stackin)); + % sT1 = S3*spdiags(st1,0,wb_n_samples,wb_n_samples); + % + % st2 = double(time_balence_stk(stackout)); + % st2_shifts = ifft(bsxfun(@times,fft(st2),exp(1i*phase_shifts_orig)),'symmetric'); + % % for count = 1:totnumshifts + % % sT2 = S3*spdiags(st2_shifts(:,count),0,wb_n_samples,wb_n_samples); + % % det_coef5(:,count) = ((sT1*st2_shifts(:,count)).*(sT2*st1))./((sT1*st1).*(sT2*st2_shifts(:,count))); + % % + % % end + % + % + % countr = 1; + % + % for count = 2:2:totnumshifts + % sT2 = S3*spdiags(st2_shifts(:,count),0,wb_n_samples,wb_n_samples); + % det_coef3(:,countr) = ((sT1*st2_shifts(:,count)).*(sT2*st1))./((sT1*st1).*(sT2*st2_shifts(:,count))); + % countr = countr +1; + % end + % det_coef3(isnan(det_coef3)) = 0; + % det_coef4 = interp1(4:4:(totnumshifts*2),det_coef3',1:( ((totnumshifts-1)/2)*4 + 3 ),'spline'); + % % add in a taper to zero out large shifts in the shallow before picking + % % the max + % det_coef4 = det_coef4'.*shift_maskstk; + % [~,stkidx]= max(det_coef4,[],2); + % stack_shift = (stkidx-(idxshift*2))*(shiftinc/2); + % + % trim_data(:,1:n_traces_gather) = interp1(time(:,1),trim_data(:,1:n_traces_gather),time(:,1)+stack_shift(:,1),'linear',0); + % + % + % stackoutb = sum(trim_data(:,startvol:endvol),2) ./ norm_fold_b; + % stackout = sum(trim_data(:,startvol:midtrc),2) ./ norm_fold; + % %stackoutb = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(fmask(:,startvol:endvol),2),[],2); + % %stackout = sum(trim_data(:,startvol:midtrc),2) ./ max(cumsum(fmask(:,startvol:midtrc),2),[],2); + % % ================================================================= + % + % if plots == 2; ilplot(:,kk) = stackout; end + % %ilplotb(:,kk) = stackoutb; + % + % + % + % results_out{2,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,:,kk) = ftrim_shift; + % traces(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,:,kk) = trim_data; + % + % results_out2{2,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = trim_sum; + % results_out2{3,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = stackin; + % results_out2{4,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = stackout; + % results_out2{5,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = stackoutb; + % results_out2{6,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = stackinb; + % + % % end + % end + % + % % if plots == 2; + % % zoom1 = 400; + % % zoom2 = 800; + % % %figure(102); imagesc((ilplotb(500:700,:) - ilplot(500:700,:))); colormap(gray); caxis([-100 100]) + % % %figure(101); imagesc(ilplotb(zoom1:zoom2,:)); colormap(gray); caxis([-200 200]) + % % figure(100); imagesc(ilplot(zoom1:zoom2,:)); colormap(gray); caxis([-200 200]) + % % figure(103); imagesc(ilplotin(zoom1:zoom2,:)); colormap(gray); caxis([-200 200]) + % % figure(102); imagesc((ilplotin(zoom1:zoom2,:) - ilplot(zoom1:zoom2,:))); colormap(gray); caxis([-100 100]) + % % %figure(104); imagesc((ilplotin(zoom1:zoom2,:) - ilplotb(zoom1:zoom2,:))); colormap(gray); caxis([-100 100]) + % % figure(105); imagesc(results_out2{2,2}(zoom1:zoom2,1:kk)) + % % figure(107); imagesc(squeeze(results_out{2,2}(zoom1:zoom2,36,1:kk))) + % % figure(108); imagesc(reshape(results_out{3,2}(zoom1:zoom2,:,1:50:kk),(zoom2-zoom1+1),[])); colormap(gray); caxis([-100 100]); + % % end + % + % % need to reshape the 2 3d matricies into 2d ones as the segy write just wants samples * total traces + % + % results_out{2,2} = reshape(results_out{2,2},in_n_samples,[]); + % traces = reshape(traces,in_n_samples,[]); + % + % + % + % % i_block = str2double(i_block); + % % % write the pre-stack dataset + % % node_segy_write(results_out,i_block, orig_sample_rate, output_dir) + % % % write the stack + % % node_segy_write(results_out2,i_block, orig_sample_rate, output_dir) + +end diff --git a/algorithms/trim_calculation/trim_shifts_calculate.m~ b/algorithms/trim_calculation/trim_shifts_calculate.m~ new file mode 100644 index 0000000..4caa400 --- /dev/null +++ b/algorithms/trim_calculation/trim_shifts_calculate.m~ @@ -0,0 +1,703 @@ +function [out_traces stack_shifts stack_traces coeff_sum ] = trim_shifts_calculate(mode,job_meta,traces,timbal,shift_param) +% this works out and applies trim statics and keeps a sum of the statics +% for each z sample +% +% mode: 'calc' or 'apply' +% job_meta: meta data for the input gathers +% traces: input traces - should be cdp-sorted nmo-corrected muted gathers +% timbal: flag for time-balancing +% zsmooth: time/depth smoothing +% +% out_traces: traces with shifts applied or shifts +% out_shifts: traces with samples replaced by shift values +% xcor_coeffs: one trace per input gather with average xcor coefficient +% +% ============================================================================================================ +% sort out parameters +timbal = str2double(timbal); +shift_param = str2double(shift_param); +% ============================================================================================================ +% zsmooth parameter was not used + +% useselectemode = 0; +% if isempty(regexp(zsmooth,'il','once')) == 0 +% useselectemode = 1; +% requiredinline = str2double(regexprep(zsmooth,'il','')); +% %requiredinline = str2double(strrep(tottracerun,'il','')); +% zsmooth = 20; +% else +% zsmooth = str2double(zsmooth); +% end + +% zsmooth = str2double(zsmooth); +%zsmooth2 = shift*2; +% if zsmooth2 < 7 +% zsmooth2 = 7; +% end +% ============================================================================================================ + + +shiftinc = 0.2; +plots = 0; +padding = 50; +% Wavelet estimation parameters +ns_win = 128; +hns_win = ns_win/2; +ns_overlap = 96; +totmaxshift = 5; + +% ============================================================================================================ +% % load the job meta file containing more parameters +% job_meta = load(job_meta_path); +sample_rate = (job_meta.s_rate/1000); +% add the history of jobs run and this one to the curent ebcdic +% ebdichdr = ['trim statics ']; +% if isfield(job_meta,'comm_history') +% ebdichdr2 = job_meta.comm_history; +% tmpebc = ebdichdr2{size(ebdichdr2,1),2}; +% else +% ebdichdr2{1,2} = ''; +% tmpebc = ''; +% end +% +% for ebcii = (size(ebdichdr2,1)-1):-1:1 +% tmpebcc = regexp(ebdichdr2{ebcii,2},'/','split'); +% tmpebc = [tmpebc tmpebcc{1} tmpebcc{end}]; +% end +% tmpebc = sprintf('%-3200.3200s',tmpebc); +% clear tmpebcc ebdichdr2; +% % +% ============================================================================================================ +% Read the data for this block + +% [~, traces, ilxl_read, offset_read] = node_segy_read(job_meta_path,'1',i_block); +% offset = unique(offset_read); +% traces = reshape(traces,size(traces,1),length(offset),[]); +% +% [n_samples,n_traces_gather,n_traces] = size(traces); + +% [seismic, results_out{3,2}, results_out{1,2}{1,1}, offset_read] = node_segy_read(job_meta_path,'1',i_block); +% offset = unique(offset_read); +% results_out{3,2} = reshape(results_out{3,2},size(results_out{3,2},1),length(offset),[]); +% +% % check to make sure it read something if not exit +% if isempty(results_out{3,2}) == 1 && isempty(results_out{1,2}{1,1}) == 1 && isempty(offset_read) == 1 +% return +% end + +% drop data as required +% order is samples, angles, skeys +% results_out{3,2} = results_out{3,2}(1:maxzout,:,:); +% job_meta.n_samples{1} = maxzout; + +%results_out{1,2}{1,1} + +[n_samples,n_traces_gather,n_traces] = size(traces); +in_n_samples = n_samples; + +% apply any itm and otm to the gathers +% sttrc = 2; +% edtrc = n_traces_gather; +% if itm > 0 +% results_out{3,2}(:,1:itm,:) = 0; +% edtrc = (n_traces_gather - itm); +% end +% if otm > 0 +% results_out{3,2}(:,otm:end,:) = 0; +% sttrc = (n_traces_gather - otm) + 2; +% end +% midtrc = startvol + floor((endvol - startvol)/2); +% ============================================================================================================ +% % Make results meta information +% +% % for the pre-stack dataset +% results_out{1,1} = 'Meta data for output files'; +% %results_out{resultno,2}{1,1} = ilxl_read; +% results_out{1,2}{2,1} = offset_read'; +% ebcstrtowrite = sprintf('%-3200.3200s',[results_out{1,1} ' ' ebdichdr ' ' tmpebc]); +% results_out{1,1} = ebcstrtowrite; +% results_out{1,3} = 'is_gather'; % 1 is yes, 0 is no +% +% +% % for the stack output +% results_out2{1,1} = 'Meta data for output files'; +% results_out2{1,2}{1,1} = results_out{1,2}{1,1}(1:n_traces_gather:end,:); +% results_out2{1,2}{2,1} = uint32(zeros(n_traces,1)); +% %ebcstrtowrite = sprintf('%-3200.3200s',[results_out{resultno,1} ' ' ebdichdr ' ' tmpebc]); +% results_out2{1,1} = ebcstrtowrite; +% results_out2{1,3} = 'is_gather'; % 1 is yes, 0 is no +% +% output_dir = [job_meta.output_dir,'trimout/']; +% % check to see if the directory exists +% if exist(output_dir,'dir') == 0 +% mkdir(output_dir); +% end +% +% +% % prestack output +% filename = 'gaths'; +% results_out{2,1} = strcat(filename,'_trim_shifts_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +% results_out{3,1} = strcat(filename,'_trim_data_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +% results_out{2,3} = 1; +% results_out{3,3} = 1; +% results_out{2,2} = zeros(in_n_samples,n_traces_gather,n_traces,'single'); +% %results_out{3,2} = zeros(n_samples,n_traces_gather,n_traces,'single'); +% +% +% +% % stack result +% filename2 = 'stack'; +% results_out2{2,1} = strcat(filename2,'_trim_sum_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +% results_out2{2,2} = zeros(in_n_samples,n_traces,'single'); +% results_out2{3,1} = strcat(filename2,'_pretrim_guide_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +% results_out2{3,2} = zeros(in_n_samples,n_traces,'single'); +% %results_out2{4,1} = strcat(filename2,'_posttrim_no_resid_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +% results_out2{4,1} = strcat(filename2,'_posttrim_guide_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +% results_out2{4,2} = zeros(in_n_samples,n_traces,'single'); +% results_out2{5,1} = strcat(filename2,'_posttrim_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +% results_out2{5,2} = zeros(in_n_samples,n_traces,'single'); +% results_out2{6,1} = strcat(filename2,'_pretrim_',num2str(startvol),'-',num2str(endvol),'_',num2str(zsmooth)); +% results_out2{6,2} = zeros(in_n_samples,n_traces,'single'); +% results_out2{2,3} = 0; +% results_out2{3,3} = 0; +% results_out2{4,3} = 0; +% results_out2{5,3} = 0; +% results_out2{6,3} = 0; +% ======================================================================== +% flattern the data to the water bottom and make a stack of the data for +% freq analysis + + +% % stack to make something to pick wb on +% stackin_freq = sum(results_out{3,2}(:,startvol:midtrc,:),2) ./ ((midtrc - startvol) +1) ; +% % pick wb +% %[wb_idx] = water_bottom_picker(stackin_freq,padding); +% [wb_idx] = water_bottom_picker(squeeze(stackin_freq),padding); +% wb_idx(wb_idx < 0) = 1; +% % write out a wbpick +% %ilxltoprint = results_out{1,2}{1,1}(1:length(offset):end,:); +% % only write out the values that are not 1, so are picked +% %dlmwrite(strcat(output_dir,'wbpick_',i_block,'.xyz'),[ilxltoprint((wb_idx ~= 1)',:),(int32(wb_idx(wb_idx ~= 1)+padding)'.*job_meta.s_rate)/1000],'delimiter', ' ', 'precision', '%-6d','newline', 'unix'); +% % +% win_sub = bsxfun(@plus,wb_idx,(0:n_samples-max(wb_idx))'); +% win_ind = bsxfun(@plus,win_sub,(0:n_samples:n_samples*(n_traces-1))); +% clear win_sub; +% % make anew stack after flattening, make sure to blank it before +% stackin_freq2 = stackin_freq(win_ind); +% %stackin_freq2 = time_balence_stk(stackin_freq2); +% [n_samples,~] = size(stackin_freq2); +clear win_ind stackin_freq; + +wb_idx=ones(n_traces); + +stack_fold = squeeze(max(1,sum(abs(traces)>0,2))); + +stackin_freq2 = squeeze(sum(traces,2))./(stack_fold/n_traces_gather); + +% find the dominant frequency of the data, take a subset of the data and +% +% returns window centre, low, high, weighted avg freq +% +% assign to arrays with same name as in previous code + +peak_freqs = peak_freq_calc(job_meta,stackin_freq2); + +min_freq = peak_freqs(:,[1 2]); +peak_freq = peak_freqs(:,[1 3]); +mid_freq = peak_freqs(:,[1 4]); + +peak_freq(:,2) = 90; +mid_freq(:,2) = 80; + + +% make taper to apply to signal before fft +taperlen = 16; + +taperst = (sin(linspace((-pi/2),(pi/2),taperlen)')+1)/2; +taperend = 1 - taperst; +% taperapply = [taperst;ones((ns_win-(taperlen*2)),1);taperend]; + +% ========================================================================= +%see if the code can resample the data down to calculate shifts at +resamp_rt = round(1000 /(max(mid_freq(:,2))*2)); +use_samp_drop = 0; +wb_n_samples = n_samples; +orig_sample_rate = sample_rate; +time = repmat((0:sample_rate:(n_samples-1)*sample_rate)',1,n_traces_gather); +if resamp_rt > (sample_rate * 1.8) + samp_drop = round(resamp_rt/(sample_rate * 1.8) + 0.1); + sample_rate = sample_rate * samp_drop; + ufoff = 1000/(sample_rate*2); + ufon = ufoff*0.8; + n_samples = length(1:samp_drop:n_samples); + peak_freq((peak_freq(:,2) > ufoff),2) = ufoff; + totmaxshift = ceil(sample_rate/2.5); % was 3 before + use_samp_drop = 1; +end + +time_sub = (0:sample_rate:(n_samples-1)*sample_rate); + +% +% for jj = 1:gathinc:n_traces; +% freq_test = results_out{3,2}(:,sttrc:midtrc,jj); +% %freq_test = time_balence(freq_test); +% +% for ii = 1:n_win +% % Estimate wavelets and store meta information +% % make a tmp array with the fft values in it +% tmpfft = zeros(2,2); +% tmpfft = abs(fft(bsxfun(@times,freq_test(start_index(ii):end_index(ii),:),taperapply))); +% avgfreq = sum(tmpfft,2,'double'); +% avgfreqsmo = conv(avgfreq(1:hns_win),filt_smof,'same'); +% %figure(12); plot(avgfreqsmo); +% cja = (avgfreqsmo > max(avgfreqsmo)*0.75); +% [~,rhs] = max(cja(end:-1:1)); +% highf_idx = (hns_win - rhs) + 1; +% %[~,idxf] = max(avgfreqsmo); +% %peak_freq(ii,:) = [(start_index(ii)+hns_win) ((peak_freq(ii,2)+freq_axis(highf_idx)))]; +% peak_freq(ii,:) = [(start_index(ii)+hns_win) max(peak_freq(ii,2),freq_axis(highf_idx))]; +% end +% end +%peak_freq(:,2) = peak_freq(:,2)/n_win; +% +% % ======================================================================== +% % calculate the shift limits and the smoothing for the trim, currently +% % the wavelength at the peak freq at 2000m/s divided by 30 +% % max_shift = [peak_freq(:,1) (2000./(peak_freq(:,2)*42))]; + +% max_shift = [peak_freq(:,1) (2000./(peak_freq(:,2)*13))]; + +max_shift = zeros(size(peak_freq)); + +max_shift(:,1) = peak_freq(:,1); +max_shift(:,2) = shift_param; + +% smooth the shifts +%filt_smos = ones(1,3)/3; +%max_shift = conv(max_shift,filt_smos,'same'); +max_shift(:,2) = floor(max_shift(:,2)./shiftinc)*shiftinc; +max_shiftstk = max_shift; +max_shiftstk(:,2) = max_shiftstk(:,2).*4; % was 3 before this allows the residual to do more + +% calculate the length of the smoother, currently 10 times the shift value +freq_grid = [max_shift(:,1) floor(max_shift(:,2).*10)]; + +shift = max(max_shift(:,2)); +% find the max shift to calculate +if totmaxshift >= shift + totmaxshift = shift; +else + shift = totmaxshift; +end + +% clip the max shifts +max_shift((max_shift(:,2) > totmaxshift),2) = totmaxshift; +max_shiftstk((max_shiftstk(:,2) > totmaxshift),2) = totmaxshift; + + +totnumshifts = length(-shift:shiftinc:shift); + +%now make the time varying smoothing as a diagonal on a matrix S +%freq_grid2 = [30 11; 300 21; 900 31]; + +totalpts = max(freq_grid(:,2)); +for mm = 1:size(freq_grid,1) + freq_interp_grid(mm,:) = [zeros(1,(totalpts-freq_grid(mm,2))) , 0:(totalpts/freq_grid(mm,2)):totalpts , (totalpts-(totalpts/freq_grid(mm,2))):-(totalpts/freq_grid(mm,2)):0 , zeros(1,(totalpts-freq_grid(mm,2))) ]; + shift_interp_grid(mm,:) = [[zeros(1,round(shift/shiftinc-((max_shift(mm,2)/shiftinc)))) , ones(1,round(max_shift(mm,2)/shiftinc))],1,fliplr([zeros(1,round(shift/shiftinc-(max_shift(mm,2)/shiftinc))) , ones(1,round(max_shift(mm,2)/shiftinc))])]; + shift_interp_gridstk(mm,:) = [[zeros(1,round(shift/shiftinc-((max_shiftstk(mm,2)/shiftinc)))) , ones(1,round((max_shiftstk(mm,2))/shiftinc))],1,fliplr([zeros(1,round(shift/shiftinc-((max_shiftstk(mm,2))/shiftinc))) , ones(1,round((max_shiftstk(mm,2))/shiftinc))])]; +end +start_interp = 1; +end_interp = n_samples; +freq_zgrid = freq_grid(:,1); + +if freq_grid(1,1) > 1 + freq_zgrid = [1; freq_zgrid]; + freq_interp_grid = [ freq_interp_grid(1,:) ; freq_interp_grid]; + shift_interp_grid = [ shift_interp_grid(1,:) ; shift_interp_grid]; + shift_interp_gridstk = [ shift_interp_gridstk(1,:) ; shift_interp_gridstk]; +end +if freq_grid(end,1) < n_samples + freq_zgrid(end+1) = n_samples; + freq_interp_grid(end+1,:) = freq_interp_grid(end,:); + shift_interp_grid(end+1,:) = shift_interp_grid(end,:); + shift_interp_gridstk(end+1,:) = shift_interp_gridstk(end,:); +end + +%make the array to go down the diagonal as a smoother +diag_smo_interp = interp1(freq_zgrid,freq_interp_grid,start_interp:1:end_interp,'linear'); +S = (1/totalpts)*spdiags(diag_smo_interp,[(-totalpts:1:0),(1:1:totalpts)], n_samples,n_samples); + +% now make a smaller smoother +dropf = 3; +dropfsel = [(totalpts + 1) - ((length((totalpts + 1:dropf:(totalpts*2)+1)) -1)*dropf):dropf:totalpts, (totalpts + 1:dropf:(totalpts*2)+1)]; +%droprows = [(-round(totalpts/dropf):1:0),(1:1:round(totalpts/dropf))]; +droprows = [(-round((length(dropfsel) -1)/2):1:0),(1:1:round((length(dropfsel) -1)/2))]; +S2 = (1/totalpts)*spdiags(diag_smo_interp(:,dropfsel),droprows, n_samples,n_samples); + +diag_smo_interp3 = interp1(freq_zgrid,freq_interp_grid,start_interp:1:wb_n_samples,'linear'); +%S3 = (1/totalpts)*spdiags(diag_smo_interp3(:,dropfsel),droprows, wb_n_samples,wb_n_samples); +S3 = (1/totalpts)*spdiags(diag_smo_interp3,[(-totalpts:1:0),(1:1:totalpts)], wb_n_samples,wb_n_samples); + +% make a mask to apply to the shifts before picking the peak +shift_mask = interp1(freq_zgrid,shift_interp_grid,start_interp:1:end_interp,'linear'); + +shift_interp_gridstk = interp1(2:2:(totnumshifts*2),shift_interp_gridstk',1:((totnumshifts*2)+1),'linear'); +shift_interp_gridstk(isnan(shift_interp_gridstk)) = 0; +shift_maskstk = interp1(freq_zgrid,shift_interp_gridstk',start_interp:1:wb_n_samples,'linear'); +shift_mask(shift_mask<1) = 0; +shift_maskstk(shift_maskstk<1) = 0; +% ============================================================================================================ +% loop round the traces 3d array one gather at a time and do calculations +f_max = (1/sample_rate)*1000; +phase_shifts = bsxfun(@times,(-shift:shiftinc:shift),(1/1000).*2.*pi.*repmat((0:f_max/(n_samples-1):f_max)',1,1+2*(shift/shiftinc))); + +f_maxorig = (1/orig_sample_rate)*1000; +phase_shifts_orig = bsxfun(@times,(-shift:shiftinc:shift),(1/1000).*2.*pi.*repmat((0:f_maxorig/(wb_n_samples-1):f_maxorig)',1,1+2*(shift/shiftinc))); + +totnumshifts = length(-shift:shiftinc:shift); +%S = (1/zsmooth)*spdiags(repmat([(1:1:zsmooth),(zsmooth-1:-1:1)],n_samples,1),[(-zsmooth+1:1:0),(1:1:zsmooth-1)],n_samples,n_samples); +%S2 = (1/zsmooth2)*spdiags(repmat([(1:1:zsmooth2),(zsmooth2-1:-1:1)],n_samples,1),[(-zsmooth2+1:1:0),(1:1:zsmooth2-1)],n_samples,n_samples); +det_coef = zeros(n_samples,totnumshifts); +det_coefb = zeros(n_samples,totnumshifts); + +%filttraces = [1 2 3 3 3 3 3 3 3 2 1]/27; +filttraces = [1 2 3 3 2 1]/12; +filt_smo = [1 2 1]/4; +filt_smo2 = ones(1,5)/5; +idxshift = (shift/shiftinc)+1; + +% initialise zeros in output +trim_shift = zeros(n_samples,n_traces_gather,'single'); +trim_shiftb = zeros(n_samples,n_traces_gather,'single'); +trim_shiftb_out = zeros(wb_n_samples,n_traces_gather,'single'); +wt_taperapply = [taperst;ones((wb_n_samples-(taperlen*2)),1);taperend]; +det_coef3 = zeros(wb_n_samples,length(2:2:totnumshifts) ); +norm_fold_b = zeros(wb_n_samples,1,'single'); +norm_fold = zeros(wb_n_samples,1,'single'); +out_traces = zeros(size(traces)); +coeff_sum = zeros(wb_n_samples,n_traces); + +% +for kk = 1:n_traces; + %for kk = 1:200; + % if useselectemode == 0 + % requiredinline = results_out{1,2}{1,1}(kk,1); + % end + % if results_out{1,2}{1,1}(kk,1) == requiredinline; + + + % get the input gather and apply shift to flattern to the water bottom + trim_data = traces(wb_idx(kk):(wb_idx(kk)+wb_n_samples-1),:,kk); + + % apply an automatic mute to remove low amp noise + fmask = low_amp_mute(trim_data); + trim_data = trim_data .* fmask; + + %drop samples if possible + if use_samp_drop == 1 + trim_data_filt = bsxfun(@times,trim_data,wt_taperapply); + trim_data_filt = bandpass_filter(trim_data_filt,(sample_rate/1000),0,0,ufon,ufoff); + trim_data_filt = trim_data_filt(1:samp_drop:end,:); + mask = fmask(1:samp_drop:end,:); + else + trim_data_filt = trim_data; + mask = fmask; + end + + % balence the data to avoid any loud parts dominating any solution + if timbal == 1 + trim_data_filtin = trim_data_filt; + [trim_data_filt scaleused] = time_balence(trim_data_filt); + end + + %trim_data = trim_data_filt; + %trim_data_filt = bandpass_filter(d,dt,f1,f2,f3,f4); + + if plots == 1; figure(101); imagesc(trim_data_filt); colormap(gray); caxis([-4000 4000]); end; + + % apply a small smoother to reduce noise + % if itm > 0 + itm=0; otm=n_traces_gather; + mask(:,1:itm) = 0; + trim_data_filt(:,1:itm) = repmat(trim_data_filt(:,(itm+1)),1,itm); + %end + %if otm > 0 + mask(:,otm:end) = 0; + trim_data_filt(:,otm:n_traces_gather) = repmat(trim_data_filt(:,(otm-1)),1,(n_traces_gather-otm)+1); + %end + + % apply a small smoother to reduce noise + %trim_data_filt = medfilt3nt(trim_data_filt,[0 9],0); +% trim_data_filt = conv2(filt_smo,filttraces,trim_data_filt,'same'); + + if plots == 1; figure(106); imagesc(trim_data_filt); colormap(gray); caxis([-4000 4000]); end; + + %apply mask to the filtered data to remove duplicated data + trim_data_filt = trim_data_filt .* mask; + + % flip the data to work from outside in + trim_data_filt = fliplr(trim_data_filt); + + %for ii = sttrc:edtrc + for ii = 2:n_traces_gather; + t1 = double(trim_data_filt(:,ii-1)); + T1 = S*spdiags(t1,0,n_samples,n_samples); + T1b = S2*spdiags(t1,0,n_samples,n_samples); + + %t2 = double(trim_data_filt(:,ii)); + t2f = fft(double(trim_data_filt(:,ii))); + t2_shifts = ifft(bsxfun(@times,t2f,exp(1i*phase_shifts)),'symmetric'); + + for count = 1:totnumshifts + %T2 = S*spdiags(t2_shifts(:,count),0,n_samples,n_samples); + T2diag = spdiags(t2_shifts(:,count),0,n_samples,n_samples); + %sparse + T2 = S*T2diag; + T2b = S2*spdiags(t2_shifts(:,count),0,n_samples,n_samples); + det_coef(:,count) = ((T1*t2_shifts(:,count)).*(T2*t1))./((T1*t1).*(T2*t2_shifts(:,count))); + det_coefb(:,count) = ((T1b*t2_shifts(:,count)).*(T2b*t1))./((T1b*t1).*(T2b*t2_shifts(:,count))); + end + % add in a taper to zero out large shifts in the shallow before picking + % the max + det_coef = det_coef.*shift_mask; + %det_coefb = det_coefb.*shift_mask; + % cj edit took out the mask as it was making steps in the + % results + + %[~,idx] = max(det_coef'); + %trim_shift(:,ii-1) = idx'-shift-1; + [~,idx]= max(det_coef,[],2); + [coeffb,idxb]= max(det_coefb,[],2); + + trim_shift(:,ii) = (idx-idxshift)*shiftinc; + trim_shiftb(:,ii) = (idxb-idxshift)*shiftinc; + trim_coeffb(:,ii) = coeffb; + %trim_shift(:,ii-1) = idx-shift-1; + + end + + maskb = [ones(n_samples,1,'single'),mask(:,1:(end -1))] .* [mask(:,2:end),ones(n_samples,1,'single')]; + trim_shift = [trim_shift(:,1),fliplr(trim_shift(:,2:end))].* maskb; + trim_shiftb = [trim_shiftb(:,1),fliplr(trim_shiftb(:,2:end))].* maskb; + trim_coeffb = [trim_coeffb(:,1),fliplr(trim_coeffb(:,2:end))].* maskb; + %trim_shift = trim_shift .* maskb; + %trimfold = max(cumsum(maskb,2),[],2); + %figure; + if plots == 1; figure(91); imagesc(trim_shift); caxis([-5 5]); end; + if plots == 1; figure(90); imagesc(trim_shiftb); caxis([-5 5]); end; + %imagesc(trim_shiftb); + + %trim_sum = sum(abs(trim_shift(:,startvol:endvol)),2) ./ max(cumsum(maskb(:,startvol:endvol),2),[],2); + % trim_shiftcj = trim_shift; + %trim_datacj = trim_data; + + trim_shift = cumsum(trim_shift,2); + trim_shift = conv2(filt_smo2,filt_smo,trim_shift,'same'); + trim_shift = trim_shift .* mask; + %trim_shift(data==0) = 0; + % trim_sum = sum(trim_shift,2); + %n = length(trim_shift); + %trim_sum = sqrt((1/n)*sum((trim_shift.^2),2)); + + + % % normalise the sum of the shifts for the fold in case we have + % % difference in fold + % norm_fold_b = max(cumsum(fmask(:,startvol:endvol),2),[],2); + % norm_fold = max(cumsum(fmask(:,startvol:midtrc),2),[],2); + % norm_fold_b(norm_fold_b == 0) = 1; + % norm_fold(norm_fold == 0) = 1; + + % %tf %stackin = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(maskb(:,startvol:endvol),2),[],2); + % stackin = sum(trim_data(:,startvol:midtrc),2) ./ norm_fold; + % stackinb = sum(trim_data(:,startvol:endvol),2) ./ norm_fold_b; + % %stackin = sum(trim_data(:,startvol:midtrc),2) ./ max(cumsum(fmask(:,startvol:midtrc),2),[],2); + % %stackinb = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(fmask(:,startvol:endvol),2),[],2); + + + %if plots == 2; ilplotin(:,kk) = stackin; end + ftrim_shift = interp1(time_sub,trim_shift,time(:,1),'linear',0); + ftrim_shiftb = interp1(time_sub,trim_shiftb,time(:,1),'linear',0); + ftrim_coeffb = interp1(time_sub,trim_coeffb,time(:,1),'linear',0); + maskpi = interp1(time_sub,mask,time(:,1),'linear',0); + + if strcmp(mode,'apply') + for ii = 1:n_traces_gather + out_traces(:,ii,kk) = interp1(time(:,ii),trim_data(:,ii),time(:,ii)-ftrim_shift(:,ii),'linear',0); + trim_coeffb_out(:,ii) = interp1(time(:,ii),ftrim_coeffb(:,ii),time(:,ii)-ftrim_shift(:,ii),'linear',0); + end + else + for ii = 1:n_traces_gather + trim_coeffb_out(:,ii) = interp1(time(:,ii),ftrim_coeffb(:,ii),time(:,ii)-ftrim_shift(:,ii),'linear',0); + out_traces(:,ii,kk) = interp1(time(:,ii),ftrim_shiftb(:,ii),time(:,ii)-ftrim_shift(:,ii),'linear',0); + end + + out_traces(:,1:n_traces_gather,kk) = cumsum(out_traces(:,1:n_traces_gather,kk),2); + out_traces(:,1:n_traces_gather,kk) = squeeze(out_traces(:,1:n_traces_gather,kk)) .* maskpi; + + + + + % pick xcorrelation peaks - these are times to pick velocities at + + % coeff_peaks_in = coeff_sum; + % coeff_peaks_out = zeros(size(coeff_peaks_in),1); + + + % while max(coeff_peaks_in)>0.95 + % + % [~,peak_idx] = max(coeff_peaks_in); + % coeff_peaks_out(peak_idx) = coeff_peaks_in(peak_idx); + % start_mask=max(peak_idx-50,1); + % end_mask=min(peak_idx+50,wb_n_samples); + % + % coeff_peaks_in(start_mask:end_mask) = 0; + % + % end + + end + trim_coeffb_out(trim_coeffb_out == 0) = NaN; % set zero to NaN for nanmean + + coeff_sum(:,kk) = nanmean(trim_coeffb_out,2); + coeff_sum(isnan(coeff_sum)) = 0; + + stack_traces = 0; + stack_shifts=0; + + + % % % % cj test version of shifts ======================== + % % zoom3 = 600; + % % zoom4 = 1000; + % % % figure(108); imagesc(trim_datacj(zoom3:zoom4,:)) ; colormap(gray); caxis([-50 50]); + % % % trim_datacjb = trim_datacj; + % % % trim_datacj = fliplr(trim_datacj); + % % % trim_shiftcj = fliplr(trim_shift); + % % % + % % % % for ii = 2:n_traces_gather + % % % % for jj = 1:ii + % % % % trim_datacj(:,jj) = interp1(time(:,1),trim_datacj(:,jj),time(:,1)-trim_shiftcj(:,ii),'linear',0); + % % % % end + % % % % end + % % % + % % % for ii = 2:n_traces_gather + % % % trim_datacj(:,1:ii) = interp1(time(:,1),trim_datacj(:,1:ii),time(:,ii)-trim_shiftcj(:,ii),'linear',0); + % % % end + % % % trim_datacj = fliplr(trim_datacj); + % % % %trim_shiftcj = fliplr(trim_shiftcj); + % % figure(109); imagesc(trim_datacj(zoom3:zoom4,:)) ; colormap(gray); caxis([-500000 500000]); + % % figure(119); imagesc(trim_datacj) ; colormap(gray); caxis([-500000 500000]); + % % % figure(110); imagesc(trim_datacjb(zoom3:zoom4,:) - trim_datacj(zoom3:zoom4,:) ) ; colormap(gray); caxis([-20 20]); + % % % figure(112); imagesc(trim_datacjb(zoom3:zoom4,:) - trim_data(zoom3:zoom4,:) ) ; colormap(gray); caxis([-20 20]); + % % figure(121); imagesc(trim_data(zoom3:zoom4,:)) ; colormap(gray); caxis([-500000 500000]); + % % figure(111); imagesc(trim_data) ; colormap(gray); caxis([-500000 500000]); + % % % =================================================== + % + % + % if plots == 1; + % figure(102); imagesc(time_balence(trim_data)); colormap(gray); caxis([-4000 4000]); + % figure(103); imagesc(trim_data); colormap(gray); + % end; + % + % % normalise the sum of the shifts for the fold in case we have + % % difference in fold + % % norm_fold_b = max(cumsum(fmask(:,startvol:endvol),2),[],2); + % % norm_fold = max(cumsum(fmask(:,startvol:midtrc),2),[],2); + % % norm_fold_b(norm_fold_b == 0) = 1; + % % norm_fold(norm_fold == 0) = 1; + % + % %tf %trim_sum = sum(abs(trim_shiftb_out(:,startvol:endvol)),2) ./ max(cumsum(maskb(:,startvol:endvol),2),[],2); + % trim_sum = sum(abs(trim_shiftb_out(:,startvol:endvol)),2) ./ norm_fold_b; + % %trim_sum = sum(abs(trim_shiftb_out(:,startvol:endvol)),2) ./ max(cumsum(fmask(:,startvol:endvol),2),[],2); + % %trim_sum = sum(abs(trim_shiftb_out(:,startvol:endvol)),2); + % if plots == 1; figure(109); imagesc(trim_shiftb_out); caxis([-5 5]); end; + % + % %tf %stackout = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(maskb(:,startvol:endvol),2),[],2); + % stackout = sum(trim_data(:,startvol:midtrc),2) ./ norm_fold; + % %stackout = sum(trim_data(:,startvol:midtrc),2) ./ max(cumsum(fmask(:,startvol:midtrc),2),[],2); + % %stackout = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(fmask(:,startvol:endvol),2),[],2); + % + % % ================================================================= + % % now add a section to apply a residual trim static to the whole gather + % % based on the mismatch between the stacks before and after trim and + % % then repeat the final stack + % + % st1 = double(time_balence_stk(stackin)); + % sT1 = S3*spdiags(st1,0,wb_n_samples,wb_n_samples); + % + % st2 = double(time_balence_stk(stackout)); + % st2_shifts = ifft(bsxfun(@times,fft(st2),exp(1i*phase_shifts_orig)),'symmetric'); + % % for count = 1:totnumshifts + % % sT2 = S3*spdiags(st2_shifts(:,count),0,wb_n_samples,wb_n_samples); + % % det_coef5(:,count) = ((sT1*st2_shifts(:,count)).*(sT2*st1))./((sT1*st1).*(sT2*st2_shifts(:,count))); + % % + % % end + % + % + % countr = 1; + % + % for count = 2:2:totnumshifts + % sT2 = S3*spdiags(st2_shifts(:,count),0,wb_n_samples,wb_n_samples); + % det_coef3(:,countr) = ((sT1*st2_shifts(:,count)).*(sT2*st1))./((sT1*st1).*(sT2*st2_shifts(:,count))); + % countr = countr +1; + % end + % det_coef3(isnan(det_coef3)) = 0; + % det_coef4 = interp1(4:4:(totnumshifts*2),det_coef3',1:( ((totnumshifts-1)/2)*4 + 3 ),'spline'); + % % add in a taper to zero out large shifts in the shallow before picking + % % the max + % det_coef4 = det_coef4'.*shift_maskstk; + % [~,stkidx]= max(det_coef4,[],2); + % stack_shift = (stkidx-(idxshift*2))*(shiftinc/2); + % + % trim_data(:,1:n_traces_gather) = interp1(time(:,1),trim_data(:,1:n_traces_gather),time(:,1)+stack_shift(:,1),'linear',0); + % + % + % stackoutb = sum(trim_data(:,startvol:endvol),2) ./ norm_fold_b; + % stackout = sum(trim_data(:,startvol:midtrc),2) ./ norm_fold; + % %stackoutb = sum(trim_data(:,startvol:endvol),2) ./ max(cumsum(fmask(:,startvol:endvol),2),[],2); + % %stackout = sum(trim_data(:,startvol:midtrc),2) ./ max(cumsum(fmask(:,startvol:midtrc),2),[],2); + % % ================================================================= + % + % if plots == 2; ilplot(:,kk) = stackout; end + % %ilplotb(:,kk) = stackoutb; + % + % + % + % results_out{2,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,:,kk) = ftrim_shift; + % traces(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,:,kk) = trim_data; + % + % results_out2{2,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = trim_sum; + % results_out2{3,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = stackin; + % results_out2{4,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = stackout; + % results_out2{5,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = stackoutb; + % results_out2{6,2}(wb_idx(kk):wb_idx(kk)+wb_n_samples-1,kk) = stackinb; + % + % % end + % end + % + % % if plots == 2; + % % zoom1 = 400; + % % zoom2 = 800; + % % %figure(102); imagesc((ilplotb(500:700,:) - ilplot(500:700,:))); colormap(gray); caxis([-100 100]) + % % %figure(101); imagesc(ilplotb(zoom1:zoom2,:)); colormap(gray); caxis([-200 200]) + % % figure(100); imagesc(ilplot(zoom1:zoom2,:)); colormap(gray); caxis([-200 200]) + % % figure(103); imagesc(ilplotin(zoom1:zoom2,:)); colormap(gray); caxis([-200 200]) + % % figure(102); imagesc((ilplotin(zoom1:zoom2,:) - ilplot(zoom1:zoom2,:))); colormap(gray); caxis([-100 100]) + % % %figure(104); imagesc((ilplotin(zoom1:zoom2,:) - ilplotb(zoom1:zoom2,:))); colormap(gray); caxis([-100 100]) + % % figure(105); imagesc(results_out2{2,2}(zoom1:zoom2,1:kk)) + % % figure(107); imagesc(squeeze(results_out{2,2}(zoom1:zoom2,36,1:kk))) + % % figure(108); imagesc(reshape(results_out{3,2}(zoom1:zoom2,:,1:50:kk),(zoom2-zoom1+1),[])); colormap(gray); caxis([-100 100]); + % % end + % + % % need to reshape the 2 3d matricies into 2d ones as the segy write just wants samples * total traces + % + % results_out{2,2} = reshape(results_out{2,2},in_n_samples,[]); + % traces = reshape(traces,in_n_samples,[]); + % + % + % + % % i_block = str2double(i_block); + % % % write the pre-stack dataset + % % node_segy_write(results_out,i_block, orig_sample_rate, output_dir) + % % % write the stack + % % node_segy_write(results_out2,i_block, orig_sample_rate, output_dir) + +end \ No newline at end of file diff --git a/algorithms/water_bottom_picker/water_bottom_picker.m b/algorithms/water_bottom_picker/water_bottom_picker.m new file mode 100644 index 0000000..9d66693 --- /dev/null +++ b/algorithms/water_bottom_picker/water_bottom_picker.m @@ -0,0 +1,70 @@ +function [wb_idx] = water_bottom_picker(traces,padding) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% water_bottom_picker: function to pick water bottom (first event) of +% seismic dataset. +% Arguments: +% traces = seismic traces as matrix (rows samples; columns traces) +% padding = zero padding of picked water bottom +% +% Outputs: +% wb_idx = index of water bottom that is picked +% +% Writes to Disk: +% nothing + + exponent = 12; + %[~, wb_idx] = max(traces); + %med_wb_idx = median(wb_idx)-10; + inverse_gain = (size(traces,1):-1:1)'.^exponent; + %inverse_gain = circshift(inverse_gain,med_wb_idx); + traces = abs(bsxfun(@times,double(traces),inverse_gain)); + [~, wb_idx] = max(traces); + filtw = [1 2 3 3 3 3 3 3 3 3 2 1]/30; + for i_trace = 1:1:size(traces,2); + conv_traces(:,i_trace) = conv(traces(:,i_trace),filtw,'same'); + end + linearInd = sub2ind(size(traces), wb_idx, 1:1:size(traces,2)); + trace_divide = bsxfun(@rdivide,traces-conv_traces,traces(linearInd)-conv_traces(linearInd)); + + trace_divide = bsxfun(@times,trace_divide > 0.3,(1:1:size(traces,1))'); + trace_divide(trace_divide == 0) = NaN; + [wb_idx,~] = min(trace_divide); + + wb_idx = wb_idx-padding; + wb_idx(isnan(wb_idx)) = 1; + wb_idx(wb_idx < 1) = 1; + %wb_idx = medfilt1(wb_idx,20); + % add header to scan file + + +% x = 0:10; +% y = sin(x); +% xx = 0:.25:10; +% yy = spline(x,y,xx); +% peaks = false(size(yy)); +% peaks(2:end-1) = sign(x(2:end-1)-x(1:end-2)) + sign(x(2:end-1)-x(3:end)) > 1; + + + +end diff --git a/algorithms/water_bottom_picker/water_bottom_picker.m~ b/algorithms/water_bottom_picker/water_bottom_picker.m~ new file mode 100644 index 0000000..56929ec --- /dev/null +++ b/algorithms/water_bottom_picker/water_bottom_picker.m~ @@ -0,0 +1,73 @@ +function [wb_idx] = water_bottom_picker(traces,padding) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. + +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 + +%% github +% https://github.com/AnalysePrestackSeismic/ + +%% ------------------ FUNCTION DEFINITION --------------------------------- +% water_bottom_picker: function to pick water bottom (first event) of +% seismic dataset. +% Arguments: +% traces = seismic traces as matrix (rows samples; columns traces) +% padding = zero padding of picked water bottom +% +% Outputs: +% wb_idx = index of water bottom that is picked +% +% Writes to Disk: +% nothing + + exponent = 12; + %[~, wb_idx] = max(traces); + %med_wb_idx = median(wb_idx)-10; + inverse_gain = (size(traces,1):-1:1)'.^exponent; + %inverse_gain = circshift(inverse_gain,med_wb_idx); + traces = abs(bsxfun(@times,double(traces),inverse_gain)); + [~, wb_idx] = max(traces); + filtw = [1 2 3 3 3 3 3 3 3 3 2 1]/30; + for i_trace = 1:1:size(traces,2); + conv_traces(:,i_trace) = conv(traces(:,i_trace),filtw,'same'); + end + linearInd = sub2ind(size(traces), wb_idx, 1:1:size(traces,2)); + trace_divide = bsxfun(@rdivide,traces-conv_traces,traces(linearInd)-conv_traces(linearInd)); + + trace_divide = bsxfun(@times,trace_divide > 0.3,(1:1:size(traces,1))'); + trace_divide(trace_divide == 0) = NaN; + [wb_idx,~] = min(trace_divide); + + wb_idx = wb_idx-padding; + wb_idx(isnan(wb_idx)) = 1; + wb_idx(wb_idx < 1) = 1; + %wb_idx = medfilt1(wb_idx,20); + % add header to scan file + + +% x = 0:10; +% y = sin(x); +% xx = 0:.25:10; +% yy = spline(x,y,xx); +% peaks = false(size(yy)); +% peaks(2:end-1) = sign(x(2:end-1)-x(1:end-2)) + sign(x(2:end-1)-x(3:end)) > 1; + + + +end diff --git a/algorithms/wavelet_estimation/wavelet_avg.m b/algorithms/wavelet_estimation/wavelet_avg.m new file mode 100644 index 0000000..c3228a9 --- /dev/null +++ b/algorithms/wavelet_estimation/wavelet_avg.m @@ -0,0 +1,169 @@ +function [] = wavelet_avg(job_meta_path) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. + +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% wavelet_avg: function to create wavelet set for use in DIGI. Currently +% wavelets vary with time and angle. Spatially variant wavelets not yet +% implemented. +% Arguments: +% job_meta_path = path to .mat file created using +% segy_make_job function. +% +% Outputs: +% all_wavelets_time.mat = mat file to be input into DIGI. +% This .mat file contains .... ?? +% all_wavelets_freq (...), all_wavelets_time (...), max_wavelet_zgrid (...), +% min_wavelet_zgrid(...) +% +% Writes to Disk: +% nothing + +job_meta = load(job_meta_path); % Load job meta information + +if job_meta.is_gather == 0 % For the case of using angle stacks + i_vol_max = job_meta.nvols; % Number of angle stacks +else % For the case of using angle gathers + i_vol_max = ((job_meta.tkey_max - job_meta.tkey_min )/ job_meta.tkey_inc) + 1; % Number of angles in angle gather +end + +%% Wavelet Database Management for all bocks-- preconditioning for averaging + +loopfin = size(job_meta.liveblocks,1); % Number of Live Blocks +lpi = 1; % Loop Index +count = 1; % Counter for blocks that have a corresponding wavelet file +while lpi <= loopfin + i_block = job_meta.liveblocks(lpi); % Reference the block numbers for live blocks + tmpfileout = sprintf('opening file %s',strcat(job_meta.wav_directory,'fft_wavelets_block_',num2str(i_block),'.bin')); + + if exist(strcat(job_meta.wav_directory,'fft_wavelets_block_',num2str(i_block),'.bin'),'file') % check if the file exists + disp(tmpfileout) + fid_wav = fopen(strcat(job_meta.wav_directory,... + 'fft_wavelets_block_',num2str(i_block),'.bin')); % open the binary wavelet file for the block + w = fread(fid_wav,'float32'); % Read the binary file and convert to 32 bit floating point precission + n_vol = w(1); % Number of volumes (angle stacks) + n_win = w(2); % Number of windows for wavelet estimation + stdev = w(3); % Standard Deviation :might like to think about calculating this properly based on live samples + live_offset = w(4); % The live angle volume + wb_z_avg = w(5); % Average Z waterbottom in the block? + wave_offset = 6; % This is the index in the wavlet file from where the individual wavelet data starts + job_meta.stdev(i_block,1) = stdev; % Store in job meta file for current live block + job_meta.wb_z_avg(i_block,1) = wb_z_avg; % Store in job meta file for current live block + job_meta.live_offset(i_block,1) = live_offset; % Store in job meta file for current live block + fclose(fid_wav); % Close file + + if count == 1 % Initialize the wavelet matrix if this is the first live block + w_all = zeros(n_win*(job_meta.ns_win+2),n_vol,loopfin); % Matrix for storing all wavelets for all volumes for all live blocks, (Note: length of wavlet array = number of samples in wavelet) + 2 + w_all(:,:,count) = reshape(w(wave_offset:end),[],n_vol);% Reshape the Matrix sperating the different angle volumes in different columns for the first block + max_n_win = n_win; % Intitialize maximum number of wavelet windows in block as number of windows in first block + max_n_vol = n_vol; % Intitialize maximum number of angle volumes in block as number of windows in first block + else % If this is not the first live block, append already initialized wavelet matrix + if n_win > max_n_win % If you encounter a block with bigger window than what has been encountered ljust append a slab for the extra window + w_append = zeros((n_win-max_n_win)*(job_meta.ns_win+2),n_vol,loopfin); % Create new slab of the extra length of window for all volumes for all live blocks + w_all = [w_all; w_append]; % Append the new slab for sccomodating the extra length of window + w_all(1:n_win*(job_meta.ns_win+2),:,count) = reshape(w(wave_offset:end),[],n_vol); % Reshape the Matrix sperating the different angle volumes in different columns for the current block + max_n_win = n_win; + else % If this block has the same or less number of wavelet windows than encountered before + w_all(1:n_win*(job_meta.ns_win+2),:,count) = reshape(w(wave_offset:end),[],n_vol);% Reshape the Matrix sperating the different angle volumes in different columns for the current block + end + end + lpi = lpi + 1; % Increment loop index + count = count + 1; % Increment counter + else % If file doesnot exist + tmpfileout = sprintf('Error opening file %s',strcat(job_meta.wav_directory,'fft_wavelets_block_',num2str(i_block),'.bin')); + disp(tmpfileout) % Display error in opening file + lpi = lpi + 1; % Increment loop index + end +end + +% Note: Description of w_all: +% Dimension 1 - time windows of wavelets +% Dimension 2 - different volumes or angles (offsets) +% Dimension 3 - different blocks (live ones) + +%% Wavelet averaging + %need to take account of zeros + w_sum = sum(w_all,3); % Sum the wavelet spectrum including number of live traces in the blocks for all the blocks + get_windows = squeeze(w_all(1:job_meta.ns_win+2:end,1,:)); % Create a matrix of window starts for all blocks (1 column for each block) + get_windows = unique(get_windows(get_windows ~= 0)); % Create an array of window starts till the maximum Z encountered in any block + w_sum(1:job_meta.ns_win+2:size(w_sum,1),:) = repmat(get_windows,1,i_vol_max); + w_sum = reshape(w_sum,job_meta.ns_win+2,[]); + + %max_traces = max(w_sum(2,:)); + %w_sum = w_sum(:,w_sum(2,:) == max_traces); + + w_avg = [w_sum(2,:); bsxfun(@rdivide,w_sum(3:end,:),w_sum(2,:))]; % Divide the summation of spectrums by total number of live traces for all windows + w_avg_time = [w_sum(1,:); circshift(ifft(w_avg(2:end,:),'symmetric'),floor(job_meta.ns_win/2))]; % Inverse fourier transform to get the time waveletl + w_avg_freq = [w_sum(1,:); w_avg(2:end,:)]; % convert wavelets from frequency to time + +% perform averaging over smaller blocks + +% ilxl_grid = job_meta.block_keys(job_meta.liveblocks,:) +% ilxl_aperture_step = 2; +% n_pos = (2*ilxl_aperture+1)^2; +% positions_right = 0:ilxl_aperture_step:ilxl_aperture; +% positions_left = fliplr(-ilxl_aperture_step:-ilxl_aperture_step:-ilxl_aperture); +% pos_diff_xl = repmat([positions_left positions_right],sqrt(n_pos),1); +% pos_diff_il = pos_diff_xl'; +% pos_diff_il = pos_diff_il(:).*mode(job_meta.pkey_inc); % turn into vector +% pos_diff_xl = pos_diff_xl(:).*mode(job_meta.skey_inc); +% rep_il_pos = bsxfun(@plus,ilxl_grid(:,1), ... +% pos_diff_il'); +% rep_xl_pos = bsxfun(@plus,ilxl_grid(:,2), ... +% pos_diff_xl'); +% rep_il_pos = rep_il_pos'; +% rep_xl_pos = rep_xl_pos'; +% rep_il_pos = rep_il_pos(:); +% rep_xl_pos = rep_xl_pos(:); +% temp_positions = [rep_il_pos rep_xl_pos]; +% +% +% % Average wavelets across blocks +% avg_w = [tmp_w(1,:); bsxfun(@rdivide,tmp_w(3:end,:),tmp_w(2,:))]; +% avg_w = avg_w(:,logical(1-logical(sum(isnan(avg_w))))); +% +% avg_w = avg_w(:,logical(sum(avg_w(2:end,:)))); + + % Save average wavelets + + %save(strcat(job_meta.wav_directory,job_meta.volumes{i_vol},'_avg_w_freq.mat'),'avg_w','-v7.3'); + %save(strcat(job_meta.wav_directory,job_meta.volumes{i_vol},'_avg_w_freq.mat'),'avg_w_time','-v7.3'); + + % Compile final wavelets into cell array to be used in IG inversion + %% + n_win = length(unique(w_sum(1,:))); + for i_vol = 1:1:i_vol_max + all_wavelets_freq{1,i_vol} = w_avg_freq(:,((i_vol-1)*n_win)+1:n_win*i_vol);% Separate the frequency spectruml of different offset volumes + all_wavelets_time{1,i_vol} = w_avg_time(:,((i_vol-1)*n_win)+1:n_win*i_vol);% Separate the wavelet of different offset volumes + wavelet_length(i_vol) = size(w_avg_time,1)-2; + end + + [~,min_ind] = min(wavelet_length); + wavelets.min_wavelet_z_grid = all_wavelets_time{1,min_ind}(1,:); + [~,max_ind] = max(wavelet_length); + wavelets.max_wavelet_z_grid = all_wavelets_time{1,max_ind}(1,:); + wavelets.all_wavelets_time = all_wavelets_time; + wavelets.all_wavelets_freq = all_wavelets_freq; + wavelet_save_path = strcat(job_meta.wav_directory,'all_wavelets_time.mat'); + save(wavelet_save_path,'-struct','wavelets','-v7.3'); + save(job_meta_path,'-struct','job_meta','-v7.3'); +end diff --git a/algorithms/wavelet_estimation/wavelet_avg.m~ b/algorithms/wavelet_estimation/wavelet_avg.m~ new file mode 100644 index 0000000..5ff212b --- /dev/null +++ b/algorithms/wavelet_estimation/wavelet_avg.m~ @@ -0,0 +1,170 @@ +function [] = wavelet_avg(job_meta_path) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. + +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% wavelet_avg: function to create wavelet set for use in DIGI. Currently +% wavelets vary with time and angle. Spatially variant wavelets not yet +% implemented. +% Arguments: +% seismic_mat_path = path to .mat file created using +% segy_make_structure function. +% n_blocks = number of blocks to divide processing into. +% +% Outputs: +% all_wavelets_time.mat = mat file to be input into DIGI. +% This .mat file contains .... ?? +% all_wavelets_freq (...), all_wavelets_time (...), max_wavelet_zgrid (...), +% min_wavelet_zgrid(...) +% +% Writes to Disk: +% nothing + +job_meta = load(job_meta_path); % Load job meta information + +if job_meta.is_gather == 0 % For the case of using angle stacks + i_vol_max = job_meta.nvols; % Number of angle stacks +else % For the case of using angle gathers + i_vol_max = ((job_meta.tkey_max - job_meta.tkey_min )/ job_meta.tkey_inc) + 1; % Number of angles in angle gather +end + +%% Wavelet Database Management for all bocks-- preconditioning for averaging + +loopfin = size(job_meta.liveblocks,1); % Number of Live Blocks +lpi = 1; % Loop Index +count = 1; % Counter for blocks that have a corresponding wavelet file +while lpi <= loopfin + i_block = job_meta.liveblocks(lpi); % Reference the block numbers for live blocks + tmpfileout = sprintf('opening file %s',strcat(job_meta.wav_directory,'fft_wavelets_block_',num2str(i_block),'.bin')); + + if exist(strcat(job_meta.wav_directory,'fft_wavelets_block_',num2str(i_block),'.bin'),'file') % check if the file exists + disp(tmpfileout) + fid_wav = fopen(strcat(job_meta.wav_directory,... + 'fft_wavelets_block_',num2str(i_block),'.bin')); % open the binary wavelet file for the block + w = fread(fid_wav,'float32'); % Read the binary file and convert to 32 bit floating point precission + n_vol = w(1); % Number of volumes (angle stacks) + n_win = w(2); % Number of windows for wavelet estimation + stdev = w(3); % Standard Deviation :might like to think about calculating this properly based on live samples + live_offset = w(4); % The live angle volume + wb_z_avg = w(5); % Average Z waterbottom in the block? + wave_offset = 6; % This is the index in the wavlet file from where the individual wavelet data starts + job_meta.stdev(i_block,1) = stdev; % Store in job meta file for current live block + job_meta.wb_z_avg(i_block,1) = wb_z_avg; % Store in job meta file for current live block + job_meta.live_offset(i_block,1) = live_offset; % Store in job meta file for current live block + fclose(fid_wav); % Close file + + if count == 1 % Initialize the wavelet matrix if this is the first live block + w_all = zeros(n_win*(job_meta.ns_win+2),n_vol,loopfin); % Matrix for storing all wavelets for all volumes for all live blocks, (Note: length of wavlet array = number of samples in wavelet) + 2 + w_all(:,:,count) = reshape(w(wave_offset:end),[],n_vol);% Reshape the Matrix sperating the different angle volumes in different columns for the first block + max_n_win = n_win; % Intitialize maximum number of wavelet windows in block as number of windows in first block + max_n_vol = n_vol; % Intitialize maximum number of angle volumes in block as number of windows in first block + else % If this is not the first live block, append already initialized wavelet matrix + if n_win > max_n_win % If you encounter a block with bigger window than what has been encountered ljust append a slab for the extra window + w_append = zeros((n_win-max_n_win)*(job_meta.ns_win+2),n_vol,loopfin); % Create new slab of the extra length of window for all volumes for all live blocks + w_all = [w_all; w_append]; % Append the new slab for sccomodating the extra length of window + w_all(1:n_win*(job_meta.ns_win+2),:,count) = reshape(w(wave_offset:end),[],n_vol); % Reshape the Matrix sperating the different angle volumes in different columns for the current block + max_n_win = n_win; + else % If this block has the same or less number of wavelet windows than encountered before + w_all(1:n_win*(job_meta.ns_win+2),:,count) = reshape(w(wave_offset:end),[],n_vol);% Reshape the Matrix sperating the different angle volumes in different columns for the current block + end + end + lpi = lpi + 1; % Increment loop index + count = count + 1; % Increment counter + else % If file doesnot exist + tmpfileout = sprintf('Error opening file %s',strcat(job_meta.wav_directory,'fft_wavelets_block_',num2str(i_block),'.bin')); + disp(tmpfileout) % Display error in opening file + lpi = lpi + 1; % Increment loop index + end +end + +% Note: Description of w_all: +% Dimension 1 - time windows of wavelets +% Dimension 2 - different volumes or angles (offsets) +% Dimension 3 - different blocks (live ones) + +%% Wavelet averaging + %need to take account of zeros + w_sum = sum(w_all,3); % Sum the wavelet spectrum including number of live traces in the blocks for all the blocks + get_windows = squeeze(w_all(1:job_meta.ns_win+2:end,1,:)); % Create a matrix of window starts for all blocks (1 column for each block) + get_windows = unique(get_windows(get_windows ~= 0)); % Create an array of window starts till the maximum Z encountered in any block + w_sum(1:job_meta.ns_win+2:size(w_sum,1),:) = repmat(get_windows,1,i_vol_max); + w_sum = reshape(w_sum,job_meta.ns_win+2,[]); + + %max_traces = max(w_sum(2,:)); + %w_sum = w_sum(:,w_sum(2,:) == max_traces); + + w_avg = [w_sum(2,:); bsxfun(@rdivide,w_sum(3:end,:),w_sum(2,:))]; % Divide the summation of spectrums by total number of live traces for all windows + w_avg_time = [w_sum(1,:); circshift(ifft(w_avg(2:end,:),'symmetric'),floor(job_meta.ns_win/2))]; % Inverse fourier transform to get the time waveletl + w_avg_freq = [w_sum(1,:); w_avg(2:end,:)]; % convert wavelets from frequency to time + +% perform averaging over smaller blocks + +% ilxl_grid = job_meta.block_keys(job_meta.liveblocks,:) +% ilxl_aperture_step = 2; +% n_pos = (2*ilxl_aperture+1)^2; +% positions_right = 0:ilxl_aperture_step:ilxl_aperture; +% positions_left = fliplr(-ilxl_aperture_step:-ilxl_aperture_step:-ilxl_aperture); +% pos_diff_xl = repmat([positions_left positions_right],sqrt(n_pos),1); +% pos_diff_il = pos_diff_xl'; +% pos_diff_il = pos_diff_il(:).*mode(job_meta.pkey_inc); % turn into vector +% pos_diff_xl = pos_diff_xl(:).*mode(job_meta.skey_inc); +% rep_il_pos = bsxfun(@plus,ilxl_grid(:,1), ... +% pos_diff_il'); +% rep_xl_pos = bsxfun(@plus,ilxl_grid(:,2), ... +% pos_diff_xl'); +% rep_il_pos = rep_il_pos'; +% rep_xl_pos = rep_xl_pos'; +% rep_il_pos = rep_il_pos(:); +% rep_xl_pos = rep_xl_pos(:); +% temp_positions = [rep_il_pos rep_xl_pos]; +% +% +% % Average wavelets across blocks +% avg_w = [tmp_w(1,:); bsxfun(@rdivide,tmp_w(3:end,:),tmp_w(2,:))]; +% avg_w = avg_w(:,logical(1-logical(sum(isnan(avg_w))))); +% +% avg_w = avg_w(:,logical(sum(avg_w(2:end,:)))); + + % Save average wavelets + + %save(strcat(job_meta.wav_directory,job_meta.volumes{i_vol},'_avg_w_freq.mat'),'avg_w','-v7.3'); + %save(strcat(job_meta.wav_directory,job_meta.volumes{i_vol},'_avg_w_freq.mat'),'avg_w_time','-v7.3'); + + % Compile final wavelets into cell array to be used in IG inversion + %% + n_win = length(unique(w_sum(1,:))); + for i_vol = 1:1:i_vol_max + all_wavelets_freq{1,i_vol} = w_avg_freq(:,((i_vol-1)*n_win)+1:n_win*i_vol);% Separate the frequency spectruml of different offset volumes + all_wavelets_time{1,i_vol} = w_avg_time(:,((i_vol-1)*n_win)+1:n_win*i_vol);% Separate the wavelet of different offset volumes + wavelet_length(i_vol) = size(w_avg_time,1)-2; + end + + [~,min_ind] = min(wavelet_length); + wavelets.min_wavelet_z_grid = all_wavelets_time{1,min_ind}(1,:); + [~,max_ind] = max(wavelet_length); + wavelets.max_wavelet_z_grid = all_wavelets_time{1,max_ind}(1,:); + wavelets.all_wavelets_time = all_wavelets_time; + wavelets.all_wavelets_freq = all_wavelets_freq; + wavelet_save_path = strcat(job_meta.wav_directory,'all_wavelets_time.mat'); + save(wavelet_save_path,'-struct','wavelets','-v7.3'); + save(job_meta_path,'-struct','job_meta','-v7.3'); +end diff --git a/algorithms/wavelet_estimation/wavelet_estimation.m b/algorithms/wavelet_estimation/wavelet_estimation.m new file mode 100644 index 0000000..54865b2 --- /dev/null +++ b/algorithms/wavelet_estimation/wavelet_estimation.m @@ -0,0 +1,357 @@ +function [] = wavelet_estimation(job_meta_path,i_block,decimate,first_live_block) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% wavelet_estimation: Function to estimate wavelets for DIGI +% Pick water bottom on 2/3 of max angle stack to get reliable pick +% Use this pick to flatten all other angle stacks +% Estimate wavelets from flattened angle stacks +% Arguments: +% job_meta_path: Path to job meta file as a string +% i_block: The block on which the program will be run +% decimate: decimation factor +% first_live_block: The block number of the first live block +% +% Outputs: +% Saves to Disk: Wavelet file for ith block in binary format +% Writes to Disk: +% nothing + +plot_on = 0; +decimate = str2double(decimate); +% Load job meta information +lsout = ls(job_meta_path); +job_meta = load(job_meta_path); + +% Wavelet estimation parameters +ns_win = 128; % Number of Samples in the wavelet +%ns_overlap = 32; +ns_overlap = 96; % Number of Samples overlap between moving wavelet window +padding = 50; + + +% Make directory to save results +if exist(strcat(job_meta.output_dir,'wavelets/'),'dir') == 0 + mkdir(strcat(job_meta.output_dir,'wavelets/')) +end +wav_directory = strcat(job_meta.output_dir,'wavelets/'); + +% this bit needs to be changes, might as well stack all the +% offsets/angles/angle stacks and then pick wb on those, this would make +% both post and pre stack reads the same and put the data into a 3d array +% Read traces for 2/3 max angle stack +%vol_index_wb = ceil(job_meta.nvols*0.6667); +if job_meta.is_gather == 0 + pick_wb_ind = ceil(job_meta.nvols*0.6667); + vol_index_wb = 1; + [~, traces{vol_index_wb}, ilxl_read{vol_index_wb}] = node_segy_read(job_meta_path,num2str(pick_wb_ind),i_block); + % check to make sure it read something if not exit + if size(traces{vol_index_wb},1) == 1 && size(traces{vol_index_wb},2) == 1 + return + end +else + % find the water bottom on a few gathers and take the middle one t use + % as an offset plane to pick the water bottom on + vol_index_wb = 1; + % read all the data for this block + % node_segy_read(job_meta_path,vol_index,i_block) + [~, gathers, ilxl_read, offset_read] = node_segy_read(job_meta_path,'1',i_block); + % find the total number of offsets + offset = unique(offset_read); + if isempty(gathers) == 1 && isempty(ilxl_read) == 1 && isempty(offset_read) == 1 + return + end + % juststack = 1; + % if juststack == 1 + traces{vol_index_wb} = zeros(size(gathers,1),size(gathers,2)/size(offset,2)); + for stki = 1:size(offset,2) + traces{vol_index_wb} = traces{vol_index_wb} + gathers(:,offset_read == offset(stki)); + end + % should reshape and sum instead of this terrible loop + % else + % this part of the code could be used to make a sub stack around + % the wb pick time that is the interpolate to find the peak for an + % accurate wb picker + %read the middle 5 gathers in the input data to find the middle tkey(angle/offset) value of the water bottom + %traces{vol_index_wb} = gathers(:,(floor(size(gathers,2)/2)-(length(offset)*2)):(floor(size(gathers,2)/2)+(length(offset)*2))); + %traces{vol_index_wb} = gathers(:,(floor(size(gathers,2)/2)-(length(offset)*2.5)+2):(floor(size(gathers,2)/2)+(length(offset)*2.5))); + %tmpoffread = offset_read((floor(size(gathers,2)/2)-(length(offset)*2.5)+2):(floor(size(gathers,2)/2)+(length(offset)*2.5))); + traces{vol_index_wb} = gathers(:,floor((size(gathers,2)/2)-(length(offset)*2.5)+2):floor((size(gathers,2)/2)+(length(offset)*2.5))); + tmpoffread = offset_read(floor((size(gathers,2)/2)-(length(offset)*2.5)+2):floor((size(gathers,2)/2)+(length(offset)*2.5))); + %pick the water bottom + [wb_idxcj] = water_bottom_picker(traces{vol_index_wb}(:,:),0); + %filter the water bottom pick to make a difference in WB time for + %traces that are not picking the wb + filtw = [1 2 3 2 1]/9; + wb_idxcjfilt = conv(wb_idxcj,filtw,'same'); + % now make a blank array the size of the wb index array + wb_idxcj2 = zeros(1,size(wb_idxcj,2)); + %now find the difference between the values of the filtered and + %unfiltered water bottom indexes, if there is a difference then it is + %likely to not be the water bottom as it should be mostly flat on the + %gathers + wb_idx_diff_ck = abs((wb_idxcj./wb_idxcjfilt)-1); + wb_idxcj2(wb_idx_diff_ck < 0.009) = wb_idxcj(wb_idx_diff_ck < 0.009); + + %now work out the index locations of the water bottom + wb_idx_index = 1:1:size(wb_idxcj,2); + %apply a logical index to the index array to give the index of where the wb is picked and less then 10 elsewhere + wb_idx_index(ismember(wb_idxcj2,floor((min(wb_idxcj2((wb_idxcj2 > 10)))*0.9)):1:ceil((min(wb_idxcj2((wb_idxcj2 > 10)))*1.1)))); + % select the angles with the wb on + tmpwbangs = (tmpoffread(wb_idx_index(ismember(wb_idxcj2,floor((min(wb_idxcj2((wb_idxcj2 > 10)))*0.9)):1:ceil((min(wb_idxcj2((wb_idxcj2 > 10)))*1.1)))))); + tmpangpickstd = ceil(std(double(tmpwbangs))); + tmpangpick = floor(mean(tmpwbangs)); + %tmpangpick = floor(mean(tmpoffread(wb_idx_index(ismember(wb_idxcj2,floor((min(wb_idxcj2((wb_idxcj2 > 10)))*0.9)):1:ceil((min(wb_idxcj2((wb_idxcj2 > 10)))*1.1))))))); + pick_wb_ind = find(offset == tmpangpick); + %tmp_first = max([min(offset) (tmpangpick - tmpangpickstd)]); + %tmp_last = min([max(offset) (tmpangpick + tmpangpickstd)]); + % tmp_first_wbidx = find(offset == max([min(offset) (tmpangpick - tmpangpickstd)])); + % tmp_last_wbidx = find(offset == min([max(offset) (tmpangpick + tmpangpickstd)])); + % %ismember(offset_read,(tmpangpick - tmpangpickstd):(tmpangpick + tmpangpickstd) + % + % traces{vol_index_wb} = zeros(size(gathers,1),size(gathers,2)/size(offset,2)); + % for stki = tmp_first_wbidx:tmp_last_wbidx + % traces{vol_index_wb} = traces{vol_index_wb} + gathers(:,offset_read == offset(stki)); + % end + %traces{vol_index_wb} = traces{vol_index_wb}./(tmp_last_wbidx - tmp_first_wbidx + 1); + + % end + % wb_idx_index(wb_idxcj2 == min(wb_idxcj2((wb_idxcj2 > 10)))); + % % calculate the gather index in each gather by removing the integer + % % number of gathers from the index number and putting back to all being + % % the same angle index in each gather ie 1-46,1-46,1-46 etc... and + % % findingf the average value of all the indexes + % pick_wb_ind = floor(mean(((wb_idx_index(wb_idxcj2 == min(wb_idxcj2((wb_idxcj2 > 10)))))/length(offset) - floor((wb_idx_index(wb_idxcj2 == min(wb_idxcj2((wb_idxcj2 > 10)))))/length(offset)))*length(offset))); + % %read the offset plane from the input data gathers. + traces{vol_index_wb} = gathers(:,offset_read == offset(pick_wb_ind)); +end + +% + +% [~, traces, ~,~] = ... +% node_segy_read(job_meta_path,num2str(vol_index_wb),i_block); +if plot_on == 1 && size(traces{1},2) > 1 + figure(2) + imagesc(traces{1}(:,:)); +end +% Pick water bottom + +if isfield(job_meta, 'wb_path') + %wb_idx = dlmread(job_meta.wb_path,'delimiter','\t'); + wb_idx_in = dlmread(job_meta.wb_path); + % col 1 inline + % col 2 xline + % col 3 twt + [~,locations] = ismember(ilxl_read{1}(1:end,:),wb_idx_in(:,1:2),'rows'); + %wb_idx = zeros(size(traces{vol_index_wb},2),1); + zero_loc = locations ~= 0; + %wb_idx(zero_loc) = wb_idx_in(locations(zero_loc),3); + xi = (1:size(traces{vol_index_wb},2))'; + x = xi(zero_loc)'; + wb_idx = interp1(x,wb_idx_in(locations(zero_loc),3),xi); + clear wb_idx_in + %min_il = min(ilxl_read{vol_index_wb}(:,1)); + %max_il = max(ilxl_read{vol_index_wb}(:,1)); + %min_xl = min(ilxl_read{vol_index_wb}(:,2)); + %max_xl = max(ilxl_read{vol_index_wb}(:,2)); + %wb_idx2 = wb_idx(wb_idx(:,1) >= min_il & wb_idx(:,1) <= max_il & wb_idx(:,2) >= min_xl & wb_idx(:,2) <= max_xl,:); + % wb_idx = wb_idx(wb_idx(:,1) >= min_il & wb_idx(:,1) <= (max_il+1) & wb_idx(:,2) >= min_xl & wb_idx(:,2) <= (max_xl+1),:); + % wb_idx(:,3) = wb_idx(:,3)./(job_meta.s_rate/1000); + wb_idx = (wb_idx./(job_meta.s_rate/1000))'; + %padding = 10; + wb_idx = round(wb_idx-padding); + win_sub = bsxfun(@plus,wb_idx,(0:job_meta.n_samples{vol_index_wb}-max(wb_idx))'); + + win_ind = bsxfun(@plus,win_sub,(0:job_meta.n_samples{vol_index_wb}:... + job_meta.n_samples{vol_index_wb}*(size(traces{vol_index_wb},2)-1))); +else + [wb_idx] = water_bottom_picker(traces{vol_index_wb}(:,1:decimate:end),padding); + wb_idx(wb_idx < 0) = 1; + %wb_idx(isnan(wb_idx)) = 1; + if job_meta.is_gather == 1 + %wbpickfile = fopen(strcat(wav_directory,'wbpick_',i_block,'.xyz'),'w'); + ilxltoprint = ilxl_read(1:length(offset):end,:); + %dlmwrite(strcat(wav_directory,'wbpick_',i_block,'.xyz'),[ilxltoprint,(int32(wb_idx+10)'.*job_meta.s_rate)/1000],'delimiter', ' ', 'precision', '%-6d','newline', 'unix'); + % only write out the values that are not 1, so are picked + dlmwrite(strcat(wav_directory,'wbpick_',i_block,'.xyz'),[ilxltoprint((wb_idx ~= 1)',:),(uint32(wb_idx(wb_idx ~= 1)+padding)'.*job_meta.s_rate)/1000],'delimiter', ' ', 'precision', '%-6d','newline', 'unix'); + %fprintf(wbpickfile,'%6d %6d %6d\n',ilxltoprint[,wb_idx); + %fclose(wbpickfile); + + else + ilxltoprint = ilxl_read{vol_index_wb}; + dlmwrite(strcat(wav_directory,'wbpick_',i_block,'.xyz'),[ilxltoprint((wb_idx ~= 1)',:),(uint32(wb_idx(wb_idx ~= 1)+padding)'.*job_meta.s_rate)/1000],'delimiter', ' ', 'precision', '%-6d','newline', 'unix'); + end + win_sub = bsxfun(@plus,wb_idx,(0:job_meta.n_samples{vol_index_wb}-max(wb_idx))'); + win_ind = bsxfun(@plus,win_sub,(0:job_meta.n_samples{vol_index_wb}:... + job_meta.n_samples{vol_index_wb}*(size(traces{vol_index_wb}(:,1:decimate:end),2)-1))); +end + +% calculate water bottom index +wb_ind_avg = mean(wb_idx); + + +% Loop over all volumes and windows to estimate wavelets, so for angle +% stacks these are seperate volumes, for angle gathers they are different +% planes in the gathers volume + +if job_meta.is_gather == 0 + i_vol_max = job_meta.nvols; +else + i_vol_max = length(offset); +end + +for i_vol = 1:1:i_vol_max + if job_meta.is_gather == 0 + [~, traces, ~, ~] = node_segy_read(job_meta_path,num2str(i_vol),i_block); + else + traces = gathers(:,offset_read == offset(i_vol)); + end + %[n_samples,n_traces] = size(traces); + traces = traces(:,1:decimate:end); + [~,n_traces] = size(traces); + if n_traces > 2 + traces = traces(win_ind); + %variance(i_vol) = var(traces(:)); + + % updated taper to be the same as int_grad_inv + %taper = linspace(0,1,25)'; + taper = single([ zeros(floor(padding-5),1)',linspace(0,1,20)])'; + %traces(1:25,:) = bsxfun(@times,traces(1:25,:),taper); + traces(1:length(taper),:) = bsxfun(@times,traces(1:length(taper),:),taper); + + variance(i_vol) = var(traces(:)); + % cjedit_30122013 + [n_samples,n_traces] = size(traces); % n samples needs to be redefined as the data has been flatterned on the waterbottom index and the array truncated + % + % keep record of number of samples included in std + % n_pop_std(i_vol) = n_samples*n_traces; + start_index = 1:ns_win-ns_overlap-1:n_samples-ns_win; + end_index = start_index+ns_win-1; + % if end_index(end) < n_samples + % end_index(end+1) = n_samples; + % start_index(end+1) = n_samples-ns_win+1; + % end + n_win = length(start_index); + w = zeros(2+ns_win,n_win); + % + % make taper to apply to signal before fft + taperlen = 16; + %taperst = linspace(0,1,taperlen)'; + taperst = (sin(linspace((-pi/2),(pi/2),taperlen)')+1)/2; + taperend = 1 - taperst; + taperapply = [taperst;ones((ns_win-(taperlen*2)),1);taperend]; + % + for ii = 1:n_win + % Estimate wavelets and store meta information + %if ii == n_win + % w(1,ii) = n_samples; + %else + w(1,ii) = start_index(ii); + %end + %w(2,ii) = n_traces; + %NFFT = 2^nextpow2(size(win_sub,1)); + % make a tmp array with the fft values in it + tmpfft = zeros(2,2); + tmpfft = abs(fft(bsxfun(@times,traces(start_index(ii):end_index(ii),:),taperapply))); + %w(2,ii) = floor((sum(tmpfft(:) ~= 0,'double'))/ns_win); + + w(2,ii) = sum(sum(tmpfft ~= 0,1,'double') ~= 0,2); + w(3:end,ii) = sum(tmpfft,2,'double'); + + %w(3:end,ii) = sum(abs(fft(bsxfun(@times,traces(start_index(ii):end_index(ii),:),taperapply))),2); + % index as linear index, summed not averaged! + + % Produce plots showing the windows + if ii == 1 && plot_on == 1 + figure(1) + imagesc(traces(:,1:1000)) + hold on + plot(repmat(end_index(ii),1000),'--') + hold off + elseif plot_on == 1 + hold on + plot(repmat(end_index(ii),1000),'--') + hold off + %figure(2) + %subplot(n_win,1,ii); + %imagesc(traces(start_index(ii):end_index(ii),:)); + end + + end + %end + % cjedit_30122013 - added if to not write out empty wavelets as far + % too many files othwerwise + %cjedit 02/01/2014 - commentout and made a single output file per + %iblock below + % %if n_traces > 1 + % % Save estimated wavelets for this volume + % fid_wav = fopen(strcat(wav_directory,job_meta.volumes{i_vol},'_fft_wavelets_block_',i_block,'.bin'),'w'); + % fwrite(fid_wav,n_win,'float32'); + % fwrite(fid_wav,w,'float32'); + % fclose(fid_wav); + %end + % cjedit 02/01/2014 added a write to only one file per iblock and made + % a slot for angle volume number in the output and total number of + % angle volumes + %% + % Save estimated wavelets for this volume + if i_vol == 1 + fid_wav = fopen(strcat(wav_directory,'fft_wavelets_block_',i_block,'.bin'),'w'); + %fwrite(fid_wav,job_meta.nvols,'float32'); + fwrite(fid_wav,i_vol_max,'float32'); + fwrite(fid_wav,n_win,'float32'); + fwrite(fid_wav,variance(1),'float32'); % this is used by wsmooth parameter in the inversion + fwrite(fid_wav,pick_wb_ind,'float32'); % offset on which the water bottom was picked + fwrite(fid_wav,wb_ind_avg,'float32'); % z of water bottom in block + end + %fwrite(fid_wav,i_vol,'float32'); + %fwrite(fid_wav,n_win,'float32'); + fwrite(fid_wav,w,'float32'); + end + +end +if n_traces > 2 + fclose(fid_wav); + % Open file again to write statistics + fid_wav = fopen(strcat(wav_directory,'fft_wavelets_block_',i_block,'.bin'),'r'); + + % Calculate + stdev = round(sqrt(median(variance))); % might like to think about calculating this properly based on live samples + w = fread(fid_wav,'float32'); + fclose(fid_wav); + w(3) = stdev; + fid_wav = fopen(strcat(wav_directory,'fft_wavelets_block_',i_block,'.bin'),'w'); + fwrite(fid_wav,w,'float32'); + fclose(fid_wav); +end + +%If this is the first live block do the following write into job meta file +if str2double(i_block) == str2double(first_live_block) + % Add processing information to job meta + job_meta.wav_directory = wav_directory; + job_meta.ns_win = ns_win; + %job_meta.n_win = n_win; not the same for each wavelet file + job_meta.ns_overlap = ns_overlap; + save(job_meta_path,'-struct','job_meta','-v7.3'); +end + +end diff --git a/algorithms/wavelet_estimation/wavelet_estimation.m~ b/algorithms/wavelet_estimation/wavelet_estimation.m~ new file mode 100644 index 0000000..db5424e --- /dev/null +++ b/algorithms/wavelet_estimation/wavelet_estimation.m~ @@ -0,0 +1,355 @@ +function [] = wavelet_estimation(job_meta_path,i_block,decimate,first_live_block) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION ---------------------------------%------------------------------------------------------------------------- +% wavelet_estimation: Function to estimate wavelets for DIGI +% Pick water bottom on 2/3 of max angle stack to get reliable pick +% Use this pick to flatten all other angle stacks +% Estimate wavelets from flattened angle stacks +% Input: +% job_meta_path: Path to job meta file as a string +% i_block: The block on which the program will be run +% decimate: decimation factor +% first_live_block: The block number of the first live block +% Output: +% Saves to Disk: Wavelet file for ith block in binary format +% +%------------------------------------------------------------------------- +plot_on = 0; +decimate = str2double(decimate); +% Load job meta information +lsout = ls(job_meta_path); +job_meta = load(job_meta_path); + +% Wavelet estimation parameters +ns_win = 128; % Number of Samples in the wavelet +%ns_overlap = 32; +ns_overlap = 96; % Number of Samples overlap between moving wavelet window +padding = 50; + + +% Make directory to save results +if exist(strcat(job_meta.output_dir,'wavelets/'),'dir') == 0 + mkdir(strcat(job_meta.output_dir,'wavelets/')) +end +wav_directory = strcat(job_meta.output_dir,'wavelets/'); + +% this bit needs to be changes, might as well stack all the +% offsets/angles/angle stacks and then pick wb on those, this would make +% both post and pre stack reads the same and put the data into a 3d array +% Read traces for 2/3 max angle stack +%vol_index_wb = ceil(job_meta.nvols*0.6667); +if job_meta.is_gather == 0 + pick_wb_ind = ceil(job_meta.nvols*0.6667); + vol_index_wb = 1; + [~, traces{vol_index_wb}, ilxl_read{vol_index_wb}] = node_segy_read(job_meta_path,num2str(pick_wb_ind),i_block); + % check to make sure it read something if not exit + if size(traces{vol_index_wb},1) == 1 && size(traces{vol_index_wb},2) == 1 + return + end +else + % find the water bottom on a few gathers and take the middle one t use + % as an offset plane to pick the water bottom on + vol_index_wb = 1; + % read all the data for this block + % node_segy_read(job_meta_path,vol_index,i_block) + [~, gathers, ilxl_read, offset_read] = node_segy_read(job_meta_path,'1',i_block); + % find the total number of offsets + offset = unique(offset_read); + if isempty(gathers) == 1 && isempty(ilxl_read) == 1 && isempty(offset_read) == 1 + return + end + % juststack = 1; + % if juststack == 1 + traces{vol_index_wb} = zeros(size(gathers,1),size(gathers,2)/size(offset,2)); + for stki = 1:size(offset,2) + traces{vol_index_wb} = traces{vol_index_wb} + gathers(:,offset_read == offset(stki)); + end + % should reshape and sum instead of this terrible loop + % else + % this part of the code could be used to make a sub stack around + % the wb pick time that is the interpolate to find the peak for an + % accurate wb picker + %read the middle 5 gathers in the input data to find the middle tkey(angle/offset) value of the water bottom + %traces{vol_index_wb} = gathers(:,(floor(size(gathers,2)/2)-(length(offset)*2)):(floor(size(gathers,2)/2)+(length(offset)*2))); + %traces{vol_index_wb} = gathers(:,(floor(size(gathers,2)/2)-(length(offset)*2.5)+2):(floor(size(gathers,2)/2)+(length(offset)*2.5))); + %tmpoffread = offset_read((floor(size(gathers,2)/2)-(length(offset)*2.5)+2):(floor(size(gathers,2)/2)+(length(offset)*2.5))); + traces{vol_index_wb} = gathers(:,floor((size(gathers,2)/2)-(length(offset)*2.5)+2):floor((size(gathers,2)/2)+(length(offset)*2.5))); + tmpoffread = offset_read(floor((size(gathers,2)/2)-(length(offset)*2.5)+2):floor((size(gathers,2)/2)+(length(offset)*2.5))); + %pick the water bottom + [wb_idxcj] = water_bottom_picker(traces{vol_index_wb}(:,:),0); + %filter the water bottom pick to make a difference in WB time for + %traces that are not picking the wb + filtw = [1 2 3 2 1]/9; + wb_idxcjfilt = conv(wb_idxcj,filtw,'same'); + % now make a blank array the size of the wb index array + wb_idxcj2 = zeros(1,size(wb_idxcj,2)); + %now find the difference between the values of the filtered and + %unfiltered water bottom indexes, if there is a difference then it is + %likely to not be the water bottom as it should be mostly flat on the + %gathers + wb_idx_diff_ck = abs((wb_idxcj./wb_idxcjfilt)-1); + wb_idxcj2(wb_idx_diff_ck < 0.009) = wb_idxcj(wb_idx_diff_ck < 0.009); + + %now work out the index locations of the water bottom + wb_idx_index = 1:1:size(wb_idxcj,2); + %apply a logical index to the index array to give the index of where the wb is picked and less then 10 elsewhere + wb_idx_index(ismember(wb_idxcj2,floor((min(wb_idxcj2((wb_idxcj2 > 10)))*0.9)):1:ceil((min(wb_idxcj2((wb_idxcj2 > 10)))*1.1)))); + % select the angles with the wb on + tmpwbangs = (tmpoffread(wb_idx_index(ismember(wb_idxcj2,floor((min(wb_idxcj2((wb_idxcj2 > 10)))*0.9)):1:ceil((min(wb_idxcj2((wb_idxcj2 > 10)))*1.1)))))); + tmpangpickstd = ceil(std(double(tmpwbangs))); + tmpangpick = floor(mean(tmpwbangs)); + %tmpangpick = floor(mean(tmpoffread(wb_idx_index(ismember(wb_idxcj2,floor((min(wb_idxcj2((wb_idxcj2 > 10)))*0.9)):1:ceil((min(wb_idxcj2((wb_idxcj2 > 10)))*1.1))))))); + pick_wb_ind = find(offset == tmpangpick); + %tmp_first = max([min(offset) (tmpangpick - tmpangpickstd)]); + %tmp_last = min([max(offset) (tmpangpick + tmpangpickstd)]); + % tmp_first_wbidx = find(offset == max([min(offset) (tmpangpick - tmpangpickstd)])); + % tmp_last_wbidx = find(offset == min([max(offset) (tmpangpick + tmpangpickstd)])); + % %ismember(offset_read,(tmpangpick - tmpangpickstd):(tmpangpick + tmpangpickstd) + % + % traces{vol_index_wb} = zeros(size(gathers,1),size(gathers,2)/size(offset,2)); + % for stki = tmp_first_wbidx:tmp_last_wbidx + % traces{vol_index_wb} = traces{vol_index_wb} + gathers(:,offset_read == offset(stki)); + % end + %traces{vol_index_wb} = traces{vol_index_wb}./(tmp_last_wbidx - tmp_first_wbidx + 1); + + % end + % wb_idx_index(wb_idxcj2 == min(wb_idxcj2((wb_idxcj2 > 10)))); + % % calculate the gather index in each gather by removing the integer + % % number of gathers from the index number and putting back to all being + % % the same angle index in each gather ie 1-46,1-46,1-46 etc... and + % % findingf the average value of all the indexes + % pick_wb_ind = floor(mean(((wb_idx_index(wb_idxcj2 == min(wb_idxcj2((wb_idxcj2 > 10)))))/length(offset) - floor((wb_idx_index(wb_idxcj2 == min(wb_idxcj2((wb_idxcj2 > 10)))))/length(offset)))*length(offset))); + % %read the offset plane from the input data gathers. + traces{vol_index_wb} = gathers(:,offset_read == offset(pick_wb_ind)); +end + +% + +% [~, traces, ~,~] = ... +% node_segy_read(job_meta_path,num2str(vol_index_wb),i_block); +if plot_on == 1 && size(traces{1},2) > 1 + figure(2) + imagesc(traces{1}(:,:)); +end +% Pick water bottom + +if isfield(job_meta, 'wb_path') + %wb_idx = dlmread(job_meta.wb_path,'delimiter','\t'); + wb_idx_in = dlmread(job_meta.wb_path); + % col 1 inline + % col 2 xline + % col 3 twt + [~,locations] = ismember(ilxl_read{1}(1:end,:),wb_idx_in(:,1:2),'rows'); + %wb_idx = zeros(size(traces{vol_index_wb},2),1); + zero_loc = locations ~= 0; + %wb_idx(zero_loc) = wb_idx_in(locations(zero_loc),3); + xi = (1:size(traces{vol_index_wb},2))'; + x = xi(zero_loc)'; + wb_idx = interp1(x,wb_idx_in(locations(zero_loc),3),xi); + clear wb_idx_in + %min_il = min(ilxl_read{vol_index_wb}(:,1)); + %max_il = max(ilxl_read{vol_index_wb}(:,1)); + %min_xl = min(ilxl_read{vol_index_wb}(:,2)); + %max_xl = max(ilxl_read{vol_index_wb}(:,2)); + %wb_idx2 = wb_idx(wb_idx(:,1) >= min_il & wb_idx(:,1) <= max_il & wb_idx(:,2) >= min_xl & wb_idx(:,2) <= max_xl,:); + % wb_idx = wb_idx(wb_idx(:,1) >= min_il & wb_idx(:,1) <= (max_il+1) & wb_idx(:,2) >= min_xl & wb_idx(:,2) <= (max_xl+1),:); + % wb_idx(:,3) = wb_idx(:,3)./(job_meta.s_rate/1000); + wb_idx = (wb_idx./(job_meta.s_rate/1000))'; + %padding = 10; + wb_idx = round(wb_idx-padding); + win_sub = bsxfun(@plus,wb_idx,(0:job_meta.n_samples{vol_index_wb}-max(wb_idx))'); + + win_ind = bsxfun(@plus,win_sub,(0:job_meta.n_samples{vol_index_wb}:... + job_meta.n_samples{vol_index_wb}*(size(traces{vol_index_wb},2)-1))); +else + [wb_idx] = water_bottom_picker(traces{vol_index_wb}(:,1:decimate:end),padding); + wb_idx(wb_idx < 0) = 1; + %wb_idx(isnan(wb_idx)) = 1; + if job_meta.is_gather == 1 + %wbpickfile = fopen(strcat(wav_directory,'wbpick_',i_block,'.xyz'),'w'); + ilxltoprint = ilxl_read(1:length(offset):end,:); + %dlmwrite(strcat(wav_directory,'wbpick_',i_block,'.xyz'),[ilxltoprint,(int32(wb_idx+10)'.*job_meta.s_rate)/1000],'delimiter', ' ', 'precision', '%-6d','newline', 'unix'); + % only write out the values that are not 1, so are picked + dlmwrite(strcat(wav_directory,'wbpick_',i_block,'.xyz'),[ilxltoprint((wb_idx ~= 1)',:),(uint32(wb_idx(wb_idx ~= 1)+padding)'.*job_meta.s_rate)/1000],'delimiter', ' ', 'precision', '%-6d','newline', 'unix'); + %fprintf(wbpickfile,'%6d %6d %6d\n',ilxltoprint[,wb_idx); + %fclose(wbpickfile); + + else + ilxltoprint = ilxl_read{vol_index_wb}; + dlmwrite(strcat(wav_directory,'wbpick_',i_block,'.xyz'),[ilxltoprint((wb_idx ~= 1)',:),(uint32(wb_idx(wb_idx ~= 1)+padding)'.*job_meta.s_rate)/1000],'delimiter', ' ', 'precision', '%-6d','newline', 'unix'); + end + win_sub = bsxfun(@plus,wb_idx,(0:job_meta.n_samples{vol_index_wb}-max(wb_idx))'); + win_ind = bsxfun(@plus,win_sub,(0:job_meta.n_samples{vol_index_wb}:... + job_meta.n_samples{vol_index_wb}*(size(traces{vol_index_wb}(:,1:decimate:end),2)-1))); +end + +% calculate water bottom index +wb_ind_avg = mean(wb_idx); + + +% Loop over all volumes and windows to estimate wavelets, so for angle +% stacks these are seperate volumes, for angle gathers they are different +% planes in the gathers volume + +if job_meta.is_gather == 0 + i_vol_max = job_meta.nvols; +else + i_vol_max = length(offset); +end + +for i_vol = 1:1:i_vol_max + if job_meta.is_gather == 0 + [~, traces, ~, ~] = node_segy_read(job_meta_path,num2str(i_vol),i_block); + else + traces = gathers(:,offset_read == offset(i_vol)); + end + %[n_samples,n_traces] = size(traces); + traces = traces(:,1:decimate:end); + [~,n_traces] = size(traces); + if n_traces > 2 + traces = traces(win_ind); + %variance(i_vol) = var(traces(:)); + + % updated taper to be the same as int_grad_inv + %taper = linspace(0,1,25)'; + taper = single([ zeros(floor(padding-5),1)',linspace(0,1,20)])'; + %traces(1:25,:) = bsxfun(@times,traces(1:25,:),taper); + traces(1:length(taper),:) = bsxfun(@times,traces(1:length(taper),:),taper); + + variance(i_vol) = var(traces(:)); + % cjedit_30122013 + [n_samples,n_traces] = size(traces); % n samples needs to be redefined as the data has been flatterned on the waterbottom index and the array truncated + % + % keep record of number of samples included in std + % n_pop_std(i_vol) = n_samples*n_traces; + start_index = 1:ns_win-ns_overlap-1:n_samples-ns_win; + end_index = start_index+ns_win-1; + % if end_index(end) < n_samples + % end_index(end+1) = n_samples; + % start_index(end+1) = n_samples-ns_win+1; + % end + n_win = length(start_index); + w = zeros(2+ns_win,n_win); + % + % make taper to apply to signal before fft + taperlen = 16; + %taperst = linspace(0,1,taperlen)'; + taperst = (sin(linspace((-pi/2),(pi/2),taperlen)')+1)/2; + taperend = 1 - taperst; + taperapply = [taperst;ones((ns_win-(taperlen*2)),1);taperend]; + % + for ii = 1:n_win + % Estimate wavelets and store meta information + %if ii == n_win + % w(1,ii) = n_samples; + %else + w(1,ii) = start_index(ii); + %end + %w(2,ii) = n_traces; + %NFFT = 2^nextpow2(size(win_sub,1)); + % make a tmp array with the fft values in it + tmpfft = zeros(2,2); + tmpfft = abs(fft(bsxfun(@times,traces(start_index(ii):end_index(ii),:),taperapply))); + %w(2,ii) = floor((sum(tmpfft(:) ~= 0,'double'))/ns_win); + + w(2,ii) = sum(sum(tmpfft ~= 0,1,'double') ~= 0,2); + w(3:end,ii) = sum(tmpfft,2,'double'); + + %w(3:end,ii) = sum(abs(fft(bsxfun(@times,traces(start_index(ii):end_index(ii),:),taperapply))),2); + % index as linear index, summed not averaged! + + % Produce plots showing the windows + if ii == 1 && plot_on == 1 + figure(1) + imagesc(traces(:,1:1000)) + hold on + plot(repmat(end_index(ii),1000),'--') + hold off + elseif plot_on == 1 + hold on + plot(repmat(end_index(ii),1000),'--') + hold off + %figure(2) + %subplot(n_win,1,ii); + %imagesc(traces(start_index(ii):end_index(ii),:)); + end + + end + %end + % cjedit_30122013 - added if to not write out empty wavelets as far + % too many files othwerwise + %cjedit 02/01/2014 - commentout and made a single output file per + %iblock below + % %if n_traces > 1 + % % Save estimated wavelets for this volume + % fid_wav = fopen(strcat(wav_directory,job_meta.volumes{i_vol},'_fft_wavelets_block_',i_block,'.bin'),'w'); + % fwrite(fid_wav,n_win,'float32'); + % fwrite(fid_wav,w,'float32'); + % fclose(fid_wav); + %end + % cjedit 02/01/2014 added a write to only one file per iblock and made + % a slot for angle volume number in the output and total number of + % angle volumes + %% + % Save estimated wavelets for this volume + if i_vol == 1 + fid_wav = fopen(strcat(wav_directory,'fft_wavelets_block_',i_block,'.bin'),'w'); + %fwrite(fid_wav,job_meta.nvols,'float32'); + fwrite(fid_wav,i_vol_max,'float32'); + fwrite(fid_wav,n_win,'float32'); + fwrite(fid_wav,variance(1),'float32'); % this is used by wsmooth parameter in the inversion + fwrite(fid_wav,pick_wb_ind,'float32'); % offset on which the water bottom was picked + fwrite(fid_wav,wb_ind_avg,'float32'); % z of water bottom in block + end + %fwrite(fid_wav,i_vol,'float32'); + %fwrite(fid_wav,n_win,'float32'); + fwrite(fid_wav,w,'float32'); + end + +end +if n_traces > 2 + fclose(fid_wav); + % Open file again to write statistics + fid_wav = fopen(strcat(wav_directory,'fft_wavelets_block_',i_block,'.bin'),'r'); + + % Calculate + stdev = round(sqrt(median(variance))); % might like to think about calculating this properly based on live samples + w = fread(fid_wav,'float32'); + fclose(fid_wav); + w(3) = stdev; + fid_wav = fopen(strcat(wav_directory,'fft_wavelets_block_',i_block,'.bin'),'w'); + fwrite(fid_wav,w,'float32'); + fclose(fid_wav); +end + +%If this is the first live block do the following write into job meta file +if str2double(i_block) == str2double(first_live_block) + % Add processing information to job meta + job_meta.wav_directory = wav_directory; + job_meta.ns_win = ns_win; + %job_meta.n_win = n_win; not the same for each wavelet file + job_meta.ns_overlap = ns_overlap; + save(job_meta_path,'-struct','job_meta','-v7.3'); +end + +end diff --git a/compile/compile_function.m b/compile/compile_function.m new file mode 100644 index 0000000..593a470 --- /dev/null +++ b/compile/compile_function.m @@ -0,0 +1,86 @@ +function [] = compile_function(algorithm_name,subfolder,thread_type) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% compile_function: function to compile a matlab function as C++ code. +% Requires the MATLAB Compiler Toolbox. Algorithms should be stored in a +% subdirectory of the algorithms folder with the same name as the function +% to be compiled. +% Arguments: +% algorithm_name = the algorithm to compile +% subfolder = sub-directory where algorithms are stored +% thread_type = 1 = Compile single thread +% 2 = Compile multi threaded +% +% Outputs: +% none +% +% Writes to Disk: +% compiled function called algorithm_name and .sh file that sets up +% MATLAB environment variables +% Notes: library_path needs to be set appropriately for your paths + +%% +system('umask 002'); + +library_path = '/apps/gsc/matlab-library/development/maps/'; +thread_type = str2double(thread_type); + +%if strcmp(subfolder,'none') = 1 +% func_path = strcat('/apps/gsc/matlab-library/final_digi_condensed/',algorithm_name,'/'); +%else + func_path = strcat(library_path,subfolder,'/'); +%end +if thread_type == 1 + % Single thread +% mcc_call = sprintf('mcc -v -M ''-O2'' -o %s -W main:%s -T link:exe -d %s -R ''-nojvm,-nodisplay,-singleCompThread'' %s.m',... +% algorithm_name,algorithm_name,func_path,algorithm_name'); + + + mcc_call = sprintf('mcc -v -M ''-O2'' -o %s -m -d %s -v -R ''-nojvm,-nodisplay,-singleCompThread'' %s.m',... + algorithm_name,func_path,algorithm_name'); + +elseif thread_type == 2 + % Multithread +% mcc_call = sprintf('mcc -v -M ''-O2'' -o %s -W main:%s -T link:exe -d %s -R ''-nojvm,-nodisplay,'' %s.m',... +% algorithm_name,algorithm_name,func_path,algorithm_name'); + mcc_call = sprintf('mcc -v -M ''-O2'' -o %s -m -d %s -v -R ''-nojvm,-nodisplay,'' %s.m',... + algorithm_name,func_path,algorithm_name'); + +end + +eval(mcc_call); + +fprintf('Function %s successfully compiled to:\n%s\n',algorithm_name,func_path); + +% Need to add chmod 777 +system(['chmod 777 ',func_path,algorithm_name]); +system(['chmod 777 ',func_path,'run_',algorithm_name,'.sh']); + +end + + + + + + + diff --git a/dir/directory_scan.m b/dir/directory_scan.m new file mode 100644 index 0000000..cb05566 --- /dev/null +++ b/dir/directory_scan.m @@ -0,0 +1,103 @@ +function [filter_files,nfiles] = directory_scan(input_dir,filename_string) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% compile_function: function to compile a matlab function as C++ code. +% Requires the MATLAB Compiler Toolbox. Algorithms should be stored in a +% subdirectory of the algorithms folder with the same name as the function +% to be compiled. +% Arguments: +% input_dir = cell array Input Directories +% filename_string = the search string used a wildcard +% +% Outputs: +% filter_files = strucutre of file names and file paths of files +% found in the directory with the search string +% nfiles = Number of filtered files found +% +% Writes to Disk: +% nothing + +%% +n_dir = max(size(input_dir)); % Number of directories +start_point = pwd; % Remember start directory and cd to input_dir directory + +% -----------------SCAN EACH DIRECTORY---------------------------------- +cumm_files = 1; +for ii=1:1:n_dir + cd(input_dir{ii}); % change directory to iith lthe input directory + + % Figure out the number of files in the current directory + [~,nfiles] = (system('ls -B * | wc -l')); + nfiles=str2double(nfiles); + + % Read all filenames and convert from ascii to double + [~,fnames] = system('ls -B1 *'); + numeric = double(fnames); + + % Preallocate memory for some variables + count = 2; + fname_index = zeros(1,nfiles+1); + + % Loop to separate out each file name from one long character string + for ij= 1:length(fnames) + if numeric(1,ij) == 10 + fname_index(1,count) = ij; + count = count+1; + end + end + + % Loop to read each file as ascii into a cell array + for ik=1:nfiles + files_in.names{cumm_files+ik-1} = fnames(1,(fname_index(1,ik)+1):(fname_index(1,ik+1)-1)); + files_in.path{cumm_files+ik-1} = input_dir{ii}; + end + + cumm_files = cumm_files + nfiles; % Increment cumm_files by number of files found in current directory + +end +files_in.nfiles = nfiles; +%------------------------------------------------------------------------- + +%--------------FILTER THE FILES WITH THE SEARCH STRING------------------- + +% fprintf('\nThe following files have been found:\n') +% for il = 1:files_in.nfiles +% fprintf('File %d: %s in %s\n',il,files_in.names{il},files_in.path{il}); +% end +%fprintf('\nApplying string filter, %s:\n',filename_string) + +ii = 1; +for il = 1:files_in.nfiles + if strfind(files_in.names{il},filename_string) % if the file has the search string +% fprintf('File %d: %s in %s\n',il,files_in.names{il},files_in.path{il}); + filter_files.names{ii} = files_in.names{il}; % Read file name in the structure + filter_files.path{ii} = files_in.path{il}; % Read the file path in the structure + ii = ii + 1; % Increment the index of filtered file to be found + end +end +nfiles = ii-1; % Number of filtered files +%------------------------------------------------------------------------ + +cd(start_point); % Go back to the directory you were in to start with + +end \ No newline at end of file diff --git a/dir/directory_scan.m~ b/dir/directory_scan.m~ new file mode 100644 index 0000000..198400c --- /dev/null +++ b/dir/directory_scan.m~ @@ -0,0 +1,118 @@ +function [filter_files,nfiles] = directory_scan(input_dir,filename_string) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% compile_function: function to compile a matlab function as C++ code. +% Requires the MATLAB Compiler Toolbox. Algorithms should be stored in a +% subdirectory of the algorithms folder with the same name as the function +% to be compiled. +% Arguments: +% input_dir = cell array Input Directories +% filename_string = the search string used a wildcard +% +% Outputs: +% filter_files = strucutre of file names and file paths of files found in the directory with the search string +% nfiles = Number of filtered files found +% +% Writes to Disk: +% compiled function called algorithm_name and .sh file that sets up +% MATLAB environment variables +% Notes: library_path needs to be set appropriately for your paths +%% + +%---------------------------------------------------------------------- +%DIRECTORY_SCAN: Function to search key filename_string in input_dir + +%Arguments : +%input_dir : Array Input Directories +%filename_string : the search string + +%OUTPUT: +%filter_files: Strucutre of fil names and file paths of files found in ... +%... the directory with the search string +%nfiles: Number of filtered files +%---------------------------------------------------------------------- + + +n_dir = max(size(input_dir)); % Number of directories +start_point = pwd; % Remember start directory and cd to the input_logs directory + +% -----------------SCAN EACH DIRECTORY---------------------------------- +cumm_files = 1; +for ii=1:1:n_dir + cd(input_dir{ii}); % change directory to iith lthe input directory + + % Figure out the number of files in the current directory + [~,nfiles] = (system('ls -B * | wc -l')); + nfiles=str2double(nfiles); + + % Read all filenames and convert from ascii to double + [~,fnames] = system('ls -B1 *'); + numeric = double(fnames); + + % Preallocate memory for some variables + count = 2; + fname_index = zeros(1,nfiles+1); + + % Loop to separate out each file name from one long character string + for ij= 1:length(fnames) + if numeric(1,ij) == 10 + fname_index(1,count) = ij; + count = count+1; + end + end + + % Loop to read each file as ascii into a cell array + for ik=1:nfiles + files_in.names{cumm_files+ik-1} = fnames(1,(fname_index(1,ik)+1):(fname_index(1,ik+1)-1)); + files_in.path{cumm_files+ik-1} = input_dir{ii}; + end + + cumm_files = cumm_files + nfiles; % Increment cumm_files by number of files found in current directory + +end +files_in.nfiles = nfiles; +%------------------------------------------------------------------------- + +%--------------FILTER THE FILES WITH THE SEARCH STRING------------------- + +% fprintf('\nThe following files have been found:\n') +% for il = 1:files_in.nfiles +% fprintf('File %d: %s in %s\n',il,files_in.names{il},files_in.path{il}); +% end +%fprintf('\nApplying string filter, %s:\n',filename_string) + +ii = 1; +for il = 1:files_in.nfiles + if strfind(files_in.names{il},filename_string) % if the file has the search string +% fprintf('File %d: %s in %s\n',il,files_in.names{il},files_in.path{il}); + filter_files.names{ii} = files_in.names{il}; % Read file name in the structure + filter_files.path{ii} = files_in.path{il}; % Read the file path in the structure + ii = ii + 1; % Increment the index of filtered file to be found + end +end +nfiles = ii-1; % Number of filtered files +%------------------------------------------------------------------------ + +cd(start_point); % Go back to the directory you were in to start with + +end \ No newline at end of file diff --git a/dir/sort_nat.m b/dir/sort_nat.m new file mode 100644 index 0000000..6278faf --- /dev/null +++ b/dir/sort_nat.m @@ -0,0 +1,116 @@ +function [cs,index] = sort_nat(c,mode) +%sort_nat: Natural order sort of cell array of strings. +% usage: [S,INDEX] = sort_nat(C) +% +% where, +% C is a cell array (vector) of strings to be sorted. +% S is C, sorted in natural order. +% INDEX is the sort order such that S = C(INDEX); +% +% Natural order sorting sorts strings containing digits in a way such that +% the numerical value of the digits is taken into account. It is +% especially useful for sorting file names containing index numbers with +% different numbers of digits. Often, people will use leading zeros to get +% the right sort order, but with this function you don't have to do that. +% For example, if C = {'file1.txt','file2.txt','file10.txt'}, a normal sort +% will give you +% +% {'file1.txt' 'file10.txt' 'file2.txt'} +% +% whereas, sort_nat will give you +% +% {'file1.txt' 'file2.txt' 'file10.txt'} +% +% See also: sort +% Version: 1.4, 22 January 2011 +% Author: Douglas M. Schwarz +% Email: dmschwarz=ieee*org, dmschwarz=urgrad*rochester*edu +% Real_email = regexprep(Email,{'=','*'},{'@','.'}) +% BSD License +% Copyright (c) 2008, Douglas M. Schwarz +% All rights reserved. +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions are +% met: +% * Redistributions of source code must retain the above copyright +% notice, this list of conditions and the following disclaimer. +% * Redistributions in binary form must reproduce the above copyright +% notice, this list of conditions and the following disclaimer in +% the documentation and/or other materials provided with the distribution +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +% POSSIBILITY OF SUCH DAMAGE. + + +% Set default value for mode if necessary. +if nargin < 2 + mode = 'ascend'; +end + +% Make sure mode is either 'ascend' or 'descend'. +modes = strcmpi(mode,{'ascend','descend'}); +is_descend = modes(2); +if ~any(modes) + error('sort_nat:sortDirection',... + 'sorting direction must be ''ascend'' or ''descend''.') +end + +% Replace runs of digits with '0'. +c2 = regexprep(c,'\d+','0'); + +% Compute char version of c2 and locations of zeros. +s1 = char(c2); +z = s1 == '0'; + +% Extract the runs of digits and their start and end indices. +[digruns,first,last] = regexp(c,'\d+','match','start','end'); + +% Create matrix of numerical values of runs of digits and a matrix of the +% number of digits in each run. +num_str = length(c); +max_len = size(s1,2); +num_val = NaN(num_str,max_len); +num_dig = NaN(num_str,max_len); +for i = 1:num_str + num_val(i,z(i,:)) = sscanf(sprintf('%s ',digruns{i}{:}),'%f'); + num_dig(i,z(i,:)) = last{i} - first{i} + 1; +end + +% Find columns that have at least one non-NaN. Make sure activecols is a +% 1-by-n vector even if n = 0. +activecols = reshape(find(~all(isnan(num_val))),1,[]); +n = length(activecols); + +% Compute which columns in the composite matrix get the numbers. +numcols = activecols + (1:2:2*n); + +% Compute which columns in the composite matrix get the number of digits. +ndigcols = numcols + 1; + +% Compute which columns in the composite matrix get chars. +charcols = true(1,max_len + 2*n); +charcols(numcols) = false; +charcols(ndigcols) = false; + +% Create and fill composite matrix, comp. +comp = zeros(num_str,max_len + 2*n); +comp(:,charcols) = double(s1); +comp(:,numcols) = num_val(:,activecols); +comp(:,ndigcols) = num_dig(:,activecols); + +% Sort rows of composite matrix and use index to sort c in ascending or +% descending order, depending on mode. +[unused,index] = sortrows(comp); +if is_descend + index = index(end:-1:1); +end +index = reshape(index,size(c)); +cs = c(index); diff --git a/dir/sort_nat.m~ b/dir/sort_nat.m~ new file mode 100644 index 0000000..8cf4f75 --- /dev/null +++ b/dir/sort_nat.m~ @@ -0,0 +1,95 @@ +function [cs,index] = sort_nat(c,mode) +%sort_nat: Natural order sort of cell array of strings. +% usage: [S,INDEX] = sort_nat(C) +% +% where, +% C is a cell array (vector) of strings to be sorted. +% S is C, sorted in natural order. +% INDEX is the sort order such that S = C(INDEX); +% +% Natural order sorting sorts strings containing digits in a way such that +% the numerical value of the digits is taken into account. It is +% especially useful for sorting file names containing index numbers with +% different numbers of digits. Often, people will use leading zeros to get +% the right sort order, but with this function you don't have to do that. +% For example, if C = {'file1.txt','file2.txt','file10.txt'}, a normal sort +% will give you +% +% {'file1.txt' 'file10.txt' 'file2.txt'} +% +% whereas, sort_nat will give you +% +% {'file1.txt' 'file2.txt' 'file10.txt'} +% +% See also: sort + +% Version: 1.4, 22 January 2011 +% Author: Douglas M. Schwarz +% Email: dmschwarz=ieee*org, dmschwarz=urgrad*rochester*edu +% Real_email = regexprep(Email,{'=','*'},{'@','.'}) + + +% Set default value for mode if necessary. +if nargin < 2 + mode = 'ascend'; +end + +% Make sure mode is either 'ascend' or 'descend'. +modes = strcmpi(mode,{'ascend','descend'}); +is_descend = modes(2); +if ~any(modes) + error('sort_nat:sortDirection',... + 'sorting direction must be ''ascend'' or ''descend''.') +end + +% Replace runs of digits with '0'. +c2 = regexprep(c,'\d+','0'); + +% Compute char version of c2 and locations of zeros. +s1 = char(c2); +z = s1 == '0'; + +% Extract the runs of digits and their start and end indices. +[digruns,first,last] = regexp(c,'\d+','match','start','end'); + +% Create matrix of numerical values of runs of digits and a matrix of the +% number of digits in each run. +num_str = length(c); +max_len = size(s1,2); +num_val = NaN(num_str,max_len); +num_dig = NaN(num_str,max_len); +for i = 1:num_str + num_val(i,z(i,:)) = sscanf(sprintf('%s ',digruns{i}{:}),'%f'); + num_dig(i,z(i,:)) = last{i} - first{i} + 1; +end + +% Find columns that have at least one non-NaN. Make sure activecols is a +% 1-by-n vector even if n = 0. +activecols = reshape(find(~all(isnan(num_val))),1,[]); +n = length(activecols); + +% Compute which columns in the composite matrix get the numbers. +numcols = activecols + (1:2:2*n); + +% Compute which columns in the composite matrix get the number of digits. +ndigcols = numcols + 1; + +% Compute which columns in the composite matrix get chars. +charcols = true(1,max_len + 2*n); +charcols(numcols) = false; +charcols(ndigcols) = false; + +% Create and fill composite matrix, comp. +comp = zeros(num_str,max_len + 2*n); +comp(:,charcols) = double(s1); +comp(:,numcols) = num_val(:,activecols); +comp(:,ndigcols) = num_dig(:,activecols); + +% Sort rows of composite matrix and use index to sort c in ascending or +% descending order, depending on mode. +[unused,index] = sortrows(comp); +if is_descend + index = index(end:-1:1); +end +index = reshape(index,size(c)); +cs = c(index); diff --git a/extra/meta_data_2d_smo_xy.m b/extra/meta_data_2d_smo_xy.m new file mode 100644 index 0000000..e6159b2 --- /dev/null +++ b/extra/meta_data_2d_smo_xy.m @@ -0,0 +1,130 @@ +function [ ] = meta_data_2d_smo_xy( job_meta_path ) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% water_bottom_picker: function to pick water bottom (first event) of +% seismic dataset. +% Arguments: +% job_meta_path = path to .mat file created using +% segy_make_job function. +% +% Outputs: +% adds following variables to job_meta file: +% job_meta.stdev_smo = smoothing of standard deviation calculated in +% wavelet_estimation function. Used by int_grad_inv_proj as scaling in +% the inversion. +% job_meta.live_offset_avg = used to provide a consistent offset to +% water_bottom_picker function +% +% Writes to Disk: +% nothing + +%ILXL_GRID Summary of this function goes here +% Input: +% Output: +% Detailed explanation goes here +%% +job_meta = load(job_meta_path); + +% minil = min(job_meta.block_keys(:,1)); +% minxl = min(job_meta.block_keys(:,3)); +% maxil = max(job_meta.block_keys(:,2)); +% maxxl = max(job_meta.block_keys(:,4)); + +ils = sort(unique(job_meta.block_keys(:,1))); % Sort inlines of fist corner point of blocks in increasing order and remove duplicates +xls = sort(unique(job_meta.block_keys(:,3))); % Sort xlines of fist corner point of blocks in increasing order and remove duplicates + +ilslen = length(ils); % Number of unique inlines of fist corner point of blocks +xlslen = length(xls); % Number of unique inlines of fist corner point of blocks + +ilxl_lookup = zeros(ilslen,xlslen,2); % Create look up table for inlines and cross-lines + +loopfin = size(job_meta.liveblocks,1); % Number of live blocks +lpi = 1; % Loop Index +count = 1; % Counter +%% +%Loop for creating look up table from Job Meta Information +while lpi <= loopfin + i_block = job_meta.liveblocks(lpi); % Block Number for Current Live Block + if(i_block == 387) + dave = 1; + end + currow = find(ils == job_meta.block_keys(i_block,1),1,'first'); % Find ROW = The inline matching ith block first coner point inline + curcol = find(xls == job_meta.block_keys(i_block,3),1,'first'); % Find COULMN = The inline matching ith block first coner point inline + + ilxl_lookup(currow,curcol,1) = i_block; % Store Block Number in the first cell indexed by found ROW and COLUMN + ilxl_lookup(currow,curcol,2) = job_meta.stdev(i_block); % Store Block wavelet variance in the 2nd cell indexed by found ROW and COLUMN + ilxl_lookup(currow,curcol,3) = job_meta.wb_z_avg(i_block); % Store Block Average Water Bottom in the 3rd cell indexed by found ROW and COLUMN + ilxl_lookup(currow,curcol,4) = job_meta.live_offset(i_block); % Store Block Live Offset Value in the 4th cell indexed by found ROW and COLUMN + lpi = lpi + 1; % Increment Loop Index +end +%% +%Plotting + +figure(1); imagesc(ilxl_lookup(:,:,2)); title('input variance');%caxis([500 1000]); % Plot Variance +figure(11); imagesc(ilxl_lookup(:,:,3)); title('input water bottom depth'); %caxis([500 1000]); % Plot Average Water Bottom Z +figure(12); imagesc(ilxl_lookup(:,:,4)); title('input live offset'); %caxis([0 50]); % Plot Live Offset +figure(14); imagesc(ilxl_lookup(:,:,1)); title('block number'); %caxis([0 50]); % Plot Block Number +%% +%Filtering +flen = 7; % Half Length of Filter +filt_smo2 = [ linspace(0,flen,(flen+1)) , linspace((flen-1),0,flen)]; % Smoothening Filter +filt_smo2 = filt_smo2/sum(filt_smo2); % Normalize Smoothening Filter +filt_smo = filt_smo2; + +input_pad = ilxl_lookup(:,:,2); % Initialize Input Pad to Variance Matrix ( il vs xl ) + +% Pad Inline and xline direction by the boundary values by (length of +% filter+1) cells +input_pad = [repmat(input_pad(:,1),1,(flen+1)), input_pad, repmat(input_pad(:,xlslen),1,(flen+1))]; +input_pad = [repmat(input_pad(1,:),(flen+1),1); input_pad; repmat(input_pad(ilslen,:),(flen+1),1)]; + +ilxl_lookup_smo = conv2(filt_smo2,filt_smo,input_pad,'same'); % Smoothening : Convolve the designed filter with the padded input +ilxl_lookup_smoout = ilxl_lookup_smo((flen+2):(flen+2)+ilslen-1,(flen+2):(flen+2)+xlslen-1); % Crop the smoothed output to original boundary +figure(2); imagesc(ilxl_lookup_smoout); title('smoothed variance'); + +ilxl_lookup_smoout(:,:,2) = ilxl_lookup(:,:,1); % Put Block Numbers the smoothed output as a second cell for every il xl +%figure(20); imagesc(ilxl_lookup_smoout(:,:,2)); title('block number'); + +ilxl_lookup_smoout = reshape(ilxl_lookup_smoout,[(ilslen*xlslen) 2]); % Reshape into matrix indexed by Block Number, 1st cell: smoothed output, 2nd cell: bllock number for libe blocks + +%ilxl_lookup_smo = sortrows(ilxl_lookup_smoout,2); + +%figure(15); imagesc(ilxl_lookup_smo(:,:,1)); %caxis([0 50]); + +job_meta.stdev_smo = ones(job_meta.n_blocks,1); % Initialized "to be" smoothed variance in job meta structure + +% Loop for entering smoothed variance for live blocks +for ii = 1:size(ilxl_lookup_smoout) + if ilxl_lookup_smoout(ii,2) > 0 + job_meta.stdev_smo(ilxl_lookup_smoout(ii,2)) = ilxl_lookup_smoout(ii,1); + end +end + +job_meta.live_offset_avg = round(mean(ilxl_lookup(currow,curcol,4))); + +save(job_meta_path,'-struct','job_meta','-v7.3'); + + +% ilxl_loc(:,1) = job_meta.block_keys(:,1) + (((job_meta.block_keys(:,2) - job_meta.block_keys(:,1))/job_meta.pkey_inc)/2)*job_meta.pkey_inc; +% ilxl_loc(:,2) = job_meta.block_keys(:,3) + (((job_meta.block_keys(:,4) - job_meta.block_keys(:,3))/job_meta.skey_inc)/2)*job_meta.skey_inc; +end diff --git a/extra/meta_data_2d_smo_xy.m~ b/extra/meta_data_2d_smo_xy.m~ new file mode 100644 index 0000000..e6159b2 --- /dev/null +++ b/extra/meta_data_2d_smo_xy.m~ @@ -0,0 +1,130 @@ +function [ ] = meta_data_2d_smo_xy( job_meta_path ) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% water_bottom_picker: function to pick water bottom (first event) of +% seismic dataset. +% Arguments: +% job_meta_path = path to .mat file created using +% segy_make_job function. +% +% Outputs: +% adds following variables to job_meta file: +% job_meta.stdev_smo = smoothing of standard deviation calculated in +% wavelet_estimation function. Used by int_grad_inv_proj as scaling in +% the inversion. +% job_meta.live_offset_avg = used to provide a consistent offset to +% water_bottom_picker function +% +% Writes to Disk: +% nothing + +%ILXL_GRID Summary of this function goes here +% Input: +% Output: +% Detailed explanation goes here +%% +job_meta = load(job_meta_path); + +% minil = min(job_meta.block_keys(:,1)); +% minxl = min(job_meta.block_keys(:,3)); +% maxil = max(job_meta.block_keys(:,2)); +% maxxl = max(job_meta.block_keys(:,4)); + +ils = sort(unique(job_meta.block_keys(:,1))); % Sort inlines of fist corner point of blocks in increasing order and remove duplicates +xls = sort(unique(job_meta.block_keys(:,3))); % Sort xlines of fist corner point of blocks in increasing order and remove duplicates + +ilslen = length(ils); % Number of unique inlines of fist corner point of blocks +xlslen = length(xls); % Number of unique inlines of fist corner point of blocks + +ilxl_lookup = zeros(ilslen,xlslen,2); % Create look up table for inlines and cross-lines + +loopfin = size(job_meta.liveblocks,1); % Number of live blocks +lpi = 1; % Loop Index +count = 1; % Counter +%% +%Loop for creating look up table from Job Meta Information +while lpi <= loopfin + i_block = job_meta.liveblocks(lpi); % Block Number for Current Live Block + if(i_block == 387) + dave = 1; + end + currow = find(ils == job_meta.block_keys(i_block,1),1,'first'); % Find ROW = The inline matching ith block first coner point inline + curcol = find(xls == job_meta.block_keys(i_block,3),1,'first'); % Find COULMN = The inline matching ith block first coner point inline + + ilxl_lookup(currow,curcol,1) = i_block; % Store Block Number in the first cell indexed by found ROW and COLUMN + ilxl_lookup(currow,curcol,2) = job_meta.stdev(i_block); % Store Block wavelet variance in the 2nd cell indexed by found ROW and COLUMN + ilxl_lookup(currow,curcol,3) = job_meta.wb_z_avg(i_block); % Store Block Average Water Bottom in the 3rd cell indexed by found ROW and COLUMN + ilxl_lookup(currow,curcol,4) = job_meta.live_offset(i_block); % Store Block Live Offset Value in the 4th cell indexed by found ROW and COLUMN + lpi = lpi + 1; % Increment Loop Index +end +%% +%Plotting + +figure(1); imagesc(ilxl_lookup(:,:,2)); title('input variance');%caxis([500 1000]); % Plot Variance +figure(11); imagesc(ilxl_lookup(:,:,3)); title('input water bottom depth'); %caxis([500 1000]); % Plot Average Water Bottom Z +figure(12); imagesc(ilxl_lookup(:,:,4)); title('input live offset'); %caxis([0 50]); % Plot Live Offset +figure(14); imagesc(ilxl_lookup(:,:,1)); title('block number'); %caxis([0 50]); % Plot Block Number +%% +%Filtering +flen = 7; % Half Length of Filter +filt_smo2 = [ linspace(0,flen,(flen+1)) , linspace((flen-1),0,flen)]; % Smoothening Filter +filt_smo2 = filt_smo2/sum(filt_smo2); % Normalize Smoothening Filter +filt_smo = filt_smo2; + +input_pad = ilxl_lookup(:,:,2); % Initialize Input Pad to Variance Matrix ( il vs xl ) + +% Pad Inline and xline direction by the boundary values by (length of +% filter+1) cells +input_pad = [repmat(input_pad(:,1),1,(flen+1)), input_pad, repmat(input_pad(:,xlslen),1,(flen+1))]; +input_pad = [repmat(input_pad(1,:),(flen+1),1); input_pad; repmat(input_pad(ilslen,:),(flen+1),1)]; + +ilxl_lookup_smo = conv2(filt_smo2,filt_smo,input_pad,'same'); % Smoothening : Convolve the designed filter with the padded input +ilxl_lookup_smoout = ilxl_lookup_smo((flen+2):(flen+2)+ilslen-1,(flen+2):(flen+2)+xlslen-1); % Crop the smoothed output to original boundary +figure(2); imagesc(ilxl_lookup_smoout); title('smoothed variance'); + +ilxl_lookup_smoout(:,:,2) = ilxl_lookup(:,:,1); % Put Block Numbers the smoothed output as a second cell for every il xl +%figure(20); imagesc(ilxl_lookup_smoout(:,:,2)); title('block number'); + +ilxl_lookup_smoout = reshape(ilxl_lookup_smoout,[(ilslen*xlslen) 2]); % Reshape into matrix indexed by Block Number, 1st cell: smoothed output, 2nd cell: bllock number for libe blocks + +%ilxl_lookup_smo = sortrows(ilxl_lookup_smoout,2); + +%figure(15); imagesc(ilxl_lookup_smo(:,:,1)); %caxis([0 50]); + +job_meta.stdev_smo = ones(job_meta.n_blocks,1); % Initialized "to be" smoothed variance in job meta structure + +% Loop for entering smoothed variance for live blocks +for ii = 1:size(ilxl_lookup_smoout) + if ilxl_lookup_smoout(ii,2) > 0 + job_meta.stdev_smo(ilxl_lookup_smoout(ii,2)) = ilxl_lookup_smoout(ii,1); + end +end + +job_meta.live_offset_avg = round(mean(ilxl_lookup(currow,curcol,4))); + +save(job_meta_path,'-struct','job_meta','-v7.3'); + + +% ilxl_loc(:,1) = job_meta.block_keys(:,1) + (((job_meta.block_keys(:,2) - job_meta.block_keys(:,1))/job_meta.pkey_inc)/2)*job_meta.pkey_inc; +% ilxl_loc(:,2) = job_meta.block_keys(:,3) + (((job_meta.block_keys(:,4) - job_meta.block_keys(:,3))/job_meta.skey_inc)/2)*job_meta.skey_inc; +end diff --git a/extra/perl_matlab_par_for.pl b/extra/perl_matlab_par_for.pl new file mode 100755 index 0000000..20f6338 --- /dev/null +++ b/extra/perl_matlab_par_for.pl @@ -0,0 +1,133 @@ +#!/usr/bin/perl -w +## ------------------ Disclaimer ------------------ +# +# BG Group plc or any of its respective subsidiaries, affiliates and +# associated companies (or by any of their respective officers, employees +# or agents) makes no representation or warranty, express or implied, in +# respect to the quality, accuracy or usefulness of this repository. The code +# is this repository is supplied with the explicit understanding and +# agreement of recipient that any action taken or expenditure made by +# recipient based on its examination, evaluation, interpretation or use is +# at its own risk and responsibility. +# +# No representation or warranty, express or implied, is or will be made in +# relation to the accuracy or completeness of the information in this +# repository and no responsibility or liability is or will be accepted by +# BG Group plc or any of its respective subsidiaries, affiliates and +# associated companies (or by any of their respective officers, employees +# or agents) in relation to it. +## ------------------ License ------------------ +# GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +## github +# https://github.com/AnalysePrestackSeismic/ +## +# this is a perl script to run compiled matlab code in a parrallel for loop on a node +## +############################################################################################## +## load required packages +## use eval to test the existance of modules +## +#### config is a core perl module, so assume it exists +use Config; +## check to see if perl version was built with threads +$Config{useithreads} or die('Recompile Perl with threads to run this program.'); +## +## +$usagemessage = "perl_matlab_par_for.pl "; +## If no arguments are supplied, prompt user with how to use script.### +if ($#ARGV < 0) { + die($usagemessage); +} +## +## set defaults ############################################################################## +$noofthreads = 4; +## +## check the command line for switches ####################################################### +$para_commnda = $ARGV[0]; +#print "a: ".$para_commnda."\n"; +$para_commndb = $ARGV[1]; +#print "b: ".$para_commndb."\n"; +$para_commndc = $ARGV[2]; +#print "c: ".$para_commndc."\n"; +$para_commndd = $ARGV[3]; +#print "d: ".$para_commndd."\n"; +$para_commnde = $ARGV[4]; +#print "e: ".$para_commnde."\n"; +$para_commndf = $ARGV[5]; +#print "f: ".$para_commndf."\n"; +$para_commndg = $ARGV[6]; +#print "g: ".$para_commndg."\n"; +## +@fileargs = split(' ', $ARGV[7]); +## +$#item_to_loop = -1; +#print @fileargs ; +#print "total number of files :".$#fileargs."\n"; +## +for ($argi=0; $argi <= $#fileargs; $argi++){ + $item_to_loop[$argi] = $fileargs[$argi]; + #print "filearg ".$argi." ".$fileargs[$argi]."\n"; +} +print "last filearg ".$#fileargs." ".$fileargs[$#fileargs]."\n"; +## +## fork manager is a cpan module, so need to test if it has been installed +## if not installed, install in a csh with +## setenv FTP_PASSIVE 1 +## perl -MCPAN -e "install 'Parallel::ForkManager'" +## +$usethread = 0; +## +eval("use Parallel::ForkManager"); +if ($@ =~ m/Can\'t locate/) { + #print "forkmanager package did not exist\n".$@."\n see in code of this program how to install\n"; +} else { + #print "package did exist\n"; + $usethread = 1; +} +## +## test to see if threads enabled, if not then uses serial loop +$i = 0; +if ($usethread == 1){ + ## + #print "in threaded loop now =================\n"; + ## start number of threads to use + my $manager = new Parallel::ForkManager( $noofthreads ); + $#runcomms = -1; + ## + ##test the digital signatures of each file + foreach (@item_to_loop) { + print $item_to_loop[$i]."\n"; + $runcomms[$i] = $para_commnda." ".$para_commndb." ".$para_commndc." ".$para_commndd." ".$para_commnde." ".$para_commndf." ".$para_commndg." ".$item_to_loop[$i]; + # + #print $runcomms[$i]."\n"; + $i++; + } + ### + ##now run the commands + umask(000); + ## + foreach my $command (@runcomms) { + $manager->start and next; + sleep 2; + #print "running $command \n"; + system( $command ); + $manager->finish; + } + $manager->wait_all_children; + # + print "all threads completed\n"; + ## +} else { + foreach (@item_to_loop) { + #print $item_to_loop[$i]."\n"; + $commcj = $para_commnda." ".$para_commndb." ".$para_commndc." ".$para_commndd." ".$para_commnde." ".$para_commndf." ".$para_commndg." ".$item_to_loop[$i]; + @out = `$commcj`; + chomp(@out); + $i++; + } +} +## +## +exit 1; + + diff --git a/extra/perl_matlab_par_for.pl~ b/extra/perl_matlab_par_for.pl~ new file mode 100755 index 0000000..03d2e14 --- /dev/null +++ b/extra/perl_matlab_par_for.pl~ @@ -0,0 +1,112 @@ +#!/usr/bin/perl -w +## +# this is a perl script to run compiled matlab code in a parrallel for loop on a node +## +############################################################################################## +## load required packages +## use eval to test the existance of modules +## +#### config is a core perl module, so assume it exists +use Config; +## check to see if perl version was built with threads +$Config{useithreads} or die('Recompile Perl with threads to run this program.'); +## +## +$usagemessage = "perl_matlab_par_for.pl "; +## If no arguments are supplied, prompt user with how to use script.### +if ($#ARGV < 0) { + die($usagemessage); +} +## +## set defaults ############################################################################## +$noofthreads = 4; +## +## check the command line for switches ####################################################### +$para_commnda = $ARGV[0]; +#print "a: ".$para_commnda."\n"; +$para_commndb = $ARGV[1]; +#print "b: ".$para_commndb."\n"; +$para_commndc = $ARGV[2]; +#print "c: ".$para_commndc."\n"; +$para_commndd = $ARGV[3]; +#print "d: ".$para_commndd."\n"; +$para_commnde = $ARGV[4]; +#print "e: ".$para_commnde."\n"; +$para_commndf = $ARGV[5]; +#print "f: ".$para_commndf."\n"; +$para_commndg = $ARGV[6]; +#print "g: ".$para_commndg."\n"; +## +@fileargs = split(' ', $ARGV[7]); +## +$#item_to_loop = -1; +#print @fileargs ; +#print "total number of files :".$#fileargs."\n"; +## +for ($argi=0; $argi <= $#fileargs; $argi++){ + $item_to_loop[$argi] = $fileargs[$argi]; + #print "filearg ".$argi." ".$fileargs[$argi]."\n"; +} +print "last filearg ".$#fileargs." ".$fileargs[$#fileargs]."\n"; +## +## fork manager is a cpan module, so need to test if it has been installed +## if not installed, install in a csh with +## setenv FTP_PASSIVE 1 +## perl -MCPAN -e "install 'Parallel::ForkManager'" +## +$usethread = 0; +## +eval("use Parallel::ForkManager"); +if ($@ =~ m/Can\'t locate/) { + #print "forkmanager package did not exist\n".$@."\n see in code of this program how to install\n"; +} else { + #print "package did exist\n"; + $usethread = 1; +} +## +## test to see if threads enabled, if not then uses serial loop +$i = 0; +if ($usethread == 1){ + ## + #print "in threaded loop now =================\n"; + ## start number of threads to use + my $manager = new Parallel::ForkManager( $noofthreads ); + $#runcomms = -1; + ## + ##test the digital signatures of each file + foreach (@item_to_loop) { + print $item_to_loop[$i]."\n"; + $runcomms[$i] = $para_commnda." ".$para_commndb." ".$para_commndc." ".$para_commndd." ".$para_commnde." ".$para_commndf." ".$para_commndg." ".$item_to_loop[$i]; + # + #print $runcomms[$i]."\n"; + $i++; + } + ### + ##now run the commands + umask(000); + ## + foreach my $command (@runcomms) { + $manager->start and next; + sleep 2; + #print "running $command \n"; + system( $command ); + $manager->finish; + } + $manager->wait_all_children; + # + print "all threads completed\n"; + ## +} else { + foreach (@item_to_loop) { + #print $item_to_loop[$i]."\n"; + $commcj = $para_commnda." ".$para_commndb." ".$para_commndc." ".$para_commndd." ".$para_commnde." ".$para_commndf." ".$para_commndg." ".$item_to_loop[$i]; + @out = `$commcj`; + chomp(@out); + $i++; + } +} +## +## +exit 1; + + diff --git a/node/node_segy_read.m b/node/node_segy_read.m new file mode 100644 index 0000000..1d50001 --- /dev/null +++ b/node/node_segy_read.m @@ -0,0 +1,358 @@ +function [seismic, traces, ilxl_read, offset_read] = node_segy_read(job_meta_path,vol_index,i_block) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% node_segy_read: function to read traces from a specific block with a +% scanned segy volume +% Arguments: +% job_meta_path = path to job_meta .mat file +% vol_index = integer indicating volume to load +% i_block = integer indicating which block to load from volume +% +% Outputs: +% seismic = structure containing seismic header information +% traces = seismic traces as matrix (rows samples; columns traces) +% ilxl_read = inlines and crosslines that have been read +% offset_read = offsets that have been read +% +% Writes to Disk: +% nothing + +%% +i_block = str2double(i_block); +job_meta = load(job_meta_path); +if job_meta.is_gather == 1 + fold = ((job_meta.tkey_max - job_meta.tkey_min )/ job_meta.tkey_inc) + 1; +end + +if i_block > job_meta.n_blocks + seismic = NaN; + traces = NaN; + ilxl_read = NaN; + offset_read = NaN; + fprintf('Job only has %d blocks...\n',job_meta.n_blocks) + return +end + +vol_keys = segy_index_byte_finder(job_meta_path,job_meta.block_keys(i_block,:),vol_index); + +vol_index = str2double(vol_index); +vol_name = job_meta.volumes{vol_index}; + +% find the names of the blocks for the given volume +ii = 1; + +if job_meta.is_gather == 0 + loop_index = size(job_meta.files,1); +else + loop_index = size(job_meta.files,2); +end + +for i_files = 1:1:loop_index + if strfind(job_meta.files{i_files},vol_name) == 1 + blocks{ii,1} = job_meta.files{i_files}; + ii = ii + 1; + end +end + +%% loop over the blocks +for ii_block = 1:1:size(blocks,1) + if size(vol_keys{ii_block},1) > 2 + vol_keys{ii_block}(end+1,3) = 0; + seismic = segy_read_binary(strcat(job_meta.paths{1},blocks{ii_block})); + + bytes_per_sample = job_meta.bytes_per_sample{vol_index}; + trc_head = 240; + trc_length = seismic.n_samples*bytes_per_sample; % could add this to seismic structure + + s_key = 1; + is_key = 1; + i_counter = 1; + is_counter = 1; + i_trace = 1; + % find the number of rows in the bytes lookuptable + while_is_gather = size(vol_keys{ii_block},1); + % loop round all the row in the lookup table + while s_key < while_is_gather + if job_meta.is_gather == 0 + if vol_keys{ii_block}(i_counter+1,3) - vol_keys{ii_block}(i_counter,3) == trc_length+trc_head + i_counter = i_counter + 1; + else % perform continuous read + n_traces_to_read = i_counter-s_key+1; + % Open the seismic segy file + [traces{ii_block}(:,s_key:s_key+n_traces_to_read-1),... + ilxl_read{ii_block}(s_key:s_key+n_traces_to_read-1,:),... + offset_read{ii_block}(s_key:s_key+n_traces_to_read-1,:)] ... + = read_traces_segy(seismic,vol_keys{ii_block}(s_key,3)-trc_head,n_traces_to_read); + s_key = s_key + n_traces_to_read; + i_counter = s_key; + end + elseif job_meta.is_gather == 1 + % test to see if the gather is the same size as the + % next one - this should see if you can do a continious + % read +% if vol_keys{ii_block}(i_counter+1,3) - vol_keys{ii_block}(i_counter,3) == vol_keys{ii_block}(i_counter,4)*(trc_length+trc_head) +% i_counter = i_counter + 1; +% %is_counter = is_counter + 1; +% else % perform continuous read +% n_traces_to_read = i_counter-s_key; +% %is_traces_to_read = is_counter-is_key+1; +% is_traces_to_read = (n_traces_to_read)*vol_keys{ii_block}(i_counter-1,4); +% % read to a temp array and then put into the correct +% % location in the output array +% +% % Open the seismic segy file +% [traces{ii_block}(:,is_key:is_key+is_traces_to_read-1), ilxl_read{ii_block}(is_key:is_key+is_traces_to_read-1,:), offset_read{ii_block}(is_key:is_key+is_traces_to_read-1,:)] ... +% = read_traces_segy(seismic,vol_keys{ii_block}(s_key,3)-trc_head,is_traces_to_read); +% +% +% %alloffpres = size(offset_read{28},1)/fold +% +% s_key = s_key + n_traces_to_read; +% %i_counter = i_counter + 1; +% is_key = is_key + is_traces_to_read; +% %is_counter = is_counter + 1; +% end + + %set the first gather to its own fold + if i_counter == 1 + prevfoldck = vol_keys{ii_block}(i_counter,4); + end + + if vol_keys{ii_block}(i_counter+1,3) - vol_keys{ii_block}(i_counter,3) == vol_keys{ii_block}(i_counter,4)*(trc_length+trc_head) && vol_keys{ii_block}(i_counter,4) == prevfoldck + prevfoldck = vol_keys{ii_block}(i_counter,4); + i_counter = i_counter + 1; + is_counter = is_counter + 1; + % + else % perform continuous read + %set the first gather to its own fold + if i_counter == 1 + prevfoldck = vol_keys{ii_block}(i_counter,4); + else + prevfoldck = vol_keys{ii_block}(i_counter-1,4); + end + % + if vol_keys{ii_block}(i_counter,4) == prevfoldck + n_traces_to_read = i_counter-s_key+1; + else + if i_counter == s_key + i_counter = i_counter + 1; + %n_traces_to_read = 1; + end + n_traces_to_read = i_counter-s_key; + + end + %is_traces_to_read = is_counter-is_key+1; + if i_counter == 1 + is_traces_to_read = (n_traces_to_read)*vol_keys{ii_block}(i_counter,4); + curtestfold = vol_keys{ii_block}(i_counter,4); + else + is_traces_to_read = (n_traces_to_read)*vol_keys{ii_block}(i_counter-1,4); + curtestfold = vol_keys{ii_block}(i_counter-1,4); + end + % read to a temp array and then put into the correct + % location in the output array + + % Open the seismic segy file +% [traces{ii_block}(:,is_key:is_key+is_traces_to_read-1), ilxl_read{ii_block}(is_key:is_key+is_traces_to_read-1,:), offset_read{ii_block}(is_key:is_key+is_traces_to_read-1,:)] ... +% = read_traces_segy(seismic,vol_keys{ii_block}(s_key,3)-trc_head,is_traces_to_read); + %[traces{ii_block}(:,is_key:is_key+is_traces_to_read-1), ilxl_read{ii_block}(is_key:is_key+is_traces_to_read-1,:), offset_read{ii_block}(is_key:is_key+is_traces_to_read-1,:)] ... + % = read_traces_segy(seismic,vol_keys{ii_block}(s_key,3)-trc_head,is_traces_to_read); + + + %alloffpres = size(offset_read{28},1)/fold + + if fold == curtestfold + [traces{ii_block}(:,is_key:is_key+is_traces_to_read-1), ilxl_read{ii_block}(is_key:is_key+is_traces_to_read-1,:), offset_read{ii_block}(is_key:is_key+is_traces_to_read-1,:)] ... + = read_traces_segy(seismic,vol_keys{ii_block}(s_key,3)-trc_head,is_traces_to_read); + else + [tmptracesblk, tmp_ilxl_read, tmp_offset_read] = read_traces_segy(seismic,vol_keys{ii_block}(s_key,3)-trc_head,is_traces_to_read); + + %filltraces = zeros(size(tmptracesblk,1),(is_counter-is_key+1)*fold,'single'); + + %traces{ii_block}(:,is_key:is_key+((is_counter-is_key+1)*fold)-1) = zeros(size(tmptracesblk,1),(is_counter-is_key+1)*fold,'single'); + %ilxl_read{ii_block}(is_key:is_key+((is_counter-is_key+1)*fold)-1,:) = zeros((is_counter-is_key+1)*fold,size(tmp_ilxl_read,2),'int32'); + + traces{ii_block}(:,is_key:is_key+((n_traces_to_read)*fold)-1) = zeros(size(tmptracesblk,1),(n_traces_to_read)*fold,'single'); + ilxl_read{ii_block}(is_key:is_key+((n_traces_to_read)*fold)-1,:) = zeros((n_traces_to_read)*fold,size(tmp_ilxl_read,2),'int32'); + + + % do unique on the tmp_ilxl_gather to get all the + % values + + %offset_read{ii_block}(is_key:is_key+((is_counter-is_key+1)*fold)-1,:) = zeros((is_counter-is_key+1)*fold,size(tmp_offset_read,2)); + offset_read{ii_block}(is_key:is_key+((n_traces_to_read)*fold)-1,:) = repmat((int32(job_meta.tkey_min):int32(job_meta.tkey_inc):int32(job_meta.tkey_max))',(n_traces_to_read),1); + % ((job_meta.tkey_max - job_meta.tkey_min )/ job_meta.tkey_inc) + % the zeros + + + lastoffval = 99999999; + locval = -1; + finalloc = 1; + lastilxlval = -9876543; + listi = 1; + for cji = 1:1:is_traces_to_read; + if tmp_offset_read(cji) <= lastoffval && sum(tmp_ilxl_read(cji,:)) ~= lastilxlval; + locval = locval + 1; + tmpilxllist(listi,:) = tmp_ilxl_read(cji,:); + listi = listi + 1; + end + finalloc = (locval * fold) + tmp_offset_read(cji) + is_key; + traces{ii_block}(:,finalloc) = tmptracesblk(:,cji); + %ilxl_read{ii_block}(finalloc,:) = tmp_ilxl_read(cji,:); + offset_read{ii_block}(finalloc,:) = tmp_offset_read(cji); + lastoffval = tmp_offset_read(cji); + lastilxlval = sum(tmp_ilxl_read(cji,:)); + end + + %replicate the list of inline and xlines to the + %fold of the gathers + for listiloop = 1:1:(listi-1) + %needs to check the dimensions + ilxl_read{ii_block}(is_key+((listiloop-1)*fold):is_key+((listiloop)*fold)-1,:) = repmat(tmpilxllist(listiloop,:),fold,1); + end + + is_traces_to_read = (n_traces_to_read)*fold; + end + %alloffpres = size(offset_read{28},1)/fold + + s_key = s_key + n_traces_to_read; + i_counter = s_key; + is_key = is_key + is_traces_to_read; + is_counter = is_key; + + end + end + end + else + % no traces + seismic = segy_read_binary(strcat(job_meta.paths{1},blocks{ii_block})); +% if job_meta.is_gather == 1 +% traces{ii_block} = zeros(seismic.n_samples,fold,'single'); +% ilxl_read{ii_block} = zeros(fold,2,'int32'); +% offset_read{ii_block} = int32(job_meta.tkey_min):int32(job_meta.tkey_inc):int32(job_meta.tkey_max)'; +% else + traces{ii_block} = zeros(seismic.n_samples,1,'single'); + ilxl_read{ii_block} = int32([0,0]); + offset_read{ii_block} = int32(0); +% end + + % could to make zero entry + end +end +%% + traces = cell2mat(traces); + %cj fell over here + ilxl_read = cell2mat(ilxl_read'); + zero_log = ilxl_read(:,1) ~= 0; + ilxl_read = ilxl_read(zero_log,:); + traces = traces(:,zero_log); + % ilxl_read = ilxl_read'; + offset_read = cell2mat(offset_read'); + offset_read = offset_read(zero_log); + offset_read = offset_read'; +end + +function [traces,ilxl_read,offset_read] = read_traces_segy(seismic,start_byte,n_traces_to_read) + + fid = fopen(char(seismic.filepath),'r','b'); + fseek(fid,start_byte,'bof'); + + if seismic.file_type == 1 + % Convert traces from IBM32FP read as UINT32 into IEEE64FP (doubles) - need to make it singles + %traces_tmp = fread(fid,[60+seismic.n_samples,n_traces_to_read],strcat(num2str(seismic.n_samples),'*uint32=>uint32')); + traces_tmp = fread(fid,[60+seismic.n_samples,n_traces_to_read],'*uint32'); + + + %ilxl_read = traces_tmp(48:49,:)'; % what happens if the inline and crossline are not in this location + trchead = traces_tmp(1:60,:); + [trace_header bytes_to_samples] = interpretbe(reshape(typecast(trchead(:),'uint16'),120,[])); + + % Inline / crossline compression step + ilxl_read(:,1) = int32(trace_header(bytes_to_samples == seismic.pkey,:))'; + ilxl_read(:,2) = int32(trace_header(bytes_to_samples == seismic.skey,:))'; + offset_read = int32(trace_header(bytes_to_samples == seismic.tkey,:))'; + + %offset_read = traces_tmp(10,:)'; + + traces = single((1-2*double(bitget(traces_tmp(61:end,:),32))).*16.^ ... + (double(bitshift(bitand(traces_tmp(61:end,:),uint32(hex2dec('7f000000'))),-24))-64).* ... + (double(bitand(traces_tmp(61:end,:),uint32(hex2dec('00ffffff'))))/2^24)); + elseif seismic.file_type == 2 + disp('This seismic file type is not currently supported. Please speak to Charles Jones.'); + elseif seismic.file_type == 5 + % Traces are IEEE32FP (singles) + traces = fread(fid,[60+seismic.n_samples,n_traces_to_read],strcat(num2str(seismic.n_samples),'*float32=>float32')); + %trace_headers = typecast(single(reshape(traces(1:60,:),1,60*n_traces_to_read)),'int32'); + %trace_headers = reshape(trace_headers,60,n_traces_to_read); + + trchead = typecast(single(reshape(traces(1:60,:),1,60*n_traces_to_read)),'uint16'); + %trchead = reshape(trchead,120,n_traces_to_read); + + [trace_header bytes_to_samples] = interpretbe(reshape(trchead,120,[])); + + % Inline / crossline compression step + ilxl_read(:,1) = int32(trace_header(bytes_to_samples == seismic.pkey,:))'; + ilxl_read(:,2) = int32(trace_header(bytes_to_samples == seismic.skey,:))'; + offset_read = int32(trace_header(bytes_to_samples == seismic.tkey,:))'; + + %ilxl_read = trace_headers(48:49,:)'; + %offset_read = trace_headers(10,:)'; + traces = traces(61:end,:); + else + disp('This seismic file type is not currently supported. Please speak to Charles Jones.'); + end + + fclose(fid); +end + + +function [trace_header bytes_to_samples] = interpretbe(tmptrheader) +byte_type = [ ... + 2*ones(7,1); ones(4,1); + 2*ones(8,1); ones(2,1); + 2*ones(4,1); ones(46,1); + 2*ones(5,1); ones(2,1); + 2*ones(1,1); ones(5,1); + 2*ones(1,1); ones(1,1); + 2*ones(1,1); ones(2,1); + 2*ones(1,1); 2*ones(1,1)]; + +ntr = size(tmptrheader,2); +trace_header = zeros(91,ntr); +bytes_to_samples = zeros(91,1); + +count =1; +for ii = 1:91 + bytes_to_samples(ii,1) = 2*count-1; + if byte_type(ii) == 1 + trace_header(ii,:) = double(tmptrheader(count,:)); + count = count+1; + elseif byte_type(ii) == 2 + trace_header(ii,:) = double(tmptrheader(count+1,:))*2^16 + double(tmptrheader(count,:)); % note this is big-endian and different to one in segy_make_structure + count = count+2; + end +end + +trace_header(21,:) = trace_header(21,:)-2^16; + +end diff --git a/node/node_segy_write.m b/node/node_segy_write.m new file mode 100644 index 0000000..572dc5c --- /dev/null +++ b/node/node_segy_write.m @@ -0,0 +1,217 @@ +function [] = node_segy_write(results_out,i_block, sample_rate, output_dir, varargin) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% node_segy_write: function to read traces from a specific block with a +% scanned segy volume +% Arguments: +% results_out = a cell array which always contains metadata in the +% first row. Subsequent rows contain data matrices to be written +% i_block = integer specifying which block results are from +% sample_rate = sample of SEGY to add to segy header +% output_dir = path specifying output location +% varargin = does not do anything at the moment +% +% Outputs: +% none +% +% Writes to Disk: +% Loops through entries in results_out and creates separate SEGY +% files at location specified by output_dir + +%% +n_results = size(results_out,1); +for i_results = 2:1:n_results % top row in results is meta inforation includes output directory (can either be local to node or on system) + %file_name = fullfile(output_dir, sprintf('%s_result_block_%d%s',results_out{i_results,1},i_block,'.segy')); + %file_name = fullfile(output_dir, sprintf('%s_block_%d',results_out{i_results,1},i_block),'.segy'); + out_dir = strcat(output_dir,results_out{i_results,1},'/'); + + if ~exist(out_dir,'dir') + mkdir(out_dir); + end + + file_name = fullfile(out_dir, sprintf('%s_block_%d%s',results_out{i_results,1},i_block,'.segy')); + + % separate folder for each i_results + + %% Define Variables + % start_time = 0; + % sample_rate = 4; + n_samples = size(results_out{i_results,2},1); + +% if n_samples < n_samples_out +% pad_samples = n_samples_out - n_samples; +% results_out{i_results,2} = [results_out{i_results,2}; zeros(size(results_out{i_results,2},2),pad_samples)]; +% n_samples = n_samples_out; +% end + + coscal_val = -100; % Coordinate scalar to be written to SEGY. + block_sz = 100; % Number of traces written at a time + + %% Initialise files and headers + fid_ilxl_f32 = fopen(file_name,'w'); % Open file for writing + header = zeros(60,block_sz,'int32'); % Define zero matrix in dimensions of header. + + % Set an array for the coordinate scalar as int16 packed into int32 data + tmpcolscal = zeros(1,(block_sz*2),'int16'); + tmpcolscal(1:2:size(tmpcolscal,2)) = coscal_val; + tmpcolscal2 = typecast(tmpcolscal,'int32'); + + % Define binary header + bin_header = zeros(200,1,'uint16'); % Define zero vector as size of trace header + bin_header(7) = 1; % Number of data traces per ensemble + bin_header(9) = sample_rate*1000; % Sample rate (needs to be in microseconds) + bin_header(11) = n_samples; % Number of samples per trace + bin_header(13) = 5; % SEGY data number format 5 = ieee float 754 + bin_header(14) = 1; % Ensemble fold + bin_header(15) = 4; % Trace sorting code 4 = horizontally stacked , 2 = cdp ensemble + bin_header(28) = 1; % Measurement system + bin_header(151) = 256; % SEGY revision number + bin_header(152) = 1; % Fixed length flag 1= size always the same + + % Write out the ebcdic_header + % seismic.text_header = ['AAAAA',blanks(3190),'ZZZZZ']; + seismic.text_header = sprintf('%-3200.3200s',results_out{1,1}); + fwrite(fid_ilxl_f32,seismic.text_header,'char*1',0,'ieee-be'); + + % Write out the binary header + fwrite(fid_ilxl_f32,bin_header,'uint16',0,'ieee-be'); + + %% Loop through the data and write out to SEGY + last_byte = 0; + + + bytes_per_sample = 4; + skip_textual_binary = 3600; + trc_head = 240; + trc_length = n_samples*bytes_per_sample; + for ii= 1:block_sz:size(results_out{i_results,2},2) + + maxblock = ii + block_sz - 1; + + if maxblock > size(results_out{i_results,2},2) + maxblock = size(results_out{i_results,2},2); + block_sz = (maxblock - ii+1); + header = zeros(60,block_sz,'int32'); + tmpcolscal = zeros(1,(block_sz*2),'int16'); + tmpcolscal(1:2:size(tmpcolscal,2)) = coscal_val; + tmpcolscal2 = typecast(tmpcolscal,'int32'); + end + + temparr = typecast(single(reshape(results_out{i_results,2}(:,ii:maxblock),1,(n_samples*(maxblock-ii+1)))),'int32'); + temparr2 = [header; reshape(temparr,n_samples,block_sz)]; + + % Set header values to byte loc 1 as 4 byte integer + count = ii:1:maxblock; + temparr2(1,:) = count; + + % Set byte 29 to 1 as a 16 bit integer into a int32, so the first 16 + % bytes have to represent 1 when read as unit16, so multiply 1 by 2^16 + % which is 65536 + temparr2(8,:) = 65536; + + % To write the int16 coordinate scalar as -100 as int32 in to byte location 71 + temparr2(18,:) = tmpcolscal2; + + % to write the no of samples into trace header 115 as 16 bit integer + temparr2(29,:) = n_samples; + + % to write the sample rate into trace header 117 as 16 bit integer + temparr2(30,:) = sample_rate*1000*65536; % Sample rate (needs to be in microseconds) + + % write the inline crossline numbers to bytes 189 and 193 + %temparr2(48,:) = cast(results_out{1,2}{1,i_results-1}(ii:maxblock,1)','int32'); % assumes inline / crossline are the same for all files + %temparr2(49,:) = cast(results_out{1,2}{1,i_results-1}(ii:maxblock,2)','int32'); + %temparr2(48,:) = typecast(results_out{1,2}{1,i_results-1}(ii:maxblock,1)','int32'); % assumes inline / crossline are the same for all files + %temparr2(49,:) = typecast(results_out{1,2}{1,i_results-1}(ii:maxblock,2)','int32'); + + % the test of n_results is to cover the ability to write results + % sets with different sets of trace headers (pkey skey tkey) they + % would go as more rows into resultsout{1,2} and would the looped + % through, rather gave up on this and tend to call multiple calls + % to node_segy_write + + if size(results_out{1,2},2) < n_results + % Write offset information to byte 37 as 4 byte 32 bit integer + temparr2(10,:) = typecast(results_out{1,2}{2,1}(ii:maxblock,1)','int32'); + % write the inline crossline numbers to bytes 189 and 193 + temparr2(48,:) = results_out{1,2}{1,1}(ii:maxblock,1)'; + temparr2(49,:) = results_out{1,2}{1,1}(ii:maxblock,2)'; + else + % Write offset information to byte 37 as 4 byte 32 bit integer + temparr2(10,:) = typecast(results_out{1,2}{2,i_results-1}(ii:maxblock,1)','int32'); + % write the inline crossline numbers to bytes 189 and 193 + temparr2(48,:) = results_out{1,2}{1,i_results-1}(ii:maxblock,1)'; + temparr2(49,:) = results_out{1,2}{1,i_results-1}(ii:maxblock,2)'; + end + + fwrite(fid_ilxl_f32,temparr2,'int32',0,'ieee-be'); + + % make byte location array % cj this needs to be a 64 bit int + byte_locs(ii:maxblock,1) = last_byte+(trc_head:trc_head+trc_length:block_sz*(trc_length+trc_head)); + last_byte = byte_locs(end,1)+trc_length; % store to add on during loop + end + fclose(fid_ilxl_f32); + + % file has written successfully so make .lite file for future use + % should be able to just use gather version of compress + byte_locs(:,1) = byte_locs(:,1)+skip_textual_binary; + + % see above for discussion on this if + if size(results_out{1,2},2) < n_results + if results_out{i_results,3} == 0 + compress_ilxl_bytes = trace_compress_ilxl_bytes([results_out{1,2}{1,1} byte_locs],size(results_out{i_results,2},2)); + else + compress_ilxl_bytes = gather_compress_ilxl_bytes([results_out{1,2}{1,1} byte_locs results_out{1,2}{2,1}],size(results_out{i_results,2},2)); + end + else + if results_out{i_result,3} == 0 + compress_ilxl_bytes = trace_compress_ilxl_bytes([results_out{1,2}{1,1} byte_locs],size(results_out{i_results,2},2)); + else + compress_ilxl_bytes = gather_compress_ilxl_bytes([results_out{1,2}{1,i_results-1} byte_locs results_out{1,2}{2,i_results-1}],size(results_out{i_results,2},2)); + end + end + clear byte_locs; +% if anggath == 1 +% compress_ilxl_bytes = gather_compress_ilxl_bytes(trace_ilxl_bytes,blocktr); +% else +% compress_ilxl_bytes = gather_compress_ilxl_bytes_offset(trace_ilxl_bytes,blocktr); +% end + + + + file_mat = fullfile(out_dir, sprintf('%s_block_%d%s',results_out{i_results,1},i_block,'.mat_orig_lite')); + + filepath_binary = uint64(file_name); + pad_filepath = zeros(1,(2000-length(filepath_binary))); + filepath_binary = [filepath_binary,pad_filepath]; + fid_write = fopen(file_mat,'w'); + %fwrite(fid_write,[filepath_binary';seismic.file_type;seismic.s_rate;seismic.n_samples;seismic.n_traces;il_byte;xl_byte;offset_byte],'double'); + % need to set is_gather + fwrite(fid_write,filepath_binary','double'); + fwrite(fid_write,[bin_header(13);bin_header(9);bin_header(11);size(results_out{i_results,2},2);189;193;37;results_out{i_results,3}],'double'); + fwrite(fid_write,reshape(compress_ilxl_bytes',[],1),'double'); + fclose(fid_write); + +end + +end \ No newline at end of file diff --git a/node/node_slurm_submit.m b/node/node_slurm_submit.m new file mode 100644 index 0000000..d243eac --- /dev/null +++ b/node/node_slurm_submit.m @@ -0,0 +1,313 @@ +function [] = node_slurm_submit(algorithm_name,job_meta_path,slurm_part,n_cores,varargin) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 +%% github +% https://github.com/AnalysePrestackSeismic/ +%% ------------------ FUNCTION DEFINITION --------------------------------- +% node_slurm_submit: function to submit jobs to cluster. A specific +% algorithm is specified and this each block is processed in parallel on a +% cluster +% Arguments: +% algorithm_name = the algorithm that should be submitted to the +% cluster. This should have already been compiled using compile_function +% job_meta_path = path to job_meta .mat file contain meta data +% slurm_part = slurm partition to use +% n_cores = specify how many cores the job requires. Used by -c flag +% in slurm. Helpful for jobs that require more memory or that +% multi-thread +% varargin = algorithm specific flags to control arguments. By +% default all algorithms require the following arguments: +% job_meta_path +% i_block +% custom arguments can be added '30','1','30','0','1' +% +% Outputs: +% none +% +% Writes to Disk: +% Log Files +% Notes: You may want to QC the running of the job using segy_plot_run_jobs.m + +%% +% submit compiled matlab function slurm +% arguments cell array needs to be in correct order +% water_bottom_flatten(block_mat,process_files_mat,join_block_id) + +run_script_path = '/apps/gsc/matlab-library/development/maps/algorithms/'; +matlab_path = '/apps/matlab/v2011a'; +job_meta = load(job_meta_path); % load job meta file + +randdir = num2str(floor(now*100000)); +datemonprev = datestr((now-100),29); +[~,usrname] = system('whoami'); +randdir = strcat(usrname,'_',randdir); % Make directory name based on the current time and the name of the user + +% Make directory to save results +logoutdir = strcat(job_meta.output_dir,'out_log_files/'); +if exist(logoutdir,'dir') == 0 + mkdir(logoutdir) + system(['chmod 777 ',logoutdir]); +end + +% assume all blocks are run +%n_blocks = num2str(job_meta.n_blocks); +% load the list of blocks to run + +% nodelist {tvlxpgcn70,tvlxpgcn71} + +% function should be compiled as single threaded so a simple call to srun +% can be used +% Thames [01-16] +% UK1 [51-56, 58-98] +% All [01-16,51-56,58-98] +if strcmp(slurm_part,'Thames') || strcmp(slurm_part,'AllDC') + n_nodes = 16; + head_node = 'tvlxpgcn01 '; + for i_node = 1:1:n_nodes + slurm_purge = sprintf('srun -p %s -n 1 --exclusive %s %s %s %s','Thames',run_script_path,'purge_function.sh',randdir,' &'); + system(slurm_purge); + end + pause(1); +elseif strcmp(slurm_part,'UK1') + n_nodes = 48; + head_node = 'tvlxpgcn53 '; + for i_node = 1:1:n_nodes + slurm_purge = sprintf('srun -p %s -n 1 --exclusive %s %s %s %s','Thames',run_script_path,'purge_function.sh',randdir,' &'); + system(slurm_purge); + end + pause(1); +end + +%--------------PREPARING ARGUMENTS ------------------ +% All functions have first two arguments as function_name(job_meta_path,i_block) +% Extra Arguments + +if strcmp(algorithm_name,'seismic_anomaly_spotter') + n_blocks = varargin{1}; + n_samps_slice = floor(job_meta.n_samples{str2double(varargin{2})}/str2double(n_blocks)); + start_block = 1:n_samps_slice:job_meta.n_samples{str2double(varargin{2})}; + end_block = start_block+n_samps_slice-1; +end + +if strcmp(algorithm_name,'wavelet_estimation') + varargin{length(varargin)+1} = num2str(job_meta.liveblocks(1)); % Find the first live block from job_meta file and append varargin arraay +end + +if strcmp(algorithm_name,'structural_tensor_dip') + %scale_sigma = varargin{1}; + scale_sigma = varargin{3}; + sigma = varargin{2}; + aperture = num2str(str2num(scale_sigma)*str2num(sigma)); + %add_aperture_to_job_meta(job_meta_path,aperture); + %node_slurm_submit('structural_tensor_dip','/data/TZA/segy/2013_kusini_inboard/pgs_enhanced_volume/structural_tensors_dip/job_meta/job_meta_07Oct2014.mat','UK1','4','1','3','1','3000') +end +% if you are running int_grad_inv_proj and user has supplied a maxzout +% horizon mask, edit varargin) + +if (strcmp(algorithm_name,'int_grad_inv_proj') && ~isempty(strfind(varargin{5},'/'))) + horizon_path = varargin{5}; % Path of the horizon + flag_horizon_mask = 1; % Flag that horizon mask will be used + varargin = varargin(1:4); % delete the last maxzout argument from varargin + arguments_crop = ''; + for i_arg = 1:(length(varargin)) % use all the arguments in varargin except the horizon path + if ~ischar(varargin{i_arg}) + varargin{i_arg} = num2str(varargin{i_arg}); %if varargin element not a character convert the numbers into string + end + arguments_crop = sprintf('%s %s',arguments_crop,char(varargin{i_arg})); % Append arguments_crop string by new entry from varargin + end +else + flag_horizon_mask = 0; % Flag that horizon mask won't be used + arguments = ''; + for i_arg = 1:1:length(varargin) + if ~ischar(varargin{i_arg}) + varargin{i_arg} = num2str(varargin{i_arg}); %if varargin element not a character convert the numbers into string + end + arguments = sprintf('%s %s',arguments,char(varargin{i_arg})); % Append arguments string by new entry from varargin + end +end +%-----------------MAKING THE SCRIPT FILE FOR SUBMISSION------------------- + +%--------Constructing Script Portion required for all algorithm---- +random_string = randi(1000000,1); +batch_script_path = [job_meta.output_dir,'script_job_',randdir,'_',num2str(random_string)]; +fid_batch = fopen(batch_script_path, 'w'); +fprintf(fid_batch, '#!/bin/sh\n'); +fprintf(fid_batch, 'umask 002\n'); +fprintf(fid_batch, 'MCR_CACHE_ROOT=/localcache/mcr_cache_umask_friendly/%s\n',randdir); +%fprintf(fid_batch, 'MCR_CACHE_ROOT=/localcache/Paradigm/jonesce/%s\n',randdir); +fprintf(fid_batch, 'MCRROOT=/apps/matlab/v2011a/ ;\n'); +fprintf(fid_batch, 'export MCR_CACHE_ROOT ;\n'); +fprintf(fid_batch, 'export MCRROOT ;\n'); +fprintf(fid_batch, 'mkdir -p ${MCR_CACHE_ROOT} ;\n'); +fprintf(fid_batch, 'LD_LIBRARY_PATH=.:${MCRROOT}/runtime/glnxa64 ;\n'); +fprintf(fid_batch, 'LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${MCRROOT}/bin/glnxa64 ;\n'); +fprintf(fid_batch, 'LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${MCRROOT}/sys/os/glnxa64;\n'); +fprintf(fid_batch, 'MCRJRE=${MCRROOT}/sys/java/jre/glnxa64/jre/lib/amd64 ;\n'); +fprintf(fid_batch, 'LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${MCRJRE}/native_threads ; \n'); +fprintf(fid_batch, 'LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${MCRJRE}/server ;\n'); +fprintf(fid_batch, 'LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${MCRJRE}/client ;\n'); +fprintf(fid_batch, 'LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${MCRJRE} ; \n'); +fprintf(fid_batch, 'XAPPLRESDIR=${MCRROOT}/X11/app-defaults ;\n'); +fprintf(fid_batch, 'export LD_LIBRARY_PATH;\n'); +fprintf(fid_batch, 'export XAPPLRESDIR;\n'); +%livetestexi = exist('job_meta','var'); +%if livetestexi == 1; +%----------------------------------------------------------------------- + +%%--------Constructing Script Portion specific to the algorithm used---- +%--------------FOR SEISMIC ANOMALY SPOTTER_---------------------------- +if strcmp(algorithm_name,'seismic_anomaly_spotter') + for i_block = 1:1:str2double(n_blocks) + fprintf(fid_batch, ['sbatch -p ',slurm_part,' -c ',n_cores,' -J ',algorithm_name,'_',... + num2str(i_block),' --wckey=',randdir,'_',algorithm_name,' -o ',logoutdir,algorithm_name,'_',... + num2str(i_block),'.out < 1; + % Pad with zeros or first wavelet + pad_size = start_interp-1; + wavelet_interp{vol_count} = [repmat(wavelet_interp{vol_count}(:,1),1,pad_size),... + wavelet_interp{vol_count}]; + end + if end_interp < ns; + % Pad with zeros or last wavelet + pad_size = ns-end_interp; + wavelet_interp{vol_count} = [wavelet_interp{vol_count},... + repmat(wavelet_interp{vol_count}(:,end),1,pad_size)]; + end + if floor(ns_wavelet/2) == ns_wavelet/2 + wavelet_interp{vol_count}(end+1,:) = wavelet_interp{vol_count}(end,:); + end + if plot_on == 1 + %figure(4) + %subplot(1,totalvol,vol_count); + %imagesc(wavelet_interp{vol_count}); + end + vol_count = vol_count + 1; +end +interp_wavelet_z_grid = 1:ns; +ns_wavelet = size(wavelet_interp{1},1); + +if plot_on == 2 + figure(5) + imagesc(cell2mat(wavelet_interp)) + +end + +if job_meta.is_gather == 0 + %wavelet_norm = wavelet_rms_norm(totalvol,wavelet_interp,interp_wavelet_z_grid,ceil(totalvol*0.6667)); + wavelet_norm = wavelet_rms_norm(totalvol,wavelet_interp,ceil(totalvol*0.6667)); +else + % need to store the water bottom live offset in the job_meta + job_meta.livewb = startvol + (floor(((endvol - startvol)/2)/volinc) * volinc); + %wavelet_norm = wavelet_rms_norm(totalvol,wavelet_interp,interp_wavelet_z_grid,job_meta.livewb); + wavelet_norm = wavelet_rms_norm(totalvol,wavelet_interp,job_meta.livewb); + %wavelet_norm = wavelet_interp; + +end + +if plot_on == 2 + figure(51) + imagesc(cell2mat(wavelet_norm)) +end +%subplot(3,job_meta.nvols,i_vol+job_meta.nvols); plot(freq_axis,w_freq(3:2+ceil(job_meta.ns_win/2),:,i_vol)); set(gca,'XTick',1:ceil(10*freq_axis(2)):ceil(freq_axis(end))) + +if plot_on == 3 + figure(10) + + xmin = 1; + xmax = 129; + wavelets_vec = cell2mat(wavelet_norm); + wavelets_vec = wavelets_vec(:); + ymin = min(wavelets_vec); + ymax = max(wavelets_vec); + + totalvol = 5; + totalsteps = 30; + plotinc = floor(ns/totalsteps); + if job_meta.is_gather == 1 + a1 = [ 5 15 20 30 35 45]; + else + a1 = 1:size(wavelet_interp,2); + end + a1 = a1(1:totalvol); + for ik = 1:totalsteps + ii = ik*plotinc; + subplot(2,totalvol,1); plot(wavelet_interp{a1(1)}(:,ii)); axis([xmin xmax ymin ymax]) ; title(strcat('pre ',num2str(a1(1)))); + subplot(2,totalvol,2); plot(wavelet_interp{a1(2)}(:,ii)); axis([xmin xmax ymin ymax]) ; title(strcat('pre ',num2str(a1(2)))); + subplot(2,totalvol,3); plot(wavelet_interp{a1(3)}(:,ii)); axis([xmin xmax ymin ymax]) ; title(strcat('pre ',num2str(a1(3)))); + subplot(2,totalvol,4); plot(wavelet_interp{a1(4)}(:,ii)); axis([xmin xmax ymin ymax]) ; title(strcat('pre ',num2str(a1(4)))); + subplot(2,totalvol,5); plot(wavelet_interp{a1(5)}(:,ii)); axis([xmin xmax ymin ymax]) ; title(strcat('pre ',num2str(a1(5)))); +% subplot(2,totalvol,6); plot(wavelet_interp{a1(6)}(:,ii)); axis([xmin xmax ymin ymax]) ; title(strcat('pre ',num2str(a1(6)))); + + subplot(2,totalvol,6); plot(wavelet_norm{a1(1)}(:,ii)); axis([xmin xmax ymin ymax]); title(strcat('post ',num2str(a1(1)))); + subplot(2,totalvol,7); plot(wavelet_norm{a1(2)}(:,ii)); axis([xmin xmax ymin ymax]); title(strcat('post ',num2str(a1(2)))); + subplot(2,totalvol,8); plot(wavelet_norm{a1(3)}(:,ii)); axis([xmin xmax ymin ymax]); title(strcat('post ',num2str(a1(3)))); + subplot(2,totalvol,9); plot(wavelet_norm{a1(4)}(:,ii)); axis([xmin xmax ymin ymax]); title(strcat('post ',num2str(a1(4)))); + subplot(2,totalvol,10); plot(wavelet_norm{a1(5)}(:,ii)); axis([xmin xmax ymin ymax]); title(strcat('post ',num2str(a1(5)))); + % subplot(2,totalvol,12); plot(wavelet_norm{a1(6)}(:,ii)); axis([xmin xmax ymin ymax]); title(strcat('post ',num2str(a1(6)),' : ',num2str(ii))); + pause(5); + end +end + +% %for i_vol = 1:1:job_meta.nvols +% fid_wav = fopen(strcat(job_meta.wav_directory,'fft_wavelets_block_',i_block,'.bin')); +% w_tmp = fread(fid_wav,'float32'); +% fclose(fid_wav); +% %n_win = w_tmp(1); +% n_vol = w_tmp(1); +% n_win = w_tmp(2); +% %w_freq{i_vol} = reshape(w,[],n_win); +% %w_freq{i_vol} = reshape(w_tmp(3:end),[],n_vol); +% w_freq = reshape(w_tmp(3:end),[],n_win,n_vol); +% % w_freq{i_vol} = w(3:end,:); +% % Convert from frequency domain to time domain +% w_time = circshift(ifft(w_freq(3:end,:,:),'symmetric'),floor(job_meta.ns_win/2)); +% %end + + +% %imagesc(w_time{1}); +% freq_axis = (1e6/job_meta.s_rate)/2*linspace(0,1,job_meta.ns_win/2); +% figure +% for i_vol = 1:1:job_meta.nvols +% subplot(3,job_meta.nvols,i_vol); imagesc(w_time(:,:,i_vol)); +% subplot(3,job_meta.nvols,i_vol+job_meta.nvols); plot(freq_axis,w_freq(3:2+ceil(job_meta.ns_win/2),:,i_vol)); set(gca,'XTick',1:ceil(10*freq_axis(2)):ceil(freq_axis(end))) +% subplot(3,job_meta.nvols,(i_vol+(job_meta.nvols*2))); imagesc(w_freq(3:2+ceil(job_meta.ns_win/2),:,i_vol)'); +% end +% %colorbar +% %colormap('gray') + +end + +function wavelet_interp = interpolate_wavelets(wavelet_z_grid,wavelet,start_interp,end_interp) +% start_interp = min(wavelet_z_grid)-mode(diff(wavelet_z_grid')); +% end_interp = max(wavelet_z_grid)+mode(diff(wavelet_z_grid')); +wavelet_interp = interp1(wavelet_z_grid,wavelet',start_interp:1:end_interp,'linear','extrap'); +end + +% function wavelet_norm = wavelet_rms_norm(totalvol,wavelet_interp,wavelet_z_grid,vol_index) +% % Normalise the wavelets to have constant energy w.r.t. angle. The energy +% % is set to that of the nearest angle wavelets. Wavelet energy still varies +% % w.r.t. time. +% A = cell2mat(wavelet_interp); +% %B = sqrt(sum(A.^2)); +% B = sqrt(max(A.^2)); +% C = reshape(B',length(wavelet_z_grid),[]); +% D = C(:,vol_index); +% for ii=1:totalvol +% E = A(:,1+(ii-1)*length(wavelet_z_grid):ii*length(wavelet_z_grid)); +% F = bsxfun(@rdivide,bsxfun(@times,E,D'),sqrt(sum(E.^2))); +% F(isnan(F)) = 0; +% wavelet_norm{ii} = F; +% +% end + +function wavelet_norm = wavelet_rms_norm(totalvol,wavelet_interp,vol_index) + % Normalise the wavelets to have constant energy w.r.t. angle. The energy + % is set to that of the nearest angle wavelets. Wavelet energy still varies + % w.r.t. time. + norm_to = sum(abs(wavelet_interp{vol_index})); + for ii=1:totalvol + curwav = sum(abs(wavelet_interp{ii})); + ratio = norm_to./curwav; + wavelet_norm{ii} = bsxfun(@times,wavelet_interp{ii},ratio); + end + + +end + + + + + diff --git a/readme.m b/readme.m new file mode 100644 index 0000000..2cbd32e --- /dev/null +++ b/readme.m @@ -0,0 +1,33 @@ +%% AnalysePrestackSeismic +% A library of MATLAB code for analysing post-migration pre-stack seismic +% data. + +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. + +%% Contributors +% James Selvage +% Jonathan Edgar +% Charles Jones +% Ratnadwip Ghosh +% Simon Wrigley +% Dan Bright + +%% Contact +% Please contact james dot selvage at bg hyphen group dot com +% 0r charles dot jones at bg hyphen group dot com diff --git a/readme.m~ b/readme.m~ new file mode 100644 index 0000000..f58fb72 --- /dev/null +++ b/readme.m~ @@ -0,0 +1,31 @@ +%% AnalysePrestackSeismic +% A library of MATLAB code for analysing post-migration pre-stack seismic +% data. + +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. + +%% Contributors +% James Selvage +% Jonathan Edgar +% Charles Jones +% Ratnadwip Ghosh + +%% Contact +% Please contact james dot selvage at bg hyphen group dot com +% 0r charles dot jones at bg hyphen group dot com diff --git a/scan_segy/trace_compress_ilxl_bytes.m b/scan_segy/trace_compress_ilxl_bytes.m index e501113..e0f2c27 100644 --- a/scan_segy/trace_compress_ilxl_bytes.m +++ b/scan_segy/trace_compress_ilxl_bytes.m @@ -35,6 +35,7 @@ % % Writes to Disk: % nothing + pkey_loc = 1; % column numbers needs to be implemented skey_loc = 2; byte_loc = 3; @@ -100,4 +101,4 @@ % now truncate the array %compress_ilxl_bytes(count+1:end,:) = []; -end \ No newline at end of file +end diff --git a/scan_segy/trace_compress_ilxl_bytes.m~ b/scan_segy/trace_compress_ilxl_bytes.m~ new file mode 100644 index 0000000..e501113 --- /dev/null +++ b/scan_segy/trace_compress_ilxl_bytes.m~ @@ -0,0 +1,103 @@ +function compress_ilxl_bytes = trace_compress_ilxl_bytes(trace_ilxl_bytes,blocktr) +%% ------------------ Disclaimer ------------------ +% +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) makes no representation or warranty, express or implied, in +% respect to the quality, accuracy or usefulness of this repository. The code +% is this repository is supplied with the explicit understanding and +% agreement of recipient that any action taken or expenditure made by +% recipient based on its examination, evaluation, interpretation or use is +% at its own risk and responsibility. +% +% No representation or warranty, express or implied, is or will be made in +% relation to the accuracy or completeness of the information in this +% repository and no responsibility or liability is or will be accepted by +% BG Group plc or any of its respective subsidiaries, affiliates and +% associated companies (or by any of their respective officers, employees +% or agents) in relation to it. + +%% ------------------ License ------------------ +% GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 + +%% github +% https://github.com/AnalysePrestackSeismic/ + +%% ------------------ FUNCTION DEFINITION --------------------------------- +% trace_compress_ilxl_bytes: function to compress scanned SEGY trace +% headers by finding repeating patterns. Only for post-stack datasets. +% Arguments: +% trace_ilxl_bytes = scan of trace headers created by segy_make_structure +% blocktr = number of input traces +% +% Outputs: +% compress_ilxl_bytes = compressed version of trace_ilxl_bytes +% +% Writes to Disk: +% nothing +pkey_loc = 1; % column numbers needs to be implemented +skey_loc = 2; +byte_loc = 3; + +start_idx = 1; +count = 0; +row_i = 1; + +%blocktr = size(trace_ilxl_bytes,1); +pkey_prev = -995837; +skey_prev = -9999437; +skey_inc = -999971; +cur_inc = -27389995; + +%compress_ilxl_bytes = zeros([blocktr,5],'int64'); + +if blocktr > 1 + for row_i = start_idx:blocktr + pkey = trace_ilxl_bytes(row_i,pkey_loc); + skey = trace_ilxl_bytes(row_i,skey_loc); + tbyte = trace_ilxl_bytes(row_i,byte_loc); + + if pkey == pkey_prev + cur_inc = skey - skey_prev; + if cur_inc ~= skey_inc + if cur_inc == 0 + count = count + 1; + compress_ilxl_bytes(count,:) = [ pkey skey tbyte skey 1 ]; + skey_inc = -999971; + skey_prev = skey; + else + if skey_inc == -999971 % cur_inc is first time or after duplicate trace + compress_ilxl_bytes(count,4:5) = [ skey cur_inc ]; + skey_inc = cur_inc; + skey_prev = skey; + else % cur_inc is not 0 + count = count + 1; + compress_ilxl_bytes(count,:) = [ pkey skey tbyte skey cur_inc ]; + skey_inc = cur_inc; + skey_prev = skey; + end + end + else % cur_inc == skey_inc + compress_ilxl_bytes(count,4) = skey; + skey_prev = skey; + end + + + else % pkey ~= pkey_prev + count = count + 1; + compress_ilxl_bytes(count,:) = [ pkey skey tbyte skey 1 ]; + pkey_prev = pkey; + skey_prev = skey; + skey_inc = -999971; + end + + end + +else % for blocktr = 1 + count = count + 1; + compress_ilxl_bytes(count,:) = [ trace_ilxl_bytes(row_i,pkey_loc) trace_ilxl_bytes(row_i,skey_loc) trace_ilxl_bytes(row_i,byte_loc) trace_ilxl_bytes(row_i,skey_loc) 1 ]; +end +% now truncate the array +%compress_ilxl_bytes(count+1:end,:) = []; + +end \ No newline at end of file