.. _array_configuration_doc: Array Configuration =================== The `NenuFAR `_ low-frequency radio telescope can be viewed as a hierarchy of elements (i.e., the individual dipole antennas, the mini-arrays and the whole array). In order to better capture these configurations, the associated parameters, while aiming at delivering the related physical properties, ``nenupy`` offers two main classes to represent this complexity: :class:`~nenupy.instru.nenufar.MiniArray` and :class:`~nenupy.instru.nenufar.NenuFAR`. Both of these classes inherit from the base class :class:`~nenupy.instru.interferometer.Interferometer`, which is an abstract Python class. Nonetheless, all derived classes share common methods and attributes. .. seealso:: Common :class:`~nenupy.instru.interferometer.Interferometer` methods to get physical quantities for a given array configuration are described in :ref:`instrument_properties_doc`. MiniArray class --------------- A `Mini-Array `_ is a tile of 19 dipole `antennas `_. Upon NenuFAR's completion, there will be 96 of them forming the core of the instrument, and 6 other called the 'remote' ones to increase the resolution in imaging mode. Mini-Array selection ^^^^^^^^^^^^^^^^^^^^ An instance of such Mini-Array is created as a :class:`~nenupy.instru.nenufar.MiniArray` object. The :attr:`~nenupy.instru.nenufar.MiniArray.index` attribute defines which Mini-Array is to be considered (out of the 96 + 6). Below, the Mini-Array '10' is selected and its antenna names are printed. .. code-block:: python >>> from nenupy.instru import MiniArray >>> ma = MiniArray(index=10) >>> ma.antenna_names array(['Ant01', 'Ant02', 'Ant03', 'Ant04', 'Ant05', 'Ant06', 'Ant07', 'Ant08', 'Ant09', 'Ant10', 'Ant11', 'Ant12', 'Ant13', 'Ant14', 'Ant15', 'Ant16', 'Ant17', 'Ant18', 'Ant19'], dtype='>> ma.rotation 290° >>> ma.plot() .. figure:: ../_images/ma_distribution_10.png :width: 450 :align: center Distribution of antennas belonging to Mini-Array 10. NenuFAR class ------------- `NenuFAR `_ is an array of 96 so-called 'core' Mini-Arrays, plus 6 'remote' Mini-Arrays (for more details, see `NenuFAR Mini-Arrays Distribution `_). NenuFAR instantiation ^^^^^^^^^^^^^^^^^^^^^ Several possibilities exist to create an instance of :class:`~nenupy.instru.nenufar.NenuFAR`, regarding the instrument configuration relevant to a given analysis: * By default, :class:`~nenupy.instru.nenufar.NenuFAR` gets instantiated as the 'core' array, meaning that NenuFAR contains 96 Mini-Arrays (each of them composed of 19 dipole antennas). .. code-block:: python >>> from nenupy.instru import NenuFAR >>> nenufar = NenuFAR() >>> nenufar.size 96 * In order to also include the 6 'remote' Mini-Arrays, the parameter :attr:`~nenupy.instru.nenufar.NenuFAR.include_remote_mas` can be set to ``True``. .. code-block:: python >>> from nenupy.instru import NenuFAR >>> nenufar = NenuFAR(include_remote_mas=True) >>> nenufar.size 102 * Finally, in combination with the two previous initialization methods, it is also possible to set the number of dipole antennas each Mini-Arrays includes. This can be done by setting :attr:`~nenupy.instru.nenufar.NenuFAR.miniarrays_antenna` to any value accepted in antenna selection of the class :class:`~nenupy.instru.nenufar.MiniArray` (see also :ref:`element_selection_sec`). .. code-block:: python >>> from nenupy.instru import NenuFAR >>> nenufar = NenuFAR(miniarrays_antenna=["Ant01", "Ant02", "Ant03"]) >>> nenufar.size 96 .. note:: Although setting specific Mini-Arrays antennas does not affect the global array distribution, instrument properties heavily depends on the number of antennas per Mini-Array (see :ref:`instrument_properties_doc` and :ref:`beam_simulation_doc`). Such as :class:`~nenupy.instru.nenufar.MiniArray`, a :class:`~nenupy.instru.nenufar.NenuFAR` instance can be easily displayed using the :meth:`~nenupy.instru.interferometer.Interferometer.plot` method: .. code-block:: python >>> from nenupy.instru import NenuFAR >>> nenufar = NenuFAR() >>> nenufar.plot() .. figure:: ../_images/nenufar_distribution.png :width: 450 :align: center NenuFAR 'core' Mini-Arrays distribution. Operations on arrays -------------------- Once an instance of :class:`~nenupy.instru.nenufar.MiniArray` or :class:`~nenupy.instru.nenufar.NenuFAR` is produced, several operations can be performed to alter the resulting array distribution of elements. .. _element_selection_sec: Element selection ^^^^^^^^^^^^^^^^^ It is for example possible to select a sub-set of elements within an existing array, using the python indexing operator ``[]``. This operation allows for four different types of input: * Normal indexing using integers as selection indices over the array elements: .. code-block:: python :emphasize-lines: 2 >>> from nenupy.instru import MiniArray >>> ma = MiniArray()[0, 1, 3] >>> ma.antenna_names array(['Ant01', 'Ant02', 'Ant04'], dtype='`_ :class:`~numpy.ndarray` object, which enables ore complicated operations on the indexing list beforehand: .. code-block:: python :emphasize-lines: 4 >>> from nenupy.instru import MiniArray >>> import numpy as np >>> ma_indices = np.concatenate((np.arange(3), np.arange(10, 12))) >>> ma = MiniArray()[ma_indices] >>> ma.antenna_names array(['Ant01', 'Ant02', 'Ant03', 'Ant11', 'Ant12'], dtype='>> from nenupy.instru import MiniArray >>> ma = MiniArray()[3:9] >>> ma.antenna_names array(['Ant04', 'Ant05', 'Ant06', 'Ant07', 'Ant08', 'Ant09'], dtype='>> from nenupy.instru import MiniArray >>> ma = MiniArray()["Ant02", "Ant18"] >>> ma.antenna_names array(['Ant02', 'Ant18'], dtype='>> from nenupy.instru import MiniArray >>> ma_1 = MiniArray()["Ant01", "Ant02"] >>> ma_2 = MiniArray()["Ant18", "Ant19"] >>> combined_ma = ma_1 + ma_2 >>> combined_ma.antenna_names array(['Ant01', 'Ant02', 'Ant18', 'Ant19'], dtype='>> from nenupy.instru import MiniArray >>> ma_1 = MiniArray()["Ant01", "Ant02"] >>> ma_2 = MiniArray()["Ant02, Ant18", "Ant19"] >>> combined_ma = ma_1 - ma_2 >>> combined_ma.antenna_names array(['Ant01'], dtype='