summaryrefslogtreecommitdiffstats
path: root/ast/fluxframe.c
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2019-05-10 18:45:23 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2019-05-10 18:45:23 (GMT)
commit0b1addf5643c828955a6add53f2a4f7a7a813e41 (patch)
tree94fe32a76399be787746c3c403cca2076a253e29 /ast/fluxframe.c
parent75fab9d80911f74aaab738fa9ab8a4f9b0f57a6b (diff)
downloadblt-0b1addf5643c828955a6add53f2a4f7a7a813e41.zip
blt-0b1addf5643c828955a6add53f2a4f7a7a813e41.tar.gz
blt-0b1addf5643c828955a6add53f2a4f7a7a813e41.tar.bz2
upgrade ast 8.7.1
Diffstat (limited to 'ast/fluxframe.c')
-rw-r--r--ast/fluxframe.c4490
1 files changed, 4490 insertions, 0 deletions
diff --git a/ast/fluxframe.c b/ast/fluxframe.c
new file mode 100644
index 0000000..aca3e5f
--- /dev/null
+++ b/ast/fluxframe.c
@@ -0,0 +1,4490 @@
+/*
+*class++
+* Name:
+* FluxFrame
+
+* Purpose:
+* Measured flux description.
+
+* Constructor Function:
+c astFluxFrame
+f AST_FLUXFRAME
+
+* Description:
+* A FluxFrame is a specialised form of one-dimensional Frame which
+* represents various systems used to represent the signal level in an
+* observation. The particular coordinate system to be used is specified
+* by setting the FluxFrame's System attribute qualified, as necessary, by
+* other attributes such as the units, etc (see the description of the
+* System attribute for details).
+*
+* All flux values are assumed to be measured at the same frequency or
+* wavelength (as given by the SpecVal attribute). Thus this class is
+* more appropriate for use with images rather than spectra.
+
+* Inheritance:
+* The FluxFrame class inherits from the Frame class.
+
+* Attributes:
+* In addition to those attributes common to all Frames, every
+* FluxFrame also has the following attributes:
+*
+* - SpecVal: The spectral position at which the flux values are measured.
+
+* Functions:
+c The FluxFrame class does not define any new functions beyond those
+f The FluxFrame class does not define any new routines beyond those
+* which are applicable to all Frames.
+
+* Copyright:
+* Copyright (C) 1997-2006 Council for the Central Laboratory of the
+* Research Councils
+
+* Licence:
+* This program is free software: you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation, either
+* version 3 of the License, or (at your option) any later
+* version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General
+* License along with this program. If not, see
+* <http://www.gnu.org/licenses/>.
+
+* Authors:
+* DSB: David S. Berry (Starlink)
+
+* History:
+* 6-DEC-2004 (DSB):
+* Original version.
+* 14-DEC-2004 (DSB):
+* Added AST__SBRIGHT and AST__SBRIGHTW systems.
+* 7-DEC-2005 (DSB):
+* Free memory allocated by calls to astReadString.
+* 14-FEB-2006 (DSB):
+* Override astGetObjSize.
+* 31-JAN-2007 (DSB):
+* Modified so that a FluxFrame can be used as a template to find a
+* FluxFrame contained within a CmpFrame. This involves changes in
+* Match and the removal of the local versions of SetMaxAxes and
+* SetMinAxes.
+* 3-SEP-2007 (DSB):
+* In SubFrame, since AlignSystem is extended by the FluxFrame class
+* it needs to be cleared before invoking the parent SubFrame
+* method in cases where the result Frame is not a FluxFrame.
+* 2-OCT-2007 (DSB):
+* In Overlay, clear AlignSystem as well as System before calling
+* the parent overlay method.
+* 29-APR-2011 (DSB):
+* Prevent astFindFrame from matching a subclass template against a
+* superclass target.
+*class--
+*/
+
+/* Module Macros. */
+/* ============== */
+/* Set the name of the class we are implementing. This indicates to
+ the header files that define class interfaces that they should make
+ "protected" symbols available. */
+#define astCLASS FluxFrame
+
+/* Define the first and last acceptable System values. */
+#define FIRST_SYSTEM AST__FLUXDEN
+#define LAST_SYSTEM AST__SBRIGHTW
+
+/* Define other numerical constants for use in this module. */
+#define GETATTRIB_BUFF_LEN 50
+#define GETLABEL_BUFF_LEN 200
+#define GETSYMBOL_BUFF_LEN 20
+#define GETTITLE_BUFF_LEN 200
+
+/* Header files. */
+/* ============= */
+/* Interface definitions. */
+/* ---------------------- */
+
+#include "globals.h" /* Thread-safe global data access */
+#include "error.h" /* Error reporting facilities */
+#include "memory.h" /* Memory allocation facilities */
+#include "unit.h" /* Units management facilities */
+#include "globals.h" /* Thread-safe global data access */
+#include "object.h" /* Base Object class */
+#include "frame.h" /* Parent Frame class */
+#include "fluxframe.h" /* Interface definition for this class */
+#include "mapping.h" /* Coordinate Mappings */
+#include "unitmap.h" /* Unit Mappings */
+#include "cmpmap.h" /* Compound Mappings */
+#include "zoommap.h" /* Scaling Mappings */
+#include "specframe.h" /* Spectral Frames */
+
+/* Error code definitions. */
+/* ----------------------- */
+#include "ast_err.h" /* AST error codes */
+
+/* C header files. */
+/* --------------- */
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stddef.h>
+#include <math.h>
+
+/* Module Variables. */
+/* ================= */
+
+/* Address of this static variable is used as a unique identifier for
+ member of this class. */
+static int class_check;
+
+/* Pointers to parent class methods which are used or extended by this
+ class. */
+static int (* parent_getobjsize)( AstObject *, int * );
+static AstSystemType (* parent_getalignsystem)( AstFrame *, int * );
+static AstSystemType (* parent_getsystem)( AstFrame *, int * );
+static const char *(* parent_getattrib)( AstObject *, const char *, int * );
+static const char *(* parent_getdomain)( AstFrame *, int * );
+static const char *(* parent_getlabel)( AstFrame *, int, int * );
+static const char *(* parent_getsymbol)( AstFrame *, int, int * );
+static const char *(* parent_gettitle)( AstFrame *, int * );
+static const char *(* parent_getunit)( AstFrame *, int, int * );
+static int (* parent_match)( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * );
+static int (* parent_subframe)( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * );
+static int (* parent_testattrib)( AstObject *, const char *, int * );
+static void (* parent_setunit)( AstFrame *, int, const char *, int * );
+static void (* parent_clearattrib)( AstObject *, const char *, int * );
+static void (* parent_overlay)( AstFrame *, const int *, AstFrame *, int * );
+static void (* parent_setattrib)( AstObject *, const char *, int * );
+static void (* parent_setsystem)( AstFrame *, AstSystemType, int * );
+static void (* parent_clearsystem)( AstFrame *, int * );
+static void (* parent_clearunit)( AstFrame *, int, int * );
+
+#if defined(THREAD_SAFE)
+static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * );
+#endif
+
+/* Define macros for accessing each item of thread specific global data. */
+#ifdef THREAD_SAFE
+
+/* Define how to initialise thread-specific globals. */
+#define GLOBAL_inits \
+ globals->Class_Init = 0; \
+ globals->GetAttrib_Buff[ 0 ] = 0; \
+ globals->GetLabel_Buff[ 0 ] = 0; \
+ globals->GetSymbol_Buff[ 0 ] = 0; \
+ globals->GetTitle_Buff[ 0 ] = 0; \
+
+/* Create the function that initialises global data for this module. */
+astMAKE_INITGLOBALS(FluxFrame)
+
+/* Define macros for accessing each item of thread specific global data. */
+#define class_init astGLOBAL(FluxFrame,Class_Init)
+#define class_vtab astGLOBAL(FluxFrame,Class_Vtab)
+#define getattrib_buff astGLOBAL(FluxFrame,GetAttrib_Buff)
+#define getlabel_buff astGLOBAL(FluxFrame,GetLabel_Buff)
+#define getsymbol_buff astGLOBAL(FluxFrame,GetSymbol_Buff)
+#define gettitle_buff astGLOBAL(FluxFrame,GetTitle_Buff)
+
+
+
+/* If thread safety is not needed, declare and initialise globals at static
+ variables. */
+#else
+
+/* Buffers for strings returned by various functions. */
+static char getattrib_buff[ AST__FLUXFRAME_GETATTRIB_BUFF_LEN + 1 ];
+static char getlabel_buff[ AST__FLUXFRAME_GETLABEL_BUFF_LEN + 1 ];
+static char getsymbol_buff[ AST__FLUXFRAME_GETSYMBOL_BUFF_LEN + 1 ];
+static char gettitle_buff[ AST__FLUXFRAME_GETTITLE_BUFF_LEN + 1 ];
+
+
+/* Define the class virtual function table and its initialisation flag
+ as static variables. */
+static AstFluxFrameVtab class_vtab; /* Virtual function table */
+static int class_init = 0; /* Virtual function table initialised? */
+
+#endif
+
+/* Prototypes for Private Member Functions. */
+/* ======================================== */
+static int GetObjSize( AstObject *, int * );
+static AstSpecFrame *GetSpecFrame( AstFluxFrame *, int * );
+static AstSystemType DensitySystem( AstSystemType, int * );
+static AstSystemType GetAlignSystem( AstFrame *, int * );
+static AstSystemType GetDensitySystem( AstFluxFrame *, int * );
+static AstSystemType SystemCode( AstFrame *, const char *, int * );
+static AstSystemType ValidateSystem( AstFrame *, AstSystemType, const char *, int * );
+static const char *DefUnit( AstSystemType, const char *, const char *, int * );
+static const char *DensityUnit( AstSystemType, int * );
+static const char *FluxSystemString( AstSystemType, int * );
+static const char *GetDensityUnit( AstFluxFrame *, int * );
+static const char *GetDomain( AstFrame *, int * );
+static const char *GetLabel( AstFrame *, int, int * );
+static const char *GetSymbol( AstFrame *, int, int * );
+static const char *GetTitle( AstFrame *, int * );
+static const char *GetUnit( AstFrame *, int, int * );
+static const char *SystemLabel( AstSystemType, int * );
+static const char *SystemString( AstFrame *, AstSystemType, int * );
+static int GetActiveUnit( AstFrame *, int * );
+static int MakeFluxMapping( AstFluxFrame *, AstFluxFrame *, AstSystemType, AstMapping **, int * );
+static int Match( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * );
+static int SubFrame( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * );
+static int TestActiveUnit( AstFrame *, int * );
+static int UnitsOK( AstSystemType, const char *, int, const char *, const char *, int * );
+static void ClearUnit( AstFrame *, int, int * );
+static void Copy( const AstObject *, AstObject *, int * );
+static void Delete( AstObject *, int * );
+static void Dump( AstObject *, AstChannel *, int * );
+static void Overlay( AstFrame *, const int *, AstFrame *, int * );
+static void SetUnit( AstFrame *, int, const char *, int * );
+
+static AstSystemType GetSystem( AstFrame *, int * );
+static void SetSystem( AstFrame *, AstSystemType, int * );
+static void ClearSystem( AstFrame *, int * );
+
+static const char *GetAttrib( AstObject *, const char *, int * );
+static int TestAttrib( AstObject *, const char *, int * );
+static void ClearAttrib( AstObject *, const char *, int * );
+static void SetAttrib( AstObject *, const char *, int * );
+
+static double GetSpecVal( AstFluxFrame *, int * );
+static int TestSpecVal( AstFluxFrame *, int * );
+static void ClearSpecVal( AstFluxFrame *, int * );
+static void SetSpecVal( AstFluxFrame *, double, int * );
+
+#if defined(THREAD_SAFE)
+static int ManageLock( AstObject *, int, int, AstObject **, int * );
+#endif
+
+/* Member functions. */
+/* ================= */
+
+static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) {
+/*
+* Name:
+* ClearAttrib
+
+* Purpose:
+* Clear an attribute value for a FluxFrame.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* void ClearAttrib( AstObject *this, const char *attrib, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astClearAttrib protected
+* method inherited from the Frame class).
+
+* Description:
+* This function clears the value of a specified attribute for a
+* FluxFrame, so that the default value will subsequently be used.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* attrib
+* Pointer to a null terminated string specifying the attribute
+* name. This should be in lower case with no surrounding white
+* space.
+* status
+* Pointer to the inherited status variable.
+
+* Notes:
+* - This function uses one-based axis numbering so that it is
+* suitable for external (public) use.
+*/
+
+/* Local Variables: */
+ AstFluxFrame *this; /* Pointer to the FluxFrame structure */
+ int len; /* Length of attrib string */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Obtain a pointer to the FluxFrame structure. */
+ this = (AstFluxFrame *) this_object;
+
+/* Obtain the length of the "attrib" string. */
+ len = strlen( attrib );
+
+/* Check the attribute name and clear the appropriate attribute. */
+
+/* SpecVal. */
+/* -------- */
+ if ( !strcmp( attrib, "specval" ) ) {
+ astClearSpecVal( this );
+
+/* If the attribute is not recognised, pass it on to the parent method
+ for further interpretation. */
+ } else {
+ (*parent_clearattrib)( this_object, attrib, status );
+ }
+}
+
+static void ClearSystem( AstFrame *this_frame, int *status ) {
+/*
+* Name:
+* ClearSystem
+
+* Purpose:
+* Clear the System attribute for a FluxFrame.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* void ClearSystem( AstFrame *this_frame, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astClearSystem protected
+* method inherited from the Frame class).
+
+* Description:
+* This function clears the System attribute for a FluxFrame.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* status
+* Pointer to the inherited status variable.
+
+*/
+
+/* Local Variables: */
+ AstFluxFrame *this; /* Pointer to FluxFrame structure */
+ AstSystemType newsys; /* System after clearing */
+ AstSystemType oldsys; /* System before clearing */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Obtain a pointer to the FluxFrame structure. */
+ this = (AstFluxFrame *) this_frame;
+
+/* Save the original system */
+ oldsys = astGetSystem( this_frame );
+
+/* Use the parent ClearSystem method to clear the System value. */
+ (*parent_clearsystem)( this_frame, status );
+
+/* Get the default System. */
+ newsys = astGetSystem( this_frame );
+
+/* If the system has actually changed. */
+ if( newsys != oldsys ) {
+
+/* Changing the System value will in general require the Units to change
+ as well. If the used has previously specified the units to be used with
+ the new system, then re-instate them (they are stored in the "usedunits"
+ array in the FluxFrame structure). Otherwise, clear the units so that
+ the default units will eb used with the new System. */
+ if( (int) newsys < this->nuunits && this->usedunits &&
+ this->usedunits[ (int) newsys ] ) {
+ (*parent_setunit)( this_frame, 0, this->usedunits[ (int) newsys ], status );
+ } else {
+ (*parent_clearunit)( this_frame, 0, status );
+ }
+
+/* Also, clear all attributes which have system-specific defaults. */
+ astClearLabel( this_frame, 0 );
+ astClearSymbol( this_frame, 0 );
+ astClearTitle( this_frame );
+ }
+
+}
+
+static void ClearUnit( AstFrame *this_frame, int axis, int *status ) {
+/*
+* Name:
+* ClearUnit
+
+* Purpose:
+* Clear the value of the Unit string for a FluxFrame's axis.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* void ClearUnit( AstFrame *this_frame, int axis )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astClearUnit method inherited
+* from the Frame class).
+
+* Description:
+* This function clears the Unit string for a specified axis of a
+* FluxFrame. It also clears the UsedUnit item in the FluxFrame
+* structure corresponding to the current System.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* axis
+* The number of the axis (zero-based).
+*/
+
+/* Local Variables: */
+ AstFluxFrame *this; /* Pointer to the FluxFrame structure */
+ int system; /* The FluxFrame's System value */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Obtain a pointer to the FluxFrame structure. */
+ this = (AstFluxFrame *) this_frame;
+
+/* Validate the axis index. */
+ astValidateAxis( this, axis, 1, "astClearUnit" );
+
+/* Clear the UsedUnit item for the current System, if current set. */
+ system = (int) astGetSystem( this );
+ if( system < this->nuunits && this->usedunits ) {
+ this->usedunits[ system ] = astFree( this->usedunits[ system ] );
+ }
+
+/* Use the parent method to clear the Unit attribute of the axis. */
+ (*parent_clearunit)( this_frame, axis, status );
+}
+
+static const char *DefUnit( AstSystemType system, const char *method,
+ const char *class, int *status ){
+/*
+* Name:
+* DefUnit
+
+* Purpose:
+* Return the default units for a flux coordinate system type.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* const char *DefUnit( AstSystemType system, const char *method,
+* const char *class, int *status )
+
+* Class Membership:
+* FluxFrame member function.
+
+* Description:
+* This function returns a textual representation of the default
+* units associated with the specified flux coordinate system.
+
+* Parameters:
+* system
+* The flux coordinate system.
+* method
+* Pointer to a string holding the name of the calling method.
+* This is only for use in constructing error messages.
+* class
+* Pointer to a string holding the name of the supplied object class.
+* This is only for use in constructing error messages.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* As tring describing the default units. This string follows the
+* units syntax described in FITS WCS paper I "Representations of world
+* coordinates in FITS" (Greisen & Calabretta).
+
+* Notes:
+* - A NULL pointer is returned if this function is invoked with
+* the global error status set or if it should fail for any reason.
+*/
+
+/* Local Variables: */
+ const char *result; /* Value to return */
+
+/* Initialize */
+ result = NULL;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Get an identifier for the default units. */
+ if( system == AST__FLUXDEN ) {
+ result = "W/m^2/Hz";
+
+ } else if( system == AST__FLUXDENW ) {
+ result = "W/m^2/Angstrom";
+
+ } else if( system == AST__SBRIGHT ) {
+ result = "W/m^2/Hz/arcmin**2";
+
+ } else if( system == AST__SBRIGHTW ) {
+ result = "W/m^2/Angstrom/arcmin**2";
+
+/* Report an error if the coordinate system was not recognised. */
+ } else {
+ astError( AST__SCSIN, "%s(%s): Corrupt %s contains illegal System "
+ "identification code (%d).", status, method, class, class,
+ (int) system );
+ }
+
+/* Return the result. */
+ return result;
+}
+
+static AstSystemType DensitySystem( AstSystemType sys, int *status ) {
+/*
+* Name:
+* DensitySystem
+
+* Purpose:
+* Obtain the System describing the spectral density for a FluxFrame
+* system.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* AstSystemType DensitySystem( AstSystemType sys, int *status )
+
+* Class Membership:
+* FluxFrame member function.
+
+* Description:
+* This function returns AST__FREQ if the FluxFrame system describes
+* a quantity measured per unit frequency, and returns AST__WAVELEN if
+* the FluxFrame system describes a quantity measured per unit wavelength.
+
+* Parameters:
+* sys
+* A System value appropriate to a FluxFrame.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* The density System value.
+
+* Notes:
+* - AST__BADSYSTEM is returned if this function is invoked with
+* the global error status set or if it should fail for any reason.
+*/
+
+/* Local Variables: */
+ AstSystemType result; /* Value to return */
+
+/* Initialise. */
+ result = AST__BADSYSTEM;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Categorise the supplied system. */
+ if( sys == AST__FLUXDEN || sys == AST__SBRIGHT ) {
+ result = AST__FREQ;
+
+ } else if( sys == AST__FLUXDENW || sys == AST__SBRIGHTW ) {
+ result = AST__WAVELEN;
+
+ } else if( astOK ) {
+ astError( AST__INTER, "DensitySystem(FluxFrame): The "
+ "DensitySystem method does not yet support "
+ "FluxFrame system %d (AST internal programming error).", status,
+ sys );
+ }
+
+/* Return the result. */
+ return result;
+}
+
+static const char *DensityUnit( AstSystemType sys, int *status ) {
+/*
+* Name:
+* DensityUnit
+
+* Purpose:
+* Obtain the default units for the spectral density of a FluxFrame
+* system.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* const char *DensityUnit( AstSystemType sys, int *status )
+
+* Class Membership:
+* FluxFrame member function.
+
+* Description:
+* This function returns "Hz" if the FluxFrame system describes
+* a quantity measured per unit frequency, and returns "Angstrom" if
+* the FluxFrame system describes a quantity measured per unit wavelength.
+
+* Parameters:
+* sys
+* A FluxFrame system value.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* A pointer to a null-terminated string containing the Unit value.
+
+* Notes:
+* - A NULL pointer will be returned if this function is invoked with the
+* global error status set, or if it should fail for any reason.
+*/
+
+/* Local Variables: */
+ const char *result; /* Pointer value to return */
+
+/* Initialise. */
+ result = NULL;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Categorise the supplied FluxFrame system. */
+ if( sys == AST__FLUXDEN || sys == AST__SBRIGHT ) {
+ result = "Hz";
+
+ } else if( sys == AST__FLUXDENW || sys == AST__SBRIGHTW ) {
+ result = "Angstrom";
+
+ } else if( astOK ) {
+ astError( AST__INTER, "DensityUnit(FluxFrame): The DensityUnit "
+ "method does not yet support FluxFrame system %d (AST "
+ "internal programming error).", status, sys );
+ }
+
+/* Return the result. */
+ return result;
+}
+
+static const char *FluxSystemString( AstSystemType system, int *status ) {
+/*
+* Name:
+* FluxSystemString
+
+* Purpose:
+* Convert a FluxFrame coordinate system type code into a string.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* const char *FluxSystemString( AstSystemType system, int *status )
+
+* Class Membership:
+* FluxFrame member function
+
+* Description:
+* This function converts a FluxFrame coordinate system type code
+* (System attribute value) into a string suitable for use as an
+* external representation of the coordinate system type.
+
+* Parameters:
+* system
+* The coordinate system type code.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* Pointer to a constant null-terminated string containing the
+* textual equivalent of the type code supplied.
+
+* Notes:
+* - A NULL pointer value is returned if the coordinate system
+* code was not recognised. This does not produce an error.
+* - A NULL pointer value is also returned if this function is
+* invoked with the global error status set or if it should fail
+* for any reason.
+*/
+
+/* Local Variables: */
+ const char *result; /* Pointer value to return */
+
+/* Initialise. */
+ result = NULL;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Match the "system" value against each possibility and convert to a
+ string pointer. */
+ switch ( system ) {
+
+ case AST__FLUXDEN:
+ result = "FLXDN";
+ break;
+
+ case AST__FLUXDENW:
+ result = "FLXDNW";
+ break;
+
+ case AST__SBRIGHT:
+ result = "SFCBR";
+ break;
+
+ case AST__SBRIGHTW:
+ result = "SFCBRW";
+ break;
+
+ }
+
+/* Return the result pointer. */
+ return result;
+}
+
+static int GetObjSize( AstObject *this_object, int *status ) {
+/*
+* Name:
+* GetObjSize
+
+* Purpose:
+* Return the in-memory size of an Object.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* int GetObjSize( AstObject *this, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astGetObjSize protected
+* method inherited from the parent class).
+
+* Description:
+* This function returns the in-memory size of the supplied FluxFrame,
+* in bytes.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* The Object size, in bytes.
+
+* Notes:
+* - A value of zero will be returned if this function is invoked
+* with the global status set, or if it should fail for any reason.
+*/
+
+/* Local Variables: */
+ AstFluxFrame *this; /* Pointer to FluxFrame structure */
+ int result; /* Result value to return */
+ int i;
+
+/* Initialise. */
+ result = 0;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Obtain a pointers to the FluxFrame structure. */
+ this = (AstFluxFrame *) this_object;
+
+/* Invoke the GetObjSize method inherited from the parent class, and then
+ add on any components of the class structure defined by thsi class
+ which are stored in dynamically allocated memory. */
+ result = (*parent_getobjsize)( this_object, status );
+
+ if( this && this->usedunits ) {
+ for( i = 0; i < this->nuunits; i++ ) {
+ result += astTSizeOf( this->usedunits[ i ] );
+ }
+ result += astTSizeOf( this->usedunits );
+ }
+
+ result += astGetObjSize( this->specframe );
+
+/* If an error occurred, clear the result value. */
+ if ( !astOK ) result = 0;
+
+/* Return the result, */
+ return result;
+}
+
+static int GetActiveUnit( AstFrame *this_frame, int *status ) {
+/*
+* Name:
+* GetActiveUnit
+
+* Purpose:
+* Obtain the value of the ActiveUnit flag for a FluxFrame.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* int GetActiveUnit( AstFrame *this_frame, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astGetActiveUnit protected
+* method inherited from the Frame class).
+
+* Description:
+* This function returns the value of the ActiveUnit flag for a
+* FluxFrame, which is always 1.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* The value to use for the ActiveUnit flag (1).
+
+*/
+ return 1;
+}
+
+static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) {
+/*
+* Name:
+* GetAttrib
+
+* Purpose:
+* Get the value of a specified attribute for a FluxFrame.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* const char *GetAttrib( AstObject *this, const char *attrib, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the protected astGetAttrib
+* method inherited from the Frame class).
+
+* Description:
+* This function returns a pointer to the value of a specified
+* attribute for a FluxFrame, formatted as a character string.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* attrib
+* Pointer to a null-terminated string containing the name of
+* the attribute whose value is required. This name should be in
+* lower case, with all white space removed.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* - Pointer to a null-terminated string containing the attribute
+* value.
+
+* Notes:
+* - This function uses one-based axis numbering so that it is
+* suitable for external (public) use.
+* - The returned string pointer may point at memory allocated
+* within the FluxFrame, or at static memory. The contents of the
+* string may be over-written or the pointer may become invalid
+* following a further invocation of the same function or any
+* modification of the FluxFrame. A copy of the string should
+* therefore be made if necessary.
+* - A NULL pointer will be returned if this function is invoked
+* with the global error status set, or if it should fail for any
+* reason.
+*/
+
+/* Local Variables: */
+ astDECLARE_GLOBALS /* Declare the thread specific global data */
+ AstFluxFrame *this; /* Pointer to the FluxFrame structure */
+ const char *result; /* Pointer value to return */
+ double dval; /* Attribute value */
+ int len; /* Length of attrib string */
+
+/* Initialise. */
+ result = NULL;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Get a pointer to the structure holding thread-specific global data. */
+ astGET_GLOBALS(this_object);
+
+/* Obtain a pointer to the FluxFrame structure. */
+ this = (AstFluxFrame *) this_object;
+
+/* Obtain the length of the attrib string. */
+ len = strlen( attrib );
+
+/* Compare "attrib" with each recognised attribute name in turn,
+ obtaining the value of the required attribute. If necessary, write
+ the value into "getattrib_buff" as a null-terminated string in an appropriate
+ format. Set "result" to point at the result string. */
+
+/* SpecVal */
+/* ------- */
+ if ( !strcmp( attrib, "specval" ) ) {
+ dval = astGetSpecVal( this );
+ if ( astOK ) {
+ if( dval != AST__BAD ) {
+ (void) sprintf( getattrib_buff, "%.*g", AST__DBL_DIG, dval );
+ result = getattrib_buff;
+ } else {
+ result = "<bad>";
+ }
+ }
+
+/* If the attribute name was not recognised, pass it on to the parent
+ method for further interpretation. */
+ } else {
+ result = (*parent_getattrib)( this_object, attrib, status );
+ }
+
+/* Return the result. */
+ return result;
+}
+
+static AstSystemType GetDensitySystem( AstFluxFrame *this, int *status ) {
+/*
+*+
+* Name:
+* astGetDensitySystem
+
+* Purpose:
+* Obtain the System describing the spectral density of a FluxFrame.
+
+* Type:
+* Protected virtual function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* AstSystemType astGetDensitySystem( AstFluxFrame *this )
+
+* Class Membership:
+* FluxFrame method.
+
+* Description:
+* This function returns AST__FREQ if the FluxFrame system describes
+* a quantity measured per unit frequency, and returns AST__WAVELEN if
+* the FluxFrame system describes a quantity measured per unit wavelength.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+
+* Returned Value:
+* The System value.
+
+* Notes:
+* - AST__BADSYSTEM is returned if this function is invoked with
+* the global error status set or if it should fail for any reason.
+*-
+*/
+
+/* Check the global error status. */
+ if ( !astOK ) return AST__BADSYSTEM;
+
+/* Get the FluxFrame system and categorise it. */
+ return DensitySystem( astGetSystem( this ), status );
+}
+
+static const char *GetDensityUnit( AstFluxFrame *this, int *status ) {
+/*
+*+
+* Name:
+* astGetDensityUnit
+
+* Purpose:
+* Obtain the default units for the spectral density of a FluxFrame.
+
+* Type:
+* Protected virtual function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* const char *astGetDensityUnit( AstFluxFrame *this )
+
+* Class Membership:
+* FluxFrame method.
+
+* Description:
+* This function returns "Hz" if the FluxFrame system describes
+* a quantity measured per unit frequency, and returns "Angstrom" if
+* the FluxFrame system describes a quantity measured per unit wavelength.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+
+* Returned Value:
+* A pointer to a null-terminated string containing the Unit value.
+
+* Notes:
+* - A NULL pointer will be returned if this function is invoked with the
+* global error status set, or if it should fail for any reason.
+*-
+*/
+
+/* Check the global error status. */
+ if ( !astOK ) return NULL;
+
+/* Get the FluxFrame system and categorise it. */
+ return DensityUnit( astGetSystem( this ), status );
+}
+
+static const char *GetDomain( AstFrame *this_frame, int *status ) {
+/*
+* Name:
+* GetDomain
+
+* Purpose:
+* Obtain a pointer to the Domain attribute string for a FluxFrame.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* const char *GetDomain( AstFrame *this, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astGetDomain protected
+* method inherited from the Frame class).
+
+* Description:
+* This function returns a pointer to the Domain attribute string
+* for a FluxFrame.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* A pointer to a constant null-terminated string containing the
+* Domain value.
+
+* Notes:
+* - The returned pointer or the string it refers to may become
+* invalid following further invocation of this function or
+* modification of the FluxFrame.
+* - A NULL pointer is returned if this function is invoked with
+* the global error status set or if it should fail for any reason.
+*/
+
+/* Local Variables: */
+ AstFluxFrame *this; /* Pointer to FluxFrame structure */
+ const char *result; /* Pointer value to return */
+
+/* Initialise. */
+ result = NULL;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Obtain a pointer to the FluxFrame structure. */
+ this = (AstFluxFrame *) this_frame;
+
+/* If a Domain attribute string has been set, invoke the parent method
+ to obtain a pointer to it. */
+ if ( astTestDomain( this ) ) {
+ result = (*parent_getdomain)( this_frame, status );
+
+/* Otherwise, provide a pointer to a suitable default string. */
+ } else {
+ result = "FLUX";
+ }
+
+/* Return the result. */
+ return result;
+}
+
+static const char *GetLabel( AstFrame *this, int axis, int *status ) {
+/*
+* Name:
+* GetLabel
+
+* Purpose:
+* Access the Label string for a FluxFrame axis.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* const char *GetLabel( AstFrame *this, int axis, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astGetLabel method inherited
+* from the Frame class).
+
+* Description:
+* This function returns a pointer to the Label string for a specified axis
+* of a FluxFrame.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* axis
+* Axis index (zero-based) identifying the axis for which information is
+* required.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* Pointer to a constant null-terminated character string containing the
+* requested information.
+
+* Notes:
+* - A NULL pointer will be returned if this function is invoked with the
+* global error status set, or if it should fail for any reason.
+*/
+
+/* Local Variables: */
+ astDECLARE_GLOBALS /* Declare the thread specific global data */
+ AstMapping *map; /* Mapping between units */
+ AstSystemType system; /* Code identifying type of flux coordinates */
+ char *new_lab; /* Modified label string */
+ const char *result; /* Pointer to label string */
+
+/* Check the global error status. */
+ if ( !astOK ) return NULL;
+
+/* Get a pointer to the structure holding thread-specific global data. */
+ astGET_GLOBALS(this);
+
+/* Initialise. */
+ result = NULL;
+
+/* Validate the axis index. */
+ astValidateAxis( this, axis, 1, "astGetLabel" );
+
+/* Check if a value has been set for the required axis label string. If so,
+ invoke the parent astGetLabel method to obtain a pointer to it. */
+ if ( astTestLabel( this, axis ) ) {
+ result = (*parent_getlabel)( this, axis, status );
+
+/* Otherwise, identify the flux coordinate system described by the
+ FluxFrame. */
+ } else {
+ system = astGetSystem( this );
+
+/* If OK, supply a pointer to a suitable default label string. */
+ if ( astOK ) {
+ result = strcpy( getlabel_buff, SystemLabel( system, status ) );
+ getlabel_buff[ 0 ] = toupper( getlabel_buff[ 0 ] );
+
+/* Modify this default to take account of the current value of the Unit
+ attribute, if set. */
+ if( astTestUnit( this, axis ) ) {
+
+/* Find a Mapping from the default Units for the current System, to the
+ units indicated by the Unit attribute. This Mapping is used to modify
+ the existing default label appropriately. For instance, if the default
+ units is "Jy" and the actual units is "log(Jy)", then the default label
+ of "Flux density" is changed to "log( Flux density )". */
+ map = astUnitMapper( DefUnit( system, "astGetLabel",
+ astGetClass( this ), status ),
+ astGetUnit( this, axis ), result,
+ &new_lab );
+ if( new_lab ) {
+ result = strcpy( getlabel_buff, new_lab );
+ new_lab = astFree( new_lab );
+ }
+
+/* Annul the unused Mapping. */
+ if( map ) map = astAnnul( map );
+
+ }
+ }
+ }
+
+/* Return the result. */
+ return result;
+}
+
+static AstSpecFrame *GetSpecFrame( AstFluxFrame *this, int *status ) {
+/*
+* Name:
+* GetSpecFrame
+
+* Purpose:
+* Get a pointer to a SpecFrame associated with a FluxFrame
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* AstSpecFrame *GetSpecFrame( AstFluxFrame *this, int *status )
+
+* Class Membership:
+* FluxFrame member function
+
+* Description:
+* This function returns a SpecFrame describing the spectral system in
+* which the FluxFrame's SpecVal attribute is stored. A default
+* SpecFrame is created and returned if the no SpecFrame was supplied
+* when the FluxFrame was created.
+
+* Parameters:
+* this
+* The FluxFrame.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* Pointer to the SpecFrame. It should be freed using astAnnul when no
+* longer needed.
+
+* Notes:
+* - A NULL pointer value is returned if this function is
+* invoked with the global error status set or if it should fail
+* for any reason.
+*/
+
+/* Local Variables: */
+ AstSpecFrame *result; /* Pointer value to return */
+
+/* Initialise. */
+ result = NULL;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* If the FluxFrame contains a SpecFrame, return a clone of its pointer. */
+ if( this->specframe ) {
+ result = astClone( this->specframe );
+
+/* Otherwise, create a SpecFrame appropriate to the FluxFrames System. */
+ } else {
+ result = astSpecFrame( "", status );
+ astSetSystem( result, astGetDensitySystem( this ) );
+ astSetUnit( result, 0, astGetDensityUnit( this ) );
+ }
+
+/* Annul the result if an error occurred. */
+ if( !astOK ) result = astAnnul( result );
+
+/* Return the result pointer. */
+ return result;
+}
+
+static const char *GetSymbol( AstFrame *this, int axis, int *status ) {
+/*
+* Name:
+* GetSymbol
+
+* Purpose:
+* Obtain a pointer to the Symbol string for a FluxFrame axis.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* const char *GetSymbol( AstFrame *this, int axis, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astGetSymbol method inherited
+* from the Frame class).
+
+* Description:
+* This function returns a pointer to the Symbol string for a specified axis
+* of a FluxFrame.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* axis
+* Axis index (zero-based) identifying the axis for which information is
+* required.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* Pointer to a constant null-terminated character string containing the
+* requested information.
+
+* Notes:
+* - A NULL pointer will be returned if this function is invoked with the
+* global error status set, or if it should fail for any reason.
+*/
+
+/* Local Variables: */
+ astDECLARE_GLOBALS /* Declare the thread specific global data */
+ AstMapping *map; /* Mapping between units */
+ AstSystemType system; /* Code identifying type of sky coordinates */
+ char *new_sym; /* Modified symbol string */
+ const char *result; /* Pointer to symbol string */
+
+/* Check the global error status. */
+ if ( !astOK ) return NULL;
+
+/* Get a pointer to the structure holding thread-specific global data. */
+ astGET_GLOBALS(this);
+
+/* Initialise. */
+ result = NULL;
+
+/* Validate the axis index. */
+ astValidateAxis( this, axis, 1, "astGetSymbol" );
+
+/* Check if a value has been set for the required axis symbol string. If so,
+ invoke the parent astGetSymbol method to obtain a pointer to it. */
+ if ( astTestSymbol( this, axis ) ) {
+ result = (*parent_getsymbol)( this, axis, status );
+
+/* Otherwise, identify the flux coordinate system described by the FluxFrame. */
+ } else {
+ system = astGetSystem( this );
+
+/* If OK, supply a pointer to a suitable default Symbol string. */
+ if ( astOK ) {
+
+ if( system == AST__FLUXDEN ) {
+ result = "S_nu";
+
+ } else if( system == AST__FLUXDENW ) {
+ result = "S_lambda";
+
+ } else if( system == AST__SBRIGHT ) {
+ result = "mu_nu";
+
+ } else if( system == AST__SBRIGHTW ) {
+ result = "mu_lambda";
+
+/* Report an error if the coordinate system was not recognised. */
+ } else {
+ astError( AST__SCSIN, "astGetSymbol(%s): Corrupt %s contains "
+ "invalid System identification code (%d).", status,
+ astGetClass( this ), astGetClass( this ), (int) system );
+ }
+
+/* Modify this default to take account of the current value of the Unit
+ attribute, if set. */
+ if( astTestUnit( this, axis ) ) {
+
+/* Find a Mapping from the default Units for the current System, to the
+ units indicated by the Unit attribute. This Mapping is used to modify
+ the existing default symbol appropriately. For instance, if the default
+ units is "Jy" and the actual units is "log(Jy)", then the default symbol
+ of "S_nu" is changed to "log( S_nu )". */
+ map = astUnitMapper( DefUnit( system, "astGetSymbol",
+ astGetClass( this ), status ),
+ astGetUnit( this, axis ), result,
+ &new_sym );
+ if( new_sym ) {
+ result = strcpy( getsymbol_buff, new_sym );
+ new_sym = astFree( new_sym );
+ }
+
+/* Annul the unused Mapping. */
+ if( map ) map = astAnnul( map );
+
+ }
+ }
+ }
+
+/* Return the result. */
+ return result;
+}
+
+static AstSystemType GetAlignSystem( AstFrame *this_frame, int *status ) {
+/*
+* Name:
+* GetAlignSystem
+
+* Purpose:
+* Obtain the AlignSystem attribute for a FluxFrame.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* AstSystemType GetAlignSystem( AstFrame *this_frame, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astGetAlignSystem protected
+* method inherited from the Frame class).
+
+* Description:
+* This function returns the AlignSystem attribute for a FluxFrame.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* The AlignSystem value.
+
+*/
+
+/* Local Variables: */
+ AstFluxFrame *this; /* Pointer to FluxFrame structure */
+ AstSystemType result; /* Value to return */
+
+/* Initialise. */
+ result = AST__BADSYSTEM;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Obtain a pointer to the FluxFrame structure. */
+ this = (AstFluxFrame *) this_frame;
+
+/* If a AlignSystem attribute has been set, invoke the parent method to obtain
+ it. */
+ if ( astTestAlignSystem( this ) ) {
+ result = (*parent_getalignsystem)( this_frame, status );
+
+/* Otherwise, provide a suitable default. */
+ } else {
+ result = AST__FLUXDEN;
+ }
+
+/* Return the result. */
+ return result;
+}
+
+static AstSystemType GetSystem( AstFrame *this_frame, int *status ) {
+/*
+* Name:
+* GetSystem
+
+* Purpose:
+* Obtain the System attribute for a FluxFrame.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* AstSystemType GetSystem( AstFrame *this_frame, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astGetSystem protected
+* method inherited from the Frame class).
+
+* Description:
+* This function returns the System attribute for a FluxFrame.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* The System value.
+
+* Notes:
+* - AST__BADSYSTEM is returned if this function is invoked with
+* the global error status set or if it should fail for any reason.
+*/
+
+/* Local Variables: */
+ AstFluxFrame *this; /* Pointer to FluxFrame structure */
+ AstMapping *map; /* Pointer to unit Mapping */
+ AstSystemType i; /* System to check */
+ AstSystemType result; /* Value to return */
+ const char *units; /* FluxFrame units */
+ int unitSet; /* Has a value been supplied for Unit? */
+
+/* Initialise. */
+ result = AST__BADSYSTEM;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Obtain a pointer to the FluxFrame structure. */
+ this = (AstFluxFrame *) this_frame;
+
+/* See if a value has been assigned to the Unit attribute. */
+ unitSet = astTestUnit( this_frame, 0 );
+
+/* If a System attribute has been set, invoke the parent method to obtain
+ it. */
+ if ( astTestSystem( this ) ) {
+ result = (*parent_getsystem)( this_frame, status );
+
+/* Otherwise, if the Unit attribute has been set, provide a suitable default
+ system based on the units. */
+ } else if( unitSet ){
+
+/* Loop round each known system value. If a Mapping can be found from the
+ current units to the default units for the system, then use the system as
+ the default system. */
+ units = astGetUnit( this_frame, 0 );
+ for( i = FIRST_SYSTEM; i <= LAST_SYSTEM; i++ ) {
+ map = astUnitMapper( units, DefUnit( i, "astGetSystem",
+ astGetClass( this ), status ), NULL, NULL );
+ if( map ) {
+ map = astAnnul( map );
+ result = i;
+ break;
+ }
+ }
+
+/* Otherwise, report an error. */
+ if( result == AST__BADSYSTEM && astOK ) {
+ astError( AST__BADUN, "astGetSystem(%s): The current units (%s) "
+ "cannot be used with any of the supported flux systems.", status,
+ astGetClass( this ), astGetUnit( this_frame, 0 ) );
+ }
+
+/* Otherwise, provide a suitable default based on the units. */
+ } else {
+ result = AST__FLUXDEN;
+ }
+
+/* Return the result. */
+ return result;
+}
+
+static const char *GetTitle( AstFrame *this_frame, int *status ) {
+/*
+* Name:
+* GetTitle
+
+* Purpose:
+* Obtain a pointer to the Title string for a FluxFrame.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* const char *GetTitle( AstFrame *this_frame, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astGetTitle method inherited
+* from the Frame class).
+
+* Description:
+* This function returns a pointer to the Title string for a FluxFrame.
+* A pointer to a suitable default string is returned if no Title value has
+* previously been set.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* Pointer to a null-terminated character string containing the requested
+* information.
+
+* Notes:
+* - A NULL pointer will be returned if this function is invoked with the
+* global error status set, or if it should fail for any reason.
+*/
+
+/* Local Variables: */
+ astDECLARE_GLOBALS /* Declare the thread specific global data */
+ AstFluxFrame *this; /* Pointer to FluxFrame structure */
+ AstSpecFrame *sf; /* Pointer to SpecFrame structure */
+ const char *result; /* Pointer to result string */
+ const char *sv; /* Formatted SpecVal string */
+ const char *su; /* Units string */
+ double specval; /* SpecVal value */
+ int pos; /* Buffer position to enter text */
+
+/* Check the global error status. */
+ if ( !astOK ) return NULL;
+
+/* Get a pointer to the structure holding thread-specific global data. */
+ astGET_GLOBALS(this_frame);
+
+/* Initialise. */
+ result = NULL;
+
+/* Obtain a pointer to the FluxFrame structure. */
+ this = (AstFluxFrame *) this_frame;
+
+/* See if a Title string has been set. If so, use the parent astGetTitle
+ method to obtain a pointer to it. */
+ if ( astTestTitle( this ) ) {
+ result = (*parent_gettitle)( this_frame, status );
+
+/* Otherwise, we will generate a default Title string. */
+ } else {
+
+/* Classify the coordinate system type and create an appropriate Title
+ string. */
+ if ( astOK ) {
+ result = gettitle_buff;
+
+/* Begin with the system's default label. */
+ pos = sprintf( gettitle_buff, "%s", SystemLabel( astGetSystem( this ), status ) );
+ gettitle_buff[ 0 ] = toupper( gettitle_buff[ 0 ] );
+
+/* Append the spectral position, if known. */
+ specval = astGetSpecVal( this );
+ sf = GetSpecFrame( this, status );
+ if( specval != AST__BAD && sf ) {
+ sv = astFormat( sf, 0, specval );
+ su = astGetUnit( sf, 0 );
+ pos += sprintf( gettitle_buff + pos, " at = %s %s", sv, su );
+ }
+ sf = astAnnul( sf );
+ }
+ }
+
+/* If an error occurred, clear the returned pointer value. */
+ if ( !astOK ) result = NULL;
+
+/* Return the result. */
+ return result;
+}
+
+static const char *GetUnit( AstFrame *this_frame, int axis, int *status ) {
+/*
+* Name:
+* GetUnit
+
+* Purpose:
+* Obtain a pointer to the Unit string for a FluxFrame's axis.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* const char *GetUnit( AstFrame *this_frame, int axis )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astGetUnit method inherited
+* from the Frame class).
+
+* Description:
+* This function returns a pointer to the Unit string for a specified axis
+* of a FluxFrame. If the Unit attribute has not been set for the axis, a
+* pointer to a suitable default string is returned instead.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* axis
+* The number of the axis (zero-based) for which information is required.
+
+* Returned Value:
+* A pointer to a null-terminated string containing the Unit value.
+
+* Notes:
+* - A NULL pointer will be returned if this function is invoked with the
+* global error status set, or if it should fail for any reason.
+*/
+
+/* Local Variables: */
+ AstFluxFrame *this; /* Pointer to the FluxFrame structure */
+ AstSystemType system; /* The FluxFrame's System value */
+ const char *result; /* Pointer value to return */
+
+/* Check the global error status. */
+ if ( !astOK ) return NULL;
+
+/* Obtain a pointer to the FluxFrame structure. */
+ this = (AstFluxFrame *) this_frame;
+
+/* Validate the axis index. */
+ astValidateAxis( this, axis, 1, "astGetUnit" );
+
+/* If a value has been set for the Unit attribute, use the parent
+ GetUnit method to return a pointer to the required Unit string. */
+ if( astTestUnit( this, axis ) ){
+ result = (*parent_getunit)( this_frame, axis, status );
+
+/* Otherwise, identify the flux coordinate system described by the
+ FluxFrame. */
+ } else {
+ system = astGetSystem( this );
+
+/* Return a string describing the default units. */
+ result = DefUnit( system, "astGetUnit", astGetClass( this ), status );
+ }
+
+/* If an error occurred, clear the returned value. */
+ if ( !astOK ) result = NULL;
+
+/* Return the result. */
+ return result;
+}
+
+void astInitFluxFrameVtab_( AstFluxFrameVtab *vtab, const char *name, int *status ) {
+/*
+*+
+* Name:
+* astInitFluxFrameVtab
+
+* Purpose:
+* Initialise a virtual function table for a FluxFrame.
+
+* Type:
+* Protected function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* void astInitFluxFrameVtab( AstFluxFrameVtab *vtab, const char *name )
+
+* Class Membership:
+* FluxFrame vtab initialiser.
+
+* Description:
+* This function initialises the component of a virtual function
+* table which is used by the FluxFrame class.
+
+* Parameters:
+* vtab
+* Pointer to the virtual function table. The components used by
+* all ancestral classes will be initialised if they have not already
+* been initialised.
+* name
+* Pointer to a constant null-terminated character string which contains
+* the name of the class to which the virtual function table belongs (it
+* is this pointer value that will subsequently be returned by the Object
+* astClass function).
+*-
+*/
+
+/* Local Variables: */
+ astDECLARE_GLOBALS /* Pointer to thread-specific global data */
+ AstFrameVtab *frame; /* Pointer to Frame component of Vtab */
+ AstObjectVtab *object; /* Pointer to Object component of Vtab */
+
+/* Check the local error status. */
+ if ( !astOK ) return;
+
+/* Get a pointer to the thread specific global data structure. */
+ astGET_GLOBALS(NULL);
+
+/* Initialize the component of the virtual function table used by the
+ parent class. */
+ astInitFrameVtab( (AstFrameVtab *) vtab, name );
+
+/* Store a unique "magic" value in the virtual function table. This
+ will be used (by astIsAFluxFrame) to determine if an object belongs
+ to this class. We can conveniently use the address of the (static)
+ class_check variable to generate this unique value. */
+ vtab->id.check = &class_check;
+ vtab->id.parent = &(((AstFrameVtab *) vtab)->id);
+
+/* Initialise member function pointers. */
+/* ------------------------------------ */
+/* Store pointers to the member functions (implemented here) that
+ provide virtual methods for this class. */
+ vtab->GetDensitySystem = GetDensitySystem;
+ vtab->GetDensityUnit = GetDensityUnit;
+
+ vtab->ClearSpecVal = ClearSpecVal;
+ vtab->TestSpecVal = TestSpecVal;
+ vtab->GetSpecVal = GetSpecVal;
+ vtab->SetSpecVal = SetSpecVal;
+
+/* Save the inherited pointers to methods that will be extended, and
+ replace them with pointers to the new member functions. */
+ object = (AstObjectVtab *) vtab;
+ frame = (AstFrameVtab *) vtab;
+ parent_getobjsize = object->GetObjSize;
+ object->GetObjSize = GetObjSize;
+
+ parent_clearattrib = object->ClearAttrib;
+ object->ClearAttrib = ClearAttrib;
+ parent_getattrib = object->GetAttrib;
+ object->GetAttrib = GetAttrib;
+ parent_setattrib = object->SetAttrib;
+ object->SetAttrib = SetAttrib;
+ parent_testattrib = object->TestAttrib;
+ object->TestAttrib = TestAttrib;
+
+#if defined(THREAD_SAFE)
+ parent_managelock = object->ManageLock;
+ object->ManageLock = ManageLock;
+#endif
+
+ parent_getdomain = frame->GetDomain;
+ frame->GetDomain = GetDomain;
+
+ parent_getsystem = frame->GetSystem;
+ frame->GetSystem = GetSystem;
+ parent_setsystem = frame->SetSystem;
+ frame->SetSystem = SetSystem;
+ parent_clearsystem = frame->ClearSystem;
+ frame->ClearSystem = ClearSystem;
+
+ parent_getalignsystem = frame->GetAlignSystem;
+ frame->GetAlignSystem = GetAlignSystem;
+
+ parent_getlabel = frame->GetLabel;
+ frame->GetLabel = GetLabel;
+
+ parent_getsymbol = frame->GetSymbol;
+ frame->GetSymbol = GetSymbol;
+
+ parent_gettitle = frame->GetTitle;
+ frame->GetTitle = GetTitle;
+
+ parent_clearunit = frame->ClearUnit;
+ frame->ClearUnit = ClearUnit;
+
+ parent_getunit = frame->GetUnit;
+ frame->GetUnit = GetUnit;
+
+ parent_setunit = frame->SetUnit;
+ frame->SetUnit = SetUnit;
+
+ parent_match = frame->Match;
+ frame->Match = Match;
+
+ parent_overlay = frame->Overlay;
+ frame->Overlay = Overlay;
+
+ parent_subframe = frame->SubFrame;
+ frame->SubFrame = SubFrame;
+
+/* Store replacement pointers for methods which will be over-ridden by new
+ member functions implemented here. */
+ frame->GetActiveUnit = GetActiveUnit;
+ frame->TestActiveUnit = TestActiveUnit;
+ frame->ValidateSystem = ValidateSystem;
+ frame->SystemString = SystemString;
+ frame->SystemCode = SystemCode;
+
+/* Declare the copy constructor, destructor and class dump
+ function. */
+ astSetCopy( vtab, Copy );
+ astSetDelete( vtab, Delete );
+ astSetDump( vtab, Dump, "FluxFrame", "Description of flux values" );
+
+/* If we have just initialised the vtab for the current class, indicate
+ that the vtab is now initialised, and store a pointer to the class
+ identifier in the base "object" level of the vtab. */
+ if( vtab == &class_vtab ) {
+ class_init = 1;
+ astSetVtabClassIdentifier( vtab, &(vtab->id) );
+ }
+}
+
+#if defined(THREAD_SAFE)
+static int ManageLock( AstObject *this_object, int mode, int extra,
+ AstObject **fail, int *status ) {
+/*
+* Name:
+* ManageLock
+
+* Purpose:
+* Manage the thread lock on an Object.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "object.h"
+* AstObject *ManageLock( AstObject *this, int mode, int extra,
+* AstObject **fail, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astManageLock protected
+* method inherited from the parent class).
+
+* Description:
+* This function manages the thread lock on the supplied Object. The
+* lock can be locked, unlocked or checked by this function as
+* deteremined by parameter "mode". See astLock for details of the way
+* these locks are used.
+
+* Parameters:
+* this
+* Pointer to the Object.
+* mode
+* An integer flag indicating what the function should do:
+*
+* AST__LOCK: Lock the Object for exclusive use by the calling
+* thread. The "extra" value indicates what should be done if the
+* Object is already locked (wait or report an error - see astLock).
+*
+* AST__UNLOCK: Unlock the Object for use by other threads.
+*
+* AST__CHECKLOCK: Check that the object is locked for use by the
+* calling thread (report an error if not).
+* extra
+* Extra mode-specific information.
+* fail
+* If a non-zero function value is returned, a pointer to the
+* Object that caused the failure is returned at "*fail". This may
+* be "this" or it may be an Object contained within "this". Note,
+* the Object's reference count is not incremented, and so the
+* returned pointer should not be annulled. A NULL pointer is
+* returned if this function returns a value of zero.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* A local status value:
+* 0 - Success
+* 1 - Could not lock or unlock the object because it was already
+* locked by another thread.
+* 2 - Failed to lock a POSIX mutex
+* 3 - Failed to unlock a POSIX mutex
+* 4 - Bad "mode" value supplied.
+
+* Notes:
+* - This function attempts to execute even if an error has already
+* occurred.
+*/
+
+/* Local Variables: */
+ AstFluxFrame *this; /* Pointer to FluxFrame structure */
+ int result; /* Returned status value */
+
+/* Initialise */
+ result = 0;
+
+/* Check the supplied pointer is not NULL. */
+ if( !this_object ) return result;
+
+/* Obtain a pointers to the FluxFrame structure. */
+ this = (AstFluxFrame *) this_object;
+
+/* Invoke the ManageLock method inherited from the parent class. */
+ if( !result ) result = (*parent_managelock)( this_object, mode, extra,
+ fail, status );
+
+/* Invoke the astManageLock method on any Objects contained within
+ the supplied Object. */
+ if( !result ) result = astManageLock( this->specframe, mode, extra, fail );
+
+ return result;
+
+}
+#endif
+
+static int MakeFluxMapping( AstFluxFrame *target, AstFluxFrame *result,
+ AstSystemType align_sys, AstMapping **map, int *status ) {
+/*
+* Name:
+* MakeFluxMapping
+
+* Purpose:
+* Generate a Mapping between two FluxFrames.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* int MakeFluxMapping( AstFluxFrame *target, AstFluxFrame *result,
+* AstSystemType align_sys, MakeFluAstMapping **map, int *status )
+
+* Class Membership:
+* FluxFrame member function.
+
+* Description:
+* This function takes two FluxFrames and generates a Mapping that
+* converts between them, taking account of differences in their
+* coordinate systems, reference frequency, etc.
+*
+* In order to cut down the number of transformations to be considered,
+* the scheme works by first converting from the target frame to an
+* "alignment" Frame, using the attributes of the target to define the
+* transformation. A transformation is then found from the alignment
+* frame to the required result Frame, using the attributes of the
+* result to define the transformation. The alignment Frame is
+* described by the supplied parameter "align_sys".
+
+* Parameters:
+* target
+* Pointer to the first FluxFrame.
+* result
+* Pointer to the second FluxFrame.
+* align_sys
+* The flux system in which to align the two FluxFrames.
+* map
+* Pointer to a location which is to receive a pointer to the
+* returned Mapping. The forward transformation of this Mapping
+* will convert from "target" coordinates to "result"
+* coordinates, and the inverse transformation will convert in
+* the opposite direction (all coordinate values in radians).
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* Non-zero if the Mapping could be generated, or zero if the two
+* FluxFrames are sufficiently un-related that no meaningful Mapping
+* can be produced (in which case a NULL Mapping pointer will be
+* returned).
+
+* Notes:
+* A value of zero is returned if this function is invoked with the
+* global error status set or if it should fail for any reason.
+*/
+
+/* Local Variables: */
+ AstFrameSet *fs;
+ AstMapping *map1;
+ AstMapping *map2;
+ AstMapping *map3;
+ AstMapping *map4;
+ AstMapping *map5;
+ AstMapping *smap;
+ AstMapping *smap_in;
+ AstMapping *smap_out;
+ AstMapping *tmap;
+ AstSpecFrame *sfin1;
+ AstSpecFrame *sfin2;
+ AstSpecFrame *sfout1;
+ AstSpecFrame *sfout2;
+ AstSystemType rsys_in;
+ AstSystemType rsys_out;
+ AstSystemType sys_in;
+ AstSystemType sys_out;
+ double specval2;
+ double specval;
+ double specval_in;
+ double specval_out;
+ double zoom;
+ int match;
+ int sb_in;
+ int sb_out;
+
+/* Check the global error status. */
+ if ( !astOK ) return 0;
+
+/* Initialise the returned values. */
+ match = 0;
+ *map = NULL;
+
+/* Initialise to avoid compiler warnings. */
+ map1 = NULL;
+ map2 = NULL;
+ map3 = NULL;
+
+/* Note the target and result System */
+ rsys_in = astGetSystem( target );
+ rsys_out = astGetSystem( result );
+
+/* First get a Mapping which converts from the units used in the target
+ to the default units associated with the target's system.
+ ---------------------------------------------------------------------- */
+ map1 = astUnitMapper( astGetUnit( target, 0 ),
+ DefUnit( rsys_in, "MakeFluxMapping", "FluxFrame", status ),
+ NULL, NULL );
+
+/* If the target system is surface brightness, change it to the
+ corresponding flux density system. We are effectively converting from
+ surface brightness to the flux density normalised to unit area. Also
+ set flags indicating if the systems are surface brightness systems. */
+ if( rsys_in == AST__SBRIGHT ) {
+ sys_in = AST__FLUXDEN;
+ sb_in = 1;
+
+ } else if( rsys_in == AST__SBRIGHTW ) {
+ sys_in = AST__FLUXDENW;
+ sb_in = 1;
+
+ } else {
+ sys_in = rsys_in;
+ sb_in = 0;
+ }
+
+/* Likewise if the result system is surface brightness, change it to the
+ corresponding flux density system. */
+ if( rsys_out == AST__SBRIGHT ) {
+ sys_out = AST__FLUXDEN;
+ sb_out = 1;
+
+ } else if( rsys_out == AST__SBRIGHTW ) {
+ sys_out = AST__FLUXDENW;
+ sb_out = 1;
+
+ } else {
+ sys_out = rsys_out;
+ sb_out = 0;
+ }
+
+/* Assume at this point in the chain of coversions that we have target values
+ in some form of flux density system (either frequency or wavelength). The
+ precise units do not matter at this point (so long as they are
+ dimensionally correct for describing the relevant form of flux density).
+ When other systems are added (e.g. antenna temperature), some code
+ will have to come before this point which produces a Mapping from (e.g.)
+ antenna temperature to flux density. */
+
+
+/* Get a Mapping from the default units for the input flux density system
+ to the default units for the output flux density system.
+ ---------------------------------------------------------------------- */
+
+/* If one but not both of the systems represent surface brightness, then
+ we cannot form a Mapping. */
+ if( sb_in != sb_out ) {
+ zoom = AST__BAD;
+
+/* If the input and output flux density systems are the same, then the
+ required Mapping is a UnitMap. */
+ } else if( sys_in == sys_out ) {
+ zoom = 1.0;
+
+/* Otherwise, the required Mapping is a zoom map in which the scale factor is
+ the rate of change of the input spectral system with respect to the output
+ spectral system, at the position given by the SpecVal attribute (we
+ cannot do the conversion if the SpecVal values in the target and result
+ differ). Each spectral system is either wavelength (in Angstrom) or
+ frequency (in Hz), depending on whether the associated flux density
+ system is "per Angstrom" or "per Hertz". The SpecVal value may be
+ stored in some other system, so the first job is to create SpecFrames
+ with the required system and units from the SpecFrames encapsulated
+ within the target and result FluxFrames. Take deep copies of the two
+ SpecFrames, and set their systems and units. */
+ } else {
+ sfin1 = GetSpecFrame( target, status );
+ sfin2 = astCopy( sfin1 );
+ astSetSystem( sfin2, DensitySystem( sys_in, status ) );
+ astSetUnit( sfin2, 0, DensityUnit( sys_in, status ) );
+
+ sfout1 = GetSpecFrame( result, status );
+ sfout2 = astCopy( sfout1 );
+ astSetSystem( sfout2, DensitySystem( sys_out, status ) );
+ astSetUnit( sfout2, 0, DensityUnit( sys_out, status ) );
+
+/* Indicate we do not yet have a zoom factor */
+ zoom = AST__BAD;
+
+/* Get the Mapping from output to input spectral coordinate system */
+ fs = astConvert( sfout2, sfin2, "" );
+ if( fs ) {
+ tmap = astGetMapping( fs, AST__BASE, AST__CURRENT );
+ fs = astAnnul( fs );
+
+/* Simplify the Mapping. */
+ smap = astSimplify( tmap );
+ tmap = astAnnul( tmap );
+
+/* We first need to transform the two SpecVal attributes into the input
+ coordinate system of the "smap" Mapping (i.e. the standardised result
+ FluxFrame), and check they are the same. For this we need the Mappings
+ from the SpecFrames stored in the FluxFrames to the modified copies
+ created above. */
+ fs = astConvert( sfin1, sfin2, "" );
+ if( fs ) {
+ smap_in = astGetMapping( fs, AST__BASE, AST__CURRENT );
+ fs = astAnnul( fs );
+ } else {
+ smap_in = NULL;
+ }
+
+ fs = astConvert( sfout1, sfout2, "" );
+ if( fs ) {
+ smap_out = astGetMapping( fs, AST__BASE, AST__CURRENT );
+ fs = astAnnul( fs );
+ } else {
+ smap_out = NULL;
+ }
+
+/* Convert the target's SpecVal into the standardised target system */
+ specval = astGetSpecVal( target );
+ astTran1( smap_in, 1, &specval, 1, &specval2 );
+
+/* Now convert it into the standardised result system. Note, we need to
+ use "smap" in the inverse direction for this. */
+ astTran1( smap, 1, &specval2, 0, &specval_in );
+
+/* Convert the results's SpecVal into the standardised result system */
+ specval = astGetSpecVal( result );
+ astTran1( smap_out, 1, &specval, 1, &specval_out );
+
+/* Check they are equal and good. */
+ if( astEQUALS( specval_in, specval_out, 1.0E8 ) && specval_in != AST__BAD ) {
+
+/* If the siSimplified Mapping is a UnitMap the required rate of change
+ factor is 1.0. If it resuts in a ZoomMap, the required factor is
+ the zoom factor in the ZoomMap. */
+ if( astIsAUnitMap( smap ) ) {
+ zoom = 1.0;
+
+ } else if( astIsAZoomMap( smap ) ) {
+ zoom = astGetZoom( smap );
+
+/* For any other type of Mapping, we must determine the rate of change factor
+ by differentiating the Mapping at the SpecVal position. */
+ } else {
+ specval = 0.5*( specval_in + specval_out );
+ zoom = astRate( smap, &specval, 0, 0 );
+ }
+ }
+
+/* Free resources */
+ if( smap_in ) smap_in = astAnnul( smap_in );
+ if( smap_out ) smap_out = astAnnul( smap_out );
+ smap = astAnnul( smap );
+ }
+
+ sfout1 = astAnnul( sfout1 );
+ sfin1 = astAnnul( sfin1 );
+ sfout2 = astAnnul( sfout2 );
+ sfin2 = astAnnul( sfin2 );
+ }
+
+/* Create the required zoom map if a scaling factor was found. */
+ if( zoom != AST__BAD ) {
+ map2 = (AstMapping *) astZoomMap( 1, fabs( zoom ), "", status );
+ } else {
+ map2 = NULL;
+ }
+
+/* Now get a Mapping which converts from the default units associated with
+ the results's system, to the units used in the result.
+ ----------------------------------------------------------------------- */
+ map3 = astUnitMapper( DefUnit( rsys_out, "MakeFluxMapping", "FluxFrame", status ),
+ astGetUnit( result, 0 ), NULL, NULL );
+
+/* Indicate a match was found and combine all Mapings in series. */
+ if( map1 && map2 && map3 ) {
+ match = 1;
+ map4 = (AstMapping *) astCmpMap( map1, map2, 1, "", status );
+ map5 = (AstMapping *) astCmpMap( map4, map3, 1, "", status );
+
+/* Return the simplified Mapping. */
+ *map = astSimplify( map5 );
+
+/* Free resources. */
+ map4 = astAnnul( map4 );
+ map5 = astAnnul( map5 );
+ }
+
+/* Free resources. */
+ if( map1 ) map1 = astAnnul( map1 );
+ if( map2 ) map2 = astAnnul( map2 );
+ if( map3 ) map3 = astAnnul( map3 );
+
+/* If an error occurred, annul the returned Mapping and clear the returned
+ values. */
+ if ( !astOK ) {
+ *map = astAnnul( *map );
+ match = 0;
+ }
+
+/* Return the result. */
+ return match;
+}
+
+static int Match( AstFrame *template_frame, AstFrame *target, int matchsub,
+ int **template_axes, int **target_axes, AstMapping **map,
+ AstFrame **result, int *status ) {
+/*
+* Name:
+* Match
+
+* Purpose:
+* Determine if conversion is possible between two coordinate systems.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* int Match( AstFrame *template, AstFrame *target, int matchsub,
+* int **template_axes, int **target_axes,
+* AstMapping **map, AstFrame **result, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the protected astMatch method
+* inherited from the Frame class).
+
+* Description:
+* This function matches a "template" FluxFrame to a "target" Frame and
+* determines whether it is possible to convert coordinates between them.
+* If it is, a mapping that performs the transformation is returned along
+* with a new Frame that describes the coordinate system that results when
+* this mapping is applied to the "target" coordinate system. In addition,
+* information is returned to allow the axes in this "result" Frame to be
+* associated with the corresponding axes in the "target" and "template"
+* Frames from which they are derived.
+
+* Parameters:
+* template
+* Pointer to the template FluxFrame. This describes the coordinate
+* system (or set of possible coordinate systems) into which we wish to
+* convert our coordinates.
+* target
+* Pointer to the target Frame. This describes the coordinate system in
+* which we already have coordinates.
+* matchsub
+* If zero then a match only occurs if the template is of the same
+* class as the target, or of a more specialised class. If non-zero
+* then a match can occur even if this is not the case.
+* template_axes
+* Address of a location where a pointer to int will be returned if the
+* requested coordinate conversion is possible. This pointer will point
+* at a dynamically allocated array of integers with one element for each
+* axis of the "result" Frame (see below). It must be freed by the caller
+* (using astFree) when no longer required.
+*
+* For each axis in the result Frame, the corresponding element of this
+* array will return the index of the template FluxFrame axis from
+* which it is derived. If it is not derived from any template
+* FluxFrame axis, a value of -1 will be returned instead.
+* target_axes
+* Address of a location where a pointer to int will be returned if the
+* requested coordinate conversion is possible. This pointer will point
+* at a dynamically allocated array of integers with one element for each
+* axis of the "result" Frame (see below). It must be freed by the caller
+* (using astFree) when no longer required.
+*
+* For each axis in the result Frame, the corresponding element of this
+* array will return the index of the target Frame axis from which it
+* is derived. If it is not derived from any target Frame axis, a value
+* of -1 will be returned instead.
+* map
+* Address of a location where a pointer to a new Mapping will be
+* returned if the requested coordinate conversion is possible. If
+* returned, the forward transformation of this Mapping may be used to
+* convert coordinates between the "target" Frame and the "result"
+* Frame (see below) and the inverse transformation will convert in the
+* opposite direction.
+* result
+* Address of a location where a pointer to a new Frame will be returned
+* if the requested coordinate conversion is possible. If returned, this
+* Frame describes the coordinate system that results from applying the
+* returned Mapping (above) to the "target" coordinate system. In
+* general, this Frame will combine attributes from (and will therefore
+* be more specific than) both the target and the template Frames. In
+* particular, when the template allows the possibility of transformaing
+* to any one of a set of alternative coordinate systems, the "result"
+* Frame will indicate which of the alternatives was used.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* A non-zero value is returned if the requested coordinate conversion is
+* possible. Otherwise zero is returned (this will not in itself result in
+* an error condition).
+
+* Notes:
+* - A value of zero will be returned if this function is invoked with the
+* global error status set, or if it should fail for any reason.
+
+* Implementation Notes:
+* This implementation addresses the matching of a FluxFrame class
+* object to any other class of Frame. A FluxFrame will match any class
+* of FluxFrame (i.e. possibly from a derived class) but will not match
+* a less specialised class of Frame.
+*/
+
+/* Local Variables: */
+ AstFrame *frame0; /* Pointer to Frame underlying axis 0 */
+ AstFluxFrame *template; /* Pointer to template FluxFrame structure */
+ int iaxis0; /* Axis index underlying axis 0 */
+ int iaxis; /* Axis index */
+ int match; /* Coordinate conversion possible? */
+ int target_axis0; /* Index of FluxFrame axis in the target */
+ int target_naxes; /* Number of target axes */
+
+/* Initialise the returned values. */
+ *template_axes = NULL;
+ *target_axes = NULL;
+ *map = NULL;
+ *result = NULL;
+ match = 0;
+
+/* Check the global error status. */
+ if ( !astOK ) return match;
+
+/* Obtain a pointer to the template FluxFrame structure. */
+ template = (AstFluxFrame *) template_frame;
+
+/* Obtain the number of axes in the target Frame. */
+ target_naxes = astGetNaxes( target );
+
+/* The first criterion for a match is that the template matches as a
+ Frame class object. This ensures that the number of axes (1) and
+ domain, etc. of the target Frame are suitable. Invoke the parent
+ "astMatch" method to verify this. */
+ match = (*parent_match)( template_frame, target, matchsub,
+ template_axes, target_axes, map, result, status );
+
+/* If a match was found, annul the returned objects, which are not
+ needed, but keep the memory allocated for the axis association
+ arrays, which we will re-use. */
+ if ( astOK && match ) {
+ *map = astAnnul( *map );
+ *result = astAnnul( *result );
+ }
+
+/* If OK so far, obtain pointers to the primary Frames which underlie
+ all target axes. Stop when a FluxFrame axis is found. */
+ if ( match && astOK ) {
+ match = 0;
+ for( iaxis = 0; iaxis < target_naxes; iaxis++ ) {
+ astPrimaryFrame( target, iaxis, &frame0, &iaxis0 );
+ if( astIsAFluxFrame( frame0 ) ) {
+ frame0 = astAnnul( frame0 );
+ target_axis0 = iaxis;
+ match = 1;
+ break;
+ } else {
+ frame0 = astAnnul( frame0 );
+ }
+ }
+ }
+
+/* Check at least one FluxFrame axis was found it the target. Store the
+ axis associataions. */
+ if( match && astOK ) {
+ (*template_axes)[ 0 ] = 0;
+ (*target_axes)[ 0 ] = target_axis0;
+
+/* Use the target's "astSubFrame" method to create a new Frame (the
+ result Frame) with copies of the target axes in the required
+ order. This process also overlays the template attributes on to the
+ target Frame and returns a Mapping between the target and result
+ Frames which effects the required coordinate conversion. */
+ match = astSubFrame( target, template, 1, *target_axes, *template_axes,
+ map, result );
+ }
+
+/* If an error occurred, or conversion to the result Frame's
+ coordinate system was not possible, then free all memory, annul the
+ returned objects, and reset the returned value. */
+ if ( !astOK || !match ) {
+ *template_axes = astFree( *template_axes );
+ *target_axes = astFree( *target_axes );
+ if( *map ) *map = astAnnul( *map );
+ if( *result ) *result = astAnnul( *result );
+ match = 0;
+ }
+
+/* Return the result. */
+ return match;
+}
+
+static void Overlay( AstFrame *template, const int *template_axes,
+ AstFrame *result, int *status ) {
+/*
+* Name:
+* Overlay
+
+* Purpose:
+* Overlay the attributes of a template FluxFrame on to another Frame.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* void Overlay( AstFrame *template, const int *template_axes,
+* AstFrame *result, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the protected astOverlay method
+* inherited from the Frame class).
+
+* Description:
+* This function overlays attributes of a FluxFrame (the "template") on to
+* another Frame, so as to over-ride selected attributes of that second
+* Frame. Normally only those attributes which have been specifically set
+* in the template will be transferred. This implements a form of
+* defaulting, in which a Frame acquires attributes from the template, but
+* retains its original attributes (as the default) if new values have not
+* previously been explicitly set in the template.
+*
+* Note that if the result Frame is a FluxFrame and a change of flux
+* coordinate system occurs as a result of overlaying its System
+* attribute, then some of its original attribute values may no
+* longer be appropriate (e.g. the Title, or attributes describing
+* its axes). In this case, these will be cleared before overlaying
+* any new values.
+
+* Parameters:
+* template
+* Pointer to the template FluxFrame, for which values should have been
+* explicitly set for any attribute which is to be transferred.
+* template_axes
+* Pointer to an array of int, with one element for each axis of the
+* "result" Frame (see below). For each axis in the result frame, the
+* corresponding element of this array should contain the (zero-based)
+* index of the template axis to which it corresponds. This array is used
+* to establish from which template axis any axis-dependent attributes
+* should be obtained.
+*
+* If any axis in the result Frame is not associated with a template
+* axis, the corresponding element of this array should be set to -1.
+*
+* If a NULL pointer is supplied, the template and result axis
+* indices are assumed to be identical.
+* result
+* Pointer to the Frame which is to receive the new attribute values.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* void
+
+* Notes:
+* - In general, if the result Frame is not from the same class as the
+* template FluxFrame, or from a class derived from it, then attributes may
+* exist in the template FluxFrame which do not exist in the result Frame.
+* In this case, these attributes will not be transferred.
+*/
+
+
+/* Local Variables: */
+ AstFluxFrame *resff; /* Result FluxFrame */
+ AstFluxFrame *tmpff; /* Template FluxFrame */
+ AstSystemType new_alignsystem;/* Code identifying alignment coords */
+ AstSystemType new_system; /* Code identifying new cordinates */
+ AstSystemType old_system; /* Code identifying old coordinates */
+ const char *method; /* Pointer to method string */
+ const char *new_class; /* Pointer to template class string */
+ const char *old_class; /* Pointer to result class string */
+ int fluxframe; /* Result Frame is a FluxFrame? */
+ int resetSystem; /* Was the template System value cleared? */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Initialise strings used in error messages. */
+ new_class = astGetClass( template );
+ old_class = astGetClass( result );
+ method = "astOverlay";
+
+/* Get the old and new systems. */
+ old_system = astGetSystem( result );
+ new_system = astGetSystem( template );
+
+/* If the result Frame is a FluxFrame, we must test to see if overlaying its
+ System attribute will change the type of coordinate system it describes.
+ Determine the value of this attribute for the result and template
+ FluxFrames. */
+ resetSystem = 0;
+ fluxframe = astIsAFluxFrame( result );
+ if( fluxframe ) {
+
+/* If the coordinate system will change, any value already set for the result
+ FluxFrame's Title will no longer be appropriate, so clear it. */
+ if ( new_system != old_system ) {
+ astClearTitle( result );
+
+/* If the systems have the same default units, we can retain the current
+ Unit value. */
+ if( strcmp( DefUnit( new_system, method, new_class, status ),
+ DefUnit( old_system, method, old_class, status ) ) ) {
+ astClearUnit( result, 0 );
+ }
+
+/* If necessary, clear inappropriate values for all those axis attributes
+ whose access functions are over-ridden by this class (these access functions
+ will then provide suitable defaults appropriate to the new coordinate system
+ instead). */
+ astClearLabel( result, 0 );
+ astClearSymbol( result, 0 );
+ }
+
+/* Transfer the default SpecVal value and the SpecFrame. */
+ resff = (AstFluxFrame *) result;
+ tmpff = (AstFluxFrame *) template;
+ resff->defspecval = tmpff->defspecval;
+ if( resff->specframe ) (void) astAnnul( resff->specframe );
+ resff->specframe = tmpff->specframe ? astCopy( tmpff->specframe ) : NULL;
+
+/* If the result Frame is not a FluxFrame, we must temporarily clear the
+ System and AlignSystem values since the values used by this class are only
+ appropriate to this class. */
+ } else {
+ if( astTestSystem( template ) ) {
+ astClearSystem( template );
+
+ new_alignsystem = astGetAlignSystem( template );
+ astClearAlignSystem( template );
+
+ resetSystem = 1;
+ }
+ }
+
+/* Invoke the parent class astOverlay method to transfer attributes inherited
+ from the parent class. */
+ (*parent_overlay)( template, template_axes, result, status );
+
+/* Reset the System and AlignSystem values if necessary */
+ if( resetSystem ) {
+ astSetSystem( template, new_system );
+ astSetAlignSystem( template, new_alignsystem );
+ }
+
+/* Check if the result Frame is a FluxFrame or from a class derived from
+ FluxFrame. If not, we cannot transfer FluxFrame attributes to it as it is
+ insufficiently specialised. In this case simply omit these attributes. */
+ if ( fluxframe && astOK ) {
+
+/* Define macros that test whether an attribute is set in the template and,
+ if so, transfers its value to the result. */
+#define OVERLAY(attribute) \
+ if ( astTest##attribute( template ) ) { \
+ astSet##attribute( result, astGet##attribute( template ) ); \
+ }
+
+/* Use the macro to transfer each FluxFrame attribute in turn. */
+ OVERLAY(SpecVal)
+
+
+ }
+
+/* Undefine macros local to this function. */
+#undef OVERLAY
+}
+
+static void SetAttrib( AstObject *this_object, const char *setting, int *status ) {
+/*
+* Name:
+* SetAttrib
+
+* Purpose:
+* Set an attribute value for a FluxFrame.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* void SetAttrib( AstObject *this, const char *setting, int *status )
+
+* Class Membership:
+* FluxFrame member function (extends the astSetAttrib method inherited from
+* the Mapping class).
+
+* Description:
+* This function assigns an attribute value for a FluxFrame, the attribute
+* and its value being specified by means of a string of the form:
+*
+* "attribute= value "
+*
+* Here, "attribute" specifies the attribute name and should be in lower
+* case with no white space present. The value to the right of the "="
+* should be a suitable textual representation of the value to be assigned
+* and this will be interpreted according to the attribute's data type.
+* White space surrounding the value is only significant for string
+* attributes.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* setting
+* Pointer to a null terminated string specifying the new attribute
+* value.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* void
+
+* Notes:
+* This protected method is intended to be invoked by the Object astSet
+* method and makes additional attributes accessible to it.
+*/
+
+/* Local Vaiables: */
+ AstFluxFrame *this; /* Pointer to the FluxFrame structure */
+ double dval; /* Floating point attribute value */
+ int len; /* Length of setting string */
+ int nc; /* No. of characters read */
+ int ulen; /* Used length of setting string */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Obtain a pointer to the FluxFrame structure. */
+ this = (AstFluxFrame *) this_object;
+
+/* Obtain the length of the setting string. */
+ len = strlen( setting );
+
+/* Obtain the used length of the setting string. */
+ ulen = astChrLen( setting );
+
+/* Test for each recognised attribute in turn, using "astSscanf" to parse the
+ setting string and extract the attribute value (or an offset to it in the
+ case of string values). In each case, use the value set in "nc" to check
+ that the entire string was matched. Once a value has been obtained, use the
+ appropriate method to set it. */
+
+/* SpecVal. */
+/* -------- */
+ if ( nc = 0,
+ ( 1 == astSscanf( setting, "specval= %lg %n", &dval, &nc ) )
+ && ( nc >= len ) ) {
+ astSetSpecVal( this, dval );
+
+/* Pass any unrecognised setting to the parent method for further
+ interpretation. */
+ } else {
+ (*parent_setattrib)( this_object, setting, status );
+ }
+}
+
+static void SetSystem( AstFrame *this_frame, AstSystemType newsys, int *status ) {
+/*
+* Name:
+* SetSystem
+
+* Purpose:
+* Set the System attribute for a FluxFrame.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* void SetSystem( AstFrame *this_frame, AstSystemType newsys, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astSetSystem protected
+* method inherited from the Frame class).
+
+* Description:
+* This function sets the System attribute for a FluxFrame.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* newsys
+* The new System value to be stored.
+* status
+* Pointer to the inherited status variable.
+
+*/
+
+/* Local Variables: */
+ AstFluxFrame *this; /* Pointer to FluxFrame structure */
+ AstSystemType oldsys; /* Original System value */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Obtain a pointer to the FluxFrame structure. */
+ this = (AstFluxFrame *) this_frame;
+
+/* Save the original System value */
+ oldsys = astGetSystem( this_frame );
+
+/* Use the parent SetSystem method to store the new System value. */
+ (*parent_setsystem)( this_frame, newsys, status );
+
+/* If the system has changed... */
+ if( oldsys != newsys ) {
+
+/* Changing the System value will in general require the Units to change
+ as well. If the user has previously specified the units to be used with
+ the new system, then re-instate them (they are stored in the "usedunits"
+ array in the FluxFrame structure). Otherwise, clear the units so that
+ the default units will eb used with the new System. */
+ if( (int) newsys < this->nuunits && this->usedunits &&
+ this->usedunits[ (int) newsys ] ) {
+ (*parent_setunit)( this_frame, 0, this->usedunits[ (int) newsys ], status );
+ } else {
+ (*parent_clearunit)( this_frame, 0, status );
+ }
+
+/* Also, clear all attributes which have system-specific defaults. */
+ astClearLabel( this_frame, 0 );
+ astClearSymbol( this_frame, 0 );
+ astClearTitle( this_frame );
+ }
+}
+
+static void SetUnit( AstFrame *this_frame, int axis, const char *value, int *status ) {
+/*
+* Name:
+* SetUnit
+
+* Purpose:
+* Set a pointer to the Unit string for a FluxFrame's axis.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* void SetUnit( AstFrame *this_frame, int axis, const char *value )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astSetUnit method inherited
+* from the Frame class).
+
+* Description:
+* This function stores a pointer to the Unit string for a specified axis
+* of a FluxFrame. It also stores the string in the "usedunits" array
+* in the FluxFrame structure, in the element associated with the
+* current System.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* axis
+* The number of the axis (zero-based) for which information is required.
+* unit
+* The new string to store.
+*/
+
+/* Local Variables: */
+ AstFluxFrame *this; /* Pointer to the FluxFrame structure */
+ AstSystemType system; /* The FluxFrame's System value */
+ int i; /* Loop counter */
+ int isystem; /* The FluxFrame's System value */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Use the parent SetUnit method to store the value in the Axis
+ structure */
+ (*parent_setunit)( this_frame, axis, value, status );
+
+/* Obtain a pointer to the FluxFrame structure. */
+ this = (AstFluxFrame *) this_frame;
+
+/* Validate the axis index. */
+ astValidateAxis( this, axis, 1, "astSetUnit" );
+
+/* If the new units are appropriate for the current System, store the
+ supplied value as the UsedUnit for the current System. First ensure the
+ array is big enough. Free any previous value stored for the current
+ system. */
+ system = astGetSystem( this );
+ if( UnitsOK( system, value, 0, "astSetUnit", astGetClass( this ), status ) ) {
+ isystem = (int) astGetSystem( this );
+ if( isystem >= this->nuunits ) {
+ this->usedunits = astGrow( this->usedunits, isystem + 1,
+ sizeof(char *) );
+ if( astOK ) {
+ for( i = this->nuunits; i < isystem + 1; i++ ) this->usedunits[ i ] = NULL;
+ this->nuunits = isystem + 1;
+ }
+ }
+
+/* Now store a copy of the value, if it is different to the stored string. */
+ if( astOK && ( !this->usedunits[ isystem ] ||
+ strcmp( this->usedunits[ isystem ], value ) ) ) {
+ this->usedunits[ isystem ] = astStore( this->usedunits[ isystem ],
+ value, strlen( value ) + 1 );
+ }
+
+/* If the new units are not appropriate for the current System, clear the
+ System value. Use the parent ClearSystem function since the
+ astClearSystem implemented by this class will clear the units. */
+ } else {
+ (*parent_clearsystem)( this_frame, status );
+ }
+
+}
+
+static int SubFrame( AstFrame *target_frame, AstFrame *template,
+ int result_naxes, const int *target_axes,
+ const int *template_axes, AstMapping **map,
+ AstFrame **result, int *status ) {
+/*
+* Name:
+* SubFrame
+
+* Purpose:
+* Select axes from a FluxFrame and convert to the new coordinate
+* system.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* int SubFrame( AstFrame *target, AstFrame *template,
+* int result_naxes, const int *target_axes,
+* const int *template_axes, AstMapping **map,
+* AstFrame **result, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the protected astSubFrame
+* method inherited from the Frame class).
+
+* Description:
+* This function selects a requested sub-set (or super-set) of the axes
+* from a "target" FluxFrame and creates a new Frame with copies of
+* the selected axes assembled in the requested order. It then
+* optionally overlays the attributes of a "template" Frame on to the
+* result. It returns both the resulting Frame and a Mapping that
+* describes how to convert between the coordinate systems described by
+* the target and result Frames. If necessary, this Mapping takes
+* account of any differences in the Frames' attributes due to the
+* influence of the template.
+
+* Parameters:
+* target
+* Pointer to the target FluxFrame, from which axes are to be
+* selected.
+* template
+* Pointer to the template Frame, from which new attributes for the
+* result Frame are to be obtained. Optionally, this may be NULL, in
+* which case no overlaying of template attributes will be performed.
+* result_naxes
+* Number of axes to be selected from the target Frame. This number may
+* be greater than or less than the number of axes in this Frame (or
+* equal).
+* target_axes
+* Pointer to an array of int with result_naxes elements, giving a list
+* of the (zero-based) axis indices of the axes to be selected from the
+* target FluxFrame. The order in which these are given determines
+* the order in which the axes appear in the result Frame. If any of the
+* values in this array is set to -1, the corresponding result axis will
+* not be derived from the target Frame, but will be assigned default
+* attributes instead.
+* template_axes
+* Pointer to an array of int with result_naxes elements. This should
+* contain a list of the template axes (given as zero-based axis indices)
+* with which the axes of the result Frame are to be associated. This
+* array determines which axes are used when overlaying axis-dependent
+* attributes of the template on to the result. If any element of this
+* array is set to -1, the corresponding result axis will not receive any
+* template attributes.
+*
+* If the template argument is given as NULL, this array is not used and
+* a NULL pointer may also be supplied here.
+* map
+* Address of a location to receive a pointer to the returned Mapping.
+* The forward transformation of this Mapping will describe how to
+* convert coordinates from the coordinate system described by the target
+* FluxFrame to that described by the result Frame. The inverse
+* transformation will convert in the opposite direction.
+* result
+* Address of a location to receive a pointer to the result Frame.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* A non-zero value is returned if coordinate conversion is possible
+* between the target and the result Frame. Otherwise zero is returned and
+* *map and *result are returned as NULL (but this will not in itself
+* result in an error condition). In general, coordinate conversion should
+* always be possible if no template Frame is supplied but may not always
+* be possible otherwise.
+
+* Notes:
+* - A value of zero will be returned if this function is invoked with the
+* global error status set, or if it should fail for any reason.
+
+* Implementation Notes:
+* - This implementation addresses the selection of axes from a
+* FluxFrame object. This results in another object of the same class
+* only if the single FluxFrame axis is selected exactly once.
+* Otherwise, the result is a Frame class object which inherits the
+* FluxFrame's axis information (if appropriate) but none of the other
+* properties of a FluxFrame.
+* - In the event that a FluxFrame results, the returned Mapping will
+* take proper account of the relationship between the target and result
+* coordinate systems.
+* - In the event that a Frame class object results, the returned Mapping
+* will only represent a selection/permutation of axes.
+
+* Implementation Deficiencies:
+* - Any axis selection is currently permitted. Probably this should be
+* restricted so that each axis can only be selected once. The
+* astValidateAxisSelection method will do this but currently there are bugs
+* in the CmpFrame class that cause axis selections which will not pass this
+* test. Install the validation when these are fixed.
+*/
+
+/* Local Variables: */
+ AstFluxFrame *target; /* Pointer to the FluxFrame structure */
+ AstFluxFrame *temp; /* Pointer to copy of target FluxFrame */
+ AstSystemType align_sys; /* System in which to align the FluxFrames */
+ int match; /* Coordinate conversion is possible? */
+ int report; /* Report errors if FluxFrames cannot be aligned? */
+
+/* Initialise the returned values. */
+ *map = NULL;
+ *result = NULL;
+ match = 0;
+
+/* Check the global error status. */
+ if ( !astOK ) return match;
+
+/* Obtain a pointer to the target FluxFrame structure. */
+ target = (AstFluxFrame *) target_frame;
+
+/* Result is a FluxFrame. */
+/* -------------------------- */
+/* Check if the result Frame is to have one axis obtained by selecting
+ the single target FluxFrame axis. If so, the result will also be
+ a FluxFrame. */
+ if ( ( result_naxes == 1 ) && ( target_axes[ 0 ] == 0 ) ) {
+
+/* Form the result from a copy of the target. */
+ *result = astCopy( target );
+
+/* Initialise a flag to indicate that MakeFluxMapping should not report
+ errors if no Mapping can be created. */
+ report = 0;
+
+/* If required, overlay the template attributes on to the result FluxFrame.
+ Also get the system in which to align the two FluxFrames. These are the
+ values from the template (if there is a template). */
+ if ( template ) {
+ astOverlay( template, template_axes, *result );
+ if( astIsAFluxFrame( template ) ) {
+ align_sys = astGetAlignSystem( template );
+
+/* Since we now know that both the template and target are FluxFrames, it
+ should usually be possible to convert betwen them. If conversion is
+ *not* possible then the user will probably be interested in knowing the
+ reason why conversion is not possible. Therefore, indicate that
+ MakeFluxMapping should report errors if no Mapping can be created. */
+ report = 1;
+
+ } else {
+ align_sys = astGetAlignSystem( target );
+ }
+
+/* If no template was supplied, align in the System of the target. */
+ } else {
+ align_sys = astGetSystem( target );
+ }
+
+/* Generate a Mapping that takes account of changes in the coordinate system
+ between the target FluxFrame and the result FluxFrame. If this Mapping can
+ be generated, set "match" to indicate that coordinate conversion is
+ possible. If the template is a fluxframe, report errors if a match is not
+ possible. */
+ match = ( MakeFluxMapping( target, (AstFluxFrame *) *result,
+ align_sys, map, status ) != 0 );
+
+/* Result is not a FluxFrame. */
+/* ------------------------------ */
+/* In this case, we select axes as if the target were from the Frame
+ class. However, since the resulting data will then be separated
+ from their enclosing FluxFrame, default attribute values may differ
+ if the methods for obtaining them were over-ridden by the FluxFrame
+ class. To overcome this, we ensure that these values are explicitly
+ set for the result Frame (rather than relying on their defaults). */
+ } else {
+
+/* Make a temporary copy of the target FluxFrame. We will explicitly
+ set the attribute values in this copy so as not to modify the original. */
+ temp = astCopy( target );
+
+/* Define a macro to test if an attribute is set. If not, set it
+ explicitly to its default value. */
+#define SET(attribute) \
+ if ( !astTest##attribute( temp ) ) { \
+ astSet##attribute( temp, astGet##attribute( temp ) ); \
+ }
+
+/* Set attribute values which apply to the Frame as a whole and which
+ we want to retain, but whose defaults are over-ridden by the
+ FluxFrame class. */
+ SET(Domain)
+ SET(Title)
+
+/* Define a macro to test if an attribute is set for axis zero (the only
+ axis of a FluxFrame). If not, set it explicitly to its default value. */
+#define SET_AXIS(attribute) \
+ if ( !astTest##attribute( temp, 0 ) ) { \
+ astSet##attribute( temp, 0, \
+ astGet##attribute( temp, 0 ) ); \
+ }
+
+/* Use this macro to set explicit values for all the axis attributes
+ for which the FluxFrame class over-rides the default value. */
+ SET_AXIS(Label)
+ SET_AXIS(Symbol)
+ SET_AXIS(Unit)
+
+/* Clear attributes which have an extended range of values allowed by
+ this class. */
+ astClearSystem( temp );
+ astClearAlignSystem( temp );
+
+/* Invoke the astSubFrame method inherited from the Frame class to
+ produce the result Frame by selecting the required set of axes and
+ overlaying the template Frame's attributes. */
+ match = (*parent_subframe)( (AstFrame *) temp, template,
+ result_naxes, target_axes, template_axes,
+ map, result, status );
+
+/* Delete the temporary copy of the target FluxFrame. */
+ temp = astDelete( temp );
+ }
+
+/* If an error occurred or no match was found, annul the returned
+ objects and reset the returned result. */
+ if ( !astOK || !match ) {
+ if( *map ) *map = astAnnul( *map );
+ if( *result ) *result = astAnnul( *result );
+ match = 0;
+ }
+
+/* Return the result. */
+ return match;
+
+/* Undefine macros local to this function. */
+#undef SET
+#undef SET_AXIS
+}
+
+static AstSystemType SystemCode( AstFrame *this, const char *system, int *status ) {
+/*
+* Name:
+* SystemCode
+
+* Purpose:
+* Convert a string into a coordinate system type code.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* AstSystemType SystemCode( AstFrame *this, const char *system, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astSystemCode method
+* inherited from the Frame class).
+
+* Description:
+* This function converts a string used for the external
+* description of a coordinate system into a FluxFrame
+* coordinate system type code (System attribute value). It is the
+* inverse of the astSystemString function.
+
+* Parameters:
+* this
+* The Frame.
+* system
+* Pointer to a constant null-terminated string containing the
+* external description of the sky coordinate system.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* The System type code.
+
+* Notes:
+* - A value of AST__BADSYSTEM is returned if the sky coordinate
+* system description was not recognised. This does not produce an
+* error.
+* - A value of AST__BADSYSTEM is also returned if this function
+* is invoked with the global error status set or if it should fail
+* for any reason.
+*/
+
+/* Local Variables: */
+ AstSystemType result; /* Result value to return */
+
+/* Initialise. */
+ result = AST__BADSYSTEM;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Match the "system" string against each possibility and assign the
+ result. */
+ if ( astChrMatch( "FLXDN", system ) ) {
+ result = AST__FLUXDEN;
+
+ } else if ( astChrMatch( "FLXDNW", system ) ) {
+ result = AST__FLUXDENW;
+
+ }else if ( astChrMatch( "SFCBR", system ) ) {
+ result = AST__SBRIGHT;
+
+ } else if ( astChrMatch( "SRCBR", system ) ) {
+ result = AST__SBRIGHTW;
+
+ }
+
+/* Return the result. */
+ return result;
+}
+
+static const char *SystemLabel( AstSystemType system, int *status ) {
+/*
+* Name:
+* SystemLabel
+
+* Purpose:
+* Return a label for a coordinate system type code.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* const char *SystemLabel( AstSystemType system, int *status )
+
+* Class Membership:
+* FluxFrame member function.
+
+* Description:
+* This function converts a FluxFrame coordinate system type code
+* (System attribute value) into a descriptive string for human readers.
+
+* Parameters:
+* system
+* The coordinate system type code.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* Pointer to a constant null-terminated string containing the
+* textual equivalent of the type code supplied.
+
+* Notes:
+* - A NULL pointer value is returned if the sky coordinate system
+* code was not recognised. This does not produce an error.
+* - A NULL pointer value is also returned if this function is
+* invoked with the global error status set or if it should fail
+* for any reason.
+*/
+
+/* Local Variables: */
+ const char *result; /* Pointer value to return */
+
+/* Initialise. */
+ result = NULL;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Match the "system" value against each possibility and convert to a
+ string pointer. */
+ switch ( system ) {
+
+ case AST__FLUXDEN:
+ result = "flux density";
+ break;
+
+ case AST__FLUXDENW:
+ result = "flux wavelength density";
+ break;
+
+ case AST__SBRIGHT:
+ result = "surface brightness";
+ break;
+
+ case AST__SBRIGHTW:
+ result = "surface brightness (per wavelength)";
+ break;
+
+ }
+
+/* Return the result pointer. */
+ return result;
+}
+
+static const char *SystemString( AstFrame *this, AstSystemType system, int *status ) {
+/*
+* Name:
+* SystemString
+
+* Purpose:
+* Convert a coordinate system type code into a string.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* const char *SystemString( AstFrame *this, AstSystemType system, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astSystemString method
+* inherited from the Frame class).
+
+* Description:
+* This function converts a FluxFrame coordinate system type code
+* (System attribute value) into a string suitable for use as an
+* external representation of the coordinate system type.
+
+* Parameters:
+* this
+* The Frame.
+* system
+* The coordinate system type code.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* Pointer to a constant null-terminated string containing the
+* textual equivalent of the type code supplied.
+
+* Notes:
+* - A NULL pointer value is returned if the coordinate system
+* code was not recognised. This does not produce an error.
+* - A NULL pointer value is also returned if this function is
+* invoked with the global error status set or if it should fail
+* for any reason.
+*/
+
+ return FluxSystemString( system, status );
+}
+
+static int TestActiveUnit( AstFrame *this_frame, int *status ) {
+/*
+* Name:
+* TestActiveUnit
+
+* Purpose:
+* Test the ActiveUnit flag for a FluxFrame.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* int TestActiveUnit( AstFrame *this_frame, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astTestActiveUnit protected
+* method inherited from the Frame class).
+
+* Description:
+* This function test the value of the ActiveUnit flag for a FluxFrame,
+* which is always "unset".
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* The result of the test (0).
+
+*/
+ return 0;
+}
+
+static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) {
+/*
+* Name:
+* TestAttrib
+
+* Purpose:
+* Test if a specified attribute value is set for a FluxFrame.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* int TestAttrib( AstObject *this, const char *attrib, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astTestAttrib protected
+* method inherited from the Frame class).
+
+* Description:
+* This function returns a boolean result (0 or 1) to indicate whether
+* a value has been set for one of a FluxFrame's attributes.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame.
+* attrib
+* Pointer to a null terminated string specifying the attribute
+* name. This should be in lower case with no surrounding white
+* space.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* One if a value has been set, otherwise zero.
+
+* Notes:
+* - This function uses one-based axis numbering so that it is
+* suitable for external (public) use.
+* - A value of zero will be returned if this function is invoked
+* with the global status set, or if it should fail for any reason.
+*/
+
+/* Local Variables: */
+ AstFluxFrame *this; /* Pointer to the FluxFrame structure */
+ int len; /* Length of attrib string */
+ int result; /* Result value to return */
+
+/* Initialise. */
+ result = 0;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Obtain a pointer to the FluxFrame structure. */
+ this = (AstFluxFrame *) this_object;
+
+/* Obtain the length of the attrib string. */
+ len = strlen( attrib );
+
+/* Check the attribute name and test the appropriate attribute. */
+
+/* SpecVal. */
+/* -------- */
+ if ( !strcmp( attrib, "specval" ) ) {
+ result = astTestSpecVal( this );
+
+/* If the attribute is not recognised, pass it on to the parent method
+ for further interpretation. */
+ } else {
+ result = (*parent_testattrib)( this_object, attrib, status );
+ }
+
+/* Return the result, */
+ return result;
+}
+
+static int UnitsOK( AstSystemType system, const char *units, int report,
+ const char *method, const char *class, int *status ) {
+/*
+* Name:
+* UnitsOK
+
+* Purpose:
+* Check if a units string is appropriate for the current System.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* int UnitsOK( AstSystemType system, const char *units, int report,
+* const char *method, const char *class, int *status )
+
+* Class Membership:
+* FluxFrame member function
+
+* Description:
+* This function returns a non-zero value if the supplied units string
+* can be mapped to the defaultunits for the current System in the
+* supplied FluxFrame.
+
+* Parameters:
+* system
+* The system type to check.
+* unit
+* The units string to check.
+* report
+* Should an error be reported if the units and system are
+* inconsistent?
+* method
+* String holding a method name to be used in error messages.
+* class
+* String holding a class name to be used in error messages.
+* status
+* Pointer to the inherited status variable.
+
+* Returns Value:
+* Non-zero if the units string can be used to describe the current
+* flux System. Zero otherwise.
+
+*/
+
+/* Local Variables: */
+ AstMapping *map;
+ int result;
+
+/* Check the global error status. */
+ if ( !astOK ) return 0;
+
+/* Get the Mapping from the default units for the supplied system to the
+ supplied Units. */
+ map = astUnitMapper( DefUnit( system, method, class, status ), units, NULL, NULL );
+
+/* If a Mapping was found succesfully, annul it and return non-zero.
+ Otherwise return zero. */
+ if( map ) {
+ result = 1;
+ map = astAnnul( map );
+
+ } else {
+ result = 0;
+
+/* Report an error if required. */
+ if( report && astOK ) {
+ astError( AST__BADUN, "%s(%s): The units (%s) and system (%s) "
+ "within the supplied %s are inconsistent.", status, method,
+ class, units, FluxSystemString( system, status ), class );
+ }
+ }
+
+/* Return the result. */
+ return result;
+}
+
+static int ValidateSystem( AstFrame *this, AstSystemType system, const char *method, int *status ) {
+/*
+*
+* Name:
+* ValidateSystem
+
+* Purpose:
+* Validate a value for a Frame's System attribute.
+
+* Type:
+* Protected virtual function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* int ValidateSystem( AstFrame *this, AstSystemType system,
+* const char *method, int *status )
+
+* Class Membership:
+* FluxFrame member function (over-rides the astValidateSystem method
+* inherited from the Frame class).
+
+* Description:
+* This function checks the validity of the supplied system value.
+* If the value is valid, it is returned unchanged. Otherwise, an
+* error is reported and a value of AST__BADSYSTEM is returned.
+
+* Parameters:
+* this
+* Pointer to the Frame.
+* system
+* The system value to be checked.
+* method
+* Pointer to a constant null-terminated character string
+* containing the name of the method that invoked this function
+* to validate an axis index. This method name is used solely
+* for constructing error messages.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* The validated system value.
+
+* Notes:
+* - A value of AST__BADSYSTEM will be returned if this function is invoked
+* with the global error status set, or if it should fail for any
+* reason.
+*/
+
+/* Local Variables: */
+ AstSystemType result; /* Validated system value */
+
+/* Initialise. */
+ result = AST__BADSYSTEM;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* If the value is out of bounds, report an error. */
+ if ( system < FIRST_SYSTEM || system > LAST_SYSTEM ) {
+ astError( AST__AXIIN, "%s(%s): Bad value (%d) given for the System "
+ "or AlignSystem attribute of a %s.", status, method,
+ astGetClass( this ), (int) system, astGetClass( this ) );
+
+/* Otherwise, return the supplied value. */
+ } else {
+ result = system;
+ }
+
+/* Return the result. */
+ return result;
+}
+
+/* Functions which access class attributes. */
+/* ---------------------------------------- */
+/*
+*att++
+* Name:
+* SpecVal
+
+* Purpose:
+* The spectral position at which flux values are measured.
+
+* Type:
+* Public attribute.
+
+* Synopsis:
+* Floating point.
+
+* Description:
+* This attribute specifies the spectral position (frequency, wavelength,
+* etc.), at which the values described by the FluxFrame are measured.
+* It is used when determining the Mapping between between FluxFrames.
+*
+* The default value and spectral system used for this attribute are
+* both specified when the FluxFrame is created.
+
+* Applicability:
+* FluxFrame
+* All FluxFrames have this attribute.
+
+*att--
+*/
+astMAKE_CLEAR(FluxFrame,SpecVal,specval,AST__BAD)
+astMAKE_GET(FluxFrame,SpecVal,double,AST__BAD,((this->specval!=AST__BAD)?this->specval:this->defspecval))
+astMAKE_SET(FluxFrame,SpecVal,double,specval,value)
+astMAKE_TEST(FluxFrame,SpecVal,( this->specval != AST__BAD ))
+
+/* Copy constructor. */
+/* ----------------- */
+static void Copy( const AstObject *objin, AstObject *objout, int *status ) {
+/*
+* Name:
+* Copy
+
+* Purpose:
+* Copy constructor for FluxFrame objects.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* void Copy( const AstObject *objin, AstObject *objout, int *status )
+
+* Description:
+* This function implements the copy constructor for FluxFrame objects.
+
+* Parameters:
+* objin
+* Pointer to the object to be copied.
+* objout
+* Pointer to the object being constructed.
+* status
+* Pointer to the inherited status variable.
+
+* Notes:
+* - This constructor makes a deep copy.
+*/
+
+/* Local Variables: */
+ AstFluxFrame *in; /* Pointer to input FluxFrame */
+ AstFluxFrame *out; /* Pointer to output FluxFrame */
+ char *usedunit; /* Pointer to an element of usedunits array */
+ int i; /* Loop count */
+ int nused; /* Size of "usedunits" array */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Obtain pointers to the input and output FluxFrames. */
+ in = (AstFluxFrame *) objin;
+ out = (AstFluxFrame *) objout;
+
+/* Nullify the pointers stored in the output object since these will
+ currently be pointing at the input data (since the output is a simple
+ byte-for-byte copy of the input). Otherwise, the input data could be
+ freed by accidient if the output object is deleted due to an error
+ occuring in this function. */
+ out->usedunits = NULL;
+ out->specframe = NULL;
+
+/* Store the last used units in the output SpecMap. */
+ if( in && in->usedunits ) {
+ nused = in->nuunits;
+ out->usedunits = astMalloc( nused*sizeof( char * ) );
+ if( out->usedunits ) {
+ for( i = 0; i < nused; i++ ) {
+ usedunit = in->usedunits[ i ];
+ if( usedunit ) {
+ out->usedunits[ i ] = astStore( NULL, usedunit,
+ strlen( usedunit ) + 1 );
+ } else {
+ out->usedunits[ i ] = NULL;
+ }
+ }
+ }
+ }
+
+/* Copy the SpecFrame */
+ if( in->specframe ) out->specframe = astCopy( in->specframe );
+
+/* If an error has occurred, free the output resources. */
+ if( !astOK ) Delete( (AstObject *) out, status );
+
+}
+
+/* Destructor. */
+/* ----------- */
+static void Delete( AstObject *obj, int *status ) {
+/*
+* Name:
+* Delete
+
+* Purpose:
+* Destructor for FluxFrame objects.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* void Delete( AstObject *obj, int *status )
+
+* Description:
+* This function implements the destructor for FluxFrame objects.
+
+* Parameters:
+* obj
+* Pointer to the object to be deleted.
+* status
+* Pointer to the inherited status variable.
+
+* Notes:
+* This function attempts to execute even if the global error status is
+* set.
+*/
+
+/* Local Variables: */
+ AstFluxFrame *this;
+ int i;
+
+/* Release the memory referred to in the FluxFrame structure. */
+ this = (AstFluxFrame *) obj;
+ if( this && this->usedunits ) {
+ for( i = 0; i < this->nuunits; i++ ) {
+ this->usedunits[ i ] = astFree( this->usedunits[ i ] );
+ }
+ this->usedunits = astFree( this->usedunits );
+ }
+
+/* Annulthe SpecFrame. */
+ if( this->specframe ) this->specframe = astAnnul( this->specframe );
+
+}
+
+/* Dump function. */
+/* -------------- */
+static void Dump( AstObject *this_object, AstChannel *channel, int *status ) {
+/*
+* Name:
+* Dump
+
+* Purpose:
+* Dump function for FluxFrame objects.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* void Dump( AstObject *this, AstChannel *channel, int *status )
+
+* Description:
+* This function implements the Dump function which writes out data
+* for the FluxFrame class to an output Channel.
+
+* Parameters:
+* this
+* Pointer to the FluxFrame whose data are being written.
+* channel
+* Pointer to the Channel to which the data are being written.
+* status
+* Pointer to the inherited status variable.
+*/
+
+/* Local Variables: */
+ AstFluxFrame *this; /* Pointer to the FluxFrame structure */
+ char buff[ 20 ]; /* Buffer for item name */
+ char comm[ 50 ]; /* Buffer for comment */
+ double dval; /* Double value */
+ int i; /* Loop count */
+ int j; /* Loop count */
+ int set; /* Attribute value set? */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Obtain a pointer to the FluxFrame structure. */
+ this = (AstFluxFrame *) this_object;
+
+/* Write out values representing the instance variables for the
+ FluxFrame class. Accompany these with appropriate comment strings,
+ possibly depending on the values being written.*/
+
+/* In the case of attributes, we first use the appropriate (private)
+ Test... member function to see if they are set. If so, we then use
+ the (private) Get... function to obtain the value to be written
+ out.
+
+ For attributes which are not set, we use the astGet... method to
+ obtain the value instead. This will supply a default value
+ (possibly provided by a derived class which over-rides this method)
+ which is more useful to a human reader as it corresponds to the
+ actual default attribute value. Since "set" will be zero, these
+ values are for information only and will not be read back. */
+
+/* SpecVal. */
+/* -------- */
+ set = TestSpecVal( this, status );
+ dval = set ? GetSpecVal( this, status ) : astGetSpecVal( this );
+ if( dval != AST__BAD ) {
+ astWriteDouble( channel, "SpcVl", set, 0, dval, "Spectral position" );
+ }
+
+/* The SpecFrame */
+/* ------------- */
+ if( this->specframe ) {
+ astWriteObject( channel, "SpcFr", 1, 0, this->specframe, "SpcVl coord system" );
+ }
+
+/* Default SpecVal. */
+/* ---------------- */
+ if( this->defspecval != AST__BAD ) {
+ astWriteDouble( channel, "DfSpc", 1, 0, this->defspecval, "Default spectral position" );
+ }
+
+/* UsedUnits */
+/* --------- */
+ if( this->usedunits ) {
+ for( i = 0; i < this->nuunits; i++ ) {
+ if( this->usedunits[ i ] ) {
+ sprintf( buff, "U%s", astSystemString( this, (AstSystemType) i ));
+ for( j = 2; j < strlen( buff ); j++ ) buff[ j ] = tolower( buff[ j ] );
+ sprintf( comm, "Preferred units for %s", SystemLabel( (AstSystemType) i, status ) );
+ astWriteString( channel, buff, 1, 0, this->usedunits[ i ], comm );
+ }
+ }
+ }
+}
+
+/* Standard class functions. */
+/* ========================= */
+/* Implement the astIsAFluxFrame and astCheckFluxFrame functions using the
+ macros defined for this purpose in the "object.h" header file. */
+astMAKE_ISA(FluxFrame,Frame)
+astMAKE_CHECK(FluxFrame)
+
+AstFluxFrame *astFluxFrame_( double specval, void *specfrm_void,
+ const char *options, int *status, ...) {
+/*
+*+
+* Name:
+* astFluxFrame
+
+* Purpose:
+* Create a FluxFrame.
+
+* Type:
+* Protected function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* AstFluxFrame *astFluxFrame( double specval, AstSpecFrame *specfrm,
+* const char *options, ..., int *status )
+
+* Class Membership:
+* FluxFrame constructor.
+
+* Description:
+* This function creates a new FluxFrame and optionally initialises its
+* attributes.
+
+* Parameters:
+* specval
+* The spectral value to which the flux values refer, given in the
+* spectral coordinate system specified by "specfrm". The value
+* supplied for the "specval" parameter becomes the default value for
+* the SpecVal attribute.
+* specfrm
+* A pointer to a SpecFrame describing the spectral coordinate system
+* in which the "specval" parameter is given. A deep copy of this object
+* is taken, so any subsequent changes to the SpecFrame using the
+* supplied pointer will have no effect on the new FluxFrame.
+* options
+* Pointer to a null terminated string containing an optional
+* comma-separated list of attribute assignments to be used for
+* initialising the new FluxFrame. The syntax used is the same as for the
+* astSet method and may include "printf" format specifiers identified
+* by "%" symbols in the normal way.
+* status
+* Pointer to the inherited status variable.
+* ...
+* If the "options" string contains "%" format specifiers, then an
+* optional list of arguments may follow it in order to supply values to
+* be substituted for these specifiers. The rules for supplying these
+* are identical to those for the astSet method (and for the C "printf"
+* function).
+
+* Returned Value:
+* A pointer to the new FluxFrame.
+
+* Notes:
+* - A NULL pointer will be returned if this function is invoked with the
+* global error status set, or if it should fail for any reason.
+*-
+
+* Implementation Notes:
+* - This function implements the basic FluxFrame constructor which
+* is available via the protected interface to the FluxFrame class.
+* A public interface is provided by the astFluxFrameId_ function.
+*/
+
+/* Local Variables: */
+ astDECLARE_GLOBALS /* Pointer to thread-specific global data */
+ AstMapping *um; /* Mapping from default to actual units */
+ AstFluxFrame *new; /* Pointer to new FluxFrame */
+ AstSpecFrame *sfrm; /* Pointer to SpecFrame */
+ AstSystemType s; /* System */
+ const char *u; /* Units string */
+ va_list args; /* Variable argument list */
+
+/* Get a pointer to the thread specific global data structure. */
+ astGET_GLOBALS(NULL);
+
+/* Check the global status. */
+ if ( !astOK ) return NULL;
+
+/* Obtain and validate a pointer to the SpecFrame structures provided. */
+ sfrm = specfrm_void ? astCheckSpecFrame( specfrm_void ) : NULL;
+
+/* Initialise the FluxFrame, allocating memory and initialising the virtual
+ function table as well if necessary. */
+ new = astInitFluxFrame( NULL, sizeof( AstFluxFrame ), !class_init,
+ &class_vtab, "FluxFrame", specval, sfrm );
+
+/* If successful, note that the virtual function table has been initialised. */
+ if ( astOK ) {
+ class_init = 1;
+
+/* Obtain the variable argument list and pass it along with the options string
+ to the astVSet method to initialise the new FluxFrame's attributes. */
+ va_start( args, status );
+ astVSet( new, options, NULL, args );
+ va_end( args );
+
+/* Check the Units are appropriate for the System. */
+ u = astGetUnit( new, 0 );
+ s = astGetSystem( new );
+ um = astUnitMapper( DefUnit( s, "astFluxFrame", "FluxFrame", status ),
+ u, NULL, NULL );
+ if( um ) {
+ um = astAnnul( um );
+ } else {
+ astError( AST__BADUN, "astFluxFrame: Inappropriate units (%s) "
+ "specified for a %s axis.", status, u, SystemLabel( s, status ) );
+ }
+
+/* If an error occurred, clean up by deleting the new object. */
+ if ( !astOK ) new = astDelete( new );
+ }
+
+/* Return a pointer to the new FluxFrame. */
+ return new;
+}
+
+AstFluxFrame *astInitFluxFrame_( void *mem, size_t size, int init,
+ AstFluxFrameVtab *vtab, const char *name,
+ double specval, AstSpecFrame *specfrm, int *status ) {
+/*
+*+
+* Name:
+* astInitFluxFrame
+
+* Purpose:
+* Initialise a FluxFrame.
+
+* Type:
+* Protected function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* AstFluxFrame *astInitFluxFrame( void *mem, size_t size, int init,
+* AstFrameVtab *vtab, const char *name,
+* double specval, AstSpecFrame *specfrm)
+
+* Class Membership:
+* FluxFrame initialiser.
+
+* Description:
+* This function is provided for use by class implementations to
+* initialise a new FluxFrame object. It allocates memory (if
+* necessary) to accommodate the FluxFrame plus any additional data
+* associated with the derived class. It then initialises a
+* FluxFrame structure at the start of this memory. If the "init"
+* flag is set, it also initialises the contents of a virtual function
+* table for a FluxFrame at the start of the memory passed via the
+* "vtab" parameter.
+
+* Parameters:
+* mem
+* A pointer to the memory in which the FluxFrame is to be
+* created. This must be of sufficient size to accommodate the
+* FluxFrame data (sizeof(FluxFrame)) plus any data used by
+* the derived class. If a value of NULL is given, this function
+* will allocate the memory itself using the "size" parameter to
+* determine its size.
+* size
+* The amount of memory used by the FluxFrame (plus derived
+* class data). This will be used to allocate memory if a value of
+* NULL is given for the "mem" parameter. This value is also stored
+* in the FluxFrame structure, so a valid value must be supplied
+* even if not required for allocating memory.
+* init
+* A logical flag indicating if the FluxFrame's virtual function
+* table is to be initialised. If this value is non-zero, the
+* virtual function table will be initialised by this function.
+* vtab
+* Pointer to the start of the virtual function table to be
+* associated with the new FluxFrame.
+* name
+* Pointer to a constant null-terminated character string which
+* contains the name of the class to which the new object belongs
+* (it is this pointer value that will subsequently be returned by
+* the astGetClass method).
+* specval
+* The spectral value to which the flux values refer, given in the
+* spectral coordinate system specified by "specfrm". The value
+* supplied for the "specval" parameter becomes the default value for
+* the SpecVal attribute. May be AST__BAD.
+* specfrm
+* A pointer to a SpecFrame describing the spectral coordinate system
+* in which the "specval" parameter is given. A deep copy of this object
+* is taken, so any subsequent changes to the SpecFrame using the
+* supplied pointer will have no effect on the new FluxFrame. Should
+* be NULL if "specval" is AST__BAD.
+
+* Returned Value:
+* A pointer to the new FluxFrame.
+
+* Notes:
+* - A null pointer will be returned if this function is invoked with the
+* global error status set, or if it should fail for any reason.
+*-
+*/
+
+/* Local Variables: */
+ AstFluxFrame *new; /* Pointer to the new FluxFrame */
+
+/* Check the global status. */
+ if ( !astOK ) return NULL;
+
+/* If necessary, initialise the virtual function table. */
+ if ( init ) astInitFluxFrameVtab( vtab, name );
+
+/* Initialise a 1D Frame structure (the parent class) as the first component
+ within the FluxFrame structure, allocating memory if necessary. */
+ new = (AstFluxFrame *) astInitFrame( mem, size, 0,
+ (AstFrameVtab *) vtab, name, 1 );
+
+ if ( astOK ) {
+
+/* Initialise the FluxFrame data. */
+/* ----------------------------- */
+/* Initialise all attributes to their "undefined" values. */
+ new->specval = AST__BAD;
+ new->defspecval = specval;
+ new->specframe = specfrm ? astCopy( specfrm ) : NULL;
+ new->nuunits = 0;
+ new->usedunits = NULL;
+
+/* If an error occurred, clean up by deleting the new object. */
+ if ( !astOK ) new = astDelete( new );
+
+ }
+
+/* Return a pointer to the new object. */
+ return new;
+}
+
+AstFluxFrame *astLoadFluxFrame_( void *mem, size_t size, AstFluxFrameVtab *vtab,
+ const char *name, AstChannel *channel, int *status ) {
+/*
+*+
+* Name:
+* astLoadFluxFrame
+
+* Purpose:
+* Load a FluxFrame.
+
+* Type:
+* Protected function.
+
+* Synopsis:
+* #include "fluxframe.h"
+* AstFluxFrame *astLoadFluxFrame( void *mem, size_t size, AstFluxFrameVtab *vtab,
+* const char *name, AstChannel *channel )
+
+* Class Membership:
+* FluxFrame loader.
+
+* Description:
+* This function is provided to load a new FluxFrame using data read
+* from a Channel. It first loads the data used by the parent class
+* (which allocates memory if necessary) and then initialises a
+* FluxFrame structure in this memory, using data read from the
+* input Channel.
+
+* Parameters:
+* mem
+* A pointer to the memory into which the FluxFrame is to be
+* loaded. This must be of sufficient size to accommodate the
+* FluxFrame data (sizeof(FluxFrame)) plus any data used by
+* derived classes. If a value of NULL is given, this function
+* will allocate the memory itself using the "size" parameter to
+* determine its size.
+* size
+* The amount of memory used by the FluxFrame (plus derived class
+* data). This will be used to allocate memory if a value of
+* NULL is given for the "mem" parameter. This value is also
+* stored in the FluxFrame structure, so a valid value must be
+* supplied even if not required for allocating memory.
+*
+* If the "vtab" parameter is NULL, the "size" value is ignored
+* and sizeof(AstFluxFrame) is used instead.
+* vtab
+* Pointer to the start of the virtual function table to be
+* associated with the new FluxFrame. If this is NULL, a pointer
+* to the (static) virtual function table for the FluxFrame class
+* is used instead.
+* name
+* Pointer to a constant null-terminated character string which
+* contains the name of the class to which the new object
+* belongs (it is this pointer value that will subsequently be
+* returned by the astGetClass method).
+*
+* If the "vtab" parameter is NULL, the "name" value is ignored
+* and a pointer to the string "FluxFrame" is used instead.
+
+* Returned Value:
+* A pointer to the new FluxFrame.
+
+* Notes:
+* - A null pointer will be returned if this function is invoked
+* with the global error status set, or if it should fail for any
+* reason.
+*-
+*/
+
+/* Local Variables: */
+ astDECLARE_GLOBALS /* Pointer to thread-specific global data */
+ AstFluxFrame *new; /* Pointer to the new FluxFrame */
+ char buff[ 20 ]; /* Buffer for item name */
+ char *sval; /* Pointer to string value */
+ int i; /* Loop count */
+ int j; /* Get a pointer to the thread specific global data structure. */
+
+/* Loop count */
+ int sys; /* System value */
+
+ astGET_GLOBALS(channel);
+
+/* Initialise. */
+ new = NULL;
+
+/* Check the global error status. */
+ if ( !astOK ) return new;
+
+/* If a NULL virtual function table has been supplied, then this is
+ the first loader to be invoked for this FluxFrame. In this case the
+ FluxFrame belongs to this class, so supply appropriate values to be
+ passed to the parent class loader (and its parent, etc.). */
+ if ( !vtab ) {
+ size = sizeof( AstFluxFrame );
+ vtab = &class_vtab;
+ name = "FluxFrame";
+
+/* If required, initialise the virtual function table for this class. */
+ if ( !class_init ) {
+ astInitFluxFrameVtab( vtab, name );
+ class_init = 1;
+ }
+ }
+
+/* Invoke the parent class loader to load data for all the ancestral
+ classes of the current one, returning a pointer to the resulting
+ partly-built FluxFrame. */
+ new = astLoadFrame( mem, size, (AstFrameVtab *) vtab, name,
+ channel );
+ if ( astOK ) {
+
+/* Read input data. */
+/* ================ */
+/* Request the input Channel to read all the input data appropriate to
+ this class into the internal "values list". */
+ astReadClassData( channel, "FluxFrame" );
+
+/* Now read each individual data item from this list and use it to
+ initialise the appropriate instance variable(s) for this class. */
+
+/* In the case of attributes, we first read the "raw" input value,
+ supplying the "unset" value as the default. If a "set" value is
+ obtained, we then use the appropriate (private) Set... member
+ function to validate and set the value properly. */
+
+/* Default SpecVal */
+/* --------------- */
+ new->defspecval = astReadDouble( channel, "dfspc", AST__BAD );
+
+/* SpecFrame */
+/* ---------- */
+ new->specframe = astReadObject( channel, "spcfr", NULL );
+
+/* SpecVal */
+/* ------- */
+ new->specval = astReadDouble( channel, "spcvl", AST__BAD );
+ if ( TestSpecVal( new, status ) ) SetSpecVal( new, new->specval, status );
+
+/* UsedUnits */
+/* --------- */
+ new->nuunits = 0;
+ new->usedunits = NULL;
+ for( sys = FIRST_SYSTEM; sys <= LAST_SYSTEM; sys++ ) {
+ sprintf( buff, "u%s", astSystemString( new, (AstSystemType) sys ));
+ for( j = 0; j < strlen( buff ); j++ ) buff[ j ] = tolower( buff[ j ] );
+ sval = astReadString( channel, buff, NULL );
+ if( sval ) {
+ if( (int) sys >= new->nuunits ) {
+ new->usedunits = astGrow( new->usedunits, sys + 1,
+ sizeof(char *) );
+ if( astOK ) {
+ for( i = new->nuunits; i < sys + 1; i++ ) new->usedunits[ i ] = NULL;
+ new->nuunits = sys + 1;
+ }
+ } else {
+ new->usedunits[ sys ] = astFree( new->usedunits[ sys ] );
+ }
+ if( astOK ) {
+ new->usedunits[ sys ] = astStore( new->usedunits[ sys ],
+ sval, strlen( sval ) + 1 );
+ }
+ sval = astFree( sval );
+ }
+ }
+
+/* If an error occurred, clean up by deleting the new FluxFrame. */
+ if ( !astOK ) new = astDelete( new );
+ }
+
+/* Return the new FluxFrame pointer. */
+ return new;
+}
+
+/* Virtual function interfaces. */
+/* ============================ */
+/* These provide the external interface to the virtual functions defined by
+ this class. Each simply checks the global error status and then locates and
+ executes the appropriate member function, using the function pointer stored
+ in the object's virtual function table (this pointer is located using the
+ astMEMBER macro defined in "object.h").
+
+ Note that the member function may not be the one defined here, as it may
+ have been over-ridden by a derived class. However, it should still have the
+ same interface. */
+
+AstSystemType astGetDensitySystem_( AstFluxFrame *this, int *status ){
+ if ( !astOK ) return AST__BADSYSTEM;
+ return (**astMEMBER(this,FluxFrame,GetDensitySystem))(this, status );
+}
+
+const char *astGetDensityUnit_( AstFluxFrame *this, int *status ){
+ if ( !astOK ) return NULL;
+ return (**astMEMBER(this,FluxFrame,GetDensityUnit))(this, status );
+}
+
+
+/* Special public interface functions. */
+/* =================================== */
+/* These provide the public interface to certain special functions
+ whose public interface cannot be handled using macros (such as
+ astINVOKE) alone. In general, they are named after the
+ corresponding protected version of the function, but with "Id"
+ appended to the name. */
+
+/* Public Interface Function Prototypes. */
+/* ------------------------------------- */
+/* The following functions have public prototypes only (i.e. no
+ protected prototypes), so we must provide local prototypes for use
+ within this module. */
+AstFluxFrame *astFluxFrameId_( double, void *, const char *, ... );
+
+/* Special interface function implementations. */
+/* ------------------------------------------- */
+AstFluxFrame *astFluxFrameId_( double specval, void *specfrm_void,
+ const char *options, ... ) {
+/*
+*++
+* Name:
+c astFluxFrame
+f AST_FLUXFRAME
+
+* Purpose:
+* Create a FluxFrame.
+
+* Type:
+* Public function.
+
+* Synopsis:
+c #include "fluxframe.h"
+c AstFluxFrame *astFluxFrame( double specval, AstSpecFrame *specfrm,
+c const char *options, ... )
+f RESULT = AST_FLUXFRAME( SPECVAL, SPECFRM, OPTIONS, STATUS )
+
+* Class Membership:
+* FluxFrame constructor.
+
+* Description:
+* This function creates a new FluxFrame and optionally initialises
+* its attributes.
+*
+* A FluxFrame is a specialised form of one-dimensional Frame which
+* represents various systems used to represent the signal level in an
+* observation. The particular coordinate system to be used is specified
+* by setting the FluxFrame's System attribute qualified, as necessary, by
+* other attributes such as the units, etc (see the description of the
+* System attribute for details).
+*
+* All flux values are assumed to be measured at the same frequency or
+* wavelength (as given by the SpecVal attribute). Thus this class is
+* more appropriate for use with images rather than spectra.
+
+* Parameters:
+c specval
+f SPECVAL = DOUBLE PRECISION (Given)
+* The spectral value to which the flux values refer, given in the
+* spectral coordinate system specified by
+c "specfrm". The value supplied for the "specval"
+f SPECFRM. The value supplied for the SPECVAL
+* parameter becomes the default value for the SpecVal attribute.
+* A value of AST__BAD may be supplied if the spectral position is
+* unknown, but this may result in it not being possible for the
+c astConvert
+f AST_CONVERT
+* function to determine a Mapping between the new FluxFrame and
+* some other FluxFrame.
+c specfrm
+f SPECFRM = INTEGER (Given)
+* A pointer to a SpecFrame describing the spectral coordinate system
+* in which the
+c "specval"
+f SPECVAL
+* parameter is given. A deep copy of this object is taken, so any
+* subsequent changes to the SpecFrame using the supplied pointer will
+* have no effect on the new FluxFrame.
+c A NULL pointer can be supplied if AST__BAD is supplied for "specval".
+f AST__NULL can be supplied if AST__BAD is supplied for SPECVAL.
+c options
+f OPTIONS = CHARACTER * ( * ) (Given)
+c Pointer to a null-terminated string containing an optional
+c comma-separated list of attribute assignments to be used for
+c initialising the new FluxFrame. The syntax used is identical to
+c that for the astSet function and may include "printf" format
+c specifiers identified by "%" symbols in the normal way.
+c If no initialisation is required, a zero-length string may be
+c supplied.
+f A character string containing an optional comma-separated
+f list of attribute assignments to be used for initialising the
+f new FluxFrame. The syntax used is identical to that for the
+f AST_SET routine. If no initialisation is required, a blank
+f value may be supplied.
+c ...
+c If the "options" string contains "%" format specifiers, then
+c an optional list of additional arguments may follow it in
+c order to supply values to be substituted for these
+c specifiers. The rules for supplying these are identical to
+c those for the astSet function (and for the C "printf"
+c function).
+f STATUS = INTEGER (Given and Returned)
+f The global status.
+
+* Returned Value:
+c astFluxFrame()
+f AST_FLUXFRAME = INTEGER
+* A pointer to the new FluxFrame.
+
+* Notes:
+* - When conversion between two FluxFrames is requested (as when
+c supplying FluxFrames to astConvert),
+f supplying FluxFrames AST_CONVERT),
+* account will be taken of the nature of the flux coordinate systems
+* they represent, together with any qualifying attribute values, including
+* the AlignSystem attribute. The results will therefore fully reflect the
+* relationship between positions measured in the two systems. In addition,
+* any difference in the Unit attributes of the two systems will also be
+* taken into account.
+* - A null Object pointer (AST__NULL) will be returned if this
+c function is invoked with the AST error status set, or if it
+f function is invoked with STATUS set to an error value, or if it
+* should fail for any reason.
+*--
+
+* Implementation Notes:
+* - This function implements the external (public) interface to
+* the astFluxFrame constructor function. It returns an ID value
+* (instead of a true C pointer) to external users, and must be
+* provided because astFluxFrame_ has a variable argument list which
+* cannot be encapsulated in a macro (where this conversion would
+* otherwise occur).
+* - The variable argument list also prevents this function from
+* invoking astFluxFrame_ directly, so it must be a
+* re-implementation of it in all respects, except for the final
+* conversion of the result to an ID value.
+*/
+
+/* Local Variables: */
+ astDECLARE_GLOBALS /* Pointer to thread-specific global data */
+ AstMapping *um; /* Mapping from default to actual units */
+ AstFluxFrame *new; /* Pointer to new FluxFrame */
+ AstSpecFrame *sfrm; /* Pointer to SpecFrame */
+ AstSystemType s; /* System */
+ const char *u; /* Units string */
+ va_list args; /* Variable argument list */
+
+ int *status; /* Pointer to inherited status value */
+
+/* Get a pointer to the thread specific global data structure. */
+ astGET_GLOBALS(NULL);
+
+/* Get a pointer to the inherited status value. */
+ status = astGetStatusPtr;
+
+/* Check the global status. */
+ if ( !astOK ) return NULL;
+
+/* Obtain and validate a pointer to the SpecFrame structures provided. */
+ sfrm = specfrm_void ? astVerifySpecFrame( astMakePointer( specfrm_void ) ) : NULL;
+
+/* Initialise the FluxFrame, allocating memory and initialising the virtual
+ function table as well if necessary. */
+ new = astInitFluxFrame( NULL, sizeof( AstFluxFrame ), !class_init,
+ &class_vtab, "FluxFrame", specval, sfrm );
+
+/* If successful, note that the virtual function table has been initialised. */
+ if ( astOK ) {
+ class_init = 1;
+
+/* Obtain the variable argument list and pass it along with the options string
+ to the astVSet method to initialise the new FluxFrame's attributes. */
+ va_start( args, options );
+ astVSet( new, options, NULL, args );
+ va_end( args );
+
+/* Check the Units are appropriate for the System. */
+ u = astGetUnit( new, 0 );
+ s = astGetSystem( new );
+ um = astUnitMapper( DefUnit( s, "astFluxFrame", "FluxFrame", status ),
+ u, NULL, NULL );
+ if( um ) {
+ um = astAnnul( um );
+ } else {
+ astError( AST__BADUN, "astFluxFrame: Inappropriate units (%s) "
+ "specified for a %s axis.", status, u, SystemLabel( s, status ) );
+ }
+
+/* If an error occurred, clean up by deleting the new object. */
+ if ( !astOK ) new = astDelete( new );
+ }
+
+/* Return an ID value for the new FluxFrame. */
+ return astMakeId( new );
+}
+
+
+
+
+
+
+
+
+