63 #include <sinfo_baryvel.h>
65 #include <sinfo_pfits.h>
66 #include <sinfo_utils.h>
67 #include <sinfo_error.h>
68 #include <sinfo_msg.h>
69 #include <sinfo_functions.h>
75 #define H_GEOLAT "ESO TEL GEOLAT"
76 #define H_GEOLON "ESO TEL GEOLON"
83 static double sinfo_pfits_get_geolat(
const cpl_propertylist * plist);
84 static double sinfo_pfits_get_geolon(
const cpl_propertylist * plist);
85 static double sinfo_pfits_get_utc(
const cpl_propertylist * plist);
89 static void deg2dms(
double in_val,
94 static void deg2hms(
double in_val,
99 static void compxy(
double inputr[19],
char inputc[4],
101 double utr,
double mod_juldat);
103 static void barvel(
double DJE,
double DEQ,
104 double DVELH[4],
double DVELB[4]);
118 static double sinfo_pfits_get_geolat(
const cpl_propertylist * plist)
120 double returnvalue = 0;
122 check(returnvalue=cpl_propertylist_get_double(plist, H_GEOLAT),
123 "Error reading keyword '%s'", H_GEOLAT);
136 static double sinfo_pfits_get_geolon(
const cpl_propertylist * plist)
138 double returnvalue = 0;
140 check(returnvalue=cpl_propertylist_get_double(plist, H_GEOLON),
141 "Error reading keyword '%s'", H_GEOLON);
157 static double sinfo_pfits_get_utc(
const cpl_propertylist * plist)
159 double returnvalue = 0;
161 check(returnvalue=cpl_propertylist_get_double(plist, H_UTC),
162 "Error reading keyword '%s'", H_UTC);
203 juldat(
double *INDATE,
236 DATE[1]=sinfo_round_double(INDATE[1]);
240 DATE[2]=sinfo_round_double(INDATE[2]);
242 DATE[3]=sinfo_round_double(INDATE[3]);
244 if ((DATE[2] == 0) && (DATE[3] == 0)) {
264 C = DATE[1] + DATE[2]*1.E-2 + DATE[3]*1.E-4 + UT*1.E-6;
266 if (C > 1582.1015E0) {
267 IA=(int) (YP/100.D0);
269 IB=2-IA+((int)(A/4.D0));
274 *JD = ((int) (365.25E0*YP)) + ((
int)(30.6001D0*(P+1.D0))) + DATE[3] + UT
284 IF (C >= 1582.1015E0) {
296 if (fabs(FRAC*ND-sinfo_round_double(FRAC*ND)) > 0.3) {
298 "integer number of days");
301 *JD = *JD+sinfo_round_double(FRAC*ND);
324 deg2hms(
double in_val,
332 in_val = fabs(in_val);
343 *hours= sinfo_round_double(tmp);
355 *minutes= sinfo_round_double(tmp);
361 tmp = tmp - *minutes;
367 if (sign ==
'-') *hours = -(*hours);
383 deg2dms(
double in_val,
388 deg2hms(in_val*15, degs, minutes, seconds);
396 #define DCFEL(x,y) dcfel[y][x]
397 #define DCFEPS(x,y) dcfeps[y][x]
398 #define CCSEL(x,y) ccsel[y][x]
399 #define DCARGS(x,y) dcargs[y][x]
400 #define CCAMPS(x,y) ccamps[y][x]
401 #define CCSEC(x,y) ccsec[y][x]
402 #define DCARGM(x,y) dcargm[y][x]
403 #define CCAMPM(x,y) ccampm[y][x]
404 #define DCEPS(x) dceps[x]
405 #define FORBEL(x) forbel[x]
406 #define SORBEL(x) sorbel[x]
408 #define SINLP(x) sinlp[x]
409 #define COSLP(x) coslp[x]
410 #define CCPAMV(x) ccpamv[x]
429 void barvel(
double DJE,
double DEQ,
430 double DVELH[4],
double DVELB[4])
433 double DT,DTL,DTSQ,DLOCAL;
435 double DXBD,DYBD,DZBD,DZHD,DXHD,DYHD;
436 double DYAHD,DZAHD,DYABD,DZABD;
437 double DML,DEPS,PHI,PHID,PSID,DPARAM,PARAM;
438 double PLON,POMG,PECC;
439 double PERTL,PERTLD,PERTRD,PERTP,PERTR,PERTPD;
442 double A,B,F,SINF,COSF,T,TSQ,TWOE,TWOG;
444 double DPSI,D1PDRO,DSINLS;
445 double DCOSLS,DSINEP,DCOSEP;
446 double forbel[8], sorbel[18], sinlp[5], coslp[5];
447 double SINLM,COSLM,SIGMA;
451 double *E = sorbel + 1 - 1;
452 double *G = forbel + 1 - 1;
453 double DC2PI = 6.2831853071796E0;
454 double CC2PI = 6.283185;
457 double DCT0 = 2415020.0E0;
458 double DCJUL = 36525.0E0;
460 double dcfel[][4] = { {0, 0, 0, 0},
461 {0, 1.7400353E+00, 6.2833195099091E+02, 5.2796E-06},
462 {0, 6.2565836E+00, 6.2830194572674E+02,-2.6180E-06},
463 {0, 4.7199666E+00, 8.3997091449254E+03,-1.9780E-05},
464 {0, 1.9636505E-01, 8.4334662911720E+03,-5.6044E-05},
465 {0, 4.1547339E+00, 5.2993466764997E+01, 5.8845E-06},
466 {0, 4.6524223E+00, 2.1354275911213E+01, 5.6797E-06},
467 {0, 4.2620486E+00, 7.5025342197656E+00, 5.5317E-06},
468 {0, 1.4740694E+00, 3.8377331909193E+00, 5.6093E-06} };
470 double dceps[4] = {0, 4.093198E-01,-2.271110E-04,-2.860401E-08};
472 double ccsel[][4] = { {0, 0, 0, 0},
473 {0, 1.675104E-02, -4.179579E-05, -1.260516E-07},
474 {0, 2.220221E-01, 2.809917E-02, 1.852532E-05},
475 {0, 1.589963E+00, 3.418075E-02, 1.430200E-05},
476 {0, 2.994089E+00, 2.590824E-02, 4.155840E-06},
477 {0, 8.155457E-01, 2.486352E-02, 6.836840E-06},
478 {0, 1.735614E+00, 1.763719E-02, 6.370440E-06},
479 {0, 1.968564E+00, 1.524020E-02, -2.517152E-06},
480 {0, 1.282417E+00, 8.703393E-03, 2.289292E-05},
481 {0, 2.280820E+00, 1.918010E-02, 4.484520E-06},
482 {0, 4.833473E-02, 1.641773E-04, -4.654200E-07},
483 {0, 5.589232E-02, -3.455092E-04, -7.388560E-07},
484 {0, 4.634443E-02, -2.658234E-05, 7.757000E-08},
485 {0, 8.997041E-03, 6.329728E-06, -1.939256E-09},
486 {0, 2.284178E-02, -9.941590E-05, 6.787400E-08},
487 {0, 4.350267E-02, -6.839749E-05, -2.714956E-07},
488 {0, 1.348204E-02, 1.091504E-05, 6.903760E-07},
489 {0, 3.106570E-02, -1.665665E-04, -1.590188E-07} };
492 double dcargs[][3] = { {0, 0, 0},
493 {0, 5.0974222E+00, -7.8604195454652E+02},
494 {0, 3.9584962E+00, -5.7533848094674E+02},
495 {0, 1.6338070E+00, -1.1506769618935E+03},
496 {0, 2.5487111E+00, -3.9302097727326E+02},
497 {0, 4.9255514E+00, -5.8849265665348E+02},
498 {0, 1.3363463E+00, -5.5076098609303E+02},
499 {0, 1.6072053E+00, -5.2237501616674E+02},
500 {0, 1.3629480E+00, -1.1790629318198E+03},
501 {0, 5.5657014E+00, -1.0977134971135E+03},
502 {0, 5.0708205E+00, -1.5774000881978E+02},
503 {0, 3.9318944E+00, 5.2963464780000E+01},
504 {0, 4.8989497E+00, 3.9809289073258E+01},
505 {0, 1.3097446E+00, 7.7540959633708E+01},
506 {0, 3.5147141E+00, 7.9618578146517E+01},
507 {0, 3.5413158E+00, -5.4868336758022E+02} };
512 {0, -2.279594E-5, 1.407414E-5, 8.273188E-6, 1.340565E-5, -2.490817E-7},
513 {0, -3.494537E-5, 2.860401E-7, 1.289448E-7, 1.627237E-5, -1.823138E-7},
514 {0, 6.593466E-7, 1.322572E-5, 9.258695E-6, -4.674248E-7, -3.646275E-7},
515 {0, 1.140767E-5, -2.049792E-5, -4.747930E-6, -2.638763E-6, -1.245408E-7},
516 {0, 9.516893E-6, -2.748894E-6, -1.319381E-6, -4.549908E-6, -1.864821E-7},
517 {0, 7.310990E-6, -1.924710E-6, -8.772849E-7, -3.334143E-6, -1.745256E-7},
518 {0, -2.603449E-6, 7.359472E-6, 3.168357E-6, 1.119056E-6, -1.655307E-7},
519 {0, -3.228859E-6, 1.308997E-7, 1.013137E-7, 2.403899E-6, -3.736225E-7},
520 {0, 3.442177E-7, 2.671323E-6, 1.832858E-6, -2.394688E-7, -3.478444E-7},
521 {0, 8.702406E-6, -8.421214E-6, -1.372341E-6, -1.455234E-6, -4.998479E-8},
522 {0, -1.488378E-6, -1.251789E-5, 5.226868E-7, -2.049301E-7, 0.0E0},
523 {0, -8.043059E-6, -2.991300E-6, 1.473654E-7, -3.154542E-7, 0.0E0},
524 {0, 3.699128E-6, -3.316126E-6, 2.901257E-7, 3.407826E-7, 0.0E0},
525 {0, 2.550120E-6, -1.241123E-6, 9.901116E-8, 2.210482E-7, 0.0E0},
526 {0, -6.351059E-7, 2.341650E-6, 1.061492E-6, 2.878231E-7, 0.0E0}};
530 double CCSEC3 = -7.757020E-08;
532 double ccsec[][4] = { {0, 0, 0, 0},
533 {0, 1.289600E-06, 5.550147E-01, 2.076942E+00},
534 {0, 3.102810E-05, 4.035027E+00, 3.525565E-01},
535 {0, 9.124190E-06, 9.990265E-01, 2.622706E+00},
536 {0, 9.793240E-07, 5.508259E+00, 1.559103E+01}};
538 double DCSLD = 1.990987E-07, CCSGD = 1.990969E-07;
540 double CCKM = 3.122140E-05, CCMLD = 2.661699E-06, CCFDI = 2.399485E-07;
542 double dcargm[][3] = {{0, 0, 0},
543 {0, 5.1679830E+00, 8.3286911095275E+03},
544 {0, 5.4913150E+00, -7.2140632838100E+03},
545 {0, 5.9598530E+00, 1.5542754389685E+04}};
547 double ccampm[][5] = {{0, 0, 0, 0, 0},
548 {0, 1.097594E-01, 2.896773E-07, 5.450474E-02, 1.438491E-07},
549 {0, -2.223581E-02, 5.083103E-08, 1.002548E-02, -2.291823E-08},
550 {0, 1.148966E-02, 5.658888E-08, 8.249439E-03, 4.063015E-08} };
552 double ccpamv[] = {0, 8.326827E-11, 1.843484E-11, 1.988712E-12, 1.881276E-12};
554 double DC1MME = 0.99999696E0;
569 for (K = 1; K <= 8; K++) {
571 DLOCAL=fmod(DCFEL(1,K)+DT*DCFEL(2,K)+DTSQ*DCFEL(3,K),DC2PI);
573 if (K == 1) DML=DLOCAL;
575 if (K != 1) FORBEL(K-1)=DLOCAL;
578 DEPS=fmod(DCEPS(1)+DT*DCEPS(2)+DTSQ*DCEPS(3), DC2PI);
580 for (K = 1; K <= 17; K++) {
582 SORBEL(K)=fmod(CCSEL(1,K)+T*CCSEL(2,K)+TSQ*CCSEL(3,K),CC2PI);
586 for (K = 1; K <= 4; K++) {
588 A=fmod(CCSEC(2,K)+T*CCSEC(3,K),CC2PI);
594 PERTL = CCSEC(1,1) *SN(1) +CCSEC(1,2)*SN(2)
595 +(CCSEC(1,3)+T*CCSEC3)*SN(3) +CCSEC(1,4)*SN(4);
601 for (K = 1; K <= 15; K++) {
603 A=fmod(DCARGS(1,K)+DT*DCARGS(2,K), DC2PI);
609 PERTL =PERTL+CCAMPS(1,K)*COSA+CCAMPS(2,K)*SINA;
611 PERTR =PERTR+CCAMPS(3,K)*COSA+CCAMPS(4,K)*SINA;
615 PERTLD=PERTLD+(CCAMPS(2,K)*COSA-CCAMPS(1,K)*SINA)*CCAMPS(5,K);
617 PERTRD=PERTRD+(CCAMPS(4,K)*COSA-CCAMPS(3,K)*SINA)*CCAMPS(5,K);
632 PHI=TWOE*((1.0-ESQ*0.125 )*sin(G[1])+E[1]*0.625 *sin(TWOG)
633 +ESQ*0.5416667 *sin(G[1]+TWOG) ) ;
641 DPSI=DPARAM/(DC1+E[1]*COSF);
643 PHID=TWOE*CCSGD*((1.0+ESQ*1.5 )*COSF+E[1]*(1.25 -SINF*SINF*0.5 ));
645 PSID=CCSGD*E[1]*SINF/sqrt(PARAM);
649 DRD=D1PDRO*(PSID+DPSI*PERTRD);
651 DRLD=D1PDRO*DPSI*(DCSLD+PHID+PERTLD);
653 DTL=fmod(DML+PHI+PERTL, DC2PI);
659 DXHD = DRD*DCOSLS-DRLD*DSINLS;
661 DYHD = DRD*DSINLS+DRLD*DCOSLS;
671 for (K = 1; K <= 3; K++) {
672 A=fmod(DCARGM(1,K)+DT*DCARGM(2,K), DC2PI);
678 PERTL =PERTL +CCAMPM(1,K)*SINA;
680 PERTLD=PERTLD+CCAMPM(2,K)*COSA;
682 PERTP =PERTP +CCAMPM(3,K)*COSA;
684 PERTPD=PERTPD-CCAMPM(4,K)*SINA;
693 SIGMA=CCKM/(1.0+PERTP);
695 A=SIGMA*(CCMLD+PERTLD);
699 DXHD=DXHD+A*SINLM+B*COSLM;
701 DYHD=DYHD-A*COSLM+B*SINLM;
703 DZHD= -SIGMA*CCFDI* cos(FORBEL(3));
711 for (K = 1; K <= 4; K++) {
719 TL=fmod(PLON+2.0*PECC* sin(PLON-POMG), CC2PI);
725 DXBD=DXBD+CCPAMV(K)*(SINLP(K)+PECC*sin(POMG));
727 DYBD=DYBD-CCPAMV(K)*(COSLP(K)+PECC*cos(POMG));
729 DZBD=DZBD-CCPAMV(K)*SORBEL(K+13)*cos(PLON-SORBEL(K+5));
735 DYAHD=DCOSEP*DYHD-DSINEP*DZHD;
736 DZAHD=DSINEP*DYHD+DCOSEP*DZHD;
737 DYABD=DCOSEP*DYBD-DSINEP*DZBD;
738 DZABD=DSINEP*DYBD+DCOSEP*DZBD;
748 for (N = 1; N <= 3; N++) {
749 DVELH[N]=DVELH[N]*1.4959787E8;
750 DVELB[N]=DVELB[N]*1.4959787E8;
782 compxy(
double inputr[19],
char inputc[4],
784 double utr,
double mod_juldat)
787 double t0, dl, theta0, pe, st0hg, stg;
789 double dvelb[4], dvelh[4];
790 double alp, del, beov, berv, EDV;
791 double HAR, phi, heov, herv;
794 double *olong, *olat, *alpha, *delta;
795 char signs[] =
"+++";
797 inpsgn[1] = inputc[1];
798 inpsgn[2] = inputc[2];
799 inpsgn[3] = inputc[3];
800 olong = rbuf + 7 - 1;
801 olat = rbuf + 10 - 1;
802 alpha = rbuf + 13 - 1;
803 delta = rbuf + 16 - 1;
809 jd = mod_juldat + 2400000.5;
815 if (olong[1] < 0 || olong[2] < 0 ||
816 olong[3] < 0 || inpsgn[1] ==
'-') {
818 olong[1] = fabs(olong[1]);
819 olong[2] = fabs(olong[2]);
820 olong[3] = fabs(olong[3]);
822 dl = olong[1]+olong[2]/60. +olong[3]/3600.;
823 if (signs[1] ==
'-') dl = -dl;
826 if (olat[1] < 0 || olat[2] < 0 ||
827 olat[3] < 0 || inpsgn[2] ==
'-') {
830 olat[1] = fabs(olat[1]);
831 olat[2] = fabs(olat[2]);
832 olat[3] = fabs(olat[3]);
836 phi = olat[1]+olat[2]/60. +olat[3]/3600.;
838 if (signs[2] ==
'-') phi = -phi;
840 phi = phi*M_PI/180. ;
844 alp = (alpha[1]*3600. +alpha[2]*60. +alpha[3])*M_PI/(12. *3600. );
846 if (delta[1] < 0 || delta[2] < 0 ||
847 delta[3] < 0 || inpsgn[3] ==
'-') {
851 delta[1] = fabs(delta[1]);
852 delta[2] = fabs(delta[2]);
853 delta[3] = fabs(delta[3]);
857 del = (delta[1]*3600.0 + delta[2]*60. + delta[3])
858 * M_PI/(3600. *180. );
862 if (signs[3] ==
'-') del = - del;
870 barvel(jd, 0.0, dvelh, dvelb);
878 dvelb[1]*cos(alp)*cos(del)+
879 dvelb[2]*sin(alp)*cos(del)+
883 dvelh[1]*cos(alp)*cos(del)+
884 dvelh[2]*sin(alp)*cos(del)+
897 jd0h = jd - (utr/24.0);
899 t0 = (jd0h-2415020. )/36525. ;
902 theta0 = 0.276919398 +100.0021359 *t0+0.000001075 *t0*t0 ;
906 theta0 = theta0 - pe;
916 stg = st0hg+utr*1.00273790931 ;
918 if (stg < dl) stg = stg +24. ;
923 if (STR >= 24. ) STR = STR-24. ;
930 EDV = -0.4654 * sin(HAR)* cos(del)* cos(phi);
969 outputr[1] = rbuf[1];
970 outputr[2] = rbuf[2];
971 outputr[3] = rbuf[3];
987 sinfo_baryvel(
const cpl_propertylist *raw_header,
994 char inputc[] =
"X+++";
1018 double ra_hour, ra_min, ra_sec;
1019 double dec_deg, dec_min, dec_sec;
1020 double lat_deg, lat_min, lat_sec;
1021 double lon_deg, lon_min, lon_sec;
1023 check( qc_ra = sinfo_pfits_get_ra(raw_header),
1024 "Error getting object right ascension");
1025 check( qc_dec = sinfo_pfits_get_dec(raw_header),
1026 "Error getting object declination");
1028 check( qc_geolat = sinfo_pfits_get_geolat(raw_header),
1029 "Error getting telescope latitude");
1030 check( qc_geolon = sinfo_pfits_get_geolon(raw_header),
1031 "Error getting telescope longitude");
1035 check( utr = sinfo_pfits_get_utc(raw_header),
1036 "Error reading UTC");
1037 check( mod_juldat = sinfo_pfits_get_mjdobs(raw_header),
1038 "Error julian date");
1040 deg2hms(qc_ra, &ra_hour, &ra_min, &ra_sec);
1041 deg2dms(qc_dec, &dec_deg, &dec_min, &dec_sec);
1042 deg2dms(qc_geolat, &lat_deg, &lat_min, &lat_sec);
1043 deg2dms(qc_geolon, &lon_deg, &lon_min, &lon_sec);
1046 inputr[7] = lon_deg;
1047 inputr[8] = lon_min;
1048 inputr[9] = lon_sec;
1051 rneg = (inputr[7]*3600.)+(inputr[8]*60.)+inputr[9];
1053 inputc[1] = (lon_deg >= 0) ?
'+' :
'-';
1055 if (rneg < 0) inputc[1] =
'-';
1058 inputr[10] = lat_deg;
1059 inputr[11] = lat_min;
1060 inputr[12] = lat_sec;
1063 rneg = (inputr[10]*3600.)+(inputr[11]*60.)+inputr[12];
1065 inputc[2] = (lat_deg >= 0) ?
'+' :
'-';
1067 if (rneg < 0) inputc[2] =
'-';
1070 inputr[13] = ra_hour;
1071 inputr[14] = ra_min;
1072 inputr[15] = ra_sec;
1075 inputr[16] = dec_deg;
1076 inputr[17] = dec_min;
1077 inputr[18] = dec_sec;
1080 inputc[3] = (dec_deg >= 0) ?
'+' :
'-';
1082 rneg = (inputr[16]*3600.)+(inputr[17]*60.)+inputr[18];
1084 if (rneg < 0) inputc[3] =
'-';
1095 compxy(inputr, inputc, outputr, utr, mod_juldat);
1097 sinfo_msg_debug(
" Total barycentric RV correction: %f km/s", outputr[1]);
1098 sinfo_msg_debug(
" Total heliocentric RV correction: %f km/s", outputr[2]);
1099 sinfo_msg_debug(
" (incl. diurnal RV correction of %f km/s)", outputr[3]);
1102 *bary_corr = outputr[1];
1103 *helio_corr = outputr[2];
1106 if (cpl_error_get_code() != CPL_ERROR_NONE) {
1107 sinfo_check_rec_status(0);
1109 return cpl_error_get_code();