int main() { int nFail = 0, stat[NSPEC], status; double restfrq, restwav, step; double awav[NSPEC], freq[NSPEC], spc1[NSPEC], spc2[NSPEC], velo[NSPEC], wave[NSPEC]; struct spxprm spx; register int j, k; printf( "Testing closure of WCSLIB spectral transformation routines (tspx.c)\n" "-------------------------------------------------------------------\n"); /* List status return messages. */ printf("\nList of spx status return values:\n"); for (status = 1; status <= 4; status++) { printf("%4d: %s.\n", status, spx_errmsg[status]); } restfrq = 1420.40595e6; restwav = C/restfrq; /* Exercise specx(). */ printf("\nTesting spectral cross-conversions (specx).\n\n"); if ((status = specx("VELO", 4.3e5, restfrq, restwav, &spx))) { printf("specx ERROR %d: %s.\n", status, spx_errmsg[status]); return 1; } printf(" restfrq:%20.12e\n", spx.restfrq); printf(" restwav:%20.12e\n", spx.restwav); printf(" wavetype:%3d\n", spx.wavetype); printf(" velotype:%3d\n", spx.velotype); printf("\n"); printf(" freq:%20.12e\n", spx.freq); printf(" afrq:%20.12e\n", spx.afrq); printf(" ener:%20.12e\n", spx.ener); printf(" wavn:%20.12e\n", spx.wavn); printf(" vrad:%20.12e\n", spx.vrad); printf(" wave:%20.12e\n", spx.wave); printf(" vopt:%20.12e\n", spx.vopt); printf(" zopt:%20.12e\n", spx.zopt); printf(" awav:%20.12e\n", spx.awav); printf(" velo:%20.12e\n", spx.velo); printf(" beta:%20.12e\n", spx.beta); printf("\n"); printf("dfreq/dafrq:%20.12e\n", spx.dfreqafrq); printf("dafrq/dfreq:%20.12e\n", spx.dafrqfreq); printf("dfreq/dener:%20.12e\n", spx.dfreqener); printf("dener/dfreq:%20.12e\n", spx.denerfreq); printf("dfreq/dwavn:%20.12e\n", spx.dfreqwavn); printf("dwavn/dfreq:%20.12e\n", spx.dwavnfreq); printf("dfreq/dvrad:%20.12e\n", spx.dfreqvrad); printf("dvrad/dfreq:%20.12e\n", spx.dvradfreq); printf("dfreq/dwave:%20.12e\n", spx.dfreqwave); printf("dwave/dfreq:%20.12e\n", spx.dwavefreq); printf("dfreq/dawav:%20.12e\n", spx.dfreqawav); printf("dawav/dfreq:%20.12e\n", spx.dawavfreq); printf("dfreq/dvelo:%20.12e\n", spx.dfreqvelo); printf("dvelo/dfreq:%20.12e\n", spx.dvelofreq); printf("dwave/dvopt:%20.12e\n", spx.dwavevopt); printf("dvopt/dwave:%20.12e\n", spx.dvoptwave); printf("dwave/dzopt:%20.12e\n", spx.dwavezopt); printf("dzopt/dwave:%20.12e\n", spx.dzoptwave); printf("dwave/dawav:%20.12e\n", spx.dwaveawav); printf("dawav/dwave:%20.12e\n", spx.dawavwave); printf("dwave/dvelo:%20.12e\n", spx.dwavevelo); printf("dvelo/dwave:%20.12e\n", spx.dvelowave); printf("dawav/dvelo:%20.12e\n", spx.dawavvelo); printf("dvelo/dawav:%20.12e\n", spx.dveloawav); printf("dvelo/dbeta:%20.12e\n", spx.dvelobeta); printf("dbeta/dvelo:%20.12e\n", spx.dbetavelo); printf("\n"); /* Construct a linear velocity spectrum. */ step = (2.0*C/NSPEC) / 2.0; for (j = 0, k = -NSPEC; j < NSPEC; j++, k += 2) { velo[j] = (k+1)*step; } printf("\nVelocity range: %.3f to %.3f km/s, step: %.3f km/s\n", velo[0]*1e-3, velo[NSPEC-1]*1e-3, (velo[1] - velo[0])*1e-3); /* Convert it to frequency. */ velofreq(restfrq, NSPEC, 1, 1, velo, freq, stat); /* Test closure of all two-way combinations. */ nFail += closure("freq", "afrq", 0.0, freqafrq, afrqfreq, freq, spc1); nFail += closure("afrq", "freq", 0.0, afrqfreq, freqafrq, spc1, spc2); nFail += closure("freq", "ener", 0.0, freqener, enerfreq, freq, spc1); nFail += closure("ener", "freq", 0.0, enerfreq, freqener, spc1, spc2); nFail += closure("freq", "wavn", 0.0, freqwavn, wavnfreq, freq, spc1); nFail += closure("wavn", "freq", 0.0, wavnfreq, freqwavn, spc1, spc2); nFail += closure("freq", "vrad", restfrq, freqvrad, vradfreq, freq, spc1); nFail += closure("vrad", "freq", restfrq, vradfreq, freqvrad, spc1, spc2); nFail += closure("freq", "wave", 0.0, freqwave, wavefreq, freq, wave); nFail += closure("wave", "freq", 0.0, wavefreq, freqwave, wave, spc2); nFail += closure("freq", "awav", 0.0, freqawav, awavfreq, freq, awav); nFail += closure("awav", "freq", 0.0, awavfreq, freqawav, awav, spc2); nFail += closure("freq", "velo", restfrq, freqvelo, velofreq, freq, velo); nFail += closure("velo", "freq", restfrq, velofreq, freqvelo, velo, spc2); nFail += closure("wave", "vopt", restwav, wavevopt, voptwave, wave, spc1); nFail += closure("vopt", "wave", restwav, voptwave, wavevopt, spc1, spc2); nFail += closure("wave", "zopt", restwav, wavezopt, zoptwave, wave, spc1); nFail += closure("zopt", "wave", restwav, zoptwave, wavezopt, spc1, spc2); nFail += closure("wave", "awav", 0.0, waveawav, awavwave, wave, spc1); nFail += closure("awav", "wave", 0.0, awavwave, waveawav, spc1, spc2); nFail += closure("wave", "velo", restwav, wavevelo, velowave, wave, spc1); nFail += closure("velo", "wave", restwav, velowave, wavevelo, spc1, spc2); nFail += closure("awav", "velo", restwav, awavvelo, veloawav, awav, spc1); nFail += closure("velo", "awav", restwav, veloawav, awavvelo, spc1, spc2); nFail += closure("velo", "beta", 0.0, velobeta, betavelo, velo, spc1); nFail += closure("beta", "velo", 0.0, betavelo, velobeta, spc1, spc2); if (nFail) { printf("\nFAIL: %d closure residuals exceed reporting tolerance.\n", nFail); } else { printf("\nPASS: All closure residuals are within reporting tolerance.\n"); } return nFail; }
int spcxps( const char ctypeS[9], double crvalX, double restfrq, double restwav, char *ptype, char *xtype, int *restreq, double *crvalS, double *dSdX) { char type[8]; int status; double dPdX, dSdP; struct spxprm spx; /* Analyse the spectral axis type. */ if (spctyp(ctypeS, 0, 0, ptype, xtype, restreq)) { return 2; } /* Do we have rest frequency and/or wavelength as required? */ if ((*restreq)%3 && restfrq == 0.0 && restwav == 0.0) { return 2; } /* Compute all spectral parameters and their derivatives. */ if (*xtype == 'F') { strcpy(type, "FREQ"); } else if (*xtype == 'W' || *xtype == 'w') { strcpy(type, "WAVE"); } else if (*xtype == 'A' || *xtype == 'a') { strcpy(type, "AWAV"); } else if (*xtype == 'V') { strcpy(type, "VELO"); } if (status = specx(type, crvalX, restfrq, restwav, &spx)) { return 2; } /* Transform X-P (non-linear) and P-S (linear). */ dPdX = 0.0; dSdP = 0.0; if (*ptype == 'F') { if (*xtype == 'F') { dPdX = 1.0; } else if (*xtype == 'W' || *xtype == 'w') { dPdX = spx.dfreqwave; } else if (*xtype == 'A' || *xtype == 'a') { dPdX = spx.dfreqawav; } else if (*xtype == 'V') { dPdX = spx.dfreqvelo; } if (strncmp(ctypeS, "FREQ", 4) == 0) { *crvalS = spx.freq; dSdP = 1.0; } else if (strncmp(ctypeS, "AFRQ", 4) == 0) { *crvalS = spx.afrq; dSdP = spx.dafrqfreq; } else if (strncmp(ctypeS, "ENER", 4) == 0) { *crvalS = spx.ener; dSdP = spx.denerfreq; } else if (strncmp(ctypeS, "WAVN", 4) == 0) { *crvalS = spx.wavn; dSdP = spx.dwavnfreq; } else if (strncmp(ctypeS, "VRAD", 4) == 0) { *crvalS = spx.vrad; dSdP = spx.dvradfreq; } } else if (*ptype == 'W') { if (*xtype == 'F') { dPdX = spx.dwavefreq; } else if (*xtype == 'W' || *xtype == 'w') { dPdX = 1.0; } else if (*xtype == 'A' || *xtype == 'a') { dPdX = spx.dwaveawav; } else if (*xtype == 'V') { dPdX = spx.dwavevelo; } if (strncmp(ctypeS, "WAVE", 4) == 0) { *crvalS = spx.wave; dSdP = 1.0; } else if (strncmp(ctypeS, "VOPT", 4) == 0) { *crvalS = spx.vopt; dSdP = spx.dvoptwave; } else if (strncmp(ctypeS, "ZOPT", 4) == 0) { *crvalS = spx.zopt; dSdP = spx.dzoptwave; } } else if (*ptype == 'A') { if (*xtype == 'F') { dPdX = spx.dawavfreq; } else if (*xtype == 'W' || *xtype == 'w') { dPdX = spx.dawavwave; } else if (*xtype == 'A' || *xtype == 'a') { dPdX = 1.0; } else if (*xtype == 'V') { dPdX = spx.dawavvelo; } if (strncmp(ctypeS, "AWAV", 4) == 0) { *crvalS = spx.awav; dSdP = 1.0; } } else if (*ptype == 'V') { if (*xtype == 'F') { dPdX = spx.dvelofreq; } else if (*xtype == 'W' || *xtype == 'w') { dPdX = spx.dvelowave; } else if (*xtype == 'A' || *xtype == 'a') { dPdX = spx.dveloawav; } else if (*xtype == 'V') { dPdX = 1.0; } if (strncmp(ctypeS, "VELO", 4) == 0) { *crvalS = spx.velo; dSdP = 1.0; } else if (strncmp(ctypeS, "BETA", 4) == 0) { *crvalS = spx.beta; dSdP = spx.dbetavelo; } } *dSdX = dSdP * dPdX; return 0; }
int spcspxe( const char ctypeS[9], double crvalS, double restfrq, double restwav, char *ptype, char *xtype, int *restreq, double *crvalX, double *dXdS, struct wcserr **err) { static const char *function = "spcspxe"; char scode[4], stype[5], type[8]; int status; double dPdS, dXdP; struct spxprm spx; /* Analyse the spectral axis code. */ if ((status = spctype(ctypeS, stype, scode, 0x0, 0x0, ptype, xtype, restreq, err))) { return status; } if (strchr("LT", (int)(*xtype))) { /* Can't handle logarithmic or tabular coordinates. */ return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Can't handle logarithmic or tabular coordinates"); } /* Do we have rest frequency and/or wavelength as required? */ if ((*restreq)%3 && restfrq == 0.0 && restwav == 0.0) { return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS), "Missing required rest frequency or wavelength"); } /* Compute all spectral parameters and their derivatives. */ strcpy(type, stype); spx.err = (err ? *err : 0x0); if ((status = specx(type, crvalS, restfrq, restwav, &spx))) { status = spc_spxerr[status]; if (err) { if ((*err = spx.err)) { (*err)->status = status; } } else { free(spx.err); } return status; } /* Transform S-P (linear) and P-X (non-linear). */ dPdS = 0.0; dXdP = 0.0; if (*ptype == 'F') { if (strcmp(stype, "FREQ") == 0) { dPdS = 1.0; } else if (strcmp(stype, "AFRQ") == 0) { dPdS = spx.dfreqafrq; } else if (strcmp(stype, "ENER") == 0) { dPdS = spx.dfreqener; } else if (strcmp(stype, "WAVN") == 0) { dPdS = spx.dfreqwavn; } else if (strcmp(stype, "VRAD") == 0) { dPdS = spx.dfreqvrad; } if (*xtype == 'F') { *crvalX = spx.freq; dXdP = 1.0; } else if (*xtype == 'W' || *xtype == 'w') { *crvalX = spx.wave; dXdP = spx.dwavefreq; } else if (*xtype == 'A' || *xtype == 'a') { *crvalX = spx.awav; dXdP = spx.dawavfreq; } else if (*xtype == 'V') { *crvalX = spx.velo; dXdP = spx.dvelofreq; } } else if (*ptype == 'W' || *ptype == 'w') { if (strcmp(stype, "WAVE") == 0) { dPdS = 1.0; } else if (strcmp(stype, "VOPT") == 0) { dPdS = spx.dwavevopt; } else if (strcmp(stype, "ZOPT") == 0) { dPdS = spx.dwavezopt; } if (*xtype == 'F') { *crvalX = spx.freq; dXdP = spx.dfreqwave; } else if (*xtype == 'W' || *xtype == 'w') { *crvalX = spx.wave; dXdP = 1.0; } else if (*xtype == 'A' || *xtype == 'a') { *crvalX = spx.awav; dXdP = spx.dawavwave; } else if (*xtype == 'V') { *crvalX = spx.velo; dXdP = spx.dvelowave; } } else if (*ptype == 'A' || *ptype == 'a') { if (strcmp(stype, "AWAV") == 0) { dPdS = 1.0; } if (*xtype == 'F') { *crvalX = spx.freq; dXdP = spx.dfreqawav; } else if (*xtype == 'W' || *xtype == 'w') { *crvalX = spx.wave; dXdP = spx.dwaveawav; } else if (*xtype == 'A' || *xtype == 'a') { *crvalX = spx.awav; dXdP = 1.0; } else if (*xtype == 'V') { *crvalX = spx.velo; dXdP = spx.dveloawav; } } else if (*ptype == 'V') { if (strcmp(stype, "VELO") == 0) { dPdS = 1.0; } else if (strcmp(stype, "BETA") == 0) { dPdS = spx.dvelobeta; } if (*xtype == 'F') { *crvalX = spx.freq; dXdP = spx.dfreqvelo; } else if (*xtype == 'W' || *xtype == 'w') { *crvalX = spx.wave; dXdP = spx.dwavevelo; } else if (*xtype == 'A' || *xtype == 'a') { *crvalX = spx.awav; dXdP = spx.dawavvelo; } else if (*xtype == 'V') { *crvalX = spx.velo; dXdP = 1.0; } } *dXdS = dXdP * dPdS; return 0; }
int spcspx( const char ctypeS[9], double crvalS, double restfrq, double restwav, char *ptype, char *xtype, int *restreq, double *crvalX, double *dXdS) { char type[8]; int status; double dPdS, dXdP; struct spxprm spx; /* Analyse the spectral axis code. */ if (spctyp(ctypeS, 0, 0, ptype, xtype, restreq)) { return 2; } /* Do we have rest frequency and/or wavelength as required? */ if ((*restreq)%3 && restfrq == 0.0 && restwav == 0.0) { return 2; } /* Compute all spectral parameters and their derivatives. */ strncpy(type, ctypeS, 4); type[4] = '\0'; if (status = specx(type, crvalS, restfrq, restwav, &spx)) { return 2; } /* Transform S-P (linear) and P-X (non-linear). */ dPdS = 0.0; dXdP = 0.0; if (*ptype == 'F') { if (strncmp(ctypeS, "FREQ", 4) == 0) { dPdS = 1.0; } else if (strncmp(ctypeS, "AFRQ", 4) == 0) { dPdS = spx.dfreqafrq; } else if (strncmp(ctypeS, "ENER", 4) == 0) { dPdS = spx.dfreqener; } else if (strncmp(ctypeS, "WAVN", 4) == 0) { dPdS = spx.dfreqwavn; } else if (strncmp(ctypeS, "VRAD", 4) == 0) { dPdS = spx.dfreqvrad; } if (*xtype == 'F') { *crvalX = spx.freq; dXdP = 1.0; } else if (*xtype == 'W' || *xtype == 'w') { *crvalX = spx.wave; dXdP = spx.dwavefreq; } else if (*xtype == 'A' || *xtype == 'a') { *crvalX = spx.awav; dXdP = spx.dawavfreq; } else if (*xtype == 'V') { *crvalX = spx.velo; dXdP = spx.dvelofreq; } } else if (*ptype == 'W' || *ptype == 'w') { if (strncmp(ctypeS, "WAVE", 4) == 0) { dPdS = 1.0; } else if (strncmp(ctypeS, "VOPT", 4) == 0) { dPdS = spx.dwavevopt; } else if (strncmp(ctypeS, "ZOPT", 4) == 0) { dPdS = spx.dwavezopt; } if (*xtype == 'F') { *crvalX = spx.freq; dXdP = spx.dfreqwave; } else if (*xtype == 'W' || *xtype == 'w') { *crvalX = spx.wave; dXdP = 1.0; } else if (*xtype == 'A' || *xtype == 'a') { *crvalX = spx.awav; dXdP = spx.dawavwave; } else if (*xtype == 'V') { *crvalX = spx.velo; dXdP = spx.dvelowave; } } else if (*ptype == 'A' || *ptype == 'a') { if (strncmp(ctypeS, "AWAV", 4) == 0) { dPdS = 1.0; } if (*xtype == 'F') { *crvalX = spx.freq; dXdP = spx.dfreqawav; } else if (*xtype == 'W' || *xtype == 'w') { *crvalX = spx.wave; dXdP = spx.dwaveawav; } else if (*xtype == 'A' || *xtype == 'a') { *crvalX = spx.awav; dXdP = 1.0; } else if (*xtype == 'V') { *crvalX = spx.velo; dXdP = spx.dveloawav; } } else if (*ptype == 'V') { if (strncmp(ctypeS, "VELO", 4) == 0) { dPdS = 1.0; } else if (strncmp(ctypeS, "BETA", 4) == 0) { dPdS = spx.dvelobeta; } if (*xtype == 'F') { *crvalX = spx.freq; dXdP = spx.dfreqvelo; } else if (*xtype == 'W' || *xtype == 'w') { *crvalX = spx.wave; dXdP = spx.dwavevelo; } else if (*xtype == 'A' || *xtype == 'a') { *crvalX = spx.awav; dXdP = spx.dawavvelo; } else if (*xtype == 'V') { *crvalX = spx.velo; dXdP = 1.0; } } *dXdS = dXdP * dPdS; return 0; }