diff --git a/grss/kernels/get_kernels.py b/grss/kernels/get_kernels.py index ee6cc54e..a97f9607 100644 --- a/grss/kernels/get_kernels.py +++ b/grss/kernels/get_kernels.py @@ -52,13 +52,16 @@ f'-O {script_dir}/earth_200101_990825_predict.bpc')) os.system((f'wget --no-verbose --no-clobber {NAIF_SITE}/pck/earth_200101_990825_predict.cmt ' f'-O {script_dir}/earth_200101_990825_predict.cmt')) +# generic frame kernels +os.system((f'wget --no-verbose --no-clobber {NAIF_SITE}/pck/pck00011.tpc ' + f'-O {script_dir}/pck00011.tpc')) # run this code if the no-tm-overwrite flag argument is not present if len(sys.argv) > 1: - tm_overwrite = sys.argv[1] != '--no-tm-overwrite' + TM_OVERWRITE = sys.argv[1] != '--no-tm-overwrite' else: - tm_overwrite = True -if tm_overwrite: + TM_OVERWRITE = True +if TM_OVERWRITE: # open the spice meta-kernels and update the line that defines # the PATH_VALUES variable to point to the same directory as this script meta_kernels = [ @@ -69,38 +72,38 @@ # read the meta-kernel and find the line that defines the PATH_VALUES variable with open(mk, 'r', encoding='utf-8') as f: lines = f.readlines() - num_chunks = 0 + NUM_CHUNKS = 0 for i, line in enumerate(lines): if 'PATH_VALUES' in line and 'placeholder' in line: # update the path to the directory containing this script # if script_dir is more that 40 characters long, then break it up # into chunks of 40 characters each - cutoff = 40 - if len(script_dir) > cutoff: - num_chunks, remainder = divmod(len(script_dir), cutoff) - chunks = [script_dir[i*cutoff:(i+1)*cutoff] for i in range(num_chunks)] + CUTOFF = 40 + if len(script_dir) > CUTOFF: + NUM_CHUNKS, remainder = divmod(len(script_dir), CUTOFF) + chunks = [script_dir[i*CUTOFF:(i+1)*CUTOFF] for i in range(NUM_CHUNKS)] if remainder > 0: chunks.append(script_dir[-remainder:]) - num_chunks += 1 + NUM_CHUNKS += 1 lines[i] = f" PATH_VALUES = ( '{chunks[0]}',\n" for chunk in chunks[1:]: - end_char = " )" if chunk == chunks[-1] else "," - lines[i] += f" '{chunk}'{end_char}\n" + END_CHAR = " )" if chunk == chunks[-1] else "," + lines[i] += f" '{chunk}'{END_CHAR}\n" else: - num_chunks = 1 + NUM_CHUNKS = 1 lines[i] = f" PATH_VALUES = ( '{script_dir}" + "' )\n" - if 'PATH_SYMBOLS' in line and "'GRSS'" in line and num_chunks > 1: + if 'PATH_SYMBOLS' in line and "'GRSS'" in line and NUM_CHUNKS > 1: # replace PATH_SYMBOLS = ( 'GRSS' ) with PATH_SYMBOLS = ( 'GRSS_1', ... ) lines[i] = " PATH_SYMBOLS = ( 'GRSS1',\n" - for j in range(2, num_chunks+1): - end_char = " )" if j == num_chunks else "," - lines[i] += f" 'GRSS{j}'{end_char}\n" - if '$GRSS' in line and num_chunks > 1: + for j in range(2, NUM_CHUNKS+1): + END_CHAR = " )" if j == NUM_CHUNKS else "," + lines[i] += f" 'GRSS{j}'{END_CHAR}\n" + if '$GRSS' in line and NUM_CHUNKS > 1: # replace '$GRSS' with '$GRSS1$GRSS2$GRSS3...' according to the number of chunks - replacement_str = '$GRSS1' - for j in range(2, num_chunks+1): - replacement_str += f'$GRSS{j}' - lines[i] = line.replace('$GRSS', replacement_str) + REPLACE_STR = '$GRSS1' + for j in range(2, NUM_CHUNKS+1): + REPLACE_STR += f'$GRSS{j}' + lines[i] = line.replace('$GRSS', REPLACE_STR) # write the updated meta-kernel with open(mk, 'w', encoding='utf-8') as f: f.writelines(lines) diff --git a/grss/kernels/planets_big16_de431_1950_2350.tm b/grss/kernels/planets_big16_de431_1950_2350.tm index a3313cf2..d545037c 100644 --- a/grss/kernels/planets_big16_de431_1950_2350.tm +++ b/grss/kernels/planets_big16_de431_1950_2350.tm @@ -12,7 +12,7 @@ PATH_SYMBOLS = ( 'GRSS' ) KERNELS_TO_LOAD = ( '$GRSS/latest_leapseconds.tls', - '$GRSS/planets_big16_de431_1950_2350.bsp', + '$GRSS/pck00011.tpc', '$GRSS/earth_200101_990825_predict.bpc', '$GRSS/earth_720101_230601.bpc', '$GRSS/earth_latest_high_prec.bpc' ) diff --git a/grss/kernels/planets_big16_de441_1950_2350.tm b/grss/kernels/planets_big16_de441_1950_2350.tm index 6443decf..5787b500 100644 --- a/grss/kernels/planets_big16_de441_1950_2350.tm +++ b/grss/kernels/planets_big16_de441_1950_2350.tm @@ -12,7 +12,7 @@ PATH_SYMBOLS = ( 'GRSS' ) KERNELS_TO_LOAD = ( '$GRSS/latest_leapseconds.tls', - '$GRSS/planets_big16_de441_1950_2350.bsp', + '$GRSS/pck00011.tpc', '$GRSS/earth_200101_990825_predict.bpc', '$GRSS/earth_720101_230601.bpc', '$GRSS/earth_latest_high_prec.bpc' ) diff --git a/grss/version.txt b/grss/version.txt index afaf360d..8cfbc905 100644 --- a/grss/version.txt +++ b/grss/version.txt @@ -1 +1 @@ -1.0.0 \ No newline at end of file +1.1.1 \ No newline at end of file diff --git a/include/simulation.h b/include/simulation.h index fcabaafa..091c2404 100644 --- a/include/simulation.h +++ b/include/simulation.h @@ -3,6 +3,11 @@ #include "utilities.h" +void get_observer_state(const real &tObsMjd, + const std::vector &observerInfo, + propSimulation *propSim, const bool tObsInUTC, + std::vector &observerState); + struct Body { private: public: diff --git a/include/utilities.h b/include/utilities.h index a8c6a3f1..886def9b 100644 --- a/include/utilities.h +++ b/include/utilities.h @@ -142,13 +142,6 @@ class CloseApproachParameters { void get_ca_parameters(propSimulation *propSim, const real &tMap); }; -void get_spice_state(const int &spiceID, const real &t0_mjd, - const Constants &consts, double state[6]); -void get_observer_state(const real &t_obs_mjd, - const std::vector &observerInfo, - const Constants &consts, const bool &tObsInUTC, - std::vector &observerState); - void jd_to_mjd(const real jd, real &mjd); real jd_to_mjd(const real jd); void mjd_to_jd(const real mjd, real &jd); diff --git a/pyproject.toml b/pyproject.toml index 9ba73300..a644064f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,6 +64,7 @@ package-data = {"grss" = [ "kernels/get_kernels.py", "kernels/*.log", "kernels/*.tm", + "kernels/*.tpc", "kernels/*.txt", ]} diff --git a/src/interpolate.cpp b/src/interpolate.cpp index cf0e0953..9dd93098 100644 --- a/src/interpolate.cpp +++ b/src/interpolate.cpp @@ -336,7 +336,7 @@ void get_radar_measurement(propSimulation *propSim, const size_t interpIdx, propSim->observerInfo[interpIdx][1], propSim->observerInfo[interpIdx][2], propSim->observerInfo[interpIdx][3]}; - get_observer_state(receiveTimeTDB, receiverInfo, propSim->consts, false, + get_observer_state(receiveTimeTDB, receiverInfo, propSim, false, xObsBaryRcv); std::vector xObsBaryTx(6, 0.0); @@ -379,7 +379,7 @@ void get_radar_measurement(propSimulation *propSim, const size_t interpIdx, while (iter < maxIter && fabs(delayUpleg - delayUplegPrev) > lightTimeTol) { get_observer_state(bounceTimeTDB - delayUpleg, transmitterInfo, - propSim->consts, false, xObsBaryTx); + propSim, false, xObsBaryTx); std::vector xRelativeOneBody(6, 0.0); for (size_t j = 0; j < 6; j++) { xRelativeOneBody[j] = xTrgtBaryBounce[j] - xObsBaryTx[j]; @@ -407,7 +407,7 @@ void get_radar_measurement(propSimulation *propSim, const size_t interpIdx, } } transmitTimeTDB = bounceTimeTDB - delayUpleg; - get_observer_state(transmitTimeTDB, transmitterInfo, propSim->consts, + get_observer_state(transmitTimeTDB, transmitterInfo, propSim, false, xObsBaryTx); // get delay measurement delayMeasurement = (delayDownleg + delayUpleg) * 86400.0L * diff --git a/src/simulation.cpp b/src/simulation.cpp index b582fac3..34803841 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -1,5 +1,115 @@ #include "simulation.h" +void get_observer_state(const real &tObsMjd, + const std::vector &observerInfo, + propSimulation *propSim, const bool tObsInUTC, + std::vector &observerState) { + SpiceInt baseBody = observerInfo[0]; + if (observerInfo[0] == 500) baseBody = 399; + if (baseBody == 0) { + observerState[0] = 0.0L; + observerState[1] = 0.0L; + observerState[2] = 0.0L; + observerState[3] = 0.0L; + observerState[4] = 0.0L; + observerState[5] = 0.0L; + return; + } + real tObsET; + real tObsMjdTDB; + mjd_to_et(tObsMjd, tObsET); + if (tObsInUTC) { + // std::cout << tObsMjd << " MJD UTC" << tObsET << " s UTC -> "; + SpiceDouble et_minus_utc; + real sec_past_j2000_utc = tObsET; + deltet_c(sec_past_j2000_utc, "UTC", &et_minus_utc); + tObsET += et_minus_utc; + et_to_mjd(tObsET, tObsMjdTDB); + // std::cout << tObsET << " s ET " << tObsMjdTDB << " MJD TDB" << + // std::endl; + } else { + tObsMjdTDB = tObsMjd; + } + double baseBodyState[9]; + get_spk_state(baseBody, tObsMjdTDB, propSim->ephem, baseBodyState); + ConstSpiceChar *baseBodyFrame; + switch ((int)observerInfo[0]) { + case 10: + baseBodyFrame = "IAU_SUN"; + break; + case 1: + case 199: + baseBodyFrame = "IAU_MERCURY"; + break; + case 2: + case 299: + baseBodyFrame = "IAU_VENUS"; + break; + case 399: + baseBodyFrame = "ITRF93"; + // High precision frame is not defined before 1972 JAN 01 00:00:42.183 TDB + if (tObsMjdTDB < 41317.0004882291666666666L) { + baseBodyFrame = "IAU_EARTH"; + } + break; + case 500: + observerState[0] = (real) baseBodyState[0] + observerInfo[1]/propSim->consts.du2m; + observerState[1] = (real) baseBodyState[1] + observerInfo[2]/propSim->consts.du2m; + observerState[2] = (real) baseBodyState[2] + observerInfo[3]/propSim->consts.du2m; + observerState[3] = (real) baseBodyState[3] + observerInfo[4]/propSim->consts.duptu2mps; + observerState[4] = (real) baseBodyState[4] + observerInfo[5]/propSim->consts.duptu2mps; + observerState[5] = (real) baseBodyState[5] + observerInfo[6]/propSim->consts.duptu2mps; + return; + break; + case 499: + baseBodyFrame = "IAU_MARS"; + break; + case 599: + baseBodyFrame = "IAU_JUPITER"; + break; + case 699: + baseBodyFrame = "IAU_SATURN"; + break; + case 799: + baseBodyFrame = "IAU_URANUS"; + break; + case 899: + baseBodyFrame = "IAU_NEPTUNE"; + break; + case 999: + baseBodyFrame = "IAU_PLUTO"; + break; + default: + std::cout << "Given base body: " << baseBody << std::endl; + throw std::invalid_argument("Given base body not supported"); + break; + } + real lon = observerInfo[1]; + real lat = observerInfo[2]; + real rho = observerInfo[3]; + ConstSpiceDouble bodyFixedX = rho * cos(lat) * cos(lon) / 1.0e3L; + ConstSpiceDouble bodyFixedY = rho * cos(lat) * sin(lon) / 1.0e3L; + ConstSpiceDouble bodyFixedZ = rho * sin(lat) / 1.0e3L; + ConstSpiceDouble bodyFixedState[6] = {bodyFixedX, bodyFixedY, bodyFixedZ, + 0.0, 0.0, 0.0}; + SpiceDouble observerStateInertial[6]; + SpiceDouble rotMat[6][6]; + sxform_c(baseBodyFrame, "J2000", tObsET, rotMat); + mxvg_c(rotMat, bodyFixedState, 6, 6, observerStateInertial); + observerStateInertial[0] *= (real)1.0e3L / propSim->consts.du2m; + observerStateInertial[1] *= (real)1.0e3L / propSim->consts.du2m; + observerStateInertial[2] *= (real)1.0e3L / propSim->consts.du2m; + observerStateInertial[3] *= (real)1.0e3L / propSim->consts.duptu2mps; + observerStateInertial[4] *= (real)1.0e3L / propSim->consts.duptu2mps; + observerStateInertial[5] *= (real)1.0e3L / propSim->consts.duptu2mps; + observerState[0] = baseBodyState[0] + observerStateInertial[0]; + observerState[1] = baseBodyState[1] + observerStateInertial[1]; + observerState[2] = baseBodyState[2] + observerStateInertial[2]; + observerState[3] = baseBodyState[3] + observerStateInertial[3]; + observerState[4] = baseBodyState[4] + observerStateInertial[4]; + observerState[5] = baseBodyState[5] + observerStateInertial[5]; +} + void Body::set_J2(real J2, real poleRA, real poleDec) { this->J2 = J2; if (this->J2 != 0.0L) { @@ -593,7 +703,7 @@ void propSimulation::prepare_for_evaluation( "The observerInfo vector must have 4/7 (optical), 9 (radar " "delay), or 10 elements (radar doppler)."); } - get_observer_state(tEval[i], observerInfo[i], this->consts, + get_observer_state(tEval[i], observerInfo[i], this, this->tEvalUTC, xObserver[i]); // std::cout << xObserver[i][0] << " " << xObserver[i][1] << " " << // xObserver[i][2] << " " << xObserver[i][3] << " " << diff --git a/src/utilities.cpp b/src/utilities.cpp index 09717271..9a871430 100644 --- a/src/utilities.cpp +++ b/src/utilities.cpp @@ -1,102 +1,5 @@ #include "utilities.h" -void get_spice_state(const int &spiceID, const real &t0_mjd, - const Constants &consts, double state[6]) { - real t0_et; - mjd_to_et(t0_mjd, t0_et); - SpiceInt center = 0; // 0 = solar system barycenter - ConstSpiceChar *frame = - "J2000"; // Earth mean equator and equinox of J2000, - // states output will be ICRF-EME2000 frame - SpiceDouble lt; - spkgeo_c(spiceID, t0_et, frame, center, state, <); - for (int i = 0; i < 6; i++) { - state[i] *= 1000.0L / consts.du2m; - } - for (int i = 3; i < 6; i++) { - state[i] *= consts.tu2s; - } -} - -void get_observer_state(const real &tObsMjd, - const std::vector &observerInfo, - const Constants &consts, const bool &tObsInUTC, - std::vector &observerState) { - SpiceInt baseBody = observerInfo[0]; - if (observerInfo[0] == 500) baseBody = 399; - if (baseBody == 0) { - observerState[0] = 0.0L; - observerState[1] = 0.0L; - observerState[2] = 0.0L; - observerState[3] = 0.0L; - observerState[4] = 0.0L; - observerState[5] = 0.0L; - return; - } - real t_obs_et; - real tObsMjdTDB; - mjd_to_et(tObsMjd, t_obs_et); - if (tObsInUTC) { - // std::cout << tObsMjd << " MJD UTC" << t_obs_et << " s UTC -> "; - SpiceDouble et_minus_utc; - real sec_past_j2000_utc = t_obs_et; - deltet_c(sec_past_j2000_utc, "UTC", &et_minus_utc); - t_obs_et += et_minus_utc; - et_to_mjd(t_obs_et, tObsMjdTDB); - // std::cout << t_obs_et << " s ET " << tObsMjdTDB << " MJD TDB" << - // std::endl; - } else { - tObsMjdTDB = tObsMjd; - } - double baseBodyState[6]; - get_spice_state(baseBody, tObsMjdTDB, consts, baseBodyState); - - // real a, f; - ConstSpiceChar *baseBodyFrame; - switch ((int)observerInfo[0]) { - case 399: - baseBodyFrame = "ITRF93"; - break; - case 500: - observerState[0] = (real) baseBodyState[0] + observerInfo[1]/consts.du2m; - observerState[1] = (real) baseBodyState[1] + observerInfo[2]/consts.du2m; - observerState[2] = (real) baseBodyState[2] + observerInfo[3]/consts.du2m; - observerState[3] = (real) baseBodyState[3] + observerInfo[4]/consts.duptu2mps; - observerState[4] = (real) baseBodyState[4] + observerInfo[5]/consts.duptu2mps; - observerState[5] = (real) baseBodyState[5] + observerInfo[6]/consts.duptu2mps; - return; - break; - default: - std::cout << "Given base body: " << baseBody << std::endl; - throw std::invalid_argument("Given base body not supported"); - break; - } - real lon = observerInfo[1]; - real lat = observerInfo[2]; - real rho = observerInfo[3]; - ConstSpiceDouble bodyFixedX = rho * cos(lat) * cos(lon) / 1.0e3L; - ConstSpiceDouble bodyFixedY = rho * cos(lat) * sin(lon) / 1.0e3L; - ConstSpiceDouble bodyFixedZ = rho * sin(lat) / 1.0e3L; - ConstSpiceDouble bodyFixedState[6] = {bodyFixedX, bodyFixedY, bodyFixedZ, - 0.0, 0.0, 0.0}; - SpiceDouble observerStateInertial[6]; - SpiceDouble rotMat[6][6]; - sxform_c(baseBodyFrame, "J2000", t_obs_et, rotMat); - mxvg_c(rotMat, bodyFixedState, 6, 6, observerStateInertial); - observerStateInertial[0] *= (real)1.0e3L / consts.du2m; - observerStateInertial[1] *= (real)1.0e3L / consts.du2m; - observerStateInertial[2] *= (real)1.0e3L / consts.du2m; - observerStateInertial[3] *= (real)1.0e3L / consts.duptu2mps; - observerStateInertial[4] *= (real)1.0e3L / consts.duptu2mps; - observerStateInertial[5] *= (real)1.0e3L / consts.duptu2mps; - observerState[0] = baseBodyState[0] + observerStateInertial[0]; - observerState[1] = baseBodyState[1] + observerStateInertial[1]; - observerState[2] = baseBodyState[2] + observerStateInertial[2]; - observerState[3] = baseBodyState[3] + observerStateInertial[3]; - observerState[4] = baseBodyState[4] + observerStateInertial[4]; - observerState[5] = baseBodyState[5] + observerStateInertial[5]; -} - void jd_to_et(const real jd, real &et) { real j2000 = 2451545.0; real day2sec = 86400.0;