/*!
    \page configopt  Configuration options

    An example configuration file can be found the examples directory (see for instance sample). within the repository.
    Only the keywords listed here will be used, all other words/characters are ignored.
    Note that if misspell a keyword it will not be used. One can check the options used by examining foo.configuration,
    where foo is your base output filename \ref Options.outname. This file lists all the options. Since this file is
    always written DO NOT name your input configuration file foo.configuration.

    There are numerous key words that can be passed to change the values stored in \ref Options. Here we list them
    \section outconfig Output related.
    See \ref outputs for types of output (and \ref io.cxx for implementation of the code)

    \arg  \e Output  Output base name. Overrides the name passed with the command line argument  \e -o . Only implemented for completeness. \ref Options.outname \n
    \arg  \e Write_group_array_file  When producing output also produce a file which lists for every particle the group they belong to. Can be used with \b tipsy format or to tag every particle. \ref Options.iwritefof
    \arg  \e Output_den  A filename for storing the intermediate step of calculating local densities. This is particularly useful if the code is not compiled with \b STRUCDEN & \b HALOONLYDEN (see \ref STF-makeflags). \ref Options.smname \n

    \section searchconfig Parameters related to search type.
    See \ref io.cxx (and related ios like \ref gadgetio.cxx), \ref search.cxx, \ref fofalgo.h for extra details
    \arg  \e Particle_search_type  A integer describing what types of particles are searched \ref Options.partsearchtype. (See \ref SEARCHTYPES) > \n
        - \b 1 \e all particles are searched
        - \b 2 \e DarkMatter particles (which are typically defined as type 1,2,3 for gadget) are searched
        - \b 3 \e Star particles (which are typically defined as type 4 for gadget) are searched
        - \b 4 \e Gas particles (which are typically defined as type 0 for gadget) are searched
    \n
    \arg  \e Baryon_searchflag  0/1/2 indicating gas/stellar search done separately from DM search \ref Options.iBaryonSearch. \n
        - \b 1 field search run as normal and then substructure search for baryons run using baryons identified in field search.
        - \b 2 field search also altered to treat baryons differently, allowing only DM particles to be used as head links (ie link dm-dm, dm-baryon, but not baryon-baryon nor baryon-dm).
        - \b 0 is do nothing special for baryon particles.
    \n
    \arg  \e Singlehalo_search  0/1 flag indicates that no field search is going to be run and the entire volume will be treated as a background region. Useful if searching for substructures in non-cosmological simulations. But can also be co-opted for other searches using different outlier criteria and FOF algorithms. \ref Options.iSingleHalo \n

    \section localdensityconfig Parameters related to local density estimator.
    See \ref localfield.cxx, \ref bgfield.cxx & \ref localbgcomp.cxx for more details

    \arg  \e Nsearch_velocity  number of velocity neighbours used to calculate velocity density, adjust \ref Options.Nvel (suggested value is 32) \n
    \arg  \e Nsearch_physical  number of physical neighbours searched for Nv to calculate velocity density  \ref Options.Nsearch (suggested value is 256) \n
    \arg  \e Cell_fraction  fraction of a halo contained in a subvolume used to characterize the background  \ref Options.Ncellfac \n
    \arg  \e Grid_type  integer describing type of grid used to decompose volume for substructure search  \ref Options.gridtype (see \ref GRIDTYPES) \n
        - \b 1 \e standard physical shannon entropy, balanced KD tree volume decomposition into cells
        - \b 2 \e phase phase-space shannon entropy, balanced KD tree volume decomposition into cells
        - \b 3 \e simple simple physical balanced KD tree decomposition of volume into cells

    \section fofconfig Parameters related to FOF search
    See \ref search.cxx \ref fofalgo.h for more details

    \subsection fofsubconfig Configuration for substructure search
    \arg  \e Search_for_substructure  By default field objects are searched for internal substructures but can disable this by setting this to 0 \n
    \arg  \e Keep_FOF  if field 6DFOF search is done, allows to keep structures found in 3DFOF (can be interpreted as the inter halo stellar mass when only stellar search is used).\n
    \arg  \e FoF_search_type  There are several substructure FOF criteria implemented (see \ref FOFTYPES for more types and \ref fofalgo.h for implementation) \n
        - \b 1 \e standard phase-space based, well tested VELOCIraptor criterion.

    \arg  \e Outlier_threshold  threshold of sigma level of outliers to be searched (default is 2.5) \ref Options.ellthreshold \n
    \arg  \e Significance_level  minimum significance level of group (default is 1) \ref Options.siglevel \n
    \arg  \e Velocity_ratio  speed ratio used in linking particles \ref Options.Vratio \n
    \arg  \e Velocity_opening_angle  angle between velocities when linking (in units of \f$ \pi \f$) \ref Options.thetaopen \n
    \arg  \e Physical_linking_length  physical linking length used in fof (if cosmological gadget file then assumed to be in units of inter particle spacing \ref gadgetio.cxx, if loading in a single halo then based on average interparticle spacing calculated in \ref haloproperties.cxx). To be deprecated and replaced by Substructure_physical_linking_length \ref Options.ellphys \n
    \arg  \e Substructure_physical_linking_length  physical linking length used in fof (if cosmological gadget file then assumed to be in units of inter particle spacing \ref gadgetio.cxx, if loading in a single halo then based on average interparticle spacing calculated in \ref haloproperties.cxx) \ref Options.ellphys \n
    \arg  \e Minimum_size  Minimum group (substructure) size \ref Options.MinSize \n

    \arg  \e Iterative_searchflag  1/0 use interactive substructure search which is designed to first identify spatially compact candidate outlier regions and then relaxes the criteria to find the more diffuse (in phase-space) regions associate with these candidate structures \ref Options.iiterflag \n
    \arg  \e Iterative_threshold_factor  factor multiplied with \ref Options.ellthreshold when using iterative method and identifying outlier regions associated with the initial candidate list of spatially compact outlier groups. Typical values are \f$ \sim 1 \f$ \ref Options.ellfac \n
    \arg  \e Iterative_linking_length_factor  factor multiplied with \ref Options.ellphys when using iterative method and identifying outlier regions associated with the initial candidate list of spatially compact outlier groups. Typical values are \f$ \sim 2 \f$ \ref Options.ellxfac \n
    \arg  \e Iterative_Vratio_length_factor  factor multiplied with \ref Options.Vratio when using iterative method and identifying outlier regions associated with the initial candidate list of spatially compact outlier groups. Typical values are \f$ \sim 1 \f$ \ref Options.vfac \n
    \arg  \e Iterative_ThetaOp_length_factor  factor multiplied with \ref Options.thetaopen when using iterative method and identifying outlier regions associated with the initial candidate list of spatially compact outlier groups. Typical values are \f$ \sim 1 \f$ \ref Options.thetafac \n
    \arg  \e CMrefadjustsubsearch_flag  1/0 flag indicating whether particles are moved to the rough CM velocity frame of the background before substructures are searched for. \ref Options.icmrefadjust \n

    \subsection foffieldconfig Configuration for field search
    \arg  \e FoF_Field_search_type  There are several FOF criteria implemented to search for so-called field objects (see \ref FOFTYPES for more types and \ref fofalgo.h for implementation) \ref Options.fofbgtype \n
        - \b 5 \e standard 3D FOF based algorithm
        - \b 4 \e standard 3D FOF based algorithm  FOLLOWED  by 6D FOF search using the velocity scale defined by the largest halo on  ONLY  particles in 3DFOF groups
        - \b 3 \e standard 3D FOF based algorithm  FOLLOWED  by 6D FOF search using the velocity scale for each 3DFOF group
    \arg  \e Minimum_halo_size  Allows field objects (or so-called halos) to require a different minimum size (typically would be <= \ref Options.MinSize. Default is -1 which sets it to \ref Options.MinSize) \ref Options.HaloMinSize \n
    \arg  \e Halo_linking_length_factor  allows one to use different physical linking lengths between field objects and substructures.  (Typically for 3DFOF searches of dark matter haloes, set to value such that this times \ref Options.ellphys = 0.2 the interparticle spacing when examining cosmological simulations ) \ref Options.ellhalophysfac \n
    \arg  \e Halo_velocity_linking_length_factor  allows one to use different velocity linking lengths between field objects and substructures when using 6D FOF searches.  (Since in such cases the general idea is to use the local velocity dispersion to define a scale, \f$ \geq5 \f$ times this value seems to correctly scale searches) \ref Options.ellhalovelfac \n
    \arg  \e Halo_6D_linking_length_factor  allows one to use different linking lengths between 3DFOF and 6DFOF field search. Typically values are \f$ \sim 1 \f$ \n
    \arg  \e Halo_6D_vel_linking_length_factor  scaling applied to dispersions used in 6DFOF field search. Typical values are \f$ \geq 1.25 \f$ \n

    \arg  \e Halo_core_search  0/1/2 flag allows one to explicitly search for large 6D FOF cores that are indicative of a recent major merger. Since substructure is defined on the scale of the maximum cell size and major mergers typically result two or more phase-space dense regions that are \e larger than the cell size used in reasonable substructure searches, one can identify them using this search. The overall goal is to treat these objects differently than a substructure. However, if 2 is set, then smaller core is treated as substruture and all particles within the FOF envelop are assigned to the cores based on their phase-space distance to core particles \ref Options.iHaloCoreSearch \n
    \arg  \e Use_adaptive_core_search  0/1 flag allows one to run complex adaptive phase-space search for large 6D FOF cores and then use these linking lengths to separate mergers. 0 is simple high density dispersively cold cores with v scale adaptive, 1 is adaptive with simple dispersions in both x and v.
    \arg  \e Use_phase_tensor_core_growth  0/1 flag allows one to run complex phase-space growth of merger remnants (6D FOF cores found). 0 is assignment with simple x and v dispersion to nearest core particle, 1 is phase-space tensor distance assignemnt to CM of core.
    \arg  \e Halo_core_ellx_fac  scaling applied to linking length when identifying merger remnants. Typically values are \f$ \sim0.5 \f$  \ref Options.halocorexfac
    \arg  \e Halo_core_ellv_fac  scaling applied to local dispersion to define the velocity scale used to identify merger remnants. Typically values are \f$ \sim1 \f$  \ref Options.halocorevfac
    \arg  \e Halo_core_ncellfac  used to determine the minimum number of particles a merger remnants is composed of, specifically \f$ N_{\rm min}= f_{\rm ncell}* N_{\rm S} \f$. Typically values are 0.005
    \arg  \e Halo_core_adaptive_sigma_fac  used when running fully adaptive core search, specifies the width of the physical linking length in configuration space dispersion (think of this as how many sigma to include). Typically values are \f$ \sim2 \f$. This has been tested on hydrodynamnical simulations to separate galaxy mergers. \ref Options.halocoresigmafac
    \arg  \e Halo_core_num_loops  allows the core search to iterate, shrinking the velocity linking length to used till the number of cores identified decreases or this limit is reached. Allows apative search with larger linking length to be robust.  Typically values are \f$ \sim5 \f$ with loops only running often twice. \ref Options.halocorenumloops.
    \arg  \e Halo_core_loop_ellx_fac  Factor by which configuration linking length is decreased when running loops for core search.  Typically values are \f$ \sim0.75 \f$. \ref Options.halocorexfaciter
    \arg  \e Halo_core_loop_ellv_fac  Factor by which velocity linking length is decreased when running loops for core search.  Typically values are \f$ \sim0.75 \f$. \ref Options.halocorevfaciter
    \arg  \e Halo_core_loop_elln_fac  Factor by which min group size is changed when running loops for core search.  Typically values are \f$ \sim1.25 \f$. \ref Options.halocorenumfaciter
    \arg  \e Halo_core_phase_significance  Significance a core must be in terms of phase-space distance scaled by dispersions (sigma).

    \section unbindconfig Unbinding Parameters
    See \ref unbinding and \ref unbind.cxx for more details

    \arg  \e Unbind_flag   whether or not substructures should be passed through an unbinding routine. \ref Options.uinfo & \ref UnbindInfo.unbindflag \n
    \arg  \e Unbind_Only_With_Baryons_flag   whether or not substructures should be passed through an unbinding routine only after having baryons added. This applies to running velociraptor on a simulation containing all different types of particles where substructure is searched using initially dark matter particles before adding baryons in a phase-space search. \ref Options.uinfo & \ref UnbindInfo.iunbindwithbaryons \n
    \arg  \e Allowed_kinetic_potential_ratio   ratio of kinetic to potential energy at which a particle is still considered bound, ie: particle is still bound
    if \f$ \alpha T+W<0 \f$, so \f$ \alpha=1 \f$ would be standard unbinding and \f$ \alpha<1 \f$ allows one to identify unbound tidal debris.
    Given that  VELOCIraptor  was designed to identify tidal streams, it makes little sense to have this set to 1 unless explicitly required.
    Note that the code still separates particles into bound and unbound. Typical values of \f$ \alpha\geq 0.2 \f$ seems to minimize the number of false positives
    in tidal debris while still identifying completely unbound tidal debris. \ref Options.uinfo & \ref UnbindInfo.Eratio \n
    \arg  \e Min_bound_mass_frac  Designed to demand a substructure still have a minimum amount of self-bound mass. \ref Options.uinfo & \ref UnbindInfo.minEfrac \n
    \arg  \e Bound_halos  0/1/2 flag to make sure field objects such as haloes are self bound before (use 1) and also after (use 2) substructures have been identified
    and extracted from the halo. Demanding boundness after substructure search can have interesting consequences as it is possible that a multiple merger will appear as
    a single FOF halo, however all with all the cores removed, the FOF halo is actually an unbound structure. \ref Options.iBoundHalos \n
    \arg  \e Keep_background_potential  1/0 flag When determining whether a structure is self-bound, the approach taken is to treat the candidate structure in isolation. Then determine the velocity reference frame to determine the kinetic energy of each particle and remove them. However, it is possible one wishes to keep the background particles when determining the potential, that is once one starts unbinding, don't treat the candidate structure in isolation but in a background sea. When finding tidal debris, it is useful to keep the background. \ref Options.uinfo & \ref UnbindInfo.bgpot \n
    \arg  \e Kinetic_reference_frame_type  specify kinetic frame when determining whether particle is bound.
    Default is to use the centre-of-mass velocity frame (0) but can also use region around minimum of the potential (1). \ref Options.uinfo & \ref UnbindInfo.cmvelreftype \n
    \arg  \e Min_npot_ref  Set the minimum number of particles used to calculate the velocity of the minimum of the potential (10). \ref Options.uinfo & \ref UnbindInfo.Npotref \n
    \arg  \e Frac_pot_ref  Set the fraction of particles used to calculate the velocity of the minimum of the potential (0.1). \ref Options.uinfo & \ref UnbindInfo.fracpotref \n
    \arg  \e Unbinding_type  Set the unbinding criteria, either just remove particles deemeed "unbound", that is those with \f$ \alpha T+W>0\f$, choosing \ref UPART. Or with \ref USYSANDPART
    removes "unbound" particles till system also has a true bound fraction > \ref UnbindInfo.minEfrac.
    \arg  \e Softening_length  Set the (simple plummer) gravitational softening length. \ref UnbindInfo.eps

    \section cosmoconfig Units & Cosmology
    \subsection unitconfig Units
    \arg  \e Length_unit  change the input length unit \ref Options.L \n
    \arg  \e Velocity_unit  change the input velocity unit \ref Options.V \n
    \arg  \e Mass_unit  change the input mass unit \ref Options.M \n
    \arg  \e Gravity  change the gravity unit. should be set such that \f$ v^2=GM/r \f$.   \ref Options.G \n
    \arg  \e Hubble_unit  change the value of Hubble expansion (from normal 100 km/s/Mpc to units used, that is velocity unit/length unit) \ref Options.G \n
    \arg  \e Mass_value  if not mass is stored using the option \b NOMASS (see \ref STF-makeflags) then this is the mass of the particles \ref Options.MassValue \n
    \arg  \e Length_unit_to_kpc  Specify the conversion factor from the output unit to kpc \ref Options.lengthtokpc \n
    \arg  \e Velocity_unit_to_kms  Specify the conversion factor from the output unit to kms \ref Options.velocitytokms \n
    \arg  \e Mass_unit_to_solarmass  Specify the conversion factor from the output unit to solar masses \ref Options.masstosolarmass \n

    \subsection cosmologyconfig Cosmology
    \arg  \e Period  if not defined in the input data one can pass the period in the input units of the data. This is not always necessary, for instance the gadget snapshot format has this in the header.  \ref Options.p \n
    \arg  \e Scale_factor  scale factor time if not defined in the input data. This is not always necessary, for instance the gadget snapshot format has this in the header.  \ref Options.a \n
    \arg  \e h_val  the "little h" value often used in cosmological simulation when defining expansion rates, distance scales, etc. This is not always necessary, for instance the gadget snapshot format has this in the header.  \ref Options.h \n
    \arg  \e Omega_m  matter density in units of the critical density used in cosmological simulations. This is not always necessary, for instance the gadget snapshot format has this in the header.  \ref Options.Omega_m \n
    \arg  \e Omega_Lambda  energy density of the cosmological constant (or can technically be used for a dark energy fluid) in units of the critical density used in cosmological simulations. This is not always necessary, for instance the gadget snapshot format has this in the header.  \ref Options.Omega_Lambda \n
    \arg  \e Omega_cdm  dark matter density in units of the critical density used in cosmological simulations. This is not always necessary since for simple pure DM cosmological simulations this is easily determined by the total mass in the simulation.  However, for multiple resolution or non-standard DM models, this should be provided.  \ref Options.Omega_cdm \n
    \arg  \e Omega_b  baryon density in units of the critical density used in cosmological simulations. This is not always necessary since for simple pure adiabatic cosmological simulations this is easily determined by the total gas mass in the simulation.  \ref Options.Omega_b \n
    \arg  \e Omega_r  radiation density in units of the critical density used in cosmological simulations. Typically 0 as negligible in most simulations.  \ref Options.Omega_r \n
    \arg  \e Omega_nu  neutrino density in units of the critical density used in cosmological simulations. Typically 0 as negligible in most simulations and may need alteration for consistent evolution across cosmic time.  \ref Options.Omega_nu \n
    \arg  \e Omega_DE  dark energy density in units of the critical density used in cosmological simulations. Typically 0 unless what evolution based on w_of_DE.  \ref Options.Omega_de \n
    \arg  \e w_of_DE  equation of state of the dark energy fluid, \f$ w=\frac{p}{\rho} \f$. This is not necessary unless one is using a cosmological simulation with a \f$ w\neq -1 \f$ \ref Options.w_de \n
    \arg  \e Virial_density  virial overdensity in units of the background matter density used in cosmological simulations. This is not absolutely necessary for gadget format as for this input, the Bryan & Norman 1998 virial density is calculated based on a LCDM cosmology as \ref Options.virlevel is set to -1 and if left, a virial density is calculated. If set and a gadget input is used, this overrides the Bryan & Norman calculation. \n
    \arg  \e Critical_density  critical density in input units used in cosmological simulations. This is not absolutely necessary for gadget format as it can be calculated from the quantities in the header for typical GR cosmologies. \ref Options.rhobg \n

    \section otherconfigs Other configuration options
    \arg  \e Effective_Resolution  If running a multiple resolution cosmological zoom simulation, simple method of scaling the linking length by using the period, ie: \f$ p/N_{\rm eff} \f$ \ref Options.Neff \n
    \arg  \e Snapshot_value  If halo ids need to be offset to some starting value based on the snapshot of the output, which is useful for some halo merger tree codes, one can specific a snapshot number, and all halo ids will be listed as internal haloid + \f$ sn\times10^{12}\f$. \ref Options.snapshotvalue \n
    \arg  \e Verbose  2/1/0 flag indicating how talkative the code is (2 very verbose, 1 verbose, 0 quiet). \ref Options.iverbose \n

    \section propconfigs Property calculation options
    \arg  \e Inclusive_halo_mass  1/0 flag indicating whether inclusive masses are calculated for field objects. \ref Options.iInclusiveHalo \n
    \arg  \e Extensive_halo_properties_output  1/0 flag indicating whether to calculate/output even more halo properties. \ref Options.iextrahalooutput \n
    \arg  \e Extended_output  1/0 flag indicating whether produce extended output for quick particle extraction from input catalog of particles in structures \ref Options.iextendedoutput \n
    \arg  \e Iterate_cm_flag  1/0 flag indicating whether to use shrinking spheres to calculate the center of mass and velocity. \ref Options.iIterateCM \n
    \arg  \e Sort_by_binding_energy  1/0 flag indicating whether to sort by particle binding energy or by potential (if 0). \ref Options.iSortByBindingEnergy \n

    \section ioconfigs I/O options
    \arg  \e Cosmological_input  1/0 indicating that input simulation is cosmological or not. With cosmological input, a variety of length/velocity scales are set to determine such things as the virial overdensity, linking length. \ref Options.icosmologicalin \n
    \arg  \e Input_chunk_size  Amount of information to read from input file in one go (100000). \ref Options.inputbufsize \n
    \arg  \e Write_group_array_file  0/1 flag indicating whether write a single large tipsy style group assignment file is written. \ref Options.iwritefof \n
    \arg  \e Separate_output_files  1/0 flag indicating whether separate files are written for field and subhalo groups. \ref Options.iseparatefiles \n
    \arg  \e Binary_output  3/2/1/0 flag indicating whether output is hdf, binary or ascii. \ref Options.ibinaryout, \ref OUTADIOS, \ref OUTHDF, \ref OUTBINARY, \ref OUTASCII \n
    \arg  \e Comoving_units  1/0 flag indicating whether the properties output is in physical or comoving little h units. \ref Options.icomoveunit \n

    \section inputflags input flags related to varies input formats
    \arg  \e NSPH_extra_blocks  If gadget snapshot is loaded one can specific the number of extra  SPH  blocks are read/in the file. \ref Options.gnsphblocks \n
    \arg  \e NStar_extra_blocks  If gadget snapshot is loaded one can specific the number of extra  Star  blocks are read/in the file. \ref Options.gnstarblocks \n
    \arg  \e NBH_extra_blocks  If gadget snapshot is loaded one can specific the number of extra  Black hole  blocks are read/in the file. \ref Options.gnbhblocks \n

    \arg  \e HDF_name_convention  HDF dataset naming convection. See \ref hdfitems.h for what naming conventions are available and what names exist. Currently have \ref HDFNUMNAMETYPES. \ref Options.ihdfnameconvention \n
    \arg  \e Input_includes_dm_particle  If dm particle specific information is in the input file. \ref Options.iusedmparticles \n
    \arg  \e Input_includes_gas_particle  If gas particle specific information is in the input file. \ref Options.iusegasparticles \n
    \arg  \e Input_includes_star_particle  If star particle specific information is in the input file. \ref Options.iusestarparticles \n
    \arg  \e Input_includes_bh_particle  If bh/sink particle specific information is in the input file. \ref Options.iusesinkparticles \n
    \arg  \e Input_includes_wind_particle  If wind particle specific information is in the input file. \ref Options.iusewindparticles \n
    \arg  \e Input_includes_tracer_particle  If tracer particle specific information is in the input file. \ref Options.iusetracerparticles \n
    \arg  \e Input_includes_star_particle  If star particle specific information is in the input file. \ref Options.iusestarparticles \n

    \section mpiconfigs MPI specific options
    \arg  \e MPI_part_allocation_fac  Memory allocated in mpi mode to store particles is (1+factor)* the memory need for the initial mpi decomposition.
    This factor should be >0 and is mean to allow a little room for particles to be exchanged between mpi threads withouth having to require new memory allocations and copying
    of data. \ref Options.mpipartfac \n
    \arg  \e MPI_particle_total_buf_size  Total memory size in bytes used to store particles in temporary buffer such that
    particles are sent to non-reading mpi processes in one communication round in chunks of size buffer_size/NProcs/sizeof(Particle). \ref Options.mpiparticlebufsize \n

    */


///Read parameters from a parameter file. For list of currently implemented options see \ref configopt
///\todo still more parameters that can be adjusted


///define the configuration constructor so all input options are stored.


///reads a tipsy file


///\name define routines for the HeaderUnitInfo


///\name define write routines for the property data structure
//{@
///write (append) the properties data to an already open binary file


///Fills the GridCell struct using KD-Tree initialized by \ref InitializeTreeGrid


/// Optimised version of 6DFOF that performs no divisions


///stream FOF algorithm that requires the primary particle to be dark matter for a link to occur


///\name XDR read routines, assist in reading nchilada data
//@{


///read a particular data field from a nchilada file


/// Returns total number of particles in a given file
/// @param filename data file of interest. Criticially returns 0 if this file cannot be read
/// interpreted as no particles


///get the number of particles of the desired type


///reads an nchilada formatted file.


///check configuration options with swift


//set simulation state


///\todo interface with swift is comoving positions, period, peculiar velocities and physical self-energy


/*
 * read the file contents to a character buffer
 */


// assumes atomic execution


// check for OpenGL errors


//------------------------------------------------------------------------------
// Function     	  : EvalHermite
// Description	    :
//------------------------------------------------------------------------------
/**
 * EvalHermite(float pA, float pB, float vA, float vB, float u)
 * @brief Evaluates Hermite basis functions for the specified coefficients.
 */


// commented out to remove unused parameter warnings in Linux


//cudaEvent_t startEvent, stopEvent;


//calculate position of software 3D cursor, not so useful right now but helps for picking in future


//end of mainRender


// transform vector by inverse of matrix (assuming orthonormal)


// integer hash function (credit: rgba/iq)


// draw points from vertex buffer objects


// draw points using given shader program


// calculate vectors for half-angle slice rendering


// draw quad for volume rendering


// draw slice of particles from camera view


// draw slice of particles from light's point of view


// draw slice of particles from light's point of view
// version with anti-aliasing


// draw particles as slices with shadowing


// blur light buffer to simulate scattering effects


// post-process final volume image


// display texture to screen


// composite final volume image on top of scene


// render scene depth to texture
// (this is to ensure that particles are correctly occluded in the low-resolution render buffer)


// create an OpenGL texture


// create textures for off-screen rendering


// create textures for light buffer


// render vectors to screen for debugging


//------------------------------------------------------------------------------
// Function     	  : EvalHermite
// Description	    :
//------------------------------------------------------------------------------
/**
* EvalHermite(float pA, float pB, float vA, float vB, float u)
* @brief Evaluates Hermite basis functions for the specified coefficients.
*/


/* some code samples and ideas are taken from IceT */


//Exports a full-structure including the multipole moments


//Only counts the items in a full-structure
//We basically count the nodes that form the external
//structure of the tree


//Functions related to domain decomposition


//Uses one communication by storing data in one buffer and communicate required information,
//such as box-sizes and number of sample particles on this process. Nsample is set to 0
//since it is not used in this function/hash-method


//Broadcast the group-tree structure (used during the LET creation)
//First we gather the size, so we can create/allocate memory
//and then we broad-cast the final structure
//This basically is a sync-operation and therefore can be quite costly
//Maybe we want to do this in a separate thread
/****** EGABUROV ****/


//Compute PH key, same function as on device


//Sum the number of particles on all processes


//Splits an array of integers, the values in srcValid indicate if a
//value is valid (1 == valid anything else is UNvalid) returns the
//split values in the output array (first all valid
//number and then the invalid ones) and the total
//number of valid items is stored in 'count'


// returns true if this iteration is the last (t_current >= t_end), false otherwise


//Input keys, output a permutation that presents the new order


//This function builds a hash-table for the particle-keys which is required for the
//domain distribution based on the SFC


//Binary search of the key within certain bounds (cij.x, cij.y)


//Compute the properties of the newly build tree-nodes


//Standard out, note we write to a buffer to make
//sure the whole line is output in one flush


/*
 * This thread watches if the simulation progresses or if it 'hangs'
 * this sometime happens (for unknown) reasons on large runs with file writing.
 * To prevent usage of precious compute cycles this thread kills the program
 * after 360 seconds of no progress.
 */


/*
 *  Signal the IO process that we're finished (this is when tCurrent == -1) *
 *
 */


/*
 *
 * Send the particle data over MPI to another process.
 * Note only works for nQuickDump data
 */


/*
 *
 * Send the particle data to a file
 * Works for both full snapshots and quickdump files
 */


/***********************************************************************
    map2alm

       input: map, lmax=3*nside-1, mmax=lmax, cl=False
              iter=3, use_weights=False

       output: alm (or cl if cl=True)
*/


/***********************************************************************
    alm2map

       input: cl or alm, nside, iter=3, use_weights=True

       output: map in RING scheme
*/


/***********************************************************************
    alm2map_der1

       input: alm, nside,

       output: map in RING scheme
*/


/*! Converts a FITS type code (i.e. the data type of a FITS column) to the
    corresponding Planck type code. */


/*! Converts a Planck type code to the corresponding FITS type code
    (i.e. the data type of a FITS column). */


/*! Routine to convert from ecliptic coordinates to equatorial (celestial)
    coordinates at the given epoch.  Adapted from the COBLIB routine by Dr.
    E. Wright. */


/*! Routine to convert galactic coordinates to ecliptic (celestial)
    coordinates at the given epoch.  First the conversion to ecliptic
    2000 is done, then if necessary the results are precessed. */


/*! Routine to convert ecliptic (celestial) coordinates at the given
    epoch to galactic coordinates.  The ecliptic coordinates are first
    precessed to 2000.0, then converted. */


/*! Function to convert between standard coordinate systems, including
    precession. */


/*! Performs one Runge-Kutta second order step. Updates loc and dir. */


/*! Second order Runge-Kutta integration on the sphere.  Given a
  starting location, a qu map of the sky, and a step size theta, this
  subroutine returns an array of vectors extending in both
  directions from the starting location.  */


/*! Create a sinusoidal kernel. */


/*! Convolve an array with a kernel. */


/*! Perform line integral convolution on sphere. */


//    *----------------------------*
//    |    GETTERS AND SETTERS     |
//    *----------------------------*


// Usuallly we assume variance is > 0, but in the scenario, y = e^x could be negative


// *------------------------------*
// |           VISUAL             |
// *------------------------------*


/**
 * Constructor for a SimplePoly with predefined top and bottom altitudes.
 *
 * @param b Bottom altitude
 * @param t Top Altitude
 */


/**
 * Create a deep copy of a SimplePoly
 *
 * @param p Source poly.
 */


/**
 * Create a SimplePoly from a Poly3D.  This SimplePoly will use Euclidean coordinates.
 */


/**
	 * Add a point to this bounding rectangle.
	 * @param x
	 * @param y
	 */


/**
	 * Determines if the given point is within the bounding rectangle. A point on
	 * the edges of this rectangle is also within the rectangle.
	 *
	 * @param x the x coordinate of the point in question
	 * @param y the y coordinate of the point in question
	 * @return true if the point is within the bounding rectangle or on any of its
	 *         edges.
	 */


/** Is this position in the contained area?  (using only the X and Y coordinates)
	 *
	 * @param p a position
	 * @return true if the point is contained
	 */


/**
	 * Return true if any point in rect is within buffer of any point in this bounding rectangle. Only two dimensions are used
	 * @return true, if the supplied BoundingRectangle intersects this one
	 */


//	/**
//	 * Returns a GeneralPath representation for testing purposes.
//	 *
//	 * @return this polygon as a GeneralPath
//	 */
//	GeneralPath Poly2D::getGeneralPath() {
//		final double epsilon = 1e-6;
//		GeneralPath gp = null;
//		//if (gp == null) {
//		gp = GeneralPath();
//		gp.moveTo((float) vertices[0].x, (float) vertices[0].y);
//		int length = vertices.size();
//		if (std::abs(vertices[length - 1].x - vertices[0].x) < epsilon && std::abs(vertices[length-1].y - vertices[0].y) < epsilon) --length;
//		for (int i = 1 ; i <= length - 1 ; i++) {
//			gp.lineTo((float) vertices[i].x, (float) vertices[i].y);
//		}
//		gp.closePath();
//		//}
//		return gp;
//	}


// New datatype dealloc method


// New datatype method to create new region


// TODO: should the routine error out if there are more mask elements
//       (i.e. set to true) than kernel items to copy? The code has
//       been adjusted to ignore these extra elements at this time,
//       rather than read out-of-bounds.
//


// The XSPEC initialization used to be done lazily - that is, only
// when the first routine from XSPEC was about to be called - but
// the module is now set up so that we need to know the version
// of XSPEC being used when the sherpa.astro.xspec module is
// being created. As the version requires a run-time check (that
// is, the get_version call is made) then we know that we need to
// initialize the XSPEC code when the Python module is installed.
// So we no-longer need to support the lazy loading.
//


// The string handling depends on whether we have access to the
// CIAO data model, in which we case we can use dmRegParse and
// so support FITS region files, or if we do not have it, in
// which case we are restricted to ASCII region files via
// regReadAsciiRegion.
//


// The constructor can be given a string and a flag, which if
// set indicates this is a file name. The file support is
// unnecessary as we can read the data in Python, so this
// API could just deal with strings (it lets the C code deal
// with the length of the region string rather than us).
//


// Return the mask indicating whether the array points
// lie inside or outside the region.
//


// Invert a region. The method takes no arguments, so I assume
// args is NULL.
//


// These functions borrowed from jdmath


// integrate from: (flo, fhi, fy)
//               to: (tlo, thi) yielding => ty


// The neville interpolation code should live in utils dir but
// because the implementation plan the code cannot be modular.


// Often, these parameter estimiation routines need to check
// if they are butting up against the hard minimum or hard
// maximum.  This helper function checks for that.  Make sure
// hard minimum and hard maximum are passed to this function!


// This function calculates the information matrix--*not* the
// covariance matrix.  The calling function has to invert the
// information matrix to get the covariance matrix.


// NaN value encountered


// This function use the projection method to estimate
// errors on best-fit parameter values.


//
// construct a regular simplex, see: Spendley, Hext and Himsworth,
// "Sequential Application of Simplex Designs in Optimization and
// "Evolutionary Operation", Technometics, Vol 4, No 4, Nov 1962
// pages 441-461.
//


//
// The nearly universal choices used in the
// standard Nelder-Mead algorithm are:
//
// reflection(rho)=1.0, expansion(chi)=2.0,
// contraction(gamma)=0.5, shrink(sigma)=0.5
//


// check_coefficients
// 4.// return of true ==> perform step 5 (shrink) otherwise do not shrink


//
// make sure the initial simplex vertices are within bounds.
//


//
// Move vertex to the position:
//                                _
//           x     = ( 1 + coef ) x - coef x
//            new                           n+1
//       _
// where x and x    are the centroid and the worst vertex of the simplex,
//              n+1
//
// respectively. Then evaluate the function at the new position.
//
//      _           _                        _
// x  = x + rho * ( x - x   ) =  ( 1 + rho ) x  - rho x               (2.4)
//  r                    n+1                           n+1
//      _               _                      _
// x  = x + chi * ( x - x ) =  ( 1 + rho chi ) x  - rho chi x         (2.5)
//  e                r                                       n+1
//      _                 _                       _
// x  = x + gamma * ( x - x ) = ( 1 + rho gamma ) x  - rho gamma x    (2.6)
//  c                  r                                          n+1
//       _           _                         _
// x   = x - gamma ( x - x   ) = ( 1 - gamma ) x + gamma x            (2.7)
//  cc                    n+1                             n+1
//


//*****************************************************************************
//
// py_difevo_lm:  Python wrapper function for C++ function difevo
//
//*****************************************************************************


//
// minim has over expanded beyond a free parameter's boundary, need
// to move back into allowed space by the same amount that was exceeded.
// However, one has to make sure that one does not overshoot the other
// boundary in the event that the boundaries are very tight
//


//
// EXPONENTIAL CROSSOVER
//
// DE/best/1/exp
// Our oldest strategy but still not bad. However, we have found several
// optimization problems where misconvergence occurs.
//


//
// DE/rand/1/exp
// This is one of my favourite strategies. It works especially well when
// the "bestit[]"-schemes experience misconvergence. Try e.g.
// F=0.7 and CR=0.5 as a first guess.
//


//
// DE/rand-to-best/1/exp
// This strategy seems to be one of the best strategies. Try F=0.85 and
// CR=1. If you get misconvergence try to increase NP. If this doesn't
// help you should play around with all three control variables.
//


//
// c     **********
// c
// c     function enorm
// c
// c     given an n-vector x, this function calculates the
// c     euclidean norm of x.
// c
// c     the euclidean norm is computed by accumulating the sum of
// c     squares in three different sums. the sums of squares for the
// c     small and large components are scaled so that no overflows
// c     occur. non-destructive underflows are permitted. underflows
// c     and overflows do not occur in the computation of the unscaled
// c     sum of squares for the intermediate components.
// c     the definitions of small, intermediate and large components
// c     depend on two constants, rdwarf and rgiant. the main
// c     restrictions on these constants are that rdwarf**2 not
// c     underflow and rgiant**2 not overflow. the constants
// c     given here are suitable for every known computer.
// c
// c     the function statement is
// c
// c       real precision function enorm(n,x)
// c
// c     where
// c
// c       n is a positive integer input variable.
// c
// c       x is an input array of length n.
// c
// c     subprograms called
// c
// c       fortran-supplied ... dabs,dsqrt
// c
// c     argonne national laboratory. minpack project. march 1980.
// c     burton s. garbow, kenneth e. hillstrom, jorge j. more
// c
// c     **********
//


// c     **********
// c
// c     subroutine covar
// c
// c     given an m by n matrix a, the problem is to determine
// c     the covariance matrix corresponding to a, defined as
// c
// c                    t
// c           inverse(a *a) .
// c
// c     this subroutine completes the solution of the problem
// c     if it is provided with the necessary information from the
// c     qr factorization, with column pivoting, of a. that is, if
// c     a*p = q*r, where p is a permutation matrix, q has orthogonal
// c     columns, and r is an upper triangular matrix with diagonal
// c     elements of nonincreasing magnitude, then covar expects
// c     the full upper triangle of r and the permutation matrix p.
// c     the covariance matrix is then computed as
// c
// c                      t     t
// c           p*inverse(r *r)*p  .
// c
// c     if a is nearly rank deficient, it may be desirable to compute
// c     the covariance matrix corresponding to the linearly independent
// c     columns of a. to define the numerical rank of a, covar uses
// c     the tolerance tol. if l is the largest integer such that
// c
// c           abs(r(l,l)) .gt. tol*abs(r(1,1)) ,
// c
// c     then covar computes the covariance matrix corresponding to
// c     the first l columns of r. for k greater than l, column
// c     and row ipvt(k) of the covariance matrix are set to zero.
// c
// c     the subroutine statement is
// c
// c       subroutine covar(n,r,ldr,ipvt,tol,wa)
// c
// c     where
// c
// c       n is a positive integer input variable set to the order of r.
// c
// c       r is an n by n array. on input the full upper triangle must
// c         contain the full upper triangle of the matrix r. on output
// c         r contains the square symmetric covariance matrix.
// c
// c       ldr is a positive integer input variable not less than n
// c         which specifies the leading dimension of the array r.
// c
// c       ipvt is an integer input array of length n which defines the
// c         permutation matrix p such that a*p = q*r. column j of p
// c         is column ipvt(j) of the identity matrix.
// c
// c       tol is a nonnegative input variable used to define the
// c         numerical rank of a in the manner described above.
// c
// c       wa is a work array of length n.
// c
// c     subprograms called
// c
// c       fortran-supplied ... dabs
// c
// c     argonne national laboratory. minpack project. august 1980.
// c     burton s. garbow, kenneth e. hillstrom, jorge j. more
// c
// c     **********


//
// c     **********
// c
// c     subroutine lmpar
// c
// c     given an m by n matrix a, an n by n nonsingular diagonal
// c     matrix d, an m-vector b, and a positive number delta,
// c     the problem is to determine a value for the parameter
// c     par such that if x solves the system
// c
// c           a*x = b ,     sqrt(par)*d*x = 0 ,
// c
// c     in the least squares sense, and dxnorm is the euclidean
// c     norm of d*x, then either par is zero and
// c
// c           (dxnorm-delta) .le. 0.1*delta ,
// c
// c     or par is positive and
// c
// c           abs(dxnorm-delta) .le. 0.1*delta .
// c
// c     this subroutine completes the solution of the problem
// c     if it is provided with the necessary information from the
// c     qr factorization, with column pivoting, of a. that is, if
// c     a*p = q*r, where p is a permutation matrix, q has orthogonal
// c     columns, and r is an upper triangular matrix with diagonal
// c     elements of nonincreasing magnitude, then lmpar expects
// c     the full upper triangle of r, the permutation matrix p,
// c     and the first n components of (q transpose)*b. on output
// c     lmpar also provides an upper triangular matrix s such that
// c
// c            t   t                   t
// c           p *(a *a + par*d*d)*p = s *s .
// c
// c     s is employed within lmpar and may be of separate interest.
// c
// c     only a few iterations are generally needed for convergence
// c     of the algorithm. if, however, the limit of 10 iterations
// c     is reached, then the output par will contain the best
// c     value obtained so far.
// c
// c     the subroutine statement is
// c
// c       subroutine lmpar(n,r,ldr,ipvt,diag,qtb,delta,par,x,sdiag,
// c                        wa1,wa2)
// c
// c     where
// c
// c       n is a positive integer input variable set to the order of r.
// c
// c       r is an n by n array. on input the full upper triangle
// c         must contain the full upper triangle of the matrix r.
// c         on output the full upper triangle is unaltered, and the
// c         strict lower triangle contains the strict upper triangle
// c         (transposed) of the upper triangular matrix s.
// c
// c       ldr is a positive integer input variable not less than n
// c         which specifies the leading dimension of the array r.
// c
// c       ipvt is an integer input array of length n which defines the
// c         permutation matrix p such that a*p = q*r. column j of p
// c         is column ipvt(j) of the identity matrix.
// c
// c       diag is an input array of length n which must contain the
// c         diagonal elements of the matrix d.
// c
// c       qtb is an input array of length n which must contain the first
// c         n elements of the vector (q transpose)*b.
// c
// c       delta is a positive input variable which specifies an upper
// c         bound on the euclidean norm of d*x.
// c
// c       par is a nonnegative variable. on input par contains an
// c         initial estimate of the levenberg-marquardt parameter.
// c         on output par contains the final estimate.
// c
// c       x is an output array of length n which contains the least
// c         squares solution of the system a*x = b, sqrt(par)*d*x = 0,
// c         for the output par.
// c
// c       sdiag is an output array of length n which contains the
// c         diagonal elements of the upper triangular matrix s.
// c
// c       wa1 and wa2 are work arrays of length n.
// c
// c     subprograms called
// c
// c       minpack-supplied ... dpmpar,enorm,qrsolv
// c
// c       fortran-supplied ... dabs,dmax1,dmin1,dsqrt
// c
// c     argonne national laboratory. minpack project. march 1980.
// c     burton s. garbow, kenneth e. hillstrom, jorge j. more
// c
// c     **********
//


//
// c     **********
// c
// c     subroutine qrfac
// c
// c     this subroutine uses householder transformations with column
// c     pivoting (optional) to compute a qr factorization of the
// c     m by n matrix a. that is, qrfac determines an orthogonal
// c     matrix q, a permutation matrix p, and an upper trapezoidal
// c     matrix r with diagonal elements of nonincreasing magnitude,
// c     such that a*p = q*r. the householder transformation for
// c     column k, k = 1,2,...,min(m,n), is of the form
// c
// c                           t
// c           i - (1/u(k))*u*u
// c
// c     where u has zeros in the first k-1 positions. the form of
// c     this transformation and the method of pivoting first
// c     appeared in the corresponding linpack subroutine.
// c
// c     the subroutine statement is
// c
// c       subroutine qrfac(m,n,a,lda,pivot,ipvt,lipvt,rdiag,acnorm,wa)
// c
// c     where
// c
// c       m is a positive integer input variable set to the number
// c         of rows of a.
// c
// c       n is a positive integer input variable set to the number
// c         of columns of a.
// c
// c       a is an m by n array. on input a contains the matrix for
// c         which the qr factorization is to be computed. on output
// c         the strict upper trapezoidal part of a contains the strict
// c         upper trapezoidal part of r, and the lower trapezoidal
// c         part of a contains a factored form of q (the non-trivial
// c         elements of the u vectors described above).
// c
// c       lda is a positive integer input variable not less than m
// c         which specifies the leading dimension of the array a.
// c
// c       pivot is a logical input variable. if pivot is set true,
// c         then column pivoting is enforced. if pivot is set false,
// c         then no column pivoting is done.
// c
// c       ipvt is an integer output array of length lipvt. ipvt
// c         defines the permutation matrix p such that a*p = q*r.
// c         column j of p is column ipvt(j) of the identity matrix.
// c         if pivot is false, ipvt is not referenced.
// c
// c       lipvt is a positive integer input variable. if pivot is false,
// c         then lipvt may be as small as 1. if pivot is true, then
// c         lipvt must be at least n.
// c
// c       rdiag is an output array of length n which contains the
// c         diagonal elements of r.
// c
// c       acnorm is an output array of length n which contains the
// c         norms of the corresponding columns of the input matrix a.
// c         if this information is not needed, then acnorm can coincide
// c         with rdiag.
// c
// c       wa is a work array of length n. if pivot is false, then wa
// c         can coincide with rdiag.
// c
// c     subprograms called
// c
// c       minpack-supplied ... dpmpar,enorm
// c
// c       fortran-supplied ... dmax1,dsqrt,min0
// c
// c     argonne national laboratory. minpack project. march 1980.
// c     burton s. garbow, kenneth e. hillstrom, jorge j. more
// c
// c     **********
//


//
// c     **********
// c
// c     subroutine qrsolv
// c
// c     given an m by n matrix a, an n by n diagonal matrix d,
// c     and an m-vector b, the problem is to determine an x which
// c     solves the system
// c
// c           a*x = b ,     d*x = 0 ,
// c
// c     in the least squares sense.
// c
// c     this subroutine completes the solution of the problem
// c     if it is provided with the necessary information from the
// c     qr factorization, with column pivoting, of a. that is, if
// c     a*p = q*r, where p is a permutation matrix, q has orthogonal
// c     columns, and r is an upper triangular matrix with diagonal
// c     elements of nonincreasing magnitude, then qrsolv expects
// c     the full upper triangle of r, the permutation matrix p,
// c     and the first n components of (q transpose)*b. the system
// c     a*x = b, d*x = 0, is then equivalent to
// c
// c                  t       t
// c           r*z = q *b ,  p *d*p*z = 0 ,
// c
// c     where x = p*z. if this system does not have full rank,
// c     then a least squares solution is obtained. on output qrsolv
// c     also provides an upper triangular matrix s such that
// c
// c            t   t               t
// c           p *(a *a + d*d)*p = s *s .
// c
// c     s is computed within qrsolv and may be of separate interest.
// c
// c     the subroutine statement is
// c
// c       subroutine qrsolv(n,r,ldr,ipvt,diag,qtb,x,sdiag,wa)
// c
// c     where
// c
// c       n is a positive integer input variable set to the order of r.
// c
// c       r is an n by n array. on input the full upper triangle
// c         must contain the full upper triangle of the matrix r.
// c         on output the full upper triangle is unaltered, and the
// c         strict lower triangle contains the strict upper triangle
// c         (transposed) of the upper triangular matrix s.
// c
// c       ldr is a positive integer input variable not less than n
// c         which specifies the leading dimension of the array r.
// c
// c       ipvt is an integer input array of length n which defines the
// c         permutation matrix p such that a*p = q*r. column j of p
// c         is column ipvt(j) of the identity matrix.
// c
// c       diag is an input array of length n which must contain the
// c         diagonal elements of the matrix d.
// c
// c       qtb is an input array of length n which must contain the first
// c         n elements of the vector (q transpose)*b.
// c
// c       x is an output array of length n which contains the least
// c         squares solution of the system a*x = b, d*x = 0.
// c
// c       sdiag is an output array of length n which contains the
// c         diagonal elements of the upper triangular matrix s.
// c
// c       wa is a work array of length n.
// c
// c     subprograms called
// c
// c       fortran-supplied ... dabs,dsqrt
// c
// c     argonne national laboratory. minpack project. march 1980.
// c     burton s. garbow, kenneth e. hillstrom, jorge j. more
// c
// c     **********
//


//
// c     **********
// c
// c     subroutine fdjac2
// c
// c     this subroutine computes a forward-difference approximation
// c     to the m by n jacobian matrix associated with a specified
// c     problem of m functions in n variables.
// c
// c     the subroutine statement is
// c
// c       subroutine fdjac2(fcn,m,n,x,fvec,fjac,ldfjac,iflag,epsfcn,wa)
// c
// c     where
// c
// c       fcn is the name of the user-supplied subroutine which
// c         calculates the functions. fcn must be declared
// c         in an external statement in the user calling
// c         program, and should be written as follows.
// c
// c         subroutine fcn(m,n,x,fvec,iflag)
// c         integer m,n,iflag
// c         real precision x(n),fvec(m)
// c         ----------
// c         calculate the functions at x and
// c         return this vector in fvec.
// c         ----------
// c         return
// c         end
// c
// c         the value of iflag should not be changed by fcn unless
// c         the user wants to terminate execution of fdjac2.
// c         in this case set iflag to a negative integer.
// c
// c       m is a positive integer input variable set to the number
// c         of functions.
// c
// c       n is a positive integer input variable set to the number
// c         of variables. n must not exceed m.
// c
// c       x is an input array of length n.
// c
// c       fvec is an input array of length m which must contain the
// c         functions evaluated at x.
// c
// c       fjac is an output m by n array which contains the
// c         approximation to the jacobian matrix evaluated at x.
// c
// c       ldfjac is a positive integer input variable not less than m
// c         which specifies the leading dimension of the array fjac.
// c
// c       iflag is an integer variable which can be used to terminate
// c         the execution of fdjac2. see description of fcn.
// c
// c       epsfcn is an input variable used in determining a suitable
// c         step length for the forward-difference approximation. this
// c         approximation assumes that the relative errors in the
// c         functions are of the order of epsfcn. if epsfcn is less
// c         than the machine precision, it is assumed that the relative
// c         errors in the functions are of the order of the machine
// c         precision.
// c
// c       wa is a work array of length m.
// c
// c     subprograms called
// c
// c       user-supplied ...... fcn
// c
// c       minpack-supplied ... dpmpar
// c
// c       fortran-supplied ... dabs,dmax1,dsqrt
// c
// c     argonne national laboratory. minpack project. march 1980.
// c     burton s. garbow, kenneth e. hillstrom, jorge j. more
// c
// c     **********
//


// c     **********
// c
// c     subroutine lmder
// c
// c     the purpose of lmder is to minimize the sum of the squares of
// c     m nonlinear functions in n variables by a modification of
// c     the levenberg-marquardt algorithm. the user must provide a
// c     subroutine which calculates the functions and the jacobian.
// c
// c     the subroutine statement is
// c
// c       subroutine lmder(fcn,m,n,x,fvec,fjac,ldfjac,ftol,xtol,gtol,
// c                        maxfev,diag,mode,factor,nprint,info,nfev,
// c                        njev,ipvt,qtf,wa1,wa2,wa3,wa4)
// c
// c     where
// c
// c       fcn is the name of the user-supplied subroutine which
// c         calculates the functions and the jacobian. fcn must
// c         be declared in an external statement in the user
// c         calling program, and should be written as follows.
// c
// c         subroutine fcn(m,n,x,fvec,fjac,ldfjac,iflag)
// c         integer m,n,ldfjac,iflag
// c         double precision x(n),fvec(m),fjac(ldfjac,n)
// c         ----------
// c         if iflag = 1 calculate the functions at x and
// c         return this vector in fvec. do not alter fjac.
// c         if iflag = 2 calculate the jacobian at x and
// c         return this matrix in fjac. do not alter fvec.
// c         ----------
// c         return
// c         end
// c
// c         the value of iflag should not be changed by fcn unless
// c         the user wants to terminate execution of lmder.
// c         in this case set iflag to a negative integer.
// c
// c       m is a positive integer input variable set to the number
// c         of functions.
// c
// c       n is a positive integer input variable set to the number
// c         of variables. n must not exceed m.
// c
// c       x is an array of length n. on input x must contain
// c         an initial estimate of the solution vector. on output x
// c         contains the final estimate of the solution vector.
// c
// c       fvec is an output array of length m which contains
// c         the functions evaluated at the output x.
// c
// c       fjac is an output m by n array. the upper n by n submatrix
// c         of fjac contains an upper triangular matrix r with
// c         diagonal elements of nonincreasing magnitude such that
// c
// c                t     t           t
// c               p *(jac *jac)*p = r *r,
// c
// c         where p is a permutation matrix and jac is the final
// c         calculated jacobian. column j of p is column ipvt(j)
// c         (see below) of the identity matrix. the lower trapezoidal
// c         part of fjac contains information generated during
// c         the computation of r.
// c
// c       ldfjac is a positive integer input variable not less than m
// c         which specifies the leading dimension of the array fjac.
// c
// c       ftol is a nonnegative input variable. termination
// c         occurs when both the actual and predicted relative
// c         reductions in the sum of squares are at most ftol.
// c         therefore, ftol measures the relative error desired
// c         in the sum of squares.
// c
// c       xtol is a nonnegative input variable. termination
// c         occurs when the relative error between two consecutive
// c         iterates is at most xtol. therefore, xtol measures the
// c         relative error desired in the approximate solution.
// c
// c       gtol is a nonnegative input variable. termination
// c         occurs when the cosine of the angle between fvec and
// c         any column of the jacobian is at most gtol in absolute
// c         value. therefore, gtol measures the orthogonality
// c         desired between the function vector and the columns
// c         of the jacobian.
// c
// c       maxfev is a positive integer input variable. termination
// c         occurs when the number of calls to fcn with iflag = 1
// c         has reached maxfev.
// c
// c       diag is an array of length n. if mode = 1 (see
// c         below), diag is internally set. if mode = 2, diag
// c         must contain positive entries that serve as
// c         multiplicative scale factors for the variables.
// c
// c       mode is an integer input variable. if mode = 1, the
// c         variables will be scaled internally. if mode = 2,
// c         the scaling is specified by the input diag. other
// c         values of mode are equivalent to mode = 1.
// c
// c       factor is a positive input variable used in determining the
// c         initial step bound. this bound is set to the product of
// c         factor and the euclidean norm of diag*x if nonzero, or else
// c         to factor itself. in most cases factor should lie in the
// c         interval (.1,100.).100. is a generally recommended value.
// c
// c       nprint is an integer input variable that enables controlled
// c         printing of iterates if it is positive. in this case,
// c         fcn is called with iflag = 0 at the beginning of the first
// c         iteration and every nprint iterations thereafter and
// c         immediately prior to return, with x, fvec, and fjac
// c         available for printing. fvec and fjac should not be
// c         altered. if nprint is not positive, no special calls
// c         of fcn with iflag = 0 are made.
// c
// c       info is an integer output variable. if the user has
// c         terminated execution, info is set to the (negative)
// c         value of iflag. see description of fcn. otherwise,
// c         info is set as follows.
// c
// c         info = 0  improper input parameters.
// c
// c         info = 1  both actual and predicted relative reductions
// c                   in the sum of squares are at most ftol.
// c
// c         info = 2  relative error between two consecutive iterates
// c                   is at most xtol.
// c
// c         info = 3  conditions for info = 1 and info = 2 both hold.
// c
// c         info = 4  the cosine of the angle between fvec and any
// c                   column of the jacobian is at most gtol in
// c                   absolute value.
// c
// c         info = 5  number of calls to fcn with iflag = 1 has
// c                   reached maxfev.
// c
// c         info = 6  ftol is too small. no further reduction in
// c                   the sum of squares is possible.
// c
// c         info = 7  xtol is too small. no further improvement in
// c                   the approximate solution x is possible.
// c
// c         info = 8  gtol is too small. fvec is orthogonal to the
// c                   columns of the jacobian to machine precision.
// c
// c       nfev is an integer output variable set to the number of
// c         calls to fcn with iflag = 1.
// c
// c       njev is an integer output variable set to the number of
// c         calls to fcn with iflag = 2.
// c
// c       ipvt is an integer output array of length n. ipvt
// c         defines a permutation matrix p such that jac*p = q*r,
// c         where jac is the final calculated jacobian, q is
// c         orthogonal (not stored), and r is upper triangular
// c         with diagonal elements of nonincreasing magnitude.
// c         column j of p is column ipvt(j) of the identity matrix.
// c
// c       qtf is an output array of length n which contains
// c         the first n elements of the vector (q transpose)*fvec.
// c
// c       wa1, wa2, and wa3 are work arrays of length n.
// c
// c       wa4 is a work array of length m.
// c
// c     subprograms called
// c
// c       user-supplied ...... fcn
// c
// c       minpack-supplied ... dpmpar,enorm,lmpar,qrfac
// c
// c       fortran-supplied ... dabs,dmax1,dmin1,dsqrt,mod
// c
// c     argonne national laboratory. minpack project. march 1980.
// c     burton s. garbow, kenneth e. hillstrom, jorge j. more
// c
// c     **********


// As of XSPEC 12.10.1, the table-model routines have been
// consolidated into one routine, so there is no need for
// a template. A template could be used to allow compile-time
// specialization over additive versus multiplicative, but
// for now have a run-time check rather than multiple versions
// of this routine.
//


//////////////////////////////////////////
// FUNCTIONS TO BYPASS THE BLCFA_OBJECT //
//////////////////////////////////////////


/***************************/
/* GENERIC ROUTINE SECTION */
/***************************/


//this function offers the possibility to return the BLCFA threshold
//without resorting to the BLCFA_Object [be aware that by bypassing the
//BLCFA_Object circuit you are also skipping all the heuristic constrols made
//there]


//comments omitted (simplified version of evaluate)


// the log_message argument will be reinitialized inside the function


//set all the simulation's quantities based on
//the value of the given reference length


//useful for debug


//you should add a function that creates an array (a std::vector is better) of BLCFA_Object


//debug (this functions could be deleted)*********************


/***************************************/
/* PAIR PRODUCTION function definition */
/***************************************/


//this method returns the nrg of the emitted electron only!
//please consider that the relation phtn_nrg = e_nrg + p_nrg
//holds if you are interested in the positron energy


//auxiliary inner function used inside the LCFA energy method
//it computes the v-value energy of the emitted photon


//auxiliary inner function used inside the BLCFA energy method
//it computes the w-value energy of the emitted photon


//return the emitted photon energy (normalized in units of m_e c^2)


//\gamma here represents the normalized energy of the particle \epsilon,
//that in case of an electron \epsilon = \gamma. In general it is not
//the sheer gamma factor
//if an increasing tail appears at low energies (log scale) please check the conditions


//this function does not internally compute the photon energy
//but it expects it to be passed from outside (second argument)


//make sure to pass an empty message string that will be
// filled with what the toolkit is doing


/**
   * Initialise Cluster instance.
   * @param[in] num_val Integer value.
   */


/**
   * Initialise FoF instance.
   */


/**
   * Initialise Zbin instance.
   * @param[in] num_val Integer value.
   * @param[in] z_val Redshift.
   * @param[in] z_bin_size Redshift bin size.
   */


/* ----------------------------------------------------------------------------
   angdidis2
-------------------------------------------------------------------------------
   This function calculates the angular diameter distance d_A from z1
   to z2 as a function of Omega_M and Omega_L in a matter-dominated
   universe, using the function propmotdis().  H0=c=1.
---------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------------
   comdis
-------------------------------------------------------------------------------
   This function calculates the line-of-sight comoving distance d_C as
   a function of z, Omega_M and Omega_L in a matter-dominated
   universe, using dcomdisdz().  H0=c=1.
---------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------------
   comvol
-------------------------------------------------------------------------------
   This function calculates the all-sky comoving volume V as a
   function of z, Omega_M and Omega_L in a matter-dominated universe.
   Formulae from Carrol, Press & Turner, 1992, and my own calculation.
---------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------------
   dcomdisdz
-------------------------------------------------------------------------------
   This function calculates the differential line-of-sight comoving
   distance dD_c/dz as a function of z, Omega_M and Omega_L in a
   matter-dominated universe.  H0=c=1.
---------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------------
   dcomvoldz
-------------------------------------------------------------------------------
   This function calculates the one-steradian differential comoving
   volume dV/dz as a function of z, Omega_M and Omega_L in a
   matter-dominated universe.  Formulae from Carrol, Press & Turner,
   1992, Kolb & Turner, 1990, and my own calculation.  H0=c=1.
---------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------------
   dlookbackdz
-------------------------------------------------------------------------------
   This function calculates the change in lookback time dt/dz with
   redshift z as a function of z, Omega_M and Omega_L in a
   matter-dominated universe.  Formula from Carrol, Press & Turner,
   1992.  H0=c=1.
---------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------------
   doptdepthdz
-------------------------------------------------------------------------------
   This function calculates the change in optical depth dtau/dz with
   redshift z as a function of z, Omega_M and Omega_L in a
   matter-dominated universe.  Formula from Peebles, 1993.
   H0=c=sigma=n=1.
---------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------------
   dpropmotdisdz
-------------------------------------------------------------------------------
   This function calculates the derivative of the proper motion
   distance d_M with respect to redshift z as a function of z, Omega_M
   and Omega_L in a matter-dominated universe.  Formula from Carrol,
   Press & Turner, 1992.  This function also requires the function
   propmotdis(). H0=c=1.
---------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------------
   intcomvol
-------------------------------------------------------------------------------
   This function calculates the all-sky comoving volume V as a
   function of z, Omega_M and Omega_L in a matter-dominated universe
   by integrating dcomvoldz().  It was written to test comvol().
---------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------------
   lookback
-------------------------------------------------------------------------------
   This function calculates the lookback time t(0)-t(z) as a function
   of z, OmegaM and OmegaL by integrating the output of dlookbackdz.
---------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------------
   optdepth
-------------------------------------------------------------------------------
   This function calculates the optical depth tau as a function
   of z, OmegaM and OmegaL by integrating the output of doptdepthdz.
   Again, H0=c=sigma=n=1.
---------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------------
   propmotdis
-------------------------------------------------------------------------------
   This function calculates the proper motion distance d_M as a
   function of z, Omega_M and Omega_L in a matter-dominated universe.
   Formulae from Carrol, Press & Turner, 1992, Kolb \& Turner, 1990,
   and my own derivation.  Makes use of comdis().  H0=c=1.
---------------------------------------------------------------------------- */


/**
     * This method finds the representative element of the UF structure,
     * while performing the path compression.
     * @return the representative UnionFind of the group.
     */


/**
    * This method joins the UnionFind passed as an argument.
    * @param[in] u UnionFind to join
    */


/**
     * Initialise Galaxy instance. [FoF mode: "spec"]
     * @param[in] num_val Integer value.
     * @param[in] id_val Galaxy ID.
     * @param[in] ra_val Galaxy right ascension.
     * @param[in] dec_val Galaxy declination.
     * @param[in] z_val Galaxy spectroscopic redshift.
     */


/**
     * Initialise Galaxy instance. [FoF mode: "phot"]
     * @param[in] num_val Integer value.
     * @param[in] id_val Galaxy ID.
     * @param[in] ra_val Galaxy right ascension.
     * @param[in] dec_val Galaxy declination.
     * @param[in] z_val Galaxy photometric redshift.
     * @param[in] z_err_val Galaxy photometric redshift error.
     */


/**
 * Unit test for Astro::num_bins.
 */


/**
 * Unit test for Astro::within.
 */


/**
 * Unit test for Astro::angsep.
 */


/**
 * Unit test for Astro::mean.
 */


/**
 * Unit test for Astro::median.
 */


/**
 * Unit test for Astro::variance.
 */


/**
 * Unit test for Astro::stdev.
 */


/**
 * Unit test for Astro::stderr_mean.
 */


/**
 * Unit test for Astro::stderr_median.
 */


/**
 * Unit test for Astro::min.
 */


/**
 * Unit test for Astro::max.
 */


/**
 * Unit test for Cosmo::angdidis.
 */


/**
 * Unit test for Cosmo::angdidis2.
 */


/**
 * Unit test for Cosmo::comdis.
 */


/**
 * Unit test for Cosmo::dlookbackdz.
 */


/**
 * Unit test for Cosmo::doptdepthdz.
 */


// ======================================================================================
// Cartesian <==> Polar


// ======================================================================================
// Galactic <==> Cartesian


// ======================================================================================
// Galactic <==> Polar


// ======================================================================================
// Equatorial <==> Galactic


// ============================================================================
// (u,v) Prolate Spheroidal Coordinate System
// ============================================================================


// ============================================================================
// Prolate Spheroidal Coordinate System
// ============================================================================


// ============================================================================
// Confocal Ellipsoidal Coordinate System
// ============================================================================


//------------------------------------------------------------------------------
//
// define static member function: set standart terminal, used by showonscreen
//  defaults: Windows - win, Linux - x11, Mac - aqua
//


//------------------------------------------------------------------------------
//
// Destructor: needed to delete temporary files
//


//------------------------------------------------------------------------------
//
// Opens up a gnuplot session, ready to receive commands
//


//------------------------------------------------------------------------------
//
// Opens a temporary file
//


// ============================================================================
// Action calculation using generating function from orbit integration
// ============================================================================


// ============================================================================
// Action calculation by averaging toy actions over toy angles
// ============================================================================


// ============================================================================
// Prolate Stackel Angle-action calculator
// ============================================================================


// ============================================================================
// Prolate Stackel Angle-action Fudge
// ============================================================================


// ============================================================================
// Triaxial Stackel Angle-action calculator
// ============================================================================


// ============================================================================
// Triaxial Stackel Fudge
// ============================================================================


// Determine if obj_ptr can be converted in a std::vector<T>


// Convert obj_ptr into a std::vector<T>


// ==========================================================================
// Now define members of python library


// ============================================================================
// Triaxial harmonic oscillator
// ============================================================================


//============================================================================
/// Interpolation tables for Axisymmetric fudge
//============================================================================


/*!
    Checks input for actions
*/


/*!
    Checks input for angles
*/


// NANs in Stackel forces on axis


// ============================================================================
// Orbit base class -- implements 3D orbit integration in a Potential_JS
// ============================================================================


// ============================================================================
// Orbit integration using GSL ode integrators
// ============================================================================


// ============================================================================
// Symplectic orbit integration
// ============================================================================


// =====
// NOTE: cuba and openmp don't like each other so must set CUBACORES=0
// =====
// ============================================================================
// Triaxial potential code -- see Section 2.5.3 of BT08
// ============================================================================


// ============================================================================
// Oblate Stackel Perfect Ellipsoid Potential
// ============================================================================


/*
// Attempts at analytic expressions for above -- doesn't work

double StackelTriaxial::G(double tau){
	// std::cout<<l<<" "<<sinm<<" "<<-(tau+CS->alpha())/(CS->alpha()-CS->gamma())<<std::endl;
	// std::cout<<ellint_third(l,sinm,-(tau+CS->alpha())/(CS->alpha()-CS->gamma()))<<std::endl;
	std::cout<<ellint_third(l,sinm,0.)<<" "<<Flm<<" "<<Elm<<std::endl;
	return Const/(tau+CS->alpha())*
		   ((tau+CS->beta())*ellint_third(l,sinm,-(tau+CS->alpha())/(CS->alpha()-CS->gamma()))
		   +(CS->alpha()-CS->beta())*Flm);
}

double StackelTriaxial::GPrime(double tau){
	return 0.5*Const/(tau+CS->alpha())/(tau+CS->gamma())*
		   (((tau+CS->alpha())*(tau+CS->gamma())-(tau+CS->alpha())*(tau+CS->beta())-(tau+CS->gamma())*(tau+CS->beta()))
		   	*ellint_third(l,sinm,-(tau+CS->alpha())/(CS->alpha()-CS->gamma()))/(tau+CS->alpha())
		   +((tau+CS->alpha())*(CS->beta()-CS->gamma())+(tau+CS->gamma())*(CS->beta()-CS->alpha()))
		    *Flm/(tau+CS->alpha())
		   -(tau+CS->alpha())*b*c*sin(l)/CS->alpha()+(CS->gamma()-CS->alpha())*Elm);
}
*/


// ============================================================================
// Jaffe Bulge Potential
// ============================================================================


// ============================================================================
// GalPot Potential for interface with Walter Dehnen's code
// ============================================================================


// ============================================================================
// Bowden NFW Potential
// ============================================================================


/*
  void PositionEngine::handlePosArray (const TENShPtr& operand)
  {
    if (!operand->isReal()  ||
        operand->valueType() != TableExprNodeRep::VTArray) {
      throw AipsError ("A single double argument given as position in a "
                       "MEAS function must be a double array of values "
                       "defining x,y,z or lon,lat or height");
    }
    // Use defaults for reference and value type if not given.
    deriveAttr (operand->unit(), 0);
    // Handle possibly given constants.
    if (operand->isConstant()) {
      handleConstant (operand);
      return;
    }
    // Try if the argument is a column.
    // If found, try to handle it as a TableMeasures column.
    const TableExprNodeArrayColumn* colNode =
      dynamic_cast<TableExprNodeArrayColumn*>(operand.get());
    Bool directCol = True;
    if (!colNode) {
      // The node is an expression, not a column.
      directCol = False;
      // Try if the node is an array part of a column.
      TableExprNodeArrayPart* partNode =
        dynamic_cast<TableExprNodeArrayPart*>(operand.get());
      if (partNode) {
        colNode = partNode->getColumnNode();
      }
    }
    if (colNode) {
      // Try if the column contains measures.
      const TableColumn& tabCol = colNode->getColumn();
      itsShape = tabCol.shapeColumn();
      itsNDim  = tabCol.ndimColumn();
      if (TableMeasDescBase::hasMeasures (tabCol)) {
        ArrayMeasColumn<MPosition> measTmp(tabCol.table(),
                                           tabCol.columnDesc().name());
        // Get and check the node's refType if it is fixed.
        MPosition::Types nodeRefType = MPosition::N_Types;
        if (! (measTmp.measDesc().isRefCodeVariable()  ||
               measTmp.measDesc().hasOffset())) {
          uInt refCode = measTmp.measDesc().getRefCode();
          itsRefType = static_cast<MPosition::Types>(refCode);
        }
        // A direct column can directly be accessed using TableMeasures.
        if (directCol) {
          itsMeasCol.reference (measTmp);
          return;
        }
        // It is a part, so we cannot use TableMeasures.
        // If the reference type is variable, the user should index after
        // the meas.pos function.
        if (nodeRefType == MPosition::N_Types) {
            throw AipsError ("Column " + tabCol.columnDesc().name() +
                             ", which has a variable reference frame, "
                             "is used in a MEAS function with slicing. "
                             "The slicing should be done after the function "
                             "like 'meas.pos('ITRF',POSITION)[0:3]'");
        }
      }
    }
    if (itsMeasCol.isNull()) {
      if (itsRefType == MPosition::N_Types) {
        throw AipsError("No reference type given for a non-constant MEAS "
                        "function position argument");
      }
      itsExprNode = operand;
    }
  }
  */


//# NAMESPACE CASACORE - BEGIN


// setShape sets the shape of a hypercube.
// It is only used by TiledCellStMan columns, because the shape
// is always known for others.


// Set the cache size for the given slice and access path.


// Calculate the cache size for the given slice and access path.


//# Create a column object for a scalar.
//# Check its data type.


//# Creating a column object for an indirect array.
//# Check its data type.


//# Creating a column object for a direct array.
//# Check its data type.


//# Compose the keyword name from the given name appended with the
//# sequence number to make the name unique.


//# Compose the file name from the table name followed by the
//# sequence number to make the name unique.


//# Register a mapping.


//# Test if the data manager is registered.


//# Get a data manager constructor.
//# Return default function if the data manager is undefined
//# after having tried to load it from a shared library.


//# The default "ctor" function for unknown data manager type names.


//# Register all mappings of the names of classes derived from
//# DataManager to a static function calling the default constructor.
//# The class name is the name as returned by the function dataManagerType.
// No locking since private and only called by ctor of static member init.


//# Creating a direct array is by default the same as creating
//# an indirect array.


//# Delete all objects created.


//# Get the shape for the array (if any) in the given row.
//# Read shape if not read yet.


//# Call the correct putScalarColumnX function depending on the data type.


//# Call the correct getScalarColumnCellsX function depending on the data type.


//# Call the correct putScalarColumnCellsX function depending on the data type.


//# Call the correct getArrayX function depending on the data type.


//# Call the correct putArrayX function depending on the data type.


//# Call the correct getColumnSliceX function depending on the data type.


//# Call the correct putSliceX function depending on the data type.


//# Call the correct getArrayColumnX function depending on the data type.


//# Call the correct putArrayColumnX function depending on the data type.


//# Call the correct getArrayColumnCellsX function depending on the data type.


//# Call the correct putArrayColumnCellsX function depending on the data type.


//# Call the correct putColumnSliceX function depending on the data type.


//# Call the correct getColumnSliceCellsX function depending on the data type.


//# Call the correct putColumnSliceCellsX function depending on the data type.


// Make new table using a ForwardColumn engine.


// Clone the engine object.


// Define the RefTable_p if not defined yet.


// Note that the column has already been added by makeXXColumn.
// This function is merely for initializing the added column.


//# Write all data into AipsIO.


//# Read all data from AipsIO.


// Find minimum and maximum.


// Scale/offset an array for get.


// Scale/offset an array for put.


// Get the proper array data type.


// Calculate the offset for a given position.


// Calculate the position for a given offset.


//# putSliceData works similar to getSliceData.


//# Create the array file (for a new column).
//# Compose the file name from the mother file name extended with
//# the unique column sequence nr.
//# Create the given nr of rows in it.


//# Close the file.
//# Delete it if required.


// Resync the file (i.e. clear possible cache information).


//# Put a complex vector at the given file offset.


//# Put a string at the given file offset.


//# Get a complex vector at the given file offset.


//# Get a string at the given file offset.


//# Copy the data of the given length from one file offset to another.


//# Write shape and reserve file space for the array by
//# increasing the length.
//# Take care it is at 8 byte boundary.
//# Write something in the last byte to make sure the file is extended.


//# Get the shape at the given file offset
//# and returns its length in the file.


//# Update the reference count.


//# The default implementations of the shape functions throw
//# an exception.


//# Create the array file (for a new column).
//# Compose the file name from the mother file name extended with
//# the unique column sequence nr.


//# Set the shape for the array in the given row for a put operation.


//# Set the shape for the array (if any) in the given row for a sliced
//# put operation.


// Test writing and updating an indirect array.


// First build a description.


// Create and fill a new table.


// <summary>
// Test program for class tTSMShape.
// </summary>


// This function tests issue 970.


// Read the table back.


// maxWeight tells maximum weight before it wraps
// (when nbytesPerSample is small).


// Build a description.


//typedef Bool Type;
//#define ARRINIT array = False
//#define ARRINCR array = !array


// This test program was created due to a problem in BucketCache found
// on 31-Aug-2012. When a bucket was added and removed before being flushed,
// only the free list (4 bytes) was written instead of the entire bucket.
// When opening the file again, it found that the nr of buckets in the file
// was one short and tried to write it, which failed if opened as readonly.
//
// The table used is tarred in tSSMAddRemove.in and unpacked by the .run file.


//# This copy constructor should only be called by VirtualColumnEngine::clone,
//# when writable_p and the column_p variables are not filled yet.
//# Check if that is indeed the case.


// The function create is called upon initialization of the virtual column.
// The initialization order of the columns is undetermined, which means
// that this function isWritable can be called before the column has been
// initialized.
// For example, suppose column A uses column B and A get initialized
// before B. Then A will call B's isWritable(), while B has not been
// initialized yet.
// This all means that isWritable must take care of the case
// where the writable_p flag is not set yet.


// Write some arrays (in chunks).


// Read back and update and copy some arrays.


// Create all global arrays using the globally defined array shapes.


// Bind a VirtualTaQLColumn.


// Create a new table and fill a few cells with an empty array.
// An empty table name defaults to tStMan_tmp.data.


// Reopen the table and check the contents again.
// This has to be done right after creating the table in function maketab.


// Store the target column names in the keywords of this column.


// Prepare the engine by allocating column objects
// for the used columns.
// Get their names from the keywords of this column.


// Tests for the non-existence of a specific bug that happened
// when writing boolean values using TSMOption::Buffer


// Test modifying the dminfo record.


// Test if a tableCommand on a table containing a TaQL column works fine.
// Note it requires recursive parsing.


// Test how getting a column performs.


// <thrown>
//   <li> TableInvExpr
// </thrown>
//# Create a table expression node for a column.
//# First use a "dummy" data type and fill it in later.
//# Similarly for the value type.


//# Take the seed from the current time and date.


// The constructor to be used by the derived classes.


//# Determine the number of rows in the main table used in the expression.


//# Supply the default functions for the get functions.


// Check the datatypes and get the common one.
// For use with operands.


// A global function to show the tables in a WITH clause (if used).


//# Construct a TableParse object and add it to the container.


// Construct from a mask.


// This function concatenates the help info below to a single string.


//# NAMESPACE CASACORE - BEGIN


//# And two vectors of ranges.
//# This means taking the intersection of all ranges in both vectors.
//# Note that the start values are kept in ascending order, so that
//# makes searching easier.


// This function can split a name.
// The name can consist of an optional shorthand, a column or keyword name,
// followed by zero or more subfield names (separated by dots).
// In the future it should also be possible to have a subfield name
// followed by a keyword name, etc. to cater for something like:
//   shorthand::key.subtable::key.subsubtable::key.
// If that gets possible, TableGram.ll should also be changed to accept
// such a string in the scanner.
// It is a question whether :: should be part of the scanner or grammar.
// For columns one can go a bit further by accepting something like:
//  col.subtable[select expression resulting in scalar]
// which is something for the far away future.


// Fill the children pointers of a node.


// Fill the children pointers of a node.
// Also reduce the tree if possible by combining constants.


//# Or two blocks of ranges.


//# And two blocks of ranges.


//# Create an expression node for either a keyword or column.


//# Create a column node on behalf of the Table class.
//# For builtin data types another type of node is created than
//# for other data types.


// Find the last TableRecord of the field names of a keyword.


//# Create a constant node for a keyword on behalf of the Table class.
//# The constructor reads in the value and stores it as a constant.


//# Parse the name of a function.


//# Add a column name to the block of column names.
//# Only take the part beyond the period.
//# Extend the block each time. Since there are only a few column names,
//# this will not be too expensive.


//# Finish the additions to the block of column names
//# by removing the deleted empty names and creating Expr objects as needed.


//# Add a column specification.


//# Execute a query in the FROM clause and return the resulting table.


//# Execute a subquery for an EXISTS operator.


//# Execute a subquery and create the correct node object for it.


//# Execute the updates.


//# Execute the inserts.


//# Execute the deletes.


//# Execute the counts.


//# Execute the groupby.


//# Execute the sort.


//# Keep the name of the resulting table.


//# Keep the resulting set expression.


//# Execute all parts of a TaQL command doing some selection.


//# Parse the command.


//# Get the next input characters for flex.


//# Parse the command.
//# Do a yyrestart(yyin) first to make the flex scanner reentrant.


//# Convert a constant to a TableExprNode object.
//# The leading and trailing " is removed from a string.


//# Simplified forms of general tableCommand function.


//# Do the actual parsing of a command and execute it.


//# Handle a wildcarded a column name.
//# Add or remove to/from the block of column names as needed.


//# Lookup a field name in the table for which the shorthand is given.
//# If no shorthand is given, use the first table.
//# The shorthand and name are separated by a period.


// This program tests table commands with an SQL-like grammar.
// The grammar is scanned and parsed using the flex/bison file TableGram.l/y
// and with the help of the class TableParse.
// It ask for commands until a "q" is given.
// When columns are selected, it will show their contents.


// Ask and execute command till empty string is given.


// Show the required columns.
// First test if they exist and contain scalars or arrays.


// Sort and select data.


// This program tests the class RecordGram to select records from a group
// of records.


// Test the expr2 functions.


// Make a Record to give to vectors a name.
// The order in which the fields are defined determines the fieldnrs
// passed to the get functions.


// Run a table command which should fail.
// Return 1 if not failing.


// <summary>
// Test program for the ExprNodeSetElem selection classes.
// </summary>


// This program tests the class RecordExpr to select records from a group
// of records.


// This program tests the class RecordGram to do expressions on a table.


// <summary>
// Test program for the ExprNodeSet selection classes.
// </summary>


// Split a line using ; as delimiter.
// Skip comments indicated by #.
// Ignore those characters if in a quoted string.
// An empty string is added where a delimiter is used.
// In this way it is clear if the first part of the next line
// has to be added to the last part of this line.


// Split a line on whitespace (except in quoted parts).


// Read a line until a non-empty line or ^D or quit is read.


// Show a date/time. Do not show time part if 0.


// Show values representing MPositions.


// Show values representing MDirections.


// Show the required columns of the table.
// First test if they exist and contain scalars or arrays.


// Show the value of an expression which can be a scalar or array (part).


// Execute a TaQL command.


// Show the variable names and tables associated to them.


// Substitute possible table variables given like $var.


// Ask and execute commands till quit or ^D is given.


// Remove quotes if necessary.
// Note that it should not be done for options given in a shell command,
// but has to be done for options given at the TaQL prompt.


// Parse the given options and set flags accordingly.
// Stop at first non-option (indicated by st).


// Execute a given command.
// Ask for commands if interactive and empty command.


//
// There are 3 axes to maximize over; antenna1, antenna2, channel
// We want to maximize all values (average abs value as large as possible)
// Example: (10=max)
//  ch1     ch2
//  a1a2a3   a1a2a3
//  ------   ------
//   1 1 1    1 1 1
//  10 1 1    1 1 1
//   1 1 1    1 1 1
// ant3 * 10 -> sum = (3 * 1 + 10 + 5 * 10) + (4 * 1 + 5 * 10) = 117
//  ch2 * 10 -> sum = 18 + 90 = 108
// both * s10 -> sum = (13 + 5*s10) + (s10*4 + 10*5) = 91.5
//  ch1     ch2
//   1 1 1    1 1 1
//   1 1 1    1 1 1
//   1 2 1    1 1.5 1
// ant3 * 10 -> sum = (3 * 1 + 10 + 5 * 10) + (4 * 1 + 5 * 10) = 117
//  ch2 * 10 -> sum = 18 + 90 = 108
// both * s10 -> sum = (13 + 5*s10) + (s10*4 + 10*5) = 91.5
//
// Approach: iterate over all antenna and channels, and find the antenna/channel
// that can increase the sum the most.


//# Put into AipsIO.
//# It was felt that putstart takes too much space, so therefore
//# the version is put "manually".


//# Get from AipsIO.


//# Get a ColumnDesc constructor.
//# Return default function if undefined.


//# Register the main "static constructors" of all XColumnDesc classes.
// No locking since private and only called by ctor of static member init.


//# Helper function.
//# Read a line and ignore lines to be skipped.


//# Helper function
//# It gets the next value from a line and stores it in result.
//# It updates at and returns the length of the value retrieved.
//# Quotes around strings are removed
//# -1 is returned if no more values are found.


//# Convert a string to a Bool


//# Read a keyword set and add it to keysets.


//#// Currently this is a very dumb implementation.
//# It should check if types are equal and take advantage of that.


// The values (might) have changed, which is not reflected in the
// internal record. Be sure to reread when the same row is asked for.


// Create a TableInfo object of one of the predefined types.
// This is a centralised way of setting the Table type/subType.


// <thrown>
//   <li> TableDescNoName
//   <li> TableDuplFile
//   <li> TableNoFile
//   <li> TableInvOpt
// </thrown>