예제 #1
0
def test_altaz_to_radec():
    radec_fast = altaz_to_radec(altaz=SkyCoord(
        300,
        45,
        unit="deg",
        frame=AltAz(obstime=Time("2022-01-01T12:00:00"),
                    location=nenufar_position)),
                                fast_compute=True)
    assert isinstance(radec_fast, SkyCoord)
    assert radec_fast.ra.deg == pytest.approx(212.967, 1e-3)
    assert radec_fast.dec.deg == pytest.approx(49.440, 1e-3)

    radec_slow = altaz_to_radec(altaz=SkyCoord(
        300,
        45,
        unit="deg",
        frame=AltAz(obstime=Time("2022-01-01T12:00:00"),
                    location=nenufar_position)),
                                fast_compute=False)
    assert isinstance(radec_slow, SkyCoord)
    assert radec_slow.ra.deg == pytest.approx(212.764, 1e-3)
    assert radec_slow.dec.deg == pytest.approx(49.546, 1e-3)

    radec_array = altaz_to_radec(altaz=SkyCoord(
        [100, 300], [45, 45],
        unit="deg",
        frame=AltAz(obstime=Time("2022-01-01T12:00:00"),
                    location=nenufar_position)),
                                 fast_compute=True)
    assert radec_array.shape == (2, )
예제 #2
0
파일: xst.py 프로젝트: AlanLoh/nenupy
    def compute_nenufar_tv(self, analog_pointing_file: str = None, **kwargs):
        """ """

        obs_time = self.time[0] + (self.time[-1] - self.time[0])/2
        fov_radius = kwargs.get("fov_radius", 27*u.deg)
        resolution = kwargs.get("resolution", 0.5*u.deg)
        stokes = kwargs.get("stokes", "I")

        if analog_pointing_file is None:
            phase_center_altaz = SkyCoord(
                0, 90, unit="deg",
                frame=AltAz(
                    obstime=obs_time,
                    location=nenufar_position
                )
            )
        else:
            pointing = Pointing.from_file(
                analog_pointing_file,
                include_corrections=False
            )[obs_time.reshape((1,))]
            phase_center_altaz = pointing.custom_ho_coordinates[0]

        data = self.get_stokes(stokes)
        sky_image = data.make_image(
            resolution=resolution,
            fov_radius=fov_radius,
            phase_center=altaz_to_radec(phase_center_altaz)
        )

        return TV_Image(
            tv_image=sky_image,
            analog_pointing=phase_center_altaz,
            fov_radius=fov_radius,
        )
예제 #3
0
def compute_uvw(interferometer: Interferometer,
                phase_center: SkyCoord = None,
                time: Time = Time.now(),
                observer: EarthLocation = nenufar_position):
    """ """

    # Get the baselines in ITRF coordinates
    baselines_itrf = interferometer.baselines.bsl
    xyz = baselines_itrf[np.tril_indices(interferometer.size)].T
    #xyz = np.array(baselines_itrf).T

    # Select zenith phase center if nothing is provided
    if phase_center is None:
        log.debug("Default zenith phase center selected.")
        zenith = SkyCoord(np.zeros(time.size),
                          np.ones(time.size) * 90,
                          unit="deg",
                          frame=AltAz(obstime=time, location=observer))
        phase_center = altaz_to_radec(zenith)
    center_dec_rad = phase_center.dec.rad
    if np.isscalar(center_dec_rad):
        center_dec_rad = np.repeat(center_dec_rad, time.size)

    # Compute the hour angle of the phase center
    lha = hour_angle(radec=phase_center,
                     time=time,
                     observer=observer,
                     fast_compute=True)
    lha_rad = lha.rad

    # Compute UVW projection
    sr = np.sin(lha_rad)
    cr = np.cos(lha_rad)
    sd = np.sin(center_dec_rad)
    cd = np.cos(center_dec_rad)
    rot_uvw = np.array([[sr, cr, np.zeros(time.size)], [-sd * cr, sd * sr, cd],
                        [cd * cr, -cd * sr, sd]])

    # Project the baselines in the UVW frame
    uvw = -np.dot(np.moveaxis(rot_uvw, -1, 0), xyz)

    return np.moveaxis(uvw, -1, 1)


# ============================================================= #
# ============================================================= #
예제 #4
0
파일: xst.py 프로젝트: AlanLoh/nenupy
    def save_fits(self, file_name: str, partial: bool = True):
        """ """
        
        phase_center_eq = altaz_to_radec(self.analog_pointing)

        header = [
            ("software", 'nenupy'),
            ("version", nenupy.__version__),
            ("contact", nenupy.__email__),
            ("azana", self.analog_pointing.az.deg),
            ("elana", self.analog_pointing.alt.deg),
            ("freq", self.tv_image.frequency[0].to(u.MHz).value),
            ("obstime", self.tv_image.time[0].isot),
            ("fov", self.fov_radius.to(u.deg).value * 2),
            ("pc_ra", phase_center_eq.ra.deg),
            ("pc_dec", phase_center_eq.dec.deg),
            ("stokes", self.tv_image.polarization[0])
        ]

        map2write = self.tv_image.value[0, 0, 0].copy()
        write_map(
            filename=file_name,
            m=map2write,
            nest=False,
            coord='C',
            overwrite=True,
            dtype=self.tv_image.value.dtype,
            extra_header=header,
            partial=partial
        )
        log.info(
            'HEALPix image of {} cells (nside={}) saved in `{}`.'.format(
                map2write.size,
                self.tv_image.nside,
                file_name
            )
        )
예제 #5
0
파일: xst.py 프로젝트: AlanLoh/nenupy
    def save_png(self, figname: str, beam_contours: bool = True, show_sources: bool = True, **kwargs):
        """ """
        image_center = altaz_to_radec(
            SkyCoord(
                self.analog_pointing.az,
                self.analog_pointing.alt,
                frame=AltAz(
                    obstime=self.tv_image.time[0],
                    location=nenufar_position
                )
            )
        )

        #kwargs = {}

        if show_sources:
            src_names = []
            src_position = []

            with open(join(dirname(__file__), "nenufar_tv_sources.json")) as src_file:
                sources = json.load(src_file)

            for name in sources["FixedSources"]:
                src = FixedTarget.from_name(name, time=self.tv_image.time[0])
                if src.coordinates.separation(image_center) <= 0.8*self.fov_radius:
                    src_names.append(name)
                    src_position.append(src.coordinates)
            for name in sources["SolarSystemSources"]:
                src = SolarSystemTarget.from_name(name, time=self.tv_image.time[0])
                if src.coordinates.separation(image_center) <= 0.8*self.fov_radius:
                    src_names.append(name)
                    src_position.append(src.coordinates)

            if len(src_position) != 0:
                kwargs["text"] = (SkyCoord(src_position), src_names, "white")

        if beam_contours:
            # Simulate the array factor
            ma = MiniArray()
            af_sky = ma.array_factor(
                sky=HpxSky(
                    resolution=0.2*u.deg,
                    time=self.tv_image.time[0],
                    frequency=self.tv_image.frequency[0]
                ),
                pointing=Pointing(
                    coordinates=image_center,
                    time=self.tv_image.time[0]
                )
            )
            # Normalize the array factor
            af = af_sky[0, 0, 0].compute()
            af_normalized = af/af.max()
            kwargs["contour"] = (af_normalized, np.arange(0.5, 1, 0.2), "copper")

        # Plot
        self.tv_image[0, 0, 0].plot(
            center=image_center,
            radius=self.fov_radius - 2.5*u.deg,
            figname=figname,
            colorbar_label=f"Stokes {self.tv_image.polarization[0]}",
            **kwargs
        )
        return
예제 #6
0
파일: xst.py 프로젝트: AlanLoh/nenupy
    def rephase_visibilities(self, phase_center, uvw):
        """ """

        # Compute the zenith original phase center
        zenith = SkyCoord(
            np.zeros(self.time.size),
            np.ones(self.time.size)*90,
            unit="deg",
            frame=AltAz(
                obstime=self.time,
                location=nenufar_position
            )
        )
        zenith_phase_center = altaz_to_radec(zenith)

        # Define the rotation matrix
        def rotation_matrix(skycoord):
            """
            """
            ra_rad = skycoord.ra.rad
            dec_rad = skycoord.dec.rad

            if np.isscalar(ra_rad):
                ra_rad = np.array([ra_rad])
                dec_rad = np.array([dec_rad])

            cos_ra = np.cos(ra_rad)
            sin_ra = np.sin(ra_rad)
            cos_dec = np.cos(dec_rad)
            sin_dec = np.sin(dec_rad)

            return np.array([
                [cos_ra, -sin_ra, np.zeros(ra_rad.size)],
                [-sin_ra*sin_dec, -cos_ra*sin_dec, cos_dec],
                [sin_ra*cos_dec, cos_ra*cos_dec, sin_dec],
            ])

        # Transformation matrices
        to_origin = rotation_matrix(zenith_phase_center) # (3, 3, ntimes)
        to_new_center = rotation_matrix(phase_center) # (3, 3, 1)
        total_transformation = np.matmul(
            np.transpose(
                to_new_center,
                (2, 0, 1)
            ),
            to_origin
        ) # (3, 3, ntimes)
        rotUVW = np.matmul(
            np.expand_dims(
                (to_origin[2, :] - to_new_center[2, :]).T,
                axis=1
            ),
            np.transpose(
                to_origin,
                (2, 1, 0)
            )
        ) # (ntimes, 1, 3)
        phase = np.matmul(
            rotUVW,
            np.transpose(uvw, (0, 2, 1))
        ) # (ntimes, 1, nvis)
        rotate_visibilities = np.exp(
            2.j*np.pi*phase/wavelength(self.frequency).to(u.m).value[None, :, None]
        ) # (ntimes, nfreqs, nvis)

        new_uvw = np.matmul(
            uvw, # (ntimes, nvis, 3)
            np.transpose(total_transformation, (2, 0, 1))
        )

        return rotate_visibilities, new_uvw
예제 #7
0
파일: pointing.py 프로젝트: AlanLoh/nenupy
    def zenith_tracking(cls,
            time: Time,
            duration: TimeDelta = TimeDelta(1, format="sec"),
            observer: EarthLocation = nenufar_position
        ):
        """ Instantiates a :class:`~nenupy.astro.pointing.Pointing`
            object at the local zenith.
        
            :param time:
                Start times of the zenith pointing.
            :type t_min:
                :class:`~astropy.time.Time`
            :param duration:
                Duration of each individual pointing. If this argument is
                a scalar, then it will be applied to every start time (defined
                in ``time``).
                Default is one hour.
            :type duration:
                :class:`~astropy.time.TimeDelta`
            :param observer:
                Earth location from where the target is observed.
                Default is NenuFAR's location.
            :type observer:
                :class:`~astropy.coordinates.EarthLocation`

            :return:
                Pointing fixed at the local zenith.
            :rtype:
                :class:`~nenupy.astro.pointing.Pointing`

            :Example:
                >>> from nenupy.astro.pointing import Pointing
                >>> from astropy.time import Time, TimeDelta
                >>> pointing = Pointing.target_transit(
                        target=cyg_a,
                        time=Time("2021-01-01 00:00:00"),
                        duration=TimeDelta(7200, format="sec"),
                        azimuth=180*u.deg
                    )

        """
        az = 0
        el = 90
        if not time.isscalar:
            az = np.repeat(az, time.size)
            el = np.repeat(el, time.size)
        altaz = SkyCoord(
            az,
            el,
            unit="deg",
            frame=AltAz(
                obstime=time,
                location=observer
            )
        )
        pointing = cls(
            coordinates=altaz_to_radec(
                altaz=altaz,
                fast_compute=False
            ),
            time=time,
            duration=duration,
            observer=observer
        )
        pointing.custom_ho_coordinates = altaz.reshape((1,)) if altaz.isscalar else altaz
        return pointing
예제 #8
0
파일: pointing.py 프로젝트: AlanLoh/nenupy
    def from_file(cls,
            file_name,
            beam_index: int = 0,
            include_corrections: bool = True
        ):
        """ Instantiates a :class:`~nenupy.astro.pointing.Pointing` object from
            a NenuFAR pointing file.
            Several beam pointings (analog and/or numerical) could be described 
            in ``file_name``. The argument ``beam_index`` allows for the selection
            of one of them.
        
            :param file_name:
                NenuFAR pointing file, either analog (ending with ``.altazA``) or 
                numerical (ending with ``.altazB``).
            :type file_name:
                `str`
            :param beam_index:
                Beam number to take into account.
            :type beam_index:
                `int`
            :param include_corrections:
                Include or not the pointing corrections (default is ``True``).
                Only has an effect on analog beam corrections.
            :type include_corrections:
                `bool`
            
            :return:
                Pointing derived from a NenuFAR pointing file.
            :rtype:
                :class:`~nenupy.astro.pointing.Pointing`

            :Example:
                >>> from nenupy.astro.pointing import Pointing
                >>> pointing = Pointing.from_file(
                        file_name=".../20211104_170000_20211104_200000_JUPITER_TRACKING.altazA",
                        beam_index=1
                    )

        """
        if file_name.endswith('.altazA'):
            try:
                pointing = np.loadtxt(
                    file_name,
                    skiprows=3,
                    comments=";",
                    dtype={
                        'names': ('time', 'anabeam', 'az', 'el', 'az_cor', 'el_cor', 'freq', 'el_eff'),
                        'formats': ('U20', 'i4', 'f4', 'f4', 'f4', 'f4', 'U5', 'f4')
                    }
                )
                available_beams = pointing["anabeam"]
                pointing = pointing[available_beams == beam_index]
                azimuths = pointing["az_cor"] if include_corrections else pointing["az"]
                elevations = pointing["el_eff"] if include_corrections else pointing["el"]
            except ValueError:
                # No correction
                pointing = np.loadtxt(
                    file_name,
                    skiprows=3,
                    comments=";",
                    dtype={
                        'names': ('time', 'anabeam', 'az', 'el', 'freq', 'el_eff'),
                        'formats': ('U20', 'i4', 'f4', 'f4', 'U5', 'f4')
                    }
                )
                available_beams = pointing["anabeam"]
                pointing = pointing[available_beams == beam_index]
                azimuths = pointing["az"]
                elevations = pointing["el_eff"] if include_corrections else pointing["el"]
            except IndexError:
                # No beamsquint
                pointing = np.loadtxt(
                    file_name,
                    skiprows=3,
                    comments=";",
                    dtype={
                        'names': ('time', 'anabeam', 'az', 'el', 'az_cor', 'el_cor'),
                        'formats': ('U20', 'i4', 'f4', 'f4', 'f4', 'f4')
                    }
                )
                available_beams = pointing["anabeam"]
                pointing = pointing[available_beams == beam_index]
                azimuths = pointing["az_cor"] if include_corrections else pointing["az"]
                elevations = pointing["el_cor"] if include_corrections else pointing["el"]
            
            if pointing.size == 0:
                raise ValueError(
                    f"Empty pointing, check the beam_index={beam_index} value "
                    f"(avalaible beam indices: {np.unique(available_beams)})."
                )

            times = Time(pointing["time"])
            azimuths *= u.deg
            elevations *= u.deg
            if times.size == 1:
                # for a transit with multiple ABeams
                azimuths = np.append(azimuths, [0]*u.deg)
                elevations = np.append(elevations, [90]*u.deg)
                times = times.insert(1, times[-1] + TimeDelta(1, format="sec"))

            duration = times[1:] - times[:-1]
            times = times[:-1]
            altaz_coords = SkyCoord(
                azimuths[:-1],
                elevations[:-1],
                frame=AltAz(
                    obstime=times,
                    location=nenufar_position
                )
            )
        elif file_name.endswith('.altazB'):
            pointing = np.loadtxt(
                file_name,
                skiprows=2,
                comments=";",
                dtype={
                    'names': ('time', 'anabeam', 'digibeam', 'az', 'el', 'l', 'm', 'n'),
                    'formats': ('U20', 'i4', 'i4', 'f4', 'f4', 'f4', 'f4', 'f4')
                }
            )
            available_beams = pointing["digibeam"]
            pointing = pointing[available_beams == beam_index]
            if pointing.size == 0:
                raise ValueError(
                    f"Empty pointing, check the beam_index={beam_index} value "
                    f"(avalaible beam indices: {np.unique(available_beams)})."
                )
            times = Time(pointing["time"])
            duration = times[1:] - times[:-1]
            # Add the last duration at the end (supposed to be 10 seconds)
            duration = duration.insert(-1, TimeDelta(10, format="sec", scale=duration.scale))
            altaz_coords = SkyCoord(
                pointing['az'],
                pointing["el"],
                unit="deg",
                frame=AltAz(
                    obstime=times,
                    location=nenufar_position
                )
            )

        pointing = cls(
            coordinates=altaz_to_radec(altaz=altaz_coords),
            time=times,
            duration=duration,
            observer=nenufar_position
        )
        pointing.custom_ho_coordinates = altaz_coords
        return pointing
예제 #9
0
파일: pointing.py 프로젝트: AlanLoh/nenupy
    def from_bst(cls,
            bst,
            beam: int = 0,
            analog: bool = True,
            max_points: int = 100
        ):
        """ Instantiates a class:`~nenupy.astro.pointing.Pointing` object from
            a :class:`~nenupy.io.bst.BST` object.

            :param bst:
            :type bst:
            :param beam:
            :type beam:
                `int`
            :param analog:
            :type analog:
                `bool`
            :param max_points:
            :type max_points:

            :returns:
                Pointing derived from a NenuFAR BST file.
            :rtype:
                :class:`~nenupy.astro.pointing.Pointing`

        """
        bst.beam = beam

        if analog:
            time, az, el = bst.analog_pointing
        else:
            time, az, el = bst.digital_pointing
        
        if time.size == 1:
            # for a transit with multiple ABeams
            az = np.append(az, [0]*u.deg)
            el = np.append(el, [90]*u.deg)
            time = time.insert(1, bst.time[-1])

        if time.size > max_points:
            julian_days = time.jd
            jd_rebin = np.linspace(julian_days[0], julian_days[-1], max_points)
            az = np.interp(jd_rebin, julian_days, az)
            el = np.interp(jd_rebin, julian_days, el)
            time = Time(jd_rebin, format='jd')

        altaz_coords = SkyCoord(
            az[:-1],
            el[:-1],
            frame=AltAz(
                obstime=time[:-1],
                location=nenufar_position
            )
        )
        pointing = cls(
            coordinates=altaz_to_radec(altaz=altaz_coords),
            time=time[:-1],
            duration=time[1:] - time[:-1],
            observer=nenufar_position
        )
        pointing.custom_ho_coordinates = altaz_coords

        return pointing