1212from . import conv
1313from . import cosmo as cm
1414from . import smoothing as sm
15- import scipy
1615from glob import glob
1716from time import time , sleep
1817import pickle
1918from joblib import cpu_count , Parallel , delayed
2019from tqdm import tqdm
2120
22-
2321def from_antenna_config_with_gains (antxyz , z , nu = None ,
2422 gain_model = {'name' : 'random_uniform' , 'min' : 0.5 , 'max' : 1.1 }):
2523 """
26- The function reads the antenna positions (N_ant antennas) from the file given.
24+ Calculates baselines and complex gain products for an antenna array.
25+
26+ This function takes antenna positions, generates complex gain values for each
27+ antenna based on a specified model, and then computes the baseline vectors
28+ (u,v,w). For each baseline, it also calculates the four products of the
29+ complex gains (g_i * g_j*) which are g_r*g_r, g_i*g_i, g_r*g_i, g_i*g_r.
2730
2831 Parameters
2932 ----------
30- antxyz: ndarray
31- The radio telescope antenna configuration.
32- z : float
33- Redhsift of the slice observed.
34- nu : float
35- The frequency observed by the telescope.
33+ antxyz: astropy.Quantity
34+ An object with antenna positions, expected to have a `.to('m').value` method.
35+ z : float
36+ Redshift of the slice observed.
37+ nu : float, optional
38+ The frequency observed by the telescope in MHz. If None, it's calculated from z.
39+ gain_model : dict or numpy.ndarray, optional
40+ Specifies how to generate antenna gains. Can be a dict defining a
41+ distribution ('random_gaussian' or 'random_uniform') or a pre-computed
42+ array of complex gains.
3643
3744 Returns
3845 -------
39- Nbase : ndarray
40- Numpy array (N_ant(N_ant-1)/2 x 3) containing the (ux,uy,uz) values derived
41- from the antenna positions .
42- N_ant : int
43- Number of antennas.
46+ Nbase : numpy. ndarray
47+ Array of shape `(n_baselines, 7)` containing `(u,v,w)` and the four
48+ gain product components for each baseline .
49+ N_ant : int
50+ The total number of antennas in the configuration .
4451 """
4552 z = float (z )
4653 if antxyz is None :
@@ -102,41 +109,48 @@ def get_uv_map_with_gains(ncells, z,
102109 subarray_type = "AA4" , total_int_time = 6. , int_time = 10. , boxsize = None , declination = - 30. ,
103110 include_mirror_baselines = False , verbose = True ):
104111 """
105- Create the gain and uv maps with individual gain values for each baseline stored per pixel.
112+ Creates a UV map where each grid cell accumulates complex gain information.
113+
114+ This function simulates a radio observation over time, accounting for
115+ evolving instrumental gains. It iterates through time steps, periodically
116+ re-calculating antenna gains, applying Earth rotation, and gridding the
117+ resulting baseline tracks. The output map stores the number of hits and the
118+ sum of four gain products for each UV cell.
106119
107120 Parameters
108121 ----------
109122 ncells : int
110123 Number of cells in each dimension of the grid.
111124 z : float
112- Redshift.
125+ Redshift of the observation .
113126 gain_model : dict or function
114- Gain model parameters or a custom function that returns random gain values .
115- gain_timescale : list
116- Timescale after which gain values will evolve .
117- subarray_type: str
118- The name of the SKA-Low layout configuration.
127+ Model for generating antenna gains. Passed to `from_antenna_config_with_gains` .
128+ gain_timescale : list of int
129+ Timescales (in seconds) at which gain values are re-calculated .
130+ subarray_type : str
131+ The name of the telescope layout configuration (e.g., "AA4") .
119132 total_int_time : float
120- Total observation time per day ( in hours) .
133+ Total observation time, in hours.
121134 int_time : float
122- Integration time ( in seconds) .
135+ Integration time per snapshot, in seconds.
123136 declination : float
124- Declination angle in degrees.
125- boxsize : float
126- Size of the observed sky area in Mpc.
137+ Declination of the pointing center, in degrees.
138+ boxsize : float, optional
139+ Comoving size of the observed sky area, in Mpc.
127140 include_mirror_baselines : bool
128- Whether to include mirror baselines .
141+ If True, grids both (u,v) and (-u,-v) tracks .
129142 verbose : bool
130- If True, enables verbose output .
143+ If True, enables progress bars and informational messages .
131144
132145 Returns
133146 -------
134- uv_map : ndarray
135- Array of lists, each containing gain values for the pixel.
147+ gain_uv_map : numpy.ndarray
148+ A 3D array of shape `(ncells, ncells, 5)`. For each UV cell (i,j),
149+ `gain_uv_map[i,j,0]` is the hit count, and the other 4 channels are
150+ the accumulated sums of the gain products.
136151 N_ant : int
137- Number of antennas.
152+ The total number of antennas.
138153 """
139-
140154 # Load the antenna configuration with gains only once
141155 if verbose :
142156 print ("Loading antenna configuration with gains..." )
@@ -161,38 +175,43 @@ def get_uv_map_with_gains(ncells, z,
161175 rotated_Nbase = earth_rotation_effect (Nbase [:,:3 ], time_idx , int_time , declination )
162176
163177 # Grid the rotated baselines with gain values
164- grid_uv_tracks_with_gains (rotated_Nbase , Nbase [:,3 :], gain_uv_map , z , ncells ,
178+ _grid_uv_tracks_with_gains (rotated_Nbase , Nbase [:,3 :], gain_uv_map , z , ncells ,
165179 boxsize = boxsize , include_mirror_baselines = include_mirror_baselines )
166180
167181 if verbose :
168182 print ("UV map generation complete." )
169183
170184 return gain_uv_map , N_ant
171185
172- def grid_uv_tracks_with_gains (Nbase , gain_vals , gain_uv_map , z , ncells , boxsize = None , include_mirror_baselines = False , verbose = True ):
186+ def _grid_uv_tracks_with_gains (Nbase , gain_vals , gain_uv_map , z , ncells , boxsize = None , include_mirror_baselines = False , verbose = True ):
173187 """
174- Grid uv tracks with gain values on a grid, storing individual gain values for each baseline at each pixel.
188+ Grids UV tracks and accumulates gain values for a single time snapshot.
189+
190+ This function projects rotated baseline coordinates onto a 2D grid. For each
191+ grid cell, it increments a hit counter and adds the four gain product
192+ components of any baseline that falls into that cell.
175193
176194 Parameters
177195 ----------
178- Nbase : ndarray
179- Array containing ux, uy, uz values of the antenna configuration .
180- gain_vals : ndarray
181- Array containing gain values for each baseline.
182- uv_map : ndarray
183- 2D array of lists, each containing gain values for the respective grid pixel .
196+ Nbase : numpy. ndarray
197+ Array `(n_baselines, 3)` of rotated (u, v, w) coordinates .
198+ gain_vals : numpy. ndarray
199+ Array `(n_baselines, 4)` of gain products for each baseline.
200+ gain_uv_map : numpy. ndarray
201+ The 3D output array `(ncells, ncells, 5)` to be modified in-place .
184202 z : float
185- Redshift of the slice observed .
203+ Redshift of the observation slice .
186204 ncells : int
187- Number of cells in the grid.
205+ Number of cells in one dimension of the target grid.
188206 boxsize : float, optional
189- Comoving size of the sky observed. Defaults to a predefined constant if None .
207+ Comoving size of the sky observed in Mpc .
190208 include_mirror_baselines : bool, optional
191- If True, includes mirror baselines.
209+ If True, also grids the hermitian conjugate baselines at (-u, -v) .
192210
193211 Returns
194212 -------
195- None : Modifies uv_map in-place to store gain values.
213+ None
214+ Modifies `gain_uv_map` in-place.
196215 """
197216 if boxsize is None :
198217 boxsize = conv .LB # Default boxsize (assumed defined globally or elsewhere)
@@ -229,21 +248,26 @@ def gain_uv_map_to_uv_map(gain_uv_map):
229248
230249def apply_uv_with_gains_response_on_image (array , gain_uv_map , verbose = True ):
231250 """
232- Apply the effect of radio observation strategy with varied antenna/baseline gains on an image.
233-
251+ Applies the instrumental response, including gains, to a sky image.
252+
253+ This function simulates the effect of observing a true sky image with an
254+ interferometer that has complex antenna gains. It operates in the Fourier
255+ domain by multiplying the Fourier transform of the sky by an effective
256+ complex gain derived from the simulated observation.
257+
234258 Parameters
235259 ----------
236- array : ndarray
237- The input image array .
238- gain_uv_map : ndarray of lists
239- The uv_map, where each entry is a list of gain values for that pixel .
260+ array : numpy. ndarray
261+ The 2D input sky image .
262+ gain_uv_map : numpy. ndarray
263+ The 3D UV map `(ncells, ncells, 5)` from `get_uv_map_with_gains` .
240264 verbose : bool, optional
241- If True, enables verbose progress output using tqdm .
242-
265+ (Currently unused) .
266+
243267 Returns
244268 -------
245- img_map : ndarray
246- The resulting radio image after applying the uv_map with gains in the Fourier domain .
269+ img_map : numpy. ndarray
270+ The resulting 2D "dirty" image after applying the instrumental response .
247271 """
248272 assert array .shape == gain_uv_map [:,:,0 ].shape , "Array and uv_map must have the same shape"
249273
@@ -261,24 +285,26 @@ def apply_uv_with_gains_response_on_image(array, gain_uv_map, verbose=True):
261285
262286def from_antenna_config_with_antenna_stamp (antxyz , z , nu = None ):
263287 """
264- The function reads the antenna positions (N_ant antennas) from the file given.
288+ Calculates baselines and attaches unique integer tags for each antenna.
289+
290+ This function converts antenna positions into baseline vectors (u,v,w) and,
291+ for each baseline, stores the integer tags of the two antennas that form it.
265292
266293 Parameters
267294 ----------
268- subarray_type: str
269- The name of the SKA-Low layout configuration .
270- z : float
271- Redhsift of the slice observed.
272- nu : float
273- The frequency observed by the telescope.
295+ antxyz: astropy.Quantity
296+ An object with antenna positions, expected to have a `.to('m').value` method .
297+ z : float
298+ Redshift of the slice observed.
299+ nu : float, optional
300+ The frequency observed by the telescope in MHz. If None, it's calculated from z .
274301
275302 Returns
276303 -------
277- Nbase : ndarray
278- Numpy array (N_ant(N_ant-1)/2 x 3) containing the (ux,uy,uz) values derived
279- from the antenna positions.
280- N_ant : int
281- Number of antennas.
304+ Nbase : numpy.ndarray
305+ Array `(n_baselines, 5)` containing `(u,v,w, ant_tag1, ant_tag2)`.
306+ N_ant : int
307+ The total number of antennas.
282308 """
283309 z = float (z )
284310 if antxyz is None :
@@ -320,7 +346,7 @@ def get_full_uv_map_with_antenna_stamp(ncells, z, subarray_type="AA4", total_int
320346 z : float
321347 Redshift.
322348 subarray_type: str
323- The name of the SKA-Low layout configuration.
349+ The name of the SKA-Low layout configuration.
324350 total_int_time : float
325351 Total observation time per day (in hours).
326352 int_time : float
@@ -365,7 +391,7 @@ def get_full_uv_map_with_antenna_stamp(ncells, z, subarray_type="AA4", total_int
365391
366392 # Parallel processing with progress bar for the first chunk
367393 results = Parallel (n_jobs = n_jobs )(
368- delayed (process_chunk_get_full_uv_map_with_antenna_stamp )(
394+ delayed (_process_chunk_get_full_uv_map_with_antenna_stamp )(
369395 chunk_start , chunk_end , ncells , z , Nbase , int_time , declination , boxsize , include_mirror_baselines , verbose , show_progress = (i == 0 ))
370396 for i , (chunk_start , chunk_end ) in enumerate (chunks )
371397 )
@@ -378,7 +404,7 @@ def get_full_uv_map_with_antenna_stamp(ncells, z, subarray_type="AA4", total_int
378404
379405 return ant_tag_uv_map , N_ant
380406
381- def process_chunk_get_full_uv_map_with_antenna_stamp (chunk_start , chunk_end , ncells , z , Nbase , int_time , declination , boxsize , include_mirror_baselines , verbose , show_progress ):
407+ def _process_chunk_get_full_uv_map_with_antenna_stamp (chunk_start , chunk_end , ncells , z , Nbase , int_time , declination , boxsize , include_mirror_baselines , verbose , show_progress ):
382408 """
383409 Process a chunk of time slices.
384410
@@ -424,36 +450,50 @@ def process_chunk_get_full_uv_map_with_antenna_stamp(chunk_start, chunk_end, nce
424450
425451 for time_idx in time_indices :
426452 rotated_Nbase = earth_rotation_effect (Nbase [:, :3 ], time_idx , int_time , declination )
427- grid_uv_tracks_with_antenna_stamp (rotated_Nbase , Nbase [:, 3 :], ant_tag_uv_map_chunk , z , ncells , time_idx - chunk_start ,
453+ _grid_uv_tracks_with_antenna_stamp (rotated_Nbase , Nbase [:, 3 :], ant_tag_uv_map_chunk , z , ncells , time_idx - chunk_start ,
428454 boxsize = boxsize , include_mirror_baselines = include_mirror_baselines )
429455
430456 return ant_tag_uv_map_chunk
431457
432- def grid_uv_tracks_with_antenna_stamp (Nbase , ant_tag , ant_tag_uv_map , z , ncells , time_idx ,
458+ def _grid_uv_tracks_with_antenna_stamp (Nbase , ant_tag , ant_tag_uv_map , z , ncells , time_idx ,
433459 boxsize = None , include_mirror_baselines = False , verbose = True ):
434460 """
435- Grid uv tracks with gain values on a grid, storing individual gain values for each baseline at each pixel.
461+ Grids UV tracks with antenna tags onto a 2D grid for a single time snapshot.
462+
463+ This function takes the rotated baseline coordinates for a single moment,
464+ projects them onto a 2D grid, and for each grid cell (pixel), it appends
465+ the antenna pair tags of all baselines that fall into that cell.
436466
437467 Parameters
438468 ----------
439- Nbase : ndarray
440- Array containing ux, uy, uz values of the antenna configuration.
441- gain_vals : ndarray
442- Array containing gain values for each baseline.
443- uv_map : ndarray
444- 2D array of lists, each containing gain values for the respective grid pixel.
469+ Nbase : numpy.ndarray
470+ Array of shape `(n_baselines, 3)` containing the rotated (u, v, w)
471+ baseline coordinates for a single time step.
472+ ant_tag : numpy.ndarray
473+ Array of shape `(n_baselines, 2)` containing the integer tags for
474+ each antenna pair.
475+ ant_tag_uv_map : numpy.ndarray
476+ The 3D output array of shape `(n_timesteps, ncells, ncells)` where each
477+ element is a list. This function appends `[ant1, ant2]` pairs to these
478+ lists. It is modified in-place.
445479 z : float
446- Redshift of the slice observed .
480+ Redshift of the observation slice .
447481 ncells : int
448- Number of cells in the grid.
482+ Number of cells in one dimension of the target grid.
483+ time_idx : int
484+ The time index within the `ant_tag_uv_map` to populate.
449485 boxsize : float, optional
450- Comoving size of the sky observed. Defaults to a predefined constant if None.
486+ Comoving size of the sky observed in Mpc. Defaults to a predefined
487+ constant if None.
451488 include_mirror_baselines : bool, optional
452- If True, includes mirror baselines.
489+ If True, includes mirror baselines. (Note: Not yet implemented).
490+ verbose : bool, optional
491+ Enables verbose output. (Note: Currently unused in this function).
453492
454493 Returns
455494 -------
456- None : Modifies uv_map in-place to store gain values.
495+ None
496+ Modifies `ant_tag_uv_map` in-place.
457497 """
458498 if boxsize is None :
459499 boxsize = conv .LB # Default boxsize (assumed defined globally or elsewhere)
@@ -550,7 +590,7 @@ def get_full_uv_lagrangian_with_antenna_stamp(ncells, z, subarray_type="AA4", to
550590
551591 # Parallel processing with progress bar for the first chunk
552592 results = Parallel (n_jobs = n_jobs )(
553- delayed (process_chunk_get_full_uv_lagrangian_with_antenna_stamp )(
593+ delayed (_process_chunk_get_full_uv_lagrangian_with_antenna_stamp )(
554594 chunk_start , chunk_end , ncells , z , Nbase , int_time , declination , boxsize , include_mirror_baselines , verbose , show_progress = (i == 0 ))
555595 for i , (chunk_start , chunk_end ) in enumerate (chunks )
556596 )
@@ -564,7 +604,7 @@ def get_full_uv_lagrangian_with_antenna_stamp(ncells, z, subarray_type="AA4", to
564604 ant_pairs = Nbase [:,- 2 :]
565605 return ant_tag_uv_lagr , ant_pairs
566606
567- def process_chunk_get_full_uv_lagrangian_with_antenna_stamp (chunk_start , chunk_end , ncells , z , Nbase , int_time , declination , boxsize , include_mirror_baselines , verbose , show_progress ):
607+ def _process_chunk_get_full_uv_lagrangian_with_antenna_stamp (chunk_start , chunk_end , ncells , z , Nbase , int_time , declination , boxsize , include_mirror_baselines , verbose , show_progress ):
568608 """
569609 Processes a chunk of observation time slices for parallel computation.
570610
@@ -611,12 +651,12 @@ def process_chunk_get_full_uv_lagrangian_with_antenna_stamp(chunk_start, chunk_e
611651
612652 for time_idx in time_indices :
613653 rotated_Nbase = earth_rotation_effect (Nbase [:, :3 ], time_idx , int_time , declination )
614- grid_uv_lagrangian_tracks_with_antenna_stamp (rotated_Nbase , Nbase [:, 3 :], ant_tag_uv_map_chunk , z , ncells , time_idx - chunk_start ,
654+ _grid_uv_lagrangian_tracks_with_antenna_stamp (rotated_Nbase , Nbase [:, 3 :], ant_tag_uv_map_chunk , z , ncells , time_idx - chunk_start ,
615655 boxsize = boxsize , include_mirror_baselines = include_mirror_baselines )
616656
617657 return ant_tag_uv_map_chunk
618658
619- def grid_uv_lagrangian_tracks_with_antenna_stamp (Nbase , ant_tag , ant_tag_uv_map , z , ncells , time_idx ,
659+ def _grid_uv_lagrangian_tracks_with_antenna_stamp (Nbase , ant_tag , ant_tag_uv_map , z , ncells , time_idx ,
620660 boxsize = None , include_mirror_baselines = False , verbose = True ):
621661 """
622662 Grids UV tracks for a single time snapshot onto an integer grid.
0 commit comments