% Script to compute the Relative Intensity Noise of a laser by recording the y-t signal
% by Mathias Neidig in 2012
% modified for DyLab use by Karthik in 2024

% The RIN is defined as 
%
%   RIN = 10* log10 [Single-sided power spectrum density / (average power)]
%
% and is given in [RIN] = dB/Hz

clear all
close all

%% Set the directory where the data is

dirDCData = 'C:\\Users\\Karthik\\Documents\\GitRepositories\\Calculations\\Time-Series-Analyzer\\Time-Series-Data\\20240915\\DC_Coupling\\';
dirACData = 'C:\\Users\\Karthik\\Documents\\GitRepositories\\Calculations\\Time-Series-Analyzer\\Time-Series-Data\\20240915\\AC_Coupling\\';

%% Load the files which contain: - the DC coupled y-t signal to obtain the averaged power
%                                 - the AC coupled y-t signal to obtain the fluctuations
%                                 - the AC coupled y-t signal with the beam blocked to obtain the background fluctuations

%--------------------------------------------------------------------------------------------------%
dcsignal   = load( [ dirDCData 'IPG1064_100W'] );                                                  %
acsignal   = load( [ dirACData 'IPG1064_100W'] );                                                  %
bgsignal   = load( [ dirACData 'Background'] );                                                    %
picosignal = load( [ dirACData 'Picoscope_Background'] );                                          %
label_0    = 'Picoscope noise floor';                                                              % 
label_1    = 'Background (Picoscope + InGaAs PIN PD + Transimp amp + Buffer amp + power supply)';  %
label_2    = 'Laser output power=100 W (Incident on PD=1mW)';                                      % 
label_3    = 'Shot-Noise limit @ 1 mW incident power';                                             % 
%------------------------------------------------------------------------------------------------- %

%% Read out the important parameters

dcdata         = dcsignal.A;
acdata         = acsignal.A;
bgdata         = bgsignal.A;
picodata       = picosignal.A;

N       = length(dcdata);               % #samples
f_s     = 1/dcsignal.Tinterval;         % Sample Frequency
delta_f = f_s/N;                        % step size in frequency domain
delta_t = 1/f_s;                        % time step

%% Custom Control Parameters

% Choose smoothing parameter; has to be odd
%----------------%  
    span = 21;   %  
%----------------%

%% Computes the RIN

% compute the average power (voltage^2)
average_P = mean(dcdata.*dcdata);  

% compute the power spectrum density FFT(A) x FFT*(A)/N^2 of the source & the bg
psd_src   = fft(acdata) .* conj(fft(acdata))/N^2;
psd_bg    = fft(bgdata) .* conj(fft(bgdata))/N^2;
psd_pico  = fft(picodata) .* conj(fft(picodata))/N^2;

% converts the psd to the single-sided psd --> psd is symmetric around zero --> omit
% negative frequencies and put the power into the positive ones --> spsd

for i = 1 : N/2+1
    if i>1
         spsd_src(i)   = 2*psd_src(i);
         spsd_bg(i)    = 2*psd_bg(i);
         spsd_pico(i)  = 2*psd_pico(i);
    else 
         spsd_src(i)   = psd_src(i);
         spsd_bg(i)    = psd_bg(i);
         spsd_pico(i)  = psd_pico(i);
    end
end

% smooths the spsd by doing a moving average
spsd_src_smooth   = smooth(spsd_src,span,'moving');
spsd_bg_smooth    = smooth(spsd_bg, span,'moving');
spsd_pico_smooth  = smooth(spsd_pico, span,'moving');

% calculates the RIN given in dB/Hz; the factor delta_f is needed to convert from dB/bin into dB/Hz
RIN_src_smooth    = 10*log10(spsd_src_smooth/(average_P*delta_f));
RIN_bg_smooth     = 10*log10(spsd_bg_smooth /(average_P*delta_f));
RIN_pico_smooth   = 10*log10(spsd_pico_smooth /(average_P*delta_f));

% creates an array for the frequencies up to half the sampling frequency
f        = f_s/2 * linspace(0,1,N/2+1);
f_smooth = smooth(f,span,'moving');
%
% Calculates the shot noise limit of the used PD given the wavelength of the light source and
% incident average power
PlanckConstant         = 6.62607015E-34;
SpeedOfLight           = 299792458;
WavelengthOfLaserLight = 1064E-9;
FrequencyOfLaserLight  = SpeedOfLight / WavelengthOfLaserLight;
QuantumEfficiencyOfPD  = 1;
AverageIncidentPower   = 0.001; % (in W)
ShotNoiseLimit         = 10*log10((2 * PlanckConstant * FrequencyOfLaserLight) / (QuantumEfficiencyOfPD * AverageIncidentPower));

%% Plots the RIN

% Plots the RIN vs frequency
f_ = clf;
figure(f_);
semilogx(f_smooth, RIN_pico_smooth, LineStyle = "-", Color = [.7 .7 .7])
hold on
semilogx(f_smooth, RIN_bg_smooth, LineStyle = "-", Color = [.0 .0 .0])
semilogx(f_smooth,RIN_src_smooth,'r-')
yline(ShotNoiseLimit,'--b');
ax = gca(f_); 
ax.XAxis.FontSize = 14;
ax.YAxis.FontSize = 14;
xlabel('Frequency [Hz]', FontSize=16)
ylabel('RIN [dBc/Hz]', FontSize=16)
xlim([10 5E6]);
ylim([-175 -55]);
title('\bf Relative Intensity Noise of IPG 1064', FontSize=16)
legend(label_0, label_1, label_2, label_3, 'Location','NorthEast', FontSize=16);
% text(1e5,-95,['\bf MovingAverage = ' num2str(span) ]);
grid on

% optional: save the picture without editing wherever you want
%------------------------------------------%     
%     saveas(f_,'FileName','png');         %
%------------------------------------------%