def test_rotation_3d_1axis(): rx = Rotation3dOperator('X', 90, degrees=True) ry = Rotation3dOperator('Y', 90, degrees=True) rz = Rotation3dOperator('Z', 90, degrees=True) ref = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] # single axis rotations exps = ([[1, 0, 0], [0, 0, 1], [0, -1, 0]], [[0, 0, -1], [0, 1, 0], [1, 0, 0]], [[0, 1, 0], [-1, 0, 0], [0, 0, 1]]) def func(rot, exp): assert_allclose(rot(ref), exp, atol=1e-15) for rot, exp in zip((rx, ry, rz), exps): yield func, rot, exp
def cartesian_horizontal2instrument(self): """ Return the galactic-to-instrument transform. """ time = self.date_obs + TimeDelta(self.time, format='sec') with rule_manager(none=False): r = Rotation3dOperator("ZY'Z''", self.azimuth, 90 - self.elevation, self.pitch, degrees=True).T return r
def create_random_pointings(center, npointings, dtheta, date_obs=None, period=None, latitude=None, longitude=None, seed=None): """ Return pointings randomly and uniformly distributed in a spherical cap. Parameters ---------- center : 2-tuple The R.A. and declination of the center of the FOV, in degrees. npointings : int The number of requested pointings dtheta : float The maximum angular distance to the center. date_obs : str or astropy.time.Time, optional The starting date of the observation (UTC). period : float, optional The sampling period of the pointings, in seconds. latitude : float, optional The observer's latitude [degrees]. Default is DOMEC's. longitude : float, optional The observer's longitude [degrees]. Default is DOMEC's. """ r = np.random.RandomState(seed) cosdtheta = np.cos(np.radians(dtheta)) theta = np.degrees( np.arccos(cosdtheta + (1 - cosdtheta) * r.rand(npointings))) phi = r.rand(npointings) * 360 pitch = r.rand(npointings) * 360 p = QubicSampling(npointings, date_obs=date_obs, period=period, latitude=latitude, longitude=longitude) time = p.date_obs + TimeDelta(p.time, format='sec') c2s = Cartesian2SphericalOperator('azimuth,elevation', degrees=True) e2h = CartesianEquatorial2HorizontalOperator('NE', time, p.latitude, p.longitude) rot = Rotation3dOperator("ZY'", center[0], 90 - center[1], degrees=True) s2c = Spherical2CartesianOperator('zenith,azimuth', degrees=True) rotation = c2s(e2h(rot(s2c))) coords = rotation(np.asarray([theta.T, phi.T]).T) p.azimuth = coords[..., 0] p.elevation = coords[..., 1] p.pitch = pitch p.angle_hwp = r.random_integers(0, 7, npointings) * 11.25 p.fix_az = False return p
def cartesian_galactic2instrument(self): """ Return the galactic-to-instrument transform. """ time = self.date_obs + TimeDelta(self.time, format='sec') with rule_manager(none=False): r = Rotation3dOperator("ZY'Z''", self.azimuth, 90 - self.elevation, self.pitch, degrees=True).T * \ CartesianEquatorial2HorizontalOperator( 'NE', time, self.latitude, self.longitude) * \ CartesianGalactic2EquatorialOperator() return r
def get_hwp_operator(self, sampling, scene): """ Return the rotation matrix for the half-wave plate. """ shape = (len(self), len(sampling)) if scene.kind == 'I': return IdentityOperator(shapein=shape) if scene.kind == 'QU': return Rotation2dOperator(-4 * sampling.angle_hwp, degrees=True, shapein=shape + (2,)) return Rotation3dOperator('X', -4 * sampling.angle_hwp, degrees=True, shapein=shape + (3,))
def fill(array, dense, index, value, angle, n): for i, (j, v, a) in enumerate(zip(index, value, angle)): array[i, n].index = j if j == -1: array[i, n].r11 = 0 array[i, n].r22 = 0 array[i, n].r32 = 0 continue r = v * Rotation3dOperator('X', a, degrees=True).todense(shapein=3) array[i, n].r11 = r[0, 0] array[i, n].r22 = r[1, 1] array[i, n].r32 = r[2, 1] dense[3*i:3*i+3, 3*j:3*j+3] += r
def create_repeat_pointings(center, npointings, dtheta, nhwp_angles=3, date_obs=None, period=None, latitude=None, longitude=None, seed=None): """ Return pointings randomly and uniformly distributed in a spherical cap. The same pointing is repeated nhwp_angles times with a different hwp angle each time. Parameters ---------- center : 2-tuple The R.A. and declination of the center of the FOV, in degrees. npointings : int The number of requested pointings dtheta : float The maximum angular distance to the center. nhwp_angles : int The number of HWP angles used. date_obs : str or astropy.time.Time, optional The starting date of the observation (UTC). period : float, optional The sampling period of the pointings, in seconds. latitude : float, optional The observer's latitude [degrees]. Default is DOMEC's. longitude : float, optional The observer's longitude [degrees]. Default is DOMEC's. seed : int Random seed. """ r = np.random.RandomState(seed) nrandom = np.int(npointings / nhwp_angles) # number of real random pointings # Creation of nrandom pointing cosdtheta = np.cos(np.radians(dtheta)) theta = np.degrees(np.arccos(cosdtheta + (1 - cosdtheta) * r.rand(nrandom))) phi = r.rand(nrandom) * 360 pitch = r.rand(nrandom) * 360 p = QubicSampling(nrandom, date_obs=date_obs, period=period, latitude=latitude, longitude=longitude) time = p.date_obs + TimeDelta(p.time, format='sec') c2s = Cartesian2SphericalOperator('azimuth,elevation', degrees=True) e2h = CartesianEquatorial2HorizontalOperator('NE', time, p.latitude, p.longitude) rot = Rotation3dOperator("ZY'", center[0], 90 - center[1], degrees=True) s2c = Spherical2CartesianOperator('zenith,azimuth', degrees=True) rotation = c2s(e2h(rot(s2c))) coords = rotation(np.asarray([theta.T, phi.T]).T) p.azimuth = coords[..., 0] p.elevation = coords[..., 1] p.pitch = pitch p.fix_az = False # Replication of the same pointing with others fix hwp angles pp = QubicSampling(nrandom * nhwp_angles, date_obs=date_obs, period=period, latitude=latitude, longitude=longitude) pp.azimuth = np.tile(p.azimuth, nhwp_angles) pp.elevation = np.tile(p.elevation, nhwp_angles) pp.pitch = np.tile(p.pitch, nhwp_angles) pp.time = np.tile(p.time, nhwp_angles) pp.angle_hwp = np.zeros(nrandom * nhwp_angles) pp.fix_az = False for hwp in range(nhwp_angles): pp.angle_hwp[hwp * nrandom:(hwp + 1) * nrandom] = np.array( np.rad2deg(hwp * np.pi / (nhwp_angles * 2))) return pp
def create_random_pointings(center, npointings, dtheta, hwp_stepsize, date_obs=None, period=None, latitude=None, longitude=None, seed=None): """ Return pointings randomly and uniformly distributed in a spherical cap. 1) Creates random coordinates theta, phi. Range: 0 < theta < dtheta, 0 < phi < 360 (then are converted from spherical to cartesian coordinates), 2) It rotates the points to center them in direction (RA, DEC) using Rotation3dOperator (equatorial reference system) 3) Convertion: Equatorial to Horizontal reference system (using CartesianEquatorial2HorizontalOperator's operator) 4) Back to cartesian coordinates (using Cartesian2SphericalOperator) Parameters ---------- center : 2-tuple The R.A. and declination of the center of the FOV, in degrees. npointings : int The number of requested pointings dtheta : float The maximum angular distance to the center. hwp_stepsize : float Step angle size for the HWP. date_obs : str or astropy.time.Time, optional The starting date of the observation (UTC). period : float, optional The sampling period of the pointings, in seconds. latitude : float, optional The observer's latitude [degrees]. Default is DOMEC's. longitude : float, optional The observer's longitude [degrees]. Default is DOMEC's. seed : int Random seed. """ r = np.random.RandomState(seed) cosdtheta = np.cos(np.radians(dtheta)) theta = np.degrees( np.arccos(cosdtheta + (1 - cosdtheta) * r.rand(npointings))) phi = r.rand(npointings) * 360 pitch = r.rand(npointings) * 360 p = QubicSampling(npointings, date_obs=date_obs, period=period, latitude=latitude, longitude=longitude) time = p.date_obs + TimeDelta(p.time, format='sec') c2s = Cartesian2SphericalOperator('azimuth,elevation', degrees=True) e2h = CartesianEquatorial2HorizontalOperator('NE', time, p.latitude, p.longitude) rot = Rotation3dOperator("ZY'", center[0], 90 - center[1], degrees=True) s2c = Spherical2CartesianOperator('zenith,azimuth', degrees=True) rotation = c2s(e2h(rot(s2c))) coords = rotation(np.asarray([theta.T, phi.T]).T) p.azimuth = coords[..., 0] p.elevation = coords[..., 1] p.pitch = pitch p.fix_az = False p.angle_hwp = r.randint(0, int(90 / hwp_stepsize + 1), npointings) * hwp_stepsize return p
def func(c): r = Rotation3dOperator(c, alpha, beta, gamma) r2 = Rotation3dOperator(c[2], gamma) * \ Rotation3dOperator(c[1], beta) * \ Rotation3dOperator(c[0], alpha) assert_allclose(r(ref), r2(ref))