/* velpro.c Copyright (c) Kapteyn Laboratorium Groningen 1990 All Rights Reserved. #> velpro.dc2 Function: VELPRO Purpose: Transformation from velocity to grid coordinates and vv. File: velpro.c Author: K.G. Begeman Use: INTEGER VELPRO( COORD1, Input DOUBLE PRECISION COORD2, Output DOUBLE PRECISION CRVAL , Input DOUBLE PRECISION CDELT , Input DOUBLE PRECISION DRVAL , Input DOUBLE PRECISION FREQ0 , Input DOUBLE PRECISION VELSYS, Input INTEGER DIR ) Input INTEGER VELPRO Returns: 0: transformation successful 9: unknown velocity system 10: rest frequency less than zero 11: crval equal to zero 12: cdelt equal to zero COORD1 Input velocity in m/s or grid. COORD2 Output grid coordinate or velocity in m/s. CRVAL Observed frequency in Hz at channel reference pixel. CDELT Grid separation in Hz. DRVAL Velocity at reference frequency in m/s. FREQ0 Rest frequency in Hz. If FREQ0 is 0.0, the new (correct) definition is used, if FREQ0 greater than 0.0, the old (approximate) definition is used. VELSYS Velocity system of input coordinates: 1 = optical definition 2 = radio definition DIR Direction of transform: DIR == 0: velocity -> grid DIR != 0: grid -> velocity Updates: Dec 8, 1989: KGB, Document created. #< Fortran to C interface: @ integer function velpro( double precision , @ double precision , @ double precision , @ double precision , @ double precision , @ double precision , @ integer , @ integer ) */ #include "stdio.h" #include "gipsyc.h" #define C 299792480.0 /* speed of light in vacuum (m/sec) */ fint velpro_c( double *coord1, double *coord2, double *crval , double *cdelt , double *drval , double *freq0 , fint *velsys, fint *dir ) { fint r = 0; if ((*freq0) < 0.0) return( 10 ); if ((*crval) <= 0.0) return( 11 ); if ((*cdelt) == 0.0) return( 12 ); if ((*dir)) { /* grid -> velocity */ switch((*velsys)) { case 1: { /* optical definition */ if ((*freq0 > 0.0)) { (*coord2) = (*drval) - C * (*freq0) * (*coord1) * (*cdelt) / (*crval) / ((*crval) + (*coord1) * (*cdelt)); } else { (*coord2) = ((*drval) * (*crval) - C * (*coord1) * (*cdelt)) / ((*crval) + (*coord1) * (*cdelt)); } break; } case 2: { if ((*freq0) > 0.0) { (*coord2) = (*drval) - C / (*freq0) * (*coord1) * (*cdelt); } else { (*coord2) = ((*drval) * ((*crval) + (*coord1) * (*cdelt)) - C * (*coord1) * (*cdelt)) / (*crval); } break; } default: { r = 9; break; } } } else { /* velocity -> grid */ switch((*velsys)) { case 1: { /* optical definition */ double d; if ((*freq0) > 0.0) { d = ((*drval) - (*coord1)) * (*crval); (*coord2) = d * (*crval) / (C * (*freq0) - d) / (*cdelt); } else { d = ((*drval) - (*coord1)) * (*crval); (*coord2) = d / (C+(*coord1)) / (*cdelt); } break; } case 2: { /* radio definition */ if ((*freq0) > 0.0) { (*coord2) = ((*drval) - (*coord1)) / C * (*freq0) / (*cdelt); } else { (*coord2) = ((*coord1) - (*drval)) / ((*drval) - C) * (*crval) / (*cdelt); } break; } default: { r = 9; break; } } } return( r ); } #if defined(TESTBED) int main() { double f0 = 1420405752.0; double cdelt = -78125.00; double crval = 1417248404.838; double drval = 650000.0; double v = 401777.7; double g = 32.0; double c; fint velsys; fint r; fint dir; f0 = 0.0; velsys = 1; dir = 0; r = velpro_c( &v, &c, &crval, &cdelt, &drval, &f0, &velsys, &dir ); printf( "velpro (%2ld): (%f) -> (%f)\n", r, v, c ); g = c; dir = 1; r = velpro_c( &g, &c, &crval, &cdelt, &drval, &f0, &velsys, &dir ); printf( "velpro (%2ld): (%f) -> (%f)\n", r, g, c ); velsys = 2; drval = v + C * g * cdelt / f0; dir = 0; r = velpro_c( &v, &c, &crval, &cdelt, &drval, &f0, &velsys, &dir ); printf( "velpro (%2ld): (%f) -> (%f)\n", r, v, c ); g = c; dir = 1; r = velpro_c( &g, &c, &crval, &cdelt, &drval, &f0, &velsys, &dir ); printf( "velpro (%2ld): (%f) -> (%f)\n", r, g, c ); } #endif