diff options
Diffstat (limited to 'ast/specframe.c')
-rw-r--r-- | ast/specframe.c | 7437 |
1 files changed, 0 insertions, 7437 deletions
diff --git a/ast/specframe.c b/ast/specframe.c deleted file mode 100644 index eef06ba..0000000 --- a/ast/specframe.c +++ /dev/null @@ -1,7437 +0,0 @@ -/* -*class++ -* Name: -* SpecFrame - -* Purpose: -* Spectral coordinate system description. - -* Constructor Function: -c astSpecFrame -f AST_SPECFRAME - -* Description: -* A SpecFrame is a specialised form of one-dimensional Frame which -* represents various coordinate systems used to describe positions within -* an electro-magnetic spectrum. The particular coordinate system to be -* used is specified by setting the SpecFrame's System attribute (the -* default is wavelength) qualified, as necessary, by other attributes -* such as the rest frequency, the standard of rest, the epoch of -* observation, units, etc (see the description of the System attribute -* for details). -* -* By setting a value for thr SpecOrigin attribute, a SpecFrame can be made -* to represent offsets from a given spectral position, rather than absolute -* spectral values. - -* Inheritance: -* The SpecFrame class inherits from the Frame class. - -* Attributes: -* In addition to those attributes common to all Frames, every -* SpecFrame also has the following attributes: -* -* - AlignSpecOffset: Align SpecFrames using the offset coordinate system? -* - AlignStdOfRest: Standard of rest in which to align SpecFrames -* - RefDec: Declination of the source (FK5 J2000) -* - RefRA: Right ascension of the source (FK5 J2000) -* - RestFreq: Rest frequency -* - SourceSys: Source velocity spectral system -* - SourceVel: Source velocity -* - SourceVRF: Source velocity rest frame -* - SpecOrigin: The zero point for SpecFrame axis values -* - StdOfRest: Standard of rest -* -* Several of the Frame attributes inherited by the SpecFrame class -* refer to a specific axis of the Frame (for instance Unit(axis), -* Label(axis), etc). Since a SpecFrame is strictly one-dimensional, -* it allows these attributes to be specified without an axis index. -* So for instance, "Unit" is allowed in place of "Unit(1)". - -* Functions: -c In addition to those functions applicable to all Frames, the -c following functions may also be applied to all SpecFrames: -f In addition to those routines applicable to all Frames, the -f following routines may also be applied to all SpecFrames: -* -c - astSetRefPos: Set reference position in any celestial system -f - AST_SETREFPOS: Set reference position in any celestial system -c - astGetRefPos: Get reference position in any celestial system -f - AST_GETREFPOS: Get reference position in any celestial system - -* 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: -* 4-NOV-2002 (DSB): -* Original version. -* 2-FEB-2005 (DSB): -* - Avoid using astStore to allocate more storage than is supplied -* in the "data" pointer. This can cause access violations since -* astStore will then read beyond the end of the "data" area. -* 22-MAR-2005 (DSB): -* - Re-structure MakeSpecMapping in order to avoid unnecessary -* access to SpecFrame attributes which may not be set, and to -* check that all required attributes have been set if UseDefs is -* zero. -* 23-MAR-2005 (DSB): -* - Added missing rest frames to SorEqual. -* 12-AUG-2005 (DSB): -* - Remove GeoLon and GeoLat attributes. Use the new ObsLon and -* ObsLat attributes in the parent Frame class instead. Note, for -* backward compatibility the public attribute accessors and the -* astLoadSpecFrame functions still recogonise GeoLon and GeoLat, -* but use the ObsLat/ObsLon attributes internally. -* 14-FEB-2006 (DSB): -* Override astGetObjSize. -* 1-MAR-2006 (DSB): -* Replace astSetPermMap within DEBUG blocks by astBeginPM/astEndPM. -* 6-OCT-2006 (DSB): -* Guard against annulling null pointers in subFrame. -* 18-OCT-2006 (DSB): -* Added SpecOrigin and AlignSpecOffset attributes. -* 23-OCT-2006 (DSB): -* Fix memory leak caused by addition of SpecOrigin and AlignSpecOffset -* attributes. -* 15-NOV-2006 (DSB): -* Only write out SpecOrigin if it is not bad. -* 8-JAN-2006 (DSB): -* - SubFrame: Copy the SourceSystem and SourceStdOfRest attributes -* to the System and StdOfRest attributes of the "align_frm" -* SpecFrame before calling MakeSpecMapping. Previously, the -* values assigned to SourceSystem and SourceStdOfRest were -* ignored, and alignment was always performed in the templates System -* and StdOfRest. -* - MakeSpecMapping: Correct logic used to decide if steps 2 and 7 -* can be cancelled. -* - OriginSystem: Clear the AlignSpecOffset attributes before -* finding the Mapping between the old and new Systems. -* 16-JAN-2006 (DSB): -* Fix bug in Dump that caused SrcVRF not to be written out. -* 31-JAN-2007 (DSB): -* Modified so that a SpecFrame can be used as a template to find a -* SpecFrame contained within a CmpFrame. This involves changes in -* Match and the removal of the local versions of SetMaxAxes and -* SetMinAxes. -* 8-AUG-2007 (DSB): -* Changed Overlay to avoid the possibility of making permanent -* changes to the supplied template Frame. -* 3-SEP-2007 (DSB): -* In SubFrame, since AlignSystem is extended by the SpecFrame class -* it needs to be cleared before invoking the parent SubFrame -* method in cases where the result Frame is not a SkyFrame. -* 2-OCT-2007 (DSB): -* In Overlay, clear AlignSystem as well as System before calling -* the parent overlay method. -* 4-SEP-2009 (DSB): -* In MakeSpecMapping, in order to produce alignment that is not -* affected by the epoch or reference position, make the alignment -* frame adapt to the epoch and reference position of the target -* and result Frames. -* 14-SEP-2009 (DSB): -* In MakeSpecMapping, extend the 4-SEP-2009 fix to cover other -* attributes that define the available rest frames (e.g. -* SourceVRF, SourceVel, ObsLat, ObsLon, ObsAlt). -* 16-SEP-2009 (DSB): -* In MakeSpecMapping, retain the original alignment frame attribute -* values if we are restoring the integrity of a FrameSet. -* 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 SpecFrame - -/* Define the first and last acceptable System values. */ -#define FIRST_SYSTEM AST__FREQ -#define LAST_SYSTEM AST__VREL - -/* Define the first and last acceptable StdOfRest values. */ -#define FIRST_SOR AST__TPSOR -#define LAST_SOR AST__SCSOR - -/* The supported spectral coordinate systems fall into two groups; - "relative", and "absolute". The relative systems define each axis - value with respect to the rest frequency, whereas the absolute systems - have axis values which do not depend on the rest frequency. Define a - macro which returns one if the specified system is absolute, and zero - otherwise. */ -#define ABS_SYSTEM(sys) \ - ( ( sys == AST__ENERGY || \ - sys == AST__WAVENUM || \ - sys == AST__WAVELEN || \ - sys == AST__AIRWAVE || \ - sys == AST__FREQ ) ? 1 : 0 ) - -/* 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 "specmap.h" /* Spectral coordinate Mappings */ -#include "frame.h" /* Parent Frame class */ -#include "skyframe.h" /* Celestial coordinate frames */ -#include "specframe.h" /* Interface definition for this class */ -#include "mapping.h" /* Coordinate Mappings */ -#include "cmpmap.h" /* Compound Mappings */ -#include "unitmap.h" /* Unit Mappings */ -#include "pal.h" /* SlaLib interface */ -#include "shiftmap.h" /* Change of origin */ - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include <stddef.h> -#include <math.h> -#include <limits.h> - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are used or extended by this - class. */ -static int (* parent_getobjsize)( AstObject *, int * ); -static AstSystemType (* parent_getalignsystem)( AstFrame *, int * ); -static AstSystemType (* parent_getsystem)( AstFrame *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static const char *(* parent_getdomain)( AstFrame *, int * ); -static const char *(* parent_getlabel)( AstFrame *, int, int * ); -static const char *(* parent_getsymbol)( AstFrame *, int, int * ); -static const char *(* parent_gettitle)( AstFrame *, int * ); -static const char *(* parent_getunit)( AstFrame *, int, int * ); -static int (* parent_match)( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int (* parent_subframe)( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_setunit)( AstFrame *, int, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_overlay)( AstFrame *, const int *, AstFrame *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); -static void (* parent_setsystem)( AstFrame *, AstSystemType, int * ); -static void (* parent_clearsystem)( AstFrame *, int * ); -static void (* parent_clearunit)( AstFrame *, int, int * ); - -/* Define a variable to hold a SkyFrame which will be used for formatting - and unformatting sky positions, etc. */ -static AstSkyFrame *skyframe; - -/* 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(SpecFrame) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(SpecFrame,Class_Init) -#define class_vtab astGLOBAL(SpecFrame,Class_Vtab) -#define getattrib_buff astGLOBAL(SpecFrame,GetAttrib_Buff) -#define getlabel_buff astGLOBAL(SpecFrame,GetLabel_Buff) -#define getsymbol_buff astGLOBAL(SpecFrame,GetSymbol_Buff) -#define gettitle_buff astGLOBAL(SpecFrame,GetTitle_Buff) - - - -static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX2 pthread_mutex_lock( &mutex2 ); -#define UNLOCK_MUTEX2 pthread_mutex_unlock( &mutex2 ); - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Buffer returned by GetAttrib. */ -static char getattrib_buff[ 51 ]; - -/* Default GetLabel string buffer */ -static char getlabel_buff[ 201 ]; - -/* Default GetSymbol buffer */ -static char getsymbol_buff[ 21 ]; - -/* Default Title string buffer */ -static char gettitle_buff[ 201 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstSpecFrameVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#define LOCK_MUTEX2 -#define UNLOCK_MUTEX2 - -#endif - - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ -static AstStdOfRestType StdOfRestCode( const char *, int * ); -static int GetObjSize( AstObject *, int * ); -static AstSystemType GetAlignSystem( AstFrame *, int * ); -static AstSystemType SystemCode( AstFrame *, const char *, int * ); -static AstSystemType ValidateSystem( AstFrame *, AstSystemType, const char *, int * ); -static const char *DefUnit( AstSystemType, const char *, const char *, int * ); -static const char *GetDomain( AstFrame *, int * ); -static const char *GetLabel( AstFrame *, int, int * ); -static const char *GetSymbol( AstFrame *, int, int * ); -static const char *GetTitle( AstFrame *, int * ); -static const char *GetUnit( AstFrame *, int, int * ); -static const char *SpecMapUnit( AstSystemType, const char *, const char *, int * ); -static const char *StdOfRestString( AstStdOfRestType, int * ); -static const char *SystemLabel( AstSystemType, int * ); -static const char *SystemString( AstFrame *, AstSystemType, int * ); -static double ConvertSourceVel( AstSpecFrame *, AstStdOfRestType, AstSystemType, int * ); -static int EqualSor( AstSpecFrame *, AstSpecFrame *, int * ); -static int GetActiveUnit( AstFrame *, int * ); -static int MakeSpecMapping( AstSpecFrame *, AstSpecFrame *, AstSpecFrame *, int, AstMapping **, int * ); -static int Match( AstFrame *, AstFrame *, int, int **, int **, AstMapping **, AstFrame **, int * ); -static int SorConvert( AstSpecFrame *, AstSpecFrame *, AstSpecMap *, int * ); -static int SubFrame( AstFrame *, AstFrame *, int, const int *, const int *, AstMapping **, AstFrame **, int * ); -static int TestActiveUnit( AstFrame *, int * ); -static void ClearUnit( AstFrame *, int, int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void Delete( AstObject *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void GetRefPos( AstSpecFrame *, AstSkyFrame *, double *, double *, int * ); -static void Overlay( AstFrame *, const int *, AstFrame *, int * ); -static void SetRefPos( AstSpecFrame *, AstSkyFrame *, double, double, int * ); -static void SetUnit( AstFrame *, int, const char *, int * ); -static void VerifyAttrs( AstSpecFrame *, const char *, const char *, const char *, int * ); -static double ToUnits( AstSpecFrame *, const char *, double, const char *, int * ); -static void OriginStdOfRest( AstSpecFrame *, AstStdOfRestType, const char *, int * ); -static void OriginSystem( AstSpecFrame *, AstSystemType, const char *, int * ); - -static AstSystemType GetSystem( AstFrame *, int * ); -static void SetSystem( AstFrame *, AstSystemType, int * ); -static void ClearSystem( AstFrame *, int * ); - -static const char *GetAttrib( AstObject *, const char *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); - -static AstStdOfRestType GetAlignStdOfRest( AstSpecFrame *, int * ); -static int TestAlignStdOfRest( AstSpecFrame *, int * ); -static void ClearAlignStdOfRest( AstSpecFrame *, int * ); -static void SetAlignStdOfRest( AstSpecFrame *, AstStdOfRestType, int * ); - -static AstStdOfRestType GetStdOfRest( AstSpecFrame *, int * ); -static int TestStdOfRest( AstSpecFrame *, int * ); -static void ClearStdOfRest( AstSpecFrame *, int * ); -static void SetStdOfRest( AstSpecFrame *, AstStdOfRestType, int * ); - -static double GetRestFreq( AstSpecFrame *, int * ); -static int TestRestFreq( AstSpecFrame *, int * ); -static void ClearRestFreq( AstSpecFrame *, int * ); -static void SetRestFreq( AstSpecFrame *, double, int * ); - -static double GetSourceVel( AstSpecFrame *, int * ); -static int TestSourceVel( AstSpecFrame *, int * ); -static void ClearSourceVel( AstSpecFrame *, int * ); -static void SetSourceVel( AstSpecFrame *, double, int * ); - -static double GetRefRA( AstSpecFrame *, int * ); -static int TestRefRA( AstSpecFrame *, int * ); -static void ClearRefRA( AstSpecFrame *, int * ); -static void SetRefRA( AstSpecFrame *, double, int * ); - -static double GetRefDec( AstSpecFrame *, int * ); -static int TestRefDec( AstSpecFrame *, int * ); -static void ClearRefDec( AstSpecFrame *, int * ); -static void SetRefDec( AstSpecFrame *, double, int * ); - -static AstStdOfRestType GetSourceVRF( AstSpecFrame *, int * ); -static int TestSourceVRF( AstSpecFrame *, int * ); -static void ClearSourceVRF( AstSpecFrame *, int * ); -static void SetSourceVRF( AstSpecFrame *, AstStdOfRestType, int * ); - -static AstSystemType GetSourceSys( AstSpecFrame *, int * ); -static int TestSourceSys( AstSpecFrame *, int * ); -static void ClearSourceSys( AstSpecFrame *, int * ); -static void SetSourceSys( AstSpecFrame *, AstSystemType, int * ); - -static double GetSpecOrigin( AstSpecFrame *, int * ); -static int TestSpecOrigin( AstSpecFrame *, int * ); -static void ClearSpecOrigin( AstSpecFrame *, int * ); -static void SetSpecOrigin( AstSpecFrame *, double, int * ); -static double GetSpecOriginCur( AstSpecFrame *, int * ); - -static int GetAlignSpecOffset( AstSpecFrame *, int * ); -static int TestAlignSpecOffset( AstSpecFrame *, int * ); -static void SetAlignSpecOffset( AstSpecFrame *, int, int * ); -static void ClearAlignSpecOffset( AstSpecFrame *, int * ); - -/* Member functions. */ -/* ================= */ - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* SpecFrame 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 -* SpecFrame, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the SpecFrame. -* 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: */ - AstSpecFrame *this; /* Pointer to the SpecFrame structure */ - char *new_attrib; /* Pointer value to new attribute name */ - int len; /* Length of attrib string */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_object; - -/* Obtain the length of the "attrib" string. */ - len = strlen( attrib ); - -/* Check the attribute name and clear the appropriate attribute. */ - -/* First look for axis attributes defined by the Frame class. Since a - SpecFrame has only 1 axis, we allow these attributes to be specified - without a trailing "(axis)" string. */ - if ( !strcmp( attrib, "direction" ) || - !strcmp( attrib, "bottom" ) || - !strcmp( attrib, "top" ) || - !strcmp( attrib, "format" ) || - !strcmp( attrib, "label" ) || - !strcmp( attrib, "symbol" ) || - !strcmp( attrib, "unit" ) ) { - -/* Create a new attribute name from the original by appending the string - "(1)" and then use the parent ClearAttrib method. */ - new_attrib = astMalloc( len + 4 ); - if( new_attrib ) { - memcpy( new_attrib, attrib, len ); - memcpy( new_attrib + len, "(1)", 4 ); - (*parent_clearattrib)( this_object, new_attrib, status ); - new_attrib = astFree( new_attrib ); - } - -/* AlignStdOfRest. */ -/* --------------- */ - } else if ( !strcmp( attrib, "alignstdofrest" ) ) { - astClearAlignStdOfRest( this ); - -/* GeoLat. */ -/* ------- */ -/* Retained for backward compatibility with older versions of AST in which - SpecFrame had GeoLon/Lat attributes (now ObsLon/Lat are used instead). */ - } else if ( !strcmp( attrib, "geolat" ) ) { - astClearAttrib( this, "obslat" ); - -/* GeoLon. */ -/* ------- */ - } else if ( !strcmp( attrib, "geolon" ) ) { - astClearAttrib( this, "obslon" ); - -/* RefDec. */ -/* ---------- */ - } else if ( !strcmp( attrib, "refdec" ) ) { - astClearRefDec( this ); - -/* RefRA. */ -/* --------- */ - } else if ( !strcmp( attrib, "refra" ) ) { - astClearRefRA( this ); - -/* RestFreq. */ -/* --------- */ - } else if ( !strcmp( attrib, "restfreq" ) ) { - astClearRestFreq( this ); - -/* SourceVel. */ -/* ---------- */ - } else if ( !strcmp( attrib, "sourcevel" ) ) { - astClearSourceVel( this ); - -/* SpecOrigin. */ -/* ---------- */ - } else if ( !strcmp( attrib, "specorigin" ) ) { - astClearSpecOrigin( this ); - -/* AlignSpecOffset. */ -/* ---------------- */ - } else if ( !strcmp( attrib, "alignspecoffset" ) ) { - astClearAlignSpecOffset( this ); - -/* SourceVRF */ -/* --------- */ - } else if ( !strcmp( attrib, "sourcevrf" ) ) { - astClearSourceVRF( this ); - -/* SourceSys */ -/* --------- */ - } else if ( !strcmp( attrib, "sourcesys" ) ) { - astClearSourceSys( this ); - -/* StdOfRest. */ -/* ---------- */ - } else if ( !strcmp( attrib, "stdofrest" ) ) { - astClearStdOfRest( this ); - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static void ClearSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* ClearSystem - -* Purpose: -* Clear the System attribute for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void ClearSystem( AstFrame *this_frame, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astClearSystem protected -* method inherited from the Frame class). - -* Description: -* This function clears the System attribute for a SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to SpecFrame structure */ - AstSystemType newsys; /* System after clearing */ - AstSystemType oldsys; /* System before clearing */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_frame; - -/* Save the original system */ - oldsys = astGetSystem( this_frame ); - -/* Use the parent ClearSystem method to clear the System value. */ - (*parent_clearsystem)( this_frame, status ); - -/* Get the default System. */ - newsys = astGetSystem( this_frame ); - -/* If the system has actually changed. */ - if( newsys != oldsys ) { - -/* Changing the System value will in general require the Units to change - as well. If the used has previously specified the units to be used with - the new system, then re-instate them (they are stored in the "usedunits" - array in the SpecFrame structure). Otherwise, clear the units so that - the default units will eb used with the new System. */ - if( (int) newsys < this->nuunits && this->usedunits && - this->usedunits[ (int) newsys ] ) { - astSetUnit( this, 0, this->usedunits[ (int) newsys ] ); - } else { - astClearUnit( this, 0 ); - } - -/* Also, clear all attributes which have system-specific defaults. */ - astClearLabel( this_frame, 0 ); - astClearSymbol( this_frame, 0 ); - astClearTitle( this_frame ); - -/* Modify the SpecOrigin value to use the new System */ - OriginSystem( this, oldsys, "astClearSystem", status ); - - } - -} - -static void ClearStdOfRest( AstSpecFrame *this, int *status ) { -/* -*+ -* Name: -* astClearStdOfRest - -* Purpose: -* Clear the StdOfRest attribute for a SpecFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "timeframe.h" -* void astClearStdOfRest( AstSpecFrame *this ) - -* Class Membership: -* SpecFrame virtual function - -* Description: -* This function clears the StdOfRest attribute for a SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. - -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Modify the SpecOrigin value stored in the SpecFrame structure to refer to the - default rest frame (heliocentric). */ - OriginStdOfRest( this, AST__HLSOR, "astClearStdOfRest", status ); - -/* Store a bad value for the standard of rest in the SpecFrame structure. */ - this->stdofrest = AST__BADSOR; -} - - -static void ClearUnit( AstFrame *this_frame, int axis, int *status ) { -/* -* Name: -* ClearUnit - -* Purpose: -* Clear the value of the Unit string for a SpecFrame's axis. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void ClearUnit( AstFrame *this_frame, int axis ) - -* Class Membership: -* SpecFrame member function (over-rides the astClearUnit method inherited -* from the Frame class). - -* Description: -* This function clears the Unit string for a specified axis of a -* SpecFrame. It also clears the UsedUnit item in the SpecFrame -* structure corresponding to the current System. - -* Parameters: -* this -* Pointer to the SpecFrame. -* axis -* The number of the axis (zero-based). -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to the SpecFrame structure */ - int system; /* The SpecFrame's System value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_frame; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astClearUnit" ); - -/* Clear the UsedUnit item for the current System, if current set. */ - system = (int) astGetSystem( this ); - if( system < this->nuunits && this->usedunits ) { - this->usedunits[ system ] = astFree( this->usedunits[ system ] ); - } - -/* Use the parent method to clear the Unit attribute of the axis. */ - (*parent_clearunit)( this_frame, axis, status ); -} - -static double ConvertSourceVel( AstSpecFrame *this, AstStdOfRestType newsor, - AstSystemType newsys, int *status ) { -/* -* Name: -* ConvertSourceVel - -* Purpose: -* Convert the SourceVel value to a specified rest frame and spectral -* system. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* double ConvertSourceVel( AstSpecFrame *this, AstStdOfRestType newsor, -* AstSystemType newsys, int *status ) - -* Class Membership: -* SpecFrame member function - -* Description: -* This function convert the SourceVel value to a specified rest frame -* and spectral system, and returns the new value. - -* Parameters: -* this -* Pointer to the SpecFrame. -* newsor -* The rest frame in which the source velocity is required. -* newsys -* The spectral system (AST__VREL or AST__REDSHIFT) in which the -* source velocity is required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The converted source velocity (m/s), or redshift. - -* Notes: -* - This function returns zero if an error occurs. -*/ - -/* Local Variables: */ - AstSpecFrame *from; /* Pointer to a source SpecFrame */ - AstSpecFrame *to; /* Pointer to a destination SpecFrame */ - AstSpecMap *specmap; /* Pointer to a SpecMap */ - AstStdOfRestType sor; /* Standard of rest in which SourceVel is defined */ - AstSystemType sys; /* Spectral system in which SourceVel is defined */ - double ret; /* The returned value */ - double rf; /* Rest frequency (Hz) */ - double temp; /* Temporary storage */ - -/* Initialise */ - ret = 0.0; - -/* Check the global error status. */ - if ( !astOK ) return ret; - -/* Get the value of the SourceVel attribute. This will be a velocity in m/s - (relativistic, radio or optical), or unitless redshift or beta factor, - depending on the current value of SourceSys. */ - ret = astGetSourceVel( this ); - -/* Check it can be used (depends on whether a value has been set and - whether the UseDefs attribute is zero). */ - VerifyAttrs( this, "convert source velocity to a new standard of rest", - "SourceVel", "astMatch", status ); - -/* Get the rest frame and spectral system to which value refers. */ - sor = astGetSourceVRF( this ); - sys = astGetSourceSys( this ); - -/* If necessary, convert to the requested rest frame and spectral system. */ - if( sor != newsor || sys != newsys ) { - -/* Verify that usable value is available for the RestFreq attribute. An - error is reported if not. */ - VerifyAttrs( this, "convert source velocity to a new standard of rest", - "RestFreq", "astMatch", status ); - -/* Take two copies of the supplied SpecFrame and set their StdOfRest - attributes to the required values. */ - from = astCopy( this ); - astSetStdOfRest( from, sor ); - - to = astCopy( this ); - astSetStdOfRest( to, newsor ); - -/* Initialise a new SpecMap to describe the conversion. The new SpecMap - initially represents a UnitMap. */ - specmap = astSpecMap( 1, 0, "", status ); - -/* Add a conversion from the spectral system in which the SourceVEl value - is stored, to relativistic velocity. */ - if( sys == AST__VRADIO ) { - astSpecAdd( specmap, "VRTOVL", 0, NULL ); - - } else if( sys == AST__VOPTICAL ) { - astSpecAdd( specmap, "VOTOVL", 0, NULL ); - - } else if( sys == AST__REDSHIFT ) { - astSpecAdd( specmap, "ZOTOVL", 0, NULL ); - - } else if( sys == AST__BETA ) { - astSpecAdd( specmap, "BTTOVL", 0, NULL ); - } - -/* Add a conversion from velocity to frequency since SorConvert converts - frequencies. */ - rf = astGetRestFreq( this ); - astSpecAdd( specmap, "VLTOFR", 1, &rf ); - -/* Now add a conversion from frequency in the SourveVRF standard of rest to - frequency in the required rest frame. */ - SorConvert( from, to, specmap, status ); - -/* Add a conversion from frequency back to velocity. Note, the value of the - rest frequency does not affect the overall conversion. */ - astSpecAdd( specmap, "FRTOVL", 1, &rf ); - -/* Add a conversion from relativistic velocity to the required spectral - system, if needed. */ - if( newsys == AST__VRADIO ) { - astSpecAdd( specmap, "VLTOVR", 0, NULL ); - - } else if( newsys == AST__VOPTICAL ) { - astSpecAdd( specmap, "VLTOVO",0, NULL ); - - } else if( newsys == AST__REDSHIFT ) { - astSpecAdd( specmap, "VLTOZO",0, NULL ); - - } else if( newsys == AST__BETA ) { - astSpecAdd( specmap, "VLTOBT",0, NULL ); - } - -/* Use the SpecMap to convert the source velocity in the SourceVRF - standard of rest and SourceSys spectral system to the required rest - frame and spectral system. */ - temp = ret; - astTran1( specmap, 1, &temp, 1, &ret ); - -/* Free resources */ - specmap = astAnnul( specmap ); - to = astAnnul( to ); - from = astAnnul( from ); - } - -/* Return zero if an error has occurred. */ - if( !astOK ) ret = 0.0; - -/* Return the answer. */ - return ret; - -} - -static const char *DefUnit( AstSystemType system, const char *method, - const char *class, int *status ){ -/* -* Name: -* DefUnit - -* Purpose: -* Return the default units for a spectral coordinate system type. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *DefUnit( AstSystemType system, const char *method, -* const char *class, int *status ) - -* Class Membership: -* SpecFrame member function. - -* Description: -* This function returns a textual representation of the default -* units associated with the specified spectral coordinate system. - -* Parameters: -* system -* The spectral coordinate system. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* As tring describing the default units. This string follows the -* units syntax described in FITS WCS paper I "Representations of world -* coordinates in FITS" (Greisen & Calabretta). - -* Notes: -* - A NULL pointer is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Value to return */ - -/* Initialize */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get an identifier for the default units. */ - if( system == AST__FREQ ) { - result = "GHz"; - } else if( system == AST__ENERGY ) { - result = "J"; - } else if( system == AST__WAVENUM ) { - result = "1/m"; - } else if( system == AST__WAVELEN ) { - result = "Angstrom"; - } else if( system == AST__AIRWAVE ) { - result = "Angstrom"; - } else if( system == AST__VRADIO ) { - result = "km/s"; - } else if( system == AST__VOPTICAL ) { - result = "km/s"; - } else if( system == AST__REDSHIFT ) { - result = ""; - } else if( system == AST__BETA ) { - result = ""; - } else if( system == AST__VREL ) { - result = "km/s"; - -/* Report an error if the coordinate system was not recognised. */ - } else { - astError( AST__SCSIN, "%s(%s): Corrupt %s contains illegal System " - "identification code (%d).", status, method, class, class, - (int) system ); - } - -/* Return the result. */ - return result; -} - -static int EqualSor( AstSpecFrame *this, AstSpecFrame *that, int *status ) { -/* -* Name: -* EqualSor - -* Purpose: -* Do two SpecFrames use the same standard of rest? - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* int EqualSor( AstSpecFrame *this, AstSpecFrame *that, int *status ) - -* Class Membership: -* SpecFrame member function - -* Description: -* This function returns non-zero if the two supplied SpecFrames use -* the same standard of rest. - -* Parameters: -* this -* Pointer to the first SpecFrame. -* that -* Pointer to the second SpecFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the two SpecFrames use the same standard of rest. Zero -* otherwise. - -*/ - -/* Local Variables: */ - AstStdOfRestType sor; /* Standard of rest */ - int result; /* Value to return */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise. */ - result = 1; - -/* Compare StdOfRest attributes. */ - sor = astGetStdOfRest( this ); - if( astGetStdOfRest( that ) != sor ) { - result = 0; - -/* If the standards of rest are equal we need to check the the attributes - which specify the precise rest frame. */ - } else { - -/* The reference RA and Dec need to be equal */ - if( !astEQUAL( astGetRefRA( this ), astGetRefRA( that ) ) || - !astEQUAL( astGetRefDec( this ), astGetRefDec( that ) ) ) { - result = 0; - -/* For source rest frame, the source velocities, rest frames and systems must - be equal */ - } else if( sor == AST__SCSOR ){ - if( !astEQUAL( astGetSourceVel( this ), astGetSourceVel( that ) ) || - astGetSourceVRF( this ) != astGetSourceVRF( that ) || - astGetSourceSys( this ) != astGetSourceSys( that ) ) { - result = 0; - } - -/* For geocentric, barycentric and heliocentric rest frames, the epochs must - be the same */ - } else if( sor == AST__GESOR || sor == AST__BYSOR || sor == AST__HLSOR ){ - if( !astEQUAL( astGetEpoch( this ), astGetEpoch( that ) ) ) result = 0; - -/* For topocentric rest frame, the epoch and position of the observer must be - the same */ - } else if( sor == AST__TPSOR ){ - if( !astEQUAL( astGetEpoch( this ), astGetEpoch( that ) ) || - !astEQUAL( astGetObsAlt( this ), astGetObsAlt( that ) ) || - !astEQUAL( astGetObsLon( this ), astGetObsLon( that ) ) || - !astEQUAL( astGetObsLat( this ), astGetObsLat( that ) ) ) result = 0; - - } else if( sor != AST__LKSOR && sor != AST__LDSOR && - sor != AST__GLSOR && sor != AST__LGSOR && astOK ) { - astError( AST__INTER, "SorEqual(SpecFrame): Function SorEqual " - "does not yet support rest frame %d (AST internal " - "programming error)", status, sor ); - } - } - -/* 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 "specframe.h" -* int GetObjSize( AstObject *this, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astGetObjSize protected -* method inherited from the parent class). - -* Description: -* This function returns the in-memory size of the supplied SpecFrame, -* in bytes. - -* Parameters: -* this -* Pointer to the SpecFrame. -* 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: */ - AstSpecFrame *this; /* Pointer to SpecFrame structure */ - int result; /* Result value to return */ - int i; - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointers to the SpecFrame structure. */ - this = (AstSpecFrame *) this_object; - -/* Invoke the GetObjSize method inherited from the parent class, and then - add on any components of the class structure defined by thsi class - which are stored in dynamically allocated memory. */ - result = (*parent_getobjsize)( this_object, status ); - if( this->usedunits ) { - for( i = 0; i < this->nuunits; i++ ) { - result += astTSizeOf( this->usedunits[ i ] ); - } - result += astTSizeOf( this->usedunits ); - } - -/* If an error occurred, clear the result value. */ - if ( !astOK ) result = 0; - -/* Return the result, */ - return result; -} - -static int GetActiveUnit( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetActiveUnit - -* Purpose: -* Obtain the value of the ActiveUnit flag for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* int GetActiveUnit( AstFrame *this_frame, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astGetActiveUnit protected -* method inherited from the Frame class). - -* Description: -* This function returns the value of the ActiveUnit flag for a -* SpecFrame, which is always 1. - -* Parameters: -* this -* Pointer to the SpecFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The value to use for the ActiveUnit flag (1). - -*/ - return 1; -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* SpecFrame 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 SpecFrame, formatted as a character string. - -* Parameters: -* this -* Pointer to the SpecFrame. -* 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 SpecFrame, 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 SpecFrame. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstSpecFrame *this; /* Pointer to the SpecFrame structure */ - AstStdOfRestType sor; /* Standard of rest */ - AstSystemType sys; /* Spectral system */ - char *new_attrib; /* Pointer value to new attribute name */ - const char *result; /* Pointer value to return */ - double dval; /* Attribute value */ - int ival; /* Attribute value */ - int len; /* Length of attrib string */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_object; - -/* Create an FK5 J2000 SkyFrame which will be used for formatting and - unformatting sky positions, etc. */ - LOCK_MUTEX2 - if( !skyframe ) { - astBeginPM; - skyframe = astSkyFrame( "system=FK5,equinox=J2000", status ); - astEndPM; - } - UNLOCK_MUTEX2 - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null-terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* First look for axis attributes defined by the Frame class. Since a - SpecFrame has only 1 axis, we allow these attributes to be specified - without a trailing "(axis)" string. */ - if ( !strcmp( attrib, "direction" ) || - !strcmp( attrib, "bottom" ) || - !strcmp( attrib, "top" ) || - !strcmp( attrib, "format" ) || - !strcmp( attrib, "label" ) || - !strcmp( attrib, "symbol" ) || - !strcmp( attrib, "unit" ) ) { - -/* Create a new attribute name from the original by appending the string - "(1)" and then use the parent GetAttrib method. */ - new_attrib = astMalloc( len + 4 ); - if( new_attrib ) { - memcpy( new_attrib, attrib, len ); - memcpy( new_attrib + len, "(1)", 4 ); - result = (*parent_getattrib)( this_object, new_attrib, status ); - new_attrib = astFree( new_attrib ); - } - -/* AlignStdOfRest. */ -/* --------------- */ -/* Obtain the AlignStdOfRest code and convert to a string. */ - } else if ( !strcmp( attrib, "alignstdofrest" ) ) { - sor = astGetAlignStdOfRest( this ); - if ( astOK ) { - result = StdOfRestString( sor, status ); - -/* Report an error if the value was not recognised. */ - if ( !result ) { - astError( AST__SCSIN, - "astGetAttrib(%s): Corrupt %s contains invalid AlignStdOfRest " - "identification code (%d).", status, astGetClass( this ), - astGetClass( this ), (int) sor ); - } - } - -/* AlignSpecOffset */ -/* --------------- */ - } else if ( !strcmp( attrib, "alignspecoffset" ) ) { - ival = astGetAlignSpecOffset( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* GeoLat. */ -/* ------- */ -/* Retained for backward compatibility with older versions of AST in which - SpecFrame had GeoLon/Lat attributes (now ObsLon/Lat are used instead). */ - } else if ( !strcmp( attrib, "geolat" ) ) { - result = astGetAttrib( this, "obslat" ); - -/* GeoLon. */ -/* ------- */ - } else if ( !strcmp( attrib, "geolon" ) ) { - result = astGetAttrib( this, "obslon" ); - -/* RefDec. */ -/* ------- */ -/* Convert to a string using the SkyFrame Format method. */ - } else if ( !strcmp( attrib, "refdec" ) ) { - dval = astGetRefDec( this ); - if ( astOK ) { - result = astFormat( skyframe, 1, dval ); - } - -/* RefRA. */ -/* ------ */ -/* Convert to a string using the SkyFrame Format method. */ - } else if ( !strcmp( attrib, "refra" ) ) { - dval = astGetRefRA( this ); - if ( astOK ) { - result = astFormat( skyframe, 0, dval ); - } - -/* RestFreq. */ -/* --------- */ - } else if ( !strcmp( attrib, "restfreq" ) ) { - dval = astGetRestFreq( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval*1.0E-9 ); - result = getattrib_buff; - } - -/* SourceVel */ -/* --------- */ - } else if ( !strcmp( attrib, "sourcevel" ) ) { - dval = astGetSourceVel( this ); - if ( astOK ) { - -/* Convert from m/s to km/s if the SourceVel value is a velocity. . */ - if( astGetSourceSys( this ) == AST__VREL || - astGetSourceSys( this ) == AST__VRADIO || - astGetSourceSys( this ) == AST__VOPTICAL ) dval *= 1.0E-3; - -/* Format */ - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - - } - -/* SpecOrigin. */ -/* ----------- */ - } else if ( !strcmp( attrib, "specorigin" ) ) { - dval = GetSpecOriginCur( this, status ); - if( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - - -/* SourceVRF */ -/* ----------*/ - } else if ( !strcmp( attrib, "sourcevrf" ) ) { - sor = astGetSourceVRF( this ); - if ( astOK ) { - result = StdOfRestString( sor, status ); - -/* Report an error if the value was not recognised. */ - if ( !result ) { - astError( AST__SCSIN, - "astGetAttrib(%s): Corrupt %s contains invalid SourceVRF " - "identification code (%d).", status, astGetClass( this ), - astGetClass( this ), (int) sor ); - } - } - -/* SourceSys */ -/* ----------*/ - } else if ( !strcmp( attrib, "sourcesys" ) ) { - sys = astGetSourceSys( this ); - if ( astOK ) { - result = SystemString( (AstFrame *) this, sys, status ); - -/* Report an error if the value was not recognised. */ - if ( !result ) { - astError( AST__SCSIN, - "astGetAttrib(%s): Corrupt %s contains invalid SourceSys " - "identification code (%d).", status, astGetClass( this ), - astGetClass( this ), (int) sys ); - } - } - -/* StdOfRest. */ -/* ---------- */ -/* Obtain the StdOfRest code and convert to a string. */ - } else if ( !strcmp( attrib, "stdofrest" ) ) { - sor = astGetStdOfRest( this ); - if ( astOK ) { - result = StdOfRestString( sor, status ); - -/* Report an error if the value was not recognised. */ - if ( !result ) { - astError( AST__SCSIN, - "astGetAttrib(%s): Corrupt %s contains invalid StdOfRest " - "identification code (%d).", status, astGetClass( this ), - astGetClass( this ), (int) sor ); - } - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Return the result. */ - return result; -} - -static const char *GetDomain( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetDomain - -* Purpose: -* Obtain a pointer to the Domain attribute string for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *GetDomain( AstFrame *this, int *status ) - -* Class Membership: -* SpecFrame 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 SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. -* 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 SpecFrame. -* - 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: */ - AstSpecFrame *this; /* Pointer to SpecFrame structure */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_frame; - -/* If a Domain attribute string has been set, invoke the parent method - to obtain a pointer to it. */ - if ( astTestDomain( this ) ) { - result = (*parent_getdomain)( this_frame, status ); - -/* Otherwise, provide a pointer to a suitable default string. */ - } else { - result = "SPECTRUM"; - } - -/* Return the result. */ - return result; -} - -static const char *GetLabel( AstFrame *this, int axis, int *status ) { -/* -* Name: -* GetLabel - -* Purpose: -* Access the Label string for a SpecFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *GetLabel( AstFrame *this, int axis, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astGetLabel method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Label string for a specified axis -* of a SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. -* axis -* Axis index (zero-based) identifying the axis for which information is -* required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated character string containing the -* requested information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstMapping *map; /* Mapping between units */ - AstSystemType system; /* Code identifying type of spectral coordinates */ - char *new_lab; /* Modified label string */ - const char *result; /* Pointer to label string */ - double orig; /* Spec origin */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Initialise. */ - result = NULL; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astGetLabel" ); - -/* Check if a value has been set for the required axis label string. If so, - invoke the parent astGetLabel method to obtain a pointer to it. */ - if ( astTestLabel( this, axis ) ) { - result = (*parent_getlabel)( this, axis, status ); - -/* Otherwise, identify the spectral coordinate system described by the - SpecFrame. */ - } else { - system = astGetSystem( this ); - -/* If OK, supply a pointer to a suitable default label string. */ - if ( astOK ) { - result = strcpy( getlabel_buff, SystemLabel( system, status ) ); - getlabel_buff[ 0 ] = toupper( getlabel_buff[ 0 ] ); - -/* If a non-zero SpecOrigin has been specified, include the offset now. */ - orig = GetSpecOriginCur( (AstSpecFrame *) this, status ); - if( orig != 0.0 ) { - sprintf( getlabel_buff + strlen( getlabel_buff ), " offset from %s", - astFormat( this, 0, orig ) ); - } - -/* Modify this default to take account of the current value of the Unit - attribute, if set. */ - if( astTestUnit( this, axis ) ) { - -/* Find a Mapping from the default Units for the current System, to the - units indicated by the Unit attribute. This Mapping is used to modify - the existing default label appropriately. For instance, if the default - units is "Hz" and the actual units is "log(Hz)", then the default label - of "Frequency" is changed to "log( frequency )". */ - map = astUnitMapper( DefUnit( system, "astGetLabel", - astGetClass( this ), status ), - astGetUnit( this, axis ), result, - &new_lab ); - if( new_lab ) { - result = strcpy( getlabel_buff, new_lab ); - new_lab = astFree( new_lab ); - } - -/* Annul the unused Mapping. */ - if( map ) map = astAnnul( map ); - - } - } - } - -/* Return the result. */ - return result; -} - -static void GetRefPos( AstSpecFrame *this, AstSkyFrame *frm, double *lon, - double *lat, int *status ){ -/* -*++ -* Name: -c astGetRefPos -f AST_GETREFPOS - -* Purpose: -* Return the reference position in a specified celestial coordinate system. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "specframe.h" -c void astGetRefPos( AstSpecFrame *this, AstSkyFrame *frm, double *lon, -c double *lat ) -f CALL AST_GETREFPOS( THIS, FRM, LON, LAT, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function -f This routine -* returns the reference position (specified by attributes RefRA and -* RefDec) converted to the celestial coordinate system represented by -* a supplied SkyFrame. The celestial longitude and latitude values -* are returned in radians. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the SpecFrame. -c frm -f FRM = INTEGER (Given) -* Pointer to the SkyFrame which defines the required celestial -* coordinate system. -c If NULL -f If AST__NULL -* is supplied, then the longitude and latitude values are returned -* as FK5 J2000 RA and Dec values. -c lon -f LON = DOUBLE PRECISION (Returned) -c A pointer to a double in which to store the -f The -* longitude of the reference point, in the coordinate system -* represented by the supplied SkyFrame (radians). -c lat -f LAT = DOUBLE PRECISION (Returned) -c A pointer to a double in which to store the -f The -* latitude of the reference point, in the coordinate system -* represented by the supplied SkyFrame (radians). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - Values of AST__BAD will be returned if this function is -c invoked with the AST error status set, or if it should fail for -f invoked with STATUS set to an error value, or if it should fail for -* any reason. -*-- -*/ - -/* Local Variables: */ - AstFrameSet *fs; /* Conversion FrameSet */ - AstFrame *fb; /* Base Frame */ - AstFrame *fc; /* Current Frame */ - double xin[ 1 ]; /* Axis 1 values */ - double yin[ 1 ]; /* Axis 2 values */ - double xout[ 1 ]; /* Axis 1 values */ - double yout[ 1 ]; /* Axis 2 values */ - -/* Initialise. */ - if( lon ) *lon = AST__BAD; - if( lat ) *lat = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* If no SkyFrame was supplied, just return the stored RefRA and RefDec - values. */ - if( !frm ) { - if( lon ) *lon = astGetRefRA( this ); - if( lat ) *lat = astGetRefDec( this ); - -/* Otherwise, convert the stored values to the requested system. */ - } else { - -/* Create an FK5 J2000 SkyFrame which will be used for formatting and - unformatting sky positions, etc. */ - LOCK_MUTEX2 - if( !skyframe ) { - astBeginPM; - skyframe = astSkyFrame( "system=FK5,equinox=J2000", status ); - astEndPM; - } - UNLOCK_MUTEX2 - -/* Find the Mapping from the SkyFrame which describes the internal format - in which the RefRA and RefDec attribute values are stored, to the - supplied Frame. */ - fs = astFindFrame( skyframe, frm, "" ); - -/* If alignment was possible, use the Mapping to transform the internal - RefRA and RefDec values. Check for axis permutatuion. */ - if( fs ) { - fb = astGetFrame( fs, AST__BASE ); - if( astGetLonAxis( fb ) == 0 ) { - xin[ 0 ] = astGetRefRA( this ); - yin[ 0 ] = astGetRefDec( this ); - } else { - yin[ 0 ] = astGetRefRA( this ); - xin[ 0 ] = astGetRefDec( this ); - } - astTran2( fs, 1, xin, yin, 1, xout, yout ); - -/* Store the returned values, checking to see if the axes of the supplied - SkyFrame have been permuted. */ - fc = astGetFrame( fs, AST__CURRENT ); - if( astGetLonAxis( fc ) == 0 ) { - if( lon ) *lon = xout[ 0 ]; - if( lat ) *lat = yout[ 0 ]; - } else { - if( lon ) *lon = yout[ 0 ]; - if( lat ) *lat = xout[ 0 ]; - } - -/* Annul object references. */ - fc = astAnnul( fc ); - fb = astAnnul( fb ); - fs = astAnnul( fs ); - } - } -} - -static const char *GetSymbol( AstFrame *this, int axis, int *status ) { -/* -* Name: -* GetSymbol - -* Purpose: -* Obtain a pointer to the Symbol string for a SpecFrame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *GetSymbol( AstFrame *this, int axis, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astGetSymbol method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Symbol string for a specified axis -* of a SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. -* axis -* Axis index (zero-based) identifying the axis for which information is -* required. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated character string containing the -* requested information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstMapping *map; /* Mapping between units */ - AstSystemType system; /* Code identifying type of sky coordinates */ - char *new_sym; /* Modified symbol string */ - const char *result; /* Pointer to symbol string */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this); - -/* Initialise. */ - result = NULL; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astGetSymbol" ); - -/* Check if a value has been set for the required axis symbol string. If so, - invoke the parent astGetSymbol method to obtain a pointer to it. */ - if ( astTestSymbol( this, axis ) ) { - result = (*parent_getsymbol)( this, axis, status ); - -/* Otherwise, identify the sky coordinate system described by the SpecFrame. */ - } else { - system = astGetSystem( this ); - -/* If OK, supply a pointer to a suitable default Symbol string. */ - if ( astOK ) { - - if( system == AST__FREQ ) { - result = "FREQ"; - } else if( system == AST__ENERGY ) { - result = "ENER"; - } else if( system == AST__WAVENUM ) { - result = "WAVN"; - } else if( system == AST__WAVELEN ) { - result = "WAVE"; - } else if( system == AST__AIRWAVE ) { - result = "AWAV"; - } else if( system == AST__VRADIO ) { - result = "VRAD"; - } else if( system == AST__VOPTICAL ) { - result = "VOPT"; - } else if( system == AST__REDSHIFT ) { - result = "ZOPT"; - } else if( system == AST__BETA ) { - result = "BETA"; - } else if( system == AST__VREL ) { - result = "VELO"; - -/* Report an error if the coordinate system was not recognised. */ - } else { - astError( AST__SCSIN, "astGetSymbol(%s): Corrupt %s contains " - "invalid System identification code (%d).", status, - astGetClass( this ), astGetClass( this ), (int) system ); - } - -/* Modify this default to take account of the current value of the Unit - attribute, if set. */ - if( astTestUnit( this, axis ) ) { - -/* Find a Mapping from the default Units for the current System, to the - units indicated by the Unit attribute. This Mapping is used to modify - the existing default symbol appropriately. For instance, if the default - units is "Hz" and the actual units is "log(Hz)", then the default symbol - of "nu" is changed to "log( nu )". */ - map = astUnitMapper( DefUnit( system, "astGetSymbol", - astGetClass( this ), status ), - astGetUnit( this, axis ), result, - &new_sym ); - if( new_sym ) { - result = strcpy( getsymbol_buff, new_sym ); - new_sym = astFree( new_sym ); - } - -/* Annul the unused Mapping. */ - if( map ) map = astAnnul( map ); - - } - } - } - -/* Return the result. */ - return result; -} - -static AstSystemType GetAlignSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetAlignSystem - -* Purpose: -* Obtain the AlignSystem attribute for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "Specframe.h" -* AstSystemType GetAlignSystem( AstFrame *this_frame, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astGetAlignSystem protected -* method inherited from the Frame class). - -* Description: -* This function returns the AlignSystem attribute for a SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The AlignSystem value. - -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to SpecFrame structure */ - AstSystemType result; /* Value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) 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__WAVELEN; - } - -/* Return the result. */ - return result; -} - -static AstSystemType GetSystem( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetSystem - -* Purpose: -* Obtain the System attribute for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* AstSystemType GetSystem( AstFrame *this_frame, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astGetSystem protected -* method inherited from the Frame class). - -* Description: -* This function returns the System attribute for a SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. -* 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: */ - AstSpecFrame *this; /* Pointer to SpecFrame structure */ - AstSystemType result; /* Value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) 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__WAVELEN; - } - -/* Return the result. */ - return result; -} - -static const char *GetTitle( AstFrame *this_frame, int *status ) { -/* -* Name: -* GetTitle - -* Purpose: -* Obtain a pointer to the Title string for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *GetTitle( AstFrame *this_frame, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astGetTitle method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Title string for a SpecFrame. -* A pointer to a suitable default string is returned if no Title value has -* previously been set. - -* Parameters: -* this -* Pointer to the SpecFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a null-terminated character string containing the requested -* information. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Declare the thread specific global data */ - AstSpecFrame *this; /* Pointer to SpecFrame structure */ - AstStdOfRestType sor; /* Code identifying standard of rest */ - AstSystemType system; /* Code identifying type of coordinates */ - const char *sor_string; /* Pointer to SOR description */ - const char *result; /* Pointer to result string */ - double rf; /* Rest frequency */ - int nc; /* No. of characters added */ - int pos; /* Buffer position to enter text */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the structure holding thread-specific global data. */ - astGET_GLOBALS(this_frame); - -/* Initialise. */ - result = NULL; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_frame; - -/* See if a Title string has been set. If so, use the parent astGetTitle - method to obtain a pointer to it. */ - if ( astTestTitle( this ) ) { - result = (*parent_gettitle)( this_frame, status ); - -/* Otherwise, we will generate a default Title string. Obtain the values of the - SpecFrame's attributes that determine what this string will be. */ - } else { - system = astGetSystem( this ); - sor = astGetStdOfRest( this ); - sor_string = StdOfRestString( sor, status ); - rf = astGetRestFreq( this ); - -/* Classify the coordinate system type and create an appropriate Title - string. (Note that when invoking the astFmtDecimalYr function we must - use a separate sprintf on each occasion so as not to over-write its - internal buffer before the result string has been used.) */ - if ( astOK ) { - result = gettitle_buff; - -/* Begin with the system's default label. */ - pos = sprintf( gettitle_buff, "%s", SystemLabel( system, status ) ); - gettitle_buff[ 0 ] = toupper( gettitle_buff[ 0 ] ); - -/* Append the standard of rest in parentheses, if set. */ - if( astTestStdOfRest( this ) ) { - nc = sprintf( gettitle_buff+pos, " (%s)", sor_string ); - pos += nc; - } - -/* Append the rest frequency if relevant. */ - if( !ABS_SYSTEM(system) && ( astTestRestFreq( this ) || - astGetUseDefs( this ) ) ) { - pos += sprintf( gettitle_buff+pos, ", rest frequency = %g GHz", rf*1.0E-9 ); - } - } - } - -/* If an error occurred, clear the returned pointer value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static double GetSpecOriginCur( AstSpecFrame *this, int *status ) { -/* -* Name: -* GetSpecOriginCur - -* Purpose: -* Obtain the SpecOrigin attribute for a SpecFrame in current units. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* double GetSpecOriginCur( AstSpecFrame *this, int *status ) - -* Class Membership: -* SpecFrame virtual function - -* Description: -* This function returns the SpecOrigin attribute for a SpecFrame, in -* the current units of the SpecFrame. The protected astGetSpecOrigin -* method can be used to obtain the time origin in the default units of -* the SpecFrame's System. - -* Parameters: -* this -* Pointer to the SpecFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The SpecOrigin value, in the units, system and rest frame specified -* by the current values of the Unit, System and StdOfRest attributes -* within "this". - -* Notes: -* - AST__BAD is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstMapping *map; - const char *cur; - const char *def; - double result; - double defval; - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the value in the default units */ - result = astGetSpecOrigin( this ); - -/* If SpecOrigin is non-zero and non-BAD we convert it to the current units.*/ - if( result != 0.0 && result != AST__BAD ) { - -/* Get the default units for the SpecFrame's System. */ - def = DefUnit( astGetSystem( this ), "astGetSpecOrigin", "SpecFrame", status ); - -/* Get the current units from the SpecFrame. */ - cur = astGetUnit( this, 0 ); - -/* If the units differ, get a Mapping from default to current units. */ - if( cur && def ){ - if( strcmp( cur, def ) ) { - map = astUnitMapper( def, cur, NULL, NULL ); - -/* Report an error if the units are incompatible. */ - if( !map ) { - astError( AST__BADUN, "%s(%s): The current units (%s) are not suitable " - "for a SpecFrame.", status, "astGetSpecOrigin", astGetClass( this ), - cur ); - -/* Otherwise, transform the stored origin value.*/ - } else { - defval = result; - astTran1( map, 1, &defval, 1, &result ); - map = astAnnul( map ); - } - } - } - } - -/* Return the result. */ - return result; -} - - -static const char *GetUnit( AstFrame *this_frame, int axis, int *status ) { -/* -* Name: -* GetUnit - -* Purpose: -* Obtain a pointer to the Unit string for a SpecFrame's axis. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *GetUnit( AstFrame *this_frame, int axis ) - -* Class Membership: -* SpecFrame member function (over-rides the astGetUnit method inherited -* from the Frame class). - -* Description: -* This function returns a pointer to the Unit string for a specified axis -* of a SpecFrame. If the Unit attribute has not been set for the axis, a -* pointer to a suitable default string is returned instead. - -* Parameters: -* this -* Pointer to the SpecFrame. -* axis -* The number of the axis (zero-based) for which information is required. - -* Returned Value: -* A pointer to a null-terminated string containing the Unit value. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to the SpecFrame structure */ - AstSystemType system; /* The SpecFrame's System value */ - const char *result; /* Pointer value to return */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_frame; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astGetUnit" ); - -/* If a value has been set for the Unit attribute, use the parent - GetUnit method to return a pointer to the required Unit string. */ - if( astTestUnit( this, axis ) ){ - result = (*parent_getunit)( this_frame, axis, status ); - -/* Otherwise, identify the spectral coordinate system described by the - SpecFrame. */ - } else { - system = astGetSystem( this ); - -/* Return a string describing the default units. */ - result = DefUnit( system, "astGetUnit", astGetClass( this ), status ); - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -void astInitSpecFrameVtab_( AstSpecFrameVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitSpecFrameVtab - -* Purpose: -* Initialise a virtual function table for a SpecFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "specframe.h" -* void astInitSpecFrameVtab( AstSpecFrameVtab *vtab, const char *name ) - -* Class Membership: -* SpecFrame vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the SpecFrame class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrameVtab *frame; /* Pointer to Frame component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitFrameVtab( (AstFrameVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This - will be used (by astIsASpecFrame) to determine if an object belongs - to this class. We can conveniently use the address of the (static) - class_check variable to generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstFrameVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that - provide virtual methods for this class. */ - vtab->GetRefPos = GetRefPos; - vtab->SetRefPos = SetRefPos; - - vtab->ClearAlignStdOfRest = ClearAlignStdOfRest; - vtab->TestAlignStdOfRest = TestAlignStdOfRest; - vtab->GetAlignStdOfRest = GetAlignStdOfRest; - vtab->SetAlignStdOfRest = SetAlignStdOfRest; - - vtab->ClearSourceVRF = ClearSourceVRF; - vtab->TestSourceVRF = TestSourceVRF; - vtab->GetSourceVRF = GetSourceVRF; - vtab->SetSourceVRF = SetSourceVRF; - - vtab->ClearSourceSys = ClearSourceSys; - vtab->TestSourceSys = TestSourceSys; - vtab->GetSourceSys = GetSourceSys; - vtab->SetSourceSys = SetSourceSys; - - vtab->ClearRefDec = ClearRefDec; - vtab->TestRefDec = TestRefDec; - vtab->GetRefDec = GetRefDec; - vtab->SetRefDec = SetRefDec; - - vtab->ClearRefRA = ClearRefRA; - vtab->TestRefRA = TestRefRA; - vtab->GetRefRA = GetRefRA; - vtab->SetRefRA = SetRefRA; - - vtab->ClearRestFreq = ClearRestFreq; - vtab->TestRestFreq = TestRestFreq; - vtab->GetRestFreq = GetRestFreq; - vtab->SetRestFreq = SetRestFreq; - - vtab->ClearStdOfRest = ClearStdOfRest; - vtab->TestStdOfRest = TestStdOfRest; - vtab->GetStdOfRest = GetStdOfRest; - vtab->SetStdOfRest = SetStdOfRest; - - vtab->ClearSourceVel = ClearSourceVel; - vtab->TestSourceVel = TestSourceVel; - vtab->GetSourceVel = GetSourceVel; - vtab->SetSourceVel = SetSourceVel; - - vtab->ClearSpecOrigin = ClearSpecOrigin; - vtab->TestSpecOrigin = TestSpecOrigin; - vtab->GetSpecOrigin = GetSpecOrigin; - vtab->SetSpecOrigin = SetSpecOrigin; - - vtab->TestAlignSpecOffset = TestAlignSpecOffset; - vtab->SetAlignSpecOffset = SetAlignSpecOffset; - vtab->GetAlignSpecOffset = GetAlignSpecOffset; - vtab->ClearAlignSpecOffset = ClearAlignSpecOffset; - -/* 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; - - 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, "SpecFrame", - "Description of spectral coordinate system" ); - -/* 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 MakeSpecMapping( AstSpecFrame *target, AstSpecFrame *result, - AstSpecFrame *align_frm, int report, - AstMapping **map, int *status ) { -/* -* Name: -* MakeSpecMapping - -* Purpose: -* Generate a Mapping between two SpecFrames. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* int MakeSpecMapping( AstSpecFrame *target, AstSpecFrame *result, -* AstSpecFrame *align_frm, int report, -* AstMapping **map, int *status ) { - -* Class Membership: -* SpecFrame member function. - -* Description: -* This function takes two SpecFrames and generates a Mapping that -* converts between them, taking account of differences in their -* coordinate systems, rest frequency, standard of rest, etc. -* -* In order to cut down the number of transformations to be considered, -* the scheme works by first converting from the target frame to an -* "alignment" Frame, using the attributes of the target to define the -* transformation. A transformation is then found from the alignment -* frame to the required result Frame, using the attributes of the -* result to define the transformation. The alignment Frame is -* described by the AlignSystem and AlignStdOfRest attributes of the -* "align_frm" SpecFrame. -* -* Thus, different forms of alignment can be obtained by suitable -* choice of the attributes of "align_frm". For instance, to compare the -* radio velocity dispersion of two lines at different rest frequencies, -* you would set "system=radio velocity" and (probably) "stdofrest=local -* group" in "align_frm". On the other hand if you wanted to re-calibrate -* an existing radio velocity Frame within a FrameSet to use a different -* rest frequency, you would make the SpecFrame the current Frame and then -* set the rest frequency attribute for the FrameSet. The "integrity -* checking" system in the FrameSet class would then get the Mapping -* between the original and the modified SpecFrames. In this case, the -* "alignment system" needs to be "frequency" since you want the original -* and modified SpecFrames to be aligned in frequency, not radio velocity. - -* Parameters: -* target -* Pointer to the first SpecFrame. -* result -* Pointer to the second SpecFrame. -* align_frm -* A SpecFrame defining the system and standard of rest in which to -* align the target and result SpecFrames. -* report -* Should errors be reported if no match is possible? These reports -* will describe why no match was possible. -* map -* Pointer to a location which is to receive a pointer to the -* returned Mapping. The forward transformation of this Mapping -* will convert from "target" coordinates to "result" -* coordinates, and the inverse transformation will convert in -* the opposite direction (all coordinate values in radians). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the Mapping could be generated, or zero if the two -* SpecFrames are sufficiently un-related that no meaningful Mapping -* can be produced (albeit an "unmeaningful" Mapping will be returned -* in this case, which will need to be annulled). - -* Notes: -* A value of zero is returned if this function is invoked with the -* global error status set or if it should fail for any reason. -*/ - -/* Local Constants: */ -#define MAX_ARGS 1 /* Max arguments for an SpecMap conversion */ - -/* Local Variables: */ - AstMapping *map1; /* Intermediate Mapping */ - AstMapping *map2; /* Intermediate Mapping */ - AstMapping *umap1; /* First Units Mapping */ - AstMapping *umap2; /* Second Units Mapping */ - AstSpecMap *specmap; /* Pointer to SpecMap */ - AstShiftMap *sm; /* ShiftMap pointer */ - AstSpecFrame *align_target; /* Alignment Frame with target properties */ - AstSpecFrame *align_result; /* Alignment Frame with result properties */ - AstSystemType serr; /* Erroneous system */ - AstSystemType align_system; /* Code to identify alignment system */ - AstSystemType target_system; /* Code to identify target system */ - AstSystemType result_system; /* Code to identify result system */ - const char *uerr; /* Erroneous units */ - const char *ures; /* Results units */ - const char *utarg; /* Target units */ - const char *vmess; /* Text for use in error messages */ - double args[ MAX_ARGS ]; /* Conversion argument array */ - double target_rf; /* Target rest frequency (Hz) */ - double result_rf; /* Result rest frequency (Hz) */ - double target_origin; /* Target origin */ - double result_origin; /* Result origin */ - int match; /* Mapping can be generated? */ - int step2; /* Perform the 2nd step in the Mapping? */ - int step3; /* Perform the 3rd step in the Mapping? */ - int step4; /* Perform the 4th step in the Mapping? */ - int step5; /* Perform the 5th step in the Mapping? */ - int step6; /* Perform the 6th step in the Mapping? */ - int step7; /* Perform the 7th step in the Mapping? */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise the returned values. */ - match = 1; - *map = NULL; - -/* Create an initial (null) SpecMap. This is a 1D Mapping which converts - spectral axis values between different systems and standard of rest. - The axis units used by the SpecMap class match the default units used - by this class. Any discrepancy between units is taken into account at - the end of this function, once the total SpecMap has been created. */ - specmap = astSpecMap( 1, 0, "", status ); - -/* Define local macros as shorthand for adding spectral coordinate - conversions to this SpecMap. Each macro simply stores details of - the additional arguments in the "args" array and then calls - astSpecAdd. The macros differ in the number of additional argument - values. */ -#define TRANSFORM_0(cvt) \ - astSpecAdd( specmap, cvt, 0, NULL ); - -#define TRANSFORM_1(cvt,arg0) \ - args[ 0 ] = arg0; \ - astSpecAdd( specmap, cvt, 1, args ); - -/* Get all the necessary attributes from the result, target and alignment - Frames. */ - target_rf = astGetRestFreq( target ); - result_rf = astGetRestFreq( result ); - - target_system = astGetSystem( target ); - result_system = astGetSystem( result ); - align_system = astGetSystem( align_frm ); - -/* Define text for error messages.*/ - vmess = "convert between spectral systems"; - -/* Verify that values for the standard of rest have been set if required - (i.e if the UseDefs attribute of either SpecFrame is false). */ - VerifyAttrs( result, vmess, "StdOfRest", "astMatch", status ); - VerifyAttrs( target, vmess, "StdOfRest", "astMatch", status ); - -/* There are two different strategies for alignment. I'll use the Source - rest frame as an example, although the same argument applies to other - rest frames. In the first strategy, all "Source" rest frames are - considered equal. That is, if two SpecFrames respresent (for example) - frequencies in the source frame, then the SpecFrames are aligned using - a UnitMap even if the details of the two source rest frames differ. - This is usually what users want to see when (for instance) aligning - plots of two spectra which both represent source frequencies but where - the source frames details differ. In the second strategy, "Source" - rest frames are aligned using a SpecMap that takes into account any - differences in the properties of the source rest frames. This is what - should happen when changes are made to the properties of a SpecFrame - within a FrameSet. For instance, if the user changes the SourceVel - attribute of the current Frame (assumed here to be a SpecFrame) in a - FrameSet, then the process of restoring the integrity of the FrameSet - (see frameset.c for details of integrity restoration) should cause the - base->current Mapping in the FrameSet to be modified to reflect the - new SourceVel value. - - So if the current call to this function is part of the process of - restoring a FrameSet's integrity following changes to the FrameSet's - current Frame, then we want to retain the properties of the supplied - alignment Frame. So we use clones of the supplied alignment Frame. */ - if( astGetFrameFlags( target ) & AST__INTFLAG ) { - align_target = astClone( align_frm ); - align_result = astClone( align_frm ); - -/* Buf if we are not restoring the integrity of a FrameSet, we want - to ignore any differences in the properties that define the available - rest frames. So create copies of the alignment Frame in which the - properies defining the available rest frames are the same as in the - target and result Frames. */ - } else { - align_target = astCopy( align_frm ); - astSetEpoch( align_target, astGetEpoch( target ) ); - astSetRefRA( align_target, astGetRefRA( target ) ); - astSetRefDec( align_target, astGetRefDec( target ) ); - astSetSourceVRF( align_target, astGetSourceVRF( target ) ); - astSetSourceVel( align_target, astGetSourceVel( target ) ); - astSetObsLat( align_target, astGetObsLat( target ) ); - astSetObsLon( align_target, astGetObsLon( target ) ); - astSetObsAlt( align_target, astGetObsAlt( target ) ); - - align_result = astCopy( align_frm ); - astSetEpoch( align_result, astGetEpoch( result ) ); - astSetRefRA( align_result, astGetRefRA( result ) ); - astSetRefDec( align_result, astGetRefDec( result ) ); - astSetSourceVRF( align_result, astGetSourceVRF( result ) ); - astSetSourceVel( align_result, astGetSourceVel( result ) ); - astSetObsLat( align_result, astGetObsLat( result ) ); - astSetObsLon( align_result, astGetObsLon( result ) ); - astSetObsAlt( align_result, astGetObsAlt( result ) ); - } - -/* The supported spectral coordinate systems fall into two groups; - "relative", and "absolute". The relative systems define each axis - value with respect to the rest frequency, whereas the absolute systems - have axis values which do not depend on the rest frequency. In order - to convert an axis value from a system in one group to a system in the - other group, the rest frequency must be known. However, the rest - frequency is not necessary in order to convert axis values between two - systems belonging to the same group. Determine if the alignment system - is absolute or relative. If absolute, we ignore the system of the supplied - "align_frm" and align in frequency, since aligning in any absolute system - will automatically ensure that all the other absolute systems are aligned. - Similarly, aligning in any relative system will automatically ensure that - all the other relative systems are aligned. Doing this cuts down the - complexity of the conversion process since we do not need to check every - possible alignment system. */ - align_system = ( ABS_SYSTEM( align_system ) ) ? AST__FREQ : AST__VREL; - -/* The total Mapping is made up of the following steps in series: - - 0) Convert from an offset value to an absolute value (if SpecOrigin set) - 1) Convert target units to default units for the targets system - 2) Convert from target system in target SOR to frequency in target SOR - 3) Convert from freq in target SOR to freq in alignment SOR - 4) Convert from freq in alignment SOR to alignment system in alignment SOR - 5) Convert from alignment system in alignment SOR to freq in alignment SOR - 6) Convert from freq in alignment SOR to freq in result SOR - 7) Convert from freq in result SOR to result system in result SOR - 8) Convert default units for the result system to results unit - 9) Convert from an absolute value to an offset value (if SpecOrigin set) - - Steps 1,2,3,4 are performed using the attributes of the target (rest - frequency, reference farem, etc), whilst steps 5,6,7,8 are performed - using the attributes of the target (rest frequency, reference frame, - etc). It is necessary to go from target system to alignment system - via frequency because SOR conversion can only be performed in the - frequency domain. - - Some of these steps may not be necessary. Initially assume all steps - are necessary (we leave steps 0, 1, 8 and 9 out of this process and - implement them once all other steps have been done). */ - step2 = 1; - step3 = 1; - step4 = 1; - step5 = 1; - step6 = 1; - step7 = 1; - -/* Step 2 is not necessary if the target system is frequency. */ - if( target_system == AST__FREQ ) step2 = 0; - -/* Step 3 is not necessary if the alignment SOR is the same as the target - SOR. */ - if( EqualSor( target, align_target, status ) ) step3 = 0; - -/* Step 6 is not necessary if the alignment SOR is the same as the result - SOR. */ - if( EqualSor( result, align_result, status ) ) step6 = 0; - -/* Step 7 is not necessary if the result system is frequency. */ - if( result_system == AST__FREQ ) step7 = 0; - -/* Steps 4 and 5 are not necessary if the alignment system is frequency, - or if the target and result rest frequencies are equal. */ - if( align_system == AST__FREQ || result_rf == target_rf ) step4 = step5 = 0; - -/* Steps 3 and 6 are not necessary if steps 4 and 5 are not necessary, and - the target sor equals the result sor. */ - if( !step4 && !step5 && EqualSor( target, result, status ) ) step3 = step6 = 0; - -/* Steps 2 and 7 are not necessary if steps 3, 4, 5 and 6 are not necessary, - and the target sor equals the result sor, and the target and results - systems are equal (if the systems are relative they must also have equal - rest frequencies). */ - if( !step3 && !step4 && !step5 && !step6 && EqualSor( target, result, status ) && - target_system == result_system ) { - if( !ABS_SYSTEM( target_system ) && result_rf == target_rf ) step2 = step7 = 0; - } - - -/* Now we know which steps are needed, let's do them (we delay unit - conversion to the end)... */ - -/* Step 2: target system in target rest frame to frequency in target rest - frame. */ - if( step2 ) { - if( target_system != AST__FREQ ) { - -/* If the target system is absolute, we can convert directly to frequency. */ - if ( target_system == AST__ENERGY ) { - TRANSFORM_0( "ENTOFR" ) - - } else if ( target_system == AST__WAVENUM ) { - TRANSFORM_0( "WNTOFR" ) - - } else if ( target_system == AST__WAVELEN ) { - TRANSFORM_0( "WVTOFR" ) - - } else if ( target_system == AST__AIRWAVE ) { - TRANSFORM_0( "AWTOFR" ) - -/* If the target target_system is relative, we first need to convert to - apparent radial velocity, and then to frequency using the rest frequency. */ - } else { - - if ( target_system == AST__VRADIO ) { - TRANSFORM_0( "VRTOVL" ) - - } else if ( target_system == AST__VOPTICAL ) { - TRANSFORM_0( "VOTOVL" ) - - } else if ( target_system == AST__REDSHIFT ) { - TRANSFORM_0( "ZOTOVL" ) - - } else if ( target_system == AST__BETA ) { - TRANSFORM_0( "BTTOVL" ) - } - - VerifyAttrs( target, vmess, "RestFreq", "astMatch", status ); - TRANSFORM_1( "VLTOFR", target_rf ) - } - } - } - -/* Step 3: frequency in target rest frame to frequency in alignment rest - frame. */ - if( step3 ) match = SorConvert( target, align_target, specmap, status ); - -/* Step 4: frequency in alignment rest frame to alignment system in alignment - rest frame. The alignment will be either relativistic velocity or - frequency. */ - if( step4 ) { - if( align_system == AST__VREL ) { - VerifyAttrs( target, vmess, "RestFreq", "astMatch", status ); - TRANSFORM_1( "FRTOVL", target_rf ) - } - } - -/* Step 5: Alignment system in alignment rest frame to frequency in alignment - rest frame (from now on use the attributes of the result SpecFrame to - define the conversion parameters). */ - if( step5 ) { - if( align_system == AST__VREL ) { - VerifyAttrs( result, vmess, "RestFreq", "astMatch", status ); - TRANSFORM_1( "VLTOFR", result_rf ) - } - } - -/* Step 6: frequency in alignment rest frame to frequency in result rest - frame. */ - if( step6 ) match = SorConvert( align_result, result, specmap, status ); - -/* Step 7: frequency in result rest frame to result system in result rest - frame. */ - if( step7 ) { - if( result_system != AST__FREQ ) { - -/* If the results system is absolute, we can convert directly. */ - if ( result_system == AST__ENERGY ) { - TRANSFORM_0( "FRTOEN" ) - - } else if ( result_system == AST__WAVENUM ) { - TRANSFORM_0( "FRTOWN" ) - - } else if ( result_system == AST__WAVELEN ) { - TRANSFORM_0( "FRTOWV" ) - - } else if ( result_system == AST__AIRWAVE ) { - TRANSFORM_0( "FRTOAW" ) - -/* If the result system is relative, we first need to convert to apparent - radial velocity from frequency using the rest frequency. Report an error - if the rest frequency is undefined. */ - } else { - VerifyAttrs( result, vmess, "RestFreq", "astMatch", status ); - TRANSFORM_1( "FRTOVL", result_rf ) - -/* Now convert from apparent radial velocity to the required result system. */ - if ( result_system == AST__VRADIO ) { - TRANSFORM_0( "VLTOVR" ) - - } else if ( result_system == AST__VOPTICAL ) { - TRANSFORM_0( "VLTOVO" ) - - } else if ( result_system == AST__REDSHIFT ) { - TRANSFORM_0( "VLTOZO" ) - - } else if ( result_system == AST__BETA ) { - TRANSFORM_0( "VLTOBT" ) - } - } - } - } - -/* The SpecMap created above class assumes that the axis values supplied to - its Transform method are in units which correspond to the default units - for its class (the returned values also use these units). However, - the Unit attributes of the supplied Frames may have been set to some - non-default value, and so we need to add Mappings before and after the - SpecMap which convert to and from the default units. Find the Mapping - from the target Frame Units to the default Units for the target's system. */ - utarg = astGetUnit( target, 0 ); - umap1 = astUnitMapper( utarg, SpecMapUnit( target_system, "MakeSpecMap", - "SpecFrame", status ), NULL, NULL ); - -/* Find the Mapping from the default Units for the result's system to the - Units of the result Frame. */ - ures = astGetUnit( result, 0 ); - umap2 = astUnitMapper( SpecMapUnit( result_system, "MakeSpecMap", - "SpecFrame", status ), ures, NULL, NULL ); - -/* If both units Mappings were created OK, sandwich the SpecMap between - them. */ - if( umap1 && umap2 ) { - map1 = (AstMapping *) astCmpMap( umap1, specmap, 1, "", status ); - map2 = (AstMapping *) astCmpMap( map1, umap2, 1, "", status ); - map1 = astAnnul( map1 ); - -/* If the simplified SpecMap is a UnitMap, and the target and result - units are the same, we do not need to know the mapping between units. - Otherwise, report an error and indicate that we cannot convert between - the Frames. */ - } else { - map2 = astSimplify( specmap ); - if( !astIsAUnitMap( map2 ) || strcmp( ures, utarg ) ) { - match = 0; - if( astOK && report ) { - if( !umap1 ) { - uerr = utarg; - serr = astGetSystem( target ); - } else { - uerr = ures; - serr = astGetSystem( result ); - } - astError( AST__BADUN, "astMatch(SpecFrame): Inappropriate units (%s) " - "specified for a %s axis.", status, uerr, SystemLabel( serr, status ) ); - } - } - } - -/* Step 0: offset to absolute value in target system. Prepend the Maping created - above with a ShiftMap that does the required shift of origin. */ - target_origin = GetSpecOriginCur( target, status ); - if( target_origin != 0.0 ) { - sm = astShiftMap( 1, &target_origin, "", status ); - map1 = (AstMapping *) astCmpMap( sm, map2, 1, "", status ); - sm = astAnnul( sm ); - } else { - map1 = astClone( map2 ); - } - map2 = astAnnul( map2 ); - -/* Step 9: absolute value to offset in result system. If we are aligning in the - offset system, use the transformed target origin as the new zero point. - Otherwise use the origin from the result frame. First get the origin for the - result system. */ - if( astGetAlignSpecOffset( target ) && astGetAlignSpecOffset( result ) ) { - result_origin = 0.0; - astTran1( map1, 1, &result_origin, 1, &result_origin ); - } else { - result_origin = GetSpecOriginCur( result, status ); - } - -/* Now create the ShiftMap and apend it to the end of the Maping. */ - if( result_origin != 0.0 ) { - result_origin = -result_origin; - sm = astShiftMap( 1, &result_origin, "", status ); - map2 = (AstMapping *) astCmpMap( map1, sm, 1, "", status ); - sm = astAnnul( sm ); - } else { - map2 = astClone( map1 ); - } - map1 = astAnnul( map1 ); - -/* Return the simplified Mapping. */ - *map = astSimplify( map2 ); - -/* Annul remaining resources. */ - map2 = astAnnul( map2 ); - specmap = astAnnul( specmap ); - if( umap1 ) umap1 = astAnnul( umap1 ); - if( umap2 ) umap2 = astAnnul( umap2 ); - align_result = astAnnul( align_result ); - align_target = astAnnul( align_target ); - -/* If an error occurred, annul the returned Mapping and clear the returned - values. */ - if ( !astOK ) { - *map = astAnnul( *map ); - match = 0; - } - -/* Return the result. */ - return match; - -/* Undefine macros local to this function. */ -#undef MAX_ARGS -#undef TRANSFORM_0 -#undef TRANSFORM_1 -} - -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 "specframe.h" -* int Match( AstFrame *template, AstFrame *target, int matchsub, -* int **template_axes, int **target_axes, -* AstMapping **map, AstFrame **result, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the protected astMatch method -* inherited from the Frame class). - -* Description: -* This function matches a "template" SpecFrame to a "target" Frame and -* determines whether it is possible to convert coordinates between them. -* If it is, a mapping that performs the transformation is returned along -* with a new Frame that describes the coordinate system that results when -* this mapping is applied to the "target" coordinate system. In addition, -* information is returned to allow the axes in this "result" Frame to be -* associated with the corresponding axes in the "target" and "template" -* Frames from which they are derived. - -* Parameters: -* template -* Pointer to the template SpecFrame. This describes the coordinate -* system (or set of possible coordinate systems) into which we wish to -* convert our coordinates. -* target -* Pointer to the target Frame. This describes the coordinate system in -* which we already have coordinates. -* matchsub -* If zero then a match only occurs if the template is of the same -* class as the target, or of a more specialised class. If non-zero -* then a match can occur even if this is not the case. -* template_axes -* Address of a location where a pointer to int will be returned if the -* requested coordinate conversion is possible. This pointer will point -* at a dynamically allocated array of integers with one element for each -* axis of the "result" Frame (see below). It must be freed by the caller -* (using astFree) when no longer required. -* -* For each axis in the result Frame, the corresponding element of this -* array will return the index of the template SpecFrame axis from -* which it is derived. If it is not derived from any template -* SpecFrame axis, a value of -1 will be returned instead. -* target_axes -* Address of a location where a pointer to int will be returned if the -* requested coordinate conversion is possible. This pointer will point -* at a dynamically allocated array of integers with one element for each -* axis of the "result" Frame (see below). It must be freed by the caller -* (using astFree) when no longer required. -* -* For each axis in the result Frame, the corresponding element of this -* array will return the index of the target Frame axis from which it -* is derived. If it is not derived from any target Frame axis, a value -* of -1 will be returned instead. -* map -* Address of a location where a pointer to a new Mapping will be -* returned if the requested coordinate conversion is possible. If -* returned, the forward transformation of this Mapping may be used to -* convert coordinates between the "target" Frame and the "result" -* Frame (see below) and the inverse transformation will convert in the -* opposite direction. -* result -* Address of a location where a pointer to a new Frame will be returned -* if the requested coordinate conversion is possible. If returned, this -* Frame describes the coordinate system that results from applying the -* returned Mapping (above) to the "target" coordinate system. In -* general, this Frame will combine attributes from (and will therefore -* be more specific than) both the target and the template Frames. In -* particular, when the template allows the possibility of transformaing -* to any one of a set of alternative coordinate systems, the "result" -* Frame will indicate which of the alternatives was used. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A non-zero value is returned if the requested coordinate conversion is -* possible. Otherwise zero is returned (this will not in itself result in -* an error condition). - -* Notes: -* - A value of zero will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. - -* Implementation Notes: -* This implementation addresses the matching of a SpecFrame class -* object to any other class of Frame. A SpecFrame will match any class -* of SpecFrame (i.e. possibly from a derived class) but will not match -* a less specialised class of Frame. -*/ - -/* Local Variables: */ - AstFrame *frame0; /* Pointer to Frame underlying axis 0 */ - AstSpecFrame *template; /* Pointer to template SpecFrame structure */ - int iaxis0; /* Axis index underlying axis 0 */ - int iaxis; /* Axis index */ - int match; /* Coordinate conversion possible? */ - int target_axis0; /* Index of SpecFrame 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 SpecFrame structure. */ - template = (AstSpecFrame *) 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 SpecFrame axis is found. */ - if ( match && astOK ) { - match = 0; - for( iaxis = 0; iaxis < target_naxes; iaxis++ ) { - astPrimaryFrame( target, iaxis, &frame0, &iaxis0 ); - if( astIsASpecFrame( frame0 ) ) { - frame0 = astAnnul( frame0 ); - target_axis0 = iaxis; - match = 1; - break; - } else { - frame0 = astAnnul( frame0 ); - } - } - - } - -/* Check at least one SpecFrame 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 OriginStdOfRest( AstSpecFrame *this, AstStdOfRestType newsor, - const char *method, int *status ){ -/* -* Name: -* OriginStdOfRest - -* Purpose: -* Convert the SpecOrigin in a SpecFrame to a new rest frame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void OriginStdOfRest( AstSpecFrame *this, AstStdOfRestType newsor, -* const char *method, int *status ) - -* Class Membership: -* SpecFrame member function - -* Description: -* This function converts the value of the SpecOrigin attribute stored -* within a supplied SpecFrame from the rest frame currently associated -* with the SpecFrame, to the new rest frame indicated by "newsor". - -* Parameters: -* this -* Point to the SpecFrame. On entry, the SpecOrigin value is -* assumed to refer to the re st frame given by the astGetStdOfRest -* method. On exit, the SpecOrigin value refers to the rest frame -* supplied in "newsor". The StdOfRest attribute of the SpecFrame -* should then be modified in order to keep things consistent. -* newsor -* The rest frame to which the SpecOrigin value stored within "this" -* should refer on exit. -* method -* Pointer to a string holding the name of the method to be -* included in any error messages. -* status -* Pointer to the inherited status variable. - -*/ - - -/* Local Variables: */ - AstSpecFrame *sf; - AstFrameSet *fs; - double origin; - double neworigin; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Do nothing if the SpecOrigin attribute has not been assigned a value. */ - if( astTestSpecOrigin( this ) ) { - -/* Do nothing if the rest frame will not change. */ - if( newsor != astGetStdOfRest( this ) ) { - -/* Save the original SpecOrigin value (in the current SpecFrame units) and then - clear it. */ - origin = GetSpecOriginCur( this, status ); - astClearSpecOrigin( this ); - -/* Take a copy of the SpecFrame and set the new StdOfRest. */ - sf = astCopy( this ); - astSetStdOfRest( sf, newsor ); - -/* Create a Mapping to perform the rest frame change, then use it to convert - the value to the new rest frame. */ - fs = astConvert( this, sf, "" ); - neworigin = AST__BAD; - if( fs ) { - astTran1( fs, 1, &origin, 1, &neworigin ); - fs = astAnnul( fs ); - } - -/* If succesful, convert from the current units to the default units, and store - in "this". */ - if( neworigin != AST__BAD ) { - astSetSpecOrigin( this, ToUnits( this, astGetUnit( this, 0 ), neworigin, - method, status ) ); - - } else if( astOK ) { - astError( AST__ATSER, "%s(%s): Cannot convert the SpecOrigin " - "value to a different rest frame.", status, method, - astGetClass( this ) ); - } - } - } -} - -static void OriginSystem( AstSpecFrame *this, AstSystemType oldsys, - const char *method, int *status ){ -/* -* Name: -* OriginSystem - -* Purpose: -* Convert the SpecOrigin in a SpecFrame to a new System. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void OriginSystem( AstSpecFrame *this, AstSystemType oldsys, -* const char *method, int *status ) - -* Class Membership: -* SpecFrame member function - -* Description: -* This function converts the value of the SpecOrigin attribute stored -* within a supplied SpecFrame from its original System, etc, to the -* System, etc, currently associated with the SpecFrame. - -* Parameters: -* this -* Point to the SpecFrame. On entry, the SpecOrigin value is -* assumed to refer to the System given by "oldsys", etc. On exit, the -* SpecOrigin value refers to the System returned by the astGetSystem -* method, etc. -* oldsys -* The System to which the SpecOrigin value stored within "this" -* refers on entry. -* method -* A string containing the method name for error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstSpecFrame *sf1; - AstSpecFrame *sf2; - AstFrameSet *fs; - double origin; - double neworigin; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Do nothing if the SpecOrigin attribute has not been assigned a value. */ - if( astTestSpecOrigin( this ) ) { - -/* Do nothing if the System will not change. */ - if( oldsys != astGetSystem( this ) ) { - -/* Note the original SpecOrigin value, in the SpecFrame's default units. */ - origin = astGetSpecOrigin( this ); - -/* Take a copy of the original SpecFrame and ensure the Units, SpecOrigin and - AlignSpecOffset attributes are cleared. */ - sf1 = astCopy( this ); - astClearUnit( sf1, 0 ); - astClearSpecOrigin( sf1 ); - astClearAlignSpecOffset( sf1 ); - -/* Take another copy of the SpecFrame and set the old system. */ - sf2 = astCopy( sf1 ); - astSetSystem( sf2, oldsys ); - -/* Create a Mapping to perform the rest frame change, then use it to convert - the value to the current system. */ - fs = astConvert( sf2, sf1, "" ); - neworigin = AST__BAD; - if( fs ) { - astTran1( fs, 1, &origin, 1, &neworigin ); - fs = astAnnul( fs ); - } - -/* Free resources */ - sf1 = astAnnul( sf1 ); - sf2 = astAnnul( sf2 ); - -/* If succesful, store it in "this". */ - if( neworigin != AST__BAD ) { - astSetSpecOrigin( this, neworigin ); - - } else if( astOK ) { - astError( AST__ATSER, "%s(%s): Cannot convert the SpecOrigin " - "value to a different spectral system.", status, method, - astGetClass( this ) ); - } - } - } -} - - -static void Overlay( AstFrame *template, const int *template_axes, - AstFrame *result, int *status ) { -/* -* Name: -* Overlay - -* Purpose: -* Overlay the attributes of a template SpecFrame on to another Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void Overlay( AstFrame *template, const int *template_axes, -* AstFrame *result, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the protected astOverlay method -* inherited from the Frame class). - -* Description: -* This function overlays attributes of a SpecFrame (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 SpecFrame and a change of spectral -* 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 SpecFrame, 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 SpecFrame, or from a class derived from it, then attributes may -* exist in the template SpecFrame which do not exist in the result Frame. -* In this case, these attributes will not be transferred. -*/ - -/* Local Variables: */ - AstFrame *templt; /* Copy of supplied template Frame */ - 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 specframe; /* Result Frame is a SpecFrame? */ - -/* 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 ); - -/* It may be necessary to make temporary changes to the template Frame - below. In order to ensure that we make no permanent changes to the - supplied frame, we will, if necessary, take a deep copy of the - supplied Frame, storing a pointer to the copy in "templt". If it is - not necessary to make any changes to the template, we still want - "templt" to hold a usable pointer, so we initialise it now to hold a - clone of the supplied pointer. This pointer will be replaced by a - pointer to a deep copy (if required) below. */ - templt = astClone( template ); - -/* If the result Frame is a SpecFrame, 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 - SpecFrames. */ - specframe = astIsASpecFrame( result ); - if( specframe ) { - -/* If the coordinate system will change, any value already set for the result - SpecFrame's Title will no longer be appropriate, so clear it. */ - if ( new_system != old_system ) { - astClearTitle( result ); - -/* If the systems have the same default units, we can retain the current - Unit value. */ - if( strcmp( DefUnit( new_system, method, new_class, status ), - DefUnit( old_system, method, old_class, status ) ) ) { - astClearUnit( result, 0 ); - } - -/* If necessary, clear inappropriate values for all those axis attributes - whose access functions are over-ridden by this class (these access functions - will then provide suitable defaults appropriate to the new coordinate system - instead). */ - astClearLabel( result, 0 ); - astClearSymbol( result, 0 ); - } - -/* If the result Frame is not a SpecFrame, we must temporarily clear the - System and AlignSystem values since the values used by this class - are only appropriate to this class. Use a deep copy to avoid the danger - of making any permanent changes to the suppied Frame. */ - } else { - if( astTestSystem( template ) ) { - templt = astAnnul( templt ); - templt = astCopy( template ); - astClearSystem( templt ); - astClearAlignSystem( templt ); - } - } - -/* Invoke the parent class astOverlay method to transfer attributes inherited - from the parent class. */ - (*parent_overlay)( templt, template_axes, result, status ); - -/* Check if the result Frame is a SpecFrame or from a class derived from - SpecFrame. If not, we cannot transfer SpecFrame attributes to it as it is - insufficiently specialised. In this case simply omit these attributes. */ - if ( specframe && 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 SpecFrame attribute in turn. Note, - SourceVRF must be overlayed before SourceVel. Otherwise the stored value - for SourceVel would be changed from the default SourceVRF to the specified - SourceVRF when SourceVRF was overlayed. */ - OVERLAY(AlignStdOfRest) - OVERLAY(AlignSpecOffset); - OVERLAY(RefDec) - OVERLAY(RefRA) - OVERLAY(RestFreq) - OVERLAY(SourceSys) - OVERLAY(SourceVRF) - OVERLAY(SourceVel) - OVERLAY(StdOfRest) - OVERLAY(SpecOrigin) - } - -/* Free resources */ - templt = astAnnul( templt ); - -/* 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 SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* SpecFrame member function (extends the astSetAttrib method inherited from -* the Mapping class). - -* Description: -* This function assigns an attribute value for a SpecFrame, 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 SpecFrame. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* void - -* Notes: -* This protected method is intended to be invoked by the Object astSet -* method and makes additional attributes accessible to it. -*/ - -/* Local Vaiables: */ - AstMapping *umap; /* Mapping between units */ - AstSpecFrame *this; /* Pointer to the SpecFrame structure */ - AstStdOfRestType sor; /* Standard of rest type code */ - AstSystemType sys; /* Spectral system type code */ - char *a; /* Pointer to next character */ - char *new_setting; /* Pointer value to new attribute setting */ - double dval; /* Double atribute value */ - double dtemp; /* Temporary double atribute value */ - int ival; /* Integer attribute value */ - int len; /* Length of setting string */ - int ulen; /* Used length of setting string */ - int namelen; /* Length of attribute name in setting */ - int nc; /* Number of characters read by astSscanf */ - int off; /* Offset of attribute value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_object; - -/* Create an FK5 J2000 SkyFrame which will be used for formatting and - unformatting sky positions, etc. */ - LOCK_MUTEX2 - if( !skyframe ) { - astBeginPM; - skyframe = astSkyFrame( "system=FK5,equinox=J2000", status ); - astEndPM; - } - UNLOCK_MUTEX2 - -/* Obtain the length of the setting string. */ - len = strlen( setting ); - -/* Obtain the used length of the setting string. */ - ulen = astChrLen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse the - setting string and extract the attribute value (or an offset to it in the - case of string values). In each case, use the value set in "nc" to check - that the entire string was matched. Once a value has been obtained, use the - appropriate method to set it. */ - -/* First look for axis attributes defined by the Frame class. Since a - SpecFrame has only 1 axis, we allow these attributes to be specified - without a trailing "(axis)" string. */ - if ( !strncmp( setting, "direction=", 10 ) || - !strncmp( setting, "bottom=", 7 ) || - !strncmp( setting, "top=", 4 ) || - !strncmp( setting, "format=", 7 ) || - !strncmp( setting, "label=", 6 ) || - !strncmp( setting, "symbol=", 7 ) || - !strncmp( setting, "unit=", 5 ) ) { - -/* Create a new setting string from the original by appending the string - "(1)" to the end of the attribute name and then use the parent SetAttrib - method. */ - new_setting = astMalloc( len + 4 ); - if( new_setting ) { - memcpy( new_setting, setting, len + 1 ); - a = strchr( new_setting, '=' ); - namelen = a - new_setting; - memcpy( a, "(1)", 4 ); - a += 3; - strcpy( a, setting + namelen ); - (*parent_setattrib)( this_object, new_setting, status ); - new_setting = astFree( new_setting ); - } - -/* AlignStdOfRest. */ -/* --------------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "alignstdofrest=%n%*s %n", &off, &nc ) ) - && ( nc >= len ) ) { - -/* Convert the string to a StdOfRest code before use. */ - sor = StdOfRestCode( setting + off, status ); - if ( sor != AST__BADSOR ) { - astSetAlignStdOfRest( this, sor ); - -/* Report an error if the string value wasn't recognised. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid standard of rest " - "description \"%s\".", status, astGetClass( this ), setting+off ); - } - -/* GeoLat. */ -/* ------- */ -/* Retained for backward compatibility with older versions of AST in which - SpecFrame had GeoLon/Lat attributes (now ObsLon/Lat are used instead). */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "geolat=%n%*s %n", &off, &nc ) ) - && ( nc >= 7 ) ) { - new_setting = astStore( NULL, setting, len + 1 ); - new_setting[ 0 ] = 'o'; - new_setting[ 1 ] = 'b'; - new_setting[ 2 ] = 's'; - astSetAttrib( this, new_setting ); - new_setting = astFree( new_setting ); - -/* GeoLon. */ -/* ------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "geolon=%n%*s %n", &off, &nc ) ) - && ( nc >= 7 ) ) { - new_setting = astStore( NULL, setting, len + 1 ); - new_setting[ 0 ] = 'o'; - new_setting[ 1 ] = 'b'; - new_setting[ 2 ] = 's'; - astSetAttrib( this, new_setting ); - new_setting = astFree( new_setting ); - -/* RefDec. */ -/* ------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "refdec=%n%*s %n", &off, &nc ) ) - && ( nc >= 7 ) ) { - -/* Convert the string to a radians value before use. */ - ival = astUnformat( skyframe, 1, setting + off, &dval ); - if ( ival == ulen - off ) { - astSetRefDec( this, dval ); - -/* Report an error if the string value wasn't recognised. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid reference " - "declination \"%s\".", status, astGetClass( this ), setting + off ); - } - -/* RefRA. */ -/* ------ */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "refra=%n%*s %n", &off, &nc ) ) - && ( nc >= 6 ) ) { - -/* Convert the string to a radians value before use. */ - ival = astUnformat( skyframe, 0, setting + off, &dval ); - if ( ival == ulen - off ) { - astSetRefRA( this, dval ); - -/* Report an error if the string value wasn't recognised. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid reference right " - "ascension \"%s\".", status, astGetClass( this ), setting + off ); - } - -/* AlignSpecOffset. */ -/* ---------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "alignspecoffset= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetAlignSpecOffset( this, ival ); - -/* RestFreq. */ -/* --------- */ -/* Without any units indication - assume GHz. Convert to Hz for storage. */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "restfreq= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetRestFreq( this, dval*1.0E9 ); - -/* With units indication. */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "restfreq= %lg %n%*s %n", &dval, &off, &nc ) ) - && ( nc >= len ) ) { - dtemp = AST__BAD; - -/* Is there a Mapping from the supplied units to Hz? If so, use the - Mapping to convert the supplied value to Hz. */ - if( ( umap = astUnitMapper( setting + off, "Hz", NULL, NULL ) ) ) { - astTran1( umap, 1, &dval, 1, &dtemp ); - umap = astAnnul( umap ); - -/* Otherwise, if there is a Mapping from the supplied units to metre, - assume the supplied unit is a vacuum wavelength. */ - } else if( ( umap = astUnitMapper( setting + off, "m", NULL, NULL ) ) ) { - -/* Convert the supplied wavelength to metres. */ - astTran1( umap, 1, &dval, 1, &dtemp ); - umap = astAnnul( umap ); - -/* Convert the wavelength (m) to frequency (Hz). */ - if( dtemp != AST__BAD && dtemp != 0.0 ) { - dtemp = AST__C/dtemp; - } else if( astOK ) { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid rest wavelength " - "\"%g %s\" supplied.", status, astGetClass( this ), dval, setting + off ); - } - -/* Otherwise, if there is a Mapping from the supplied units to Joule, - assume the supplied unit is an energy. */ - } else if( ( umap = astUnitMapper( setting + off, "J", NULL, NULL ) ) ) { - -/* Convert the supplied energy to Joules. */ - astTran1( umap, 1, &dval, 1, &dtemp ); - umap = astAnnul( umap ); - -/* Convert the energy (J) to frequency (Hz). */ - if( dtemp != AST__BAD ) { - dtemp *= 1.0/AST__H; - } else if( astOK ) { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid rest energy " - "\"%g %s\" supplied.", status, astGetClass( this ), dval, setting + off ); - } - -/* Otherwise report an error. */ - } else if( astOK ) { - astError( AST__ATTIN, "astSetAttrib(%s): Rest frequency given in an " - "unsupported system of units \"%g %s\".", status, - astGetClass( this ), dval, setting + off ); - } - -/* Set the rest frequency. */ - astSetRestFreq( this, dtemp ); - -/* SourceVel. */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "sourcevel= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - -/* Convert from km/s to m/s if the SourceVel value is a velocity. */ - if( astGetSourceSys( this ) == AST__VREL || - astGetSourceSys( this ) == AST__VRADIO || - astGetSourceSys( this ) == AST__VOPTICAL ) dval *= 1.0E3; - -/* Store the value */ - astSetSourceVel( this, dval ); - -/* SourceVRF */ -/* --------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "sourcevrf=%n%*s %n", &off, &nc ) ) - && ( nc >= len ) ) { - -/* Convert the string to a StdOfRest code before use. */ - sor = StdOfRestCode( setting + off, status ); - if ( sor != AST__BADSOR ) { - astSetSourceVRF( this, sor ); - -/* Report an error if the string value wasn't recognised. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid standard of rest " - "description \"%s\".", status, astGetClass( this ), setting+off ); - } - -/* SourceSys */ -/* --------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "sourcesys=%n%*s %n", &off, &nc ) ) - && ( nc >= len ) ) { - -/* Convert the string to a System code before use. */ - sys = SystemCode( (AstFrame *) this, setting + off, status ); - astSetSourceSys( this, sys ); - -/* StdOfRest. */ -/* ---------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "stdofrest=%n%*s %n", &off, &nc ) ) - && ( nc >= len ) ) { - -/* Convert the string to a StdOfRest code before use. */ - sor = StdOfRestCode( setting + off, status ); - if ( sor != AST__BADSOR ) { - astSetStdOfRest( this, sor ); - -/* Report an error if the string value wasn't recognised. */ - } else { - astError( AST__ATTIN, "astSetAttrib(%s): Invalid standard of rest " - "description \"%s\".", status, astGetClass( this ), setting + off ); - } - -/* SpecOrigin */ -/* ---------- */ - -/* Floating-point without any units indication - assume the current Unit - value. Convert from current units to default units for current system. */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "specorigin= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - - astSetSpecOrigin( this, ToUnits( this, astGetUnit( this, 0 ), dval, - "astSetSpecOrigin", status ) ); - -/* Floating-point with units. Convert the supplied value to the default units - for the SpecFrame's System. */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "specorigin= %lg %n%*s %n", &dval, &off, &nc ) ) - && ( nc >= len ) ) { - astSetSpecOrigin( this, ToUnits( this, setting + off, dval, "astSetSpecOrigin", status ) ); - -/* Pass any unrecognised setting to the parent method for further - interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } -} - -static void SetRefPos( AstSpecFrame *this, AstSkyFrame *frm, double lon, - double lat, int *status ){ -/* -*++ -* Name: -c astSetRefPos -f AST_SETREFPOS - -* Purpose: -* Set the reference position in a specified celestial coordinate system. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "specframe.h" -c void astSetRefPos( AstSpecFrame *this, AstSkyFrame *frm, double lon, -c double lat ) -f CALL AST_SETREFPOS( THIS, FRM, LON, LAT, STATUS ) - -* Class Membership: -* Frame method. - -* Description: -c This function -f This routine -* sets the reference position (see attributes RefRA and RefDec) using -* axis values (in radians) supplied within the celestial coordinate -* system represented by a supplied SkyFrame. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the SpecFrame. -c frm -f FRM = INTEGER (Given) -* Pointer to the SkyFrame which defines the celestial coordinate -* system in which the longitude and latitude values are supplied. -c If NULL -f If AST__NULL -* is supplied, then the supplied longitude and latitude values are -* assumed to be FK5 J2000 RA and Dec values. -c lon -f LON = DOUBLE PRECISION (Given) -* The longitude of the reference point, in the coordinate system -* represented by the supplied SkyFrame (radians). -c lat -f LAT = DOUBLE PRECISION (Given) -* The latitude of the reference point, in the coordinate system -* represented by the supplied SkyFrame (radians). -f STATUS = INTEGER (Given and Returned) -f The global status. - -*-- -*/ - -/* Local Variables: */ - AstFrameSet *fs; /* Conversion FrameSet */ - AstFrame *fb; /* Base Frame */ - AstFrame *fc; /* Current Frame */ - double xin[ 1 ]; /* Axis 1 values */ - double yin[ 1 ]; /* Axis 2 values */ - double xout[ 1 ]; /* Axis 1 values */ - double yout[ 1 ]; /* Axis 2 values */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* If no SkyFrame was supplied, just store the supplied RefRA and RefDec - values. */ - if( !frm ) { - astSetRefRA( this, lon ); - astSetRefDec( this, lat ); - -/* Otherwise, convert the supplied values from the requested system. */ - } else { - -/* Create an FK5 J2000 SkyFrame which will be used for formatting and - unformatting sky positions, etc. */ - LOCK_MUTEX2 - if( !skyframe ) { - astBeginPM; - skyframe = astSkyFrame( "system=FK5,equinox=J2000", status ); - astEndPM; - } - UNLOCK_MUTEX2 - -/* Find the Mapping from the supplied SkyFrame, to the SkyFrame which - describes the internal format in which the RefRA and RefDec attribute - values are stored. */ - fs = astFindFrame( frm, skyframe, "" ); - -/* If alignment was possible, use the Mapping to transform the supplied - axis values, checking to see if the axes of the supplied SkyFrame have - been permuted. */ - if( fs ) { - -/* Find the longitude axis in the Base Frame, and store the supplied - longitude and latitude values. */ - fb = astGetFrame( fs, AST__BASE ); - if( astGetLonAxis( fb ) == 0 ) { - xin[ 0 ] = lon; - yin[ 0 ] = lat; - } else { - xin[ 0 ] = lat; - yin[ 0 ] = lon; - } - astTran2( fs, 1, xin, yin, 1, xout, yout ); - -/* Store the corresponding RefRA and RefDec values. */ - fc = astGetFrame( fs, AST__CURRENT ); - if( astGetLonAxis( fc ) == 0 ) { - astSetRefRA( this, xout[ 0 ] ); - astSetRefDec( this, yout[ 0 ] ); - } else { - astSetRefRA( this, yout[ 0 ] ); - astSetRefDec( this, xout[ 0 ] ); - } - -/* Annul object references. */ - fc = astAnnul( fc ); - fb = astAnnul( fb ); - fs = astAnnul( fs ); - } - } -} - -static void SetStdOfRest( AstSpecFrame *this, AstStdOfRestType value, int *status ) { -/* -*+ -* Name: -* astSetStdOfRest - -* Purpose: -* Set the StdOfRest attribute for a SpecFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "specframe.h" -* void astSetStdOfRest( AstSpecFrame *this, AstStdOfRestType value ) - -* Class Membership: -* SpecFrame virtual function - -* Description: -* This function set a new value for the StdOfRest attribute for a -* SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. -* value -* The new value. - -*- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - - -/* Validate the StdOfRest value being set and report an error if necessary. */ - if( value < FIRST_SOR || value > LAST_SOR ) { - astError( AST__ATTIN, "%s(%s): Bad value (%d) given for StdOfRest attribute.", status, - "astSetStdOfRest", astGetClass( this ), (int) value ); - -/* Otherwise set the new StdOfRest */ - } else { - -/* Modify the SpecOrigin value stored in the SpecFrame structure to refer - to the new rest frame. */ - OriginStdOfRest( this, value, "astSetStdOfRest", status ); - -/* Store the new value for the rest frame in the SpecFrame structure. */ - this->stdofrest = value; - - } -} - -static void SetSystem( AstFrame *this_frame, AstSystemType newsys, int *status ) { -/* -* Name: -* SetSystem - -* Purpose: -* Set the System attribute for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void SetSystem( AstFrame *this_frame, AstSystemType newsys, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astSetSystem protected -* method inherited from the Frame class). - -* Description: -* This function sets the System attribute for a SpecFrame. - -* Parameters: -* this -* Pointer to the SpecFrame. -* newsys -* The new System value to be stored. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to SpecFrame structure */ - AstSystemType oldsys; /* Original System value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_frame; - -/* Save the original System value */ - oldsys = astGetSystem( this_frame ); - -/* Use the parent SetSystem method to store the new System value. */ - (*parent_setsystem)( this_frame, newsys, status ); - -/* If the system has changed... */ - if( oldsys != newsys ) { - -/* Changing the System value will in general require the Units to change - as well. If the user has previously specified the units to be used with - the new system, then re-instate them (they are stored in the "usedunits" - array in the SpecFrame structure). Otherwise, clear the units so that - the default units will eb used with the new System. */ - if( (int) newsys < this->nuunits && this->usedunits && - this->usedunits[ (int) newsys ] ) { - astSetUnit( this, 0, this->usedunits[ (int) newsys ] ); - } else { - astClearUnit( this, 0 ); - } - -/* Modify the stored SpecOrigin. */ - OriginSystem( this, oldsys, "astSetSystem", status ); - -/* Also, clear all attributes which have system-specific defaults. */ - astClearLabel( this_frame, 0 ); - astClearSymbol( this_frame, 0 ); - astClearTitle( this_frame ); - } -} - -static void SetUnit( AstFrame *this_frame, int axis, const char *value, int *status ) { -/* -* Name: -* SetUnit - -* Purpose: -* Set a pointer to the Unit string for a SpecFrame's axis. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void SetUnit( AstFrame *this_frame, int axis, const char *value ) - -* Class Membership: -* SpecFrame member function (over-rides the astSetUnit method inherited -* from the Frame class). - -* Description: -* This function stores a pointer to the Unit string for a specified axis -* of a SpecFrame. It also stores the string in the "usedunits" array -* in the SpecFrame structure, in the element associated with the -* current System. - -* Parameters: -* this -* Pointer to the SpecFrame. -* axis -* The number of the axis (zero-based) for which information is required. -* unit -* The new string to store. -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to the SpecFrame structure */ - int i; /* Loop counter */ - int system; /* The SpecFrame's System value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_frame; - -/* Validate the axis index. */ - astValidateAxis( this, axis, 1, "astSetUnit" ); - -/* Store the supplied value as the UsedUnit for the current System. First - ensure the array is big enough. Free any previous value stored for the - current system. */ - system = (int) astGetSystem( this ); - if( system >= this->nuunits ) { - this->usedunits = astGrow( this->usedunits, system + 1, - sizeof(char *) ); - if( astOK ) { - for( i = this->nuunits; i < system + 1; i++ ) this->usedunits[ i ] = NULL; - this->nuunits = system + 1; - } - } - -/* Now store a copy of the value, if it is different to the stored string. */ - if( astOK && ( !this->usedunits[ system ] || - strcmp( this->usedunits[ system ], value ) ) ) { - this->usedunits[ system ] = astStore( this->usedunits[ system ], - value, strlen( value ) + 1 ); - } - -/* Now use the parent SetUnit method to store the value in the Axis - structure */ - (*parent_setunit)( this_frame, axis, value, status ); - -} - -static int SorConvert( AstSpecFrame *this, AstSpecFrame *that, - AstSpecMap *specmap, int *status ) { -/* -* Name: -* SorConvert - -* Purpose: -* Add a conversion to a SpecMap which transforms between two -* standards of rest. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* int SorConvert( AstSpecFrame *this, AstSpecFrame *that, -* AstSpecMap *specmap, int *status ) - -* Class Membership: -* SpecFrame member function. - -* Description: -* This function adds a conversion to a SpecMap which transforms -* frequencies from the standard of rest specified by "this" to -* the standard of rest specified by "that". Note the conversion is -* always between frequency in the two rest frames no matter what the -* System attributes of the two SpecFrames may be (which are ignored). - -* Parameters: -* this -* The SpecFrame which defines the input rest frame. -* that -* The SpecFrame which defines the output rest frame. -* specmap -* The SpecMap to which the conversion is to be added. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero is returned if the conversion could not be performed. One is -* returned otherwise. - -*/ - -/* Local Constants: */ -#define MAX_ARGS 7 /* Max arguments for an SpecMap conversion */ - -/* Local Variables: */ - AstStdOfRestType from; /* Input standard of rest */ - AstStdOfRestType to; /* Output standard of rest */ - const char *vmess; /* Text for use in error messages */ - double args[ MAX_ARGS ]; /* Conversion argument array */ - double dec; /* DEC of source (radians, FK5 J2000) */ - double epoch; /* Epoch of observation (MJD) */ - double alt; /* Observers geodetic altitude (radians) */ - double lat; /* Observers geodetic latitude (radians) */ - double lon; /* Observers geodetic longitude (radians) */ - double ra; /* RA of source (radians, FK5 J2000) */ - int result; /* Returned value */ - -/* Initialise */ - result = 1; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* No conversion is required if the rest frames are equal. */ - if( !EqualSor( this, that, status ) ) { - -/* Define local macros as shorthand for adding spectral coordinate - conversions to the SpecMap. Each macro simply stores details of - the additional arguments in the "args" array and then calls - astSpecAdd. The macros differ in the number of additional argument - values. */ -#define TRANSFORM_2(cvt,arg0,arg1) \ - args[ 0 ] = arg0; \ - args[ 1 ] = arg1; \ - astSpecAdd( specmap, cvt, 2, args ); - -#define TRANSFORM_3(cvt,arg0,arg1,arg2) \ - args[ 0 ] = arg0; \ - args[ 1 ] = arg1; \ - args[ 2 ] = arg2; \ - astSpecAdd( specmap, cvt, 3, args ); - -#define TRANSFORM_6(cvt,arg0,arg1,arg2,arg3,arg4,arg5) \ - args[ 0 ] = arg0; \ - args[ 1 ] = arg1; \ - args[ 2 ] = arg2; \ - args[ 3 ] = arg3; \ - args[ 4 ] = arg4; \ - args[ 5 ] = arg5; \ - astSpecAdd( specmap, cvt, 6, args ); - -/* A string for use in error messages. */ - vmess = "convert between different standards of rest"; - -/* Get the required values from "this". */ - from = astGetStdOfRest( this ); - ra = astGetRefRA( this ); - dec = astGetRefDec( this ); - lon = astGetObsLon( this ); - lat = astGetObsLat( this ); - alt = astGetObsAlt( this ); - epoch = astGetEpoch( this ); - -/* Verify that the reference RA and DEC can be used (they are needed by all - the conversions used below). */ - VerifyAttrs( this, vmess, "RefRA RefDec", "astMatch", status ); - -/* Convert from the "this" rest frame to heliographic. */ - if( from == AST__TPSOR ) { - VerifyAttrs( this, vmess, "ObsLon ObsLat ObsAlt Epoch", "astMatch", status ); - TRANSFORM_6( "TPF2HL", lon, lat, alt, epoch, ra, dec ) - - } else if( from == AST__GESOR ) { - VerifyAttrs( this, vmess, "Epoch", "astMatch", status ); - TRANSFORM_3( "GEF2HL", epoch, ra, dec ) - - } else if( from == AST__BYSOR ) { - VerifyAttrs( this, vmess, "Epoch", "astMatch", status ); - TRANSFORM_3( "BYF2HL", epoch, ra, dec ) - - } else if( from == AST__LKSOR ) { - TRANSFORM_2( "LKF2HL", ra, dec ) - - } else if( from == AST__LDSOR ) { - TRANSFORM_2( "LDF2HL", ra, dec ) - - } else if( from == AST__LGSOR ) { - TRANSFORM_2( "LGF2HL", ra, dec ) - - } else if( from == AST__GLSOR ) { - TRANSFORM_2( "GLF2HL", ra, dec ) - - } else if( from == AST__SCSOR ) { - TRANSFORM_3( "USF2HL", ConvertSourceVel( this, AST__HLSOR, AST__VREL, status ), - ra, dec ) - } - -/* Now go from heliocentric to the "to" frame. */ - to = astGetStdOfRest( that ); - ra = astGetRefRA( that ); - dec = astGetRefDec( that ); - lon = astGetObsLon( that ); - lat = astGetObsLat( that ); - alt = astGetObsAlt( that ); - epoch = astGetEpoch( that ); - VerifyAttrs( that, vmess, "RefRA RefDec", "astMatch", status ); - - if( to == AST__TPSOR ) { - VerifyAttrs( that, vmess, "ObsLon ObsLat ObsAlt Epoch", "astMatch", status ); - TRANSFORM_6( "HLF2TP", lon, lat, alt, epoch, ra, dec ) - - } else if( to == AST__GESOR ) { - VerifyAttrs( that, vmess, "Epoch", "astMatch", status ); - TRANSFORM_3( "HLF2GE", epoch, ra, dec ) - - } else if( to == AST__BYSOR ) { - VerifyAttrs( that, vmess, "Epoch", "astMatch", status ); - TRANSFORM_3( "HLF2BY", epoch, ra, dec ) - - } else if( to == AST__LKSOR ) { - TRANSFORM_2( "HLF2LK", ra, dec ) - - } else if( to == AST__LDSOR ) { - TRANSFORM_2( "HLF2LD", ra, dec ) - - } else if( to == AST__LGSOR ) { - TRANSFORM_2( "HLF2LG", ra, dec ) - - } else if( to == AST__GLSOR ) { - TRANSFORM_2( "HLF2GL", ra, dec ) - - } else if( to == AST__SCSOR ) { - TRANSFORM_3( "HLF2US", ConvertSourceVel( that, AST__HLSOR, AST__VREL, status ), - ra, dec ) - } - } - -/* Return the result. */ - return result; - -/* Undefine macros local to this function. */ -#undef MAX_ARGS -#undef TRANSFORM_2 -#undef TRANSFORM_3 -#undef TRANSFORM_6 -} - -static const char *SpecMapUnit( AstSystemType system, const char *method, - const char *class, int *status ){ -/* -* Name: -* SpecMapUnit - -* Purpose: -* Return the default units for a spectral coordinate system type used -* by the SpecMap class. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *SpecMapUnit( AstSystemType system, const char *method, -* const char *class, int *status ) - -* Class Membership: -* SpecFrame member function. - -* Description: -* This function returns a textual representation of the -* units used by the SpecMap class for the specified spectral -* coordinate system. In general, the SpecMap class uses SI units -* (m/s, Hz, m, etc), but this class (SpecFrame) has default units -* more appropriate to astronomers (km/s, GHz, Angstroms, etc). - -* Parameters: -* system -* The spectral coordinate system. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A string describing the default units. This string follows the -* units syntax described in FITS WCS paper I "Representations of world -* coordinates in FITS" (Greisen & Calabretta). - -* Notes: -* - A NULL pointer is returned if this function is invoked with -* the global error status set or if it should fail for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Value to return */ - -/* Initialize */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get an identifier for the default units. */ - if( system == AST__FREQ ) { - result = "Hz"; - } else if( system == AST__ENERGY ) { - result = "J"; - } else if( system == AST__WAVENUM ) { - result = "1/m"; - } else if( system == AST__WAVELEN ) { - result = "m"; - } else if( system == AST__AIRWAVE ) { - result = "m"; - } else if( system == AST__VRADIO ) { - result = "m/s"; - } else if( system == AST__VOPTICAL ) { - result = "m/s"; - } else if( system == AST__REDSHIFT ) { - result = ""; - } else if( system == AST__BETA ) { - result = ""; - } else if( system == AST__VREL ) { - result = "m/s"; - -/* Report an error if the coordinate system was not recognised. */ - } else { - astError( AST__SCSIN, "%s(%s): Corrupt %s contains illegal System " - "identification code (%d).", status, method, class, class, - (int) system ); - } - -/* Return the result. */ - return result; -} - -static AstStdOfRestType StdOfRestCode( const char *sor, int *status ) { -/* -* Name: -* StdOfRestCode - -* Purpose: -* Convert a string into a standard of rest type code. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* AstStdOfRestType StdOfRestCode( const char *sor ) - -* Class Membership: -* SpecFrame member function. - -* Description: -* This function converts a string used for the external description of -* a standard of rest into a SpecFrame standard of rest type code -* (StdOfRest attribute value). It is the inverse of the -* StdOfRestString function. - -* Parameters: -* sor -* Pointer to a constant null-terminated string containing the -* external description of the standard of rest. - -* Returned Value: -* The StdOfRest type code. - -* Notes: -* - A value of AST__BADSOR is returned if the standard of rest -* description was not recognised. This does not produce an error. -* - A value of AST__BADSOR is also returned if this function -* is invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - AstStdOfRestType result; /* Result value to return */ - -/* Initialise. */ - result = AST__BADSOR; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "sor" string against each possibility and assign the - result. */ - if ( astChrMatch( "TOPO", sor ) || astChrMatch( "TOPOCENT", sor ) || astChrMatch( "TOPOCENTRIC", sor ) ) { - result = AST__TPSOR; - - } else if ( astChrMatch( "GEO", sor ) || astChrMatch( "GEOCENTR", sor ) || astChrMatch( "GEOCENTRIC", sor ) ) { - result = AST__GESOR; - - } else if ( astChrMatch( "BARY", sor ) || astChrMatch( "BARYCENT", sor ) || astChrMatch( "BARYCENTRIC", sor ) ) { - result = AST__BYSOR; - - } else if ( astChrMatch( "HELIO", sor ) || astChrMatch( "HELIOCEN", sor ) || astChrMatch( "HELIOCENTRIC", sor ) ) { - result = AST__HLSOR; - - } else if ( astChrMatch( "LSRK", sor ) || astChrMatch( "LSR", sor ) ) { - result = AST__LKSOR; - - } else if ( astChrMatch( "LSRD", sor ) ) { - result = AST__LDSOR; - - } else if ( astChrMatch( "GAL", sor ) || astChrMatch( "GALACTOC", sor ) || astChrMatch( "GALACTIC", sor ) ) { - result = AST__GLSOR; - - } else if ( astChrMatch( "LG", sor ) || astChrMatch( "LOCALGRP", sor ) || - astChrMatch( "LOCAL_GROUP", sor ) || astChrMatch( "LOCAL-GROUP", sor ) ) { - result = AST__LGSOR; - - } else if ( astChrMatch( "SOURCE", sor ) || astChrMatch( "SRC", sor ) ) { - result = AST__SCSOR; - - } - -/* Return the result. */ - return result; -} - -static const char *StdOfRestString( AstStdOfRestType sor, int *status ) { -/* -* Name: -* StdOfRestString - -* Purpose: -* Convert a standard of rest type code into a string. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *StdOfRestString( AstStdOfRestType sor, int *status ) - -* Class Membership: -* SpecFrame member function. - -* Description: -* This function converts a SpecFrame standard of rest type code -* (StdOfRest attribute value) into a string suitable for use as an -* external representation of the standard of rest type. - -* Parameters: -* sor -* The standard of rest 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 standard of rest -* 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 "sor" 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 standard of rest). */ - switch ( sor ) { - - case AST__TPSOR: - result = "Topocentric"; - break; - - case AST__GESOR: - result = "Geocentric"; - break; - - case AST__BYSOR: - result = "Barycentric"; - break; - - case AST__HLSOR: - result = "Heliocentric"; - break; - - case AST__LDSOR: - result = "LSRD"; - break; - - case AST__LKSOR: - result = "LSRK"; - break; - - case AST__LGSOR: - result = "Local_group"; - break; - - case AST__GLSOR: - result = "Galactic"; - break; - - case AST__SCSOR: - result = "Source"; - 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 SpecFrame and convert to the new coordinate -* system. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.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: -* SpecFrame 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" SpecFrame 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 SpecFrame, 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 SpecFrame. 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 -* SpecFrame 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 -* SpecFrame object. This results in another object of the same class -* only if the single SpecFrame axis is selected exactly once. -* Otherwise, the result is a Frame class object which inherits the -* SpecFrame's axis information (if appropriate) but none of the other -* properties of a SpecFrame. -* - In the event that a SpecFrame 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: */ - AstSpecFrame *target; /* Pointer to the SpecFrame structure */ - AstSpecFrame *temp; /* Pointer to copy of target SpecFrame */ - AstSpecFrame *align_frm; /* Frame in which to align the SpecFrames */ - int match; /* Coordinate conversion is possible? */ - int report; /* Report errors if SpecFrames 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 SpecFrame structure. */ - target = (AstSpecFrame *) target_frame; - -/* Result is a SpecFrame. */ -/* -------------------------- */ -/* Check if the result Frame is to have one axis obtained by selecting - the single target SpecFrame axis. If so, the result will also be - a SpecFrame. */ - 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 MakeSpecMapping should not report - errors if no Mapping can be created. */ - report = 0; - -/* If required, overlay the template attributes on to the result SpecFrame. - Also get the system and standard of rest in which to align the two - SpecFrames. These are the values from the template (if there is a - template). */ - if ( template ) { - astOverlay( template, template_axes, *result ); - if( astIsASpecFrame( template ) ) { - align_frm = astCopy( template ); - -/* Since we now know that both the template and target are SpecFrames, it - should usually be possible to convert betwen them. If conversion is - *not* possible (fpr instance if no rest frequency is availalbe, etc) - then the user will probably be interested in knowing the reason why - conversion is not possible. Therefore, indicate that MakeSpecMapping - should report errors if no Mapping can be created. */ - report = 1; - - } else { - align_frm = astCopy( target ); - } - -/* If no template was supplied, align in the System and StdOfRest of the - target. */ - } else { - VerifyAttrs( target, "convert between different spectral systems", - "StdOfRest", "astMatch", status ); - align_frm = astCopy( target ); - } - -/* The MakeSpecMapping function uses the System and StdOfRest attributes to - define the alignment frame. But the AlignSystem and AlignStdOfRest - attributes should be used for this purpose. Therefore, copy the values - of the AlignSystem and AlignStdOfRest attributes to the System and - StdOfRest attribute. */ - astSetSystem( align_frm, astGetAlignSystem( align_frm ) ); - astSetStdOfRest( align_frm, astGetAlignStdOfRest( align_frm ) ); - -/* Generate a Mapping that takes account of changes in the sky coordinate - system (equinox, epoch, etc.) between the target SpecFrame and the result - SpecFrame. If this Mapping can be generated, set "match" to indicate that - coordinate conversion is possible. If the template is a specframe, - report errors if a match is not possible. */ - match = ( MakeSpecMapping( target, (AstSpecFrame *) *result, - align_frm, report, map, status ) != 0 ); - -/* Free resources. */ - align_frm = astAnnul( align_frm ); - -/* Result is not a SpecFrame. */ -/* ------------------------------ */ -/* 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 SpecFrame, default attribute values may differ - if the methods for obtaining them were over-ridden by the SpecFrame - 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 SpecFrame. 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 - SpecFrame class. */ - SET(Domain) - SET(Title) - -/* Define a macro to test if an attribute is set for axis zero (the only - axis of a SpecFrame). 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 SpecFrame 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 SpecFrame. */ - 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 "specframe.h" -* AstSystemType SystemCode( AstFrame *this, const char *system, int *status ) - -* Class Membership: -* SpecFrame 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 SpecFrame -* coordinate system type code (System attribute value). It is the -* inverse of the astSystemString function. - -* Parameters: -* this -* The Frame. -* system -* Pointer to a constant null-terminated string containing the -* external description of the sky coordinate system. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The System type code. - -* Notes: -* - A value of AST__BADSYSTEM is returned if the sky coordinate -* system description was not recognised. This does not produce an -* error. -* - A value of AST__BADSYSTEM is also returned if this function -* is invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - AstSystemType result; /* Result value to return */ - -/* Initialise. */ - result = AST__BADSYSTEM; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" string against each possibility and assign the - result. */ - if ( astChrMatch( "FREQ", system ) ) { - result = AST__FREQ; - - } else if ( astChrMatch( "ENER", system ) || astChrMatch( "ENERGY", system ) ) { - result = AST__ENERGY; - - } else if ( astChrMatch( "WAVN", system ) || astChrMatch( "WAVENUM", system ) ) { - result = AST__WAVENUM; - - } else if ( astChrMatch( "WAVE", system ) || astChrMatch( "WAVELEN", system ) ) { - result = AST__WAVELEN; - - } else if ( astChrMatch( "AWAV", system ) || astChrMatch( "AIRWAVE", system ) ) { - result = AST__AIRWAVE; - - } else if ( astChrMatch( "VRAD", system ) || astChrMatch( "VRADIO", system ) ) { - result = AST__VRADIO; - - } else if ( astChrMatch( "VOPT", system ) || astChrMatch( "VOPTICAL", system ) ) { - result = AST__VOPTICAL; - - } else if ( astChrMatch( "ZOPT", system ) || astChrMatch( "REDSHIFT", system ) ) { - result = AST__REDSHIFT; - - } else if ( astChrMatch( "BETA", system ) ) { - result = AST__BETA; - - } else if ( astChrMatch( "VELO", system ) || astChrMatch( "VREL", system ) ) { - result = AST__VREL; - - } - -/* Return the result. */ - return result; -} - -static const char *SystemLabel( AstSystemType system, int *status ) { -/* -* Name: -* SystemLabel - -* Purpose: -* Return a label for a coordinate system type code. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *SystemLabel( AstSystemType system, int *status ) - -* Class Membership: -* SpecFrame member function. - -* Description: -* This function converts a SpecFrame coordinate system type code -* (System attribute value) into a descriptive string for human readers. - -* Parameters: -* system -* The coordinate system type code. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Pointer to a constant null-terminated string containing the -* textual equivalent of the type code supplied. - -* Notes: -* - A NULL pointer value is returned if the sky coordinate system -* code was not recognised. This does not produce an error. -* - A NULL pointer value is also returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" value against each possibility and convert to a - string pointer. */ - switch ( system ) { - - case AST__FREQ: - result = "frequency"; - break; - - case AST__ENERGY: - result = "energy"; - break; - - case AST__WAVENUM: - result = "wave-number"; - break; - - case AST__WAVELEN: - result = "wavelength"; - break; - - case AST__AIRWAVE: - result = "wavelength in air"; - break; - - case AST__VRADIO: - result = "radio velocity"; - break; - - case AST__VOPTICAL: - result = "optical velocity"; - break; - - case AST__REDSHIFT: - result = "redshift"; - break; - - case AST__BETA: - result = "beta factor"; - break; - - case AST__VREL: - result = "apparent radial velocity"; - break; - } - -/* Return the result pointer. */ - return result; -} - -static const char *SystemString( AstFrame *this, AstSystemType system, int *status ) { -/* -* Name: -* SystemString - -* Purpose: -* Convert a coordinate system type code into a string. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* const char *SystemString( AstFrame *this, AstSystemType system, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astSystemString method -* inherited from the Frame class). - -* Description: -* This function converts a SpecFrame 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 sky coordinate system -* code was not recognised. This does not produce an error. -* - A NULL pointer value is also returned if this function is -* invoked with the global error status set or if it should fail -* for any reason. -*/ - -/* Local Variables: */ - const char *result; /* Pointer value to return */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Match the "system" value against each possibility and convert to a - string pointer. (Where possible, return the same string as would be - used in the FITS WCS representation of the coordinate system). */ - switch ( system ) { - - case AST__FREQ: - result = "FREQ"; - break; - - case AST__ENERGY: - result = "ENER"; - break; - - case AST__WAVENUM: - result = "WAVN"; - break; - - case AST__WAVELEN: - result = "WAVE"; - break; - - case AST__AIRWAVE: - result = "AWAV"; - break; - - case AST__VRADIO: - result = "VRAD"; - break; - - case AST__VOPTICAL: - result = "VOPT"; - break; - - case AST__REDSHIFT: - result = "ZOPT"; - break; - - case AST__BETA: - result = "BETA"; - break; - - case AST__VREL: - result = "VELO"; - break; - } - -/* Return the result pointer. */ - return result; -} - -static int TestActiveUnit( AstFrame *this_frame, int *status ) { -/* -* Name: -* TestActiveUnit - -* Purpose: -* Test the ActiveUnit flag for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* int TestActiveUnit( AstFrame *this_frame, int *status ) - -* Class Membership: -* SpecFrame member function (over-rides the astTestActiveUnit protected -* method inherited from the Frame class). - -* Description: -* This function test the value of the ActiveUnit flag for a SpecFrame, -* which is always "unset". - -* Parameters: -* this -* Pointer to the SpecFrame. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The result of the test (0). - -*/ - return 0; -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* SpecFrame 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 SpecFrame's attributes. - -* Parameters: -* this -* Pointer to the SpecFrame. -* 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: */ - AstSpecFrame *this; /* Pointer to the SpecFrame structure */ - char *new_attrib; /* Pointer value to new attribute name */ - int len; /* Length of attrib string */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Check the attribute name and test the appropriate attribute. */ - -/* First look for axis attributes defined by the Frame class. Since a - SpecFrame has only 1 axis, we allow these attributes to be specified - without a trailing "(axis)" string. */ - if ( !strcmp( attrib, "direction" ) || - !strcmp( attrib, "bottom" ) || - !strcmp( attrib, "top" ) || - !strcmp( attrib, "format" ) || - !strcmp( attrib, "label" ) || - !strcmp( attrib, "symbol" ) || - !strcmp( attrib, "unit" ) ) { - -/* Create a new attribute name from the original by appending the string - "(1)" and then use the parent TestAttrib method. */ - new_attrib = astMalloc( len + 4 ); - if( new_attrib ) { - memcpy( new_attrib, attrib, len ); - memcpy( new_attrib + len, "(1)", 4 ); - result = (*parent_testattrib)( this_object, new_attrib, status ); - new_attrib = astFree( new_attrib ); - } - -/* AlignStdOfRest. */ -/* --------------- */ - } else if ( !strcmp( attrib, "alignstdofrest" ) ) { - result = astTestAlignStdOfRest( this ); - -/* GeoLat. */ -/* ------- */ -/* Retained for backward compatibility with older versions of AST in which - SpecFrame had GeoLon/Lat attributes (now ObsLon/Lat are used instead). */ - } else if ( !strcmp( attrib, "geolat" ) ) { - result = astTestAttrib( this, "obslat" ); - -/* GeoLon. */ -/* ------- */ - } else if ( !strcmp( attrib, "geolon" ) ) { - result = astTestAttrib( this, "obslon" ); - -/* RefDec. */ -/* ------- */ - } else if ( !strcmp( attrib, "refdec" ) ) { - result = astTestRefDec( this ); - -/* RefRA. */ -/* ------ */ - } else if ( !strcmp( attrib, "refra" ) ) { - result = astTestRefRA( this ); - -/* RestFreq. */ -/* --------- */ - } else if ( !strcmp( attrib, "restfreq" ) ) { - result = astTestRestFreq( this ); - -/* SourceVel. */ -/* ---------- */ - } else if ( !strcmp( attrib, "sourcevel" ) ) { - result = astTestSourceVel( this ); - -/* SourceVRF */ -/* --------- */ - } else if ( !strcmp( attrib, "sourcevrf" ) ) { - result = astTestSourceVRF( this ); - -/* SourceSys */ -/* --------- */ - } else if ( !strcmp( attrib, "sourcesys" ) ) { - result = astTestSourceSys( this ); - -/* StdOfRest. */ -/* ---------- */ - } else if ( !strcmp( attrib, "stdofrest" ) ) { - result = astTestStdOfRest( this ); - -/* SpecOrigin. */ -/* --------- */ - } else if ( !strcmp( attrib, "specorigin" ) ) { - result = astTestSpecOrigin( this ); - -/* AlignSpecOffset */ -/* --------------- */ - } else if ( !strcmp( attrib, "alignspecoffset" ) ) { - result = astTestAlignSpecOffset( this ); - -/* If the attribute is not recognised, pass it on to the parent method - for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static double ToUnits( AstSpecFrame *this, const char *oldunit, double oldval, - const char *method, int *status ){ -/* -* -* Name: -* ToUnits - -* Purpose: -* Convert a supplied spectral value to the default units of the supplied -* SpecFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "timeframe.h" -* double ToUnits( AstSpecFrame *this, const char *oldunit, double oldval, -* const char *method, int *status ) - -* Class Membership: -* SpecFrame member function - -* Description: -* This function converts the supplied value from the supplied units to -* the default units associated with the supplied SpecFrame's System. - -* Parameters: -* this -* Pointer to the SpecFrame. -* oldunit -* The units in which "oldval" is supplied. -* oldval -* The value to be converted. -* method -* Pointer to a string holding the name of the method to be -* included in any error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The converted value. - -*/ - -/* Local Variables: */ - AstMapping *map; - const char *defunit; - double result; - -/* Initialise. */ - result = AST__BAD; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get default units associated with the System attribute of the supplied - SpecFrame, and find a Mapping from the old units to the default. */ - defunit = DefUnit( astGetSystem( this ), method, "SpecFrame", status ); - map = astUnitMapper( oldunit, defunit, NULL, NULL ); - if( map ) { - -/* Use the Mapping to convert the supplied value. */ - astTran1( map, 1, &oldval, 1, &result ); - -/* Free resources. */ - map = astAnnul( map ); - -/* Report an error if no conversion is possible. */ - } else if( astOK ){ - astError( AST__BADUN, "%s(%s): Cannot convert the supplied attribute " - "value from units of %s to %s.", status, method, astGetClass( this ), - oldunit, defunit ); - } - -/* Return the result */ - return result; -} - - -static int ValidateSystem( AstFrame *this, AstSystemType system, const char *method, int *status ) { -/* -* -* Name: -* ValidateSystem - -* Purpose: -* Validate a value for a Frame's System attribute. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "specframe.h" -* int ValidateSystem( AstFrame *this, AstSystemType system, -* const char *method, int *status ) - -* Class Membership: -* SpecFrame 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; -} - -static void VerifyAttrs( AstSpecFrame *this, const char *purp, - const char *attrs, const char *method, int *status ) { -/* -* Name: -* VerifyAttrs - -* Purpose: -* Verify that usable attribute values are available. - -* Type: -* Private function. - -* Synopsis: -* #include "specframe.h" -* void VerifyAttrs( AstSpecFrame *this, const char *purp, -* const char *attrs, const char *method, int *status ) - -* Class Membership: -* SpecFrame member function - -* Description: -* This function tests each attribute listed in "attrs". It returns -* without action if 1) an explicit value has been set for each attribute -* or 2) the UseDefs attribute of the supplied SpecFrame is non-zero. -* -* If UseDefs is zero (indicating that default values should not be -* used for attributes), and any of the named attributes does not have -* an explicitly set value, then an error is reported. - -* Parameters: -* this -* Pointer to the SpecFrame. -* purp -* Pointer to a text string containing a message which will be -* included in any error report. This shouldindicate the purpose -* for which the attribute value is required. -* attrs -* A string holding a space separated list of attribute names. -* method -* A string holding the name of the calling method for use in error -* messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - const char *a; - const char *desc; - const char *p; - int len; - int set; - int state; - -/* Check inherited status */ - if( !astOK ) return; - -/* If the SpecFrame has a non-zero value for its UseDefs attribute, then - all attributes are assumed to have usable values, since the defaults - will be used if no explicit value has been set. So we only need to do - any checks if UseDefs is zero. */ - if( !astGetUseDefs( this ) ) { - -/* Stop compiler warnings about uninitialised variables */ - a = NULL; - desc = NULL; - len = 0; - set = 0; - -/* Loop round the "attrs" string identifying the start and length of each - non-blank word in the string. */ - state = 0; - p = attrs; - while( 1 ) { - if( state == 0 ) { - if( !isspace( *p ) ) { - a = p; - len = 1; - state = 1; - } - } else { - if( isspace( *p ) || !*p ) { - -/* The end of a word has just been reached. Compare it to each known - attribute value. Get a flag indicating if the attribute has a set - value, and a string describing the attribute.*/ - if( len > 0 ) { - - if( !strncmp( "ObsLat", a, len ) ) { - set = astTestObsLat( this ); - desc = "observer's latitude"; - - } else if( !strncmp( "ObsLon", a, len ) ) { - set = astTestObsLon( this ); - desc = "observer's longitude"; - - } else if( !strncmp( "ObsAlt", a, len ) ) { - set = astTestObsAlt( this ); - desc = "observer's altitude"; - - } else if( !strncmp( "RefRA", a, len ) ) { - set = astTestRefRA( this ); - desc = "source RA"; - - } else if( !strncmp( "RefDec", a, len ) ) { - set = astTestRefDec( this ); - desc = "source Dec"; - - } else if( !strncmp( "RestFreq", a, len ) ) { - set = astTestRestFreq( this ); - desc = "rest frequency"; - - } else if( !strncmp( "SourceVel", a, len ) ) { - set = astTestSourceVel( this ); - desc = "source velocity"; - - } else if( !strncmp( "StdOfRest", a, len ) ) { - set = astTestStdOfRest( this ); - desc = "spectral standard of rest"; - - } else if( !strncmp( "Epoch", a, len ) ) { - set = astTestEpoch( this ); - desc = "epoch of observation"; - - } else { - astError( AST__INTER, "VerifyAttrs(SpecFrame): " - "Unknown attribute name \"%.*s\" supplied (AST " - "internal programming error).", status, len, a ); - } - -/* If the attribute does not have a set value, report an error. */ - if( !set && astOK ) { - astError( AST__NOVAL, "%s(%s): Cannot %s.", status, method, - astGetClass( this ), purp ); - astError( AST__NOVAL, "No value has been set for " - "the AST \"%.*s\" attribute (%s).", status, len, a, - desc ); - } - -/* Continue the word search algorithm. */ - } - len = 0; - state = 0; - } else { - len++; - } - } - if( !*(p++) ) break; - } - } -} - -/* Functions which access class attributes. */ -/* ---------------------------------------- */ -/* -*att++ -* Name: -* AlignSpecOffset - -* Purpose: -* Align SpecFrames using the offset coordinate system? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute is a boolean value which controls how a SpecFrame -* behaves when it is used (by -c astFindFrame or astConvert) as a template to match another (target) -f AST_FINDFRAME or AST_CONVERT) as a template to match another (target) -* SpecFrame. It determines whether alignment occurs between the offset -* values defined by the current value of the SpecOffset attribute, or -* between the corresponding absolute spectral values. -* -* The default value of zero results in the two SpecFrames being aligned -* so that a given absolute spectral value in one is mapped to the same -* absolute value in the other. A non-zero value results in the SpecFrames -* being aligned so that a given offset value in one is mapped to the same -* offset value in the other. - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. -*att-- -*/ -astMAKE_CLEAR(SpecFrame,AlignSpecOffset,alignspecoffset,-INT_MAX) -astMAKE_GET(SpecFrame,AlignSpecOffset,int,0,( ( this->alignspecoffset != -INT_MAX ) ? - this->alignspecoffset : 0 )) -astMAKE_SET(SpecFrame,AlignSpecOffset,int,alignspecoffset,( value != 0 )) -astMAKE_TEST(SpecFrame,AlignSpecOffset,( this->alignspecoffset != -INT_MAX )) - - - -/* -*att++ -* Name: -* AlignStdOfRest - -* Purpose: -* Standard of rest to use when aligning SpecFrames. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute controls how a SpecFrame behaves when it is used (by -c astFindFrame or astConvert) as a template to match another (target) -f AST_FINDFRAME or AST_CONVERT) as a template to match another (target) -* SpecFrame. It identifies the standard of rest in which alignment is -* to occur. See the StdOfRest attribute for a desription of the values -* which may be assigned to this attribute. The default AlignStdOfRest -* value is "Helio" (heliographic). -* -c When astFindFrame or astConvert is used on two SpecFrames (potentially -f When AST_FindFrame or AST_CONVERT is used on two SpecFrames (potentially -* describing different spectral coordinate systems), it returns a Mapping -* which can be used to transform a position in one SpecFrame into the -* corresponding position in the other. The Mapping is made up of the -* following steps in the indicated order: -* -* - Map values from the system used by the target (wavelength, -* apparent radial velocity, etc) to the system specified by the -* AlignSystem attribute, using the target's rest frequency if necessary. -* -* - Map these values from the target's standard of rest to the standard of -* rest specified by the AlignStdOfRest attribute, using the Epoch, ObsLat, -* ObsLon, ObsAlt, RefDec and RefRA attributes of the target to define the -* two standards of rest. -* -* - Map these values from the standard of rest specified by the -* AlignStdOfRest attribute, to the template's standard of rest, using the -* Epoch, ObsLat, ObsLon, ObsAlt, RefDec and RefRA attributes of the -* template to define the two standards of rest. -* -* - Map these values from the system specified by the AlignSystem -* attribute, to the system used by the template, using the template's -* rest frequency if necessary. - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -*att-- -*/ -/* The AlignStdOfRest value has a value of AST__BADSOR when not set yielding - a default of AST__HLSOR. */ -astMAKE_TEST(SpecFrame,AlignStdOfRest,( this->alignstdofrest != AST__BADSOR )) -astMAKE_CLEAR(SpecFrame,AlignStdOfRest,alignstdofrest,AST__BADSOR) -astMAKE_GET(SpecFrame,AlignStdOfRest,AstStdOfRestType,AST__BADSOR,( - ( this->alignstdofrest == AST__BADSOR ) ? AST__HLSOR : this->alignstdofrest ) ) - -/* Validate the AlignStdOfRest value being set and report an error if necessary. */ -astMAKE_SET(SpecFrame,AlignStdOfRest,AstStdOfRestType,alignstdofrest,( - ( ( value >= FIRST_SOR ) && ( value <= LAST_SOR ) ) ? - value : - ( astError( AST__ATTIN, "%s(%s): Bad value (%d) " - "given for AlignStdOfRest attribute.", status, - "astSetAlignStdOfRest", astGetClass( this ), (int) value ), - -/* Leave the value unchanged on error. */ - this->alignstdofrest ) ) ) - -/* -*att++ -* Name: -* RefDec - -* Purpose: -* The declination of the reference point - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute specifies the FK5 J2000.0 declination of a reference -* point on the sky. See the description of attribute RefRA for details. -* The default RefDec is "0:0:0". - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -*att-- -*/ -/* The reference declination (FK5 J2000, radians). Clear the RefDec value by - setting it to AST__BAD, which results in a default value of zero. Any - value is acceptable. */ -astMAKE_CLEAR(SpecFrame,RefDec,refdec,AST__BAD) -astMAKE_GET(SpecFrame,RefDec,double,0.0,((this->refdec!=AST__BAD)?this->refdec:0.0)) -astMAKE_SET(SpecFrame,RefDec,double,refdec,value) -astMAKE_TEST(SpecFrame,RefDec,( this->refdec != AST__BAD )) - -/* -*att++ -* Name: -* RefRA - -* Purpose: -* The right ascension of the reference point - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute, together with the RefDec attribute, specifies the FK5 -* J2000.0 coordinates of a reference point on the sky. For 1-dimensional -* spectra, this should normally be the position of the source. For -* spectral data with spatial coverage (spectral cubes, etc), this should -* be close to centre of the spatial coverage. It is used to define the -* correction for Doppler shift to be applied when using the -c astFindFrame or astConvert -f AST_FINDFRAME or AST_CONVERT -* method to convert between different standards of rest. -* -* The SpecFrame class assumes this velocity correction is spatially -* invariant. If a single SpecFrame is used (for instance, as a -* component of a CmpFrame) to describe spectral values at different -* points on the sky, then it is assumes that the doppler shift at any -* spatial position is the same as at the reference position. The -* maximum velocity error introduced by this assumption is of the order -* of V*SIN(FOV), where FOV is the angular field of view, and V is the -* relative velocity of the two standards of rest. As an example, when -* correcting from the observers rest frame (i.e. the topocentric rest -* frame) to the kinematic local standard of rest the maximum value of V -* is about 20 km/s, so for 5 arc-minute field of view the maximum velocity -* error introduced by the correction will be about 0.03 km/s. As another -* example, the maximum error when correcting from the observers rest frame -* to the local group is about 5 km/s over a 1 degree field of view. -* -* The RefRA and RefDec attributes are stored internally in radians, but -* are converted to and from a string for access. The format "hh:mm:ss.ss" -* is used for RefRA, and "dd:mm:ss.s" is used for RefDec. The methods -c astSetRefPos and astGetRefPos may be used to access the values of -f AST_SETREFPOS and AST_GETREFPOS may be used to access the value of -* these attributes directly as unformatted values in radians. -* -* The default for RefRA is "0:0:0". - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -*att-- -*/ -/* The reference right ascension (FK5 J2000, radians). Clear the RefRA value - by setting it to AST__BAD, which gives a default value of 0.0. Any - value is acceptable. */ -astMAKE_CLEAR(SpecFrame,RefRA,refra,AST__BAD) -astMAKE_GET(SpecFrame,RefRA,double,0.0,((this->refra!=AST__BAD)?this->refra:0.0)) -astMAKE_SET(SpecFrame,RefRA,double,refra,value) -astMAKE_TEST(SpecFrame,RefRA,( this->refra != AST__BAD )) - - -/* -*att++ -* Name: -* RestFreq - -* Purpose: -* The rest frequency. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute specifies the frequency corresponding to zero -* velocity. It is used when converting between between velocity-based -* coordinate systems and and other coordinate systems (such as frequency, -* wavelength, energy, etc). The default value is 1.0E5 GHz. -* -* When setting a new value for this attribute, the new value can be -* supplied either directly as a frequency, or indirectly as a wavelength -* or energy, in which case the supplied value is converted to a frequency -* before being stored. The nature of the supplied value is indicated by -* appending text to the end of the numerical value indicating the units in -* which the value is supplied. If the units are not specified, then the -* supplied value is assumed to be a frequency in units of GHz. If the -* supplied unit is a unit of frequency, the supplied value is assumed to -* be a frequency in the given units. If the supplied unit is a unit of -* length, the supplied value is assumed to be a (vacuum) wavelength. If -* the supplied unit is a unit of energy, the supplied value is assumed to -* be an energy. For instance, the following strings all result in -* a rest frequency of around 1.4E14 Hz being used: "1.4E5", "1.4E14 Hz", -* "1.4E14 s**-1", "1.4E5 GHz", "2.14E-6 m", "21400 Angstrom", "9.28E-20 J", -* "9.28E-13 erg", "0.58 eV", etc. -* -* When getting the value of this attribute, the returned value is -* always a frequency in units of GHz. - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -*att-- -*/ -/* The rest frequency (Hz). Clear the RestFreq value by setting it to AST__BAD, - which gives 1.0E14 as the default value. Any value is acceptable. */ -astMAKE_CLEAR(SpecFrame,RestFreq,restfreq,AST__BAD) -astMAKE_GET(SpecFrame,RestFreq,double,1.0E14,((this->restfreq!=AST__BAD)?this->restfreq:1.0E14)) -astMAKE_SET(SpecFrame,RestFreq,double,restfreq,value) -astMAKE_TEST(SpecFrame,RestFreq,( this->restfreq != AST__BAD )) - -/* -*att++ -* Name: -* SourceVel - -* Purpose: -* The source velocity. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute (together with SourceSys, SourceVRF, RefRA and RefDec) -* defines the "Source" standard of rest (see attribute StdOfRest). This is -* a rest frame which is moving towards the position given by RefRA and -* RefDec at a velocity given by SourceVel. A positive value means -* the source is moving away from the observer. When a new value is -* assigned to this attribute, the supplied value is assumed to refer -* to the spectral system specified by the SourceSys attribute. For -* instance, the SourceVel value may be supplied as a radio velocity, a -* redshift, a beta factor, etc. Similarly, when the current value of -* the SourceVel attribute is obtained, the returned value will refer -* to the spectral system specified by the SourceSys value. If the -* SourceSys value is changed, any value previously stored for the SourceVel -* attribute will be changed automatically from the old spectral system -* to the new spectral system. -* -* When setting a value for SourceVel, the value should be supplied in the -* rest frame specified by the SourceVRF attribute. Likewise, when getting -* the value of SourceVel, it will be returned in the rest frame specified -* by the SourceVRF attribute. -* -* The default SourceVel value is zero. - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -* Notes: -* - It is important to set an appropriate value for SourceVRF and -* SourceSys before setting a value for SourceVel. If a new value is later -* set for SourceVRF or SourceSys, the value stored for SourceVel will -* simultaneously be changed to the new standard of rest or spectral -* system. - -*att-- -*/ -/* The source velocity (velocities are stored internally in m/s). Clear it - by setting it to AST__BAD, which returns a default value of zero. Any - value is acceptable. */ -astMAKE_CLEAR(SpecFrame,SourceVel,sourcevel,AST__BAD) -astMAKE_SET(SpecFrame,SourceVel,double,sourcevel,value) -astMAKE_TEST(SpecFrame,SourceVel,( this->sourcevel != AST__BAD )) -astMAKE_GET(SpecFrame,SourceVel,double,0.0,((this->sourcevel!=AST__BAD)?this->sourcevel:0.0)) - -/* -*att++ -* Name: -* SourceVRF - -* Purpose: -* Rest frame in which the source velocity is stored. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute identifies the rest frame in which the source -* velocity or redshift is stored (the source velocity or redshift is -* accessed using attribute SourceVel). When setting a new value for the -* SourceVel attribute, the source velocity or redshift should be supplied -* in the rest frame indicated by this attribute. Likewise, when getting -* the value of the SourceVel attribute, the velocity or redshift will be -* returned in this rest frame. -* -* If the value of SourceVRF is changed, the value stored for SourceVel -* will be converted from the old to the new rest frame. -* -* The values which can be supplied are the same as for the StdOfRest -* attribute (except that SourceVRF cannot be set to "Source"). The -* default value is "Helio". - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -*att-- -*/ -/* The SourceVRF value has a value of AST__BADSOR when not set yielding - a default of AST__HLSOR. */ -astMAKE_TEST(SpecFrame,SourceVRF,( this->sourcevrf != AST__BADSOR )) -astMAKE_GET(SpecFrame,SourceVRF,AstStdOfRestType,AST__BADSOR,( - ( this->sourcevrf == AST__BADSOR ) ? AST__HLSOR : this->sourcevrf ) ) - -/* When clearing SourceVRF, convert the SourceVel value to heliocentric - (but only if set)*/ -astMAKE_CLEAR(SpecFrame,SourceVRF,sourcevrf,((astTestSourceVel( this )? - (void)(astSetSourceVel( this, ConvertSourceVel( this, AST__HLSOR, - astGetSourceSys( this ), status ) ),NULL): - NULL),AST__BADSOR)) - -/* Validate the SourceVRF value being set and report an error if necessary. - If OK, convert the stored SourceVel value into the new rest frame (but -only if set)*/ -astMAKE_SET(SpecFrame,SourceVRF,AstStdOfRestType,sourcevrf,( - ( ( value >= FIRST_SOR ) && ( value <= LAST_SOR ) && value != AST__SCSOR ) ? - (astTestSourceVel( this )? - (void)(astSetSourceVel( this,ConvertSourceVel(this,value,astGetSourceSys( this ), status )),NULL): - NULL), value:( astError( AST__ATTIN, "%s(%s): Bad value (%d) " - "given for SourceVRF attribute.", status, - "astSetSourceVRF", astGetClass( this ), (int) value ), - -/* Leave the value unchanged on error. */ - this->sourcevrf ) ) ) - -/* -*att++ -* Name: -* SourceSys - -* Purpose: -* Spectral system in which the source velocity is stored. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute identifies the spectral system in which the -* SourceVel attribute value (the source velocity) is supplied and -* returned. It can be one of the following: -* -* - "VRAD" or "VRADIO": Radio velocity (km/s) -* - "VOPT" or "VOPTICAL": Optical velocity (km/s) -* - "ZOPT" or "REDSHIFT": Redshift (dimensionless) -* - "BETA": Beta factor (dimensionless) -* - "VELO" or "VREL": Apparent radial ("relativistic") velocity (km/s) -* -* When setting a new value for the SourceVel attribute, the source -* velocity should be supplied in the spectral system indicated -* by this attribute. Likewise, when getting the value of the SourceVel -* attribute, the velocity will be returned in this spectral system. -* -* If the value of SourceSys is changed, the value stored for SourceVel -* will be converted from the old to the new spectral systems. -* -* The default value is "VELO" (apparent radial velocity). - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -*att-- -*/ -/* The SourceSys value has a value of AST__BADSYS when not set yielding - a default of AST__VREL. */ -astMAKE_TEST(SpecFrame,SourceSys,( this->sourcesys != AST__BADSYSTEM )) -astMAKE_GET(SpecFrame,SourceSys,AstSystemType,AST__BADSYSTEM,( - ( this->sourcesys == AST__BADSYSTEM ) ? AST__VREL : this->sourcesys ) ) - -/* When clearing SourceSys, convert the SourceVel value to relativistic - velocity (but only if set) */ -astMAKE_CLEAR(SpecFrame,SourceSys,sourcesys,((astTestSourceVel( this )? -(void)(astSetSourceVel( this, ConvertSourceVel( this, astGetSourceVRF( this ), - AST__VREL, status ) ),NULL):NULL),AST__BADSYSTEM)) - -/* Validate the SourceSys value being set and report an error if necessary. - If OK, convert the stored SourceVel value into the new rest frame (but - only if set)*/ -astMAKE_SET(SpecFrame,SourceSys,AstSystemType,sourcesys,( - ( ( value == AST__VREL ) || ( value == AST__BETA ) || - ( value == AST__VRADIO ) || ( value == AST__REDSHIFT ) || - ( value == AST__VOPTICAL ) ) ? - (astTestSourceVel( this )? - (void)(astSetSourceVel( this, ConvertSourceVel( this, astGetSourceVRF( this ), - value, status )),NULL):NULL), - value: - ( astError( AST__ATTIN, "%s(%s): Bad value (%d) " - "given for SourceSys attribute.", status, - "astSetSourceSys", astGetClass( this ), (int) value ), - -/* Leave the value unchanged on error. */ - this->sourcesys ) ) ) - -/* -*att++ -* Name: -* StdOfRest - -* Purpose: -* Standard of rest. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute identifies the standard of rest to which the spectral -* axis values of a SpecFrame refer, and may take any of the values -* listed in the "Standards of Rest" section (below). -* -* The default StdOfRest value is "Helio". - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -* Standards of Rest: -* The SpecFrame class supports the following StdOfRest values (all are -* case-insensitive): -* -* - "Topocentric", "Topocent" or "Topo": The observers rest-frame (assumed -* to be on the surface of the earth). Spectra recorded in this standard of -* rest suffer a Doppler shift which varies over the course of a day -* because of the rotation of the observer around the axis of the earth. -* This standard of rest must be qualified using the ObsLat, ObsLon, -* ObsAlt, Epoch, RefRA and RefDec attributes. -* -* - "Geocentric", "Geocentr" or "Geo": The rest-frame of the earth centre. -* Spectra recorded in this standard of rest suffer a Doppler shift which -* varies over the course of a year because of the rotation of the earth -* around the Sun. This standard of rest must be qualified using the Epoch, -* RefRA and RefDec attributes. -* -* - "Barycentric", "Barycent" or "Bary": The rest-frame of the solar-system -* barycentre. Spectra recorded in this standard of rest suffer a Doppler -* shift which depends both on the velocity of the Sun through the Local -* Standard of Rest, and on the movement of the planets through the solar -* system. This standard of rest must be qualified using the Epoch, RefRA -* and RefDec attributes. -* -* - "Heliocentric", "Heliocen" or "Helio": The rest-frame of the Sun. -* Spectra recorded in this standard of rest suffer a Doppler shift which -* depends on the velocity of the Sun through the Local Standard of Rest. -* This standard of rest must be qualified using the RefRA and RefDec -* attributes. -* -* - "LSRK", "LSR": The rest-frame of the kinematical Local Standard of -* Rest. Spectra recorded in this standard of rest suffer a Doppler shift -* which depends on the velocity of the kinematical Local Standard of Rest -* through the galaxy. This standard of rest must be qualified using the -* RefRA and RefDec attributes. -* -* - "LSRD": The rest-frame of the dynamical Local Standard of Rest. Spectra -* recorded in this standard of rest suffer a Doppler shift which depends -* on the velocity of the dynamical Local Standard of Rest through the -* galaxy. This standard of rest must be qualified using the RefRA and -* RefDec attributes. -* -* - "Galactic", "Galactoc" or "Gal": The rest-frame of the galactic centre. -* Spectra recorded in this standard of rest suffer a Doppler shift which -* depends on the velocity of the galactic centre through the local group. -* This standard of rest must be qualified using the RefRA and RefDec -* attributes. -* -* - "Local_group", "Localgrp" or "LG": The rest-frame of the local group. -* This standard of rest must be qualified using the RefRA and RefDec -* attributes. -* -* - "Source", or "src": The rest-frame of the source. This standard of -* rest must be qualified using the RefRA, RefDec and SourceVel attributes. -* -* Where more than one alternative System value is shown above, the -* first of these will be returned when an enquiry is made. -*att-- -*/ -/* The StdOfRest value has a value of AST__BADSOR when not set yielding - a default of AST__HLSOR. */ -astMAKE_TEST(SpecFrame,StdOfRest,( this->stdofrest != AST__BADSOR )) -astMAKE_GET(SpecFrame,StdOfRest,AstStdOfRestType,AST__BADSOR,( - ( this->stdofrest == AST__BADSOR ) ? AST__HLSOR : this->stdofrest ) ) - -/* -*att++ -* Name: -* SpecOrigin - -* Purpose: -* The zero point for SpecFrame axis values - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This specifies the origin from which all spectral values are measured. -* The default value (zero) results in the SpecFrame describing -* absolute spectral values in the system given by the System attribute -* (e.g. frequency, velocity, etc). If a SpecFrame is to be used to -* describe offset from some origin, the SpecOrigin attribute -* should be set to hold the required origin value. The SpecOrigin value -* stored inside the SpecFrame structure is modified whenever SpecFrame -* attribute values are changed so that it refers to the original spectral -* position. -* -* When setting a new value for this attribute, the supplied value is assumed -* to be in the system, units and standard of rest described by the SpecFrame. -* Likewise, when getting the value of this attribute, the value is returned -* in the system, units and standard of rest described by the SpecFrame. If -* any of these attributes are changed, then any previously stored SpecOrigin -* value will also be changed so that refers to the new system, units or -* standard of rest. - -* Applicability: -* SpecFrame -* All SpecFrames have this attribute. - -*att-- -*/ -/* The spec origin, stored internally in the default units associated - with the current System value. Clear the SpecOrigin value by setting it - to AST__BAD, which gives 0.0 as the default value. Any value is acceptable. */ -astMAKE_CLEAR(SpecFrame,SpecOrigin,specorigin,AST__BAD) -astMAKE_GET(SpecFrame,SpecOrigin,double,0.0,((this->specorigin!=AST__BAD)?this->specorigin:0.0)) -astMAKE_SET(SpecFrame,SpecOrigin,double,specorigin,value) -astMAKE_TEST(SpecFrame,SpecOrigin,( this->specorigin != AST__BAD )) - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for SpecFrame objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for SpecFrame 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: */ - AstSpecFrame *in; /* Pointer to input SpecFrame */ - AstSpecFrame *out; /* Pointer to output SpecFrame */ - char *usedunit; /* Pointer to an element of usedunits array */ - int i; /* Loop count */ - int nused; /* Size of "usedunits" array */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output SpecFrames. */ - in = (AstSpecFrame *) objin; - out = (AstSpecFrame *) objout; - -/* Nullify the pointers stored in the output object since these will - currently be pointing at the input data (since the output is a simple - byte-for-byte copy of the input). Otherwise, the input data could be - freed by accidient if the output object is deleted due to an error - occuring in this function. */ - out->usedunits = NULL; - -/* Store the last used units in the output SpecMap. */ - if( in && in->usedunits ) { - nused = in->nuunits; - out->usedunits = astMalloc( nused*sizeof( char * ) ); - if( out->usedunits ) { - for( i = 0; i < nused; i++ ) { - usedunit = in->usedunits[ i ]; - if( usedunit ) { - out->usedunits[ i ] = astStore( NULL, usedunit, - strlen( usedunit ) + 1 ); - } else { - out->usedunits[ i ] = NULL; - } - } - } - } - -/* If an error has occurred, free the output resources. */ - if( !astOK ) Delete( (AstObject *) out, status ); - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for SpecFrame objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for SpecFrame 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: */ - AstSpecFrame *this; - int i; - -/* Release the memory referred to in the SpecFrame structure. */ - this = (AstSpecFrame *) obj; - if( this && this->usedunits ) { - for( i = 0; i < this->nuunits; i++ ) { - this->usedunits[ i ] = astFree( this->usedunits[ i ] ); - } - this->usedunits = astFree( this->usedunits ); - } -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for SpecFrame 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 SpecFrame class to an output Channel. - -* Parameters: -* this -* Pointer to the SpecFrame whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstSpecFrame *this; /* Pointer to the SpecFrame structure */ - AstStdOfRestType sor; /* StdOfRest attribute value */ - AstSystemType sys; /* Spectral system value */ - char buff[ 20 ]; /* Buffer for item name */ - char comm[ 50 ]; /* Buffer for comment */ - const char *sval; /* Pointer to string value */ - double dval; /* Double value */ - int i; /* Loop count */ - int ival; /* int value */ - int j; /* Loop count */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the SpecFrame structure. */ - this = (AstSpecFrame *) this_object; - -/* Write out values representing the instance variables for the - SpecFrame 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. */ - -/* StdOfRest. */ -/* ---------- */ - set = TestStdOfRest( this, status ); - sor = set ? GetStdOfRest( this, status ) : astGetStdOfRest( this ); - -/* If set, convert explicitly to a string for the external - representation. */ - sval = ""; - if ( set ) { - if ( astOK ) { - sval = StdOfRestString( sor, status ); - -/* Report an error if the StdOfRest value was not recognised. */ - if ( !sval ) { - astError( AST__SCSIN, - "%s(%s): Corrupt %s contains invalid standard of rest " - "identification code (%d).", status, "astWrite", - astGetClass( channel ), astGetClass( this ), (int) sor ); - } - } - -/* If not set, use astGetAttrib which returns a string value using - (possibly over-ridden) methods. */ - } else { - sval = astGetAttrib( this_object, "stdofrest" ); - } - -/* Write out the value. */ - astWriteString( channel, "SoR", set, 1, sval, "Standard of rest" ); - -/* AlignStdOfRest. */ -/* --------------- */ - set = TestAlignStdOfRest( this, status ); - sor = set ? GetAlignStdOfRest( this, status ) : astGetAlignStdOfRest( this ); - -/* If set, convert explicitly to a string for the external representation. */ - if ( set ) { - if ( astOK ) { - sval = StdOfRestString( sor, status ); - -/* Report an error if the StdOfRest value was not recognised. */ - if ( !sval ) { - astError( AST__SCSIN, - "%s(%s): Corrupt %s contains invalid alignment standard " - "of rest identification code (%d).", status, "astWrite", - astGetClass( channel ), astGetClass( this ), (int) sor ); - } - } - -/* If not set, use astGetAttrib which returns a string value using - (possibly over-ridden) methods. */ - } else { - sval = astGetAttrib( this_object, "alignstdofrest" ); - } - -/* Write out the value. */ - astWriteString( channel, "AlSoR", set, 0, sval, "Alignment standard of rest" ); - -/* RefRA. */ -/* ------ */ - set = TestRefRA( this, status ); - dval = set ? GetRefRA( this, status ) : astGetRefRA( this ); - astWriteDouble( channel, "RefRA", set, 0, dval, "Reference RA (rads, FK5 J2000)" ); - -/* RefDec. */ -/* ------- */ - set = TestRefDec( this, status ); - dval = set ? GetRefDec( this, status ) : astGetRefDec( this ); - astWriteDouble( channel, "RefDec", set, 0, dval, "Reference Dec (rads, FK5 J2000)" ); - -/* RestFreq. */ -/* --------- */ - set = TestRestFreq( this, status ); - dval = set ? GetRestFreq( this, status ) : astGetRestFreq( this ); - astWriteDouble( channel, "RstFrq", set, 0, dval, "Rest frequency (Hz)" ); - -/* SourceVel. */ -/* ---------- */ - set = TestSourceVel( this, status ); - dval = set ? GetSourceVel( this, status ) : astGetSourceVel( this ); - astWriteDouble( channel, "SrcVel", set, 0, dval, "Source velocity (m/s)" ); - -/* SourceVRF. */ -/* ---------- */ - set = TestSourceVRF( this, status ); - sor = set ? GetSourceVRF( this, status ) : astGetSourceVRF( this ); - -/* If set, convert explicitly to a string for the external representation. */ - if ( set ) { - if ( astOK ) { - sval = StdOfRestString( sor, status ); - -/* Report an error if the value was not recognised. */ - if ( !sval ) { - astError( AST__SCSIN, - "%s(%s): Corrupt %s contains invalid source velocity " - "rest frame identification code (%d).", status, "astWrite", - astGetClass( channel ), astGetClass( this ), (int) sor ); - } - } - -/* If not set, use astGetAttrib which returns a string value using - (possibly over-ridden) methods. */ - } else { - sval = astGetAttrib( this_object, "sourcevrf" ); - } - -/* Write out the value. */ - astWriteString( channel, "SrcVRF", set, 0, sval, "Source velocity rest frame" ); - -/* SourceSys. */ -/* ---------- */ - set = TestSourceSys( this, status ); - sys = set ? GetSourceSys( this, status ) : astGetSourceSys( this ); - -/* If set, convert explicitly to a string for the external representation. */ - if ( set ) { - if ( astOK ) { - sval = SystemString( (AstFrame *) this, sys, status ); - -/* Report an error if the value was not recognised. */ - if ( !sval ) { - astError( AST__SCSIN, - "%s(%s): Corrupt %s contains invalid source velocity " - "spectral system identification code (%d).", status, "astWrite", - astGetClass( channel ), astGetClass( this ), (int) sys ); - } - } - -/* If not set, use astGetAttrib which returns a string value using - (possibly over-ridden) methods. */ - } else { - sval = astGetAttrib( this_object, "sourcesys" ); - } - -/* Write out the value. */ - astWriteString( channel, "SrcSys", set, 0, sval, "Source velocity spectral system" ); - -/* AlignSpecOffset. */ -/* ---------------- */ - set = TestAlignSpecOffset( this, status ); - ival = set ? GetAlignSpecOffset( this, status ) : astGetAlignSpecOffset( this ); - astWriteInt( channel, "AlSpOf", set, 0, ival, - ival ? "Align in offset coords" : - "Align in system coords" ); - -/* UsedUnits */ -/* --------- */ - if( this->usedunits ) { - for( i = 0; i < this->nuunits; i++ ) { - if( this->usedunits[ i ] ) { - sprintf( buff, "U%s", astSystemString( this, (AstSystemType) i )); - for( j = 2; j < strlen( buff ); j++ ) buff[ j ] = tolower( buff[ j ] ); - sprintf( comm, "Preferred units for %s", SystemLabel( (AstSystemType) i, status ) ); - astWriteString( channel, buff, 1, 0, this->usedunits[ i ], comm ); - } - } - } - -/* SpecOrigin. */ -/* ----------- */ - set = TestSpecOrigin( this, status ); - dval = set ? GetSpecOrigin( this, status ) : astGetSpecOrigin( this ); - if( dval != AST__BAD ) { - astWriteDouble( channel, "SpOrg", set, 0, dval, "Spec offset" ); - } - -} - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsASpecFrame and astCheckSpecFrame functions using the - macros defined for this purpose in the "object.h" header file. */ -astMAKE_ISA(SpecFrame,Frame) -astMAKE_CHECK(SpecFrame) - -AstSpecFrame *astSpecFrame_( const char *options, int *status, ...) { -/* -*+ -* Name: -* astSpecFrame - -* Purpose: -* Create a SpecFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "specframe.h" -* AstSpecFrame *astSpecFrame( const char *options, int *status, ... ) - -* Class Membership: -* SpecFrame constructor. - -* Description: -* This function creates a new SpecFrame and optionally initialises its -* attributes. - -* Parameters: -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new SpecFrame. The syntax used is the same as for the -* astSet method and may include "printf" format specifiers identified -* by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then an -* optional list of arguments may follow it in order to supply values to -* be substituted for these specifiers. The rules for supplying these -* are identical to those for the astSet method (and for the C "printf" -* function). - -* Returned Value: -* A pointer to the new SpecFrame. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- - -* Implementation Notes: -* - This function implements the basic SpecFrame constructor which -* is available via the protected interface to the SpecFrame class. -* A public interface is provided by the astSpecFrameId_ function. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMapping *um; /* Mapping from default to actual units */ - AstSpecFrame *new; /* Pointer to new SpecFrame */ - AstSystemType s; /* System */ - const char *u; /* Units string */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the SpecFrame, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitSpecFrame( NULL, sizeof( AstSpecFrame ), !class_init, - &class_vtab, "SpecFrame" ); - -/* 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 SpecFrame's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* Check the Units are appropriate for the System. */ - u = astGetUnit( new, 0 ); - s = astGetSystem( new ); - um = astUnitMapper( DefUnit( s, "astSpecFrame", "SpecFrame", status ), - u, NULL, NULL ); - if( um ) { - um = astAnnul( um ); - } else { - astError( AST__BADUN, "astSpecFrame: Inappropriate units (%s) " - "specified for a %s axis.", status, u, SystemLabel( s, status ) ); - } - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return a pointer to the new SpecFrame. */ - return new; -} - -AstSpecFrame *astInitSpecFrame_( void *mem, size_t size, int init, - AstSpecFrameVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitSpecFrame - -* Purpose: -* Initialise a SpecFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "specframe.h" -* AstSpecFrame *astInitSpecFrame( void *mem, size_t size, int init, -* AstFrameVtab *vtab, const char *name ) - -* Class Membership: -* SpecFrame initialiser. - -* Description: -* This function is provided for use by class implementations to -* initialise a new SpecFrame object. It allocates memory (if -* necessary) to accommodate the SpecFrame plus any additional data -* associated with the derived class. It then initialises a -* SpecFrame 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 SpecFrame at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the SpecFrame is to be -* created. This must be of sufficient size to accommodate the -* SpecFrame data (sizeof(SpecFrame)) 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 SpecFrame (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 SpecFrame structure, so a valid value must be supplied -* even if not required for allocating memory. -* init -* A logical flag indicating if the SpecFrame'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 SpecFrame. -* 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). - -* Returned Value: -* A pointer to the new SpecFrame. - -* 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: */ - AstSpecFrame *new; /* Pointer to the new SpecFrame */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* If necessary, initialise the virtual function table. */ - if ( init ) astInitSpecFrameVtab( vtab, name ); - -/* Initialise a 1D Frame structure (the parent class) as the first component - within the SpecFrame structure, allocating memory if necessary. */ - new = (AstSpecFrame *) astInitFrame( mem, size, 0, - (AstFrameVtab *) vtab, name, 1 ); - - if ( astOK ) { - -/* Initialise the SpecFrame data. */ -/* ----------------------------- */ -/* Initialise all attributes to their "undefined" values. */ - new->alignstdofrest = AST__BADSOR; - new->refdec = AST__BAD; - new->refra = AST__BAD; - new->restfreq = AST__BAD; - new->sourcevel = AST__BAD; - new->sourcevrf = AST__BADSOR; - new->sourcesys = AST__BADSYSTEM; - new->stdofrest = AST__BADSOR; - new->nuunits = 0; - new->usedunits = NULL; - new->specorigin = AST__BAD; - new->alignspecoffset = -INT_MAX; - -/* 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; -} - -AstSpecFrame *astLoadSpecFrame_( void *mem, size_t size, - AstSpecFrameVtab *vtab, - const char *name, AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadSpecFrame - -* Purpose: -* Load a SpecFrame. - -* Type: -* Protected function. - -* Synopsis: -* #include "specframe.h" -* AstSpecFrame *astLoadSpecFrame( void *mem, size_t size, -* AstSpecFrameVtab *vtab, -* const char *name, AstChannel *channel ) - -* Class Membership: -* SpecFrame loader. - -* Description: -* This function is provided to load a new SpecFrame 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 -* SpecFrame structure in this memory, using data read from the -* input Channel. - -* Parameters: -* mem -* A pointer to the memory into which the SpecFrame is to be -* loaded. This must be of sufficient size to accommodate the -* SpecFrame data (sizeof(SpecFrame)) 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 SpecFrame (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 SpecFrame 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(AstSpecFrame) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new SpecFrame. If this is NULL, a pointer -* to the (static) virtual function table for the SpecFrame 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 "SpecFrame" is used instead. - -* Returned Value: -* A pointer to the new SpecFrame. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstSpecFrame *new; /* Pointer to the new SpecFrame */ - char buff[ 20 ]; /* Buffer for item name */ - char *sval; /* Pointer to string value */ - double obslat; /* Value for ObsLat attribute */ - double obslon; /* Get a pointer to the thread specific global data structure. */ - -/* Value for ObsLon attribute */ - int i; /* Loop count */ - int j; /* Loop count */ - int nc; /* String length */ - int sys; /* System value */ - - astGET_GLOBALS(channel); - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this SpecFrame. In this case the - SpecFrame belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstSpecFrame ); - vtab = &class_vtab; - name = "SpecFrame"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitSpecFrameVtab( 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 SpecFrame. */ - 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, "SpecFrame" ); - -/* 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. */ - -/* StdOfRest. */ -/* ---------- */ -/* Set the default and read the external representation as a string. */ - new->stdofrest = AST__BADSOR; - sval = astReadString( channel, "sor", NULL ); - -/* If a value was read, convert from a string to a StdOfRest code. */ - if ( sval ) { - if ( astOK ) { - new->stdofrest = StdOfRestCode( sval, status ); - -/* Report an error if the value wasn't recognised. */ - if ( new->stdofrest == AST__BADSOR ) { - astError( AST__ATTIN, - "astRead(%s): Invalid standard of rest description " - "\"%s\".", status, astGetClass( channel ), sval ); - } - } - -/* Free the string value. */ - sval = astFree( sval ); - } - -/* AlignStdOfRest. */ -/* --------------- */ -/* Set the default and read the external representation as a string. */ - new->alignstdofrest = AST__BADSOR; - sval = astReadString( channel, "alsor", NULL ); - -/* If a value was read, convert from a string to a StdOfRest code. */ - if ( sval ) { - if ( astOK ) { - new->alignstdofrest = StdOfRestCode( sval, status ); - -/* Report an error if the value wasn't recognised. */ - if ( new->alignstdofrest == AST__BADSOR ) { - astError( AST__ATTIN, - "astRead(%s): Invalid alignment standard of rest " - "description \"%s\".", status, astGetClass( channel ), sval ); - } - } - -/* Free the string value. */ - sval = astFree( sval ); - } - -/* GeoLat. */ -/* ------- */ -/* Retained for backward compatibility with older versions of AST in - which SpecFrame had a GeoLat attribute (now ObsLat is used instead). */ - if( !astTestObsLat( new ) ) { - obslat = astReadDouble( channel, "geolat", AST__BAD ); - if ( obslat != AST__BAD ) astSetObsLat( new, obslat ); - } - -/* GeoLon. */ -/* ------- */ -/* Retained for backward compatibility with older versions of AST in - which SpecFrame had a GeoLon attribute (now ObsLon is used instead). */ - if( !astTestObsLon( new ) ) { - obslon = astReadDouble( channel, "geolon", AST__BAD ); - if ( obslon != AST__BAD ) astSetObsLon( new, obslon ); - } - -/* RefRA. */ -/* ------ */ - new->refra = astReadDouble( channel, "refra", AST__BAD ); - if ( TestRefRA( new, status ) ) SetRefRA( new, new->refra, status ); - -/* RefDec. */ -/* ------- */ - new->refdec = astReadDouble( channel, "refdec", AST__BAD ); - if ( TestRefDec( new, status ) ) SetRefDec( new, new->refdec, status ); - -/* RestFreq. */ -/* --------- */ - new->restfreq = astReadDouble( channel, "rstfrq", AST__BAD ); - if ( TestRestFreq( new, status ) ) SetRestFreq( new, new->restfreq, status ); - -/* AlignSpecOffset */ -/* --------------- */ - new->alignspecoffset = astReadInt( channel, "alspof", -INT_MAX ); - if ( TestAlignSpecOffset( new, status ) ) SetAlignSpecOffset( new, new->alignspecoffset, status ); - -/* SourceVel. */ -/* ---------- */ - new->sourcevel = astReadDouble( channel, "srcvel", AST__BAD ); - if ( TestSourceVel( new, status ) ) SetSourceVel( new, new->sourcevel, status ); - -/* SourceVRF */ -/* --------- */ -/* Set the default and read the external representation as a string. */ - new->sourcevrf = AST__BADSOR; - sval = astReadString( channel, "srcvrf", NULL ); - -/* If a value was read, convert from a string to a StdOfRest code. */ - if ( sval ) { - if ( astOK ) { - new->sourcevrf = StdOfRestCode( sval, status ); - -/* Report an error if the value wasn't recognised. */ - if ( new->sourcevrf == AST__BADSOR ) { - astError( AST__ATTIN, - "astRead(%s): Invalid source velocity rest frame " - "description \"%s\".", status, astGetClass( channel ), sval ); - } - } - -/* Free the string value. */ - sval = astFree( sval ); - } - -/* SourceSys */ -/* --------- */ -/* Set the default and read the external representation as a string. */ - new->sourcesys = AST__BADSYSTEM; - sval = astReadString( channel, "srcsys", NULL ); - -/* If a value was read, convert from a string to a System code. */ - if ( sval ) { - if ( astOK ) { - new->sourcesys = SystemCode( (AstFrame *) new, sval, status ); - -/* Report an error if the value wasn't recognised. */ - if ( new->sourcesys == AST__BADSYSTEM ) { - astError( AST__ATTIN, - "astRead(%s): Invalid source velocity spectral system " - "description \"%s\".", status, astGetClass( channel ), sval ); - } - } - -/* Free the string value. */ - sval = astFree( sval ); - } - -/* UsedUnits */ -/* --------- */ - new->nuunits = 0; - new->usedunits = NULL; - for( sys = FIRST_SYSTEM; sys <= LAST_SYSTEM; sys++ ) { - nc = sprintf( buff, "u%s", astSystemString( new, (AstSystemType) sys )); - for( j = 0; j < nc; j++ ) buff[ j ] = tolower( buff[ j ] ); - sval = astReadString( channel, buff, NULL ); - if( sval ) { - if( (int) sys >= new->nuunits ) { - new->usedunits = astGrow( new->usedunits, sys + 1, - sizeof(char *) ); - if( astOK ) { - for( i = new->nuunits; i < sys + 1; i++ ) new->usedunits[ i ] = NULL; - new->nuunits = sys + 1; - } - } else { - new->usedunits[ sys ] = astFree( new->usedunits[ sys ] ); - } - if( astOK ) { - new->usedunits[ sys ] = astStore( new->usedunits[ sys ], - sval, strlen( sval ) + 1 ); - } - sval = astFree( sval); - } - } - -/* SpecOrigin. */ -/* --------- */ - new->specorigin = astReadDouble( channel, "sporg", AST__BAD ); - if ( TestSpecOrigin( new, status ) ) SetSpecOrigin( new, new->specorigin, status ); - - -/* If an error occurred, clean up by deleting the new SpecFrame. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new SpecFrame pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ -void astGetRefPos_( AstSpecFrame *this, AstSkyFrame *frm, double *lon, - double *lat, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,SpecFrame,GetRefPos))(this,frm,lon,lat, status ); -} -void astSetRefPos_( AstSpecFrame *this, AstSkyFrame *frm, double lon, - double lat, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,SpecFrame,SetRefPos))(this,frm,lon,lat, status ); -} - -void astSetStdOfRest_( AstSpecFrame *this, AstStdOfRestType value, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,SpecFrame,SetStdOfRest))(this,value, status ); -} - -void astClearStdOfRest_( AstSpecFrame *this, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,SpecFrame,ClearStdOfRest))(this, status ); -} - - - -/* Special public interface functions. */ -/* =================================== */ -/* These provide the public interface to certain special functions - whose public interface cannot be handled using macros (such as - astINVOKE) alone. In general, they are named after the - corresponding protected version of the function, but with "Id" - appended to the name. */ - -/* Public Interface Function Prototypes. */ -/* ------------------------------------- */ -/* The following functions have public prototypes only (i.e. no - protected prototypes), so we must provide local prototypes for use - within this module. */ -AstSpecFrame *astSpecFrameId_( const char *, ... ); - -/* Special interface function implementations. */ -/* ------------------------------------------- */ -AstSpecFrame *astSpecFrameId_( const char *options, ... ) { -/* -*++ -* Name: -c astSpecFrame -f AST_SPECFRAME - -* Purpose: -* Create a SpecFrame. - -* Type: -* Public function. - -* Synopsis: -c #include "specframe.h" -c AstSpecFrame *astSpecFrame( const char *options, ... ) -f RESULT = AST_SPECFRAME( OPTIONS, STATUS ) - -* Class Membership: -* SpecFrame constructor. - -* Description: -* This function creates a new SpecFrame and optionally initialises -* its attributes. -* -* A SpecFrame is a specialised form of one-dimensional Frame which -* represents various coordinate systems used to describe positions within -* an electro-magnetic spectrum. The particular coordinate system to be -* used is specified by setting the SpecFrame's System attribute (the -* default is wavelength) qualified, as necessary, by other attributes -* such as the rest frequency, the standard of rest, the epoch of -* observation, etc (see the description of the System attribute for -* details). -* -* By setting a value for thr SpecOrigin attribute, a SpecFrame can be made -* to represent offsets from a given spectral position, rather than absolute - -* Parameters: -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 SpecFrame. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -c If no initialisation is required, a zero-length string may be -c supplied. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new SpecFrame. The syntax used is identical to that for the -f AST_SET routine. If no initialisation is required, a blank -f value may be supplied. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astSpecFrame() -f AST_SPECFRAME = INTEGER -* A pointer to the new SpecFrame. - -* Examples: -c frame = astSpecFrame( "" ); -f FRAME = AST_SPECFRAME( ' ', STATUS ) -* Creates a SpecFrame to describe the default wavelength spectral -* coordinate system. The RestFreq attribute (rest frequency) is -* unspecified, so it will not be possible to align this SpecFrame -* with another SpecFrame on the basis of a velocity-based system. The -* standard of rest is also unspecified. This means that alignment -* will be possible with other SpecFrames, but no correction will be -* made for Doppler shift caused by change of rest frame during the -* alignment. -c frame = astSpecFrame( "System=VELO, RestFreq=1.0E15, StdOfRest=LSRK" ); -f FRAME = AST_SPECFRAME( 'System=VELO, RestFreq=1.0E15, StdOfRest=LSRK', STATUS ) -* Creates a SpecFrame describing a apparent radial velocity ("VELO") axis -* with rest frequency 1.0E15 Hz (about 3000 Angstroms), measured -* in the kinematic Local Standard of Rest ("LSRK"). Since the -* source position has not been specified (using attributes RefRA and -* RefDec), it will only be possible to align this SpecFrame with -* other SpecFrames which are also measured in the LSRK standard of -* rest. - -* Notes: -* - When conversion between two SpecFrames is requested (as when -c supplying SpecFrames to astConvert), -f supplying SpecFrames AST_CONVERT), -* account will be taken of the nature of the spectral coordinate systems -* they represent, together with any qualifying rest frequency, standard -* of rest, epoch values, etc. The AlignSystem and AlignStdOfRest -* attributes will also be taken into account. The results will therefore -* fully reflect the relationship between positions measured in the two -* systems. In addition, any difference in the Unit attributes of the two -* systems will also be taken into account. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astSpecFrame constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astSpecFrame_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - The variable argument list also prevents this function from -* invoking astSpecFrame_ directly, so it must be a -* re-implementation of it in all respects, except for the final -* conversion of the result to an ID value. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMapping *um; /* Mapping from default to actual units */ - AstSpecFrame *new; /* Pointer to new SpecFrame */ - AstSystemType s; /* System */ - const char *u; /* Units string */ - va_list args; /* Variable argument list */ - - int *status; /* Pointer to inherited status value */ - astGET_GLOBALS(NULL); /* Get a pointer to the thread specific global data structure. */ - -/* Get a pointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise the SpecFrame, allocating memory and initialising the virtual - function table as well if necessary. */ - new = astInitSpecFrame( NULL, sizeof( AstSpecFrame ), !class_init, - &class_vtab, "SpecFrame" ); - -/* 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 SpecFrame's attributes. */ - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* Check the Units are appropriate for the System. */ - u = astGetUnit( new, 0 ); - s = astGetSystem( new ); - um = astUnitMapper( DefUnit( s, "astSpecFrame", "SpecFrame", status ), - u, NULL, NULL ); - if( um ) { - um = astAnnul( um ); - } else { - astError( AST__BADUN, "astSpecFrame: Inappropriate units (%s) " - "specified for a %s axis.", status, u, SystemLabel( s, status ) ); - } - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return an ID value for the new SpecFrame. */ - return astMakeId( new ); -} - |