import decimal
import numpy as np
import pipeline.infrastructure as infrastructure
LOG = infrastructure.get_logger(__name__)
# Ozone line frequency ranges, used to skip flagging for sharps/birdies that
# are likely ozone lines (CAS-12242).
# freqStart(GHz) freqStop(GHz) created by au.ozoneLineLineFinder(threshold=0.0024)
OZONE_RANGES = [
(67.327500, 67.392500),
(76.392500, 76.392500),
(76.512500, 76.562500),
(93.832500, 93.852500),
(93.942500, 93.977500),
(96.187500, 96.277500),
(101.662500, 101.802500),
(101.842500, 101.847500),
(103.862500, 103.902500),
(109.537500, 109.582500),
(110.742500, 110.932500),
(114.972500, 114.992500),
(125.307500, 125.487500),
(128.302500, 128.327500),
(136.842500, 136.882500),
(142.057500, 142.302500),
(144.862500, 144.977500),
(148.717500, 148.777500),
(153.942500, 153.952500),
(154.022500, 154.082500),
(164.892500, 165.012500),
(165.657500, 165.917500),
(167.567500, 167.582500),
(175.177500, 175.197500),
(175.417500, 175.477500),
(184.262500, 184.492500),
(184.717500, 184.792500),
(193.317500, 193.387500),
(195.297500, 195.557500),
(195.692500, 195.772500),
(199.377500, 199.397500),
(206.117500, 206.152500),
(208.547500, 208.742500),
(210.752500, 210.762500),
(210.777500, 210.847500),
(214.877500, 215.042500),
(226.012500, 226.097500),
(229.552500, 229.602500),
(231.152500, 231.417500),
(235.547500, 235.872500),
(236.987500, 237.312500),
(238.937500, 239.252500),
(242.162500, 242.477500),
(243.307500, 243.607500),
(244.117500, 244.202500),
(247.712500, 247.802500),
(248.037500, 248.337500),
(249.642500, 249.852500),
(249.887500, 250.132500),
(258.172500, 258.232500),
(258.582500, 258.857500),
(262.807500, 262.907500),
(263.552500, 263.822500),
(263.892500, 263.912500),
(264.892500, 264.962500),
(267.152500, 267.387500),
(272.922500, 273.182500),
(274.392500, 274.572500),
(276.877500, 276.977500),
(279.442500, 279.532500),
(279.882500, 279.907500),
(282.802500, 282.877500),
(285.942500, 286.242500),
(286.272500, 286.402500),
(288.802500, 289.117500),
(290.967500, 290.987500),
(293.072500, 293.272500),
(293.522500, 293.587500),
(300.632500, 300.737500),
(301.632500, 301.997500),
(303.047500, 303.292500),
(310.027500, 310.107500),
(315.757500, 315.982500),
(316.202500, 316.467500),
(316.672500, 316.707500),
(317.177500, 317.222500),
(319.877500, 320.122500),
(326.722500, 327.082500),
(327.792500, 327.902500),
(332.552500, 332.797500),
(332.842500, 332.987500),
(335.227500, 335.317500),
(343.142500, 343.182500),
(343.207500, 343.302500),
(343.502500, 343.522500),
(352.172500, 352.452500),
(352.552500, 352.642500),
(352.737500, 352.927500),
(354.927500, 355.112500),
(357.512500, 357.747500),
(358.107500, 358.292500),
(358.657500, 359.057500),
(359.542500, 359.767500),
(361.622500, 361.722500),
(363.387500, 363.552500),
(364.242500, 364.657500),
(366.652500, 366.907500),
(368.927500, 368.977500),
(370.907500, 371.142500),
(387.037500, 387.137500),
(387.212500, 387.397500),
(392.502500, 392.812500),
(395.032500, 395.097500),
(396.442500, 396.622500),
(396.977500, 397.082500),
(399.962500, 400.192500),
(401.077500, 401.362500),
(401.927500, 401.937500),
(402.182500, 402.617500),
(403.792500, 403.892500),
(408.127500, 408.462500),
(412.957500, 413.067500),
(414.037500, 414.477500),
(420.762500, 420.832500),
(423.497500, 423.847500),
(424.742500, 424.947500),
(425.107500, 425.227500),
(426.032500, 426.112500),
(427.937500, 427.952500),
(428.662500, 428.922500),
(429.377500, 429.467500),
(430.197500, 430.477500),
(437.312500, 437.677500),
(438.427500, 438.542500),
(441.112500, 441.567500),
(441.992500, 442.257500),
(445.342500, 445.577500),
(446.072500, 446.222500),
(446.612500, 446.692500),
(448.692500, 449.062500),
(452.227500, 452.252500),
(453.777500, 453.807500),
(454.632500, 454.707500),
(457.232500, 457.602500),
(462.237500, 462.492500),
(463.012500, 463.382500),
(464.052500, 464.172500),
(466.477500, 466.807500),
(467.742500, 468.157500),
(468.292500, 468.547500),
(469.002500, 469.182500),
(469.267500, 469.362500),
(469.407500, 469.602500),
(469.817500, 470.112500),
(470.822500, 471.167500),
(472.257500, 472.342500),
(472.722500, 473.037500),
(473.072500, 473.132500),
(474.157500, 474.177500),
(475.832500, 476.212500),
(479.367500, 479.427500),
(479.617500, 479.652500),
(479.977500, 480.027500),
(480.102500, 480.272500),
(480.537500, 480.882500),
(481.062500, 481.317500),
(481.437500, 481.867500),
(483.542500, 483.552500),
(487.167500, 487.532500),
(489.477500, 489.597500),
(491.907500, 491.997500),
(496.077500, 496.427500),
(496.982500, 497.222500),
(497.927500, 498.022500),
(498.612500, 498.887500),
(607.812500, 607.887500),
(609.587500, 609.857500),
(610.107500, 610.597500),
(611.102500, 611.467500),
(614.682500, 614.872500),
(616.237500, 616.332500),
(617.267500, 617.347500),
(620.472500, 621.067500),
(623.532500, 623.847500),
(625.317500, 625.432500),
(632.042500, 632.317500),
(633.312500, 633.397500),
(634.287500, 634.642500),
(638.722500, 639.092500),
(640.017500, 640.167500),
(640.307500, 640.332500),
(641.507500, 641.562500),
(642.167500, 642.537500),
(644.627500, 644.987500),
(645.612500, 645.732500),
(647.647500, 648.037500),
(650.672500, 650.787500),
(651.247500, 651.762500),
(653.552500, 653.957500),
(654.452500, 654.922500),
(654.937500, 655.447500),
(655.492500, 655.712500),
(655.747500, 656.102500),
(656.127500, 656.777500),
(657.447500, 657.587500),
(657.897500, 658.197500),
(658.777500, 658.862500),
(661.327500, 661.597500),
(664.487500, 664.487500),
(665.497500, 665.817500),
(665.857500, 665.907500),
(666.517500, 666.727500),
(666.772500, 666.807500),
(669.657500, 670.062500),
(671.482500, 671.767500),
(671.792500, 671.902500),
(671.942500, 671.957500),
(672.737500, 672.862500),
(673.817500, 674.017500),
(676.007500, 676.122500),
(677.117500, 677.177500),
(683.557500, 683.722500),
(684.202500, 684.292500),
(691.337500, 691.382500),
(691.657500, 691.677500),
(692.192500, 692.547500),
(693.287500, 693.667500),
(694.632500, 694.897500),
(696.022500, 696.162500),
(698.932500, 699.032500),
(700.657500, 701.042500),
(701.312500, 701.407500),
(701.472500, 701.577500),
(708.097500, 708.192500),
(709.592500, 709.692500),
(711.442500, 711.552500),
(716.807500, 716.857500),
(718.107500, 718.492500),
(719.622500, 719.967500),
(792.232500, 792.302500),
(792.997500, 793.072500),
(793.107500, 793.377500),
(794.657500, 794.677500),
(798.687500, 798.842500),
(799.382500, 799.397500),
(802.317500, 802.422500),
(804.652500, 804.672500),
(807.412500, 807.842500),
(810.552500, 810.737500),
(810.907500, 811.007500),
(811.357500, 811.577500),
(813.002500, 813.277500),
(813.847500, 814.142500),
(818.382500, 818.457500),
(819.262500, 819.262500),
(819.637500, 819.862500),
(824.787500, 824.807500),
(825.502500, 825.797500),
(825.812500, 826.007500),
(826.437500, 826.697500),
(827.277500, 827.307500),
(827.587500, 827.597500),
(827.962500, 828.057500),
(830.477500, 830.612500),
(830.742500, 831.062500),
(831.077500, 831.207500),
(831.437500, 831.722500),
(832.022500, 832.222500),
(832.577500, 832.902500),
(832.917500, 833.037500),
(833.492500, 833.737500),
(835.007500, 835.452500),
(835.692500, 835.692500),
(836.177500, 836.272500),
(836.417500, 836.477500),
(836.742500, 837.052500),
(837.632500, 837.982500),
(838.237500, 838.542500),
(838.592500, 838.647500),
(839.387500, 840.002500),
(840.537500, 840.837500),
(840.857500, 841.137500),
(841.377500, 841.682500),
(841.712500, 841.947500),
(841.992500, 842.017500),
(842.052500, 842.277500),
(842.297500, 842.482500),
(842.507500, 843.502500),
(843.727500, 843.812500),
(848.927500, 849.177500),
(849.937500, 849.957500),
(850.167500, 850.192500),
(851.357500, 851.362500),
(852.687500, 852.727500),
(857.747500, 858.192500),
(860.547500, 860.547500),
(861.307500, 861.607500),
(862.727500, 863.112500),
(866.032500, 866.227500),
(869.027500, 869.112500),
(870.372500, 870.387500),
(875.522500, 875.557500),
(882.832500, 883.287500),
(885.337500, 885.367500),
(886.327500, 886.567500),
(886.697500, 886.777500),
(887.177500, 887.397500),
(887.967500, 888.357500),
(894.322500, 894.407500),
(895.882500, 896.252500),
(900.857500, 900.897500),
(901.247500, 901.327500),
(902.352500, 902.372500),
(908.027500, 908.472500),
(908.652500, 908.867500),
(911.927500, 911.997500),
(918.762500, 918.932500),
(919.602500, 919.687500),
(925.057500, 925.407500),
(926.167500, 926.212500),
(926.312500, 926.497500),
(927.447500, 927.637500),
(932.382500, 932.392500),
(932.897500, 933.422500),
(937.157500, 937.212500),
(944.867500, 944.952500),
(948.667500, 949.037500),
]
[docs]def get_ozone_channels_for_spw(ms, spwid):
"""
For given spectral window in measurement set, compute an array of booleans
where each element corresponds to a channel in the spectral window and
signifies whether that channel falls inside a known atmospheric ozone line.
:param ms: measurement set to inspect
:type ms: :class:`~pipeline.domain.MeasurementSet`
:param spwid: spectral window id to inspect
:type spwid: int
:return: Numpy array of booleans, representing mask of channels where
channels corresponding to ozone lines are set to True.
:rtype: numpy.array[boolean]
"""
# Get spectral window info from MS.
spw = ms.get_spectral_window(spwid)
# Initialize array of channels where ozone lines appear.
oz_chans = np.zeros([spw.num_channels], np.bool)
# For each channel in spw, check if it matches one of the ozone lines.
for ichan, chan_freq in enumerate(spw.channels.chan_freqs):
match = [oz_range for oz_range in OZONE_RANGES
if oz_range[0] <= chan_freq*1.E-9 <= oz_range[1]]
if match:
oz_chans[ichan] = True
# PIPE-131: if the given spectral window came from a double sideband (DSB)
# receiver (e.g. ALMA Band 9 and 10), then check if any of the channels in
# image sideband match the location of ozone lines.
if spw.receiver == "DSB":
LOG.info("DSB receiver found for {}, spw {}: extending the atmospheric line check to the image sideband."
"".format(ms.basename, spwid))
# First derive the frequency range for the image sideband based on the LO1
# frequency and the frequency range of the signal sideband, using:
# image_freq = 2 * LO1 - signal_freq.
imsb_chan_freqs = [decimal.Decimal(2.0) * spw.freq_lo[0].value - decimal.Decimal(freq)
for freq in spw.channels.chan_freqs]
# For each channel in image sideband, check if it matches one of the ozone lines.
for ichan, chan_freq in enumerate(imsb_chan_freqs):
match = [oz_range for oz_range in OZONE_RANGES
if oz_range[0] <= chan_freq * decimal.Decimal(1.0E-9) <= oz_range[1]]
if match:
oz_chans[ichan] = True
return oz_chans