..
   Athena document is copyright 2016 Bruce Ravel and released under
   The Creative Commons Attribution-ShareAlike License
   http://creativecommons.org/licenses/by-sa/3.0/

Plotting and basic data processing
==================================

Types of plots
--------------

Once you have imported data, you will want to start doing interesting
things with it. :quoted:`Interesting things` are, of course, the topic
of the rest of this programming guide. The first interesting thing to
discuss is plotting.

One might think that topics such as background removal, normalization,
and Fourier transforms are discussion-worthy.  In fact,
:demeter:`demeter` goes to great lengths to assure that you do not
need to ever worry about having to explicitly do any of those data
processing chores.  Certainly methods exist for doing those data
processing chores, but it should never be necessary to call them
explicitly.  (If you find a case where you need to do so, please
consider that as a bug and report it to Bruce.)

:demeter:`demeter` keeps track of the state of the Data object and
will re-perform data processing steps as necessary. For example, if
you change the value of one of the back-Fourier transform range
attributes, :demeter:`demeter` will know that the back-transform must
be recomputed the next time the |chi| (q) data is in some way
used. Similarly, if a background removal attribute is changed, then
:demeter:`demeter` will know that all steps of data processing must be
re-done.

:demeter:`demeter` is also aware of what data processing steps must be
up-to-date in order to properly perform any method, including
plotting. Thus if you do this:

.. code-block:: perl
      
   $data -> plot('R');

:demeter:`demeter` knows to check whether the background removal,
normalization, and forward transform are up to date and to perform
them if they are not.

Plotting in the four spaces is quite straightforward:

**plot in energy**
   .. code-block:: perl
      
       $data->plot('E');

**plot in k**
   .. code-block:: perl
      
       $data->plot('k');

**plot in R**
   .. code-block:: perl
      
       $data->plot('R');

**plot in back-transform k**
   .. code-block:: perl
      
       $data->plot('q');

There are also a number of pre-defined, specialty plots. 

.. todo:: Show biquad plot

**plot the magnitude and real part of chi(R)**
   .. code-block:: perl
      
       $data->plot('rmr');

   .. _fig-rmrplot:
   .. figure:: ../../_images/plot_r_rmr.png
      :target: ../_images/plot_r_rmr.png
      :align: left

      The :quoted:`rmr` plot displays a stack plot with the magnitude
      and real part of |chi| (R).

.. linebreak::

**plot chi(k) with k-weights of 1, 2, and 3, scaled to be the same size**
   .. code-block:: perl
      
       $data->plot('k123');

   .. _fig-k123plot:
   .. figure:: ../../_images/plot_k_k123.png
      :target: ../_images/plot_k_k123.png
      :align: left

      The :quoted:`k123` plot displays a stack plot with the |chi| (k)
      weighted by k\ :sup:`1`, k\ :sup:`2`, and k\ :sup:`3`.  The k\
      :sup:`1` and k\ :sup:`3` plots are scaled to be about the same
      size as the k\ :sup:`2` plot.

.. linebreak::

**plot chi(R) with k-weights of 1, 2, and 3, scaled to be the same size**
   .. code-block:: perl
      
       $data->plot('R123');

   .. _fig-r123plot:
   .. figure:: ../../_images/plot_r_r123.png
      :target: ../_images/plot_r_r123.png
      :align: left

      The :quoted:`r123` plot displays a stack plot with the |chi| (R)
      with the Fourier transforms made with k\ :sup:`1`, k\ :sup:`2`,
      and k\ :sup:`3` weighting.  The k\ :sup:`1` and k\ :sup:`3`
      plots are scaled to be about the same size as the k\ :sup:`2`
      plot.

.. linebreak::

**plot in chi(k) with the real part of chi(q)**
   .. code-block:: perl
      
       $data->plot('kq');

   .. _fig-kqplot:
   .. figure:: ../../_images/plot_kq.png
      :target: ../_images/plot_kq.png
      :align: left

      The :quoted:`k123` plot displays |chi| (k) and the real part of
      |chi| (q) overplotted.

.. linebreak::

**quad plot with data in all four spaces**
   .. code-block:: perl
      
       $data->plot('quad');


   .. _fig-quadplot:
   .. figure:: ../../_images/plot_quad.png
      :target: ../_images/plot_quad.png
      :align: left

      This quad plot shows data on an Fe foil in all four spaces. The
      current value of k-weighting in the Plot object is used in this
      kind of plot.  *This kind of plot cannot be made with the pgplot
      plotting backend.*


There are two more pre-packaged plot types which are specifically about
visualizing merged data and its standard deviation:

.. code-block:: perl

   $data->plot('stddev');
   $data->plot('variance'); 

See `the section on merged data <../mue/merge.html>`__ for details of
those two plot types.

Finally, it is plossible to plot |chi| (k) data in energy. This is done by
setting the ``chie`` attribute of the Plot object to a true value. When
that attribute is true and the data are plotted in k, the x-axis values
will instead be absolute energy.

.. code-block:: perl

    $data -> po -> set(kweight => 2, space => 'k', chie => 1);
    $data -> plot;

.. _fig-chieplot:
.. figure:: ../../_images/plot_chie.png
   :target: ../_images/plot_chie.png
   :align: center

   |chi| (k) plotted in energy.


.. note:: The argument of the ``plot`` method is case insensitive.
   Little attempt is made to glean meaning from that argument.  If it
   is not one of the strings shown above, the ``plot`` method will
   likely return an error.



Plotting and overplotting
-------------------------

The ``plot`` method typically will overplot data, that is add a new
trace to the existing plot. If you wish to start a new plot, you must
explicitly do so, as shown on line 8 of this example.

.. code-block:: perl
   :linenos:

    #!/usr/bin/perl
    use Demeter;

    my $prj = Demeter::Data::Prj -> new(file=>'iron_data.prj');
    my ($data1, $data2) = $prj -> records(1,2);
    $_ -> plot('k') foreach ($data1, $data2);
    sleep 3;
    $data1 -> po -> start_plot;
    $_ -> plot('R') foreach ($data1, $data2);

The quad plot is an exception, however. There is an implicit
``start_plot`` when a quad plot is made.

The details of the funny syntax using the ``po`` method is explained in
`the section on the Plot object <../highlevel/plot.html>`__.



The singlefile plotting backend
-------------------------------

Although the :program:`Gnuplot` and :program:`PGPLOT` plotting
backends work just fine, sometimes you would like to be able to
replicate a particular plot in another plotting program. To that end,
:demeter:`demeter` provides a special plotting backend called the
:quoted:`SingleFile` backend. This will replicate a plot form of a
column data file. The data in those columns include whatever
y-offsets, energy shifts, or scaling factors were included in the
plot. The plot can then be replicated in another program simply by
importing and plotting the columns.

Here is an example. The fit is the standard copper fit. At the end,
the data, the fit, the window, and the paths are plotted usin the
gnuplot backend. Then, at line 67, the :quoted:`SingleFile` backend is
used to output that plot to a file.

.. code-block:: perl
   :linenos:

    #!/usr/bin/perl
    use Demeter qw(:ui=screen);
    print "Sample fit to copper data demonstrating the singlefile plotting backend.\n";

    my $data = Demeter::Data -> new();
    $data->set_mode(screen  => 0, backend => 1);
    $data ->set(file       => "../../cu/cu10k.chi",
                fft_kmin   => 3,        fft_kmax   => 14,
                fit_space  => 'r',
                fit_k1     => 1,        fit_k3     => 1,
                bft_rmin   => 1.6,      bft_rmax   => 4.3,
                fit_do_bkg => 0,
                name       => 'My copper data',
               );

    my @gds =  (Demeter::GDS -> new(gds => 'guess', name => 'alpha', mathexp => 0),
                Demeter::GDS -> new(gds => 'guess', name => 'amp',   mathexp => 1),
                Demeter::GDS -> new(gds => 'guess', name => 'enot',  mathexp => 0),
                Demeter::GDS -> new(gds => 'guess', name => 'theta', mathexp => 500),
                Demeter::GDS -> new(gds => 'set',   name => 'temp',  mathexp => 300),
                Demeter::GDS -> new(gds => 'set',   name => 'sigmm', mathexp => 0.00052),
               );

    my $feff = Demeter::Feff->new(file=>'../../cu/orig.inp', screen=>0, workspace=>'temp/');
    $feff -> rmax(5);
    $feff -> run;
    my @sp = @{ $feff->pathlist };

    my @paths = ();
    foreach my $i (0 .. 4) {
      $paths[$i] = Demeter::Path -> new();
      $paths[$i]->set(data     => $data,
                      sp       => $sp[$i],
		      s02      => 'amp',
		      e0       => 'enot',
		      delr     => 'alpha*reff',
		      sigma2   => 'debye(temp, theta) + sigmm',
		     );
    };

    my $fit = Demeter::Fit -> new(gds   => \@gds,
                                  data  => [$data],
                                  paths => \@paths
                                 );

    $fit -> fit;

    ## plot normally using gnuplot
    $data->po->set(plot_data => 1, plot_fit  => 1,
                   plot_bkg  => 0, plot_res  => 0,
                   plot_win  => 1, plot_run  => 0,
                   kweight   => 2,
                   r_pl      => 'm', 'q_pl'    => 'r',
                  );
    $data->po->space('R');
    $data -> plot_with('gnuplot');
    my $step = 0;  # stack the plot interestingly...
    foreach my $obj ($data, @paths,) {
        $obj -> plot;
        $step -= 0.8;
        $data -> y_offset($step);
    };
    $data -> y_offset(0);
    $data -> pause;

    ## replicate that plot in a single file
    $data->plot_with('singlefile');           # 1: switch to single file backend
    $data -> po -> prep(file=>'nifty_plot.dat', standard=>$data, space=>'R');

    $step = 0;
    foreach my $obj ($data, @paths,) {        # 5: make the plot
        $obj -> plot;
        $step -= 0.8;
        $data -> y_offset($step);
    };
    $data -> y_offset(0);
    $data -> po -> finish;
    $data -> unset_standard;

Note that at line 68, some additional information is provided to make
the SingleFile output, including the name of the output file. A Data
object with data included in the file is set as the SingleFile standard.
The x-axis in the file will be the x-axis of that Data object. in the
case of a plot in energy, all other data will be interpolated onto that
energy grid.

The plot is then remade at lines 70-76. The ``finish`` method is called
at line 77 to actually write out the file. It is good practice to unset
the standard, as at line 78, to avoid future confusion.

The ``prep`` method at line 68 is a convenience method which does the
following:

.. code-block:: perl

   $data->po->space('R');
   $data->standard;
   $data->po->file('nifty_plot.dat');
   $data->po->start_plot;

Other odds and ends
-------------------

The ``plotkey`` atribute of the Data object is a convenient way to
override the label of a plotted object. Normally, the ``name`` attribute
is used for this purpose, but it is sometimes useful to not rename an
object but still provide a specific bit of text to use as a plotting
label.

