/*!
  Performs the part of the error propagation that does not depend on
 the parameters being fit by incorporating the intrinsic dispersion
 and redshift errors with the magnitude errors.  Thus, we don't need
 to keep recalculating these.  If we are doing a fit where \f$\alpha\f$
 and \f$\beta\f$ have been completely pre-calculated, then we
 go even further and calculate the full errors for each SN.

 Also, if the nuisance parameters are fixed, and we have a covariance
 matrix we can pre-invert it for later use.

 Note that we are ignoring the fact that the redshift errors converted
 into magnitude space actually depend on the cosmology.  This is a
 very good approximation as long as you have spectroscopic redshifts
 for your SN.  Someday, when people are using photo-zs, this will have
 to be changed.

 If we have fixed values of \f$\alpha\f$ and \f$\beta\f$ at this point
 we will incorporate those parts of the errors.  Note that if you
 have only one fixed, there is a cross term that has to be evaluated
 later.
*/


/*!
  Updates the inverse covariance matrix and fills in the row
  sums and analytic marginalization parameters.

  \param[in] alpha \f$\alpha\f$
  \param[in] beta \f$\beta\f$

  If the requisite \f$\alpha, \beta\f$ covariance matrix
  isn't available, alpha and/or beta are ignored.
*/


/*!
  Driver for 0D cosmological fits -- i.e., only the nuisance
  parameters are fit.  It is assumed that the user specifies
  at least \f$\Omega_m\f$ and a flat fit.

  \param[out] results_map  Results of fit are added to this structure
  \param[out] maxlikelihood Maximum likelihood of fit
  \param[out] fittag String description of type of fit performed
*/


/*!
  Driver for 1D cosmological fits.  Currently this only supports
  fixed curvature \f$\Omega_m\f$ fits.

  \param[out] results_map  Results of fit are added to this structure
  \param[out] maxlikelihood Maximum likelihood of fit
  \param[out] fittag String description of type of fit performed
*/


/*!
  Driver for 2D cosmological fits.  Currently this only supports
  \f$\Omega_m, \Omega_{DE}\f$ and fixed curvature \f$\Omega_m, w_0\f$ fits.

  \param[out] results_map  Results of fit are added to this structure
  \param[out] maxlikelihood Maximum likelihood of fit
  \param[out] fittag String description of type of fit performed
*/


/*!
  Driver for 3D cosmological fits.  Currently this only supports
  \f$\Omega_m, \Omega_{DE}, w_0\f$ and
  fixed curvature \f$\Omega_m, w_0, w_a\f$ fits.

  \param[out] results_map  Results of fit are added to this structure
  \param[out] maxlikelihood Maximum likelihood of fit
  \param[out] fittag String description of type of fit performed
*/


/*!
  Handles 0D cosmological fit in case where the errors are diagonal

  \param[out] results_map  A map that will be filled with the
                   results of the fit
  \param[out] maxlikelihood The maximum likelihood

  As a side effect, this may write out a cosgrid as
  a file containing the probability surface of the nuisance parameters.
*/


/*!
  Handles 0D cosmological fit (i.e., cosmo parameters fixed)
  with non-diagonal errors

  \param[out] results_map  A map that will be filled with the
                   results of the fit
  \param[out] maxlikelihood The maximum likelihood

  As a side effect, this will write out a cosgrid as
  a file containing the probability surface.
*/


/*!
  Handles 1D cosmological fit in case where the outer loop is
  the cosmological parameters (i.e., when the luminosity distance
  is the most expensive thing to calcluate).

  \param[in] cosmo_fit Type of fit to perform
  \param[out] results_map  A map that will be filled with the
                   results of the fit
  \param[out] maxlikelihood The maximum likelihood

  As a side effect, this will write out a cosgrid as
  a file containing the probability surface.
*/


//This one is relatively simple because the only fit we support
// for one-D is fixed curvature, omega_m


/*!
  Handles 2D cosmological fit in case where the outer loop is
  the cosmological parameters (i.e., when the luminosity distance
  is the most expensive thing to calcluate).  Only two types of
  fits are currently supported: omega_m/omega_de and flat omega_m/ w0

  \param[in] cosmo_fit  The type of fit to do
  \param[out] results_map  A map that will be filled with the
                   results of the fit
  \param[out] maxlikelihood The maximum likelihood

  As a side effect, this will write out a cosgrid as
  a file containing the probability surface.
*/


/*!
  Handles 2D cosmological fit in case where the inner loop is
  the cosmoogical parameters (i.e., when the covariance matrix
  inversion is the most expensive thing to calcluate).  Only two types of
  fits are currently supported: omega_m/omega_de and flat omega_m/ w0

  \param[in] cosmo_fit  The type of fit to do
  \param[out] results_map  A map that will be filled with the
                   results of the fit
  \param[out] maxlikelihood The maximum likelihood

  As a side effect, this will write out a cosgrid as
  a file containing the probability surface.
*/


/*!
  Handles 3D cosmological fit in case where the outer loop is
  the cosmoogical parameters (i.e., when the luminosity distance
  is the most expensive thing to calcluate).  Only two types of
  fits are currently supported: omega_m/omega_de/w_0 and
  flat omega_m/w_0/w_a

  \param[in] cosmo_fit  The type of fit to do
  \param[out] results_map  A map that will be filled with the
                   results of the fit
  \param[out] maxlikelihood The maximum likelihood

  As a side effect, this will write out a cosgrid as
  a file containing the probability surface.
*/


/*! Assuming that the luminosity distance has already been
  calculated, loops over the values of alpha and beta in
  the input array and fills it in with the relative probability.
  This version assumes the errors are diagonal.

  \param[out] likelihoodtarg On output, has the probabilities.  On input,
      the axis must be initialized with alpha and beta.
*/


/*! Assuming that the luminosity distance has already been
  calculated, loops over the values of alpha in
  the input array and fills it in with the relative probability.
  This version assumes the errors are diagonal.

  \param[out] likelihoodtarg On output, has the probabilities.  On input,
      the axis must be initialized with the alpha.
*/


/*! Assuming that the luminosity distance has already been
  calculated, loops over the values of beta in
  the input array and fills it in with the relative probability.
  This version assumes the errors are diagonal.

  \param[out] likelihoodtarg On output, has the probabilities.  On input,
      the axis must be initialized with the beta.
*/


/*! Assuming that the luminosity distance has already been
  calculated, loops over the values of alpha/beta in
  the input array and fills it in with the relative probability.
  This version assumes the errors are diagonal.
*/


/*!
  This handles the non-diagonal 0D case, and is overloaded with
  the dimensional cases.  This inverts the covariance matrix
  for given values of \f$\alpha, \beta\f$.

  \param[in] alpha The value of \f$\alpha\f$ to use
  \param[in] beta The value of \f$\beta\f$ to use
  \param[in] lar The precomputed array of luminosity distances
  \return The likelihood of the result
*/


/*!
  This handles the non-diagonal 1D case, and is overloaded with
  the multi-dimensional cases.  This inverts the covariance matrix
  for given values of \f$\alpha, \beta\f$ and loops over the cosmological
  parameters specified by likelihoodtarg.

  \param[out] likelihoodtarg On input must be loaded with the axis
    information for the cosmological parameter, on output is filled with
    the relative probability values.
  \param[in] alpha The value of \f$\alpha\f$ to use
  \param[in] beta The value of \f$\beta\f$ to use
  \param[in] lar The precomputed array of luminosity distances

*/


/*!
  This handles the non-diagonal 2D case, and is overloaded with
  the other-dimensional cases.  This inverts the covariance matrix
  for given values of \f$\alpha, \beta\f$ and loops over the cosmological
  parameters specified by likelihoodtarg.

  \param[out] likelihoodtarg On input must be loaded with the axis
    information for the cosmological parameter, on output is filled with
    the relative probability values.
  \param[in] alpha The value of \f$\alpha\f$ to use
  \param[in] beta The value of \f$\beta\f$ to use
  \param[in] lar The precomputed array of luminosity distances
*/


/*!
  This handles the non-diagonal 3D case, and is overloaded with
  the other-dimensional cases.  This inverts the covariance matrix
  for given values of \f$\alpha, \beta\f$ and loops over the cosmological
  parameters specified by likelihoodtarg.

  \param[out] likelihoodtarg On input must be loaded with the axis
    information for the cosmological parameter, on output is filled with
    the relative probability values.
  \param[in] alpha The value of \f$\alpha\f$ to use
  \param[in] beta The value of \f$\beta\f$ to use
  \param[in] lar The precomputed array of luminosity distances
*/


/*!
  \param[in] results_map Map of information about cosmological parameters
  \param[in] intrinsic Assumed intrinsic 'dispersion' in magnitudes
*/


//If you make changes in here, make sure you update convert_to_fits,
// which reads this output file.


/*!
  \param[in] results_map Map of parameter values
*/


/*!
  \param[in] results_map Results of cosmological fit
  \return The estimates of \f${\mathcal M}\f$ given the other parameters.
 */


/*!
  Read in the parameter file.
*/


/*!
  Reads in parameters from parameterfile, then loads the supernova
  data and calculates the non-parameter dependent variances.
 */


/*!
  If it is necessary to calculate a large number of these, it is more
  efficient to do it by hand than to use this function.

  \param[in] alpha Width (stretch) correction coefficient
  \param[in] beta Colour correction coefficient
  \returns Error in corrected magnitude, not including peculiar velocity
    or intrinsic dispersion
*/


/*!
  If it is necessary to calculate a large number of these, it is more
  efficient to do it by hand than to use this function

  \param[in] alpha Width (stretch) correction coefficient
  \param[in] beta Colour correction coefficient
  \returns Variance corrected magnitude, not including peculiar velocity
    or intrinsic dispersion
*/


/*!
  Makes sure that all the defined correlation coefficients are
  less than 1.
 */


/*!
Each line in the data file should have the format:
snname zcmb zhel dz widthpar dwidthpar colourpar dcolourpar cov_mag_width cov_mag_colourpar cov_widthpar_colourpar scriptmset [dataset]

snname is a string (quotes are not necessary, and in fact probably not
a good idea), but the others are all
doubleing point numbers.  There can't be any spaces in snname, or bad
things will happen.  The lines must have an entry for each of the
above parameters, although they can be set to zero.

dataset is optional, and is an integer.  This is to support different
 dispersions for different datasets, which is controlled via the
SNDISP option.  It is up to you to ensure that, if you specify datasets,
you specify a dispersion for each.

Lines that begin with # are ignored.

Any old data is eliminated, as is the covariance matrix if present.

Some examples can be found in the test subdirectory.

*/


/*!
  \param[in] FileNames Vector of string filenames, matched by position
    to the six cov matricies.  An empty string will result in a skipped read.
*/


/*!
  Read in a Woodbury style covariance matrix.  Replaces the existing one.
*/


/*!
  Uses the same format as SNeData::readData.
  \param[in] outfile File to write to
*/


/*!
  \param[in] indxarr Array of indicies into old array.
  \returns A new SNeData with only the specified objects present

  No bounds checking is performed, so it is up to the caller
  to ensure that the indicies in indxarr are valid.
*/


/*!
  \param[in] namearr Vector of strings corresponding to names
    of SN
  \returns A new SNeData with only the specified objects present

  Error checking is done, and an out_of_range exception is thrown
  if any of the passed in names are not found.
*/


/*!
  \param[in] indxarr List of indicies to remove

  Duplicate indicies are allowed, but no range checking is performed,
  so it is up to the caller to ensure that only valid indicies are passed.
*/


/*!
  \param[in] namearr List of names to remove.
  \param[in] strict Complain if one of the passed in names is
     not found in the list.

  Duplicate indicies are allowed.  Invalid entries in namearr
  result in a out_of_range error being thrown unless strict
  is set to false
*/


/*!
  \param[in] indxarr List of indicies to remove from returned copy

  Duplicate indicies are allowed, but no range checking is performed,
  so it is up to the caller to ensure that only valid indicies are passed.

*/


/*!
  \param[in] namearr List of names to remove from returned copy
  \param[in] strict Complain if one of the passed in names is
     not found in the list.
  \returns Copy of SNeData with specified entries removed

  Duplicate indicies are allowed.  Invalid entries in namearr
  result in a out_of_range error being thrown unless strict
  is set to false.
*/


/*!
  \param[in] zfin Redshift to evaluate growth factor at
  \param[in] cosparams Cosmological parameters to use
  \param[in] nstep Number of steps to use.  10000 is reasonable
  \returns The growth factor at redshift zfin
*/


/*!
  4th order Runge-Kutta integrator
  From numerical recipies, specialized to case of 2 variables
  and to this particular problem

  \param[in] y Initial value for variables at x
  \param[in] dydx Derivatives of variables at x
  \param[in] x Starting position
  \param[in] h Amount to advance integral
  \param[in] params Cosmological parameters for this problem, used to get
                     derivatives
  \param[out] yout New values of variables
*/


/*!
  \param[in] x Place to evaluate derivative
  \param[in] y Input values
  \param[out] dydx Derivatives at x
  \param[in] params Cosmological parameters

  For this particular problem, x is a, y[0] is the growth factor,
  y[1] is d growth_factor/da.
*/


/*!
  Interface to find growth factor at a given redshift
  \param[in] zfin Redshift to get growth factor at
  \param[in] om \f$\Omega_m\f$
  \param[in] w0 w at z=0
  \param[in] wa Derivative of w with a.  Specifically,
     \f$w\left(a\right) = w0 + wa \left(1 - a\right)\f$.  a is the scale
     factor: \f$ a = \frac{1}{1+z}\f$.
  \returns The growth factor at zfin
*/


/*!
  Fill in grid of probability values by comparing growth factor
  measurement with the theoretical value.  This is specialized
  to the flat \f$ w \f$, \f$ \Omega_m \f$ case.

  \param[in] fval The measured growth of structure parameter
  \param[in] dfval The error in fval
  \param[in] z The redshift fval was measured at
  \param[in] nw The number of \f$ w \f$ points to calculate
  \param[in] minw The minimum \f$ w \f$ value to consider
  \param[in] maxw The maximum \f$ w \f$ value to consider
  \param[in] nom The number of \f$ \Omega_m \f$ points to calculate
  \param[in] minom The minimum \f$ \Omega_m \f$ value to consider
  \param[in] maxom The maximum \f$ \Omega_m \f$ value to consider
  \returns A cosgrid2D loaded up with the relative probability levels
    for various values of the cosmological parameters.
*/


/*!
  Fill in grid of probability values by comparing growth factor
  measurement with the theoretical value.  This is specialized
  to the flat \f$w\f$, \f$\Omega_m\f$ case.

  \param[in] fval The measured growth of structure parameter
  \param[in] dfval The error in fval
  \param[in] z The redshift fval was measured at
  \param[in] ingrid cosgrid2D used to set the values the grid is calculated at
  \returns A cosgrid2D loaded up with the relative probability levels
    for various values of the cosmological parameters.
*/


//1D cosgrid case


/*!
  Which value is returned depends on what type of fit was performed.
*/


/*!
  \ingroup fitter

  \param[in] c Cosgrid to get results from
  \param[out] retvec Vector of results
*/


/*!
  \ingroup fitter

  \param[in] c Cosgrid to get results from
  \param[out] retmap Map of results
*/


/*!
  \param[in] params Map of parameter specifications to be processed
  \param[out] retmap Map that the fixed params are added to

  This is how we propogate the parameters we held fixed in the fit
  into the results.  retmap is appended to, so it can already
  have entries in it.
 */


/*!
  This is internal because the user shouldn't be able to interface
  with the matrix when it's in lower triangular form.  Also, if you
  pass it something that isn't lower triangular, bad things will happen.
*/


/*
  Factors the matrix into it's lower diagonal Cholesky form
  such that \f$A = L \cdot L^T\f$.  If the process fails,
  possibly because the matrix is not symmetric positive definite,
  then status will be non-zero on return.

  \param status 0 on success, -1 if non-spd
 */


/*!
  Form the product of a lower triangular matrix and it's transpose,
  overwriting the current matrix.

  Note that the result is always symmetric.  This is internal
  because the user shouldn't interface with the lower triangular
  forms.
*/


/*!
  \param[out] newmat Matrix with output information
  \param[in] idx  Index array to select with.  The boundaries are
                  not checked
*/


/*!
  Fails if vector is wrong size, but fails silently, so be careful
*/


/*!
  Returns \f$ A \cdot \vec{b}\f$ where A is the current matrix

  \param[in] b The input vector
  \param     status zero on successful calculation

  The arithmetic is done in double precision internally.
*/


/*!
  Returns \f$ A \cdot \vec{b}\f$, where A is the current matrix

  \param[in] b      The input vector
  \param     status zero on successful calculation, should be zero
                     on input.
*/


/*!
  Writes a covaraince matrix.  Right now this just uses the overloaded
  operator<< for covMatrix
  \param[in] FileName File to write to
  \param[in] covmat  Covariance matrix to write
*/


/*!
  Reads in the magnitude covariance matrix.  Right now this just uses the
  overloaded operator>> for covMatrix.  Replaces any existing one.
  \param[in] FileName The file to read the matrix from
*/


/*!
  Reads in the width covariance matrix.  Right now this just uses the
  overloaded operator>> for covMatrix.  Replaces any existing one.
  \param[in] FileName The file to read the matrix from
*/


/*!
  Reads in the colour covariance matrix.  Right now this just uses the
  overloaded operator>> for covMatrix.  Replaces any existing one.
  \param[in] FileName The file to read the matrix from
*/


/*!
  Reads in the mag-width covariance matrix.  Right now this just uses the
  overloaded operator>> for covMatrix.  Replaces any existing one.
  \param[in] FileName The file to read the matrix from
*/


/*!
  Reads in the mag-colour covariance matrix.  Right now this just uses the
  overloaded operator>> for covMatrix.  Replaces any existing one.
  \param[in] FileName The file to read the matrix from
*/


/*!
  Reads in the width-colour covariance matrix.  Right now this just uses the
  overloaded operator>> for covMatrix.  Replaces any existing one.
  \param[in] FileName The file to read the matrix from
*/


/*!
  \param[in] FileNames Vector of string filenames, matched by position
    to the six cov matricies.  An empty string will result in a skipped write.
*/


/*!
  \param[out] cov  The combined covariance matrix
  \param[in] alpha  \f$\alpha\f$
  \param[in] beta   \f$\beta\f$

*/


/*!
  \param[in] alpha \f$\alpha\f$
  \param[in] beta  \f$\beta\f$
  \param[in] i     Element index
  \param[in] j     Element index
  \return The corresponding element of the combined covariance matrix

  //This doesn't work if you have a woodbury cov matrix
 */


/*!
  Does the work of the constructors, except for setting the flags
  \param[in] inclass Class generating exception
  \param[in] inmethod Method generating exception
  \param[in] inerrstr Error string
  \param[in] inerr Error number
*/


/*!
  Error with error string, class and method generating exception
*/


/*!
  Full error specification: error std::string, number, class, and method.
 */


/*!
  This is in the form for the GSL

  \param[in] z Redshift
  \param[in] params Cosmological parameters
  (\f$\Omega_m\f$,\f$\Omega_{\Lambda}\f$)
  \returns 1/E term used in many cosmological expressions
*/


/*!
  This is in the form for the GSL

  \param[in] z Redshift
  \param[in] params Cosmological parameters
  (\f$w\f$, \f$\Omega_m\f$,\f$\Omega_{DE}\f$)
  \returns 1/E term used in many cosmological expressions
*/


/*!
  This is in the form for the GSL

  \param[in] z Redshift
  \param[in] params Cosmological parameters
  (\f$w_0\f$, \f$w_a\f$ \f$\Omega_m\f$,\f$\Omega_{DE}\f$)
  \returns 1/E term used in many cosmological expressions
*/


/*!
  This is in the form for the GSL

  \param[in] z Redshift
  \param[in] params Cosmological parameters
  (\f$w_0\f$, \f$w_a\f$ \f$\Omega_m\f$,\f$\Omega_{DE}, atrans\f$)
  \returns 1/E term used in many cosmological expressions

  This uses the Komatsu et al. (2008) form for the expansion history
*/


/*!
  This is in the form for the GSL

  \param[in] z Redshift
  \param[in] params Cosmological parameters
  (\f$\Omega_m\f$,\f$\Omega_{\Lambda}, \Omega_r\f$)
  \returns 1/E term used in many cosmological expressions
  This version includes \f$\Omega_r\f$
*/


/*!
  This is in the form for the GSL

  \param[in] z Redshift
  \param[in] params Cosmological parameters
  (\f$w\f$, \f$\Omega_m\f$,\f$\Omega_{DE}\f$,\f$\Omega_r\f$)
  \returns 1/E term used in many cosmological expressions
  This version includes \f$\Omega_r\f$
*/


/*!
  This is in the form for the GSL

  \param[in] z Redshift
  \param[in] params Cosmological parameters
  (\f$w_0\f$, \f$w_a\f$ \f$\Omega_m\f$,\f$\Omega_{DE}\f$, \f$\Omega_r\f$)
  \returns 1/E term used in many cosmological expressions
  This version includes \f$\Omega_r\f$
*/


/*!
  This is in the form for the GSL

  \param[in] z Redshift
  \param[in] params Cosmological parameters
  (\f$w_0\f$, \f$w_a\f$ \f$\Omega_m\f$,\f$\Omega_{DE}\f$, \f$\Omega_r,
  atrans\f$)
  \returns 1/E term used in many cosmological expressions
  This version includes \f$\Omega_r\f$, and is in the Komatsu form
  for w(a)
*/


/*!
  This is in the form for the GSL

  \param[in] a Scale factor
  \param[in] params Cosmological parameters
  (\f$\Omega_m , \Omega_{\Lambda} , \Omega_b h^2 , h\f$)
  \returns The integral term for the \f$r_s \left( z_{cmb} \right)\f$ equation
*/


/*!
  This is in the form for the GSL

  \param[in] a Scale factor
  \param[in] params Cosmological parameters
  (\f$w, \Omega_m , \Omega_{DE} , \Omega_b h^2 , h\f$)
  \returns The integral term for the \f$r_s \left( z_{cmb} \right)\f$ equation
*/


/*!
  This is in the form for the GSL

  \param[in] a Scale factor
  \param[in] params Cosmological parameters
  (\f$w_0 , w_a, \Omega_m , \Omega_{DE} , \Omega_b h^2 , h\f$)
  \returns The integral term for the \f$r_s \left( z_{cmb} \right)\f$ equation
*/


/*!
  This is in the form for the GSL

  \param[in] a Scale factor
  \param[in] params Cosmological parameters
  (\f$w_0 , w_a, \Omega_m , \Omega_{DE} , \Omega_b h^2 , h, atrans\f$)
  \returns The integral term for the \f$r_s \left( z_{cmb} \right)\f$ equation

  Uses the Komatsu et al. (2008) form for w(a)
*/


/*!
  This is in the form for the GSL

  \param[in] a Scale factor
  \param[in] params Cosmological parameters
  (\f$\Omega_m , \Omega_{\Lambda} , \Omega_b h^2, h \f$)
  \returns The integral term for \f$r_s H_0 / c\f$  Does not include the
  \f$\sqrt(3)\f$ term, and is done in terms of \f$a\f$
*/


/*!
  This is in the form for the GSL

  \param[in] a Scale factor
  \param[in] params Cosmological parameters
  (\f$w, Omega_m , \Omega_{\Lambda} , \Omega_b h^2, h \f$)
  \returns The integral term for \f$r_s H_0 / c\f$  Does not include the
  \f$\sqrt(3)\f$ term, and is done in terms of \f$a\f$
*/


/*!
  This is in the form for the GSL

  \param[in] a Scale factor
  \param[in] params Cosmological parameters
  (\f$w_0, w_a, Omega_m , \Omega_{\Lambda} , \Omega_b h^2, h \f$)
  \returns The integral term for \f$r_s H_0 / c\f$  Does not include the
  \f$\sqrt(3)\f$ term, and is done in terms of \f$a\f$
*/


/*!
  This is in the form for the GSL

  \param[in] a Scale factor
  \param[in] params Cosmological parameters
  (\f$w_0, w_a, Omega_m , \Omega_{\Lambda} , \Omega_b h^2, h, atrans \f$)
  \returns The integral term for \f$r_s H_0 / c\f$  Does not include the
  \f$\sqrt(3)\f$ term, and is done in terms of \f$a\f$

  Uses the Komatsu et al. (2008) form for w(a)
*/


/*!
  Based on formulae from
  Carroll and Press, AARA 1993, 30: 499.
  Ignores \f$\Omega_{rad}\f$.  This is only valid for
  the cosmological constant case (\f$w=-1\f$).
*/


/*!
  \param[in] v Vector of \f$h, \Omega_b h^2\f$
  \param[in] params Other parameters, very indirectly
  \returns \f$\chi^2\f$
*/


/*!
  \param[in] v Vector of \f$h, \Omega_b h^2\f$
  \param[in] params Other parameters, very indirectly
  \returns \f$\chi^2\f$ of Percival BAO and WMAP7
*/


/*!
  \param[in] z Redshift
  \param[in] obh2 \f$ \Omega_b h^2 \f$
  \param[in] om \f$ \Omega_m \f$
  \param[in] ode \f$ \Omega_{DE}\f$
  \param[in] w0 \f$w_{0}\f$
  \param[in] wa \f$w_{a}\f$
  \param[in] h \f$H_{0} = 100 h\f$ km/sec
  \param[out] success 1 if computation was successful, 0 if failed
  \returns \f$K_1 = H_{0} r_{s} \left( z \right) / c\f$

*/


/*!
  \param[in] z Redshift
  \param[in] om \f$ \Omega_m \f$
  \param[in] ode \f$ \Omega_{DE}\f$
  \param[in] orad \f$ \Omega_r\f$, the density of radiation (not just photons)
  \param[in] w0 \f$w_{0}\f$
  \param[in] wa \f$w_{a}\f$
  \param[out] success 1 if computation was successful, 0 if failed
  \returns \f$K_2 = \left(1 + z \right) H_{0}
  D_{A} \left( z_{\star} \right) / c\f$, where \f$D_{A}\f$ is
  the comoving angular diameter distance
*/


/*!
  \param[in] z Redshift
  \param[in] om \f$ \Omega_m \f$
  \param[in] ode \f$ \Omega_{DE}\f$
  \param[in] orad \f$ \Omega_r\f$, the density of radiation (not just photons)
  \param[in] w0 \f$w_{0}\f$
  \param[in] wa \f$w_{a}\f$
  \param[out] success 1 if computation was successful, 0 if failed
  \returns \f$1/E = H_{0} / H\left( z \right)\f$
*/


/*!
  \param[in] obh2  \f$\Omega_b h^2\f$
  \param[in] omh2  \f$\Omega_m h^2\f$
  \returns The value of \f$z_{\star}\f$, the decopuling redshift

  Fitting forumula from Hu & Sugiyama (1996)
*/


/*!
  \param[in] obh2  \f$\Omega_b h^2\f$
  \param[in] omh2  \f$\Omega_m h^2\f$
  \returns The value of \f$z_{d}\f$, the drag redshift

  Fitting formula from Eisenstein & Hu (1998)
*/


/*!
  Little utility function to update a vector with values
  of the cosmological parameters in the order that getLumDist
  understands.

  \param[in] code The parameter code from param_tags
  \param[out] vec The vector to update
  \param[in] val The value to insert

  vec is in the order \f$\Omega_m, \Omega_{DE}, w_0, w_a\f$.
*/


/*!
  \param[in] params 4 element vector of parameter values in the order
              \f$\Omega_m, \Omega_{DE}, w_0, w_a\f$
  \returns \f$\chi^2\f$
 */


/*!
  \param[in] params 4 element vector of parameter values in the order
  \f$\Omega_m, \Omega_{DE}, w_{0}, w_{a}\f$
  \returns Eisenstein A parameter
*/


/*!
  \param[in] w0   \f$w_0\f$
  \param[in] wa   \f$w_a\f$
  \param[in] om  \f$\Omega_m\f$
  \param[in] ode \f$\Omega_{DE}\f$
  \returns \f$\chi^2\f$ at parameter values

  If you specify a neutrino fraction, this will be modified
  following Goobar et al. (2006).
  Note that an expansion is used for the neutrino fraction, so if
  the value is large the expansion is probably invalid
*/


////////////////////////////////////////////////////////////////////
//               WMAP3 Shift parameter
////////////////////////////////////////////////////////////////////


/*!
  \param[in] w0  \f$w_0\f$
  \param[in] wa  \f$w_a\f$
  \param[in] om  \f$\Omega_m\f$
  \param[in] ode \f$\Omega_{DE}\f$
  \returns Value of \f${\mathcal R}\f$, the shift parameter, at the
  given values of the cosmological parameters

*/


/*!
  \param[in] params 4 element vector of parameter values in the order
  \f$\Omega_m, \Omega_{DE}, w_0, w_a\f$
  \returns Shift parameter \f$R\f$
*/


/*!
  \param[in] w0  \f$w_0\f$
  \param[in] wa  \f$w_a\f$
  \param[in] om  \f$\Omega_m\f$
  \param[in] ode \f$\Omega_{DE}\f$
  \param[in] obh2 \f$\Omega_b h^2\f$
  \param[in] h \f$h\f$
  \returns Value of \f$l_a\f$, the second shift parameter, at the
  given values of the cosmological parameters

*/


/*!
  \param[in] params 4 element vector of parameter values in the order
  \f$\Omega_m, \Omega_{DE}, w_0, w_a\f$
  \param[in] obh2 \f$\Omega_b h^2\f$
  \param[in] h \f$h\f$
  \returns Shift parameter \f$l_a\f$, the second shift parameter
*/


/*!
  \param[in] r \f$R\f$ shift parameter from rval
  \param[in] w0  \f$w_0\f$
  \param[in] wa  \f$w_a\f$
  \param[in] om  \f$\Omega_m\f$
  \param[in] ode \f$\Omega_{DE}\f$
  \param[in] obh2 \f$\Omega_b h^2\f$
  \param[in] h \f$h\f$
  \returns Value of \f$l_a\f$, the second shift parameter, at the
  given values of the cosmological parameters

*/


/*!
  \param[in] r \f$R\f$ shift parameter from rval
  \param[in] params 4 element vector of parameter values in the order
  \f$\Omega_m, \Omega_{DE}, w_0, w_a\f$
  \param[in] obh2 \f$\Omega_b h^2\f$
  \param[in] h \f$h\f$
  \returns Shift parameter \f$l_a\f$, the second shift parameter
*/


/*!
  \param[in] w0   \f$w_0\f$
  \param[in] wa   \f$w_a\f$
  \param[in] om  \f$\Omega_m\f$
  \param[in] ode \f$\Omega_{DE}\f$
  \returns \f$\chi^2\f$ at parameter values

  This version only does the first shift parameter, which does not
  require an external prior on \f$h\f$.
*/


/*!
  \param[in] w0   \f$w_0\f$
  \param[in] wa   \f$w_a\f$
  \param[in] om  \f$\Omega_m\f$
  \param[in] ode \f$\Omega_{DE}\f$
  \returns \f$\chi^2\f$ at parameter values

  This version incorporates the second shift paramter \f$l_a\f$ of
  Wang and Mukherjee 2007, astro-ph/0703780, and numerically marginalizes
  over \f$\Omega_b h^2\f$ and \f$h\f$ using the WMAP3 value for the first
  and some sort of external prior on the second.

*/


//This is disturbingly difficult to do in c++
//The locale stuff doesn't work on strings properly, so
// we have to go through C


/*!
  Breaks an input string up into a vector of string, which correspond
  to the input string split on spaces.  Cheerfully stolen from Rob
  Knop.
*/


/*!
  Given three data points, fits a parabola and determines the x value
  of the maximum for that parabola.  Assumes that x1,x2,x3 are equally
  spaced in ascending order
*/


/*!
  Uses parabolamax to estimate the abcissa of the maximum value of the
  input cosgrid1D, given the maximum index
*/


/*!
  \param[in] axis Abscissa values for interpolating.  Must be ordered!
  \param[in] values Data values
  \param[in] x Point to interpolate to
  \param[out] status Status variable, 0 on success.  1 if the value is
    off the beginning, and 2 if it's off the end
  \returns The interpolant

*/


/*!
  Little utility function to update a vector with values
  of the cosmological parameters in the order that getLumDist
  understands.

  \param[in] code The parameter code from param_tags
  \param[in] fparam The fitparam holding info about the fit
  \param[out] vec The vector to update
  \param[in] val The value to insert

  vec is in the order \f$\Omega_m, \Omega_{DE}, w_0, w_a\f$.
*/


/*!
  \brief General w=-1 integrand in GSL form
  \ingroup lumdist
  Not in lumdist class because the GSL does not accept pointers to member
  functions.
  \param[in] z Redshift
  \param[in] params Array of parameters
     (\f$\Omega_m\f$, \f$\Omega_{\Lambda}\f$)
  \returns The value of the integral term
             \f$ \frac{1}{\sqrt{ \left(1+z\right)^2\left(1+\Omega_m z \right)
                                 - z \left( 2 + z \right) \Omega_{\Lambda}}}\f$

 */


/*!
  \brief General w=-1 integrand in GSL ODE form
  \ingroup lumdist
  Not in lumdist class because the GSL does not accept pointers to member
  functions.
  \param[in] z Redshift
  \param[in] y Current value of integral.  Not used
  \param[out] f The value of the integral term
             \f$ \frac{1}{\sqrt{ \left(1+z\right)^2\left(1+\Omega_m z \right)
                  - z \left( 2 + z \right) \Omega_{\Lambda}}}\f$
  \param[in] params Array of parameters
     (\f$\Omega_m\f$, \f$\Omega_{\Lambda}\f$)
 */


/*!
  \brief Integrand for constant w in GSL form
  \ingroup lumdist
  Not in lumdist class because the GSL does not accept pointers to member
  functions.
  \param[in] z Redshift
  \param[in] params Array of parameters
     (\f$w, \Omega_m, \Omega_{DE}\f$)
  \returns The value of the integral term
     \f$ \frac{1}{\sqrt{ \left(1+z\right)^2 \Omega_m +
             \left(1+z\right)^2 \Omega_k +
             \left(1+z\right)^{3\left(1+w\right)} \Omega_{DE} } } \f$

 */


/*!
  \brief General w=const integrand in GSL ODE form
  \ingroup lumdist
  Not in lumdist class because the GSL does not accept pointers to member
  functions.
  \param[in] z Redshift
  \param[in] y Current value of integral.  Not used
  \param[out] f The value of the integral term
     \f$ \frac{1}{\sqrt{ \left(1+z\right)^3 \Omega_m +
             \left(1+z\right)^2 \Omega_k +
             \left(1+z\right)^{3\left(1+w\right)} \Omega_{DE} } } \f$
  \param[in] params Array of parameters
     (\f$w\f$, \f$\Omega_m\f$, \f$\Omega_{DE}\f$)
 */


/*!
  \brief Integrand for w0, wa in GSL form
  \ingroup lumdist
  Not in lumdist class because the GSL does not accept pointers to member
  functions.
  \param[in] z Redshift
  \param[in] params Array of parameters
     (\f$w0, wa, \Omega_m, \Omega_{DE}\f$)
  \returns The value of the integral term
*/


/*!
  \brief General w0, wa integrand in GSL ODE form
  \ingroup lumdist
  Not in lumdist class because the GSL does not accept pointers to member
  functions.
  \param[in] z Redshift
  \param[in] y Current value of integral.  Not used
  \param[out] f The value of the integral term
  \param[in] params Array of parameters
     (\f$w_0, w_a, \Omega_m, \Omega_{DE}\f$)
 */


/*!
  \brief Integrand for w0, wa in GSL form, using Komatsu parameterization
  \ingroup lumdist
  Not in lumdist class because the GSL does not accept pointers to member
  functions.
  \param[in] z Redshift
  \param[in] params Array of parameters
     (\f$w0, wa, \Omega_m, \Omega_{DE}, atrans\f$)
  \returns The value of the integral term
*/


/*!
  \brief General w0, wa integrand in GSL ODE form
  \ingroup lumdist
  Not in lumdist class because the GSL does not accept pointers to member
  functions.
  \param[in] z Redshift
  \param[in] y Current value of integral.  Not used
  \param[out] f The value of the integral term
  \param[in] params Array of parameters
     (\f$w_0, w_a, \Omega_m, \Omega_{DE}, atrans\f$)
 */


/*!
  Evaluates only the integral part of the luminosity distance term
  \param[in] om \f$\Omega_m\f$
  \param[in] ol \f$\Omega_{\Lambda}\f$
  \param[out] intval Filled with the integral values
  \returns 0 on success

  Uses a brute-force trapezoidal algorithm.
*/


/*!
  Uses a fairly brute-force trapezoidal algorithm.
  \param[in] sne List of SN to find luminosity distance integrals for.  Must
                  be sorted by SNeDataEntry::zcmb
  \param[in] om \f$\Omega_m\f$
  \param[in] ol \f$\Omega_{\Lambda}\f$
  \param[out] dl luminosity distance (c/H0 removed).  Assumed pre-allocated.
            actually, 5 * log10 (dl) is returned for each SN
  \returns 0 on success
*/


/*!
  Evaluates only the integral part of the luminosity distance term
  \param[in] om \f$\Omega_m\f$
  \param[in] ol \f$\Omega_{\Lambda}\f$
  \param[out] intval Filled with the integral values
  \returns 0 on success

  Uses a Runge-Kutta-Felhberg 4-5 method
*/


/*!
  Uses Runge-Kutta-Felhberg 4-5 method.  Faster than trapezoidal algorithm
  \param[in] sne List of SN to find luminosity distance integrals for.  Must
                  be sorted by SNeDataEntry::zcmb
  \param[in] om \f$\Omega_m\f$
  \param[in] ol \f$\Omega_{\Lambda}\f$, the density parameter of the
                   cosmological constant
  \param[out] dl luminosity distance (c/H0 removed).  Assumed pre-allocated.
            actually, 5 * log10 (dl) is returned for each SN
  \returns 0 on success
*/


/*!
  Based on calculations presented in Kantowski et al., 2000 ApJ 545, 549
  \param[in] zcmb Redshift to evaluate at
  \param[in] om \f$\Omega_m\f$
  \param[in] ol \f$\Omega_{\Lambda}\f$
  \param[out] integralval The integral value
  \returns 0 on success

  These equations require ol >= 0.
*/


/*!
  Based on calculations presented in Kantowski et al., 2000 ApJ 545, 549
  \param[in] SN Object with SN information
  \param[in] om \f$\Omega_m\f$
  \param[in] ol \f$\Omega_{\Lambda}\f$
  \param[out] dl luminosity distance (c/H0 removed).
            Actually, 5 * log10 (dl) is returned for each SN
  \returns 0 on success

  This requires ol >= 0.0.
*/


/*!
  Evaluates only the integral part of the luminosity distance term
  \param[in] w \f$w\f$
  \param[in] om \f$\Omega_m\f$
  \param[in] ol \f$\Omega_{\Lambda}\f$
  \param[out] intval Filled with the integral values
  \returns 0 on success

  Uses a brute-force trapezoidal algorithm.
*/


/*!
  Uses a fairly brute-force trapezoidal algorithm.
  \param[in] sne List of SN to find luminosity distance integrals for.  Must
                  be sorted by SNeDataEntry::zcmb
  \param[in] w \f$w\f$, the equation of state parameter of the dark energy
  \param[in] om \f$\Omega_m\f$
  \param[in] ow \f$\Omega_{DE}\f$, density parameter for dark energy
  \param[out] dl luminosity distance (c/H0 removed).  Assumed pre-allocated.
            actually, 5 * log10 (dl) is returned for each SN
  \returns 0 on success
*/


/*!
  Uses GSL numeric integration to find luminosity distance.
  \param[in] SN Object with info about SN
  \param[in] w \f$w\f$, the equation of state parameter of the dark energy
  \param[in] om \f$\Omega_m\f$
  \param[in] ode \f$\Omega_{DE}\f$, the density parameter of the dark energy
  \param[out] dl luminosity distance (c/H0 removed).
            Actually, 5 * log10 (dl) is returned for each SN
  \returns 0 on success
*/


/*!
  Evaluates only the integral part of the luminosity distance term
  \param[in] w \f$w\f$
  \param[in] om \f$\Omega_m\f$
  \param[in] ol \f$\Omega_{\Lambda}\f$
  \param[out] intval Filled with the integral values
  \returns 0 on success

  Uses Runge-Kutta-Felhberg 4-5 method.  Faster than trapezoidal algorithm.
*/


/*!
  Uses Runge-Kutta-Felhberg 4-5 method.  Faster than trapezoidal algorithm
  \param[in] sne List of SN to find luminosity distance integrals for.  Must
                  be sorted by SNeDataEntry::zcmb
  \param[in] w \f$w\f$, the equation of state parameter for the dark energy
  \param[in] om \f$\Omega_m\f$
  \param[in] ow \f$\Omega_{DE}\f$, the density parameter of the
                  dark energy.
  \param[out] dl luminosity distance (c/H0 removed).  Assumed pre-allocated.
            actually, 5 * log10 (dl) is returned for each SN
  \returns 0 on success
*/


/*!
  Evaluates only the integral part of the luminosity distance term
  \param[in] w0 \f$w_0\f$
  \param[in] wa \f$w_a\f$
  \param[in] om \f$\Omega_m\f$
  \param[in] ode \f$\Omega_{DE}\f$
  \param[out] intval Filled with the integral values
  \returns 0 on success

  Uses a brute-force trapezoidal algorithm.
*/


/*!
  Uses a fairly brute-force trapezoidal algorithm.
  \param[in] sne List of SN to find luminosity distance integrals for.  Must
                  be sorted by SNeDataEntry::zcmb
  \param[in] w0 \f$w_0\f$
  \param[in] wa \f$w_a\f$
  \param[in] om \f$\Omega_m\f$
  \param[in] ow \f$\Omega_{DE}\f$, density parameter for dark energy
  \param[out] dl luminosity distance (c/H0 removed).  Assumed pre-allocated.
            actually, 5 * log10 (dl) is returned for each SN
  \returns 0 on success
*/


/*!
  Uses GSL numeric integration to find luminosity distance.
  \param[in] SN Object with info about SN
  \param[in] w0 \f$w_0\f$
  \param[in] wa \f$w_a\f$
  \param[in] om \f$\Omega_m\f$
  \param[in] ode \f$\Omega_{DE}\f$, the density parameter of the dark energy
  \param[out] dl luminosity distance (c/H0 removed).
            Actually, 5 * log10 (dl) is returned for each SN
  \returns 0 on success
*/


/*!
  Evaluates only the integral part of the luminosity distance term
  \param[in] w0 \f$w_0\f$
  \param[in] wa \f$w_a\f$
  \param[in] om \f$\Omega_m\f$
  \param[in] ode \f$\Omega_{DE}\f$
  \param[out] intval Filled with the integral values
  \returns 0 on success

  Uses Runge-Kutta-Felhberg 4-5 method.  Faster than trapezoidal algorithm,
  except for large numbers of SN (where the overheads kill you).
*/


/*!
  Uses Runge-Kutta-Felhberg 4-5 method.  Usually faster than trapezoidal
  algorithm
  \param[in] sne List of SN to find luminosity distance integrals for.  Must
                  be sorted by SNeDataEntry::zcmb
  \param[in] w0 \f$w_0\f$
  \param[in] wa \f$w_a\f$
  \param[in] om \f$\Omega_m\f$
  \param[in] ow \f$\Omega_{DE}\f$, the density parameter of the
                  dark energy.
  \param[out] dl luminosity distance (c/H0 removed).  Assumed pre-allocated.
            actually, 5 * log10 (dl) is returned for each SN
  \returns 0 on success
*/


/*!
  \param[in] sne List of SN to find luminosity distance integrals for.  Must
                  be sorted by SNeDataEntry::zcmb
  \param[in] om \f$\Omega_m\f$
  \param[in] ode \f$\Omega_{DE}\f$, the density parameter of the
                  dark energy.
  \param[in] w0 \f$w_0\f$, the equation of state parameter for the dark energy
                  at the current epoch
  \param[in] wa \f$w_a\f$ Minus the derivative of \f$w\f$ with respect to
                 \f$a\f$
  \param[in] method Which integration method to use.  If the specified
                      method is not possible, an error is returned.
  \param[out] dl luminosity distance (c/H0 removed).  Assumed pre-allocated.
            actually, 5 * log10 (dl) is returned for each SN
  \returns 0 on success

  The model here is \f$w \left(a\right) = w_0 + w_a \left( 1 - a \right)\f$
  (i.e., Linder (2003)).
*/


/*!
  \param[in] sne List of SN to find luminosity distance integrals for.  Must
                  be sorted by SNeDataEntry::zcmb
  \param[in] params 4 element vector of parameter values in the order
              \f$\Omega_m, \Omega_{DE}, w_0, w_a\f$
  \param[in] method Which integration method to use.  If the specified
                      method is not possible, an error is returned.
  \param[out] dl luminosity distance (c/H0 removed).  Assumed pre-allocated.
            actually, 5 * log10 (dl) is returned for each SN
  \returns 0 on success

  The model here is \f$w \left(a\right) = w_0 + w_a \left( 1 - a \right)\f$
  (i.e., Linder (2003)) or the Komatsu et al. (2008) form.
*/


/*!
  \param[in] sn  Single SN to find luminosity distance for.
  \param[in] om \f$\Omega_m\f$
  \param[in] ode \f$\Omega_{DE}\f$, the density parameter of the
                  dark energy.
  \param[in] w0 \f$w_0\f$, the equation of state parameter for the dark energy
                  at the current epoch
  \param[in] wa \f$w_a\f$ Minus the derivative of \f$w\f$ with
                 respect to \f$a\f$
  \param[out] dl luminosity distance (c/H0 removed).  Assumed pre-allocated.
            actually, 5 * log10 (dl) is returned
  \returns 0 on success

  The model here is \f$w \left(a\right) = w_0 + w_a \left( 1 - a \right)\f$
  (i.e., Linder (2003)) or the Komatsu et al. (2008) form.
*/


//First, a utility for reading the axisnames from
// binary files, as the writeBinaryFile stuff specifies


/*!
  \param[in] filename Name of file to check
  \param[in] binaryfile Is file in cosgrid binary format?  (def: false)
  \returns Number of axes
*/


/*!
 \param[in] n0 Number of data entries along axis 0
 \param[in] min0 Minimum axis value along axis 0
 \param[in] max0 Maximum axis value along axis 0
 \param[in] d0 Step size for axis along axis 0
 \param[in] label0 Name of axis 0 parameter.  Should not have spaces in it.
 \param[in] spec0 Spec for axis 0 parameter
*/


/*!
  \param[in] param Information about parameter describing axis 0
*/


/*!
  Find and return maximum value in array.
  \param[out] i0 The position of the maximum in the array
  \return The maximum value of the data array
*/


/*!
  \return The sum of all of the elements in the data array
 */


/*!
  Normalizes the total sum of all data entries to one.
  \return The sum of all of the elements in the data array prior to
           normalization.
 */


/*!
  Serializes the contents of the data array and the axis labels to a file
  in a human readable format.  The format of the output file is defined as:
  - The first line is axisname0, n0, min0, max0, d0
  - This is followed by n0 lines containing the data values
  \param[in] filename The file to write the data to
*/


/*!
  Reads in the data from a file in the format specified by
 cosgrid1D::writeTextFile
 \param[in] filename The file to read from
 */


/*!
  Serializes the contents of the data array and the axis labels to a file
  in a non human readable, binary, format.  The format of the output file
  is defined as:
  - an integer specifying the number of axes.  This is always one for this
     function (duh)
  - an integer specifying the number of characters in the zero terminated
     axisname
  - the axis name
  - an integer specifying n0
  - doubles specifying min0, max0, d0
  - then n0 doubles storing the data
  Note that this will not be machine portable because of endianess and
  the sizes of various outputs.  Unlike the version which writes in text,
  here we don't care if the axisnames have spaces in them.
  \param[in] filename The file to write the data to
*/


/*!
  Reads in the data from a file in the format specified by
 cosgrid1D::writeBinaryFile
 \param[in] filename The file to read from
 */


/*!
  \param[in] axis Which axis to return
  \param[in] x Position along axis
*/


/*! Returns index of axis with the specified name, throwing a CosFitterExcpt
 if no such axis is found.
 \param[in] axislabel Name of axis to find
 \returns Index of matching axis
 */


/*!
  Find and return maximum value in array.
  \param[out] i0 The position of the maximum in the array along axis 0
  \param[out] i1 The position of the maximum in the array along axis 1
  \return The maximum value of the data array
*/


/*!
  \return The sum of all of the elements in the data array
*/


/*!
  Normalizes the total sum of all data entries to one.
  \return The sum of all of the elements in the data array prior to
           normalization.
*/


/*!
  Serializes the contents of the data array and the axis labels to a file
  in a human readable format.  The format of the output file is defined as:
  - The first line is Naxes: 2
  - The second line is axisname0, n0, min0, max0, d0
  - The third line is axisname1, n1, min1, max1, d1
  - This is followed by n0*n1 lines containing the data values in c++
     style order (i.e., the axis1 index changes the most rapidly)
  \param[in] filename The file to write the data to
*/


/*!
  Serializes the contents of the data array and the axis labels to a file
  in a non human readable, binary, format.  The format of the output file
  is defined as:
  - an integer specifying the number of axes.
  - an integer specifying the number of characters in the zero terminated
     axisname
  - the axis name
  - an integer specifying n0
  - doubles specifying min0, max0, d0
  - a repeat of items 2-5 for the second axis
  - then n0*n1 doubles storing the data in c order
  Note that this will not be machine portable because of endianess and
  the sizes of various outputs.  Unlike the version which writes in text,
  here we don't care if the axisnames have spaces in them.
  \param[in] filename The file to write the data to
*/


/*!
  Collapse the grid along the specified axis by summing.
  \param[in] axisnum Index of axis.  A CosFitterExcpt is thrown if this is
              out of range
  \returns A cosgrid1D containing the collapsed data array
*/


/*!
  Find and return maximum value in array.
  \param[out] i0 The position of the maximum in the array along axis 0
  \param[out] i1 The position of the maximum in the array along axis 1
  \param[out] i2 The position of the maximum in the array along axis 2
  \return The maximum value of the data array
*/


/*!
  Serializes the contents of the data array and the axis labels to a file
  in a human readable format.  The format of the output file is defined as:
  - The first line is Naxes: 3
  - The second line is axisname0, n0, min0, max0, d0
  - The third line is axisname1, n1, min1, max1, d1
  - The fourth line is axisname2, n2, min2, max2, d2
  - This is followed by n0*n1*n2 lines containing the data values in c++
     style order (i.e., the axis2 index changes the most rapidly)
  \param[in] filename The file to write the data to
*/


/*!
  Serializes the contents of the data array and the axis labels to a file
  in a non human readable, binary, format.  The format of the output file
  is defined as:
  - an integer specifying the number of axes.
  - an integer specifying the number of characters in the zero terminated
     axisname
  - the axis name
  - an integer specifying n0
  - doubles specifying min0, max0, d0
  - a repeat of items 2-5 for the second axis, and again for the third
  - then n0*n1*n2 doubles storing the data in c order
  Note that this will not be machine portable because of endianess and
  the sizes of various outputs.  Unlike the version which writes in text,
  here we don't care if the axisnames have spaces in them.
  \param[in] filename The file to write the data to
*/


/*!
  Collapse the grid along the specified axis by summing.
  \param[in] axisnum Index of axis.  A CosFitterExcpt is thrown if this is
              out of range
  \returns A cosgrid2D containing the collapsed data array
*/


/*!
  Collapse the grid along the specified axes by summing.
  \param[in] axisnum1 Index of 1st axis.  A CosFitterExcpt is thrown if this is
              out of range
  \param[in] axisnum2 Index of 2nd axis.  A CosFitterExcpt is thrown if this is
              out of range
  \returns A cosgrid1D containing the collapsed data array
*/


/*!
  Collapse the grid along the specified axes by summing.
  \param[in] axisname1 Name of 1st axis.  A CosFitterExcpt is thrown if this is
              out of range
  \param[in] axisname2 Name of 2nd axis.  A CosFitterExcpt is thrown if this is
              out of range
  \returns A cosgrid1D containing the collapsed data array
*/


/*! Returns index of axis with the specified name, throwing a CosFitterExcpt
 if no such axis is found.
 \param[in] axislabel Name of axis to find
 \returns Index of matching axis
*/


/*!
  \param[out] i0 Index of maximum along axis 0
  \param[out] i1 Index of maximum along axis 1
  \param[out] i2 Index of maximum along axis 2
  \param[out] i3 Index of maximum along axis 3
  \returns The maximum value
*/


/*!
  \returns The total of all of the elements in the grid
*/


/*!
  \returns The previous total of all of the elements in the grid prior
     to normalization
*/


/*!
  Serializes the contents of the data array and the axis labels to a file
  in a human readable format.  The format of the output file is defined as:
  - The first line is Naxes: 4
  - The second line is axisname0, n0, min0, max0, d0
  - The third line is axisname1, n1, min1, max1, d1
  - The fourth line is axisname2, n2, min2, max2, d2
  - The fifth line is axisname3, n3, min3, max3, d3
  - This is followed by n0*n1*n2*n3 lines containing the data values in c++
     style order (i.e., the axis3 index changes the most rapidly)
  \param[in] filename The file to write the data to
*/


/*!
  Serializes the contents of the data array and the axis labels to a file
  in a non human readable, binary, format.  The format of the output file
  is defined as:
  - an integer specifying the number of axes.
  - an integer specifying the number of characters in the zero terminated
     axisname
  - the axis name
  - an integer specifying n0
  - doubles specifying min0, max0, d0
  - a repeat of items 2-5 for the second, third, and fourth
  - then n0*n1*n2*n3 doubles storing the data in c order
  Note that this will not be machine portable because of endianess and
  the sizes of various outputs.  Unlike the version which writes in text,
  here we don't care if the axisnames have spaces in them.
  \param[in] filename The file to write the data to
*/


/*!
  Collapse the grid along the specified axis by summing.
  Note that the efficiency of this operation varies considerably
  depending on which axies are summed over.  Generally, summing over
  later indicides is far faster than earlier ones.

  \param[in] axisnum Index of axis.  A CosFitterExcpt is thrown if this is
              out of range
  \returns A cosgrid3D containing the collapsed data array
*/


/*!
  Collapse the grid along the specified axes by summing.
  Note that the efficiency of this operation varies considerably
  depending on which axies are summed over.  Generally, summing over
  later indicides is far faster than earlier ones.

  \param[in] axisnum1 Index of 1st axis.  A CosFitterExcpt is thrown if this is
              out of range
  \param[in] axisnum2 Index of 2nd axis.  A CosFitterExcpt is thrown if this is
              out of range
  \returns A cosgrid2D containing the collapsed data array
*/


/*!
  Collapse the grid along the specified axes by summing.
  \param[in] axisname1 Name of 1st axis.  A CosFitterExcpt is thrown if this is
              out of range
  \param[in] axisname2 Name of 2nd axis.  A CosFitterExcpt is thrown if this is
              out of range
  \returns A cosgrid2D containing the collapsed data array
*/


/*!
  Collapse the grid along the specified axes by summing.
  Note that the efficiency of this operation varies considerably
  depending on which axies are summed over.  Generally, summing over
  later indicides is far faster than earlier ones.

  \param[in] axisnum1 Index of 1st axis.  A CosFitterExcpt is thrown if this is
              out of range
  \param[in] axisnum2 Index of 2nd axis.  A CosFitterExcpt is thrown if this is
              out of range
  \param[in] axisnum3 Index of 3rd axis.  A CosFitterExcpt is thrown if this is
              out of range
  \returns A cosgrid1D containing the collapsed data array
*/


/*!
  Collapse the grid along the specified axes by summing.
  Note that the efficiency of this operation varies considerably
  depending on which axies are summed over.  Generally, summing over
  later indicides is far faster than earlier ones.

  \param[in] axisname1 Name of 1st axis.  A CosFitterExcpt is thrown if this is
              out of range
  \param[in] axisname2 Name of 2nd axis.  A CosFitterExcpt is thrown if this is
              out of range
  \param[in] axisname3 Name of 3rd axis.  A CosFitterExcpt is thrown if this is
              out of range
  \returns A cosgrid1D containing the collapsed data array
*/


/*!
  \param[in] axislabel Name of axis
  \returns Index (0,1,2,3,4) of matching axis
*/


/*!
  \param[out] i0 Index of maximum along axis 0
  \param[out] i1 Index of maximum along axis 1
  \param[out] i2 Index of maximum along axis 2
  \param[out] i3 Index of maximum along axis 3
  \param[out] i4 Index of maximum along axis 4
  \returns The maximum value
*/


/*!
  \returns The previous total of all of the elements in the grid
            prior to normalization
*/


/*!
  Serializes the contents of the data array and the axis labels to a file
  in a human readable format.  The format of the output file is defined as:
  - The first line is Naxes: 5
  - The second line is axisname0, n0, min0, max0, d0
  - The third line is axisname1, n1, min1, max1, d1
  - The fourth line is axisname2, n2, min2, max2, d2
  - The fifth line is axisname3, n3, min3, max3, d3
  - The sixth line is axisname4, n4, min4, max4, d4
  - This is followed by n0*n1*n2*n3*n4 lines containing the data values in c++
     style order (i.e., the axis4 index changes the most rapidly)
  \param[in] filename The file to write the data to
*/


/*!
  Collapse the grid along the specified axis by summing.
  Note that the efficiency of this operation varies considerably
  depending on which axies are summed over.  Generally, summing over
  later indicides is far faster than earlier ones.

  \param[in] axisnum Index of axis.  A CosFitterExcpt is thrown if this is
              out of range
  \returns A cosgrid4D containing the collapsed data array
*/


/*!
  Collapse the grid along the specified axes by summing.
  Note that the efficiency of this operation varies considerably
  depending on which axies are summed over.  Generally, summing over
  later indicides is far faster than earlier ones.

  \param[in] axisnum1 Index of 1st axis.  A CosFitterExcpt is thrown if this is
              out of range
  \param[in] axisnum2 Index of 2nd axis.  A CosFitterExcpt is thrown if this is
              out of range
  \returns A cosgrid3D containing the collapsed data array
*/


/*!
  Collapse the grid along the specified axes by summing.
  Note that the efficiency of this operation varies considerably
  depending on which axies are summed over.  Generally, summing over
  later indicides is far faster than earlier ones.

  \param[in] axisname1 Name of 1st axis.  A CosFitterExcpt is thrown if this is
              out of range
  \param[in] axisname2 Name of 2nd axis.  A CosFitterExcpt is thrown if this is
              out of range
  \returns A cosgrid3D containing the collapsed data array
*/


/*!
  Collapse the grid along the specified axes by summing.
  Note that the efficiency of this operation varies considerably
  depending on which axies are summed over.  Generally, summing over
  later indicides is far faster than earlier ones.

  \param[in] axisnum1 Index of 1st axis.  A CosFitterExcpt is thrown if this is
              out of range
  \param[in] axisnum2 Index of 2nd axis.  A CosFitterExcpt is thrown if this is
              out of range
  \param[in] axisnum3 Index of 3rd axis.  A CosFitterExcpt is thrown if this is
              out of range
  \returns A cosgrid2D containing the collapsed data array
*/


/*!
  Collapse the grid along the specified axes by summing.
  Note that the efficiency of this operation varies considerably
  depending on which axies are summed over.  Generally, summing over
  later indicides is far faster than earlier ones.

  \param[in] axisname1 Name of 1st axis.  A CosFitterExcpt is thrown if this is
              out of range
  \param[in] axisname2 Name of 2nd axis.  A CosFitterExcpt is thrown if this is
              out of range
  \param[in] axisname3 Name of 3rd axis.  A CosFitterExcpt is thrown if this is
              out of range
  \returns A cosgrid2D containing the collapsed data array
*/


/*!
  \param[in] sne      List of SN
  \param[in] fparam   parameters of fit
*/


/*!
  \param[in] sn       List of SN
  \param[in] fparam   Parameters of fit
  \param[in] verbose  Show progress meter
*/


/*!
  \param[in] om       \f$\Omega_m\f$
  \param[in] ode      \f$\Omega_{DE}\f$
  \param[in] w0       \f$w_0\f$
  \param[in] wa       \f$w_a\f$
  \param[in] sn       List of SN
  \param[in] verbose  Show progress meter
*/


/*!
  \param[in] cosgrid  Grid of cosmological parameters
  \param[in] sne      List of SN
  \param[in] fparam   parameters of fit
*/


/*!
  \param[in] cosgrid  Grid of cosmological parameters
  \param[in] sne       List of SN
  \param[in] fparam    Parameters of fit
*/


/*!
  \param[in] cosgrid  Grid of cosmological parameters
  \param[in] sne      List of SN
  \param[in] fparam   Parameters of fit
*/


//We avoid exceptions and most run-time error checking for
//performance reasons, so be careful.
/*!
  Sets all the elements of the vectors to zero.
*/


/*!
  \param[in] A  Matrix to copy
*/


/*!
  We don't check to make sure the vectors are the same size,
  so be careful.  The input u should be in column major order
  (i.e., Fortran convention)
*/


/*!
  This doesn't propogate boundary checks for performance reasons, so be careful
*/


/*!
  \param[in] idx  Index array to reorder with.  The boundaries are
                  not checked, nor are repeats.  Must be of length n_.
*/


/////////////////////////////////////////////////////////////////////
/*!
  Sets all the elements of the vectors to zero.
*/


/*!
  \param[out] cov The covariance matrix in standard form
  \param[in] diag The diagonal elements of the cov matrix
  \param[in] alpha The stretch correction parameter -- set to 0 to ignore
  \param[in] beta The colour correction parameter -- set to 0 to ignore
  \returns A reference to the Woodbury Cov matrix
*/


/*!
  \param[out] invcov The inverse covariance matrix in normal form
  \param[in] diag The diagonal elements of the cov matrix
  \param[in] alpha The stretch correction parameter -- set to 0 to ignore
  \param[in] beta The colour correction parameter -- set to 0 to ignore
  \param[out] status Status variable -- 0 if everything is copacetic
  \returns A reference to the Woodbury Cov matrix
*/


/*!
  \param[in] filename0 File to read \f$m_B\f$ matrix from
  \param[in] filenamea File to read \f$s\f$ matrix from
  \param[in] filenameb File to read \f$\mathcal C\f$ matrix from
*/


/*!
  \param[in] filename0 File to write \f$m_B\f$ matrix to
  \param[in] filenamea File to write \f$s\f$ matrix to
  \param[in] filenameb File to write \f$\mathcal C\f$ matrix to
*/


//Adds header keywords to fp reflecting fit parameters


/**
 * MKL Blas and OpenBlas implementation use multithreading by default, which
 * tends to play badly with sourcextractor++ own multithreading.
 * We disable multithreading here *always* as enabling multithreading causes bugs
 */


/// Return the arguments that the program accepts


/**
 * Intercepts writes to a file descriptor old_fd into a pipe, and returns the reading end
 * @param old_fd
 *    File descriptor to intercept
 * @param backup_fd
 *    Duplicate the file descriptor and put it here, so we can restore later
 * @return
 *    A new file descriptor, corresponding now to the read end of the intercepting pipe
 */


/**
   * Initialize the ncurses screen
   * @param outfd
   *    File descriptor to use for output
   * @param infd
   *    File descriptor to use for input
   */


/**
 * Intercept SIGTSTP (Ctrl+Z)
 */


/**
 * Intercept SIGCONT (after fg, for instance)
 */


/**
 * Intercept SIGWICH (resize)
 */


/**
   * Constructor
   * @param display_height
   *    Displayed height on the screen. The actual pad height is handled internally.
   * @param display_width
   *    Displayed width on the screen.
   * @param display_y
   *    Y position on the screen.
   * @param display_x
   *    X position on the screen.
   * @param bar_color
   *    Color for the progress bar
   * @param ind_color
   *    Color for the bar indicator
   */


/**
   * Write into the widget
   */


/**
   * Update the screen size
   */


/**
   * Allow to scroll the pad
   * @note Scroll is a ncurses macro, so we can not use it as a name :(
   */


/**
   * Handle key presses (scrolling)
   */


/**
   * Draw scroll marker
   */


/**
   * Draw log lines
   */


/**
   * Update and redraw the progress information
   */


/**
   * Draw the elapsed counter
   */


/**
   * Draw the set of progress bar/report on the bottom of the screen
   */


/**
   * Main UI thread. All (almost) ncurses handling should be done here, as it is not thread safe
   */


/**
   * When we enter we are in ncurses, when we exit we are not (yay RAII)
   */


/**
   * Constructor
   * @note
   *    Intercepts stdout and stderr and starts up the UI thread
   */


/**
   * Update the progress information
   */


/**
 * Render a Sersic model, using old sharp.
 * The central area is oversampled, so the "missing flux" is spread across the central pixels
 */


//  po::options_description defineSpecificProgramOptions() override {
//    po::options_description config_options { "TestImage options" };
//
//    // Add the specific program options
//    config_options.add_options()
//        ("output", po::value<string>()->required(), "filename to save the created test image")
//        ;
//
//    return config_options;
//  }


/*
 * boost::upgrade_lock can only be acquired by a single thread, even if none of them
 * ends needing an exclusive lock. Cache lookup must be done with a shared_lock instead
 * so multiples can retrieve from the cache at the same time.
 */


/**
 * Translate the return code from wcspih to an elements exception
 */


/**
 * Translate the return code from wcss2p and wcsp2s to an elements exception
 */


/**
 * Extract the keywords from the headers
 */


/**
 * Look for some known inconsistencies that wcslib will not report
 */


/**
 * Wrap wcslib error report and display them via logger
 */


/**
 * wcslib < 5.18 is not fully safe thread, as some functions (like discpy, called by lincpy)
 * rely on global variables for determining the allocation sizes. For those versions, this is called
 * instead, wrapping the call with a mutex.
 */


/**
 * Cast a string to a C++ type depending on the format of the content.
 * - if only digits are present, it will be casted to int64_t
 * - if it matches the regex (one dot and/or exponent present), it will be casted to double
 * - if there is one single character, it will be casted to char
 * - anything else will be casted to std::string, removing simple quotes if necessary
 */


/// Not all coefficient matrices have the proper dimensionality


/// Too many coefficients


/// There is only a constant coefficient, so the coordinates must not matter


// Previous tests are easy to reason about, and even can be verified with pen and paper.
// However, they are small (3x3) and with "simple" values
// This one uses a linear variable PSF extracted from a real PsfEx file,
// so it is more complex (25x25), and imply moving around the limits of the numbers that can
// be represented by a float.
// Note that the expected value was computed with a Python prototype that was validated
// against the PSF snapshot created by PsfEx, so this kind of expects the validation to be
// commutative :)


// This one is yet more complicated.
// It has been extracted from a PsfEx file, 45x45, and the degree is 3


/**
 * Ask for chunks that cross the X boundary between two tiles
 */


/**
 * Ask for chunks that cross the X boundary across multiple tiles
 */


/**
 * Ask for chunks that cross the Y boundary between two tiles
 */


/**
 * Ask for chunks that cross the Y boundary across multiple tiles
 */


/**
 * Ask for chunks that cross both X and Y
 */


/**
 * Ask for chunks that cross both X and Y across multiple tiles
 */


// Access from bottom right to top left


// Give a hint that we will read around the pixel, so a single access is required


//-----------------------------------------------------------------------------
// There are two close missing pixels. They should not influence each other
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// Median with a box size of 3x3
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// Box with 3 pixels wide, 1 pixel tall
//----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// Box with 1 pixel wide, 3 pixels tall
//----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// Verify that the histogram result matches the implementation before refactoring
//-----------------------------------------------------------------------------


// Frame0 pixels are 4x as big as the detection frame (x2 in each dimension)
// Frame1 pixels are 9x as big as the detection frame (x3 in each dimension)
// Max and step size must be set accordingly


// Frame0 is rotated 90, and scaled 2x
// Frame1 is flipped on the X axis, so so no effect is expected


// Ask for the GrowthCurve property on a frame where the source is out of bounds


// Asking for the flux fraction 0 (or negative) should give 0
// Note that the configuration should catch these, but the code should be robust


// Asking for the flux fraction > 1 should give the last bin, and 1 the first where the CDF = 1
// Note that the configuration should catch these, but the code should be robust


/**
 * Every pixel in the detection image corresponds to 4 on the measurement image (square of 2x2)
 */


/**
 * Measurement frame is deformed
 */


// Adds the source_image to the target image scaled by scale_factor and centered at x, y


/**
 * Generate a property name based on domain, graph name and output name
 */


// So we first convert the Python parameter to our internal coordinates, then do the transformation of coordinate,
// subtract the offset to the image cut-out and shift the result by 0.5 pixels


// Used to set a dummy property in case of error that contains no result but just an error flag


/*
 * Reading in a stacked PSF as it is being developed for co-added images in Euclid
 */


/// Reads a PSF from a fits file. The image must be square and have sides of odd
/// number of pixels.


/// Handles a new Source


/// Handles a ProcessSourcesEvent to trigger the processing of some of the Sources stored in SourceGrouping


// Depth-first search of taxonomy tree, reporting info at each node


/**
 * Encode the 64-bit hash code x as an 32-bit integer, to be used in the sparse representation.
 *
 * Difference from the algorithm described in the paper:
 * The index always is in the p most significant bits
 *
 * see section 5.3 in Heule et al.
 * @param x the hash bits
 * @return encoded hash value
 */


/**
 * Bias correction factors for specific m's
 * @param m
 * @return
 */


/**
 * Gives the estimated cardinality for m bins, v of which are non-zero
 * using linear counting of Whang et al., 1990: n_hat = -m ln(v)
 * @param m number of bins in the matrix
 * @param v number of non-zero bins
 * @return
 */


/**
 * calculate the raw estimate as harmonic mean of the ranks in the register
 */


/**
 * returns a 'register histogram' vector C,
 *  where C[i] is the number of elements in M with value i
 *  it's size is q+1 = 64-p+1
 * used in Ertl's improved estimator
 */


/**
 * Ertl - calculation of sigma correction for 0-registers in M
 *  x is the proportion of 0-registers, thus x \in [0, 1]
 *  sigma := x + sum[from k=1 to Inf] ( x^(2^k) * 2^(k-1) )
 */


// modification of the implementation - currently not used


/**
 * Ertl - calculation of tau correction for values higher then q in M
 *  x is the proportion of registers with a value below q in M, thus x \in [0,1]
 *  tau := 1/3 (1 - x - sum[from k=1 to Inf](1-x^(2^(-k))^2 * 2^(-k) ))
 */


/**
 * from Numerical Recipes, 3rd Edition, p 352
 * Returns hash of u as a 64-bit integer.
 *
 */


// A quick but nondeterministic build


// Slightly slower but deterministic when multithreaded


// This function exists to deal with NCBI's use of \x01 characters to denote
// the start of a new FASTA header in the same line (for non-redundant DBs).
// We return all sequence IDs in a header line, not just the first.


// Mark the given taxonomy node and all its unmarked ancestors


// Logic here depends on higher nodes having smaller IDs
// Idea: advance B tracker up tree, A is ancestor iff B tracker hits A


// Logic here depends on higher nodes having smaller IDs
// Idea: track two nodes, advance lower tracker up tree, trackers meet @ LCA


// Dump binary data to file


// Linear probing may be ok for accuracy, as long as occupancy is < 95%
// Linear probing leads to more clustering, longer probing paths, and
//   higher probability of a false answer
// Double hashing can have shorter probing paths, but less cache efficiency


// Main state machine to parse arguments


// match filename to output pattern
// esp_output_[PLANETNAME]_[OUTPUT_NUMBER].h5
// returns planet name and output number


// define all the variables we can check in the debugging functions


// Check if output log file exists in output_directory and has data
// returns true if exists and found names of output files, false if not
// if exists, returns name of last written output file, last file number, and iteration number
// throws an exception if it couldn't parse the file or open the file


/*! This function uses the 'inputFileType' entry in the userOptions class to decide on the function that will be used to read the input data. */


/*! This function reads the particle data used for the DTFE computation. */


/*! This function writes the output data to a file, each different 'variable' being written to a separate file.
You can modify this function as you please. */


/* This function interpolates the density and velocity to grid using the TSC (triangular shape cloud) method. */


/* This function uses the TSC method to interpolate quantities to a grid. It interpolates only the density and the velocity.
NOTE: It does not interpolate the velocity to the grid, but in fact the momentum. The velocity is than obtained as the momentum in the cell divided by the mass in the grid cell.
*/


/* This function interpolates the density and velocity to grid using the NGP (cloud in cell) method. */


/* This function uses the NGP method to interpolate quantities to a grid. It interpolates only the density and the velocity.
NOTE: It does not interpolate the velocity to the grid, but in fact the momentum. The velocity is than obtained as the momentum in the cell divided by the mass in the grid cell.
*/


/* This function counts how many particles are in each cell of a grid using the NGP method. */


/* This function interpolates fileds to a grid using the DTFE method.
It takes the following arguments:
        allParticles - stores the particle positions, velocities, scalars (if any) and weights
        samples - stores the position of the grid points where samples are taken (if this grid points don't have a uniform distribution)
        userOptions - options specified by the user plus additional program wise variables
        uQuantities - structure that will store the output quantities - i.e. the fields at the sampling points (NOTE: "uQuantities" stands for "unaveraged quantities" meaning that this fields were NOT averaged over the sampling cell)
        aQuantities - structure that will store the volume averaged output quantities - i.e. the fields volume averaged over the sampling cells (NOTE: "aQuantities" stands for "averaged quantities")

NOTE: This function clears the vector 'allParticles'. */


/* Calls the function corresponding to the chosen interpolation method. */


/* This function splits the data in several partitions that can be used by shared memory processors to do the computations in parallel. It uses the OpenMP directives for doing so. */


//! Velocity derivative quantities
/* Computes the velocity divergence from the velocity gradient. */


/* Computes the velocity shear from the velocity gradient. */


/* This function computes the velocity divergence, shear and vorticity. */


/* This function interpolates the density and velocity to grid using the SPH (smoothed particle hydrodynamics) method. */


/* Computes the values of the SPH smoothing kernel (except the h^-2 (in 2D) and h^-3 (in 3D) normalizeation factor). */


/* Computes the derivative of the SPH smoothing kernel (except the h^-2 (in 2D) and h^-3 (in 3D) normalizeation factor). */


/* Function that returns the constant in front of W(r,h), constant that depends only on h. */


/* This function uses the SPH method to interpolate quantities to a grid.
NOTE: The algorithm implemented here is described at: http://ciera.northwestern.edu/StarCrash/manual/html/node7.html
It has the following steps:

    1) Loop over all particles - for each particle (here denoted by i) define h_i=R/2 where R is the distance to the N-th closest neighbor. Within the same loop assign the W(r_ij,h_i) part of the contribution to the particle density of neighbor j. (The full expression for density is: \rho = \sum_j m_j 1/2 [W(r_ij,h_i) + W(r_ij,h_j)]. )

    2) Loop over all the density grid points and assign a smoothing length to each cell (h_cell=R/2 where R is the sphere in which we find the N-th closest particle neighbors). Use this loop to also add the first part of the SPH smoothing kernel (similar to above).

    3) Loop again over all particles to assign the 2nd part of the smoothing kernel to the grid quantity. This can be done via two methods:
        - for a regular grid, loop over all the grid points that are with r<h_i for particle i.
        - construct a tree from the grid point distribution and use tree searching algorithms to find all the grid points with h_i distance from particle i.
*/


//print help information to the user


/* Print to the user what options the program will use. */


/* Updates the values of the full box. */


/* Updates some of the members of the class after reading the input data file.
NOTE: This function does additional error checks on the values of the 'User_options' class members. */


/* Computes the values of the padding length. */


/* Function used to copy the results obtain on a subgrid using the option 'partion' to the results for the full grid.
NOTE: For additional details on how to compute the 'subgrid' and 'subgridOffset' check the function 'subgridAxesSize' in the file 'subpartition.h'. */


/* Returns what is the size of any non-empty object.
NOTE: All non-empty objects should have the same size. */


/* This function reserves memory for the main grid quantities when using the 'partition' option. */


/* This function interpolates the density and velocity to grid using the CIC (triangular shape cloud) method. */


/* This function uses the CIC method to interpolate quantities to a grid. It interpolates only the density and the velocity.
NOTE: It does not interpolate the velocity to the grid, but in fact the momentum. The velocity is than obtained as the momentum in the cell divided by the mass in the grid cell.
*/


/* This function selects from the input data a random subsample, with the subsample size given by 'User_options::randomSample'. */


/* This function generates random particles in a box of unit length. */


/* Your custom functions for reading the input data. */


/* Your custom function for writting the output data to a file. */


/*! This function reads a Gadget snapshots saved in a single or multiple files.

NOTE: This function is a not the best choice to understand how to read input data for users unfamiliar with the Gadget snapshot files. */


/*! Function that counts how many particles are in a Gadget file snapshot that was saved in multiple files.
*/


/*! This function reads the gadget data from a single file. This function should be called from within a loop to read a gadget snapshot saved in multiple files.
*/


// constructor - initializes to 0 or to non-assigned value (=-1)


// print the content of the density header to the standard output


// update entries in the header using the userOptions class


// copy information from the gadget header


/*! Reads the Gadget data from a single HDF5 file. This function should be called to do the actual data reading for snapshots saved in single or multiple files.
*/


/*! The function that reads the data from single or multiple HDF5 files.
*/


// return the file name for a Gadget snapshot saved in single or multiple files - note that the name must contain a '%i' or '%s' character


// Function that prints the Gadget header.


// Checks for the type of the Gadget file -> can detected Gadget file type 1 & 2. Returns true if it could identify the gadget file type.


/*! Return the file name for the input data saved in a single or in multiple files
 * NOTE:  that the name must contain a '%i' or '%s' character for multiple files
*/


/*! Reads some of the entries for the header of the HDF5 file.
NOTE: it does not read all the entries, it only reads the particle number in the file, the mass, the box length and the number of files per snapshot.
*/


/*! Read the file header for and intialize some of the values in the userOptions class.
*/


/*! Reads the DESI data from an single HDF5 file. This function should be called to do the actual data reading for snapshots saved in single or multiple files.
*/


/*! This function reads a Gadget snapshots saved in a single or multiple files.
 *  It also reads the GR and MOG forces from a separate file.
 * */


/*! This function reads the forces from a binary file.
*/


/* This function shows an example of how to read the particle data from a text file. The text file has the following data:
    1 line: number of particles
    2 line: "xMin xMax yMin yMax zMin zMax" for the box fully encompassing the given particle data
    3rd line: "posX posY posZ velX velY velZ weight scalar" for the 1st particle
    rest of the lines: same as line 3, but for the other particles

To read the file one must open in. It can do so using functions:
    openInputTextFile( fstream file, string filename ) - to open a text file for reading
    openInputBinaryFile( fstream file, string filename ) - to open a binary file for reading

After reading the number of particle in the file, memory can be reserved for reading the data. One can do so using the function "Read_data::position(size_t noParticles)" which allocates memory for storing NO_DIM*noParticles 'Reals' that are the particle positions. The function returns a pointer to the allocated emory block, so a typical call of the function is:
    Real *positions = readData->position( noParticles );
Once the memory for storing particle positions was allocated, the pointer to the memory can also be called using:
    Real *positions2 = readData->position();    // this will give an error if no memory was allocated beforehand
One has similar functions for allocating memory for the rest of the particle properties quantities:
    position:
                Real* Read_data :: position( size_t noParticles );  //allocate memory and return pointer
                Real* Read_data :: position();  // return pointer (can be called only after calling the previous function)
    velocity:
                Real* Read_data :: velocity( size_t noParticles );  //allocate memory and return pointer
                Real* Read_data :: velocity();  // return pointer
    weight:
                Real* Read_data :: weight( size_t noParticles );  //allocate memory and return pointer
                Real* Read_data :: weight();  // return pointer
    scalar:
                Real* Read_data :: scalar( size_t noParticles );  //allocate memory and return pointer
                Real* Read_data :: scalar();  // return pointer
NOTE: When calling the above functions the number of particle has to be the same for position, velocity, weight and scalar.
*/


/* This function reads only the particle positions from a text file that contains only the positions. */


/* Example of how to read the particle positions from a text file and also how to read in user defined sampling points for the grid where to interpolate the output fields. */


/* This function writes the data to a text file.
 The field components at each sampling point are written in a single line, in different columns (i.e. number of columns = number of field components at a given point).*/


/* This function writes the data to a text file.
On each line it writes:
        1) the grid indices
        2) the field value at that grid position (writes all the field components in different columns)
*/


/* This function writes the data to a text file. This particular function works only for regular rectangular grids (you can write a similar version for redshift coordinate grids).
On each line it writes:
        1) the coordinates of the sampling point
        2) the field value at that sampling point (writes all the field components in different columns)
*/


/* This function writes the data to a text file. This particular function works only for regular rectangular grids (you can write a similar version for redshift coordinate grids).
On each line it writes:
        1) the coordinates of the sampling point (can choose between (r,theta,psi) or (x,y,z) )
        2) the field value at that sampling point (writes all the field components in different columns)
*/


/* This function reds the input data from a binary file.
This function works when the binary file has the following format:
    1) file begins with an int value that gives the number of particles
    2) continues with 6 float values that give the coordinates of the box encompassing the data (i.e. xMin, xMax, yMin, yMax, zMin, zMax)
    3) the next part of the file gives the positions of the particles which are saved as x1, y1, z1, x2, y2, z2, x3, ... (with x1 = x coordinate for particle 1, y1 = y coordinate for particle 1, etc ...)
    4) after the particle positions, come the particle weights array saved as w1, w2, w3, ... (with w1 = weight of particle 1, etc ...)
    5) after the weights array, comes the velocity array which are is saved as vx1, vy1, vz1, vx2, vy2, vz2, ... (with vx1 = the velocity along the x direction of particle 1, ...)

NOTE: In this example the data is saved in the binary file in single precision format (float 32 bytes).
*/


/* This function reds the input data from a binary file.
This function works when the binary file has the following format:
    1) file begins with an int value that gives the number of particles
    2) for each particle there are N binary values which give: X, Y, Z, d1, ..., dN-3
    3) Each particle has the above N values, which are stored starting with particle 1 to noParticles

NOTE: In this example the data is saved in the binary file in single precision format (float 32 bytes).
*/


/*! Reads some of the entries for the Gadget header from an HDF5 file.
NOTE: it does not read all the entries, it only reads the particle number in the file, the mass array, the box length and the number of files per snapshot.
*/


/*! Function that counts how many particles are in a Gadget file snapshot that was saved in multiple files. Works only for HDF5 files.
 */


/*! Read the gadget header for one snapshot and intialize some of the values in the userOptions class.
*/


/*! Reads the HI Gadget data using 2 HDF5 files: the first gives the gas content while the second gives the HI fraction. This function should be called to do the actual data reading for snapshots saved in single or multiple files.
 */


/*! The function that reads the HI data from single or multiple HDF5 files.

NOTE_this function reads the HI mass and not the gas mass.
 */


/* This function interpolates the fields to a uniform grid - it computes the volume averaged value of the fields within the grid cell. To compute the volume average in each grid cell it uses a Monte Carlo algorithm to sample 'noRandPoints' in each grid cell and take the average.
The arguments are:
    'dt' - the periodic Delaunay triangulation; with the density at the vertex points already computed
    'userOptions' - structure which store the number of grid points along each axis and the number of random sample points in each grid cell. This structure also gives information about the size of the box along each axis.
    'quantities' - structure storing the vectors for the output fields on the grid
*/


/* This function interpolates the fields to a redshift cone grid (usefull for galaxy surveys) - it computes the volume averaged value of the fields within the grid cell. To compute the volume average in each grid cell it uses a Monte Carlo algorithm to sample 'noRandPoints' in each grid cell and take the average.
The arguments are:
    'dt' - the periodic Delaunay triangulation; with the density at the vertex points already computed
    'userOptions' - structure which store the number of grid points along each axis and also gives information about the size of the box along each axis. It also contains information about what quantity/qunatities to compute.
    'quantities' - vectors storing the interpolated grid fields
*/


/* This function interpolates the fields at user defined sampling points - it computes the volume averaged value of the fields within the grid cell. To compute the volume average in each grid cell it uses a Monte Carlo algorithm to sample 'noRandPoints' in each grid cell and take the average.
The arguments are:
    'dt' - the periodic Delaunay triangulation; with the density at the vertex points already computed
    'userOptions' - structure which store the number of grid points along each axis and also gives information about the size of the box along each axis. It also contains information about what quantity/qunatities to compute.
    'quantities' - vectors storing the interpolated fields
*/


/* Computes the contribution to the input variable for the grid cells given in 'indices'.  */
/* Each entry of the array 'contributions' contains the first 2/3 entries the numbers that need to be multiplied with the gradient to give you the field while the last entry (NO_DIM) contains the intersection volume between the simplex and the grid cell. This needs to be multiplied with the value of the field corresponding to the base vertex of the Delaunay cell (e.g. density_base). */


/* Returns true if the Delaunay cell is outside the region of interest. */


/* Stores a sequence of quasi-random numbers using the GSL quasi-number generator. */


/* Generates quasi-random sample points inside the Delaunay cell: traingle in 2D and tetrahedron in 3D. */


/* Checks the position of a Delaunay Cell and computes the vertices position matrix 'vertexMatrix'.
NOTE: The vertex matrix position is stored as a multiple of the grid spacing along the given coordinate. */


/* Checks if the given grid cell is valid. */


/* Finds the grid cell where the sample point lies and checks if it is a valid grid cell. */


/* Computes the average density in a Delaunay triangle/tetrahedron in 2D/3D. */


/* Print information to the user about the amount of time taken. */


/* Computes the minor determinant coresponding to entry (row,column) of a 3x3 matrix. */


/* Computes the inverse of a 2x2 or 3x3 matrix. */


/* Computes the vertex position difference matrix for a given Delaunay cell. */


/* Checks the values of the angles to give correct interval values and transforms the angles from degrees to radians. */


/* This function computes the grid density in a periodic cosmological box of size [0,1] on each axis. If a non-periodic box is used, than points can have coordinates outside the [0,1] box to give a full Delaunay triangulation cover of the box.
The function arguments are:
        p - vector which stores the particle positions and properties
        samples - vector storing the user defined sampling points, if any
        userOptions - structure to keep track of user given options and parameters for the interpolation
        uQuantities - struture that will hold the output fields, fields interpolated at the sampling points
        aQuantities - struture that will hold the output volume averaged fields, fields volume averaged over the grid cell associated to each sampling point
        dt - the CGAL Delaunay triangulation structure that stores the full triangulation of the point set
*/


// Accesses the above 'DTFE_interpolation', but without returning the Delaunay triangulation


/* Constructs the Delaunay triangulation using a set of points. */


/* The function computes the volume of all Delaunay tetrahedra for each vertex and than computes the density at each vertex as the inverse of the total tetrahedra volumes incident on the respective vertex. */


/* Inserts dummy points to test the efficiency of the padding. */


/* Keep track of the cells that have wrong values of the density. */


/* Checks if there are any cells which may have an error in the density estimation due to an incomplete Delaunay tesselation over the region of interest. */


/* This function returns the inverse of the vertex difference matrix for a given Delaunay cell (triangle/tetrahedron in 2D/3D).*/


/* Returns the relative position of the sample point. */


/* Returns the density associated to a sample point (sample point coordinates are with respect to the base vertex of the Delaunay cell). */


/* Computes the velocity value at the sample point (sample point coordinates are with respect to the base vertex of the Delaunay cell). */


/* Returns the velocity gradient in a 'Pvector<Real,noGradComp>' object. */


/* Computes the scalar value at the sample point (sample point coordinates are with respect to the base vertex of the Delaunay cell). */


/* Returns the scalar gradient in a 'Pvector<Real,noScalarGradComp>' object. */


/* This function interpolates the fields to a uniform grid by computing the field values at the sample points.
The arguments are:
    'dt' - the periodic Delaunay triangulation; with the density at the vertex points already computed
    'userOptions' - structure which store the number of grid points along each axis and also gives information about the size of the box along each axis. It also contains information about what quantity/qunatities to compute.
    'quantities' - vectors storing the interpolated grid fields

NOTE: this does NOT take volume average the fields inside the sampling cell.
*/


/* This function interpolates the fields to a redshift cone grid (usefull for galaxy surveys) by computing the field values at the sample points.
The arguments are:
    'dt' - the periodic Delaunay triangulation; with the density at the vertex points already computed
    'userOptions' - structure which store the number of grid points along each axis and also gives information about the size of the box along each axis. It also contains information about what quantity/qunatities to compute.
    'quantities' - vectors storing the interpolated grid fields

NOTE: this does NOT take volume average the fields inside the sampling cell.
*/


/* This function interpolates the fields at user defined sampling points by computing the field values at the sample points.
The arguments are:
    'dt' - the periodic Delaunay triangulation; with the density at the vertex points already computed
    'userOptions' - structure which store the number of grid points along each axis and also gives information about the size of the box along each axis. It also contains information about what quantity/qunatities to compute.
    'quantities' - vectors storing the interpolated fields

NOTE: this does NOT take volume average the fields inside the sampling cell.
*/


// search for n nearest to a given query vector 'qv'.


/* This function computes the density at the given sample point using the Delaunay cell as input. */


/** Print a demangled stack backtrace of the caller function to FILE* out. */


//A test it the Narayan Ostriker Luminosity makes population visible in Parkes


//A sigma test for a bug


//cuts the population


//should be for the L400


//Narayan, Ostriker 1990


///result in [Jy], freq in [MHz]


///Miyamoto & Nagai potential for Disk
///Mass[1e10Msun]
///fParA,fParB,Position[kpc]


//Potential of the Hernquist's Shperoid
//fMass[1e10Msun]
//fParC,Position[kpc]


//Potential of Paczynski's Halo
//fMass[1e10Msun]
//


//void CModel::ReadBinaryHDF5(const char* FileName)
//{
//	m_pPop->ReadBinaryHDF5(FileName);
//}


//BDecay
//In fact Julia has pretty good macros too.


//Damn... I even used regexp's to write those down.
//Such a waste of macro-potential...


//	void m_AddToMap(const SProbabilitySpacePointRadio SpacePoint);
//
//jak jest element objetosci??


// returns We, effective width of the pulsar (observed in a survey)


// returns S/N for pulsar with flux S


//Do sprawdzania czy kat l jest w prawo (+1.) czy w lewo (-1.)


///fSunAngle - angle between ey(0,1,0) and the SunPos vector. [rad]


/* gal2eq.c

   Converts galactic coordinates to equatorial coordinates.
   2000.0

   Formulas and data from the article
   The 1997 reference of diffuse night sky brightness
   by Leinert et al
   A&A Supplement series, Vol. 127, January I 1998, 1-99
   http://aanda.u-strasbg.fr:2002/articles/aas/full/1998/01/ds1449/ds1449.html
   See also: Caroll: 937

   input:
      l = galactic longitude, from ... to, radians
      b
   output:
      alpha = right ascension angle 0,2pi, radians
      delta - declination angle -pi/2,pi/2, radians

   TO DO
use a define???
    B1950
   l_zero=33*M_PI/180;
   alpha_zero=282.25*M_PI/180;
   delta_NGP=(27.4)*M_PI/180;

*/


//Draw random number from -3sigma + 3sigma from Normal Distribution
//Will be slow :(


// Push new gap, move s count bytes further (skipping the gap).
// Collapse previous gap.


// Collapse all gaps, return past-the-end pointer


// DOCTYPE consists of nested sections of the following possible types:
// <!-- ... -->, <? ... ?>, "...", '...'
// <![...]]>
// <!...>
// First group can not contain nested groups
// Second group can contain nested groups of the same type
// Third group can contain all other groups


// we need to get length of entire file to load it in memory; the only (relatively) sane way to do it is via seek/tell trick


// PrimaryExpr ::= VariableReference | '(' Expr ')' | Literal | Number | FunctionCall


// FilterExpr ::= PrimaryExpr | FilterExpr Predicate
// Predicate ::= '[' PredicateExpr ']'
// PredicateExpr ::= Expr


// Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep
// AxisSpecifier ::= AxisName '::' | '@'?
// NodeTest ::= NameTest | NodeType '(' ')' | 'processing-instruction' '(' Literal ')'
// NameTest ::= '*' | NCName ':' '*' | QName
// AbbreviatedStep ::= '.' | '..'


// LocationPath ::= RelativeLocationPath | AbsoluteLocationPath
// AbsoluteLocationPath ::= '/' RelativeLocationPath? | '//' RelativeLocationPath


// PathExpr ::= LocationPath
//				| FilterExpr
//				| FilterExpr '/' RelativeLocationPath
//				| FilterExpr '//' RelativeLocationPath
// UnionExpr ::= PathExpr | UnionExpr '|' PathExpr
// UnaryExpr ::= UnionExpr | '-' UnaryExpr


/////////////////////////////// Unified Lander Interface ////////////////////////


// PLEXIL application setup functions start here.


// This is the only non-template function so far, which motivated this .cpp file.


//TODO: Add second test case with more tests and clearer outlets


//generate DEM with Perlin Noise


// *** Move semantics, similar to auto_ptr ***


// Report the error condition then exit the process


//This reacts correctly if the flow direction wedge number exceeds 7.


// Standard issue constructor


/// Verify an option name


/// Return a lower case version of a string


/// Find and replace a substring with another substring


/// Check if a string is a member of a list of strings and optionally ignore case or ignore underscores


/// Split a string '"one two" "three"' into 'one two', 'three'
/// Quote characters can be ` ' or "


/// Add a leader to the beginning of all new lines (nothing is added
/// at the start of the first line). `"; "` would be for ini files
///
/// Can't use Regex, or this would be a subs.