def test_06_rotate(self): v1 = coord.rand_vec(stat) rot_axis = np.hstack(coord.rand_vec(1)) angle = 0.25 v2 = coord.rotate(v1, rot_axis, angle) angles = coord.angle(v1, v2) self.assertTrue((angles > 0).all() & (angles <= angle).all()) # rotate back v3 = coord.rotate(v2, rot_axis, -angle) v4 = coord.rotate(v2, rot_axis, 2 * np.pi - angle) self.assertTrue(np.allclose(v1, v3)) self.assertTrue(np.allclose(v3, v4)) # when rotating around z-axis and vectors have z=0: all angles have to be 0.25 rot_axis = np.array([0, 0, 1]) v1 = coord.ang2vec(coord.rand_phi(stat), np.zeros(stat)) v2 = coord.rotate(v1, rot_axis, angle) angles = coord.angle(v1, v2) self.assertTrue((angles > angle - 1e-3).all() & (angles < angle + 1e-3).all()) # when rotating around z-axis all angles correspond to longitude shift angles = 2 * np.pi * np.random.random(stat) v1 = coord.rand_vec(stat) lon1, lat1 = coord.vec2ang(v1) v2 = np.array( [coord.rotate(vi, rot_axis, ai) for vi, ai in zip(v1.T, angles)]).T lon2, lat2 = coord.vec2ang(v2) self.assertTrue(np.allclose(lat1, lat2)) lon_diff = lon1 - lon2 lon_diff[lon_diff < 0] += 2 * np.pi self.assertTrue(np.allclose(lon_diff, angles))
def sensitivity_2pt(self, set_idx=None, niso=1000, bins=180, **kwargs): """ Function to calculate the sensitivity by the 2pt-auto-correlation over a scrambling of the right ascension coordinates. :param set_idx: If set, only this set number will be evaluated :param niso: Number of isotropic sets to calculate :param bins: Number of angular bins, 180 correspond to 1 degree binning (np.linspace(0, np.pi, bins+1). :param kwargs: additional named arguments passed to obs.two_pt_auto() :return: pvalues in the shape (self.nsets, bins) """ kwargs.setdefault('cumulative', True) vec_crs = self.get('vecs') _, dec = coord.vec2ang(coord.gal2eq(np.reshape(vec_crs, (3, -1)))) # calculate auto correlation for isotropic scrambled data _ac_iso = np.zeros((niso, bins)) for i in range(niso): _vecs = coord.ang2vec(coord.rand_phi(self.ncrs), np.random.choice(dec, size=self.ncrs)) _ac_iso[i] = obs.two_pt_auto(_vecs, bins, **kwargs) # calculate p-value by comparing the true sets with the isotropic ones set_idx = np.arange(self.nsets) if set_idx is None else [set_idx] pvals = np.zeros((len(set_idx), bins)) for i, idx in enumerate(set_idx): _ac_crs = obs.two_pt_auto(vec_crs[:, idx], bins, **kwargs) pvals[i] = np.sum(_ac_iso >= _ac_crs[np.newaxis], axis=0) / float(niso) return pvals
def test_05_ang2vec(self): phi = coord.rand_phi(stat) theta = coord.rand_theta(stat) vec = coord.ang2vec(phi, theta) self.assertTrue(np.allclose(np.sum(vec**2, axis=0), np.ones(stat))) phi2, theta2 = coord.vec2ang(vec) self.assertTrue(np.allclose(phi, phi2)) self.assertTrue(np.allclose(theta, theta2))
def test_11_test_vecs_galactic(self): lon, lat = coord.rand_phi(stat), coord.rand_theta(stat) v = coord.ang2vec(lon, lat) self.assertTrue( np.allclose(lon, coord.get_longitude(v, coord_system='gal'))) self.assertTrue( np.allclose(lat, coord.get_latitude(v, coord_system='gal'))) v_eq = coord.gal2eq(v) self.assertTrue( np.allclose(lon, coord.get_longitude(v_eq, coord_system='eq'))) self.assertTrue( np.allclose(lat, coord.get_latitude(v_eq, coord_system='eq')))
def test_10_test_vecs_equatorial(self): ras, decs = coord.rand_phi(stat), coord.rand_theta(stat) v = coord.ang2vec(ras, decs) self.assertTrue( np.allclose(ras, coord.get_right_ascension(v, coord_system='eq'))) self.assertTrue( np.allclose(decs, coord.get_declination(v, coord_system='eq'))) v_gal = coord.eq2gal(v) self.assertTrue( np.allclose(ras, coord.get_right_ascension(v_gal, coord_system='gal'))) self.assertTrue( np.allclose(decs, coord.get_declination(v_gal, coord_system='gal')))
def sensitivity_2pt(self, niso=1000, bins=180, **kwargs): """ Function to calculate the sensitivity by the 2pt-auto-correlation over a scrambling of the right ascension coordinates. :param niso: Number of isotropic sets to calculate. :param bins: Number of angular bins, 180 correspond to 1 degree binning (np.linspace(0, np.pi, bins+1). :param kwargs: additional named arguments passed to obs.two_pt_auto() :return: pvalues in the shape (bins) """ kwargs.setdefault('cumulative', True) vec_crs = self.get('vecs') _, dec = coord.vec2ang(coord.gal2eq(vec_crs)) # calculate auto correlation for isotropic scrambled data _ac_iso = np.zeros((niso, bins)) for i in range(niso): _vecs = coord.ang2vec(coord.rand_phi(self.ncrs), dec) _ac_iso[i] = obs.two_pt_auto(_vecs, bins, **kwargs) # calculate p-value by comparing the true sets with the isotropic ones _ac_crs = obs.two_pt_auto(vec_crs, bins, **kwargs) pvals = np.sum(_ac_iso >= _ac_crs[np.newaxis], axis=0) / float(niso) return pvals
def test_09_get_hour_angle(self): ra = coord.rand_phi(stat) self.assertTrue(np.sum(coord.get_hour_angle(ra, ra) == 0) == stat) lst = coord.rand_phi(stat) ha = coord.get_hour_angle(ra, lst) self.assertTrue(np.sum((ha >= 0) & (ha < 2 * np.pi)) == stat)
import numpy as np import matplotlib.pyplot as plt from astrotools import auger, coord, skymap print("Test: module coord.py") # Creates an isotropic arrival map and convert galactic longitudes (lons) and # galactic latitudes (lats) into cartesian vectors ncrs = 3000 # number of cosmic rays log10e_min = 18.5 # minimum energy in log10(E / eV) lons = coord.rand_phi(ncrs) # isotropic in phi (~Uniform(-pi, pi)) lats = coord.rand_theta(ncrs) # isotropic in theta (Uniform in cos(theta)) vecs = coord.ang2vec(lons, lats) log10e = auger.rand_energy_from_auger(n=ncrs, log10e_min=log10e_min) # Plot an example map with sampled energies. If you specify the opath keyword in # the skymap function, the plot will be automatically saved and closed skymap.scatter(vecs, c=log10e, opath='isotropic_sky.png') # Creates an arrival map with a source located at v_src=(1, 0, 0) and apply a # fisher distribution around it with gaussian spread sigma=10 degree v_src = np.array([1, 0, 0]) kappa = 1. / np.radians(10.)**2 vecs = coord.rand_fisher_vec(v_src, kappa=kappa, n=ncrs) # if you dont specify the opath you can use (fig, ax) to plot more stuff fig, ax = skymap.scatter(vecs, c=log10e) plt.scatter(0, 0, s=100, c='red', marker='*') # plot source in the center plt.savefig('fisher_single_source_10deg.png', bbox_inches='tight') plt.close() # We can also use the coord.rand_fisher_vec() function to apply an angular uncertainty