80 FormattedDouble::operator=(s);
86 void SolarSystemEphemeris::readASCIIheader(
const string& filename)
95 strm.open(filename.c_str());
98 Exception e(
"Failed to open input file " + filename +
". Abort.");
107 int group = 0, n = 0;
117 if (line.substr(0, 5) ==
"GROUP")
130 if (strm.eof() || !strm.good())
147 if (
word ==
"NCOEFF=")
156 "Confused on the first line - 3rd word is not NCOEFF=");
161 else if (group == 1010)
165 Exception e(
"Too many labels under GROUP 1010");
172 LOG(
VERBOSE) <<
"label " << n <<
" is " << line;
177 else if (group == 1030)
187 <<
"Times JD " << fixed << setprecision(3) << startJD
188 <<
" to JD " << endJD <<
" = " <<
interval <<
" days";
191 else if (group == 1070)
197 while (!line.empty())
206 LOG(
DEBUG) <<
"Nconst is " << Nconst;
210 const_names.push_back(
word);
213 else if (group == 1041)
219 Exception e(
"Nconst does not match N in GROUP 1041 : " +
224 <<
"Nconst matches: " << Nconst <<
" = " <<
word;
231 else if (group == 1050)
236 LOG(
DEBUG) <<
"c_offset[" << n <<
"] = " << c_offset[n];
242 <<
"c_ncoeff[" << n - 13 <<
"] = " << c_ncoeff[n - 13];
248 <<
"c_nsets[" << n - 26 <<
"] = " << c_nsets[n - 26];
259 if (strm.eof() || !strm.good())
277 EphemerisNumber = int(constants[
"DENUM"]);
288 Exception E(
"std except: " +
string(e.what()));
299 int SolarSystemEphemeris::readASCIIdata(vector<string>& filenames)
306 if (filenames.size() == 0)
312 for (i = 0; i < filenames.size(); i++)
314 int iret = readASCIIdata(filenames[i]);
322 map<double, vector<double>>::iterator it = store.begin();
323 startJD = it->second[0];
326 endJD = it->second[1];
328 LOG(
VERBOSE) <<
"After reading data files, store size is "
329 << store.size() <<
" and new start and stop times are JD "
330 << fixed << setprecision(9) << startJD <<
" and JD "
337 oss <<
"Start Epoch: JED= " << fixed << setw(10) << setprecision(1)
338 << startJD <<
" = " << yy <<
"/" << mm <<
"/" << dd;
340 oss.seekp(ios_base::beg);
344 oss <<
"Final Epoch: JED= " << fixed << setw(10) << setprecision(1)
345 << endJD <<
" = " << yy <<
"/" << mm <<
"/" << dd;
359 Exception E(
"std except: " +
string(e.what()));
364 Exception e(
"Unknown exception");
370 int SolarSystemEphemeris::readASCIIdata(
const string& filename)
374 if (EphemerisNumber < 0)
376 Exception e(
"readASCIIdata called before header read");
385 strm.open(filename.c_str());
388 Exception e(
"Could not open file " + filename);
400 vector<double> dataVector;
432 "readASCIIdata finds conflicting sizes in header (" +
434 ") in file " + filename +
" at line #" +
asString(ntot));
441 for (
int j = 0; j < 3; j++)
445 dataVector.push_back(
coeff);
448 vector<double> dtemp = dataVector;
449 store[dataVector[0]] = dtemp;
476 LOG(
INFO) <<
"Read " << rec <<
" records from file " << filename;
488 Exception E(
"std except: " +
string(e.what()));
493 Exception e(
"Unknown exception");
499 int SolarSystemEphemeris::writeASCIIheader(ostream& os)
503 if (EphemerisNumber < 0)
510 string blank(81,
' ');
511 blank += string(
"\n");
514 oss <<
"KSIZE= 0000 NSIZE=" << setw(5) <<
Ncoeff << blank;
516 oss.seekp(ios_base::beg);
518 os <<
leftJustify(
"GROUP 1010", 81) << endl << blank;
519 for (i = 0; i < 3; i++)
526 os <<
leftJustify(
"GROUP 1030", 81) << endl << blank;
527 oss << fixed << setprecision(2) << setw(12) << startJD << setw(12)
528 << endJD << setw(12) <<
interval << blank;
530 oss.seekp(ios_base::beg);
532 os <<
leftJustify(
"GROUP 1040", 81) << endl << blank;
533 oss << setw(6) << Nconst << blank;
535 oss.seekp(ios_base::beg);
537 map<string, double>::const_iterator it = constants.begin();
538 for (i = 0; it != constants.end(); it++, i++)
541 if ((i + 1) % 10 == 0)
545 oss.seekp(ios_base::beg);
548 if (Nconst % 10 != 0)
552 oss.seekp(ios_base::beg);
556 os <<
leftJustify(
"GROUP 1041", 81) << endl << blank;
557 oss << setw(6) << Nconst << blank;
559 oss.seekp(ios_base::beg);
561 for (i = 0, it = constants.begin(); it != constants.end(); it++, i++)
564 if ((i + 1) % 3 == 0)
568 oss.seekp(ios_base::beg);
574 while ((i + 1) % 3 != 0)
581 oss.seekp(ios_base::beg);
585 os <<
leftJustify(
"GROUP 1050", 81) << endl << blank;
586 for (i = 0; i < 13; i++)
590 oss.seekp(ios_base::beg);
591 for (i = 0; i < 13; i++)
595 oss.seekp(ios_base::beg);
596 for (i = 0; i < 13; i++)
600 oss.seekp(ios_base::beg);
603 os <<
leftJustify(
"GROUP 1070", 81) << endl << blank;
614 Exception E(
"std except: " +
string(e.what()));
625 int SolarSystemEphemeris::writeASCIIdata(ostream& os)
629 if (EphemerisNumber < 0)
634 string blank(81,
' ');
635 blank += string(
"\n");
639 map<double, vector<double>>::iterator jt;
640 for (nrec = 1, jt = store.begin(); jt != store.end(); jt++, nrec++)
642 os << setw(6) << nrec << setw(6) <<
Ncoeff <<
" " << endl;
643 for (i = 0; i <
Ncoeff; i++)
646 if ((i + 1) % 3 == 0)
650 oss.seekp(ios_base::beg);
656 while ((i + 1) % 3 != 0)
663 oss.seekp(ios_base::beg);
678 Exception E(
"std except: " +
string(e.what()));
689 int SolarSystemEphemeris::writeBinaryFile(
const string& filename)
696 if (EphemerisNumber <= 0)
703 strm.open(filename.c_str(), ios::out | ios::binary);
706 Exception e(
"Failed to open output file " + filename +
". Abort.");
718 for (i = 0; i < 3; i++)
721 writeBinary(strm,
leftJustify(str, 84).c_str(), 84);
723 LOG(
VERBOSE) <<
"writeBinaryFile label " << i <<
" " << label[i];
727 map<string, double>::const_iterator it = constants.begin();
728 for (i = 0; i < 400; i++)
730 if (it != constants.end())
738 writeBinary(strm,
" ", 6);
744 writeBinary(strm, (
char *)&startJD,
sizeof(
double));
745 writeBinary(strm, (
char *)&endJD,
sizeof(
double));
746 writeBinary(strm, (
char *)&
interval,
sizeof(
double));
747 recLength += 3 *
sizeof(double);
750 writeBinary(strm, (
char *)&
Ncoeff,
sizeof(
int));
751 recLength +=
sizeof(int);
754 writeBinary(strm, (
char *)&constants[
"AU"],
sizeof(
double));
755 writeBinary(strm, (
char *)&constants[
"EMRAT"],
sizeof(
double));
756 recLength += 2 *
sizeof(double);
759 for (i = 0; i < 12; i++)
761 writeBinary(strm, (
char *)&c_offset[i],
sizeof(
int));
762 writeBinary(strm, (
char *)&c_ncoeff[i],
sizeof(
int));
763 writeBinary(strm, (
char *)&c_nsets[i],
sizeof(
int));
764 recLength += 3 *
sizeof(int);
768 writeBinary(strm, (
char *)&constants[
"DENUM"],
sizeof(
double));
769 recLength +=
sizeof(double);
770 LOG(
VERBOSE) <<
"WriteBinary outputs DENUM " << constants[
"DENUM"];
773 writeBinary(strm, (
char *)&c_offset[12],
sizeof(
int));
774 writeBinary(strm, (
char *)&c_ncoeff[12],
sizeof(
int));
775 writeBinary(strm, (
char *)&c_nsets[12],
sizeof(
int));
776 recLength += 3 *
sizeof(int);
779 LOG(
DEBUG) <<
"Pad length 1 = " <<
Ncoeff *
sizeof(double) - recLength;
781 for (i = 0; i <
Ncoeff *
sizeof(double) - recLength; i++)
782 writeBinary(strm, &c, 1);
788 it = constants.begin();
789 for (i = 0; i < 400; i++)
791 if (it != constants.end())
793 writeBinary(strm, (
char *)&(it->second),
sizeof(
double));
798 writeBinary(strm, (
char *)&z,
sizeof(
double));
801 LOG(
DEBUG) <<
"Pad length 2 = " << (400 - Nconst) *
sizeof(
double);
802 for (i = 0; i < (400 - Nconst) *
sizeof(
double); i++)
803 writeBinary(strm, &c, 1);
809 map<double, vector<double>>::iterator jt;
810 for (jt = store.begin(); jt != store.end(); jt++)
812 LOG(
DEBUG) <<
"writeBinaryFile writes " << nrec <<
" " << fixed
813 << setprecision(6) << jt->second[0];
814 for (i = 0; i < jt->second.size(); i++)
815 writeBinary(strm, (
char *)&jt->second[i],
sizeof(
double));
833 Exception E(
"std except: " +
string(e.what()));
844 int SolarSystemEphemeris::readBinaryFile(
const string& filename)
849 readBinaryHeader(filename);
850 iret = readBinaryData(
true);
863 Exception E(
"std except: " +
string(e.what()));
874 int SolarSystemEphemeris::initializeWithBinaryFile(
const string& filename)
883 readBinaryHeader(filename);
884 iret = readBinaryData(
false);
892 EphemerisNumber = int(constants[
"DENUM"]);
893 LOG(
DEBUG) <<
"initialize sets EphemerisNumber " << EphemerisNumber;
904 Exception E(
"std except: " +
string(e.what()));
916 void SolarSystemEphemeris::relativeInertialPositionVelocity(
925 for (i = 0; i < 6; i++)
943 if (iret == retEarly || iret == retLate)
945 Exception e(
string(
"Requested time is ") +
946 (iret == retEarly ?
string(
"before") :
string(
"after")) +
947 string(
" the range spanned by the ephemeris."));
950 else if (iret == retStrm)
952 Exception e(
string(
"Stream error on ephemeris binary file"));
955 else if (iret == retEphN)
957 Exception e(
string(
"Ephemeris not initialized"));
962 Exception e(
string(
"Unknown error on ephemeris binary file"));
968 if (target == idNutations || target == idLibrations)
970 inertialPositionVelocity(
971 MJD, target == idNutations ? NUTATIONS : LIBRATIONS, pv);
982 else if (target == idSolarSystemBarycenter)
986 else if (target == idEarthMoonBarycenter)
995 else if (
center == idSolarSystemBarycenter)
999 else if (
center == idEarthMoonBarycenter)
1006 double pvmoon[6], pvembary[6], Eratio, Mratio;
1009 if (target == idEarth &&
center == idMoon)
1013 if (
center == idEarth && target == idMoon)
1019 if ((target == idEarth &&
center != idMoon) ||
1020 (
center == idEarth && target != idMoon))
1022 Eratio = 1.0 / (1.0 + constants[
"EMRAT"]);
1023 inertialPositionVelocity(
MJD, MOON, pvmoon);
1025 if ((target == idMoon &&
center != idEarth) ||
1026 (
center == idMoon && target != idEarth))
1028 Mratio = constants[
"EMRAT"] / (1.0 + constants[
"EMRAT"]);
1029 inertialPositionVelocity(
MJD, EMBARY, pvembary);
1033 double pvtarget[6], pvcenter[6];
1034 inertialPositionVelocity(
MJD, TARGET, pvtarget);
1035 inertialPositionVelocity(
MJD, CENTER, pvcenter);
1039 if (target == idEarth &&
center != idMoon)
1041 for (i = 0; i < 6; i++)
1043 pvtarget[i] -= pvmoon[i] * Eratio;
1046 if (
center == idEarth && target != idMoon)
1048 for (i = 0; i < 6; i++)
1050 pvcenter[i] -= pvmoon[i] * Eratio;
1054 if (target == idMoon &&
center != idEarth)
1056 for (i = 0; i < 6; i++)
1058 pvtarget[i] = pvembary[i] + pvtarget[i] * Mratio;
1061 if (
center == idMoon && target != idEarth)
1063 for (i = 0; i < 6; i++)
1065 pvcenter[i] = pvembary[i] + pvcenter[i] * Mratio;
1070 for (i = 0; i < 6; i++)
1072 pv[i] = pvtarget[i] - pvcenter[i];
1077 double AU = constants[
"AU"];
1078 for (i = 0; i < 6; i++)
1086 catch (exception& e)
1088 Exception E(
"std except: " +
string(e.what()));
1101 void SolarSystemEphemeris::writeBinary(ofstream& strm,
const char *ptr,
1106 strm.write(ptr, size);
1117 catch (exception& e)
1119 Exception E(
"std except: " +
string(e.what()));
1131 void SolarSystemEphemeris::readBinary(
char *ptr,
size_t size)
1135 istrm.read(ptr, size);
1136 if (istrm.eof() || !istrm.good())
1138 Exception e(
"Stream error or premature EOF");
1146 catch (exception& e)
1148 Exception E(
"std except: " +
string(e.what()));
1160 void SolarSystemEphemeris::readBinaryHeader(
const string& filename)
1164 int i, DENUM, recLength;
1170 istrm.open(filename.c_str(), ios::in | ios::binary);
1171 if (!istrm.is_open())
1173 Exception e(
"Failed to open input binary file " + filename +
1179 EphemerisNumber = -1;
1187 for (i = 0; i < 3; i++)
1189 readBinary(buffer, 84);
1193 LOG(
DEBUG) <<
"readBinaryHeader reads label " << label[i];
1197 vector<string> consts_names;
1198 for (i = 0; i < 400; i++)
1200 readBinary(buffer, 6);
1206 consts_names.push_back(
word);
1207 LOG(
DEBUG) <<
"readBinaryHeader reads constant label " <<
word;
1210 Nconst = consts_names.size();
1213 readBinary((
char *)&startJD,
sizeof(
double));
1214 LOG(
DEBUG) <<
"readBinaryHeader reads start JD " << fixed
1215 << setprecision(2) << startJD;
1217 readBinary((
char *)&endJD,
sizeof(
double));
1218 LOG(
DEBUG) <<
"readBinaryHeader reads end JD " << fixed
1219 << setprecision(2) << endJD;
1221 readBinary((
char *)&
interval,
sizeof(
double));
1224 recLength += 3 *
sizeof(double);
1227 readBinary((
char *)&
Ncoeff,
sizeof(
int));
1228 recLength +=
sizeof(int);
1229 LOG(
DEBUG) <<
"readBinaryHeader reads number of coefficients "
1233 buffer[
sizeof(double)] =
'\0';
1234 readBinary((
char *)&AU,
sizeof(
double));
1235 recLength +=
sizeof(double);
1236 LOG(
DEBUG) <<
"readBinaryHeader reads AU " << fixed << setprecision(4)
1239 readBinary((
char *)&EMRAT,
sizeof(
double));
1240 recLength +=
sizeof(double);
1241 LOG(
DEBUG) <<
"readBinaryHeader reads EMRAT " << EMRAT;
1244 for (i = 0; i < 12; i++)
1246 readBinary((
char *)&c_offset[i],
sizeof(
int));
1247 readBinary((
char *)&c_ncoeff[i],
sizeof(
int));
1248 readBinary((
char *)&c_nsets[i],
sizeof(
int));
1249 recLength += 3 *
sizeof(int);
1250 LOG(
DEBUG) <<
"readBinaryHeader reads " << i <<
" " << c_offset[i]
1251 <<
" " << c_ncoeff[i] <<
" " << c_nsets[i];
1256 readBinary((
char *)&denum,
sizeof(
double));
1257 recLength +=
sizeof(double);
1258 LOG(
DEBUG) <<
"readBinaryHeader reads DENUM directly " << denum;
1261 readBinary((
char *)&c_offset[12],
sizeof(
int));
1262 readBinary((
char *)&c_ncoeff[12],
sizeof(
int));
1263 readBinary((
char *)&c_nsets[12],
sizeof(
int));
1264 recLength += 3 *
sizeof(int);
1265 LOG(
DEBUG) <<
"readBinaryHeader reads " << 12 <<
" " << c_offset[12]
1266 <<
" " << c_ncoeff[12] <<
" " << c_nsets[12];
1271 LOG(
DEBUG) <<
"Pad length 1 = " <<
Ncoeff *
sizeof(double) - recLength;
1272 for (i = 0; i <
Ncoeff *
sizeof(double) - recLength; i++)
1274 readBinary(buffer, 1);
1280 for (i = 0; i < 400; i++)
1282 readBinary((
char *)&d,
sizeof(
double));
1286 LOG(
DEBUG) <<
"readBinaryHeader reads " << consts_names[i]
1287 <<
" = " << fixed << setprecision(18) << setw(24)
1292 LOG(
DEBUG) <<
"Pad length 2 = " << (400 - Nconst) *
sizeof(
double);
1293 for (i = 0; i < (400 - Nconst) *
sizeof(
double); i++)
1295 readBinary(buffer, 1);
1300 if (denum == constants[
"DENUM"])
1302 LOG(
DEBUG) <<
"DENUM agrees " << denum;
1309 EphemerisNumber = 0;
1317 <<
") does not equal the array value ("
1318 << constants[
"DENUM"] <<
")";
1325 catch (exception& e)
1327 Exception E(
"std except: " +
string(e.what()));
1340 int SolarSystemEphemeris ::readBinaryData(
bool save)
1345 if (EphemerisNumber == -1)
1351 int iret = retEarly, nrec = 1;
1353 vector<double> dataVector;
1354 while (!istrm.eof() && istrm.good())
1356 long filepos = istrm.tellg();
1357 iret = readBinaryRecord(dataVector);
1358 if (iret == retLate)
1371 store[dataVector[0]] = dataVector;
1377 coefficients = dataVector;
1381 fileposMap[dataVector[0]] = filepos;
1383 if (nrec > 1 && dataVector[0] != prev)
1386 oss <<
"ERROR: found gap in data at " << nrec << fixed
1387 << setprecision(6) <<
" : prev end = " << prev
1388 <<
" != new beg = " << dataVector[0];
1394 prev = dataVector[1];
1408 catch (exception& e)
1410 Exception E(
"std except: " +
string(e.what()));
1427 int SolarSystemEphemeris::readBinaryRecord(vector<double>& dataVector)
1435 if (istrm.eof() || !istrm.good())
1439 if (EphemerisNumber <= -1)
1447 for (
int i = 0; i <
Ncoeff; i++)
1449 istrm.read((
char *)&d,
1459 dataVector.push_back(d);
1468 catch (exception& e)
1470 Exception E(
"std except: " +
string(e.what()));
1489 int SolarSystemEphemeris ::seekToJD(
double JD)
1497 if (istrm.eof() || !istrm.good())
1501 if (EphemerisNumber !=
int(constants[
"DENUM"]))
1506 if (coefficients[0] <= JD && JD <= coefficients[1])
1511 map<double, long>::const_iterator it;
1512 it = fileposMap.lower_bound(
1515 if (it == fileposMap.begin() && JD < it->first)
1527 istrm.seekg(it->second, ios_base::beg);
1528 int iret = readBinaryRecord(coefficients);
1529 if (iret == retLate)
1538 if (JD > coefficients[1])
1549 catch (exception& e)
1551 Exception E(
"std except: " +
string(e.what()));
1563 void SolarSystemEphemeris::inertialPositionVelocity(
1568 int i, j, i0, ncomp, offset;
1570 for (i = 0; i < 6; i++)
1582 double T, Tbeg, Tspan, Tspan0;
1583 Tbeg = coefficients[0];
1584 Tspan0 = Tspan = coefficients[1] - coefficients[0];
1585 i0 = c_offset[which] - 1;
1586 ncomp = (which == NUTATIONS ? 2 : 3);
1589 if (c_nsets[which] > 1)
1591 Tspan /= double(c_nsets[which]);
1592 for (j = c_nsets[which]; j > 0; j--)
1594 Tbeg = coefficients[0] + double(j - 1) * Tspan;
1597 i0 += (j - 1) * ncomp * c_ncoeff[which];
1607 int N = c_ncoeff[which];
1608 vector<double> C(N, 0.0);
1609 vector<double> U(N, 0.0);
1610 for (i = 0; i < ncomp; i++)
1620 for (j = 2; j < N; j++)
1622 C[j] = 2 * T * C[j - 1] - C[j - 2];
1623 U[j] = 2 * T * U[j - 1] + 2 * C[j - 1] - U[j - 2];
1628 for (j = N - 1; j > -1; j--)
1630 PV[i] += coefficients[i0 + j + i * N] * C[j];
1632 for (j = N - 1; j > 0; j--)
1634 PV[i + ncomp] += coefficients[i0 + j + i * N] * U[j];
1638 PV[i + ncomp] *= 2 * double(c_nsets[which]) / Tspan0;
1645 catch (exception& e)
1647 Exception E(
"std except: " +
string(e.what()));