SUBROUTINE WCI2_READ( NARG, ARGS, OARG, STATUS ) *+ * Name: * WCI2_READ * Purpose: * Read in the WCS info from a FITS file * Language: * Starlink Fortran * Invocation: * CALL WCI2_READ( NARG, ARGS, OARG, STATUS ) * Description: * Constructs the data objects required by WCI from the supplied HDS * dataset. This may be any Starlink NDF, but if an ASTERIX dataset * is supplied then additional astrometic information can be extracted. * Arguments: * NARG = INTEGER (given) * Number of method arguments * ARGS(*) = INTEGER (given) * ADI identifier of method arguments * OARG = INTEGER (returned) * Output data * STATUS = INTEGER (given and returned) * The global status. * Examples: * {routine_example_text} * {routine_example_description} * Pitfalls: * {pitfall_description}... * Notes: * {routine_notes}... * Prior Requirements: * {routine_prior_requirements}... * Side Effects: * Creates a PSF_SLOT property on the property list of the first * argument if one is not already present. * Algorithm: * {algorithm_description}... * Accuracy: * {routine_accuracy} * Timing: * {routine_timing} * External Routines Used: * SLA: * SLA_EPJ - MJD to Julian epoch conversion * Implementation Deficiencies: * {routine_deficiencies}... * References: * WCI Subroutine Guide : http://www.sr.bham.ac.uk:8080/asterix-docs/Programmer/Guides/wci.html * Keywords: * package:wci, usage:private * Copyright: * Copyright (C) University of Birmingham, 1995 * Authors: * DJA: David J. Allan (Jet-X, University of Birmingham) * {enter_new_authors_here} * History: * 14 Feb 1995 (DJA): * Original version. * {enter_changes_here} * Bugs: * {note_any_bugs_here} *- * Type Definitions: IMPLICIT NONE ! No implicit typing * Global Constants: INCLUDE 'SAE_PAR' ! SAE constants INCLUDE 'ADI_PAR' ! ADI constants INCLUDE 'WCI_PAR' ! WCI constants * Arguments Given: INTEGER NARG, ARGS(*) * Arguments Returned: INTEGER OARG * Status: INTEGER STATUS ! Global status * External References: EXTERNAL SLA_EPJ DOUBLE PRECISION SLA_EPJ * Local Constants: INTEGER MAXPP ! Max # proj params PARAMETER ( MAXPP = 10 ) * Local Variables: CHARACTER*40 CTYPE ! CTYPE value CHARACTER*80 LABEL ! X,Y axis labels CHARACTER*3 PRJ ! Projection name CHARACTER*3 RADECSYS ! Coord system name CHARACTER*3 SYS ! Coord system name CHARACTER*40 UNITS(2) ! X,Y axis units DOUBLE PRECISION EPOCH ! Epoch DOUBLE PRECISION LONGPOLE ! DOUBLE PRECISION MJD ! Observation time DOUBLE PRECISION PA ! Position angle DOUBLE PRECISION SPOINT(2) ! RA, DEC REAL BASE(2), SCALE(2) ! Axis values REAL EQNX ! Equinox REAL PPARS(MAXPP) ! Projections params REAL TOR ! Radian conversion INTEGER DIMS(2) ! Axis dimensions INTEGER IP ! Loop over proj params INTEGER IPSF ! Psf system handle INTEGER NPRJP ! # projection pars INTEGER PHDU ! Primary HDU INTEGER PIXID ! Pixellation object INTEGER PRJID ! Projection object INTEGER PTR(2) ! Axis data pointers INTEGER SYSID ! CoordSystem object INTEGER X_AX,Y_AX,E_AX,T_AX ! Axis numbers LOGICAL EQOK, EPOK ! Equinox & epoch ok? LOGICAL HASPIX ! Spatial axes exist? LOGICAL LPOK ! Longpole found? LOGICAL RAOK, DECOK, PAOK ! Found ok flags LOGICAL REG(2) ! Axes regular LOGICAL PRJOK, SYSOK ! Projection/system ok? *. * Check inherited global status. IF ( STATUS .NE. SAI__OK ) RETURN * Initialise flags EPOK = .FALSE. EQOK = .FALSE. DECOK = .FALSE. LPOK = .FALSE. RAOK = .FALSE. PAOK = .FALSE. PRJOK = .FALSE. SYS = ' ' SYSOK = .FALSE. * Introduce the identifier to the PSF system IF ( ARGS(1) .EQ. ADI__NULLID ) THEN CALL PSF_INTRO( ARGS(2), IPSF, STATUS ) ELSE CALL PSF_INTRO( ARGS(1), IPSF, STATUS ) END IF IF ( STATUS .EQ. SAI__OK ) THEN HASPIX = .TRUE. ELSE CALL ERR_ANNUL( STATUS ) HASPIX = .FALSE. END IF * Locate main HDU CALL ADI2_FNDHDU( ARGS(2), ' ', PHDU, STATUS ) * Look for the RADECSYS keyword CALL ADI2_HGKYC( PHDU, 'RADECSYS', RADECSYS, STATUS ) IF ( STATUS .EQ. SAI__OK ) THEN IF ( RADECSYS .EQ. 'FK4' ) THEN SYS = 'FK4' ELSE IF ( RADECSYS .EQ. 'FK5' ) THEN SYS = 'FK5' ELSE STATUS = SAI__ERROR CALL MSG_SETC( 'SYS', RADECSYS ) CALL ERR_REP( ' ', 'Unrecognised RADECSYS value', STATUS ) CALL ERR_ANNUL( STATUS ) END IF IF ( SYS(1:1) .NE. ' ' ) SYSOK = .TRUE. ELSE RADECSYS = ' ' CALL ERR_ANNUL( STATUS ) END IF * Epoch of observation? CALL ADI2_HGKYD( PHDU, 'MJD-OBS', MJD, STATUS ) IF ( STATUS .EQ. SAI__OK ) THEN EPOCH = SLA_EPJ( MJD ) EPOK = .TRUE. ELSE CALL ERR_ANNUL( STATUS ) END IF * Equinox of coordinates CALL ADI2_HGKYR( PHDU, 'EQUINOX', EQNX, STATUS ) IF ( STATUS .EQ. SAI__OK ) THEN EQOK = .TRUE. IF ( .NOT. EPOK ) THEN EPOCH = DBLE(EQNX) EPOK = .TRUE. END IF ELSE CALL ERR_ANNUL( STATUS ) END IF * Look for old EPOCH keyword if epoch not defined IF ( .NOT. EPOK ) THEN CALL ADI2_HGKYD( PHDU, 'EPOCH', EPOCH, STATUS ) IF ( STATUS .EQ. SAI__OK ) THEN EPOK = .TRUE. ELSE CALL ERR_ANNUL( STATUS ) END IF END IF * Look for projection params NPRJP = 0 IP = 1 DO WHILE ( (STATUS .EQ. SAI__OK) .AND. (IP.LE.MAXPP) ) CALL ADI2_HGKYIR( PHDU, 'PROJP', IP, PPARS(IP), STATUS ) IF ( STATUS .EQ. SAI__OK ) THEN NPRJP = NPRJP + 1 IP = IP + 1 END IF END DO CALL ERR_ANNUL( STATUS ) * Look at CTYPEi to determinate projection, and possibly system too CALL ADI2_HGKYC( PHDU, 'CTYPE1', CTYPE, STATUS ) IF ( STATUS .EQ. SAI__OK ) THEN * Projection defined? IF ( CTYPE(6:) .GT. ' ' ) THEN PRJ = CTYPE(6:) PRJOK = .TRUE. END IF * Determine system from first 4 characters? IF ( .NOT. SYSOK ) THEN IF ( CTYPE(1:2) .EQ. 'RA' ) THEN IF ( EPOK ) THEN IF ( EPOCH .GT. 1984.0 ) THEN SYS = 'FK5' ELSE SYS = 'FK4' END IF END IF ELSE IF ( CTYPE(1:4) .EQ. 'ELON' ) THEN SYS = 'ECL' ELSE IF ( CTYPE(1:4) .EQ. 'GLON' ) THEN SYS = 'GAL' END IF IF ( SYS .GT. ' ' ) SYSOK = .TRUE. END IF ELSE CALL ERR_ANNUL( STATUS ) END IF CALL ADI2_HGKYC( PHDU, 'CTYPE2', CTYPE, STATUS ) IF ( STATUS .EQ. SAI__OK ) THEN * Projection defined? IF ( CTYPE(6:) .GT. ' ' ) THEN PRJ = CTYPE(6:) PRJOK = .TRUE. END IF * Determine system from first 4 characters? IF ( .NOT. SYSOK ) THEN IF ( CTYPE(1:3) .EQ. 'DEC' ) THEN IF ( EPOK ) THEN IF ( EPOCH .GT. 1984.0 ) THEN SYS = 'FK5' ELSE SYS = 'FK4' END IF END IF ELSE IF ( CTYPE(1:4) .EQ. 'ELAT' ) THEN SYS = 'ECL' ELSE IF ( CTYPE(1:4) .EQ. 'GLAT' ) THEN SYS = 'GAL' END IF IF ( SYS .GT. ' ' ) SYSOK = .TRUE. END IF ELSE CALL ERR_ANNUL( STATUS ) END IF * Extract axis info CALL ADI2_HGKYD( PHDU, 'CRVAL1', SPOINT(1), STATUS ) IF ( STATUS .NE. SAI__OK ) THEN CALL ERR_ANNUL( STATUS ) ELSE RAOK = .TRUE. END IF CALL ADI2_HGKYD( PHDU, 'CRVAL2', SPOINT(2), STATUS ) IF ( STATUS .NE. SAI__OK ) THEN CALL ERR_ANNUL( STATUS ) ELSE DECOK = .TRUE. END IF IF ( HASPIX ) THEN CALL PSF_QAXES( IPSF, X_AX, Y_AX, E_AX, T_AX, STATUS ) IF ( (X_AX .LT. 1) .OR. (Y_AX.LT.1) ) THEN HASPIX = .FALSE. ELSE CALL PSF_QAXIS( IPSF, X_AX, DIMS(1), REG(1), PTR(1), BASE(1), : SCALE(1), LABEL, UNITS(1), TOR, STATUS ) BASE(1) = BASE(1) / TOR SCALE(1) = SCALE(1) / TOR CALL PSF_QAXIS( IPSF, Y_AX, DIMS(2), REG(2), PTR(2), BASE(2), : SCALE(2), LABEL, UNITS(2), TOR, STATUS ) BASE(2) = BASE(2) / TOR SCALE(2) = SCALE(2) / TOR END IF END IF * Try to get position angle CALL ADI2_HGKYD( PHDU, 'CROTA2', PA, STATUS ) IF ( STATUS .NE. SAI__OK ) THEN CALL ERR_ANNUL( STATUS ) CALL ADI2_HGKYD( PHDU, 'DROLLANG', PA, STATUS ) IF ( STATUS .NE. SAI__OK ) THEN CALL ERR_ANNUL( STATUS ) ELSE PAOK = .TRUE. END IF ELSE PAOK = .TRUE. END IF * Create the CoordSystem object. Define suitable defaults for missing data IF ( .NOT. SYSOK ) SYS = 'FK5' IF ( .NOT. EQOK ) EQNX = 2000.0 IF ( .NOT. EPOK ) EPOCH = WCI__FLAG CALL WCI_NEWSYS( SYS, EQNX, EPOCH, SYSID, STATUS ) * Create the Projection object, providing defaults IF ( .NOT. PRJOK ) PRJ = 'CAR' IF ( .NOT. RAOK ) SPOINT(1) = 0D0 IF ( .NOT. DECOK ) SPOINT(2) = 0D0 IF ( .NOT. LPOK ) LONGPOLE = 180D0 CALL WCI_NEWPRJ( PRJ, NPRJP, PPARS, SPOINT, LONGPOLE, : PRJID, STATUS ) * Create the pixellation object, providing defaults IF ( HASPIX ) THEN IF ( .NOT. PAOK ) PA = 0D0 CALL WCI_NEWPX( DIMS, BASE, SCALE, UNITS, PA, PIXID, STATUS ) END IF * Create the output structure CALL ADI_NEW0( 'STRUC', OARG, STATUS ) IF ( HASPIX ) THEN CALL ADI_CPUTID( OARG, 'Pix', PIXID, STATUS ) END IF CALL ADI_CPUTID( OARG, 'Proj', PRJID, STATUS ) CALL ADI_CPUTID( OARG, 'Sys', SYSID, STATUS ) * Release primary HDU CALL ADI_ERASE( PHDU, STATUS ) * Report any errors IF ( STATUS .NE. SAI__OK ) THEN CALL AST_REXIT( 'WCI2_READ', STATUS ) END IF END