1717
1818from arl .data .data_models import GainTable , BlockVisibility , Skycomponent
1919from arl .visibility .iterators import vis_timeslice_iter
20+ from arl .visibility .operations import create_visibility_from_rows
2021from arl .calibration .operations import create_gaintable_from_blockvisibility
2122
2223log = logging .getLogger (__name__ )
@@ -45,52 +46,73 @@ def solve_gaintable(vis: BlockVisibility, modelvis: BlockVisibility, phase_only=
4546 gt = create_gaintable_from_blockvisibility (vis )
4647
4748 for chunk , rows in enumerate (vis_timeslice_iter (vis )):
48-
49- x , xwt = remove_model (vis .vis [rows ], vis .weight [rows ], modelvis .vis [rows ],
50- isscalar = vis .polarisation_frame .npol == 1 , crosspol = crosspol )
51-
52- # Now average over time, chan. The axes of x are time, antenna2, antenna1, chan, pol
53-
54- xave = numpy .average (x , axis = 0 )
55- xwtAve = numpy .average (xwt , axis = 0 )
56-
57- mask = xwtAve <= 0.0
58- xave [mask ] = 0.0
59-
60- gainshape = gt .data ['gain' ][chunk , ...].shape
61- if vis .polarisation_frame .npol > 1 :
62- if crosspol :
63- gt .data ['gain' ][chunk , ...], gt .data ['weight' ][chunk , ...], gt .data ['residual' ][chunk , ...] = \
64- solve_antenna_gains_itsubs_matrix (gainshape , xave , xwtAve , phase_only = phase_only , niter = niter ,
65- tol = tol )
66- else :
67- gt .data ['gain' ][chunk , ...], gt .data ['weight' ][chunk , ...], gt .data ['residual' ][chunk , ...] = \
68- solve_antenna_gains_itsubs_vector (gainshape , xave , xwtAve , phase_only = phase_only , niter = niter ,
69- tol = tol )
70-
71- else :
72- gt .data ['gain' ][chunk , ...], gt .data ['weight' ][chunk , ...], gt .data ['residual' ][chunk , ...] = \
73- solve_antenna_gains_itsubs_scalar (gainshape , xave , xwtAve , phase_only = phase_only , niter = niter ,
74- tol = tol )
49+ subvis = create_visibility_from_rows (vis , rows )
50+ model_subvis = create_visibility_from_rows (vis , rows )
51+ xAve , xwtAve = visibility_divide_and_average (subvis , model_subvis , isscalar = vis .polarisation_frame .npol == 1 ,
52+ crosspol = crosspol )
53+
54+ gt = solve_from_X (gt , xAve , xwtAve , chunk , crosspol , niter , phase_only , tol , npol = vis .polarisation_frame .npol )
7555
7656 assert type (gt ) is GainTable , "gt is not a GainTable: %r" % gt
7757
7858 return gt
7959
8060
81- def remove_model (vis , weight , modelvis , isscalar , crosspol ):
61+ def solve_from_X (gt : GainTable , x : numpy .ndarray , xwt :numpy .ndarray , chunk , crosspol , niter , phase_only , tol , npol )\
62+ -> GainTable :
63+ """ Solve for gains from the point source equivavlents
64+
65+ :param gt:
66+ :param x:
67+ :param xwt:
68+ :param chunk:
69+ :param crosspol:
70+ :param niter:
71+ :param phase_only:
72+ :param tol:
73+ :param npol:
74+ :return:
75+ """
76+ gainshape = gt .data ['gain' ][chunk , ...].shape
77+ if npol > 1 :
78+ if crosspol :
79+ gt .data ['gain' ][chunk , ...], gt .data ['weight' ][chunk , ...], gt .data ['residual' ][chunk , ...] = \
80+ solve_antenna_gains_itsubs_matrix (gainshape , x , xwt , phase_only = phase_only , niter = niter ,
81+ tol = tol )
82+ else :
83+ gt .data ['gain' ][chunk , ...], gt .data ['weight' ][chunk , ...], gt .data ['residual' ][chunk , ...] = \
84+ solve_antenna_gains_itsubs_vector (gainshape , x , xwt , phase_only = phase_only , niter = niter ,
85+ tol = tol )
86+
87+ else :
88+ gt .data ['gain' ][chunk , ...], gt .data ['weight' ][chunk , ...], gt .data ['residual' ][chunk , ...] = \
89+ solve_antenna_gains_itsubs_scalar (gainshape , x , xwt , phase_only = phase_only , niter = niter ,
90+ tol = tol )
91+ return gt
92+
93+ def visibility_divide_and_average (vis : BlockVisibility , modelvis : BlockVisibility , isscalar , crosspol ):
94+ """ Divide visibility by model and average
95+
96+ :param vis:
97+ :param modelvis:
98+ :param isscalar:
99+ :param crosspol:
100+ :return:
101+ """
82102 # Form the point source equivalent visibility
83103
84104 # Different for scalar and vector/matrix cases
85105
106+ weight = vis .weight
107+
86108 if isscalar :
87109 # Scalar case is straightforward
88- x = numpy .zeros_like (vis )
89- xwt = numpy .abs (modelvis ) ** 2 * weight
110+ x = numpy .zeros_like (vis . vis )
111+ xwt = numpy .abs (modelvis . vis ) ** 2 * weight
90112 mask = xwt > 0.0
91- x [mask ] = vis [mask ] / modelvis [mask ]
113+ x [mask ] = vis . vis [mask ] / modelvis . vis [mask ]
92114 else :
93- nrows , nants , _ , nchan , npol = vis .shape
115+ nrows , nants , _ , nchan , npol = vis .vis . shape
94116 nrec = 2
95117 assert nrec * nrec == npol
96118 xshape = (nrows , nants , nants , nchan , nrec , nrec )
@@ -100,13 +122,18 @@ def remove_model(vis, weight, modelvis, isscalar, crosspol):
100122 for ant1 in range (nants ):
101123 for ant2 in range (ant1 + 1 , nants ):
102124 for chan in range (nchan ):
103- ovis = numpy .matrix (vis [row , ant2 , ant1 , chan ].reshape ([2 ,2 ]))
104- mvis = numpy .matrix (modelvis [row , ant2 , ant1 , chan ].reshape ([2 ,2 ]))
125+ ovis = numpy .matrix (vis . vis [row , ant2 , ant1 , chan ].reshape ([2 ,2 ]))
126+ mvis = numpy .matrix (modelvis . vis [row , ant2 , ant1 , chan ].reshape ([2 ,2 ]))
105127 wt = numpy .matrix (weight [row , ant2 , ant1 , chan ].reshape ([2 ,2 ]))
106128 x [row , ant2 , ant1 , chan ] = numpy .matmul (numpy .linalg .inv (mvis ), ovis )
107129 xwt [row , ant2 , ant1 , chan ] = numpy .dot (mvis , numpy .multiply (wt , mvis .H )).real
108-
109- return x , xwt
130+
131+ xAve = numpy .average (x , axis = 0 )
132+ xwtAve = numpy .average (xwt , axis = 0 )
133+ mask = xwtAve <= 0.0
134+ xAve [mask ] = 0.0
135+
136+ return xAve , xwtAve
110137
111138
112139def solve_antenna_gains_itsubs_scalar (gainshape , x , xwt , niter = 30 , tol = 1e-8 , phase_only = True , refant = 0 ):
0 commit comments