/* COPYRIGHT (c) 1992 Kapteyn Astronomical Institute University of Groningen, The Netherlands All Rights Reserved. #> skytrans.dc1 Program: SKYTRANS Purpose: Transformation between equatorial, galactic, ecliptic and supergalactic coordinates. Category: COORDINATES, UTILITY File: skytrans.c Author: M.G.R. Vogelaar Keywords: FILENAME= Write output to file with name: [skip writing] Write output to a file on disk. Output coordinates are written in degrees in two column format. You are not allowed to write to a file that already exists. SKYSYSIN= Give sky system of input *, G, E or S: [*(=Equatorial)] * == equatorial system. G == Galactic system. E == Ecliptic system. S == Supergalactic system. EPOCHIN= Give epoch of input: [1950.0] Precession correction for the year EPOCHIN= is applied for the Equatorial and Ecliptic system. SKYSYSOUT= Give sky system of output *, G, E or S: [Galactic] EPOCHOUT= Give epoch of output: [1950.0] See remark at EPOCHIN= COORD= Position RA,DEC as d d or hms dms: [stop] or: Position l,b as d d or dms dms: [stop] Positions can be given as coordinate pairs in degrees or in hms/dms notation (6 numbers needed). If you enter a negative declination in dms notation, only the first field needs the minus sign. QUIT= Quit? [Y]/N Quit program or enter new sky systems. Description: SKYTRANS is an coordinate transformation utility that performs transformations between equatorial, galactic, ecliptic and supergalactic coordinates. Input coordinate system is defined by SKYSYSIN= Known sky systems are: * == equatorial system. G == Galactic system. E == Ecliptic system. S == Supergalactic system. If the equatorial system is selected, an epoch is needed also. This number is in years after 0.0. The same remarks can be made for the output sky system. Positions can be given entered as: COORD=123.4 34.0 | Two numbers in degrees (all systems) COORD=4 23 23.3 5 34 0 | hms 4h23m23.3s dms 5d34m0s (equatorial) COORD=4 23 23.3 5 34 0 | dms 4d23m23.3s dms 5d34m0s (not equatorial) COORD=4 23 23.3 -5 34 0 | hms 4d23m23.3s dms -5d34m0s Notes: Example: SKYTRANS SKYTRANS Version 1.0 (Nov 4 1992) SKYTRANS SKYSYSIN= SKYTRANS EPOCHIN= SKYTRANS SKYSYSOUT=S RA DEC (1950.0) ==> Super gal. l b =============================================================== SKYTRANS COORD=2 10 0 45 0 0 2h10m 0.00s , 45d 0m 0.0s ==> 344d50m 35.0s , - 2d 0m 19.3s ( 32.500000, 45.000000 deg. ==> 344.843068, -2.005373 deg.) SKYTRANS COORD= SKYTRANS QUIT= SKYTRANS +++ FINISHED +++ Updates: Nov 3, 1992: VOG, Document created. Sep 15, 1995: VOG, FILENAME= added. #< */ /* skytrans.c: include files */ #include "stdio.h" /* Defines ANSI C input and output utilities */ #include "stdlib.h" /* Defines the ANSI C functions for number */ /* conversion, storage allocation, and similar tasks.*/ #include "string.h" /* Declares the ANSI C string functions*/ /* like:strcpy, strcat etc.*/ #include "math.h" /* Declares the mathematical functions and macros.*/ #include "cmain.h" /* Defines the main body of a C program with */ /* MAIN_PROGRAM_ENTRY and IDENTIFICATION */ #include "gipsyc.h" /* Defines the ANSI-F77 types for Fortran to C intface */ /* including def. of char2str,str2char,tofchar,zadd */ /* and macros tobool and toflog */ #include "float.h" /* Definition of FLT_MAX etc.*/ #include "ctype.h" /* Declares ANSI C functions for testing characters */ /* like: isalpha, isdigit etc. also tolower, toupper.*/ /* Common includes */ #include "init.h" /* Declare task running to HERMES and initialize.*/ #include "finis.h" /* Informs HERMES that servant quits and cleans up the mess.*/ #include "anyout.h" /* General character output routine for GIPSY programs.*/ #include "setfblank.h" /* Subroutine to set a data value to the universal BLANK.*/ #include "error.h" /* User error handling routine. */ #include "myname.h" /* Obtain the name under which a GIPSY task is being run.*/ #include "nelc.h" /* Characters in F-string discarding trailing blanks.*/ /* User input routines */ #include "userlog.h" #include "userdble.h" #include "userchar.h" #include "usercharu.h" #include "reject.h" /* Reject user input.*/ #include "cancel.h" /* Remove user input from table maintained by HERMES.*/ /* Input of sets */ #include "gdsinp.h" /* Input of set, subsets, return # subsets.*/ #include "gdspos.h" /* Define a position in a subset.*/ #include "gdsbox.h" /* Define a box inside/around a subset.*/ #include "gdsc_range.h" /* Return lower left and upper right corner of a subset.*/ #include "gdsc_ndims.h" /* Return the dimensionality of a coordinate word.*/ #include "gdsc_grid.h" /* Extract grid value.*/ #include "gdsc_fill.h" /* return coordinate word filled with a grid */ /* value for each axis.*/ #include "gdsi_read.h" /* Reads data from (part of) a set.*/ #include "dcddble.h" #include "epoco.h" #include "skyco.h" #include "eclipco.h" /* DEFINITIONS: */ /* Initialize Fortran compatible string with macro 'fmake' */ #define fmake(fchr,size) { \ static char buff[size+1]; \ int i; \ for (i = 0; i < size; buff[i++] = ' '); \ buff[i] = 0; \ fchr.a = buff; \ fchr.l = size; \ } /* Malloc version of 'fmake' */ #define finit( fc , len ) { fc.a = malloc( ( len + 1 ) * sizeof( char ) ) ; \ fc.a[ len ] = '\0' ; \ fc.l = len ; } #define MYMAX(a,b) ( (a) > (b) ? (a) : (b) ) #define MYMIN(a,b) ( (a) > (b) ? (b) : (a) ) #define NINT(a) ( (a) < 0 ? (int)((a)-.5) : (int)((a)+.5) ) #define ABS(a) ( (a) < 0 ? (-(a)) : (a) ) #define PI 3.141592653589793 #define RAD(a) ( a * 0.017453292519943295769237 ) #define DEG(a) ( a * 57.295779513082320876798155 ) #define RELEASE "1.0" /* Version number */ #define MAXAXES 10 /* Max. axes in a set */ #define MAXSUBSETS 1 /* Max. allowed subsets */ #define MAXBUF 4096 /* Buffer size for I/O */ #define STRLEN 80 /* Max length of strings */ #define KEYLEN 20 /* Max length of keywords */ #define MAXFILENAMELEN 256 #define NONE 0 /* Default levels in userxxx routines */ #define REQUEST 1 #define HIDDEN 2 #define EXACT 4 #define YES 1 /* C versions of .TRUE. and .FALSE. */ #define NO 0 #define FIELDS 6 #define FIELDLEN 20 #define SHRT 20 #define EQUATORIAL 1 #define GALACTIC 2 #define ECLIPTIC 3 #define SUPERGALACTIC 4 /* Miscellaneous */ static fchar Key, Mes; static float blank; /* Global value for BLANK. */ static char message[120]; /* All purpose character buffer. */ static bool agreed; /* Loop guard. */ void anyoutC( int dev, char *anyCstr ) /*------------------------------------------------------------------*/ /* The C version of 'anyout_c' needs two parameters: */ /* an integer and a C-type string. The integer determines */ /* the destination of the output which is: */ /* 0 use default [set by HERMES to 3 but can be changed by user]*/ /* 1 terminal */ /* 2 LOG file */ /* 8 terminal, suppressed in "experienced mode" */ /* 16 terminal, only when in "test mode" */ /*------------------------------------------------------------------*/ { fint ldev = (fint) dev; anyout_c( &ldev, tofchar( anyCstr ) ); } static void dms( double degrees, char *convstr, int prec ) /*----------------------------------------------------------------------------- * Convert degrees to deg/min/sec *----------------------------------------------------------------------------- */ { double seconds; int Idegs; double min; int Imin; int negative; double power; power = pow( 10.0, (double) prec ); negative = 0; if ( degrees < 0 ) { negative = 1; degrees = fabs(degrees); } Idegs = (int) degrees; min = degrees*60.0 - ((double)Idegs)*60.0; Imin = (int) min; seconds = min*60.0 - ((double)Imin*60.0 ); /* Avoid rounding by formatting */ seconds = (double) ((int) (seconds * power) ) / power; if (negative) sprintf( convstr, "-%2dd%2dm%5.*fs", Idegs, Imin, prec, seconds ); else sprintf( convstr, "%2dd%2dm%5.*fs", Idegs, Imin, prec, seconds ); } static void hms( double degrees, char *convstr, int prec ) /*----------------------------------------------------------------------------- * Convert degrees to hours/min/sec *----------------------------------------------------------------------------- */ { double seconds; double hours; int Ihours; double min; int Imin; int negative; double power; power = pow( 10.0, (double) prec ); negative = 0; if ( degrees < 0 ) { negative = 1; degrees = -1.0 * degrees; } hours = degrees / 15.0; Ihours = (int) hours; min = hours*60.0 - ((double)Ihours)*60.0; Imin = (int) ( min ); seconds = min*60.0 - ((double)Imin)*60.0; seconds = (double) ((int) (seconds * power) ) / power; if (negative) sprintf( convstr, "-%2dh%2dm%5.*fs", Ihours, Imin, prec, seconds ); else sprintf( convstr, "%2dh%2dm%5.*fs", Ihours, Imin, prec, seconds ); } static void convpos( double epochIN, fint skysysIN, double epochOUT, fint skysysOUT, FILE *fp ) /*------------------------------------------------------------*/ /* Convert position from (sky1, epoch1) to (sky2, epoch2) */ /*------------------------------------------------------------*/ { fint nitems; fint dfault; fint r1, r2, r3; fchar Postxt; char field[FIELDS][FIELDLEN]; double posI[FIELDS]; double posO[FIELDS]; fint one = 1; bool quit; bool degrees; char str1[SHRT], str2[SHRT], str3[SHRT], str4[SHRT]; bool agreed; char mes1[40], mes2[40]; double epochdum; int i; fmake( Postxt, FIELDS * FIELDLEN ); Postxt.l = FIELDLEN; anyoutC( 3, " " ); if (skysysIN == EQUATORIAL) { sprintf( mes1, " RA DEC (%6.1f) ==>", epochIN ); } if (skysysIN == ECLIPTIC) { sprintf( mes1, "ecliptic long. lat.(%6.1f) ==>", epochIN ); } if (skysysIN == GALACTIC) { sprintf( mes1, "Galactic l b ==>" ); } if (skysysIN == SUPERGALACTIC) { sprintf( mes1, "Super gal. l b ==>" ); } if (skysysOUT == EQUATORIAL) { sprintf( mes2, " RA DEC (%6.1f)", epochOUT ); } if (skysysOUT == ECLIPTIC) { sprintf( mes2, " ecliptic long. lat.(%6.1f)", epochOUT ); } if (skysysOUT == GALACTIC) { sprintf( mes2, " Galactic l b" ); } if (skysysOUT == SUPERGALACTIC) { sprintf( mes2, " Super gal. l b" ); } sprintf( message, "%s%s", mes1, mes2 ); anyoutC( 3, message ); memset( message, '=', 63 ); anyoutC( 3, message ); do{ do { do { nitems = FIELDS; dfault = REQUEST; Key = tofchar("COORD="); if (skysysIN == 1) { Mes = tofchar("Position RA,DEC as d d or hms dms: [stop]"); } else { Mes = tofchar("Position l,b as d d or dms dms: [stop]"); } r1 = userchar_c( Postxt, &nitems, &dfault, Key, Mes ); if (r1 == 2) degrees = YES; else degrees = NO; agreed = ((r1 == 0) || (r1 == FIELDS) || (r1 == 2)); if (!agreed) reject_c( Key, tofchar("Wrong number of coords.") ); } while (!agreed); quit = (r1 == 0); if (!quit) { for (i = 0; i < r1; i++) { char ch; int k; for (k = 0; k < STRLEN; k++) { ch = Postxt.a[i*FIELDLEN+k]; if (ch != ' ') { field[i][k] = ch; } else { break; } } field[i][k] = '\0'; } for (i = 0; i < r1; i++) { r2 = dcddble_c( tofchar(field[i]), &posI[i], &one, &r3 ); agreed = (r3 == 0); if (!agreed) { reject_c( Key, tofchar("Cannot convert!") ); break; } } } } while (!agreed); if (!quit) { if (!degrees) { int negative = (posI[0] < 0.0); posI[0] = (fabs(posI[0]) + fabs(posI[1])/60.0 + fabs(posI[2])/3600.0 ); if (skysysIN == 1) { posI[0] *= 15.0; } if (negative) posI[0] *= -1.0; negative = (posI[3] < 0.0); posI[1] = (fabs(posI[3]) + fabs(posI[4])/60.0 + fabs(posI[5])/3600.0 ); if (negative) posI[1] *= -1.0; } posO[0] = posI[0]; posO[1] = posI[1]; if (skysysIN == EQUATORIAL) { epochdum = 1950.0; epoco_c( &posI[0], &posI[1], &epochIN, &posO[0], &posO[1], &epochdum ); } if (skysysIN == ECLIPTIC) { epochdum = 1950.0; eclipco_c( &posI[0], &posI[1], &epochIN, &posO[0], &posO[1], &epochdum ); } r3 = skyco_c( &posO[0], &posO[1], &skysysIN, &posO[0], &posO[1], &skysysOUT ); if (skysysOUT == EQUATORIAL) { epochdum = 1950.0; epoco_c( &posO[0], &posO[1], &epochdum, &posO[0], &posO[1], &epochOUT ); } if (skysysOUT == ECLIPTIC) { epochdum = 1950.0; eclipco_c( &posO[0], &posO[1], &epochdum, &posO[0], &posO[1], &epochOUT ); } if (skysysIN == EQUATORIAL) { hms(posI[0], str1, 2); dms(posI[1], str2, 1); if (skysysOUT == EQUATORIAL) { hms(posO[0], str3, 2); dms(posO[1], str4, 1); } else { dms(posO[0], str3, 1); dms(posO[1], str4, 1); } } else { /* Input NOT equatorial */ dms(posI[0], str1, 1); dms(posI[1], str2, 1); if (skysysOUT == EQUATORIAL) { hms(posO[0], str3, 2); dms(posO[1], str4, 1); } else { dms(posO[0], str3, 1); dms(posO[1], str4, 1); } } sprintf( message, "%s , %s ==> %s , %s", str1, str2, str3, str4 ); anyoutC( 3, message ); sprintf( message, "(%10f, %10f deg. ==> %10f, %10f deg.)", posI[0], posI[1], posO[0], posO[1] ); if (fp) fprintf( fp, "%15f %15f\n", posO[0], posO[1] ); anyoutC( 3, message ); } cancel_c( Key ); } while (!quit); } MAIN_PROGRAM_ENTRY /*-------------------------------------------------------------------------*/ /* The macro MAIN_PROGRAM_ENTRY replaces the C-call main() to start the */ /* main body of your GIPSY application. Variables defined as 'fchar' start */ /* with a capital. */ /*-------------------------------------------------------------------------*/ { fint nitems; fint dfault; fint r1; fint skysysOUT = 0; fint skysysIN = 0; double epochIN = 1950.0; double epochOUT = 1950.0; bool quit; fchar Skysys; fchar Filename; FILE *fp = NULL; init_c(); /* contact Hermes */ /* Task identification */ { static fchar Task; /* Name of current task */ fmake( Task, 20 ); /* Macro 'fmake' must be available */ (void) myname_c( Task ); /* Get task name */ Task.a[nelc_c(Task)] = '\0'; /* Terminate task name with null char*/ IDENTIFICATION( Task.a, RELEASE ); /* Show task and version */ } setfblank_c( &blank ); fmake( Key, KEYLEN ); fmake( Mes, STRLEN ); fmake( Skysys, FIELDLEN ); nitems = 1; dfault = REQUEST; fmake( Filename, MAXFILENAMELEN ); r1 = userchar_c( Filename, &nitems, &dfault, tofchar("FILENAME="), tofchar("Write output to file with name: [skip writing]" ) ); if (r1) { char longmes[300]; Filename.a[nelc_c(Filename)] = '\0'; fp = fopen( Filename.a, "r" ); if (fp != NULL) { sprintf( longmes, "Cannot open file because file [%s] exists!", Filename.a ); anyoutC( 1, longmes ); fp = NULL; } else { fp = fopen( Filename.a, "w" ); if (fp == NULL) { sprintf( longmes, "Cannot open [%s]", Filename.a ); anyoutC( 1, longmes ); } } } do { do { nitems = 1; dfault = REQUEST; Key = tofchar("SKYSYSIN="); Mes = tofchar("Give sky system of input */G/E/S: [*(=equatorial)]"); Skysys.a[0] = '*'; r1 = usercharu_c( Skysys, &nitems, &dfault, Key, Mes ); if (strchr(Skysys.a, '*') != NULL) skysysIN = EQUATORIAL; if (strchr(Skysys.a, 'G') != NULL) skysysIN = GALACTIC; if (strchr(Skysys.a, 'E') != NULL) skysysIN = ECLIPTIC; if (strchr(Skysys.a, 'S') != NULL) skysysIN = SUPERGALACTIC; agreed = ((skysysIN >=1) && (skysysIN <= 4)); if (!agreed) reject_c( Key, tofchar("Wrong sky system!") ); } while (!agreed); cancel_c( Key ); if ((skysysIN == EQUATORIAL) || (skysysIN == ECLIPTIC)) { nitems = 1; Key = tofchar("EPOCHIN="); if (skysysIN == EQUATORIAL) { Mes = tofchar("Give epoch of input: [1950.0]"); epochIN = 1950.0; } if (skysysIN == ECLIPTIC) { Mes = tofchar("Give epoch of input: [1983.5]"); epochIN = 1983.5; } r1 = userdble_c( &epochIN, &nitems, &dfault, Key, Mes ); cancel_c( Key ); } do { nitems = 1; dfault = REQUEST; Key = tofchar("SKYSYSOUT="); Mes = tofchar("Give sky system of output */G/E/S: [G(alactic)]"); Skysys.a[0] = 'G'; r1 = usercharu_c( Skysys, &nitems, &dfault, Key, Mes ); if (strchr(Skysys.a, '*') != NULL) skysysOUT = EQUATORIAL; if (strchr(Skysys.a, 'G') != NULL) skysysOUT = GALACTIC; if (strchr(Skysys.a, 'E') != NULL) skysysOUT = ECLIPTIC; if (strchr(Skysys.a, 'S') != NULL) skysysOUT = SUPERGALACTIC; agreed = ((skysysOUT >=1) && (skysysOUT <= 4)); if (!agreed) reject_c( Key, tofchar("Wrong sky system!") ); } while (!agreed); cancel_c( Key ); if ((skysysOUT == EQUATORIAL) || (skysysOUT == ECLIPTIC)) { nitems = 1; Key = tofchar("EPOCHOUT="); if (skysysOUT == EQUATORIAL) { Mes = tofchar("Give epoch of output: [1950.0]"); epochOUT = 1950.0; } if (skysysOUT == ECLIPTIC) { Mes = tofchar("Give epoch of output: [1983.5]"); epochOUT = 1983.5; } r1 = userdble_c( &epochOUT, &nitems, &dfault, Key, Mes ); cancel_c( Key ); } convpos( epochIN, skysysIN, epochOUT, skysysOUT, fp ); nitems = 1; quit = toflog(YES); Key = tofchar("QUIT="); Mes = tofchar("Quit? [Y]/N"); r1 = userlog_c( &quit, &nitems, &dfault, Key, Mes ); quit = tobool( quit ); cancel_c( Key ); } while (!quit); if (fp) fclose( fp ); finis_c(); return(EXIT_SUCCESS); /* Dummy return */ }