def test_creation(self): float_val = 10.0 angle = VAngle(float_val) self.assertEqual(float_val, angle.deg) self.assertEqual(angle.original_unit, u.degree) copied = VAngle(angle) self.assertEqual(angle.radian, copied.radian)
def __init__(self, start, stop, duration, offset=Coord(HOR, VAngle(1), VAngle(0))): """ @param start: elevation start @type start: VAngle @param stop: elevation stop @type stop: stop @param duration: skydip duration @type duration: seconds @param offset: skydip offset from specified target @type offset: frame.Coord """ ScanMode.__init__(self) self.start = start self.stop = stop self.duration = duration self.offset = offset # The minimum observation is composed of 2 subscans # one sidereal subscan to position the antenna in # proximity of the source, and one OTF subscan to perform # the skydip acquisition self.unit_subscans = 2
def _do_scan(self, _target, _receiver, _frequency): _subscans = [] for element in self.sequence: if element[1] == "on": #ON SOURCE ss = subscan.get_sidereal(_target, Coord(self.offset_frame, VAngle(0.0), VAngle(0.0)), self.duration, is_cal=element[2]) elif element[1] == "off": #OFF SOURCE ss = subscan.get_sidereal(_target, Coord(self.offset_frame, self.offset_lon, self.offset_lat), self.duration, is_cal=element[2]) else: raise ScheduleError("unknown onoff position: %s" % (element[1], )) #TSYS is calculated at off position st = subscan.get_tsys( _target, Coord(self.offset_frame, self.offset_lon, self.offset_lat)) for repetitions in range(element[0]): _subscans.append((ss, st)) return _subscans
def test_ceil_to_odd_valid_angle(self): a = VAngle(4.2) b = utils.ceil_to_odd(a) self.assertEqual(a.original_unit, b.original_unit) self.assertEqual(a.sexa, b.sexa) self.assertEqual(b.deg, 5) a = VAngle(5.2) b = utils.ceil_to_odd(a) self.assertEqual(b.deg, 7)
def _do_scan(self, _target, _receiver, _frequency): beamsize = VAngle(_receiver.get_beamsize(max(_frequency))) _subscans = [] #Fill informations for each OTF subscan in the 4 directions #This is a default implementation, maybe one day we could parametrize #this if needed for _const_axis, _direction in [('LON', 'INC'), ('LAT', 'INC')]: _subscans.append( subscan.get_cen_otf_tsys(_target, self.duration, self.length, VAngle(0.0), _const_axis, _direction, self.frame, beamsize)) return _subscans
def _do_scan(self, _target, _receiver, _frequency): beamsize = VAngle(_receiver.get_beamsize(max(_frequency))) _subscans = [] null_offset = Coord(_target.coord.frame, VAngle(0), VAngle(0)) _subscans.append((subscan.get_sidereal(_target, null_offset, 0, is_cal=False), subscan.get_tsys(_target, null_offset))) _subscans.append( subscan.get_skydip_tsys(_subscans[0][0].ID, _target, self.duration, self.start, self.stop, self.offset)) return _subscans
def test_sum_keeps_attributes(self): a = VAngle(10.0) b = VAngle(15.0) c = a + b d = VAngle(1, unit=u.hour) e = d + a self.assertTrue(hasattr(c, "original_unit")) self.assertTrue(hasattr(c, "sexa")) self.assertEqual(a.original_unit, c.original_unit) self.assertEqual(a.sexa, c.sexa) self.assertTrue(hasattr(e, "original_unit")) self.assertTrue(hasattr(e, "sexa")) self.assertEqual(d.original_unit, e.original_unit) self.assertEqual(d.sexa, e.sexa) self.assertNotEqual(a.original_unit, e.original_unit) self.assertNotEqual(a.sexa, e.sexa)
def test_parsing(self): ang = VAngle(15.0) dec = angle_parser.check_angle("15.0d") dms = angle_parser.check_angle("15:00:00.0") hms = angle_parser.check_angle("01:00:00.0h") self.assertEqual(ang.radian, dec.radian) self.assertEqual(ang.radian, dms.radian) self.assertEqual(ang.radian, hms.radian) dms_neg = angle_parser.check_angle("-15:00:00.0") self.assertEqual(ang.radian, -dms_neg.radian) dms_neg_zero = angle_parser.check_angle("-00:00:03.0") assert(dms_neg_zero.radian < 0)
def test_parse_file(self): targets = target_parser.parse_file(TARGETS_PATH) self.assertNotEqual(targets, []) t_zero, scan_zero, _, _ = targets[0] self.assertEqual(t_zero.label, "Alpha") self.assertEqual(scan_zero, "EqCross1_3") self.assertEqual(t_zero.coord.lon.fmt(), "12:00:00.0000h") t_gamma, _, _, _ = targets[8] self.assertEqual(t_gamma.tsys, 2) self.assertEqual(t_gamma.repetitions, 4) t_offset, _, _, _ = targets[9] self.assertEqual(t_offset.offset_coord.lon, VAngle(-0.5))
def test_validate_configuration(self): conf = validate_configuration(CONF_PATH) self.assertNotEqual(conf, {}) self.assertEqual(conf['projectID'], "ProjectName") self.assertNotEqual(conf['scantypes'], []) #Here we also test scans creation cross_scan = conf['scantypes']['EqCross1_3'] self.assertEqual(cross_scan.length, VAngle(0.4)) onoff_scan = conf['scantypes']['OnOff'] self.assertIsInstance(onoff_scan, ScanMode) self.assertIsInstance(onoff_scan, OnOffScan) self.assertEqual(onoff_scan.unit_subscans, 10)
def setUp(self): self._recv = Receiver("TEST", 0, 100, [[0.0, 100.0], [5.0, 5.0]], nfeed=7, npols=2, has_derotator=True) self._recv.feed_extent = VAngle(30) self._recv.interleave = VAngle(10) self._srecv = Receiver("TEST", 0, 100, [[0.0, 100.0], [5.0, 5.0]], nfeed=1, npols=2, has_derotator=False) self._length_x = VAngle(150) self._length_y = VAngle(150) self._spacing = VAngle(1) self._scans_per_beam = 5 self._scan_fixed = maps.MapScan(EQ, "TL", "LON", self._length_x, self._length_y, self._spacing) self._scan_dynamic = maps.MapScan(EQ, "TL", "LON", self._length_x, self._length_y, self._scans_per_beam)
def ceil_to_odd(dec): """ @param dec: a floating point number or angle @type dec: VAngle or float @return: the minor integer odd number greater then dec. """ _ceil = np.ceil(dec) #TODO: there must be a better way for broadcasting divmod operations to all #types if isinstance(dec, VAngle): _is_angle = True _is_even = (_ceil.value % 2 == 0) else: _is_angle = False _is_even = (_ceil % 2 == 0) if _is_even: if _is_angle: return _ceil + VAngle(1) else: return _ceil + 1 else: return _ceil
def test_sum_dec_hms(self): a = VAngle(10.0) b = VAngle(1, unit=u.hour) c = a + b self.assertEqual(c.deg, a.deg + b.deg)
def _get_spacing(self, receiver, frequency): self.beamsize = VAngle(receiver.get_beamsize(max(frequency))) if receiver.is_multifeed() and receiver.has_derotator: #we can exploit multifeed derotator optimization logger.info( "applying multifeed derotator optimization for map generation") if not isinstance(self.spacing, VAngle): approx_spacing = self.beamsize / self.spacing scans_per_interleave = ceil(receiver.interleave / approx_spacing) if not scans_per_interleave == self.spacing: #logger.warning("Rounding to {0} scans per interleave".format(scans_per_interleave)) pass self.spacing = receiver.interleave / scans_per_interleave logger.info("Spacing subscans by {0}".format(self.spacing)) else: if (self.spacing > (receiver.interleave / 2)): logger.warning( "Spacing is too high, map will be undersampled") scans_per_interleave = floor(receiver.interleave / self.spacing) #this is necessary for tsys and offsets self.beamsize = receiver.feed_extent * 2 if scans_per_interleave == 0: #logger.warning("Spacing is too high for this receiver") raise ScanError("Spacing is too high for this receiver") #scans_per_interleave = 1 #self.spacing = 0 major_spacing = receiver.feed_extent * 2 self.dimension_x = 0 self.offset_x = [] self.dimension_y = 0 self.offset_y = [] if self.scan_axis == "LON": _offset_x = (-1 * (self.length_x / 2)) - receiver.feed_extent while _offset_x <= (self.length_x / 2 + receiver.feed_extent): self.offset_x.append(_offset_x) _offset_x = _offset_x + self.spacing _offset_y = (-1 * (self.length_y / 2)) + receiver.feed_extent while _offset_y <= (self.length_y / 2 + receiver.feed_extent): for i in range(int(scans_per_interleave)): self.offset_y.append(_offset_y) _offset_y = _offset_y + self.spacing #self.offset_y.append(_offset_y + i * self.spacing) _offset_y = _offset_y + major_spacing else: #self.scan_axis == "LAT" _offset_x = (-1 * (self.length_x / 2)) + receiver.feed_extent while _offset_x <= (self.length_x / 2 + receiver.feed_extent): for i in range(int(scans_per_interleave)): self.offset_x.append(_offset_x) _offset_x = _offset_x + self.spacing #self.offset_x.append(_offset_x + i * self.spacing) _offset_x = _offset_x + major_spacing _offset_y = (-1 * (self.length_y / 2)) - receiver.feed_extent while _offset_y <= (self.length_y / 2 + receiver.feed_extent): self.offset_y.append(_offset_y) _offset_y = _offset_y + self.spacing self.dimension_x = len(self.offset_x) self.dimension_y = len(self.offset_y) else: super(RasterMapScan, self)._get_spacing(receiver, frequency)
def _get_spacing(self, receiver, frequency): self.beamsize = VAngle(receiver.get_beamsize(max(frequency))) if receiver.is_multifeed() and receiver.has_derotator: #we can exploit multifeed derotator optimization logger.info( "applying multifeed derotator optimization for map generation") if not isinstance(self.spacing, VAngle): approx_spacing = self.beamsize / self.spacing scans_per_interleave = ceil(receiver.interleave / approx_spacing) if not scans_per_interleave == self.spacing: #logger.warning("Rounding to {0} scans per interleave".format(scans_per_interleave)) pass self.spacing = receiver.interleave / scans_per_interleave logger.info("Spacing subscans by {0}".format(self.spacing)) else: if (self.spacing > (receiver.interleave / 2)): logger.warning( "Spacing is too high, map will be undersampled") scans_per_interleave = floor(receiver.interleave / self.spacing) #this is necessary for tsys and offsets self.beamsize = receiver.feed_extent * 2 if scans_per_interleave == 0: logger.warning("Spacing is too high for this receiver") scans_per_interleave = 1 self.spacing = 0 major_spacing = receiver.feed_extent * 2 + receiver.interleave + self.spacing _offset_x = (-1 * (self.length_x / 2)) + receiver.feed_extent self.dimension_x = 0 self.offset_x = [] while _offset_x <= (self.length_x / 2 + receiver.feed_extent): for i in range(int(scans_per_interleave)): self.offset_x.append(_offset_x + i * self.spacing) _offset_x = _offset_x + major_spacing self.dimension_x = len(self.offset_x) _offset_y = (-1 * (self.length_y / 2)) + receiver.feed_extent self.dimension_y = 0 self.offset_y = [] while _offset_y <= (self.length_y / 2 + receiver.feed_extent): for i in range(int(scans_per_interleave)): self.offset_y.append(_offset_y + i * self.spacing) _offset_y = _offset_y + major_spacing self.dimension_y = len(self.offset_y) else: if not isinstance(self.spacing, VAngle): self.spacing = self.beamsize / self.spacing self.dimension_x = utils.ceil_to_odd(self.length_x.deg / self.spacing.deg + 1) self.dimension_y = utils.ceil_to_odd(self.length_y.deg / self.spacing.deg + 1) logger.debug("Scan {0:d} dim_x {1:f} dim_y {2:f}".format( self.ID, self.dimension_x, self.dimension_x)) self.offset_x = [ i * self.spacing for i in range(int(-1 * (self.dimension_x // 2)), int((self.dimension_x // 2) + 1)) ] self.offset_y = [ i * self.spacing for i in range(int(-1 * (self.dimension_y // 2)), int((self.dimension_y // 2) + 1)) ]
def test_parsing_dec(self): ang = angle_parser.check_dec_angle("15.0d") self.assertEqual(ang.deg, VAngle(15.0).deg)
def test_parsing_hour(self): ang = angle_parser.check_hms_angle("01:00:00.0h") self.assertAlmostEqual(ang.deg, VAngle(15.0).deg)
def test_fmt_dec(self): ang = VAngle(15.0) self.assertEqual(ang.fmt_dec(), u"15.0000d")
def test_parsing_deg(self): ang = angle_parser.check_dms_angle("15:00:00.0") self.assertEqual(ang.deg, VAngle(15.0).deg)
def test_fmt_dms(self): ang = VAngle(15.0) self.assertEqual(ang.fmt_dms(), u"15:00:00.0000")
def test_fmt_hms(self): ang = VAngle(15.0) _str = ang.fmt_hms() self.assertEqual(_str, u"01:00:00.0000h")
def test_get_beamsize(self): beamsize = VAngle(self.receiver.beamsize) self.assertTrue(beamsize >= VAngle(0))
def test_fmt_dec_neg(self): ang = VAngle(-15.0) self.assertEqual(ang.fmt_dec(), u"-15.0000d")
def test_sum_is_vangle(self): a = VAngle(10.0) b = VAngle(5.0) c = a + b self.assertTrue(isinstance(c, type(a)))
def test_sum(self): a = VAngle(10.0) b = VAngle(5.0) c = a + b self.assertEqual(c.deg, a.deg + b.deg)