SUBROUTINE AXORDER( STATUS ) *+ * Name: * AXORDER * Purpose: * Rearranges specified axes in a dataset * Language: * Starlink Fortran * Type of Module: * ASTERIX task * Invocation: * CALL AXORDER( STATUS ) * Arguments: * STATUS = INTEGER (Given and Returned) * The global status. * Description: * {routine_description} * Usage: * axorder {parameter_usage} * Environment Parameters: * INP = CHAR (read) * Input object - may be primitive * SELAX[] = INTEGER (read) * New order of axes * OUT = CHAR (read) * Output dataset * Examples: * {routine_example_text} * {routine_example_description} * Pitfalls: * {pitfall_description}... * Notes: * {routine_notes}... * Prior Requirements: * {routine_prior_requirements}... * Side Effects: * {routine_side_effects}... * Algorithm: * {algorithm_description}... * Accuracy: * {routine_accuracy} * Timing: * {routine_timing} * Implementation Status: * {routine_implementation_status} * External Routines Used: * {name_of_facility_or_package}: * {routine_used}... * Implementation Deficiencies: * {routine_deficiencies}... * References: * {task_references}... * Keywords: * axorder, usage:public * Copyright: * Copyright (C) University of Birmingham, 1995 * Authors: * DJA: David J. Allan (Jet-X, University of Birmingham) * {enter_new_authors_here} * History: * 13 Dec 1989 V1.0-0 (DJA): * Original version. * 12 Mar 1990 V1.2-0 (DJA): * Was copying output axes incorrectly * 4 Jul 1990 V1.2-1 (DJA): * Swaps 1d data with axis values. Bit of a dodgy thing to do. * 8 May 1991 V1.4-0 (DJA): * Re-named from AXSWAP * 6 Mar 1992 V1.6-0 (DJA): * OUT prompt moved back to pre-processing * 24 Nov 1994 V1.8-0 (DJA): * Now use USI for user interface * 26 Mar 1995 V1.8-1 (DJA): * Use new data interface * 17 Jul 1995 V1.8-2 (DJA): * Corrected bug copying 1-D axis widths * 1 Dec 1995 V2.0-0 (DJA): * ADI port * 4 Jan 1996 V2.0-1 (DJA): * Use USI_NAMES for history update * 5 Mar 1996 V2.0-2 (DJA): * Added support for Grouping item * {enter_changes_here} * Bugs: * {note_any_bugs_here} *- * Type Definitions: IMPLICIT NONE ! No implicit typing * Global Constants: INCLUDE 'SAE_PAR' ! Standard SAE constants INCLUDE 'ADI_PAR' * Status: INTEGER STATUS ! Global status * Local Constants: CHARACTER*30 VERSION PARAMETER ( VERSION = 'AXORDER Version V2.0-2' ) * Local Variables: CHARACTER*80 HTXT ! History text INTEGER DIMS(ADI__MXDIM) ! Input dimensions INTEGER IDPTR,IGPTR,IVPTR,IQPTR ! Input data pointers INTEGER ODIMS(ADI__MXDIM) ! Output dimensions INTEGER SELAX(ADI__MXDIM) ! New axis order INTEGER I ! Loop over dimensions INTEGER IAPTR ! Input & output axis data INTEGER IFID ! Input dataset id INTEGER IFILES ! USI input files list INTEGER IWPTR ! Input axis widths INTEGER NDIM ! Dimensionality INTEGER ODPTR,OGPTR,OVPTR,OQPTR ! Output data pointers INTEGER OFID ! Output dataset id INTEGER OWPTR ! Output axis widths INTEGER NSEL ! # axes specified LOGICAL IWOK ! Input widths ok? LOGICAL OK, GOK, VOK, QOK ! Input objects ok? LOGICAL SPEC(ADI__MXDIM) ! Axis specified in output? LOGICAL SWAP_1D ! Special 1D swap? *. * Check inherited global status. IF ( STATUS .NE. SAI__OK ) RETURN * Version id CALL MSG_PRNT( VERSION ) * Initialise ASTERIX CALL AST_INIT() * Get input object CALL USI_ASSOC( 'INP', 'BinDS', 'READ', IFID, STATUS ) CALL USI_CREAT( 'OUT', ADI__NULLID, OFID, STATUS ) IF ( STATUS .NE. SAI__OK ) GOTO 99 * Check and map the data SWAP_1D = .FALSE. CALL BDI_CHK( IFID, 'Data', OK, STATUS ) CALL BDI_GETSHP( IFID, ADI__MXDIM, DIMS, NDIM, STATUS ) IF ( .NOT. OK ) THEN STATUS = SAI__ERROR CALL ERR_REP( ' ', 'FATAL ERROR : Invalid data', STATUS ) ELSE IF ( NDIM .EQ. 0 ) THEN STATUS = SAI__ERROR CALL ERR_REP( ' ', 'Object is scalar - no axes to swap!', : STATUS ) ELSE IF ( NDIM .EQ. 1 ) THEN SWAP_1D = .TRUE. CALL MSG_PRNT( 'Swapping data and axis values' ) END IF IF ( STATUS .NE. SAI__OK ) GOTO 99 CALL BDI_MAPR( IFID, 'Data', 'READ', IDPTR, STATUS ) * Variance CALL BDI_CHK( IFID, 'Variance', VOK, STATUS ) IF ( VOK ) THEN CALL BDI_MAPR( IFID, 'Variance', 'READ', IVPTR, STATUS ) END IF * Grouping CALL BDI_CHK( IFID, 'Grouping', GOK, STATUS ) IF ( GOK ) THEN CALL BDI_MAPI( IFID, 'Grouping', 'READ', IGPTR, STATUS ) END IF * Quality CALL BDI_CHK( IFID, 'Quality', QOK, STATUS ) IF ( QOK .AND. .NOT. SWAP_1D ) THEN CALL BDI_MAPUB( IFID, 'Quality', 'READ', IQPTR, STATUS ) END IF * Get new axis order if NDIM > 2 IF ( NDIM .GT. 2 ) THEN * Tell user about different axes CALL MSG_PRNT('Axes in input object are :') CALL MSG_PRNT(' ') CALL AXIS_TLIST( IFID, NDIM, STATUS ) NSEL = 0 CALL PRS_GETLIST( 'SELAX', NDIM, SELAX, NSEL, STATUS ) IF ( ( STATUS .NE. SAI__OK ) .OR. ( NSEL .EQ. 0 ) ) GOTO 99 ELSE IF ( NDIM .EQ. 2 ) THEN NSEL = 2 SELAX(1) = 2 SELAX(2) = 1 ELSE NSEL = 1 END IF * Check contents of swap array IF ( NSEL .NE. NDIM ) THEN CALL MSG_SETI( 'ND', NDIM ) CALL MSG_PRNT( 'You must specify the positions of all'/ : /' ^ND axes' ) ELSE IF ( SWAP_1D ) THEN HTXT = 'Data array and axis values swapped' ODIMS(1) = DIMS(1) ELSE * Donor dimensions not set yet CALL ARR_INIT1L( .FALSE., ADI__MXDIM, SPEC, STATUS ) * Loop over input and create output dimensions DO I =1, NSEL IF ( ( SELAX(I) .GT. NDIM ) .OR. ( SELAX(I) .LT. 0 ) ) THEN STATUS = SAI__ERROR CALL ERR_REP( ' ', 'FATAL ERROR : No such axis in input'/ : /' file!', STATUS ) ELSE IF ( SPEC(I) ) THEN CALL MSG_SETI( 'AX', I ) STATUS = SAI__ERROR CALL ERR_REP( ' ', 'FATAL ERROR : Axis ^AX is multiply'/ : /' specified in output', STATUS ) ELSE SPEC(I) = .TRUE. ODIMS(I) = DIMS(SELAX(I)) END IF IF ( STATUS .NE. SAI__OK ) GOTO 99 END DO * Make history string HTXT = 'New axis order ' CALL STR_DIMTOC( NSEL, SELAX, HTXT(16:) ) END IF * Define output file CALL BDI_LINK( 'BinDS', NDIM, ODIMS, 'REAL', OFID, STATUS ) * Create and map output data CALL BDI_MAPR( OFID, 'Data', 'WRITE', ODPTR, STATUS ) IF ( STATUS .NE. SAI__OK ) GOTO 99 * One dimensional swap IF ( SWAP_1D ) THEN * Map input axis CALL BDI_AXMAPR( IFID, 1, 'Data', 'READ', IAPTR, STATUS ) * Create irregular output axis and map CALL BDI_PUT1R( OFID, 'Data', ODIMS(1), %VAL(IAPTR), STATUS ) CALL BDI_AXPUT1R( OFID, 1, 'Data', ODIMS(1), %VAL(IDPTR), : STATUS ) * Variances become axis widths and vice versa IF ( VOK ) THEN * Create output widths CALL BDI_AXMAPR( OFID, 1, 'Width', 'WRITE', OWPTR, STATUS ) * Copy and square root CALL ARR_COP1R( ODIMS(1), %VAL(IVPTR), %VAL(OWPTR), STATUS ) CALL ARR_SQRT1R( %VAL(OWPTR), ODIMS(1), STATUS ) END IF * Input widths exist? CALL BDI_AXCHK( IFID, 1, 'Width', IWOK, STATUS ) IF ( IWOK ) THEN * Map input widths CALL BDI_AXMAPR( OFID, 1, 'Width', 'READ', IWPTR, STATUS ) * Create output variance CALL BDI_MAPR( OFID, 'Variance', 'WRITE', OVPTR, STATUS ) * Copy widths, divide by 2 and square CALL ARR_COP1R( ODIMS(1), %VAL(IWPTR), %VAL(OVPTR), STATUS ) CALL ARR_MULT1R( ODIMS(1), %VAL(OVPTR), 0.5, %VAL(OVPTR), : STATUS ) CALL ARR_SQR1R( %VAL(OVPTR), ODIMS(1), STATUS ) END IF * Just copy quality IF ( QOK ) THEN CALL BDI_COPY( IFID, 'Quality,QualityMask', OFID, ' ', : STATUS ) END IF * Copy text strings CALL BDI_COPY( IFID, 'Label', OFID, 'Axis_1_Label', STATUS ) CALL BDI_COPY( IFID, 'Units', OFID, 'Axis_1_Units', STATUS ) CALL BDI_COPY( IFID, 'Axis_1_Label', OFID, 'Label', STATUS ) CALL BDI_COPY( IFID, 'Axis_1_Units', OFID, 'Units', STATUS ) * normal swap ELSE * Copy axes DO I = 1, NDIM CALL BDI_AXCOPY( IFID, SELAX(I), ' ', OFID, I, STATUS ) END DO * Copy top-level text CALL BDI_COPY( IFID, 'Title,Label,Units', OFID, ' ', STATUS ) * Copy quality mask IF ( QOK ) THEN CALL BDI_COPY( IFID, 'QualityMask', OFID, ' ', STATUS ) END IF * Map output variance and quality IF ( VOK ) THEN CALL BDI_MAPR( OFID, 'Variance', 'WRITE', OVPTR, STATUS ) END IF IF ( GOK ) THEN CALL BDI_MAPI( OFID, 'Grouping', 'WRITE', OGPTR, STATUS ) END IF IF ( QOK ) THEN CALL BDI_MAPUB( OFID, 'Quality', 'WRITE', OQPTR, STATUS ) END IF IF ( STATUS .NE. SAI__OK ) GOTO 99 * Pad out dimensions for 7D CALL AR7_PAD( NDIM, DIMS, STATUS ) CALL AR7_PAD( NDIM, ODIMS, STATUS ) DO I = NDIM + 1, ADI__MXDIM SELAX(I) = I END DO * Swap the appropriate axes CALL AR7_AXSWAP_R( DIMS, %VAL(IDPTR), SELAX, ODIMS, : %VAL(ODPTR), STATUS ) IF ( VOK ) THEN CALL AR7_AXSWAP_R( DIMS, %VAL(IVPTR), SELAX, ODIMS, : %VAL(OVPTR), STATUS ) END IF IF ( GOK ) THEN CALL AR7_AXSWAP_I( DIMS, %VAL(IGPTR), SELAX, ODIMS, : %VAL(OGPTR), STATUS ) END IF IF ( QOK ) THEN CALL AR7_AXSWAP_B( DIMS, %VAL(IQPTR), SELAX, ODIMS, : %VAL(OQPTR), STATUS ) END IF END IF * Copy ancillary stuff CALL UDI_COPANC( IFID, 'grf,grp', OFID, STATUS ) * History CALL HSI_COPY( IFID, OFID, STATUS ) CALL HSI_ADD( OFID, VERSION, STATUS ) CALL USI_NAMES( 'I', IFILES, STATUS ) CALL HSI_PTXTI( OFID, IFILES, .TRUE., STATUS ) CALL HSI_PTXT( OFID, 1, HTXT, STATUS ) * Tidy up 99 CALL AST_CLOSE() CALL AST_ERR( STATUS ) END