.. _analyzing-an-entire-simulation:

Analyzing an Entire Simulation
==============================
.. sectionauthor:: Britton Smith <britton.smith@colorado.edu>

The EnzoSimulation class provides a simple framework for performing the same 
analysis on multiple datasets in a single simulation.  At its most basic, an 
EnzoSimulation object gives you access to a time-ordered list of datasets over 
the time or redshift interval of your choosing.  It also includes more 
sophisticated machinery for stitching together cosmological datasets to create 
a continuous volume spanning a given redshift interval.  This is the engine that 
powers the light cone generator (see :ref:`light-cone-generator`).  See 
:ref:`cookbook-simulation_halo_profiler` for an example of using the EnzoSimulation 
class to run the HaloProfiler on multiple datasets within a simulation.

EnzoSimulation Options
----------------------

The only argument required to instantiate an EnzoSimulation is the path to the 
parameter file used to run the simulation:

.. code-block:: python

  import yt.extensions.EnzoSimulation as ES
  es = ES.EnzoSimulation("my_simulation.par")

The EnzoSimulation object will then read through the simulation parameter file 
to figure out what datasets are available and where they are located.  Comment 
characters are respected, so commented-out lines will be ignored.  If no time 
and/or redshift interval is specified using the keyword arguments listed below, 
the EnzoSimulation object will create a time-ordered list of all datasets.

.. note:: For cosmological simulations, the interval of interest can be
   specified with a combination of time and redshift keywords.

The additional keyword options are:

 * **initial_time** (*float*): the initial time in code units for the
   dataset list.  Default: None.

 * **final_time** (*float*): the final time in code units for the dataset
   list.  Default: None.

 * **initial_redshift** (*float*): the initial (highest) redshift for the
   dataset list.  Only for cosmological simulations.  Default: None.

 * **final_redshift** (*float*): the final (lowest) redshift for the dataset
   list.  Only for cosmological simulations.  Default: None.

 * **links** (*bool*): if True, each entry in the dataset list will
   contain entries, *previous* and *next*, that point to the previous and next
   entries on the dataset list.  Default: False.

 * **enzo_parameters** (*dict*): a dictionary specify additional
   parameters to be retrieved from the parameter file.  The format should be the
   name of the parameter as the key and the variable type as the value.  For
   example, {'CosmologyComovingBoxSize':float}.  All parameter values will be
   stored in the dictionary attribute, *enzoParameters*.  Default: None.

 * **get_time_outputs** (*bool*): if False, the time datasets, specified
   in Enzo with the *dtDataDump*, will not be added to the dataset list.  Default:
   True.

 * **get_redshift_outputs** (*bool*): if False, the redshift datasets will
   not be added to the dataset list.  Default: True.

.. warning:: The EnzoSimulation object will use the *GlobalDir* Enzo parameter
   to determine the absolute path to the data, so make sure this is set correctly
   if the data has been moved.  If this parameter is not present in the parameter
   file, the code will look for the data in the current directory.

The Dataset List
----------------

The primary attribute of an EnzoSimulation object is the dataset list, 
*allOutputs*.  Each list item is a dictionary, containing the time, redshift 
(if cosmological), and filename of the dataset.

.. code-block:: python

  >>> es.allOutputs[0]
  {'filename': '/Users/britton/EnzoRuns/cool_core_unreasonable/RD0000/RD0000',
   'time': 0.81631644849936602, 'redshift': 99.0}

Now, analyzing each dataset is easy:

.. code-block:: python

  for output in es.allOutputs:
      # load up a dataset
      pf = load(output['filename'])
      # do something!

Cosmology Splices
-----------------

For cosmological simulations, the physical width of the simulation box 
corresponds to some :math:`\Delta z`, which varies with redshift.  Using this 
logic, one can stitch together a series of datasets to create a continuous 
volume or length element from one redshift to another.  The 
:meth:`create_cosmology_splice` method will return such a list:

.. code-block:: python

  cosmo = es.create_cosmology_splice(minimal=True, deltaz_min=0.0, initial_redshift=1.0, final_redshift=0.0)

The returned list is of the same format as the *allOutputs* attribute.  The 
keyword arguments are:

 * **minimal** (*bool*): if True, the minimum number of datasets is used
   to connect the initial and final redshift.  If false, the list will contain as
   many entries as possible within the redshift interval.  Default: True.

 * **deltaz_min** (*float*): specifies the minimum :math:`\Delta z` between
   consecutive datasets in the returned list.  Default: 0.0.

 * **initial_redshift** (*float*): the initial (highest) redshift in the
   cosmology splice list.  If none given, the highest redshift dataset present
   will be used.  Default: None.

 * **final_redshift** (*float*): the final (lowest) redshift in the
   cosmology splice list.  If none given, the lowest redshift dataset present will
   be used.  Default: None.

The most well known application of this function is the
:ref:`light-cone-generator`.

Planning a Cosmological Simulation
----------------------------------

If you want to run a cosmological simulation that will have just enough data outputs 
to create a cosmology splice, the :meth:`imagine_minimal_splice` method will calculate 
a list of redshifts outputs that will minimally connect a redshift interval.

.. code-block:: python

  initial_redshift = 0.4
  final_redshift = 0.0 
  outputs = es.imagine_minimal_splice(initial_redshift, final_redshift, filename='outputs.out')

This function will return a list of dictionaries with "redshift" and "deltazMax" 
entries.  The keyword arguments are:

 * **decimals** (*int*): The decimal place to which the output redshift will be rounded.  If the decimal place in question is nonzero, the redshift will be rounded up to ensure continuity of the splice.  Default: 3.

 * **filename** (*str*): If provided, a file will be written with the redshift outputs in the form in which they should be given in the enzo parameter file.  Default: None.

 * **redshift_output_string** (*str*): The parameter accompanying the redshift outputs in the enzo parameter file.  Default: "CosmologyOutputRedshift".

 * **start_index** (*int*): The index of the first redshift output.  Default: 0.
