def CartesianToEquatorial(pos, observer=[0,0,0]): """ Convert Cartesian position coordinates to equatorial right ascension and declination, using the specified observer location. .. note:: RA and DEC will be returned in degrees, with RA in the range [0,360] and DEC in the range [-90, 90]. Parameters ---------- pos : array_like a N x 3 array holding the Cartesian position coordinates observer : array_like a length 3 array holding the observer location Returns ------- ra, dec : array_like the right ascension and declination coordinates, in degrees. RA will be in the range [0,360] and DEC in the range [-90, 90] """ # recenter based on observer pos = pos - observer s = da.hypot(pos[:,0], pos[:,1]) lon = da.arctan2(pos[:,1], pos[:,0]) lat = da.arctan2(pos[:,2], s) # convert to degrees lon = da.rad2deg(lon) lat = da.rad2deg(lat) # wrap lon to [0,360] lon = da.mod(lon-360., 360.) return lon, lat
def get_alt_az(utc_time, lon, lat): """Return sun altitude and azimuth from *utc_time*, *lon*, and *lat*. lon,lat in degrees What is the unit of the returned angles and heights!? FIXME! """ lon = da.deg2rad(lon) lat = da.deg2rad(lat) ra_, dec = sun_ra_dec(utc_time) h__ = _local_hour_angle(utc_time, lon, ra_) return (da.arcsin( da.sin(lat) * np.sin(dec) + da.cos(lat) * np.cos(dec) * np.cos(h__)), da.arctan2( -np.sin(h__), (da.cos(lat) * np.tan(dec) - da.sin(lat) * np.cos(h__))))
def test_arithmetic(): x = np.arange(5).astype('f4') + 2 y = np.arange(5).astype('i8') + 2 z = np.arange(5).astype('i4') + 2 a = da.from_array(x, chunks=(2,)) b = da.from_array(y, chunks=(2,)) c = da.from_array(z, chunks=(2,)) assert eq(a + b, x + y) assert eq(a * b, x * y) assert eq(a - b, x - y) assert eq(a / b, x / y) assert eq(b & b, y & y) assert eq(b | b, y | y) assert eq(b ^ b, y ^ y) assert eq(a // b, x // y) assert eq(a ** b, x ** y) assert eq(a % b, x % y) assert eq(a > b, x > y) assert eq(a < b, x < y) assert eq(a >= b, x >= y) assert eq(a <= b, x <= y) assert eq(a == b, x == y) assert eq(a != b, x != y) assert eq(a + 2, x + 2) assert eq(a * 2, x * 2) assert eq(a - 2, x - 2) assert eq(a / 2, x / 2) assert eq(b & True, y & True) assert eq(b | True, y | True) assert eq(b ^ True, y ^ True) assert eq(a // 2, x // 2) assert eq(a ** 2, x ** 2) assert eq(a % 2, x % 2) assert eq(a > 2, x > 2) assert eq(a < 2, x < 2) assert eq(a >= 2, x >= 2) assert eq(a <= 2, x <= 2) assert eq(a == 2, x == 2) assert eq(a != 2, x != 2) assert eq(2 + b, 2 + y) assert eq(2 * b, 2 * y) assert eq(2 - b, 2 - y) assert eq(2 / b, 2 / y) assert eq(True & b, True & y) assert eq(True | b, True | y) assert eq(True ^ b, True ^ y) assert eq(2 // b, 2 // y) assert eq(2 ** b, 2 ** y) assert eq(2 % b, 2 % y) assert eq(2 > b, 2 > y) assert eq(2 < b, 2 < y) assert eq(2 >= b, 2 >= y) assert eq(2 <= b, 2 <= y) assert eq(2 == b, 2 == y) assert eq(2 != b, 2 != y) assert eq(-a, -x) assert eq(abs(a), abs(x)) assert eq(~(a == b), ~(x == y)) assert eq(~(a == b), ~(x == y)) assert eq(da.logaddexp(a, b), np.logaddexp(x, y)) assert eq(da.logaddexp2(a, b), np.logaddexp2(x, y)) assert eq(da.exp(b), np.exp(y)) assert eq(da.log(a), np.log(x)) assert eq(da.log10(a), np.log10(x)) assert eq(da.log1p(a), np.log1p(x)) assert eq(da.expm1(b), np.expm1(y)) assert eq(da.sqrt(a), np.sqrt(x)) assert eq(da.square(a), np.square(x)) assert eq(da.sin(a), np.sin(x)) assert eq(da.cos(b), np.cos(y)) assert eq(da.tan(a), np.tan(x)) assert eq(da.arcsin(b/10), np.arcsin(y/10)) assert eq(da.arccos(b/10), np.arccos(y/10)) assert eq(da.arctan(b/10), np.arctan(y/10)) assert eq(da.arctan2(b*10, a), np.arctan2(y*10, x)) assert eq(da.hypot(b, a), np.hypot(y, x)) assert eq(da.sinh(a), np.sinh(x)) assert eq(da.cosh(b), np.cosh(y)) assert eq(da.tanh(a), np.tanh(x)) assert eq(da.arcsinh(b*10), np.arcsinh(y*10)) assert eq(da.arccosh(b*10), np.arccosh(y*10)) assert eq(da.arctanh(b/10), np.arctanh(y/10)) assert eq(da.deg2rad(a), np.deg2rad(x)) assert eq(da.rad2deg(a), np.rad2deg(x)) assert eq(da.logical_and(a < 1, b < 4), np.logical_and(x < 1, y < 4)) assert eq(da.logical_or(a < 1, b < 4), np.logical_or(x < 1, y < 4)) assert eq(da.logical_xor(a < 1, b < 4), np.logical_xor(x < 1, y < 4)) assert eq(da.logical_not(a < 1), np.logical_not(x < 1)) assert eq(da.maximum(a, 5 - a), np.maximum(a, 5 - a)) assert eq(da.minimum(a, 5 - a), np.minimum(a, 5 - a)) assert eq(da.fmax(a, 5 - a), np.fmax(a, 5 - a)) assert eq(da.fmin(a, 5 - a), np.fmin(a, 5 - a)) assert eq(da.isreal(a + 1j * b), np.isreal(x + 1j * y)) assert eq(da.iscomplex(a + 1j * b), np.iscomplex(x + 1j * y)) assert eq(da.isfinite(a), np.isfinite(x)) assert eq(da.isinf(a), np.isinf(x)) assert eq(da.isnan(a), np.isnan(x)) assert eq(da.signbit(a - 3), np.signbit(x - 3)) assert eq(da.copysign(a - 3, b), np.copysign(x - 3, y)) assert eq(da.nextafter(a - 3, b), np.nextafter(x - 3, y)) assert eq(da.ldexp(c, c), np.ldexp(z, z)) assert eq(da.fmod(a * 12, b), np.fmod(x * 12, y)) assert eq(da.floor(a * 0.5), np.floor(x * 0.5)) assert eq(da.ceil(a), np.ceil(x)) assert eq(da.trunc(a / 2), np.trunc(x / 2)) assert eq(da.degrees(b), np.degrees(y)) assert eq(da.radians(a), np.radians(x)) assert eq(da.rint(a + 0.3), np.rint(x + 0.3)) assert eq(da.fix(a - 2.5), np.fix(x - 2.5)) assert eq(da.angle(a + 1j), np.angle(x + 1j)) assert eq(da.real(a + 1j), np.real(x + 1j)) assert eq((a + 1j).real, np.real(x + 1j)) assert eq(da.imag(a + 1j), np.imag(x + 1j)) assert eq((a + 1j).imag, np.imag(x + 1j)) assert eq(da.conj(a + 1j * b), np.conj(x + 1j * y)) assert eq((a + 1j * b).conj(), (x + 1j * y).conj()) assert eq(da.clip(b, 1, 4), np.clip(y, 1, 4)) assert eq(da.fabs(b), np.fabs(y)) assert eq(da.sign(b - 2), np.sign(y - 2)) l1, l2 = da.frexp(a) r1, r2 = np.frexp(x) assert eq(l1, r1) assert eq(l2, r2) l1, l2 = da.modf(a) r1, r2 = np.modf(x) assert eq(l1, r1) assert eq(l2, r2) assert eq(da.around(a, -1), np.around(x, -1))
def test_arithmetic(): x = np.arange(5).astype('f4') + 2 y = np.arange(5).astype('i8') + 2 z = np.arange(5).astype('i4') + 2 a = da.from_array(x, chunks=(2, )) b = da.from_array(y, chunks=(2, )) c = da.from_array(z, chunks=(2, )) assert eq(a + b, x + y) assert eq(a * b, x * y) assert eq(a - b, x - y) assert eq(a / b, x / y) assert eq(b & b, y & y) assert eq(b | b, y | y) assert eq(b ^ b, y ^ y) assert eq(a // b, x // y) assert eq(a**b, x**y) assert eq(a % b, x % y) assert eq(a > b, x > y) assert eq(a < b, x < y) assert eq(a >= b, x >= y) assert eq(a <= b, x <= y) assert eq(a == b, x == y) assert eq(a != b, x != y) assert eq(a + 2, x + 2) assert eq(a * 2, x * 2) assert eq(a - 2, x - 2) assert eq(a / 2, x / 2) assert eq(b & True, y & True) assert eq(b | True, y | True) assert eq(b ^ True, y ^ True) assert eq(a // 2, x // 2) assert eq(a**2, x**2) assert eq(a % 2, x % 2) assert eq(a > 2, x > 2) assert eq(a < 2, x < 2) assert eq(a >= 2, x >= 2) assert eq(a <= 2, x <= 2) assert eq(a == 2, x == 2) assert eq(a != 2, x != 2) assert eq(2 + b, 2 + y) assert eq(2 * b, 2 * y) assert eq(2 - b, 2 - y) assert eq(2 / b, 2 / y) assert eq(True & b, True & y) assert eq(True | b, True | y) assert eq(True ^ b, True ^ y) assert eq(2 // b, 2 // y) assert eq(2**b, 2**y) assert eq(2 % b, 2 % y) assert eq(2 > b, 2 > y) assert eq(2 < b, 2 < y) assert eq(2 >= b, 2 >= y) assert eq(2 <= b, 2 <= y) assert eq(2 == b, 2 == y) assert eq(2 != b, 2 != y) assert eq(-a, -x) assert eq(abs(a), abs(x)) assert eq(~(a == b), ~(x == y)) assert eq(~(a == b), ~(x == y)) assert eq(da.logaddexp(a, b), np.logaddexp(x, y)) assert eq(da.logaddexp2(a, b), np.logaddexp2(x, y)) assert eq(da.exp(b), np.exp(y)) assert eq(da.log(a), np.log(x)) assert eq(da.log10(a), np.log10(x)) assert eq(da.log1p(a), np.log1p(x)) assert eq(da.expm1(b), np.expm1(y)) assert eq(da.sqrt(a), np.sqrt(x)) assert eq(da.square(a), np.square(x)) assert eq(da.sin(a), np.sin(x)) assert eq(da.cos(b), np.cos(y)) assert eq(da.tan(a), np.tan(x)) assert eq(da.arcsin(b / 10), np.arcsin(y / 10)) assert eq(da.arccos(b / 10), np.arccos(y / 10)) assert eq(da.arctan(b / 10), np.arctan(y / 10)) assert eq(da.arctan2(b * 10, a), np.arctan2(y * 10, x)) assert eq(da.hypot(b, a), np.hypot(y, x)) assert eq(da.sinh(a), np.sinh(x)) assert eq(da.cosh(b), np.cosh(y)) assert eq(da.tanh(a), np.tanh(x)) assert eq(da.arcsinh(b * 10), np.arcsinh(y * 10)) assert eq(da.arccosh(b * 10), np.arccosh(y * 10)) assert eq(da.arctanh(b / 10), np.arctanh(y / 10)) assert eq(da.deg2rad(a), np.deg2rad(x)) assert eq(da.rad2deg(a), np.rad2deg(x)) assert eq(da.logical_and(a < 1, b < 4), np.logical_and(x < 1, y < 4)) assert eq(da.logical_or(a < 1, b < 4), np.logical_or(x < 1, y < 4)) assert eq(da.logical_xor(a < 1, b < 4), np.logical_xor(x < 1, y < 4)) assert eq(da.logical_not(a < 1), np.logical_not(x < 1)) assert eq(da.maximum(a, 5 - a), np.maximum(a, 5 - a)) assert eq(da.minimum(a, 5 - a), np.minimum(a, 5 - a)) assert eq(da.fmax(a, 5 - a), np.fmax(a, 5 - a)) assert eq(da.fmin(a, 5 - a), np.fmin(a, 5 - a)) assert eq(da.isreal(a + 1j * b), np.isreal(x + 1j * y)) assert eq(da.iscomplex(a + 1j * b), np.iscomplex(x + 1j * y)) assert eq(da.isfinite(a), np.isfinite(x)) assert eq(da.isinf(a), np.isinf(x)) assert eq(da.isnan(a), np.isnan(x)) assert eq(da.signbit(a - 3), np.signbit(x - 3)) assert eq(da.copysign(a - 3, b), np.copysign(x - 3, y)) assert eq(da.nextafter(a - 3, b), np.nextafter(x - 3, y)) assert eq(da.ldexp(c, c), np.ldexp(z, z)) assert eq(da.fmod(a * 12, b), np.fmod(x * 12, y)) assert eq(da.floor(a * 0.5), np.floor(x * 0.5)) assert eq(da.ceil(a), np.ceil(x)) assert eq(da.trunc(a / 2), np.trunc(x / 2)) assert eq(da.degrees(b), np.degrees(y)) assert eq(da.radians(a), np.radians(x)) assert eq(da.rint(a + 0.3), np.rint(x + 0.3)) assert eq(da.fix(a - 2.5), np.fix(x - 2.5)) assert eq(da.angle(a + 1j), np.angle(x + 1j)) assert eq(da.real(a + 1j), np.real(x + 1j)) assert eq((a + 1j).real, np.real(x + 1j)) assert eq(da.imag(a + 1j), np.imag(x + 1j)) assert eq((a + 1j).imag, np.imag(x + 1j)) assert eq(da.conj(a + 1j * b), np.conj(x + 1j * y)) assert eq((a + 1j * b).conj(), (x + 1j * y).conj()) assert eq(da.clip(b, 1, 4), np.clip(y, 1, 4)) assert eq(da.fabs(b), np.fabs(y)) assert eq(da.sign(b - 2), np.sign(y - 2)) l1, l2 = da.frexp(a) r1, r2 = np.frexp(x) assert eq(l1, r1) assert eq(l2, r2) l1, l2 = da.modf(a) r1, r2 = np.modf(x) assert eq(l1, r1) assert eq(l2, r2) assert eq(da.around(a, -1), np.around(x, -1))
USEcalibr0V_i = [] USEcalibr0V_time = [['2018-04-17T17:28', '2018-04-17T17:38']] # [['2018-04-17T19:10', '2018-04-17T19:20']] nAveragePrefer = 128 # 1200 # Filter min_P = 0.5 # Displey vecScale = 1 DISP_TimeZoom = [['2018-04-17T20:00', '2018-04-18T00:00']] maxGsumMinus1 = 0.3 # 0.1 TimeShiftedFromUTC_s = 0 # Angles in radians: fPitch = lambda Gxyz: -da.arctan2(Gxyz[0, :], da.sqrt(da.sum(da.square(Gxyz[1:, :]), 0))) fRoll = lambda Gxyz: da.arctan2(Gxyz[1, :], Gxyz[2, :]) # da.arctan2(Gxyz[1,:], da.sqrt(da.sum(da.square(Gxyz[(0,2),:]), 0))) #=da.arctan2(Gxyz[1,:], da.sqrt(da.square(Gxyz[0,:])+da.square(Gxyz[2,:])) ) fInclination = lambda Gxyz: da.arctan2(da.sqrt(da.sum(da.square(Gxyz[:-1, :]), 0)), Gxyz[2, :]) fHeading = lambda H, p, r: da.arctan2(H[2, :] * da.sin(r) - H[1, :] * da.cos(r), H[0, :] * da.cos(p) + (H[1, :] * da.sin(r) + H[2, :] * da.cos(r)) * da.sin(p)) fG = lambda Axyz, Ag, Cg: da.dot(Ag.T, (Axyz - Cg[0, :]).T) fGi = lambda Ax, Ay, Az, Ag, Cg, i: da.dot(Ag.T, (da.column_stack((Ax, Ay, Az))[slice(*i)] - Cg[0, :]).T) fbinningClip = lambda x, bin2_iStEn, bin1_nAverage: da.mean(da.reshape(x[slice(*bin2_iStEn)], (-1, bin1_nAverage)), 1) fbinning = lambda x, bin1_nAverage: da.mean(da.reshape(x, (-1, bin1_nAverage)), 1) repeat3shift1 = lambda A2: [A2[t:(len(A2) - 2 + t)] for t in range(3)] median3cols = lambda a, b, c: da.where(a < b, da.where(c < a, a, da.where(b < c, b, c)), da.where(a < c, a, da.where(c < b, b, c))) median3 = lambda x: da.hstack((np.NaN, median3cols(*repeat3shift1(x)), np.NaN))
def CartesianToEquatorial(pos, observer=[0,0,0], frame='icrs'): """ Convert Cartesian position coordinates to equatorial right ascension and declination, using the specified observer location. .. note:: RA and DEC will be returned in degrees, with RA in the range [0,360] and DEC in the range [-90, 90]. Parameters ---------- pos : array_like a N x 3 array holding the Cartesian position coordinates observer : array_like a length 3 array holding the observer location frame : string A string, 'icrs' or 'galactic'. The frame of the input position. Use 'icrs' if the cartesian position is already in Equatorial. Returns ------- ra, dec : array_like the right ascension and declination coordinates, in degrees. RA will be in the range [0,360] and DEC in the range [-90, 90] """ # split x, y, z to signify that we do not need to have pos # as a full chunk in the last dimension. # this is useful when we use apply_gufunc. x, y, z = [pos[..., i] - observer[i] for i in range(3)] if frame == 'icrs': # FIXME: Convert these to a gufunc that uses astropy? # might be a step backward. # from equatorial to equatorial s = da.hypot(x, y) lon = da.arctan2(y, x) lat = da.arctan2(z, s) # convert to degrees lon = da.rad2deg(lon) lat = da.rad2deg(lat) # wrap lon to [0,360] lon = da.mod(lon-360., 360.) ra, dec = lon, lat else: from astropy.coordinates import SkyCoord def cart_to_eq(x, y, z): try: sc = SkyCoord(x, y, z, representation_type='cartesian', frame=frame) scg = sc.transform_to(frame='icrs') scg.representation_type = 'unitspherical' except: sc = SkyCoord(x, y, z, representation='cartesian', frame=frame) scg = sc.transform_to(frame='icrs') scg.representation = 'unitspherical' ra, dec = scg.ra.value, scg.dec.value return ra, dec dtype = pos.dtype ra, dec = da.apply_gufunc(cart_to_eq, '(),(),()->(),()', x, y, z, output_dtypes=[dtype, dtype]) return da.stack((ra, dec), axis=0)
from distributed import Client, progress import dask.array as da dask_client = Client( scheduler_file="/global/cscratch1/sd/rkube/scheduler.json") with np.load("../dask_fft_data_s0000.npz") as df: num_channels, num_fft = df["fft_data"].shape print(num_channels, num_fft) fft_data = da.from_array(df["fft_data"], chunks=(1, num_fft)) dask_client.persist(fft_data) # Calculate the crosspower using the array interface res1 = (fft_data[:2, :] * fft_data[-2:, :].conj()).mean(axis=1) print("type res1 = ", type(res1)) res2 = da.arctan2(res1.real, res1.imag).real print("type res2 = ", type(res2)) print("result res2 = ", res2.compute()) # Calculate the crosspower using the distributed interface def cross_phase(ft_data, ch1, ch2): _tmp1 = (ft_data[ch1, :] * ft_data[ch2, :].conj()).mean().compute() print("** crosspower: type(tmp1) =", type(_tmp1)) _tmp2 = np.arctan2(_tmp1.real, _tmp1.imag).real #_tmp2 = _tmp1.real + _tmp1.imag return (_tmp2)
def sinfit(array, periods, dim=None, coord=None, unit='s'): """ Least squares sinusoidal fit. Fit sinusoidal functions ``y = A[p] * sin(2 * pi * ax * f[1] + phi[1])`` Parameters ---------- array : xarray.DataArray Data to be fitted periods: float or list of float The periods of the sinusoidal functions to be fitted dim : str, optional The dimension along which the data will be fitted. If not precised, the first dimension will be used unit : {'D', 'h', 'm', 's', 'ms', 'us', 'ns'}, optional If the fit uses a datetime dimension, the unit of the period may be specified here. Returns ------- modes : Dataset A Dataset with the amplitude and the phase for each periods """ if dim is None: dim = array.dims[0] if _utils.is_scalar(periods): periods = [ periods, ] n = 2 * len(periods) + 1 # Sort frequencies in ascending order periods.sort(reverse=True) # Re-order the array to place the fitting dimension as the first dimension # + stack the other dimensions array_stacked = _order_and_stack(array, dim) dim_chunk = array.chunks[array.get_axis_num(dim)][0] # Check if the dimension is associated with a numpy.datetime # and normalize to use periods and time in seconds if coord is None: coord = array[dim] if _utils.is_datetime(coord): # Use the 1e-9 to scale nanoseconds to seconds (by default, xarray use # datetime in nanoseconds t = coord.data.astype('f8') * 1e-9 freqs = 1. / pd.to_timedelta(periods, unit=unit).total_seconds() else: t = coord.data freqs = 1. / periods # Build coefficient matrix for the fit using the exponential form x = da.vstack([da.cos(2 * np.pi * f * t) for f in reversed(freqs)] + [ da.ones(len(t), chunks=dim_chunk), ] + [da.sin(2 * np.pi * f * t) for f in freqs]).T x = x.rechunk((dim_chunk, n)) # Solve the least-square system c, _, _, _ = da.linalg.lstsq(x, array_stacked.data) # Get cosine (a) and sine (b) ampitudes b = c[0:n // 2, ][::-1] a = c[n // 2 + 1:, ] # Compute amplitude and phase amplitude = da.sqrt(a**2 + b**2) phase = da.arctan2(b, a) * 180. / np.pi # Store the results new_dims = ('periods', ) + array_stacked.dims[1:] new_coords = { co: array_stacked.coords[co] for co in array_stacked.coords if co != dim } var_dict = { 'amplitude': (new_dims, amplitude), 'phase': (new_dims, phase), 'offset': (array_stacked.dims[1:], c[n // 2, ]) } ds = xr.Dataset(var_dict, coords=new_coords) ds = ds.assign_coords(periods=periods) ds['periods'].attrs['units'] = unit # Unstack the data modes = _unstack(ds) return modes
assert mapper is not None self.fullname, self.unit, self.mapper, self.column, self.extras = fullname, unit, mapper, column, extras self.conjugate = conjugate self.axis = axis _identity = lambda x: x # this dict maps short axis names into full DataMapper objects data_mappers = OrderedDict( _=DataMapper("", "", _identity), amp=DataMapper("Amplitude", "", abs), logamp=DataMapper("Log-amplitude", "", lambda x: da.log10(abs(x))), phase=DataMapper( "Phase", "deg", lambda x: da.arctan2(da.imag(x), da.real(x)) * 180 / math.pi), real=DataMapper("Real", "", da.real), imag=DataMapper("Imag", "", da.imag), TIME=DataMapper("Time", "s", axis=0, column="TIME", mapper=_identity), ROW=DataMapper("Row number", "", column=False, axis=0, extras=["rows"], mapper=lambda x, rows: rows), BASELINE=DataMapper("Baseline", "", column=False, axis=0, extras=["baselines"], mapper=lambda x, baselines: baselines),
def CartesianToEquatorial(pos, observer=[0,0,0], frame='icrs'): """ Convert Cartesian position coordinates to equatorial right ascension and declination, using the specified observer location. .. note:: RA and DEC will be returned in degrees, with RA in the range [0,360] and DEC in the range [-90, 90]. Parameters ---------- pos : array_like a N x 3 array holding the Cartesian position coordinates observer : array_like a length 3 array holding the observer location frame : string A string, 'icrs' or 'galactic'. The frame of the input position. Use 'icrs' if the cartesian position is already in Equatorial. Returns ------- ra, dec : array_like the right ascension and declination coordinates, in degrees. RA will be in the range [0,360] and DEC in the range [-90, 90] """ # split x, y, z to signify that we do not need to have pos # as a full chunk in the last dimension. # this is useful when we use apply_gufunc. x, y, z = [pos[..., i] - observer[i] for i in range(3)] if frame == 'icrs': # FIXME: Convert these to a gufunc that uses astropy? # might be a step backward. # from equatorial to equatorial s = da.hypot(x, y) lon = da.arctan2(y, x) lat = da.arctan2(z, s) # convert to degrees lon = da.rad2deg(lon) lat = da.rad2deg(lat) # wrap lon to [0,360] lon = da.mod(lon-360., 360.) ra, dec = lon, lat else: from astropy.coordinates import SkyCoord def cart_to_eq(x, y, z): try: sc = SkyCoord(x, y, z, representation_type='cartesian', frame=frame) scg = sc.transform_to(frame='icrs') scg.representation_type = 'unitspherical' except: sc = SkyCoord(x, y, z, representation='cartesian', frame=frame) scg = sc.transform_to(frame='icrs') scg.representation = 'unitspherical' ra, dec = scg.ra.value, scg.dec.value return ra, dec dtype = pos.dtype ra, dec = da.apply_gufunc(cart_to_eq, '(),(),()->(),()', x, y, z, output_dtypes=[dtype, dtype]) return da.stack((ra, dec), axis=0)