36 #include "muse_astro.h" 38 #include "muse_pfits.h" 44 #define MUSE_ASTRO_AIRMASS_APPROX 2 50 static const double kT0 = 2415020.;
51 static const double kEpoch1900 = 1900.;
52 static const double kJulianCentury = 36525.;
53 static const double kTropYear = 365.242198781;
54 static const double kBesselOffset = 0.31352;
55 static const double kAU = 149597870.7;
88 muse_astro_get_zenith_distance(
double aHourAngle,
double aDelta,
91 double p0 = sin(aLatitude) * sin(aDelta),
92 p1 = cos(aLatitude) * cos(aDelta),
93 z = p0 + cos(aHourAngle) * p1;
94 return fabs(z) < FLT_EPSILON ? 0. : z;
97 #if MUSE_ASTRO_AIRMASS_APPROX == 0 112 muse_astro_get_airmass_youngirvine(
double aSecZ)
114 return aSecZ * (1. - 0.0012 * (pow(aSecZ, 2) - 1.));
118 #if MUSE_ASTRO_AIRMASS_APPROX == 1 135 muse_astro_get_airmass_young(
double aCosZt)
137 return (1.002432 * aCosZt*aCosZt + 0.148386 * aCosZt + 0.0096467)
138 / (aCosZt*aCosZt*aCosZt + 0.149864 * aCosZt*aCosZt + 0.0102963 * aCosZt
143 #if MUSE_ASTRO_AIRMASS_APPROX == 2 159 muse_astro_get_airmass_hardie(
double aSecZ)
161 double secm1 = aSecZ - 1;
162 return aSecZ - 0.0018167 * secm1 - 0.002875 * secm1*secm1
163 - 0.0008083 * secm1*secm1*secm1;
208 double aExptime,
double aLatitude)
210 cpl_ensure(aRA >= 0. && aRA < 360. && aDEC >= -90. && aDEC <= 90. &&
211 aLST >= 0. && aLST < 86400. && aLatitude >= -90. && aLatitude <= 90.,
212 CPL_ERROR_ILLEGAL_INPUT, -1.);
213 cpl_ensure(aExptime >= 0., CPL_ERROR_ILLEGAL_INPUT, -1.);
216 double HA = aLST * 15./3600. - aRA;
226 double delta = aDEC * CPL_MATH_RAD_DEG,
227 latitude = aLatitude * CPL_MATH_RAD_DEG,
228 hourangle = HA * CPL_MATH_RAD_DEG;
233 double cosz = muse_astro_get_zenith_distance(hourangle, delta, latitude);
234 #if MUSE_ASTRO_AIRMASS_APPROX == 2 235 double z = acos(cosz) * CPL_MATH_DEG_RAD;
236 const double zlimit = 80.;
238 cpl_msg_warning(__func__,
"Zenith angle %f > %f!", z, zlimit);
241 if (cosz == 0. || fabs(1. / cosz) < FLT_EPSILON ||
242 acos(cosz) > CPL_MATH_PI_2) {
243 cpl_msg_error(__func__,
"Airmass computation unsuccessful. Object is below " 244 "the horizon at start (z = %f).", acos(cosz) * CPL_MATH_DEG_RAD);
245 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_OUTPUT);
250 #if MUSE_ASTRO_AIRMASS_APPROX == 0 251 airmass = muse_astro_get_airmass_youngirvine(1. / cosz);
253 #if MUSE_ASTRO_AIRMASS_APPROX == 1 254 airmass = muse_astro_get_airmass_young(cosz);
256 #if MUSE_ASTRO_AIRMASS_APPROX == 2 257 airmass = muse_astro_get_airmass_hardie(1. / cosz);
259 #if MUSE_ASTRO_AIRMASS_APPROX > 2 260 #error set MUSE_ASTRO_AIRMASS_APPROX to 0, 1, 2 267 const double weights[] = {1./6., 2./3., 1./6.};
268 const int nweights =
sizeof(weights) /
sizeof(
double);
270 double timeStep = aExptime / (nweights - 1) * 15./3600. * CPL_MATH_RAD_DEG;
271 airmass *= weights[0];
274 for (i = 1; i < nweights; i++) {
275 cosz = muse_astro_get_zenith_distance(hourangle + i * timeStep, delta, latitude);
276 #if MUSE_ASTRO_AIRMASS_APPROX == 2 277 z = acos(cosz) * CPL_MATH_DEG_RAD;
279 cpl_msg_warning(__func__,
"Zenith angle %f > %f!", z, zlimit);
282 if (cosz == 0. || fabs(1. / cosz) < FLT_EPSILON ||
283 acos(cosz) > CPL_MATH_PI_2) {
284 cpl_msg_error(__func__,
"Airmass computation unsuccessful at timeStep. " 285 "Object is below the horizon at %s exposure (z=%f).",
286 i == 1 ?
"mid" :
"end", acos(cosz) * CPL_MATH_DEG_RAD);
287 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_OUTPUT);
291 #if MUSE_ASTRO_AIRMASS_APPROX == 0 292 airmass += weights[i] * muse_astro_get_airmass_youngirvine(1. / cosz);
294 #if MUSE_ASTRO_AIRMASS_APPROX == 1 295 airmass += weights[i] * muse_astro_get_airmass_young(cosz);
297 #if MUSE_ASTRO_AIRMASS_APPROX == 2 298 airmass += weights[i] * muse_astro_get_airmass_hardie(1. / cosz);
303 #if MUSE_ASTRO_AIRMASS_APPROX == 0 305 const double airmasslimit = 4.;
306 if (airmass > airmasslimit) {
307 cpl_msg_warning(__func__,
"Airmass larger than %f", airmasslimit);
333 cpl_ensure(aHeader, CPL_ERROR_NULL_INPUT, -1.);
335 cpl_errorstate prestate = cpl_errorstate_get();
338 cpl_errorstate_set(prestate);
344 prestate = cpl_errorstate_get();
346 if (!cpl_errorstate_is_equal(prestate)) {
349 prestate = cpl_errorstate_get();
351 if (!cpl_errorstate_is_equal(prestate)) {
354 prestate = cpl_errorstate_get();
356 if (!cpl_errorstate_is_equal(prestate)) {
359 prestate = cpl_errorstate_get();
361 if (!cpl_errorstate_is_equal(prestate)) {
369 if (airmass < 0. && airm1 != 0. && airm2 != 0.) {
371 double average = (airm1 + airm2) / 2.;
372 cpl_msg_warning(__func__,
"airmass computation unsuccessful (%s), using simple " 373 "average of start and end values (%f)", cpl_error_get_message(),
379 cpl_msg_debug(__func__,
"airmass=%f (header %f, %f)", airmass, airm1, airm2);
380 if (airm1 != 0. && airm2 != 0.) {
381 cpl_boolean check = airmass > fmin(airm1, airm2) - 0.005
382 && airmass < fmax(airm1, airm2) + 0.005;
384 cpl_msg_warning(__func__,
"Computed airmass %.3f is NOT in the range " 385 "recorded in the FITS header (%f, %f)", airmass,
415 cpl_ensure(aHeader, CPL_ERROR_NULL_INPUT, 0.);
418 if (mode && !strncmp(mode,
"SKY", 4)) {
420 }
else if (mode && strncmp(mode,
"STAT", 5)) {
421 cpl_msg_warning(__func__,
"Derotator mode is neither SKY nor STAT! " 422 "Effective position angle may be wrong!");
424 cpl_msg_warning(__func__,
"Derotator mode is not given! Effective position " 425 "angle may be wrong!");
451 cpl_ensure(aHeader, CPL_ERROR_NULL_INPUT, 0.);
452 cpl_errorstate es = cpl_errorstate_get();
455 if (!cpl_errorstate_is_equal(es)) {
456 cpl_msg_warning(__func__,
"One or both TEL.PARANG keywords are missing!");
459 double parang = (p1 + p2) / 2.;
460 if (fabs(p1 - p2) < 90.) {
471 double d1 = copysign(180. - fabs(p1), p1),
472 d2 = copysign(180. - fabs(p2), p2);
473 parang = 180. - fabs((d1 + d2) / 2.);
474 if (fabs(d1) > fabs(d2)) {
475 parang = copysign(parang, p1);
477 parang = copysign(parang, p2);
499 double ra1 = aRA1 * CPL_MATH_RAD_DEG,
500 dec1 = aDEC1 * CPL_MATH_RAD_DEG,
501 ra2 = aRA2 * CPL_MATH_RAD_DEG,
502 dec2 = aDEC2 * CPL_MATH_RAD_DEG;
504 double dra = ra2 - ra1,
511 double t1 = cosdec2 * sin(dra),
512 t2 = cosdec1 * sindec2 - sindec1 * cosdec2 * cosdra,
513 dsigma = atan2(sqrt(t1*t1 + t2*t2),
514 sindec1 * sindec2 + cosdec1 * cosdec2 * cosdra);
515 return dsigma * CPL_MATH_DEG_RAD;
536 return aVac / (1. + 2.735182e-4 + 131.4182 / pow(aVac, 2)
537 + 2.76249e8 / pow(aVac, 4));
569 muse_astro_create_rotation(
const char *aMode,
double aPhi,
double aTheta,
572 int nrotations = strlen(aMode);
573 nrotations = nrotations <= 3 ? nrotations : 3;
574 cpl_matrix *
self = cpl_matrix_new(3, 3);
577 cpl_matrix_fill_diagonal(
self, 1., 0);
585 cpl_matrix *R = cpl_matrix_new(3, 3);
586 double angle[3] = { aPhi, aTheta, aPsi },
587 *_R = cpl_matrix_get_data(R);
589 for (i = 0; i < nrotations; ++i) {
590 double sa = sin(angle[i]),
592 cpl_matrix_fill(R, 0.);
593 switch (tolower(aMode[i])) {
617 cpl_matrix_delete(R);
618 cpl_matrix_delete(
self);
621 cpl_matrix *mt = cpl_matrix_product_create(R,
self);
622 cpl_matrix_delete(
self);
625 cpl_matrix_delete(R);
647 muse_astro_precession_matrix(
double aEpoch1,
double aEpoch2)
650 double sigma0 = 2000.,
654 double T = (sigmaF - sigma0) / 1000.,
655 t = (sigmaD - sigmaF) / 1000.;
657 double thetaA = (20042.0207 - 85.3131 * T - 0.2111 * T*T
658 + 0.3642 * T*T*T + 0.0008 * T*T*T*T - 0.0005 * T*T*T*T*T) * t
659 + (-42.6566 - 0.2111 * T + 0.5463 * T*T
660 + 0.0017 * T*T*T - 0.0012 * T*T*T*T) * t*t
661 + (-41.8238 + 0.0359 * T + 0.0027 *T*T - 0.0001 * T*T*T) * t*t*t
662 + (-0.0731 + 0.0019 * T + 0.0009 *T*T) * t*t*t*t
663 + (-0.0127 + 0.0011 * T) * t*t*t*t*t
664 + (0.0004) * t*t*t*t*t*t,
665 zetaA = (23060.9097 + 139.7495 * T - 0.0038 * T*T - 0.5918 * T*T*T
666 - 0.0037 * T*T*T*T + 0.0007 * T*T*T*T*T) * t
667 + (30.2226 - 0.2523 * T - 0.3840 * T*T - 0.0014 *T*T*T
668 + 0.0007 * T*T*T*T) * t*t
669 + (18.0183 - 0.1326 * T + 0.0006 * T*T + 0.0005 * T*T*T) * t*t*t
670 + (-0.0583 - 0.0001 * T + 0.0007 * T*T) * t*t*t*t
671 + (-0.0285) * t*t*t*t*t
672 + (-0.0002) * t*t*t*t*t*t,
673 zA = (23060.9097 +139.7495 * T -0.0038 * T*T -0.5918 * T*T*T
674 - 0.0037 * T*T*T*T + 0.0007 * T*T*T*T*T) * t
675 + (109.5270 + 0.2446 * T - 1.3913 * T*T - 0.0134 * T*T*T
676 + 0.0026 * T*T*T*T) * t*t
677 + (18.2667 - 1.1400 * T - 0.0173 * T*T + 0.0044 * T*T*T) * t*t*t
678 + (-0.2821 - 0.0093 * T + 0.0032 * T*T) * t*t*t*t
679 + (-0.0301 + 0.0006 * T) * t*t*t*t*t
680 + (-0.0001) * t*t*t*t*t*t;
682 thetaA *= CPL_MATH_RAD_DEG / 3600.;
683 zetaA *= CPL_MATH_RAD_DEG / 3600.;
684 zA *= CPL_MATH_RAD_DEG / 3600.;
687 return muse_astro_create_rotation(
"zyz", -zetaA, thetaA, -zA);
705 muse_astro_sidereal_time(
double aJD,
double aLong)
709 const double d1 = 1.739935934667999,
710 d2 = 6.283319509909095e02,
711 d3 = 6.755878646261384e-06,
713 double djd0 = floor(aJD) + 0.5;
717 double dut = (aJD - djd0) * CPL_MATH_2PI,
718 dt = (djd0 - kT0) / kJulianCentury,
719 dst0 = d1 + d2 * dt + d3 * dt * dt;
720 dst0 = fmod(dst0, CPL_MATH_2PI);
721 double dst = df * dut + dst0 - aLong;
722 dst = fmod(dst + 2.*CPL_MATH_2PI, CPL_MATH_2PI);
756 muse_astro_geo_correction(
double aLat,
double aElev,
double aDEC,
double aHA)
759 const double da = 6378.137;
762 const double df = 1. / 298.257222;
765 const double dw = CPL_MATH_2PI / 86164.;
766 const double de2 = df * (2.0 - df),
767 dsdlats = sin(aLat) * sin(aLat);
770 double d1 = 1.0 - de2 * (2.0 - de2) * dsdlats,
771 d2 = 1.0 - de2 * dsdlats,
772 dr0 = da * sqrt(d1 / d2);
775 d1 = de2 * sin(2.0 * aLat);
777 double dlatg = aLat - atan(d1 / d2);
780 double drh = dr0 * cos(dlatg) + (aElev / 1000.) * cos(aLat);
784 return dw * drh * cos(aDEC) * sin(aHA);
816 muse_astro_earth_velocity(
double aDJE,
double aDEqu,
double*
const aHVel,
821 const double dcfel[][3] = {
822 { 1.7400353e+00, 6.2833195099091e+02, 5.2796e-06 },
823 { 6.2565836e+00, 6.2830194572674e+02, -2.6180e-06 },
824 { 4.7199666e+00, 8.3997091449254e+03, -1.9780e-05 },
825 { 1.9636505e-01, 8.4334662911720e+03, -5.6044e-05 },
826 { 4.1547339e+00, 5.2993466764997e+01, 5.8845e-06 },
827 { 4.6524223e+00, 2.1354275911213e+01, 5.6797e-06 },
828 { 4.2620486e+00, 7.5025342197656e+00, 5.5317e-06 },
829 { 1.4740694e+00, 3.8377331909193e+00, 5.6093e-06 }
834 const double dceps[3] = {
835 4.093198e-01, -2.271110e-04, -2.860401e-08
837 const double ccsel[][3] = {
838 { 1.675104e-02, -4.179579e-05, -1.260516e-07 },
839 { 2.220221e-01, 2.809917e-02, 1.852532e-05 },
840 { 1.589963e+00, 3.418075e-02, 1.430200e-05 },
841 { 2.994089e+00, 2.590824e-02, 4.155840e-06 },
842 { 8.155457e-01, 2.486352e-02, 6.836840e-06 },
843 { 1.735614e+00, 1.763719e-02, 6.370440e-06 },
844 { 1.968564e+00, 1.524020e-02, -2.517152e-06 },
845 { 1.282417e+00, 8.703393e-03, 2.289292e-05 },
846 { 2.280820e+00, 1.918010e-02, 4.484520e-06 },
847 { 4.833473e-02, 1.641773e-04, -4.654200e-07 },
848 { 5.589232e-02, -3.455092e-04, -7.388560e-07 },
849 { 4.634443e-02, -2.658234e-05, 7.757000e-08 },
850 { 8.997041e-03, 6.329728e-06, -1.939256e-09 },
851 { 2.284178e-02, -9.941590e-05, 6.787400e-08 },
852 { 4.350267e-02, -6.839749e-05, -2.714956e-07 },
853 { 1.348204e-02, 1.091504e-05, 6.903760e-07 },
854 { 3.106570e-02, -1.665665e-04, -1.590188e-07 }
860 const double dcargs[][2] = {
861 { 5.0974222e+00, -7.8604195454652e+02 },
862 { 3.9584962e+00, -5.7533848094674e+02 },
863 { 1.6338070e+00, -1.1506769618935e+03 },
864 { 2.5487111e+00, -3.9302097727326e+02 },
865 { 4.9255514e+00, -5.8849265665348e+02 },
866 { 1.3363463e+00, -5.5076098609303e+02 },
867 { 1.6072053e+00, -5.2237501616674e+02 },
868 { 1.3629480e+00, -1.1790629318198e+03 },
869 { 5.5657014e+00, -1.0977134971135e+03 },
870 { 5.0708205e+00, -1.5774000881978e+02 },
871 { 3.9318944e+00, 5.2963464780000e+01 },
872 { 4.8989497e+00, 3.9809289073258e+01 },
873 { 1.3097446e+00, 7.7540959633708e+01 },
874 { 3.5147141e+00, 7.9618578146517e+01 },
875 { 3.5413158e+00, -5.4868336758022e+02 }
880 const double ccamps[][5] = {
881 { -2.279594e-5, 1.407414e-5, 8.273188e-6, 1.340565e-5, -2.490817e-7 },
882 { -3.494537e-5, 2.860401e-7, 1.289448e-7, 1.627237e-5, -1.823138e-7 },
883 { 6.593466e-7, 1.322572e-5, 9.258695e-6, -4.674248e-7, -3.646275e-7 },
884 { 1.140767e-5, -2.049792e-5, -4.747930e-6, -2.638763e-6, -1.245408e-7 },
885 { 9.516893e-6, -2.748894e-6, -1.319381e-6, -4.549908e-6, -1.864821e-7 },
886 { 7.310990e-6, -1.924710e-6, -8.772849e-7, -3.334143e-6, -1.745256e-7 },
887 { -2.603449e-6, 7.359472e-6, 3.168357e-6, 1.119056e-6, -1.655307e-7 },
888 { -3.228859e-6, 1.308997e-7, 1.013137e-7, 2.403899e-6, -3.736225e-7 },
889 { 3.442177e-7, 2.671323e-6, 1.832858e-6, -2.394688e-7, -3.478444e-7 },
890 { 8.702406e-6, -8.421214e-6, -1.372341e-6, -1.455234e-6, -4.998479e-8 },
891 { -1.488378e-6, -1.251789e-5, 5.226868e-7, -2.049301e-7, 0.0e0 },
892 { -8.043059e-6, -2.991300e-6, 1.473654e-7, -3.154542e-7, 0.0e0 },
893 { 3.699128e-6, -3.316126e-6, 2.901257e-7, 3.407826e-7, 0.0e0 },
894 { 2.550120e-6, -1.241123e-6, 9.901116e-8, 2.210482e-7, 0.0e0 },
895 { -6.351059e-7, 2.341650e-6, 1.061492e-6, 2.878231e-7, 0.0e0 }
901 const double ccsec3 = -7.757020e-08,
903 { 1.289600e-06, 5.550147e-01, 2.076942e+00 },
904 { 3.102810e-05, 4.035027e+00, 3.525565e-01 },
905 { 9.124190e-06, 9.990265e-01, 2.622706e+00 },
906 { 9.793240e-07, 5.508259e+00, 1.559103e+01 }
910 const double dcsld = 1.990987e-07,
911 ccsgd = 1.990969e-07;
915 const double cckm = 3.122140e-05,
916 ccmld = 2.661699e-06,
917 ccfdi = 2.399485e-07;
922 const double dcargm[][2] = {
923 { 5.1679830e+00, 8.3286911095275e+03 },
924 { 5.4913150e+00, -7.2140632838100e+03 },
925 { 5.9598530e+00, 1.5542754389685e+04 }
930 const double ccampm[][4] = {
931 { 1.097594e-01, 2.896773e-07, 5.450474e-02, 1.438491e-07 },
932 {-2.223581e-02, 5.083103e-08, 1.002548e-02, -2.291823e-08 },
933 { 1.148966e-02, 5.658888e-08, 8.249439e-03, 4.063015e-08 }
937 const double ccpamv[4] = { 8.326827e-11, 1.843484e-11,
938 1.988712e-12, 1.881276e-12 };
941 const double dc1mme = 0.99999696;
944 int ideq = (int)aDEqu;
945 double dt = (aDJE - kT0) / kJulianCentury,
952 forbel[7] = { 0., 0., 0., 0., 0., 0., 0. };
954 for (k = 0; k < 8; k++) {
955 double dlocal = fmod(dcfel[k][0] + dt * dcfel[k][1] + dtsq * dcfel[k][2],
961 forbel[k - 1] = dlocal;
964 double deps = fmod(dceps[0] + dt * dceps[1] + dtsq * dceps[2], CPL_MATH_2PI),
966 for (k = 0; k < 17; k++) {
967 sorbel[k] = fmod(ccsel[k][0] + t * ccsel[k][1] + tsq * ccsel[k][2],
973 for (k = 0; k < 4; k++) {
974 double a = fmod(ccsec[k][1] + t * ccsec[k][2], CPL_MATH_2PI);
979 double pertl = ccsec[0][0] * sn[0] + ccsec[1][0] * sn[1]
980 + (ccsec[2][0] + t * ccsec3) * sn[2] + ccsec[3][0] * sn[3],
984 for (k = 0; k < 15; k++) {
985 double a = fmod(dcargs[k][0] + dt * dcargs[k][1], CPL_MATH_2PI);
986 pertl += (ccamps[k][0] * cos(a) + ccamps[k][1] * sin(a));
987 pertr += (ccamps[k][2] * cos(a) + ccamps[k][3] * sin(a));
991 pertld += ((ccamps[k][1] * cos(a) - ccamps[k][0] * sin(a)) * ccamps[k][4]);
992 pertrd += ((ccamps[k][3] * cos(a) - ccamps[k][2] * sin(a)) * ccamps[k][4]);
996 double esq = sorbel[0] * sorbel[0],
999 twoe = sorbel[0] + sorbel[0],
1000 twog = forbel[0] + forbel[0],
1001 phi = twoe * ((1.0 - esq * (1.0 / 8.0)) * sin(forbel[0])
1002 + sorbel[0] * (5.0 / 8.0) * sin(twog)
1003 + esq * 0.5416667 * sin(forbel[0] + twog)),
1004 f = forbel[0] + phi,
1005 dpsi = dparam / (1. + sorbel[0] * cos(f)),
1006 phid = twoe * ccsgd * ((1.0 + esq * 1.50) * cos(f)
1007 + sorbel[0] * (1.250 - sin(f) * sin(f) * 0.50)),
1008 psid = ccsgd * sorbel[0] * sin(f) / sqrt(param);
1011 double d1pdro = 1. + pertr,
1012 drd = d1pdro * (psid + dpsi * pertrd),
1013 drld = d1pdro * dpsi * (dcsld + phid + pertld),
1014 dtl = fmod(dml + phi + pertl, CPL_MATH_2PI),
1015 dxhd = drd * cos(dtl) - drld * sin(dtl),
1016 dyhd = drd * sin(dtl) + drld * cos(dtl);
1024 for (k = 0; k < 3; k++) {
1025 double a = fmod(dcargm[k][0] + dt * dcargm[k][1], CPL_MATH_2PI);
1026 pertl += ccampm[k][0] * sin(a);
1027 pertld += ccampm[k][1] * cos(a);
1028 pertp += ccampm[k][2] * cos(a);
1029 pertpd -= ccampm[k][3] * sin(a);
1033 double tl = forbel[1] + pertl,
1034 sigma = cckm / (1. + pertp),
1035 a = sigma * (ccmld + pertld),
1037 dxhd = dxhd + a * sin(tl) + b * cos(tl);
1038 dyhd = dyhd - a * cos(tl) + b * sin(tl);
1039 double dzhd = -sigma * ccfdi * cos(forbel[2]);
1042 double dxbd = dxhd * dc1mme,
1043 dybd = dyhd * dc1mme,
1044 dzbd = dzhd * dc1mme;
1045 for (k = 0; k < 4; k++) {
1046 double plon = forbel[k + 3],
1047 pomg = sorbel[k + 1],
1048 pecc = sorbel[k + 9];
1049 tl = fmod(plon + 2.0 * pecc * sin(plon - pomg), CPL_MATH_2PI);
1050 dxbd = dxbd + ccpamv[k] * (sin(tl) + pecc * sin(pomg));
1051 dybd = dybd - ccpamv[k] * (cos(tl) + pecc * cos(pomg));
1052 dzbd = dzbd - ccpamv[k] * sorbel[k + 13] * cos(plon - sorbel[k + 5]);
1056 double dyahd = cos(deps) * dyhd - sin(deps) * dzhd,
1057 dzahd = sin(deps) * dyhd + cos(deps) * dzhd,
1058 dyabd = cos(deps) * dybd - sin(deps) * dzbd,
1059 dzabd = sin(deps) * dybd + cos(deps) * dzbd;
1069 double deqdat = (aDJE - kT0 - kBesselOffset) / kTropYear + kEpoch1900;
1070 cpl_matrix* prec = muse_astro_precession_matrix(deqdat, aDEqu);
1072 for (n = 0; n < 3; n++) {
1073 aHVel[n] = dxhd * cpl_matrix_get(prec, 0, n)
1074 + dyahd * cpl_matrix_get(prec, 1, n)
1075 + dzahd * cpl_matrix_get(prec, 2, n);
1076 aBVel[n] = dxbd * cpl_matrix_get(prec, 0, n)
1077 + dyabd * cpl_matrix_get(prec, 1, n)
1078 + dzabd * cpl_matrix_get(prec, 2, n);
1080 cpl_matrix_delete(prec);
1112 double aLat,
double aElev,
double aRA,
double aDEC,
1116 double eqt = (aJD - kT0 - kBesselOffset) / kTropYear + kEpoch1900,
1117 dc[3] = { cos(aRA * 15.0 * CPL_MATH_RAD_DEG) * cos(aDEC * CPL_MATH_RAD_DEG),
1118 sin(aRA * 15.0 * CPL_MATH_RAD_DEG) * cos(aDEC * CPL_MATH_RAD_DEG),
1119 sin(aDEC * CPL_MATH_RAD_DEG) };
1120 cpl_matrix *precession = muse_astro_precession_matrix(aEqui, eqt);
1123 for (i = 0; i < 3; ++i) {
1124 dcc[i] = dc[0] * cpl_matrix_get(precession, i, 0)
1125 + dc[1] * cpl_matrix_get(precession, i, 1)
1126 + dc[2] * cpl_matrix_get(precession, i, 2);
1128 cpl_matrix_delete(precession);
1132 dec2 = asin(dcc[2]);
1134 ra2 = atan(dcc[1] / dcc[0]);
1139 ra2 += CPL_MATH_2PI;
1144 ra2 = CPL_MATH_PI_2;
1146 ra2 = 1.5 * CPL_MATH_PI;
1152 double st = muse_astro_sidereal_time(aJD, aLong * CPL_MATH_RAD_DEG),
1157 aRV->
geo = muse_astro_geo_correction(aLat * CPL_MATH_RAD_DEG, aElev, dec2, -ha);
1161 double hv[3] = { 0., 0., 0. },
1162 bv[3] = { 0., 0., 0. };
1163 muse_astro_earth_velocity(aJD, eqt, hv, bv);
1169 for (i = 0; i < 3; ++i) {
1170 aRV->
bary += bv[i] * dcc[i] * kAU;
1171 aRV->
helio += hv[i] * dcc[i] * kAU;
1200 cpl_ensure(aHeader, CPL_ERROR_NULL_INPUT, rvcorr);
1203 cpl_errorstate state = cpl_errorstate_get();
1211 jd += 2400000.5 + 0.5 * exptime / (24. * 3600.);
1212 if (!cpl_errorstate_is_equal(state)) {
1213 cpl_error_set_message(__func__, CPL_ERROR_DATA_NOT_FOUND,
"Could not find all" 1214 " properties necessary for radial velocity computation!");
1221 if (!cpl_errorstate_is_equal(state)) {
1222 cpl_errorstate_set(state);
1226 muse_rvcorrection_compute(&rvcorr, jd, lon, lat, elev, ra, dec, equinox);
double muse_pfits_get_ra(const cpl_propertylist *aHeaders)
find out the right ascension
double muse_pfits_get_airmass_start(const cpl_propertylist *aHeaders)
find out the airmass at start of exposure
Structure to store bary-, helio-, and geocentric velocity corrections.
double muse_astro_parangle(const cpl_propertylist *aHeader)
Properly average parallactic angle values of one exposure.
double muse_pfits_get_drot_posang(const cpl_propertylist *aHeaders)
find out the MUSE derotator position angle (in degrees)
double muse_pfits_get_equinox(const cpl_propertylist *aHeaders)
find out the equinox
double muse_pfits_get_geolat(const cpl_propertylist *aHeaders)
find out the telescope's latitude
double muse_astro_wavelength_vacuum_to_air(double aVac)
Compute air wavelength for a given vacuum wavelength.
const char * muse_pfits_get_drot_mode(const cpl_propertylist *aHeaders)
find out the MUSE derotator mode
double muse_astro_compute_airmass(double aRA, double aDEC, double aLST, double aExptime, double aLatitude)
Compute the effective airmass of an observation.
double muse_pfits_get_dec(const cpl_propertylist *aHeaders)
find out the declination
muse_astro_rvcorr muse_astro_rvcorr_compute(const cpl_propertylist *aHeader)
Compute radial velocity corrections given the header of an exposure.
double muse_pfits_get_parang_start(const cpl_propertylist *aHeaders)
find out the parallactic angle at start of exposure (in degrees)
double muse_astro_posangle(const cpl_propertylist *aHeader)
Derive the position angle of an observation from information in a FITS header.
double muse_pfits_get_airmass_end(const cpl_propertylist *aHeaders)
find out the airmass at end of exposure
double muse_pfits_get_mjdobs(const cpl_propertylist *aHeaders)
find out the Julian Date of the observation
double muse_pfits_get_exptime(const cpl_propertylist *aHeaders)
find out the exposure time
double muse_pfits_get_geoelev(const cpl_propertylist *aHeaders)
find out the telescope's elevation
double muse_pfits_get_lst(const cpl_propertylist *aHeaders)
find out the local siderial time
double muse_pfits_get_geolon(const cpl_propertylist *aHeaders)
find out the telescope's longitude
double muse_astro_angular_distance(double aRA1, double aDEC1, double aRA2, double aDEC2)
Compute angular distance in the sky between two positions.
double muse_pfits_get_parang_end(const cpl_propertylist *aHeaders)
find out the parallactic angle at end of exposure (in degrees)
double muse_astro_airmass(cpl_propertylist *aHeader)
Derive the effective airmass of an observation from information in a FITS header. ...