xradio 0.0.34__py3-none-any.whl → 0.0.37__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.
xradio/vis/schema.py CHANGED
@@ -12,10 +12,16 @@ import numpy
12
12
  # Dimensions
13
13
  Time = Literal["time"]
14
14
  """ Observation time dimension """
15
- AntennaId = Literal["antenna_id"]
16
- """ Antenna ID dimension """
17
- ReceptorName = Literal["receptor_name"]
18
- """ Receptor name dimension """
15
+ AntennaName = Literal["antenna_name"]
16
+ """ Antenna name dimension """
17
+ StationId = Literal["station_id"]
18
+ """ Station ID dimension """
19
+ ReceptorId = Literal["receptor_id"]
20
+ """ Receptor ID dimension """
21
+ ReceptorLabel = Literal["receptor_label"]
22
+ """ Receptor label dimension """
23
+ ToneLabel = Literal["tone_label"]
24
+ """ Tone label dimension """
19
25
  BaselineId = Literal["baseline_id"]
20
26
  """ Baseline ID dimension """
21
27
  Frequency = Literal["frequency"]
@@ -24,40 +30,77 @@ Polarization = Literal["polarization"]
24
30
  """ Polarization dimension """
25
31
  UvwLabel = Literal["uvw_label"]
26
32
  """ Coordinate dimension of UVW data (typically shape 3 for 'u', 'v', 'w') """
27
- XyzLabel = Literal["xyz_label"]
28
- """ Coordinate dimension of earth location data (typically shape 3 and 'x', 'y', 'z')"""
33
+ SkyDirLabel = Literal["sky_dir_label"]
34
+ """ Coordinate labels of sky directions (typically shape 2 and 'ra', 'dec') """
35
+ SphericalDirLabel = Literal["spherical_dir_label"]
36
+ """ Coordinate labels of spherical directions (shape 2 and 'lon', 'lat1' """
37
+ SkyPosLabel = Literal["sky_pos_label"]
38
+ """ Coordinate labels of sky positions (typically shape 3 and 'ra', 'dec', 'dist') """
39
+ SphericalPosLabel = Literal["spherical_pos_label"]
40
+ """ Coordinate labels of spherical positions (shape shape 3 and 'lon', 'lat1', 'dist2') """
41
+ EllipsoidPosLabel = Literal["ellipsoid_pos_label"]
42
+ """ Coordinate labels of geodetic earth location data (typically shape 3 and 'lon', 'lat', 'height')"""
43
+ CartesianPosLabel = Literal["cartesian_pos_label"]
44
+ """ Coordinate labels of geocentric earth location data (typically shape 3 and 'x', 'y', 'z')"""
45
+ TimePhaseCal = Literal["time_phase_cal"]
46
+ """ Coordinate label for VLBI-specific phase cal time axis """
29
47
  TimePolynomial = Literal["time_polynomial"]
30
48
  """ For data that is represented as variable in time using Taylor expansion """
31
- SkyCoordLabel = Literal["sky_coord_label"]
32
- """ Unlabeled axis """
49
+ PolyTerm = Literal["poly_term"]
50
+ """ Polynomial term used in VLBI GAIN_CURVE """
51
+ LineLabel = Literal["line_label"]
52
+ """ Line labels (for line names and variables). """
33
53
 
54
+ # Represents "no dimension", i.e. used for coordinates and data variables with
55
+ # zero dimensions.
56
+ ZD = tuple[()]
34
57
 
35
- # Plain data class models
36
- @dict_schema
37
- class SourceInfoDict:
38
- # TODO
39
- pass
58
+ # Quantities
40
59
 
41
60
 
42
61
  @xarray_dataarray_schema
43
62
  class TimeArray:
44
- data: Data[Time, float]
63
+ """
64
+ Representation of a time quantity.
65
+
66
+ :py:class:`astropy.time.Time` serves as the reference implementation.
67
+ Data can be converted as follows::
68
+
69
+ astropy.time.Time(data * astropy.units.Unit(attrs['units'][0]),
70
+ format=attrs['format'], scale=attrs['scale'])
71
+
72
+ All formats that express time as floating point numbers since an epoch
73
+ are permissible, so at present the realistic options are:
74
+
75
+ * ``mjd`` (from 1858-11-17 00:00:00 UTC)
76
+ * ``unix`` (from 1970-01-01 00:00:00 UTC)
77
+ * ``unix_tai`` (from 1970-01-01 00:00:00 TAI)
78
+ * ``cxcsec`` (from 1998-01-01 00:00:00 TT)
79
+ * ``gps`` (from 1980-01-06 00:00:00 UTC)
80
+
81
+ """
82
+
83
+ data: Data[ZD, float]
84
+ """Time since epoch, typically in seconds (see ``units``)."""
45
85
 
46
86
  scale: Attr[str] = "tai"
47
- """Astropy time scales."""
48
- format: Attr[str] = "unix"
49
- """Seconds from 1970-01-01 00:00:00 UTC"""
87
+ """
88
+ Time scale of data. Must be one of ``(‘tai’, ‘tcb’, ‘tcg’, ‘tdb’, ‘tt’, ‘ut1’, ‘utc’)``,
89
+ see :py:class:`astropy.time.Time`
90
+ """
91
+ format: Attr[str] = "unix_tai"
92
+ """Time representation and epoch, see :py:class:`TimeArray`."""
50
93
 
51
94
  type: Attr[str] = "time"
52
- units: Attr[list] = ("s",)
95
+ units: Attr[list[str]] = ("s",)
53
96
 
54
97
 
55
98
  @xarray_dataarray_schema
56
99
  class SkyCoordArray:
57
- data: Data[SkyCoordLabel, float]
100
+ data: Data[Union[SkyDirLabel, SkyPosLabel], float]
58
101
 
59
102
  type: Attr[str] = "sky_coord"
60
- units: Attr[list] = ("rad", "rad")
103
+ units: Attr[list[str]] = ("rad", "rad")
61
104
  frame: Attr[str] = ""
62
105
  """
63
106
  From fixvis docs: clean and the im tool ignore the reference frame
@@ -69,8 +112,61 @@ class SkyCoordArray:
69
112
  """
70
113
 
71
114
 
72
- @dict_schema
73
- class FieldInfoDict:
115
+ @xarray_dataarray_schema
116
+ class SkyCoordOffsetArray:
117
+ data: Data[Union[SkyDirLabel, SkyPosLabel], float]
118
+
119
+ type: Attr[str] = "sky_coord"
120
+ units: Attr[list[str]] = ("rad", "rad")
121
+
122
+
123
+ @xarray_dataarray_schema
124
+ class QuantityArray:
125
+ """
126
+ Anonymous quantity, possibly with associated units
127
+
128
+ Often used for distances / differences (integration time, channel width etcetera).
129
+ """
130
+
131
+ data: Data[ZD, float]
132
+
133
+ units: Attr[list[str]]
134
+ type: Attr[str] = "quantity"
135
+
136
+
137
+ # Coordinates / Axes
138
+ @xarray_dataarray_schema
139
+ class TimeCoordArray:
140
+ """Data model of visibility time axis. See also :py:class:`TimeArray`."""
141
+
142
+ data: Data[Time, float]
143
+ """
144
+ Time, expressed in seconds since the epoch (see ``scale`` &
145
+ ``format``), see also see :py:class:`TimeArray`.
146
+ """
147
+
148
+ integration_time: Optional[Attr[QuantityArray]] = None
149
+ """ The nominal sampling interval (ms v2). Units of seconds. """
150
+ effective_integration_time: Optional[Attr[str]] = None
151
+ """
152
+ Name of data array that contains the integration time that includes
153
+ the effects of missing data.
154
+ """
155
+
156
+ type: Attr[str] = "time"
157
+ """ Coordinate type. Should be ``"time"``. """
158
+ units: Attr[list[str]] = ("s",)
159
+ """ Units to associate with axis"""
160
+ scale: Attr[str] = "tai"
161
+ """ Astropy time scales, see :py:class:`TimeArray` """
162
+ format: Attr[str] = "unix"
163
+ """ Astropy format, see :py:class:`TimeArray`"""
164
+ long_name: Optional[Attr[str]] = "Observation Time"
165
+ """ Long-form name to use for axis"""
166
+
167
+
168
+ @xarray_dataset_schema
169
+ class FieldSourceXds:
74
170
  """
75
171
  Field positions for each source.
76
172
 
@@ -78,52 +174,154 @@ class FieldInfoDict:
78
174
  For single dishes, this is the nominal pointing direction.
79
175
  """
80
176
 
81
- name: str
177
+ source_name: Optional[Coord[Union[ZD, Time], str]]
178
+ """ Source name. """
179
+ field_name: Optional[Coord[Union[ZD, Time], str]]
82
180
  """Field name."""
83
- field_id: int
84
- """Field id"""
85
- code: str
86
- """Field code indicating special characteristics of the field; user specified."""
87
- time_reference: Optional[TimeArray]
181
+
182
+ time: Optional[Coordof[TimeCoordArray]]
183
+ """Midpoint of time for which this set of parameters is accurate"""
184
+
185
+ line_label: Optional[Coord[LineLabel, str]]
186
+ """ Line labels (for line names and variables). """
187
+
188
+ line_names: Optional[Coord[Union[tuple[LineLabel], tuple[Time, LineLabel]], str]]
189
+ """ Line names (e.g. v=1, J=1-0, SiO). """
190
+
191
+ FIELD_PHASE_CENTER: Optional[Data[Union[ZD, Time], SkyCoordOffsetArray]]
88
192
  """
89
- Time reference for the directions and rates. When used in :py:class:`VisibilityXds` should match
90
- the scale and format given for ``time`` (see :py:class:`TimeArray`).
193
+ Offset from the SOURCE_DIRECTION that gives the direction of phase
194
+ center for which the fringes have been stopped-that is a point source in
195
+ this direction will produce a constant measured phase (page 2 of
196
+ https://articles.adsabs.harvard.edu/pdf/1999ASPC..180...79F). For
197
+ conversion from MSv2, frame refers column keywords by default. If frame
198
+ varies with field, it refers DelayDir_Ref column instead.
199
+ """
200
+ FIELD_DELAY_CENTER: Optional[
201
+ Data[Union[tuple[SkyDirLabel], tuple[Time, SkyDirLabel]], numpy.float64]
202
+ ]
203
+ """
204
+ Offset from the SOURCE_DIRECTION that gives the direction of delay
205
+ center where coherence is maximized by inserting delay into one element of
206
+ an interferometer to compensate for the geometrical and instrumental
207
+ differential delay. (For conversion from MSv2, frame refers column keywords
208
+ by default. If frame varies with field, it refers PhaseDir_Ref column
209
+ instead.)
210
+ """
211
+
212
+ SOURCE_LOCATION: Optional[
213
+ Data[
214
+ Union[
215
+ tuple[SkyPosLabel],
216
+ tuple[Time, SkyPosLabel],
217
+ tuple[SkyDirLabel],
218
+ tuple[Time, SkyDirLabel],
219
+ ],
220
+ numpy.float64,
221
+ ]
222
+ ]
223
+ """
224
+ CASA Table Cols: RA,DEC,Rho."Astrometric RA and Dec and Geocentric
225
+ distance with respect to the observer’s location (Geocentric). "Adjusted
226
+ for light-time aberration only. With respect to the reference plane and
227
+ equinox of the chosen system (ICRF or FK4/B1950). If the FK4/B1950 frame
228
+ output is selected, elliptic aberration terms are added. Astrometric RA/DEC
229
+ is generally used when comparing or reducing data against a star catalog."
230
+ https://ssd.jpl.nasa.gov/horizons/manual.html : 1. Astrometric RA & DEC
91
231
  """
92
- delay_direction: SkyCoordArray
93
232
 
233
+ LINE_REST_FREQUENCY: Optional[
234
+ Data[Union[tuple[LineLabel], tuple[Time, LineLabel]], numpy.float64]
235
+ ]
236
+ """ Rest frequencies for the transitions. """
94
237
 
95
- @xarray_dataarray_schema
96
- class QuantityArray:
97
- """
98
- Anonymous quantity
238
+ LINE_SYSTEMIC_VELOCITY: Optional[
239
+ Data[Union[tuple[LineLabel], tuple[Time, LineLabel]], numpy.float64]
240
+ ]
241
+ """ Systemic velocity at reference """
242
+
243
+ SOURCE_RADIAL_VELOCITY: Optional[Data[tuple[Time], numpy.float64]]
244
+ """ CASA Table Cols: RadVel. Geocentric distance rate """
245
+
246
+ NORTH_POLE_POSITION_ANGLE: Optional[Data[tuple[Time], numpy.float64]]
247
+ """ CASA Table cols: NP_ang, "Targets' apparent north-pole position angle (counter-clockwise with respect to direction of true-of-date reference-frame north pole) and angular distance from the sub-observer point (center of disc) at print time. A negative distance indicates the north-pole is on the hidden hemisphere." https://ssd.jpl.nasa.gov/horizons/manual.html : 17. North pole position angle & distance from disc center. """
248
+
249
+ NORTH_POLE_ANGULAR_DISTANCE: Optional[Data[tuple[Time], numpy.float64]]
250
+ """ CASA Table cols: NP_dist, "Targets' apparent north-pole position angle (counter-clockwise with respect to direction of true-of date reference-frame north pole) and angular distance from the sub-observer point (center of disc) at print time. A negative distance indicates the north-pole is on the hidden hemisphere."https://ssd.jpl.nasa.gov/horizons/manual.html : 17. North pole position angle & distance from disc center. """
251
+
252
+ SUB_OBSERVER_DIRECTION: Optional[
253
+ Data[tuple[Time, SphericalDirLabel], numpy.float64]
254
+ ]
255
+ """ CASA Table cols: DiskLong, DiskLat. "Apparent planetodetic longitude and latitude of the center of the target disc seen by the OBSERVER at print-time. This is not exactly the same as the "nearest point" for a non-spherical target shape (since the center of the disc might not be the point closest to the observer), but is generally very close if not a very irregular body shape. The IAU2009 rotation models are used except for Earth and MOON, which use higher-precision models. For the gas giants Jupiter, Saturn, Uranus and Neptune, IAU2009 longitude is based on the "System III" prime meridian rotation angle of the magnetic field. By contrast, pole direction (thus latitude) is relative to the body dynamical equator. There can be an offset between the magnetic pole and the dynamical pole of rotation. Down-leg light travel-time from target to observer is taken into account. Latitude is the angle between the equatorial plane and perpendicular to the reference ellipsoid of the body and body oblateness thereby included. The reference ellipsoid is an oblate spheroid with a single flatness coefficient in which the y-axis body radius is taken to be the same value as the x-axis radius. Whether longitude is positive to the east or west for the target will be indicated at the end of the output ephemeris." https://ssd.jpl.nasa.gov/horizons/manual.html : 14. Observer sub-longitude & sub-latitude """
256
+
257
+ SUB_SOLAR_POSITION: Optional[Data[tuple[Time, SphericalPosLabel], numpy.float64]]
258
+ """ CASA Table cols: Sl_lon, Sl_lat, r. "Heliocentric distance along with "Apparent sub-solar longitude and latitude of the Sun on the target. The apparent planetodetic longitude and latitude of the center of the target disc as seen from the Sun, as seen by the observer at print-time. This is _NOT_ exactly the same as the "sub-solar" (nearest) point for a non-spherical target shape (since the center of the disc seen from the Sun might not be the closest point to the Sun), but is very close if not a highly irregular body shape. Light travel-time from Sun to target and from target to observer is taken into account. Latitude is the angle between the equatorial plane and the line perpendicular to the reference ellipsoid of the body. The reference ellipsoid is an oblate spheroid with a single flatness coefficient in which the y-axis body radius is taken to be the same value as the x-axis radius. Uses IAU2009 rotation models except for Earth and Moon, which uses a higher precision models. Values for Jupiter, Saturn, Uranus and Neptune are Set III, referring to rotation of their magnetic fields. Whether longitude is positive to the east or west for the target will be indicated at the end of the output ephemeris." https://ssd.jpl.nasa.gov/horizons/manual.html : 15. Solar sub-longitude & sub-latitude """
259
+
260
+ HELIOCENTRIC_RADIAL_VELOCITY: Optional[Data[tuple[Time], numpy.float64]]
261
+ """ CASA Table cols: rdot."The Sun's apparent range-rate relative to the target, as seen by the observer. A positive "rdot" means the target was moving away from the Sun, negative indicates movement toward the Sun." https://ssd.jpl.nasa.gov/horizons/manual.html : 19. Solar range & range-rate (relative to target) """
262
+
263
+ OBSERVER_PHASE_ANGLE: Optional[Data[tuple[Time], numpy.float64]]
264
+ """ CASA Table cols: phang.""phi" is the true PHASE ANGLE at the observers' location at print time. "PAB-LON" and "PAB-LAT" are the FK4/B1950 or ICRF/J2000 ecliptic longitude and latitude of the phase angle bisector direction; the outward directed angle bisecting the arc created by the apparent vector from Sun to target center and the astrometric vector from observer to target center. For an otherwise uniform ellipsoid, the time when its long-axis is perpendicular to the PAB direction approximately corresponds to lightcurve maximum (or maximum brightness) of the body. PAB is discussed in Harris et al., Icarus 57, 251-258 (1984)." https://ssd.jpl.nasa.gov/horizons/manual.html : Phase angle and bisector """
265
+
266
+ OBSERVER_POSITION: Optional[
267
+ Data[Union[tuple[EllipsoidPosLabel], tuple[CartesianPosLabel]], numpy.float64]
268
+ ]
269
+ """ Observer location. """
270
+
271
+ # --- Attributes ---
272
+ DOPPLER_SHIFT_VELOCITY: Optional[Attr[numpy.float64]]
273
+ """ Velocity definition of the Doppler shift, e.g., RADIO or OPTICAL velocity in m/s """
274
+
275
+ source_model_url: Optional[Attr[str]]
276
+ """URL to access source model"""
277
+ ephemeris_name: Optional[Attr[str]]
278
+ """The name of the ephemeris. For example DE430.
279
+
280
+ This can be used with Astropy solar_system_ephemeris.set('DE430'), see
281
+ https://docs.astropy.org/en/stable/coordinates/solarsystem.html.
99
282
  """
283
+ is_ephemeris: Attr[bool] = False
100
284
 
101
- data: Data[tuple[()], float]
285
+ type: Attr[str] = "field_and_source"
286
+ """
287
+ Type of dataset.
288
+ """
102
289
 
103
- type: Attr[str]
104
- units: Attr[list]
290
+ # --- Optional coordinates ---
291
+ sky_dir_label: Optional[Coord[SkyDirLabel, str]] = ("ra", "dec")
292
+ """ Coordinate labels of sky directions (typically shape 2 and 'ra', 'dec') """
293
+ sky_pos_label: Optional[Coord[SkyPosLabel, str]] = ("ra", "dec", "dist")
294
+ """ Coordinate lables of sky positions (typically shape 3 and 'ra', 'dec', 'dist') """
295
+ ellipsoid_pos_label: Optional[Coord[EllipsoidPosLabel, str]] = (
296
+ "lon",
297
+ "lat",
298
+ "height",
299
+ )
300
+ """ Coordinate labels of geodetic earth location data (typically shape 3 and 'lon', 'lat', 'height')"""
301
+ cartesian_pos_label: Optional[Coord[CartesianPosLabel, str]] = ("x", "y", "z")
302
+ """ Coordinate labels of geocentric earth location data (typically shape 3 and 'x', 'y', 'z')"""
105
303
 
106
304
 
107
305
  @xarray_dataarray_schema
108
306
  class SpectralCoordArray:
109
- data: Data[tuple[()], float]
307
+ data: Data[ZD, float]
110
308
 
111
309
  frame: Attr[str] = "gcrs"
112
310
  """Astropy time scales."""
113
311
 
114
312
  type: Attr[str] = "frequency"
115
- units: Attr[list] = ("Hz",)
313
+ units: Attr[list[str]] = ("Hz",)
116
314
 
117
315
 
118
316
  @xarray_dataarray_schema
119
317
  class EarthLocationArray:
120
- data: Data[XyzLabel, float]
318
+ data: Data[CartesianPosLabel, float]
121
319
 
122
320
  ellipsoid: Attr[str]
123
321
  """
124
322
  ITRF makes use of GRS80 ellipsoid and WGS84 makes use of WGS84 ellipsoid
125
323
  """
126
- units: Attr[list] = ("m", "m", "m")
324
+ units: Attr[list[str]] = ("m", "m", "m")
127
325
  """
128
326
  If the units are a list of strings then it must be the same length as
129
327
  the last dimension of the data array. This allows for having different
@@ -132,9 +330,25 @@ class EarthLocationArray:
132
330
  """
133
331
 
134
332
 
333
+ @dict_schema
334
+ class PartitionInfoDict:
335
+ # spectral_window_id: missing / remove for good?
336
+ spectral_window_name: str
337
+ # field_id: missing / probably remove for good?
338
+ field_name: list[str]
339
+ # source_id: mising / remove for good?
340
+ line_name: list[str]
341
+ scan_number: list[int]
342
+ source_name: list[str]
343
+ polarization_setup: list[str]
344
+ num_lines: int
345
+ obs_mode: list[str]
346
+ taql: Optional[str]
347
+
348
+
135
349
  @dict_schema
136
350
  class ObservationInfoDict:
137
- observer: List[str]
351
+ observer: list
138
352
  """List of observer names."""
139
353
  project: str
140
354
  """Project Code/Project_UID"""
@@ -169,41 +383,6 @@ class ProcessorInfoDict:
169
383
  """Processor sub-type, e.g. ”GBT” or ”JIVE”."""
170
384
 
171
385
 
172
- # Coordinates / Axes
173
- @xarray_dataarray_schema
174
- class TimeArray:
175
- """Data model of time axis"""
176
-
177
- data: Data[Time, float]
178
- """ Time, expressed in SI seconds since the epoch (see ``scale`` & ``format``). """
179
-
180
- integration_time: Attr[Optional[TimeArray]] = None
181
- """ The nominal sampling interval (ms v2). Units of seconds. """
182
- effective_integration_time: Attr[Optional[TimeArray]] = None
183
- """ Name of data array that contains the integration time that includes the effects of missing data. """
184
-
185
- type: Attr[str] = "time"
186
- """ Coordinate type. Should be ``"time"``. """
187
- units: Attr[list[str]] = ("s",)
188
- """ Units to associate with axis"""
189
- scale: Attr[str] = "tai"
190
- """ Astropy time scales, see :py:class:`astropy.time.Time` """
191
- format: Attr[str] = "unix"
192
- """ Astropy format, see :py:class:`astropy.time.Time`. Default seconds from 1970-01-01 00:00:00 UTC """
193
- long_name: Optional[Attr[str]] = "Observation Time"
194
- """ Long-form name to use for axis"""
195
-
196
-
197
- @xarray_dataarray_schema
198
- class AntennaArray:
199
- data: Data[AntennaId, int]
200
- """
201
- Antenna id of an antenna. Maps to ``antenna_id``
202
- in :py:class:`AntennaXds`.
203
- """
204
- long_name: Optional[Attr[str]] = "Antenna ID"
205
-
206
-
207
386
  @xarray_dataarray_schema
208
387
  class BaselineArray:
209
388
  """TODO: documentation"""
@@ -214,13 +393,22 @@ class BaselineArray:
214
393
 
215
394
 
216
395
  @xarray_dataarray_schema
217
- class BaselineAntennaArray:
218
- data: Data[BaselineId, Union[numpy.int64, numpy.int32]]
219
- """
220
- Antenna id for an antenna in a baseline. Maps to ``attrs['antenna_xds'].antenna_id``
221
- in :py:class:`VisibilityXds`
222
- """
223
- long_name: Optional[Attr[str]] = "Baseline Antenna ID"
396
+ class BaselineAntennaNameArray:
397
+ """Array of antenna_name by baseline_id, as used in main_xds and main_sd_xds
398
+ (antenna_name by baseline_id dim"""
399
+
400
+ data: Data[BaselineId, str]
401
+ """Unique id for each baseline."""
402
+ long_name: Optional[Attr[str]] = "Antenna name by baseline_id"
403
+
404
+
405
+ @xarray_dataarray_schema
406
+ class AntennaNameArray:
407
+ """TODO: documentation"""
408
+
409
+ data: Data[AntennaName, str]
410
+ """Unique name for each antenna(_station)."""
411
+ long_name: Optional[Attr[str]] = "Antenna name"
224
412
 
225
413
 
226
414
  @xarray_dataset_schema
@@ -237,14 +425,14 @@ class FrequencyArray:
237
425
  """ Time, expressed in SI seconds since the epoch. """
238
426
  spectral_window_name: Attr[str]
239
427
  """ Name associated with spectral window. """
240
- frequency_group_name: Attr[str]
428
+ frequency_group_name: Optional[Attr[str]]
241
429
  """ Name associated with frequency group - needed for multi-band VLBI fringe-fitting."""
242
430
  reference_frequency: Attr[SpectralCoordArray]
243
431
  """ A frequency representative of the spectral window, usually the sky
244
432
  frequency corresponding to the DC edge of the baseband. Used by the calibration
245
433
  system if a fixed scaling frequency is required or in algorithms to identify the
246
434
  observing band. """
247
- channel_width: Attr[SpectralCoordArray]
435
+ channel_width: Attr[QuantityArray] # Not SpectralCoord, as it is a difference
248
436
  """ The nominal channel bandwidth. Same units as data array (see units key). """
249
437
  doppler: Optional[Attr[DopplerXds]]
250
438
  """ Doppler tracking information """
@@ -312,14 +500,40 @@ class VisibilityArray:
312
500
  tuple[Time, BaselineId, Frequency, Polarization],
313
501
  Union[numpy.complex64, numpy.complex128],
314
502
  ]
315
- time: Coord[tuple[()], TimeArray]
503
+
504
+ time: Coord[tuple[()], TimeCoordArray]
316
505
  baseline_id: Coord[tuple[()], BaselineArray]
317
- frequency: Coord[tuple[()], FrequencyArray]
318
506
  polarization: Coord[tuple[()], PolarizationArray]
319
- field_info: Attr[FieldInfoDict]
507
+ frequency: Coord[tuple[()], FrequencyArray]
508
+ time: Coord[ZD, TimeCoordArray]
509
+ baseline_id: Coord[ZD, BaselineArray]
510
+ polarization: Coord[ZD, PolarizationArray]
511
+ frequency: Coord[ZD, FrequencyArray]
512
+
513
+ field_and_source_xds: Attr[FieldSourceXds]
320
514
  long_name: Optional[Attr[str]] = "Visibility values"
321
515
  """ Long-form name to use for axis. Should be ``"Visibility values"``"""
322
- units: Attr[list] = ("Jy",)
516
+ units: Attr[list[str]] = ("Jy",)
517
+
518
+
519
+ @xarray_dataarray_schema
520
+ class SpectrumArray:
521
+ """Definition of xr.DataArray for SPECTRUM data (single dish)"""
522
+
523
+ data: Data[
524
+ tuple[Time, AntennaName, Frequency, Polarization],
525
+ Union[numpy.float64, numpy.float32, numpy.float16],
526
+ ]
527
+
528
+ time: Coordof[TimeCoordArray]
529
+ antenna_name: Coordof[AntennaNameArray]
530
+ frequency: Coordof[FrequencyArray]
531
+ polarization: Coordof[PolarizationArray]
532
+
533
+ field_and_source_xds: Attr[FieldSourceXds]
534
+ long_name: Optional[Attr[str]] = "Spectrum values"
535
+ """ Long-form name to use for axis. Should be ``"Spectrum values"``"""
536
+ units: Attr[list[str]] = ("Jy",)
323
537
 
324
538
 
325
539
  @xarray_dataarray_schema
@@ -335,11 +549,13 @@ class FlagArray:
335
549
  tuple[Time, BaselineId, Frequency, Polarization],
336
550
  tuple[Time, BaselineId, Frequency],
337
551
  tuple[Time, BaselineId],
552
+ tuple[Time, AntennaName, Frequency, Polarization], # SD
338
553
  ],
339
554
  bool,
340
555
  ]
341
- time: Coordof[TimeArray]
342
- baseline_id: Coordof[BaselineArray]
556
+ time: Coordof[TimeCoordArray]
557
+ baseline_id: Optional[Coordof[BaselineArray]] # Only IF
558
+ antenna_name: Optional[Coordof[AntennaNameArray]] # Only SD
343
559
  frequency: Coordof[FrequencyArray]
344
560
  polarization: Optional[Coordof[PolarizationArray]] = None
345
561
  long_name: Optional[Attr[str]] = "Visibility flags"
@@ -360,12 +576,14 @@ class WeightArray:
360
576
  tuple[Time, BaselineId, Frequency, Polarization],
361
577
  tuple[Time, BaselineId, Frequency],
362
578
  tuple[Time, BaselineId],
579
+ tuple[Time, AntennaName, Frequency, Polarization], # SD
363
580
  ],
364
581
  Union[numpy.float16, numpy.float32, numpy.float64],
365
582
  ]
366
583
  """Visibility weights"""
367
- time: Coordof[TimeArray]
368
- baseline_id: Coordof[BaselineArray]
584
+ time: Coordof[TimeCoordArray]
585
+ baseline_id: Optional[Coordof[BaselineArray]] # Only IF
586
+ antenna_name: Optional[Coordof[AntennaNameArray]] # Only SD
369
587
  frequency: Optional[Coordof[FrequencyArray]] = None
370
588
  polarization: Optional[Coordof[PolarizationArray]] = None
371
589
  long_name: Optional[Attr[str]] = "Visibility weights"
@@ -406,6 +624,9 @@ class UvwArray:
406
624
  tuple[Time, BaselineId, Frequency, Polarization, UvwLabel],
407
625
  tuple[Time, BaselineId, Frequency, UvwLabel],
408
626
  tuple[Time, BaselineId, UvwLabel],
627
+ tuple[Time, AntennaName, UvwLabel], # SD
628
+ tuple[Time, AntennaName, Frequency, UvwLabel], # SD
629
+ tuple[Time, AntennaName, Frequency, Polarization], # SD
409
630
  ],
410
631
  Union[
411
632
  numpy.float16,
@@ -414,8 +635,9 @@ class UvwArray:
414
635
  ],
415
636
  ]
416
637
  """Baseline coordinates from ``baseline_antenna2_id`` to ``baseline_antenna1_id``"""
417
- time: Coordof[TimeArray]
418
- baseline_id: Coordof[BaselineArray]
638
+ time: Coordof[TimeCoordArray]
639
+ baseline_id: Optional[Coordof[BaselineArray]] # Only IF
640
+ antenna_name: Optional[Coordof[AntennaNameArray]] # Only SD
419
641
  frequency: Optional[Coordof[FrequencyArray]] = None
420
642
  polarization: Optional[Coordof[PolarizationArray]] = None
421
643
  uvw_label: Coordof[UvwLabelArray] = ("u", "v", "w")
@@ -433,12 +655,14 @@ class TimeSamplingArray:
433
655
  tuple[Time, BaselineId, Frequency, Polarization],
434
656
  tuple[Time, BaselineId, Frequency],
435
657
  tuple[Time, BaselineId],
658
+ tuple[Time, AntennaName], # SD
436
659
  ],
437
660
  float,
438
661
  ]
439
662
 
440
- time: Coordof[TimeArray]
441
- baseline_id: Coordof[BaselineArray]
663
+ time: Coordof[TimeCoordArray]
664
+ baseline_id: Optional[Coordof[BaselineArray]] # Only IF
665
+ antenna_name: Optional[Coordof[AntennaNameArray]] # Only SD
442
666
  frequency: Optional[Coordof[FrequencyArray]] = None
443
667
  polarization: Optional[Coordof[PolarizationArray]] = None
444
668
 
@@ -448,7 +672,7 @@ class TimeSamplingArray:
448
672
  """ Astropy format, see :py:class:`astropy.time.Time`. Default seconds from 1970-01-01 00:00:00 UTC """
449
673
 
450
674
  long_name: Optional[Attr[str]] = "Time sampling data"
451
- units: Attr[str] = "s"
675
+ units: Attr[list[str]] = ("s",)
452
676
 
453
677
 
454
678
  @xarray_dataarray_schema
@@ -470,11 +694,11 @@ class FreqSamplingArray:
470
694
  :py:class:`VisibilityXds`.
471
695
  """
472
696
  frequency: Coordof[FrequencyArray]
473
- time: Optional[Coordof[TimeArray]] = None
697
+ time: Optional[Coordof[TimeCoordArray]] = None
474
698
  baseline_id: Optional[Coordof[BaselineArray]] = None
475
699
  polarization: Optional[Coordof[PolarizationArray]] = None
476
700
  long_name: Optional[Attr[str]] = "Frequency sampling data"
477
- units: Attr[str] = "Hz"
701
+ units: Attr[list[str]] = ("Hz",)
478
702
  frame: Attr[str] = "icrs"
479
703
  """
480
704
  Astropy velocity reference frames (see :external:ref:`astropy-spectralcoord`).
@@ -489,105 +713,220 @@ class FreqSamplingArray:
489
713
 
490
714
  @xarray_dataset_schema
491
715
  class AntennaXds:
492
- # --- Coordinates ---
493
- antenna_id: Coordof[AntennaArray]
494
- """Antenna ID"""
495
- name: Coord[AntennaId, str]
496
-
497
- """Antenna name."""
498
- station: Coord[AntennaId, str]
499
- """Name of the station pad (relevant to arrays with moving antennas)."""
500
- antenna_type: Optional[Coord[AntennaId, str]]
501
- """Antenna type.
502
-
503
- Reserved keywords include: (``GROUND-BASED`` - conventional
504
- antennas; ``SPACE-BASED`` - orbiting antennas; ``TRACKING-STN`` - tracking
505
- stations)."""
506
- mount: Coord[AntennaId, str]
507
- """Mount type of the antenna.
508
-
509
- Reserved keywords include: (``EQUATORIAL`` - equatorial mount; ``ALTAZ`` -
510
- azimuth-elevation mount; ``X-Y`` - x-y mount; ``SPACE-HALCA`` - specific
511
- orientation model.)"""
512
- observatory: Optional[Coord[AntennaId, str]]
513
- """Support for VLBI"""
514
- receptor_name: Optional[Coord[ReceptorName, str]]
515
- """Names of receptors"""
516
- xyz_label: Coord[XyzLabel, str]
517
- """Coordinate dimension of earth location data (typically shape 3 and 'x', 'y', 'z')"""
518
- sky_coord_label: Optional[Coord[SkyCoordLabel, str]]
519
- """Coordinate dimension of sky coordinate data (possibly shape 2 and 'RA', "Dec")"""
520
-
521
- # --- Data variables ---
522
- POSITION: Data[AntennaId, EarthLocationArray]
716
+ # Coordinates
717
+ antenna_name: Coordof[AntennaNameArray]
718
+ """ Antenna name """
719
+ station: Coord[AntennaName, str]
720
+ """ Name of the station pad (relevant to arrays with moving antennas). """
721
+ mount: Coord[AntennaName, str]
722
+ """ Mount type of the antenna. Reserved keywords include: ”EQUATORIAL” - equatorial mount;
723
+ ”ALT-AZ” - azimuth-elevation mount;
724
+ "ALT-AZ+ROTATOR" alt-az mount with feed rotator; introduced for ASKAP dishes;
725
+ "ALT-AZ+NASMYTH-R": Nasmyth mount with receivers at the right-hand side of the cabin. Many high-frequency antennas used for VLBI have such a mount typel;
726
+ "ALT-AZ+NASMYTH-L:: Nasmyth mount with receivers at the left-hand side of the cabin.
727
+ ”X-Y” - x-y mount;
728
+ SPACE-HALCA” - specific orientation model."""
729
+ telescope_name: Optional[Coord[AntennaName, str]]
730
+ """ Useful when data is combined from mutiple arrays for example ACA + ALMA. """
731
+ # TODO: receptor_label, polarization_type, sky_dir_label set as optional
732
+ # for datasets like test_alma_ephemris_mosaic. See also BEAM_OFFSET below.
733
+ receptor_label: Optional[Coord[ReceptorLabel, str]]
734
+ """ Names of receptors """
735
+ polarization_type: Optional[Coord[tuple[AntennaName, ReceptorLabel], str]]
736
+ """ Polarization type to which each receptor responds (e.g. ”R”,”L”,”X” or ”Y”).
737
+ This is the receptor polarization type as recorded in the final correlated data (e.g. ”RR”); i.e.
738
+ as measured after all polarization combiners. ['X','Y'], ['R','L'] """
739
+ cartesian_pos_label: Optional[Coord[CartesianPosLabel, str]]
740
+ """ (x,y,z) - either cartesian or ellipsoid """
741
+ ellipsoid_pos_label: Optional[Coord[EllipsoidPosLabel, str]]
742
+ """ (lon, lat, dist) - either cartesian or ellipsoid"""
743
+ sky_dir_label: Optional[Coord[SkyDirLabel, str]]
744
+ """ ra, dec """
745
+ time: Optional[Coordof[TimeCoordArray]]
746
+ """ Time for VLBI phase cal"""
747
+ time_phase_cal: Optional[Coord[TimePhaseCal, numpy.float64]]
748
+ """ Time for VLBI phase cal"""
749
+ tone_label: Optional[Coord[ToneLabel, str]]
750
+ """ ? """
751
+ gain_curve_type: Optional[Coord[AntennaName, str]]
752
+ """ ? """
753
+
754
+ # Data variables
755
+ ANTENNA_POSITION: Data[
756
+ Union[
757
+ tuple[AntennaName, EllipsoidPosLabel], tuple[AntennaName, CartesianPosLabel]
758
+ ],
759
+ QuantityArray,
760
+ ] # EarthLocationArray
523
761
  """
524
762
  In a right-handed frame, X towards the intersection of the equator and
525
763
  the Greenwich meridian, Z towards the pole.
526
764
  """
527
- FEED_OFFSET: Data[tuple[AntennaId, XyzLabel], QuantityArray]
765
+ ANTENNA_FEED_OFFSET: Data[
766
+ Union[
767
+ tuple[AntennaName, EllipsoidPosLabel], tuple[AntennaName, CartesianPosLabel]
768
+ ],
769
+ QuantityArray,
770
+ ]
528
771
  """
529
772
  Offset of feed relative to position (``Antenna_Table.offset + Feed_Table.position``).
530
773
  """
531
- DISH_DIAMETER: Data[AntennaId, QuantityArray]
774
+ ANTENNA_DISH_DIAMETER: Optional[Data[tuple[AntennaName], QuantityArray]]
532
775
  """
533
776
  Nominal diameter of dish, as opposed to the effective diameter.
534
777
  """
535
- BEAM_OFFSET: Optional[Data[AntennaId, SkyCoordArray]]
778
+ ANTENNA_EFFECTIVE_DISH_DIAMETER: Optional[
779
+ Data[tuple[AntennaName, ReceptorLabel, SkyDirLabel], QuantityArray]
780
+ ]
781
+ """ Airy Disk Model .... """
782
+
783
+ # TODO: setting BEAM_OFFSET and RECEPTOR_ANGLE as optional for now, as it
784
+ # is not present in some datasets (example: test_alma_ephemris_mosaic)
785
+ BEAM_OFFSET: Optional[Data[tuple[AntennaName, ReceptorLabel], SkyCoordArray]]
536
786
  """
537
787
  Beam position offset, as defined on the sky but in the antenna
538
788
  reference frame.
539
789
  """
540
- RECEPTOR_ANGLE: Optional[Data[tuple[AntennaId, ReceptorName], QuantityArray]]
790
+ RECEPTOR_ANGLE: Optional[Data[tuple[AntennaName, ReceptorLabel], QuantityArray]]
541
791
  """
542
792
  Polarization reference angle. Converts into parallactic angle in the sky domain.
543
793
  """
544
- FOCUS_LENGTH: Optional[Data[AntennaId, QuantityArray]]
794
+ FOCUS_LENGTH: Optional[Data[tuple[AntennaName], QuantityArray]]
545
795
  """
546
796
  Focus length. As defined along the optical axis of the antenna.
547
797
  """
548
- ARRAY_CENTER: Optional[Data[AntennaId, EarthLocationArray]]
549
- EFFECTIVE_DISH_DIAMETER: Optional[Data[AntennaId, QuantityArray]]
550
798
 
551
- # --- Attributes ---
552
- telescope_name: Optional[Attr[str]]
799
+ GAIN_CURVE: Optional[
800
+ Data[tuple[AntennaName, ReceptorLabel, PolyTerm], numpy.float32]
801
+ ]
802
+ """ VLBI. ? """
803
+ GAIN_CURVE_INTERVAL: Optional[Data[tuple[AntennaName], QuantityArray]]
804
+ """ VLBI. ? """
805
+ GAIN_CURVE_SENSITIVITY: Optional[
806
+ Data[tuple[AntennaName, ReceptorLabel], numpy.float32]
807
+ ]
808
+ """ VLBI. ? """
809
+ PHASE_CAL: Optional[
810
+ Data[
811
+ Union[
812
+ tuple[AntennaName, Time, ReceptorLabel, ToneLabel],
813
+ tuple[AntennaName, TimePhaseCal, ReceptorLabel, ToneLabel],
814
+ ],
815
+ numpy.complex64,
816
+ ]
817
+ ]
818
+ """ VLBI. ? """
819
+ PHASE_CAL_CABLE_CAL: Optional[
820
+ Data[
821
+ Union[tuple[AntennaName, Time], tuple[AntennaName, TimePhaseCal]],
822
+ QuantityArray,
823
+ ]
824
+ ]
825
+ """ VLBI. ? """
826
+ PHASE_CAL_INTERVAL: Optional[
827
+ Data[
828
+ Union[tuple[AntennaName, Time], tuple[AntennaName, TimePhaseCal]],
829
+ QuantityArray,
830
+ ]
831
+ ]
832
+ """ VLBI. ? """
833
+ PHASE_CAL_TONE_FREQUENCY: Optional[
834
+ Data[
835
+ Union[
836
+ tuple[AntennaName, Time, ReceptorLabel, ToneLabel],
837
+ tuple[AntennaName, TimePhaseCal, ReceptorLabel, ToneLabel],
838
+ ],
839
+ QuantityArray,
840
+ ]
841
+ ]
842
+ """ VLBI. ? """
843
+
844
+ # Attributes
845
+ overall_telescope_name: Optional[Attr[str]]
553
846
  """
554
- From MS v2 observation table
847
+ The name of the collection of arrays and dishes that were used for the observation.
848
+ In many instances this will only be a single array or dish. An example of a
849
+ telescope consistening of mutiple arrays and dishes is the EHT. The coordinate
850
+ telescope_name will give the names of the constituent arrays and dishes. From
851
+ MSv2 observation table.
555
852
  """
853
+ relocatable_antennas: Optional[Attr[bool]]
854
+ """ Can the antennas be moved (ALMA, VLA, NOEMA) """
556
855
  type: Attr[str] = "antenna"
557
856
  """
558
857
  Type of dataset. Expected to be ``antenna``
559
858
  """
560
859
 
561
860
 
861
+ @xarray_dataset_schema
862
+ class WeatherXds:
863
+ """Weather. Contains station positions and time-dependent mean external
864
+ atmosphere and weather information"""
865
+
866
+ # Coordinates
867
+ time: Coordof[TimeCoordArray]
868
+ """ Mid-point of the time interval """
869
+ station_id: Coord[StationId, numpy.int64]
870
+ """ Station identifier """
871
+ antenna_name: Optional[Coordof[AntennaNameArray]]
872
+ """ Antenna identifier """
873
+
874
+ # Data variables (all optional)
875
+ H2O: Optional[Data[tuple[StationId, Time], QuantityArray]] = None
876
+ """ Average column density of water """
877
+ IONOS_ELECTRON: Optional[Data[tuple[StationId, Time], QuantityArray]] = None
878
+ """ Average column density of electrons """
879
+ PRESSURE: Optional[Data[tuple[StationId, Time], QuantityArray]] = None
880
+ """ Ambient atmospheric pressure """
881
+ REL_HUMIDITY: Optional[Data[tuple[StationId, Time], QuantityArray]] = None
882
+ """ Ambient relative humidity """
883
+ TEMPERATURE: Optional[Data[tuple[StationId, Time], QuantityArray]] = None
884
+ """ Ambient air temperature for an antenna """
885
+ DEW_POINT: Optional[Data[tuple[StationId, Time], QuantityArray]] = None
886
+ """ Dew point """
887
+ WIND_DIRECTION: Optional[Data[tuple[StationId, Time], QuantityArray]] = None
888
+ """ Average wind direction """
889
+ WIND_SPEED: Optional[Data[tuple[StationId, Time], QuantityArray]] = None
890
+ """ Average wind speed """
891
+ STATION_POSITION: Optional[Data[tuple[StationId], QuantityArray]] = None
892
+ """ Station position """
893
+
894
+ # Attributes
895
+ type: Attr[str] = "weather"
896
+ """
897
+ Type of dataset.
898
+ """
899
+
900
+
562
901
  @xarray_dataset_schema
563
902
  class PointingXds:
564
- time: Coordof[TimeArray]
903
+ time: Coordof[TimeCoordArray]
565
904
  """
566
905
  Mid-point of the time interval for which the information in this row is
567
906
  valid. Required to use the same time measure reference as in visibility dataset
568
907
  """
569
- antenna_id: Coordof[AntennaArray]
908
+ antenna_name: Coordof[AntennaNameArray]
570
909
  """
571
- Antenna identifier, as specified by baseline_antenna1/2_id in visibility dataset
910
+ Antenna name, as specified by baseline_antenna1/2_name in visibility dataset
572
911
  """
573
- sky_coord_label: Coord[SkyCoordLabel, str]
912
+ sky_dir_label: Coord[SkyDirLabel, str]
574
913
  """
575
914
  Direction labels.
576
915
  """
577
916
 
578
917
  BEAM_POINTING: Data[
579
- Union[tuple[Time, AntennaId, TimePolynomial], tuple[Time, AntennaId]],
918
+ Union[tuple[Time, AntennaName, TimePolynomial], tuple[Time, AntennaName]],
580
919
  SkyCoordArray,
581
920
  ]
582
921
  """
583
922
  Antenna pointing direction, optionally expressed as polynomial coefficients. DIRECTION in MSv3.
584
923
  """
585
- DISH_MEASURED_POINTING: Optional[Data[tuple[Time, AntennaId], SkyCoordArray]]
924
+ DISH_MEASURED_POINTING: Optional[Data[tuple[Time, AntennaName], SkyCoordArray]]
586
925
  """
587
926
  The current encoder values on the primary axes of the mount type for
588
927
  the antenna. ENCODER in MSv3.
589
928
  """
590
- OVER_THE_TOP: Optional[Data[tuple[Time, AntennaId], bool]]
929
+ OVER_THE_TOP: Optional[Data[tuple[Time, AntennaName], bool]]
591
930
 
592
931
 
593
932
  @xarray_dataset_schema
@@ -597,15 +936,59 @@ class SpectralCoordXds:
597
936
 
598
937
 
599
938
  @xarray_dataset_schema
600
- class SourceXds:
939
+ class PhasedArrayXds:
601
940
  # TODO
602
941
  pass
603
942
 
604
943
 
605
944
  @xarray_dataset_schema
606
- class PhasedArrayXds:
607
- # TODO
608
- pass
945
+ class SystemCalibrationXds:
946
+ """System calibration. Contains time- and frequency- variable
947
+ calibration measurements for each antenna, as indexed on receptor"""
948
+
949
+ # Coordinates
950
+ antenna_name: Coordof[AntennaNameArray]
951
+ """ Antenna identifier """
952
+ time: Coordof[TimeCoordArray]
953
+ """ Midpoint of time for which this set of parameters is accurate """
954
+ receptor_id: Optional[Coord[ReceptorId, numpy.float64]] = None
955
+ """ """
956
+ frequency: Optional[Coordof[FrequencyArray]] = None
957
+ """ """
958
+
959
+ # Data variables (all optional)
960
+ PHASE_DIFFERENCE: Optional[Data[tuple[Time, AntennaName], numpy.float64]] = None
961
+ """ Phase difference between receptor 0 and receptor 1 """
962
+ TCAL: Optional[
963
+ Data[tuple[Time, AntennaName, ReceptorId, Frequency], QuantityArray]
964
+ ] = None
965
+ """ Calibration temp """
966
+ TRX: Optional[
967
+ Data[tuple[Time, AntennaName, ReceptorId, Frequency], QuantityArray]
968
+ ] = None
969
+ """ Receiver temperature """
970
+ TSKY: Optional[
971
+ Data[tuple[Time, AntennaName, ReceptorId, Frequency], QuantityArray]
972
+ ] = None
973
+ """ Sky temperature """
974
+ TSYS: Optional[
975
+ Data[tuple[Time, AntennaName, ReceptorId, Frequency], QuantityArray]
976
+ ] = None
977
+ """ System temperature """
978
+ TANT: Optional[
979
+ Data[tuple[Time, AntennaName, ReceptorId, Frequency], QuantityArray]
980
+ ] = None
981
+ """ Antenna temperature """
982
+ TANT_SYS: Optional[
983
+ Data[tuple[Time, AntennaName, ReceptorId, Frequency], QuantityArray]
984
+ ] = None
985
+ """ TANT/TSYS """
986
+
987
+ # Attributes
988
+ type: Attr[str] = "system_calibration"
989
+ """
990
+ Type of dataset.
991
+ """
609
992
 
610
993
 
611
994
  @xarray_dataset_schema
@@ -613,12 +996,17 @@ class VisibilityXds:
613
996
  """TODO: documentation"""
614
997
 
615
998
  # --- Required Coordinates ---
616
- time: Coordof[TimeArray]
999
+ time: Coordof[TimeCoordArray]
617
1000
  """
618
1001
  The time coordinate is the mid-point of the nominal sampling interval, as
619
1002
  specified in the ``ms_v4.time.attrs['integration_time']`` (ms v2 interval).
620
1003
  """
621
- baseline_id: Coordof[BaselineArray]
1004
+ baseline_id: Optional[Coordof[BaselineArray]] # IF. not present in main_sd_xds
1005
+ """ Baseline ID """
1006
+ antenna_name: Optional[
1007
+ Coordof[AntennaNameArray]
1008
+ ] # Single-dish. not present in main_xds
1009
+ """ antenna_name """
622
1010
  frequency: Coordof[FrequencyArray]
623
1011
  """Center frequencies for each channel."""
624
1012
  polarization: Coordof[PolarizationArray]
@@ -626,27 +1014,50 @@ class VisibilityXds:
626
1014
  Labels for polarization types, e.g. ``['XX','XY','YX','YY']``, ``['RR','RL','LR','LL']``.
627
1015
  """
628
1016
  uvw_label: Optional[Coordof[UvwLabelArray]]
629
-
630
- # --- Required data variables ---
631
- VISIBILITY: Dataof[VisibilityArray]
1017
+ """ u,v,w """
1018
+ baseline_antenna1_name: Optional[Coordof[BaselineAntennaNameArray]] # IF
1019
+ """Antenna name for 1st antenna in baseline. Maps to ``attrs['antenna_xds'].antenna_name``"""
1020
+ baseline_antenna2_name: Optional[Coordof[BaselineAntennaNameArray]] # IF
1021
+ """Antenna name for 2nd antenna in baseline. Maps to ``attrs['antenna_xds'].antenna_name``"""
632
1022
 
633
1023
  # --- Required Attributes ---
1024
+ partition_info: Attr[PartitionInfoDict]
634
1025
  antenna_xds: Attr[AntennaXds]
635
1026
 
636
1027
  # --- Optional Coordinates ---
637
- baseline_antenna1_id: Optional[Coordof[BaselineAntennaArray]] = None
638
- """Antenna id for 1st antenna in baseline. Maps to ``attrs['antenna_xds'].antenna_id``"""
639
- baseline_antenna2_id: Optional[Coordof[BaselineAntennaArray]] = None
640
- """Antenna id for 2nd antenna in baseline. Maps to ``attrs['antenna_xds'].antenna_id``"""
641
- scan_id: Optional[Coord[Time, int]] = None
1028
+ scan_number: Optional[Coord[Time, Union[numpy.int64, numpy.int32]]] = None
642
1029
  """Arbitary scan number to identify data taken in the same logical scan."""
643
1030
 
1031
+ # --- Required data variables ---
1032
+
644
1033
  # --- Optional data variables / arrays ---
1034
+
1035
+ # Either VISIBILITY (interferometry) or SPECTRUM (single-dish)
1036
+ VISIBILITY: Optional[Dataof[VisibilityArray]] = None
645
1037
  """Complex visibilities, either simulated or measured by interferometer."""
1038
+ SPECTRUM: Optional[Dataof[SpectrumArray]] = None
1039
+ """Single dish data, either simulated or measured by an antenna."""
1040
+
1041
+ VISIBILITY_CORRECTED: Optional[Dataof[VisibilityArray]] = None
1042
+ VISIBILITY_MODEL: Optional[Dataof[VisibilityArray]] = None
1043
+ SPECTRUM_CORRECTED: Optional[Dataof[SpectrumArray]] = None
1044
+
646
1045
  FLAG: Optional[Dataof[FlagArray]] = None
647
1046
  WEIGHT: Optional[Dataof[WeightArray]] = None
648
1047
  UVW: Optional[Dataof[UvwArray]] = None
649
- EFFECTIVE_INTEGRATION_TIME: Optional[Dataof[TimeSamplingArray]] = None
1048
+ EFFECTIVE_INTEGRATION_TIME: Optional[
1049
+ Data[
1050
+ Union[
1051
+ tuple[Time, BaselineId],
1052
+ tuple[Time, BaselineId, Frequency],
1053
+ tuple[Time, BaselineId, Frequency, Polarization],
1054
+ tuple[Time, AntennaName], # SD
1055
+ tuple[Time, AntennaName, Frequency], # SD
1056
+ tuple[Time, AntennaName, Frequency, Polarization], # SD
1057
+ ],
1058
+ QuantityArray,
1059
+ ]
1060
+ ] = None
650
1061
  """
651
1062
  The integration time, including the effects of missing data, in contrast to
652
1063
  ``integration_time`` attribute of the ``time`` coordinate,
@@ -665,11 +1076,12 @@ class VisibilityXds:
665
1076
  """Includes the effects of missing data unlike ``frequency``."""
666
1077
 
667
1078
  # --- Optional Attributes ---
668
- pointing_xds: Optional[Attr[PointingXds]] = None
669
- source_xds: Optional[Attr[SourceXds]] = None
670
- pased_array_xds: Optional[Attr[PhasedArrayXds]] = None
671
1079
  observation_info: Optional[Attr[ObservationInfoDict]] = None
672
- observation_info: Optional[Attr[ProcessorInfoDict]] = None
1080
+ processor_info: Optional[Attr[ProcessorInfoDict]] = None
1081
+ weather_xds: Optional[Attr[WeatherXds]] = None
1082
+ pointing_xds: Optional[Attr[PointingXds]] = None
1083
+ phased_array_xds: Optional[Attr[PhasedArrayXds]] = None
1084
+ system_calibration_xds: Optional[Attr[SystemCalibrationXds]] = None
673
1085
 
674
1086
  version: Optional[Attr[str]] = None # TODO:
675
1087
  """Semantic version of xradio data format"""
@@ -685,3 +1097,6 @@ class VisibilityXds:
685
1097
  """
686
1098
 
687
1099
  type: Attr[str] = "visibility"
1100
+ """
1101
+ Dataset type
1102
+ """