1use std::ops::Range;
54
55use thiserror::Error;
56
57use crate::{ndarray::Array3, num_traits::Zero, Jones};
58
59#[cfg(feature = "mwalib")]
60use mwalib::{CorrelatorContext, MetafitsContext};
61
62#[derive(Error, Debug)]
63pub enum SelectionError {
64 #[error("No common timesteps found. CorrelatorContext hdu info: {hdu_info}")]
65 NoCommonTimesteps {
67 hdu_info: String,
69 },
70
71 #[error("No timesteps were provided. CorrelatorContext hdu info: {hdu_info}")]
72 NoProvidedTimesteps {
74 hdu_info: String,
76 },
77
78 #[error("Insufficient memory available; need {need_gib} GiB of memory.\nPlease specify the maximum amount of memory to use.")]
79 InsufficientMemory {
81 need_gib: usize,
83 },
84
85 #[error("bad array shape supplied to argument {argument} of function {function}. expected {expected}, received {received}")]
86 BadArrayShape {
88 argument: String,
90 function: String,
92 expected: String,
94 received: String,
96 },
97
98 #[error("bad baseline index supplied to function {function}. expected {expected}, received {received}")]
99 BadBaselineIdx {
100 function: String,
102 expected: String,
104 received: String,
106 },
107
108 #[cfg(feature = "mwalib")]
109 #[error(transparent)]
110 Mwalib(#[from] mwalib::GpuboxError),
111}
112
113#[derive(Debug, Default, Clone)]
120pub struct VisSelection {
121 pub timestep_range: Range<usize>,
123 pub coarse_chan_range: Range<usize>,
125 pub baseline_idxs: Vec<usize>,
127}
128
129impl VisSelection {
130 #[cfg(feature = "mwalib")]
166 pub fn from_mwalib(corr_ctx: &CorrelatorContext) -> Result<Self, SelectionError> {
167 Ok(Self {
168 timestep_range: match (
169 corr_ctx.common_timestep_indices.first(),
170 corr_ctx.provided_timestep_indices.last(),
171 ) {
172 (Some(&first), Some(&last)) if first <= last => first..last + 1,
173 (.., None) => {
174 return Err(SelectionError::NoProvidedTimesteps {
175 hdu_info: format!("{:?}", &corr_ctx.gpubox_time_map),
176 })
177 }
178 _ => {
179 return Err(SelectionError::NoCommonTimesteps {
180 hdu_info: format!("{:?}", &corr_ctx.gpubox_time_map),
181 })
182 }
183 },
184 coarse_chan_range: match (
185 corr_ctx.common_coarse_chan_indices.first(),
186 corr_ctx.common_coarse_chan_indices.last(),
187 ) {
188 (Some(&first), Some(&last)) if first <= last => (first)..(last + 1),
189 _ => {
190 return Err(SelectionError::NoCommonTimesteps {
191 hdu_info: format!("{:?}", &corr_ctx.gpubox_time_map),
192 })
193 }
194 },
195 baseline_idxs: (0..corr_ctx.metafits_context.num_baselines).collect(),
196 })
197 }
198
199 #[cfg(feature = "mwalib")]
201 pub fn retain_antennas(&mut self, meta_ctx: &MetafitsContext, ant_idxs: &[usize]) {
202 self.baseline_idxs.retain(|&bl_idx| {
203 let bl = &meta_ctx.baselines[bl_idx];
204 ant_idxs.contains(&bl.ant1_index) && ant_idxs.contains(&bl.ant2_index)
205 });
206 }
207
208 #[cfg(feature = "mwalib")]
210 pub fn filter_antennas(&mut self, meta_ctx: &MetafitsContext, ant_idxs: &[usize]) {
211 self.baseline_idxs.retain(|&bl_idx| {
212 let bl = &meta_ctx.baselines[bl_idx];
213 !ant_idxs.contains(&bl.ant1_index) && !ant_idxs.contains(&bl.ant2_index)
214 });
215 }
216
217 #[cfg(feature = "mwalib")]
219 pub fn filter_autos(&mut self, meta_ctx: &MetafitsContext) {
220 self.baseline_idxs.retain(|&bl_idx| {
221 let bl = &meta_ctx.baselines[bl_idx];
222 bl.ant1_index != bl.ant2_index
223 });
224 }
225
226 #[cfg(feature = "mwalib")]
228 pub fn get_ant_pairs(&self, meta_ctx: &MetafitsContext) -> Vec<(usize, usize)> {
229 self.baseline_idxs
230 .iter()
231 .map(|&idx| {
232 (
233 meta_ctx.baselines[idx].ant1_index,
234 meta_ctx.baselines[idx].ant2_index,
235 )
236 })
237 .collect()
238 }
239
240 pub fn get_shape(&self, fine_chans_per_coarse: usize) -> (usize, usize, usize) {
242 let num_chans = self.coarse_chan_range.len() * fine_chans_per_coarse;
243 let num_baselines = self.baseline_idxs.len();
244 let num_timesteps = self.timestep_range.len();
245 (num_timesteps, num_chans, num_baselines)
246 }
247
248 pub fn estimate_bytes_best(&self, fine_chans_per_coarse: usize) -> usize {
250 let shape = self.get_shape(fine_chans_per_coarse);
251 shape.0
252 * shape.1
253 * shape.2
254 * (std::mem::size_of::<Jones<f32>>()
255 + std::mem::size_of::<f32>()
256 + std::mem::size_of::<bool>())
257 }
258
259 pub fn allocate_jones(
265 &self,
266 fine_chans_per_coarse: usize,
267 ) -> Result<Array3<Jones<f32>>, SelectionError> {
268 let shape = self.get_shape(fine_chans_per_coarse);
269 let num_elems = shape.0 * shape.1 * shape.2;
270 let mut v = Vec::new();
271
272 if v.try_reserve_exact(num_elems) == Ok(()) {
273 v.resize(num_elems, Jones::zero());
275 Ok(Array3::from_shape_vec(shape, v).unwrap())
276 } else {
277 let need_gib = self.estimate_bytes_best(fine_chans_per_coarse) / 1024_usize.pow(3);
280 Err(SelectionError::InsufficientMemory { need_gib })
281 }
282 }
283
284 pub fn allocate_flags(
290 &self,
291 fine_chans_per_coarse: usize,
292 ) -> Result<Array3<bool>, SelectionError> {
293 let shape = self.get_shape(fine_chans_per_coarse);
294 let num_elems = shape.0 * shape.1 * shape.2;
295 let mut v = Vec::new();
296
297 if v.try_reserve_exact(num_elems) == Ok(()) {
298 v.resize(num_elems, false);
300 Ok(Array3::from_shape_vec(shape, v).unwrap())
301 } else {
302 let need_gib = self.estimate_bytes_best(fine_chans_per_coarse) / 1024_usize.pow(3);
305 Err(SelectionError::InsufficientMemory { need_gib })
306 }
307 }
308
309 pub fn allocate_weights(
315 &self,
316 fine_chans_per_coarse: usize,
317 ) -> Result<Array3<f32>, SelectionError> {
318 let shape = self.get_shape(fine_chans_per_coarse);
319 let num_elems = shape.0 * shape.1 * shape.2;
320 let mut v = Vec::new();
321
322 if v.try_reserve_exact(num_elems) == Ok(()) {
323 v.resize(num_elems, 0.);
325 Ok(Array3::from_shape_vec(shape, v).unwrap())
326 } else {
327 let need_gib = self.estimate_bytes_best(fine_chans_per_coarse) / 1024_usize.pow(3);
330 Err(SelectionError::InsufficientMemory { need_gib })
331 }
332 }
333
334 #[cfg(all(test, feature = "mwalib"))]
336 pub(crate) fn read_mwalib(
337 &self,
338 corr_ctx: &CorrelatorContext,
339 mut jones_array: ndarray::ArrayViewMut3<Jones<f32>>,
340 mut flag_array: ndarray::ArrayViewMut3<bool>,
341 ) -> Result<(), SelectionError> {
342 use itertools::izip;
343 use ndarray::prelude::*;
344 use rayon::prelude::*;
345
346 let fine_chans_per_coarse = corr_ctx.metafits_context.num_corr_fine_chans_per_coarse;
347 let shape = self.get_shape(fine_chans_per_coarse);
348
349 if jones_array.dim() != shape {
350 return Err(SelectionError::BadArrayShape {
351 argument: "jones_array".to_string(),
352 function: "VisSelection::read_mwalib".to_string(),
353 expected: format!("{shape:?}"),
354 received: format!("{:?}", jones_array.dim()),
355 });
356 };
357
358 if flag_array.dim() != shape {
359 return Err(SelectionError::BadArrayShape {
360 argument: "flag_array".to_string(),
361 function: "VisSelection::read_mwalib".to_string(),
362 expected: format!("{shape:?}"),
363 received: format!("{:?}", flag_array.dim()),
364 });
365 };
366
367 let max_bl_idx = corr_ctx.metafits_context.baselines.len();
368 if self.baseline_idxs.iter().any(|&idx| idx >= max_bl_idx) {
370 return Err(SelectionError::BadBaselineIdx {
371 function: "VisSelection::read_mwalib".to_string(),
372 expected: format!(" < {max_bl_idx}"),
373 received: format!("{:?}", self.baseline_idxs.clone()),
374 });
375 }
376
377 let floats_per_chan = 8;
382 assert_eq!(
383 corr_ctx.metafits_context.num_visibility_pols * 2,
384 floats_per_chan
385 );
386
387 let floats_per_baseline = floats_per_chan * fine_chans_per_coarse;
388 let floats_per_hdu = floats_per_baseline * corr_ctx.metafits_context.num_baselines;
389
390 jones_array
392 .axis_chunks_iter_mut(Axis(1), fine_chans_per_coarse)
393 .into_par_iter()
394 .zip(flag_array.axis_chunks_iter_mut(Axis(1), fine_chans_per_coarse))
395 .zip(self.coarse_chan_range.clone())
396 .try_for_each(|((mut jones_array, mut flag_array), coarse_chan_idx)| {
397 let mut hdu_buffer: Vec<f32> = vec![0.0; floats_per_hdu];
399
400 for (mut jones_array, mut flag_array, timestep_idx) in izip!(
402 jones_array.outer_iter_mut(),
403 flag_array.outer_iter_mut(),
404 self.timestep_range.clone(),
405 ) {
406 match corr_ctx.read_by_baseline_into_buffer(
407 timestep_idx,
408 coarse_chan_idx,
409 hdu_buffer.as_mut_slice(),
410 ) {
411 Ok(()) => {
412 for (mut jones_array, baseline_idx) in izip!(
414 jones_array.axis_iter_mut(Axis(1)),
415 self.baseline_idxs.iter()
416 ) {
417 let hdu_baseline_chunk = &hdu_buffer
419 [baseline_idx * floats_per_baseline..][..floats_per_baseline];
420 for (jones, hdu_chan_chunk) in izip!(
421 jones_array.iter_mut(),
422 hdu_baseline_chunk.chunks_exact(floats_per_chan)
423 ) {
424 *jones = Jones::from([
425 hdu_chan_chunk[0],
426 hdu_chan_chunk[1],
427 hdu_chan_chunk[2],
428 hdu_chan_chunk[3],
429 hdu_chan_chunk[4],
430 hdu_chan_chunk[5],
431 hdu_chan_chunk[6],
432 hdu_chan_chunk[7],
433 ]);
434 }
435 }
436 }
437 Err(mwalib::GpuboxError::NoDataForTimeStepCoarseChannel { .. }) => {
438 eprintln!(
439 "Flagging missing HDU @ ts={}, cc={}",
440 timestep_idx, coarse_chan_idx
441 );
442 flag_array.fill(true);
443 }
444 Err(e) => return Err(e),
445 }
446 }
447 Ok(())
448 })?;
449
450 Ok(())
451 }
452}
453
454#[cfg(test)]
455#[cfg(feature = "mwalib")]
456mod tests {
457 use approx::assert_abs_diff_eq;
458
459 use crate::Complex;
460
461 use super::*;
462
463 pub fn get_mwax_context() -> CorrelatorContext {
464 CorrelatorContext::new(
465 "tests/data/1297526432_mwax/1297526432.metafits",
466 &[
467 "tests/data/1297526432_mwax/1297526432_20210216160014_ch117_000.fits",
468 "tests/data/1297526432_mwax/1297526432_20210216160014_ch117_001.fits",
469 "tests/data/1297526432_mwax/1297526432_20210216160014_ch118_000.fits",
470 "tests/data/1297526432_mwax/1297526432_20210216160014_ch118_001.fits",
471 ],
472 )
473 .unwrap()
474 }
475
476 pub fn get_mwa_legacy_context() -> CorrelatorContext {
477 CorrelatorContext::new(
478 "tests/data/1196175296_mwa_ord/1196175296.metafits",
479 &[
480 "tests/data/1196175296_mwa_ord/1196175296_20171201145440_gpubox01_00.fits",
481 "tests/data/1196175296_mwa_ord/1196175296_20171201145440_gpubox02_00.fits",
482 "tests/data/1196175296_mwa_ord/1196175296_20171201145540_gpubox01_01.fits",
483 "tests/data/1196175296_mwa_ord/1196175296_20171201145540_gpubox02_01.fits",
484 ],
485 )
486 .unwrap()
487 }
488
489 pub fn get_mwa_dodgy_context() -> CorrelatorContext {
499 CorrelatorContext::new(
500 "tests/data/1196175296_mwa_ord/1196175296.metafits",
501 &[
502 "tests/data/1196175296_mwa_ord/adjusted_-1/1196175296_20171201145440_gpubox01_00.fits",
503 "tests/data/1196175296_mwa_ord/limited_1/1196175296_20171201145540_gpubox01_01.fits",
504 "tests/data/1196175296_mwa_ord/1196175296_20171201145440_gpubox02_00.fits",
505 "tests/data/1196175296_mwa_ord/1196175296_20171201145540_gpubox02_01.fits",
506 ]
507 ).unwrap()
508 }
509
510 #[test]
511 #[allow(clippy::unnecessary_cast)]
512 fn test_read_mwalib_mwax_flags_missing_hdus() {
515 let corr_ctx = get_mwa_dodgy_context();
516 let vis_sel = VisSelection::from_mwalib(&corr_ctx).unwrap();
517 let fine_chans_per_coarse = corr_ctx.metafits_context.num_corr_fine_chans_per_coarse;
519 let mut flag_array = vis_sel.allocate_flags(fine_chans_per_coarse).unwrap();
520 let mut jones_array = vis_sel.allocate_jones(fine_chans_per_coarse).unwrap();
521 vis_sel
523 .read_mwalib(&corr_ctx, jones_array.view_mut(), flag_array.view_mut())
524 .unwrap();
525
526 assert_abs_diff_eq!(
528 jones_array[(0, 0, 0)],
529 Jones::from([
530 Complex::new(0x10c5be as f32, -0x10c5bf as f32),
531 Complex::new(0x10c5ae as f32, 0x10c5af as f32),
532 Complex::new(0x10c5ae as f32, -0x10c5af as f32),
533 Complex::new(0x10bec6 as f32, -0x10bec7 as f32),
534 ])
535 );
536 assert_abs_diff_eq!(
538 jones_array[(1, 0, 0)],
539 Jones::from([
540 Complex::new(0x14c5be as f32, -0x14c5bf as f32),
541 Complex::new(0x14c5ae as f32, 0x14c5af as f32),
542 Complex::new(0x14c5ae as f32, -0x14c5af as f32),
543 Complex::new(0x14bec6 as f32, -0x14bec7 as f32),
544 ])
545 );
546 assert_abs_diff_eq!(
548 jones_array[(2, 0, 0)],
549 Jones::from([
550 Complex::new(0x18c5be as f32, -0x18c5bf as f32),
551 Complex::new(0x18c5ae as f32, 0x18c5af as f32),
552 Complex::new(0x18c5ae as f32, -0x18c5af as f32),
553 Complex::new(0x18bec6 as f32, -0x18bec7 as f32),
554 ])
555 );
556 assert_abs_diff_eq!(
558 jones_array[(3, 0, 0)],
559 Jones::from([
560 Complex::new(0x1cc5be as f32, -0x1cc5bf as f32),
561 Complex::new(0x1cc5ae as f32, 0x1cc5af as f32),
562 Complex::new(0x1cc5ae as f32, -0x1cc5af as f32),
563 Complex::new(0x1cbec6 as f32, -0x1cbec7 as f32),
564 ])
565 );
566
567 assert_abs_diff_eq!(
571 jones_array[(0, 2, 0)],
572 Jones::from([
573 Complex::new(0x04c5be as f32, -0x04c5bf as f32),
574 Complex::new(0x04c5ae as f32, 0x04c5af as f32),
575 Complex::new(0x04c5ae as f32, -0x04c5af as f32),
576 Complex::new(0x04bec6 as f32, -0x04bec7 as f32),
577 ])
578 );
579 assert!(!flag_array[(0, 2, 0)]);
580 assert_abs_diff_eq!(jones_array[(1, 2, 0)], Jones::<f32>::default());
582 assert!(flag_array[(1, 2, 0)]);
583 assert_abs_diff_eq!(
585 jones_array[(2, 2, 0)],
586 Jones::from([
587 Complex::new(0x08c5be as f32, -0x08c5bf as f32),
588 Complex::new(0x08c5ae as f32, 0x08c5af as f32),
589 Complex::new(0x08c5ae as f32, -0x08c5af as f32),
590 Complex::new(0x08bec6 as f32, -0x08bec7 as f32),
591 ])
592 );
593 assert!(!flag_array[(2, 2, 0)]);
594 assert_abs_diff_eq!(jones_array[(3, 2, 0)], Jones::<f32>::default());
596 assert!(flag_array[(3, 2, 0)]);
597 }
598
599 #[test]
600 fn test_read_mwalib_mwax() {
601 let corr_ctx = get_mwax_context();
602 let vis_sel = VisSelection::from_mwalib(&corr_ctx).unwrap();
603 let fine_chans_per_coarse = corr_ctx.metafits_context.num_corr_fine_chans_per_coarse;
605 let mut flag_array = vis_sel.allocate_flags(fine_chans_per_coarse).unwrap();
606 let mut jones_array = vis_sel.allocate_jones(fine_chans_per_coarse).unwrap();
607 vis_sel
609 .read_mwalib(&corr_ctx, jones_array.view_mut(), flag_array.view_mut())
610 .unwrap();
611
612 assert_abs_diff_eq!(
614 jones_array[(0, 0, 0)],
615 Jones::from([
616 Complex::new(0x410000 as f32, 0x410001 as f32),
617 Complex::new(0x410002 as f32, 0x410003 as f32),
618 Complex::new(0x410004 as f32, 0x410005 as f32),
619 Complex::new(0x410006 as f32, 0x410007 as f32),
620 ])
621 );
622
623 assert_abs_diff_eq!(
625 jones_array[(0, 0, 1)],
626 Jones::from([
627 Complex::new(0x410010 as f32, 0x410011 as f32),
628 Complex::new(0x410012 as f32, 0x410013 as f32),
629 Complex::new(0x410014 as f32, 0x410015 as f32),
630 Complex::new(0x410016 as f32, 0x410017 as f32),
631 ])
632 );
633
634 assert_abs_diff_eq!(
636 jones_array[(0, 0, 2)],
637 Jones::from([
638 Complex::new(0x410020 as f32, 0x410021 as f32),
639 Complex::new(0x410022 as f32, 0x410023 as f32),
640 Complex::new(0x410024 as f32, 0x410025 as f32),
641 Complex::new(0x410026 as f32, 0x410027 as f32),
642 ])
643 );
644
645 assert_abs_diff_eq!(
647 jones_array[(0, 1, 2)],
648 Jones::from([
649 Complex::new(0x410028 as f32, 0x410029 as f32),
650 Complex::new(0x41002a as f32, 0x41002b as f32),
651 Complex::new(0x41002c as f32, 0x41002d as f32),
652 Complex::new(0x41002e as f32, 0x41002f as f32),
653 ])
654 );
655
656 assert_abs_diff_eq!(
658 jones_array[(1, 0, 0)],
659 Jones::from([
660 Complex::new(0x410100 as f32, 0x410101 as f32),
661 Complex::new(0x410102 as f32, 0x410103 as f32),
662 Complex::new(0x410104 as f32, 0x410105 as f32),
663 Complex::new(0x410106 as f32, 0x410107 as f32),
664 ])
665 );
666
667 assert_abs_diff_eq!(
669 jones_array[(2, 0, 0)],
670 Jones::from([
671 Complex::new(0x410200 as f32, 0x410201 as f32),
672 Complex::new(0x410202 as f32, 0x410203 as f32),
673 Complex::new(0x410204 as f32, 0x410205 as f32),
674 Complex::new(0x410206 as f32, 0x410207 as f32),
675 ])
676 );
677
678 assert_abs_diff_eq!(
680 jones_array[(3, 3, 1)],
681 Jones::from([
682 Complex::new(0x410718 as f32, 0x410719 as f32),
683 Complex::new(0x41071a as f32, 0x41071b as f32),
684 Complex::new(0x41071c as f32, 0x41071d as f32),
685 Complex::new(0x41071e as f32, 0x41071f as f32),
686 ])
687 );
688 }
689
690 #[test]
691 fn test_read_mwalib_bad_baseline_idxs() {
692 let corr_ctx = get_mwax_context();
693 let mut vis_sel = VisSelection::from_mwalib(&corr_ctx).unwrap();
694 vis_sel.baseline_idxs = vec![99999999];
695 let fine_chans_per_coarse = corr_ctx.metafits_context.num_corr_fine_chans_per_coarse;
697 let mut flag_array = vis_sel.allocate_flags(fine_chans_per_coarse).unwrap();
698 let mut jones_array = vis_sel.allocate_jones(fine_chans_per_coarse).unwrap();
699 assert!(vis_sel
701 .read_mwalib(&corr_ctx, jones_array.view_mut(), flag_array.view_mut())
702 .is_err());
703 }
704
705 #[test]
706 #[allow(clippy::unnecessary_cast)]
707 fn test_read_mwalib_mwa_legacy() {
708 let corr_ctx = get_mwa_legacy_context();
709 let vis_sel = VisSelection::from_mwalib(&corr_ctx).unwrap();
710 let fine_chans_per_coarse = corr_ctx.metafits_context.num_corr_fine_chans_per_coarse;
712 let mut flag_array = vis_sel.allocate_flags(fine_chans_per_coarse).unwrap();
713 let mut jones_array = vis_sel.allocate_jones(fine_chans_per_coarse).unwrap();
714 vis_sel
716 .read_mwalib(&corr_ctx, jones_array.view_mut(), flag_array.view_mut())
717 .unwrap();
718
719 assert_abs_diff_eq!(
721 jones_array[(0, 0, 0)],
722 Jones::from([
723 Complex::new(0x10c5be as f32, -0x10c5bf as f32),
724 Complex::new(0x10c5ae as f32, 0x10c5af as f32),
725 Complex::new(0x10c5ae as f32, -0x10c5af as f32),
726 Complex::new(0x10bec6 as f32, -0x10bec7 as f32),
727 ])
728 );
729 assert_abs_diff_eq!(
731 jones_array[(1, 0, 0)],
732 Jones::from([
733 Complex::new(0x14c5be as f32, -0x14c5bf as f32),
734 Complex::new(0x14c5ae as f32, 0x14c5af as f32),
735 Complex::new(0x14c5ae as f32, -0x14c5af as f32),
736 Complex::new(0x14bec6 as f32, -0x14bec7 as f32),
737 ])
738 );
739 assert_abs_diff_eq!(
741 jones_array[(2, 0, 0)],
742 Jones::from([
743 Complex::new(0x18c5be as f32, -0x18c5bf as f32),
744 Complex::new(0x18c5ae as f32, 0x18c5af as f32),
745 Complex::new(0x18c5ae as f32, -0x18c5af as f32),
746 Complex::new(0x18bec6 as f32, -0x18bec7 as f32),
747 ])
748 );
749 assert_abs_diff_eq!(
751 jones_array[(3, 0, 0)],
752 Jones::from([
753 Complex::new(0x1cc5be as f32, -0x1cc5bf as f32),
754 Complex::new(0x1cc5ae as f32, 0x1cc5af as f32),
755 Complex::new(0x1cc5ae as f32, -0x1cc5af as f32),
756 Complex::new(0x1cbec6 as f32, -0x1cbec7 as f32),
757 ])
758 );
759
760 assert_abs_diff_eq!(
762 jones_array[(0, 0, 5)],
763 Jones::from([
764 Complex::new(0x10f1ce as f32, -0x10f1cf as f32),
765 Complex::new(0x10ea26 as f32, -0x10ea27 as f32),
766 Complex::new(0x10f1be as f32, -0x10f1bf as f32),
767 Complex::new(0x10ea16 as f32, -0x10ea17 as f32),
768 ])
769 );
770 assert_abs_diff_eq!(
772 jones_array[(1, 0, 5)],
773 Jones::from([
774 Complex::new(0x14f1ce as f32, -0x14f1cf as f32),
775 Complex::new(0x14ea26 as f32, -0x14ea27 as f32),
776 Complex::new(0x14f1be as f32, -0x14f1bf as f32),
777 Complex::new(0x14ea16 as f32, -0x14ea17 as f32),
778 ])
779 );
780 assert_abs_diff_eq!(
782 jones_array[(2, 0, 5)],
783 Jones::from([
784 Complex::new(0x18f1ce as f32, -0x18f1cf as f32),
785 Complex::new(0x18ea26 as f32, -0x18ea27 as f32),
786 Complex::new(0x18f1be as f32, -0x18f1bf as f32),
787 Complex::new(0x18ea16 as f32, -0x18ea17 as f32),
788 ])
789 );
790 assert_abs_diff_eq!(
792 jones_array[(3, 0, 5)],
793 Jones::from([
794 Complex::new(0x1cf1ce as f32, -0x1cf1cf as f32),
795 Complex::new(0x1cea26 as f32, -0x1cea27 as f32),
796 Complex::new(0x1cf1be as f32, -0x1cf1bf as f32),
797 Complex::new(0x1cea16 as f32, -0x1cea17 as f32),
798 ])
799 );
800
801 assert_abs_diff_eq!(
803 jones_array[(0, 2, 0)],
804 Jones::from([
805 Complex::new(0x00c5be as f32, -0x00c5bf as f32),
806 Complex::new(0x00c5ae as f32, 0x00c5af as f32),
807 Complex::new(0x00c5ae as f32, -0x00c5af as f32),
808 Complex::new(0x00bec6 as f32, -0x00bec7 as f32),
809 ])
810 );
811 assert_abs_diff_eq!(
813 jones_array[(1, 2, 0)],
814 Jones::from([
815 Complex::new(0x04c5be as f32, -0x04c5bf as f32),
816 Complex::new(0x04c5ae as f32, 0x04c5af as f32),
817 Complex::new(0x04c5ae as f32, -0x04c5af as f32),
818 Complex::new(0x04bec6 as f32, -0x04bec7 as f32),
819 ])
820 );
821 assert_abs_diff_eq!(
823 jones_array[(2, 2, 0)],
824 Jones::from([
825 Complex::new(0x08c5be as f32, -0x08c5bf as f32),
826 Complex::new(0x08c5ae as f32, 0x08c5af as f32),
827 Complex::new(0x08c5ae as f32, -0x08c5af as f32),
828 Complex::new(0x08bec6 as f32, -0x08bec7 as f32),
829 ])
830 );
831 assert_abs_diff_eq!(
833 jones_array[(3, 2, 0)],
834 Jones::from([
835 Complex::new(0x0cc5be as f32, -0x0cc5bf as f32),
836 Complex::new(0x0cc5ae as f32, 0x0cc5af as f32),
837 Complex::new(0x0cc5ae as f32, -0x0cc5af as f32),
838 Complex::new(0x0cbec6 as f32, -0x0cbec7 as f32),
839 ])
840 );
841 assert_abs_diff_eq!(
843 jones_array[(3, 3, 5)],
844 Jones::from([
845 Complex::new(0x0df3ce as f32, -0x0df3cf as f32),
846 Complex::new(0x0dec26 as f32, -0x0dec27 as f32),
847 Complex::new(0x0df3be as f32, -0x0df3bf as f32),
848 Complex::new(0x0dec16 as f32, -0x0dec17 as f32),
849 ])
850 );
851 }
852
853 #[test]
854 fn test_retain_antennas() {
855 let corr_ctx = get_mwa_legacy_context();
856 let mut vis_sel = VisSelection::from_mwalib(&corr_ctx).unwrap();
857 assert_eq!(vis_sel.baseline_idxs.len(), 8256);
858
859 vis_sel.retain_antennas(&corr_ctx.metafits_context, &[1, 2]);
861
862 assert_eq!(vis_sel.baseline_idxs, vec![128, 129, 255]);
863 }
864
865 #[test]
866 fn test_filter_antennas() {
867 let corr_ctx = get_mwa_legacy_context();
868 let mut vis_sel = VisSelection::from_mwalib(&corr_ctx).unwrap();
869 assert_eq!(vis_sel.baseline_idxs.len(), 8256);
870
871 vis_sel.filter_antennas(&corr_ctx.metafits_context, &[1, 2]);
873
874 assert_eq!(vis_sel.baseline_idxs.len(), 8001);
875
876 println!("baseline_idxs: {:?}", vis_sel.baseline_idxs);
877
878 assert!(vis_sel.baseline_idxs.contains(&0));
879 assert!(!vis_sel.baseline_idxs.contains(&1));
880 assert!(!vis_sel.baseline_idxs.contains(&2));
881 assert!(vis_sel.baseline_idxs.contains(&3));
882 assert!(!vis_sel.baseline_idxs.contains(&128));
883 assert!(!vis_sel.baseline_idxs.contains(&129));
884 assert!(!vis_sel.baseline_idxs.contains(&130));
885 assert!(!vis_sel.baseline_idxs.contains(&254));
886 assert!(!vis_sel.baseline_idxs.contains(&255));
887 assert!(!vis_sel.baseline_idxs.contains(&256));
888 assert!(vis_sel.baseline_idxs.contains(&381));
889 assert!(vis_sel.baseline_idxs.contains(&8255));
890 }
891
892 #[test]
893 fn test_filter_autos() {
894 let corr_ctx = get_mwa_legacy_context();
895 let mut vis_sel = VisSelection::from_mwalib(&corr_ctx).unwrap();
896 assert_eq!(vis_sel.baseline_idxs.len(), 8256);
897
898 vis_sel.filter_autos(&corr_ctx.metafits_context);
899
900 assert_eq!(vis_sel.baseline_idxs.len(), 8128);
901 assert!(!vis_sel.baseline_idxs.contains(&0));
902 assert!(vis_sel.baseline_idxs.contains(&1));
903 assert!(vis_sel.baseline_idxs.contains(&2));
904 assert!(vis_sel.baseline_idxs.contains(&3));
905 assert!(!vis_sel.baseline_idxs.contains(&128));
906 assert!(vis_sel.baseline_idxs.contains(&129));
907 assert!(vis_sel.baseline_idxs.contains(&130));
908 assert!(vis_sel.baseline_idxs.contains(&254));
909 assert!(!vis_sel.baseline_idxs.contains(&255));
910 assert!(vis_sel.baseline_idxs.contains(&256));
911 assert!(!vis_sel.baseline_idxs.contains(&381));
912 assert!(vis_sel.baseline_idxs.contains(&8127));
913 assert!(!vis_sel.baseline_idxs.contains(&8255));
914 }
915}