% This script is to plot, correct and export solution SAXS data to SASfit % accounts for transmission, time and thickness correction % scales the data to a calibration factor % background correction, removal of bad pixels % not suitable for anisotropic data % saves the output to be used in SASfit %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % EDIT HERE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % give the calibration factor for absolute intensity, calculated previously cal_factor_SAXS = 2.91e-4; cal_factor_WAXS = 2.01e-5 ; % where the data is saved (Data10, afs, p-account) base_dir = '~/Data10/';%'/sls/X12SA/Data20/e16598/'; save_dir = '~/Data10/';%'/mnt/das-gpfs/work/p16598/'; eaccount = beamline.identify_eaccount; % 'e16598'; % samples and thicknesses Air = 15; % scan used for transmission calculation sample_scan = [34:38]; % should be given sample_thickness = 0.15; % in cm: important for absolute scattering back_scan = []; % used as background, leave it empty [] for no subtraction !!NOT TESTED!! back_thickness = 0.01; % in cm: important for absolute scattering % export data for SASfit? export_sasfit = 1; %plot curves? plot_curves = 0; % save figures? save_fig = 0; % average the scan points? 1 = yes, 0 = no average_scan = 1; % scale also the waxs data? yes = 1; no = 0; use_waxs = 0; % which bad pixels should be removed bad_pixel = []; %given as a vector [811, 825] % use all data measurement points or skip some (faster) skip_measurements = [100]; % use 1 to show all % used to reduce noise at the beginning and end of scattering curve skip_first_points = 55; skip_last_points = 150; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% load the diode value for the air S_air = io.spec_read(base_dir,'ScanNr',Air); %scale in case the exposure times are different exp_time = S_air.sec(1,1); scale_air = 1/exp_time; Air_data = load(sprintf('%s/analysis/radial_integration/%s_1_%05d_00000_00000_integ.mat', base_dir, eaccount, Air)); I_air = mean(Air_data.I_all, 3); % average over the segments when needed if size(I_air, 2) > 1 I_air = (I_air .* Air_data.norm_sum)./sum(Air_data.norm_sum, 2); I_air = sum(I_air, 2); end if use_waxs Air_waxs = load(sprintf('%s/analysis/radial_integration_waxs/%s_2_%05d_00000_00000_integ.mat', base_dir, eaccount, Air)); I_air_waxs = mean(squeeze(Air_waxs.I_all), 2); end %% background correction if ~isempty(back_scan) for b = 1:length(back_scan) bgr = load(sprintf('%s/analysis/radial_integration/%s_1_%05d_00000_00000_integ.mat', base_dir, eaccount, back_scan(b))); S_back = spec_read(base_dir,'ScanNr',back_scan(b)); % in case the burst scan takes place, the transmission is % calculated differently if ~isempty(findstr(S_back.S, 'burst_scan')) delimiter = ' '; formatSpec = '%*s%*s%s%[^\n\r]'; fileID = fopen(sprintf('%smcs/S00000-00999/S%05d/%s_%05d.dat', base_dir,back_scan(b), eaccount, back_scan(b)), 'r'); dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter, 'MultipleDelimsAsOne', true, 'ReturnOnError', false); exp_time = dataArray{1,1}{7,1}; scale_back = 1/str2num(exp_time); diode = mean(str2num(dataArray{1,1}{9,end})); transm_back = ((diode*scale_back)/(mean(S_air.diode)*scale_air)); fclose(fileID); else %scale in case the exposure times are different exp_time = S_back.sec(1,1); scale_back = 1/exp_time; transm_back = (mean(S_back.diode)/mean(S_back.bpm4i))/(mean(S_air.diode)/mean(S_air.bpm4i)); end %average background I_bgr = mean(bgr.I_all, 3); if size(I_bgr, 2) > 1 I_bgr = (I_bgr .* bgr.norm_sum)./sum(bgr.norm_sum, 2); I_bgr = sum(I_bgr, 2); end I_bgr = ((((I_bgr*scale_back)*1/transm_back)-(I_air*scale_air))*1/back_thickness); I_bgr = I_bgr * cal_factor_SAXS; if use_waxs %average background_WAXS bgr_waxs = importdata(sprintf('%s/analysis/radial_integration_waxs/%s_2_%05d_00000_00000_integ.mat', base_dir, eaccount, back_scan(b))); I_bgr_waxs = mean(squeeze(bgr_waxs.I_all), 2); I_bgr_waxs = ((((I_bgr_waxs*scale_back)*1/transm_back)-(I_air_waxs*scale_air))*1/back_thickness); I_bgr_waxs = I_bgr_waxs * cal_factor_WAXS; end end else I_bgr_waxs = 0; I_bgr = 0; end %% load and correct the sample for s = 1:length(sample_scan) sample_filename=sprintf('%s/analysis/radial_integration/%s_1_%05d_00000_00000_integ.mat', base_dir, eaccount, sample_scan(s)); if exist(sample_filename) == 2 display(['reading file ',sample_filename]) sample = load(sample_filename); else continue end S_s = io.spec_read(base_dir,'ScanNr',sample_scan(s)); if ~isempty(findstr(S_s.S, 'burst_scan')) delimiter = ' '; formatSpec = '%*s%*s%s%[^\n\r]'; fileID = fopen(sprintf('%smcs/S00000-00999/S%05d/%s_%05d.dat', base_dir,sample_scan(s), eaccount,sample_scan(s)), 'r'); dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter, 'MultipleDelimsAsOne', true, 'ReturnOnError', false); exp_time = dataArray{1,1}{7,1}; scale_s = 1/str2num(exp_time); diode = mean(str2num(dataArray{1,1}{9,end})); transm_sample = ((diode*scale_s)/(mean(S_air.diode)*scale_air)); fclose(fileID); else %scale in case the exposure times are different exp_time = S_s.sec(1,1); scale_s = 1/exp_time; transm_sample = (mean(S_s.diode)/mean(S_s.bpm4i))/(mean(S_air.diode)/mean(S_air.bpm4i)); end %load the sample I_sample = squeeze(sample.I_all); q_sample = sample.q'; if use_waxs %average background_WAXS sample_waxs = load(sprintf('%s/analysis/radial_integration_waxs/%s_2_%05d_00000_00000_integ.mat', base_dir, eaccount, sample_scan(s))); I_sample_waxs = (sample_waxs.I_all); q_sample_waxs = sample_waxs.q'; else q_sample_waxs = []; I_sample_waxs = []; end if average_scan I_sample = mean(I_sample, 3); I_std = mean(sample.I_std, 3); if size(I_sample, 2) > 1 I_sample = (I_sample .* sample.norm_sum)./sum(sample.norm_sum, 2); I_std = (I_std .* sample.norm_sum)./sum(sample.norm_sum, 2); I_std = sum(I_std, 2).*cal_factor_SAXS; I_sample = sum(I_sample, 2); end I_std = I_std(skip_first_points:end-skip_last_points,:); I_sample = ((((I_sample*scale_s)*1/transm_sample)-(I_air*scale_air))*1/sample_thickness); if ~isempty(bad_pixel) I_sample(bad_pixel,1) = (I_sample(bad_pixel-1,1)+I_sample(bad_pixel+1,1))/2; end I_sample = I_sample * cal_factor_SAXS; I_cor = (I_sample-I_bgr); I_cor = I_cor(skip_first_points:end-skip_last_points,:); if use_waxs hold on I_sample_waxs = median(I_sample_waxs,3); I_sample_waxs = ((((I_sample_waxs.*scale_s).*1/transm_sample)-(I_air_waxs.*scale_air)).*1/sample_thickness); I_sample_waxs = I_sample_waxs * cal_factor_WAXS; I_cor_waxs = (I_sample_waxs-I_bgr_waxs); else I_cor_waxs = []; end I_total = [I_cor; I_cor_waxs]; q_total = [q_sample(skip_first_points: end-skip_last_points,:); q_sample_waxs]; [q_total, index] = sort(q_total); I_total = I_total(index); if plot_curves figure plot(q_total*10, I_total); set(gca,'XScale','log', 'YScale','log'); grid on; box on; xlabel('scattering vector q (nm^{-1})'); ylabel('differential scattering cross-section (cm^{-1})'); hold on end if export_sasfit save_data = [q_total*10, I_total, I_std]; filename = sprintf('scan_%05d_avg', sample_scan); save(sprintf('%sanalysis/dat_files/%s.dat', save_dir , filename) , 'save_data', '-ascii'); end else if plot_curves figure hold on end for i = 1:skip_measurements:size(sample.I_all, 3) I_point = sample.I_all(:,:,i); I_point_std = sample.I_std(:,:, i); if size(I_point, 2) > 1 I_point = (I_point .* sample.norm_sum)./sum(sample.norm_sum, 2); I_point = sum(I_point, 2); I_point_std = (I_point_std .* sample.norm_sum)./sum(sample.norm_sum, 2); I_point_std = sum(I_point_std, 2).*cal_factor_SAXS; end I_point_std = I_point_std(skip_first_points:end-skip_last_points,:); if ~isempty(bad_pixel) I_point(bad_pixel,1) = (I_point(bad_pixel-1,1) + I_point(bad_pixel+1,1))/2; end I_point = ((((I_point*scale_s)*1/transm_sample)-(I_air*scale_air))*1/sample_thickness); I_point = I_point * cal_factor_SAXS; I_cor = (I_point-I_bgr); I_cor = I_cor(skip_first_points: end-skip_last_points,:); if use_waxs I_point_waxs = I_sample_waxs(:,i); I_point_waxs = ((((I_point_waxs*scale_s)*1/transm_sample)-(I_air_waxs*scale_air))*1/sample_thickness); I_point_waxs = I_point_waxs * cal_factor_WAXS; I_cor_waxs = (I_point_waxs-I_bgr_waxs); I_point_std_WAXS = I_sample_waxs(:,:, i); I_point_std_WAXS = I_point_std_WAXS.*cal_factor_WAXS; I_point_std_WAXS = sum(I_point_std_WAXS, 2).*cal_factor_SAXS; else I_cor_waxs = []; end I_total = [I_cor; I_cor_waxs]; q_total = [q_sample(skip_first_points: end-skip_last_points,:); q_sample_waxs]; [q_total, index] = sort(q_total); I_total = I_total(index); I_point_std_total= [I_point_std; I_point_std_WAXS]; if plot_curves plot(q_total*10, I_total); grid on; box on; set(gca,'XScale','log', 'YScale','log'); xlabel('scattering vector q (nm^{-1})'); ylabel('differential scattering cross-section (cm^{-1})'); axis tight hold on drawnow end if export_sasfit save_data = [q_total*10, I_total, I_point_std_total]; filename = sprintf('scan_%05d_pt_%05d', sample_scan(s), i); save(sprintf('%sanalysis/dat-files/%s.dat', save_dir , filename) , 'save_data', '-ascii'); end end end end if save_fig %save the results saveas(gcf, sprintf('%sanalysis/scanNr_%05d.jpg', save_dir , sample_scan)) end %*-----------------------------------------------------------------------* %|                                                                       | %|  Except where otherwise noted, this work is licensed under a          | %|  Creative Commons Attribution-NonCommercial-ShareAlike 4.0            | %|  International (CC BY-NC-SA 4.0) license.                             | %|                                                                       | %|  Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch)    | %|                                                                       | %|      Author: CXS group, PSI  | %*-----------------------------------------------------------------------* % You may use this code with the following provisions: % % If the code is fully or partially redistributed, or rewritten in another % computing language this notice should be included in the redistribution. % % If this code, or subfunctions or parts of it, is used for research in a % publication or if it is fully or partially rewritten for another % computing language the authors and institution should be acknowledged % in written form in the publication: “Data processing was carried out % using the “cSAXS matlab package” developed by the CXS group, % Paul Scherrer Institut, Switzerland.” % Variations on the latter text can be incorporated upon discussion with % the CXS group if needed to more specifically reflect the use of the package % for the published work. % % A publication that focuses on describing features, or parameters, that % are already existing in the code should be first discussed with the % authors. % % This code and subroutines are part of a continuous development, they % are provided “as they are” without guarantees or liability on part % of PSI or the authors. It is the user responsibility to ensure its % proper use and the correctness of the results.