def test_random_salt(): acis_taco.set_random_salt(None) illum1 = acis_taco.calc_earth_vis(p_chandra_eci, att)[1] illum2 = acis_taco.calc_earth_vis(p_chandra_eci, att)[1] assert not np.all(illum1 == illum2) acis_taco.set_random_salt(1) illum1 = acis_taco.calc_earth_vis(p_chandra_eci, att)[1] illum2 = acis_taco.calc_earth_vis(p_chandra_eci, att)[1] assert np.all(illum1 == illum2) acis_taco.set_random_salt(2) illum2 = acis_taco.calc_earth_vis(p_chandra_eci, att)[1] assert not np.all(illum1 == illum2)
def dvals(self): try: import acis_taco as taco except ImportError: import Chandra.taco as taco if not hasattr(self, '_dvals') and not self.get_cached(): # Collect individual MSIDs for use in calc_earth_vis() ephem_xyzs = [getattr(self, 'orbitephem0_{}'.format(x)) for x in ('x', 'y', 'z')] aoattqt_1234s = [getattr(self, 'aoattqt{}'.format(x)) for x in range(1, 5)] ephems = np.array([x.dvals for x in ephem_xyzs]).transpose() q_atts = np.array([x.dvals for x in aoattqt_1234s]).transpose() self._dvals = np.empty(self.model.n_times, dtype=float) for i, ephem, q_att in zip(count(), ephems, q_atts): q_norm = np.sqrt(np.sum(q_att ** 2)) if q_norm < 0.9: print("Bad quaternion", i) q_att = np.array([0.0, 0.0, 0.0, 1.0]) else: q_att = q_att / q_norm _, illums, _ = taco.calc_earth_vis(ephem, q_att) self._dvals[i] = illums.sum() self.put_cache() return self._dvals
def calc_perigee_map(start='2010:114:20:00:00', stop='2010:117:16:00:00', ngrid=50): # Get orbital ephemeris in requested time range print('Fetching ephemeris') objs = ('orbit', 'lunar', 'solar') axes = ('x', 'y', 'z') msids = ['{0}ephem0_{1}'.format(obj, axis) for obj in objs for axis in axes] ephems = fetch.MSIDset(msids, start, stop) times = ephems[msids[0]].times.copy() n_ephem = len(ephems[msids[0]].vals) if any(len(ephems[msid].vals) != n_ephem for msid in msids): raise ValueError('Unexpected mismatch in ephemeris telemetry sampling') ephem_xyzs = {} for obj in ('orbit', 'lunar', 'solar'): msids = ('{0}ephem0_{1}'.format(obj, axis) for axis in axes) ephem_xyzs[obj] = np.array([ephems[msid].vals for msid in msids]) illum_maps = [] illum_idxs = [] antisun, xs, ys = get_antisun_grid(ngrid) antisun_pitches, phis = antisun.img2polar(xs, ys) for i_ephem, ephem_xyz in enumerate(ephem_xyzs['orbit'].transpose()): # Calculate a grid of attitude vectors centered on the anti-sun line and extending # from sun-pitch=180 (center) to sun-pitch=45 (edge). orbit_r = np.sqrt(np.sum(ephem_xyzs['orbit'][:, i_ephem]**2)) if orbit_r > 50000e3: continue sun_eci = ephem_xyzs['solar'][:, i_ephem] - ephem_xyzs['orbit'][:, i_ephem] att_vecs = antisun.img2eci(xs, ys, sun_eci) ras, decs = Ska.quatutil.eci2radec(att_vecs) illum_map = np.zeros((ngrid, ngrid), dtype=np.float32) print(i_ephem, n_ephem, ephem_xyz) for iy in range(ngrid): for ix in range(ngrid): i_vec = iy * ngrid + ix if antisun_pitches[i_vec] < 135: ra, dec = ras[i_vec], decs[i_vec] roll = Ska.Sun.nominal_roll(ra, dec, times[i_ephem]) _, att_illums, _ = acis_taco.calc_earth_vis(ephem_xyz, [ra, dec, roll], max_reflect=5) illum = sum(att_illums) else: illum = 0.0 illum_map[iy, ix] = illum illum_idxs.append(i_ephem) illum_maps.append(illum_map) # debug_here() return dict(illums=np.array(illum_maps), illum_idxs=np.array(illum_idxs), times=times, antisun=antisun, ephem_xyzs=ephem_xyzs, )
def calc_illums(queue, chandra_ecis, att): """Calculate the illumination (Earth solid angle) at specified ephemeris points ``chandra_ecis`` and attitude ``att``. Put the result into the multiprocess ``queue``. """ illums = [] for chandra_eci in chandra_ecis: vis, illum, rays = acis_taco.calc_earth_vis(chandra_eci, att, max_reflect=5) illums.append(sum(illum)) queue.put(illums)
def make_earth_vis_grids(nside=32, n_reps=1): from acis_taco import calc_earth_vis, RAD_EARTH, acis_taco hp = astropy_healpix.HEALPix(nside=nside, order='nested') npix = astropy_healpix.nside_to_npix(nside) print(f'npix={npix}') lons, lats = hp.healpix_to_lonlat(np.arange(npix)) time0 = time.time() # Allow randomization between altitudes for i_rep in range(n_reps): vis_arrays = [] # Randomize the ray-trace points for each rep acis_taco._RANDOM_SALT = None acis_taco.SPHERE_XYZ = acis_taco.random_hemisphere(acis_taco.N_SPHERE) acis_taco.SPHERE_X = acis_taco.SPHERE_XYZ[:, 0].copy() for i_alt, alt in enumerate(alts): srs = SphericalRepresentation(lon=lons, lat=lats, distance=alt + RAD_EARTH) xyzs = srs.to_cartesian() peb_xs = xyzs.x.to_value() peb_ys = xyzs.y.to_value() peb_zs = xyzs.z.to_value() vis = [] for peb_x, peb_y, peb_z in zip(peb_xs, peb_ys, peb_zs): _, illums, _ = calc_earth_vis( p_earth_body=[peb_x, peb_y, peb_z]) vis.append(np.sum(illums)) vis = np.array(vis) vis_arrays.append(vis) vis_grid = np.vstack(vis_arrays) if i_alt % 10 == 0: print( f'alt={alt / 1000:.2f} km at dt={time.time() - time0:.1f}') ii = 1 while True: filename = Path(f'earth_vis_grid_nside{nside}_rep{ii}.npy') if filename.exists(): ii += 1 continue else: print(f'Saving {filename}') np.save(filename, vis_grid) break return vis_grid
def _earth_solid_angle(ds): # Collect individual MSIDs for use in calc_earth_vis() ephem_xyzs = [ ds["msids", "orbitephem0_{}".format(x)] for x in "xyz" ] aoattqt_1234s = [ ds["msids", "aoattqt{}".format(x)] for x in range(1, 5) ] ephems = np.array([x.value for x in ephem_xyzs]).transpose() q_atts = np.array([x.value for x in aoattqt_1234s]).transpose() ret = np.empty(ds["msids", "orbitephem0_x"].shape, dtype=float) for i, ephem, q_att in zip(count(), ephems, q_atts): q_norm = np.sqrt(np.sum(q_att**2)) if q_norm < 0.9: q_att = np.array([0.0, 0.0, 0.0, 1.0]) else: q_att = q_att / q_norm _, illums, _ = calc_earth_vis(ephem, q_att) ret[i] = illums.sum() return APQuantity(ret, ds.msids["orbitephem0_x"].times, "sr")
def test_illum_regress(): acis_taco.set_random_salt(1) illum = acis_taco.calc_earth_vis(p_chandra_eci, att)[1] assert_allclose(illum, illum_gold)
def calc_perigee_map(start='2010:114:20:00:00', stop='2010:117:16:00:00', ngrid=50): # Get orbital ephemeris in requested time range print('Fetching ephemeris') objs = ('orbit', 'lunar', 'solar') axes = ('x', 'y', 'z') msids = [ '{0}ephem0_{1}'.format(obj, axis) for obj in objs for axis in axes ] ephems = fetch.MSIDset(msids, start, stop) times = ephems[msids[0]].times.copy() n_ephem = len(ephems[msids[0]].vals) if any(len(ephems[msid].vals) != n_ephem for msid in msids): raise ValueError('Unexpected mismatch in ephemeris telemetry sampling') ephem_xyzs = {} for obj in ('orbit', 'lunar', 'solar'): msids = ('{0}ephem0_{1}'.format(obj, axis) for axis in axes) ephem_xyzs[obj] = np.array([ephems[msid].vals for msid in msids]) illum_maps = [] illum_idxs = [] antisun, xs, ys = get_antisun_grid(ngrid) antisun_pitches, phis = antisun.img2polar(xs, ys) for i_ephem, ephem_xyz in enumerate(ephem_xyzs['orbit'].transpose()): # Calculate a grid of attitude vectors centered on the anti-sun line and extending # from sun-pitch=180 (center) to sun-pitch=45 (edge). orbit_r = np.sqrt(np.sum(ephem_xyzs['orbit'][:, i_ephem]**2)) if orbit_r > 50000e3: continue sun_eci = ephem_xyzs['solar'][:, i_ephem] - ephem_xyzs['orbit'][:, i_ephem] att_vecs = antisun.img2eci(xs, ys, sun_eci) ras, decs = Ska.quatutil.eci2radec(att_vecs) illum_map = np.zeros((ngrid, ngrid), dtype=np.float32) print(i_ephem, n_ephem, ephem_xyz) for iy in range(ngrid): for ix in range(ngrid): i_vec = iy * ngrid + ix if antisun_pitches[i_vec] < 135: ra, dec = ras[i_vec], decs[i_vec] roll = Ska.Sun.nominal_roll(ra, dec, times[i_ephem]) _, att_illums, _ = acis_taco.calc_earth_vis( ephem_xyz, [ra, dec, roll], max_reflect=5) illum = sum(att_illums) else: illum = 0.0 illum_map[iy, ix] = illum illum_idxs.append(i_ephem) illum_maps.append(illum_map) # debug_here() return dict( illums=np.array(illum_maps), illum_idxs=np.array(illum_idxs), times=times, antisun=antisun, ephem_xyzs=ephem_xyzs, )