Open In Colab

astrohack

VLA Holography Tutorial

Important External Information

  • xarray Official Documentation (docs).

  • Dask Official Documentation (docs).

  • zarr Official Documentation (docs)

[ ]:
import os

try:
    import astrohack

    print('AstroHACK version', astrohack.__version__, 'already installed.')
except ImportError as e:
    print(e)
    print('Installing AstroHACK')

    os.system("python -m pip install --upgrade astrohack")

    import astrohack
    print('astrohack version', astrohack.__version__, ' installed.')

Download Tutorial Data

[1]:
import astrohack
import graphviper

graphviper.utils.data.download('ea25_cal_small_after_fixed.split.ms', folder='data')

Holography Data File API

As part of the astroHACK API a set of functions to allow users to easily open on disk holography files has been provided. Each function takes an astroHACK holography file name as an argument and returns an object related to the given file type, ie. holog, image, panel, point. Each object allows the user to access data via dictionary keys with values consisting of the relevant holography dataset. Each object also provides a summary() helper function to list available keys for each file. An example call for each file type is show below and the API documentation for all data-io functions can be found here.

from astrohack.dio import open_holog
from astrohack.dio import open_image
from astrohack.dio import open_panel
from astrohack.dio import open_pointing

holog_data = open_holog(file='./data/ea25_cal_small_spw1_4_60_ea04_after.holog.zarr')
image_data = open_image(file='./data/ea25_cal_small_spw1_4_60_ea04_after.image.zarr')
panel_data = open_panel(file='./data/ea25_cal_small_spw1_4_60_ea04_after.panel.zarr')
pointing_data = open_pointing(file='./data/ea25_cal_small_spw1_4_60_ea04_after.point.zarr')

Setup Dask Local Cluster

The local Dask client handles scheduling and worker managment for the parallelization. The user has the option of choosing the number of cores and memory allocations for each worker howerver, we recommend a minimum of 8Gb per core with standard settings.

A significant amount of information related to the client and scheduling can be found using the Dask Dashboard. This is a built in dashboard native to Dask and allows the user to monitor the workers during processing. This is especially useful for profilling. For those that are interested in working soley within Jupyterlab a dashboard extension is availabe for Jupyterlab.

dashboard

[2]:
from graphviper.dask.client import local_client
client = local_client(cores=2, memory_limit='8GB')

[2024-02-14 12:52:40,103]     INFO  graphviper:  Checking parameter values for client.local_client
[2024-02-14 12:52:40,104]     INFO      logger:  /export/home/ajax/jhoskins/.conda/envs/viper-3.10/lib/python3.10//site-packages/
[2024-02-14 12:52:40,104]     INFO  graphviper:  Searching /export/home/ajax/jhoskins/.conda/envs/viper-3.10/lib/python3.10/site-packages/graphviper/config/ for configuration file, please wait ...
[2024-02-14 12:52:40,113]  WARNING  graphviper:  It is recommended that the local cache directory be set using the dask_local_dir parameter.
[2024-02-14 12:52:41,487]     INFO  graphviper:  Created client <MenrvaClient: 'tcp://127.0.0.1:33735' processes=2 threads=2, memory=14.90 GiB>

Extract Holog

The extraction and restructuring of the holography data is done using the extract_holog function. This function is similar in function to the UVHOL task in AIPS. The holography data that is extracted can be set using the compound dictionary holog_obs_description: mapping, scan, and antenna id. A detailed description of the structure of the holog_obs_description dictionary can be found in the documentation here. The extract_holog can automatically generate the holog_obs_description by inspecting the pointing table.

Inline information on the input parameters can also be gotten using help(extract_holog) in the cell.

[3]:
from astrohack.extract_pointing import extract_pointing
from astrohack.extract_holog import extract_holog

extract_pointing(
      ms_name='data/ea25_cal_small_after_fixed.split.ms',
      point_name='data/ea25_cal_small_after_fixed.split.point.zarr',
      parallel=True,
      overwrite=True
)

holog_mds = extract_holog(
    ms_name='data/ea25_cal_small_after_fixed.split.ms',
    point_name='data/ea25_cal_small_after_fixed.split.point.zarr',
    data_column='CORRECTED_DATA',
    parallel=True,
    overwrite=True
)


[2024-02-14 12:52:41,493]     INFO  graphviper:  Checking parameter values for extract_pointing.extract_pointing
[2024-02-14 12:52:41,493]     INFO   astrohack:  /export/home/ajax/jhoskins/Development/astrohack/
[2024-02-14 12:52:41,494]     INFO  graphviper:  Searching /export/home/ajax/jhoskins/.conda/envs/viper-3.10/lib/python3.10/site-packages/graphviper/config/ for configuration file, please wait ...
[2024-02-14 12:52:41,495]     INFO   astrohack:  Failed to find module in PARAMETER_CONFIG_PATH ... attempting to check common directories ...
[2024-02-14 12:52:41,495]     INFO  graphviper:  Searching /export/home/ajax/jhoskins/Development/astrohack/ for configuration file, please wait ...
Successful readonly open of usernoread-locked table data/ea25_cal_small_after_fixed.split.ms/ANTENNA: 8 columns, 3 rows
[2024-02-14 12:52:47,678]     INFO  graphviper:  Finished processing
[2024-02-14 12:52:47,712]     INFO  graphviper:  Checking parameter values for extract_holog.extract_holog
[2024-02-14 12:52:47,713]     INFO   astrohack:  /export/home/ajax/jhoskins/Development/astrohack/
[2024-02-14 12:52:47,713]     INFO  graphviper:  Searching /export/home/ajax/jhoskins/.conda/envs/viper-3.10/lib/python3.10/site-packages/graphviper/config/ for configuration file, please wait ...
[2024-02-14 12:52:47,714]     INFO   astrohack:  Failed to find module in PARAMETER_CONFIG_PATH ... attempting to check common directories ...
[2024-02-14 12:52:47,714]     INFO  graphviper:  Searching /export/home/ajax/jhoskins/Development/astrohack/ for configuration file, please wait ...
[2024-02-14 12:52:47,760]     INFO  graphviper:  Creating output file name: data/ea25_cal_small_after_fixed.split.holog.zarr
Successful readonly open of usernoread-locked table data/ea25_cal_small_after_fixed.split.ms/DATA_DESCRIPTION: 3 columns, 2 rows
Successful readonly open of usernoread-locked table data/ea25_cal_small_after_fixed.split.ms/ANTENNA: 8 columns, 3 rows
Successful readonly open of usernoread-locked table data/ea25_cal_small_after_fixed.split.ms: 23 columns, 36580 rows
Successful readonly open of usernoread-locked table data/ea25_cal_small_after_fixed.split.ms/STATE: 7 columns, 44 rows
Successful readonly open of usernoread-locked table data/ea25_cal_small_after_fixed.split.ms/SPECTRAL_WINDOW: 20 columns, 2 rows
Successful readonly open of usernoread-locked table data/ea25_cal_small_after_fixed.split.ms/POLARIZATION: 4 columns, 1 rows
Successful readonly open of usernoread-locked table data/ea25_cal_small_after_fixed.split.ms/OBSERVATION: 9 columns, 1 rows
Successful readonly open of usernoread-locked table data/ea25_cal_small_after_fixed.split.ms/HISTORY: 9 columns, 157 rows
[2024-02-14 12:52:47,804]     INFO  graphviper:  Processing ddi: 0, scans: [8 ... 57]
[2024-02-14 12:52:47,805]     INFO  graphviper:  Processing ddi: 1, scans: [8 ... 57]
Successful readonly open of default-locked table data/ea25_cal_small_after_fixed.split.ms/ANTENNA: 8 columns, 3 rows
Successful readonly open of default-locked table data/ea25_cal_small_after_fixed.split.ms/OBSERVATION: 9 columns, 1 rows
[2024-02-14 12:53:01,368]     INFO    worker_0:  Writing holog file to data/ea25_cal_small_after_fixed.split.holog.zarr
[2024-02-14 12:53:01,542]     INFO    worker_0:  Writing holog file to data/ea25_cal_small_after_fixed.split.holog.zarr
Successful readonly open of default-locked table data/ea25_cal_small_after_fixed.split.ms/ANTENNA: 8 columns, 3 rows
Successful readonly open of default-locked table data/ea25_cal_small_after_fixed.split.ms/OBSERVATION: 9 columns, 1 rows
[2024-02-14 12:53:01,648]     INFO    worker_1:  Writing holog file to data/ea25_cal_small_after_fixed.split.holog.zarr
[2024-02-14 12:53:01,663]     INFO    worker_0:  Finished extracting holography chunk for ddi: 1 holog_map_key: map_0
[2024-02-14 12:53:01,854]     INFO    worker_1:  Writing holog file to data/ea25_cal_small_after_fixed.split.holog.zarr
[2024-02-14 12:53:02,079]     INFO    worker_1:  Finished extracting holography chunk for ddi: 0 holog_map_key: map_0
[2024-02-14 12:53:02,094]     INFO  graphviper:  Finished processing
[2024-02-14 12:53:02,136]  WARNING  graphviper:  Cell size not consistent: [0.000719484970141879, 0.000719484970141879, 0.0006386556122807017, 0.0006386556122807017]
[2024-02-14 12:53:02,137]  WARNING  graphviper:  Calculating suggested cell size ...
[2024-02-14 12:53:02,138]  WARNING  graphviper:  [0.00071948 0.00071948 0.00063866 0.00063866]
[2024-02-14 12:53:02,141]     INFO  graphviper:  The suggested cell size is calculated to be: 0.0006790702912112905
[2024-02-14 12:53:02,144]  WARNING  graphviper:  Number of pixels not consistent: [729, 729, 961, 961]
[2024-02-14 12:53:02,147]  WARNING  graphviper:  Calculating suggested number of pixels ...
[2024-02-14 12:53:02,148]  WARNING  graphviper:  [729 729 961 961]
[2024-02-14 12:53:02,150]     INFO  graphviper:  The suggested number of pixels is calculated to be: 845 (grid: 29 x 29)

Two files are created by extract_holog: The extracted pointing information in the form of <point_name>.point.zarr and the extracted holography data as <point_name>.holog.zarr. In addition, a holography data object is returned. This is the same holography data object returned by the hologrphy data API above. The holog_mds object is a python dict containing the extracted holography data found in .holog.zarr but with extended functionality such as providing a summary of the run infomation in table form. Below for each DDI we can see the available scan and antenna information.

point_name.point.zarr: The pointing zarr file contains position and pointing information extracted from the pointing table of the input measurement set. In addition, the antenna and mapping scan information is listed for each antenna. The pointing object is structured as a simple dictionary with key:value sets with the key being the antenna id and the value being the pointing dataset.

point_mds =
{
   ant_0: point_ds,
            ⋮
   ant_n: point_ds
}

holog_name.holog.zarr: The holog zarr file contains ungridded data extracted from the pointing and main tables in the measurement set. The holog file includes the directional, visibility and weight information recorded on a shared time axis; the sampling is done because the native sample rates between the pointing and main tables are not the same. In addition, the meta data such as sampled parallactic data (beginning, middle and end of scan) and l(m) extent is recorded in the file attributes. The holog file structure is a compound dictionary keyed according to ddi -> map -> ant with values consisting of the holog dataset.

holog_mds =
{
   ddi_0:{
          map_0:{
                 ant_0: holog_ds,
                          ⋮
                 ant_n: holog_ds
                },
              ⋮
          map_p: …
         },
       ⋮
   ddi_m: …
}

An example of the holog dataset object is show below.

[4]:
holog_mds['ddi_0']['map_0']['ant_ea25']
[4]:
<xarray.Dataset>
Dimensions:                    (time: 8914, lm: 2, chan: 64, pol: 4)
Coordinates:
  * chan                       (chan) float64 1.41e+10 1.411e+10 ... 1.423e+10
  * pol                        (pol) <U2 'RR' 'RL' 'LR' 'LL'
  * time                       (time) float64 5.17e+09 5.17e+09 ... 5.17e+09
Dimensions without coordinates: lm
Data variables:
    DIRECTIONAL_COSINES        (time, lm) float64 dask.array<chunksize=(8914, 2), meta=np.ndarray>
    IDEAL_DIRECTIONAL_COSINES  (time, lm) float64 dask.array<chunksize=(8914, 2), meta=np.ndarray>
    VIS                        (time, chan, pol) complex64 dask.array<chunksize=(2229, 16, 2), meta=np.ndarray>
    WEIGHT                     (time, chan, pol) float64 dask.array<chunksize=(2229, 16, 2), meta=np.ndarray>
Attributes:
    antenna_name:             ea25
    ddi:                      0
    grid_params:              {'cell_size': 0.000719484970141879, 'n_pix': 729}
    holog_map_key:            map_0
    l_max:                    0.009675024871632517
    l_min:                    -0.009674930411087166
    m_max:                    0.009698666161358812
    m_min:                    -0.00975229251000802
    parallactic_samples:      [5.308157433326323, 5.357028871639436, 5.502977...
    telescope_name:           EVLA
    time_smoothing_interval:  1.0

In this case, there is only one selection in the holography file as seen in the summary. Using the available keys we can see an overview of the Dask dataset structure. In addition, the numpy arrays for the data are accessed by calling values on a given dataset variable. For instance accessing the data for the DIRECTIONAL_COSINES below would be simply

>> holog_mds['ddi_0']['map_0']['ant_ea25'].DIRECTIONAL_COSINES.values
>> array([[-0.00433549, -0.0027946 ],
       [-0.00870191, -0.00682571],
       [-0.00965634, -0.00908509],
       ...,
       [ 0.00966373,  0.00957556],
       [ 0.00966267,  0.00957601],
       [ 0.00965895,  0.00956941]])

>> holog_mds['ddi_0']['map_0']['ant_ea25'].DIRECTIONAL_COSINES.values.shape
>> (9145, 2)

where the dimension are given in the mds output for each data variable (in this case (time, lm)). A more in-depth overview of how to interact with Dask dataset can be found here.

A summary of the available key values can be obtained using the summary convenience function.

[5]:
holog_mds.summary()
####################################################################################################
###                                         Summary for:                                         ###
###                       data/ea25_cal_small_after_fixed.split.holog.zarr                       ###
####################################################################################################

Full documentation for AstrohackHologFile objects' API at:
https://astrohack.readthedocs.io/en/stable/_api/autoapi/astrohack/mds/index.html#astrohack.mds.AstrohackHologFile

Input Parameters:
+---------------------------+--------------------------------------------------+
| Parameter                 | Value                                            |
+---------------------------+--------------------------------------------------+
| ms_name                   | data/ea25_cal_small_after_fixed.split.ms         |
| point_name                | data/ea25_cal_small_after_fixed.split.point.zarr |
| holog_name                | data/ea25_cal_small_after_fixed.split.holog.zarr |
| holog_obs_dict            | None                                             |
| ddi                       | all                                              |
| baseline_average_distance | all                                              |
| baseline_average_nearest  | all                                              |
| data_column               | CORRECTED_DATA                                   |
| time_smoothing_interval   | None                                             |
| parallel                  | True                                             |
| overwrite                 | True                                             |
| version                   | 0.4.5                                            |
| origin                    | extract_holog                                    |
+---------------------------+--------------------------------------------------+

Contents:
+-------+-------+--------------------------+
| DDI   | Map   | Antenna                  |
+-------+-------+--------------------------+
| ddi_0 | map_0 | ['ant_ea25', 'ant_ea06'] |
| ddi_1 | map_0 | ['ant_ea25', 'ant_ea06'] |
+-------+-------+--------------------------+

Available methods:
+----------------------+-----------------------------------------------------------------------+
| Methods              | Description                                                           |
+----------------------+-----------------------------------------------------------------------+
| summary              | Prints summary of the AstrohackHologFile object, with available data, |
|                      | attributes and available methods                                      |
| select               | Select data on the basis of ddi, scan, ant. This is a convenience     |
|                      | function.                                                             |
| plot_diagnostics     | Plot diagnostic calibration plots from the holography data file.      |
| plot_lm_sky_coverage | Plot directional cosine coverage.                                     |
+----------------------+-----------------------------------------------------------------------+

Estimated Memory Requirements

A new functionality, currently being refined, is a function to estimate the amount of memory per core max that would be required to process a given file. The estimation is given as the suggested memory per core need to not spilling over into swap memory. If the user has already computed the holog_obs_dict, it can be added as a parameter to speed up the estitmate as this is a serial function currently.

In the resulting table the following definitions are important:

  • Available memory: The available memory on the system currently, ie. the total not currently in use.

  • Total memory: The total system memory

  • Suggested memory per core: Memory allocation per core estimated to not spill ove rinto swap memory.

    Reference: https://psutil.readthedocs.io/en/latest/#psutil.virtual_memory

[6]:
from astrohack.extract_holog import model_memory_usage
from astrohack.extract_holog import generate_holog_obs_dict

holog_obs_dict = generate_holog_obs_dict(
    ms_name="data/ea25_cal_small_after_fixed.split.ms",
    point_name="data/ea25_cal_small_after_fixed.split.point.zarr",
)

model_memory_usage(
    ms_name="data/ea25_cal_small_after_fixed.split.ms",
    holog_obs_dict=holog_obs_dict
)

Successful readonly open of usernoread-locked table data/ea25_cal_small_after_fixed.split.ms/ANTENNA: 8 columns, 3 rows
Successful readonly open of usernoread-locked table data/ea25_cal_small_after_fixed.split.ms: 23 columns, 36580 rows
[2024-02-14 12:53:02,344]     INFO  graphviper:  Writing distance matrix to /export/home/ajax/jhoskins/Development/astrohack/docs/.baseline_distance_matrix.csv ...
/export/home/ajax/jhoskins/.conda/envs/viper-3.10/lib/python3.10/site-packages/sklearn/base.py:376: InconsistentVersionWarning: Trying to unpickle estimator ElasticNet from version 1.3.2 when using version 1.4.0. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to:
https://scikit-learn.org/stable/model_persistence.html#security-maintainability-limitations
  warnings.warn(
                                      System Info                                       
┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ N-cores  Available memory (MB)  Total memory (MB)  Suggested memory per core (MB) ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│       4  3017                   15881                                       11911 │
└─────────┴───────────────────────┴───────────────────┴────────────────────────────────┘
    Available memory: represents the system memory available without going into swap    
[6]:
11911

Holog

The holog function processes the holography data and produces a holog image file on disk with the suffix, .image.zarr. This function is a direct replacement for the task HOLOG in AIPS. It is required that the user provide the grid_size and cell_size when processing holography data. The grid_size defines the number of l x m points used to when doing the gridding. The cell_size defines the value in arseconds of each grid spacing. More in-depth parameter information can be found in readthedocs here.

Inline information on the input paramters can also be gotten using help(holog) in the cell.

[7]:
import numpy as np

from astrohack import holog

cell_size = np.array([-0.0006442, 0.0006442]) # arcseconds
grid_size = np.array([31, 31])                # pixels

image_mds = holog(
    holog_name='data/ea25_cal_small_after_fixed.split.holog.zarr',
    overwrite=True,
    phase_fit=True,
    apply_mask=True,
    to_stokes=True,
    parallel=True
)
[2024-02-14 12:53:09,721]     INFO  graphviper:  Checking parameter values for holog.holog
[2024-02-14 12:53:09,722]     INFO   astrohack:  /export/home/ajax/jhoskins/Development/astrohack/
[2024-02-14 12:53:09,723]     INFO  graphviper:  Searching /export/home/ajax/jhoskins/.conda/envs/viper-3.10/lib/python3.10/site-packages/graphviper/config/ for configuration file, please wait ...
[2024-02-14 12:53:09,725]     INFO   astrohack:  Failed to find module in PARAMETER_CONFIG_PATH ... attempting to check common directories ...
[2024-02-14 12:53:09,726]     INFO  graphviper:  Searching /export/home/ajax/jhoskins/Development/astrohack/ for configuration file, please wait ...
[2024-02-14 12:53:09,772]     INFO  graphviper:  Creating output file name: data/ea25_cal_small_after_fixed.split.image.zarr
[2024-02-14 12:53:09,774]     INFO  graphviper:  Cell size: [-0.00067907  0.00067907], Grid size [29 29]
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_holog.py:68: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  n_chan = ant_data_dict[ddi][map0].dims["chan"]
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_holog.py:69: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  n_pol = ant_data_dict[ddi][map0].dims["pol"]
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_holog.py:68: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  n_chan = ant_data_dict[ddi][map0].dims["chan"]
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_holog.py:69: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  n_pol = ant_data_dict[ddi][map0].dims["pol"]
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_holog.py:119: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  time_centroid_index = ant_data_dict[ddi][holog_map].dims["time"] // 2
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_holog.py:119: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  time_centroid_index = ant_data_dict[ddi][holog_map].dims["time"] // 2
[2024-02-14 12:53:10,180]     INFO    worker_1:  Calculating aperture pattern ...
[2024-02-14 12:53:10,180]     INFO    worker_1:  Calculating aperture illumination pattern ...
[2024-02-14 12:53:10,181]     INFO    worker_0:  Calculating aperture pattern ...
[2024-02-14 12:53:10,181]     INFO    worker_0:  Calculating aperture illumination pattern ...
[2024-02-14 12:53:10,502]     INFO    worker_0:  Applying phase correction
[2024-02-14 12:53:10,554]     INFO    worker_1:  Applying phase correction
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_holog.py:68: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  n_chan = ant_data_dict[ddi][map0].dims["chan"]
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_holog.py:69: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  n_pol = ant_data_dict[ddi][map0].dims["pol"]
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_holog.py:68: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  n_chan = ant_data_dict[ddi][map0].dims["chan"]
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_holog.py:69: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  n_pol = ant_data_dict[ddi][map0].dims["pol"]
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_holog.py:119: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  time_centroid_index = ant_data_dict[ddi][holog_map].dims["time"] // 2
[2024-02-14 12:53:15,146]     INFO    worker_0:  Calculating aperture pattern ...
[2024-02-14 12:53:15,146]     INFO    worker_0:  Calculating aperture illumination pattern ...
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_holog.py:119: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  time_centroid_index = ant_data_dict[ddi][holog_map].dims["time"] // 2
[2024-02-14 12:53:15,411]     INFO    worker_1:  Calculating aperture pattern ...
[2024-02-14 12:53:15,411]     INFO    worker_1:  Calculating aperture illumination pattern ...
[2024-02-14 12:53:15,462]     INFO    worker_0:  Applying phase correction
[2024-02-14 12:53:15,609]     INFO    worker_1:  Applying phase correction
[2024-02-14 12:53:15,873]     INFO  graphviper:  Finished processing

image_name.image.zarr: The image zarr file contains gridded image data the beam, extracted aperture and the amplitude and phase components. It also contains all of the relevant coordinate information. The image file structure is a compound dictionary keys according to ant -> ddi with the dictionary values consisting of the image dataset.

image_mds =
{
   ant_0:{
          ddi_0: image_ds,
                 ⋮
          ddi_m: image_ds
         },
       ⋮
   ant_n: …
}

An example of the image dataset object is show below.

[8]:
image_mds['ant_ea25']['ddi_0']
[8]:
<xarray.Dataset>
Dimensions:          (time: 1, chan: 1, pol: 4, u_prime: 552, v_prime: 552,
                      u: 627, v: 627, l: 29, m: 29, ddi: 1)
Coordinates:
  * chan             (chan) float64 1.417e+10
  * ddi              (ddi) <U5 'ddi_0'
  * l                (l) float64 0.009507 0.008828 ... -0.008828 -0.009507
  * m                (m) float64 -0.009507 -0.008828 ... 0.008828 0.009507
  * pol              (pol) <U1 'I' 'Q' 'U' 'V'
  * u                (u) float64 735.1 732.8 730.4 ... -730.4 -732.8 -735.1
  * u_prime          (u_prime) float64 648.2 645.9 643.5 ... -643.5 -645.9
  * v                (v) float64 -735.1 -732.8 -730.4 ... 730.4 732.8 735.1
  * v_prime          (v_prime) float64 -648.2 -645.9 -643.5 ... 643.5 645.9
Dimensions without coordinates: time
Data variables:
    AMPLITUDE        (time, chan, pol, u_prime, v_prime) float64 dask.array<chunksize=(1, 1, 1, 276, 276), meta=np.ndarray>
    APERTURE         (time, chan, pol, u, v) complex128 dask.array<chunksize=(1, 1, 1, 157, 314), meta=np.ndarray>
    BEAM             (time, chan, pol, l, m) complex128 dask.array<chunksize=(1, 1, 4, 29, 29), meta=np.ndarray>
    CORRECTED_PHASE  (time, chan, pol, u_prime, v_prime) float64 dask.array<chunksize=(1, 1, 1, 276, 276), meta=np.ndarray>
Attributes:
    ant_id:               ant_ea25
    ant_name:             ea25
    aperture_resolution:  [1.413428251773375, 1.413428251773375]
    ddi:                  ddi_0
    telescope_name:       EVLA
    time_centroid:        5170359434.000001

A summary of the available key values can be obtained using the summary convenience function.

[9]:
image_mds.summary()
####################################################################################################
###                                         Summary for:                                         ###
###                       data/ea25_cal_small_after_fixed.split.image.zarr                       ###
####################################################################################################

Full documentation for AstrohackImageFile objects' API at:
https://astrohack.readthedocs.io/en/stable/_api/autoapi/astrohack/mds/index.html#astrohack.mds.AstrohackImageFile

Input Parameters:
+-------------------------+--------------------------------------------------+
| Parameter               | Value                                            |
+-------------------------+--------------------------------------------------+
| holog_name              | data/ea25_cal_small_after_fixed.split.holog.zarr |
| grid_size               | None                                             |
| cell_size               | None                                             |
| image_name              | data/ea25_cal_small_after_fixed.split.image.zarr |
| padding_factor          | 50                                               |
| grid_interpolation_mode | linear                                           |
| chan_average            | True                                             |
| chan_tolerance_factor   | 0.005                                            |
| scan_average            | True                                             |
| ant                     | all                                              |
| ddi                     | all                                              |
| to_stokes               | True                                             |
| apply_mask              | True                                             |
| phase_fit               | True                                             |
| overwrite               | True                                             |
| parallel                | True                                             |
| version                 | 0.4.5                                            |
| origin                  | holog                                            |
+-------------------------+--------------------------------------------------+

Contents:
+----------+--------------------+
| Antenna  | DDI                |
+----------+--------------------+
| ant_ea25 | ['ddi_0', 'ddi_1'] |
| ant_ea06 | ['ddi_0', 'ddi_1'] |
+----------+--------------------+

Available methods:
+----------------+------------------------------------------------------------------------------+
| Methods        | Description                                                                  |
+----------------+------------------------------------------------------------------------------+
| summary        | Prints summary of the AstrohackImageFile object, with available data,        |
|                | attributes and available methods                                             |
| select         | Select data on the basis of ddi, scan, ant. This is a convenience function.  |
| export_to_fits | Export contents of an AstrohackImageFile object to several FITS files in the |
|                | destination folder                                                           |
| plot_beams     | Beam plots from the data in an AstrohackImageFIle object.                    |
| plot_apertures | Aperture amplitude and phase plots from the data in an AstrohackImageFIle    |
|                | object.                                                                      |
+----------------+------------------------------------------------------------------------------+

Each of the holography output files is a compound dictionary with respect to the run parameters and contains a xarray Dataset, this means that the holography files have access to all native xarray functionality. The user can use their favorite plotting package to visualize the data or use xarray’s internal functions to do simple filtering and plotting.

[10]:
image_mds['ant_ea25']['ddi_0'].CORRECTED_PHASE.isel(chan=0, pol=0).plot()
[10]:
<matplotlib.collections.QuadMesh at 0x7f18f7d3e620>
_images/tutorial_vla_26_1.png

Panel

The panel function takes the place of and expands the PANEL AIPS function to processes the image information and derives adjustements to the dish panels. This produces a file on disk of format .panel.zarr containing information on corrections, residuals and screw adjustments. As an added bonus the panel function has a helper function to convert aips data to astrohack format and process it using the aips_holog_to_astrohack function. For a full description of the operation and arguments of the panel function see docs.

[11]:
from astrohack.panel import panel

panel_model = 'rigid'

panel_mds = panel(
    image_name='data/ea25_cal_small_after_fixed.split.image.zarr',
    panel_model=panel_model,
    panel_margins=0.2,
    clip_type='relative',
    clip_level=0.2,
    parallel=True,
    overwrite=True
)
[2024-02-14 12:53:36,343]     INFO  graphviper:  Checking parameter values for panel.panel
[2024-02-14 12:53:36,345]     INFO   astrohack:  /export/home/ajax/jhoskins/Development/astrohack/
[2024-02-14 12:53:36,346]     INFO  graphviper:  Searching /export/home/ajax/jhoskins/.conda/envs/viper-3.10/lib/python3.10/site-packages/graphviper/config/ for configuration file, please wait ...
[2024-02-14 12:53:36,347]     INFO   astrohack:  Failed to find module in PARAMETER_CONFIG_PATH ... attempting to check common directories ...
[2024-02-14 12:53:36,347]     INFO  graphviper:  Searching /export/home/ajax/jhoskins/Development/astrohack/ for configuration file, please wait ...
[2024-02-14 12:53:36,395]     INFO  graphviper:  Creating output file name: data/ea25_cal_small_after_fixed.split.panel.zarr
[2024-02-14 12:53:37,189]     INFO    worker_0:  processing ant_ea25 ddi_0
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_panel_classes/antenna_surface.py:77: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  if inputxds.dims['chan'] != 1:
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_panel_classes/antenna_surface.py:93: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  self.npoint = np.sqrt(inputxds.dims['l'] ** 2 + inputxds.dims['m'] ** 2)
[2024-02-14 12:53:37,529]     INFO    worker_1:  processing ant_ea25 ddi_1
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_panel_classes/antenna_surface.py:77: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  if inputxds.dims['chan'] != 1:
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_panel_classes/antenna_surface.py:93: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  self.npoint = np.sqrt(inputxds.dims['l'] ** 2 + inputxds.dims['m'] ** 2)
[2024-02-14 12:53:40,159]     INFO    worker_0:  processing ant_ea06 ddi_0
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_panel_classes/antenna_surface.py:77: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  if inputxds.dims['chan'] != 1:
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_panel_classes/antenna_surface.py:93: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  self.npoint = np.sqrt(inputxds.dims['l'] ** 2 + inputxds.dims['m'] ** 2)
[2024-02-14 12:53:41,502]     INFO    worker_1:  processing ant_ea06 ddi_1
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_panel_classes/antenna_surface.py:77: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  if inputxds.dims['chan'] != 1:
/export/home/ajax/jhoskins/Development/astrohack/src/astrohack/_utils/_panel_classes/antenna_surface.py:93: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
  self.npoint = np.sqrt(inputxds.dims['l'] ** 2 + inputxds.dims['m'] ** 2)
[2024-02-14 12:53:43,122]  WARNING    worker_1:  Fit failed with the rigid model and a simple mean has been used instead for the following panels: ['ea06', 'ddi_1']
[2024-02-14 12:53:43,122]  WARNING    worker_1:  ['6-10']
[2024-02-14 12:53:43,762]     INFO  graphviper:  Finished processing

panel_name.panel.zarr: The panel zarr file contains process information regarding the per panel screw corrections as well as residuals, masks and phase corrections used to produce them. The panel file structure is a compound dictionary keyed according to ant -> ddi with the value consisting of the panel dataset.

panel_mds =
{
   ant_0:{
          ddi_0: panel_ds,
                 ⋮
          ddi_m: panel_ds
         },
       ⋮
   ant_n: …

An example of the panel dataset object is show below.

[12]:
panel_mds['ant_ea25']['ddi_0']
[12]:
<xarray.Dataset>
Dimensions:             (u: 552, v: 552, labels: 172, pars: 3, screws: 4)
Coordinates:
  * labels              (labels) object '1-1' '1-2' '1-3' ... '6-39' '6-40'
  * pars                (pars) int64 0 1 2
  * screws              (screws) <U2 'il' 'ir' 'ol' 'or'
  * u                   (u) float64 13.72 13.67 13.62 ... -13.57 -13.62 -13.67
  * v                   (v) float64 -13.72 -13.67 -13.62 ... 13.57 13.62 13.67
Data variables:
    AMPLITUDE           (u, v) float64 dask.array<chunksize=(138, 276), meta=np.ndarray>
    CORRECTIONS         (u, v) float64 dask.array<chunksize=(138, 276), meta=np.ndarray>
    DEVIATION           (u, v) float64 dask.array<chunksize=(138, 276), meta=np.ndarray>
    MASK                (u, v) bool dask.array<chunksize=(276, 552), meta=np.ndarray>
    PANEL_DISTRIBUTION  (u, v) int32 dask.array<chunksize=(276, 276), meta=np.ndarray>
    PANEL_PARAMETERS    (labels, pars) float64 dask.array<chunksize=(172, 3), meta=np.ndarray>
    PANEL_SCREWS        (labels, screws) float64 dask.array<chunksize=(172, 4), meta=np.ndarray>
    PHASE               (u, v) float64 dask.array<chunksize=(138, 276), meta=np.ndarray>
    PHASE_CORRECTIONS   (u, v) float64 dask.array<chunksize=(138, 276), meta=np.ndarray>
    PHASE_RESIDUALS     (u, v) float64 dask.array<chunksize=(138, 276), meta=np.ndarray>
    RESIDUALS           (u, v) float64 dask.array<chunksize=(138, 276), meta=np.ndarray>
Attributes: (12/16)
    amp_unit:             V
    ant_name:             ea25
    aperture_resolution:  [1.413428251773375, 1.413428251773375]
    clip:                 0.7180989426650104
    ddi:                  ddi_0
    fitted:               True
    ...                   ...
    panel_margin:         0.2
    panel_model:          rigid
    solved:               True
    telescope_name:       VLA
    theoretical_gain:     100.1817827185667
    wavelength:           0.021161322651231735

A summary of the available key values can be obtained using the summary convenience function.

[13]:
panel_mds.summary()
####################################################################################################
###                                         Summary for:                                         ###
###                       data/ea25_cal_small_after_fixed.split.panel.zarr                       ###
####################################################################################################

Full documentation for AstrohackPanelFile objects' API at:
https://astrohack.readthedocs.io/en/stable/_api/autoapi/astrohack/mds/index.html#astrohack.mds.AstrohackPanelFile

Input Parameters:
+--------------------+--------------------------------------------------+
| Parameter          | Value                                            |
+--------------------+--------------------------------------------------+
| image_name         | data/ea25_cal_small_after_fixed.split.image.zarr |
| panel_name         | data/ea25_cal_small_after_fixed.split.panel.zarr |
| clip_type          | relative                                         |
| clip_level         | 0.2                                              |
| panel_model        | rigid                                            |
| panel_margins      | 0.2                                              |
| polarization_state | I                                                |
| ant                | all                                              |
| ddi                | all                                              |
| parallel           | True                                             |
| overwrite          | True                                             |
| version            | 0.4.5                                            |
| origin             | panel                                            |
+--------------------+--------------------------------------------------+

Contents:
+----------+--------------------+
| Antenna  | DDI                |
+----------+--------------------+
| ant_ea25 | ['ddi_0', 'ddi_1'] |
| ant_ea06 | ['ddi_0', 'ddi_1'] |
+----------+--------------------+

Available methods:
+----------------+-----------------------------------------------------------------------+
| Methods        | Description                                                           |
+----------------+-----------------------------------------------------------------------+
| summary        | Prints summary of the AstrohackPanelFile object, with available data, |
|                | attributes and available methods                                      |
| get_antenna    | Retrieve an AntennaSurface object for interaction                     |
| export_screws  | Export screw adjustments to text files and optionally plots.          |
| export_to_fits | Export contents of an Astrohack MDS file to several FITS files in the |
|                | destination folder                                                    |
| plot_antennas  | Create diagnostic plots of antenna surfaces from panel data file.     |
+----------------+-----------------------------------------------------------------------+

Additional Functions

The panel_mds object provides two helper functions for the user to export or investigate the results of the panel function. - export_screws(): This method exports the screw and panel adjustements from the panel output file. - plot_antennas(): This method plots one of three diagnostics plots from the panel output file data. The plots types are: deviation, phase and ancillary.

Examples usage for each helper functions are given below and more detailed documentation can be found in the visualization tutorial.

[14]:
export_folder = 'exports'

panel_mds.export_screws(
    destination=export_folder,
    ant='ea25',
    ddi=0,
    unit='mm',
    threshold=0.5, # Threshold in mm for significant adjustments
    display=True
)
[2024-02-14 12:53:43,938]     INFO  graphviper:  Checking parameter values for mds.AstrohackPanelFile.export_screws
[2024-02-14 12:53:43,940]     INFO   astrohack:  /export/home/ajax/jhoskins/Development/astrohack/
[2024-02-14 12:53:43,941]     INFO  graphviper:  Searching /export/home/ajax/jhoskins/.conda/envs/viper-3.10/lib/python3.10/site-packages/graphviper/config/ for configuration file, please wait ...
[2024-02-14 12:53:43,946]     INFO   astrohack:  Failed to find module in PARAMETER_CONFIG_PATH ... attempting to check common directories ...
[2024-02-14 12:53:43,948]     INFO  graphviper:  Searching /export/home/ajax/jhoskins/Development/astrohack/ for configuration file, please wait ...
[2024-02-14 12:53:44,035]  WARNING  graphviper:  Destination folder already exists, results may be overwritten
_images/tutorial_vla_34_1.png
[15]:
with open(export_folder+'/panel_screws_ant_ea25_ddi_0.txt', 'r') as file:
    for _ in range(30):
        print(file.readline()[:-1])
# Screw adjustments for VLA ea25 antenna
# Adjustments are in mm

# Lower means away from subreflector
# Raise means toward the subreflector
# LOWER the panel if the number is POSITIVE
# RAISE the panel if the number is NEGATIVE


Panel           il         ir         ol         or
1-1           -0.15       0.21       0.15       0.83
1-2           -0.25      -0.36       0.35       0.13
1-3            0.41       0.39       0.01      -0.03
1-4           -0.43      -0.75      -0.09      -0.68
1-5           -0.39      -0.24      -0.40      -0.13
1-6           -0.74      -0.67       0.01       0.13
1-7           -1.04      -1.05       0.18       0.16
1-8           -1.45      -1.20       0.15       0.62
1-9            0.37       0.12      -0.14      -0.61
1-10           0.32       0.71      -0.84      -0.11
1-11           0.95       1.16      -0.37       0.01
1-12           0.63       0.11       0.70      -0.27
2-1            0.57       0.74       0.24       0.49
2-2           -0.26      -0.35       0.03      -0.10
2-3            0.29       0.20      -0.43      -0.56
2-4           -0.08      -0.08      -0.18      -0.18
2-5           -0.49       0.10      -0.45       0.45
2-6            0.27      -0.31       0.89       0.01
2-7           -0.80      -0.50      -0.40       0.06
2-8            0.22       0.11      -0.24      -0.42
[16]:
panel_mds.plot_antennas(
    destination=export_folder,
    ant='ea25',
    ddi=0,
    plot_type='deviation',
    plot_screws=False,
    dpi=300,
    parallel=False,
    display=True
)
[2024-02-14 12:53:47,289]     INFO  graphviper:  Checking parameter values for mds.AstrohackPanelFile.plot_antennas
[2024-02-14 12:53:47,292]     INFO   astrohack:  /export/home/ajax/jhoskins/Development/astrohack/
[2024-02-14 12:53:47,293]     INFO  graphviper:  Searching /export/home/ajax/jhoskins/.conda/envs/viper-3.10/lib/python3.10/site-packages/graphviper/config/ for configuration file, please wait ...
[2024-02-14 12:53:47,294]     INFO   astrohack:  Failed to find module in PARAMETER_CONFIG_PATH ... attempting to check common directories ...
[2024-02-14 12:53:47,298]     INFO  graphviper:  Searching /export/home/ajax/jhoskins/Development/astrohack/ for configuration file, please wait ...
[2024-02-14 12:53:47,365]  WARNING  graphviper:  Destination folder already exists, results may be overwritten
_images/tutorial_vla_36_1.png
_images/tutorial_vla_36_2.png
_images/tutorial_vla_36_3.png