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