Array Configuration

The NenuFAR low-frequency radio telescope can de 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: MiniArray and NenuFAR.

Both of these classes inherit from the base class Interferometer, which is an abstract Python class. Nonetheless, all derived classes share common methods and attributes.

See also

Common Interferometer methods to get physical quantities for a given array configuration are described in Instrument Properties.

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 MiniArray object. The 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.

>>> 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='<U5')

See also

Element selection, to learn how to select given dipole antennas for a particular MiniArray instance.

Rotation and plotting

Each Mini-Array is oriented differently compared to the others. This essential information is kept in the rotation attribute (as a Quantity object) and is used in determining the array imprint on the ground. The distribution of array elements is displayed using the plot() method:

>>> ma.rotation
290°
>>> ma.plot()
../_images/ma_distribution_10.png

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 NenuFAR, regarding the instrument configuration relevant to a given analysis:

  • By default, NenuFAR gets instantiated as the ‘core’ array, meaning that NenuFAR contains 96 Mini-Arrays (each of them composed of 19 dipole antennas).

    >>> from nenupy.instru import NenuFAR
    >>> nenufar = NenuFAR()
    >>> nenufar.size
    96
    
  • In order to also include the 6 ‘remote’ Mini-Arrays, the parameter include_remote_mas can be set to True.

    >>> 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 miniarrays_antenna to any value accepted in antenna selection of the class MiniArray (see also Element selection).

    >>> 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 Instrument Properties and NenuFAR Beam Simulation).

Such as MiniArray, a NenuFAR instance can be easily displayed using the plot() method:

>>> from nenupy.instru import NenuFAR
>>> nenufar = NenuFAR()
>>> nenufar.plot()
../_images/nenufar_distribution.png

NenuFAR ‘core’ Mini-Arrays distribution.

Operations on arrays

Once an instance of MiniArray or NenuFAR is produced, several operations can be performed to alter the resulting array distribution of elements.

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:

    >>> from nenupy.instru import MiniArray
    >>> ma = MiniArray()[0, 1, 3]
    >>> ma.antenna_names
    array(['Ant01', 'Ant02', 'Ant04'], dtype='<U5')
    
  • Numpy ndarray object, which enables ore complicated operations on the indexing list beforehand:

    >>> 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='<U5')
    
  • Python slice notation:

    >>> from nenupy.instru import MiniArray
    >>> ma = MiniArray()[3:9]
    >>> ma.antenna_names
    array(['Ant04', 'Ant05', 'Ant06', 'Ant07', 'Ant08', 'Ant09'], dtype='<U5')
    
  • Antenna names, such as listed in antenna_names:

    >>> from nenupy.instru import MiniArray
    >>> ma = MiniArray()["Ant02", "Ant18"]
    >>> ma.antenna_names
    array(['Ant02', 'Ant18'], dtype='<U5')
    

Note

Errors possibly raised are:

  • DuplicateAntennaError: when an antenna is referenced more than once (e.g., MiniArray()[0, 0, 1]) ;

  • AntennaIndexError: when the required index does not match the current state of the array distribution (e.g., MiniArray()[0, 1, 20]) ;

  • AntennaNameError: when the required element name does not match any of the array element names (e.g., MiniArray()["Ant23"]).

Array combinations

Array combinations may be useful in some specific cases, or to ease the manipulation of Interferometer objects while programming.

Two Interferometer instances are merged with the use of + operator. This operation takes care of duplicated elements belong to both of the summed instances.

>>> 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='<U5')

Array elements from one instance Interferometer can be removed with the use of - operator. Every element of the first instance which also belongs to the second instance is excluded.

>>> 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='<U5')