Starlink-AST
view release on metacpan or search on metacpan
ast/src/fluxframe.c view on Meta::CPAN
* wavelength (as given by the SpecVal attribute). Thus this class is
* more appropriate for use with images rather than spectra.
* Inheritance:
* The FluxFrame class inherits from the Frame class.
* Attributes:
* In addition to those attributes common to all Frames, every
* FluxFrame also has the following attributes:
*
* - SpecVal: The spectral position at which the flux values are measured.
* Functions:
c The FluxFrame class does not define any new functions beyond those
f The FluxFrame class does not define any new routines beyond those
* which are applicable to all Frames.
* Copyright:
* Copyright (C) 1997-2006 Council for the Central Laboratory of the
* Research Councils
* Licence:
* This program is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* License along with this program. If not, see
* <http://www.gnu.org/licenses/>.
* Authors:
* DSB: David S. Berry (Starlink)
* History:
* 6-DEC-2004 (DSB):
* Original version.
* 14-DEC-2004 (DSB):
* Added AST__SBRIGHT and AST__SBRIGHTW systems.
* 7-DEC-2005 (DSB):
* Free memory allocated by calls to astReadString.
* 14-FEB-2006 (DSB):
* Override astGetObjSize.
* 31-JAN-2007 (DSB):
* Modified so that a FluxFrame can be used as a template to find a
* FluxFrame contained within a CmpFrame. This involves changes in
* Match and the removal of the local versions of SetMaxAxes and
* SetMinAxes.
* 3-SEP-2007 (DSB):
* In SubFrame, since AlignSystem is extended by the FluxFrame class
* it needs to be cleared before invoking the parent SubFrame
* method in cases where the result Frame is not a FluxFrame.
* 2-OCT-2007 (DSB):
* In Overlay, clear AlignSystem as well as System before calling
* the parent overlay method.
* 29-APR-2011 (DSB):
* Prevent astFindFrame from matching a subclass template against a
* superclass target.
*class--
*/
/* Module Macros. */
/* ============== */
/* Set the name of the class we are implementing. This indicates to
the header files that define class interfaces that they should make
"protected" symbols available. */
#define astCLASS FluxFrame
/* Define the first and last acceptable System values. */
#define FIRST_SYSTEM AST__FLUXDEN
#define LAST_SYSTEM AST__SBRIGHTW
/* Define other numerical constants for use in this module. */
#define GETATTRIB_BUFF_LEN 50
#define GETLABEL_BUFF_LEN 200
#define GETSYMBOL_BUFF_LEN 20
#define GETTITLE_BUFF_LEN 200
/* Header files. */
/* ============= */
/* Interface definitions. */
/* ---------------------- */
#include "globals.h" /* Thread-safe global data access */
#include "error.h" /* Error reporting facilities */
#include "memory.h" /* Memory allocation facilities */
#include "unit.h" /* Units management facilities */
#include "globals.h" /* Thread-safe global data access */
#include "object.h" /* Base Object class */
#include "frame.h" /* Parent Frame class */
#include "fluxframe.h" /* Interface definition for this class */
#include "mapping.h" /* Coordinate Mappings */
#include "unitmap.h" /* Unit Mappings */
#include "cmpmap.h" /* Compound Mappings */
#include "zoommap.h" /* Scaling Mappings */
#include "specframe.h" /* Spectral Frames */
/* Error code definitions. */
/* ----------------------- */
#include "ast_err.h" /* AST error codes */
/* C header files. */
/* --------------- */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stddef.h>
#include <math.h>
/* Module Variables. */
/* ================= */
/* Address of this static variable is used as a unique identifier for
member of this class. */
static int class_check;
/* Pointers to parent class methods which are used or extended by this
class. */
static size_t (* parent_getobjsize)( AstObject *, int * );
static AstSystemType (* parent_getalignsystem)( AstFrame *, int * );
static AstSystemType (* parent_getsystem)( AstFrame *, int * );
static const char *(* parent_getattrib)( AstObject *, const char *, int * );
static const char *(* parent_getdomain)( AstFrame *, int * );
static const char *(* parent_getlabel)( AstFrame *, int, int * );
static const char *(* parent_getsymbol)( AstFrame *, int, int * );
static const char *(* parent_gettitle)( AstFrame *, int * );
static const char *(* parent_getunit)( AstFrame *, int, int * );
static int (* parent_match)( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * );
static int (* parent_subframe)( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * );
static int (* parent_testattrib)( AstObject *, const char *, int * );
static void (* parent_setunit)( AstFrame *, int, const char *, int * );
static void (* parent_clearattrib)( AstObject *, const char *, int * );
static void (* parent_overlay)( AstFrame *, const int *, AstFrame *, int * );
static void (* parent_setattrib)( AstObject *, const char *, int * );
static void (* parent_setsystem)( AstFrame *, AstSystemType, int * );
static void (* parent_clearsystem)( AstFrame *, int * );
static void (* parent_clearunit)( AstFrame *, int, int * );
#if defined(THREAD_SAFE)
static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * );
#endif
/* Define macros for accessing each item of thread specific global data. */
#ifdef THREAD_SAFE
/* Define how to initialise thread-specific globals. */
#define GLOBAL_inits \
globals->Class_Init = 0; \
globals->GetAttrib_Buff[ 0 ] = 0; \
globals->GetLabel_Buff[ 0 ] = 0; \
globals->GetSymbol_Buff[ 0 ] = 0; \
globals->GetTitle_Buff[ 0 ] = 0; \
/* Create the function that initialises global data for this module. */
astMAKE_INITGLOBALS(FluxFrame)
/* Define macros for accessing each item of thread specific global data. */
#define class_init astGLOBAL(FluxFrame,Class_Init)
#define class_vtab astGLOBAL(FluxFrame,Class_Vtab)
#define getattrib_buff astGLOBAL(FluxFrame,GetAttrib_Buff)
#define getlabel_buff astGLOBAL(FluxFrame,GetLabel_Buff)
#define getsymbol_buff astGLOBAL(FluxFrame,GetSymbol_Buff)
#define gettitle_buff astGLOBAL(FluxFrame,GetTitle_Buff)
/* If thread safety is not needed, declare and initialise globals at static
variables. */
#else
/* Buffers for strings returned by various functions. */
static char getattrib_buff[ AST__FLUXFRAME_GETATTRIB_BUFF_LEN + 1 ];
static char getlabel_buff[ AST__FLUXFRAME_GETLABEL_BUFF_LEN + 1 ];
static char getsymbol_buff[ AST__FLUXFRAME_GETSYMBOL_BUFF_LEN + 1 ];
static char gettitle_buff[ AST__FLUXFRAME_GETTITLE_BUFF_LEN + 1 ];
/* Define the class virtual function table and its initialisation flag
as static variables. */
static AstFluxFrameVtab class_vtab; /* Virtual function table */
static int class_init = 0; /* Virtual function table initialised? */
#endif
/* Prototypes for Private Member Functions. */
/* ======================================== */
static size_t GetObjSize( AstObject *, int * );
static AstSpecFrame *GetSpecFrame( AstFluxFrame *, int * );
static AstSystemType DensitySystem( AstSystemType, int * );
static AstSystemType GetAlignSystem( AstFrame *, int * );
static AstSystemType GetDensitySystem( AstFluxFrame *, int * );
static AstSystemType SystemCode( AstFrame *, const char *, int * );
static AstSystemType ValidateSystem( AstFrame *, AstSystemType, const char *, int * );
ast/src/fluxframe.c view on Meta::CPAN
vtab->ClearSpecVal = ClearSpecVal;
vtab->TestSpecVal = TestSpecVal;
vtab->GetSpecVal = GetSpecVal;
vtab->SetSpecVal = SetSpecVal;
/* Save the inherited pointers to methods that will be extended, and
replace them with pointers to the new member functions. */
object = (AstObjectVtab *) vtab;
frame = (AstFrameVtab *) vtab;
parent_getobjsize = object->GetObjSize;
object->GetObjSize = GetObjSize;
parent_clearattrib = object->ClearAttrib;
object->ClearAttrib = ClearAttrib;
parent_getattrib = object->GetAttrib;
object->GetAttrib = GetAttrib;
parent_setattrib = object->SetAttrib;
object->SetAttrib = SetAttrib;
parent_testattrib = object->TestAttrib;
object->TestAttrib = TestAttrib;
#if defined(THREAD_SAFE)
parent_managelock = object->ManageLock;
object->ManageLock = ManageLock;
#endif
parent_getdomain = frame->GetDomain;
frame->GetDomain = GetDomain;
parent_getsystem = frame->GetSystem;
frame->GetSystem = GetSystem;
parent_setsystem = frame->SetSystem;
frame->SetSystem = SetSystem;
parent_clearsystem = frame->ClearSystem;
frame->ClearSystem = ClearSystem;
parent_getalignsystem = frame->GetAlignSystem;
frame->GetAlignSystem = GetAlignSystem;
parent_getlabel = frame->GetLabel;
frame->GetLabel = GetLabel;
parent_getsymbol = frame->GetSymbol;
frame->GetSymbol = GetSymbol;
parent_gettitle = frame->GetTitle;
frame->GetTitle = GetTitle;
parent_clearunit = frame->ClearUnit;
frame->ClearUnit = ClearUnit;
parent_getunit = frame->GetUnit;
frame->GetUnit = GetUnit;
parent_setunit = frame->SetUnit;
frame->SetUnit = SetUnit;
parent_match = frame->Match;
frame->Match = Match;
parent_overlay = frame->Overlay;
frame->Overlay = Overlay;
parent_subframe = frame->SubFrame;
frame->SubFrame = SubFrame;
/* Store replacement pointers for methods which will be over-ridden by new
member functions implemented here. */
frame->GetActiveUnit = GetActiveUnit;
frame->TestActiveUnit = TestActiveUnit;
frame->ValidateSystem = ValidateSystem;
frame->SystemString = SystemString;
frame->SystemCode = SystemCode;
/* Declare the copy constructor, destructor and class dump
function. */
astSetCopy( vtab, Copy );
astSetDelete( vtab, Delete );
astSetDump( vtab, Dump, "FluxFrame", "Description of flux values" );
/* If we have just initialised the vtab for the current class, indicate
that the vtab is now initialised, and store a pointer to the class
identifier in the base "object" level of the vtab. */
if( vtab == &class_vtab ) {
class_init = 1;
astSetVtabClassIdentifier( vtab, &(vtab->id) );
}
}
#if defined(THREAD_SAFE)
static int ManageLock( AstObject *this_object, int mode, int extra,
AstObject **fail, int *status ) {
/*
* Name:
* ManageLock
* Purpose:
* Manage the thread lock on an Object.
* Type:
* Private function.
* Synopsis:
* #include "object.h"
* AstObject *ManageLock( AstObject *this, int mode, int extra,
* AstObject **fail, int *status )
* Class Membership:
* FluxFrame member function (over-rides the astManageLock protected
* method inherited from the parent class).
* Description:
* This function manages the thread lock on the supplied Object. The
* lock can be locked, unlocked or checked by this function as
* deteremined by parameter "mode". See astLock for details of the way
* these locks are used.
* Parameters:
* this
* Pointer to the Object.
* mode
ast/src/fluxframe.c view on Meta::CPAN
int match; /* Coordinate conversion possible? */
int target_axis0; /* Index of FluxFrame axis in the target */
int target_naxes; /* Number of target axes */
/* Initialise the returned values. */
*template_axes = NULL;
*target_axes = NULL;
*map = NULL;
*result = NULL;
match = 0;
/* Check the global error status. */
if ( !astOK ) return match;
/* Obtain a pointer to the template FluxFrame structure. */
template = (AstFluxFrame *) template_frame;
/* Obtain the number of axes in the target Frame. */
target_naxes = astGetNaxes( target );
/* The first criterion for a match is that the template matches as a
Frame class object. This ensures that the number of axes (1) and
domain, etc. of the target Frame are suitable. Invoke the parent
"astMatch" method to verify this. */
match = (*parent_match)( template_frame, target, matchsub,
template_axes, target_axes, map, result, status );
/* If a match was found, annul the returned objects, which are not
needed, but keep the memory allocated for the axis association
arrays, which we will re-use. */
if ( astOK && match ) {
*map = astAnnul( *map );
*result = astAnnul( *result );
}
/* If OK so far, obtain pointers to the primary Frames which underlie
all target axes. Stop when a FluxFrame axis is found. */
if ( match && astOK ) {
match = 0;
for( iaxis = 0; iaxis < target_naxes; iaxis++ ) {
astPrimaryFrame( target, iaxis, &frame0, &iaxis0 );
if( astIsAFluxFrame( frame0 ) ) {
frame0 = astAnnul( frame0 );
target_axis0 = iaxis;
match = 1;
break;
} else {
frame0 = astAnnul( frame0 );
}
}
}
/* Check at least one FluxFrame axis was found it the target. Store the
axis associataions. */
if( match && astOK ) {
(*template_axes)[ 0 ] = 0;
(*target_axes)[ 0 ] = target_axis0;
/* Use the target's "astSubFrame" method to create a new Frame (the
result Frame) with copies of the target axes in the required
order. This process also overlays the template attributes on to the
target Frame and returns a Mapping between the target and result
Frames which effects the required coordinate conversion. */
match = astSubFrame( target, template, 1, *target_axes, *template_axes,
map, result );
}
/* If an error occurred, or conversion to the result Frame's
coordinate system was not possible, then free all memory, annul the
returned objects, and reset the returned value. */
if ( !astOK || !match ) {
*template_axes = astFree( *template_axes );
*target_axes = astFree( *target_axes );
if( *map ) *map = astAnnul( *map );
if( *result ) *result = astAnnul( *result );
match = 0;
}
/* Return the result. */
return match;
}
static void Overlay( AstFrame *template, const int *template_axes,
AstFrame *result, int *status ) {
/*
* Name:
* Overlay
* Purpose:
* Overlay the attributes of a template FluxFrame on to another Frame.
* Type:
* Private function.
* Synopsis:
* #include "fluxframe.h"
* void Overlay( AstFrame *template, const int *template_axes,
* AstFrame *result, int *status )
* Class Membership:
* FluxFrame member function (over-rides the protected astOverlay method
* inherited from the Frame class).
* Description:
* This function overlays attributes of a FluxFrame (the "template") on to
* another Frame, so as to over-ride selected attributes of that second
* Frame. Normally only those attributes which have been specifically set
* in the template will be transferred. This implements a form of
* defaulting, in which a Frame acquires attributes from the template, but
* retains its original attributes (as the default) if new values have not
* previously been explicitly set in the template.
*
* Note that if the result Frame is a FluxFrame and a change of flux
* coordinate system occurs as a result of overlaying its System
* attribute, then some of its original attribute values may no
* longer be appropriate (e.g. the Title, or attributes describing
* its axes). In this case, these will be cleared before overlaying
* any new values.
* Parameters:
* template
* Pointer to the template FluxFrame, for which values should have been
* explicitly set for any attribute which is to be transferred.
* template_axes
* Pointer to an array of int, with one element for each axis of the
* "result" Frame (see below). For each axis in the result frame, the
* corresponding element of this array should contain the (zero-based)
* index of the template axis to which it corresponds. This array is used
* to establish from which template axis any axis-dependent attributes
* should be obtained.
*
* If any axis in the result Frame is not associated with a template
* axis, the corresponding element of this array should be set to -1.
*
* If a NULL pointer is supplied, the template and result axis
* indices are assumed to be identical.
* result
* Pointer to the Frame which is to receive the new attribute values.
* status
* Pointer to the inherited status variable.
* Returned Value:
* void
* Notes:
* - In general, if the result Frame is not from the same class as the
* template FluxFrame, or from a class derived from it, then attributes may
* exist in the template FluxFrame which do not exist in the result Frame.
* In this case, these attributes will not be transferred.
*/
/* Local Variables: */
AstFluxFrame *resff; /* Result FluxFrame */
AstFluxFrame *tmpff; /* Template FluxFrame */
AstSystemType new_alignsystem;/* Code identifying alignment coords */
AstSystemType new_system; /* Code identifying new cordinates */
AstSystemType old_system; /* Code identifying old coordinates */
const char *method; /* Pointer to method string */
const char *new_class; /* Pointer to template class string */
const char *old_class; /* Pointer to result class string */
int fluxframe; /* Result Frame is a FluxFrame? */
int resetSystem; /* Was the template System value cleared? */
/* Check the global error status. */
if ( !astOK ) return;
/* Initialise strings used in error messages. */
new_class = astGetClass( template );
old_class = astGetClass( result );
method = "astOverlay";
/* Get the old and new systems. */
old_system = astGetSystem( result );
new_system = astGetSystem( template );
/* If the result Frame is a FluxFrame, we must test to see if overlaying its
System attribute will change the type of coordinate system it describes.
Determine the value of this attribute for the result and template
FluxFrames. */
resetSystem = 0;
fluxframe = astIsAFluxFrame( result );
if( fluxframe ) {
/* If the coordinate system will change, any value already set for the result
FluxFrame's Title will no longer be appropriate, so clear it. */
if ( ( new_system != old_system ) && astTestSystem( template ) ) {
astClearTitle( result );
/* If the systems have the same default units, we can retain the current
Unit value. */
if( strcmp( DefUnit( new_system, method, new_class, status ),
DefUnit( old_system, method, old_class, status ) ) ) {
astClearUnit( result, 0 );
}
/* If necessary, clear inappropriate values for all those axis attributes
whose access functions are over-ridden by this class (these access functions
will then provide suitable defaults appropriate to the new coordinate system
instead). */
astClearLabel( result, 0 );
astClearSymbol( result, 0 );
}
/* Transfer the default SpecVal value and the SpecFrame. */
resff = (AstFluxFrame *) result;
tmpff = (AstFluxFrame *) template;
resff->defspecval = tmpff->defspecval;
if( resff->specframe ) (void) astAnnul( resff->specframe );
resff->specframe = tmpff->specframe ? astCopy( tmpff->specframe ) : NULL;
/* If the result Frame is not a FluxFrame, we must temporarily clear the
System and AlignSystem values since the values used by this class are only
appropriate to this class. */
} else {
if( astTestSystem( template ) ) {
astClearSystem( template );
new_alignsystem = astGetAlignSystem( template );
astClearAlignSystem( template );
resetSystem = 1;
}
}
/* Invoke the parent class astOverlay method to transfer attributes inherited
from the parent class. */
(*parent_overlay)( template, template_axes, result, status );
/* Reset the System and AlignSystem values if necessary */
if( resetSystem ) {
astSetSystem( template, new_system );
astSetAlignSystem( template, new_alignsystem );
}
/* Check if the result Frame is a FluxFrame or from a class derived from
FluxFrame. If not, we cannot transfer FluxFrame attributes to it as it is
insufficiently specialised. In this case simply omit these attributes. */
if ( fluxframe && astOK ) {
/* Define macros that test whether an attribute is set in the template and,
if so, transfers its value to the result. */
#define OVERLAY(attribute) \
if ( astTest##attribute( template ) ) { \
astSet##attribute( result, astGet##attribute( template ) ); \
}
/* Use the macro to transfer each FluxFrame attribute in turn. */
OVERLAY(SpecVal)
}
/* Undefine macros local to this function. */
#undef OVERLAY
}
static void SetAttrib( AstObject *this_object, const char *setting, int *status ) {
/*
* Name:
* SetAttrib
* Purpose:
* Set an attribute value for a FluxFrame.
* Type:
* Private function.
* Synopsis:
* #include "fluxframe.h"
* void SetAttrib( AstObject *this, const char *setting, int *status )
* Class Membership:
* FluxFrame member function (extends the astSetAttrib method inherited from
* the Mapping class).
* Description:
* This function assigns an attribute value for a FluxFrame, the attribute
* and its value being specified by means of a string of the form:
*
* "attribute= value "
*
* Here, "attribute" specifies the attribute name and should be in lower
* case with no white space present. The value to the right of the "="
* should be a suitable textual representation of the value to be assigned
* and this will be interpreted according to the attribute's data type.
* White space surrounding the value is only significant for string
* attributes.
ast/src/fluxframe.c view on Meta::CPAN
array is big enough. Free any previous value stored for the current
system. */
system = astGetSystem( this );
if( UnitsOK( system, value, 0, "astSetUnit", astGetClass( this ), status ) ) {
isystem = (int) astGetSystem( this );
if( isystem >= this->nuunits ) {
this->usedunits = astGrow( this->usedunits, isystem + 1,
sizeof(char *) );
if( astOK ) {
for( i = this->nuunits; i < isystem + 1; i++ ) this->usedunits[ i ] = NULL;
this->nuunits = isystem + 1;
}
}
/* Now store a copy of the value, if it is different to the stored string. */
if( astOK && ( !this->usedunits[ isystem ] ||
strcmp( this->usedunits[ isystem ], value ) ) ) {
this->usedunits[ isystem ] = astStore( this->usedunits[ isystem ],
value, strlen( value ) + 1 );
}
/* If the new units are not appropriate for the current System, clear the
System value. Use the parent ClearSystem function since the
astClearSystem implemented by this class will clear the units. */
} else {
(*parent_clearsystem)( this_frame, status );
}
}
static int SubFrame( AstFrame *target_frame, AstFrame *template,
int result_naxes, const int *target_axes,
const int *template_axes, AstMapping **map,
AstFrame **result, int *status ) {
/*
* Name:
* SubFrame
* Purpose:
* Select axes from a FluxFrame and convert to the new coordinate
* system.
* Type:
* Private function.
* Synopsis:
* #include "fluxframe.h"
* int SubFrame( AstFrame *target, AstFrame *template,
* int result_naxes, const int *target_axes,
* const int *template_axes, AstMapping **map,
* AstFrame **result, int *status )
* Class Membership:
* FluxFrame member function (over-rides the protected astSubFrame
* method inherited from the Frame class).
* Description:
* This function selects a requested sub-set (or super-set) of the axes
* from a "target" FluxFrame and creates a new Frame with copies of
* the selected axes assembled in the requested order. It then
* optionally overlays the attributes of a "template" Frame on to the
* result. It returns both the resulting Frame and a Mapping that
* describes how to convert between the coordinate systems described by
* the target and result Frames. If necessary, this Mapping takes
* account of any differences in the Frames' attributes due to the
* influence of the template.
* Parameters:
* target
* Pointer to the target FluxFrame, from which axes are to be
* selected.
* template
* Pointer to the template Frame, from which new attributes for the
* result Frame are to be obtained. Optionally, this may be NULL, in
* which case no overlaying of template attributes will be performed.
* result_naxes
* Number of axes to be selected from the target Frame. This number may
* be greater than or less than the number of axes in this Frame (or
* equal).
* target_axes
* Pointer to an array of int with result_naxes elements, giving a list
* of the (zero-based) axis indices of the axes to be selected from the
* target FluxFrame. The order in which these are given determines
* the order in which the axes appear in the result Frame. If any of the
* values in this array is set to -1, the corresponding result axis will
* not be derived from the target Frame, but will be assigned default
* attributes instead.
* template_axes
* Pointer to an array of int with result_naxes elements. This should
* contain a list of the template axes (given as zero-based axis indices)
* with which the axes of the result Frame are to be associated. This
* array determines which axes are used when overlaying axis-dependent
* attributes of the template on to the result. If any element of this
* array is set to -1, the corresponding result axis will not receive any
* template attributes.
*
* If the template argument is given as NULL, this array is not used and
* a NULL pointer may also be supplied here.
* map
* Address of a location to receive a pointer to the returned Mapping.
* The forward transformation of this Mapping will describe how to
* convert coordinates from the coordinate system described by the target
* FluxFrame to that described by the result Frame. The inverse
* transformation will convert in the opposite direction.
* result
* Address of a location to receive a pointer to the result Frame.
* status
* Pointer to the inherited status variable.
* Returned Value:
* A non-zero value is returned if coordinate conversion is possible
* between the target and the result Frame. Otherwise zero is returned and
* *map and *result are returned as NULL (but this will not in itself
* result in an error condition). In general, coordinate conversion should
* always be possible if no template Frame is supplied but may not always
* be possible otherwise.
* Notes:
* - A value of zero will be returned if this function is invoked with the
* global error status set, or if it should fail for any reason.
* Implementation Notes:
* - This implementation addresses the selection of axes from a
* FluxFrame object. This results in another object of the same class
* only if the single FluxFrame axis is selected exactly once.
* Otherwise, the result is a Frame class object which inherits the
* FluxFrame's axis information (if appropriate) but none of the other
* properties of a FluxFrame.
* - In the event that a FluxFrame results, the returned Mapping will
* take proper account of the relationship between the target and result
* coordinate systems.
* - In the event that a Frame class object results, the returned Mapping
* will only represent a selection/permutation of axes.
* Implementation Deficiencies:
* - Any axis selection is currently permitted. Probably this should be
* restricted so that each axis can only be selected once. The
* astValidateAxisSelection method will do this but currently there are bugs
* in the CmpFrame class that cause axis selections which will not pass this
* test. Install the validation when these are fixed.
*/
/* Local Variables: */
AstFluxFrame *target; /* Pointer to the FluxFrame structure */
AstFluxFrame *temp; /* Pointer to copy of target FluxFrame */
AstSystemType align_sys; /* System in which to align the FluxFrames */
int match; /* Coordinate conversion is possible? */
int report; /* Report errors if FluxFrames cannot be aligned? */
/* Initialise the returned values. */
*map = NULL;
*result = NULL;
match = 0;
/* Check the global error status. */
if ( !astOK ) return match;
/* Obtain a pointer to the target FluxFrame structure. */
target = (AstFluxFrame *) target_frame;
/* Result is a FluxFrame. */
/* -------------------------- */
/* Check if the result Frame is to have one axis obtained by selecting
the single target FluxFrame axis. If so, the result will also be
a FluxFrame. */
if ( ( result_naxes == 1 ) && ( target_axes[ 0 ] == 0 ) ) {
/* Form the result from a copy of the target. */
*result = astCopy( target );
/* Initialise a flag to indicate that MakeFluxMapping should not report
errors if no Mapping can be created. */
report = 0;
/* If required, overlay the template attributes on to the result FluxFrame.
Also get the system in which to align the two FluxFrames. These are the
values from the template (if there is a template). */
if ( template ) {
astOverlay( template, template_axes, *result );
if( astIsAFluxFrame( template ) ) {
align_sys = astGetAlignSystem( template );
/* Since we now know that both the template and target are FluxFrames, it
should usually be possible to convert betwen them. If conversion is
*not* possible then the user will probably be interested in knowing the
reason why conversion is not possible. Therefore, indicate that
MakeFluxMapping should report errors if no Mapping can be created. */
report = 1;
} else {
align_sys = astGetAlignSystem( target );
}
/* If no template was supplied, align in the System of the target. */
} else {
align_sys = astGetSystem( target );
}
/* Generate a Mapping that takes account of changes in the coordinate system
between the target FluxFrame and the result FluxFrame. If this Mapping can
be generated, set "match" to indicate that coordinate conversion is
possible. If the template is a fluxframe, report errors if a match is not
possible. */
match = ( MakeFluxMapping( target, (AstFluxFrame *) *result,
align_sys, map, status ) != 0 );
/* Result is not a FluxFrame. */
/* ------------------------------ */
/* In this case, we select axes as if the target were from the Frame
class. However, since the resulting data will then be separated
from their enclosing FluxFrame, default attribute values may differ
if the methods for obtaining them were over-ridden by the FluxFrame
class. To overcome this, we ensure that these values are explicitly
set for the result Frame (rather than relying on their defaults). */
} else {
/* Make a temporary copy of the target FluxFrame. We will explicitly
set the attribute values in this copy so as not to modify the original. */
temp = astCopy( target );
/* Define a macro to test if an attribute is set. If not, set it
explicitly to its default value. */
#define SET(attribute) \
if ( !astTest##attribute( temp ) ) { \
astSet##attribute( temp, astGet##attribute( temp ) ); \
}
/* Set attribute values which apply to the Frame as a whole and which
we want to retain, but whose defaults are over-ridden by the
FluxFrame class. */
SET(Domain)
SET(Title)
/* Define a macro to test if an attribute is set for axis zero (the only
axis of a FluxFrame). If not, set it explicitly to its default value. */
#define SET_AXIS(attribute) \
if ( !astTest##attribute( temp, 0 ) ) { \
astSet##attribute( temp, 0, \
astGet##attribute( temp, 0 ) ); \
}
/* Use this macro to set explicit values for all the axis attributes
for which the FluxFrame class over-rides the default value. */
SET_AXIS(Label)
SET_AXIS(Symbol)
SET_AXIS(Unit)
/* Clear attributes which have an extended range of values allowed by
this class. */
astClearSystem( temp );
astClearAlignSystem( temp );
/* Invoke the astSubFrame method inherited from the Frame class to
produce the result Frame by selecting the required set of axes and
overlaying the template Frame's attributes. */
match = (*parent_subframe)( (AstFrame *) temp, template,
result_naxes, target_axes, template_axes,
map, result, status );
/* Delete the temporary copy of the target FluxFrame. */
temp = astDelete( temp );
}
/* If an error occurred or no match was found, annul the returned
objects and reset the returned result. */
if ( !astOK || !match ) {
if( *map ) *map = astAnnul( *map );
if( *result ) *result = astAnnul( *result );
match = 0;
}
/* Return the result. */
return match;
/* Undefine macros local to this function. */
#undef SET
#undef SET_AXIS
}
static AstSystemType SystemCode( AstFrame *this, const char *system, int *status ) {
/*
* Name:
* SystemCode
* Purpose:
* Convert a string into a coordinate system type code.
* Type:
* Private function.
* Synopsis:
* #include "fluxframe.h"
* AstSystemType SystemCode( AstFrame *this, const char *system, int *status )
* Class Membership:
* FluxFrame member function (over-rides the astSystemCode method
* inherited from the Frame class).
* Description:
* This function converts a string used for the external
* description of a coordinate system into a FluxFrame
* coordinate system type code (System attribute value). It is the
* inverse of the astSystemString function.
* Parameters:
* this
* The Frame.
* system
* Pointer to a constant null-terminated string containing the
* external description of the sky coordinate system.
* status
* Pointer to the inherited status variable.
* Returned Value:
* The System type code.
( run in 0.522 second using v1.01-cache-2.11-cpan-7fcb06a456a )