2222
2323from processing_library .util .array_functions import average_chunks2
2424from processing_library .util .coordinate_support import xyz_to_uvw , skycoord_to_lmn
25+ from processing_components .visibility .base import simulate_point
2526
2627def simulate_DTV (frequency , times , power = 50e3 , timevariable = False , frequency_variable = False ):
2728 """ Calculate DTV sqrt(power) as a function of time and frequency
@@ -58,23 +59,6 @@ def simulate_DTV(frequency, times, power=50e3, timevariable=False, frequency_var
5859 return signal
5960
6061
61- def add_noise (visibility , bandwidth , int_time ):
62- """Determine noise rms per visibility
63-
64- :returns: visibility with noise added
65- """
66- # The specified sensitivity (effective area / T_sys) is roughly 610 m ^ 2 / K in the range 160 - 200MHz
67- # sigma_vis = 2 k T_sys / (area * sqrt(tb)) = 2 k 512 / (610 * sqrt(tb)
68- sens = 610
69- k_b = 1.38064852e-23
70- bt = bandwidth * int_time
71- sigma = 2 * 1e26 * k_b / ((sens / 512 ) * (numpy .sqrt (bt )))
72- print ("RMS noise per sample = %g Jy" % sigma )
73- sshape = visibility .shape
74- visibility += numpy .random .normal (0.0 , sigma , sshape ) + 1j * numpy .random .normal (0.0 , sigma , sshape )
75- return visibility
76-
77-
7862def create_propagators (config , interferer , frequency , attenuation = 1e-9 ):
7963 """ Create a set of propagators
8064
@@ -96,62 +80,29 @@ def create_propagators(config, interferer, frequency, attenuation=1e-9):
9680def calculate_rfi_at_station (propagators , emitter ):
9781 """ Calculate the rfi at each station
9882
99- :param propagators:
100- :param emitter:
101- :return: Complex array [nants , ntimes, nchannels]
83+ :param propagators: [nstations, nchannels]
84+ :param emitter: [ntimes, nchannels]
85+ :return: Complex array [nstations , ntimes, nchannels]
10286 """
103- rfi_at_station = emitter [numpy .newaxis , :, : ] * propagators [:, numpy .newaxis , : ]
87+ rfi_at_station = emitter [:, numpy .newaxis , ... ] * propagators [numpy .newaxis , ... ]
10488 rfi_at_station [numpy .abs (rfi_at_station )< 1e-15 ] = 0.
10589 return rfi_at_station
10690
107-
108- def calculate_station_fringe_rotation (ants_xyz , times , frequency , phasecentre , pole ):
109- """Calculate fringe rotation vectors
110-
111- :param ants_xyz:
112- :param times:
113- :param frequency:
114- :param phasecentre:
115- :param pole:
116- :return: phasor, uvw
117- """
118-
119- uvw = xyz_to_uvw (ants_xyz , times , phasecentre .dec .rad )
120- nants , _ = uvw .shape
121- ntimes = len (times )
122- uvw = uvw .reshape ([nants , 3 , ntimes ])
123- uvw = numpy .transpose (uvw , [0 , 2 , 1 ])
124-
125- l , m , n = skycoord_to_lmn (phasecentre , pole )
126- s = numpy .array ([l , m , numpy .sqrt (1 - l ** 2 - m ** 2 ) - 1.0 ])
127- delay = numpy .dot (uvw , s )
128- nchan = len (frequency )
129- phase = numpy .zeros ([nants , ntimes , nchan ])
130- for ant in range (nants ):
131- for chan in range (nchan ):
132- phase [ant , :, chan ] = delay [ant ] * frequency [chan ] / constants .c .value
133- phase [...] -= phase [0 , :, :][numpy .newaxis ,...]
134- return numpy .exp (- 2.0 * numpy .pi * 1j * phase ), uvw
135-
136-
137- def calculate_station_correlation_rfi (fringe_rotation , rfi_at_station ):
138- """ Form the correlation from the rfi at the station and the fringe rotation
91+ def calculate_station_correlation_rfi (rfi_at_station ):
92+ """ Form the correlation from the rfi at the station
13993
140- :param fringe_rotation:
14194 :param rfi_at_station:
14295 :return: Correlation(nant, nants, ntimes, nchan] in Jy
14396 """
144- phased_rotated_rfi_at_station = fringe_rotation * rfi_at_station
145- nants , ntimes , nchan = fringe_rotation .shape
146- correlation = numpy .zeros ([nants , nants , ntimes , nchan ], dtype = 'complex' )
97+ ntimes , nants , nchan = rfi_at_station .shape
98+ correlation = numpy .zeros ([ntimes , nants , nants , nchan ], dtype = 'complex' )
14799
148- # We only phaserotate one station in an interferometer
149- for time in range (ntimes ):
100+ for itime in range (ntimes ):
150101 for chan in range (nchan ):
151- correlation [..., time , chan ] = numpy .outer (rfi_at_station [..., time , chan ],
152- numpy .conjugate (phased_rotated_rfi_at_station [..., time , chan ]))
102+ correlation [itime , ..., chan ] = numpy .outer (rfi_at_station [itime , : , chan ],
103+ numpy .conjugate (rfi_at_station [ itime , : , chan ]))
153104
154- return correlation * 1e26
105+ return correlation [..., numpy . newaxis ] * 1e26
155106
156107
157108def calculate_averaged_correlation (correlation , channel_width , time_width ):
@@ -166,8 +117,7 @@ def calculate_averaged_correlation(correlation, channel_width, time_width):
166117 return average_chunks2 (correlation , wts , (channel_width , time_width ))[0 ]
167118
168119
169- def simulate_rfi_block (config , times , frequency , phasecentre , emitter_location , emitter_power = 5e4 ,
170- attenuation = 1.0 ):
120+ def simulate_rfi_block (bvis , emitter_location , emitter_power = 5e4 , attenuation = 1.0 ):
171121 """ Simulate RFI block
172122
173123 :param config: ARL telescope Configuration
@@ -179,26 +129,35 @@ def simulate_rfi_block(config, times, frequency, phasecentre, emitter_location,
179129 :param attenuation: Attenuation to be applied to signal
180130 :return:
181131 """
132+
182133 # Calculate the power spectral density of the DTV station: Watts/Hz
183- emitter = simulate_DTV (frequency , times , power = emitter_power , timevariable = False )
134+ emitter = simulate_DTV (bvis . frequency , bvis . time , power = emitter_power , timevariable = False )
184135
185136 # Calculate the propagators for signals from Perth to the stations in low
186137 # These are fixed in time but vary with frequency. The ad hoc attenuation
187138 # is set to produce signal roughly equal to noise at LOW
188- propagators = create_propagators (config , emitter_location , frequency = frequency ,
139+ propagators = create_propagators (bvis . configuration , emitter_location , frequency = bvis . frequency ,
189140 attenuation = attenuation )
190141 # Now calculate the RFI at the stations, based on the emitter and the propagators
191142 rfi_at_station = calculate_rfi_at_station (propagators , emitter )
192-
193- # Station fringe rotation: shape [nants, ntimes, nchan] complex phasor to be applied to
194- # reference to the pole.
143+
144+ # Calculate the rfi correlation using the fringe rotation and the rfi at the station
145+ # [ntimes, nants, nants, nchan, npol]
146+ bvis .data ['vis' ][...] = calculate_station_correlation_rfi (rfi_at_station )
147+
148+ ntimes , nant , _ , nchan , npol = bvis .vis .shape
149+
195150 pole = SkyCoord (ra = + 0.0 * u .deg , dec = - 90.0 * u .deg , frame = 'icrs' , equinox = 'J2000' )
196- ha = times * numpy .pi / 43200.0
197151
198- fringe_rotation , uvw = calculate_station_fringe_rotation (config .xyz , ha , frequency , phasecentre , pole )
199-
200- # Calculate the rfi correlationm using the fringe rotation and the rfi at the station
201- # [nants, nants, ntimes, nchan]
202- correlation = calculate_station_correlation_rfi (fringe_rotation , rfi_at_station )
203-
204- return correlation , uvw
152+ # Calculate phasor needed to shift from the phasecentre to the pole
153+ l , m , n = skycoord_to_lmn (pole , bvis .phasecentre )
154+ k = numpy .array (bvis .frequency ) / constants .c .to ('m s^-1' ).value
155+ uvw = bvis .uvw [..., numpy .newaxis ] * k
156+ phasor = numpy .ones ([ntimes , nant , nant , nchan , npol ], dtype = 'complex' )
157+ for chan in range (nchan ):
158+ phasor [:, :, :, chan , :] = simulate_point (uvw [..., chan ], l , m )[..., numpy .newaxis ]
159+
160+ # Now fill this into the BlockVisibility
161+ bvis .data ['vis' ] = bvis .data ['vis' ] * phasor
162+
163+ return bvis
0 commit comments