%% Solution to "Spectral Analysis of High Resolution X-ray Binary Data"
%%    Exercise by M. Nowak
%%    http://cxc.cfa.harvard.edu/xrayschool/analysis/mnowak_example_I.pdf
%%
%% ISIS script by L. Corrales
%% 2015.08.17 - lia@space.mit.edu

%%--------------------------------------------------------------------------------------------
%% BEFORE ANYTHING: Use TGcat (http://tgcat.mit.edu) to download gratings data for ObsId 5461

%%--------------------------------------------------------------------------------------------
%% 1. Load the TGcat data into ISIS

% We can load the MEG and HEG +/- 1 orders by specifying what rows of the PHA file to read in
%   Rows 3 and 4 are HEG -1 and +1; Rows 9 and 10 are MEG -1 and +1

variable HEG1 = load_data("pha2.gz", [3,4]);
variable MEG1 = load_data("pha2.gz", [9,10]);

% Show what we have loaded so far
% Note the "id" column, which shows the integer value used to identify each particular dataset

list_data;

% Notice that the arf and rmf were not automatically loaded.
% They will have to be read in separately and assigned to the proper data set

() = load_arf("heg_-1.arf.gz");
() = load_arf("heg_1.arf.gz");
() = load_arf("meg_-1.arf.gz");
() = load_arf("meg_1.arf.gz");

% Examine the loaded arfs
list_arf;

% Now assign them to the datasets - be sure that the ids match properly!
assign_arf([1:4], [HEG1, MEG1]);
list_data;

% Now do the same for the rmfs

() = load_rmf("heg_-1.rmf.gz");
() = load_rmf("heg_1.rmf.gz");
() = load_rmf("meg_-1.rmf.gz");
() = load_rmf("meg_1.rmf.gz");

list_rmf;
assign_rmf([1:4], [HEG1, MEG1]);
list_data;

%%--------------------------------------------------------------------------------------------
%% 2. Play with plotting the data
%%    Unfortunately, the default ISIS plotting tools are very limited.
%%    That's why we asked you to download the Remeis ISIS scripts
%%    http://www.sternwarte.uni-erlangen.de/isis/

() = evalfile("isisscripts.sl");

%% Here's how to do counts/bin with the default ISIS plot commands
plot_unit("Angstrom");
plot_bin_integral;
xrange(1.5,30);
plot_data_counts( MEG1[0], 2 );  % MEG -1 data (red)
oplot_data_counts( HEG1[0], 4 ); % HEG -1 data (blue)

%% Here's how to do it with the ISIS scripts
fancy_plot_unit("Angstrom");
plot_counts( MEG1[0]; dsym=0, dcol=2, decol=15 );
plot_counts( HEG1[0]; dsym=0, dcol=4, decol=15, oplt=1 );

%% Now for counts/bin/sec
plot_data( MEG1[0]; dsym=0, dcol=2, decol=15 );
plot_data( HEG1[0]; dsym=0, dcol=4, decol=15, oplt=1 );


%%--------------------------------------------------------------------------------------------
%% 3. Play with combining the data

%% **VERY IMPORTANT** -- First, the datasets need to be placed on the same spectral grid

match_dataset_grids( [MEG1, HEG1] );

%% This will improve the fit statistic, and will give correct values for overall reduced chi^2
%%    see:   help combine_datasets
variable cid = combine_datasets( [MEG1, HEG1] );

%% Now group the data so that the *combined* s/n is >=5 and at least two channels per bin
%%    see:   help group
group( [MEG1, HEG1]; min_sn=5, min_chan=2 );

%%--------------------------------------------------------------------------------------------
%% 4. Plot the flux corrected spectrum.  This first requires running fluxcorr

flux_corr( [MEG1, HEG1] );

%% The default ISIS way of plotting flux corrected spectrum
plot_bin_density; ylog;
plot_data_flux( MEG1[0], 2 );
oplot_data_flux( HEG1[0], 4 );
% (notice that the endpoints are background dominated)

%% Let's zoom in on 12-16 Angs spectrum, then plot using the Remeis ISIS scripts way
xrange(12, 16);
plot_unfold( MEG1[0]; dsym=0, dcol=2, decol=15 );
plot_unfold( HEG1[0]; dsym=0, dcol=4, decol=15, oplt=1 );

%% One great feature of the Remeis plotting tools -- you can plot the combined data
%%    by giving it a list of dataset ids
%%    (This is correct, only if the dataset grids have been matched)
plot_unfold( [MEG1, HEG1]; dsym=0, dcol=1, decol=15 );

%%--------------------------------------------------------------------------------------------
%% Fitting fun!  "You should notice an absorption edge in these data, as well as 
%%    several prominent absorption lines".  Let's fit them!
%%--------------------------------------------------------------------------------------------


%%--------------------------------------------------------------------------------------------
%% 5. Restrict the range of the noticed data and use a power law to
%%    fit the local continuum model

xnotice( [MEG1, HEG1], 13.5, 15 ); % Angs
list_data;

fit_fun("powerlaw(1)");
() = fit_counts;

variable pstyle = struct{ dsym=0, dcol=1, decol=15, mcol=2 };
xrange(13.5, 15);
plot_unfold( [MEG1, HEG1], pstyle; res=6 );
% See the plot_unfold help for information on plotting residual options
%    isis> plot_unfold;

%%--------------------------------------------------------------------------------------------
%% 6. Add an edge model to the data

fit_fun("powerlaw(1)*edge(1)");

% Let's check out what the parameters are
list_par;

% We need to give it a preliminary value for the edge position
%    From the plot, it looks like my edge is around 14.3 Angstroms
%    You can convert to keV using the Const_hc parameter
%
% I'm also going to set the min and max possible values to be within a reasonable range
%    see 'help set_par'
set_par("edge(1).edgeE", Const_hc/14.3, 0, Const_hc/14.5, Const_hc/13.8);

% Now fit it!
() = fit_counts;

% ... and plot
plot_unfold( [MEG1, HEG1], pstyle; res=6 );


%%--------------------------------------------------------------------------------------------
%% 7. Add Gaussian to fit the most prominent absorption feature

fit_fun("powerlaw(1)*edge(1) - gaussian(1)");
list_par;

set_par("gaussian(1).LineE", Const_hc/14.6, 0, Const_hc/14.7, Const_hc/14.55);

%% You can freeze parameters according to name
%    I like to freeze the original model before fitting the line
%    You can freeze all of the parameters for a given model using a *
freeze("powerlaw(1).*");
freeze("edge(1).*");
() = fit_counts;

% Then thaw and fit again to get best fit
thaw("powerlaw(1).*");
thaw("edge(1).*");
() = fit_counts;

plot_unfold( [MEG1, HEG1], pstyle; res=6 );

%%--------------------------------------------------------------------------------------------
%% 8. Incorporate the next three additional absorption lines

% I see three prominent lines at 14.3, 14.5, and 14.8
% The latter two are easier to get at, so do them first
fit_fun("powerlaw(1)*edge(1) - gaussian(1) - gaussian(2) - gaussian(3)");

% You can also freeze parameters by parameter id index
%    Use list_par and make note of the "idx" column
list_par;
freeze([1:7]);

% Make the suggest lines similarly thin to the first absorption feature
% The 14.5 Angs line:
set_par("gaussian(2).LineE", Const_hc/14.5, 0, Const_hc/14.55, Const_hc/14.45);
set_par("gaussian(2).Sigma", get_par("gaussian(1).Sigma"));

% The 14.8 Angs line:
set_par("gaussian(3).LineE", Const_hc/14.8, 0, Const_hc/14.90, Const_hc/14.70);
set_par("gaussian(3).Sigma", get_par("gaussian(1).Sigma"));

() = fit_counts;
plot_unfold( [MEG1, HEG1], pstyle; res=6 );

% Looks pretty good, so finally I need to incorporate the line that
% looks like it is part of the edge structure

fit_fun("powerlaw(1)*edge(1) - gaussian(1) - gaussian(2) - gaussian(3) - gaussian(4)");
list_par;

freeze([1:13]);

% For now, I'm going to freeze the line position at 14.3 Angs
set_par("gaussian(4).LineE", Const_hc/14.3, 1, Const_hc/14.33, Const_hc/14.27);
set_par("gaussian(4).Sigma", get_par("gaussian(1).Sigma"));

() = fit_counts;
thaw("gaussian(4).LineE");
() = fit_counts;

plot_unfold( [MEG1, HEG1], pstyle; res=6 );
% Looks pretty good!

% Thaw everything to get final fit
thaw([1:16]);
() = fit_counts;

% Here I've changed the residual plot to just show me chi values
plot_unfold( [MEG1, HEG1], pstyle; res=4 );

%%--------------------------------------------------------------------------------------------
%% 9. Get error bars

% See 'help conf' and 'help conf_loop'

% Get 1-sigma CI (level = 0 means 68% C.I.) on line widths
variable smin, smax;
(smin,smax) = conf_loop("gaussian(*).Sigma", 0, 0);


