xradio 0.0.31__py3-none-any.whl → 0.0.34__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. xradio/_utils/list_and_array.py +5 -3
  2. xradio/vis/__init__.py +3 -5
  3. xradio/vis/_processing_set.py +3 -3
  4. xradio/vis/_vis_utils/_ms/_tables/load_main_table.py +4 -4
  5. xradio/vis/_vis_utils/_ms/_tables/read.py +57 -41
  6. xradio/vis/_vis_utils/_ms/_tables/read_main_table.py +17 -18
  7. xradio/vis/_vis_utils/_ms/_tables/read_subtables.py +5 -5
  8. xradio/vis/_vis_utils/_ms/_tables/write.py +2 -4
  9. xradio/vis/_vis_utils/_ms/_tables/write_exp_api.py +19 -13
  10. xradio/vis/_vis_utils/_ms/chunks.py +5 -72
  11. xradio/vis/_vis_utils/_ms/conversion.py +238 -55
  12. xradio/vis/_vis_utils/_ms/{_tables/create_field_and_source_xds.py → create_field_and_source_xds.py} +114 -85
  13. xradio/vis/_vis_utils/_ms/descr.py +8 -8
  14. xradio/vis/_vis_utils/_ms/msv4_sub_xdss.py +249 -77
  15. xradio/vis/_vis_utils/_ms/partition_queries.py +19 -185
  16. xradio/vis/_vis_utils/_ms/partitions.py +18 -22
  17. xradio/vis/_vis_utils/_ms/subtables.py +2 -2
  18. xradio/vis/_vis_utils/_utils/partition_attrs.py +2 -2
  19. xradio/vis/_vis_utils/_utils/xds_helper.py +12 -12
  20. xradio/vis/_vis_utils/ms.py +1 -43
  21. xradio/vis/_vis_utils/zarr.py +0 -1
  22. xradio/vis/convert_msv2_to_processing_set.py +8 -1
  23. xradio/vis/load_processing_set.py +0 -3
  24. xradio/vis/read_processing_set.py +2 -2
  25. {xradio-0.0.31.dist-info → xradio-0.0.34.dist-info}/METADATA +1 -1
  26. {xradio-0.0.31.dist-info → xradio-0.0.34.dist-info}/RECORD +29 -31
  27. {xradio-0.0.31.dist-info → xradio-0.0.34.dist-info}/WHEEL +1 -1
  28. xradio/vis/_vis_utils/ms_column_descriptions_dicts.py +0 -1360
  29. xradio/vis/vis_io.py +0 -146
  30. {xradio-0.0.31.dist-info → xradio-0.0.34.dist-info}/LICENSE.txt +0 -0
  31. {xradio-0.0.31.dist-info → xradio-0.0.34.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,4 @@
1
1
  import numcodecs
2
- import math
3
2
  import time
4
3
  from .._zarr.encoding import add_encoding
5
4
  from typing import Dict, Union
@@ -11,7 +10,7 @@ import xarray as xr
11
10
 
12
11
  from casacore import tables
13
12
  from .msv4_sub_xdss import create_ant_xds, create_pointing_xds, create_weather_xds
14
- from xradio.vis._vis_utils._ms._tables.create_field_and_source_xds import (
13
+ from xradio.vis._vis_utils._ms.create_field_and_source_xds import (
15
14
  create_field_and_source_xds,
16
15
  )
17
16
  from .msv2_to_msv4_meta import (
@@ -27,7 +26,7 @@ from ._tables.read import (
27
26
  convert_casacore_time,
28
27
  extract_table_attributes,
29
28
  read_col_conversion,
30
- read_generic_table,
29
+ load_generic_table,
31
30
  )
32
31
  from ._tables.read_main_table import get_baselines, get_baseline_indices, get_utimes_tol
33
32
  from .._utils.stokes_types import stokes_types
@@ -215,7 +214,7 @@ def mem_chunksize_to_dict_main_balanced(
215
214
 
216
215
  # Iterate through the dims, starting from the dims with lower chunk size
217
216
  # (=bigger impact of a +1)
218
- # Note the use of math.floor, this iteration can either increase or decrease sizes,
217
+ # Note the use of np.floor, this iteration can either increase or decrease sizes,
219
218
  # if increasing sizes we want to keep mem use below the upper limit, floor(2.3) = +2
220
219
  # if decreasing sizes we want to take mem use below the upper limit, floor(-2.3) = -3
221
220
  indices = np.argsort(dim_chunksizes[free_dims_mask])
@@ -411,27 +410,27 @@ def create_coordinates(
411
410
  "baseline_id": np.arange(len(baseline_ant1_id)),
412
411
  }
413
412
 
414
- ddi_xds = read_generic_table(in_file, "DATA_DESCRIPTION").sel(row=ddi)
415
- pol_setup_id = ddi_xds.polarization_id.values
416
- spectral_window_id = int(ddi_xds.spectral_window_id.values)
413
+ ddi_xds = load_generic_table(in_file, "DATA_DESCRIPTION").sel(row=ddi)
414
+ pol_setup_id = ddi_xds.POLARIZATION_ID.values
415
+ spectral_window_id = int(ddi_xds.SPECTRAL_WINDOW_ID.values)
417
416
 
418
- spectral_window_xds = read_generic_table(
417
+ spectral_window_xds = load_generic_table(
419
418
  in_file,
420
419
  "SPECTRAL_WINDOW",
421
420
  rename_ids=subt_rename_ids["SPECTRAL_WINDOW"],
422
421
  ).sel(spectral_window_id=spectral_window_id)
423
- coords["frequency"] = spectral_window_xds["chan_freq"].data[
424
- ~(np.isnan(spectral_window_xds["chan_freq"].data))
422
+ coords["frequency"] = spectral_window_xds["CHAN_FREQ"].data[
423
+ ~(np.isnan(spectral_window_xds["CHAN_FREQ"].data))
425
424
  ]
426
425
 
427
- pol_xds = read_generic_table(
426
+ pol_xds = load_generic_table(
428
427
  in_file,
429
428
  "POLARIZATION",
430
429
  rename_ids=subt_rename_ids["POLARIZATION"],
431
430
  )
432
- num_corr = int(pol_xds["num_corr"][pol_setup_id].values)
431
+ num_corr = int(pol_xds["NUM_CORR"][pol_setup_id].values)
433
432
  coords["polarization"] = np.vectorize(stokes_types.get)(
434
- pol_xds["corr_type"][pol_setup_id, :num_corr].values
433
+ pol_xds["CORR_TYPE"][pol_setup_id, :num_corr].values
435
434
  )
436
435
 
437
436
  xds = xds.assign_coords(coords)
@@ -443,18 +442,25 @@ def create_coordinates(
443
442
 
444
443
  msv4_measure = column_description_casacore_to_msv4_measure(
445
444
  freq_column_description["CHAN_FREQ"],
446
- ref_code=spectral_window_xds["meas_freq_ref"].data,
445
+ ref_code=spectral_window_xds["MEAS_FREQ_REF"].data,
447
446
  )
448
447
  xds.frequency.attrs.update(msv4_measure)
449
448
 
450
- xds.frequency.attrs["spectral_window_name"] = str(spectral_window_xds.name.values)
449
+ if (spectral_window_xds.NAME.values.item() is None) or (
450
+ spectral_window_xds.NAME.values.item() == "none"
451
+ ):
452
+ spw_name = "spw_" + str(spectral_window_id)
453
+ else:
454
+ spw_name = spectral_window_xds.NAME.values.item()
455
+
456
+ xds.frequency.attrs["spectral_window_name"] = spw_name
451
457
  msv4_measure = column_description_casacore_to_msv4_measure(
452
458
  freq_column_description["REF_FREQUENCY"],
453
- ref_code=spectral_window_xds["meas_freq_ref"].data,
459
+ ref_code=spectral_window_xds["MEAS_FREQ_REF"].data,
454
460
  )
455
461
  xds.frequency.attrs["reference_frequency"] = {
456
462
  "dims": [],
457
- "data": float(spectral_window_xds.ref_frequency.values),
463
+ "data": float(spectral_window_xds.REF_FREQUENCY.values),
458
464
  "attrs": msv4_measure,
459
465
  }
460
466
  xds.frequency.attrs["spectral_window_id"] = spectral_window_id
@@ -465,8 +471,8 @@ def create_coordinates(
465
471
  # xds.frequency.attrs["doppler_type"] =
466
472
 
467
473
  unique_chan_width = unique_1d(
468
- spectral_window_xds.chan_width.data[
469
- np.logical_not(np.isnan(spectral_window_xds.chan_width.data))
474
+ spectral_window_xds["CHAN_WIDTH"].data[
475
+ np.logical_not(np.isnan(spectral_window_xds["CHAN_WIDTH"].data))
470
476
  ]
471
477
  )
472
478
  # assert len(unique_chan_width) == 1, "Channel width varies for spectral_window."
@@ -475,7 +481,7 @@ def create_coordinates(
475
481
  # ] # unique_chan_width[0]
476
482
  msv4_measure = column_description_casacore_to_msv4_measure(
477
483
  freq_column_description["CHAN_WIDTH"],
478
- ref_code=spectral_window_xds["meas_freq_ref"].data,
484
+ ref_code=spectral_window_xds["MEAS_FREQ_REF"].data,
479
485
  )
480
486
  if not msv4_measure:
481
487
  msv4_measure["type"] = "quantity"
@@ -538,7 +544,7 @@ def find_min_max_times(tb_tool: tables.table, taql_where: str) -> tuple:
538
544
 
539
545
 
540
546
  def create_data_variables(
541
- in_file, xds, tb_tool, time_baseline_shape, tidxs, bidxs, didxs
547
+ in_file, xds, tb_tool, time_baseline_shape, tidxs, bidxs, didxs, use_table_iter
542
548
  ):
543
549
  # Create Data Variables
544
550
  col_names = tb_tool.colnames()
@@ -552,20 +558,16 @@ def create_data_variables(
552
558
  try:
553
559
  start = time.time()
554
560
  if col == "WEIGHT":
555
- xds[col_to_data_variable_names[col]] = xr.DataArray(
556
- np.tile(
557
- read_col_conversion(
558
- tb_tool,
559
- col,
560
- time_baseline_shape,
561
- tidxs,
562
- bidxs,
563
- )[:, :, None, :],
564
- (1, 1, xds.sizes["frequency"], 1),
565
- ),
566
- dims=col_dims[col],
561
+ xds = get_weight(
562
+ xds,
563
+ col,
564
+ tb_tool,
565
+ time_baseline_shape,
566
+ tidxs,
567
+ bidxs,
568
+ use_table_iter,
569
+ main_column_descriptions,
567
570
  )
568
-
569
571
  else:
570
572
  xds[col_to_data_variable_names[col]] = xr.DataArray(
571
573
  read_col_conversion(
@@ -574,28 +576,71 @@ def create_data_variables(
574
576
  time_baseline_shape,
575
577
  tidxs,
576
578
  bidxs,
579
+ use_table_iter,
577
580
  ),
578
581
  dims=col_dims[col],
579
582
  )
580
- logger.debug(
581
- "Time to read column "
582
- + str(col)
583
- + " : "
584
- + str(time.time() - start)
585
- )
583
+
584
+ xds[col_to_data_variable_names[col]].attrs.update(
585
+ create_attribute_metadata(col, main_column_descriptions)
586
+ )
587
+
588
+ logger.debug(
589
+ "Time to read column " + str(col) + " : " + str(time.time() - start)
590
+ )
586
591
  except:
587
- # logger.debug("Could not load column",col)
588
- # print("Could not load column", col)
589
- continue
592
+ logger.debug("Could not load column", col)
593
+
594
+ if ("WEIGHT_SPECTRUM" == col) and (
595
+ "WEIGHT" in col_names
596
+ ): # Bogus WEIGHT_SPECTRUM column, need to use WEIGHT.
597
+ xds = get_weight(
598
+ xds,
599
+ "WEIGHT",
600
+ tb_tool,
601
+ time_baseline_shape,
602
+ tidxs,
603
+ bidxs,
604
+ use_table_iter,
605
+ main_column_descriptions,
606
+ )
590
607
 
591
- xds[col_to_data_variable_names[col]].attrs.update(
592
- create_attribute_metadata(col, main_column_descriptions)
593
- )
608
+
609
+ def get_weight(
610
+ xds,
611
+ col,
612
+ tb_tool,
613
+ time_baseline_shape,
614
+ tidxs,
615
+ bidxs,
616
+ use_table_iter,
617
+ main_column_descriptions,
618
+ ):
619
+ xds[col_to_data_variable_names[col]] = xr.DataArray(
620
+ np.tile(
621
+ read_col_conversion(
622
+ tb_tool,
623
+ col,
624
+ time_baseline_shape,
625
+ tidxs,
626
+ bidxs,
627
+ use_table_iter,
628
+ )[:, :, None, :],
629
+ (1, 1, xds.sizes["frequency"], 1),
630
+ ),
631
+ dims=col_dims[col],
632
+ )
633
+
634
+ xds[col_to_data_variable_names[col]].attrs.update(
635
+ create_attribute_metadata(col, main_column_descriptions)
636
+ )
637
+ return xds
594
638
 
595
639
 
596
640
  def create_taql_query(partition_info):
597
641
  main_par_table_cols = [
598
642
  "DATA_DESC_ID",
643
+ "OBSERVATION_ID",
599
644
  "STATE_ID",
600
645
  "FIELD_ID",
601
646
  "SCAN_NUMBER",
@@ -619,6 +664,7 @@ def convert_and_write_partition(
619
664
  out_file: str,
620
665
  ms_v4_id: int,
621
666
  partition_info: Dict,
667
+ use_table_iter: bool,
622
668
  partition_scheme: str = "ddi_intent_field",
623
669
  main_chunksize: Union[Dict, float, None] = None,
624
670
  with_pointing: bool = True,
@@ -669,6 +715,7 @@ def convert_and_write_partition(
669
715
  """
670
716
 
671
717
  taql_where = create_taql_query(partition_info)
718
+ # print("taql_where", taql_where)
672
719
  ddi = partition_info["DATA_DESC_ID"][0]
673
720
  obs_mode = str(partition_info["OBS_MODE"][0])
674
721
 
@@ -694,6 +741,26 @@ def convert_and_write_partition(
694
741
  time_baseline_shape = (len(utime), len(baseline_ant1_id))
695
742
  logger.debug("Calc indx for row split " + str(time.time() - start))
696
743
 
744
+ observation_id = check_if_consistent(
745
+ tb_tool.getcol("OBSERVATION_ID"), "OBSERVATION_ID"
746
+ )
747
+
748
+ def get_observation_info(in_file, observation_id, obs_mode):
749
+ generic_observation_xds = load_generic_table(
750
+ in_file,
751
+ "OBSERVATION",
752
+ taql_where=f" where (ROWID() IN [{str(observation_id)}])",
753
+ )
754
+
755
+ if obs_mode == "None":
756
+ obs_mode = "obs_" + str(observation_id)
757
+
758
+ return generic_observation_xds["TELESCOPE_NAME"].values[0], obs_mode
759
+
760
+ telescope_name, obs_mode = get_observation_info(
761
+ in_file, observation_id, obs_mode
762
+ )
763
+
697
764
  start = time.time()
698
765
  xds = xr.Dataset()
699
766
  # interval = check_if_consistent(tb_tool.getcol("INTERVAL"), "INTERVAL")
@@ -715,13 +782,62 @@ def convert_and_write_partition(
715
782
 
716
783
  start = time.time()
717
784
  create_data_variables(
718
- in_file, xds, tb_tool, time_baseline_shape, tidxs, bidxs, didxs
785
+ in_file,
786
+ xds,
787
+ tb_tool,
788
+ time_baseline_shape,
789
+ tidxs,
790
+ bidxs,
791
+ didxs,
792
+ use_table_iter,
719
793
  )
794
+
795
+ # Add data_groups and field_info
796
+ xds, is_single_dish = add_data_groups(xds)
797
+
798
+ if (
799
+ "WEIGHT" not in xds.data_vars
800
+ ): # Some single dish datasets don't have WEIGHT.
801
+ if is_single_dish:
802
+ xds["WEIGHT"] = xr.DataArray(
803
+ np.ones(xds.SPECTRUM.shape, dtype=np.float64),
804
+ dims=xds.SPECTRUM.dims,
805
+ )
806
+ else:
807
+ xds["WEIGHT"] = xr.DataArray(
808
+ np.ones(xds.VISIBILITY.shape, dtype=np.float64),
809
+ dims=xds.VISIBILITY.dims,
810
+ )
811
+
720
812
  logger.debug("Time create data variables " + str(time.time() - start))
721
813
 
722
814
  # Create ant_xds
723
815
  start = time.time()
724
- ant_xds = create_ant_xds(in_file)
816
+ feed_id = unique_1d(
817
+ np.concatenate(
818
+ [
819
+ unique_1d(tb_tool.getcol("FEED1")),
820
+ unique_1d(tb_tool.getcol("FEED2")),
821
+ ]
822
+ )
823
+ )
824
+ antenna_id = unique_1d(
825
+ np.concatenate(
826
+ [xds["baseline_antenna1_id"].data, xds["baseline_antenna2_id"].data]
827
+ )
828
+ )
829
+
830
+ ant_xds = create_ant_xds(
831
+ in_file,
832
+ xds.frequency.attrs["spectral_window_id"],
833
+ antenna_id,
834
+ feed_id,
835
+ telescope_name,
836
+ )
837
+
838
+ # Change antenna_ids to antenna_names
839
+ xds = antenna_ids_to_names(xds, ant_xds)
840
+
725
841
  logger.debug("Time ant xds " + str(time.time() - start))
726
842
 
727
843
  # Create weather_xds
@@ -761,9 +877,6 @@ def convert_and_write_partition(
761
877
  if len(xds.time) > 1 and xds.time[1] - xds.time[0] < 0:
762
878
  xds = xds.sel(time=slice(None, None, -1))
763
879
 
764
- # Add data_groups and field_info
765
- xds, is_single_dish = add_data_groups(xds)
766
-
767
880
  # Create field_and_source_xds (combines field, source and ephemeris data into one super dataset)
768
881
  start = time.time()
769
882
  if ephemeris_interpolate:
@@ -828,13 +941,13 @@ def convert_and_write_partition(
828
941
  )
829
942
 
830
943
  xds.attrs["partition_info"] = {
831
- "spectral_window_id": xds.frequency.attrs["spectral_window_id"],
944
+ # "spectral_window_id": xds.frequency.attrs["spectral_window_id"],
832
945
  "spectral_window_name": xds.frequency.attrs["spectral_window_name"],
833
- "field_id": to_list(unique_1d(field_id)),
946
+ # "field_id": to_list(unique_1d(field_id)),
834
947
  "field_name": to_list(
835
948
  np.unique(field_and_source_xds.field_name.values)
836
949
  ),
837
- "source_id": to_list(unique_1d(source_id)),
950
+ # "source_id": to_list(unique_1d(source_id)),
838
951
  "source_name": to_list(
839
952
  np.unique(field_and_source_xds.source_name.values)
840
953
  ),
@@ -856,7 +969,9 @@ def convert_and_write_partition(
856
969
  )
857
970
 
858
971
  if with_pointing:
859
- pointing_xds.to_zarr(store=file_name + "/POINTING", mode=mode)
972
+ pointing_xds.to_zarr(
973
+ store=os.path.join(file_name, "POINTING"), mode=mode
974
+ )
860
975
 
861
976
  if weather_xds:
862
977
  weather_xds.to_zarr(
@@ -871,6 +986,74 @@ def convert_and_write_partition(
871
986
  # logger.info("Saved ms_v4 " + file_name + " in " + str(time.time() - start_with) + "s")
872
987
 
873
988
 
989
+ def antenna_ids_to_names(xds, ant_xds):
990
+
991
+ if ant_xds.attrs["overall_telescope_name"] in ["ALMA", "VLA", "NOEMA", "EVLA"]:
992
+ moving_antennas = True
993
+ else:
994
+ moving_antennas = False
995
+
996
+ if moving_antennas:
997
+ if "baseline_antenna1_id" in xds: # Interferometer
998
+
999
+ baseline_ant1_name = np.core.defchararray.add(
1000
+ ant_xds["name"].sel(antenna_id=xds["baseline_antenna1_id"]).values, "_"
1001
+ )
1002
+ baseline_ant1_name = np.core.defchararray.add(
1003
+ baseline_ant1_name,
1004
+ ant_xds["station"].sel(antenna_id=xds["baseline_antenna1_id"]).values,
1005
+ )
1006
+ baseline_ant2_name = np.core.defchararray.add(
1007
+ ant_xds["name"].sel(antenna_id=xds["baseline_antenna2_id"]).values, "_"
1008
+ )
1009
+ baseline_ant2_name = np.core.defchararray.add(
1010
+ baseline_ant2_name,
1011
+ ant_xds["station"].sel(antenna_id=xds["baseline_antenna2_id"]).values,
1012
+ )
1013
+
1014
+ xds["baseline_antenna1_id"] = xr.DataArray(
1015
+ baseline_ant1_name, dims="baseline_id"
1016
+ )
1017
+ xds["baseline_antenna2_id"] = xr.DataArray(
1018
+ baseline_ant2_name, dims="baseline_id"
1019
+ )
1020
+ xds = xds.rename(
1021
+ {
1022
+ "baseline_antenna1_id": "baseline_antenna1_name",
1023
+ "baseline_antenna2_id": "baseline_antenna2_name",
1024
+ }
1025
+ )
1026
+ else: # Single Dish
1027
+ antenna_name = np.core.defchararray.add(
1028
+ ant_xds["name"].sel(antenna_id=xds["antenna_id"]).values, "_"
1029
+ )
1030
+ antenna_name = np.core.defchararray.add(
1031
+ antenna_name,
1032
+ ant_xds["station"].sel(antenna_id=xds["antenna_id"]).values,
1033
+ )
1034
+ xds["antenna_id"] = xr.DataArray(antenna_name, dims="baseline_id")
1035
+ xds = xds.rename({"antenna_id": "antenna_name"})
1036
+ else:
1037
+ if "baseline_antenna1_id" in xds: # Interferometer
1038
+ xds["baseline_antenna1_id"] = ant_xds["name"].sel(
1039
+ antenna_id=xds["baseline_antenna1_id"]
1040
+ )
1041
+ xds["baseline_antenna2_id"] = ant_xds["name"].sel(
1042
+ antenna_id=xds["baseline_antenna2_id"]
1043
+ )
1044
+ xds = xds.rename(
1045
+ {
1046
+ "baseline_antenna1_id": "baseline_antenna1_name",
1047
+ "baseline_antenna2_id": "baseline_antenna2_name",
1048
+ }
1049
+ )
1050
+ else: # Single Dish
1051
+ xds["antenna_id"] = ant_xds["name"].sel(antenna_id=xds["antenna_id"])
1052
+ xds = xds.rename({"antenna_id": "antenna_name"})
1053
+
1054
+ return xds
1055
+
1056
+
874
1057
  def add_data_groups(xds):
875
1058
  xds.attrs["data_groups"] = {}
876
1059
  if "VISIBILITY" in xds: