Starlink-AST

 view release on metacpan or  search on metacpan

ast/src/frame.c  view on Meta::CPAN

                                        strlen( ptr ) + (size_t) 1 );

/* Obtain a pointer to the target domain. */
            target_domain = astGetDomain( target );

/* Compare the domain strings for equality. Then free the memory
   allocated above. */
            match = astOK && !strcmp( template_domain, target_domain );
            template_domain = astFree( template_domain );
         }
      }
   }

/* If the template matches, obtain the values of the template's PreserveAxes
   and MatchEnd attributes and determine the number of template axes. */
   if ( astOK && match ) {
      preserve_axes = astGetPreserveAxes( template );
      match_end = astGetMatchEnd( template );
      template_naxes = astGetNaxes( template );

/* If the PreserveAxes attribute is non-zero, the target axes should be
   preserved, so the number of result axes equals the number of target axes.
   Otherwise the number of template axes is used. */
      result_naxes = preserve_axes ? target_naxes : template_naxes;

/* Allocate memory for the arrays of axis associations to be returned. */
      *template_axes = astMalloc( sizeof( int ) * (size_t) result_naxes );
      *target_axes = astMalloc( sizeof( int ) * (size_t) result_naxes );
      if ( astOK ) {

/* Loop through each of the result axes. */
         for ( result_axis = 0; result_axis < result_naxes; result_axis++ ) {

/* Set up the axis associations. By default, associate the first result axis
   with the first template/target axis. */
            (*template_axes)[ result_axis ] = result_axis;
            (*target_axes)[ result_axis ] = result_axis;

/* However, if the MatchEnd attribute is non-zero, associate the last result
   axis with the last template/target axis (this only makes a difference if
   there is a difference in the number of axes). */
            if ( match_end ) {
               (*template_axes)[ result_axis ] +=
                                               template_naxes - result_naxes;
               (*target_axes)[ result_axis ] += target_naxes - result_naxes;
            }

/* If any of the associations would be with a template/target axis that doesn't
   exist, then use an axis index of -1 for the association instead. */
            if ( ( (*template_axes)[ result_axis ] < 0 ) ||
                 ( (*template_axes)[ result_axis ] >= template_naxes ) ) {
               (*template_axes)[ result_axis ] = -1;
	    }
            if ( ( (*target_axes)[ result_axis ] < 0 ) ||
                 ( (*target_axes)[ result_axis ] >= target_naxes ) ) {
               (*target_axes)[ result_axis ] = -1;
	    }
         }

/* Use the target's astSubFrame method to select the required axes from it,
   overlaying the template's attributes on to the resulting Frame. This process
   also generates the required Mapping between the target and result Frames. */
         match = astSubFrame( target, template,
                              result_naxes, *target_axes, *template_axes,
                              map, result );
      }
   }

/* If an error occurred, free any allocated memory and reset the result. */
   if ( !astOK || !match ) {
      *template_axes = astFree( *template_axes );
      *target_axes = astFree( *target_axes );
      match = 0;
   }

/* Return the result. */
   return match;
}

static void MatchAxes( AstFrame *frm1, AstFrame *frm2, int *axes,
                       int *status ) {
/*
*++
*  Name:
c     astMatchAxes
f     AST_MATCHAXES

*  Purpose:
*     Find any corresponding axes in two Frames.

*  Type:
*     Public virtual function.

*  Synopsis:
c     #include "frame.h"
c     void astMatchAxes( AstFrame *frm1, AstFrame *frm2, int *axes )
f     CALL AST_MATCHAXES( FRM1, FRM2, AXES, STATUS )

*  Class Membership:
*     Frame method.

*  Description:
*     This function looks for corresponding axes within two supplied
*     Frames. An array of integers is returned that contains an element
*     for each axis in the second supplied Frame. An element in this array
*     will be set to zero if the associated axis within the second Frame
*     has no corresponding axis within the first Frame. Otherwise, it
*     will be set to the index (a non-zero positive integer) of the
*     corresponding axis within the first supplied Frame.

*  Parameters:
c     frm1
f     FRM1 = INTEGER (Given)
*        Pointer to the first Frame.
c     frm2
f     FRM2 = INTEGER (Given)
*        Pointer to the second Frame.
c     axes
f     AXES = INTEGER( * ) (Returned)
c        Pointer to an
f        An

ast/src/frame.c  view on Meta::CPAN

         if ( ( point1[ axis ] == AST__BAD ) ||
              ( point2[ axis ] == AST__BAD ) ) {
            dist = AST__BAD;
            break;

/* Otherwise, accumulate the sum of squared displacements along each
   axis. */
         } else {
            delta = point1[ axis ] - point2[ axis ];
            dist += ( delta * delta );
         }
      }

/* Take the square root to find the distance (if valid). */
      if ( dist != AST__BAD ) dist = sqrt( dist );

/* If the distance between the points cannot be found, or the distance
   is zero but the required offset is non-zero, then set the result
   coordinates to be bad. */
      if ( ( dist == AST__BAD ) ||
           ( ( dist == 0.0 ) && ( offset != 0.0 ) ) ) {
         for ( axis = 0; axis < naxes; axis++ ) {
            point3[ axis ] = AST__BAD;
         }

/* Otherwise, calculate what fraction of the distance between the
   points we need to move, and apply this fraction of the displacement
   along each axis. */
      } else {
         fract = ( dist == 0.0 ) ? 0.0 : offset / dist;
         for ( axis = 0; axis < naxes; axis++ ) {
            point3[ axis ] = point1[ axis ] +
                             fract * ( point2[ axis ] - point1[ axis ] );
         }
      }
   }
}

static void Overlay( AstFrame *template, const int *template_axes,
                     AstFrame *result, int *status ) {
/*
*+
*  Name:
*     astOverlay

*  Purpose:
*     Overlay the attributes of a template Frame on to another Frame.

*  Type:
*     Protected virtual function.

*  Synopsis:
*     #include "frame.h"
*     void astOverlay( AstFrame *template, const int *template_axes,
*                      AstFrame *result )

*  Class Membership:
*     Frame method.

*  Description:
*     This function overlays attributes of one Frame (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.

*  Parameters:
*     template
*        Pointer to the template Frame, 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.
*-
*/

/* Local Variables: */
   AstAxis *result_ax;           /* Pointer to result Axis object */
   AstAxis *template_ax;         /* Pointer to template Axis object */
   AstSystemType sys;            /* System value */
   int result_axis;              /* Loop counter for result Frame axes */
   int result_naxes;             /* Number of result Frame axes */
   int template_axis;            /* Index of template Frame axis */
   int template_naxes;           /* Number of template Frame axes */

/* Check the global error status. */
   if ( !astOK ) return;

/* Define a macro that tests whether an attribute is set in the template and,
   if so, transfers its value to the target. */
#define OVERLAY(attribute) \
   if ( astTest##attribute( template ) ) { \
      astSet##attribute( result, astGet##attribute( template ) ); \
   }

/* Use the macro to transfer each Frame attribute in turn. */
   OVERLAY(Dtai);
   OVERLAY(Dut1);
   OVERLAY(Digits);
   OVERLAY(Domain);
   OVERLAY(Epoch);
   OVERLAY(Title);
   OVERLAY(ObsLat)
   OVERLAY(ObsLon)
   OVERLAY(ObsAlt)

/* Transfer the ActiveUnit flag. */
   astSetActiveUnit( result, astGetActiveUnit( template ) );

/* Only overlay the System and AlignSystem attribute if the values are
   valid for the result class. */
   if( astTestSystem( template ) ) {
      sys = astGetSystem( template );
      if( astValidateSystem( result, sys, "astOverlay" ) ) {
         astSetSystem( result, sys );
      }
   }

   if( astTestAlignSystem( template ) ) {
      sys = astGetAlignSystem( template );
      if( astValidateSystem( result, sys, "astOverlay" ) ) {
         astSetAlignSystem( result, sys );
      }
   }

/* Now transfer attributes associated with individual axes. Obtain the number
   of axes in the template and result Frames. */
   template_naxes = astGetNaxes( template );
   result_naxes = astGetNaxes( result );
   if ( astOK ) {

/* Loop through all the axes in the result Frame and determine to which
   template axis each one corresponds. Check that the resulting axis index is
   valid. If not, then the axis will not receive new attributes. */
      for ( result_axis = 0; result_axis < result_naxes; result_axis++ ) {
         template_axis = template_axes ? template_axes[ result_axis ] : result_axis;
         if ( ( template_axis >= 0 ) && ( template_axis < template_naxes ) ) {

/* Obtain pointers to the relevant Axis objects of each Frame and use the
   astAxisOverlay method of the template Axis to overlay attributes on to
   the result Axis. Annul the Axis pointers afterwards. */
            template_ax = astGetAxis( template, template_axis );
            result_ax = astGetAxis( result, result_axis );
            astAxisOverlay( template_ax, result_ax );
            template_ax = astAnnul( template_ax );
            result_ax = astAnnul( result_ax );

/* Quit looping if an error occurs. */
            if ( !astOK ) break;
         }
      }
   }

/* Undefine macros local to this function. */
#undef OVERLAY
}

static void PermAxes( AstFrame *this, const int perm[], int *status ) {
/*
*+
*  Name:
*     astPermAxes

*  Purpose:
*     Permute the order of a Frame's axes.

*  Type:
*     Protected virtual function.

*  Synopsis:
*     #include "frame.h"
*     void astPermAxes( AstFrame *this, const int perm[] )

*  Class Membership:
*     Frame method.

*  Description:
*     This function permutes the order in which a Frame's axes occur.

*  Parameters:
*     this
*        Pointer to the Frame.
*     perm
*        An array of int (with one element for each axis of the Frame)
*        which lists the axes in their new order. Each element of this
*        array should be a (zero-based) axis index identifying the
*        axes according to their old (un-permuted) order.

*  Notes:
*     - Only genuine permutations of the axis order are permitted, so
*     each axis must be referenced exactly once in the "perm" array.
*     - If more than one axis permutation is applied to a Frame, the
*     effects are cumulative.
*-

*  Implementation Notes:
*     - This function implements the basic astPermAxes method which is
*     available via the protected interface to the Frame class. A
*     public interface to this method is provided by the
*     astPermAxesId_ function.

ast/src/frame.c  view on Meta::CPAN

      c[ l ] = 0;

/* Validate the axis index and obtain a pointer to the required Axis. */
   (void) astValidateAxis( this, axis, 1, "astSetUnit" );
      ax = astGetAxis( this, axis );

/* The new unit may require the Label and/or Symbol to be changed, but
   only if the Frames ActiveUnit flag is set. */
      if( astGetActiveUnit( this ) ) {

/* Get the existing Axis unit, using the astGetUnit method (rather than
   astGetAxisUnit) in order to get any default value in the case where
   the Unit attribute is not set. */
         oldunit = astGetUnit( this, axis );

/* Assign the new Unit value. This modifies labels and/or Symbols if
   necessary. */
         NewUnit( ax, oldunit, c, "astSetUnit", astGetClass( this ), status );
      }

/* Set the Axis Unit attribute value. */
      astSetAxisUnit( ax, c );

/* Annul the Axis pointer. */
      ax = astAnnul( ax );
   }

/* Free the string copy */
   c = astFree( c );

}

static int SubFrame( AstFrame *target, AstFrame *template,
                     int result_naxes, const int *target_axes,
                     const int *template_axes, AstMapping **map,
                     AstFrame **result, int *status ) {
/*
*+
*  Name:
*     astSubFrame

*  Purpose:
*     Select axes from a Frame and convert to the new coordinate system.

*  Type:
*     Protected virtual function.

*  Synopsis:
*     #include "frame.h"
*     int astSubFrame( AstFrame *target, AstFrame *template,
*                      int result_naxes, const int *target_axes,
*                      const int *template_axes, AstMapping **map,
*                      AstFrame **result )

*  Class Membership:
*     Frame method.

*  Description:
*     This function selects a requested sub-set (or super-set) of the axes from
*     a "target" Frame 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 Frame, 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 Frame. 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
*        Frame 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.

*  Returned Value:
*     A non-zero value is returned if coordinate conversion is
*     possible between the target and the result Frame. Otherwise zero
*     is returned and *map and *result are returned as NULL (but this
*     will not in itself result in an error condition). In general,
*     coordinate conversion should always be possible if no template
*     Frame is supplied but may not always be possible otherwise.

*  Notes:
*     - A value of zero will be returned if this function is invoked
*     with the global error status set, or if it should fail for any
*     reason.

*  Implementation Deficiencies:
*     - 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.
*-

*  Implementation Notes:
*     - This implementation addresses the selection of axes from a
*     Frame class object. This simply results in another object of the
*     same class and a Mapping which describes an axis permutation (or
*     a unit Mapping as a special case). Changes of Frame attributes
*     have no significance for coordinate values in this class, so do
*     not affect the Mapping returned.
*/

/* Local Variables: */
   AstAxis *newaxis;             /* Pointer to new Axis object */
   AstFrame *tempframe;          /* Pointer to temporary Frame */
   AstMapping *aumap;            /* A units Mapping for a single axis */
   AstMapping *numap;            /* The new total units Mapping */
   AstMapping *umap;             /* The total units Mapping */
   int *inperm;                  /* Pointer to permutation array */
   int *outperm;                 /* Pointer to permutation array */
   int match;                    /* Coordinate conversion possible? */
   int result_axis;              /* Result Frame axis index */
   int target_axis;              /* Target Frame axis index */
   int target_naxes;             /* Number of target Frame axes */
   int unit;                     /* Unit Mapping appropriate? */
   int uunit;                    /* Is the "umap" Mapping a UnitMap? */

ast/src/frame.c  view on Meta::CPAN

   if ( result_naxes < 0 ) result_naxes = 0;

/* Create a temporary new Frame with the required number of axes. This will
   have a default Axis object associated with each of its axes. We will
   replace these where necessary with copies of the actual Axis objects we
   require. */
   tempframe = astFrame( result_naxes, "", status );

/* Allocate memory to store two permutation arrays. These will be used to
   construct the Mapping that relates the target and result Frames. */
   inperm = astMalloc( sizeof( int ) * (size_t) target_naxes );
   outperm = astMalloc( sizeof( int ) * (size_t) result_naxes );
   if ( astOK ) {

/* Initialise the array that associates each target axis with the corresponding
   result axis (filling it with the value -1 initially signifies no
   associations). */
      for ( target_axis = 0; target_axis < target_naxes; target_axis++ ) {
         inperm[ target_axis ] = -1;
      }

/* Loop through each axis in the result Frame and obtain the index of the axis
   in the target Frame from which it is to be derived. */
      for ( result_axis = 0; result_axis < result_naxes; result_axis++ ) {
         target_axis = target_axes[ result_axis ];

/* Check if the resulting axis index is valid. If not, this result axis is not
   to be derived from any target axis, and it will therefore be left with its
   default attributes. Make an entry in the appropriate permutation array to
   indicate that this result axis is unassociated. */
         if ( ( target_axis < 0 ) || ( target_axis >= target_naxes ) ) {
            outperm[ result_axis ] = -1;

/* Otherwise, obtain a pointer to the target Axis object and modify the
   temporary Frame so that its axis is associated with the same Axis object.
   Annul the Axis pointer afterwards. */
         } else {
            newaxis = astGetAxis( target, target_axis );
            astSetAxis( tempframe, result_axis, newaxis );
            newaxis = astAnnul( newaxis );

/* Update both permutation arrays to record the association between the target
   and result axes. */
            outperm[ result_axis ] = target_axis;
            inperm[ target_axis ] = result_axis;
         }

/* Quit looping if an error occurs. */
         if ( !astOK ) break;
      }

/* So far, we have only modified pointers in the temporary Frame to refer to
   the target Frame's Axis objects. Since we will next modify these objects'
   attributes, we must make a deep copy of the entire temporary Frame so that
   we do not modify the target's axes. This copy now becomes our result Frame.
   Annul the temporary one. */
      if ( astOK ) {
         *result = astCopy( tempframe );
         tempframe = astAnnul( tempframe );

/* Invoke the target "astOverlay" method to overlay any remaining
   attributes from the target Frame which are not associated with
   individual axes (e.g.  the Frame's Title and Domain). */
         astOverlay( target, target_axes, *result );

/* If a template Frame was supplied, also invoke its astOverlay method to
   overlay its attributes on the result Frame. (Note that in this particular
   case this has no effect other than transferring attributes. In general,
   however, i.e. in derived classes, this process is vital to determining the
   mapping below, whose main purpose is to convert between the target and
   result Frames. These will have different attributes as a result of the
   influence that the template has here.) */
         if ( template ) astOverlay( template, template_axes, *result );

/* We will next generate the Mapping that relates the target and result
   Frames. If appropriate this should be a unit Mapping (UnitMap), so test if
   the number of axes in both Frames is equal. */
         unit = ( target_naxes == result_naxes );

/* If so, check the contents of one of the permutation arrays to see if all
   result axes are associated with the corresponding target axis (the converse
   then also follows). If not, note this fact and quit checking. */
         if ( unit ) {
            for ( result_axis = 0; result_axis < result_naxes;
                                   result_axis++ ) {
               if ( outperm[ result_axis ] != result_axis ) {
                  unit = 0;
                  break;
	       }
	    }
	 }

/* If a unit Mapping is appropriate, then construct it. */
         if ( unit ) {
            *map = (AstMapping *) astUnitMap( result_naxes, "", status );

/* Otherwise, construct a Mapping describing the axis permutation we have
   produced. */
         } else {
            *map = (AstMapping *) astPermMap( target_naxes, inperm,
                                              result_naxes, outperm, NULL,
                                              "", status );
         }

/* Note that coordinate conversion is possible. */
         match = 1;

/* If the ActiveUnit flag in both template and result Frame is non-zero, we
   now modify the Mapping to take account of any differences in the Units
   attributes of the target and results Frames. */
         if( template && astGetActiveUnit( template ) &&
                         astGetActiveUnit( *result ) ) {

/* Loop round the axes of the results Frame, accumulating a parallel CmpMap
   ("umap") in which each Mapping is the 1-D Mapping which transforms the
   Units of the corresponding target axis into the Units of the results
   axis. */
            umap = NULL;
            uunit = 1;
            for( result_axis = 0; result_axis < result_naxes; result_axis++ ) {

/* Find the index of the corresponding target axis. */
               if( unit ) {
                  target_axis = result_axis;
               } else {
                  target_axis = outperm[ result_axis ];
               }



( run in 0.762 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )