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