def _calculate_pos_itrs(self, site): """Calculate positions for the given time epochs The positions are calculated as simple linear offsets based on the reference epoch. If there is a post-seismic deformations model for a station the motion due to that model is added to the linear velocity model. Makes sure to pick out the correct time interval to use. Args: site (String): Key saying which site to calculate position for. Returns: Array: Positions, one 3-vector for each time epoch. """ station_info = self.data[site] ref_epoch = Time(station_info["ref_epoch"], scale="utc") pos = np.zeros((self.time.size, 3)) for pv in station_info["pos_vel"].values(): idx = np.logical_and(self.time.utc.datetime >= pv["start"], self.time.utc.datetime < pv["end"]) if self.time.size == 1: idx = np.array([idx]) if not any(idx): continue ref_pos = np.array([pv["STAX"], pv["STAY"], pv["STAZ"]]) ref_vel = np.array([pv["VELX"], pv["VELY"], pv["VELZ"]]) interval_years = (self.time - ref_epoch).jd * Unit.day2julian_years if isinstance(interval_years, float): interval_years = np.array([interval_years]) pos[idx, :] = ref_pos + interval_years[idx, None] * ref_vel[None, :] # Post-seismic deformations, see Appendix C in :cite:'itrf2014' if "psd" in station_info: llh = sofa.vectorized_llh(pos) psd = station_info["psd"] denu = dict(H=np.zeros(self.time.size), E=np.zeros(self.time.size), N=np.zeros(self.time.size)) for param in psd.values(): t_0 = Time(param["epoch"], format="datetime", scale="utc") delta_t = (self.time - t_0).jd * Unit.day2julian_years if isinstance(delta_t, float): delta_t = np.array([delta_t]) idx = delta_t > 0 for L in "ENH": aexp = np.array(param.get("AEXP_" + L, list())) texp = np.array(param.get("TEXP_" + L, list())) for a, t in zip(aexp, texp): denu[L][idx] += a * (1 - np.exp(-delta_t[idx] / t)) alog = np.array(param.get("ALOG_" + L, list())) tlog = np.array(param.get("TLOG_" + L, list())) for a, t in zip(alog, tlog): denu[L][idx] += a * np.log(1 + delta_t[idx] / t) rot = rotation.enu2trs(llh[:, 0], llh[:, 1]) denu = np.vstack((denu["E"], denu["N"], denu["H"])).T dxyz = (rot @ denu[:, :, None])[:, :, 0] pos += dxyz if self.time.size == 1: pos = pos[0, :] return pos
def setUp(self): # TODO: Configuration has to be defined? How? where.set_config(2016, 3, 1, 'gps')? time = Time(2457448.5, format="jd", scale="tdb") # Julian Day in TDB time scale self.eph = apriori.get("ephemerides", time=time, ephemerides="de430")