%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function: 
%
% [absorbed_photons]=dose_calc(ptycho_recon, ptycho_data, param)
%
% Description:
%
% The function (1) takes one reconstruction and its data and estimate the
% dose (2) saves the dose estimation into a .txt file.
%
% Input: 
%
% ptycho_recon: reconstruction, including object, probe, and p
% ptycho_data: data for the reconstruction
% param_dose.mu = 1/(451*1e-6);     % 1/attenuation_length   in 1/m   (for CH2 @6.2keV)
%                                   % 1/(152.7*1e-6) for zeolite Na2Al2Si3O102H4O with 2 g/cm3 density at 6.2 keV
% param_dose.rho = 1000;            % Density in kg/m^3
% param_dose.setup_transmission = 0.55; % Intensity transmission of sample 
%                                       % (e.g. air path after the sample, windows, He, detector efficiency)
%                                       % 0.943 for 700 cm He gas at 760 Torr and 295 K @ 6.2 keV
%                                       % 0.780 for 10 cm air at 760 Torr and 295 K @ 6.2 keV
%                                       % 0.976 for 13 micron Kapton (polymide) with 1.43
%                                       % g/cm3 @ 6.2 keV
%                                       % 0.841 for 7 micron muskovite mica
%                                       % (KAl3Si3O11.8H1.8F0.2) with 2.76 g/cm3 @ 6.2 keV
%                                       % 0.914 for 5 cm of air at 6.2 keV 750 Torr 295 K
%                                       % 0.55 for 300 micron of mylar C10H8O4 with density 1.38 g/cm3 at 6.2 keV
% param_dose.overhead = 0.0;    % Extra dose during movement overhead, only applicable 
%                               % if shutter is not closed between exposures
% param_dose.fmask
% param_dose.scan_number 
% param_dose.num_proj 
% param_dose.output_folder (default: ./)
%
% Output:
%
% absorbed_photons: number of photons absorbed by the sample  
% one jpg for one_data_frame
% one jpg for photons_per_shot_all
% one jpg for photons_per_obj_pix
% one jpg for transmitted_photons_per_obj_pix
% one txt for dose_estimate
%
% 2017-03-30
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%*-----------------------------------------------------------------------*
%|                                                                       |
%|  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 software 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.

function [absorbed_photons]=dose_calc(ptycho_recon, ptycho_data, param)
import utils.* 


%Estimating detected photons
probe = ptycho_recon.probe;
object = ptycho_recon.object;
p = ptycho_recon.p;
data = ptycho_data.data;
fmask = ptycho_data.fmask; 

if isfield(param,'mu') && isfield(param,'rho') && isfield(param,'setup_transmission') && isfield(param,'overhead') 
    mu = param.mu;
    rho = param.rho;
    setup_transmission = param.setup_transmission;
    overhead = param.overhead;
else
    error('Please specify param.mu, param.rho, param.setup_transmission, and param.overhead.\n');
end 

if isfield(param,'num_proj')
    num_proj = param.num_proj;
else
    verbose(0,'Using num_proj = 1');
    num_proj = 1;
end 

if isfield(param,'scan_number')
    scan_number = param.scan_number;
else
    scan_number = [];
end 

if isfield(param,'output_folder')
    output_folder = param.output_folder;
else
    verbose(0,'Using output_folder = ./');
    output_folder = '.';
end 

data = data .* fmask; 
photons_per_shot_all = sum(sum(data)); 
photons_per_shot = max(photons_per_shot_all);  

%Normalizing probe to photons per shot
probe_norm0 = sum(abs(probe).^2,3); 

probe_norm1 = probe_norm0/sum(probe_norm0(:));
probe_norm = probe_norm1*photons_per_shot;

% probe_norm_all=data*0.0;
% for jj=1:size(data,3)
%     probe_norm_all(:,:,jj)=probe_norm*photons_per_shot_all(jj);
% end
%
asize = size(probe);
%objaux = object*0;
illum_sum = zeros(size(object,1)+10,size(object,2)+10);
absorption_sum = illum_sum;

scanfirstindex = [1 cumsum(p.numpts)+1]; % First index for scan number
for ii = 1:p.numscans
    p.scanindexrange(ii,:) = [scanfirstindex(ii) scanfirstindex(ii+1)-1];
    p.scanidxs{ii} = p.scanindexrange(ii,1):p.scanindexrange(ii,end); 
end

for ii = p.scanidxs{1}
    Indy = round(p.positions(ii,1)) + [1:asize(1)];
    Indx = round(p.positions(ii,2)) + [1:asize(2)];
    illum_sum(Indy,Indx) = illum_sum(Indy,Indx)+probe_norm;
    absorption_sum(Indy,Indx) = absorption_sum(Indy,Indx)+probe_norm1*photons_per_shot_all(ii);
end

illum_sum = illum_sum(asize(1)/2:end-asize(1)/2,asize(2)/2:end-asize(2)/2);
absorption_sum = absorption_sum(asize(1)/2:end-asize(1)/2,asize(2)/2:end-asize(2)/2);

% in case of laminography the field of view isnot rectangular ->
% exclude the empty regions in the illumination function 
illum_mask = illum_sum > mean(illum_sum) * 0.1; 
absorption_mask = absorption_sum > mean(absorption_sum) * 0.1;

flux_in_area = sum(sum(illum_sum .* illum_mask)); %photons
flux_after_sample= sum(sum(absorption_sum .* absorption_mask)); %photons
absorbed_photons=flux_in_area-flux_after_sample;
area = sum(illum_mask(:))*p.dx_spec(1)^2;  % meters^2

I = flux_in_area/area;  %ph/meters^2
hv = 9.9334947e-16*(p.energy/6.2);      %6.2keV in joules

absorbed_photons=absorbed_photons*num_proj;
D = mu*I*hv*num_proj/rho;
D_with_gas = D/setup_transmission;
D_with_overhead = D_with_gas*(1+overhead);
verbose(0,'**********************************************')
verbose(0,'Dose report for %d projections, Scan %d',num_proj, scan_number)
verbose(0,'**********************************************')
verbose(0,'Measured photons per frame = %.2e photons',photons_per_shot);
verbose(0,'N_0 used for imaging for one projection = %.2e photons/micron^2',I*1e-12);
verbose(0,'Dose used for imaging, D = %.2e Gy',D)
verbose(0,'Accounting for experiment transmission, D = %.2e Gy',D_with_gas)
verbose(0,'Accounting for experiment transmission and overhead, D = %.2e Gy',D_with_overhead)
verbose(0,'Absorbed photons = %.2e photons',absorbed_photons)

%=======================
figure(1); clf
plotting.imagesc3D(log10(1+data));
caxis([0,log10(max(data(:)))])
colormap(plotting.colormaps.franzmap); colorbar
axis xy equal tight
title('Data frames, log10')
filename = fullfile(output_folder,sprintf('/%s_one_data_frame.jpg',p.run_name));
verbose(1,'saving %s',filename);
print('-djpeg','-r300',filename);

figure(2); clf
plot(squeeze(photons_per_shot_all)); grid on;
title(['Number of measured photons per frame = ' num2str(photons_per_shot)]); 
filename = fullfile(output_folder,sprintf('/%s_photons_per_shot_all.jpg',p.run_name));
verbose(1,'saving %s',filename);
print('-djpeg','-r300',filename);

figure(3); clf
imagesc(illum_sum)
colormap(plotting.colormaps.franzmap); colorbar
axis image xy 
title('Photons per pixel of the object')
filename = fullfile(output_folder,sprintf('/%s_photons_per_obj_pix.jpg',p.run_name));
verbose(1,'saving %s',filename);
print('-djpeg','-r300',filename);

figure(4); clf
imagesc(absorption_sum)
colormap(plotting.colormaps.franzmap); colorbar
axis image xy 
title('Transmitted photons per pixel of the object')
filename = fullfile(output_folder,sprintf('/%s_transmitted_photons_per_obj_pix.jpg',p.run_name));
verbose(1,'saving %s',filename);
print('-djpeg','-r300',filename);

%=======================
filename = fullfile(output_folder,sprintf('/%s_dose_estimate_S%05d.txt',p.run_name, scan_number));
fid = fopen(filename,'w');
fprintf(fid,'Scan = %d\n',scan_number);
fprintf(fid,'Measured photons per frame = %.3e\n',photons_per_shot);
fprintf(fid,'N_0 used for imaging for one projection (I*1e-12) = %.3e photons/micron^2\n',I*1e-12);
fprintf(fid,'num_proj = %d\n',num_proj);
fprintf(fid,'hv = %.5e\n\n',hv);
fprintf(fid,'D = mu*I*hv*num_proj/rho \n');
fprintf(fid,'D_with_gas = D/setup_transmission \n');
fprintf(fid,'D_with_overhead = D_with_gas*(1+overhead) \n\n');
fprintf(fid,'If mu = %.3e m^-1, rho = %.3e kg/m^3, setup_transmission = %.3f, then:\n', mu, rho, setup_transmission);
fprintf(fid,'Accounting for experiment transmission, D_with_gas = %.3e Gy = %.3f MGy\n\n', D_with_gas, D_with_gas/1e6);
fprintf(fid,'asize = %d, pixel size = %.4f nm\n', asize(1), p.dx_spec(1)*1e9);
fclose(fid);
