Commits
7 7 | import pprint |
8 8 | import numpy as np |
9 9 | from numpy import array |
10 10 | import ast |
11 11 | |
12 12 | from casatasks.private.casa_transition import is_CASA6 |
13 13 | if is_CASA6: |
14 14 | import sys |
15 15 | |
16 16 | from casatasks import flagcmd, flagdata, mstransform, setjy, delmod, split |
17 - | from casatools import ctsys, agentflagger, table |
17 + | from casatools import ctsys, agentflagger, table, measures, quanta |
18 18 | from casatasks.private.parallel.parallel_task_helper import ParallelTaskHelper |
19 19 | from casatasks.private import flaghelper as fh |
20 20 | |
21 21 | ### for testhelper import |
22 22 | #sys.path.append(os.path.abspath(os.path.dirname(__file__))) |
23 23 | #import testhelper as th |
24 24 | |
25 25 | # CASA6 doesn't need defaul |
26 26 | def default(atask): |
27 27 | pass |
28 28 | |
29 29 | ctsys_resolve = ctsys.resolve |
30 30 | else: |
31 31 | from tasks import flagcmd, flagdata, mstransform, setjy, delmod, split |
32 32 | from taskinit import aftool as agentflagger |
33 33 | from taskinit import tbtool as table |
34 + | from taskinit import metool as measures |
35 + | from taskinit import qatool as quanta |
34 36 | from __main__ import default |
35 37 | from parallel.parallel_task_helper import ParallelTaskHelper |
36 38 | import flaghelper as fh |
37 39 | #import testhelper as th |
38 40 | |
39 41 | def ctsys_resolve(apath): |
40 42 | dataPath = os.path.join(os.environ['CASAPATH'].split()[0],'casatestdata/') |
41 43 | return os.path.join(dataPath,apath) |
42 44 | |
43 45 | from casatestutils import testhelper as th |
288 290 | |
289 291 | def setUp_data4preaveraging(self): |
290 292 | # Four_ants_3C286_spw9_small_for_preaveraging.ms was generated with a command like: |
291 293 | # mstransform(vis='Four_ants_3C286.ms', |
292 294 | # outputvis='Four_ants_3C286_spw9_small_for_preaveraging.ms', |
293 295 | # datacolumn='data',spw='9', antenna='1&2', |
294 296 | # timerange='2010/10/16/14:45:08.50~2010/10/16/14:45:11.50') |
295 297 | self.vis = 'Four_ants_3C286_spw9_small_for_preaveraging.ms' |
296 298 | self._check_path_move_remove_versions_unflag_etc() |
297 299 | |
300 + | def setUp_data4timeavg(self): |
301 + | # Four_ants_3C286_spw9_small_for_preaveraging.ms was generated with a command like: |
302 + | # The different wrt data4preaveraging is that we include more rows / integrations so |
303 + | # that it is possible to run timeavg with a bigger timebin (up to 100s). |
304 + | # mstransform(vis='Four_ants_3C286.ms', |
305 + | # outputvis='Four_ants_3C286_spw9_small_for_timeavg.ms', |
306 + | # datacolumn='data',spw='9', antenna='1&2', |
307 + | # timerange='2010/10/16/14:45:08.50~2010/10/16/14:46:48.50') |
308 + | self.vis = 'Four_ants_3C286_spw9_small_for_timeavg.ms' |
309 + | self._check_path_move_remove_versions_unflag_etc() |
310 + | |
298 311 | def setUp_shadowdata1(self): |
299 312 | '''ALMA ACA observation with one field in APP ref frame''' |
300 313 | self.vis = "shadowAPP.ms" |
301 314 | |
302 315 | if os.path.exists(self.vis): |
303 316 | print("The MS is already around, just unflag") |
304 317 | else: |
305 318 | print("Moving data...") |
306 319 | os.system('cp -RH '+os.path.join(datapath,self.vis)+' '+ self.vis) |
307 320 | |
2366 2379 | # should not flag anything |
2367 2380 | res = flagdata(vis=self.vis, mode='summary', spw='5,9,10,11') |
2368 2381 | self.assertEqual(res['flagged'], 0) |
2369 2382 | |
2370 2383 | def test_residual_col(self): |
2371 2384 | '''flagdata: clip RESIDUAL column''' |
2372 2385 | flagdata(vis=self.vis, flagbackup=False, mode='clip', datacolumn='RESIDUAL', clipzeros=True) |
2373 2386 | res = flagdata(vis=self.vis, mode='summary') |
2374 2387 | self.assertEqual(res['flagged'], 137472) |
2375 2388 | |
2376 - | def test_timeavg1(self): |
2389 + | def test_clip_timeavg_cmp_mstransform(self): |
2377 2390 | '''flagdata: clip with time average and compare with mstransform''' |
2391 + | |
2392 + | def check_expected_flag_positions(self, msname): |
2393 + | """ |
2394 + | Implements a very hand-made check on the exact positions of flags for the test |
2395 + | dataset used in these tests. |
2396 + | |
2397 + | This has been crossed-checked manually, looking at the visibility values and the |
2398 + | thresholds set in clip (clipminmax). The pattern used here must be produced by |
2399 + | the (back)propagation of flags with time average if it is working correctly. |
2400 + | """ |
2401 + | try: |
2402 + | tbt = table() |
2403 + | tbt.open(msname) |
2404 + | flags = tbt.getcol('FLAG') |
2405 + | |
2406 + | # Indices are: correlation, channel, time: |
2407 + | exp_flags = [[ 0, 51, 0], [ 0, 51, 1], [ 0, 60, 0], [ 0, 60, 1], |
2408 + | [ 1, 51, 0], [ 1, 51, 1], [ 1, 60, 1], [ 2, 51, 0], |
2409 + | [ 2, 51, 1], [ 2, 60, 0], [ 2, 60, 1], [ 3 ,21, 1], |
2410 + | [ 3, 51, 0], [ 3, 51, 1], [ 3, 60, 0], [ 3, 60, 1]] |
2411 + | expected = np.full((4, 64, 2), False) |
2412 + | for pos in exp_flags: |
2413 + | expected[pos[0], pos[1], pos[2]] = True |
2414 + | |
2415 + | np.testing.assert_equal(flags, expected, |
2416 + | "Flags do not match the expected, manually verified " |
2417 + | "pattern.") |
2418 + | finally: |
2419 + | tbt.close() |
2420 + | |
2378 2421 | # Create an output with 4 rows |
2379 2422 | split(vis=self.vis,outputvis='timeavg.ms',datacolumn='data',spw='9',scan='30',antenna='1&2', |
2380 2423 | timerange='2010/10/16/14:45:08.50~2010/10/16/14:45:11.50') |
2424 + | flagdata('timeavg.ms', flagbackup=False, mode='unflag') |
2381 2425 | |
2382 2426 | # STEP 1 |
2383 2427 | # Create time averaged output in mstransform |
2384 - | mstransform('timeavg.ms',outputvis='test_residual_step1_timeavg.ms', |
2428 + | ms_step1 = 'test_residual_step1_timeavg.ms' |
2429 + | mstransform('timeavg.ms',outputvis=ms_step1, |
2385 2430 | datacolumn='data',timeaverage=True,timebin='2s') |
2386 2431 | |
2387 2432 | # clip it |
2388 - | flagdata('test_residual_step1_timeavg.ms',flagbackup=False, mode='clip', |
2433 + | flagdata(ms_step1, flagbackup=False, mode='clip', |
2389 2434 | clipminmax=[0.0,0.08]) |
2390 - | res1 = flagdata(vis='test_residual_step1_timeavg.ms', mode='summary', spwchan=True) |
2435 + | res1 = flagdata(vis=ms_step1, mode='summary', spwchan=True) |
2391 2436 | |
2392 2437 | # STEP 2 |
2393 2438 | # Clip with time averaging. |
2394 - | flagdata('timeavg.ms', flagbackup=False, mode='unflag') |
2439 + | ms_step2 = 'test_residual_step2_timeavg.ms' |
2395 2440 | flagdata(vis='timeavg.ms', flagbackup=False, mode='clip', datacolumn='DATA', |
2396 2441 | timeavg=True, timebin='2s', clipminmax=[0.0,0.08]) |
2397 2442 | |
2398 2443 | # Do another time average in mstransform to have the corrected averaged visibilities |
2399 - | mstransform('timeavg.ms',outputvis='test_residual_step2_timeavg.ms', |
2444 + | mstransform('timeavg.ms', outputvis=ms_step2, |
2400 2445 | datacolumn='data',timeaverage=True,timebin='2s') |
2401 2446 | |
2402 - | res2 = flagdata(vis='test_residual_step2_timeavg.ms', mode='summary', spwchan=True) |
2447 + | res2 = flagdata(vis=ms_step2, mode='summary', spwchan=True) |
2403 2448 | |
2449 + | # Compare step1 vs step2 |
2404 2450 | self.assertEqual(res1['flagged'], res2['flagged']) |
2451 + | # Check specific channels |
2405 2452 | self.assertEqual(res2['spw:channel']['0:21']['flagged'], 1) |
2406 2453 | self.assertEqual(res2['spw:channel']['0:51']['flagged'], 8) |
2407 2454 | self.assertEqual(res2['spw:channel']['0:60']['flagged'], 7) |
2408 2455 | |
2409 - | def test_timeavg2(self): |
2456 + | # Additional checks on the exact positions of flags, to better cover issues found |
2457 + | # in CAS-12737, CAS-12910. |
2458 + | check_expected_flag_positions(self, ms_step1) |
2459 + | check_expected_flag_positions(self, ms_step2) |
2460 + | |
2461 + | def test_timeavg_spw9_2scans(self): |
2410 2462 | '''flagdata: clip with time averaging in spw 9''' |
2411 2463 | |
2412 2464 | flagdata(vis=self.vis, flagbackup=False, mode='clip', datacolumn='DATA', spw='9', |
2413 2465 | timeavg=True, timebin='2s', clipminmax=[0.0,0.08]) |
2414 2466 | |
2415 2467 | res = flagdata(vis=self.vis, mode='summary', spw='9') |
2416 - | self.assertEqual(res['spw']['9']['flagged'], 42370) |
2417 - | self.assertEqual(res['flagged'], 42370) |
2468 + | self.assertEqual(res['spw']['9']['flagged'], 42106) |
2469 + | self.assertEqual(res['flagged'], 42106) |
2418 2470 | |
2419 2471 | |
2420 2472 | def test_clip_no_model_col(self): |
2421 2473 | "flagdata: Should fail when MODEL or virtual MODEL columns do not exist" |
2422 2474 | # Use an MS without MODEL_DATA column |
2423 2475 | self.setUp_ngc5921(True) |
2424 2476 | |
2425 2477 | # RESIDUAL = CORRECTED - MODEL. |
2426 2478 | # It should fail and not flag anything |
2427 2479 | datacols = ["RESIDUAL","RESIDUAL_DATA"] |
3741 3793 | self.assertEqual(res[6]['mode'], 'summary3') |
3742 3794 | |
3743 3795 | |
3744 3796 | class test_preaveraging(test_base): |
3745 3797 | """Test channel/time pre-averaging for visibility-based flagging""" |
3746 3798 | |
3747 3799 | def setUp(self): |
3748 3800 | self.setUp_data4preaveraging() |
3749 3801 | self.corrs = ['RL', 'LL', 'LR', 'RR'] |
3750 3802 | |
3751 - | def tearDown(self): |
3803 + | def tearDown(self): |
3752 3804 | os.system('rm -rf test_preaveraging.ms') |
3753 3805 | os.system('rm -rf test_clip_timeavg*') |
3754 3806 | os.system('rm -rf test_clip_chanavg*') |
3755 3807 | os.system('rm -rf test_clip_time_chanavg*') |
3756 3808 | os.system('rm -rf test_rflag_timeavg*') |
3757 3809 | os.system('rm -rf test_rflag_chanavg*') |
3758 3810 | os.system('rm -rf test_rflag_time_chanavg*') |
3759 3811 | os.system('rm -rf test_tfcrop_timeavg*') |
3760 3812 | os.system('rm -rf test_tfcrop_chanavg*') |
3761 3813 | os.system('rm -rf test_tfcrop_time_chanavg*') |
3762 3814 | |
3763 3815 | def test_clip_timeavg(self): |
3764 3816 | '''flagdata: clip with time average and compare vs mstransform''' |
3765 3817 | |
3766 - | # Unflag the original input data |
3767 - | flagdata(self.vis, flagbackup=False, mode='unflag') |
3818 + | # Unflag the original input data - alread done by setUp |
3819 + | # flagdata(self.vis, flagbackup=False, mode='unflag') |
3768 3820 | |
3769 3821 | # STEP 1: Time average with mstransform, then flagging with normal clip |
3770 3822 | mstransform(vis=self.vis,outputvis='test_clip_timeavg_step1.ms',datacolumn='data', |
3771 3823 | timeaverage=True,timebin='2s') |
3772 3824 | flagdata(vis='test_clip_timeavg_step1.ms',flagbackup=False, mode='clip',clipminmax=[0.0,0.08]) |
3773 3825 | res1 = flagdata(vis='test_clip_timeavg_step1.ms', mode='summary', spwchan=True) |
3774 3826 | |
3775 3827 | # Unflag the original input data |
3776 3828 | flagdata(self.vis, flagbackup=False, mode='unflag') |
3777 3829 | |
3781 3833 | mstransform(vis=self.vis,outputvis='test_clip_timeavg_step2.ms',datacolumn='data', |
3782 3834 | timeaverage=True,timebin='2s') |
3783 3835 | res2 = flagdata(vis='test_clip_timeavg_step2.ms', mode='summary', spwchan=True) |
3784 3836 | |
3785 3837 | # Compare results |
3786 3838 | self.assertEqual(res1['flagged'], res2['flagged']) |
3787 3839 | |
3788 3840 | def test_clip_chanavg(self): |
3789 3841 | '''flagdata: clip with chan average and compare vs mstransform''' |
3790 3842 | |
3791 - | # Unflag the original input data |
3792 - | flagdata(self.vis, flagbackup=False, mode='unflag') |
3843 + | # Unflag the original input data - alread done by setUp |
3844 + | # flagdata(self.vis, flagbackup=False, mode='unflag') |
3793 3845 | |
3794 3846 | # STEP 1: Chan average with mstransform, then flagging with normal clip |
3795 3847 | mstransform(vis=self.vis,outputvis='test_clip_chanavg_step1.ms',datacolumn='data', |
3796 3848 | chanaverage=True,chanbin=2) |
3797 3849 | flagdata(vis='test_clip_chanavg_step1.ms',flagbackup=False, mode='clip',clipminmax=[0.0,0.08]) |
3798 3850 | res1 = flagdata(vis='test_clip_chanavg_step1.ms', mode='summary', spwchan=True) |
3799 3851 | |
3800 3852 | # Unflag the original input data |
3801 3853 | flagdata(vis=self.vis, flagbackup=False, mode='unflag') |
3802 3854 | |
3806 3858 | mstransform(vis=self.vis, outputvis='test_clip_chanavg_step2.ms',datacolumn='data', |
3807 3859 | chanaverage=True,chanbin=2) |
3808 3860 | res2 = flagdata(vis='test_clip_chanavg_step2.ms', mode='summary', spwchan=True) |
3809 3861 | |
3810 3862 | # Compare results |
3811 3863 | self.assertEqual(res1['flagged'], res2['flagged']) |
3812 3864 | |
3813 3865 | def test_clip_time_chanavg(self): |
3814 3866 | '''flagdata: clip with time/chan average and compare vs mstransform''' |
3815 3867 | |
3816 - | # Unflag the original input data |
3817 - | flagdata(self.vis, flagbackup=False, mode='unflag') |
3868 + | # Unflag the original input data - alread done by setUp |
3869 + | # flagdata(self.vis, flagbackup=False, mode='unflag') |
3818 3870 | |
3819 3871 | # STEP 1: Chan average with mstransform, then flagging with normal clip |
3820 3872 | mstransform(vis=self.vis,outputvis='test_clip_time_chanavg_step1.ms',datacolumn='data', |
3821 3873 | timeaverage=True,timebin='2s',chanaverage=True,chanbin=2) |
3822 3874 | flagdata(vis='test_clip_time_chanavg_step1.ms',flagbackup=False, mode='clip',clipminmax=[0.0,0.08]) |
3823 3875 | res1 = flagdata(vis='test_clip_time_chanavg_step1.ms', mode='summary', spwchan=True) |
3824 3876 | |
3825 3877 | # Unflag the original input data |
3826 3878 | flagdata(vis=self.vis, flagbackup=False, mode='unflag') |
3827 3879 | |
3828 3880 | # STEP 2: Flagging with clip using time average, then time average with mstransform |
3829 3881 | flagdata(vis=self.vis, flagbackup=False, mode='clip', datacolumn='DATA', |
3830 3882 | timeavg=True, timebin='2s', channelavg=True, chanbin=2, clipminmax=[0.0,0.08]) |
3831 3883 | mstransform(vis=self.vis, outputvis='test_clip_time_chanavg_step2.ms',datacolumn='data', |
3832 3884 | timeaverage=True,timebin='2s',chanaverage=True,chanbin=2) |
3833 3885 | res2 = flagdata(vis='test_clip_time_chanavg_step2.ms', mode='summary', spwchan=True) |
3834 3886 | |
3835 3887 | # Compare results |
3836 - | self.assertEqual(res1['flagged'], res2['flagged']) |
3888 + | self.assertEqual(res1['flagged'], res2['flagged']) |
3837 3889 | |
3838 3890 | def test_rflag_timeavg(self): |
3839 3891 | '''flagdata: rflag with time average and compare vs mstransform''' |
3840 3892 | |
3841 - | # Unflag the original input data |
3842 - | flagdata(self.vis, flagbackup=False, mode='unflag') |
3893 + | # # Unflag the original input data - alread done by setUp |
3894 + | # flagdata(self.vis, flagbackup=False, mode='unflag') |
3843 3895 | |
3844 3896 | # STEP 1: Time average with mstransform, then flagging with normal rflag |
3845 3897 | mstransform(vis=self.vis,outputvis='test_rflag_timeavg_step1.ms',datacolumn='data', |
3846 3898 | timeaverage=True,timebin='2s') |
3847 3899 | flagdata(vis='test_rflag_timeavg_step1.ms',flagbackup=False, mode='rflag',extendflags=False) |
3848 3900 | res1 = flagdata(vis='test_rflag_timeavg_step1.ms', mode='summary', spwchan=True) |
3849 - | |
3850 - | # Unflag the original input data |
3851 - | flagdata(self.vis, flagbackup=False, mode='unflag') |
3901 + | |
3902 + | # # Unflag the original input data - not needed |
3903 + | # flagdata(self.vis, flagbackup=False, mode='unflag') |
3852 3904 | |
3853 3905 | # STEP 2: Flagging with rflag using time average, then time average with mstransform |
3854 3906 | flagdata(vis=self.vis, flagbackup=False, mode='rflag', datacolumn='DATA', |
3855 3907 | timeavg=True, timebin='2s', extendflags=False) |
3856 3908 | mstransform(vis=self.vis,outputvis='test_rflag_timeavg_step2.ms',datacolumn='data', |
3857 3909 | timeaverage=True,timebin='2s') |
3858 3910 | res2 = flagdata(vis='test_rflag_timeavg_step2.ms', mode='summary', spwchan=True) |
3859 3911 | |
3860 3912 | # Compare results |
3861 - | self.assertEqual(res1['total'], res2['total']) |
3913 + | self.assertEqual(res1['flagged'], res2['flagged']) |
3862 3914 | self.assertEqual(res1['flagged'], 27) |
3863 - | self.assertEqual(res2['flagged'], 20) |
3915 + | for cor in self.corrs: |
3916 + | self.assertEqual(res1['correlation'][cor]['flagged'], |
3917 + | res2['correlation'][cor]['flagged']) |
3864 3918 | |
3865 3919 | def test_rflag_timeavg_extendflags(self): |
3866 3920 | '''flagdata: rflag with time average + extendflags, and compare vs mstransform''' |
3867 3921 | # Unflag the original input data |
3868 3922 | flagdata(self.vis, flagbackup=False, mode='unflag') |
3869 3923 | |
3870 3924 | timebin = '2s' |
3871 3925 | |
3872 3926 | # STEP 1: Time average with mstransform, then flagging with normal rflag+extendflags |
3873 3927 | mstransform(vis=self.vis, outputvis='test_rflag_timeavg_extendflags_step1.ms', |
3881 3935 | |
3882 3936 | # STEP 2: Flagging with rflag using time average, then time average with mstransform |
3883 3937 | flagdata(vis=self.vis, flagbackup=False, mode='rflag', datacolumn='DATA', |
3884 3938 | timeavg=True, timebin='2s', extendflags=True) |
3885 3939 | mstransform(vis=self.vis, outputvis='test_rflag_timeavg_extendflags_step2.ms', |
3886 3940 | datacolumn='data', timeaverage=True, timebin=timebin) |
3887 3941 | res2 = flagdata(vis='test_rflag_timeavg_extendflags_step2.ms', mode='summary') |
3888 3942 | |
3889 3943 | # Compare results |
3890 3944 | self.assertEqual(res1['total'], res2['total']) |
3945 + | self.assertEqual(res1['flagged'], res2['flagged']) |
3891 3946 | self.assertEqual(res1['flagged'], 40) |
3892 - | self.assertEqual(res2['flagged'], 24) |
3893 3947 | for cor in self.corrs: |
3894 3948 | self.assertEqual(res1['correlation'][cor]['flagged'],10) |
3895 - | self.assertEqual(res2['correlation'][cor]['flagged'],6) |
3949 + | self.assertEqual(res1['correlation'][cor]['flagged'], |
3950 + | res2['correlation'][cor]['flagged']) |
3896 3951 | |
3897 3952 | def test_rflag_chanavg(self): |
3898 3953 | '''flagdata: rflag with chan average and compare vs mstransform''' |
3899 3954 | |
3900 - | # Unflag the original input data |
3901 - | flagdata(self.vis, flagbackup=False, mode='unflag') |
3955 + | # Unflag the original input data - alread done by setUp |
3956 + | # flagdata(self.vis, flagbackup=False, mode='unflag') |
3902 3957 | |
3903 3958 | # STEP 1: Chan average with mstransform, then flagging with normal rflag |
3904 3959 | mstransform(vis=self.vis,outputvis='test_rflag_chanavg_step1.ms',datacolumn='data', |
3905 3960 | chanaverage=True,chanbin=2) |
3906 3961 | flagdata(vis='test_rflag_chanavg_step1.ms',flagbackup=False, mode='rflag',extendflags=False) |
3907 3962 | res1 = flagdata(vis='test_rflag_chanavg_step1.ms', mode='summary', spwchan=True) |
3908 3963 | |
3909 3964 | # Unflag the original input data |
3910 3965 | flagdata(vis=self.vis, flagbackup=False, mode='unflag') |
3911 3966 | |
3917 3972 | res2 = flagdata(vis='test_rflag_chanavg_step2.ms', mode='summary', spwchan=True) |
3918 3973 | |
3919 3974 | # Compare results |
3920 3975 | self.assertEqual(res1['flagged'], res2['flagged']) |
3921 3976 | for cor in self.corrs: |
3922 3977 | self.assertEqual(res2['correlation'][cor]['flagged'], |
3923 3978 | res1['correlation'][cor]['flagged']) |
3924 3979 | |
3925 3980 | def test_rflag_chanavg_extendflags(self): |
3926 3981 | '''flagdata: rflag with chan average + extendflags, and compare vs mstransform''' |
3927 - | # Unflag the original input data |
3928 - | flagdata(self.vis, flagbackup=False, mode='unflag') |
3982 + | |
3983 + | # Unflag the original input data - alread done by setUp |
3984 + | # flagdata(self.vis, flagbackup=False, mode='unflag') |
3929 3985 | |
3930 3986 | chanbin = 8 |
3931 3987 | |
3932 3988 | # STEP 1: Chan average with mstransform, then flagging with normal rflag |
3933 3989 | mstransform(vis=self.vis, outputvis='test_rflag_chanavg_extendflags_step1.ms', |
3934 3990 | datacolumn='data', chanaverage=True, chanbin=chanbin) |
3935 3991 | flagdata(vis='test_rflag_chanavg_extendflags_step1.ms', flagbackup=False, |
3936 3992 | mode='rflag', extendflags=True) |
3937 3993 | res1 = flagdata(vis='test_rflag_chanavg_extendflags_step1.ms', mode='summary') |
3938 3994 | |
3951 4007 | self.assertEqual(res1['flagged'], res2['flagged']) |
3952 4008 | self.assertEqual(res1['flagged'], 20) |
3953 4009 | for cor in self.corrs: |
3954 4010 | self.assertEqual(res1['correlation'][cor]['flagged'], 5) |
3955 4011 | self.assertEqual(res2['correlation'][cor]['flagged'], |
3956 4012 | res1['correlation'][cor]['flagged']) |
3957 4013 | |
3958 4014 | def test_rflag_time_chanavg(self): |
3959 4015 | '''flagdata: rflag with time/chan average and compare vs mstransform''' |
3960 4016 | |
3961 - | # Unflag the original input data |
3962 - | flagdata(self.vis, flagbackup=False, mode='unflag') |
4017 + | # Unflag the original input data - alread done by setUp |
4018 + | # flagdata(self.vis, flagbackup=False, mode='unflag') |
3963 4019 | |
3964 4020 | # STEP 1: chan+time average with mstransform, then flagging with normal rflag |
3965 4021 | mstransform(vis=self.vis,outputvis='test_rflag_time_chanavg_step1.ms', |
3966 4022 | datacolumn='data', timeaverage=True, timebin='2s', |
3967 4023 | chanaverage=True, chanbin=2) |
3968 4024 | res1 = flagdata(vis='test_rflag_time_chanavg_step1.ms', action='calculate', |
3969 4025 | mode='rflag', extendflags=False) |
3970 4026 | |
3971 4027 | # STEP 2: rflag using chan+time average, then mstransform using chan+time avg |
3972 4028 | flagdata(vis=self.vis, flagbackup=False, mode='rflag', datacolumn='DATA', |
3987 4043 | tolerances = [1.1, 7.5e-1] |
3988 4044 | for threshold_type, tol in zip(['freqdev', 'timedev'], tolerances): |
3989 4045 | self.assertTrue(np.less_equal(res2['report0'][threshold_type], |
3990 4046 | res1['report0'][threshold_type]).all()) |
3991 4047 | self.assertTrue(np.allclose(res1['report0'][threshold_type], |
3992 4048 | res2['report0'][threshold_type], rtol=tol)) |
3993 4049 | |
3994 4050 | def test_tfcrop_timeavg(self): |
3995 4051 | '''flagdata: tfcrop with time average and compare vs mstransform''' |
3996 4052 | |
3997 - | # Unflag the original input data |
3998 - | flagdata(self.vis, flagbackup=False, mode='unflag') |
4053 + | # Unflag the original input data - alread done by setUp |
4054 + | # flagdata(self.vis, flagbackup=False, mode='unflag') |
3999 4055 | |
4000 4056 | # STEP 1: Time average with mstransform, then flagging with normal tfcrop |
4001 4057 | mstransform(vis=self.vis,outputvis='test_tfcrop_timeavg_step1.ms',datacolumn='data', |
4002 4058 | timeaverage=True,timebin='2s') |
4003 4059 | flagdata(vis='test_tfcrop_timeavg_step1.ms',flagbackup=False, mode='tfcrop', |
4004 4060 | extendflags=False) |
4005 4061 | res1 = flagdata(vis='test_tfcrop_timeavg_step1.ms', mode='summary', spwchan=True) |
4006 4062 | |
4007 4063 | # Unflag the original input data |
4008 4064 | flagdata(self.vis, flagbackup=False, mode='unflag') |
4009 4065 | |
4010 4066 | # STEP 2: Flagging with tfcrop using time average, then time average with mstransform |
4011 4067 | flagdata(vis=self.vis, flagbackup=False, mode='tfcrop', datacolumn='DATA', |
4012 4068 | timeavg=True, timebin='2s', extendflags=False) |
4013 4069 | mstransform(vis=self.vis,outputvis='test_tfcrop_timeavg_step2.ms',datacolumn='data', |
4014 4070 | timeaverage=True,timebin='2s') |
4015 4071 | res2 = flagdata(vis='test_tfcrop_timeavg_step2.ms', mode='summary', spwchan=True) |
4016 4072 | |
4017 4073 | # Check results |
4018 - | self.assertEqual(res1['flagged'], 36) |
4019 - | self.assertEqual(res2['flagged'], 60) |
4074 + | self.assertEqual(res2['flagged'], res2['flagged']) |
4075 + | for cor in self.corrs: |
4076 + | self.assertEqual(res2['correlation'][cor]['flagged'], |
4077 + | res1['correlation'][cor]['flagged']) |
4020 4078 | |
4021 4079 | def test_tfcrop_timeavg_extendflags(self): |
4022 4080 | '''flagdata: tfcrop with time average + extendflags, and compare vs mstransform''' |
4023 4081 | |
4024 - | # Unflag the original input data |
4025 - | flagdata(self.vis, flagbackup=False, mode='unflag') |
4082 + | # Unflag the original input data - alread done by setUp |
4083 + | # flagdata(self.vis, flagbackup=False, mode='unflag') |
4026 4084 | |
4027 4085 | timebin = '2s' |
4028 4086 | |
4029 4087 | # STEP 1: Time average with mstransform, then flagging with normal tfcrop |
4030 4088 | mstransform(vis=self.vis, outputvis='test_tfcrop_timeavg_extendflags_step1.ms', |
4031 4089 | datacolumn='data', timeaverage=True, timebin=timebin) |
4032 4090 | flagdata(vis='test_tfcrop_timeavg_extendflags_step1.ms', flagbackup=False, |
4033 4091 | mode='tfcrop', extendflags=True) |
4034 4092 | res1 = flagdata(vis='test_tfcrop_timeavg_extendflags_step1.ms', mode='summary') |
4035 4093 | |
4038 4096 | |
4039 4097 | # STEP 2: Flagging with tfcrop using time average, then time average with mstransform |
4040 4098 | flagdata(vis=self.vis, flagbackup=False, mode='tfcrop', datacolumn='DATA', |
4041 4099 | timeavg=True, timebin=timebin, extendflags=True) |
4042 4100 | mstransform(vis=self.vis,outputvis='test_tfcrop_timeavg_extendflags_step2.ms', |
4043 4101 | datacolumn='data', timeaverage=True, timebin='2s') |
4044 4102 | res2 = flagdata(vis='test_tfcrop_timeavg_extendflags_step2.ms', mode='summary') |
4045 4103 | |
4046 4104 | # Check results |
4047 4105 | self.assertEqual(res1['total'], res2['total']) |
4106 + | self.assertEqual(res1['flagged'], res2['flagged']) |
4048 4107 | self.assertEqual(res1['flagged'], 96) |
4049 - | self.assertEqual(res2['flagged'], 128) |
4050 4108 | for cor in self.corrs: |
4051 4109 | self.assertEqual(res1['correlation'][cor]['flagged'], 24) |
4052 - | self.assertEqual(res2['correlation'][cor]['flagged'], 32) |
4110 + | self.assertEqual(res1['correlation'][cor]['flagged'], |
4111 + | res2['correlation'][cor]['flagged']) |
4053 4112 | |
4054 4113 | def test_tfcrop_chanavg(self): |
4055 4114 | '''flagdata: tfcrop with chan average and compare vs mstransform''' |
4056 4115 | |
4057 - | # Unflag the original input data |
4058 - | flagdata(self.vis, flagbackup=False, mode='unflag') |
4116 + | # Unflag the original input data - alread done by setUp |
4117 + | # flagdata(self.vis, flagbackup=False, mode='unflag') |
4059 4118 | |
4060 4119 | chanbin = 2 |
4061 4120 | |
4062 4121 | # STEP 1: Chan average with mstransform, then flagging with normal tfcrop |
4063 4122 | mstransform(vis=self.vis,outputvis='test_tfcrop_chanavg_step1.ms',datacolumn='data', |
4064 4123 | chanaverage=True,chanbin=2) |
4065 4124 | flagdata(vis='test_tfcrop_chanavg_step1.ms',flagbackup=False, mode='tfcrop', |
4066 4125 | extendflags=False) |
4067 4126 | res1 = flagdata(vis='test_tfcrop_chanavg_step1.ms', mode='summary', spwchan=True) |
4068 4127 | |
4078 4137 | |
4079 4138 | # Compare results |
4080 4139 | self.assertEqual(res1['flagged'], res2['flagged']) |
4081 4140 | for cor in self.corrs: |
4082 4141 | self.assertEqual(res2['correlation'][cor]['flagged'], |
4083 4142 | res1['correlation'][cor]['flagged']) |
4084 4143 | |
4085 4144 | def test_tfcrop_chanavg_extendflags(self): |
4086 4145 | '''flagdata: tfcrop with chan average + extendflags, and compare vs mstransform''' |
4087 4146 | |
4088 - | # Unflag the original input data |
4089 - | flagdata(self.vis, flagbackup=False, mode='unflag') |
4147 + | # Unflag the original input data - alread done by setUp |
4148 + | # flagdata(self.vis, flagbackup=False, mode='unflag') |
4090 4149 | |
4091 4150 | chanbin = 4 |
4092 4151 | |
4093 4152 | # STEP 1: Chan average with mstransform, then flagging with normal tfcrop |
4094 4153 | mstransform(vis=self.vis, outputvis='test_tfcrop_chanavg_extendflags_step1.ms', |
4095 4154 | datacolumn='data', chanaverage=True, chanbin=chanbin) |
4096 4155 | flagdata(vis='test_tfcrop_chanavg_extendflags_step1.ms', flagbackup=False, |
4097 4156 | mode='tfcrop', extendflags=True) |
4098 4157 | res1 = flagdata(vis='test_tfcrop_chanavg_extendflags_step1.ms', mode='summary') |
4099 4158 | |
4111 4170 | self.assertEqual(res1['total'], res2['total']) |
4112 4171 | self.assertEqual(res1['flagged'], res2['flagged']) |
4113 4172 | for cor in self.corrs: |
4114 4173 | self.assertEqual(res1['correlation'][cor]['flagged'], 8) |
4115 4174 | self.assertEqual(res2['correlation'][cor]['flagged'], |
4116 4175 | res1['correlation'][cor]['flagged']) |
4117 4176 | |
4118 4177 | def test_tfcrop_time_chanavg(self): |
4119 4178 | '''flagdata: tfcrop with time/chan average and compare vs mstransform''' |
4120 4179 | |
4121 - | # Unflag the original input data |
4122 - | flagdata(self.vis, flagbackup=False, mode='unflag') |
4123 - | |
4180 + | # Unflag the original input data - alread done by setUp |
4181 + | # flagdata(self.vis, flagbackup=False, mode='unflag') |
4182 + | |
4124 4183 | # STEP 1: Chan average with mstransform, then flagging with normal tfcrop |
4125 - | mstransform(vis=self.vis,outputvis='test_tfcrop_time_chanavg_step1.ms',datacolumn='data', |
4126 - | timeaverage=True,timebin='2s',chanaverage=True,chanbin=2) |
4127 - | flagdata(vis='test_tfcrop_time_chanavg_step1.ms',flagbackup=False, mode='tfcrop',extendflags=False) |
4184 + | mstransform(vis=self.vis,outputvis='test_tfcrop_time_chanavg_step1.ms', |
4185 + | datacolumn='data', timeaverage=True, timebin='2s', chanaverage=True, |
4186 + | chanbin=2) |
4187 + | flagdata(vis='test_tfcrop_time_chanavg_step1.ms',flagbackup=False, mode='tfcrop', |
4188 + | extendflags=False) |
4128 4189 | res1 = flagdata(vis='test_tfcrop_time_chanavg_step1.ms', mode='summary', spwchan=True) |
4129 4190 | |
4130 4191 | # Unflag the original input data |
4131 4192 | flagdata(vis=self.vis, flagbackup=False, mode='unflag') |
4132 4193 | |
4133 4194 | # STEP 2: Flagging with tfcrop using time average, then time average with mstransform |
4134 4195 | flagdata(vis=self.vis, flagbackup=False, mode='tfcrop', datacolumn='DATA', |
4135 4196 | timeavg=True, timebin='2s', channelavg=True, chanbin=2, extendflags=False) |
4136 4197 | mstransform(vis=self.vis, outputvis='test_tfcrop_time_chanavg_step2.ms',datacolumn='data', |
4137 4198 | timeaverage=True,timebin='2s',chanaverage=True,chanbin=2) |
4138 4199 | res2 = flagdata(vis='test_tfcrop_time_chanavg_step2.ms', mode='summary', spwchan=True) |
4139 4200 | |
4140 4201 | # Compare results |
4141 4202 | self.assertEqual(res2['flagged'], res2['flagged']) |
4203 + | for cor in self.corrs: |
4204 + | self.assertEqual(res2['correlation'][cor]['flagged'], |
4205 + | res1['correlation'][cor]['flagged']) |
4142 4206 | |
4143 4207 | |
4144 4208 | # Motivated by CAS-11397. test_preaveraging is about datacolumn='data', and checks what |
4145 4209 | # flags are written to the output |
4146 4210 | # test_preaveraging_rflag_residual is about datacolumn='residual' and doesn't write flags. It |
4147 4211 | # checks the threshold calculations from RFlag |
4148 4212 | class test_preaveraging_rflag_residual(test_base): |
4149 4213 | """Test pre-averaging (channel / time) with RFlag and datacolumn='residual'""" |
4150 4214 | |
4151 4215 | def setUp(self): |
4308 4372 | # Run setjy to create a normal MODEl column (SOURCE_MODEL) |
4309 4373 | setjy(vis=self.vis, field='1331+305*',modimage='',standard='Perley-Taylor 99', |
4310 4374 | scalebychan=False, usescratch=True) |
4311 4375 | |
4312 4376 | flagdata(vis=self.vis,mode='clip',datacolumn='RESIDUAL_DATA',clipminmax=[2.3,3.1],clipoutside=False) |
4313 4377 | res = flagdata(vis=self.vis, mode='summary')['flagged'] |
4314 4378 | |
4315 4379 | self.assertEqual(res_virtual, res, 'Flagging using virtual MODEL column differs from normal MODEL column') |
4316 4380 | |
4317 4381 | |
4382 + | class test_flags_propagation_base(test_base): |
4383 + | """ |
4384 + | Common methods and infrastructure used in test_flags_propagation_channelavg and |
4385 + | test_flags_propagation_timeavg. |
4386 + | """ |
4387 + | |
4388 + | def tearDown(self): |
4389 + | shutil.rmtree(self.vis) |
4390 + | |
4391 + | def get_flags(self, mss): |
4392 + | """ |
4393 + | Returns the flags column of an MS. Use only on tiny MSs as the one used in this |
4394 + | test |
4395 + | |
4396 + | :param mss: An MS |
4397 + | :return: The FLAG column of the MS |
4398 + | """ |
4399 + | try: |
4400 + | tbt = table() |
4401 + | tbt.open(mss) |
4402 + | flags = tbt.getcol('FLAG') |
4403 + | return flags |
4404 + | finally: |
4405 + | tbt.close() |
4406 + | |
4407 + | def check_flags_preserved(self, flags_before, flags_after): |
4408 + | """ |
4409 + | Check 'flags before' against 'flags after' and ensures that all the flags set |
4410 + | 'before' are also set 'after'. |
4411 + | The flags are expected in the same format as returned by tbtool.getcol('FLAG'). |
4412 + | This is to ensure the desired behavior from CAS-12737 (never lose flags). |
4413 + | |
4414 + | :param before_flags: flags before manipulating/flagging an MS |
4415 + | :param after_flags: flags after manipulating/flagging an MS |
4416 + | :return: true if all flags set in flags_before are also set in flags_after |
4417 + | """ |
4418 + | flag_cnt_before = np.count_nonzero(flags_before) |
4419 + | and_flags = np.logical_and(flags_before, flags_after) |
4420 + | flag_cnt_and = np.count_nonzero(and_flags) |
4421 + | |
4422 + | if flag_cnt_and != flag_cnt_before: |
4423 + | print(' * Not all the flags set before ({}) are set after ({}). Flags before: ' |
4424 + | '{}\n Flags after: {}'.format(flag_cnt_before, flag_cnt_and, |
4425 + | flags_before, flags_after)) |
4426 + | return flag_cnt_and == flag_cnt_before |
4427 + | |
4428 + | |
4429 + | skipIf(False, | .
4430 + | "These tests were added in CAS-12737. Not clear what would be the right" |
4431 + | "place for them.") |
4432 + | class test_flags_propagation_channelavg(test_flags_propagation_base): |
4433 + | """ |
4434 + | Tests on the number and positions of flags when using |
4435 + | flagdata + channelavg + autoflag_methods AND the dataset is already flagged |
4436 + | ... where channelavg is implemented via the ChannelAverageTVI |
4437 + | This is to make sure that flags set before the flagdata command are preserved |
4438 + | (CAS-12737). The tests check the expected number of flags from several methods (clip, |
4439 + | tfcrop, rflag) and that all the data points originally flagged are still flagged after |
4440 + | applying, in the exact same positions. |
4441 + | |
4442 + | Uses the small VLA dataset from "data4preaveraging" which is convenient for visual |
4443 + | and/or manual inspection via the browser, table tool, etc. |
4444 + | |
4445 + | To illustrate the potential "loss" of flags before the fix from CAS-12737, the tests |
4446 + | use a range of chanbin values (~2...5) with intentionally sparse "a priori" flags like |
4447 + | X 0 X 0 X 0 X 0 (with chanbin=2 could produce a total loss of "a priori" flags) |
4448 + | or |
4449 + | X 0 0 X 0 0 X 0 0 (with chanbin=3 could produce a total loss of "a priori" flags) |
4450 + | ... |
4451 + | There are notes in the comments that give the final number of flags that would be seen |
4452 + | before the fix from CAS-12737 (much lower, lower than the original "a priori" flags). |
4453 + | """ |
4454 + | |
4455 + | def setUp(self): |
4456 + | self.setUp_data4preaveraging() |
4457 + | |
4458 + | def run_auto_flag_preavg_propagation(self, chanbin=2, mode='clip', ims='', **kwargs): |
4459 + | """ |
4460 + | Enables channel average and prepares a priori flags in a sparse pattern across |
4461 + | channels such that we can test (back)propagation of flags after channel-averaging. |
4462 + | One channel is flagged every 'chanbin' |
4463 + | With chanbin=2, 50% of channels will be a priori flagged (X 0 X 0 X 0...) |
4464 + | With chanbin-3, 33% of channels will be a priori flagged, and so on (X 0 0 X 0 0...) |
4465 + | This would maximize the "loss" of flags as seen in CAS-12737 |
4466 + | |
4467 + | :param chanbin: chanbin as used in flagdata |
4468 + | :param mode: auto-flag mode |
4469 + | :param kwargs: Use kwargs to pass mode specific parameters, such as clipminmax for |
4470 + | clip, etc. |
4471 + | :return: res+apriori_flags+final_flags. res is the flagdata summary dict from the |
4472 + | MS after applying flagging with channelavg. apriori_flags is the FLAG column before |
4473 + | applying channelavg+autoflag_method. final_flags is the FLAG column after applying |
4474 + | channelavg+autoflag_method. |
4475 + | """ |
4476 + | def get_nchan(ims): |
4477 + | """ |
4478 + | This function assumes single-SPW (as is the case in this test) or all SPWs |
4479 + | have the same number of channels. |
4480 + | |
4481 + | :param ims: an MS name |
4482 + | :return: number of channels in SPW(s) |
4483 + | """ |
4484 + | try: |
4485 + | tbt = table() |
4486 + | tbt.open(os.path.join(ims, 'SPECTRAL_WINDOW')) |
4487 + | chans = tbt.getcol('NUM_CHAN') |
4488 + | if len(chans) < 1: |
4489 + | raise RuntimeError('Inconsistency found, NUM_CHAN: {}'.format(chans)) |
4490 + | if not np.all(chans[0] == chans): |
4491 + | raise RuntimeError('This supports only MSs with all SPWs with the same ' |
4492 + | 'number of channels. Got NUM_CHAN: {}'.format(chans)) |
4493 + | nchan = chans[0] |
4494 + | except RuntimeError as exc: |
4495 + | raise RuntimeError('Error while trying to figure out the #channels: {}'. |
4496 + | format(exc)) |
4497 + | finally: |
4498 + | tbt.close() |
4499 + | |
4500 + | return nchan |
4501 + | |
4502 + | flagdata(vis=ims, mode='unflag') |
4503 + | |
4504 + | # Pre-flag channels, for example '*:0,1,2,4,...62' |
4505 + | nchan = get_nchan(ims) |
4506 + | flag_chans = np.arange(0, nchan, chanbin) |
4507 + | flag_spw_str = '*:{}'.format(';'.join(['{}'.format(chan) for chan in flag_chans])) |
4508 + | flagdata(vis=ims, mode='manual', spw=flag_spw_str) |
4509 + | |
4510 + | apriori_flags = self.get_flags(self.vis) |
4511 + | |
4512 + | res_avg = flagdata(vis=ims, mode=mode, channelavg=True, chanbin=chanbin, **kwargs) |
4513 + | |
4514 + | res = flagdata(vis=ims, mode='summary') |
4515 + | |
4516 + | final_flags = self.get_flags(self.vis) |
4517 + | |
4518 + | return res, apriori_flags, final_flags |
4519 + | |
4520 + | def test_propagation_clip_chanbin_2(self): |
4521 + | """ clip, chanavg, chanbin=2, propagate flags forth and back """ |
4522 + | |
4523 + | # Make clip flag something (if no flags are added, the flag cube is not written) |
4524 + | res, apriori_flags, final_flags =\ |
4525 + | self.run_auto_flag_preavg_propagation(chanbin=2, ims=self.vis, |
4526 + | clipminmax=[0.0, 0.1]) |
4527 + | |
4528 + | self.assertEqual(res['total'], 1024) |
4529 + | # Before CAS-12727, there is some 'loss' of flags. This would be: 44 |
4530 + | # Instead of >= 512 (a priori) |
4531 + | self.assertEqual(res['flagged'], 534) |
4532 + | self.assertTrue(self.check_flags_preserved(apriori_flags, final_flags), |
4533 + | 'Not all the flags set "before" are set "after"') |
4534 + | |
4535 + | def test_propagation_clip_chanbin_3(self): |
4536 + | """ clip, chanavg, chanbin=3, propagate flags forth and back """ |
4537 + | |
4538 + | # Make clip flag something (if no flags are added, the flag cube is not written) |
4539 + | res, apriori_flags, final_flags =\ |
4540 + | self.run_auto_flag_preavg_propagation(chanbin=3, ims=self.vis, |
4541 + | clipminmax=[0.001, 0.1]) |
4542 + | |
4543 + | self.assertEqual(res['total'], 1024) |
4544 + | # Before CAS-12727, there is some 'loss' of flags. This would be: 40 |
4545 + | # Instead of >= 352 (a priori) |
4546 + | self.assertEqual(res['flagged'], 368) |
4547 + | self.assertTrue(self.check_flags_preserved(apriori_flags, final_flags), |
4548 + | 'Not all the flags set "before" are set "after"') |
4549 + | |
4550 + | def test_propagation_tfcrop_chanbin_4(self): |
4551 + | """ tfcrop, chanavg, chanbin=4, propagate flags forth and back """ |
4552 + | |
4553 + | # Make tfcrop flag something (if no flags are added, the flag cube is not written) |
4554 + | res, apriori_flags, final_flags =\ |
4555 + | self.run_auto_flag_preavg_propagation(chanbin=4, ims=self.vis, |
4556 + | mode='tfcrop', extendflags=False) |
4557 + | |
4558 + | self.assertEqual(res['total'], 1024) |
4559 + | # Before CAS-12727, there is some 'loss' of flags. This would be: 68 |
4560 + | # Instead of >= 256 |
4561 + | self.assertEqual(res['flagged'], 307) |
4562 + | self.assertTrue(self.check_flags_preserved(apriori_flags, final_flags), |
4563 + | 'Not all the flags set "before" are set "after"') |
4564 + | |
4565 + | def test_propagation_rflag_chanbin_5(self): |
4566 + | """ rflag, chanavg, chanbin=2, propagate flags forth and back """ |
4567 + | |
4568 + | # Make rflag flag something (if no flags are added, the flag cube is not written) |
4569 + | res, apriori_flags, final_flags =\ |
4570 + | self.run_auto_flag_preavg_propagation(chanbin=5, ims=self.vis, |
4571 + | mode='rflag', extendflags=False) |
4572 + | |
4573 + | self.assertEqual(res['total'], 1024) |
4574 + | # Before CAS-12727, there is some 'loss' of flags. This would be: 35 |
4575 + | # Instead of >= 208 |
4576 + | self.assertEqual(res['flagged'], 236) |
4577 + | self.assertTrue(self.check_flags_preserved(apriori_flags, final_flags), |
4578 + | 'Not all the flags set "before" are set "after"') |
4579 + | |
4580 + | def test_propagation_clip_chanbin_64(self): |
4581 + | """ clip, chanavg, chanbin=64 (all), propagate flags forth and back """ |
4582 + | |
4583 + | # Make clip flag something (if no flags are added, the flag cube is not written) |
4584 + | # Use min=0.0025 to flag very little but still something |
4585 + | res, apriori_flags, final_flags =\ |
4586 + | self.run_auto_flag_preavg_propagation(chanbin=64, ims=self.vis, |
4587 + | clipminmax=[0.004, 0.1]) |
4588 + | |
4589 + | self.assertEqual(res['total'], 1024) |
4590 + | # Before CAS-12727, there is some 'loss' of flags. This would be: 196 |
4591 + | # (the total is >= 16 a priori, but losing some of the initial flags which would |
4592 + | # be overwritten as False). |
4593 + | self.assertEqual(res['flagged'], 205) |
4594 + | self.assertTrue(self.check_flags_preserved(apriori_flags, final_flags), |
4595 + | 'Not all the flags set "before" are set "after"') |
4596 + | |
4597 + | |
4598 + | skipIf(False, | .
4599 + | "These tests were added in CAS-12737. Not clear what would be the right" |
4600 + | "place for them.") |
4601 + | class test_flags_propagation_timeavg(test_flags_propagation_base): |
4602 + | """ |
4603 + | Tests on the number and positions of flags when using |
4604 + | flagdata + timeavg + autoflag_methods AND the dataset is already flagged |
4605 + | ... where timeavg is implemented via the AveragingTVI |
4606 + | This is to make sure that flags set before the flagdata command are preserved |
4607 + | (CAS-12737). Similarly as in the tests test_flags_propagation_timeavg, the tests of this |
4608 + | class check the expected number of flags from several methods (clip, tfcrop, rflag) and |
4609 + | that all the data points originally flagged are still flagged after applying, in the |
4610 + | exact same positions. |
4611 + | |
4612 + | Uses the small VLA dataset from "data4timeavg" which has enough integrations to test |
4613 + | a range of timebins |
4614 + | |
4615 + | To illustrate the potential "loss" of flags before the fix from CAS-12737, the tests |
4616 + | use a range of timebin values (2s...100s) with intentionally sparse "a priori" flags |
4617 + | like |
4618 + | X 0 X 0 X 0 X 0 (with timebin=2 could produce a total loss of "a priori" flags) |
4619 + | or |
4620 + | X 0 0 X 0 0 X 0 0 (with timebin=3 could produce a total loss of "a priori" flags) |
4621 + | ... |
4622 + | |
4623 + | There are notes in the comments that give the final number of flags that would be seen |
4624 + | before the fix from CAS-12737 (much lower, lower than the initial "a priori" flags). |
4625 + | """ |
4626 + | |
4627 + | def setUp(self): |
4628 + | self.setUp_data4timeavg() |
4629 + | |
4630 + | def run_auto_flag_preavg_propagation(self, timebin=2, mode='clip', ims='', **kwargs): |
4631 + | """ |
4632 + | Enables time average and prepares a priori flags in a sparse pattern through rows/ |
4633 + | time. The pattern is then used to test the (back)propagation of flags after |
4634 + | time-averaging. |
4635 + | One row or timestamp is flagged every 'timebin' where timebin is an integer flagging |
4636 + | step. |
4637 + | With timebin=2, 50% of timestamps will be flagged (X 0 X 0 X 0...) |
4638 + | With timebin-3, 33% of timestamps will be flagged (X 0 0 X 0 0...) and so on. |
4639 + | This pattern maximizes the "loss" of flags as seen in CAS-12737. |
4640 + | Uses the column 'TIME_CENTROID' (and the time reference from there) to find the list |
4641 + | of timestamps to flag. |
4642 + | |
4643 + | :param timebin: number of timestamps to average (in time) - does not check actual |
4644 + | integrations times |
4645 + | :param mode: one auto-flag mode |
4646 + | :param ims: input ms name |
4647 + | :param kwargs: to pass mode specific parameters, such as rflag thresholds, etc. |
4648 + | :return: res+apriori_flags+final_flags. res is the flagdata summary dict from the |
4649 + | MS after applying flagging with timeavg. apriori_flags is the FLAG column before |
4650 + | applying timeavg+autoflag_method. final_flags is the FLAG column after applying |
4651 + | timeavg+autoflag_method. |
4652 + | """ |
4653 + | |
4654 + | def get_unique_ms_times(ims): |
4655 + | """ |
4656 + | Get the list of unique time stamps of the MS (from TIME_CENTROID). |
4657 + | |
4658 + | :param: ims: an MS name |
4659 + | :return: list of unique times in the MS. Times as produced by the quanta tool. |
4660 + | """ |
4661 + | try: |
4662 + | tbt = table() |
4663 + | tbt.open(ims) |
4664 + | times = tbt.getcol('TIME_CENTROID') |
4665 + | |
4666 + | ref = tbt.getcolkeyword('TIME_CENTROID', 'MEASINFO')['Ref'] |
4667 + | except RuntimeError as exc: |
4668 + | pass |
4669 + | finally: |
4670 + | tbt.close() |
4671 + | |
4672 + | centroids = np.unique(times) |
4673 + | # Produce time records ready for flagdata. |
4674 + | # This could be done without measures tool: |
4675 + | # times = [qat.time({'unit': 's', 'value': cent, 'refer': ref, # 'UTC' |
4676 + | # 'type': 'epoch'}, |
4677 + | # form=['ymd'], prec=9)[0] |
4678 + | # for cent in centroids] |
4679 + | # Or even with plain string formatting: |
4680 + | # times = [time.strftime('%Y/%m/%d/%H:%M:%S.%f', |
4681 + | # time.gmtime(cent)) for cent in centroids] |
4682 + | # But better to produce times with the measures tool and using MEASINFO: |
4683 + | qat = quanta() |
4684 + | met = measures() |
4685 + | times = [qat.time(met.epoch('ref', '{}s'.format(cent))['m0'], form=['ymd'], |
4686 + | prec=9)[0] |
4687 + | for cent in centroids] |
4688 + | return times |
4689 + | |
4690 + | flagdata(vis=ims, mode='unflag') |
4691 + | |
4692 + | # Pre-flag some timestamps, at 'timebin' steps |
4693 + | times = get_unique_ms_times(ims) |
4694 + | flag_times = ['timerange={}'.format(one) for one in times[0::timebin]] |
4695 + | |
4696 + | flagdata(vis=ims, mode='list', inpfile=flag_times) |
4697 + | |
4698 + | apriori_flags = self.get_flags(self.vis) |
4699 + | |
4700 + | res_avg = flagdata(vis=ims, mode=mode, timeavg=True, timebin='{}s'. |
4701 + | format(timebin), **kwargs) |
4702 + | |
4703 + | res = flagdata(vis=ims, mode='summary') |
4704 + | |
4705 + | final_flags = self.get_flags(self.vis) |
4706 + | |
4707 + | return res, apriori_flags, final_flags |
4708 + | |
4709 + | def test_propagation_clip_timebin_2s(self): |
4710 + | """ clip, timeavg, timebin=2, propagate flags forth and back """ |
4711 + | |
4712 + | # Make clip flag something (if no flags are added, the flag cube is not written) |
4713 + | res, apriori_flags, final_flags =\ |
4714 + | self.run_auto_flag_preavg_propagation(timebin=2, ims=self.vis, |
4715 + | clipminmax=[0.0, 0.1]) |
4716 + | |
4717 + | self.assertEqual(res['total'], 25600) |
4718 + | # Before CAS-12727, there is some 'loss' of flags. This would be: 1490 |
4719 + | self.assertEqual(res['flagged'], 10311) |
4720 + | self.assertTrue(self.check_flags_preserved(apriori_flags, final_flags), |
4721 + | 'Not all the flags set "before" are set "after"') |
4722 + | |
4723 + | def test_propagation_clip_timebin_5s(self): |
4724 + | """ clip, timeavg, timebin=5, propagate flags forth and back """ |
4725 + | |
4726 + | # Make clip flag something (if no flags are added, the flag cube is not written) |
4727 + | res, apriori_flags, final_flags =\ |
4728 + | self.run_auto_flag_preavg_propagation(timebin=5, ims=self.vis, |
4729 + | clipminmax=[0.001, 0.1]) |
4730 + | |
4731 + | self.assertEqual(res['total'], 25600) |
4732 + | # Before CAS-12727, there is some 'loss' of flags. This would be: 1339 |
4733 + | self.assertEqual(res['flagged'], 5140) |
4734 + | self.assertTrue(self.check_flags_preserved(apriori_flags, final_flags), |
4735 + | 'Not all the flags set "before" are set "after"') |
4736 + | |
4737 + | def test_propagation_tfcrop_timebin_20(self): |
4738 + | """ tfcrop, timeavg, timebin=20, propagate flags forth and back """ |
4739 + | |
4740 + | res, apriori_flags, final_flags =\ |
4741 + | self.run_auto_flag_preavg_propagation(timebin=20, ims=self.vis, |
4742 + | mode='tfcrop', extendflags=False) |
4743 + | |
4744 + | self.assertEqual(res['total'], 25600) |
4745 + | # Before CAS-12727, there is some 'loss' of flags. This would be: 68 |
4746 + | # Instead of >= 1280 (= 5 rows x 4 pol x 64 chan) |
4747 + | self.assertEqual(res['flagged'], 2905) |
4748 + | self.assertTrue(self.check_flags_preserved(apriori_flags, final_flags), |
4749 + | 'Not all the flags set "before" are set "after"') |
4750 + | |
4751 + | def test_propagation_rflag_timebin_20(self): |
4752 + | """ rflag, timeavg, timebin=20, propagate flags forth and back """ |
4753 + | |
4754 + | res, apriori_flags, final_flags =\ |
4755 + | self.run_auto_flag_preavg_propagation(timebin=20, ims=self.vis, |
4756 + | mode='rflag', extendflags=False) |
4757 + | |
4758 + | self.assertEqual(res['total'], 25600) |
4759 + | # Before CAS-12727, there is some 'loss' of flags. This would be: 756 |
4760 + | # Instead of >= 1280 |
4761 + | self.assertEqual(res['flagged'], 3586) |
4762 + | self.assertTrue(self.check_flags_preserved(apriori_flags, final_flags), |
4763 + | 'Not all the flags set "before" are set "after"') |
4764 + | |
4765 + | def test_propagation_clip_timebin_100s(self): |
4766 + | """ clip, timeavg, timebin=100, propagate flags forth and back """ |
4767 + | |
4768 + | # Make clip flag something (if no flags are added, the flag cube is not written) |
4769 + | res, apriori_flags, final_flags =\ |
4770 + | self.run_auto_flag_preavg_propagation(timebin=100, ims=self.vis, |
4771 + | clipminmax=[0.001, 0.1]) |
4772 + | |
4773 + | self.assertEqual(res['total'], 25600) |
4774 + | # Before CAS-12727, there is some 'loss' of flags. This would be: 1339 |
4775 + | self.assertEqual(res['flagged'], 1609) |
4776 + | self.assertTrue(self.check_flags_preserved(apriori_flags, final_flags), |
4777 + | 'Not all the flags set "before" are set "after"') |
4778 + | |
4779 + | |
4318 4780 | class test_forbid_avg_in_non_autoflagging_list(test_base): |
4319 4781 | """ |
4320 4782 | CAS-12294: forbid the use of timeavg or chanavg in methods other than the |
4321 4783 | auto-flagging methods (clip, tfcrop, rflag) when given inside the list of |
4322 4784 | commands in list mode. |
4323 4785 | """ |
4324 4786 | |
4325 4787 | def setUp(self): |
4326 4788 | self.setUp_data4tfcrop() |
4327 4789 | |
4627 5089 | test_tsys, |
4628 5090 | test_bandpass, |
4629 5091 | test_newcal, |
4630 5092 | test_weight_spectrum, |
4631 5093 | test_float_column, |
4632 5094 | test_tbuff, |
4633 5095 | TestMergeManualTimerange, |
4634 5096 | test_preaveraging, |
4635 5097 | test_preaveraging_rflag_residual, |
4636 5098 | test_virtual_col, |
5099 + | test_flags_propagation_channelavg, |
5100 + | test_flags_propagation_timeavg, |
4637 5101 | test_forbid_avg_in_non_autoflagging_list, |
4638 5102 | test_list_modes_forbidden_with_avg, |
4639 5103 | test_auto_methods_display, |
4640 5104 | cleanup] |
4641 5105 | |
4642 5106 | if is_CASA6: |
4643 5107 | if __name__ == '__main__': |
4644 5108 | unittest.main() |