!! *Description*:
!!
!! Returns .TRUE. if this StochasticOrbit instance contains an
!! orbital-element pdf in the form of sample orbits and their
!! weights. Otherwise returns .FALSE.
!!


!! *Description*:
!!
!! Automated version of MCMC ranging. Stable version (pre-2015 version, see autoMCMCRanging2)
!!
!! Calls MCMCRanging (earlier: MCMCRanging3).
!!
!! For initialization using either
!!
!!  - no a priori orbit information: Ranging (i.e. uniform proposal)
!!
!!  - orbital distribution from input file
!!


!! *Description*:
!!
!! Automated version of random walk. Calls randomWalkRanging.
!!
!! For initialization using either
!!
!! - no a priori orbit information: Ranging (i.e. uniform proposal)
!!
!! - orbital distribution from input file
!!


!! *Description:*
!!
!! Random-walk ranging method.
!!
!!   - Burn in phase: discard accepted orbits until first chi2 in the phase-space area
!!     defined by dchi2.
!!
!!   - Random-walk option (ran_walk) can be turned off, which reverts the routine to
!!     a version of MCMC ranging
!!


!! *Description:*
!!
!! Markov Chain Monte Carlo ranging method.
!!   - Currently stable version! (Pre-2015 version, see MCMCRanging2)
!!   - Burn in phase: discard accepted orbits until (R.A., Dec.) residual rms are reasonable.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Computation of the least-squares orbital elements (Cartesian or
!! Keplerian) and their covariances in the two-body and full
!! many-body approaches.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Computation of the least-squares orbital elements (Cartesian or
!! Keplerian) and their covariances in the two-body or full
!! many-body approaches using the Levenberg-Marquardt algorithm.
!!
!! Returns error.
!!


! LevenbergMarquardt_private and coefficients are essentially
! identical to the subroutines found in estimators.f90.


!! *Description*:
!!
!! Arrange observations in pairs. Observation mask used.
!!
!! Returns error.
!!
!! Modifications needed:
!! To make ranging more efficient, too close pairs should be avoided.
!! Also, it might be useful to use only observations from the far ends of
!! the data set. Where should this filtering be done?
!!


!! *Description*:
!!
!! Statistical orbital ranging using two astrometric observations.
!! Make use of the multiple orbit propagation scheme. CONTINUE TESTING!
!!
!! Output: Probability density function for Cartesian position and
!!         velocity at specified epoch in two-body approximation.
!!
!! Simplified:
!!      - No random observation selection (note: is available but cannot be used because of the multi-propagation scheme)
!!
!! Returns error.
!!


!!  *Description*:
!!
!! Finds initial values for the full inversion by including the
!! observations one at a time and perfoming a partial inversion.
!! A limited amount of required sample orbits and trial orbits are
!! used during the initiation phase.
!!
!!


!! *Description*:
!!
!! Optimizes the range distribution corresponding to the first and
!! last observation of a set of observations which is a combination
!! of this%obss and the additional observations supplied with this
!! subroutine. For the estimation of the ranges the algorithm
!! selects all orbits which reproduce the observations with
!! acceptable residuals (limit is set by the 1-sigma astrometric
!! uncertainty multiplied by this%accept_multiplier_prm) or, if i<10
!! orbits with acceptable residuals are found, selects the 10-i
!! orbits that produce the smallest rchi2 values.
!!
!! Also updates orb_ml
!! Sets error=.TRUE. if an error occurs.
!!


!! *Description*:
!!
!! Optimizes the range distribution corresponding to the first and
!! last observation of a set of observations which is a combination
!! of this%obss and the additional observations supplied with this
!! subroutine. For the estimation of the ranges the algorithm
!! selects all orbits which reproduce the observations with
!! acceptable residuals (limit is set by the 1-sigma astrometric
!! uncertainty multiplied by this%accept_multiplier_prm) or, if i<10
!! orbits with acceptable residuals are found, selects the 10-i
!! orbits that produce the smallest rchi2 values.
!!
!! Sets error=.TRUE. if an error occurs.
!!


!! *Description*:
!!
!! Updates the StochasticOrbit between subsequent calls
!! of statistical ranging.
!!
!! Updates:
!!      - range bounds, currently from the 3-sigma cutoff values
!!         of the range probability density.
!!      - Minimum chi2
!!      - Optional outlier detection: recognizes outlier observations
!!         and optionally flags them (obs_masks -> .false.).
!!
!!
!! Returns error.
!!


! Prints out residuals for all objects.


! Prints out the mean MCMC residuals for all objects.


! Used to update the mean residuals for MCMC objects after
! each accepted proposal.


! Detects and masks outliers for storb objects
! based on it's mean residuals.


! Detects and masks outliers for storb objects
! based on input residuals.


!! *Description*:
!!
!! Sets the mask of all Gaia observations in to false.
!! Used in e.g. mass_estimation_mcmc.


!! *Description*:
!! Sets the mask of percentage% Gaia observations to true.
!! Used in e.g. mass_estimation_mcmc.


!! *Description*:
!!
!! Initializes a new Observations instance with default values.
!!
!! Returns _error_ =
!!     - _false_, if everything is ok.
!!     - _true_, if this object already has been initialized or
!!               something goes wrong.
!!
!! *Usage*:
!!
!! <pre>
!! type (Observations) :: obss
!! .
!! .
!! .
!! call new(obss)
!! </pre>


!! *Description*:
!!
!! Initializes a new Observations instance. Reads the given
!! observations file, transforms the dates to a Julian dates,
!! target coordinates to radians and observatory codes to
!! geocentric equatorial coordinates in AUs of the observatories.
!!
!! Returns _error_ =
!!     - _false_, if everything is ok.
!!     - _true_, if this object already has been initialized or
!!               something goes wrong.
!!
!! *Usage*:
!!
!! <pre>
!! type (Observations) :: obss
!! type (File)         :: myfile
!! .
!! .
!! .
!! call new(myfile,"myfilen.ame")
!! call open(myfile)
!! call new(obss, myfile)
!! </pre>
!!


!! *Description*:
!!
!! Initializes a new Observations instance using the given
!! Observation object.
!!
!! Returns _error_ =
!!     - _false_, if everything is ok.
!!     - _true_, if this object already has been initialized or
!!               something goes wrong.
!!
!! *Usage*:
!!
!! <pre>
!! type (Observations) :: obss
!! type (Observation)  :: myobs
!! .
!! .
!! .
!! call new(obss, myobs)
!! </pre>
!!


!! *Description*:
!!
!! Initializes a new Observations instance using the given
!! array of Observation objects.
!!
!! Returns _error_ =
!!     - _false_, if everything is ok.
!!     - _true_, if this object already has been initialized or
!!               something goes wrong.
!!
!! *Usage*:
!!
!! <pre>
!! type (Observations) :: obss
!! type (Observation), dimension(7) :: myobs_arr
!! .
!! .
!! .
!! call new(obss, myobs_arr)
!! </pre>
!!


!! *Description*:
!!
!! Nullifies this object, i.e. deallocates arrays and
!! sets default values to parameters.
!!
!! *Usage*:
!!
!! <pre>
!! type (Observations) :: obss
!! .
!! .
!! .
!! call nullify(obss)
!! </pre>


!! *Description*:
!!
!! Returns a copy of this object.
!!
!! Returns error if allocation fails.
!!


!! *Description*:
!!
!! Adds Gaussian deviates to the observations, optionally using a
!! mask. The new center relative to the original coordinates and the
!! covariance matrices should be given in radians for the angular
!! space coordinates, AUs for distance, radians per day for angular
!! velocities and AUs per day for line-of-sight velocity. If mask is
!! present, apply only for observations for which mask is true.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Adds uniform deviates to the observations (i), optionally using a
!! mask. The center relative to the original state and the absolute
!! values of the boundary values ((i,j,1)=center,
!! (i,j,2)=abs(boundary), position j=1:3 and velocity j=4:6) should
!! be given in radians for the angular space coordinates, AUs for
!! distance, radians per day for angular velocities and AUs per day
!! for line-of-sight velocity.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Returns the sum of two objects, i.e. one object that contains all
!! observations from both original objects.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Adds a single observation to this object.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Removes multiple instances of the identical observations,
!! reallocates the observation arrays, and sorts the data according
!! to (1) designations and (2) numbers..
!!
!! Returns error.
!!


!! *Description*:
!!
!! Returns true, if there are different coordinates for simultaneous
!! observations from the same observatory code.
!!


!! *Description*:
!!
!! Groups a set of observations into subgroups based on observation
!! date and number of observations.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Intrinsic routine that reads a file of the given format.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Intrisic routine that reads a file of elgb-format (used by Ted B.).
!!
!! Returns error.
!!


!! *Description*:
!!
!!
!!
!!
!! Returns error.
!!


!! *Description*:
!!
!! Reallocates a pointer array of Observations-objects and
!! copies the existing (not-nullified) data from the old array to
!! the new array (if it fits).
!!
!! *Usage*:
!!
!! myobservations => reallocate(myobservations,4)
!!
!! Returns error.
!!


!! *Description*:
!!
!! Internal routine. Searches for different objects (different (1)
!! number or (2) designation) and updates the total number of
!! observations. Updates the index vector, which is used to
!! sort the observations in order of ascending epoch.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Writes the observations in specified format to the given logical unit.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Collapses a Gaia transit into a single normal point. See Fedorets
!! et al. (2018), A&A 620, A101
!!
!! Returns error.
!!


!! *Description*:
!!
!! Complementary function for Gaia transits. Calculates the
!! midpoint time of a single Gaia transit.
!!


!! *Description*:
!!
!! Complementary function for Gaia transits. Calculates the
!! midpoint position of a single Gaia transit.
!!


!! *Description*:
!!
!! Complementary function for Gaia transits. Calculates the
!! midpoint velocity of a single Gaia transit.
!!


!! *Description*:
!!
!! Subtract the incorrectly applied relativistic correction from Gaia DR2.
!! Based on code generously shared by F. Mignard. Only use this for DR2 data!
!!


!! *Description*:
!!
!! Initializes a simple File instance, i.e. a scratchfile with
!! sequential access, and both read and write permissions.
!!
!! Returns error.
!!
!! *Usage*:
!!
!! type (File) :: myfile
!!
!! ...
!!
!! call new(myfile)
!!


!! *Description*:
!!
!! Initializes a new File instance. It's a named file (either old
!! or new) with sequential access, and both read and write permissions.
!! Returns _error_ =
!!     - _false_, if everything is ok.
!!     - _true_, if the file name is too long (more than 64 letters)
!!
!! *Usage*:
!!
!! type (File) :: myfile
!!
!! ...
!!
!! call new(myfile, "myfile.dat")
!!


!! *Description*:
!!
!! Closes a file. Returns _error_ =
!!     - _false_, if the file is properly closed, or if it
!!                has not been opened.
!!     - _true_,  if an error occurs during the procedure.
!!
!! *Usage*:
!!
!! type (File) :: myfile
!!
!! ...
!!
!! call closeFile(myfile)
!!


!! *Description*:
!!
!! Returns the status of the object, i.e. whether
!! it exists or not.
!!


!! *Description*:
!!
!! Counts the number of lines in a file, which
!! match a given char.
!! Returns _error_ =
!!     - _false_, no errors occur.
!!     - _true_, if an error occurs during the procedure.
!!
!! *Usage*:
!!
!! type (File) :: myfile
!!
!! integer :: nr_of_lines
!!
!! ...
!!
!! nr_of_lines = MatchCharNrLines(myfile, error)
!!


!! *Description*:
!!
!! Returns
!!     - _true_, if the file has been opened.
!!     - _false_, if the file has not been opened
!!
!! *Usage*:
!!
!! type (File) :: myfile
!!
!! logical :: open
!!
!! ...
!!
!! open = isOpen(myfile)
!!


!! *Description*:
!!
!! Opens a file. Open specifiers can be altered with the
!! _set_ routines (see below). Returns _error_ =
!!  - _false_, if the file is opened, or if it already has been
!!             opened.
!!  - _true_,  if an error occurs during the procedure.
!!
!! *Usage*:
!!
!! type (File) :: myfile
!!
!! ...
!!
!! call openFile(myfile)
!!


!! *Description*:
!!
!! Reads a formatted (_len_ = *) character string (_len_ = *) from
!! file and moves to the following line. Returns _error_ =
!!     - _false_, if the file has been opened and
!!       no errors occured during the procedure.
!!     - _true_, if the file has not been opened, or
!!       an error occured during the procedure.
!!
!! *Usage*:
!!
!! type (File) :: myfile
!!
!! character(len=20) :: mystring
!!
!! character(len=20) :: myformat = "(a30)"
!!
!! ...
!!
!! call readString(myfile, trim(myformat), mystring)
!!


!! *Description*:
!!
!! Reads a singel, list-directed character string (_len_ = *)
!! from file and moves to the following line. Returns _error_ =
!!     - _false_, if the file has been opened and
!!       no errors occured during the procedure.
!!     - _true_, if the file has not been opened, or
!!       an error occured during the procedure.
!!
!! *Usage*:
!!
!! type (File) :: myfile
!!
!! character(len=20) :: mystring
!!
!! ...
!!
!! call readString(myfile, mystring)
!!


!! *Description*:
!!
!! Writes a formatted (_len_ = *) string (_len_ = *) to
!! file and moves to the following line. Returns _error_ =
!!     - _false_, if the file has been opened and
!!       no errors occured during the procedure.
!!     - _true_, if the file has not been opened, or
!!       an error occured during the procedure.
!!
!! *Usage*:
!!
!! type (File) :: myfile
!!
!! character(len=20) :: mystring = "Hello!"
!!
!! character(len=20) :: myformat = "(a10)"
!!
!! ...
!!
!! call writeString(myfile, myformat, mystring)
!!


!! *Description*:
!!
!! Writes a string (_len_ = *) to file and moves
!! to the following line. Returns _error_ =
!!     - _false_, if the file has been opened and
!!       no errors occured during the procedure.
!!     - _true_, if the file has not been opened, or
!!       an error occured during the procedure.
!!
!! *Usage*:
!!
!! type (File) :: myfile
!!
!! character(len=20) :: mystring = "Hello!"
!!
!! ...
!!
!! call writeString(myfile, mystring)
!!


!! *Description*:
!!
!! Given cosinus and sinus of an angle, returns the angle in radians.
!!


!! Description:
!!
!! This routine converts calendar date and time to the corresponding
!! Julian date. The algorithm from Van Flandern and Pulkkinen,
!! Ap.J. Suppl. vol 41, page 392.
!!


!! *Description*:
!!
!! Transforms degrees, arcminutes, and/or -seconds to radians.
!!


!! Description:
!!
!! Converts fractional days to hours, minutes, and seconds. Note
!! that "d" must be positive!
!!


!! *Description*:
!!
!! This routines reports errors in a standard fashion. The first
!! character string is the name of the routine from which this
!! routine is invoked. It is nice to know from where this message
!! originates. The other character string is the error
!! description. The error message is written to the standard error
!! logical unit, and can be presented to the end-user.
!!
!! The standard array of I/O errors can occur but they are ignored
!! because this is an error handling routine and it would be easy
!! to get into an error loop.
!!
!! *Usage*:
!!
!! <pre>
!! use Base_cl !(contains global logical variable "error")
!! .
!! .
!! .
!! subroutine thisroutine(...)
!! .
!! .
!! .
!! if (error) then
!! call errorMessage("thisroutine","Experienced this error.",1)
!! return
!! end if
!! </pre>
!!


!! *Description*:
!!
!! This routines reports warnings in a standard fashion. The first
!! character string is the name of the routine from which this
!! routine is invoked. It is nice to know from where this message
!! originates. The other character string is the warning
!! description. The warning message is written to the standard error
!! logical unit, and can be presented to the end-user.
!!
!! The standard array of I/O errors can occur but they are ignored
!! because this is an error handling routine and it would be easy
!! to get into an error loop.
!!
!! *Usage*:
!!
!! <pre>
!! use Base_cl !(contains global logical variable "error")
!! .
!! .
!! .
!! subroutine thisroutine(...)
!! .
!! .
!! .
!! if (error) then
!! call warningMessage("thisroutine","Experienced this event.",1)
!! return
!! end if
!! </pre>
!!


!! *Description*:
!!
!! Transforms hours, minutes, and/or seconds to radians.
!!


!! *Description*:
!!
!! This routines prints information in a standard fashion. The first
!! character string is the name of the routine from which this
!! routine is invoked. It is nice to know from where this message
!! originates. The other character string is the message. The info
!! message is written to the standard error logical unit, and can be
!! presented to the end-user.
!!
!! *Usage*:
!!
!! <pre>
!! use Base_cl
!! .
!! .
!! .
!! call infoMessage("thisroutine", "Experienced this thing.", stdout, 1)
!! return
!! end if
!! </pre>
!!


!! *Description*:
!!
!! This routine converts the Julian date to calendar date and time.
!! The algorithm from Q.J.R. Astr. Soc. 1984, vol 25) page 53.
!!
!! Note:
!!
!! For 100 year dates which are not leap years
!! (ie 1900, 2100, etc) the conversion at mar 1 is wrong.
!!       eg    2415078.5  --->  1900,2,28  (correct)
!!             2415079.5  --->  1900,2,29  (should be 1900,3,1 !)
!!             2415080.5  --->  1900,3,2   (correct)
!!


!! Mean obliquity of ecliptic (J2000.0?). See Astronomical Almanac
!! 1987, B18.
!!
!!  INPUT:    mjd   -   Modified Julian Date (TT)
!!
!!  OUTPUT:   in radians
!!


!! *Description*:
!!
!! Transforms radians to degrees, arcminutes, and -seconds.
!!


!! *Description*:
!!
!! Transforms radians to hours, minutes, and -seconds.
!!


!! *Description*:
!!
!! Rotation matrix around i'th axis: If X are "old" coordinates and
!! X' are "new" coordinates (referred to a frame which is rotated by
!! an angle alpha around an axis in direct sense), then X' = R X,
!! where R is the rotation matrix.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Returns the angular distance in radians between two points on the
!! sky (that is, a unit sphere).
!!


!! *Description*:
!!
!! Transforms MPC3 type designation to MPC type.
!!
!! Example:
!!
!! K04A0001S -> K04A01S
!!
!! Returns error.
!!


!! *Description*:
!!
!! Transforms MPC type designation to MPC3 type.
!!
!! Example:
!!
!! K04A01S -> K04A0001S
!!
!! Returns error.
!!


!! *Description*:
!!
!! Decodes an encoded MPC type designation.
!!
!! Example:
!!
!! K04A01S -> 2004 AS1
!!
!! Returns error.
!!


!! *Description*:
!!
!! Decodes an encoded MPC type designation.
!!
!! Example:
!!
!! K04A0001S -> 2004 AS1
!!
!! Returns error.
!!


!! *Description*:
!!
!! Encodes a decoded MPC type designation.
!!
!! Example:
!!
!! 2004 AS1 -> K04A01S
!!
!! Returns error.
!!


!! *Description*:
!!
!! Encodes a number using the MPC scheme.
!!
!! Example:
!!
!! 100001 -> A0001
!!
!! Returns error.
!!


!! *Description*:
!!
!! Encodes a decoded MPC type designation to the MPC3 format.
!!
!! Example:
!!
!! 2004 AS1 -> K04A0001S
!!
!! Returns error.
!!


!! *Description*:
!!
!! This routine returns the date and time in Greenwich England.
!! date(1) is day, date(2) is month (Jan=1,...,Dec=12), date(3) is
!! year, t(1) is hour, t(2) is minute, and t(3) is second.
!!


!! *Description*:
!!
!! Initializes a new object based on given information. The position
!! contains the body-fixed Cartesian geocentric equatorial
!! coordinates of the observatory given in AUs.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Initializes a Orbit-object. Position and velocity are
!! zero-vectors. Coordinate frame is equatorial and propagation
!! scheme is 2-body. Central body is the Sun.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Initializes a Orbit-object using a given
!! CartesianCoordinates-object. Propagation scheme
!! is 2-body and central body is the Sun.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Initializes a Orbit-object using given elements. Propagation
!! scheme is 2-body. Optional argument can be used to define the
!! central body other than the Sun.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Derives Cartesian orbital elements (this) from two positions
!! (ccoord0 and ccoord1) using either (i) the p-iteration method
!! (2-body) by Herrick and Liu, (ii) the continued fraction method
!! by Hansen (2-body), or (iii) the amoeba method by Granvik and
!! Muinonen (n-body). The frame of the output orbit is defined by
!! the equal frames of the input positions. The Sun is the central
!! body.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Initializes a Orbit object using a given SphericalCoordinates
!! object. Coordinate frame s equal to the frame of the input frame
!! and propagation scheme is 2-body.  Central body is the Sun.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Initializes an array of Orbit objects that reproduce the three
!! Keplerian elements (a,e,i), the Cartesian position (x,y,z) and
!! the epoch provided as input.
!!
!! Reference: Granvik et al. (2012), Icarus 218(1), 262-277.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Checks the orbit, bound/unbound.
!!
!! Returns error.
!!


!! *Description*:
!!
!! The continued fraction for computing the orbit parameter
!! Comments: Based on f77 routine by Karri Muinonen,
!!           partly based on software written by Olof Hernius.
!!
!! Reference: "The determination of orbits" (1961), A. D. Dubyago.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Computes an estimate for the cosine of the true anomaly
!! difference.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Calculates the Jacobian matrix of final coordinates wrt initial
!! coordinates when Gauss' f- and g-functions are used.
!!


!! Partial derivative of the function to be minimized
!! (df/dv, see Sitarski 1968).
!!


!! *Description*:
!!
!! Computes the opposite Cartesian orbit, e.g., position and
!! velocity multiplied by -1.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Returns the partial derivatives of Cartesian orbital elements
!! wrt cometary orbital elements.
!!
!!       dx/dq      dx/de      dx/di      dx/dOmega      dx/domega      dx/dt
!!
!!       dy/dq      dy/de      dy/di      dy/dOmega      dy/domega      dy/dt
!!
!!       dz/dq      dz/de      dz/di      dz/dOmega      dz/domega      dz/dt
!!
!!      ddx/dq     ddx/de     ddx/di     ddx/dOmega     ddx/domega     ddx/dt
!!
!!      ddy/dq     ddy/de     ddy/di     ddy/dOmega     ddy/domega     ddy/dt
!!
!!      ddz/dq     ddz/de     ddz/di     ddz/dOmega     ddz/domega     ddz/dt
!!


!! *Description*:
!!
!! Returns the partial derivatives of Cartesian orbital elements
!! wrt Keplerian orbital elements.
!!
!!       dx/da      dx/de      dx/di      dx/dOmega      dx/domega      dx/dM
!!
!!       dy/da      dy/de      dy/di      dy/dOmega      dy/domega      dy/dM
!!
!!       dz/da      dz/de      dz/di      dz/dOmega      dz/domega      dz/dM
!!
!!      ddx/da     ddx/de     ddx/di     ddx/dOmega     ddx/domega     ddx/dM
!!
!!      ddy/da     ddy/de     ddy/di     ddy/dOmega     ddy/domega     ddy/dM
!!
!!      ddz/da     ddz/de     ddz/di     ddz/dOmega     ddz/domega     ddz/dM
!!


!! *Description*:
!!
!! Returns the partial derivatives of cometary orbital elements
!! wrt Keplerian orbital elements.
!!
!!       dq/da      dq/de      dq/di      dq/dOmega      dq/domega      dq/dM
!!
!!       de/da      de/de      de/di      de/dOmega      de/domega      de/dM
!!
!!       di/da      di/de      di/di      di/dOmega      di/domega      di/dM
!!
!!   dOmega/da  dOmega/de  dOmega/di  dOmega/dOmega  dOmega/domega  dOmega/dM
!!
!!   domega/da  domega/de  domega/di  domega/dOmega  domega/domega  domega/dM
!!
!!       dt/da      dt/de      dt/di      dt/dOmega      dt/domega      dt/dM
!!


!! *Description*:
!!
!! Returns the partial derivatives of Keplerian orbital elements
!! wrt Cartesian orbital elements.
!!
!! partials-matrix:
!!
!!       dq/dx     dq/dy     dq/dz     dq/ddx     dq/ddy     dq/ddz
!!       de/dx     de/dy     de/dz     de/ddx     de/ddy     de/ddz
!!       di/dx     di/dy     di/dz     di/ddx     di/ddy     di/ddz
!!   dOmega/dx dOmega/dy dOmega/dz dOmega/ddx dOmega/ddy dOmega/ddz
!!   domega/dx domega/dy domega/dz domega/ddx domega/ddy domega/ddz
!!       dt/dx     dt/dy     dt/dz     dt/ddx     dt/ddy     dt/ddz
!!


!! *Description*:
!!
!! Returns the partial derivatives of Keplerian orbital elements
!! wrt Cartesian orbital elements.
!!
!! partials-matrix:
!!
!!       da/dx     da/dy     da/dz     da/ddx     da/ddy     da/ddz
!!       de/dx     de/dy     de/dz     de/ddx     de/ddy     de/ddz
!!       di/dx     di/dy     di/dz     di/ddx     di/ddy     di/ddz
!!   dOmega/dx dOmega/dy dOmega/dz dOmega/ddx dOmega/ddy dOmega/ddz
!!   domega/dx domega/dy domega/dz domega/ddx domega/ddy domega/ddz
!!       dM/dx     dM/dy     dM/dz     dM/ddx     dM/ddy     dM/ddz
!!


!! *Description*:
!!
!! Returns the partial derivatives of Keplerian orbital elements
!! wrt cometary orbital elements.
!!
!!       da/dq      da/de      da/di      da/dOmega      da/domega      da/dt
!!
!!       de/dq      de/de      de/di      de/dOmega      de/domega      de/dt
!!
!!       di/dq      di/de      di/di      di/dOmega      di/domega      di/dt
!!
!!   dOmega/dq  dOmega/de  dOmega/di  dOmega/dOmega  dOmega/domega  dOmega/dt
!!
!!   domega/dq  domega/de  domega/di  domega/dOmega  domega/domega  domega/dt
!!
!!       dM/dq      dM/de      dM/di      dM/dOmega      dM/domega      dM/dt
!!


!! *Description*:
!!
!! Returns the partial derivatives of polar coordinates
!! wrt Keplerian orbital elements.
!!
!! partials-matrix:
!!
!!       dr/da      dr/de      dr/di      dr/dOmega      dr/domega      dr/dM
!!
!!   dalpha/da  dalpha/de  dalpha/di  dalpha/dOmega  dalpha/domega  dalpha/dM
!!
!!   ddelta/da  ddelta/de  ddelta/di  ddelta/dOmega  ddelta/domega  ddelta/dM
!!
!!      ddr/da     ddr/de     ddr/di     ddr/dOmega     ddr/domega     ddr/dM
!!
!!  ddalpha/da ddalpha/de ddalpha/di ddalpha/dOmega ddalpha/domega ddalpha/dM
!!
!!  dddelta/da dddelta/de dddelta/di dddelta/dOmega dddelta/domega dddelta/dM
!!


!! *Description*:
!!
!! Returns the partial derivatives of spherical coordinates wrt
!! Cartesian orbital elements. The partial derivatives are obtained
!! indirectly by utilizing partial derivatives of Keplerian elements
!! in the process.
!!
!! partials-matrix:
!!
!!       dr/dx      dr/dy      dr/dz      dr/ddx      dr/ddy      dr/ddz
!!
!!   dalpha/dx  dalpha/dy  dalpha/dz  dalpha/ddx  dalpha/ddy  dalpha/ddz
!!
!!   ddelta/dx  ddelta/dy  ddelta/dz  ddelta/ddx  ddelta/ddy  ddelta/ddz
!!
!!      ddr/dx     ddr/dy     ddr/dz     ddr/ddx     ddr/ddy     ddr/ddz
!!
!!  ddalpha/dx ddalpha/dy ddalpha/dz ddalpha/ddx ddalpha/ddy ddalpha/ddz
!!
!!  dddelta/dx dddelta/dy dddelta/dz dddelta/ddx dddelta/ddy dddelta/ddz
!!


!! *Description*:
!!
!! Returns the partial derivatives of spherical coordinates wrt
!! Cartesian orbital elements. Note that the origin and frame for
!! both coordinate systems must coincide.
!!
!! partials-matrix:
!!
!!       dr/dx      dr/dy      dr/dz      dr/ddx      dr/ddy      dr/ddz
!!
!!   dalpha/dx  dalpha/dy  dalpha/dz  dalpha/ddx  dalpha/ddy  dalpha/ddz
!!
!!   ddelta/dx  ddelta/dy  ddelta/dz  ddelta/ddx  ddelta/ddy  ddelta/ddz
!!
!!      ddr/dx     ddr/dy     ddr/dz     ddr/ddx     ddr/ddy     ddr/ddz
!!
!!  ddalpha/dx ddalpha/dy ddalpha/dz ddalpha/ddx ddalpha/ddy ddalpha/ddz
!!
!!  dddelta/dx dddelta/dy dddelta/dz dddelta/ddx dddelta/ddy dddelta/ddz
!!


!! *Description*:
!!
!! Returns the partial derivatives of spherical coordinates wrt
!! cometary orbital elements.
!!
!! partials-matrix:
!!
!!       dr/dq      dr/de      dr/di      dr/dOmega      dr/domega      dr/dt
!!
!!   dalpha/dq  dalpha/de  dalpha/di  dalpha/dOmega  dalpha/domega  dalpha/dt
!!
!!   ddelta/dq  ddelta/de  ddelta/di  ddelta/dOmega  ddelta/domega  ddelta/dt
!!
!!      ddr/dq     ddr/de     ddr/di     ddr/dOmega     ddr/domega     ddr/dt
!!
!!  ddalpha/dq ddalpha/de ddalpha/di ddalpha/dOmega ddalpha/domega ddalpha/dt
!!
!!  dddelta/dq dddelta/de dddelta/di dddelta/dOmega dddelta/domega dddelta/dt
!!


!! *Description*:
!!
!! Returns the partial derivatives of spherical coordinates wrt
!! Keplerian orbital elements.
!!
!! partials-matrix:
!!
!!       dr/da      dr/de      dr/di      dr/dOmega      dr/domega      dr/dM
!!
!!   dalpha/da  dalpha/de  dalpha/di  dalpha/dOmega  dalpha/domega  dalpha/dM
!!
!!   ddelta/da  ddelta/de  ddelta/di  ddelta/dOmega  ddelta/domega  ddelta/dM
!!
!!      ddr/da     ddr/de     ddr/di     ddr/dOmega     ddr/domega     ddr/dM
!!
!!  ddalpha/da ddalpha/de ddalpha/di ddalpha/dOmega ddalpha/domega ddalpha/dM
!!
!!  dddelta/da dddelta/de dddelta/di dddelta/dOmega dddelta/domega dddelta/dM
!!


!! *Description*:
!!
!! Propagates the Cartesian or Keplerian orbital elements to the
!! given epoch using either the 2-body or the n-body model. The
!! dynamical model as well as other propagation parameters can be
!! set with the _setParameters_-routine. Optionally,
!! the Jacobian matrix of final coordinates wrt. initial coordinates
!! is calculated. Doesn"t alter the original orbit, if an error occurs.
!!
!! *2-body*propagation*:
!!
!! In Keplerian elements, trivially computes a new mean anomaly.
!!
!! In Cartesian elements, transforms position and velocity at one
!! epoch into those at another epoch by using f- and g-functions.
!!
!! *N-body*propagation*:
!!
!! If necessary, transforms input orbit to equatorial Cartesian
!! (assumed heliocentric).
!!
!! Transforms position and velocity at one epoch into those at
!! another epoch, using the Bulirsch-Stoer method, full force
!! integration including nine planets and the Moon.
!!
!! Transforms output to match the element type of the input orbit.
!!
!! *Jacobian*:
!!
!! Optionally, a Jacobian matrix (partial derivatives between final
!! orbital elements and initial orbital elements) is
!! computed. Depending on the elements used, the layout of the
!! Jacobian matrix is either (Keplerian elements)
!!
!!  da1/da0     da1/de0     da1/di0     da1/dOmega0     da1/domega0     da1/dM0
!!
!!  de1/da0     de1/de0     de1/di0     de1/dOmega0     de1/domega0     de1/dM0
!!
!!  di1/da0     di1/de0     di1/di0     di1/dOmega0     di1/domega0     di1/dM0
!!
!!  dOmega1/da0 dOmega1/de0 dOmega1/di0 dOmega1/dOmega0 dOmega1/domega0 dOmega1/dM0
!!
!!  domega1/da0 domega1/de0 domega1/di0 domega1/dOmega0 domega1/domega0 domega1/dM0
!!
!!  dM1/da0     dM1/de0     dM1/di0     dM1/dOmega0     dM1/domega0     dM1/dM0
!!
!!
!! or (Cartesian elements)
!!
!!  dx1/dx0     dx1/dy0     dx1/dz0     dx1/ddx0        dx1/ddy0        dx1/ddz0
!!
!!  dy1/dx0     dy1/dy0     dy1/dz0     dy1/ddx0        dy1/ddy0        dy1/ddz0
!!
!!  dz1/dx0     dz1/dy0     dz1/dz0     dz1/ddx0        dz1/ddy0        dz1/ddz0
!!
!!  ddx1/dx0    ddx1/dy0    ddx1/dz0    ddx1/ddx0       ddx1/ddy0       ddx1/ddz0
!!
!!  ddy1/dx0    ddy1/dy0    ddy1/dz0    ddy1/ddx0       ddy1/ddy0       ddy1/ddz0
!!
!!  ddz1/dx0    ddz1/dy0    ddz1/dz0    ddz1/ddx0       ddz1/ddy0       ddz1/ddz0
!!
!!
!! Returns error.
!!
!!


!! *Description*:
!!
!! Propagates the Cartesian or Keplerian orbital elements to the
!! given epoch using either the 2-body or the n-body model. The
!! dynamical model as well as other propagation parameters can be
!! set with the _setParameters_-routine. Optionally,
!! the Jacobian matrix of final coordinates wrt. initial coordinates
!! is calculated. Doesn"t alter the original orbit, if an error occurs.
!!
!! *2-body*propagation*:
!!
!! In Keplerian elements, trivially computes a new mean anomaly.
!!
!! In Cartesian elements, transforms position and velocity at one
!! epoch into those at another epoch by using f- and g-functions.
!!
!! *N-body*propagation*:
!!
!! If necessary, transforms input orbit to equatorial Cartesian
!! (assumed heliocentric).
!!
!! Transforms position and velocity at one epoch into those at
!! another epoch, using the Bulirsch-Stoer method, full force
!! integration including nine planets and the Moon.
!!
!! Transforms output to match the element type of the input orbit.
!!
!! *Jacobian*:
!!
!! Optionally, a Jacobian matrix (partial derivatives between final
!! orbital elements and initial orbital elements) is computed for
!! each orbit. Depending on the elements used, the layout of the
!! Jacobian matrix is either (Keplerian elements)
!!
!!  da1/da0     da1/de0     da1/di0     da1/dOmega0     da1/domega0     da1/dM0
!!
!!  de1/da0     de1/de0     de1/di0     de1/dOmega0     de1/domega0     de1/dM0
!!
!!  di1/da0     di1/de0     di1/di0     di1/dOmega0     di1/domega0     di1/dM0
!!
!!  dOmega1/da0 dOmega1/de0 dOmega1/di0 dOmega1/dOmega0 dOmega1/domega0 dOmega1/dM0
!!
!!  domega1/da0 domega1/de0 domega1/di0 domega1/dOmega0 domega1/domega0 domega1/dM0
!!
!!  dM1/da0     dM1/de0     dM1/di0     dM1/dOmega0     dM1/domega0     dM1/dM0
!!
!!
!! or (Cartesian elements)
!!
!!  dx1/dx0     dx1/dy0     dx1/dz0     dx1/ddx0        dx1/ddy0        dx1/ddz0
!!
!!  dy1/dx0     dy1/dy0     dy1/dz0     dy1/ddx0        dy1/ddy0        dy1/ddz0
!!
!!  dz1/dx0     dz1/dy0     dz1/dz0     dz1/ddx0        dz1/ddy0        dz1/ddz0
!!
!!  ddx1/dx0    ddx1/dy0    ddx1/dz0    ddx1/ddx0       ddx1/ddy0       ddx1/ddz0
!!
!!  ddy1/dx0    ddy1/dy0    ddy1/dz0    ddy1/ddx0       ddy1/ddy0       ddy1/ddz0
!!
!!  ddz1/dx0    ddz1/dy0    ddz1/dz0    ddz1/ddx0       ddz1/ddy0       ddz1/ddz0
!!
!!
!! Returns error.
!!
!!


!! *Description*:
!!
!! Reallocates a pointer array of Orbit-objects and
!! copies the data from the old array to the new array (if it fits).
!!
!! *Usage*:
!!
!! myorbits => reallocate(myorbits,4)
!!
!! Returns error.
!!


!! *Description*:
!!
!! Reallocates a pointer array of Orbit-objects and
!! copies the data from the old array to the new array (if it fits).
!!
!! *Usage*:
!!
!! myorbits => reallocate(myorbits,4,2)
!!
!! Returns error.
!!


!! *Description*:
!!
!! Reallocates a pointer array of Orbit-objects by removing
!! non-initialized objects.
!!
!! *Usage*:
!!
!! myorbits => reallocate(myorbits)
!!
!! Returns error.
!!


!! *Description*:
!!
!! Rotates coordinates to the ecliptical coordinate frame, if not
!! already the case.
!!


!! *Description*:
!!
!! Rotates coordinates to the equatorial coordinate frame, if not
!! already the case.
!!


!! *Description*:
!!
!! Iterates Kepler's equation for input Keplerian orbital elements
!! and epoch with accelerated Newton's method, and returns the
!! eccentric anomaly at the given time. If an error occurs, the
!! subroutine returns a negative eccentric anomaly.
!!
!! References:
!!
!! J. M. A. Danby: "Fundamentals of Celestial mechanics"
!! pp. 149-154
!!
!! Returns error.
!!


!! *Description*:
!!
!! Solves Kepler's equation using universal variables and returns the values
!! of the scaled Stumpff functions c1, c2, and c3.
!!
!! Returns error.
!!
!! Reference:
!! Danby, J. M.: Fundamentals of Celestial Mechanics, 2nd ed.,
!!               rev. ed. Richmond, VA: Willmann-Bell, pp. 170-178, 1988
!!


!! *Description*:
!!
!! Initializes a CartesianCoordinates-object. Position and velocity
!! are zero-vectors. Coordinate frame is ecliptic.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Initializes a CartesianCoordinates-object using a given
!! coordinates, coordinate frame, and epoch.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Initializes a CartesianCoordinates-object using a given
!! SphericalCoordinates-object.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Initializes a CartesianCoordinates-object using a given position,
!! velocity, coordinate frame, and epoch.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Adds "that" to "this", and returns the sum as a new object.
!! Makes sure they are given in the same frame of reference
!! and that they are in the same epoch before adding. Returns
!! a nullified object if an error occurs.
!!
!! *NOTE*:
!! *Do*not*use*this*function*by*name,*but*by*using*the*addition*operator*!
!!


!! *Description*:
!!
!! Computes light-time-corrected epoch for object's
!! Cartesian coordinates given the distance to the observer.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Rotates coordinates from the ecliptical to the equatorial
!! coordinate frame.
!!


!! *Description*:
!!
!! Rotates coordinates from the equatorial to the ecliptical
!! coordinate frame.
!!


!! *Description*:
!!
!! Returns the partial derivatives of spherical coordinates
!! (ra,dec) wrt Cartesian coordinates.
!!
!! @author TL
!!


!! *Description*:
!!
!! Computes the opposite Cartesian coordinates, e.g., position and
!! velocity multiplied by -1.
!!
!! Returns error.
!!


!! *Description*:
!!
!! Reallocates a pointer array of CartesianCoordinates-objects by
!! copying only the initialized objects to the new array.
!!
!! *Usage*:
!!
!! myccoords => reallocate(myccoords)
!!
!! Returns error.
!!


!! *Description*:
!!
!! Reallocates a pointer array of CartesianCoordinates-objects and
!! copies the data from the old array to the new array (if it fits).
!!
!! *Usage*:
!!
!! myccoords => reallocate(myccoords,4)
!!
!! Returns error.
!!


!! *Description*:
!!
!! Reallocates a pointer array of CartesianCoordinates-objects and
!! copies the data from the old array to the new array (if it fits).
!!
!! *Usage*:
!!
!! myccoords => reallocate(myccoords,4,2)
!!
!! Returns error.
!!


!! *Description*:
!!
!! Rotates coordinates to the ecliptic coordinate frame, if not
!! already the case.
!!


!! *Description*:
!!
!! Subtracts "that" from "this", and returns the difference as a new
!! object. Makes sure they are given in the same frame of reference
!! and that they are in the same epoch before subtracting. Returns
!! a nullified object if an error occurs.
!!
!! *NOTE*:
!! *Do*not*use*this*function*by*name,*but*by*using*the*subtraction*operator*!
!!


!! *Description*:
!!
!! Initializes a new object and finds a free
!! logical unit. Returns _error_ =
!!     - _false_, if a free unit is found.
!!     - _true_, if this unit has already been opened,
!!       or a free logical unit ca not be found.
!!
!! *Usage*:
!!
!! type (Unit) :: myunit
!!
!! ...
!!
!! call new(myunit)
!!


!! *Description*:
!!
!! Closes logical unit. Returns _error_ =
!!     - _false_, if the unit is properly closed, or if the unit
!!                has not been opened at all.
!!     - _true_, if an error occurs during the closing procedure.
!!
!! *Usage*:
!!
!! type (Unit) :: myunit
!!
!! ...
!!
!! call nullify(myunit)
!!


!! *Description*:
!!
!! Examines a Unit instance. Returns
!!     - _true_, if the unit is initialized and in use.
!!     - _false_, if the unit is not used or not initialized.
!!
!! Returns error.
!!
!! *Usage*:
!!
!! type (Unit) :: myunit
!!
!! logical :: open
!!
!! ...
!!
!! open = isOpen(myunit)
!!


!! *Description*:
!!
!! Examines a logical unit number. If it is unused,
!! the value is returned unchanged. If it is in use,
!! the routine finds an unused logical unit number
!! between parameters "min_lu" and "max_lu" (incl.)
!! and returns that value. Returns _error_ =
!!     - _false_, if the input unit is ok, or a free
!!                unit was found.
!!     - _true_,  if the input unit is not ok, and a
!!                free unit ca not be found.
!!
!! *Usage*:
!!
!! integer :: unit_nr = 10
!!
!! ...
!!
!! call safeLogicalUnit(unit_nr)
!!


!
! LSST Data Management System
! Copyright 2008, 2009 LSST Corporation.
!
! This product includes software developed by the
! LSST Project (http://www.lsst.org/).
!
! This program is free software: you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
! This program is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! You should have received a copy of the LSST License Statement and
! the GNU General Public License along with this program.  If not,
! see <http://www.lsstcorp.org/LegalNotices/>.
!
!
! OpenOrb library
! F. Pierfederici <fpierfed@gmail.com>
!
! Description
!
! Notes
! error is a boolean global and is defined somewhere in liboorb.so!
!
!
! Implementation notes:
!   1. both oorb_ranging_fast and oorb_lsl_fast have a useless loop in them:
!      either clean them up or make them useful!
!
!
! Orbital elements that we support.
! ORBITAL_ELEMENTS = (/ "keplerian",  "delaunay", "poincare", "equinoctial" /)


!JD 08/13 New function for nonlinear lensing of CMB + MPK compatibility
!Build master redshift array from array of desired Nonlinear lensing (NLL)
!redshifts and an array of desired Power spectrum (PK) redshifts.
!At the same time fill arrays for NLL and PK that indicate indices
!of their desired redshifts in the master redshift array.
!Finally define number of redshifts in master array. This is usually given by:
!P%num_redshifts = P%PK_num_redshifts + NLL_num_redshifts - 1.  The -1 comes
!from the fact that z=0 is in both arrays (when non-linear is on)


!JD 08/13 for nonlinear lensing of CMB + LSS compatibility
!Changed input variable from itf to itf_PK because we are looking for the itf_PK'th
!redshift in the PK_redshifts array.  The position of this redshift in the master redshift
!array, itf, is given by itf = CP%Transfer%Pk_redshifts_index(itf_PK)
!Also changed (CP%NonLinear/=NonLinear_None) to
!CP%NonLinear/=NonLinear_none .and. CP%NonLinear/=NonLinear_Lens)


!Call this routine with a set of parameters to generate the results you want.


!Return real (NOT double precision) arrays of the computed CMB  Cls
!Output is l(l+1)C_l/2pi
!If GC_Conventions = .false. use E-B conventions (as the rest of CAMB does)
!Used by WriteFits only


! =============MGXrecon=============
!> this subroutine computes the MG functions at a time-step


!---------------------------------------------------------------------------
!> this subroutine computes the shear sigma in MG or sigma^star in the notes


!---------------------------------------------------------------------------
!> this subroutine computes the perturbation Z in MG


!------------------------------------------------------------GaugeInterface_EvolveScal---------------
!> this subroutine computes the ISW term in MG


!---------------------------------------------------------------------------
!> this subroutine computes the lensing term in MG


!-----------------------------------------------
!> mu(a,k) function


!-----------------------------------------------
!> \dot{mu}(a,k) function


!----------------------------------------------------------------------------------------------
!> MGCAMB (beta, m) parametrization, QSA for scalar-tensor models
!-----------------------------------------------
!> m(a) function


!-----------------------------------------------
!> \dot{m}(a) function


!-----------------------------------------------
!> beta(a) function


!-----------------------------------------------
!> \dot{beta}(a) function


!----------------------------------------------------------------------------------------------
!> MGCAMB (Q,R) parametrization, QSA for scalar-tensor models
!-----------------------------------------------
!> Q(a,k) function


!-----------------------------------------------
!> \dot{Q}(a,k) function


! ---------------------------------------------------------------------------------------------
!> Modifying the background


!>this subroutine reads MG parameters into the module


! ---------------------------------------------------------------------------------------------
!> Subroutine that reads the MGCAMB model parameters


! ---------------------------------------------------------------------------------------------
!> Subroutine that prints to screen the MGCAMB header.


! ---------------------------------------------------------------------------------------------
!> Subroutine that sets the mgcamb_cache to zero


! ---------------------------------------------------------------------------------------------
!> Subroutine that opens the MGCAMB cache files (for Debug)


! ---------------------------------------------------------------------------------------------
!> Subroutine that closes the MGCAMB cache files (for Debug)


! ---------------------------------------------------------------------------------------------
!> Subroutine that prints the MGCAMB cache on a file


! Equations module for background and ! To avoid circular module issues, some things are not part of module
! Background evolution, return d tau/ d a, where tau is the conformal time


!***********************************************************************
!                                                                      *
! Calculates Phi(l,beta,chi) using recursion on l.                     *
! See Abbot and Schaefer, ApJ 308, 546 (1986) for needed               *
! recursion relations and closed-form expressions for l=0,1.           *
! (Note: Their variable y is the same as chi here.)                    *
!                                                                      *
! When the flag direction is negative, downwards recursion on l        *
! must be used because the upwards direction is unstable to roundoff   *
! errors. The downwards recursion begins with arbitrary values and     *
! continues downwards to l=1, where the desired l value is normalized  *
! using the closed form solution for l=1. (See, e.g., Numerical        *
! Recipes of Bessel functions for more detail)                         *
!                                                                      *
!***********************************************************************


!not needed for local NG


! Early Quintessence example, axion potential from e.g. arXiv: 1908.06995


!  initial variables, number of steps, etc.


!flat source integration


!non-flat source integration


! equation of state of the PPF DE


!subroutine to export Cls in FITS format for HEALPix 1.2
!Antony Lewis July 2003


! ----------------------------------------------------------------
! CVodeStats
!
! Print CVODE statstics to stdandard out
! ----------------------------------------------------------------


! =================================================================
! Other routines
! =================================================================
! -----------------------------------------------------------------
! NOT INTERFACED SUNSparseMatrix_Print
! -----------------------------------------------------------------


! ================================================================
! Helpful routines
! ================================================================
! ----------------------------------------------------------------
! FSUNMatGetData_Sparse
!
! Extracts data array from a SUNDIALS Sparse Matrix
! ----------------------------------------------------------------


! =================================================================
! Other routines
! =================================================================
! -----------------------------------------------------------------
! NOT INTERFACED SUNBandMatrix_Print
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! NOT INTERFACED SUNBandMatrix_Cols
! -----------------------------------------------------------------


! ================================================================
! Helpful routines
! ================================================================
! ----------------------------------------------------------------
! FSUNMatGetData_Band
!
! Extracts data array from a SUNDIALS Band Matrix
! ----------------------------------------------------------------


! =================================================================
! Other routines
! =================================================================
! -----------------------------------------------------------------
! NOT INTERFACED SUNDenseMatrix_Print
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! NOT INTERFACED SUNDenseMatrix_Cols
! -----------------------------------------------------------------


! ================================================================
! Helpful routines
! ================================================================
! ----------------------------------------------------------------
! FSUNMatGetData_Dense
!
! Extracts data array from a SUNDIALS Dense Matrix
! ----------------------------------------------------------------


! -----------------------------------------------------------------
! N_VCloneVectorArray_OpenMP: NOT INTERFACED
! -----------------------------------------------------------------
! -----------------------------------------------------------------
! N_VCloneVectorArrayEmpty_OpenMP: NOT INTERFACED
! -----------------------------------------------------------------
! =================================================================
! Destructors
! =================================================================
! -----------------------------------------------------------------
! N_VDestroy_OpenMP
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! N_VDestroyVectorArray_OpenMP: NOT INTERFACED
! -----------------------------------------------------------------
! =================================================================
! Other routines
! =================================================================
! -----------------------------------------------------------------
! N_VGetLength_OpenMP
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! NOT INTERFACED: N_VPrintFile_OpenMP
! -----------------------------------------------------------------
! =================================================================
! Operations
! =================================================================
! -----------------------------------------------------------------
! N_VGetVectorID_OpenMP
! -----------------------------------------------------------------


! ================================================================
! Helpful routines
! ================================================================
! ----------------------------------------------------------------
! FN_VGetData_OpenMP
!
! Extracts data array from a OpenMP SUNDIALS N_Vector
! ----------------------------------------------------------------


! -----------------------------------------------------------------
! N_VCloneVectorArray_Pthreads: NOT INTERFACED
! -----------------------------------------------------------------
! -----------------------------------------------------------------
! N_VCloneVectorArrayEmpty_Pthreads: NOT INTERFACED
! -----------------------------------------------------------------
! =================================================================
! Destructors
! =================================================================
! -----------------------------------------------------------------
! N_VDestroy_Pthreads
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! N_VDestroyVectorArray_Pthreads: NOT INTERFACED
! -----------------------------------------------------------------
! =================================================================
! Other routines
! =================================================================
! -----------------------------------------------------------------
! N_VGetLength_Pthreads
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! NOT INTERFACED: N_VPrintFile_Pthreads
! -----------------------------------------------------------------
! =================================================================
! Operations
! =================================================================
! -----------------------------------------------------------------
! N_VGetVectorID_Pthreads
! -----------------------------------------------------------------


! ================================================================
! Helpful routines
! ================================================================
! ----------------------------------------------------------------
! FN_VGetData_Pthreads
!
! Extracts data array from a Pthreads SUNDIALS N_Vector
! ----------------------------------------------------------------


! -----------------------------------------------------------------
! N_VCloneVectorArray_Serial: NOT INTERFACED
! -----------------------------------------------------------------
! -----------------------------------------------------------------
! N_VCloneVectorArrayEmpty_Serial: NOT INTERFACED
! -----------------------------------------------------------------
! =================================================================
! Destructors
! =================================================================
! -----------------------------------------------------------------
! N_VDestroy_Serial
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! N_VDestroyVectorArray_Serial: NOT INTERFACED
! -----------------------------------------------------------------
! =================================================================
! Other routines
! =================================================================
! -----------------------------------------------------------------
! N_VGetLength_Serial
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! NOT INTERFACED: N_VPrintFile_Serial
! -----------------------------------------------------------------
! =================================================================
! Operations
! =================================================================
! -----------------------------------------------------------------
! N_VGetVectorID_Serial
! -----------------------------------------------------------------


! ================================================================
! Helpful routines
! ================================================================
! ----------------------------------------------------------------
! FN_VGetData_Serial
!
! Extracts data array from a serial SUNDIALS N_Vector
! ----------------------------------------------------------------


! =================================================================
! Interfaces for cvode.h
! =================================================================
! -----------------------------------------------------------------
! CVodeCreate
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! Integrator optional input specification functions
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! NOT INTERFACED: CVodeSetErrFile
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! CVodeSStolerances
! CVodeSVtolerances
! CVodeWFtolerances
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! Integrator optional output extraction functions
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! Nonlinear solver optional output extraction functions
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! NOT INTERFACED: CVodeGetReturnFlagName
! -----------------------------------------------------------------
! -----------------------------------------------------------------
! CVodeFree
! -----------------------------------------------------------------


! =================================================================
! Interfaces from cvode_ls.h
! =================================================================


! -----------------------------------------------------------------
! Optional inputs to the CVLS linear solver
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! Optional outputs from the CVLS linear solver
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! NOT INTERFACED: CVodeGetLinReturnFlagName
! -----------------------------------------------------------------
! =================================================================
! Interfaces for cvode_diag.h
! =================================================================
! -----------------------------------------------------------------
! CVDiag
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! Optional outputs from the CVDIAG linear solver
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! NOT INTERFACED: CVDiagGetReturnFlagName
! -----------------------------------------------------------------
! =================================================================
! Interfaces from cvode_bandpre.h
! =================================================================
! -----------------------------------------------------------------
! CVBandPrecInit
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! Optional output functions : CVBandPrecGet*
! -----------------------------------------------------------------


! =================================================================
! Interfaces for cvode_bbdpre.h
! =================================================================
! -----------------------------------------------------------------
! CVBBDPrecInit
! -----------------------------------------------------------------


! -----------------------------------------------------------------
! BBDPRE optional output extraction routines
! -----------------------------------------------------------------


!
! Electric dipole Raman-Wave-Function intensities and cross section calculations
!


!
!
! Electric dipole Raman-Wave-Function intensities and cross section calculations
!


!
!read eigenvalues and their assignment
!


!
! In order to speed up the line strength evaluation,
! S_if = | <i|mu|f> |^2  = | \sum_{nm} C_in C_fm <n|mu|m> |^2
! in three steps:
! 1. Evaluating the expansion of the i-state
!    s_{im} =  \sum_{n} C_in  <n|mu|m>
! 2. performing the expansion of the final state f:
!    s_{if} =  \sum_{m} C_fm  s_{im}.
! 3. Building S_{if}
!    S_{if} = s_{if}^2
!
!  This routine performs the first half of <i|mu|f>.
!


!
! This basis set composition is for contr=VIB, State-Lambda-Sigma
!


!subroutine transfer_allocated_property(src,dst)
!  type(fieldT),pointer,intent(in)  :: src
!  type(fieldT),pointer,intent(out)  :: dst
!  !
!  !
!end subroutine transfer_allocated_property
!


!
! remove "-x" from the field name, identify the parent object
!


!
!
!
! Book keeping for a reduced basis |Omega>=|Lambda>|Sigma> with Omega = Lambda + Sigma as main QN


! if chemical symbols of the atoms are given in ATOMS gets from those masses and spins.
! if masses or spins are given explicitely, uses those values


!
!
! This funciton finds a crossing point between tow PECs
!


!
!  vibrational reduced density of a rovibronic eigenstate at the igrid point


!
!
!  vibrational reduced density of a rovibronic eigenstate at the igrid point


!
!  vibrational reduced density of a rovibronic eigenstate at the igrid point in the omega representation


!
!
! Transform the PECs+SOCs+couplings from the input to the Omega representation
!


!
! integration with Simpson rules
!


!
!
! calculate factorial by log function
!


! gives a character variable with the name of the element


! gives a character variable with the full name of the nuclide (eg., Carbon-14 )


! gives a character variable with the symbol of the element


! takes in Z and A and returns the counter ii identifying each nuclide
! used only internally in this module
! gives ii = 0 if not found


! gives atomic mass of the element


! gives atomic mass uncertainty of the element


! used for isatty


!
! Matrix elements with Numerov-eigenfunctions
!


!
!********************************************************************!
!                                                                    !
! numerov calculates bending functions and stores them               !
!                                                                    !
!                                                                    !
!********************************************************************!


!     subroutine solves eqn 6.5 , for the given value of kqua ,
!     by the numerov - cooley technique.
!
!                  (                       0                  )
!      2           (                    2 i                   )
!     d            (                2      pp                 )
!     ---phi (p) = ( f (p) + f (p) k  + ----- ( v   (p) - e ) ) phi (p)
!       2   b      (  1       2         _2       eff          )    b
!     dp           (                    h                     )
!
!     for this the following defintions (equations 6.14 to 6.17) are
!     needed :-
!
!     ph  = phi  (p )
!       i      b   i
!
!             0         _2
!     i  = 2 i   (p ) / h
!      i      pp   i
!
!                             2      0                   _2
!     u  = f  (p ) + f  (p ) k  + 2 i   (p ) v    (p ) / h
!      i    1   i     2   i          pp   i   eff   i
!
!                 2
!     y  = ( 1 - h  ( u  - i  e ) ) ph
!      i         --    i    i         i
!                12
!
!     starting from an initial guess for the energy , given in wavfun
!     an iterative scheme is followed. this is performed by using the
!     recursion relation (eqn 6.18) :-
!
!                           2
!     y    + y    - 2 y  = h  ( u  - i  e ) ph
!      i+1    i-1      i         i    i       i
!
!     h is here the rhostep length used to generate the f1 , f2 , i0's
!
!     to calculate values of y(i) and phi_f(i) both from rho = 0
!     and from rho = rhomax. these two parts are called the outward
!     and inward integrations respectively.
!     the outward integration is carried out until a maximum is reached
!     in the wavefunction. this crossing point (ic , yc , pc) is then
!     the stopping point used for the inward integration.
!     both sets of wavefunctions are scaled so that pc(out) = pc(in) = 1
!     an error for the energy can be calculated from eqn 6.24 :-
!
!                                                         npoints
!               out           in       2                    \--      2
!     d(e) = (-y    + 2 y  - y    ) / h + u  - i  e ) y  /   \  i  ph
!               c-1      c    c+1          c    c      c     /   i   i
!                                                           /--
!                                                           i=1
!
!     and this is added to the eguess at each iteration , when d(e)
!     is less than thrsh3 the iteration has converged.
!


!
!     subroutine performs the outward integration of numcoo ,
!     until the first maximum in the wave function is found.
!     the sum i0(i)*phi_f(i)**2 is saved for the outward integration
!     and will later br divided by pc(out)**2.


! integration with Simpson rules
!


!
!
! extrapolation at borders
!


!
! Morse/Long-Range, see Le Roy manuals
!


! Morse/Long-Range with Douketis damping, see Le Roy manuals
!


!
!
! SO functional form
!


!
! The Chebyshev polynomial is evaluated at a point y=[x-(b + a)/2]/[(b - a)/2],
! and the result is returned as the function value = \sum_{k=0} a_k P_k  - a0/2
!


!
! Dipole moment Pade-2 by J. Goodisman, Dipole-moment function for diatomic molecules,
! J. Chem. Phys. 38 (1963) 2597-2599. doi: 10.1063/1.1733557.
! based on Chebyshev polynomials
!


! Potential BOB correction
! polynomial with mass-dependence in a reduced coordinate z with a switching function between long and short range
!


!
! polynomial with exp decay
!


!
! A lorentzian function for the couplings between diabatic curves
!


!
! A sqrt(lorentzian) function for the couplings between diabatic curves
!


!
! An angle used for a unitary transformation to the diabatic representaion
! for the lorentzian case
!


!
! An angle used for a unitary transformation to the diabatic representaion
! for the Laplacian case
!


!
!
! Irregular DMF by Medvedev Opt. spectrosc. 130, 1334 (2022)
!


!
! does not do anything
!


!
!
! A coupled PEC with an arbitrary number of states
!


!
!  Start new State unit
!


!
!  End an State unit
!


!
!  Reduce the array allocation
!


!
! Lorenzo Lodi, last modified 24 March 2016
!
! This is a companion test suite to the program
! `DUO: a general program for calculating spectra of diatomic molecules'
! by Sergei N. Yurchenko, Lorenzo Lodi, Jonathan Tennyson and Andrey V. Stolyarov
! Computer Physics Communication (2016)
!
! The present test suite produces input files, feeds them to DUO and
! tries to determine if they ran successfully.
! For each test input file there is a certain number of subtests; typically we
! check that a few energies or other key values have their expected (correct) value.
! USAGE:
! Just run it in the same directory where the duo executable is located:
!
! ./duo_test.exe
!
! The DUO executable should be named 'duo.exe'. This can be changed by modifying
! the `executable' character variable at the very beginning of the program.
! The test suite accepts numbers as command line parameters, indicating which
! test files should be skipped. For example
!
! ./duo_test.exe 1 2 4
!
! runs all tests EXCEPT tests number 1,2 and 4. Any other command line parameter
! apart from a number in the appropriate range is ignored.
!
! INSTRUCTIONS TO ADD NEW SUBTESTS FOR AN EXISTING TEST FILE
! If you want to add further subtests for an existing test file,
! here's what you have to do.
! 1) go to the section immediately after the relative test input and update the line
!    `n_subtests(itest)='
! 2) Immediately below, add new `SubtestDescription' for the new subtests
! 3) In the do loop immediately below insert the new test, e.g. the new
!    output line you want to check
!
! INSTRUCTIONS TO ADD A NEW TEST FILE AND RELATIVE NEW SUBTESTS
! 1) Modify the parameter `n_test_files' at the beginning of the program
! 2) Use another file input section as a model: Copy, paste and modify.
! In particular:
! -update TestFileName(itest)
! -change nlines (number of lines expected in the output).
! -change n_subtests(itest) to the number of subtests for the new test file
! -change SubtestDescription(.) to some meaningful description of the subtest
! -modify the output lines to be checked. Leave out all spaces both on the left and
!  on the right.
!
! Note that the way results are checked is often rather primitive (comparison of whole lines)
! so that changes in the formatting of the output may cause a subtest to fail.
!
!*****************************************************************************
! I need a subroutine to run externally the DUO executable.
! There is no standard way of doing that in Fortran 2003 or earlier;
! Fortran 2008 added the intrinsic subroutine execute_command_line but not all
! compilers support it at this time. According to
! www.fortranplus.co.uk/.../fortran_2003_2008_compiler_support.pdf
! this feature is supported by: Absoft v14, Cray v8.4.0, gfortran 4.9,
! IBM 15.1, Intel 16.0, NAG 6.0.
! It is NOT supported by: g95, HP, Pathscale, PGI, Oracle.
! When execute_command_line is not available as an intrisic, usually an
! equivalent routine is available under another name. For example,
! the Intel compiler before v15 has a routine called SYSTEM.
! The following 4-line subroutine is a wrapper to the version available
! in a specific compiler.
! Note that if the intrisic version is available, it will be used automatically.


!
!
!
!`-------------------------------------------------------------------------
!                 Matrix Element/Line Strength Evaluation
! -------------------------------------------------------------------------
!   To speed up the line strength evaluation, we perform the calculation:
!       S_{if} = | <i|a|f> |^2  = | \sum_{nm} C_in C_fm <n|a|m> |^2
!   in three steps:
!     1. Evaluate the expansion of the initial state:
!             s_{im} = sum_{n} C_in <n|a|m>
!     2. Evaluate the product with the expansion of the final state:
!             s_{if} = sum_{m} C_fm s_{im}
!     3. Square the result to obtain S_{if}
!             S_{if} = s_{if}^2
! -----------------------------------------------------------------------
!
!


!
! Electric dipole moment intensities and transition moments calculations
!


!
!read eigenvalues and their assignment
!


!
! In order to speed up the line strength evaluation,
! S_if = | <i|mu|f> |^2  = | \sum_{nm} C_in C_fm <n|mu|m> |^2
! in three steps:
! 1. Evaluating the expansion of the i-state
!    s_{im} =  \sum_{n} C_in  <n|mu|m>
! 2. performing the expansion of the final state f:
!    s_{if} =  \sum_{m} C_fm  s_{im}.
! 3. Building S_{if}
!    S_{if} = s_{if}^2
!
!  This routine performs the first half of <i|mu|f>.
!


!--------------------------------------------------------------------------------------------
! Subroutine to calculate pressure and composition due to thermo-gravitational effects using the
! algorithm for bubble points at T and Z (see the main paper)


!--------------------------------------------------------------------------------------------
! Subroutine to calculate the K-factor at P, T, X, Y
! Originally, it is for vapor-liquid equilibria, but now modified for thermo-gravity purposes


!------------------------------------------------------------------------------
! Subroutine to calculate the net heat diffusion in a phase at P, T, X
! Based on Firoozabadi et al. (2000)


!=============================================================================
!>	This subroutin performs an one-dimensional integration in
!>	the x-direction for every y and stores the results in itg.
!>	In principle it works the same as the function Romberg.
!>	Extra argument : itg	the results of the integrations


!=======================================================================
!> calculates the thermal evolution of one grid point


!=======================================================================
!> calculates time dependent ionization state for hydrogen


!=======================================================================
!> Sets the boundary condition for the hydrogen column density


!=======================================================================
!> find temperature from pressure


! =======================================================================
!> find pressure from temperature


! =======================================================================
!> Calculates the cosmological evolution of space and densities\n
!! Changes variables: ndens, r, dr, vol


!===========================================================================
!> Calculate the cooling rate


!----------------------------------------------------------------------------
!> Call the individual routines needed for photon statistics calculation


!----------------------------------------------------------------------------
!> Calculates the number of neutrals and ions at the start of the time step


!----------------------------------------------------------------------------
!> Calculates total number of recombinations and collisions


!----------------------------------------------------------------------------
!> Calculates the number of neutrals and ions at the end of the time step


!----------------------------------------------------------------------------
!> Calculate the total number of ionizing photons used


!-----------------------------------------------------------------------------
!> Closes global output files which have been open the entire run


!----------------------------------------------------------------------------
!> produces output for a time frame. See below for format
!!
!! Output format: ASCII table
!! \li r-position
!! \li neutral hydrogen fraction
!! \li ionized hydrogen fraction
!! \li temperature
!! \li density
!!
!! No time information is available in the output, but the
!! file names are Ifront_xx.xxx.dat, where xx.xxx is the
!! fraction of the simulation time passed (initial condition 0.000,
!! last output 1.000).


!---------------------------------------------------------------------------
!> Calculate the location of the ionization front analytically\n
!! \b Authors: Erik-Jan Rijkhorst, Ilian Iliev, Garrelt Mellema\n
!! \b Date: 20-Oct-2004 (5-Aug-2004)\n
!! This routine needs several external functions:
!!  - LambertW(x): the LambertW function.(real argument and ouput)
!!  - expint(n,x): the exponentional integral of order n


!---------------------------------------------------------------------------
!> finds the the location of the numerical ionization front.\n
!! \b Author: Erik-Jan Rijkhorst\n
!! \b Date: 5-Aug-2004


!---------------------------------------------------------------------------
!> calculates exponential integral of order n for x


! Local procedures for program los_attenuation
!     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


! Internal procedures for program neqair_data
!     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


! Internal procedure for COMPARE_FLOWS
!       ------------------------------------------------------------------


!     Internal procedures for program PREPARE_FIAT_DATA:
!     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


!     Internal procedures for program TRIANGULATION_TOOL:
!     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


!     Internal procedure for program columnedit:
!     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


! Local procedures for program Radio_Blackout
!     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


!     Internal routine for program cfd_conditions:
!     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


!     --------------------------------------------------------------------------
!!!   subroutine norm_denorm (mode, ne, np, ie, xmean, xsd, x)
!!!   Normalize or denormalize the indicated data, in-place.
!!!   This version is retained for posterity, but not used.
!!!   Arguments:
!!!   integer, intent (in)    :: mode     ! 1 => normalize; 2 => denormalize
!!!   integer, intent (in)    :: ne, np   ! # elements per point & # points
!!!   integer, intent (in)    :: ie       ! Element x/y/.. or f1/f2/.. to adjust
!!!   real,    intent (in)    :: xmean    ! Mean of indicated quantity
!!!   real,    intent (in)    :: xsd      ! Standard deviation of that quantity
!!!   real,    intent (inout) :: x(ne,np) ! Packed data
!!!   Local variable:
!!!   real :: rsd
!!!   Execution:
!!!   select case (mode)
!!!   case (1)
!!!      rsd = one / xsd;  x(ie,:) = (x(ie,:) - xmean) * rsd
!!!   case (2)
!!!      x(ie,:) = x(ie,:) * xsd + xmean
!!!   end select
!!!   end subroutine norm_denorm
!     --------------------------------------------------------------------------


!                                             +--------------------------------------+
!                                             | "iblank" variants are grouped below. |
!                                             +--------------------------------------+
!     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


! Search routines:
! * n_nearest_to(tp, qv, n, indexes, distances)
! Find the 'n' vectors in the tree nearest to 'qv' in euclidean norm
! returning their indexes and distances in 'indexes' and 'distances'
! arrays already allocated passed to the subroutine.


! Another main routine you call from your user program


! No longer recommended; retained for posterity
!        -----------------------------------------------------------------------
!


!     Internal procedures for subroutine min_max_curv_edge_2d:
!     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


!-Stretch--------------------------------------------------------------------
!
!  Routine to compute one-sided grid stretching on [0.0, 1.0].
!
!  Inputs:
!     1. nk    = number of points on the line
!     2. ds    = initial spacing (normalized to the unit interval)
!     3. beta  = initial guess for the stretching parameter (> 1.0);
!                try 1 + ds for small ds
!  Outputs:
!     1. beta  = value of the stretching parameter
!     2. s     = stretching function (ranges from 0 to 1)
!
!  Routines called: None
!
!  References:  Roberts, G. O. Computational Meshes for Boundary Layer
!               Problems, Proc. Second Int. Conf. Num. Methods Fluid Dyn.,
!               Lect. Notes Phys., vol. 8, Springer-Verlag, New York,
!               pp. 171-177 (1971).
!               Tannehill, J. C., Anderson, D. A. and Pletcher, R. H.,
!               Computational Fluid Mechanics and Heat Transfer,
!               second Edition, Taylor & Francis, Washington DC,
!               pp. 333-338 (1997).
!
!  Written by:  Dr. Dinesh K. Prabhu, Thermosciences Institute, NASA ARC
!
!  Date:        Nov. 18, 1996  Initial Fortran 90 version.
!               Mar. 22, 2004  Omit total length argument;
!                              pass normalized ds instead.
!----------------------------------------------------------------------------


!     Internal procedures for subroutine AeBxplusC:
!     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


!     Internal procedures for subroutine AxBeCx:
!     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
!  Calculate 1st and 2nd derivatives w.r.t. each coordinate for nf functions
!  defined on a rectangular table with ndim dimensions, using 3-point finite
!  differencing.  A curvature-like quantity is also returned at each point.
!
!  The present approach takes advantage of multiple subscripts, but it's hard to
!  generalize.  Therefore, a different routine is provided for each number of
!  dimensions desired.  Add more dimensions as necessary.
!
!  The language supports implied passing of planes (and higher-rank sub-arrays)
!  as arguments.
!
!  All argument arrays are assumed to be sized exactly.  The coordinates and
!  functions at one table entry are contiguous (first index).
!
!  03/14/07  Initial adaptation of table_coordinates.f90.
!
!  Author:  David Saunders, ELORET/NASA Ames Research Center, Moffett Field, CA
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
!  Expand the coordinates of a rectangular table from the compact form (a vector
!  of coordinates for each dimension, packed into one vector).
!
!  If anyone can see how to do this without itemizing the cases, please let me
!  know!  It requires a variable number of nested loops.  Recursion may be the
!  answer, but the weak way out is taken here.
!
!  The present approach takes advantage of multiple subscripts, but it's hard to
!  generalize.  Therefore, a different routine is provided for each number of
!  dimensions desired.  Add more dimensions as necessary.
!
!  All argument arrays are assumed to be sized exactly.  The coordinates at one
!  table entry are contiguous (first index).
!
!  01/22/07  Initial implementation.
!
!  Author:  David Saunders, ELORET/NASA Ames Research Center, Moffett Field, CA
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


! ==================================================================================
! Extra routines required for atm_profile.f90:
! ==================================================================================
! ---------------------
! H2O
! ---------------------
! ==================================================================================


Validity and Initialization Check(s)


Load EROS path


Exports the content of dataProb and dataT2 matrices to ascii files


Archive Tephra2 output files


Opens the manage grid panel


Function for DOWNLOAD button in main panel


Selection change function for type pannel


Prepare data for plotting


Plotting functions
Plot single profiles


Plot separate profiles


Plot averaged profiles


Change the text font on figure resize.


colorm returns a colormap which is really good for creating informative
heatmap style figures.
No particular color stands out and it doesn't do too badly for colorblind people either.
It works by interpolating the data from the
'spectral' setting on http://colorbrewer2.org/ set to 11 colors
It is modified a little to make the brightest yellow a little less bright.


Plot Cumulative data


the fun expfun
---------- all calculations inside the fminsearch "loop" (expfun) are below ----------


follow helper functions (the ones easy to convert from python ;-)
-----------------------------------------------------------------


follow helper functions
-----------------------


End of main function


End of the main function


End of function


Description:
Visualize and print an eight-band multispectral image.

Interface:
showImage8(I_MS,print,id,flag_cut_bounds,dim_cut,th_values,L)

Inputs:
I_MS:               Eight band multispectral image;
print:              Flag. If print == 1, print EPS image;
id:                 Identifier (name) of the printed EPS image;
flag_cut_bounds:    Cut the boundaries of the viewed Panchromatic image;
dim_cut:            Define the dimension of the boundary cut;
th_values:          Flag. If th_values == 1, apply an hard threshold to the dynamic range;
L:                  Radiomatric resolution of the input image.

function showImage8(I_MS,print,id,flag_cut_bounds,dim_cut,th_values,L,location)


Get the single particle perimeter

Inputs:
image_buffer - n x photodiodes/8 raw image buffer without timestamps
Outputs:
Perimeter

*  Created by Wei Wu, July 4th, 2014


holroyd - identified particle habit according to Holroyd  (1987)
inputs:
handles - handles structure outlined in run_img_processing.m
image_buffer - n x photodiodes/8 raw image buffer without timestamps
outputs:
holroyd_habit - habit code as listed below


Calculate image sample area assuming Heymsfield and Parish (1978)
bins_mid - mid-point of each bins in doide number
res - photodiode resolution, bin width in microns
armdst - distance between probe arms in millimeters
num_diodes - number of photodiodes (does not need to equal number of bins)
SAmethod - method to calculate SA. Could be 0: center in, 1: entire in and 2 with correction

** Created to replace calc_sa to include different bin setup, and three choices of SA
calculation methods. Notice the parameter differences.        Will, 2014/06/04


Returns terminal velocity for a single particle
Both options to calculate the terminal velocity
Default is to use the Heymsfield and Westbrook (2010) method,
but you can also choose to to use Mitchel (1996)
Created by Will Wu, 2014/01/15
- Mass and Diameter uses metric system
- Pressure use hPa
- Temperature use Celsius


Aux function for integration


Value changed function: Reactants


Value changed function: Products


Code that executes after component creation


Button pushed function: Calculate


Value changed function: PR1


Menu selected function: DiscussionsMenu


Value changed function: PP2


Value changed function: PR2


Button pushed function: Clear


Menu selected function: xlsMenu


Menu selected function: matMenu


Button pushed function: AddButton1


Button pushed function: RemoveButton1


Button pushed function: figure_size


Value changing function: edit_seeker_1


Value changing function: edit_seeker_2


Button pushed function: AddButton2


Button pushed function: RemoveButton2


Menu selected function: property_inspector_menu


Button pushed function: figure_settings


Key press function: UIFigure


Value changing function: PR4


Value changing function: PP4


Value changing function: PR5


Value changing function: PP5


Callback function: Tree_variable_x


Callback function: Tree_variable_y


Menu selected function: RemoveMenu_2


Create UIFigure and components


Code that executes before app deletion


Image clicked function: element_1, element_10, element_11,
% ...and 77 other components


Value changed function: listbox_LS, listbox_LS_DB


Button pushed function: Export


Button pushed function: Copy


Menu selected function: enableremoveMenu


Value changing function: edit_seeker


Value changed function: ionized


Value changed function: condensed


Value changed function: burcat


Selection changed function: Tree


Set parameters to default


Delete all objects from object


Create title panel right


Create label panel's children


Create editfield panel's children


Create dropdown panel's children


Create checkbox panel's children


Button pushed function: RunButton


Plotting subfunctions %


Generative subfunctions %


--- Outputs from this function are returned to the command line.


--- Executes on button press in button_xup.


--- Executes during object creation, after setting all properties.


--- Executes on button press in holidays_check.


--- Executes on selection change in rowanom_popup.


--- Executes on selection change in clouds_popup.


--- Executes on selection change in projection_popup.


--- Executes on button press in states_checkbox.


--- Executes on selection change in coast_popup.


function [presSave, szaSave, vzaSave, phiSave, albedoSave, surfPresSave, dAmfSave, dAmf] = rDamf2(fileDamf, pressure, sza, vza, phi, albedo, surfPres)


OTHER FUNCTIONS %%%%


PLOTTING FUNCTIONS %%%%%


MAIN SUBFUNCTIONS %


FUNCTIONS THAT EXTEND PROFILES TO SURFACE AND TROPOPAUSE %


--- Executes on button press in no2reject_button.


--- Executes on button press in no2blh_button.


--- Executes on button press in no2AddRange_button.


--- Executes on button press in no2MoveUp_button.


--- Executes on button press in no2Widen_button.


--- Executes on button press in no2Shrink_button.


--- Executes on button press in no2MoveDown_button.


--- Executes on button press in h2oAddRange_button.


--- Executes on button press in h2oMoveUp_button.


--- Executes on button press in h2oWiden_button.


--- Executes on button press in h2oMoveDown_button.


--- Executes on button press in thetaAddRange_button.


--- Executes on button press in thetaMoveUp_button.


--- Executes on button press in thetaWiden_button.


--- Executes on button press in thetaShrink_button.


--- Executes on button press in thetaMoveDown_button.


--- Executes on button press in thetareject_button.


--- Executes on button press in thetablh_button.


--- Executes on button press in h2oreject_button.


--- Executes on button press in h2oblh_button.


--- Executes on mouse press over axes background.


--- Executes on button press in done_button.


--- Executes on button press in help_button.


--- Executes when user attempts to close select_bl_heights_GUI.


Redraw the ranges for the given axes


Delete the currently selected range


--- Executes on button press in load_merge.


--- Executes on button press in delete_range.


--- Executes on button press in clear_ranges.


--- Executes on button press in new_range.


--- Executes when user attempts to close alt_range_gui.


--- Executes when selected cell(s) is changed in cat_table.


--- Executes on selection change in campaign_menu.


--- Executes on button press in make_plot_btn.


NESTED FUNCTIONS %%%%%


Script for the figures of Leitao (2010) profiles from the data in the
.mat file Leitao 16 Scenarios (saved in NO2 Profiles/Workspaces)


HELPER FUNCTIONS %


OTHER FUNCTIONS %%%%%


NESTED PLOTTING FUNCTIONS %%%%%


SUB FUNCTIONS %%%%%


JLL 2-18-2014: The flight vector is the straight line between two points
on the earth's surface. It is the chord connecting those points, not the
arc across the surface.


{
Latitude=zeros(60,y); Longitude=zeros(60,y); SpacecraftLatitude=zeros(60,y);
SpacecraftLongitude=zeros(60,y); SpacecraftAltitude=zeros(60,y)
where y = number of scanlines in the orbit, with 60 scenes per scanline
returns array (60,y,2,5), 2=lon,lat, 5=corners(5th=center)
}


JLl 2-19-2014: I believe that lat and lon SHOULD be single numbers but am
not positive.  This then returns the distance from the satellite to the
latitude and longitude input.


Nested functions for output


Nested functions to parse numbers


--- Executes on button press in button_zjump_up.


--- Executes on button press in checkbox_fix_zlim.


--- Executes on button press in button_next.


--- Executes on button press in button_prev.


--- Executes on selection change in menu_shading.


Converts a given correlation matrix into a covariance matrix

	Parameters
	----------
	corr: 2D float array
		Correlation matrix of n components
	var: 1D float array
		Variance of the n components

	Returns
	-------
	corr: 2D float array
		Covariance matrix


Computes the azimuthally-averaged radial profile of a given map.

	Parameters
	----------
	image: 2D float or complex array
	  Input image.
	pixel_size_arcmin: float
	  Pixel size in arcmin.
	return_k: bool, optional
	  If set to True, the provided image is assumed to be a power spectrum
	  and the x-coordinate of the returned data is converted to the
	  two-dimensional spatial frequency k. Default: None

	Returns
	-------
	kradialprofile: float array
	  x-coordinate of the radial profile. Either the radial separation
	  from the image center or spatial frequency k, depending on the
	  value of the variable return_k.
	radialprofile: float or complex array
	  azimuthally averaged radial profile.


Computes the azimuthally-averaged power spectrum of a given map.

	Parameters
	----------
	image: 2D float array
		Input image
	pixel_size_arcmin: float
		Pixel size in arcmin.
	return_k: bool, optional
		If set to True, the provided image is assumed to be a power spectrum
		and the x-coordinate of the returned data is converted to the
		two-dimensional spatial frequency k. Default: None

	Returns
	-------
	k: float array
		x-coordinate of the radial profile. Either the radial separation
		from the image center or spatial frequency k, depending on the
		value of the variable return_k.
	Pk: float or complex array
		azimuthally-averaged power spectrum


Computes the azimuthally-averaged cross-spectrum of a given set of maps.

	Parameters
	----------
	images: 3D float array
		Data cube containing the input images
	pixel_size_arcmin: float
		Pixel size in arcmin.
	return_k: bool, optional
		If set to True, the provided image is assumed to be a powerspectrum
		and the x-coordinate of the returned data is converted to the
		two-dimensional spatial frequency k. Default: None
	global_cross: bool, optional
		If set to True, the cross power of the maps is computed globally
		(i.e. averaged over the full maps / all scales). If False, the
		cross power is computed at each spatial frequency. Default: False

	Returns
	-------
	cc_maps: float array
		Data cube of dimensions n_nu * n_nu containing the azimuthally-averaged
		cross-spectra maps.


Creates a 2D map from an azimuthally-averaged radial profile.
       This is useful for the computing 2D window functions from profiles.

	Parameters
	----------
	reference_image: 2D float or complex array
		Input reference image. Only used to determine the desired image
		dimensions.
	x: float array
		x-coordinate of the azimuthally-averaged radial profile.
		Radial separation from the image center in usints of pixels.
	window: float array
		Azimuthally averaged radial profile to be used to construct the
		2D map

	Returns
	-------
	image: 2D float or complex array
		2D map created from the provided azimuthally-averaged radial
		profile.


Computes and applies a matched filter to a given map. The filter is build from a
       provided source template and the power spectrum of the map.

	Parameters
	----------
	image: 2D float array
		Input image.
	source: 2D float array
		Source template. Needs to have identical dimensions as the provided image.
	noise_map: 2D float array, optional
		The provided noise map will be used to compute noise power spectrum. Otherwise
		the noise power spectrum is directly computed from the image. Default: None
	sigma_noise: float, optional
		Standard deviation of the map noise. Does allow analytic computation of the
		noise power spectrum. Useful for tests with white noise. Default: None

	Returns
	-------
	filtered_image: 2D float array
		Image convolved with the computed matched filter.
	filter_ft: 2D float array
		2D window function of the matched filter.
	noise: float
		Noise level of the filtered map.


Computes and applies a constrained matched filter to a given map. The filter is
       build from a provided source template and the power spectrum of the map.

	Parameters
	----------
	image: 2D float array
		Input image.
	templates: 3D float array
		Data cube containing the individual source templates that will be used to
		construct the filter. The dimensions are supposed to be n * n_x * n_y,
		where n is the number of templates and n_x and n_y are the number of pixels
		along the * and y axis of the images. The latter have to be identical to
		the dimensions of image.
	response: float array
		Array containing the desired response of the filter to each provided source
        template.
	noise_map: 2D float array, optional
		The provided noise map will be used to compute noise power spectrum. Otherwise
		the noise power spectrum is directly computed from the image. Default: None
	sigma_noise: float, optional
		Standard deviation of the map noise. Does allow analytic computation of the
		noise power spectrum. Useful for tests with white noise. Default: None

	Returns
	-------
	filtered_image: 2D float array
		Image convolved with the computed constrained matched filter.
	filter_ft: 2D float array
		2D window function of the constrained matched filter.
	noise: float
		Noise level of the filtered map.


Computes and applies a matched multifilter to a set of multi-frequency map. The
       filter is build from provided spatial and spectral source templates and the cross
       spectrum of a set of maps at different frequencies.

	Parameters
	----------
	images: 3D float array
		Data cube containing the input images that are provided at n_f frequencies.
		The dimensions are supposed to be n_f * n_x * n_y, where n_x and n_y are
		the number of pixels along the * and y axis of the images.
	source: 2D or 3D float array
		Source template. Can either be a single image or alternatively a data cube
		if each image comes at a different spatial resolution. Needs to have identical
		dimensions as images if a cube is provided. Otherwise the single source image
		needs to match the dimensions of a single image.
	spec: float array
		SED of the source. Needs to be provided at the same n_f frequencies as the
		input images.
	noise_maps: 3D float array, optional
		Data cube containing provided noise maps that will be used to compute noise
		power spectrum matrix. Otherwise the noise power spectrum matrix is directly
		computed from the images. noise_maps need to have the same dimensions as images.
		Default: None
	sigma_noise: float array, optional
		Array containing the standard deviation of the noise for the n_f maps. Does
		allow the analytic computation of the noise power spectrum. Useful for tests
		with white noise. Default: None
	no_cross: bool, optional
		If True the frequency-to-frequency cross terms of the n_f maps will be ignored,
		i.e. non-diagonal elements of the noise power spectrum matrix are set to zero.
		Default: False
	global_cross: bool, optional
		If set to True, the cross power of the maps is computed globally
		(i.e. averaged over the full maps / all scales). If False, the
		cross power is computed at each spatial frequency. Default: False

	Returns
	-------
	filtered_image: 2D float array
		Linear combination of the images convolved with the computed matched multifilter.
	filter_ft: 3D float array
		Data cube containing the 2D window functions of the matched multifilter.
	noise: float
		Noise level of the filtered map.