% Reduced spectral density mapping.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{Reduced spectral density mapping} \label{ch: J(w) mapping}
\index{reduced spectral density mapping|textbf}

% Introduction.
%%%%%%%%%%%%%%%

\section{Introduction to reduced spectral density mapping}

The reduced spectral density mapping analysis is often performed when the system under study is not suitable for model-free analysis, or as a last resort if a model-free analysis fails.
The aim is to convert the relaxation data into three $J(\omega)$ values for the given field strength.
Interpretation of this data, although slightly less convoluted than the relaxation data, is still plagued by problems related to non-spherical diffusion and much care must be taken when making conclusions.
A full understanding of the model-free analysis and the effect of diffusion tensor anisotropy and rhombicity allows for better interpretation of the raw numbers.

To understand how reduced spectral density mapping is implemented in relax, the sample script will be worked through.
This analysis type is not implemented in the GUI yet, though it shouldn't be too hard if anyone would like to contribute this and have a reference added to Chapter~\ref{ch: citations}, the citations chapter.


% The sample script.
%%%%%%%%%%%%%%%%%%%%

\section{J(w) mapping script mode -- the sample script}

\begin{lstlisting}
"""Script for reduced spectral density mapping."""


# Create the data pipe.
pipe.create(pipe_name='my_protein', pipe_type='jw')

# Set up the 15N spins.
sequence.read(file='noe.600.out', res_num_col=1, res_name_col=2)
spin.name(name='N')
spin.element(element='N')
spin.isotope(isotope='15N', spin_id='@N')

# Load the 15N relaxation data.
relax_data.read(ri_id='R1_600',  ri_type='R1',  frq=600.0*1e6, file='r1.600.out', res_num_col=1, data_col=3, error_col=4)
relax_data.read(ri_id='R2_600',  ri_type='R2',  frq=600.0*1e6, file='r2.600.out', res_num_col=1, data_col=3, error_col=4)
relax_data.read(ri_id='NOE_600', ri_type='NOE', frq=600.0*1e6, file='noe.600.out', res_num_col=1, data_col=3, error_col=4)

# Generate 1H spins for the magnetic dipole-dipole relaxation interaction.
sequence.attach_protons()

# Define the magnetic dipole-dipole relaxation interaction.
interatom.define(spin_id1='@N', spin_id2='@H', direct_bond=True)
interatom.set_dist(spin_id1='@N', spin_id2='@H', ave_dist=1.02 * 1e-10)

# Define the chemical shift relaxation interaction.
value.set(val=-172 * 1e-6, param='csa')

# Select the frequency.
jw_mapping.set_frq(frq=600.0 * 1e6)

# Reduced spectral density mapping.
minimise.calculate()

# Monte Carlo simulations (well, bootstrapping as this is a calculation and not a fit!).
monte_carlo.setup(number=500)
monte_carlo.create_data()
minimise.calculate()
monte_carlo.error_analysis()

# Create grace files.
grace.write(y_data_type='j0', file='j0.agr', force=True)
grace.write(y_data_type='jwx', file='jwx.agr', force=True)
grace.write(y_data_type='jwh', file='jwh.agr', force=True)

# View the grace files.
grace.view(file='j0.agr')
grace.view(file='jwx.agr')
grace.view(file='jwh.agr')

# Write out the values.
value.write(param='j0', file='j0.txt', force=True)
value.write(param='jwx', file='jwx.txt', force=True)
value.write(param='jwh', file='jwh.txt', force=True)

# Finish.
results.write(file='results', force=True)
state.save('save', force=True)
\end{lstlisting}



% Data pipe and spin system setup.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{J(w) mapping script mode -- data pipe and spin system setup}

The steps for setting up relax and the data model concept are described in full detail in Chapter~\ref{ch: data model}.
The first step, as for all analyses in relax, is to create a data pipe for storing all the data:

\begin{lstlisting}[firstnumber=4]
# Create the data pipe.
pipe.create(pipe_name='my_protein', pipe_type='jw')
\end{lstlisting}

Then, in this example, the $^{15}$N spins are created from one of the NOE relaxation data files (Chapter~\ref{ch: NOE}):

\begin{lstlisting}[firstnumber=7]
# Set up the 15N spins.
sequence.read(file='noe.600.out', res_num_col=1, res_name_col=2)
spin.name(name='N')
spin.element(element='N')
spin.isotope(isotope='15N', spin_id='@N')
\end{lstlisting}

Skipping the relaxation data loading, the next part of the analysis is to create protons attached to the nitrogens for the magnetic dipole-dipole relaxation interaction:

\begin{lstlisting}[firstnumber=18]
# Generate 1H spins for the magnetic dipole-dipole relaxation interaction.
sequence.attach_protons()
\end{lstlisting}

This is needed to define the magnetic dipole-dipole interaction which governs relaxation.



% Relaxation data loading.
%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{J(w) mapping script mode -- relaxation data loading}

The loading of relaxation data is straight forward.
This is performed prior to the creation of the proton spins so that the data is loaded only into the $^{15}$N spin containers and not both spins for each residue.
Only data for a single field strength can be loaded:

\begin{lstlisting}[firstnumber=13]
# Load the 15N relaxation data.
relax_data.read(ri_id='R1_600',  ri_type='R1',  frq=600.0*1e6, file='r1.600.out', res_num_col=1, data_col=3, error_col=4)
relax_data.read(ri_id='R2_600',  ri_type='R2',  frq=600.0*1e6, file='r2.600.out', res_num_col=1, data_col=3, error_col=4)
relax_data.read(ri_id='NOE_600', ri_type='NOE', frq=600.0*1e6, file='noe.600.out', res_num_col=1, data_col=3, error_col=4)
\end{lstlisting}

The frequency of the data must also be explicitly specified:

\begin{lstlisting}[firstnumber=28]
# Select the frequency.
jw_mapping.set_frq(frq=600.0 * 1e6)
\end{lstlisting}



% Relaxation interactions.
%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{J(w) mapping script mode -- relaxation interactions}

Prior to calculating the $J(\omega)$ values, the physical interactions which govern relaxation of the spins must be defined.
For the magnetic dipole-dipole relaxation interaction, the user functions are:

\begin{lstlisting}[firstnumber=21]
# Define the magnetic dipole-dipole relaxation interaction.
interatom.define(spin_id1='@N', spin_id2='@H', direct_bond=True)
interatom.set_dist(spin_id1='@N', spin_id2='@H', ave_dist=1.02 * 1e-10)
\end{lstlisting}

For the chemical shift relaxation interaction, the user function call is:

\begin{lstlisting}[firstnumber=25]
# Define the chemical shift relaxation interaction.
value.set(val=-172 * 1e-6, param='csa')
\end{lstlisting}



% Calculation and error propagation.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{J(w) mapping script mode -- calculation and error propagation}

Optimisation for this analysis is not needed as this is a direct calculation.
Therefore the $J(\omega)$ values are simply calculated with the call:

\begin{lstlisting}[firstnumber=31]
# Reduced spectral density mapping.
minimise.calculate()
\end{lstlisting}

The propagation of errors is more complicated.
The Monte Carlo simulation framework of relax can be used to propagate the relaxation data errors to the spectral density errors.
As this is a direct calculation, this collapses into the standard bootstrapping method.
The normal Monte Carlo user functions can be called:

\begin{lstlisting}[firstnumber=34]
# Monte Carlo simulations (well, bootstrapping as this is a calculation and not a fit!).
monte_carlo.setup(number=500)
monte_carlo.create_data()
minimise.calculate()
monte_carlo.error_analysis()
\end{lstlisting}

In this case, the \uf{monte\ufus{}carlo\ufsep{}initial\ufus{}values} user function call is not required.


% Visualisation and data output.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{J(w) mapping script mode -- visualisation and data output}

The rest of the script is used to output the results to 2D Grace files for visualisation (the \uf{grace\ufsep{}view} user function calls will launch Grace with the created files), and the output of the values into plain text files.
