summaryrefslogtreecommitdiffstats
path: root/ast/cmpframe.c
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2018-01-09 19:06:17 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2018-01-09 19:06:17 (GMT)
commitd64cf9c0bd23e752867b149be636d1bbd4501cf4 (patch)
treeec600c696fe3dbf15f166d22a95c47a1c0867509 /ast/cmpframe.c
parent62d555c8f989ab6eb026387cbf52bb46ebb2dfea (diff)
downloadblt-d64cf9c0bd23e752867b149be636d1bbd4501cf4.zip
blt-d64cf9c0bd23e752867b149be636d1bbd4501cf4.tar.gz
blt-d64cf9c0bd23e752867b149be636d1bbd4501cf4.tar.bz2
update ast 8.6.2
Diffstat (limited to 'ast/cmpframe.c')
-rw-r--r--ast/cmpframe.c10654
1 files changed, 0 insertions, 10654 deletions
diff --git a/ast/cmpframe.c b/ast/cmpframe.c
deleted file mode 100644
index 09b5f73..0000000
--- a/ast/cmpframe.c
+++ /dev/null
@@ -1,10654 +0,0 @@
-/*
-*class++
-* Name:
-* CmpFrame
-
-* Purpose:
-* Compound Frame.
-
-* Constructor Function:
-c astCmpFrame
-f AST_CMPFRAME
-
-* Description:
-* A CmpFrame is a compound Frame which allows two component Frames
-* (of any class) to be merged together to form a more complex
-* Frame. The axes of the two component Frames then appear together
-* in the resulting CmpFrame (those of the first Frame, followed by
-* those of the second Frame).
-*
-* Since a CmpFrame is itself a Frame, it can be used as a
-* component in forming further CmpFrames. Frames of arbitrary
-* complexity may be built from simple individual Frames in this
-* way.
-*
-* Also since a Frame is a Mapping, a CmpFrame can also be used as a
-* Mapping. Normally, a CmpFrame is simply equivalent to a UnitMap,
-* but if either of the component Frames within a CmpFrame is a Region
-* (a sub-class of Frame), then the CmpFrame will use the Region as a
-* Mapping when transforming values for axes described by the Region.
-* Thus input axis values corresponding to positions which are outside the
-* Region will result in bad output axis values.
-
-* Inheritance:
-* The CmpFrame class inherits from the Frame class.
-
-* Attributes:
-* The CmpFrame class does not define any new attributes beyond
-* those which are applicable to all Frames. However, the attributes
-* of the component Frames can be accessed as if they were attributes
-* of the CmpFrame. For instance, if a CmpFrame contains a SpecFrame
-* and a SkyFrame, then the CmpFrame will recognise the "Equinox"
-* attribute and forward access requests to the component SkyFrame.
-* Likewise, it will recognise the "RestFreq" attribute and forward
-* access requests to the component SpecFrame. An axis index can
-* optionally be appended to the end of any attribute name, in which
-* case the request to access the attribute will be forwarded to the
-* primary Frame defining the specified axis.
-
-* Functions:
-c The CmpFrame class does not define any new functions beyond those
-f The CmpFrame 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
-* Copyright (C) 2009 Science & Technology Facilities Council.
-* All Rights Reserved.
-
-* 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:
-* RFWS: R.F. Warren-Smith (Starlink)
-* DSB: David S. Berry (Starlink)
-
-* History:
-* 4-MAR-1996 (RFWS):
-* Original version.
-* 27-FEB-1997 (RFWS):
-* Improved public prologues.
-* 25-FEB-1998 (RFWS):
-* Over-ride the astUnformat method.
-* 6-APR-1998 (RFWS):
-* Fixed bug in returned value of GenAxisSelection.
-* 22-SEP-1998 (RFWS):
-* Fixed bug in Match function - was not checking Domain values
-* for equality.
-* 11-JUN-1999 (RFWS):
-* Fixed bug in GenAxisSelection- some selections were being omitted.
-* 5-FEB-2001 (DSB):
-* Ensure that Title and Domain values appropriate to a CmpFrame
-* are preserved if a CmpFrame result is generated by SubFrame.
-* 27-FEB-2001 (DSB):
-* Modified Match so that all the frames have some axes in order to
-* match. Otherwise, null pointers are created (for zero axes),
-* resulting in a seg vio.
-* 21-JUN-2001 (DSB):
-* Added astAngle.
-* 7-SEP-2001 (DSB):
-* Added astResolve.
-* 26-SEP-2001 (DSB):
-* Over-ride the astDecompose method.
-* 20-DEC-2002 (DSB):
-* Allows any attribute of a component frame to be accessed as though
-* it were an attribute of the CmpFrame by including an axis index in
-* the attribute name (e.g. "System(3)").
-* 8-JAN-2003 (DSB):
-* - Changed private InitVtab method to protected astInitCmpFrameVtab
-* method.
-* - Override astGetAttrib, astClearAttrib, astTestAttrib,
-* astSetAttrib to allow attributes to be set for individual
-* axes.
-* - Override astGetEpoch astGetSystem, astGetAlignSystem.
-* astValidateSystem, astSystemString, astSystemCode.
-* 27-FEB-2003 (DSB):
-* - Modify the default Domain name for a CmpFrame to be the
-* domains of the two subFrames separated by a "-".
-* 24-JAN-2004 (DSB):
-* o Override the astFields method.
-* o Added argument "fmt" to Abbrev.
-* 24-MAR-2004 (DSB):
-* Over-ride the astSimplify and astTransform methods.
-* 8-SEP-2004 (DSB):
-* Over-ride astResolvePoints method.
-* 21-JAN-2005 (DSB):
-* Over-ride the astGetActiveUnit and astSetActiveUnit methods.
-* 23-FEB-2005 (DSB):
-* Modify GetDomain to avoid over-writing the static "buff" array
-* if called recursively.
-* 29-MAR-2005 (DSB):
-* Override astSetEpoch and astClearEpoch by implementations which
-* propagate the changed epoch value to the component Frames.
-* 5-APR-2005 (DSB):
-* Correct error checking in Clear/Get/Set/TestAttrib.
-* 12-MAY-2005 (DSB):
-* Override astNormBox method.
-* 12-AUG-2005 (DSB):
-* Override astSetObsLat/Lon and astClearObslat/Lon by implementations
-* which propagate the changed value to the component Frames.
-* 14-FEB-2006 (DSB):
-* Override astGetObjSize.
-* 3-APR-2006 (DSB):
-* Modify Match so that an attempt is made to align the target with
-* each of the two component Frames if the target cannot be matched
-* with the CmpFrame as a whole.
-* 3-MAY-2006 (DSB):
-* Fix bug in Match that could cause segvio when matching a target
-* against the second component of a CmpFrame.
-* 31-OCT-2006 (DSB):
-* Over-ride the SetFrameFlags method.
-* 1-NOV-2005 (DSB):
-* Override astSetDut1, astGetDut1 and astClearDut1.
-* 15-MAR-2007 (DSB):
-* Override astClearAlignSystem by an implementation that clears
-* AlignSystem in the component Frames.
-* 7-FEB-2008 (DSB):
-* Allow the MaxAxes and MinAxes attributes to be specified for a
-* CmpFrame (rather than just being the sum of the attribute values
-* in the component frames). This enables, for instance, a (detector
-* index,mjd) frame to match with a ((velocity,detector index),mjd)
-* frame.
-* 5-MAY-2009 (DSB):
-* In GetAttrib, if an index is included in the attribute name, attempt
-* to use the GetAttrib method of the primary frame before using the
-* parent GetAttrib method. This is because the Frame getattrib
-* method will dissociate axes from their parent class. Thus, a
-* SkyAxis attribute such as AsTime will come out wrong since its
-* value is managed by the SkyFrame class rather than the SkyAxis
-* class.
-* 18-JUN-2009 (DSB):
-* Override astSetObsAlt and astClearObsAlt.
-* 29-SEP-2009 (DSB):
-* Ensure the astMatch method provided by this class honours the
-* PreserveAxes, MaxAxes and MinAxes attribute settings.
-* 22-MAR-2011 (DSB):
-* Override astFrameGrid method.
-* 29-APR-2011 (DSB):
-* Prevent astFindFrame from matching a subclass template against a
-* superclass target.
-* 10-FEB-2015 (DSB):
-* When checking attribute settings for attribute names that end with
-* an axis index, stop looking for the axis index when the first equals
-* sign is encountered.
-* 26-MAR-2015 (DSB):
-* Increase size of "buf2" buffer in SetAttrib, and trap buffer overflow.
-*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 CmpFrame
-
-/* Define the first and last acceptable System values. */
-#define FIRST_SYSTEM AST__COMP
-#define LAST_SYSTEM AST__COMP
-
-/* Define macros to implement member functions for accessing axis
- attributes. */
-/*
-* Name:
-* MAKE_CLEAR
-
-* Purpose:
-* Implement a function to clear an attribute value for a CmpFrame axis.
-
-* Type:
-* Private macro.
-
-* Synopsis:
-* #include "cmpframe.h"
-* MAKE_CLEAR(attribute)
-
-* Class Membership:
-* Defined by the CmpFrame class.
-
-* Description:
-* This macro expands to an implementation of a private member
-* function of the form:
-*
-* static void Clear<Attribute>( AstFrame *this, int axis )
-*
-* which clears an attribute value for a specified axis of a CmpFrame.
-
-* Parameters:
-* attribute
-* The name of the attribute to be cleared, as it appears in the
-* function name (e.g. Label in "ClearLabel").
-
-* Notes:
-* - This macro assumes the existence of a method of the form:
-*
-* void astClear<Attribute>( AstFrame *this, int axis )
-*
-* which clears the required attribute for a Frame object.
-* - To avoid problems with some compilers, you should not leave
-* any white space around the macro arguments.
-*/
-
-/* Define the macro. */
-#define MAKE_CLEAR(attribute) \
-static void Clear##attribute( AstFrame *this_frame, int axis, int *status ) { \
- AstCmpFrame *this; /* Pointer to CmpFrame structure */ \
- int naxes1; /* Number of axes in frame1 */ \
-\
-/* Check the global error status. */ \
- if ( !astOK ) return; \
-\
-/* Obtain a pointer to the CmpFrame structure. */ \
- this = (AstCmpFrame *) this_frame; \
-\
-/* Validate and alidateAxispermute the axis index supplied. */ \
- axis = astValidateAxis( this, axis, 1, "astSet" #attribute ); \
-\
-/* Determine the number of axes in the first component Frame. */ \
- naxes1 = astGetNaxes( this->frame1 ); \
- if ( astOK ) { \
-\
-/* Decide which Frame contains the axis and invoke its astClear... method to \
- clear the attribute value. */ \
- if ( axis < naxes1 ) { \
- astClear##attribute( this->frame1, axis ); \
- } else { \
- astClear##attribute( this->frame2, axis - naxes1 ); \
- } \
- } \
-}
-
-/*
-* Name:
-* MAKE_GET
-
-* Purpose:
-* Implement a function to get an attribute value for a CmpFrame axis.
-
-* Type:
-* Private macro.
-
-* Synopsis:
-# #include "cmpframe.h"
-* MAKE_GET(attribute,type,bad_value,default,assign_default)
-
-* Class Membership:
-* Defined by the CmpFrame class.
-
-* Description:
-* This macro expands to an implementation of a private member
-* function of the form:
-*
-* static <Type> Get<Attribute>( AstFrame *this, int axis )
-*
-* which gets an attribute value for a specified axis of a
-* CmpFrame.
-
-* Parameters:
-* attribute
-* The name of the attribute whose value is to be obtained, as
-* it appears in the function name (e.g. Label in "GetLabel").
-* type
-* The C type of the attribute.
-* bad_value
-* A constant value to return if the global error status is set,
-* or if the function fails.
-* default
-* A boolean (int) value that indicates whether a new default
-* value should be returned if the requested attribute has not
-* been set for the appropriate axis of the appropriate
-* component Frame. If this value is zero, the component Frame's
-* default (for the appropriate axis) will be used instead.
-* assign_default
-* An expression that evaluates to the new default value to be
-* assigned. This value is ignored if "default" is zero, but a
-* valid (e.g. constant) value should nevertheless be supplied.
-
-* Notes:
-* - This macro assumes the existence of a method of the form:
-*
-* <Type> astGet<Attribute>( AstFrame *this, int axis )
-*
-* which gets the required attribute for a Frame object.
-* - To avoid problems with some compilers, you should not leave
-* any white space around the macro arguments.
-*/
-
-/* Define the macro. */
-#define MAKE_GET(attribute,type,bad_value,default,assign_default) \
-static type Get##attribute( AstFrame *this_frame, int axis, int *status ) { \
- astDECLARE_GLOBALS /* Declare the thread specific global data */ \
- AstCmpFrame *this; /* Pointer to CmpFrame structure */ \
- AstFrame *frame; /* Pointer to Frame containing axis */\
- int axis_p; /* Permuted axis index */ \
- int naxes1; /* Number of axes in frame1 */ \
- int set; /* Digits attribute set? */ \
- type result; /* Result value to return */ \
- \
-/* Initialise. */ \
- result = (bad_value); \
-\
-/* Check the global error status. */ \
- if ( !astOK ) return result; \
-\
-/* Get a pointer to the structure holding thread-specific global data. */ \
- astGET_GLOBALS(this_frame); \
-\
-/* Obtain a pointer to the CmpFrame structure. */ \
- this = (AstCmpFrame *) this_frame; \
-\
-/* Validate and permute the axis index supplied. */ \
- axis_p = astValidateAxis( this, axis, 1, "astGet" #attribute ); \
-\
-/* Determine the number of axes in the first component Frame. */ \
- naxes1 = astGetNaxes( this->frame1 ); \
- if ( astOK ) { \
-\
-/* Decide which Frame contains the axis and adjust the axis index if \
- necessary. */ \
- frame = ( axis_p < naxes1 ) ? this->frame1 : this->frame2; \
- axis_p = ( axis_p < naxes1 ) ? axis_p : axis_p - naxes1; \
-\
-/* Since the component Frame is "managed" by the enclosing CmpFrame, we next \
- test if any Frame attributes which may affect the result are undefined \
- (i.e. have not been explicitly set). If so, we over-ride them, giving \
- them temporary values dictated by the CmpFrame. Only the Digits attribute \
- is relevant here. */ \
- set = astTestDigits( frame ); \
- if ( !set ) astSetDigits( frame, astGetDigits( this ) ); \
-\
-/* If the default value is to be over-ridden, test if the Frame's axis \
- attribute has been set. Then, if required, obtain the attribute value from \
- the Frame. */ \
- if ( !(default) || astTest##attribute( frame, axis_p ) ) { \
- result = astGet##attribute( frame, axis_p ); \
-\
-/* If required, assign the new default value. */ \
- } else { \
- result = (assign_default); \
- } \
-\
-/* Clear Frame attributes which were temporarily over-ridden. */ \
- if ( !set ) astClearDigits( frame ); \
- } \
-\
-/* If an error occurred, clear the result value. */ \
- if ( !astOK ) result = (bad_value); \
-\
-/* Return the result. */ \
- return result; \
-}
-
-/*
-* Name:
-* MAKE_SET
-
-* Purpose:
-* Implement a function to set an attribute value for a CmpFrame axis.
-
-* Type:
-* Private macro.
-
-* Synopsis:
-* #include "cmpframe.h"
-* MAKE_SET(attribute,type)
-
-* Class Membership:
-* Defined by the CmpFrame class.
-
-* Description:
-* This macro expands to an implementation of a private member
-* function of the form:
-*
-* static void Set<Attribute>( AstFrame *this, int axis, <Type> value )
-*
-* which sets an attribute value for a specified axis of a CmpFrame.
-
-* Parameters:
-* attribute
-* The name of the attribute to be set, as it appears in the
-* function name (e.g. Label in "SetLabel").
-* type
-* The C type of the attribute.
-
-* Notes:
-* - This macro assumes the existence of a method of the form:
-*
-* void astSet<Attribute>( AstFrame *this, int axis, <Type> value )
-*
-* which sets the required attribute for a Frame object.
-* - To avoid problems with some compilers, you should not leave
-* any white space around the macro arguments.
-*/
-
-/* Define the macro. */
-#define MAKE_SET(attribute,type) \
-static void Set##attribute( AstFrame *this_frame, int axis, type value, int *status ) { \
- AstCmpFrame *this; /* Pointer to CmpFrame structure */ \
- int naxes1; /* Number of axes in frame1 */ \
-\
-/* Check the global error status. */ \
- if ( !astOK ) return; \
-\
-/* Obtain a pointer to the CmpFrame structure. */ \
- this = (AstCmpFrame *) this_frame; \
-\
-/* Validate and permute the axis index supplied. */ \
- axis = astValidateAxis( this, axis, 1, "astSet" #attribute ); \
-\
-/* Determine the number of axes in the first component Frame. */ \
- naxes1 = astGetNaxes( this->frame1 ); \
- if ( astOK ) { \
-\
-/* Decide which Frame contains the axis and invoke its astSet... method to \
- set the attribute value. */ \
- if ( axis < naxes1 ) { \
- astSet##attribute( this->frame1, axis, value ); \
- } else { \
- astSet##attribute( this->frame2, axis - naxes1, value ); \
- } \
- } \
-}
-
-/*
-* Name:
-* MAKE_TEST
-
-* Purpose:
-* Implement a function to test if an attribute is set for a CmpFrame axis.
-
-* Type:
-* Private macro.
-
-* Synopsis:
-* #include "cmpframe.h"
-* MAKE_TEST(attribute)
-
-* Class Membership:
-* Defined by the CmpFrame class.
-
-* Description:
-* This macro expands to an implementation of a private member
-* function of the form:
-*
-* static int Test<Attribute>( AstFrame *this, int axis )
-*
-* which tests whether an attribute value is set for a specified
-* axis of a CmpFrame.
-
-* Parameters:
-* attribute
-* The name of the attribute to be tested, as it appears in the
-* function name (e.g. Label in "TestLabel").
-
-* Notes:
-* - This macro assumes the existence of a method of the form:
-*
-* int astTest<Attribute>( AstFrame *this, int axis )
-*
-* which tests the required attribute for a Frame object.
-* - To avoid problems with some compilers, you should not leave
-* any white space around the macro arguments.
-*/
-
-/* Define the macro. */
-#define MAKE_TEST(attribute) \
-static int Test##attribute( AstFrame *this_frame, int axis, int *status ) { \
- AstCmpFrame *this; /* Pointer to CmpFrame structure */ \
- int naxes1; /* Number of axes in frame1 */ \
- int result; /* Result value to return */ \
-\
-/* Initialise. */ \
- result = 0; \
-\
-/* Check the global error status. */ \
- if ( !astOK ) return result; \
-\
-/* Obtain a pointer to the CmpFrame structure. */ \
- this = (AstCmpFrame *) this_frame; \
-\
-/* Validate and permute the axis index supplied. */ \
- axis = astValidateAxis( this, axis, 1, "astSet" #attribute ); \
-\
-/* Determine the number of axes in the first component Frame. */ \
- naxes1 = astGetNaxes( this->frame1 ); \
- if ( astOK ) { \
-\
-/* Decide which Frame contains the axis and invoke its astTest... method to \
- test the attribute. */ \
- if ( axis < naxes1 ) { \
- result = astTest##attribute( this->frame1, axis ); \
- } else { \
- result = astTest##attribute( this->frame2, axis - naxes1 ); \
- } \
- } \
-\
-/* Return the result. */ \
- return result; \
-}
-
-/* Include files. */
-/* ============== */
-/* Interface definitions. */
-/* ---------------------- */
-
-#include "globals.h" /* Thread-safe global data access */
-#include "error.h" /* Error reporting facilities */
-#include "memory.h" /* Memory allocation facilities */
-#include "pointset.h" /* Sets of points */
-#include "object.h" /* Base Object class */
-#include "mapping.h" /* Coordinate Mappings */
-#include "unitmap.h" /* Unit Mappings */
-#include "permmap.h" /* Coordinate permutation Mappings */
-#include "cmpmap.h" /* Compound Mappings */
-#include "axis.h" /* Coordinate axes */
-#include "frame.h" /* Parent Frame class */
-#include "cmpframe.h" /* Interface definition for this class */
-#include "globals.h" /* Thread-safe global data access */
-
-/* Error code definitions. */
-/* ----------------------- */
-#include "ast_err.h" /* AST error codes */
-
-/* C header files. */
-/* --------------- */
-#include <limits.h>
-#include <float.h>
-#include <math.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.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 extended by this class. */
-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_gettitle)( AstFrame *, int * );
-static double (* parent_angle)( AstFrame *, const double[], const double[], const double[], int * );
-static double (* parent_getdut1)( AstFrame *, int * );
-static double (* parent_getepoch)( AstFrame *, int * );
-static double (* parent_getobsalt)( AstFrame *, int * );
-static double (* parent_getobslat)( AstFrame *, int * );
-static double (* parent_getobslon)( AstFrame *, int * );
-static int (* parent_getactiveunit)( AstFrame *, int * );
-static int (* parent_getmaxaxes)( AstFrame *, int * );
-static int (* parent_getminaxes)( AstFrame *, int * );
-static int (* parent_getobjsize)( AstObject *, int * );
-static int (* parent_getusedefs)( AstObject *, int * );
-static int (* parent_testattrib)( AstObject *, const char *, int * );
-static void (* parent_clearalignsystem)( AstFrame *, int * );
-static void (* parent_clearattrib)( AstObject *, const char *, int * );
-static void (* parent_cleardut1)( AstFrame *, int * );
-static void (* parent_clearepoch)( AstFrame *, int * );
-static void (* parent_clearobsalt)( AstFrame *, int * );
-static void (* parent_clearobslat)( AstFrame *, int * );
-static void (* parent_clearobslon)( AstFrame *, int * );
-static void (* parent_overlay)( AstFrame *, const int *, AstFrame *, int * );
-static void (* parent_setactiveunit)( AstFrame *, int, int * );
-static void (* parent_setattrib)( AstObject *, const char *, int * );
-static void (* parent_setdut1)( AstFrame *, double, int * );
-static void (* parent_setepoch)( AstFrame *, double, int * );
-static void (* parent_setframeflags)( AstFrame *, int, int * );
-static void (* parent_setobsalt)( AstFrame *, double, int * );
-static void (* parent_setobslat)( AstFrame *, double, int * );
-static void (* parent_setobslon)( AstFrame *, double, 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->Label_Buff[ 0 ] = 0; \
- globals->Symbol_Buff[ 0 ] = 0; \
- globals->GetDomain_Buff[ 0 ] = 0; \
- globals->GetTitle_Buff[ 0 ] = 0;
-
-/* Create the function that initialises global data for this module. */
-astMAKE_INITGLOBALS(CmpFrame)
-
-/* Define macros for accessing each item of thread specific global data. */
-#define class_init astGLOBAL(CmpFrame,Class_Init)
-#define class_vtab astGLOBAL(CmpFrame,Class_Vtab)
-#define getdomain_buff astGLOBAL(CmpFrame,GetDomain_Buff)
-#define gettitle_buff astGLOBAL(CmpFrame,GetTitle_Buff)
-#define label_buff astGLOBAL(CmpFrame,Label_Buff)
-#define symbol_buff astGLOBAL(CmpFrame,Symbol_Buff)
-#define qsort_axes astGLOBAL(CmpFrame,qsort_axes)
-
-
-
-/* If thread safety is not needed, declare and initialise globals at static
- variables. */
-#else
-
-/* Pointer to axis index array accessed by "qsort". */
-static int *qsort_axes;
-
-/* Default Label string buffer */
-static char label_buff[ 101 ];
-
-/* Default Symbol buffer */
-static char symbol_buff[ 51 ];
-
-/* Buffer for returned domain name in GetDomain */
-static char getdomain_buff[ 101 ];
-
-/* Buffer for returned title in GetTitle */
-static char gettitle_buff[ 101 ];
-
-
-/* Define the class virtual function table and its initialisation flag
- as static variables. */
-static AstCmpFrameVtab class_vtab; /* Virtual function table */
-static int class_init = 0; /* Virtual function table initialised? */
-
-#endif
-
-
-/* External 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. */
-AstCmpFrame *astCmpFrameId_( void *, void *, const char *, ... );
-
-/* Prototypes for Private Member Functions. */
-/* ======================================== */
-static AstAxis *GetAxis( AstFrame *, int, int * );
-static AstMapping *RemoveRegions( AstMapping *, int * );
-static AstMapping *Simplify( AstMapping *, int * );
-static AstObject *Cast( AstObject *, AstObject *, int * );
-static AstPointSet *FrameGrid( AstFrame *, int, const double *, const double *, int * );
-static AstPointSet *ResolvePoints( AstFrame *, const double [], const double [], AstPointSet *, AstPointSet *, int * );
-static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * );
-static AstSystemType GetAlignSystem( AstFrame *, int * );
-static AstSystemType GetSystem( AstFrame *, int * );
-static AstSystemType SystemCode( AstFrame *, const char *, int * );
-static AstSystemType ValidateSystem( AstFrame *, AstSystemType, const char *, int * );
-static const char *Abbrev( AstFrame *, int, const char *, const char *, const char *, int * );
-static const char *Format( AstFrame *, int, double, int * );
-static const char *GetDomain( AstFrame *, int * );
-static const char *GetFormat( AstFrame *, int, 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 *SystemString( AstFrame *, AstSystemType, int * );
-static const int *GetPerm( AstFrame *, int * );
-static double Angle( AstFrame *, const double[], const double[], const double[], int * );
-static double Distance( AstFrame *, const double[], const double[], int * );
-static double Centre( AstFrame *, int, double, double, int * );
-static double Gap( AstFrame *, int, double, int *, int * );
-static int ComponentMatch( AstCmpFrame *, AstFrame *, int, int, int **, int **, AstMapping **, AstFrame **, int * );
-static int Fields( AstFrame *, int, const char *, const char *, int, char **, int *, double *, int * );
-static int GenAxisSelection( int, int, int [], int * );
-static int GetActiveUnit( AstFrame *, int * );
-static int GetDirection( AstFrame *, int, int * );
-static int GetMaxAxes( AstFrame *, int * );
-static int GetMinAxes( AstFrame *, int * );
-static int GetNaxes( AstFrame *, int * );
-static int GetObjSize( AstObject *, int * );
-static int GetUseDefs( AstObject *, int * );
-static int GoodPerm( int, const int [], int, const int [], int * );
-static int IsUnitFrame( AstFrame *, int * );
-static int Match( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * );
-static int PartMatch( AstCmpFrame *, AstFrame *, int, int, const int [], int, const int [], int **, int **, AstMapping **, AstFrame **, int * );
-static int QsortCmpAxes( const void *, const void * );
-static int SubFrame( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * );
-static int TestDirection( AstFrame *, int, int * );
-static int TestFormat( AstFrame *, int, int * );
-static int TestLabel( AstFrame *, int, int * );
-static int TestSymbol( AstFrame *, int, int * );
-static int TestUnit( AstFrame *, int, int * );
-static int Unformat( AstFrame *, int, const char *, double *, int * );
-static void AddExtraAxes( int, int [], int, int, int, int * );
-static void ClearDirection( AstFrame *, int, int * );
-static void ClearFormat( AstFrame *, int, int * );
-static void ClearLabel( AstFrame *, int, int * );
-static void ClearSymbol( AstFrame *, int, int * );
-static void ClearUnit( AstFrame *, int, int * );
-static void Copy( const AstObject *, AstObject *, int * );
-static void Decompose( AstMapping *, AstMapping **, AstMapping **, int *, int *, int *, int * );
-static void Delete( AstObject *, int * );
-static void Dump( AstObject *, AstChannel *, int * );
-static void MatchAxesX( AstFrame *, AstFrame *, int *, int * );
-static void Norm( AstFrame *, double [], int * );
-static void NormBox( AstFrame *, double[], double[], AstMapping *, int * );
-static void Offset( AstFrame *, const double [], const double [], double, double [], int * );
-static void Overlay( AstFrame *, const int *, AstFrame *, int * );
-static void PartitionSelection( int, const int [], const int [], int, int, int [], int, int * );
-static void PermAxes( AstFrame *, const int[], int * );
-static void PrimaryFrame( AstFrame *, int, AstFrame **, int *, int * );
-static void RenumberAxes( int, int [], int * );
-static void Resolve( AstFrame *, const double [], const double [], const double [], double [], double *, double *, int * );
-static void SetActiveUnit( AstFrame *, int, int * );
-static void SetAxis( AstFrame *, int, AstAxis *, int * );
-static void SetDirection( AstFrame *, int, int, int * );
-static void SetFormat( AstFrame *, int, const char *, int * );
-static void SetFrameFlags( AstFrame *, int, int * );
-static void SetLabel( AstFrame *, int, const char *, int * );
-static void SetSymbol( AstFrame *, int, const char *, int * );
-static void SetUnit( AstFrame *, int, const char *, 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 GetEpoch( AstFrame *, int * );
-static void ClearEpoch( AstFrame *, int * );
-static void SetEpoch( AstFrame *, double, int * );
-
-static double GetDut1( AstFrame *, int * );
-static void ClearDut1( AstFrame *, int * );
-static void SetDut1( AstFrame *, double, int * );
-
-static double GetObsLon( AstFrame *, int * );
-static void ClearObsLon( AstFrame *, int * );
-static void SetObsLon( AstFrame *, double, int * );
-
-static double GetObsLat( AstFrame *, int * );
-static void ClearObsLat( AstFrame *, int * );
-static void SetObsLat( AstFrame *, double, int * );
-
-static double GetObsAlt( AstFrame *, int * );
-static void ClearObsAlt( AstFrame *, int * );
-static void SetObsAlt( AstFrame *, double, int * );
-
-static void ClearAlignSystem( AstFrame *, int * );
-
-#if defined(THREAD_SAFE)
-static int ManageLock( AstObject *, int, int, AstObject **, int * );
-#endif
-
-/* Member functions. */
-/* ================= */
-static const char *Abbrev( AstFrame *this_frame, int axis, const char *fmt,
- const char *str1, const char *str2, int *status ) {
-/*
-* Name:
-* Abbrev
-
-* Purpose:
-* Abbreviate a formatted CmpFrame axis value by skipping leading fields.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* const char *Abbrev( AstFrame *this, int axis, const char *fmt,
-* const char *str1, const char *str2, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the protected astAbbrev
-* method inherited from the Frame class).
-
-* Description:
-* This function compares two CmpFrame axis values that have been
-* formatted (using astFormat) and determines if they have any
-* redundant leading fields (i.e. leading fields in common which
-* can be suppressed when tabulating the values or plotting them on
-* the axis of a graph).
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* axis
-* The number of the CmpFrame axis for which the values have
-* been formatted (axis numbering starts at zero for the first
-* axis).
-* fmt
-* Pointer to a constant null-terminated string containing the
-* format specification used to format the two values.
-* str1
-* Pointer to a constant null-terminated string containing the
-* first formatted value. If this is null, the returned pointer
-* points to the start of the final field in str2.
-* str2
-* Pointer to a constant null-terminated string containing the
-* second formatted value.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A pointer into the "str2" string which locates the first
-* character in the first field that differs between the two
-* formatted values.
-*
-* If the two values have no leading fields in common, the returned
-* value will point at the start of string "str2". If the two
-* values are equal, it will point at the terminating null at the
-* end of this string.
-
-* Notes:
-* - This function assumes that the format specification used was
-* the same when both values were formatted and that they both
-* apply to the same CmpFrame axis.
-* - A pointer to the start of "str2" will be returned if this
-* function is invoked with the global error status set, or if it
-* should fail for any reason.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to CmpFrame structure */
- AstFrame *frame; /* Pointer to Frame containing axis */
- const char *result; /* Pointer value to return */
- int naxes1; /* Number of axes in frame1 */
- int set; /* Digits attribute set? */
-
-/* Initialise. */
- result = str2;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Validate and permute the axis index supplied. */
- axis = astValidateAxis( this, axis, 1, "astAbbrev" );
-
-/* Determine the number of axes in the first component Frame. */
- naxes1 = astGetNaxes( this->frame1 );
- if ( astOK ) {
-
-/* Decide which component Frame contains the axis and adjust the axis
- index if necessary. */
- frame = ( axis < naxes1 ) ? this->frame1 : this->frame2;
- axis = ( axis < naxes1 ) ? axis : axis - naxes1;
-
-/* Since the component Frame is "managed" by the enclosing CmpFrame,
- we next test if any Frame attributes which may affect the result
- are undefined (i.e. have not been explicitly set). If so, we
- over-ride them, giving them temporary values dictated by the
- CmpFrame. Only the Digits attribute is relevant here. */
- set = astTestDigits( frame );
- if ( !set ) astSetDigits( frame, astGetDigits( this ) );
-
-/* Invoke the Frame's astAbbrev method to perform the processing. */
- result = astAbbrev( frame, axis, fmt, str1, str2 );
-
-/* Clear Frame attributes which were temporarily over-ridden. */
- if ( !set ) astClearDigits( frame );
- }
-
-/* If an error occurred, clear the returned value. */
- if ( !astOK ) result = str2;
-
-/* Return the result. */
- return result;
-}
-
-static void AddExtraAxes( int naxes, int axes[], int i1, int i2,
- int following, int *status ) {
-/*
-* Name:
-* AddExtraAxes
-
-* Purpose:
-* Add extra axis indices in place of missing ones.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void AddExtraAxes( int naxes, int axes[], int i1, int i2,
-* int following, int *status )
-
-* Class Membership:
-* CmpFrame member function.
-
-* Description:
-* This function takes an array of axis indices that refer to the
-* axes of a Frame, and which may have values missing (denoted by
-* an index of -1). It replaces each occurrence of -1 by a new axis
-* index (and re-numbers the others to avoid duplication) in such a
-* way that the new indices introduced are "associated" with
-* certain of the pre-existing indices, by virtue of being numbered
-* consecutively with them.
-*
-* The purpose of this operation is to establish the relative
-* location of new axes in relation to the pre-existing ones.
-*
-* Normally, each new axis will be associated with (i.e. numbered
-* one more than) the pre-existing index which precedes
-* it. However, if the "following" parameter is non-zero, it will
-* instead be associated with (numbered one less than) the one
-* which follows it. If there is no preceding (or following)
-* pre-existing index, the following (or preceding) one is used
-* instead. If several adjacent occurrences of -1 must be replaced,
-* they are numbered consecutively in their order of occurrence.
-
-* Parameters:
-* naxes
-* The number of axis indices in the array.
-* axes
-* The array containing the axis indices.
-* i1
-* Index of the first element of the array to be processed.
-* i2
-* Index of the last element of the array to be processed.
-* following
-* Boolean flag to determine if new indices are associated with
-* the preceding index (if zero) or the following index (if
-* non-zero).
-* status
-* Pointer to the inherited status variable.
-
-* Notes:
-* - The values of "i1" and "i2" dictate the range of array
-* elements where values of -1 will be replaced, but all array
-* elements are candidates for renumbering in order to avoid
-* duplicate axis indices.
-* - This function aims to establish the location of new axes only
-* by means of the relative numerical value of the indices assigned
-* to them. It does not constrain the actual indices assigned in
-* any further way.
-* - Because axis indices are always incremented (never
-* decremented) in order to avoid duplicates, where a number of new
-* indices have been introduced, the maximum index present in the
-* result array may exceed the original maximum.
-* - Some axis indices may remain unused (i.e. not present) in the
-* result array.
-*/
-
-/* Local Variables: */
- int end; /* Loop termination value */
- int extra; /* Index to apply to next "extra" axis */
- int found; /* Default value found? */
- int i; /* Main loop counter */
- int inc; /* Loop increment value */
- int j; /* Loop counter for eliminating duplicates */
- int start; /* Loop starting value */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Initialise the default index of the next extra axis to add. This
- will apply only if there are no valid axis indices from which to
- obtain a better default. */
- extra = 0;
-
-/* Initialise loop parameters so as to scan the axis indices provided
- in either the forward or reverse direction, according to the value
- of "following". Start with the section of the array being processed,
- but continue looking for a default right up to the end of the array
- (this prevents the current section being numbered inconsistently
- with respect to adjacent ones that may already have been
- processed). */
- start = following ? i2 : i1;
- end = following ? -1 : naxes;
- inc = following ? -1 : 1;
-
-/* Search for the first (in whichever direction this is) valid axis
- index and use it to set a new default index for the next extra axis
- to add. If scanning forward, use the valid axis index (causing any
- preceding extra axis to displace it upwards). If scanning
- backwards, use one more than the valid axis index (causing any
- following extra axis to tag on the end). */
- found = 0;
- for ( i = start; i != end; i += inc ) {
- if ( axes[ i ] != -1 ) {
- found = 1;
- extra = axes[ i ] + ( following ? 1 : 0 );
- break;
- }
- }
-
-/* If no default has yet been found, repeat the above process by
- scanning in the opposite direction (by inverting the "following"
- value used). Again, this prevents inconsistency with neighbouring
- regions. This time a default must be found unless the entire array
- is filled with -1's (in which case a default of zero is used). */
- if ( !found ) {
- start = !following ? i2 : i1;
- end = !following ? -1 : naxes;
- inc = !following ? -1 : 1;
- for ( i = start; i != end; i += inc ) {
- if ( axes[ i ] != -1 ) {
- extra = axes[ i ] + ( !following ? 1 : 0 );
- break;
- }
- }
- }
-
-/* Reset the loop parameters to scan just the region of interest in
- the original (correct) direction. */
- start = following ? i2 : i1;
- end = following ? i1 - 1 : i2 + 1;
- inc = following ? -1 : 1;
-
-/* Identify those indices which are not valid. */
- for ( i = start; i != end; i += inc ) {
- if ( axes[ i ] == -1 ) {
-
-/* We wish to assign the value "extra" in place of this invalid axis
- index. However, this may duplicate an index already present, so
- increment by one all valid indices which are not less than the new
- index. This eliminates any possibility duplication, although it may
- leave an axis index value unused (if no duplication would actually
- have occurred). */
- for ( j = 0; j < naxes; j++ ) {
- if ( axes[ j ] != -1 ) {
- if ( axes[ j ] >= extra ) axes[ j ]++;
- }
- }
-
-/* We can now assign the new axis index. */
- axes[ i ] = extra;
-
-/* Assign the value to be used for the next extra axis index. If
- scanning forward, this will be one more than the last one used (so
- it will follow it). If scanning backwards, it is equal to the last
- one (so that it will displace the last one upwards). */
- extra += ( following ? 0 : 1 );
-
-/* When a valid axis index is encountered, reset the value to be used
- for the next extra axis index. If scanning forward, this is one
- more than the last valid index (so the extra axis will follow
- it). If scanning backwards, it is equal to the last valid index (so
- it will displace the valid index upwards). */
- } else {
- extra = axes[ i ] + ( following ? 0 : 1 );
- }
- }
-}
-
-static double Angle( AstFrame *this_frame, const double a[],
- const double b[], const double c[], int *status ) {
-/*
-* Name:
-* Angle
-
-* Purpose:
-* Calculate the angle subtended by two points at a third point.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* double Angle( AstFrame *this_frame, const double a[],
-* const double b[], const double c[], int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astAngle method
-* inherited from the Frame class).
-
-* Description:
-* This function finds the angle at point B between the line joining
-* points A and B, and the line joining points C and B, in the context
-* of a CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* a
-* An array of double, with one element for each CmpFrame axis,
-* containing the coordinates of the first point.
-* b
-* An array of double, with one element for each CmpFrame axis,
-* containing the coordinates of the second point.
-* c
-* An array of double, with one element for each CmpFrame axis,
-* containing the coordinates of the third point.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The required angle, or AST__BAD if the angle is undefined.
-
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- AstFrame *pframe; /* Pointer to the primary Frame for an axis */
- const int *perm; /* Pointer to axis permutation array */
- double *pa; /* Permuted coordinates for point a */
- double *pb; /* Permuted coordinates for point b */
- double *pc; /* Permuted coordinates for point c */
- double ang1; /* Angle between input points in frame1 */
- double ang2; /* Angle between input points in frame2 */
- double result; /* Required angle */
- int axis; /* Loop counter for axes */
- int iscart; /* Is the CmpFrame a Cartesian system? */
- int naxes1; /* Number of axes in frame1 */
- int naxes; /* Total number of axes in CmpFrame */
- int paxis; /* Axis index within primary Frame */
-
-/* Initialise. */
- result = AST__BAD;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Obtain the number of axes in the CmpFrame. */
- naxes = astGetNaxes( this );
-
-/* See if all axes within the CmpFrame belong to a simple Frame, in which
- case we assume that the CmpFrame describes a Cartesian coordinate system. */
- iscart = 1;
- for( axis = 0; axis < naxes; axis++ ){
- PrimaryFrame( this_frame, axis, &pframe, &paxis, status );
- if( strcmp( astGetClass( pframe ), "Frame" ) ) {
- iscart = 0;
- pframe = astAnnul( pframe );
- break;
- }
- pframe = astAnnul( pframe );
- }
-
-/* If the CmpFrame describes a Cartesian coordinate system, we can use the
- Angle method from the parent Frame class. */
- if( iscart ) {
- result = (*parent_angle)( this_frame, a, b, c, status );
-
-/* If the CmpFrame is not Cartesian... */
- } else {
-
-/* Obtain a pointer to the CmpFrame's axis permutation array. */
- perm = astGetPerm( this );
-
-/* Get workspace. */
- pa = (double *) astMalloc( sizeof(double)*naxes );
- pb = (double *) astMalloc( sizeof(double)*naxes );
- pc = (double *) astMalloc( sizeof(double)*naxes );
-
-/* If OK, apply the axis permutation array to obtain the coordinates in the
- required order. */
- if( astOK ) {
- for( axis = 0; axis < naxes; axis++ ) {
- pa[ perm[ axis ] ] = a[ axis ];
- pb[ perm[ axis ] ] = b[ axis ];
- pc[ perm[ axis ] ] = c[ axis ];
- }
-
-/* Obtain the number of axes in the first component Frame. */
- naxes1 = astGetNaxes( this->frame1 );
-
-/* Project the two input points into the two component Frames and
- determine the angle between the points in each Frame. */
- ang1 = astAngle( this->frame1, pa, pb, pc );
- ang2 = astAngle( this->frame2, pa + naxes1, pb + naxes1,
- pc + naxes1 );
-
-/* The required angle is defined if one and only one of the two component
- frames gives a defined angle between the two points. */
- if( ang1 == AST__BAD ) {
- result = ang2;
- } else if( ang2 == AST__BAD ) {
- result = ang1;
- }
- }
-
-/* Free the workspace */
- pa = (double *) astFree( (void *) pa );
- pb = (double *) astFree( (void *) pb );
- pc = (double *) astFree( (void *) pc );
- }
-
-/* Return the result. */
- return result;
-}
-
-static AstObject *Cast( AstObject *this_object, AstObject *obj, int *status ) {
-/*
-* Name:
-* Cast
-
-* Purpose:
-* Cast an Object into an instance of a sub-class.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* AstObject *Cast( AstObject *this, AstObject *obj, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the protected astCast
-* method inherited from the Frame class).
-
-* Description:
-* This function returns a deep copy of an ancestral component of the
-* supplied object. The required class of the ancestral component is
-* specified by another object. Specifically, if "this" and "new" are
-* of the same class, a copy of "this" is returned. If "this" is an
-* instance of a subclass of "obj", then a copy of the component
-* of "this" that matches the class of "obj" is returned. Otherwise,
-* a NULL pointer is returned without error.
-
-* Parameters:
-* this
-* Pointer to the Object to be cast.
-* obj
-* Pointer to an Object that defines the class of the returned Object.
-* The returned Object will be of the same class as "obj".
-
-* Returned Value:
-* A pointer to the new Object. NULL if "this" is not a sub-class of
-* "obj", or if an error occurs.
-
-* 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; */
- AstAxis *newaxis;
- AstFrame *cfrm;
- AstFrame *this;
- AstObject *new;
- astDECLARE_GLOBALS
- int generation_gap;
- int i;
- int naxes;
-
-/* Initialise */
- new = NULL;
-
-/* Check inherited status */
- if( !astOK ) return new;
-
-/* Get a pointer to the thread specific global data structure. */
- astGET_GLOBALS(NULL);
-
-/* See how many steps up the class inheritance ladder it is from "obj"
- to this class (CmpFrame). A positive value is returned if CmpFrame
- is a sub-class of "obj". A negative value is returned if "obj" is
- a sub-class of CmpFrame. Zero is returned if "obj" is a CmpFrame.
- AST__COUSIN is returned if "obj" is not on the same line of descent
- as CmpFrame. */
- generation_gap = astClassCompare( (AstObjectVtab *) &class_vtab,
- astVTAB( obj ) );
-
-/* If "obj" is a CmpFrame or a sub-class of CmpFrame, we can cast by
- truncating the vtab for "this" so that it matches the vtab of "obJ",
- and then taking a deep copy of "this". */
- if( generation_gap <= 0 && generation_gap != AST__COUSIN ) {
- new = astCastCopy( this_object, obj );
-
-/* If "obj" is not a CmpFrame or a sub-class of CmpFrame (e.g. it's a
- Frame), we create a basic Frame containing the same axes and attributes
- as the CmpFrame, and then attempt to cast this Frame into the class
- indicated by "obj". */
- } else {
- this = (AstFrame *) this_object;
-
-/* Create a basic Frame with the right number of axes. */
- naxes = astGetNaxes( this );
- cfrm = astFrame( naxes, " ", status );
-
-/* Replace the Axis structures in the basic Frame with those in the
- CmpFrame. */
- for( i = 0; i < naxes; i++ ) {
- newaxis = astGetAxis( this, i );
- astSetAxis( cfrm, i, newaxis );
- newaxis = astAnnul( newaxis );
- }
-
-/* Overlay the properties of the CmpFrame onto the basic Frame. */
- astOverlay( this, NULL, cfrm );
-
-/* Try to cast the basic Frame to the class of "obj". */
- new = astCast( cfrm, obj );
-
-/* Annull the basic Frame. */
- cfrm = astAnnul( cfrm );
- }
-
-/* Return the new pointer. */
- return new;
-}
-
-static double Centre( AstFrame *this_frame, int axis, double value, double gap, int *status ) {
-/*
-* Name:
-* Centre
-
-* Purpose:
-* Find a "nice" central value for tabulating CmpFrame axis values.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* double Centre( AstFrame *this_frame, int axis, double value,
-* double gap, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the protected astCentre method
-* inherited from the Frame class).
-
-* Description:
-* This function returns an axis value which produces a nice formatted
-* value suitable for a major tick mark on a plot axis, close to the
-* supplied axis value.
-
-* Parameters:
-* this
-* Pointer to the Frame.
-* axis
-* The number of the axis (zero-based) for which a central value
-* is to be found.
-* value
-* An arbitrary axis value in the section that is being plotted.
-* gap
-* The gap size.
-
-* Returned Value:
-* The nice central axis value.
-
-* Notes:
-* - A value of zero is returned if the supplied gap size is zero.
-* - 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.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to CmpFrame structure */
- AstFrame *frame; /* Pointer to Frame containing axis */
- double result; /* Result value to return */
- int naxes1; /* Number of axes in frame1 */
- int set1; /* Digits attribute set? */
- int set2; /* Format attribute set? */
-
-/* Initialise. */
- result = 0.0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Validate and permute the axis index supplied. */
- axis = astValidateAxis( this, axis, 1, "astCentre" );
-
-/* Determine the number of axes in the first component Frame. */
- naxes1 = astGetNaxes( this->frame1 );
- if ( astOK ) {
-
-/* Decide which component Frame contains the axis and adjust the axis
- index if necessary. */
- frame = ( axis < naxes1 ) ? this->frame1 : this->frame2;
- axis = ( axis < naxes1 ) ? axis : axis - naxes1;
-
-/* Since the component Frame is "managed" by the enclosing CmpFrame,
- we next test if any Frame attributes which may affect the result
- are undefined (i.e. have not been explicitly set). If so, we
- over-ride them, giving them temporary values dictated by the
- CmpFrame. Only the Digits and Format attributes are relevant here. */
- set1 = astTestDigits( frame );
- if ( !set1 ) astSetDigits( frame, astGetDigits( this ) );
-
- set2 = astTestFormat( frame, axis );
- if ( !set2 ) astSetFormat( frame, axis, astGetFormat( this, axis ) );
-
-/* Invoke the Frame's astCentre method to find the central value. */
- result = astCentre( frame, axis, value, gap );
-
-/* Clear Frame attributes which were temporarily over-ridden. */
- if ( !set1 ) astClearDigits( frame );
- if ( !set2 ) astClearFormat( frame, axis );
- }
-
-/* If an error occurred, clear the returned value. */
- if ( !astOK ) result = 0.0;
-
-/* Return the result. */
- return result;
-}
-
-static void ClearAlignSystem( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* ClearAlignSystem
-
-* Purpose:
-* Clear the value of the AlignSystem attribute for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void ClearAlignSystem( AstFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astClearAlignSystem method
-* inherited from the Frame class).
-
-* Description:
-* This function clears the AlignSystem value in the component Frames as
-* well as this CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Invoke the parent method to clear the CmpFrame AlignSystem value. */
- (*parent_clearalignsystem)( this_frame, status );
-
-/* Now clear the AlignSystem attribute in the two component Frames. */
- astClearAlignSystem( this->frame1 );
- astClearAlignSystem( this->frame2 );
-}
-
-static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) {
-/*
-* Name:
-* ClearAttrib
-
-* Purpose:
-* Clear an attribute value for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void ClearAttrib( AstObject *this, const char *attrib, int *status )
-
-* Class Membership:
-* CmpFrame 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
-* CmpFrame, so that the default value will subsequently be used.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* 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: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- AstFrame *pfrm; /* Pointer to primary Frame containing axis */
- char buf1[80]; /* For for un-indexed attribute name */
- char buf2[80]; /* For for indexed attribute name */
- int axis; /* Sipplied (1-based) axis index */
- int len; /* Length of attrib string */
- int nc; /* Number of characters used so dar */
- int oldrep; /* Original error reporting state */
- int paxis; /* Index of primary Frame axis */
- int ok; /* Has the attribute been accessed succesfully? */
-
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_object;
-
-/* Obtain the length of the "attrib" string. */
- len = strlen( attrib );
-
-/* Indicate we have not yet acessed the attribute succesfully. */
- ok = 0;
-
-/* First check the supplied attribute name against each of the attribute
- names defined by this class. In fact there is nothing to do here
- since the CmpFrame class currently defines no extra attributes, but
- this may change in the future. */
- if( 0 ) {
-
-
-
-/* If the attribute is not a CmpFrame specific attribute... */
- } else if( astOK ) {
-
-/* We want to allow easy access to the attributes of the component Frames.
- That is, we do not want it to be necessary to extract a Frame from
- its parent CmpFrame in order to access its attributes. For this reason
- we first temporarily switch off error reporting so that if an attempt
- to access the attribute fails, we can try a different approach. */
- oldrep = astReporting( 0 );
-
-/* Our first attempt is to see if the attribute is recognised by the parent
- class (Frame). */
- (*parent_clearattrib)( this_object, attrib, status );
-
-/* Indicate success. */
- if( astOK ) {
- ok = 1;
-
-/* Otherwise, clear the error condition so that we can try a different
- approach. */
- } else {
- astClearStatus;
-
-/* If the attribute is qualified by an axis index, try accessing it as an
- attribute of the primary Frame containing the specified index. */
- if ( nc = 0,
- ( 2 == astSscanf( attrib, "%[^(](%d)%n", buf1, &axis, &nc ) )
- && ( nc >= len ) ) {
-
-/* Find the primary Frame containing the specified axis. */
- astPrimaryFrame( this, axis - 1, &pfrm, &paxis );
- if( astOK ) {
-
-/* astPrimaryFrame returns the original - unpermuted - axis index within
- the primary Frame. So we need to take into account any axis permutation
- which has been applied to the primary Frame when forming the attribute name
- to use below. Find the permuted (external) axis index which corresponds to
- the internal (unpermuted) axis index "paxis". */
- paxis = astValidateAxis( pfrm, paxis, 0, "astClear" );
-
-/* Create a new attribute with the same name but with the axis index
- appropriate to the primary Frame. */
- sprintf( buf2, "%s(%d)", buf1, paxis + 1 );
-
-/* Attempt to access the attribute. */
- astClearAttrib( pfrm, buf2 );
-
-/* Indicate success. */
- if( astOK ) {
- ok = 1;
-
-/* Otherwise clear the status value, and try again without any axis index. */
- } else {
- astClearStatus;
- astClearAttrib( pfrm, buf1 );
-
-/* Indicate success, or clear the status value. */
- if( astOK ) {
- ok = 1;
- } else {
- astClearStatus;
- }
- }
-
-/* Free the primary frame pointer. */
- pfrm = astAnnul( pfrm );
- }
-
-/* If the attribute is not qualified by an axis index, try accessing it
- using the primary Frame of each axis in turn. */
- } else {
-
-/* Loop round all axes attribute. */
- for( axis = 0; axis < astGetNaxes( this ); axis++ ) {
-
-/* Get the primary Frame containing this axis. */
- astPrimaryFrame( this, axis, &pfrm, &paxis );
-
-/* Attempt to access the attribute as an attribute of the primary Frame. */
- astClearAttrib( pfrm, attrib );
-
-/* Free the primary Frame pointer. */
- pfrm = astAnnul( pfrm );
-
-/* Indicate success, or clear the status value. */
- if( astOK ) {
- ok = 1;
- } else {
- astClearStatus;
- }
- }
- }
- }
-
-/* Re-instate the original error reporting state. */
- astReporting( oldrep );
-
- }
-
-/* Report an error if the attribute could not be accessed. */
- if( !ok && astOK ) {
- astError( AST__BADAT, "astClear: The %s given does not have an attribute "
- "called \"%s\".", status, astGetClass( this ), attrib );
- }
-
-}
-
-static void ClearDut1( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* ClearDut1
-
-* Purpose:
-* Clear the value of the Dut1 attribute for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void ClearDut1( AstFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astClearDut1 method
-* inherited from the Frame class).
-
-* Description:
-* This function clears the Dut1 value in the component Frames as
-* well as this CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Invoke the parent method to clear the CmpFrame Dut1 value. */
- (*parent_cleardut1)( this_frame, status );
-
-/* Now clear the Dut1 attribute in the two component Frames. */
- astClearDut1( this->frame1 );
- astClearDut1( this->frame2 );
-}
-
-static void ClearEpoch( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* ClearEpoch
-
-* Purpose:
-* Clear the value of the Epoch attribute for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void ClearEpoch( AstFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astClearEpoch method
-* inherited from the Frame class).
-
-* Description:
-* This function clears the Epoch value in the component Frames as
-* well as this CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Invoke the parent method to clear the CmpFrame epoch. */
- (*parent_clearepoch)( this_frame, status );
-
-/* Now clear the Epoch attribute in the two component Frames. */
- astClearEpoch( this->frame1 );
- astClearEpoch( this->frame2 );
-}
-
-static void ClearObsAlt( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* ClearObsAlt
-
-* Purpose:
-* Clear the value of the ObsAlt attribute for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void ClearObsAlt( AstFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astClearObsAlt method
-* inherited from the Frame class).
-
-* Description:
-* This function clears the ObsAlt value in the component Frames as
-* well as this CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Invoke the parent method to clear the CmpFrame ObsAlt. */
- (*parent_clearobsalt)( this_frame, status );
-
-/* Now clear the ObsAlt attribute in the two component Frames. */
- astClearObsAlt( this->frame1 );
- astClearObsAlt( this->frame2 );
-}
-
-static void ClearObsLat( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* ClearObsLat
-
-* Purpose:
-* Clear the value of the ObsLat attribute for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void ClearObsLat( AstFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astClearObsLat method
-* inherited from the Frame class).
-
-* Description:
-* This function clears the ObsLat value in the component Frames as
-* well as this CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Invoke the parent method to clear the CmpFrame ObsLat. */
- (*parent_clearobslat)( this_frame, status );
-
-/* Now clear the ObsLat attribute in the two component Frames. */
- astClearObsLat( this->frame1 );
- astClearObsLat( this->frame2 );
-}
-
-static void ClearObsLon( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* ClearObsLon
-
-* Purpose:
-* Clear the value of the ObsLon attribute for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void ClearObsLon( AstFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astClearObsLon method
-* inherited from the Frame class).
-
-* Description:
-* This function clears the ObsLon value in the component Frames as
-* well as this CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Invoke the parent method to clear the CmpFrame ObsLon. */
- (*parent_clearobslon)( this_frame, status );
-
-/* Now clear the ObsLon attribute in the two component Frames. */
- astClearObsLon( this->frame1 );
- astClearObsLon( this->frame2 );
-}
-
-static int ComponentMatch( AstCmpFrame *template, AstFrame *target, int matchsub,
- int icomp, int **template_axes, int **target_axes,
- AstMapping **map, AstFrame **result, int *status ) {
-/*
-* Name:
-* ComponentMatch
-
-* Purpose:
-* Determine if conversion is possible between a component Frame in a
-* template CmpFrame and another target Frame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* int ComponentMatch( AstCmpFrame *template, AstFrame *target, int matchsub,
-* int icomp, int **template_axes, int **target_axes,
-* AstMapping **map, AstFrame **result, int *status )
-
-* Class Membership:
-* CmpFrame member function
-
-* Description:
-* This function is like astMatch, but it compares the supplied target
-* Frame with a specified component Frame of the supplied template
-* CmpFrame, rather than with the entire template CmpFrame. If a match
-* is found, the returned Mapping, Frame and axis lists are adjusted so
-* that they refer to the entire template CmpFrame.
-
-* Parameters:
-* template
-* Pointer to the template CmpFrame. 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 (i.e. if the
-* target is of a more specialised class than the template). In
-* this latter case, the target is cast down to the class of the
-* template.
-* icomp
-* The index of the component Frame to use within the template
-* CmpFrame; 0 or 1.
-* 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 (zero-based) index of the
-* template CmpFrame axis from which it is derived. If it is not
-* derived from any template 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 (zero-based) index of the
-* target Frame axis from which it is derived. If it is not
-* derived from any target 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 Frame and the template
-* CmpFrame. 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:
-* - By default, the "result" Frame will have its number of axes
-* and axis order determined by the "template" CmpFrame. However,
-* if the PreserveAxes attribute of the template CmpFrame is
-* non-zero, then the axis count and axis order of the "target"
-* Frame will be used instead.
-* - 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.
-*/
-
-/* Local Variables: */
- AstFrame *ctemplate;
- AstFrame *fother;
- AstFrame *fresult;
- AstMapping *fmap;
- AstPermMap *pm;
- const int *perm;
- int *ftarget_axes;
- int *ftemplate_axes;
- int *inperm;
- int *operm;
- int *outperm;
- int axis;
- int match;
- int nax1;
- int nax2;
- int naxr;
- int prax;
- int praxo;
- int result_naxes;
- int template_naxes;
-
-/* 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;
-
-/* Get a pointer to the requested component Frame of the template CmpFrame. */
- ctemplate = icomp ? template->frame2 :template->frame1;
-
-/* Temporarily set the component Frame PreserveAxes value to that of the
- template CmpFrame. PreserveAxes determines whether astMatch returns a
- result Frame that looks like the template or the target. */
- if( astTestPreserveAxes( ctemplate ) ) {
- praxo = astGetPreserveAxes( ctemplate ) ? 1 : 0;
- } else {
- praxo = -1;
- }
- prax = astGetPreserveAxes( template );
- astSetPreserveAxes( ctemplate, prax );
-
-/* Attempt to find a match between the axes of the supplied target Frame
- and the axes of the selected component Frame in the template. */
- match = astMatch( ctemplate, target, matchsub, &ftemplate_axes, &ftarget_axes,
- &fmap, &fresult );
-
-/* Restore the original PreserveAxes value in the component template
- Frame. */
- if( praxo == -1 ) {
- astClearPreserveAxes( ctemplate );
- } else {
- astSetPreserveAxes( ctemplate, praxo );
- }
-
-/* If a match was found, we need to adjust the Mapping, Frame and axis
- lists returned by the above call to astMatch so that they refer to the
- full template CmpFrame or target (depending on PreserveAxes). */
- if( match ) {
-
-/* Get the number of axes in each component Frame and the total number of
- axes in the template CmpFrame. */
- nax1 = astGetNaxes( template->frame1 );
- nax2 = astGetNaxes( template->frame2 );
- template_naxes = nax1 + nax2;
-
-/* Get the axis permutation array from the template and get its inverse.
- The "perm" array holds the internal axis index at each external axis
- index. The "operm" array holds the external axis index at each
- internal axis index. */
- perm = astGetPerm( template );
- operm = astMalloc( sizeof( int )*(size_t)template_naxes );
- if( astOK) {
- for( axis = 0; axis < template_naxes; axis++ ) {
- operm[ perm[ axis ] ] = axis;
- }
-
-/* The PreserveAxes attribute is used by astMatch to decide whether the
- result Frame should inherit its axes from the target frame or the
- template frame. First deal with cases where the order and count of axes
- in the result frame is the same as the target. */
- if( prax ) {
-
-/* Return the result Frame and Mapping unchanged since they already refer
- to the full target Frame used in the above call to astMatch. */
- *result = astClone( fresult );
- *map = astClone( fmap );
-
-/* Also return the lists of target axes unchanged. */
- *target_axes = ftarget_axes;
-
-/* The values in the template axes list refer to the component template
- Frame, but we want to return values that refer to the full template
- CmpFrame. This involve sup to two setps 1) for the second component
- Frame only, increase the axis numbers by the number of axes in the
- first component Frame, and 2) take account of any axis permutation in
- the template. First allocate memory for the returned list (which,
- because PreserveAxes is zero, will have an entry for each template axis). */
- *template_axes = astMalloc( sizeof( int )*template_naxes );
-
-/* Now, if the second component of the template has been selected, increment
- the template axes so that they give the internal axis indices of the
- second component Frame within the CmpFrame. The first component axes
- will be unchanged. */
- result_naxes = astGetNaxes( fresult );
- if( icomp ) {
- for( axis = 0; axis < result_naxes; axis++ ) {
- ftemplate_axes[ axis ] += nax1;
- }
- }
-
-/* Now copy the internal axis value into the returned array, modifying them
- in the process from internal to external axis ordering. */
- for( axis = 0; axis < result_naxes; axis++ ) {
- (*template_axes)[ axis ] = operm[ ftemplate_axes[ axis ] ];
- }
-
-/* If the order and count of axes in the result frame is the same as the
- template CmpFrame... */
- } else {
-
-/* We need to adjust the Mapping, Frame and axis lists returned by the
- above call to astMatch so that they refer to the supplied template
- CmpFrame rather than to the selected component Frame. Get the number
- of axes in the result Frame returned by astMatch (naxr) and the number
- in the result Frame returned by this function (result-naxes). */
- naxr = astGetNaxes( fresult );
- result_naxes = ( icomp ? nax1 : nax2 ) + naxr;
-
-/* Create the full result Frame by combining the partial result Frame
- returned by astMatch above with the other component Frame from the
- template. */
- if( icomp ) {
- fother = astCopy( template->frame1 );
- *result = (AstFrame *) astCmpFrame( fother, fresult, "", status );
- } else {
- fother = astCopy( template->frame2 );
- *result = (AstFrame *) astCmpFrame( fresult, fother, "", status );
- }
- fother = astAnnul( fother );
-
-/* Modify the Mapping returned by the above call to astMatch so that it
- produces positions within the full result Frame created above. */
- if( icomp ) {
- inperm = astMalloc( sizeof( int )*(size_t) naxr );
- outperm = astMalloc( sizeof( int )*(size_t) result_naxes );
- if( astOK ) {
- for( axis = 0; axis < nax1; axis++ ) outperm[ axis ] = -1;
- for( axis = 0; axis < naxr; axis++ ) {
- outperm[ axis + nax1 ] = axis;
- inperm[ axis ] = axis + nax1;
- }
- }
-
- } else {
- inperm = NULL;
- outperm = NULL;
- }
-
- pm = astPermMap( naxr, inperm, result_naxes, outperm, NULL, "", status );
- *map = (AstMapping *) astCmpMap( fmap, pm, 1, "", status );
-
-/* Free resources. */
- pm = astAnnul( pm );
- if( inperm ) inperm = astFree( inperm );
- if( outperm ) outperm = astFree( outperm );
-
-/* Allocate memory for the returned list of axes. */
- *template_axes = astMalloc( sizeof( int )*(size_t)result_naxes );
- *target_axes = astMalloc( sizeof( int )*(size_t)result_naxes );
-
-/* The axis indices returned by astMatch above will refer to the selected
- component Frame rather than the permuted (i.e. external) axis indices for
- the template CmpFrame. Change the template axes list so that they describe
- the axes in the full result Frame in terms of the external template axis
- numbering. This involves shifting the indices for the second component
- Frame to leave room for the axes of the first component Frame, and
- also permuting the axis indices from internal to external order. */
- if( icomp ) {
- for( axis = 0; axis < nax1; axis++ ) {
- (*template_axes)[ axis ] = operm[ axis ];
- }
-
- for( ; axis < result_naxes; axis++ ) {
- (*template_axes)[ axis ] = operm[ nax1 + ftemplate_axes[ axis - nax1 ] ];
- }
-
- } else {
- for( axis = 0; axis < nax1; axis++ ) {
- (*template_axes)[ axis ] = operm[ ftemplate_axes[ axis ] ];
- }
-
- for( ; axis < result_naxes; axis++ ) {
- (*template_axes)[ axis ] = operm[ axis ];
- }
- }
-
-/* Change the target axes list so that they describe the axes in the
- full result Frame (this just means padding with -1 to indicate that
- the extra axes do not correspond to any axis in the target). */
- for( axis = 0; axis < naxr; axis++ ) {
- (*target_axes)[ axis ] = ftarget_axes[ axis ];
- }
-
- for( ; axis < result_naxes; axis++ ) {
- (*target_axes)[ axis ] = -1;
- }
-
-/* Free resources */
- ftarget_axes = astFree( ftarget_axes );
- }
- }
-
- operm = astFree( operm );
- ftemplate_axes = astFree( ftemplate_axes );
- fmap = astAnnul( fmap );
- fresult = astAnnul( fresult );
-
- }
-
-/* If an error occurred, free all allocated memory, annul the result
- Object pointers and clear all returned values. */
- if ( !astOK ) {
- *template_axes = astFree( *template_axes );
- *target_axes = astFree( *target_axes );
- *map = astAnnul( *map );
- *result = astAnnul( *result );
- match = 0;
- }
-
-/* Return the result. */
- return match;
-}
-
-static void Decompose( AstMapping *this_cmpframe, AstMapping **map1,
- AstMapping **map2, int *series, int *invert1,
- int *invert2, int *status ) {
-/*
-*
-* Name:
-* Decompose
-
-* Purpose:
-* Decompose a CmpFrame into two component CmpFrames.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "mapping.h"
-* void Decompose( AstMapping *this, AstMapping **map1,
-* AstMapping **map2, int *series,
-* int *invert1, int *invert2, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the protected astDecompose
-* method inherited from the Mapping class).
-
-* Description:
-* This function returns pointers to two Mappings which, when applied
-* either in series or parallel, are equivalent to the supplied Mapping.
-*
-* Since the Frame class inherits from the Mapping class, Frames can
-* be considered as special types of Mappings and so this method can
-* be used to decompose either CmpMaps or CmpFrames.
-
-* Parameters:
-* this
-* Pointer to the Mapping.
-* map1
-* Address of a location to receive a pointer to first component
-* Mapping.
-* map2
-* Address of a location to receive a pointer to second component
-* Mapping.
-* series
-* Address of a location to receive a value indicating if the
-* component Mappings are applied in series or parallel. A non-zero
-* value means that the supplied Mapping is equivalent to applying map1
-* followed by map2 in series. A zero value means that the supplied
-* Mapping is equivalent to applying map1 to the lower numbered axes
-* and map2 to the higher numbered axes, in parallel.
-* invert1
-* The value of the Invert attribute to be used with map1.
-* invert2
-* The value of the Invert attribute to be used with map2.
-* status
-* Pointer to the inherited status variable.
-
-* Notes:
-* - Any changes made to the component rames using the returned
-* pointers will be reflected in the supplied CmpFrame.
-
-*-
-*/
-
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to CmpMap structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpMap structure. */
- this = (AstCmpFrame *) this_cmpframe;
-
-/* The components Frames of a CmpFrame are considered to be parallel
- Mappings. */
- if( series ) *series = 0;
-
-/* The Frames are returned in their original order whether or not the
- CmpFrame has been inverted. */
- if( map1 ) *map1 = astClone( this->frame1 );
- if( map2 ) *map2 = astClone( this->frame2 );
-
-/* If the CmpFrame has been inverted, return inverted Invert flags. */
- if( astGetInvert( this ) ) {
- if( invert1 ) *invert1 = astGetInvert( this->frame1 ) ? 0 : 1;
- if( invert2 ) *invert2 = astGetInvert( this->frame2 ) ? 0 : 1;
-
-/* If the CmpFrame has not been inverted, return the current Invert flags. */
- } else {
- if( invert1 ) *invert1 = astGetInvert( this->frame1 );
- if( invert2 ) *invert2 = astGetInvert( this->frame2 );
- }
-}
-
-static double Distance( AstFrame *this_frame,
- const double point1[], const double point2[], int *status ) {
-/*
-* Name:
-* Distance
-
-* Purpose:
-* Calculate the distance between two points.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* double Distance( AstFrame *this,
-* const double point1[], const double point2[], int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astDistance method
-* inherited from the Frame class).
-
-* Description:
-* This function finds the distance between two points whose
-* CmpFrame coordinates are given. The distance calculated is that
-* along the geodesic curve that joins the two points. This is
-* computed as the Cartesian sum of the distances between the
-* points when their coordinates are projected into each of the
-* CmpFrame's component Frames.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* point1
-* An array of double, with one element for each CmpFrame axis,
-* containing the coordinates of the first point.
-* point2
-* An array of double, with one element for each CmpFrame axis,
-* containing the coordinates of the second point.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The distance between the two points.
-
-* Notes:
-* - This function will return a "bad" result value (AST__BAD) if
-* any of the input coordinates has this value.
-* - A "bad" value will also be returned if this function is
-* invoked with the AST error status set or if it should fail for
-* any reason.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to CmpFrame structure */
- const int *perm; /* Axis permutation array */
- double *p1; /* Pointer to permuted point1 coordinates */
- double *p2; /* Pointer to permuted point2 coordinates */
- double dist1; /* Distance in frame1 */
- double dist2; /* Distance in frame2 */
- double result; /* Value to return */
- int axis; /* Loop counter for axes */
- int naxes1; /* Number of axes in frame1 */
- int naxes; /* Number of axes in CmpFrame */
- int ok; /* No "bad" coordinates found? */
-
-/* Initialise. */
- result = AST__BAD;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Obtain a pointer to the CmpFrame's axis permutation array. */
- perm = astGetPerm( this );
-
-/* Obtain the number of axes in the CmpFrame and in the first
- component Frame. */
- naxes = astGetNaxes( this );
- naxes1 = astGetNaxes( this->frame1 );
-
-/* Allocate memory to hold the permuted coordinates of each point. */
- p1 = astMalloc( sizeof( double ) * (size_t) naxes );
- p2 = astMalloc( sizeof( double ) * (size_t) naxes );
- if ( astOK ) {
-
-/* Examine the coordinates of both points and note if any coordinate
- value is "bad". */
- ok = 1;
- for ( axis = 0; axis < naxes; axis++ ) {
- if ( ( point1[ axis ] == AST__BAD ) ||
- ( point2[ axis ] == AST__BAD ) ) {
- ok = 0;
- break;
-
-/* Permute good coordinates using the CmpFrame's axis permutation
- array to put them into the order required internally (i.e. by the
- two component Frames). */
- } else {
- p1[ perm[ axis ] ] = point1[ axis ];
- p2[ perm[ axis ] ] = point2[ axis ];
- }
- }
-
-/* If no "bad" coordinates were found, obtain the distance between the
- two points when their coordinates are projected into each component
- Frame. */
- if ( ok ) {
- dist1 = astDistance( this->frame1, p1, p2 );
- dist2 = astDistance( this->frame2, p1 + naxes1, p2 + naxes1 );
-
-/* If the distances found were OK, compute the distance between the
- two points as the Cartesian sum of the two component distances. */
- if ( astOK && ( dist1 != AST__BAD ) && ( dist2 != AST__BAD ) ) {
- result = sqrt( ( dist1 * dist1 ) + ( dist2 * dist2 ) );
- }
- }
- }
-
-/* Free the memory used for the permuted coordinates. */
- p1 = astFree( p1 );
- p2 = astFree( p2 );
-
-/* If an error occurred, clear the result value. */
- if ( !astOK ) result = AST__BAD;
-
-/* Return the result. */
- return result;
-}
-
-static int Fields( AstFrame *this_frame, int axis, const char *fmt,
- const char *str, int maxfld, char **fields,
- int *nc, double *val, int *status ) {
-/*
-*+
-* Name:
-* astFields
-
-* Purpose:
-* Identify numerical fields within a formatted CmpFrame axis value.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* int astFields( AstFrame *this, int axis, const char *fmt,
-* const char *str, int maxfld, char **fields,
-* int *nc, double *val )
-
-* Class Membership:
-* CmpFrame member function (over-rides the protected astFields
-* method inherited from the Frame class).
-
-* Description:
-* This function identifies the numerical fields within a CmpFrame axis
-* value that has been formatted using astAxisFormat. It assumes that
-* the value was formatted using the supplied format string. It also
-* returns the equivalent floating point value.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* axis
-* The number of the CmpFrame axis for which the values have been
-* formatted (axis numbering starts at zero for the first axis).
-* fmt
-* Pointer to a constant null-terminated string containing the
-* format used when creating "str".
-* str
-* Pointer to a constant null-terminated string containing the
-* formatted value.
-* maxfld
-* The maximum number of fields to identify within "str".
-* fields
-* A pointer to an array of at least "maxfld" character pointers.
-* Each element is returned holding a pointer to the start of the
-* corresponding field in "str" (in the order in which they occur
-* within "str"), or NULL if no corresponding field can be found.
-* nc
-* A pointer to an array of at least "maxfld" integers. Each
-* element is returned holding the number of characters in the
-* corresponding field, or zero if no corresponding field can be
-* found.
-* val
-* Pointer to a location at which to store the value
-* equivalent to the returned field values. If this is NULL,
-* it is ignored.
-
-* Returned Value:
-* The number of fields succesfully identified and returned.
-
-* Notes:
-* - Leading and trailing spaces are ignored.
-* - If the formatted value is not consistent with the supplied format
-* string, then a value of zero will be returned, "fields" will be
-* returned holding NULLs, "nc" will be returned holding zeros, and
-* "val" is returned holding VAL__BAD.
-* - Fields are counted from the start of the formatted string. If the
-* string contains more than "maxfld" fields, then trailing fields are
-* ignored.
-* - If this function is invoked with the global error status set, or
-* if it should fail for any reason, then a value of zero will be returned
-* as the function value, and "fields", "nc" and "val" will be returned
-* holding their supplied values
-*-
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to CmpFrame structure */
- AstFrame *frame; /* Pointer to Frame containing axis */
- int naxes1; /* Number of axes in frame1 */
- int result; /* Result field count to return */
-
-/* Initialise. */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Validate and permute the axis index supplied. */
- axis = astValidateAxis( this, axis, 1, "astFields" );
-
-/* Determine the number of axes in the first component Frame. */
- naxes1 = astGetNaxes( this->frame1 );
- if ( astOK ) {
-
-/* Decide which component Frame contains the axis and adjust the axis
- index if necessary. */
- frame = ( axis < naxes1 ) ? this->frame1 : this->frame2;
- axis = ( axis < naxes1 ) ? axis : axis - naxes1;
-
-/* Invoke the Frame's astFields method to perform the processing. */
- result = astFields( frame, axis, fmt, str, maxfld, fields,
- nc, val );
- }
-
-/* If an error occurred, clear the returned value. */
- if ( !astOK ) result = 0;
-
-/* Return the result. */
- return result;
-}
-
-static const char *Format( AstFrame *this_frame, int axis, double value, int *status ) {
-/*
-* Name:
-* Format
-
-* Purpose:
-* Format a coordinate value for a CmpFrame axis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* const char *Format( AstFrame *this, int axis, double value, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astFormat method
-* inherited from the Frame class).
-
-* Description:
-* This function returns a pointer to a string containing the
-* formatted (character) version of a coordinate value for a
-* CmpFrame axis. The formatting applied is that specified by a
-* previous invocation of the astSetFormat method (or a default
-* format appropriate to the axis in question).
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* axis
-* The number of the axis (zero-based) for which formatting is
-* to be performed.
-* value
-* The coordinate value to be formatted.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A pointer to a null-terminated string containing the formatted
-* 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: */
- AstCmpFrame *this; /* Pointer to CmpFrame structure */
- AstFrame *frame; /* Pointer to Frame containing axis */
- const char *result; /* Pointer value to return */
- int naxes1; /* Number of axes in frame1 */
- int set; /* Digits attribute set? */
-
-/* Initialise. */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Validate and permute the axis index supplied. */
- axis = astValidateAxis( this, axis, 1, "astFormat" );
-
-/* Determine the number of axes in the first component Frame. */
- naxes1 = astGetNaxes( this->frame1 );
- if ( astOK ) {
-
-/* Decide which component Frame contains the axis and adjust the axis
- index if necessary. */
- frame = ( axis < naxes1 ) ? this->frame1 : this->frame2;
- axis = ( axis < naxes1 ) ? axis : axis - naxes1;
-
-/* Since the component Frame is "managed" by the enclosing CmpFrame,
- we next test if any Frame attributes which may affect the result
- are undefined (i.e. have not been explicitly set). If so, we
- over-ride them, giving them temporary values dictated by the
- CmpFrame. Only the Digits attribute is relevant here. */
- set = astTestDigits( frame );
- if ( !set ) astSetDigits( frame, astGetDigits( this ) );
-
-/* Invoke the Frame's astFormat method to format the value. */
- result = astFormat( frame, axis, value );
-
-/* Clear Frame attributes which were temporarily over-ridden. */
- if ( !set ) astClearDigits( frame );
- }
-
-/* If an error occurred, clear the result value. */
- if ( !astOK ) result = NULL;
-
-/* Return the result. */
- return result;
-}
-
-static AstPointSet *FrameGrid( AstFrame *this_object, int size, const double *lbnd,
- const double *ubnd, int *status ){
-/*
-* Name:
-* FrameGrid
-
-* Purpose:
-* Return a grid of points covering a rectangular area of a Frame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* AstPointSet *FrameGrid( AstFrame *this_frame, int size,
-* const double *lbnd, const double *ubnd,
-* int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the protected astFrameGrid
-* method inherited from the Frame class).
-
-* Description:
-* This function returns a PointSet containing positions spread
-* approximately evenly throughtout a specified rectangular area of
-* the Frame.
-
-* Parameters:
-* this
-* Pointer to the Frame.
-* size
-* The preferred number of points in the returned PointSet. The
-* actual number of points in the returned PointSet may be
-* different, but an attempt is made to stick reasonably closely to
-* the supplied value.
-* lbnd
-* Pointer to an array holding the lower bound of the rectangular
-* area on each Frame axis. The array should have one element for
-* each Frame axis.
-* ubnd
-* Pointer to an array holding the upper bound of the rectangular
-* area on each Frame axis. The array should have one element for
-* each Frame axis.
-
-* Returned Value:
-* A pointer to a new PointSet holding the grid of points.
-
-* Notes:
-* - A NULL pointer is returned if an error occurs.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this;
- AstPointSet *ps1;
- AstPointSet *ps2;
- AstPointSet *result;
- const int *perm;
- double **ptr1;
- double **ptr2;
- double **ptr;
- double *lbnd1;
- double *lbnd2;
- double *p;
- double *ubnd1;
- double *ubnd2;
- double v;
- int axis;
- int iax1;
- int iax2;
- int iaxis;
- int ip1;
- int ip2;
- int nax1;
- int nax2;
- int naxes;
- int npoint1;
- int npoint2;
- int npoint;
- int size1;
- int size2;
-
-/* Initialise. */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_object;
-
-/* Get the number of axes in each component Frame, and the total number
- of axes. */
- nax1 = astGetNaxes( this->frame1 );
- nax2 = astGetNaxes( this->frame2 );
- naxes = nax1 + nax2;
-
-/* Allocate memory to hold bounds for each component Frame */
- lbnd1 = astMalloc( nax1*sizeof( double ) );
- ubnd1 = astMalloc( nax1*sizeof( double ) );
- lbnd2 = astMalloc( nax2*sizeof( double ) );
- ubnd2 = astMalloc( nax2*sizeof( double ) );
-
-/* Obtain a pointer to the CmpFrame's axis permutation array. This array
- holds the original axis index for each current Frame axis index. */
- perm = astGetPerm( this );
-
-/* Check pointers can be used safely, and check the supplied size value
- is good. */
- if( astOK && size > 0 ) {
-
-/* Copy the supplied bounds into the work arrays, permuting them in the
- process so that they use the internal axis numbering of the two
- component Frames. */
- for( axis = 0; axis < naxes; axis++ ) {
- iaxis = perm[ axis ];
- if( iaxis < nax1 ) {
- lbnd1[ iaxis ] = lbnd[ axis ];
- ubnd1[ iaxis ] = ubnd[ axis ];
- } else {
- iaxis -= nax1;
- lbnd2[ iaxis ] = lbnd[ axis ];
- ubnd2[ iaxis ] = ubnd[ axis ];
- }
- }
-
-/* Get the target number of points to be used in the grid that covers the
- first Frame. */
- size1 = (int)( pow( size, (double)nax1/(double)naxes ) + 0.5 );
-
-/* Get the target number of points to be used in the grid that covers the
- second Frame. */
- size2 = (int)( (double)size/(double)size1 + 0.5 );
-
-/* Get the grids covering the two component Frames, and get the actual sizes
- of the resulting PointSets. */
- ps1 = astFrameGrid( this->frame1, size1, lbnd1, ubnd1 );
- ptr1 = astGetPoints( ps1 );
- npoint1 = astGetNpoint( ps1 );
-
- ps2 = astFrameGrid( this->frame2, size2, lbnd2, ubnd2 );
- ptr2 = astGetPoints( ps2 );
- npoint2 = astGetNpoint( ps2 );
-
-/* Get the number of points in the returned FrameSet, and then create a
- PointSet large enough to hold them. */
- npoint = npoint1*npoint2;
- result = astPointSet( npoint, naxes, " ", status );
- ptr = astGetPoints( result );
- if( astOK ) {
-
-/* For every point in the first Frame's PointSet, duplicate the second
- Frame's entire PointSet, using the first Frame's axis values. */
- for( ip1 = 0; ip1 < npoint1; ip1++ ) {
- for( iax1 = 0; iax1 < nax1; iax1++ ) {
- p = ptr[ iax1 ];
- v = ptr1[ iax1 ][ ip1 ];
- for( ip2 = 0; ip2 < npoint2; ip2++ ) {
- *(p++) = v;
- }
- ptr[ iax1 ] = p;
- }
- for( iax2 = 0; iax2 < nax2; iax2++ ) {
- memcpy( ptr[ iax2 + nax1 ], ptr2[ iax2 ], npoint2*sizeof( double ) );
- ptr[ iax2 + nax1 ] += npoint2*sizeof( double );
- }
- }
-
-/* Permute the returned PointSet so that it uses external axis numbering. */
- astPermPoints( result, 1, perm );
- }
-
-/* Free resources. */
- ps1 = astAnnul( ps1 );
- ps2 = astAnnul( ps2 );
-
-/* Report error if supplied values were bad. */
- } else if( astOK ) {
- astError( AST__ATTIN, "astFrameGrid(%s): The supplied grid "
- "size (%d) is invalid (programming error).",
- status, astGetClass( this ), size );
- }
-
-/* Free resources. */
- lbnd1 = astFree( lbnd1 );
- ubnd1 = astFree( ubnd1 );
- lbnd2 = astFree( lbnd2 );
- ubnd2 = astFree( ubnd2 );
-
-/* Annul the returned PointSet if an error has occurred. */
- if( !astOK ) result = astAnnul( result );
-
-/* Return the PointSet holding the grid. */
- return result;
-}
-
-static double Gap( AstFrame *this_frame, int axis, double gap, int *ntick, int *status ) {
-/*
-* Name:
-* Gap
-
-* Purpose:
-* Find a "nice" gap for tabulating CmpFrame axis values.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* double Gap( AstFrame *this, int axis, double gap, int *ntick, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the protected astGap method
-* inherited from the Frame class).
-
-* Description:
-* This function returns a gap size which produces a nicely spaced
-* series of formatted values for a CmpFrame axis, the returned gap
-* size being as close as possible to the supplied target gap
-* size. It also returns a convenient number of divisions into
-* which the gap can be divided.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* axis
-* The number of the axis (zero-based) for which a gap is to be found.
-* gap
-* The target gap size.
-* ntick
-* Address of an int in which to return a convenient number of
-* divisions into which the gap can be divided.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The nice gap size.
-
-* Notes:
-* - A value of zero is returned if the target gap size is zero.
-* - A negative gap size is returned if the supplied gap size is negative.
-* - 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.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to CmpFrame structure */
- AstFrame *frame; /* Pointer to Frame containing axis */
- double result; /* Result value to return */
- int naxes1; /* Number of axes in frame1 */
- int set; /* Digits attribute set? */
-
-/* Initialise. */
- result = 0.0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Validate and permute the axis index supplied. */
- axis = astValidateAxis( this, axis, 1, "astGap" );
-
-/* Determine the number of axes in the first component Frame. */
- naxes1 = astGetNaxes( this->frame1 );
- if ( astOK ) {
-
-/* Decide which component Frame contains the axis and adjust the axis
- index if necessary. */
- frame = ( axis < naxes1 ) ? this->frame1 : this->frame2;
- axis = ( axis < naxes1 ) ? axis : axis - naxes1;
-
-/* Since the component Frame is "managed" by the enclosing CmpFrame,
- we next test if any Frame attributes which may affect the result
- are undefined (i.e. have not been explicitly set). If so, we
- over-ride them, giving them temporary values dictated by the
- CmpFrame. Only the Digits attribute is relevant here. */
- set = astTestDigits( frame );
- if ( !set ) astSetDigits( frame, astGetDigits( this ) );
-
-/* Invoke the Frame's astGap method to find the gap size. */
- result = astGap( frame, axis, gap, ntick );
-
-/* Clear Frame attributes which were temporarily over-ridden. */
- if ( !set ) astClearDigits( frame );
- }
-
-/* If an error occurred, clear the returned value. */
- if ( !astOK ) result = 0.0;
-
-/* Return the result. */
- 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 "cmpframe.h"
-* int GetObjSize( AstObject *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astGetObjSize protected
-* method inherited from the parent class).
-
-* Description:
-* This function returns the in-memory size of the supplied CmpFrame,
-* in bytes.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* 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: */
- AstCmpFrame *this; /* Pointer to CmpFrame structure */
- int result; /* Result value to return */
-
-/* Initialise. */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointers to the CmpFrame structure. */
- this = (AstCmpFrame *) 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 );
-
- result += astGetObjSize( this->frame1 );
- result += astGetObjSize( this->frame2 );
- result += astTSizeOf( this->perm );
-
-/* If an error occurred, clear the result value. */
- if ( !astOK ) result = 0;
-
-/* Return the result, */
- return result;
-}
-
-static AstSystemType GetAlignSystem( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* GetAlignSystem
-
-* Purpose:
-* Obtain the AlignSystem attribute for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* AstSystemType GetAlignSystem( AstFrame *this_frame, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astGetAlignSystem protected
-* method inherited from the Frame class).
-
-* Description:
-* This function returns the AlignSystem attribute for a CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The AlignSystem value.
-
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to CmpFrame structure */
- AstSystemType result; /* Value to return */
-
-/* Initialise. */
- result = AST__BADSYSTEM;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) 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__COMP;
- }
-
-/* Return the result. */
- return result;
-}
-
-static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) {
-/*
-* Name:
-* GetAttrib
-
-* Purpose:
-* Get the value of a specified attribute for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "CmpFrame.h"
-* const char *GetAttrib( AstObject *this, const char *attrib, int *status )
-
-* Class Membership:
-* CmpFrame 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 CmpFrame, formatted as a character string.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* 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 CmpFrame, 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 CmpFrame. 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: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- AstFrame *pfrm; /* Pointer to primary Frame containing axis */
- char buf1[80]; /* For for un-indexed attribute name */
- char buf2[80]; /* For for indexed attribute name */
- const char *result; /* Pointer value to return */
- int axis; /* Supplied (1-base) axis index */
- int len; /* Length of attrib string */
- int nc; /* Length of string used so far */
- int ok; /* Has the attribute been accessed succesfully? */
- int oldrep; /* Original error reporting state */
- int paxis; /* Index of primary Frame axis */
-
-/* Initialise. */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_object;
-
-/* Obtain the length of the attrib string. */
- len = strlen( attrib );
-
-/* Indicate we have not yet acessed the attribute succesfully. */
- ok = 0;
-
-/* First check the supplied attribute name against each of the attribute
- names defined by this class. In fact there is nothing to do here
- since the CmpFrame class currently defines no extra attributes, but
- this may change in the future. */
- if( 0 ) {
-
-/* If the attribute is not a CmpFrame specific attribute... */
- } else if( astOK ) {
-
-/* We want to allow easy access to the attributes of the component Frames.
- That is, we do not want it to be necessary to extract a Frame from
- its parent CmpFrame in order to access its attributes. For this reason
- we first temporarily switch off error reporting so that if an attempt
- to access the attribute fails, we can try a different approach. */
- oldrep = astReporting( 0 );
-
-/* If the attribute is qualified by an axis index, try accessing it as an
- attribute of the primary Frame containing the specified index. */
- if ( nc = 0,
- ( 2 == astSscanf( attrib, "%[^(](%d)%n", buf1, &axis, &nc ) )
- && ( nc >= len ) ) {
-
-/* Find the primary Frame containing the specified axis. */
- astPrimaryFrame( this, axis - 1, &pfrm, &paxis );
- if( astOK ) {
-
-/* astPrimaryFrame returns the original - unpermuted - axis index within
- the primary Frame. So we need to take into account any axis permutation
- which has been applied to the primary Frame when forming the attribute name
- to use below. Find the permuted (external) axis index which corresponds to
- the internal (unpermuted) axis index "paxis". */
- paxis = astValidateAxis( pfrm, paxis, 0, "astGet" );
-
-/* Create a new attribute with the same name but with the axis index
- appropriate to the primary Frame. */
- sprintf( buf2, "%s(%d)", buf1, paxis + 1 );
-
-/* Attempt to access the attribute. */
- result = astGetAttrib( pfrm, buf2 );
-
-/* Indicate success. */
- if( astOK ) {
- ok = 1;
-
-/* Otherwise clear the status value, and try again without any axis index. */
- } else {
- astClearStatus;
- result = astGetAttrib( pfrm, buf1 );
-
-/* Indicate success, or clear the status value. */
- if( astOK ) {
- ok = 1;
- } else {
- astClearStatus;
- }
- }
-
-/* Free the primary frame pointer. */
- pfrm = astAnnul( pfrm );
- }
-
-/* If the attribute is not qualified by an axis index, try accessing it
- using the parent Frame method. */
- } else if( astOK ){
- result = (*parent_getattrib)( this_object, attrib, status );
-
-/* Indicate success. */
- if( astOK ) {
- ok = 1;
-
-/* Otherwise, clear the error condition so that we can try a different
- approach. */
- } else {
- astClearStatus;
-
-/* Next try accessing it using the primary Frame of each axis in turn.
- Loop round all axes, until one is found which defines the specified
- attribute. */
- for( axis = 0; axis < astGetNaxes( this ) && !ok; axis++ ) {
-
-/* Get the primary Frame containing this axis. */
- astPrimaryFrame( this, axis, &pfrm, &paxis );
-
-/* Attempt to access the attribute as an attribute of the primary Frame. */
- result = astGetAttrib( pfrm, attrib );
-
-/* Indicate success, or clear the status value. */
- if( astOK ) {
- ok = 1;
- } else {
- astClearStatus;
- }
-
-/* Free the primary Frame pointer. */
- pfrm = astAnnul( pfrm );
-
- }
- }
- }
-
-/* Re-instate the original error reporting state. */
- astReporting( oldrep );
-
- }
-
-/* Report an error if the attribute could not be accessed. */
- if( !ok && astOK ) {
- astError( AST__BADAT, "astGet: The %s given does not have an attribute "
- "called \"%s\".", status, astGetClass( this ), attrib );
- }
-
-/* Return the result. */
- return result;
-
-}
-
-static int GenAxisSelection( int naxes, int nselect, int axes[], int *status ) {
-/*
-* Name:
-* GenAxisSelection
-
-* Purpose:
-* Generate a sequence of axis selections.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* int GenAxisSelection( int naxes, int nselect, int axes[], int *status )
-
-* Class Membership:
-* CmpFrame member function.
-
-* Description:
-* This function generates a sequence of axis selections covering
-* all possible ways of selecting a specified number of axes from a
-* Frame.
-
-* Parameters:
-* naxes
-* The number of axes in the Frame.
-* nselect
-* The number of axes to be selected (between zero and "naxes").
-* axes
-* An array with "nselect" elements. On entry it should contain
-* the (zero-based) indices of the initial set of distinct axes
-* to be selected, in increasing order (initiallly this should
-* just be the sequence [0,1,...nselect-1]). On exit, these
-* indices will be updated to identify the next possible axis
-* selection.
-*
-* By invoking the function repeatedly, and passing this array
-* each time, all possible selections will be covered.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* One if a new axis selection has been returned. Zero if all
-* possible selections have already been returned (in which case
-* the selection returned this time is not valid and should not be
-* used).
-
-* 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.
-*/
-
-/* Local Variables: */
- int i; /* Loop counter for axes */
- int iselect; /* Selection index */
-
-/* Check the global error status. */
- if ( !astOK ) return 0;
-
-/* Start with the first axis index and loop until the selection has
- been updated. */
- iselect = 0;
- while ( 1 ) {
-
-/* Increment the current axis index if it is the final one or it can
- be incremented without equalling the one which follows (this ensures
- the indices remain in increasing order). */
- if ( ( iselect == ( nselect - 1 ) ) ||
- ( axes[ iselect + 1 ] > ( axes[ iselect ] + 1 ) ) ) {
- axes[ iselect ]++;
-
-/* After incrementing an index, reset all previous indices to their
- starting values. */
- for ( i = 0; i < iselect; i++ ) axes[ i ] = i;
- break;
-
-/* If this axis index can't be incremented, consider the next one.
- Quit if we go beyond the end of the selection array. */
- } else if ( ++iselect >= nselect ) {
- break;
- }
- }
-
-/* Return a result to indicate if we've reached the final selection
- (when the final axis index goes out of range). */
- return ( nselect > 0 ) && ( axes[ nselect - 1 ] < naxes );
-}
-
-static AstAxis *GetAxis( AstFrame *this_frame, int axis, int *status ) {
-/*
-* Name:
-* GetAxis
-
-* Purpose:
-* Obtain a pointer to a specified Axis from a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* AstAxis *GetAxis( AstFrame *this, int axis, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astGetAxis method
-* inherited from the Frame class).
-
-* Description:
-* This function returns a pointer to the Axis object associated
-* with one of the axes of a CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* axis
-* The number of the axis (zero-based) for which an Axis pointer
-* is required.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A pointer to the requested Axis object.
-
-* Notes:
-* - The reference count of the requested Axis object will be
-* incremented by one to reflect the additional pointer returned by
-* this function.
-* - 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 Vaiables: */
- AstAxis *result; /* Pointer value to return */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- int naxes1; /* Number of axes for frame1 */
-
-/* Initialise. */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Validate and permute the axis index supplied. */
- axis = astValidateAxis( this, axis, 1, "astGetAxis" );
-
-/* Obtain the number of axes for frame1. */
- naxes1 = astGetNaxes( this->frame1 );
-
-/* Decide which Frame the axis belongs to and obtain the required
- Axis pointer. */
- if ( axis < naxes1 ) {
- result = astGetAxis( this->frame1, axis );
- } else {
- result = astGetAxis( this->frame2, axis - naxes1 );
- }
-
-/* Return the result. */
- return result;
-}
-
-static const char *GetDomain( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* GetDomain
-
-* Purpose:
-* Obtain a pointer to the Domain attribute string for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* const char *GetDomain( AstFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame 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 CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* 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 CmpFrame.
-* - 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: */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
- AstCmpFrame *this; /* Pointer to CmpFrame structure */
- char *dom1; /* Pointer to first sub domain */
- char *dom2; /* Pointer to second sub domain */
- const char *result; /* Pointer value to return */
- const char *t; /* Temporary pointer */
-
-/* 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_frame);
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) 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 {
-
-/* Get the Domain value for the two component Frames and store new
- copies of them. This is necessary because the component Frames may
- themselves be CmpFrames, resulting in this function being called
- recursively and so causing the static "getdomain_buff" array to be used in
- multiple contexts. */
- t = astGetDomain( this->frame1 );
- dom1 = t ? astStore( NULL, t, strlen(t) + 1 ) : NULL;
- t = astGetDomain( this->frame2 );
- dom2 = t ? astStore( NULL, t, strlen(t) + 1 ) : NULL;
-
- if( dom2 ) {
- if( strlen( dom1 ) > 0 || strlen( dom2 ) > 0 ) {
- sprintf( (char *) getdomain_buff, "%s-%s", dom1, dom2 );
- result = getdomain_buff;
- } else {
- result = "CMP";
- }
- }
-
- dom1 = astFree( dom1 );
- dom2 = astFree( dom2 );
- }
-
-/* Return the result. */
- return result;
-}
-
-static int GetMaxAxes( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* GetMaxAxes
-
-* Purpose:
-* Get a value for the MaxAxes attribute of a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* int GetMaxAxes( AstFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astGetMaxAxes method
-* inherited from the Frame class).
-
-* Description:
-* This function returns a value for the MaxAxes attribute of a
-* CmpFrame. A large default value is supplied that is much larger
-* than the maximum likely number of axes in a Frame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The MaxAxes attribute value.
-
-* 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.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- int result; /* Result value to return */
-
-/* Initialise. */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* If a value has been set explicitly for the CmpFrame, return it.
- Otherwise returned a large default value. */
- if( astTestMaxAxes( this ) ) {
- result = (*parent_getmaxaxes)( this_frame, status );
- } else {
- result = 1000000;
- }
-
-/* Return the result. */
- return result;
-}
-
-static int GetMinAxes( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* GetMinAxes
-
-* Purpose:
-* Get a value for the MinAxes attribute of a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* int GetMinAxes( AstFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astGetMinAxes method
-* inherited from the Frame class).
-
-* Description:
-* This function returns a value for the MinAxes attribute of a
-* CmpFrame. A default value of zero is used.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The MinAxes attribute value.
-
-* 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.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- int result; /* Result value to return */
-
-/* Initialise. */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* If a value has been set explicitly for the CmpFrame, return it.
- Otherwise returned a default value of zero. */
- if( astTestMinAxes( this ) ) {
- result = (*parent_getminaxes)( this_frame, status );
- } else {
- result = 0;
- }
-
-/* Return the result. */
- return result;
-}
-
-static double GetDut1( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* GetDut1
-
-* Purpose:
-* Get a value for the Dut1 attribute of a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* double GetDut1( AstFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astGetDut1 method
-* inherited from the Frame class).
-
-* Description:
-* This function returns a value for the Dut1 attribute of a
-* CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The Dut1 attribute value.
-
-* Notes:
-* - A value of AST__BAD will be returned if this function is invoked
-* with the global error status set or if it should fail for any
-* reason.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- double result; /* Result value to return */
-
-/* Initialise. */
- result = AST__BAD;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* If an Dut1 attribute value has been set, invoke the parent method
- to obtain it. */
- if ( astTestDut1( this ) ) {
- result = (*parent_getdut1)( this_frame, status );
-
-/* Otherwise, if the Dut1 value is set in the first component Frame,
- return it. */
- } else if( astTestDut1( this->frame1 ) ){
- result = astGetDut1( this->frame1 );
-
-/* Otherwise, if the Dut1 value is set in the second component Frame,
- return it. */
- } else if( astTestDut1( this->frame2 ) ){
- result = astGetDut1( this->frame2 );
-
-/* Otherwise, return the default Dut1 value from the first component
- Frame. */
- } else {
- result = astGetDut1( this->frame1 );
- }
-
-/* Return the result. */
- return result;
-}
-
-static double GetEpoch( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* GetEpoch
-
-* Purpose:
-* Get a value for the Epoch attribute of a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* double GetEpoch( AstFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astGetEpoch method
-* inherited from the Frame class).
-
-* Description:
-* This function returns a value for the Epoch attribute of a
-* CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The Epoch attribute value.
-
-* Notes:
-* - A value of AST__BAD will be returned if this function is invoked
-* with the global error status set or if it should fail for any
-* reason.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- double result; /* Result value to return */
-
-/* Initialise. */
- result = AST__BAD;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* If an Epoch attribute value has been set, invoke the parent method
- to obtain it. */
- if ( astTestEpoch( this ) ) {
- result = (*parent_getepoch)( this_frame, status );
-
-/* Otherwise, if the Epoch value is set in the first component Frame,
- return it. */
- } else if( astTestEpoch( this->frame1 ) ){
- result = astGetEpoch( this->frame1 );
-
-/* Otherwise, if the Epoch value is set in the second component Frame,
- return it. */
- } else if( astTestEpoch( this->frame2 ) ){
- result = astGetEpoch( this->frame2 );
-
-/* Otherwise, return the default Epoch value from the first component
- Frame. */
- } else {
- result = astGetEpoch( this->frame1 );
- }
-
-/* Return the result. */
- return result;
-}
-
-static double GetObsAlt( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* GetObsAlt
-
-* Purpose:
-* Get a value for the ObsAlt attribute of a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* double GetObsAlt( AstFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astGetObsAlt method
-* inherited from the Frame class).
-
-* Description:
-* This function returns a value for the ObsAlt attribute of a
-* CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The ObsAlt attribute value.
-
-* Notes:
-* - A value of AST__BAD will be returned if this function is invoked
-* with the global error status set or if it should fail for any
-* reason.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- double result; /* Result value to return */
-
-/* Initialise. */
- result = AST__BAD;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* If an ObsAlt attribute value has been set, invoke the parent method
- to obtain it. */
- if ( astTestObsAlt( this ) ) {
- result = (*parent_getobsalt)( this_frame, status );
-
-/* Otherwise, if the ObsAlt value is set in the first component Frame,
- return it. */
- } else if( astTestObsAlt( this->frame1 ) ){
- result = astGetObsAlt( this->frame1 );
-
-/* Otherwise, if the ObsAlt value is set in the second component Frame,
- return it. */
- } else if( astTestObsAlt( this->frame2 ) ){
- result = astGetObsAlt( this->frame2 );
-
-/* Otherwise, return the default ObsAlt value from the first component
- Frame. */
- } else {
- result = astGetObsAlt( this->frame1 );
- }
-
-/* Return the result. */
- return result;
-}
-
-static double GetObsLat( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* GetObsLat
-
-* Purpose:
-* Get a value for the ObsLat attribute of a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* double GetObsLat( AstFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astGetObsLat method
-* inherited from the Frame class).
-
-* Description:
-* This function returns a value for the ObsLat attribute of a
-* CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The ObsLat attribute value.
-
-* Notes:
-* - A value of AST__BAD will be returned if this function is invoked
-* with the global error status set or if it should fail for any
-* reason.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- double result; /* Result value to return */
-
-/* Initialise. */
- result = AST__BAD;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* If an ObsLat attribute value has been set, invoke the parent method
- to obtain it. */
- if ( astTestObsLat( this ) ) {
- result = (*parent_getobslat)( this_frame, status );
-
-/* Otherwise, if the ObsLat value is set in the first component Frame,
- return it. */
- } else if( astTestObsLat( this->frame1 ) ){
- result = astGetObsLat( this->frame1 );
-
-/* Otherwise, if the ObsLat value is set in the second component Frame,
- return it. */
- } else if( astTestObsLat( this->frame2 ) ){
- result = astGetObsLat( this->frame2 );
-
-/* Otherwise, return the default ObsLat value from the first component
- Frame. */
- } else {
- result = astGetObsLat( this->frame1 );
- }
-
-/* Return the result. */
- return result;
-}
-
-static double GetObsLon( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* GetObsLon
-
-* Purpose:
-* Get a value for the ObsLon attribute of a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* double GetObsLon( AstFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astGetObsLon method
-* inherited from the Frame class).
-
-* Description:
-* This function returns a value for the ObsLon attribute of a
-* CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The ObsLon attribute value.
-
-* Notes:
-* - A value of AST__BAD will be returned if this function is invoked
-* with the global error status set or if it should fail for any
-* reason.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- double result; /* Result value to return */
-
-/* Initialise. */
- result = AST__BAD;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* If an ObsLon attribute value has been set, invoke the parent method
- to obtain it. */
- if ( astTestObsLon( this ) ) {
- result = (*parent_getobslon)( this_frame, status );
-
-/* Otherwise, if the ObsLon value is set in the first component Frame,
- return it. */
- } else if( astTestObsLon( this->frame1 ) ){
- result = astGetObsLon( this->frame1 );
-
-/* Otherwise, if the ObsLon value is set in the second component Frame,
- return it. */
- } else if( astTestObsLon( this->frame2 ) ){
- result = astGetObsLon( this->frame2 );
-
-/* Otherwise, return the default ObsLon value from the first component
- Frame. */
- } else {
- result = astGetObsLon( this->frame1 );
- }
-
-/* Return the result. */
- return result;
-}
-
-static int GetNaxes( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* GetNaxes
-
-* Purpose:
-* Determine how many axes a CmpFrame has.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* int GetNaxes( AstFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astGetNaxes method
-* inherited from the Frame class).
-
-* Description:
-* This function returns the number of axes for a CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The number of CmpFrame axes.
-
-* 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.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- int naxes1; /* Number of axes for frame1 */
- int naxes2; /* Number of axes for frame2 */
- int result; /* Number of CmpFrame axes */
-
-/* Initialise. */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Obtain the number of axes for each component Frame. */
- naxes1 = astGetNaxes( this->frame1 );
- naxes2 = astGetNaxes( this->frame2 );
-
-/* If OK, calculate the total number of axes. */
- if ( astOK ) result = naxes1 + naxes2;
-
-/* Return the result. */
- return result;
-}
-
-static const int *GetPerm( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* GetPerm
-
-* Purpose:
-* Access the axis permutation array for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* const int *astGetPerm( AstFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the protected astGetPerm
-* method inherited from the Frame class).
-
-* Description:
-* This function returns a pointer to the axis permutation array
-* for a CmpFrame. This array constitutes a lookup-table that
-* converts between an axis number supplied externally and the
-* corresponding index in the CmpFrame's internal data.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Pointer to the CmpFrame's axis permutation array (a constant
-* array of int). Each element of this contains the (zero-based)
-* internal axis index to be used in place of the external index
-* which is used to address the permutation array. If the CmpFrame
-* has zero axes, this pointer will be NULL.
-
-* Notes:
-* - This protected method is provided to assist class
-* implementations which need to implement axis-dependent
-* extensions to CmpFrame methods, and which therefore need to know
-* how a CmpFrames's external axis index is converted for internal
-* use.
-* - The pointer returned by this function gives direct access to
-* data internal to the CmpFrame object. It remains valid only so
-* long as the CmpFrame exists. The permutation array contents may
-* be modified by other functions which operate on the CmpFrame and
-* this may render the returned pointer invalid.
-* - 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 performs essentially the same operation as the
-* Frame member function which it over-rides. However, it returns a
-* pointer to the "perm" array held in the CmpFrame structure
-* (rather than the one in the parent Frame structure). This
-* duplication of the array is necessary because the one in the
-* Frame structure is of zero length, the number of axes in the
-* Frame structure having been set to zero to prevent unnecessary
-* allocation of Axis objects which are not needed by the CmpFrame.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
-
-/* Check the global error status. */
- if ( !astOK ) return NULL;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Return a pointer to the axis permutation array. */
- return this->perm;
-}
-
-static AstSystemType GetSystem( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* GetSystem
-
-* Purpose:
-* Obtain the System attribute for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* AstSystemType GetSystem( AstFrame *this_frame, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astGetSystem protected
-* method inherited from the Frame class).
-
-* Description:
-* This function returns the System attribute for a CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* 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: */
- AstCmpFrame *this; /* Pointer to CmpFrame structure */
- AstSystemType result; /* Value to return */
-
-/* Initialise. */
- result = AST__BADSYSTEM;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* If a System attribute has been set, invoke the parent method to obtain
- it. */
- if ( astTestSystem( this ) ) {
- result = (*parent_getsystem)( this_frame, status );
-
-/* Otherwise, provide a suitable default. */
- } else {
- result = AST__COMP;
- }
-
-/* Return the result. */
- return result;
-}
-
-static const char *GetTitle( AstFrame *this_frame, int *status ) {
-/*
-* Name:
-* GetTitle
-
-* Purpose:
-* Obtain a pointer to the Title attribute string for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* const char *GetTitle( AstFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astGetTitle protected
-* method inherited from the Frame class).
-
-* Description:
-* This function returns a pointer to the Title attribute string for
-* a CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A pointer to a constant null-terminated string containing the
-* Title value.
-
-* Notes:
-* - The returned pointer or the string it refers to may become
-* invalid following further invocation of this function or
-* modification of the CmpFrame.
-* - 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: */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
- AstCmpFrame *this; /* Pointer to CmpFrame structure */
- const char *result; /* Pointer value to return */
-
-/* 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_frame);
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* If a Title attribute string has been set, invoke the parent method
- to obtain a pointer to it. */
- if ( astTestTitle( this ) ) {
- result = (*parent_gettitle)( this_frame, status );
-
-/* Otherwise, create a suitable default string and return a pointer to
- this. */
- } else {
- (void) sprintf( gettitle_buff, "%d-d compound coordinate system",
- astGetNaxes( this ) );
- if ( astOK ) result = gettitle_buff;
- }
-
-/* Return the result. */
- return result;
-
-}
-
-static int GetUseDefs( AstObject *this_object, int *status ) {
-/*
-* Name:
-* GetUseDefs
-
-* Purpose:
-* Get a value for the UseDefs attribute of a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* int GetUseDefs( AstCmpFrame *this, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astGetUseDefs method
-* inherited from the Frame class).
-
-* Description:
-* This function returns a value for the UseDefs attribute of a
-* CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The UseDefs attribute value.
-
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- int result; /* Result value to return */
-
-/* Initialise. */
- result = 1;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_object;
-
-/* If an UseDefs attribute value has been set, invoke the parent method
- to obtain it. */
- if ( astTestUseDefs( this ) ) {
- result = (*parent_getusedefs)( this_object, status );
-
-/* Otherwise, use the UseDefs value in the first component Frame as the
- default. */
- } else {
- result = (*parent_getusedefs)( (AstObject *) this->frame1, status );
- }
-
-/* Return the result. */
- return result;
-}
-
-static int GoodPerm( int ncoord_in, const int inperm[],
- int ncoord_out, const int outperm[], int *status ) {
-/*
-* Name:
-* GoodPerm
-
-* Purpose:
-* Test if a PermMap will be non-null.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* int GoodPerm( int ncoord_in, const int inperm[],
-* int ncoord_out, const int outperm[], int *status )
-
-* Class Membership:
-* CmpFrame member function.
-
-* Description:
-* This function tests if a pair of permutation arrays will, when
-* used to create a PermMap, result in a PermMap which has a
-* non-null effect (i.e. one which is not simply equivalent to a
-* unit Mapping).
-
-* Parameters:
-* ncoord_in
-* The number of input coordinates for the PermMap.
-* inperm
-* The input permutation array for the PermMap (with "ncoord_in"
-* elements).
-* ncoord_out
-* The number of output coordinates for the PermMap.
-* outperm
-* The output permutation array for the PermMap (with
-* "ncoord_out" elements).
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Zero if the PermMap would be equivalent to a unit Mapping,
-* otherwise one.
-
-* 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.
-*/
-
-/* Local Variables: */
- int axis; /* Loop counter for axes */
- int result; /* Result value to return */
-
-/* Initialise. */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* First test if the number of input and output coordinates are
- different. */
- result = ( ncoord_in != ncoord_out );
-
-/* If they are not, examine the contents of the "inperm" array. */
- if ( !result ) {
- for ( axis = 0; axis < ncoord_in; axis++ ) {
-
-/* We have a non-null Mapping if any element of this array selects an
- output axis with a different index to the input axis (or selects an
- invalid axis or a constant). */
- if ( inperm[ axis ] != axis ) {
- result = 1;
- break;
- }
- }
- }
-
-/* If the Mapping still appears to be null, also examine the "outperm"
- array in the same way. */
- if ( !result ) {
- for ( axis = 0; axis < ncoord_out; axis++ ) {
- if ( outperm[ axis ] != axis ) {
- result = 1;
- break;
- }
- }
- }
-
-/* Return the result. */
- return result;
-}
-
-void astInitCmpFrameVtab_( AstCmpFrameVtab *vtab, const char *name, int *status ) {
-/*
-*+
-* Name:
-* astInitCmpFrameVtab
-
-* Purpose:
-* Initialise a virtual function table for a CmpFrame.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void astInitCmpFrameVtab( AstCmpFrameVtab *vtab, const char *name )
-
-* Class Membership:
-* CmpFrame vtab initialiser.
-
-* Description:
-* This function initialises the component of a virtual function
-* table which is used by the CmpFrame 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 */
- AstObjectVtab *object; /* Pointer to Object component of Vtab */
- AstFrameVtab *frame; /* Pointer to Frame component of Vtab */
- AstMappingVtab *mapping; /* Pointer to Mapping 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 astIsACmpFrame) 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. */
-
-/* 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;
- mapping = (AstMappingVtab *) vtab;
-
- 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;
-
- parent_getusedefs = object->GetUseDefs;
- object->GetUseDefs = GetUseDefs;
-
-#if defined(THREAD_SAFE)
- parent_managelock = object->ManageLock;
- object->ManageLock = ManageLock;
-#endif
-
- mapping->RemoveRegions = RemoveRegions;
- mapping->Simplify = Simplify;
- mapping->Transform = Transform;
-
- parent_getdomain = frame->GetDomain;
- frame->GetDomain = GetDomain;
-
- parent_gettitle = frame->GetTitle;
- frame->GetTitle = GetTitle;
-
- parent_getepoch = frame->GetEpoch;
- frame->GetEpoch = GetEpoch;
-
- parent_setepoch = frame->SetEpoch;
- frame->SetEpoch = SetEpoch;
-
- parent_clearepoch = frame->ClearEpoch;
- frame->ClearEpoch = ClearEpoch;
-
- parent_getdut1 = frame->GetDut1;
- frame->GetDut1 = GetDut1;
-
- parent_setdut1 = frame->SetDut1;
- frame->SetDut1 = SetDut1;
-
- parent_cleardut1 = frame->ClearDut1;
- frame->ClearDut1 = ClearDut1;
-
- parent_getobslon = frame->GetObsLon;
- frame->GetObsLon = GetObsLon;
-
- parent_setobslon = frame->SetObsLon;
- frame->SetObsLon = SetObsLon;
-
- parent_clearobslon = frame->ClearObsLon;
- frame->ClearObsLon = ClearObsLon;
-
- parent_getobslat = frame->GetObsLat;
- frame->GetObsLat = GetObsLat;
-
- parent_setobslat = frame->SetObsLat;
- frame->SetObsLat = SetObsLat;
-
- parent_clearobslat = frame->ClearObsLat;
- frame->ClearObsLat = ClearObsLat;
-
- parent_getobsalt = frame->GetObsAlt;
- frame->GetObsAlt = GetObsAlt;
-
- parent_setobsalt = frame->SetObsAlt;
- frame->SetObsAlt = SetObsAlt;
-
- parent_clearobsalt = frame->ClearObsAlt;
- frame->ClearObsAlt = ClearObsAlt;
-
- parent_angle = frame->Angle;
- frame->Angle = Angle;
-
- parent_getsystem = frame->GetSystem;
- frame->GetSystem = GetSystem;
-
- parent_getalignsystem = frame->GetAlignSystem;
- frame->GetAlignSystem = GetAlignSystem;
-
- parent_clearalignsystem = frame->ClearAlignSystem;
- frame->ClearAlignSystem = ClearAlignSystem;
-
- parent_overlay = frame->Overlay;
- frame->Overlay = Overlay;
-
- parent_setactiveunit = frame->SetActiveUnit;
- frame->SetActiveUnit = SetActiveUnit;
-
- parent_getactiveunit = frame->GetActiveUnit;
- frame->GetActiveUnit = GetActiveUnit;
-
- parent_setframeflags = frame->SetFrameFlags;
- frame->SetFrameFlags = SetFrameFlags;
-
- parent_getmaxaxes = frame->GetMaxAxes;
- frame->GetMaxAxes = GetMaxAxes;
-
- parent_getminaxes = frame->GetMinAxes;
- frame->GetMinAxes = GetMinAxes;
-
-/* Store replacement pointers for methods which will be over-ridden by
- new member functions implemented here. */
- object->Cast = Cast;
- mapping->Decompose = Decompose;
- frame->Abbrev = Abbrev;
- frame->ClearDirection = ClearDirection;
- frame->ClearFormat = ClearFormat;
- frame->ClearLabel = ClearLabel;
- frame->ClearSymbol = ClearSymbol;
- frame->ClearUnit = ClearUnit;
- frame->Distance = Distance;
- frame->Fields = Fields;
- frame->Format = Format;
- frame->FrameGrid = FrameGrid;
- frame->Centre = Centre;
- frame->Gap = Gap;
- frame->GetAxis = GetAxis;
- frame->GetDirection = GetDirection;
- frame->GetFormat = GetFormat;
- frame->GetLabel = GetLabel;
- frame->GetNaxes = GetNaxes;
- frame->GetPerm = GetPerm;
- frame->GetSymbol = GetSymbol;
- frame->GetUnit = GetUnit;
- frame->IsUnitFrame = IsUnitFrame;
- frame->Match = Match;
- frame->Norm = Norm;
- frame->NormBox = NormBox;
- frame->Offset = Offset;
- frame->PermAxes = PermAxes;
- frame->PrimaryFrame = PrimaryFrame;
- frame->Resolve = Resolve;
- frame->ResolvePoints = ResolvePoints;
- frame->SetAxis = SetAxis;
- frame->SetDirection = SetDirection;
- frame->SetFormat = SetFormat;
- frame->SetLabel = SetLabel;
- frame->SetSymbol = SetSymbol;
- frame->SetUnit = SetUnit;
- frame->SubFrame = SubFrame;
- frame->TestDirection = TestDirection;
- frame->TestFormat = TestFormat;
- frame->TestLabel = TestLabel;
- frame->TestSymbol = TestSymbol;
- frame->TestUnit = TestUnit;
- frame->Unformat = Unformat;
- frame->ValidateSystem = ValidateSystem;
- frame->SystemString = SystemString;
- frame->SystemCode = SystemCode;
- frame->MatchAxesX = MatchAxesX;
-
-/* Declare the copy constructor, destructor and class dump
- function. */
- astSetCopy( vtab, Copy );
- astSetDelete( vtab, Delete );
- astSetDump( vtab, Dump, "CmpFrame",
- "Compound coordinate system description" );
-
-/* 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) );
- }
-}
-
-static int IsUnitFrame( AstFrame *this_frame, int *status ){
-/*
-* Name:
-* IsUnitFrame
-
-* Purpose:
-* Is this Frame equivalent to a UnitMap?
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* int IsUnitFrame( AstFrame *this, int *status )
-
-* Class Membership:
-* Region member function (over-rides the protected astIsUnitFrame
-* method inherited from the Frame class).
-
-* Description:
-* This function returns a flag indicating if the supplied Frame is
-* equivalent to a UnitMap when treated as a Mapping (note, the Frame
-* class inherits from Mapping and therefore every Frame is also a Mapping).
-
-* Parameters:
-* this
-* Pointer to the Frame.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A non-zero value is returned if the supplied Frame is equivalent to
-* a UnitMap when treated as a Mapping.
-
-*-
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
-
-/* Check the global error status. */
- if ( !astOK ) return 0;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Return the result. */
- return astIsUnitFrame( this->frame1 ) && astIsUnitFrame( this->frame2 );
-}
-
-#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:
-* CmpFrame 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: */
- AstCmpFrame *this; /* Pointer to CmpFrame 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 CmpFrame structure. */
- this = (AstCmpFrame *) 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->frame1, mode, extra, fail );
- if( !result ) result = astManageLock( this->frame2, mode, extra, fail );
-
- return result;
-
-}
-#endif
-
-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 "cmpframe.h"
-* int Match( AstFrame *template, AstFrame *target, int matchsub,
-* int **template_axes, int **target_axes,
-* AstMapping **map, AstFrame **result, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the protected astMatch
-* method inherited from the Frame class).
-
-* Description:
-* This function matches a "template" CmpFrame 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" Frame and
-* "template" CmpFrame from which they are derived.
-
-* Parameters:
-* template
-* Pointer to the template CmpFrame. 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 (i.e. if the
-* target is of a more specialised class than the template). In
-* this latter case, the target is cast down to the class of the
-* template. NOTE, this argument is handled by the global method
-* wrapper function "astMatch_", rather than by the class-specific
-* implementations of this method.
-* 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 (zero-based) index of the
-* template CmpFrame axis from which it is derived. If it is not
-* derived from any template 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 (zero-based) index of the
-* target Frame axis from which it is derived. If it is not
-* derived from any target 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 Frame and the template
-* CmpFrame. 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:
-* - By default, the "result" Frame will have its number of axes
-* and axis order determined by the "template" CmpFrame. However,
-* if the PreserveAxes attribute of the template CmpFrame is
-* non-zero, then the axis count and axis order of the "target"
-* Frame will be used instead.
-* - 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.
-*/
-
-/* Local Variables: */
- AstCmpFrame *template; /* Pointer to template CmpFrame structure */
- char *template_domain; /* Pointer to copy of template domain */
- const char *ptr; /* Pointer to domain string */
- const char *target_domain; /* Pointer to target domain string */
- int *axes1; /* Pointer to axis selection 1 */
- int *axes2; /* Pointer to axis selection 2 */
- int *used; /* Pointer to flags array */
- int axis2; /* Index for axis selection 2 */
- int axis; /* Index for axis arrays */
- int last_target; /* Last target axis association */
- int last_template; /* Last template axis associateion */
- int match; /* Match obtained (returned result)? */
- int maxax1; /* MaxAxes attribute for component 1 */
- int maxax2; /* MaxAxes attribute for component 2 */
- int maxax; /* Max axes that can be matched by template */
- int minax1; /* MinAxes attribute for component 1 */
- int minax2; /* MinAxes attribute for component 2 */
- int minax; /* Min axes that can be matched by template */
- int naxes1; /* Number of axes assigned to component 1 */
- int naxes2; /* Number of axes assigned to component 2 */
- int naxes; /* Total number of target axes */
- int naxes_max1; /* First estimate of naxes_max */
- int naxes_max2; /* Second estimate of naxes_max */
- int naxes_max; /* Max number of axes to match component 1 */
- int naxes_min1; /* First estimate of naxes_min */
- int naxes_min2; /* Second estimate of naxes_min */
- int naxes_min; /* Min number of axes to match component 1 */
- int permute; /* Permute attribute for template */
- int result_naxes; /* Number of result Frame 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 CmpFrame structure. */
- template = (AstCmpFrame *) template_frame;
-
-/* Further initialisation to avoid compiler warnings. */
- naxes_min = 0;
- naxes_max = 0;
-
-/* Obtain the maximum number of axes that the template CmpFrame, and each
- component Frame of the template CmpFrame, can match. If the MaxAxes
- attribute is set for the template, use it and assume that each
- component Frame can match any number of axes. */
- if( astTestMaxAxes( template ) ) {
- maxax = astGetMaxAxes( template );
- maxax1 = 100000;
- maxax2 = 100000;
- } else {
- maxax1 = astGetMaxAxes( template->frame1 );
- maxax2 = astGetMaxAxes( template->frame2 );
- maxax = maxax1 + maxax2;
- }
-
-/* Do the same for the minimum number of axes that can be matched by the
- template CmpFrame. */
- if( astTestMinAxes( template ) ) {
- minax = astGetMinAxes( template );
- minax1 = 1;
- minax2 = 1;
- } else {
- minax1 = astGetMinAxes( template->frame1 );
- minax2 = astGetMinAxes( template->frame2 );
- minax = minax1 + minax2;
- }
-
-/* Obtain the number of axes in the target Frame and test to see if it
- is possible for the template to match it on the basis of axis
- counts. */
- naxes = astGetNaxes( target );
- match = ( naxes >= minax && naxes <= maxax );
-
-/* The next requirement is that all the frames have some axes. */
- if( naxes == 0 || maxax1 == 0 || maxax2 == 0 ) match = 0;
-
-/* The next requirement is that if the template CmpFrame has its
- Domain attribute defined, then the target Frame must also have the
- same Domain (although it need not be set - the default will
- do). First check if the template has a domain. */
- if ( astOK && match ) {
- if ( astTestDomain( template ) ) {
-
-/* Obtain a pointer to the template domain. Then allocate memory and
- make a copy of it (this is necessary as we will next inquire the
- domain of the target and may over-write the buffer holding the
- template's domain). */
- ptr = astGetDomain( template );
- if ( astOK ) {
- template_domain = astStore( NULL, ptr,
- strlen( ptr ) + (size_t) 1 );
-
-/* Obtain a pointer to the target domain. */
- target_domain = astGetDomain( target );
-
-/* Compare the domain strings for equality. Then free the memory
- allocated above. */
- match = astOK && !strcmp( template_domain, target_domain );
- template_domain = astFree( template_domain );
- }
- }
- }
-
-/* If a match still appears possible, determine the minimum number of
- target axes that will have to match the first component Frame of
- the template CmpFrame. */
- if ( astOK && match ) {
- naxes_min1 = minax1;
- naxes_min2 = naxes - maxax2;
- naxes_min = ( naxes_min1 > naxes_min2 ) ? naxes_min1 : naxes_min2;
-
-/* Also determine the maximum number of target axes that may match
- this component of the template. */
- naxes_max1 = maxax1;
- naxes_max2 = naxes - minax2;
- naxes_max = ( naxes_max1 < naxes_max2 ) ? naxes_max1 : naxes_max2;
-
-/* No match possible if the number of axes are inconsistent. */
- if( naxes_min > naxes_max ) match = 0;
- }
-
-/* If a match is still possible, allocate workspace. */
- if( match ) {
- axes1 = astMalloc( sizeof( int ) * (size_t) naxes );
- axes2 = astMalloc( sizeof( int ) * (size_t) naxes );
- used = astMalloc( sizeof( int ) * (size_t) naxes );
-
-/* Obtain the value of the template's Permute attribute. */
- permute = astGetPermute( template );
- if ( astOK ) {
-
-/* Loop to consider all possible choices of the number of template
- axes that might match the first component Frame of the template,
- and derive the corresponding number of axes that must match the
- second component at the same time. */
- for ( naxes1 = naxes_max; naxes1 >= naxes_min; naxes1-- ) {
- naxes2 = naxes - naxes1;
-
-/* Initialise the selection of target axes that we will attempt to
- match against the first template component (to [0,1,2,...]). */
- for ( axis = 0; axis < naxes1; axis++ ) axes1[ axis ] = axis;
-
-/* Loop to consider all possible selections with this number of axes,
- until a match is found. */
- while ( 1 ) {
-
-/* Initialise an array of flags to zero for each target axis. Then set
- the flag to 1 for each axis which is in the first selection.*/
- for ( axis = 0; axis < naxes; axis++ ) used[ axis ] = 0;
- for( axis = 0; axis < naxes1; axis++ ) {
- used[ axes1[ axis ] ] = 1;
- }
-
-/* Generate the second selection by including all target axes that are
- not in the first selection. */
- axis2 = 0;
- for ( axis = 0; axis < naxes; axis++ ) {
- if ( !used[ axis ] ) axes2[ axis2++ ] = axis;
- }
-
-/* Attempt to match the target axes partitioned in this way to the two
- template components. */
- match = PartMatch( template, target, matchsub,
- naxes1, axes1, naxes2, axes2,
- template_axes, target_axes, map, result, status );
-
-/* If a match was obtained but the template's Permute attribute is zero,
- then we must check to see if the match involves permuting the target
- axes. */
- if ( astOK && match && !permute ) {
-
-/* Obtain the number of result Frame axes. */
- result_naxes = astGetNaxes( *result );
-
-/* Loop to check the target and template axis associations for all the
- result Frame axes. The match will only be accepted if both of these
- are monotonically increasing (indicating no axis permutation) after
- allowing for any absent associations . */
- last_template = -1;
- last_target = -1;
- for ( axis = 0; axis < result_naxes; axis++ ) {
-
-/* Check the template axis association against the previous value,
- omitting any axes witout valid associations. */
- if ( ( *template_axes )[ axis ] != -1 ) {
- if ( ( *template_axes )[ axis ] <= last_template ) {
- match = 0;
- break;
-
-/* Update the previous association value. */
- } else {
- last_template = ( *template_axes )[ axis ];
- }
- }
-
-/* Repeat this process for the target axis associations. */
- if ( ( *target_axes )[ axis ] != -1 ) {
- if ( ( *target_axes )[ axis ] <= last_target ) {
- match = 0;
- break;
- } else {
- last_target = ( *target_axes )[ axis ];
- }
- }
- }
-
-/* If the match was rejected because it involves an axis permutation,
- then free the allocated memory and annul the Object pointers
- associated with the match. */
- if ( !match ) {
- *template_axes = astFree( *template_axes );
- *target_axes = astFree( *target_axes );
- *map = astAnnul( *map );
- *result = astAnnul( *result );
- }
- }
-
-/* If an error occurred or a match was found, quit searching,
- otherwise generate the next axis selection and try that
- instead. Quit if there are no more selections to try. */
- if ( !astOK || match ||
- !GenAxisSelection( naxes, naxes1, axes1, status ) ) break;
- }
-
-/* Quit the outer loop if an error occurs or a match is found. */
- if ( !astOK || match ) break;
- }
- }
-
-/* Free the workspace arrays. */
- axes1 = astFree( axes1 );
- axes2 = astFree( axes2 );
- used = astFree( used );
- }
-
-/* If the target did not match the supplied template CmpFrame, see if it
- will match either of the component Frames. First try matching it against
- the first component Frame. */
- if( !match ) match = ComponentMatch( template, target, matchsub, 0,
- template_axes, target_axes, map, result,
- status );
-
-/* If we still dont have a mcth, try matching it against the second
- component Frame. */
- if( !match ) match = ComponentMatch( template, target, matchsub, 1,
- template_axes, target_axes, map,
- result, status );
-
-/* If an error occurred, free all allocated memory, annul the result
- Object pointers and clear all returned values. */
- if ( !astOK ) {
- *template_axes = astFree( *template_axes );
- *target_axes = astFree( *target_axes );
- *map = astAnnul( *map );
- *result = astAnnul( *result );
- match = 0;
- }
-
-/* Return the result. */
- return match;
-}
-
-static void MatchAxesX( AstFrame *frm2_frame, AstFrame *frm1, int *axes,
- int *status ) {
-/*
-* Name:
-* MatchAxesX
-
-* Purpose:
-* Find any corresponding axes in two Frames.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void MatchAxesX( AstFrame *frm2, AstFrame *frm1, int *axes )
-* int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the protected astMatchAxesX
-* method inherited from the Frame class).
-
-* Description:
-* This function looks for corresponding axes within two supplied
-* Frames. An array of integers is returned that contains an element
-* for each axis in the second supplied Frame. An element in this array
-* will be set to zero if the associated axis within the second Frame
-* has no corresponding axis within the first Frame. Otherwise, it
-* will be set to the index (a non-zero positive integer) of the
-* corresponding axis within the first supplied Frame.
-
-* Parameters:
-* frm2
-* Pointer to the second Frame.
-* frm1
-* Pointer to the first Frame.
-* axes
-* Pointer to an integer array in which to return the indices of
-* the axes (within the first Frame) that correspond to each axis
-* within the second Frame. Axis indices start at 1. A value of zero
-* will be stored in the returned array for each axis in the second
-* Frame that has no corresponding axis in the first Frame.
-*
-* The number of elements in this array must be greater than or
-* equal to the number of axes in the second Frame.
-* status
-* Pointer to inherited status value.
-
-* Notes:
-* - Corresponding axes are identified by the fact that a Mapping
-* can be found between them using astFindFrame or astConvert. Thus,
-* "corresponding axes" are not necessarily identical. For instance,
-* SkyFrame axes in two Frames will match even if they describe
-* different celestial coordinate systems
-*/
-
-/* Local Variables: */
- AstCmpFrame *frm2;
- const int *perm;
- int *work;
- int i;
- int nax2;
- int nax1;
- int nax;
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Get a pointer to the CmpFrame. */
- frm2 = (AstCmpFrame *) frm2_frame;
-
-/* Get the number of axes in the two component Frames, and the total
- number of axes in the CmpFrame. */
- nax2 = astGetNaxes( frm2->frame1 );
- nax1 = astGetNaxes( frm2->frame2 );
- nax = nax2 + nax1;
-
-/* Allocate a work array to hold the unpermuted axis indices */
- work = astMalloc( sizeof( int )*nax );
- if( astOK ) {
-
-/* Use the astMatchAxes method to match axes in the first component Frame
- within CmpFrame "frm2". Write the associated axis indices into the first
- part of the work array. */
- astMatchAxes( frm1, frm2->frame1, work );
-
-/* Use the MatchAxes method to match axes in the second component
- Frame. Write the associated axis indices into the work array
- following the end of the values already in there. */
- astMatchAxes( frm1, frm2->frame2, work + nax2 );
-
-/* Obtain a pointer to the CmpFrame's axis permutation array. The index
- into "perm" represents the external axis index, and the value held in
- each element of "perm" represents the corresponding internal axis index. */
- perm = astGetPerm( frm2 );
- if( astOK ) {
-
-/* Copy the frm2 axis indices from the work array into the returned "axes"
- array, permuting their order into the external axis order of the
- CmpFrame. */
- for( i = 0; i < nax; i++ ) axes[ i ] = work[ perm[ i ] ];
- }
-
-/* Free resources */
- work = astFree( work );
- }
-}
-
-static void Norm( AstFrame *this_frame, double value[], int *status ) {
-/*
-* Name:
-* Norm
-
-* Purpose:
-* Normalise a set of CmpFrame coordinates.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void Norm( AstAxis *this, double value[], int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astNorm method
-* inherited from the Frame class).
-
-* Description:
-* This function converts a set of CmpFrame coordinate values,
-* which might potentially be unsuitable for display to a user (for
-* instance, may lie outside the expected range of values) into a
-* set of acceptable alternative values suitable for display.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* value
-* An array of double, with one element for each CmpFrame axis.
-* This should contain the initial set of coordinate values,
-* which will be modified in place.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to CmpFrame structure */
- const int *perm; /* Axis permutation array */
- double *v; /* Pointer to permuted coordinates */
- int axis; /* Loop counter for axes */
- int naxes1; /* Number of axes in frame1 */
- int naxes; /* Number of axes in CmpFrame */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Obtain a pointer to the CmpFrame's axis permutation array. */
- perm = astGetPerm( this );
-
-/* Obtain the number of axes in the CmpFrame and in the first
- component Frame. */
- naxes = astGetNaxes( this );
- naxes1 = astGetNaxes( this->frame1 );
-
-/* Allocate memory to hold the permuted coordinates. */
- v = astMalloc( sizeof( double ) * (size_t) naxes );
- if ( astOK ) {
-
-/* Permute the coordinates using the CmpFrame's axis permutation array
- to put them into the order required internally (i.e. by the two
- component Frames). */
- for ( axis = 0; axis < naxes; axis++ ) v[ perm[ axis ] ] = value[ axis ];
-
-/* Invoke the astNorm method of both component Frames, passing the
- relevant (permuted) coordinate values for normalisation. */
- astNorm( this->frame1, v );
- astNorm( this->frame2, v + naxes1 );
-
-/* Copy the normalised values back into the original coordinate array,
- un-permuting them in the process. */
- for ( axis = 0; axis < naxes; axis++ ) value[ axis ] = v[ perm[ axis ] ];
- }
-
-/* Free the memory used for the permuted coordinates. */
- v = astFree( v );
-}
-
-static void NormBox( AstFrame *this_frame, double lbnd[], double ubnd[],
- AstMapping *reg, int *status ) {
-/*
-* Name:
-* NormBox
-
-* Purpose:
-* Extend a box to include effect of any singularities in the Frame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void astNormBox( AstFrame *this, double lbnd[], double ubnd[],
-* AstMapping *reg, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astNormBox method inherited
-* from the Frame class).
-
-* Description:
-* This function modifies a supplied box to include the effect of any
-* singularities in the co-ordinate system represented by the Frame.
-* For a normal Cartesian coordinate system, the box will be returned
-* unchanged. Other classes of Frame may do other things. For instance,
-* a SkyFrame will check to see if the box contains either the north
-* or south pole and extend the box appropriately.
-
-* Parameters:
-* this
-* Pointer to the Frame.
-* lbnd
-* An array of double, with one element for each Frame axis
-* (Naxes attribute). Initially, this should contain a set of
-* lower axis bounds for the box. They will be modified on exit
-* to include the effect of any singularities within the box.
-* ubnd
-* An array of double, with one element for each Frame axis
-* (Naxes attribute). Initially, this should contain a set of
-* upper axis bounds for the box. They will be modified on exit
-* to include the effect of any singularities within the box.
-* reg
-* A Mapping which should be used to test if any singular points are
-* inside or outside the box. The Mapping should leave an input
-* position unchanged if the point is inside the box, and should
-* set all bad if the point is outside the box.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this;
- AstCmpMap *m1;
- AstCmpMap *m2;
- AstCmpMap *m3;
- AstCmpMap *m4;
- AstCmpMap *m5;
- AstCmpMap *m6;
- AstPermMap *pm1;
- AstPermMap *pm2;
- AstPermMap *pm3;
- const int *perm;
- double *vl;
- double *vu;
- int *inperm;
- int axis;
- int naxes1;
- int naxes;
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Obtain a pointer to the CmpFrame's axis permutation array. */
- perm = astGetPerm( this );
-
-/* Obtain the number of axes in the CmpFrame and in the first
- component Frame. */
- naxes = astGetNaxes( this );
- naxes1 = astGetNaxes( this->frame1 );
-
-/* Allocate memory to hold the permuted coordinates. */
- vl = astMalloc( sizeof( double ) * (size_t) naxes );
- vu = astMalloc( sizeof( double ) * (size_t) naxes );
- inperm = astMalloc( sizeof( int ) * (size_t) naxes );
- if( inperm ) {
-
-/* Permute the coordinates using the CmpFrame's axis permutation array
- to put them into the order required internally (i.e. by the two
- component Frames). */
- for ( axis = 0; axis < naxes; axis++ ) {
- vl[ perm[ axis ] ] = lbnd[ axis ];
- vu[ perm[ axis ] ] = ubnd[ axis ];
- }
-
-/* Create a PermMap with a forward transformation which reorders a position
- which uses internal axis ordering into a position which uses external axis
- ordering. */
- pm1 = astPermMap( naxes, NULL, naxes, perm, NULL, "", status );
-
-/* Put it in front of the supplied Mapping. The combination transforms an
- input internal position into an output external position. */
- m1 = astCmpMap( pm1, reg, 1, "", status );
-
-/* Invert it and add it to the end. This combination now transforms an
- input internal position into an output internal position. */
- astInvert( pm1 );
- m2 = astCmpMap( m1, pm1, 1, "", status );
-
-/* Create a PermMap with a forward transformation which copies the lower
- naxes1 inputs to the same outputs, and supplies AST__BAD for the other
- outputs. */
- for( axis = 0; axis < naxes1; axis++ ) inperm[ axis ] = axis;
- pm2 = astPermMap( naxes1, inperm, naxes, NULL, NULL, "", status );
-
-/* Put it in front of the Mapping created above, then invert it and add
- it at the end. */
- m3 = astCmpMap( pm2, m2, 1, "", status );
- astInvert( pm2 );
- m4 = astCmpMap( m3, pm2, 1, "", status );
-
-/* Invoke the astNormBox method of the first component Frame, passing the
- relevant (permuted) coordinate values for normalisation. */
- astNormBox( this->frame1, vl, vu, m4 );
-
-/* Create a PermMap with a forward transformation which copies the upper
- inputs to the same outputs, and supplied AST__BAD for the other
- outputs. */
- for( axis = 0; axis < naxes - naxes1; axis++ ) inperm[ axis ] = naxes1 + axis;
- pm3 = astPermMap( naxes1, inperm, naxes, NULL, NULL, "", status );
-
-/* Put it in front of the Mapping created above, then invert it and add
- it at the end. */
- m5 = astCmpMap( pm3, m2, 1, "", status );
- astInvert( pm3 );
- m6 = astCmpMap( m5, pm3, 1, "", status );
-
-/* Invoke the astNormBox method of the seond component Frame, passing the
- relevant (permuted) coordinate values for normalisation. */
- astNormBox( this->frame2, vl + naxes1, vu + naxes1, m6 );
-
-/* Copy the normalised values back into the original coordinate array,
- un-permuting them in the process. */
- for ( axis = 0; axis < naxes; axis++ ) {
- lbnd[ axis ] = vl[ perm[ axis ] ];
- ubnd[ axis ] = vu[ perm[ axis ] ];
- }
-
-/* Free resources. */
- pm1 = astAnnul( pm1 );
- pm2 = astAnnul( pm2 );
- pm3 = astAnnul( pm3 );
- m1 = astAnnul( m1 );
- m2 = astAnnul( m2 );
- m3 = astAnnul( m3 );
- m4 = astAnnul( m4 );
- m5 = astAnnul( m5 );
- m6 = astAnnul( m6 );
- }
- inperm = astFree( inperm );
- vl = astFree( vl );
- vu = astFree( vu );
-}
-
-static void Offset( AstFrame *this_frame, const double point1[],
- const double point2[], double offset, double point3[], int *status ) {
-/*
-* Name:
-* Offset
-
-* Purpose:
-* Calculate an offset along a geodesic curve.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void Offset( AstFrame *this,
-* const double point1[], const double point2[],
-* double offset, double point3[], int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astOffset method
-* inherited from the Frame class).
-
-* Description:
-* This function finds the CmpFrame coordinate values of a point
-* which is offset a specified distance along the geodesic curve
-* between two other points.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* point1
-* An array of double, with one element for each CmpFrame axis.
-* This should contain the coordinates of the point marking the
-* start of the geodesic curve.
-* point2
-* An array of double, with one element for each CmpFrame axis.
-* This should contain the coordinates of the point marking the
-* end of the geodesic curve.
-* offset
-* The required offset from the first point along the geodesic
-* curve. If this is positive, it will be towards the second
-* point. If it is negative, it will be in the opposite
-* direction. This offset need not imply a position lying
-* between the two points given, as the curve will be
-* extrapolated if necessary.
-* point3
-* An array of double, with one element for each CmpFrame axis
-* in which the coordinates of the required point will be
-* returned.
-* status
-* Pointer to the inherited status variable.
-
-* Notes:
-* - The geodesic curve used by this function is the path of
-* shortest distance between two points, as defined by the
-* astDistance function.
-* - This function will return "bad" coordinate values (AST__BAD)
-* if any of the input coordinates has this value.
-* - "Bad" coordinate values will also be returned if the two
-* points supplied are coincident (or otherwise fail to uniquely
-* specify a geodesic curve) but the requested offset is non-zero.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- const int *perm; /* Pointer to axis permutation array */
- double *p1; /* Permuted coordinates for point1 */
- double *p2; /* Permuted coordinates for point2 */
- double *p3; /* Permuted coordinates for point3 */
- double dist1; /* Distance between input points in frame1 */
- double dist2; /* Distance between input points in frame2 */
- double dist; /* Total distance between input points */
- double offset1; /* Offset distance required in frame1 */
- double offset2; /* Offset distance required in frame2 */
- int axis; /* Loop counter for axes */
- int bad; /* Set bad output coordinates? */
- int naxes1; /* Number of axes in frame1 */
- int naxes; /* Total number of axes in CmpFrame */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Obtain the number of axes in the CmpFrame. */
- naxes = astGetNaxes( this );
-
-/* Obtain a pointer to the CmpFrame's axis permutation array. */
- perm = astGetPerm( this );
-
-/* Allocate workspace. */
- p1 = astMalloc( sizeof( double ) * (size_t) naxes );
- p2 = astMalloc( sizeof( double ) * (size_t) naxes );
- p3 = astMalloc( sizeof( double ) * (size_t) naxes );
-
-/* Initialise variables to avoid compiler warnings. */
- dist1 = 0.0;
- dist2 = 0.0;
- offset1 = 0.0;
- offset2 = 0.0;
- naxes1 = 0;
-
-/* Initialise a flag to indicate whether "bad" coordinates should be
- returned. */
- bad = 0;
-
-/* Check that all the coordinates of both input points are OK. If not,
- set the "bad" flag and quit checking. */
- if ( astOK ) {
- for ( axis = 0; axis < naxes; axis++ ) {
- if ( ( point1[ axis ] == AST__BAD ) ||
- ( point2[ axis ] == AST__BAD ) ) {
- bad = 1;
- break;
-
-/* If the coordinates are OK, apply the axis permutation array to
- obtain them in the required order. */
- } else {
- p1[ perm[ axis ] ] = point1[ axis ];
- p2[ perm[ axis ] ] = point2[ axis ];
- }
- }
- }
-
-/* If OK, obtain the number of axes in the first component Frame. */
- if ( astOK && !bad ) {
- naxes1 = astGetNaxes( this->frame1 );
-
-/* Project the two input points into the two component Frames and
- determine the distance between the points in each Frame. */
- dist1 = astDistance( this->frame1, p1, p2 );
- dist2 = astDistance( this->frame2, p1 + naxes1, p2 + naxes1 );
-
-/* Check that the returned distances are not bad. */
- if ( astOK ) bad = ( ( dist1 == AST__BAD ) || ( dist2 == AST__BAD ) );
- }
-
-/* If OK, calculate the total distance between the two points. */
- if ( astOK && !bad ) {
- dist = sqrt( dist1 * dist1 + dist2 * dist2 );
-
-/* If the points are co-incident, but "offset" is non-zero, then set
- the "bad" flag. */
- if ( dist == 0.0 ) {
- if ( offset != 0.0 ) {
- bad = 1;
-
-/* Otherwise, set the offset distance required in each Frame to
- zero. */
- } else {
- offset1 = 0.0;
- offset2 = 0.0;
- }
-
-/* If the points are not co-incident, divide the total offset required
- between each component Frame in such a way that the path being
- followed will pass through the second point. */
- } else {
- offset1 = offset * dist1 / dist;
- offset2 = offset * dist2 / dist;
- }
- }
-
-/* If OK, apply the separate offsets to each component Frame. */
- if ( astOK && !bad ) {
- astOffset( this->frame1, p1, p2, offset1, p3 );
- astOffset( this->frame2, p1 + naxes1, p2 + naxes1, offset2,
- p3 + naxes1 );
-
-/* Copy the resulting coordinates into the output array "point3",
- permuting them back into the required order. */
- if ( astOK ) {
- for ( axis = 0; axis < naxes; axis++ ) {
- point3[ axis ] = p3[ perm[ axis ] ];
-
-/* If any of the result coordinates is bad, set the "bad" flag and
- quit copying. */
- if ( point3[ axis ] == AST__BAD ) {
- bad = 1;
- break;
- }
- }
- }
- }
-
-/* Free the workspace arrays. */
- p1 = astFree( p1 );
- p2 = astFree( p2 );
- p3 = astFree( p3 );
-
-/* If no error has occurred, but bad coordinates must be returned,
- then set these in the output array. */
- if ( astOK && bad ) {
- for ( axis = 0; axis < naxes; axis++ ) point3[ axis ] = AST__BAD;
- }
-}
-
-static void Overlay( AstFrame *template_frame, const int *template_axes,
- AstFrame *result, int *status ) {
-/*
-* Name:
-* Overlay
-
-* Purpose:
-* Overlay the attributes of a template CmpFrame on to another Frame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void Overlay( AstFrame *template, const int *template_axes,
-* AstFrame *result, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the protected astOverlay
-* method inherited from the Frame class).
-
-* Description:
-* This function overlays attributes from a CmpFrame 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.
-
-* Parameters:
-* template
-* Pointer to the template CmpFrame, for whose current Frame
-* 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 axis in the current Frame of
-* the template CmpFrame to which it corresponds. This array is
-* used to establish from which template Frame axis any
-* axis-dependent attributes should be obtained.
-*
-* If any axis in the result Frame is not associated with a
-* template Frame 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.
-*/
-
-/* Local Variables: */
- AstCmpFrame *res; /* Pointer to the result CmpFrame structure */
- AstCmpFrame *template; /* Pointer to the template CmpFrame structure */
- AstFrame *sub1; /* Template subframe for 1st result subframe */
- AstFrame *sub2; /* Template subframe for 2nd result subframe */
- const int *perm; /* Template axis permutation array */
- const int *rperm; /* Result axis permutation array */
- int *axes1; /* Axis associations with template frame1 */
- int *axes2; /* Axis associations with template frame2 */
- int done; /* Have attributes been overlayed yet? */
- int i; /* Index of result axis */
- int icmp; /* Internal template axis number */
- int isfirst; /* Res. subframe -> 1st template subframe? */
- int issecond; /* Res. subframe -> 2nd template subframe? */
- int j; /* Index of template axis */
- int nc1; /* Number of axes in template frame1 */
- int nres1; /* Number of axes in first result subframe */
- int nres2; /* Number of axes in second result subframe */
- int nres; /* Number of axes in result Frame */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- template = (AstCmpFrame *) template_frame;
-
-/* Get the axis permutation array for the template CmpFrame. */
- perm = astGetPerm( template );
-
-/* Get the number of axes in the first component Frame in the template
- CmpFrame. */
- nc1 = astGetNaxes( template->frame1 );
-
-/* Indicate we have not yet overlayed any attributes. */
- done = 0;
-
-/* If the result Frame is a CmpFrame... */
- if( astIsACmpFrame( result ) ) {
-
-/* Get the number of axes in the two component Frames of the result CmpFrame. */
- res = (AstCmpFrame *) result;
- nres1 = astGetNaxes( res->frame1 );
- nres2 = astGetNaxes( res->frame2 );
-
-/* Get the total number of axes in the result CmpFrame. */
- nres = nres1 + nres2;
-
-/* Get the axis permutation array for the result CmpFrame. */
- rperm = astGetPerm( result );
-
-/* Allocate memory for two new axes arrays, one for each result sub-frame. */
- axes1 = astMalloc( sizeof(int)*(size_t)nres1 );
- axes2 = astMalloc( sizeof(int)*(size_t)nres2 );
- if( astOK ) {
-
-/* Assume that there is a 1-to-1 correspondence between axes in the
- subframes of the result and template CmpFrame. That is, all the axes
- in each result sub-frame are overlayed from the same template sub-frame. */
- done = 1;
-
-/* Loop round each axis in the first result sub-frame. */
- isfirst = 0;
- issecond = 0;
- for( i = 0; i < nres1; i++ ) {
-
-/* Find the external result CmpFrame axis index (j) for internal axis i. */
- for( j = 0; j < nres; j++ ) {
- if( rperm[ j ] == i ) break;
- }
-
-/* Get the internal axis number within the template CmpFrame which
- provides attribute values for the current result axis. */
- icmp = perm[ template_axes ? template_axes[ j ] : j ];
-
-/* If this template axis is in the first template subframe, store the
- corresponding internal frame axis index in "axes1" and set a flag
- indicating that the first result subframe corresponds to the first
- template subframe. If the correspondance has already been established,
- but is broken by this axis, then set "done" false and exit the axis
- loop. */
- if( icmp < nc1 ) {
- if( issecond ) {
- done = 0;
- break;
- } else {
- isfirst = 1;
- axes1[ i ] = icmp;
- }
-
- } else {
- if( isfirst ) {
- done = 0;
- break;
- } else {
- issecond = 1;
- axes1[ i ] = icmp - nc1;
- }
- }
- }
-
-/* Save a pointer to the template subframe which is associated with the first
- result subframe.*/
- sub1 = isfirst ? template->frame1 :template->frame2;
-
-/* Now do the same for the axes in the second result sub-frame. */
- isfirst = 0;
- issecond = 0;
- for( i = 0; i < nres2; i++ ) {
- for( j = 0; j < nres; j++ ) {
- if( rperm[ j ] == i + nres1 ) break;
- }
-
- icmp = perm[ template_axes ? template_axes[ j ] : j ];
-
- if( icmp < nc1 ) {
- if( issecond ) {
- done = 0;
- break;
- } else {
- isfirst = 1;
- axes2[ i ] = icmp;
- }
-
- } else {
- if( isfirst ) {
- done = 0;
- break;
- } else {
- issecond = 1;
- axes2[ i ] = icmp - nc1;
- }
- }
- }
-
-/* Save a pointer to the template subframe which is associated with the
- second result subframe.*/
- sub2 = isfirst ? template->frame1 :template->frame2;
-
-/* If the two used template subframes are the same, something has gone
- wrong. */
- if( sub1 == sub2 ) done = 0;
-
-/* If all axes within each result subframe are associated with the same
- template subframe we continue to use the subframe astOverlay methods. */
- if( done ) {
-
-/* Overlay the first result subframe. */
- astOverlay( sub1, axes1, res->frame1 );
- astOverlay( sub2, axes2, res->frame2 );
- }
- }
-
-/* Free the axes arrays. */
- axes1 = astFree( axes1 );
- axes2 = astFree( axes2 );
- }
-
-/* If we have not yet overlayed any attributes... */
- if( !done ) {
-
-/* Get the number of axes in the result Frame. */
- nres = astGetNaxes( result );
-
-/* Allocate memory for two new template_axes arrays. */
- axes1 = astMalloc( sizeof(int)*(size_t)nres );
- axes2 = astMalloc( sizeof(int)*(size_t)nres );
- if( astOK ) {
-
-/* Set elements to -1 in "axes1" if they do not refer to the first component
- Frame in the template CmpFrame. Likewise, set elements to -1 in "axes2" if
- they do not refer to the second component Frame in the template CmpFrame. */
- for( i = 0; i < nres; i++ ) {
-
-/* Get the internal axis number within the template CmpFrame which
- provides attribute values for the current results axis. */
- icmp = perm[ template_axes ? template_axes[ i ] : i ];
-
-/* If this template axis is in the first component Frame, store the
- corresponding internal frame axis index in "axes1" and set "axis2" to
- -1. */
- if( icmp < nc1 ) {
- axes1[ i ] = icmp;
- axes2[ i ] = -1;
-
-/* If this template axis is in the second component Frame, store the
- corresponding internal frame axis index in "axes2" and set "axis1" to
- -1. */
- } else {
- axes1[ i ] = -1;
- axes2[ i ] = icmp - nc1;
- }
- }
-
-/* Now use the astOverlay methods of the two component Frames to overlay
- attributes onto the appropriate axes of the results Frame. */
- astOverlay( template->frame1, axes1, result );
- astOverlay( template->frame2, axes2, result );
- }
-
-/* Free the axes arrays. */
- axes1 = astFree( axes1 );
- axes2 = astFree( axes2 );
- }
-}
-
-static void PartitionSelection( int nselect, const int select[],
- const int perm[], int naxes1, int naxes2,
- int iframe[], int following, int *status ) {
-/*
-* Name:
-* PartitionSelection
-
-* Purpose:
-* Partition a CmpFrame axis selection into two component Frame selections.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void PartitionSelection( int nselect, const int select[],
-* const int perm[], int naxes1, int naxes2,
-* int iframe[], int following, int *status )
-
-* Class Membership:
-* CmpFrame member function.
-
-* Description:
-* This function accepts an array containing the indices of axes
-* which are to be selected from a CmpFrame, and partitions these
-* indices to indicate which must be selected from each of the
-* CmpFrame's two component Frames.
-*
-* This operation is trivial if all the axis indices supplied refer
-* to valid CmpFrame axes. However, if some of them do not (these
-* should generally be set to -1), this function assigns these
-* "extra" axes to one or other of the component Frames by
-* associating them with the axes selected immediately before (or
-* after). Allowance is made for the possibility that several
-* consecutive selected axes may be "extra" ones, or even that they
-* may all be. The CmpFrame's axis permutation array is also taken
-* into account.
-
-* Parameters:
-* nselect
-* The number of axes to be selected.
-* select
-* An array containing the (zero-based) indices of the CmpFrame
-* axes to be selected, or -1 where "extra" axes are required.
-* perm
-* The CmpFrame's axis permutation array.
-* naxes1
-* The number of axes in the CmpFrame's first component Frame.
-* naxes2
-* The number of axes in the CmpFrame's second component Frame.
-* iframe
-* An array with "nselect" elements in which to return a number
-* (either 1 or 2) to indicate to which component Frame (frame1
-* or frame2) each selected axis belongs.
-* following
-* If this is zero, "extra" axes will be associated with the
-* preceding normal selected axis which appears in the "select"
-* array (if any), otherwise they will be associated with the
-* following normal selected axis.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- int end; /* Loop termination value */
- int ifr; /* Choice of Frame for next "extra" axis */
- int inc; /* Loop increment value */
- int iselect; /* Loop counter for axis selections */
- int naxes; /* Total number of CmpFrame axes */
- int start; /* Loop starting value */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain the total number of CmpFrame axes. */
- naxes = naxes1 + naxes2;
-
-/* Loop through each axis selection and identify those which refer to
- valid CmpFrame axes. */
- for ( iselect = 0; iselect < nselect; iselect++ ) {
- if ( ( select[ iselect ] >= 0 ) && ( select[ iselect ] < naxes ) ) {
-
-/* For these selections (only), enter a flag into the "iframe" array
- which indicates which component Frame the selected axis resides
- in. Permute each axis index before deciding this. */
- iframe[ iselect ] = 1 + ( perm[ select[ iselect ] ] >= naxes1 );
- }
- }
-
-/* Set up a start, end, and increment value for looping through the
- array of axis selections forward (if "following" is 0) or backwards
- (otherwise). */
- start = following ? nselect - 1 : 0;
- end = following ? -1 : nselect;
- inc = following ? -1 : 1;
-
-/* Set the default choice of component Frame. This will be used if
- there are no normal axis selections to guide the choice at all. */
- ifr = following ? 2 : 1;
-
-/* Search for the first normal axis selection so that we can replace
- this default, if possible. (Here, "first" actually means "last" if
- "following" is set, because we will then be scanning the array of
- selections in reverse.) */
- for ( iselect = start; iselect != end; iselect += inc ) {
-
-/* Identify normal axis selections and obtain the choice of component
- Frame for the first one found. The resulting value "ifr" will be
- used for initial (or final, if "following" is set) "extra"
- selections for which no earlier normal selection exists - see
- below. */
- if ( ( select[ iselect ] >= 0 ) && ( select[ iselect ] < naxes ) ) {
- ifr = iframe[ iselect ];
- break;
- }
- }
-
-/* Loop through the selections again to allocate a choice of Frame to
- the "extra" selected axes. */
- for ( iselect = start; iselect != end; iselect += inc ) {
-
-/* Remember the component Frame used by the most recently encountered
- normal axis selection. */
- if ( ( select[ iselect ] >= 0 ) && ( select[ iselect ] < naxes ) ) {
- ifr = iframe[ iselect ];
-
-/* For "extra" axes, allocate the most recent Frame choice. The
- default choice (found above) will apply if no "most recent" choice
- has been encountered. */
- } else {
- iframe[ iselect ] = ifr;
- }
- }
-}
-
-static int PartMatch( AstCmpFrame *template, AstFrame *target,
- int matchsub, int naxes1, const int axes1[],
- int naxes2, const int axes2[],
- int **template_axes, int **target_axes,
- AstMapping **map, AstFrame **result, int *status ) {
-/*
-* Name:
-* PartMatch
-
-* Purpose:
-* Match a CmpFrame template to partitioned target axes.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* int PartMatch( AstCmpFrame *template, AstFrame *target,
-* int matchsub, int naxes1, const int axes1[],
-* int naxes2, const int axes2[],
-* int **template_axes, int **target_axes,
-* AstMapping **map, AstFrame **result, int *status )
-
-* Class Membership:
-* CmpFrame member function.
-
-* Description:
-* This function matches a "template" CmpFrame 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" Frame and
-* "template" CmpFrame from which they are derived.
-*
-* To simplify the matching process for a CmpFrame template, this
-* function requires the caller to specify how the axes of the
-* target Frame should be partitioned between the two component
-* Frames of the template. The function attempts to find a match
-* using this axis partitioning only. In general, the way in which
-* the target axes must be partitioned is not known in advance, so
-* this function must be invoked several times with alternative
-* partitioning before a match will be found.
-
-* Parameters:
-* template
-* Pointer to the template CmpFrame. 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 (i.e. if the
-* target is of a more specialised class than the template). In
-* this latter case, the target is cast down to the class of the
-* template.
-* naxes1
-* The number of target axes to be matched against the first
-* component Frame of the template CmpFrame.
-* axes1
-* An array with "naxes1" elements containing the (zero-based)
-* indices of the target axes to be matched against the first
-* component Frame. Order is not significant.
-* naxes2
-* The number of target axes to be matched against the second
-* component Frame of the template CmpFrame.
-* axes2
-* An array with "naxes2" elements containing the (zero-based)
-* indices of the target axes to be matched against the second
-* component Frame. Order is not significant.
-* 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 (zero-based) index of the
-* template CmpFrame axis from which it is derived. If it is not
-* derived from any template 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 (zero-based) 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 Frame and the template
-* CmpFrame. 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:
-* - The "axes1" and "axes2" arrays should not contain any axis
-* indices in common and should, taken together, list all the axes
-* of the target Frame.
-* - By default, the "result" Frame will have its number of axes
-* and axis order determined by the "template" CmpFrame. However,
-* if the PreserveAxes attribute of the template is non-zero, then
-* the axis count and axis order of the "target" Frame will be used
-* instead.
-* - 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.
-*/
-
-/* Local Variables: */
- AstFrame *frame1; /* Pointer to first sub-Frame from target */
- AstFrame *frame2; /* Pointer to second sub-Frame from target */
- AstFrame *result1; /* Result Frame pointer from first match */
- AstFrame *result2; /* Result Frame pointer from second match */
- AstFrame *tmp_frame; /* Temporary Frame pointer */
- AstMapping *junk_map; /* Mapping pointer returned by astSubFrame */
- AstMapping *map1; /* Mapping pointer from first match */
- AstMapping *map2; /* Mapping pointer from second match */
- AstMapping *permmap; /* Pointer to PermMap */
- AstMapping *tmp_map; /* Temporary Mapping pointer */
- const int *perm; /* Template axis permutation array pointer */
- int *inperm; /* Pointer to temporary permutation array */
- int *invperm; /* Inverse axis permutation array pointer */
- int *outperm; /* Pointer to temporary permutation array */
- int *pick; /* Pointer to array of axis selections */
- int *result_order; /* Relative result axis order array pointer */
- int *result_perm; /* Result axis permutation array pointer */
- int *target_assoc; /* Target axis association array pointer */
- int *target_axes1; /* Target axis associations from 1st match */
- int *target_axes2; /* Target axis associations from 2nd match */
- int *template_assoc; /* Template axis association array pointer */
- int *template_axes1; /* Template axis associations, 1st match */
- int *template_axes2; /* Template axis associations, 2nd match */
- int first; /* Axis in 1st component? */
- int full_axis; /* Result Frame axis index, before sub-set */
- int match1; /* First match successful? */
- int match2; /* Second match successful? */
- int match; /* Both matches successful? (result) */
- int match_end1; /* MatchEnd attribute for component 1 */
- int match_end2; /* MatchEnd attribute for component 2 */
- int match_end; /* MatchEnd attribute for template */
- int match_end_set; /* Component MatchEnd attribute set? */
- int output_axis; /* Output axis index */
- int part_result_axis; /* Result Frame component axis index */
- int part_target_axis; /* Target Frame component axis index */
- int part_template_axis; /* Template CmpFrame component axis index */
- int permute_set; /* Component Permute attribute set? */
- int permute_value; /* Component Permute attribute value */
- int preserve_axes; /* Template PreserveAxes attribute value */
- int preserve_axes_set; /* Component PreserveAxes attribute set? */
- int ref_naxes; /* Number of reference Frame axes */
- int result_axis; /* Result Frame axis index */
- int result_naxes1; /* Number of result Frame axes, component 1 */
- int result_naxes2; /* Number of result Frame axes, component 2 */
- int result_naxes; /* Total number of result Frame axes */
- int target_axis; /* Target Frame axis index */
- int target_naxes; /* Number of target Frame axes */
- int template_axis; /* Template CmpFrame axis index */
- int template_naxes1; /* Number of template axes, component 1 */
- int template_naxes; /* Total number of template 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;
-
-/* Initialise other variables to avoid compiler errors. */
- ref_naxes = 0;
-
-/* Select the required sub-Frames from the target. */
-/* ----------------------------------------------- */
-/* We first create two sub-Frames (that can be matched against the two
- template component Frames) by selecting the two specified sets of
- axes from the target. This is done without overlaying any template
- attributes. Annul the Mappings produced by this process, as these
- are not needed. */
-
- frame1 = NULL;
- junk_map = NULL;
- (void) astSubFrame( target, NULL, naxes1, axes1, NULL, &junk_map, &frame1 );
- if( junk_map ) junk_map = astAnnul( junk_map );
-
- frame2 = NULL;
- junk_map = NULL;
- (void) astSubFrame( target, NULL, naxes2, axes2, NULL, &junk_map, &frame2 );
- if( junk_map ) junk_map = astAnnul( junk_map );
-
-/* Match the sub-Frames with the template component Frames. */
-/* -------------------------------------------------------- */
-/* We now have two sub-Frames obtained from the target, and will
- attempt to match these with the component Frames contained within
- the template CmpFrame. */
-
-/* Before using each template component Frame, see whether any of its
- attributes that control matching is "un-set". If so, over-ride it
- with the attribute value of the template CmpFrame as a whole. */
- match_end_set = astTestMatchEnd( template->frame1 );
- if ( !match_end_set ) {
- astSetMatchEnd( template->frame1, astGetMatchEnd( template ) );
- }
- preserve_axes_set = astTestPreserveAxes( template->frame1 );
- if ( !preserve_axes_set ) {
- astSetPreserveAxes( template->frame1, astGetPreserveAxes( template ) );
- }
-
-/* We must also temporarily set the Permute attribute to 1 (this is
- normally the default, but might have been set otherwise). This is
- needed so that permutations of the target axes will be considered.
- Without this, the order in which the axes are presented is
- significant and we would have to test all the permutations. If the
- Permute attribute of the template CmpFrame as a whole is zero, then
- the resulting match may still have to be rejected, but this must be
- done at a higher level. */
- permute_set = astTestPermute( template->frame1 );
- permute_value = ( permute_set ) ? astGetPermute( template->frame1 ) : 0;
- astSetPermute( template->frame1, 1 );
-
-/* Test for a match with the first template component Frame. */
- match1 = astMatch( template->frame1, frame1, matchsub,
- &template_axes1, &target_axes1, &map1, &result1 );
-
-/* Clear the attribute values again afterwards if necessary. */
- if ( !match_end_set ) astClearMatchEnd( template->frame1 );
- if ( !preserve_axes_set ) astClearPreserveAxes( template->frame1 );
-
-/* Also restore the original Permute attribute setting. */
- if ( permute_set ) {
- astSetPermute( template->frame1, permute_value );
- } else {
- astClearPermute( template->frame1 );
- }
-
-/* Repeat the whole process for the second component Frame. */
- match_end_set = astTestMatchEnd( template->frame2 );
- if ( !match_end_set ) {
- astSetMatchEnd( template->frame2, astGetMatchEnd( template ) );
- }
- preserve_axes_set = astTestPreserveAxes( template->frame2 );
- if ( !preserve_axes_set ) {
- astSetPreserveAxes( template->frame2, astGetPreserveAxes( template ) );
- }
- permute_set = astTestPermute( template->frame2 );
- if ( permute_set ) permute_value = astGetPermute( template->frame2 );
- astSetPermute( template->frame2, 1 );
-
- match2 = astMatch( template->frame2, frame2, matchsub,
- &template_axes2, &target_axes2, &map2, &result2 );
-
- if ( !match_end_set ) astClearMatchEnd( template->frame2 );
- if ( !preserve_axes_set ) astClearPreserveAxes( template->frame2 );
- if ( permute_set ) {
- astSetPermute( template->frame2, permute_value );
- } else {
- astClearPermute( template->frame2 );
- }
-
-/* See if both matches were successful. */
- if ( astOK && match1 && match2 ) {
- match = 1;
-
-/* Obtain the number of target axes. */
- target_naxes = astGetNaxes( target );
-
-/* Obtain the number of axes in each of the result Frames produced by
- the matching operation. */
- result_naxes1 = astGetNaxes( result1 );
- result_naxes2 = astGetNaxes( result2 );
-
-/* Obtain the number of axes in the first template component Frame and
- in the template CmpFrame as a whole. */
- template_naxes1 = astGetNaxes( template->frame1 );
- template_naxes = astGetNaxes( template );
-
-/* Obtain the value of the MatchEnd attribute for each of the
- template's component Frames and for the template CmpFrame as a
- whole. */
- match_end1 = astGetMatchEnd( template->frame1 );
- match_end2 = astGetMatchEnd( template->frame2 );
- match_end = astGetMatchEnd( template );
-
-/* Obtain a pointer to the template CmpFrame's axis permutation
- array. Allocate space for a further array and fill it with the
- inverse of this axis permutation. */
- perm = astGetPerm( template );
- invperm = astMalloc( sizeof( int ) * (size_t) template_naxes );
- if ( astOK ) {
- for ( template_axis = 0; template_axis < template_naxes;
- template_axis++ ) {
- invperm[ perm[ template_axis ] ] = template_axis;
- }
- }
-
-/* Generate template and target axis associations. */
-/* ----------------------------------------------- */
-/* We now construct two arrays which identify the axis associations
- between the result axes (in the order obtained from the matching
- process above) and the axes of the template and target. This
- involves tracing back through several steps. */
-
-/* First calculate the total number of result axes and allocate memory
- for the association arrays. */
- result_naxes = result_naxes1 + result_naxes2;
- template_assoc = astMalloc( sizeof( int ) * (size_t) result_naxes );
- target_assoc = astMalloc( sizeof( int ) * (size_t) result_naxes );
- if ( astOK ) {
-
-/* Produce associations for each result axis in turn. */
- for ( result_axis = 0; result_axis < result_naxes; result_axis++ ) {
-
-/* Decide whether this result axis is contained in the first (or
- second) individual result Frame. */
- first = ( result_axis < result_naxes1 );
-
-/* Obtain the index of the axis within the individual result Frame.
- This involves adjusting for the axis numbering offset of the second
- result Frame if necessary. */
- part_result_axis = first ? result_axis :
- result_axis - result_naxes1;
-
-/* Find the template and target axis associations for this axis by
- looking them up in the association arrays returned from the
- matching process. This gives axis indices that apply to the
- individual template/target Frames supplied as input to the matching
- process. */
- part_template_axis = first ? template_axes1[ part_result_axis ] :
- template_axes2[ part_result_axis ];
- part_target_axis = first ? target_axes1[ part_result_axis ] :
- target_axes2[ part_result_axis ];
-
-/* Check that the resulting template association identifies a valid
- template axis. */
- if ( part_template_axis != -1 ) {
-
-/* If so, obtain the template axis index. This involves adjusting for
- the axis numbering offset of the second template component Frame
- (if necessary) and then applying the inverse template axis
- permutation to convert to the external template axis
- numbering. Store the result in the template association array. */
- template_assoc[ result_axis ] =
- invperm[ first ? part_template_axis :
- part_template_axis + template_naxes1 ];
-
-/* Indicate if there is no template axis association by storing an
- index of -1. */
- } else {
- template_assoc[ result_axis ] = -1;
- }
-
-/* Similarly, check that the target association identifies a valid
- target axis. */
- if ( part_target_axis != -1 ) {
-
-/* If so, obtain the target axis index. This simply involves using the
- axis selection arrays provided by the caller to look up which
- target axes were involved in the matching process. */
- target_assoc[ result_axis ] =
- first ? axes1[ part_target_axis ] :
- axes2[ part_target_axis ];
-
-/* Indicate if there is no target axis association by storing an index
- of -1. */
- } else {
- target_assoc[ result_axis ] = -1;
- }
- }
- }
-
-/* Free the inverse axis permutation array. */
- invperm = astFree( invperm );
-
-/* Create the output Frame. */
-/* ------------------------ */
-/* Initialise. */
- result_order = NULL;
- result_perm = NULL;
-
-/* Construct the basis of the final result Frame by combining the two
- individual result Frames (from the matching process) using a
- CmpFrame. */
- if ( astOK ) {
- *result = (AstFrame *) astCmpFrame( result1, result2, "", status );
-
-/* The next step is to permute the result Frame's axis order so that
- it corresponds with the axis order of the "reference Frame". The
- reference Frame is either the template or the target, depending on
- whether the template's PreserveAxes attribute is non-zero. Obtain
- the value of this attribute. */
- preserve_axes = astGetPreserveAxes( template );
-
-/* Decide how many axes the reference Frame contains. */
- ref_naxes = preserve_axes ? target_naxes : template_naxes;
-
-/* Make a copy of the axis association array that refers to the
- reference Frame. */
- result_order = astStore( NULL,
- preserve_axes ? target_assoc :
- template_assoc,
- sizeof( int ) * (size_t) result_naxes );
-
-/* The intention is to use this axis association array to permute the
- result axes into the same order as the reference Frame's axes. It
- is not that simple, however, because some of the axis associations
- may be null (i.e. result axes may exist that are not associated
- with reference axes) and they may also be incomplete (i.e. not
- every reference axis may be associated with a result axis).
-
- This prevents us from permuting the result axis order using this
- array directly, essentially because we haven't yet defined where
- any "extra" result axes (those with no association) should appear
- in the final axis order. */
-
-/* To overcome this, we replace all the null (-1) entries in the
- "result_order" array with new values which define their position
- relative to the other entries. This also involves re-numbering
- other entries to avoid clashes. The new numbers assigned depend on
- the MatchEnd attribute for each of the template component Frames,
- so we handle the associations for each of these components
- separately. */
- AddExtraAxes( result_naxes, result_order,
- 0, result_naxes1 - 1, match_end1, status );
- AddExtraAxes( result_naxes, result_order,
- result_naxes1, result_naxes - 1, match_end2, status );
-
-/* There may now be some reference Frame axes which are not referenced
- in this array, so we renumber the entries starting at zero (but
- preserving their relative order) so that there are no missing
- values due to these. */
- RenumberAxes( result_naxes, result_order, status );
-
-/* The resulting "result_order" array no longer describes the original
- reference Frame axis associations, but is now suitable for
- permuting the result axes into the required order. However, we
- require the inverse of this permutation, so allocate an array and
- fill it with the inverse. */
- result_perm = astMalloc( sizeof( int ) * (size_t) result_naxes );
- if ( astOK ) {
- for ( result_axis = 0; result_axis < result_naxes;
- result_axis++ ) {
- result_perm[ result_order[ result_axis ] ] = result_axis;
- }
- }
-
-/* Apply the inverse permutation to the result CmpFrame to put its
- axes into the required order. */
- astPermAxes( *result, result_perm );
-
-/* Check if the number of result Frame axes differs from the number of
- reference axes. This can arise if the PreserveAxes attribute of
- either template component Frame is set to a value that differs from
- that of the template CmpFrame as a whole. If this is the case, we
- must select a sub-set (or super-set) of the result axes, so that we
- end up with the same number of axes as the reference Frame. */
- if ( ref_naxes != result_naxes ) {
-
-/* Allocate an array to hold the indices of the axes required. */
- pick = astMalloc( sizeof( int ) * (size_t) ref_naxes );
- if ( astOK ) {
-
-/* Generate the axis indices, using the template CmpFrame's MatchEnd
- attribute to decide which ones to use. */
- for ( output_axis = 0; output_axis < ref_naxes;
- output_axis++ ) {
- full_axis =
- match_end ? output_axis + ( result_naxes - ref_naxes ) :
- output_axis;
-
-/* If the index is valid (i.e. the required axis is available), store
- it. Otherwise, use an index of -1, which requests that new
- (default) axes be supplied where needed. */
- if ( ( full_axis >= 0 ) && ( full_axis < result_naxes ) ) {
- pick[ output_axis ] = full_axis;
- } else {
- pick[ output_axis ] = -1;
- }
- }
- }
-
-/* Pick the required axes from the result Frame and replace it with
- the new one. */
- tmp_frame = astPickAxes( *result, ref_naxes, pick, NULL );
- *result = astAnnul( *result );
- *result = tmp_frame;
-
-/* Free the array of axis indices. */
- pick = astFree( pick );
- }
- }
-
-/* Create output axis association arrays. */
-/* -------------------------------------- */
-/* We now construct the two arrays that are returned to identify which
- template and target axes (if any) are associated with each final
- result Frame axis. Allocate memory for these arrays. */
- if ( astOK ) {
- *target_axes = astMalloc( sizeof( int ) * (size_t) ref_naxes );
- *template_axes = astMalloc( sizeof( int ) * (size_t) ref_naxes );
- if ( astOK ) {
-
-/* For each output axis, obtain the original result axis index (before
- any sub-set or super-set of the output axes was selected). */
- for ( output_axis = 0; output_axis < ref_naxes; output_axis++ ) {
- full_axis =
- match_end ? output_axis + ( result_naxes - ref_naxes ) :
- output_axis;
-
-/* Derive the result axis index before the axes were permuted into
- their final order. */
- if ( ( full_axis >= 0 ) && ( full_axis < result_naxes ) ) {
- result_axis = result_perm[ full_axis ];
-
-/* Use this axis index and the axis association arrays generated
- earlier to obtain the required associations, and store these in the
- output arrays. */
- ( *template_axes )[ output_axis ] =
- template_assoc[ result_axis ];
- ( *target_axes )[ output_axis ] =
- target_assoc[ result_axis ];
-
-/* Store a value of -1 if there is no association. */
- } else {
- ( *template_axes )[ output_axis ] = -1;
- ( *target_axes )[ output_axis ] = -1;
- }
- }
- }
- }
-
-/* Free the original (un-permuted) axis association arrays. */
- template_assoc = astFree( template_assoc );
- target_assoc = astFree( target_assoc );
-
-/* Create the output Mapping. */
-/* -------------------------- */
-/* Construct the basis of the final output Mapping by combining the
- Mappings produced by the individual matching processes in parallel,
- using a CmpMap. */
- *map = (AstMapping *) astCmpMap( map1, map2, 0, "", status );
-
-/* It is now necessary to prefix and suffix this CmpMap with two
- PermMaps, which correct the input and output axis order to
- correspond with the target and result Frame axes.
-
- At the target end, this reflects the partitioning of the target
- axes into two groups, as specified by the caller. At the result
- end, it reflects the axis permutation applied (above) to put the
- final result Frame axes into the required order, together with the
- selection of any sub-set or super-set of these axes. */
-
-/* Allocate memory for permutation arrays to describe the prefix
- PermMap. */
- inperm = astMalloc( sizeof( int ) * (size_t) target_naxes );
- outperm = astMalloc( sizeof( int ) * (size_t) target_naxes );
- if ( astOK ) {
-
-/* Consider the target axes in the order that they were supplied to
- the matching processes (i.e. the order that corresponds with the
- input coordinates of the CmpMap produced above). */
- for ( target_axis = 0; target_axis < target_naxes; target_axis++ ) {
-
-/* Decide whether each axis belongs to the first (or second) selected
- group of target axes. */
- first = ( target_axis < naxes1 );
-
-/* Obtain the index of the target axis within the group. This involves
- allowing for the numbering offset of the second group if
- necessary. */
- part_target_axis = first ? target_axis :
- target_axis - naxes1;
-
-/* Obtain the original target axis index by looking up the axis in the
- appropriate axis selection array provided by the caller. */
- outperm[ target_axis ] = first ? axes1[ part_target_axis ] :
- axes2[ part_target_axis ];
-
-/* Fill the "inperm" array with the inverse of this permutation. */
- inperm[ outperm[ target_axis ] ] = target_axis;
- }
- }
-
-/* If the permutation is not null, use these permutation arrays to
- construct the required prefix PermMap. */
- if ( GoodPerm( target_naxes, inperm, target_naxes, outperm, status ) ) {
- permmap = (AstMapping *) astPermMap( target_naxes, inperm,
- target_naxes, outperm,
- NULL, "", status );
-
-/* Add the PermMap as a prefix to the result Mapping and then annul
- the original Mapping pointers. */
- tmp_map = (AstMapping *) astCmpMap( permmap, *map, 1, "", status );
- (void) astAnnul( *map );
- *map = tmp_map;
- permmap = astAnnul( permmap );
- }
-
-/* Free the permutation arrays. */
- inperm = astFree( inperm );
- outperm = astFree( outperm );
-
-/* Allocate memory for permutation arrays to describe the suffix
- PermMap. */
- inperm = astMalloc( sizeof( int ) * (size_t) result_naxes );
- outperm = astMalloc( sizeof( int ) * (size_t) ref_naxes );
- if ( astOK ) {
-
-/* Initialise the "inperm" array. */
- for ( result_axis = 0; result_axis < result_naxes; result_axis++ ) {
- inperm[ result_axis ] = -1;
- }
-
-/* For each output axis, obtain the index of the corresponding result
- axis before any sub-set or super-set was selected. */
- for ( output_axis = 0; output_axis < ref_naxes; output_axis++ ) {
- full_axis =
- match_end ? output_axis + ( result_naxes - ref_naxes ) :
- output_axis;
-
-/* Store the axis index before the result axes were permuted, and also
- construct the inverse permutation. */
- if ( ( full_axis >= 0 ) && ( full_axis < result_naxes ) ) {
- outperm[ output_axis ] = result_perm[ full_axis ];
- inperm[ outperm[ output_axis ] ] = output_axis;
-
-/* Note which output axes do not exist in the result Frame
- (e.g. because a super-set was selected). */
- } else {
- outperm[ output_axis ] = -1;
- }
- }
- }
-
-/* If the permutation is not null, use these permutation arrays to
- construct the required suffix PermMap. */
- if ( GoodPerm( target_naxes, inperm, target_naxes, outperm, status ) ) {
- permmap = (AstMapping *) astPermMap( result_naxes, inperm,
- ref_naxes, outperm,
- NULL, "", status );
-
-/* Add the PermMap as a suffix to the result Mapping and then annul
- the original Mapping pointers. */
- tmp_map = (AstMapping *) astCmpMap( *map, permmap, 1, "", status );
- (void) astAnnul( *map );
- *map = tmp_map;
- permmap = astAnnul( permmap );
- }
-
-/* Free the permutation arrays. */
- inperm = astFree( inperm );
- outperm = astFree( outperm );
-
-/* Free the result axis permutation arrays. */
- result_order = astFree( result_order );
- result_perm = astFree( result_perm );
- }
-
-/* If necessary, free the results of the first matching process. */
- if ( match1 ) {
- template_axes1 = astFree( template_axes1 );
- target_axes1 = astFree( target_axes1 );
- map1 = astAnnul( map1 );
- result1 = astAnnul( result1 );
- }
-
-/* If necessary, free the results of the second matching process. */
- if ( match2 ) {
- template_axes2 = astFree( template_axes2 );
- target_axes2 = astFree( target_axes2 );
- map2 = astAnnul( map2 );
- result2 = astAnnul( result2 );
- }
-
-/* Annul the pointers to the sub-Frames selected from the target. */
- frame1 = astAnnul( frame1 );
- frame2 = astAnnul( frame2 );
-
-/* If an error occurred, free all allocated memory, annul the result
- Object pointers and clear all returned values. */
- if ( !astOK ) {
- *template_axes = astFree( *template_axes );
- *target_axes = astFree( *target_axes );
- *map = astAnnul( *map );;
- *result = astAnnul( *result );
- match = 0;
- }
-
-/* Return the result. */
- return match;
-}
-
-static void PermAxes( AstFrame *this_frame, const int perm[], int *status ) {
-/*
-* Name:
-* PermAxes
-
-* Purpose:
-* Permute the order of a CmpFrame's axes.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void astPermAxes( AstFrame *this, const int perm[], int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astPermAxes method
-* inherited from the Frame class).
-
-* Description:
-* This function permutes the order in which a CmpFrame's axes occur.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* perm
-* An array of int (with one element for each axis of the
-* CmpFrame) which lists the axes in their new order. Each
-* element of this array should be a (zero-based) axis index
-* identifying the axes according to their old (un-permuted)
-* order.
-* status
-* Pointer to the inherited status variable.
-
-* Notes:
-* - Only genuine permutations of the axis order are permitted, so
-* each axis must be referenced exactly once in the "perm" array.
-* - If more than one axis permutation is applied to a CmpFrame,
-* the effects are cumulative.
-
-* Implementation Notes:
-* - This function performs essentially the same operation as the
-* Frame member function which it over-rides. However, it operates
-* on a "perm" array held in the CmpFrame structure (rather than
-* the one in the parent Frame structure). This duplication of the
-* array is necessary because the one in the Frame structure is of
-* zero length, the number of axes in the Frame structure having
-* been set to zero to prevent unnecessary allocation of Axis
-* objects which are not needed by the CmpFrame.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to CmpFrame structure */
- int *old; /* Pointer to copy of old permutation array */
- int axis; /* Loop counter for CmpFrame axes */
- int naxes; /* Number of CmpFrame axes */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Validate the permutation array, to check that it describes a
- genuine permutation. */
- astCheckPerm( this, perm, "astPermAxes" );
-
-/* Obtain the number of CmpFrame axes. */
- naxes = astGetNaxes( this );
-
-/* Allocate memory and use it to store a copy of the old permutation
- array for the CmpFrame. */
- old = astStore( NULL, this->perm, sizeof( int ) * (size_t) naxes );
-
-/* Apply the new axis permutation cumulatively to the old one and
- store the result in the CmpFrame. */
- if ( astOK ) {
- for ( axis = 0; axis < naxes; axis++ ) {
- this->perm[ axis ] = old[ perm[ axis ] ];
- }
- }
-
-/* Free the temporary copy of the old array. */
- old = astFree( old );
-}
-
-static void PrimaryFrame( AstFrame *this_frame, int axis1,
- AstFrame **frame, int *axis2, int *status ) {
-/*
-* Name:
-* PrimaryFrame
-
-* Purpose:
-* Uniquely identify a primary Frame and one of its axes.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void astPrimaryFrame( AstFrame *this, int axis1, AstFrame **frame,
-* int *axis2, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the protected
-* astPrimaryFrame method inherited from the Frame class).
-
-* Description:
-* This function returns information about the underlying (primary)
-* Frame corresponding to a specified CmpFrame axis.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* axis1
-* An axis index (zero-based) identifying the CmpFrame axis for
-* which information is required.
-* frame
-* Address of a location to receive a pointer to the underlying
-* (primary) Frame to which the requested axis belongs
-* (i.e. this will not be a compound Frame).
-* axis2
-* Pointer to an int which is to receive the (zero-based) axis
-* index within "frame" which identifies the axis being referred
-* to, using the axis order that applied when the primary Frame
-* was originally constructed (i.e. this function undoes all
-* subsequent axis pemutations and the effects of combining
-* Frames, in order to reveal the original underlying axis
-* order).
-* status
-* Pointer to the inherited status variable.
-
-* Notes:
-* - This protected method is provided so that class
-* implementations can distinguish the axes of Frames from one
-* another (e.g. can distinguish a longitude axis as being
-* different from a latitide axis) even after their order has been
-* permuted and they have been combined with axes from other
-* Frames.
-* - The reference count of the primary Frame will be incremented
-* by one to reflect the new pointer returned.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to CmpFrame structure */
- int naxes1; /* Number of axes in frame1 */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Validate and permute the axis index supplied. */
- axis1 = astValidateAxis( this, axis1, 1, "astPrimaryFrame" );
-
-/* Obtain the number of axes in the first component Frame. */
- naxes1 = astGetNaxes( this->frame1 );
- if ( astOK ) {
-
-/* Decide which Frame contains the axis and invoke its astPrimaryFrame
- method to obtain the required information. */
- if ( axis1 < naxes1 ) {
- astPrimaryFrame( this->frame1, axis1, frame, axis2 );
- } else {
- astPrimaryFrame( this->frame2, axis1 - naxes1, frame, axis2 );
- }
- }
-}
-
-static int QsortCmpAxes( const void *a, const void *b ) {
-/*
-* Name:
-* QsortCmpAxes
-
-* Purpose:
-* Compare two axis indices for "qsort".
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* int QsortCmpAxes( const void *a, const void *b )
-
-* Class Membership:
-* CmpFrame member function.
-
-* Description:
-* This is a service function for the C RTL routine "qsort". It
-* takes the two values supplied and interprets them as integer
-* indices into the static "qsort_axes" array. It compares the
-* values of these two array elements and returns the result
-* required by "qsort".
-*
-* This function is used when sorting an array of indices so that
-* they access the "qsort_axes" array in ascending order.
-
-* Parameters:
-* As required by "qsort".
-
-* Returned Value:
-* As required by "qsort".
-*/
-
-/* Local Variables. */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
- int result; /* Result value to return */
- int val_a; /* First axis index */
- int val_b; /* Second axis index */
-
-/* Get a pointer to the structure holding thread-specific global data. */
- astGET_GLOBALS(NULL);
-
-/* Convert the values passed by "qsort" into integer array indices and
- use these to access the "qsort_axes" array (this pointer to the
- array being assigned by the caller of "qsort"). Extract the two
- values being compared. */
- val_a = qsort_axes[ *( (const int *) a ) ];
- val_b = qsort_axes[ *( (const int *) b ) ];
-
-/* Compare the two values as required by "qsort". */
- if ( val_a < val_b ) {
- result = -1;
- } else if ( val_a == val_b ) {
- result = 0;
- } else {
- result = 1;
- }
-
-/* Return the result. */
- return result;
-}
-
-static AstMapping *RemoveRegions( AstMapping *this_mapping, int *status ) {
-/*
-* Name:
-* RemoveRegions
-
-* Purpose:
-* Remove any Regions from a Mapping.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* AstMapping *RemoveRegions( AstMapping *this, int *status )
-
-* Class Membership:
-* CmpFrame method (over-rides the astRemoveRegions method inherited
-* from the Frame class).
-
-* Description:
-* This function searches the supplied Mapping (which may be a
-* compound Mapping such as a CmpMap) for any component Mappings
-* that are instances of the AST Region class. It then creates a new
-* Mapping from which all Regions have been removed. If a Region
-* cannot simply be removed (for instance, if it is a component of a
-* parallel CmpMap), then it is replaced with an equivalent UnitMap
-* in the returned Mapping.
-*
-* The implementation provided by the CmpFrame class invokes the
-* astRemoveRegions method on the two component Frames, and joins
-* the results together into a new CmpFrame. This replaces any Regions
-* with their equivalent Frames.
-
-* Parameters:
-* this
-* Pointer to the original Region.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A pointer to the modified mapping.
-
-* Notes:
-* - A NULL pointer value will be returned if this function is
-* invoked with the AST error status set, or if it should fail for
-* any reason.
-*/
-
-/* Local Variables: */
- AstCmpFrame *new; /* Pointer to new CmpFrame */
- AstCmpFrame *this; /* Pointer to CmpFrame structure */
- AstFrame *newfrm1; /* New first component Frame */
- AstFrame *newfrm2; /* New second component Frame */
- AstMapping *result; /* Result pointer to return */
-
-/* Initialise. */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Get a pointer to the CmpFrame. */
- this = (AstCmpFrame *) this_mapping;
-
-/* Invoke the astRemoveRegions method on the two component Frames. */
- newfrm1 = astRemoveRegions( this->frame1 );
- newfrm2 = astRemoveRegions( this->frame2 );
-
-/* If neither component was modified, just return a clone of the supplied
- pointer. */
- if( this->frame1 == newfrm1 && this->frame2 == newfrm2 ) {
- result = astClone( this );
-
-/* Annul new new Frame pointers. */
- newfrm1 = astAnnul( newfrm1 );
- newfrm2 = astAnnul( newfrm2 );
-
-/* Otherwise, we need to create a new CmpFrame to return. */
- } else {
-
-/* Make a copy of the supplied CmpFrame so that the new CmpFrame retains
- any attribute settings of the supplied CmpFrame. */
- new = astCopy( this );
- result = (AstMapping *) new;
-
-/* Replace the two component Frames with the simplified Frames. */
- (void) astAnnul( new->frame1 );
- (void) astAnnul( new->frame2 );
- new->frame1 = (AstFrame *) newfrm1;
- new->frame2 = (AstFrame *) newfrm2;
- }
-
-/* Annul the returned Mapping if an error has occurred. */
- if( !astOK ) result = astAnnul( result );
-
-/* Return the result. */
- return result;
-}
-
-static void RenumberAxes( int naxes, int axes[], int *status ) {
-/*
-* Name:
-* RenumberAxes
-
-* Purpose:
-* Renumber axis indices to eliminate missing ones.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void RenumberAxes( int naxes, int axes[], int *status )
-
-* Class Membership:
-* CmpFrame member function.
-
-* Description:
-* This function takes an array containing a list of (zero-based)
-* axis indices referring to the axes of a Frame, some of whose
-* axes may not be referenced. It renumbers the axis indices, to
-* eliminate any which are missing (i.e. not referenced), while
-* preserving the original order. It does this by replacing each
-* axis index by its rank (starting at zero) when the indices are
-* sorted into ascending order.
-
-* Parameters:
-* naxes
-* The number of axis indices present.
-* axes
-* An array, with "naxes" elements, containing the indices. This
-* is modified by this function to contain the new indices.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Declare the thread specific global data */
- int *work; /* Pointer to workspace array */
- int i; /* Loop counter */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Get a pointer to the structure holding thread-specific global data. */
- astGET_GLOBALS(NULL);
-
-/* Allocate workspace. */
- work = astMalloc( sizeof( int ) * (size_t) naxes );
- if ( astOK ) {
-
-/* Fill the workspace with indices which address the axis index values
- in their natural order. */
- for ( i = 0; i < naxes; i++ ) work[ i ] = i;
-
-/* Make the "axes" values available to the C RTL function "qsort" via
- the static "qsort_axes" pointer. Then use "qsort" to permute the
- contents of "work" so that it addresses the axis indices in
- ascending order. */
- qsort_axes = axes;
- qsort( work, (size_t) naxes, sizeof( int ), QsortCmpAxes );
-
-/* Use the result to replace each axis index by its rank when sorted
- into ascending order (starting with zero). */
- for ( i = 0; i < naxes; i++ ) axes[ work[ i ] ] = i;
- }
-
-/* Free the workspace array. */
- work = astFree( work );
-}
-
-static void Resolve( AstFrame *this_frame, const double point1[],
- const double point2[], const double point3[],
- double point4[], double *d1, double *d2, int *status ){
-/*
-* Name:
-* Resolve
-
-* Purpose:
-* Resolve a vector into two orthogonal components
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void Resolve( AstFrame *this, const double point1[],
-* const double point2[], const double point3[],
-* double point4[], double *d1, double *d2, int *status );
-
-* Class Membership:
-* CmpFrame member function (over-rides the astOffset method
-* inherited from the Frame class).
-
-* Description:
-* This function resolves a vector into two perpendicular components.
-* The vector from point 1 to point 2 is used as the basis vector.
-* The vector from point 1 to point 3 is resolved into components
-* parallel and perpendicular to this basis vector. The lengths of the
-* two components are returned, together with the position of closest
-* aproach of the basis vector to point 3.
-
-* Parameters:
-* this
-* Pointer to the Frame.
-* point1
-* An array of double, with one element for each Frame axis
-* (Naxes attribute). This marks the start of the basis vector,
-* and of the vector to be resolved.
-* point2
-* An array of double, with one element for each Frame axis
-* (Naxes attribute). This marks the end of the basis vector.
-* point3
-* An array of double, with one element for each Frame axis
-* (Naxes attribute). This marks the end of the vector to be
-* resolved.
-* point4
-* An array of double, with one element for each Frame axis
-* in which the coordinates of the point of closest approach of the
-* basis vector to point 3 will be returned.
-* d1
-* The address of a location at which to return the distance from
-* point 1 to point 4 (that is, the length of the component parallel
-* to the basis vector). Positive values are in the same sense as
-* movement from point 1 to point 2.
-* d2
-* The address of a location at which to return the distance from
-* point 4 to point 3 (that is, the length of the component
-* perpendicular to the basis vector). The returned value is always
-* positive.
-* status
-* Pointer to the inherited status variable.
-
-* Notes:
-* - Each vector used in this function is the path of
-* shortest distance between two points, as defined by the
-* astDistance function.
-* - This function will return "bad" coordinate values (AST__BAD)
-* if any of the input coordinates has this value, or if the required
-* output values are undefined.
-*--
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- const int *perm; /* Pointer to axis permutation array */
- double *p1; /* Permuted coordinates for point1 */
- double *p2; /* Permuted coordinates for point2 */
- double *p3; /* Permuted coordinates for point3 */
- double *p4; /* Permuted coordinates for point4 */
- double d1a; /* Parallel distance in frame1 */
- double d1b; /* Parallel distance in frame2 */
- double d2a; /* Perpendicular distance in frame1 */
- double d2b; /* Perpendicular distance in frame2 */
- double d; /* Total length of basis vector */
- double da; /* Length of basis vector in frame1 */
- double db; /* Length of basis vector in frame2 */
- int axis; /* Loop counter for axes */
- int bad; /* Set bad output coordinates? */
- int naxes1; /* Number of axes in frame1 */
- int naxes; /* Total number of axes in CmpFrame */
-
-/* Check the global error status. */
- *d1 = AST__BAD;
- *d2 = AST__BAD;
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Obtain the number of axes in the CmpFrame. */
- naxes = astGetNaxes( this );
-
-/* Obtain a pointer to the CmpFrame's axis permutation array. */
- perm = astGetPerm( this );
-
-/* Allocate workspace. */
- p1 = astMalloc( sizeof( double ) * (size_t) naxes );
- p2 = astMalloc( sizeof( double ) * (size_t) naxes );
- p3 = astMalloc( sizeof( double ) * (size_t) naxes );
- p4 = astMalloc( sizeof( double ) * (size_t) naxes );
-
-/* Initialise a flag to indicate whether "bad" coordinates should be
- returned. */
- bad = 0;
-
-/* Initialise ther variables to avoid compiler warnings. */
- da = 0.0;
- db = 0.0;
-
-/* Check that all the coordinates of both input points are OK. If not,
- set the "bad" flag and quit checking. */
- if ( astOK ) {
- for ( axis = 0; axis < naxes; axis++ ) {
- if ( ( point1[ axis ] == AST__BAD ) ||
- ( point2[ axis ] == AST__BAD ) ||
- ( point3[ axis ] == AST__BAD ) ) {
- bad = 1;
- break;
-
-/* If the coordinates are OK, apply the axis permutation array to
- obtain them in the required order. */
- } else {
- p1[ perm[ axis ] ] = point1[ axis ];
- p2[ perm[ axis ] ] = point2[ axis ];
- p3[ perm[ axis ] ] = point3[ axis ];
- }
- }
- }
-
-/* If OK, obtain the number of axes in the first component Frame. */
- if ( astOK && !bad ) {
- naxes1 = astGetNaxes( this->frame1 );
-
-/* Find the projection of the required parallel distance into each of the
- two Frames. */
- astResolve( this->frame1, p1, p2, p3, p4, &d1a, &d2a );
- astResolve( this->frame2, p1 + naxes1, p2 + naxes1, p3 + naxes1,
- p4 + naxes1, &d1b, &d2b );
-
-/* Project the first two input points into the two component Frames and
- determine the length of the basis vector in each Frame. */
- da = astDistance( this->frame1, p1, p2 );
- db = astDistance( this->frame2, p1 + naxes1, p2 + naxes1 );
-
-/* Check that the returned distances are not bad. */
- if ( astOK ) bad = ( bad || ( da == AST__BAD ) || ( db == AST__BAD ) );
-
-/* We can tolerate a bad parallel distance within a sub-Frame if the
- basis vector has zero length in the sub-Frame, because the bad
- parallel distance will have zero weight in the calculation. Set such
- bad parallel distanced arbitrarily to zero. */
- if( d1a == AST__BAD && da == 0.0 ) d1a = 0.0;
- if( d1b == AST__BAD && db == 0.0 ) d1b = 0.0;
-
-/* Check that the final parallel distances are not bad. */
- if ( astOK ) bad = ( bad || ( d1a == AST__BAD ) || ( d1b == AST__BAD ) );
-
- }
-
-/* If OK, calculate the total distance between the two points. */
- if ( astOK && !bad ) {
- d = sqrt( da * da + db * db );
-
-/* If the points are co-incident, then set the "bad" flag. */
- if ( d == 0.0 ) {
- bad = 1;
-
-/* If the points are not co-incident, combine the parallel distances for
- the individual Frames into a single parallel distance for the entire
- CmpFrame. */
- } else {
- *d1 = ( da*d1a + db*d1b )/d;
-
-/* Offset this distance away from point 1 towards point 2 to get point 4. */
- astOffset( this, point1, point2, *d1, point4 );
-
-/* Now find the perpendicular distance (the distance between point4 and
- point3). */
- *d2 = astDistance( this, point4, point3 );
-
- }
- }
-
-/* Free the workspace arrays. */
- p1 = astFree( p1 );
- p2 = astFree( p2 );
- p3 = astFree( p3 );
- p4 = astFree( p4 );
-
-/* If no error has occurred, but bad coordinates must be returned,
- then set these in the output array. */
- if ( astOK && bad ) {
- *d1 = AST__BAD;
- *d2 = AST__BAD;
- for ( axis = 0; axis < naxes; axis++ ) point4[ axis ] = AST__BAD;
- }
-
-}
-
-static AstPointSet *ResolvePoints( AstFrame *this_frame, const double point1[],
- const double point2[], AstPointSet *in,
- AstPointSet *out, int *status ) {
-/*
-* Name:
-* ResolvePoints
-
-* Purpose:
-* Resolve a set of vectors into orthogonal components
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* AstPointSet *ResolvePoints( AstFrame *this, const double point1[],
-* const double point2[], AstPointSet *in,
-* AstPointSet *out )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astResolvePoints method
-* inherited from the Frame class).
-
-* Description:
-* This function takes a CmpFrame and a set of vectors encapsulated
-* in a PointSet, and resolves each one into two orthogonal components,
-* returning these two components in another PointSet.
-*
-* This is exactly the same as the public astResolve method, except
-* that this method allows many vectors to be processed in a single call,
-* thus reducing the computational cost of overheads of many
-* individual calls to astResolve.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* point1
-* An array of double, with one element for each Frame axis
-* (Naxes attribute). This marks the start of the basis vector,
-* and of the vectors to be resolved.
-* point2
-* An array of double, with one element for each Frame axis
-* (Naxes attribute). This marks the end of the basis vector.
-* in
-* Pointer to the PointSet holding the ends of the vectors to be
-* resolved.
-* out
-* Pointer to a PointSet which will hold the length of the two
-* resolved components. A NULL value may also be given, in which
-* case a new PointSet will be created by this function.
-
-* Returned Value:
-* Pointer to the output (possibly new) PointSet. The first axis will
-* hold the lengths of the vector components parallel to the basis vector.
-* These values will be signed (positive values are in the same sense as
-* movement from point 1 to point 2. The second axis will hold the lengths
-* of the vector components perpendicular to the basis vector. These
-* values will always be positive.
-
-* Notes:
-* - The number of coordinate values per point in the input
-* PointSet must match the number of axes in the supplied Frame.
-* - If an output PointSet is supplied, it must have space for
-* sufficient number of points and 2 coordinate values per point.
-* - 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: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- AstPointSet *in1; /* Pointer to input PointSet for frame1 */
- AstPointSet *in2; /* Pointer to input PointSet for frame2 */
- AstPointSet *out1; /* Pointer to output PointSet for frame1 */
- AstPointSet *out2; /* Pointer to output PointSet for frame2 */
- AstPointSet *result; /* Pointer to output PointSet */
- const int *perm; /* Pointer to axis permutation array */
- double **ptr_in; /* Pointers to input axis values */
- double **ptr_out1; /* Pointers to frame1 component lengths */
- double **ptr_out2; /* Pointers to frame2 component lengths */
- double **ptr_out; /* Pointers to returned component lengths */
- double *d1; /* Pointer to next parallel component value */
- double *d1_1; /* arallel distance in frame1 */
- double *d1_2; /* Parallel distance in frame2 */
- double *d2; /* Pointer to next perpendicular component value */
- double *d2_1; /* Perpendicular distance in frame1 */
- double *d2_2; /* Perpendicular distance in frame2 */
- double *p1; /* Permuted coordinates for point1 */
- double *p2; /* Permuted coordinates for point2 */
- double *p3; /* Supplied vector */
- double *p4; /* Closest approach to supplied vector */
- double b1; /* Length of basis vector in frame1 */
- double b2; /* Length of basis vector in frame2 */
- double b; /* Length of basis vector */
- int axis; /* Loop counter for axes */
- int ipoint; /* Index of next point */
- int nax; /* Number of Frame axes */
- int naxes1; /* Number of axes in frame1 */
- int naxes2; /* Number of axes in frame2 */
- int ncoord_in; /* Number of input PointSet coordinates */
- int ncoord_out; /* Number of coordinates in output PointSet */
- int npoint; /* Number of points to transform */
- int npoint_out; /* Number of points in output PointSet */
-
-/* Initialise. */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Further initialise to prevent compiler "uninitialised use" messages. */
- d1 = NULL;
- d2 = NULL;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Obtain the number of axes in the two component Frames */
- naxes1 = astGetNaxes( this->frame1 );
- naxes2 = astGetNaxes( this->frame2 );
-
-/* For the total number of axes. */
- nax = naxes1 + naxes2;
-
-/* Obtain the number of input vectors to resolve and the number of coordinate
- values per vector. */
- npoint = astGetNpoint( in );
- ncoord_in = astGetNcoord( in );
-
-/* If OK, check that the number of input coordinates matches the number
- required by the Frame. Report an error if these numbers do not match. */
- if ( astOK && ( ncoord_in != nax ) ) {
- astError( AST__NCPIN, "astResolvePoints(%s): Bad number of coordinate "
- "values (%d) in input %s.", status, astGetClass( this ), ncoord_in,
- astGetClass( in ) );
- astError( AST__NCPIN, "The %s given requires %d coordinate value(s) for "
- "each input point.", status, astGetClass( this ), nax );
- }
-
-/* If still OK, and a non-NULL pointer has been given for the output PointSet,
- then obtain the number of points and number of coordinates per point for
- this PointSet. */
- if ( astOK && out ) {
- npoint_out = astGetNpoint( out );
- ncoord_out = astGetNcoord( out );
-
-/* Check that the dimensions of this PointSet are adequate to accommodate the
- output coordinate values and report an error if they are not. */
- if ( astOK ) {
- if ( npoint_out < npoint ) {
- astError( AST__NOPTS, "astResolvePoints(%s): Too few points (%d) in "
- "output %s.", status, astGetClass( this ), npoint_out,
- astGetClass( out ) );
- astError( AST__NOPTS, "The %s needs space to hold %d transformed "
- "point(s).", status, astGetClass( this ), npoint );
- } else if ( ncoord_out < 2 ) {
- astError( AST__NOCTS, "astResolvePoints(%s): Too few coordinate "
- "values per point (%d) in output %s.", status,
- astGetClass( this ), ncoord_out, astGetClass( out ) );
- astError( AST__NOCTS, "The %s supplied needs space to store 2 "
- "coordinate value(s) per transformed point.", status,
- astGetClass( this ) );
- }
- }
- }
-
-/* If all the validation stages are passed successfully, and a NULL output
- pointer was given, then create a new PointSet to encapsulate the output
- coordinate data. */
- if ( astOK ) {
- if ( !out ) {
- result = astPointSet( npoint, 2, "", status );
-
-/* Otherwise, use the PointSet supplied. */
- } else {
- result = out;
- }
- }
-
-/* Store points to the first two axis arrays in the returned PointSet. */
- ptr_out = astGetPoints( result );
- if( astOK ) {
- d1 = ptr_out[ 0 ];
- d2 = ptr_out[ 1 ];
- }
-
-/* Obtain a pointer to the CmpFrame's axis permutation array. This array
- holds the original axis index for each current Frame axis index. */
- perm = astGetPerm( this );
-
-/* Temporarily permute the coordinates within the supplied PointSet back
- in to the axis order which existed when the CmpFrame was created. */
- astPermPoints( in, 0, perm );
-
-/* Extract the axis values relevant to each of the two sub-Frames from the
- point1 and point2 arrays, at the same time undoing any axis permutation
- applied to the CmpFrame as a whole. */
- p1 = astMalloc( sizeof( double )*( size_t )nax );
- p2 = astMalloc( sizeof( double )*( size_t )nax );
- if( astOK ) {
- for( axis = 0; axis < nax; axis++ ) {
- p1[ perm[ axis ] ] = point1[ axis ];
- p2[ perm[ axis ] ] = point2[ axis ];
- }
- }
-
-/* Project the first two input points into the two component Frames and
- determine the length of the basis vector in each Frame. */
- b1 = astDistance( this->frame1, p1, p2 );
- b2 = astDistance( this->frame2, p1 + naxes1, p2 + naxes1 );
-
-/* If either of these distances is bad or if both are zero, then fill the
- returned PointSet with bad values. */
- if( b1 == AST__BAD || b2 == AST__BAD || ( b1 == 0.0 && b2 == 0.0 ) ) {
- for( ipoint = 0; ipoint < npoint; ipoint++, d1++, d2++ ) {
- *d1 = AST__BAD;
- *d2 = AST__BAD;
- }
-
-/* Otherwise we continue to calculate the resolved components */
- } else if( astOK ){
-
-/* Calculate the total distance between the two points. */
- b = sqrt( b1*b1 + b2*b2 );
-
-/* Create PointSets holding the input values which refer to each of the
- two component Frames. */
- in1 = astPointSet( npoint, naxes1, "", status );
- in2 = astPointSet( npoint, naxes2, "", status );
-
-/* Associated the appropriate subset of the data in the supplied input
- PointSet with each of these two PointSets. */
- astSetSubPoints( in, 0, 0, in1 );
- astSetSubPoints( in, 0, naxes1, in2 );
-
-/* Invoke the astResolvePoints method on each of the sub-Frames. These
- invocations create two new PointSets containing the output values. */
- out1 = astResolvePoints( this->frame1, p1, p2, in1, NULL );
- out2 = astResolvePoints( this->frame2, p1 + naxes1, p2 + naxes1, in2, NULL );
-
-/* Get pointers to the axis values in these pointsets. */
- ptr_out1 = astGetPoints( out1 );
- ptr_out2 = astGetPoints( out2 );
-
-/* More work space */
- p3 = astMalloc( sizeof( double )*( size_t )nax );
- p4 = astMalloc( sizeof( double )*( size_t )nax );
-
-/* Get pointers to the input axis values (these are still permuted to
- undo any axis permutation applied to the CmpFrame). */
- ptr_in = astGetPoints( in );
-
-/* Check pointers can be used safely. */
- if( astOK ) {
-
-/* Get pointers to the parallel (d1) and perpendiclar (d2) components
- within the two sub-Frames (_1 and _2). */
- d1_1 = ptr_out1[ 0 ];
- d2_1 = ptr_out1[ 1 ];
- d1_2 = ptr_out2[ 0 ];
- d2_2 = ptr_out2[ 1 ];
-
-/* Loop round each supplied vector. */
- for( ipoint = 0; ipoint < npoint; ipoint++, d1++, d2++,
- d1_1++, d2_1++,
- d1_2++, d2_2++ ) {
-
-/* We can tolerate a bad parallel distance within a sub-Frame if the
- basis vector has zero length in the sub-Frame, because the bad
- parallel distance will have zero weight in the calculation. Set such
- bad parallel distanced arbitrarily to zero. */
- if( *d1_1 == AST__BAD && b1 == 0.0 ) *d1_1 = 0.0;
- if( *d1_2 == AST__BAD && b2 == 0.0 ) *d1_2 = 0.0;
-
-/* Combine the parallel distances for the individual Frames into a single
- parallel distance for the entire CmpFrame. */
- if( *d1_1 != AST__BAD && *d1_2 != AST__BAD ) {
- *d1 = ( b1*(*d1_1) + b2*(*d1_2) )/b;
-
-/* Offset this distance away from point 1 towards point 2 to get point 4. */
- astOffset( this, p1, p2, *d1, p4 );
-
-/* Now find the perpendicular distance (the distance between point4 and
- point3). */
- for( axis = 0; axis < nax; axis++ ) p3[ axis ] = ptr_in[ axis ][ ipoint ];
- *d2 = astDistance( this, p4, p3 );
-
- } else {
- *d1 = AST__BAD;
- *d2 = AST__BAD;
- }
- }
- }
-
-/* Free resources */
- in1 = astAnnul( in1 );
- in2 = astAnnul( in2 );
- out1 = astAnnul( out1 );
- out2 = astAnnul( out2 );
- p3 = astFree( p3 );
- p4 = astFree( p4 );
- }
-
-/* Free resources */
- p1 = astFree( p1 );
- p2 = astFree( p2 );
-
-/* Re-instate the original ordering of the coordinates within the
- supplied PointSet. */
- astPermPoints( in, 1, perm );
-
-/* Annul the returned PointSet if an error occurred. */
- if( !astOK ) result = astAnnul( result );
-
-/* Return a pointer to the output PointSet. */
- return result;
-}
-
-static void SetActiveUnit( AstFrame *this_frame, int value, int *status ){
-/*
-* Name:
-* SetActiveUnit
-
-* Purpose:
-* Specify how the Unit attribute should be used.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void SetActiveUnit( AstFrame *this, int value, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astSetActiveUnit method
-* inherited from the Frame class).
-
-* Description:
-* This function sets the current value of the ActiveUnit flag for a
-* CmpFrame, which controls how the Frame behaves when it is used (by
-* astFindFrame) as a template to match another (target) Frame, or is
-* used as the "to" Frame by astConvert. It determines if the Mapping
-* between the template and target Frames should take differences in
-* axis units into account.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* value
-* The new value to use.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Invoke the parent method to set the ActiveUnitFlag for the CmpFrame,
- then set the same value for the component Frames. */
- (*parent_setactiveunit)( this_frame, value, status );
- astSetActiveUnit( ((AstCmpFrame *)this_frame)->frame1, value );
- astSetActiveUnit( ((AstCmpFrame *)this_frame)->frame2, value );
-}
-
-static void SetFrameFlags( AstFrame *this_frame, int value, int *status ){
-/*
-* Name:
-* SetFrameFlags
-
-* Purpose:
-* Set flags that control current Frame behaviour.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void SetFrameFlags( AstFrame *this, int value, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astSetFrameFlags method
-* inherited from the Frame class).
-
-* Description:
-* This function sets values for the bit mask of flags that control
-* how the CmpFrame behaves. It ensures that both component Frames use
-* the the same bitmask as the parent CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* value
-* The new value to use.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Invoke the parent method to set the FrameFlags for the CmpFrame,
- then set the same value for the component Frames. */
- (*parent_setframeflags)( this_frame, value, status );
- astSetFrameFlags( ((AstCmpFrame *)this_frame)->frame1, value );
- astSetFrameFlags( ((AstCmpFrame *)this_frame)->frame2, value );
-}
-
-static int GetActiveUnit( AstFrame *this_frame, int *status ){
-/*
-* Name:
-* GetActiveUnit
-
-* Purpose:
-* Determines how the Unit attribute will be used.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* int GetActiveUnit( AstFrame *this_frame, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astGetActiveUnit method
-* inherited from the Frame class).
-
-* Description:
-* This function returns the current value of the ActiveUnit flag for a
-* CmpFrame. See the description of the astSetActiveUnit function
-* for a description of the ActiveUnit flag.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The current value of the ActiveUnit flag.
-
-*/
-
-/* Local Variables; */
- int result; /* The ActiveUnit flag for the CmpFrame */
-
-/* Check the global error status. */
- if ( !astOK ) return 0;
-
-/* If the ActiveUnit value has been set for the CmpFrame use the parent
- implementation to get its value. */
- if( astTestActiveUnit( this_frame ) ) {
- result = (*parent_getactiveunit)( this_frame, status );
-
-/* Otherwise, the default is determined by the component Frames. If both
- components have active units, the default for the CmpFrame is "on" */
- } else {
- result = astGetActiveUnit( ((AstCmpFrame *)this_frame)->frame1 ) ||
- astGetActiveUnit( ((AstCmpFrame *)this_frame)->frame2 );
- }
-
-/* Return the result */
- return result;
-}
-
-static void SetAttrib( AstObject *this_object, const char *setting, int *status ) {
-/*
-* Name:
-* SetAttrib
-
-* Purpose:
-* Set an attribute value for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void SetAttrib( AstObject *this, const char *setting, int *status )
-
-* Class Membership:
-* CmpFrame member function (extends the astSetAttrib method inherited from
-* the Mapping class).
-
-* Description:
-* This function assigns an attribute value for a CmpFrame, 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 CmpFrame.
-* 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.
-*/
-
-#define BUF_LEN 1024
-
-/* Local Vaiables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- AstFrame *pfrm; /* Pointer to primary Frame containing axis */
- char buf1[BUF_LEN]; /* For for un-indexed attribute name */
- char buf2[BUF_LEN]; /* For for indexed attribute name */
- int axis; /* Supplied (1-base) axis index */
- int len; /* Length of setting string */
- int nc; /* Number of characters read by astSscanf */
- int oldrep; /* Original error reporting state */
- int paxis; /* Index of primary Frame axis */
- int ok; /* Have we accessed the attribute succesfully? */
- int value; /* Offset to start fo value string */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_object;
-
-/* Obtain the length of the setting string. */
- len = strlen( setting );
-
-/* Indicate we have not yet acessed the attribute succesfully. */
- ok = 0;
-
-/* First check the supplied attribute name against each of the attribute
- names defined by this class. In fact there is nothing to do here
- since the CmpFrame class currently defines no extra attributes, but
- this may change in the future. */
- if( 0 ) {
-
-
-
-/* If the attribute is not a CmpFrame specific attribute... */
- } else if( astOK ) {
-
-/* We want to allow easy access to the attributes of the component Frames.
- That is, we do not want it to be necessary to extract a Frame from
- its parent CmpFrame in order to access its attributes. For this reason
- we first temporarily switch off error reporting so that if an attempt
- to access the attribute fails, we can try a different approach. */
- oldrep = astReporting( 0 );
-
-/* Our first attempt is to see if the attribute is recognised by the parent
- class (Frame). */
- (*parent_setattrib)( this_object, setting, status );
-
-/* Indicate success. */
- if( astOK ) {
- ok = 1;
-
-/* Otherwise, clear the error condition so that we can try a different
- approach. */
- } else {
- astClearStatus;
-
-/* If the attribute is qualified by an axis index, try accessing it as an
- attribute of the primary Frame containing the specified index. */
- if ( nc = 0,
- ( 2 == astSscanf( setting, "%[^(=](%d)= %n%*s %n", buf1, &axis,
- &value, &nc ) ) && ( nc >= len ) ) {
-
-/* Find the primary Frame containing the specified axis. */
- astPrimaryFrame( this, axis - 1, &pfrm, &paxis );
- if( astOK ) {
-
-/* astPrimaryFrame returns the original - unpermuted - axis index within
- the primary Frame. So we need to take into account any axis permutation
- which has been applied to the primary Frame when forming the attribute name
- to use below. Find the permuted (external) axis index which corresponds to
- the internal (unpermuted) axis index "paxis". */
- paxis = astValidateAxis( pfrm, paxis, 0, "astSet" );
-
-/* Create a new setting with the same name but with the axis index
- appropriate to the primary Frame. */
- nc = sprintf( buf2, "%s(%d)=%s", buf1, paxis + 1,
- setting+value );
- if( nc < BUF_LEN ) {
-
-/* Attempt to access the attribute. */
- astSetAttrib( pfrm, buf2 );
-
-/* Indicate success. */
- if( astOK ) {
- ok = 1;
-
-/* Otherwise clear the status value, and try again without any axis index. */
- } else {
- astClearStatus;
- sprintf( buf2, "%s=%s", buf1, setting+value );
- astSetAttrib( pfrm, buf2 );
-
-/* Indicate success, or clear the status value. */
- if( astOK ) {
- ok = 1;
- } else {
- astClearStatus;
- }
- }
-
-/* Buffer overflow */
- } else if( astOK ) {
- astError( AST__INTER, "SetAttrib(CmpFrame): Buffer "
- "over-flow (internal AST programming error).",
- status );
- }
-
-/* Free the primary frame pointer. */
- pfrm = astAnnul( pfrm );
- }
-
-/* If the attribute is not qualified by an axis index, try accessing it
- using the primary Frame of each axis in turn. */
- } else {
-
-/* Loop round all axes attribute. */
- for( axis = 0; axis < astGetNaxes( this ); axis++ ) {
-
-/* Get the primary Frame containing this axis. */
- astPrimaryFrame( this, axis, &pfrm, &paxis );
-
-/* Attempt to access the attribute as an attribute of the primary Frame. */
- astSetAttrib( pfrm, setting );
-
-/* Free the primary Frame pointer. */
- pfrm = astAnnul( pfrm );
-
-/* Indicate success, or clear the status value. */
- if( astOK ) {
- ok = 1;
- } else {
- astClearStatus;
- }
- }
- }
- }
-
-/* Re-instate the original error reporting state. */
- astReporting( oldrep );
-
- }
-
-/* Report an error if the attribute could not be accessed. */
- if( !ok && astOK ) {
- astError( AST__BADAT, "astSet: The attribute setting \"%s\" is invalid "
- "for the given %s.", status, setting, astGetClass( this ) );
- }
-
-#undef BUF_LEN
-}
-
-static void SetAxis( AstFrame *this_frame, int axis, AstAxis *newaxis, int *status ) {
-/*
-* Name:
-* SetAxis
-
-* Purpose:
-* Set a new Axis for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void astSetAxis( AstFrame *this, int axis, AstAxis *newaxis, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astSetAxis method
-* inherited from the Frame class).
-
-* Description:
-* This function allows a new Axis object to be associated with one
-* of the axes of a CmpFrame, replacing the previous one. Each Axis
-* object contains a description of the quantity represented along
-* one of the CmpFrame's axes, so this function allows this
-* description to be exchanged for another one.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* axis
-* The index (zero-based) of the CmpFrame axis whose associated
-* Axis object is to be replaced.
-* newaxis
-* Pointer to the new Axis object.
-* status
-* Pointer to the inherited status variable.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- int naxes1; /* Number of axes in frame1 */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Validate and permute the axis index supplied. */
- axis = astValidateAxis( this, axis, 1, "astSetAxis" );
-
-/* Determine the number of axes in the first component Frame. */
- naxes1 = astGetNaxes( this->frame1 );
- if ( astOK ) {
-
-/* Decide which Frame contains the axis and invoke its astSetAxis
- method to set the new Axis. */
- if ( axis < naxes1 ) {
- astSetAxis( this->frame1, axis, newaxis );
- } else {
- astSetAxis( this->frame2, axis - naxes1, newaxis );
- }
- }
-}
-
-static void SetDut1( AstFrame *this_frame, double val, int *status ) {
-/*
-* Name:
-* SetDut1
-
-* Purpose:
-* Set the value of the Dut1 attribute for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void SetDut1( AstFrame *this, double val, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astSetDut1 method
-* inherited from the Frame class).
-
-* Description:
-* This function sets the Dut1 value in the component Frames as
-* well as this CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* val
-* New Dut1 value.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Invoke the parent method to set the CmpFrame Dut1 value. */
- (*parent_setdut1)( this_frame, val, status );
-
-/* Now set the Dut1 attribute in the two component Frames. */
- astSetDut1( this->frame1, val );
- astSetDut1( this->frame2, val );
-}
-
-static void SetEpoch( AstFrame *this_frame, double val, int *status ) {
-/*
-* Name:
-* SetEpoch
-
-* Purpose:
-* Set the value of the Epoch attribute for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void SetEpoch( AstFrame *this, double val, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astSetEpoch method
-* inherited from the Frame class).
-
-* Description:
-* This function sets the Epoch value in the component Frames as
-* well as this CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* val
-* New Epoch value.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Invoke the parent method to set the CmpFrame epoch. */
- (*parent_setepoch)( this_frame, val, status );
-
-/* Now set the Epoch attribute in the two component Frames. */
- astSetEpoch( this->frame1, val );
- astSetEpoch( this->frame2, val );
-}
-
-static void SetObsAlt( AstFrame *this_frame, double val, int *status ) {
-/*
-* Name:
-* SetObsAlt
-
-* Purpose:
-* Set the value of the ObsAlt attribute for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void SetObsAlt( AstFrame *this, double val, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astSetObsAlt method
-* inherited from the Frame class).
-
-* Description:
-* This function sets the ObsAlt value in the component Frames as
-* well as this CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* val
-* New ObsAlt value.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Invoke the parent method to set the CmpFrame ObsAlt. */
- (*parent_setobsalt)( this_frame, val, status );
-
-/* Now set the ObsAlt attribute in the two component Frames. */
- astSetObsAlt( this->frame1, val );
- astSetObsAlt( this->frame2, val );
-}
-
-static void SetObsLat( AstFrame *this_frame, double val, int *status ) {
-/*
-* Name:
-* SetObsLat
-
-* Purpose:
-* Set the value of the ObsLat attribute for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void SetObsLat( AstFrame *this, double val, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astSetObsLat method
-* inherited from the Frame class).
-
-* Description:
-* This function sets the ObsLat value in the component Frames as
-* well as this CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* val
-* New ObsLat value.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Invoke the parent method to set the CmpFrame ObsLat. */
- (*parent_setobslat)( this_frame, val, status );
-
-/* Now set the ObsLat attribute in the two component Frames. */
- astSetObsLat( this->frame1, val );
- astSetObsLat( this->frame2, val );
-}
-
-static void SetObsLon( AstFrame *this_frame, double val, int *status ) {
-/*
-* Name:
-* SetObsLon
-
-* Purpose:
-* Set the value of the ObsLon attribute for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* void SetObsLon( AstFrame *this, double val, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astSetObsLon method
-* inherited from the Frame class).
-
-* Description:
-* This function sets the ObsLon value in the component Frames as
-* well as this CmpFrame.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* val
-* New ObsLon value.
-* status
-* Pointer to the inherited status variable.
-
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Invoke the parent method to set the CmpFrame ObsLon. */
- (*parent_setobslon)( this_frame, val, status );
-
-/* Now set the ObsLon attribute in the two component Frames. */
- astSetObsLon( this->frame1, val );
- astSetObsLon( this->frame2, val );
-}
-
-static AstMapping *Simplify( AstMapping *this_mapping, int *status ) {
-/*
-* Name:
-* Simplify
-
-* Purpose:
-* Simplify the Mapping represented by a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* AstMapping *Simplify( AstMapping *this, int *status )
-
-* Class Membership:
-* CmpFrame method (over-rides the astSimplify method inherited
-* from the Frame class).
-
-* Description:
-* This function simplifies the Mapping represented by a CmpFrame,
-* by using the astSimplify method on each of the component Frames and
-* combining the resulting Mappings together.
-
-* Parameters:
-* this
-* Pointer to the original CmpFrame.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* A new pointer to the simplified CmpFrame.
-
-* Notes:
-* - A NULL pointer value will be returned if this function is
-* invoked with the AST error status set, or if it should fail for
-* any reason.
-*/
-
-/* Local Variables: */
- AstCmpFrame *new; /* Pointer to new CmpFrame structure */
- AstCmpFrame *this; /* Pointer to original CmpFrame structure */
- AstMapping *map1; /* Intermediate Mapping */
- AstMapping *map2; /* Intermediate Mapping */
- AstMapping *result; /* Result pointer to return */
-
-/* Initialise. */
- result = NULL;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_mapping;
-
-/* Simplify each of the component Frames. */
- map1 = astSimplify( this->frame1 );
- map2 = astSimplify( this->frame2 );
-
-/* Did any usable simplification occur? */
- if( astIsAFrame( map1 ) && astIsAFrame( map2 ) &&
- ( map1 != (AstMapping *) this->frame1 ||
- map2 != (AstMapping *) this->frame2 ) ) {
-
-/* Make a copy of the supplied CmpFrame. */
- new = astCopy( this );
- result = (AstMapping *) new;
-
-/* Replace the two component Frames with the simplified Frames. */
- (void) astAnnul( new->frame1 );
- (void) astAnnul( new->frame2 );
- new->frame1 = (AstFrame *) map1;
- new->frame2 = (AstFrame *) map2;
-
-/* If no simplication took place, annul the Mapping pointers and return a
- clone of the supplied pointer. */
- } else {
- map1 = astAnnul( map1 );
- map2 = astAnnul( map2 );
- result= astClone( this );
- }
-
-/* If an error occurred, annul the returned pointer. */
- if ( !astOK ) result = astAnnul( result );
-
-/* Return the result. */
- return result;
-}
-
-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 "cmpframe.h"
-* AstSystemType SystemCode( AstFrame *this, const char *system, int *status )
-
-* Class Membership:
-* CmpFrame 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 CmpFrame
-* 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 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 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. The CmpFrame class only supports a single system "Compound". */
- if ( astChrMatch( "Compound", system ) ) {
- result = AST__COMP;
- }
-
-/* Return the result. */
- 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 "cmpframe.h"
-* const char *SystemString( AstFrame *this, AstSystemType system, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astSystemString method
-* inherited from the Frame class).
-
-* Description:
-* This function converts a CmpFrame 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.
-*/
-
-/* 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. (Where possible, return the same string as would be
- used in the FITS WCS representation of the coordinate system). A
- CmpFrame only allows a single System value, "Compound". */
- switch ( system ) {
- case AST__COMP:
- result = "Compound";
- break;
- }
-
-/* Return the result pointer. */
- return result;
-}
-
-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 CmpFrame and convert to the new coordinate system.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.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:
-* CmpFrame 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" CmpFrame 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 CmpFrame, 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 CmpFrame. 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 CmpFrame 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 Deficiencies:
-* - It is not clear that the method of handling "extra" axes is
-* the best one, nor is the method of setting the "following" flag
-* necessarily correct. However, it is also not obvious that this
-* feature will ever be needed, so improvements have been left
-* until the requirement is clearer.
-*/
-
-/* Local Variables: */
- AstCmpFrame *target; /* Pointer to target CmpFrame structure */
- AstFrame *sub_result1; /* Pointer to result Frame for frame1 */
- AstFrame *sub_result2; /* Pointer to result Frame for frame2 */
- AstMapping *permmap_pref; /* Pointer to PermMap used as a prefix */
- AstMapping *permmap_suff; /* Pointer to PermMap used as a suffix */
- AstMapping *sub_map1; /* Pointer to Mapping from frame1 */
- AstMapping *sub_map2; /* Pointer to Mapping from frame2 */
- AstMapping *sub_map; /* Pointer to combined component Mappings */
- AstMapping *tmp_map; /* Temporary Mapping pointer */
- const int *perm; /* Pointer to axis permutation array */
- int *frame_choice; /* Pointer to flag array for partitioning */
- int *inperm_pref; /* Pointer to prefix permutation array */
- int *inperm_suff; /* Pointer to suffix permutation array */
- int *outperm_pref; /* Pointer to prefix permutation array */
- int *outperm_suff; /* Pointer to suffix permutation array */
- int *target_axes1; /* Pointer to frame1 axis selection array */
- int *target_axes2; /* Pointer to frame2 axis selection array */
- int *template_axes1; /* Pointer to frame1 template axis array */
- int *template_axes2; /* Pointer to frame2 template axis array */
- int axis_p; /* Permuted axis index */
- int following; /* Associate extra axis and following axis? */
- int i1; /* Count of axes obtained from frame1 */
- int i2; /* Count of axes obtained from frame2 */
- int match; /* Result value to return */
- int n1; /* Number of axes obtained from frame1 */
- int n2; /* Number of axes obtained from frame2 */
- int naxes1; /* Number of axes in frame1 */
- int naxes2; /* Number of axes in frame2 */
- int naxes; /* Number of axes in target */
- int result_axis; /* Result axis index */
- int target_axis; /* Target axis index */
-
-/* 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 CmpFrame structure. */
- target = (AstCmpFrame *) target_frame;
-
-/* Obtain the number of axes in the target CmpFrame and in each of its
- component Frames. */
- naxes = astGetNaxes( target );
- naxes1 = astGetNaxes( target->frame1 );
- naxes2 = astGetNaxes( target->frame2 );
-
-/* Iinitialise variables to avoid compiler warnings. */
- template_axes1 = NULL;
- template_axes2 = NULL;
- n1 = 0;
- n2 = 0;
-
-/* Obtain the axis permutation array for the target CmpFrame. */
- perm = astGetPerm( target );
-
-/* Determine how any "extra" axes should be associated with existing
- axes (i.e. whether to associate with the preceding or following
- axis). */
- following = astGetMatchEnd( target );
-
-/* Split selected axes into two groups. */
-/* ------------------------------------ */
-/* Allocate a workspace array to hold the choice of component Frame
- for each selected target axis. */
- frame_choice = astMalloc( sizeof( int ) * (size_t) result_naxes );
-
-/* Obtain an array of flags indicating whether each selected target
- axis should be obtained from the first or second component
- Frame. */
- PartitionSelection( result_naxes, target_axes, perm, naxes1, naxes2,
- frame_choice, following, status );
-
-/* Allocate two arrays to hold the axis indices that refer to each of
- the component Frames. The maximum number of indices is given by
- "result_naxes" (if all the selected axes come from one component
- Frame alone). */
- target_axes1 = astMalloc( sizeof( int ) * (size_t) result_naxes );
- target_axes2 = astMalloc( sizeof( int ) * (size_t) result_naxes );
-
-/* If a template Frame has been provided, allocate similar arrays to
- hold the indices of the two groups of template axes. */
- if ( template ) {
- template_axes1 = astMalloc( sizeof( int ) * (size_t) result_naxes );
- template_axes2 = astMalloc( sizeof( int ) * (size_t) result_naxes );
- }
-
-/* Initialise the count of axes selected from each component Frame. */
- if ( astOK ) {
- n1 = n2 = 0;
-
-/* Loop through each axis index to be selected from the CmpFrame. */
- for ( result_axis = 0; result_axis < result_naxes; result_axis++ ) {
- target_axis = target_axes[ result_axis ];
-
-/* Determine if the index refers to a valid CmpFrame axis. If it does,
- then permute the index, otherwise set it to -1. */
- if ( ( target_axis >= 0 ) && ( target_axis < naxes ) ) {
- axis_p = perm[ target_axis ];
- } else {
- axis_p = -1;
- }
-
-/* If the axis is to be selected from the first component Frame, store
- the index of the axis to be selected. Also store the associated
- template axis index (if any). */
- if ( frame_choice[ result_axis ] == 1 ) {
- target_axes1[ n1 ] = axis_p;
- if ( template ) {
- template_axes1[ n1 ] = template_axes[ result_axis ];
- }
-
-/* Count the axes selected from the first component Frame. */
- n1++;
-
-/* If the axis is to be selected from the second component Frame,
- store the index of the index to be selected (adjusting for the
- offset in axis numbering). Also store the associated template axis
- index (if any) and count the axes selected. */
- } else {
- target_axes2[ n2 ] = ( axis_p == -1 ) ? -1 : axis_p - naxes1;
- if ( template ) {
- template_axes2[ n2 ] = template_axes[ result_axis ];
- }
- n2++;
- }
- }
- }
-
-/* Select from first component Frame only. */
-/* --------------------------------------- */
-/* If all the selected axes come from the first component Frame, use
- that Frame's astSubFrame method to select them (and overlay the
- template attributes if required). */
- if ( astOK ) {
- if ( n1 && !n2 ) {
- sub_map1 = NULL;
- match = astSubFrame( target->frame1, template, n1, target_axes1,
- template_axes1, &sub_map1, result );
-
-/* If this is successful, the "result" Frame will be ready to return
- and "sub_map1" will point at a Mapping that converts from the first
- component Frame to the "result" Frame. We must now modify this
- mapping to account for the CmpFrame's axis permutation array
- (i.e. make it refer back to the CmpFrame's original axis order). */
- if ( astOK && match ) {
-
-/* To do this we must prefix the Mapping with a PermMap which converts
- between the target CmpFrame axes and those of the first component
- Frame. Allocate space for the permutation arrays required. */
- inperm_pref = astMalloc( sizeof( int ) * (size_t) naxes );
- outperm_pref = astMalloc( sizeof( int ) * (size_t) naxes1 );
- if ( astOK ) {
-
-/* Permute each target axis index. */
- for ( target_axis = 0; target_axis < naxes; target_axis++ ) {
- axis_p = perm[ target_axis ];
-
-/* Set up arrays that describe this permutation and its inverse. */
- if ( axis_p < naxes1 ) {
- inperm_pref[ target_axis ] = axis_p;
- outperm_pref[ axis_p ] = target_axis;
-
-/* Note which target axes do not correspond with axes in the first
- component Frame and assign -1 (so the PermMap will assign "bad"
- coordinate values to these axes). */
- } else {
- inperm_pref[ target_axis ] = -1;
- }
- }
-
-/* Use these permutation arrays to construct the PermMap. Prefix this
- to the Mapping obtained earlier to give the final Mapping to be
- returned. */
- permmap_pref =
- (AstMapping *) astPermMap( naxes, inperm_pref,
- naxes1, outperm_pref, NULL, "", status );
- *map = (AstMapping *) astCmpMap( permmap_pref, sub_map1, 1, "", status );
-
-/* Annul the PermMap pointer. */
- permmap_pref = astAnnul( permmap_pref );
- }
-
-/* Free the permutation arrays and annul the original Mapping pointer. */
- inperm_pref = astFree( inperm_pref );
- outperm_pref = astFree( outperm_pref );
- sub_map1 = astAnnul( sub_map1 );
- }
-
-/* Select from second component Frame only. */
-/* ---------------------------------------- */
-/* If all the selected axes come from the second component Frame, use
- that Frame's astSubFrame method to select them (and overlay the
- template attributes if required). */
- } else if ( n2 && !n1 ) {
- sub_map2 = NULL;
- match = astSubFrame( target->frame2, template, n2, target_axes2,
- template_axes2, &sub_map2, result );
-
-/* If this is successful, the "result" Frame will be ready to return
- and "sub_map2" will point at a Mapping that converts from the second
- component Frame to the "result" Frame. We must now modify this
- mapping to account for the CmpFrame's axis permutation array
- (i.e. make it refer back to the CmpFrame's original axis order). */
- if ( astOK && match ) {
-
-/* To do this we must prefix the Mapping with a PermMap which converts
- between the target CmpFrame axes and those of the second component
- Frame. Allocate space for the permutation arrays required. */
- inperm_pref = astMalloc( sizeof( int ) * (size_t) naxes );
- outperm_pref = astMalloc( sizeof( int ) * (size_t) naxes2 );
- if ( astOK ) {
-
-/* Permute each target axis index. */
- for ( target_axis = 0; target_axis < naxes; target_axis++ ) {
- axis_p = perm[ target_axis ];
-
-/* Set up arrays that describe this permutation and its inverse,
- allowing for the shift in axis numbering for the second component
- Frame. */
- if ( axis_p >= naxes1 ) {
- inperm_pref[ target_axis ] = axis_p - naxes1;
- outperm_pref[ axis_p - naxes1 ] = target_axis;
-
-/* Note which target axes do not correspond with axes in the second
- component Frame and assign -1 (so the PermMap will assign "bad"
- coordinate values to these axes). */
- } else {
- inperm_pref[ target_axis ] = -1;
- }
- }
-
-/* Use these permutation arrays to construct the PermMap. Prefix this
- to the Mapping obtained earlier to give the final Mapping to be
- returned. */
- permmap_pref =
- (AstMapping *) astPermMap( naxes, inperm_pref,
- naxes2, outperm_pref, NULL, "", status );
-
- *map = (AstMapping *) astCmpMap( permmap_pref, sub_map2, 1, "", status );
-
-/* Annul the PermMap pointer. */
- permmap_pref = astAnnul( permmap_pref );
- }
-
-/* Free the permutation arrays and annul the original Mapping pointer. */
- inperm_pref = astFree( inperm_pref );
- outperm_pref = astFree( outperm_pref );
- sub_map2 = astAnnul( sub_map2 );
- }
-
-/* Select from both component Frames. */
-/* ---------------------------------- */
-/* If the selected axes come from both component Frames, then use both
- Frames' astSubFrame methods to select the required axes from each
- of them (and overlay the template attributes if required). */
- } else {
- sub_map1 = NULL;
- sub_map2 = NULL;
- sub_result1 = NULL;
- sub_result2 = NULL;
- match = astSubFrame( target->frame1, template, n1, target_axes1,
- template_axes1, &sub_map1, &sub_result1 );
- if ( match ) {
- match = astSubFrame( target->frame2, template, n2, target_axes2,
- template_axes2, &sub_map2, &sub_result2 );
- }
-
-/* If this is successful, the two "result" Frames will need to be
- combined together (in a CmpFrame) in order to produce the required
- result, and the two accompanying Mappings will also need to be
- applied in parallel (in a CmpMap). However, the axis order
- resulting from this will still not match that required.
-
- On the target side, this is because of the target's axis
- permutation array. On the result side, it is because the result
- axes cannot be inter-mingled (as may be required) simply by joining
- the Frames and Mappings in parallel. The resulting CmpFrame axes
- will therefore need permuting into the required final order. */
- if ( astOK && match ) {
-
-/* In addition, the Mappings will need to be both prefixed and
- suffixed with suitable PermMaps which re-order the axes. Allocate
- space for the permutation arrays required. */
- inperm_pref = astMalloc( sizeof( int ) * (size_t) naxes );
- outperm_pref = astMalloc( sizeof( int ) * (size_t) naxes );
- inperm_suff = astMalloc( sizeof( int ) * (size_t) result_naxes );
- outperm_suff = astMalloc( sizeof( int ) * (size_t) result_naxes );
- if ( astOK ) {
-
-/* Set up permutation arrays to construct the prefix PermMap. This
- simply represents the target CmpFrame's axis permutation array and
- its inverse. */
- for ( target_axis = 0; target_axis < naxes; target_axis++ ) {
- axis_p = perm[ target_axis ];
- inperm_pref[ target_axis ] = axis_p;
- outperm_pref[ axis_p ] = target_axis;
- }
-
-/* Set up permutation arrays to construct the suffix PermMap. This
- represents the way the original axis selections were partitioned
- between the two component frames. */
- i1 = i2 = 0;
- for ( result_axis = 0; result_axis < result_naxes;
- result_axis++ ) {
-
-/* For each result axis derived from the first component Frame, set up
- permutation array elements to link the output axis with the next
- component Frame axis. Count the number of component Frame axes
- used. */
- if ( frame_choice[ result_axis ] == 1 ) {
- inperm_suff[ i1 ] = result_axis;
- outperm_suff[ result_axis ] = i1;
- i1++;
-
-/* Similarly link the axes derived from the second component Frame
- with the appropriate axes of that Frame. */
- } else {
- inperm_suff[ n1 + i2 ] = result_axis;
- outperm_suff[ result_axis ] = n1 + i2;
- i2++;
- }
- }
-
-/* Combine the Mappings supplied by the two component Frames in
- parallel. */
- sub_map = (AstMapping *) astCmpMap( sub_map1, sub_map2, 0, "", status );
-
-/* Create the PermMaps which are to be used as a prefix and a suffix. */
- permmap_pref =
- (AstMapping *) astPermMap( naxes, inperm_pref,
- naxes, outperm_pref, NULL, "", status );
- permmap_suff =
- (AstMapping *) astPermMap( result_naxes, inperm_suff,
- result_naxes, outperm_suff,
- NULL, "", status );
-
-/* Add the prefix and suffix PermMaps. */
- tmp_map = (AstMapping *) astCmpMap( permmap_pref, sub_map,
- 1, "", status );
- *map = (AstMapping *) astCmpMap( tmp_map, permmap_suff, 1, "", status );
-
-/* Annul the Mapping pointers that are no longer required. */
- sub_map = astAnnul( sub_map );
- permmap_pref = astAnnul( permmap_pref );
- permmap_suff = astAnnul( permmap_suff );
- tmp_map = astAnnul( tmp_map );
-
-/* Create the result CmpFrame by combining the two component result
- Frames and permuting the resulting axes into the required order. */
- *result = (AstFrame *) astCmpFrame( sub_result1, sub_result2,
- "", status );
- astPermAxes( *result, outperm_suff );
-
-/* ADDED BY DSB (5-FEB-2001). Without this, properties of the target frame
- (most importantly, Domain) are not transferred to the result frame.
- This results in Frames not matching which should match.
- =================================================================== */
-
-/* If the result CmpFrame includes all the axes of the target CmpFrame,
- then it should inherit any Domain and Title attributes set in the target
- CmpFrame. */
- if( result_naxes == naxes ) {
-
- if( astTestDomain( target ) ) {
- astSetDomain( *result, astGetDomain( target ) );
- }
-
- if( astTestTitle( target ) ) {
- astSetTitle( *result, astGetTitle( target ) );
- }
- }
-
-/* End of DSB insertion (5/2/01).
- =================================================================== */
- }
-
-/* Free the temporary permutation arrays. */
- inperm_pref = astFree( inperm_pref );
- inperm_suff = astFree( inperm_suff );
- outperm_pref = astFree( outperm_pref );
- outperm_suff = astFree( outperm_suff );
- }
-
-/* Annul the Mapping and Frame pointers obtained from each component
- Frame. */
- if( sub_map1 ) sub_map1 = astAnnul( sub_map1 );
- if( sub_map2 ) sub_map2 = astAnnul( sub_map2 );
- if( sub_result1 ) sub_result1 = astAnnul( sub_result1 );
- if( sub_result2 ) sub_result2 = astAnnul( sub_result2 );
- }
- }
-
-/* Free the workspace used to store the choice of component Frame and the
- axis indices for each component Frame. */
- frame_choice = astFree( frame_choice );
- target_axes1 = astFree( target_axes1 );
- target_axes2 = astFree( target_axes2 );
-
-/* If necessary, also free the memory used for the template axis
- indices. */
- if ( template ) {
- template_axes1 = astFree( template_axes1 );
- template_axes2 = astFree( template_axes2 );
- }
-
-/* If an error occurred, clean up by annulling the result pointers and
- returning appropriate null values. */
- if ( !astOK ) {
- *map = astAnnul( *map );
- *result = astAnnul( *result );
- match = 0;
- }
-
-/* Return the result. */
- return match;
-}
-
-static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) {
-/*
-* Name:
-* TestAttrib
-
-* Purpose:
-* Test if a specified attribute value is set for a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* int TestAttrib( AstObject *this, const char *attrib, int *status )
-
-* Class Membership:
-* CmpFrame 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 CmpFrame's attributes.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* 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: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- AstFrame *pfrm; /* Pointer to primary Frame containing axis */
- char buf1[80]; /* For for un-indexed attribute name */
- char buf2[80]; /* For for indexed attribute name */
- int axis; /* Supplied (1-base) axis index */
- int len; /* Length of attrib string */
- int nc; /* Length of string used so far */
- int oldrep; /* Original error reporting state */
- int paxis; /* Index of primary Frame axis */
- int result; /* Result value to return */
- int ok; /* Has the attribute been accessed succesfully? */
-
-/* Initialise. */
- result = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return result;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_object;
-
-/* Obtain the length of the attrib string. */
- len = strlen( attrib );
-
-/* Indicate we have not yet acessed the attribute succesfully. */
- ok = 0;
-
-/* First check the supplied attribute name against each of the attribute
- names defined by this class. In fact there is nothing to do here
- since the CmpFrame class currently defines no extra attributes, but
- this may change in the future. */
- if( 0 ) {
-
-
-
-/* If the attribute is not a CmpFrame specific attribute... */
- } else if( astOK ) {
-
-/* We want to allow easy access to the attributes of the component Frames.
- That is, we do not want it to be necessary to extract a Frame from
- its parent CmpFrame in order to access its attributes. For this reason
- we first temporarily switch off error reporting so that if an attempt
- to access the attribute fails, we can try a different approach. */
- oldrep = astReporting( 0 );
-
-/* Our first attempt is to see if the attribute is recognised by the parent
- class (Frame). */
- result = (*parent_testattrib)( this_object, attrib, status );
-
-/* Indicate success. */
- if( astOK ) {
- ok = 1;
-
-/* Otherwise, clear the error condition so that we can try a different
- approach. */
- } else {
- astClearStatus;
-
-/* If the attribute is qualified by an axis index, try accessing it as an
- attribute of the primary Frame containing the specified index. */
- if ( nc = 0,
- ( 2 == astSscanf( attrib, "%[^(](%d)%n", buf1, &axis, &nc ) )
- && ( nc >= len ) ) {
-
-/* Find the primary Frame containing the specified axis. */
- astPrimaryFrame( this, axis - 1, &pfrm, &paxis );
- if( astOK ) {
-
-/* astPrimaryFrame returns the original - unpermuted - axis index within
- the primary Frame. So we need to take into account any axis permutation
- which has been applied to the primary Frame when forming the attribute name
- to use below. Find the permuted (external) axis index which corresponds to
- the internal (unpermuted) axis index "paxis". */
- paxis = astValidateAxis( pfrm, paxis, 0, "astTest" );
-
-/* Create a new attribute with the same name but with the axis index
- appropriate to the primary Frame. */
- sprintf( buf2, "%s(%d)", buf1, paxis + 1 );
-
-/* Attempt to access the attribute. */
- result = astTestAttrib( pfrm, buf2 );
-
-/* Indicate success. */
- if( astOK ) {
- ok = 1;
-
-/* Otherwise clear the status value, and try again without any axis index. */
- } else {
- astClearStatus;
- result = astTestAttrib( pfrm, buf1 );
-
-/* Indicate success, or clear the status value. */
- if( astOK ) {
- ok = 1;
- } else {
- astClearStatus;
- }
- }
-
-/* Free the primary frame pointer. */
- pfrm = astAnnul( pfrm );
- }
-
-/* If the attribute is not qualified by an axis index, try accessing it
- using the primary Frame of each axis in turn. */
- } else {
-
-/* Loop round all axes, until one is found which defines the specified
- attribute. */
- for( axis = 0; axis < astGetNaxes( this ) && !ok; axis++ ) {
-
-/* Get the primary Frame containing this axis. */
- astPrimaryFrame( this, axis, &pfrm, &paxis );
-
-/* Attempt to access the attribute as an attribute of the primary Frame. */
- result = astTestAttrib( pfrm, attrib );
-
-/* Indicate success, or clear the status value. */
- if( astOK ) {
- ok = 1;
- } else {
- astClearStatus;
- }
-
-/* Free the primary Frame pointer. */
- pfrm = astAnnul( pfrm );
-
- }
- }
- }
-
-/* Re-instate the original error reporting state. */
- astReporting( oldrep );
-
- }
-
-/* Report an error if the attribute could not be accessed. */
- if( !ok && astOK ) {
- astError( AST__BADAT, "astTest: The %s given does not have an attribute "
- "called \"%s\".", status, astGetClass( this ), attrib );
- }
-
-/* Return the result. */
- return result;
-
-}
-
-static AstPointSet *Transform( AstMapping *this_mapping, AstPointSet *in,
- int forward, AstPointSet *out, int *status ) {
-/*
-* Name:
-* Transform
-
-* Purpose:
-* Transform a set of points.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* AstPointSet *Transform( AstMapping *this, AstPointSet *in,
-* int forward, AstPointSet *out, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the astTransform method
-* inherited from the Frame class).
-
-* Description:
-* This function takes a CmpFrame and a set of points encapsulated
-* in a PointSet, and applies the coordinate transformation equivalent
-* to the CmpFrame (this will normally be a UnitMap but may not be if
-* the CmpFrame contains any Regions).
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* in
-* Pointer to the PointSet holding the input coordinate data.
-* forward
-* A non-zero value indicates that the forward coordinate transformation
-* should be applied, while a zero value requests the inverse
-* transformation.
-* out
-* Pointer to a PointSet which will hold the transformed (output)
-* coordinate values. A NULL value may also be given, in which case a
-* new PointSet will be created by this function.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* Pointer to the output (possibly new) PointSet.
-
-* Notes:
-* - The number of coordinate values per point in the input
-* PointSet must match the number of axes in the CmpFrame.
-* - If an output PointSet is supplied, it must have space for
-* sufficient number of points and coordinate values per point to
-* accommodate the result (e.g. the number of CmpFrame axes). Any
-* excess space will be ignored.
-* - 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: */
- AstCmpFrame *this; /* Pointer to original CmpFrame structure */
- AstCmpMap *map2; /* Intermediate Mapping */
- AstCmpMap *map; /* Equivalent Mapping */
- AstPermMap *pmap; /* Intermediate PermMap */
- AstPointSet *result; /* Pointer value to return */
- const int *inperm; /* Pointer to axis permutation array */
- int *outperm; /* Pointer to inverse axis permutation array */
- int i; /* External axis index */
- int naxes; /* Number of axes in CmpFrame */
- int perm; /* Is there an axis permutation to undo? */
-
-/* Check the global error status. */
- if ( !astOK ) return NULL;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_mapping;
-
-/* Form a parallel CmpMap from the two component Frames. */
- map = astCmpMap( this->frame1, this->frame2, 0, "", status );
-
-/* The above CmpMap does not take into account any axis permutation
- which has been applied to the CmpFrame as a whole (as opposed to axis
- permutations applied to the individual component Frames, which are taken
- care of by the Transform methods of the individual Frames). Therefore
- we need to modify the Mapping by adding a PermMap at the start which
- converts from external axis numbering to internal axis numbering, and a
- corresponding PermMap at the end which converts from internal to external
- axis numbering. Obtain the number of axes in the CmpFrame */
- naxes = astGetNaxes( this );
-
-/* Obtain a pointer to the CmpFrame's axis permutation array. This
- contains internal axis numbers and is indexed by external axis number. */
- inperm = astGetPerm( this );
-
-/* Check if there is any axis permutation to be performed. */
- perm = 0;
- for( i = 0; i < naxes; i++ ) {
- if( inperm[ i ] != i ) {
- perm = 1;
- break;
- }
- }
-
-/* If so, create an array holding the inverse permutation - one which
- contains external axis numbers and is indexed by internal axis number. */
- if( perm ) {
- outperm = astMalloc( sizeof( int )*(size_t) naxes );
- if( astOK ) for( i = 0; i < naxes; i++ ) outperm[ inperm[ i ] ] = i;
-
-/* Create a PermMap from these permutation arrays. The forward
- transformation maps from external axis indices to internal axis
- indices. */
- pmap = astPermMap( naxes, inperm, naxes, outperm, NULL, "", status );
- outperm = astFree( outperm );
-
-/* Combine this PermMap with the CmpMap created above, adding it in the
- forward direction at the start and in the inverse direction at the end. */
- map2 = astCmpMap( pmap, map, 1, "", status );
- map = astAnnul( map );
- astInvert( pmap );
- map = astCmpMap( map2, pmap, 1, "", status );
- map2 = astAnnul( map2 );
- pmap = astAnnul( pmap );
-
- }
-
-/* Apply the Mapping to the input PointSet. */
- result = astTransform( map, in, forward, out );
-
-/* Annul the Mapping pointer. */
- map = astAnnul( map );
-
-/* If an error has occurred and a new PointSet may have been created, then
- clean up by annulling it. In any case, ensure that a NULL result is
- returned.*/
- if ( !astOK ) {
- if ( !out ) result = astAnnul( result );
- result = NULL;
- }
-
-/* Return a pointer to the output PointSet. */
- return result;
-}
-
-static int Unformat( AstFrame *this_frame, int axis, const char *string,
- double *value, int *status ) {
-/*
-* Name:
-* Unformat
-
-* Purpose:
-* Read a formatted coordinate value for a CmpFrame axis.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* int Unformat( AstFrame *this, int axis, const char *string,
-* double *value, int *status )
-
-* Class Membership:
-* CmpFrame member function (over-rides the public astUnformat
-* method inherited from the Frame class).
-
-* Description:
-* This function reads a formatted coordinate value for a CmpFrame
-* axis (supplied as a string) and returns the equivalent numerical
-* value as a double. It also returns the number of characters read
-* from the string.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame.
-* axis
-* The number of the CmpFrame axis for which the coordinate
-* value is to be read (axis numbering starts at zero for the
-* first axis).
-* string
-* Pointer to a constant null-terminated string containing the
-* formatted coordinate value.
-* value
-* Pointer to a double in which the coordinate value read will be
-* returned.
-* status
-* Pointer to the inherited status variable.
-
-* Returned Value:
-* The number of characters read from the string to obtain the
-* coordinate value.
-
-* Notes:
-* - Any white space at the beginning of the string will be
-* skipped, as also will any trailing white space following the
-* coordinate value read. The function's return value will reflect
-* this.
-* - A function value of zero (and no coordinate value) will be
-* returned, without error, if the string supplied does not contain
-* a suitably formatted value.
-* - The string "<bad>" is recognised as a special case and will
-* generate the value AST__BAD, without error. The test for this
-* string is case-insensitive and permits embedded white space.
-* - A function result of zero will be returned and no coordinate
-* value will be returned via the "value" pointer if this function
-* is invoked with the global error status set, or if it should
-* fail for any reason.
-*/
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to CmpFrame structure */
- AstFrame *frame; /* Pointer to Frame containing axis */
- double coord; /* Coordinate value read */
- int naxes1; /* Number of axes in frame1 */
- int nc; /* Number of characters read */
- int set; /* Digits attribute set? */
-
-/* Initialise. */
- nc = 0;
-
-/* Check the global error status. */
- if ( !astOK ) return nc;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_frame;
-
-/* Validate and permute the axis index supplied. */
- axis = astValidateAxis( this, axis, 1, "astUnformat" );
-
-/* Determine the number of axes in the first component Frame. */
- naxes1 = astGetNaxes( this->frame1 );
- if ( astOK ) {
-
-/* Decide which component Frame contains the axis and adjust the axis
- index if necessary. */
- frame = ( axis < naxes1 ) ? this->frame1 : this->frame2;
- axis = ( axis < naxes1 ) ? axis : axis - naxes1;
-
-/* Since the component Frame is "managed" by the enclosing CmpFrame,
- we next test if any Frame attributes which may affect the result
- are undefined (i.e. have not been explicitly set). If so, we
- over-ride them, giving them temporary values dictated by the
- CmpFrame. Only the Digits attribute is potentially relevant
- here. */
- set = astTestDigits( frame );
- if ( !set ) astSetDigits( frame, astGetDigits( this ) );
-
-/* Invoke the Frame's astUnformat method to read the coordinate value. */
- nc = astUnformat( frame, axis, string, &coord );
-
-/* Clear Frame attributes which were temporarily over-ridden. */
- if ( !set ) astClearDigits( frame );
- }
-
-/* If an error occurred, clear the number of characters read. */
- if ( !astOK ) {
- nc = 0;
-
-/* Otherwise, if characters were read, return the coordinate value. */
- } else if ( nc ) {
- *value = coord;
- }
-
-/* Return the number of chracters read. */
- return nc;
-}
-
-static int ValidateSystem( AstFrame *this, AstSystemType system, const char *method, int *status ) {
-/*
-*
-* Name:
-* ValidateSystem
-
-* Purpose:
-* Validate a value for a CmpFrame's System attribute.
-
-* Type:
-* Protected virtual function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* int ValidateSystem( AstFrame *this, AstSystemType system,
-* const char *method, int *status )
-
-* Class Membership:
-* CmpFrame 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. */
-/* ---------------------------------------- */
-/* Implement member functions to access the attributes associated with
- the axes of a CmpFrame using the private macros defined for this
- purpose at the start of this file. */
-
-/* Direction(axis). */
-/* ---------------- */
-MAKE_CLEAR(Direction)
-MAKE_GET(Direction,int,0,0,0)
-MAKE_SET(Direction,int)
-MAKE_TEST(Direction)
-
-/* Format(axis). */
-/* ------------- */
-MAKE_CLEAR(Format)
-MAKE_GET(Format,const char *,NULL,0,NULL)
-MAKE_SET(Format,const char *)
-MAKE_TEST(Format)
-
-/* Label(axis). */
-/* ------------ */
-MAKE_CLEAR(Label)
-
-/* Over-ride the default axis labels produced by Frame class objects
- and substitute the axis numbering of the enclosing CmpFrame
- instead. */
-static const char *label_class;
-MAKE_GET(Label,const char *,NULL,( label_class = astGetClass( frame ),
- ( astOK && !strcmp( label_class,
- "Frame" ) ) ),
- ( (void) sprintf( label_buff, "Axis %d", axis + 1 ), label_buff ))
-MAKE_SET(Label,const char *)
-MAKE_TEST(Label)
-
-/* Symbol(axis). */
-/* ------------- */
-MAKE_CLEAR(Symbol)
-
-/* Over-ride the default axis symbols produced by Frame class objects
- and substitute the axis numbering of the enclosing CmpFrame
- instead. */
-static const char *symbol_class;
-MAKE_GET(Symbol,const char *,NULL,( symbol_class = astGetClass( frame ),
- ( astOK && !strcmp( symbol_class,
- "Frame" ) ) ),
- ( (void) sprintf( symbol_buff, "x%d", axis + 1 ), symbol_buff ))
-MAKE_SET(Symbol,const char *)
-MAKE_TEST(Symbol)
-
-/* Unit(axis). */
-/* ----------- */
-MAKE_CLEAR(Unit)
-MAKE_GET(Unit,const char *,NULL,0,NULL)
-MAKE_SET(Unit,const char *)
-MAKE_TEST(Unit)
-
-/* Copy constructor. */
-/* ----------------- */
-static void Copy( const AstObject *objin, AstObject *objout, int *status ) {
-/*
-* Name:
-* Copy
-
-* Purpose:
-* Copy constructor for CmpFrame objects.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* void Copy( const AstObject *objin, AstObject *objout, int *status )
-
-* Description:
-* This function implements the copy constructor for CmpFrame 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: */
- AstCmpFrame *in; /* Pointer to input CmpFrame */
- AstCmpFrame *out; /* Pointer to output CmpFrame */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain pointers to the input and output CmpFrames. */
- in = (AstCmpFrame *) objin;
- out = (AstCmpFrame *) objout;
-
-/* Copy the two component Frames. */
- out->frame1 = astCopy( in->frame1 );
- out->frame2 = astCopy( in->frame2 );
-
-/* Determine the number of axes and copy the axis permutation
- array. */
- out->perm = astStore( NULL, in->perm, sizeof( int ) *
- (size_t) GetNaxes( (AstFrame *) in, status ) );
-}
-
-/* Destructor. */
-/* ----------- */
-static void Delete( AstObject *obj, int *status ) {
-/*
-* Name:
-* Delete
-
-* Purpose:
-* Destructor for CmpFrame objects.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* void Delete( AstObject *obj, int *status )
-
-* Description:
-* This function implements the destructor for CmpFrame 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: */
- AstCmpFrame *this; /* Pointer to CmpFrame structure */
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) obj;
-
-/* Annul the two component Frame pointers. */
- if ( this->frame1 ) this->frame1 = astAnnul( this->frame1 );
- if ( this->frame2 ) this->frame2 = astAnnul( this->frame2 );
-
-/* Free the axis permutation array. */
- if ( this->perm ) this->perm = astFree( this->perm );
-}
-
-/* Dump function. */
-/* -------------- */
-static void Dump( AstObject *this_object, AstChannel *channel, int *status ) {
-/*
-* Name:
-* Dump
-
-* Purpose:
-* Dump function for CmpFrame 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 CmpFrame class to an output Channel.
-
-* Parameters:
-* this
-* Pointer to the CmpFrame 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 Constants: */
-#define COMMENT_LEN 150 /* Maximum length of a comment string */
-#define KEY_LEN 50 /* Maximum length of a keyword */
-
-/* Local Variables: */
- AstCmpFrame *this; /* Pointer to the CmpFrame structure */
- char comment[ COMMENT_LEN + 1 ]; /* Buffer for comment strings */
- char key[ KEY_LEN + 1 ]; /* Buffer for keywords */
- int axis; /* Loop counter for CmpFrame axes */
- int full; /* Full attribute value */
- int full_set; /* Full attribute set? */
- int ival; /* Integer value */
- int naxes; /* Number of CmpFrame axes */
- int set; /* Attribute value set? */
-
-/* Check the global error status. */
- if ( !astOK ) return;
-
-/* Obtain a pointer to the CmpFrame structure. */
- this = (AstCmpFrame *) this_object;
-
-/* Write out values representing the instance variables for the
- CmpFrame 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. */
-
-/* Axis permutation array. */
-/* ----------------------- */
-/* Obtain the number of CmpFrame axes. */
- naxes = GetNaxes( (AstFrame *) this, status );
-
-/* Write out the CmpFrame axis permutation array value for each axis,
- converting to 1-based axis numbering. */
- for ( axis = 0; axis < naxes; axis++ ) {
- set = ( this->perm[ axis ] != axis );
- ival = this->perm[ axis ] + 1;
-
-/* Create a keyword and comment appropriate to the axis. */
- (void) sprintf( key, "Axp%d", axis + 1 );
- if ( set ) {
- (void) sprintf( comment,
- "Axis %d permuted to use internal axis %d",
- axis + 1, ival );
- } else {
- (void) sprintf( comment, "Axis %d not permuted", axis + 1 );
- }
- astWriteInt( channel, key, set, 0, ival, comment );
- }
-
-/* Component Frames. */
-/* ----------------- */
-/* Temporarily set the Channel's Full attribute to -1 (unless it is +1
- to start with), remembering the original setting. This prevents any
- unnecessary "un-set" Frame values being output that would otherwise
- simply duplicate the CmpFrame's attributes which have already been
- written. "Set" Frame values are still written, however (and all
- values are written if Full is set to 1). */
- full_set = astTestFull( channel );
- full = astGetFull( channel );
- if ( full <= 0 ) astSetFull( channel, -1 );
-
-/* Write out Object descriptions for the two component Frames. */
- astWriteObject( channel, "FrameA", 1, 1, this->frame1,
- "First component Frame" );
- astWriteObject( channel, "FrameB", 1, 1, this->frame2,
- "Second component Frame" );
-
-/* Restore the Channel's original Full attribute setting. */
- if ( full_set ) {
- astSetFull( channel, full );
- } else {
- astClearFull( channel );
- }
-
-/* Undefine macros local to this function. */
-#undef COMMENT_LEN
-#undef KEY_LEN
-}
-
-/* Standard class functions. */
-/* ========================= */
-/* Implement the astIsACmpFrame and astCheckCmpFrame functions using the macros
- defined for this purpose in the "object.h" header file. */
-astMAKE_ISA(CmpFrame,Frame)
-astMAKE_CHECK(CmpFrame)
-
-AstCmpFrame *astCmpFrame_( void *frame1_void, void *frame2_void,
- const char *options, int *status, ...) {
-/*
-*++
-* Name:
-c astCmpFrame
-f AST_CMPFRAME
-
-* Purpose:
-* Create a CmpFrame.
-
-* Type:
-* Public function.
-
-* Synopsis:
-c #include "cmpframe.h"
-c AstCmpFrame *astCmpFrame( AstFrame *frame1, AstFrame *frame2,
-c const char *options, ... )
-f RESULT = AST_CMPFRAME( FRAME1, FRAME2, OPTIONS, STATUS )
-
-* Class Membership:
-* CmpFrame constructor.
-
-* Description:
-* This function creates a new CmpFrame and optionally initialises
-* its attributes.
-*
-* A CmpFrame is a compound Frame which allows two component Frames
-* (of any class) to be merged together to form a more complex
-* Frame. The axes of the two component Frames then appear together
-* in the resulting CmpFrame (those of the first Frame, followed by
-* those of the second Frame).
-*
-* Since a CmpFrame is itself a Frame, it can be used as a
-* component in forming further CmpFrames. Frames of arbitrary
-* complexity may be built from simple individual Frames in this
-* way.
-*
-* Also since a Frame is a Mapping, a CmpFrame can also be used as a
-* Mapping. Normally, a CmpFrame is simply equivalent to a UnitMap,
-* but if either of the component Frames within a CmpFrame is a Region
-* (a sub-class of Frame), then the CmpFrame will use the Region as a
-* Mapping when transforming values for axes described by the Region.
-* Thus input axis values corresponding to positions which are outside the
-* Region will result in bad output axis values.
-
-* Parameters:
-c frame1
-f FRAME1 = INTEGER (Given)
-* Pointer to the first component Frame.
-c frame2
-f FRAME2 = INTEGER (Given)
-* Pointer to the second component Frame.
-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 CmpFrame. 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.
-f A character string containing an optional comma-separated
-f list of attribute assignments to be used for initialising the
-f new CmpFrame. The syntax used is identical to that for the
-f AST_SET routine.
-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 astCmpFrame()
-f AST_CMPFRAME = INTEGER
-* A pointer to the new CmpFrame.
-
-* Notes:
-* - 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.
-
-* Status Handling:
-* The protected interface to this function includes an extra
-* parameter at the end of the parameter list descirbed above. This
-* parameter is a pointer to the integer inherited status
-* variable: "int *status".
-
-*--
-
-* Implementation Notes:
-* - This function implements the basic CmpFrame constructor which
-* is available via the protected interface to the CmpFrame class.
-* A public interface is provided by the astCmpFrameId_ function.
-* - Because this function has a variable argument list, it is
-* invoked by a macro that evaluates to a function pointer (not a
-* function invocation) and no checking or casting of arguments is
-* performed before the function is invoked. Because of this, the
-* "frame1" and "frame2" parameters are of type (void *) and are
-* converted and validated within the function itself.
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
- AstCmpFrame *new; /* Pointer to new CmpFrame */
- AstFrame *frame1; /* Pointer to first Frame structure */
- AstFrame *frame2; /* Pointer to second Frame structure */
- va_list args; /* Variable argument list */
-
-/* Get a pointer to the thread specific global data structure. */
- astGET_GLOBALS(NULL);
-
-/* Check the global status. */
- new = NULL;
- if ( !astOK ) return new;
-
-/* Obtain and validate pointers to the Frame structures provided. */
- frame1 = astCheckFrame( frame1_void );
- frame2 = astCheckFrame( frame2_void );
- if ( astOK ) {
-
-/* Initialise the CmpFrame, allocating memory and initialising the
- virtual function table as well if necessary. */
- new = astInitCmpFrame( NULL, sizeof( AstCmpFrame ), !class_init,
- &class_vtab, "CmpFrame", frame1, frame2 );
-
-/* 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
- CmpFrame's attributes. */
- va_start( args, status );
- astVSet( new, options, NULL, args );
- va_end( args );
-
-/* If an error occurred, clean up by deleting the new object. */
- if ( !astOK ) new = astDelete( new );
- }
- }
-
-/* Return a pointer to the new CmpFrame. */
- return new;
-}
-
-AstCmpFrame *astCmpFrameId_( void *frame1_void, void *frame2_void,
- const char *options, ... ) {
-/*
-* Name:
-* astCmpFrameId_
-
-* Purpose:
-* Create a CmpFrame.
-
-* Type:
-* Private function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* AstCmpFrame *astCmpFrameId_( void *frame1_void, void *frame2_void,
-* const char *options, ... )
-
-* Class Membership:
-* CmpFrame constructor.
-
-* Description:
-* This function implements the external (public) interface to the
-* astCmpFrame constructor function. It returns an ID value
-* (instead of a true C pointer) to external users, and must be
-* provided because astCmpFrame_ has a variable argument list which
-* cannot be encapsulated in a macro (where this conversion would
-* otherwise occur). For the same reason, the "frame1" and "frame2"
-* parameters are of type (void *) and are converted and validated
-* within the function itself.
-*
-* The variable argument list also prevents this function from
-* invoking astCmpFrame_ 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.
-
-* Parameters:
-* As for astCmpFrame_.
-
-* Returned Value:
-* The ID value associated with the new CmpFrame.
-*/
-
-/* Local Variables: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
- AstCmpFrame *new; /* Pointer to new CmpFrame */
- AstFrame *frame1; /* Pointer to first Frame structure */
- AstFrame *frame2; /* Pointer to second Frame structure */
- va_list args; /* Variable argument list */
-
- int *status; /* Get a pointer to the thread specific global data structure. */
- astGET_GLOBALS(NULL);
-
-/* Pointer to inherited status value */
-
-/* Get a pointer to the inherited status value. */
- status = astGetStatusPtr;
-
-/* Check the global status. */
- new = NULL;
- if ( !astOK ) return new;
-
-/* Obtain the Frame pointers from the ID's supplied and validate the
- pointers to ensure they identify valid Frames. */
- frame1 = astVerifyFrame( astMakePointer( frame1_void ) );
- frame2 = astVerifyFrame( astMakePointer( frame2_void ) );
- if ( astOK ) {
-
-/* Initialise the CmpFrame, allocating memory and initialising the
- virtual function table as well if necessary. */
- new = astInitCmpFrame( NULL, sizeof( AstCmpFrame ), !class_init,
- &class_vtab, "CmpFrame", frame1, frame2 );
-
-/* 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
- CmpFrame's attributes. */
- va_start( args, options );
- astVSet( new, options, NULL, args );
- va_end( args );
-
-/* If an error occurred, clean up by deleting the new object. */
- if ( !astOK ) new = astDelete( new );
- }
- }
-
-/* Return an ID value for the new CmpFrame. */
- return astMakeId( new );
-}
-
-AstCmpFrame *astInitCmpFrame_( void *mem, size_t size, int init,
- AstCmpFrameVtab *vtab, const char *name,
- AstFrame *frame1, AstFrame *frame2, int *status ) {
-/*
-*+
-* Name:
-* astInitCmpFrame
-
-* Purpose:
-* Initialise a CmpFrame.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* AstCmpFrame *astInitCmpFrame( void *mem, size_t size, int init,
-* AstCmpFrameVtab *vtab, const char *name,
-* AstFrame *frame1, AstFrame *frame2 )
-
-* Class Membership:
-* CmpFrame initialiser.
-
-* Description:
-* This function is provided for use by class implementations to
-* initialise a new CmpFrame object. It allocates memory (if
-* necessary) to accommodate the CmpFrame plus any additional data
-* associated with the derived class. It then initialises a
-* CmpFrame 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 CmpFrame at the start of the memory passed
-* via the "vtab" parameter.
-
-* Parameters:
-* mem
-* A pointer to the memory in which the CmpFrame is to be
-* created. This must be of sufficient size to accommodate the
-* CmpFrame data (sizeof(CmpFrame)) 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 CmpFrame (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 CmpFrame structure, so a valid value must be
-* supplied even if not required for allocating memory.
-* init
-* A logical flag indicating if the CmpFrame'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 CmpFrame.
-* 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 Object astClass function).
-* frame1
-* Pointer to the first Frame to be included in the new CmpFrame.
-* frame2
-* Pointer to the second Frame to be included in the new CmpFrame.
-
-* Returned Value:
-* A pointer to the new CmpFrame.
-
-* 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: */
- AstCmpFrame *new; /* Pointer to new CmpFrame */
- int axis; /* Loop counter for axes */
- int naxes; /* Number of CmpFrame axes */
-
-/* Check the global status. */
- if ( !astOK ) return NULL;
-
-/* If necessary, initialise the virtual function table. */
- if ( init ) astInitCmpFrameVtab( vtab, name );
-
-/* Initialise a Frame structure (the parent class) as the first
- component within the CmpFrame structure, allocating memory if
- necessary. Set the number of Frame axes to zero, since all axis
- information is stored within the component Frames. */
- new = (AstCmpFrame *) astInitFrame( mem, size, 0, (AstFrameVtab *) vtab,
- name, 0 );
-
- if ( astOK ) {
-
-/* Initialise the CmpFrame data. */
-/* ----------------------------- */
-/* Clone the component Frame pointers. */
- new->frame1 = astClone( frame1 );
- new->frame2 = astClone( frame2 );
-
-/* Determine the number of CmpFrame axes. */
- naxes = astGetNaxes( frame1 ) + astGetNaxes( frame2 );
-
-/* Allocate memory to hold the axis permutation array and initialise
- this array. */
- new->perm = astMalloc( sizeof( int ) * (size_t) naxes );
- if ( astOK ) {
- for ( axis = 0; axis < naxes; axis++ ) new->perm[ axis ] = axis;
- }
-
-/* 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;
-}
-
-AstCmpFrame *astLoadCmpFrame_( void *mem, size_t size,
- AstCmpFrameVtab *vtab, const char *name,
- AstChannel *channel, int *status ) {
-/*
-*+
-* Name:
-* astLoadCmpFrame
-
-* Purpose:
-* Load a CmpFrame.
-
-* Type:
-* Protected function.
-
-* Synopsis:
-* #include "cmpframe.h"
-* AstCmpFrame *astLoadCmpFrame( void *mem, size_t size,
-* AstCmpFrameVtab *vtab, const char *name,
-* AstChannel *channel )
-
-* Class Membership:
-* CmpFrame loader.
-
-* Description:
-* This function is provided to load a new CmpFrame 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
-* CmpFrame structure in this memory, using data read from the
-* input Channel.
-
-* Parameters:
-* mem
-* A pointer to the memory into which the CmpFrame is to be
-* loaded. This must be of sufficient size to accommodate the
-* CmpFrame data (sizeof(CmpFrame)) 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 CmpFrame (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 CmpFrame 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(AstCmpFrame) is used instead.
-* vtab
-* Pointer to the start of the virtual function table to be
-* associated with the new CmpFrame. If this is NULL, a pointer
-* to the (static) virtual function table for the CmpFrame 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 "CmpFrame" is used instead.
-
-* Returned Value:
-* A pointer to the new CmpFrame.
-
-* 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 Constants: */
- astDECLARE_GLOBALS /* Pointer to thread-specific global data */
-#define KEY_LEN 50 /* Maximum length of a keyword */
-
-/* Local Variables: */
- AstCmpFrame *new; /* Pointer to the new CmpFrame */
- char key[ KEY_LEN + 1 ]; /* Buffer for keywords */
- int axis; /* Loop counter for axes */
- int naxes; /* Number of CmpFrame axes */
-
-/* Get a pointer to the thread specific global data structure. */
- 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 CmpFrame. In this case the
- CmpFrame belongs to this class, so supply appropriate values to be
- passed to the parent class loader (and its parent, etc.). */
- if ( !vtab ) {
- size = sizeof( AstCmpFrame );
- vtab = &class_vtab;
- name = "CmpFrame";
-
-/* If required, initialise the virtual function table for this class. */
- if ( !class_init ) {
- astInitCmpFrameVtab( 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 CmpFrame. */
- 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, "CmpFrame" );
-
-/* 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. */
-
-/* Component Frames. */
-/* ----------------- */
-/* Read both component Frames, supplying a default 1-dimensional Frame
- if necessary. */
- new->frame1 = astReadObject( channel, "framea", NULL );
- if ( !new->frame1 ) new->frame1 = astFrame( 1, "", status );
-
- new->frame2 = astReadObject( channel, "frameb", NULL );
- if ( !new->frame2 ) new->frame2 = astFrame( 1, "", status );
-
-/* Axis permutation array. */
-/* ----------------------- */
-/* Obtain the number of CmpFrame axes and allocate memory to hold the
- axis permutation array. */
- naxes = GetNaxes( (AstFrame *) new, status );
- new->perm = astMalloc( sizeof( int ) * (size_t) naxes );
-
-/* If OK, loop to read the array value for each axis. */
- if ( astOK ) {
- for ( axis = 0; axis < naxes; axis++ ) {
-
-/* Convert from 1-based to zero-based axis numbering at this
- point. The default is the "un-permuted" value. */
- sprintf( key, "axp%d", axis + 1 );
- new->perm[ axis ] = astReadInt( channel, key, axis + 1 ) - 1;
-
-/* Quit looping if an error occurs. */
- if ( !astOK ) break;
- }
- }
-
-/* If an error occurred, clean up by deleting the new CmpFrame. */
- if ( !astOK ) new = astDelete( new );
- }
-
-/* Return the new CmpFrame pointer. */
- return new;
-
-/* Undefine macros local to this function. */
-#undef KEY_LEN
-}
-
-/* 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. */
-
-
-
-
-