5 #include <gsl/gsl_blas.h>
6 #include <gsl/gsl_linalg.h>
7 #include <gsl/gsl_matrix_double.h>
17 using namespace netCDF;
18 using namespace netCDF::exceptions;
20 #define VERSION "0.01"
29 int main(
int argc,
char *argv[]) {
31 cout <<
"geolocate_oci " <<
VERSION <<
" ("
32 << __DATE__ <<
" " << __TIME__ <<
")" << endl;
36 <<
"geolocate_oci input_l1a_filename output_geo_filename" << endl;
43 NcFile *l1afile =
new NcFile( argv[1], NcFile::read);
47 ncGrps[0] = l1afile->getGroup(
"scan_line_attributes");
48 ncGrps[1] = l1afile->getGroup(
"spatial_spectral_modes");
49 ncGrps[2] = l1afile->getGroup(
"engineering_data");
50 ncGrps[3] = l1afile->getGroup(
"navigation_data");
51 ncGrps[4] = l1afile->getGroup(
"onboard_calibration_data");
52 ncGrps[5] = l1afile->getGroup(
"science_data");
59 att = l1afile->getAtt(
"time_coverage_start");
60 att.getValues(tstart);
61 cout << tstart << endl;
63 att = l1afile->getAtt(
"time_coverage_end");
68 NcDim nscan_dim = l1afile->getDim(
"number_of_scans");
69 uint32_t
nscan = nscan_dim.getSize();
71 double *sstime =
new double[
nscan];
72 var = ncGrps[0].getVar(
"scan_start_time");
76 var = ncGrps[0].getVar(
"spin_ID");
79 uint8_t *hside =
new uint8_t[
nscan];
80 var = ncGrps[0].getVar(
"HAM_side");
86 sstime[sdim] = sstime[
i];
87 hside[sdim] = hside[
i];
92 NcDim natt_dim = l1afile->getDim(
"att_records");
93 uint32_t n_att_rec = natt_dim.getSize();
95 double *att_time =
new double[n_att_rec];
96 var = ncGrps[3].getVar(
"att_time");
97 var.getVar( att_time);
99 NcDim nquat_dim = l1afile->getDim(
"quaternion_elements");
100 uint32_t n_quat_elems = nquat_dim.getSize();
102 float **att_quat =
new float *[n_att_rec];
103 att_quat[0] =
new float[n_quat_elems*n_att_rec];
104 for (
size_t i=1;
i<n_att_rec;
i++)
105 att_quat[
i] = att_quat[
i-1] + n_quat_elems;
107 var = ncGrps[3].getVar(
"att_quat");
108 var.getVar( &att_quat[0][0]);
110 NcDim norb_dim = l1afile->getDim(
"orb_records");
111 uint32_t n_orb_rec = norb_dim.getSize();
113 double *orb_time =
new double[n_orb_rec];
114 var = ncGrps[3].getVar(
"orb_time");
115 var.getVar( orb_time);
117 float **orb_pos =
new float *[n_orb_rec];
118 orb_pos[0] =
new float[3*n_orb_rec];
119 for (
size_t i=1;
i<n_orb_rec;
i++) orb_pos[
i] = orb_pos[
i-1] + 3;
120 var = ncGrps[3].getVar(
"orb_pos");
121 var.getVar( &orb_pos[0][0]);
123 float **orb_vel =
new float *[n_orb_rec];
124 orb_vel[0] =
new float[3*n_orb_rec];
125 for (
size_t i=1;
i<n_orb_rec;
i++) orb_vel[
i] = orb_vel[
i-1] + 3;
126 var = ncGrps[3].getVar(
"orb_vel");
127 var.getVar( &orb_vel[0][0]);
129 NcDim ntilt_dim = l1afile->getDim(
"tilt_samples");
130 uint32_t n_tilts = ntilt_dim.getSize();
131 float *
tilt =
new float[n_tilts];
132 var = ncGrps[3].getVar(
"tilt");
138 double revpsec, secpline;
139 int32_t *mspin =
new int32_t[
nscan];
140 int32_t *ot_10us =
new int32_t[
nscan];
141 uint8_t *enc_count =
new uint8_t[
nscan];
143 NcDim nenc_dim = l1afile->getDim(
"encoder_samples");
144 uint32_t nenc = nenc_dim.getSize();
146 float **hamenc =
new float *[
nscan];
147 hamenc[0] =
new float[nenc*
nscan];
148 for (
size_t i=1;
i<
nscan;
i++) hamenc[
i] = hamenc[
i-1] + nenc;
150 float **rtaenc =
new float *[
nscan];
151 rtaenc[0] =
new float[nenc*
nscan];
152 for (
size_t i=1;
i<
nscan;
i++) rtaenc[
i] = rtaenc[
i-1] + nenc;
155 secpline, mspin, ot_10us, enc_count, hamenc, rtaenc);
165 double omegae = 7.29211585494e-5;
169 for (
size_t i = 0;
i < n_orb_rec;
i++) {
172 for (
size_t j = 0;
j < 3;
j++) {
173 posr[
i][
j] = ecmat[
j][0] * orb_pos[
i][0] +
174 ecmat[
j][1] * orb_pos[
i][1] +
175 ecmat[
j][2] * orb_pos[
i][2];
176 velr[
i][
j] = ecmat[
j][0] * orb_vel[
i][0] +
177 ecmat[
j][1] * orb_vel[
i][1] +
178 ecmat[
j][2] * orb_vel[
i][2];
180 velr[
i][0] += posr[
i][1] * omegae;
181 velr[
i][1] -= posr[
i][0] * omegae;
185 for (
size_t i = 0;
i < n_att_rec;
i++) {
186 double ecq[4], qt2[4];
191 memcpy(qt1, &att_quat[
i][0], 3 *
sizeof(
float));
192 qt1[3] = att_quat[
i][3];
194 qprod(ecq, qt1, qt2);
195 for (
size_t j = 0;
j < 4;
j++) quatr[
i][
j] = qt2[
j];
202 NcDim spatzn_dim = l1afile->getDim(
"spatial_zones");
203 uint32_t spatzn = spatzn_dim.getSize();
205 int16_t *
dtype =
new int16_t[spatzn];
206 var = ncGrps[1].getVar(
"spatial_zone_data_type");
209 int16_t *
lines =
new int16_t[spatzn];
210 var = ncGrps[1].getVar(
"spatial_zone_lines");
213 int16_t *iagg =
new int16_t[spatzn];
214 var = ncGrps[1].getVar(
"spatial_aggregation");
217 float clines[32400], slines[4050];
218 uint16_t pcdim, psdim;
220 double ev_toff, deltc[32400], delts[4050];
222 clines, slines, deltc, delts, iret);
224 cout <<
"No Earth view in file: " << argv[1] << endl;
229 double *evtime =
new double[
nscan];
230 for (
size_t i = 0;
i <
nscan;
i++) evtime[
i] = sstime[
i] + ev_toff;
236 orb_interp(n_orb_rec, sdim, orb_time, posr, velr, evtime, posi, veli);
239 q_interp(n_att_rec, sdim, att_time, quatr, evtime, quati);
241 float *
xlon =
new float[sdim * psdim]();
242 float *
xlat =
new float[sdim * psdim]();
243 short *
solz =
new short[sdim * psdim]();
244 short *
sola =
new short[sdim * psdim]();
245 short *
senz =
new short[sdim * psdim]();
246 short *
sena =
new short[sdim * psdim]();
247 uint8_t *qfl =
new uint8_t[sdim * psdim]();
248 short *
range =
new short[sdim * psdim]();
249 short *height =
new short[sdim * psdim]();
250 short *sfl =
new short[sdim]();
253 for (
size_t i = 0;
i < sdim * psdim;
i++) {
264 float **pview =
new float *[psdim];
265 pview[0] =
new float[3*psdim];
266 for (
size_t i=1;
i<psdim;
i++) pview[
i] = pview[
i-1] + 3;
270 l_sun(sdim,
iyr, iday, evtime, sunr);
275 NcFile *geoLUTfile =
new NcFile( argv[2], NcFile::read);
278 NcGroup gidTime, gidCT, gidRTA_HAM;
280 gidTime = geoLUTfile->getGroup(
"time_params");
281 var = gidTime.getVar(
"master_clock");
283 var = gidTime.getVar(
"MCE_clock");
286 gidCT = geoLUTfile->getGroup(
"coord_trans");
287 var = gidCT.getVar(
"sc_to_tilt");
289 var = gidCT.getVar(
"tilt_axis");
291 var = gidCT.getVar(
"tilt_angles");
293 var = gidCT.getVar(
"tilt_to_oci_mech");
295 var = gidCT.getVar(
"oci_mech_to_oci_opt");
298 gidRTA_HAM = geoLUTfile->getGroup(
"RTA_HAM_params");
299 var = gidRTA_HAM.getVar(
"RTA_axis");
301 var = gidRTA_HAM.getVar(
"HAM_axis");
303 var = gidRTA_HAM.getVar(
"HAM_AT_angles");
305 var = gidRTA_HAM.getVar(
"HAM_CT_angles");
307 var = gidRTA_HAM.getVar(
"RTA_enc_scale");
309 var = gidRTA_HAM.getVar(
"HAM_enc_scale");
311 var = gidRTA_HAM.getVar(
"RTA_nadir");
317 gsl_matrix *sc2tiltp = gsl_matrix_alloc(3, 3);
318 gsl_matrix *sc2ocim = gsl_matrix_alloc(3, 3);
319 gsl_matrix *sc_to_oci = gsl_matrix_alloc(3, 3);
320 gsl_matrix *smat = gsl_matrix_alloc(3, 3);
322 double *thetap =
new double[psdim]();
327 for (
size_t i = 0;
i < sdim;
i++) {
328 if (sstime[
i] != -999.0) {
347 A = gsl_matrix_view_array( (
double *) geoLUT.
sc_to_tilt, 3, 3);
348 B = gsl_matrix_view_array( (
double *) tiltm, 3, 3);
349 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0,
350 &A.matrix, &B.matrix, 0.0, sc2tiltp);
351 ptr_C = gsl_matrix_ptr(sc2tiltp, 0, 0);
355 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0,
356 sc2tiltp, &B.matrix, 0.0, sc2ocim);
357 ptr_C = gsl_matrix_ptr(sc2ocim, 0, 0);
361 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0,
362 sc2ocim, &B.matrix, 0.0, sc_to_oci);
363 ptr_C = gsl_matrix_ptr(sc_to_oci, 0, 0);
368 qtom(quati[
i], qmat);
371 B = gsl_matrix_view_array(&qmat[0][0], 3, 3);
372 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0,
373 sc_to_oci, &B.matrix, 0.0, smat);
379 ptr_C = gsl_matrix_ptr(smat, 0, 0);
381 scan_ell(posi[
i], (
double(*)[3])ptr_C, coef);
385 revpsec, ppr_off, mspin, ot_10us, enc_count, &hamenc[0],
386 &rtaenc[0], pview, thetap, iret);
390 size_t ip =
i * psdim;
392 sunr[
i], pview, psdim, delts[
i], &
xlat[ip], &
xlon[ip],
399 gsl_matrix_free(smat);
400 gsl_matrix_free(sc2tiltp);
401 gsl_matrix_free(sc2ocim);
402 gsl_matrix_free(sc_to_oci);
405 geo_name.assign(argv[3]);
412 "$OCDATAROOT/oci/OCI_GEO_Data_Structure.cdl",
413 sdim, &geo_ncid, geo_gid);
442 count.push_back(sdim);
444 var = outfile.
ncGrps[0].getVar(
"time");
447 var = outfile.
ncGrps[0].getVar(
"HAM_side");
450 var = outfile.
ncGrps[0].getVar(
"scan_quality");
455 var = outfile.
ncGrps[2].getVar(
"att_quat");
461 var = outfile.
ncGrps[2].getVar(
"att_ang");
464 var = outfile.
ncGrps[2].getVar(
"orb_pos");
467 var = outfile.
ncGrps[2].getVar(
"orb_vel");
470 var = outfile.
ncGrps[2].getVar(
"sun_ref");
474 count.push_back(psdim);
476 var = outfile.
ncGrps[1].getVar(
"latitude");
479 var = outfile.
ncGrps[1].getVar(
"longitude");
482 var = outfile.
ncGrps[1].getVar(
"quality_flag");
485 var = outfile.
ncGrps[1].getVar(
"sensor_azimuth");
488 var = outfile.
ncGrps[1].getVar(
"sensor_zenith");
491 var = outfile.
ncGrps[1].getVar(
"solar_azimuth");
494 var = outfile.
ncGrps[1].getVar(
"solar_zenith");
497 var = outfile.
ncGrps[1].getVar(
"range");
500 var = outfile.
ncGrps[1].getVar(
"height");
531 uint32_t
nscan, uint32_t nenc, int32_t& ppr_off,
532 double& revpsec,
double&secpline, int32_t *mspin,
533 int32_t *ot_10us, uint8_t *enc_count,
534 float **hamenc,
float **rtaenc) {
536 NcDim mce_dim = l1afile->getDim(
"MCE_block");
537 uint32_t mce_blk = mce_dim.getSize();
538 NcDim ddc_dim = l1afile->getDim(
"DDC_tlm");
539 uint32_t nddc = ddc_dim.getSize();
540 NcDim tlm_dim = l1afile->getDim(
"tlm_packets");
541 uint32_t ntlm = tlm_dim.getSize();
543 uint8_t **mtlm =
new uint8_t *[
nscan];
544 mtlm[0] =
new uint8_t[mce_blk*
nscan];
545 for (
size_t i=1;
i<
nscan;
i++) mtlm[
i] = mtlm[
i-1] + mce_blk;
547 int16_t **enc =
new int16_t *[
nscan];
548 enc[0] =
new int16_t[4*nenc*
nscan];
549 for (
size_t i=1;
i<
nscan;
i++) enc[
i] = enc[
i-1] + 4*nenc;
551 uint8_t **ddctlm =
new uint8_t *[ntlm];
552 ddctlm[0] =
new uint8_t[nddc*ntlm];
553 for (
size_t i=1;
i<ntlm;
i++) ddctlm[
i] = ddctlm[
i-1] + nddc;
578 var = egid.getVar(
"MCE_telemetry");
579 var.getVar( &mtlm[0][0]);
581 var = egid.getVar(
"MCE_encoder_data");
583 count.push_back(4*nenc);
584 var.getVar( &enc[0][0]);
586 var = egid.getVar(
"MCE_spin_ID");
589 var = egid.getVar(
"DDC_telemetry");
590 var.getVar( &ddctlm[0][0]);
592 int32_t max_enc_cts = 131072;
593 double clock[2] = {1.36e8,1.0e8};
597 uint32_t ref_pulse_div[2];
598 memcpy( &ui32, &mtlm[0][0], 4);
599 ref_pulse_div[0] =
SWAP_4( ui32) % 16777216;
600 memcpy( &ui32, &mtlm[0][4], 4);
601 ref_pulse_div[1] =
SWAP_4( ui32) % 16777216;
603 int32_t ref_pulse_sel = mtlm[0][9] / 128;
605 revpsec = clock[ref_pulse_sel] / 2 / max_enc_cts /
606 (ref_pulse_div[ref_pulse_sel]/256.0 + 1);
609 memcpy( &ui32, &mtlm[0][8], 4);
610 ppr_off =
SWAP_4( ui32) % max_enc_cts;
612 memcpy( &ui32, &mtlm[
i][368], 4);
613 ot_10us[
i] =
SWAP_4( ui32) % 4;
618 memcpy( &ui16, &ddctlm[0][346], 2);
619 int32_t tditime =
SWAP_2( ui16);
620 secpline = (tditime+1) / clock[0];
623 for (
size_t i=0;
i<
nscan;
i++) enc_count[
i] = mtlm[
i][475];
624 float enc_s = 81.0 / 2560;
626 for (
size_t j=0;
j<nenc;
j++) {
627 hamenc[
i][
j] = enc[
i][4*
j+0] * enc_s;
628 rtaenc[
i][
j] = enc[
i][4*
j+1] * enc_s;
661 double xnut[3][3], ut1utc;
666 double day =
idy + (sec + ut1utc) / 86400;
667 double gha, gham[3][3];
670 gham[0][0] = cos(gha /
RADEG);
671 gham[1][1] = cos(gha /
RADEG);
673 gham[0][1] = sin(gha /
RADEG);
674 gham[1][0] = -sin(gha /
RADEG);
682 gsl_matrix_view A = gsl_matrix_view_array(&gham[0][0], 3, 3);
683 gsl_matrix_view B = gsl_matrix_view_array(&xnut[0][0], 3, 3);
684 gsl_matrix *
C = gsl_matrix_alloc(3, 3);
686 gsl_blas_dgemm(CblasNoTrans, CblasTrans, 1.0, &A.matrix, &B.matrix, 0.0,
C);
688 gsl_matrix_view D = gsl_matrix_view_array(&j2mod[0][0], 3, 3);
689 gsl_matrix *E = gsl_matrix_alloc(3, 3);
690 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0,
C, &D.matrix, 0.0, E);
691 double *ptr_E = gsl_matrix_ptr(E, 0, 0);
693 memcpy(ecmat, ptr_E, 9 *
sizeof(
double));
716 double t =
jday(iyear, 1, iday) - (
double)2451545.5 + sec / 86400;
719 double zeta0 =
t * (2306.2181 + 0.302 *
t + 0.018 *
t *
t) /
RADEG / 3600;
720 double thetap =
t * (2004.3109 - 0.4266 *
t - 0.04160 *
t *
t) /
RADEG / 3600;
721 double xip =
t * (2306.2181 + 1.095 *
t + 0.018 *
t *
t) /
RADEG / 3600;
723 j2mod[0][0] = -sin(zeta0) * sin(xip) + cos(zeta0) * cos(xip) * cos(thetap);
724 j2mod[0][1] = -cos(zeta0) * sin(xip) - sin(zeta0) * cos(xip) * cos(thetap);
725 j2mod[0][2] = -cos(xip) * sin(thetap);
726 j2mod[1][0] = sin(zeta0) * cos(xip) + cos(zeta0) * sin(xip) * cos(thetap);
727 j2mod[1][1] = cos(zeta0) * cos(xip) - sin(zeta0) * sin(xip) * cos(thetap);
728 j2mod[1][2] = -sin(xip) * sin(thetap);
729 j2mod[2][0] = cos(zeta0) * sin(thetap);
730 j2mod[2][1] = -sin(zeta0) * sin(thetap);
731 j2mod[2][2] = cos(thetap);
740 double t =
jday(iyear, 1, iday) - (
double)2451545.5;
742 double xls, gs, xlm,
omega;
743 double dpsi, eps, epsm;
747 xnut[0][0] = cos(dpsi /
RADEG);
748 xnut[1][0] = -sin(dpsi /
RADEG) * cos(epsm /
RADEG);
749 xnut[2][0] = -sin(dpsi /
RADEG) * sin(epsm /
RADEG);
750 xnut[0][1] = sin(dpsi /
RADEG) * cos(eps /
RADEG);
751 xnut[1][1] = cos(dpsi /
RADEG) * cos(eps /
RADEG) * cos(epsm /
RADEG) +
753 xnut[2][1] = cos(dpsi /
RADEG) * cos(eps /
RADEG) * sin(epsm /
RADEG) -
755 xnut[0][2] = sin(dpsi /
RADEG) * sin(eps /
RADEG);
756 xnut[1][2] = cos(dpsi /
RADEG) * sin(eps /
RADEG) * cos(epsm /
RADEG) -
758 xnut[2][2] = cos(dpsi /
RADEG) * sin(eps /
RADEG) * sin(epsm /
RADEG) +
775 xls = (
double)280.46592 + ((
double)0.9856473516) *
t;
776 xls = fmod(xls, (
double)360);
779 gs = (
double)357.52772 + ((
double)0.9856002831) *
t;
780 gs = fmod(gs, (
double)360);
783 xlm = (
double)218.31643 + ((
double)13.17639648) *
t;
784 xlm = fmod(xlm, (
double)360);
794 double &dpsi,
double &eps,
double &epsm) {
807 1.3187 * sin(2. * xls /
RADEG) + 0.1426 * sin(gs /
RADEG) -
808 0.2274 * sin(2. * xlm /
RADEG);
811 epsm = (
double)23.439291 - ((
double)3.560e-7) *
t;
814 double deps = 9.2025 * cos(
omega /
RADEG) + 0.5736 * cos(2. * xls /
RADEG);
817 eps = epsm + deps / 3600;
828 static int32_t ijd[25000];
829 static double ut1[25000];
830 string utcpole =
"$OCVARROOT/modis/utcpole.dat";
831 static bool first =
true;
838 ifstream utcpfile(
utcpole.c_str());
839 if (utcpfile.is_open()) {
840 getline(utcpfile,
line);
841 getline(utcpfile,
line);
842 while (getline(utcpfile,
line)) {
845 istr.str(
line.substr(0, 5));
848 istr.str(
line.substr(44, 9));
856 cout <<
utcpole.c_str() <<
" not found" << endl;
862 int mjd =
jday(iyear, 1, iday) - 2400000;
885 double fday =
day - iday;
887 double t =
jd - (
double)2451545.5 + fday;
890 double gmst = (
double)100.4606184 + (
double)0.9856473663 *
t +
894 double xls, gs, xlm,
omega;
895 double dpsi, eps, epsm;
900 gha = gmst + dpsi * cos(eps /
RADEG) + fday * 360;
901 gha = fmod(gha, (
double)360);
906 int mtoq(
double rm[3][3],
double q[4]) {
913 double cphi = (rm[0][0] + rm[1][1] + rm[2][2] - 1) / 2;
917 double ssphi = (pow(rm[0][1] - rm[1][0], 2) +
918 pow(rm[2][0] - rm[0][2], 2) +
919 pow(rm[1][2] - rm[2][1], 2)) /
921 phi = asin(sqrt(ssphi));
922 if (
cphi < 0) phi =
PI - phi;
926 e[0] = (rm[2][1] - rm[1][2]) / (sin(phi) * 2);
927 e[1] = (rm[0][2] - rm[2][0]) / (sin(phi) * 2);
928 e[2] = (rm[1][0] - rm[0][1]) / (sin(phi) * 2);
929 double norm = sqrt(e[0] * e[0] + e[1] * e[1] + e[2] * e[2]);
935 q[0] = e[0] * sin(phi / 2);
936 q[1] = e[1] * sin(phi / 2);
937 q[2] = e[2] * sin(phi / 2);
943 int qprod(
double q1[4],
float q2[4],
double q3[4]) {
946 q3[0] = q1[0] * q2[3] + q1[1] * q2[2] - q1[2] * q2[1] + q1[3] * q2[0];
947 q3[1] = -q1[0] * q2[2] + q1[1] * q2[3] + q1[2] * q2[0] + q1[3] * q2[1];
948 q3[2] = q1[0] * q2[1] - q1[1] * q2[0] + q1[2] * q2[3] + q1[3] * q2[2];
949 q3[3] = -q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] + q1[3] * q2[3];
954 int qprod(
float q1[4],
float q2[4],
float q3[4]) {
957 q3[0] = q1[0] * q2[3] + q1[1] * q2[2] - q1[2] * q2[1] + q1[3] * q2[0];
958 q3[1] = -q1[0] * q2[2] + q1[1] * q2[3] + q1[2] * q2[0] + q1[3] * q2[1];
959 q3[2] = q1[0] * q2[1] - q1[1] * q2[0] + q1[2] * q2[3] + q1[3] * q2[2];
960 q3[3] = -q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] + q1[3] * q2[3];
996 double a0[3], a1[3], a2[3], a3[3];
1011 for (
size_t i = 0;
i < sdim;
i++) {
1013 for (
size_t j = ind;
j < n_orb_rec;
j++) {
1021 double dt = torb[ind + 1] - torb[ind];
1022 for (
size_t j = 0;
j < 3;
j++) {
1024 a1[
j] =
v[ind][
j] * dt;
1025 a2[
j] = 3 *
p[ind + 1][
j] - 3 *
p[ind][
j] - 2 *
v[ind][
j] * dt -
1027 a3[
j] = 2 *
p[ind][
j] - 2 *
p[ind + 1][
j] +
v[ind][
j] * dt +
1032 double x = (
time[
i] - torb[ind]) / dt;
1035 for (
size_t j = 0;
j < 3;
j++) {
1036 posi[
i][
j] = a0[
j] + a1[
j] *
x + a2[
j] * x2 + a3[
j] * x3;
1037 veli[
i][
j] = (a1[
j] + 2 * a2[
j] *
x + 3 * a3[
j] * x2) / dt;
1051 for (
size_t i = 0;
i < sdim;
i++) {
1053 for (
size_t j = ind;
j < n_att_rec;
j++) {
1061 double dt = tq[ind + 1] - tq[ind];
1063 qin[0] = -
q[ind][0];
1064 qin[1] = -
q[ind][1];
1065 qin[2] = -
q[ind][2];
1069 qprod(qin,
q[ind + 1], qr);
1070 memcpy(e, qr, 3 *
sizeof(
double));
1071 double sto2 = sqrt(e[0] * e[0] + e[1] * e[1] + e[2] * e[2]);
1072 for (
size_t j = 0;
j < 3;
j++) e[
j] /= sto2;
1075 double x = (
time[
i] - tq[ind]) / dt;
1076 float qri[4], qp[4];
1077 for (
size_t j = 0;
j < 3;
j++) qri[
j] = e[
j] * sto2 *
x;
1080 memcpy(qi[
i], qp, 4 *
sizeof(
float));
1086 int l_sun(
size_t sdim, int32_t
iyr, int32_t iday,
double *sec,
1095 for (
size_t i = 0;
i < sdim;
i++) {
1096 double day = iday + sec[
i] / 86400;
1099 double ghar = gha /
RADEG;
1102 float temp0 = sunr[
i][0] * cos(ghar) + sunr[
i][1] * sin(ghar);
1103 float temp1 = sunr[
i][1] * cos(ghar) - sunr[
i][0] * sin(ghar);
1120 float xk = 0.0056932;
1124 int16_t iyear =
iyr;
1127 for (
size_t i = 0;
i < sdim;
i++) {
1129 jday(iyear, 1, iday) - (
double)2451545.0 + (sec[
i] - 43200) / 86400;
1131 double xls, gs, xlm,
omega;
1132 double dpsi, eps, epsm;
1141 double g2 = 50.40828 + 1.60213022 *
t;
1142 g2 = fmod(g2, (
double)360);
1145 double g4 = 19.38816 + 0.52402078 *
t;
1146 g4 = fmod(g4, (
double)360);
1149 double g5 = 20.35116 + 0.08309121 *
t;
1150 g5 = fmod(g5, (
double)360);
1154 1.00014 - 0.01671 * cos(gs /
RADEG) - 0.00014 * cos(2. * gs /
RADEG);
1157 double dls = (6893. - 4.6543463e-4 *
t) * sin(gs /
RADEG) +
1158 72. * sin(2. * gs /
RADEG) - 7. * cos((gs - g5) /
RADEG) +
1159 6. * sin((xlm - xls) /
RADEG) +
1160 5. * sin((4. * gs - 8. * g4 + 3. * g5) /
RADEG) -
1161 5. * cos((2. * gs - 2. * g2) /
RADEG) -
1162 4. * sin((gs - g2) /
RADEG) +
1163 4. * cos((4. * gs - 8. * g4 + 3. * g5) /
RADEG) +
1164 3. * sin((2. * gs - 2. * g2) /
RADEG) - 3. * sin(g5 /
RADEG) -
1165 3. * sin((2. * gs - 2. * g5) /
RADEG);
1167 double xlsg = xls + dls / 3600;
1171 double xlsa = xlsg + dpsi - xk / rs;
1174 sun[
i][0] = cos(xlsa /
RADEG);
1185 rm[0][0] =
q[0] *
q[0] -
q[1] *
q[1] -
q[2] *
q[2] +
q[3] *
q[3];
1186 rm[0][1] = 2 * (
q[0] *
q[1] +
q[2] *
q[3]);
1187 rm[0][2] = 2 * (
q[0] *
q[2] -
q[1] *
q[3]);
1188 rm[1][0] = 2 * (
q[0] *
q[1] -
q[2] *
q[3]);
1189 rm[1][1] = -
q[0] *
q[0] +
q[1] *
q[1] -
q[2] *
q[2] +
q[3] *
q[3];
1190 rm[1][2] = 2 * (
q[1] *
q[2] +
q[0] *
q[3]);
1191 rm[2][0] = 2 * (
q[0] *
q[2] +
q[1] *
q[3]);
1192 rm[2][1] = 2 * (
q[1] *
q[2] -
q[0] *
q[3]);
1193 rm[2][2] = -
q[0] *
q[0] -
q[1] *
q[1] +
q[2] *
q[2] +
q[3] *
q[3];
1198 int scan_ell(
float p[3],
double sm[3][3],
double coef[10]) {
1213 double re = 6378.137;
1214 double f = 1 / 298.257;
1215 double omf2 = (1 -
f) * (1 -
f);
1221 coef[0] = 1 + (
rd - 1) * sm[0][2] * sm[0][2];
1222 coef[1] = 1 + (
rd - 1) * sm[1][2] * sm[1][2];
1223 coef[2] = 1 + (
rd - 1) * sm[2][2] * sm[2][2];
1224 coef[3] = (
rd - 1) * sm[0][2] * sm[1][2] * 2;
1225 coef[4] = (
rd - 1) * sm[0][2] * sm[2][2] * 2;
1226 coef[5] = (
rd - 1) * sm[1][2] * sm[2][2] * 2;
1227 coef[6] = (sm[0][0] *
p[0] + sm[0][1] *
p[1] + sm[0][2] *
p[2] *
rd) * 2;
1228 coef[7] = (sm[1][0] *
p[0] + sm[1][1] *
p[1] + sm[1][2] *
p[2] *
rd) * 2;
1229 coef[8] = (sm[2][0] *
p[0] + sm[2][1] *
p[1] + sm[2][2] *
p[2] *
rd) * 2;
1230 coef[9] =
p[0] *
p[0] +
p[1] *
p[1] +
p[2] *
p[2] *
rd -
re *
re;
1236 float sunr[3],
float **pview,
size_t npix,
double delt,
1295 float f = 1 / 298.257;
1296 float omf2 = (1 -
f) * (1 -
f);
1297 gsl_vector *
C = gsl_vector_alloc(3);
1299 for (
size_t i = 0;
i <
npix;
i++) {
1303 coef[0] * pview[
i][0] * pview[
i][0] +
1304 coef[1] * pview[
i][1] * pview[
i][1] +
1305 coef[2] * pview[
i][2] * pview[
i][2] +
1306 coef[3] * pview[
i][0] * pview[
i][1] +
1307 coef[4] * pview[
i][0] * pview[
i][2] +
1308 coef[5] * pview[
i][1] * pview[
i][2];
1311 coef[6] * pview[
i][0] + coef[7] * pview[
i][1] + coef[8] * pview[
i][2];
1315 double r =
p *
p - 4 *
q * o;
1330 double d = (-
p - sqrt(
r)) / (2 * o);
1332 for (
size_t j = 0;
j < 3;
j++) x1[
j] = d * pview[
i][
j];
1335 float re = 6378.137;
1336 double omegae = 7.29211585494e-05;
1339 double rg =
re*(1.-
f)/sqrt(1.-(2.-
f)*
f*clatg*clatg);
1341 v[0] = (vel[0] -
pos[1]*omegae) *
rg /
pm;
1342 v[1] = (vel[1] -
pos[0]*omegae) *
rg /
pm;
1343 v[2] = vel[2] *
rg /
pm;
1346 gsl_matrix_view A = gsl_matrix_view_array((
double *)smat, 3, 3);
1347 gsl_vector_view B = gsl_vector_view_array(x1, 3);
1349 gsl_blas_dgemv(CblasTrans, 1.0, &A.matrix, &B.vector, 0.0,
C);
1351 float rh[3], geovec[3];
1352 double *ptr_C = gsl_vector_ptr(
C, 0);
1353 for (
size_t j = 0;
j < 3;
j++) {
1355 geovec[
j] =
pos[
j] + rh[
j] +
v[
j]*delt;
1359 float uxy = geovec[0] * geovec[0] + geovec[1] * geovec[1];
1360 float temp = sqrt(geovec[2] * geovec[2] +
omf2 *
omf2 * uxy);
1363 up[0] =
omf2 * geovec[0] / temp;
1364 up[1] =
omf2 * geovec[1] / temp;
1365 up[2] = geovec[2] / temp;
1366 float upxy = sqrt(up[0] * up[0] + up[1] * up[1]);
1369 ea[0] = -up[1] / upxy;
1370 ea[1] = up[0] / upxy;
1375 no[0] = -up[2] * ea[1];
1376 no[1] = up[2] * ea[0];
1377 no[2] = up[0] * ea[1] - up[1] * ea[0];
1386 rl[0] = -ea[0] * rh[0] - ea[1] * rh[1] - ea[2] * rh[2];
1387 rl[1] = -no[0] * rh[0] - no[1] * rh[1] - no[2] * rh[2];
1388 rl[2] = -up[0] * rh[0] - up[1] * rh[1] - up[2] * rh[2];
1390 sl[0] = sunr[0] * ea[0] + sunr[1] * ea[1] + sunr[2] * ea[2];
1391 sl[1] = sunr[0] * no[0] + sunr[1] * no[1] + sunr[2] * no[2];
1392 sl[2] = sunr[0] * up[0] + sunr[1] * up[1] + sunr[2] * up[2];
1396 atan2(sqrt(sl[0] * sl[0] + sl[1] * sl[1]), sl[2]));
1399 if (
solz[
i] > 0.01)
sola[
i] = (short)(100 *
RADEG * atan2(sl[0], sl[1]));
1403 atan2(sqrt(rl[0] * rl[0] + rl[1] * rl[1]), rl[2]));
1406 if (
senz[
i] > 0.01)
sena[
i] = (short)(100 *
RADEG * atan2(rl[0], rl[1]));
1415 int mat2rpy(
float pos[3],
float vel[3],
double smat[3][3],
float rpy[3]) {
1432 double f = 1 / (
double)298.257;
1433 double omegae = 7.29211585494e-5;
1434 double omf2 = (1 -
f) * (1 -
f);
1438 for (
size_t j = 0;
j < 3;
j++) {
1442 v[0] -=
p[1] * omegae;
1443 v[1] +=
p[0] * omegae;
1446 double pm = sqrt(
p[0] *
p[0] +
p[1] *
p[1] +
p[2] *
p[2]);
1447 double omf2p = (
omf2 * rem +
pm - rem) /
pm;
1448 double pxy =
p[0] *
p[0] +
p[1] *
p[1];
1449 double temp = sqrt(
p[2] *
p[2] + omf2p * omf2p * pxy);
1452 z[0] = -omf2p *
p[0] / temp;
1453 z[1] = -omf2p *
p[1] / temp;
1454 z[2] = -
p[2] / temp;
1458 on[0] =
v[1] * z[2] -
v[2] * z[1];
1459 on[1] =
v[2] * z[0] -
v[0] * z[2];
1460 on[2] =
v[0] * z[1] -
v[1] * z[0];
1462 double onm = sqrt(
on[0] *
on[0] +
on[1] *
on[1] +
on[2] *
on[2]);
1465 for (
size_t j = 0;
j < 3;
j++)
y[
j] = -
on[
j] / onm;
1469 x[0] =
y[1] * z[2] -
y[2] * z[1];
1470 x[1] =
y[2] * z[0] -
y[0] * z[2];
1471 x[2] =
y[0] * z[1] -
y[1] * z[0];
1475 memcpy(&om[0][0], &
x, 3 *
sizeof(
double));
1476 memcpy(&om[1][0], &
y, 3 *
sizeof(
double));
1477 memcpy(&om[2][0], &z, 3 *
sizeof(
double));
1481 gsl_matrix_view rm_mat = gsl_matrix_view_array(&rm[0][0], 3, 3);
1485 gsl_permutation *perm = gsl_permutation_alloc(3);
1488 gsl_matrix_view B = gsl_matrix_view_array(&om[0][0], 3, 3);
1489 gsl_linalg_LU_decomp(&B.matrix, perm, &
s);
1493 gsl_matrix_view inv_mat = gsl_matrix_view_array(&inv[0][0], 3, 3);
1495 gsl_linalg_LU_invert(&B.matrix, perm, &inv_mat.matrix);
1497 gsl_matrix_view A = gsl_matrix_view_array(&smat[0][0], 3, 3);
1499 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, &A.matrix, &inv_mat.matrix,
1500 0.0, &rm_mat.matrix);
1502 gsl_permutation_free(perm);
1505 rpy[0] =
RADEG * atan(-rm[2][1] / rm[2][2]);
1506 double cosp = sqrt(rm[2][1] * rm[2][1] + rm[2][2] * rm[2][2]);
1507 if (rm[2][2] < 0) cosp *= -1;
1508 rpy[1] =
RADEG * atan2(rm[2][0], cosp);
1509 rpy[2] =
RADEG * atan(-rm[1][0] / rm[0][0]);
1519 size_t sdim,
int *ncid,
int *gid) {
1524 catch ( NcException& e) {
1526 cerr <<
"Failure creating OCI GEO file: " <<
filename << endl;
1530 ifstream output_data_structure;
1532 string dataStructureFile;
1534 dataStructureFile.assign( cdlfile);
1537 output_data_structure.open( dataStructureFile.c_str(), ifstream::in);
1538 if ( output_data_structure.fail() ==
true) {
1539 cout <<
"\"" << dataStructureFile.c_str() <<
"\" not found" << endl;
1545 getline( output_data_structure,
line);
1546 size_t pos =
line.find(
"dimensions:");
1547 if (
pos == 0)
break;
1554 getline( output_data_structure,
line);
1555 size_t pos =
line.find(
" = ");
1556 if (
pos == string::npos)
break;
1559 istringstream iss(
line.substr(
pos+2, string::npos));
1564 iss >> skipws >>
line;
1569 if (
line.compare(
"number_of_scans") == 0) {
1574 ncDims[ndims++] =
geofile->addDim(
line, dimSize);
1576 catch ( NcException& e) {
1578 cerr <<
"Failure creating dimension: " <<
line.c_str() << endl;
1582 cout <<
"Dimension Name: " <<
line.c_str() <<
" Dimension Size: "
1589 getline( output_data_structure,
line);
1590 size_t pos =
line.find(
"// global attributes");
1591 if (
pos == 0)
break;
1595 getline( output_data_structure,
line);
1596 size_t pos =
line.find(
" = ");
1597 if (
pos == string::npos)
break;
1602 attValue.assign(
line.substr(
pos+4));
1603 size_t posQuote = attValue.find(
"\"");
1604 attValue.assign(attValue.substr(0, posQuote));
1606 istringstream iss(
line.substr(
pos+2));
1609 iss >> skipws >>
line;
1612 if (
line.compare(
"//") == 0)
continue;
1615 attName.assign(
line.substr(1).c_str());
1618 if (attName.compare(
"orbit_number") == 0)
continue;
1619 if (attName.compare(
"history") == 0)
continue;
1620 if (attName.compare(
"format_version") == 0)
continue;
1621 if (attName.compare(
"instrument_number") == 0)
continue;
1622 if (attName.compare(
"pixel_offset") == 0)
continue;
1623 if (attName.compare(
"number_of_filled_scans") == 0)
continue;
1625 cout << attName.c_str() <<
" " << attValue.c_str() << endl;
1628 geofile->putAtt(attName, attValue);
1630 catch ( NcException& e) {
1632 cerr <<
"Failure creating attribute: " + attName << endl;
1642 getline( output_data_structure,
line);
1646 if (
line.substr(0,1).compare(
"}") == 0) {
1647 output_data_structure.close();
1652 size_t pos =
line.find(
"group:");
1658 istringstream iss(
line.substr(6, string::npos));
1659 iss >> skipws >>
line;
1673 string flag_meanings;
1676 double fill_value=0.0;
1678 vector<NcDim> varVec;
1684 getline( output_data_structure,
line);
1686 getline( output_data_structure,
line);
1688 if (
line.substr(0,2) ==
"//")
continue;
1689 if (
line.length() == 0)
continue;
1690 if (
line.substr(0,1).compare(
"\r") == 0)
continue;
1691 if (
line.substr(0,1).compare(
"\n") == 0)
continue;
1696 if (
pos == string::npos) {
1700 createField( ncGrps[ngrps-1], sname.c_str(), lname.c_str(),
1702 (
void *) &fill_value,
1703 flag_values.c_str(), flag_meanings.c_str(),
1706 flag_values.assign(
"");
1707 flag_meanings.assign(
"");
1716 if (
line.substr(0,10).compare(
"} // group") == 0)
break;
1720 istringstream iss(
line);
1721 iss >> skipws >> varType;
1724 if ( varType.compare(
"char") == 0) ntype = NC_CHAR;
1725 else if ( varType.compare(
"byte") == 0) ntype = NC_BYTE;
1726 else if ( varType.compare(
"short") == 0) ntype = NC_SHORT;
1727 else if ( varType.compare(
"int") == 0) ntype = NC_INT;
1728 else if ( varType.compare(
"long") == 0) ntype = NC_INT;
1729 else if ( varType.compare(
"float") == 0) ntype = NC_FLOAT;
1730 else if ( varType.compare(
"real") == 0) ntype = NC_FLOAT;
1731 else if ( varType.compare(
"double") == 0) ntype = NC_DOUBLE;
1732 else if ( varType.compare(
"ubyte") == 0) ntype = NC_UBYTE;
1733 else if ( varType.compare(
"ushort") == 0) ntype = NC_USHORT;
1734 else if ( varType.compare(
"uint") == 0) ntype = NC_UINT;
1735 else if ( varType.compare(
"ulong") == 0) ntype = NC_UINT;
1736 else if ( varType.compare(
"int64") == 0) ntype = NC_INT64;
1737 else if ( varType.compare(
"uint64") == 0) ntype = NC_UINT64;
1741 size_t posSname =
line.substr(0,
pos).rfind(
" ");
1742 sname.assign(
line.substr(posSname+1,
pos-posSname-1));
1743 cout <<
"sname: " << sname.c_str() << endl;
1746 this->
parseDims( line.substr(
pos+1, string::npos), varVec);
1747 numDims = varVec.size();
1751 size_t posEql =
line.find(
"=");
1752 size_t pos1qte =
line.find(
"\"");
1753 size_t pos2qte =
line.substr(pos1qte+1, string::npos).find(
"\"");
1759 if (
attrName.compare(
"long_name") == 0) {
1760 lname.assign(
line.substr(pos1qte+1, pos2qte));
1765 else if (
attrName.compare(
"units") == 0) {
1766 units.assign(
line.substr(pos1qte+1, pos2qte));
1771 else if (
attrName.compare(
"_FillValue") == 0) {
1773 iss.str(
line.substr(posEql+1, string::npos));
1779 else if (
attrName.compare(
"flag_values") == 0) {
1780 flag_values.assign(
line.substr(pos1qte+1, pos2qte));
1784 else if (
attrName.compare(
"flag_meanings") == 0) {
1785 flag_meanings.assign(
line.substr(pos1qte+1, pos2qte));
1789 else if (
attrName.compare(
"valid_min") == 0) {
1791 iss.str(
line.substr(posEql+1, string::npos));
1797 else if (
attrName.compare(
"valid_max") == 0) {
1799 iss.str(
line.substr(posEql+1, string::npos));
1820 size_t pos = dimString.find(
",", curPos);
1821 if (
pos == string::npos)
1822 pos = dimString.find(
")");
1825 istringstream iss(dimString.substr(curPos,
pos-curPos));
1826 iss >> skipws >> varDimName;
1828 for (
int i=0;
i<ndims;
i++) {
1831 dimName = ncDims[
i].getName();
1833 catch ( NcException& e) {
1835 cerr <<
"Failure accessing dimension: " + dimName << endl;
1839 if ( varDimName.compare(dimName) == 0) {
1840 cout <<
" " << dimName <<
" " << ncDims[
i].getSize() << endl;
1841 varDims.push_back(ncDims[
i]);
1845 if ( dimString.substr(
pos, 1).compare(
")") == 0)
break;