def test_quantity_output(self): q = 500.25 * u.day dt = TimeDelta(q) assert dt.to(u.day) == q assert dt.to(u.second).value == q.to_value(u.second) with pytest.raises(u.UnitsError): dt.to(u.m)
def test_quantity_output(self): q = 500.25*u.day dt = TimeDelta(q) assert dt.to(u.day) == q assert dt.to(u.second).value == q.to_value(u.second) with pytest.raises(u.UnitsError): dt.to(u.m)
def test_quantity_output(self): q = 500.25 * u.day dt = TimeDelta(q) assert dt.to(u.day) == q assert dt.to_value(u.day) == q.value assert dt.to_value('day') == q.value assert dt.to(u.second).value == q.to_value(u.second) assert dt.to_value(u.second) == q.to_value(u.second) assert dt.to_value('s') == q.to_value(u.second) # Following goes through "format", but should be the same. assert dt.to_value('sec') == q.to_value(u.second)
def sample_times( size, rate, dead_time=TimeDelta(0, format="sec"), return_diff=False, random_state="random-seed", ): """Make random times assuming a Poisson process. This function can be used to test event time series, to have a comparison what completely random data looks like. Can be used in two ways (in either case the return type is `~astropy.time.TimeDelta`): * ``return_delta=False`` - Return absolute times, relative to zero (default) * ``return_delta=True`` - Return time differences between consecutive events. Parameters ---------- size : int Number of samples rate : `~astropy.units.Quantity` Event rate (dimension: 1 / TIME) dead_time : `~astropy.units.Quantity` or `~astropy.time.TimeDelta`, optional Dead time after event (dimension: TIME) return_diff : bool Return time difference between events? (default: no, return absolute times) random_state : {int, 'random-seed', 'global-rng', `~numpy.random.RandomState`} Defines random number generator initialisation. Passed to `~gammapy.utils.random.get_random_state`. Returns ------- time : `~astropy.time.TimeDelta` Time differences (second) after time zero. Examples -------- Example how to simulate 100 events at a rate of 10 Hz. As expected the last event occurs after about 10 seconds. >>> from astropy.units import Quantity >>> from gammapy.utils.random import sample_times >>> rate = Quantity(10, 'Hz') >>> times = sample_times(size=100, rate=rate, random_state=0) >>> times[-1] <TimeDelta object: scale='None' format='sec' value=9.186484131475074> """ random_state = get_random_state(random_state) dead_time = TimeDelta(dead_time) scale = (1 / rate).to("s").value time_delta = random_state.exponential(scale=scale, size=size) time_delta += dead_time.to("s").value if return_diff: return TimeDelta(time_delta, format="sec") else: time = time_delta.cumsum() return TimeDelta(time, format="sec")
def random_times( size, rate, dead_time=TimeDelta(0, format="sec"), return_diff=False, random_state="random-seed", ): """Make random times assuming a Poisson process. This function can be used to test event time series, to have a comparison what completely random data looks like. Can be used in two ways (in either case the return type is `~astropy.time.TimeDelta`): * ``return_delta=False`` - Return absolute times, relative to zero (default) * ``return_delta=True`` - Return time differences between consecutive events. Parameters ---------- size : int Number of samples rate : `~astropy.units.Quantity` Event rate (dimension: 1 / TIME) dead_time : `~astropy.units.Quantity` or `~astropy.time.TimeDelta`, optional Dead time after event (dimension: TIME) return_diff : bool Return time difference between events? (default: no, return absolute times) random_state : {int, 'random-seed', 'global-rng', `~numpy.random.RandomState`} Defines random number generator initialisation. Passed to `~gammapy.utils.random.get_random_state`. Returns ------- time : `~astropy.time.TimeDelta` Time differences (second) after time zero. Examples -------- Example how to simulate 100 events at a rate of 10 Hz. As expected the last event occurs after about 10 seconds. >>> from astropy.units import Quantity >>> from gammapy.time import random_times >>> rate = Quantity(10, 'Hz') >>> times = random_times(size=100, rate=rate, random_state=0) >>> times[-1] <TimeDelta object: scale='None' format='sec' value=9.186484131475076> """ random_state = get_random_state(random_state) dead_time = TimeDelta(dead_time) scale = (1 / rate).to("s").value time_delta = random_state.exponential(scale=scale, size=size) time_delta += dead_time.to("s").value if return_diff: return TimeDelta(time_delta, format="sec") else: time = time_delta.cumsum() return TimeDelta(time, format="sec")
def test_scales_for_delta_scale_is_none(self, scale, op): """T(X) +/- dT(None) or T(X) +/- Quantity(time-like) This is always allowed and just adds JDs, i.e., the scale of the TimeDelta or time-like Quantity will be taken to be X. The one exception is again for X=UTC, where TAI is assumed instead, so that a day is always defined as 86400 seconds. """ dt_none = TimeDelta([0., 1., -1., 1000.], format='sec') assert dt_none.scale is None q_time = dt_none.to('s') dt = self.dt[scale] dt1 = op(dt, dt_none) assert dt1.scale == dt.scale assert allclose_jd(dt1.jd, op(dt.jd, dt_none.jd)) dt2 = op(dt_none, dt) assert dt2.scale == dt.scale assert allclose_jd(dt2.jd, op(dt_none.jd, dt.jd)) dt3 = op(q_time, dt) assert dt3.scale == dt.scale assert allclose_jd(dt3.jd, dt2.jd) t = self.t[scale] t1 = op(t, dt_none) assert t1.scale == t.scale assert allclose_jd(t1.jd, op(t.jd, dt_none.jd)) if op is operator.add: t2 = op(dt_none, t) assert t2.scale == t.scale assert allclose_jd(t2.jd, t1.jd) t3 = op(t, q_time) assert t3.scale == t.scale assert allclose_jd(t3.jd, t1.jd)
def test_quantity_output_errors(self): dt = TimeDelta(250., format='sec') with pytest.raises(u.UnitsError): dt.to(u.m) with pytest.raises(u.UnitsError): dt.to_value(u.m) with pytest.raises(u.UnitsError): dt.to_value(unit=u.m) with pytest.raises(ValueError, match=("not one of the known formats.*" "failed to parse as a unit")): dt.to_value('parrot') with pytest.raises(TypeError): dt.to_value('sec', unit=u.s) with pytest.raises(TypeError): # TODO: would be nice to make this work! dt.to_value(u.s, subfmt='str')
def test_valid_quantity_operations2(self): """Check that TimeDelta is treated as a quantity where possible.""" t0 = TimeDelta(100000., format='sec') f = 1. / t0 assert isinstance(f, u.Quantity) assert f.unit == 1. / u.day g = 10. * u.m / u.second**2 v = t0 * g assert isinstance(v, u.Quantity) assert u.allclose(v, t0.sec * g.value * u.m / u.second) q = np.log10(t0 / u.second) assert isinstance(q, u.Quantity) assert q.value == np.log10(t0.sec) s = 1. * u.m v = s / t0 assert isinstance(v, u.Quantity) assert u.allclose(v, 1. / t0.sec * u.m / u.s) t = 1. * u.s t2 = t0 * t assert isinstance(t2, u.Quantity) assert u.allclose(t2, t0.sec * u.s**2) t3 = [1] / t0 assert isinstance(t3, u.Quantity) assert u.allclose(t3, 1 / (t0.sec * u.s)) # broadcasting t1 = TimeDelta(np.arange(100000., 100012.).reshape(6, 2), format='sec') f = np.array([1., 2.]) * u.cycle * u.Hz phase = f * t1 assert isinstance(phase, u.Quantity) assert phase.shape == t1.shape assert u.allclose(phase, t1.sec * f.value * u.cycle) q = t0 * t1 assert isinstance(q, u.Quantity) assert np.all(q == t0.to(u.day) * t1.to(u.day)) q = t1 / t0 assert isinstance(q, u.Quantity) assert np.all(q == t1.to(u.day) / t0.to(u.day))
def test_valid_quantity_operations2(self): """Check that TimeDelta is treated as a quantity where possible.""" t0 = TimeDelta(100000., format='sec') f = 1./t0 assert isinstance(f, u.Quantity) assert f.unit == 1./u.day g = 10.*u.m/u.second**2 v = t0 * g assert isinstance(v, u.Quantity) assert u.allclose(v, t0.sec * g.value * u.m / u.second) q = np.log10(t0/u.second) assert isinstance(q, u.Quantity) assert q.value == np.log10(t0.sec) s = 1.*u.m v = s/t0 assert isinstance(v, u.Quantity) assert u.allclose(v, 1. / t0.sec * u.m / u.s) t = 1.*u.s t2 = t0 * t assert isinstance(t2, u.Quantity) assert u.allclose(t2, t0.sec * u.s ** 2) t3 = [1] / t0 assert isinstance(t3, u.Quantity) assert u.allclose(t3, 1 / (t0.sec * u.s)) # broadcasting t1 = TimeDelta(np.arange(100000., 100012.).reshape(6, 2), format='sec') f = np.array([1., 2.]) * u.cycle * u.Hz phase = f * t1 assert isinstance(phase, u.Quantity) assert phase.shape == t1.shape assert u.allclose(phase, t1.sec * f.value * u.cycle) q = t0 * t1 assert isinstance(q, u.Quantity) assert np.all(q == t0.to(u.day) * t1.to(u.day)) q = t1 / t0 assert isinstance(q, u.Quantity) assert np.all(q == t1.to(u.day) / t0.to(u.day))
def test_delta_day_is_86400_seconds(self, scale): """TimeDelta or Quantity holding 1 day always means 24*60*60 seconds This holds true for all timescales but UTC, for which leap-second days are longer or shorter by one second. """ t = self.t[scale] dt_day = TimeDelta(1., format='jd') q_day = dt_day.to('day') dt_day_leap = t[-1] - t[0] # ^ = exclusive or, so either equal and not UTC, or not equal and UTC assert allclose_jd(dt_day_leap.jd, dt_day.jd) ^ (scale == 'utc') t1 = t[0] + dt_day assert allclose_jd(t1.jd, t[-1].jd) ^ (scale == 'utc') t2 = q_day + t[0] assert allclose_jd(t2.jd, t[-1].jd) ^ (scale == 'utc') t3 = t[-1] - dt_day assert allclose_jd(t3.jd, t[0].jd) ^ (scale == 'utc') t4 = t[-1] - q_day assert allclose_jd(t4.jd, t[0].jd) ^ (scale == 'utc')
curtime = starttime while curtime <= endtime: tpos, tvel = get_body_barycentric_posvel(body, curtime) # convert positions to light seconds pos.append(tpos.xyz.to('m')/const.c) # convert velocities to light seconds per second vel.append(tvel.xyz.to('m/s')/const.c) # calculate accelerations (using velocities +/- dt/2 around the current time) ctminus = curtime - dt/2. _, mvel = get_body_barycentric_posvel(body, ctminus) ctplus = curtime + dt/2. _, pvel = get_body_barycentric_posvel(body, ctplus) acc.append(((pvel.xyz.to('m/s')-mvel.xyz.to('m/s'))/const.c)/dt.to('s')) curtime += dt # set output header headdic = {} headdic['exec'] = os.path.basename(sys.argv[0]) headdic['author'] = __author__ headdic['gitid'] = __id__ headdic['gitbranch'] = __branch__ headdic['gitdate'] = __date__ headdic['command'] = ' '.join([os.path.basename(sys.argv[0])]+sys.argv[1:]) headdic['ephem'] = args.ephemeris.upper() headdic['ephemurl'] = ephemfile outfile = args.output
hpc_x = np.zeros_like(hpc_y) ############################################################################## # Let's define how many days in the future we want to rotate to. dt = TimeDelta(4 * u.day) future_date = aia_map.date + dt ############################################################################## # Now let's plot the original and rotated positions on the AIA map. fig = plt.figure() ax = fig.add_subplot(projection=aia_map) aia_map.plot(axes=ax, clip_interval=(1, 99.99) * u.percent) ax.set_title('The effect of {} days of differential rotation'.format( dt.to(u.day).value)) aia_map.draw_grid(axes=ax) for this_hpc_x, this_hpc_y in zip(hpc_x, hpc_y): start_coord = SkyCoord(this_hpc_x, this_hpc_y, frame=aia_map.coordinate_frame) rotated_coord = solar_rotate_coordinate(start_coord, time=future_date) coord = SkyCoord([start_coord.Tx, rotated_coord.Tx], [start_coord.Ty, rotated_coord.Ty], frame=aia_map.coordinate_frame) ax.plot_coord(coord, 'o-') ax.set_ylim(0, aia_map.data.shape[1]) ax.set_xlim(0, aia_map.data.shape[0]) plt.show()
class MSParset(object): """ """ def __init__(self, **kwargs): self.msname = 'noname.ms' self.savepath = '' self.antennatable = 'nenufar' self.ra = 0 * u.deg self.dec = 90 * u.deg self.f0 = 50 * u.MHz self.df = 0.1953125 * u.MHz self.nf = 16 self.nbands = 16 self.t0 = Time.now() self.dt = TimeDelta(1, format='sec') self.nt = 10 self._fill_attr(kwargs) # --------------------------------------------------------- # # --------------------- Getter/Setter --------------------- # @property def msname(self): return self._msname @msname.setter def msname(self, m): if basename(m) != m: raise ValueError( 'Just provide the MS name, path is `savepath`' ) if not m.endswith('.ms'): raise ValueError( 'msname should ends with .ms' ) self._msname = m return @property def savepath(self): return self._savepath @savepath.setter def savepath(self, s): s = abspath(s) if not isdir(s): raise NotADirectoryError( '{} not found'.format(s) ) self._savepath = s return @property def antennatable(self): return self._antennatable @antennatable.setter def antennatable(self, a): if a.lower() == 'nenufar': a = nenufar_antennas else: raise ValueError( 'Unexpected antenna distribution' ) self._antennatable = a return @property def nbands(self): return self._nbands @nbands.setter def nbands(self, n): if not isinstance(n, int): raise TypeError( 'nbands should be integer' ) self._nbands = n return @property def nf(self): return self._nf @nf.setter def nf(self, n): if not isinstance(n, int): raise TypeError( 'nf should be integer' ) self._nf = n return @property def nt(self): return self._nt @nt.setter def nt(self, n): if not isinstance(n, int): raise TypeError( 'nt should be integer' ) self._nt = n return @property def t0(self): return self._t0 @t0.setter def t0(self, t): if not isinstance(t, Time): t = Time(t) self._t0 = t return @property def dt(self): return self._dt @dt.setter def dt(self, d): if not isinstance(d, TimeDelta): d = TimeDelta(d, format='sec') self._dt = d return @property def ra(self): return self._ra @ra.setter def ra(self, r): if not isinstance(r, u.Quantity): r = float(r) r *= u.deg self._ra = r.to(u.deg) return @property def dec(self): return self._dec @dec.setter def dec(self, d): if not isinstance(d, u.Quantity): d = float(d) d *= u.deg self._dec = d.to(u.deg) return @property def f0(self): return self._f0 @f0.setter def f0(self, f): if not isinstance(f, list): f = [f] if not all([isinstance(fi, u.Quantity) for fi in f]): f = [float(fi) * u.MHz for fi in f] self._f0 = [fi.to(u.Hz) for fi in f] return @property def df(self): return self._df @df.setter def df(self, d): if not isinstance(d, u.Quantity): d = float(d) d *= u.MHz self._df = d.to(u.Hz) return # --------------------------------------------------------- # # ------------------------ Methods ------------------------ # def check_conformity(self): """ Once all attributes are set, this verifies that everything is convenient for being a makems parset. """ conform = True if self.nf % self.nbands != 0: log.warning( 'nf must be divisible by nbands' ) conform *= False try: phase_center = to_skycoord((self.ra, self.dec)) except ValueError: log.warning( 'ra and dec are not properly set' ) conform *= False if self.antennatable.endswith('.zip'): with zipfile.ZipFile(self.antennatable) as zipf: zipf.extractall(self.savepath) self._anttable = join( self.savepath, basename(self.antennatable).replace('.zip', '') ) log.info( 'Antenna table {} created.'.format( self._anttable ) ) else: log.warning( 'antenna table is expected as a zip file' ) conform *= False if (len(self.f0) != 1) and (len(self.f0) != self.nbands): log.warning( 'f0 sould either have a length=1 or =nbands' ) conform *= False return bool(conform) def write_parset(self): """ """ if not self.check_conformity(): raise Exception( 'Attributes are not properly filled.' ) log.info( 'Parameters conform for empty MS creation' ) config = { 'MSName': join(self.savepath, self.msname), 'VDSPath': self.savepath, 'AntennaTableName': self._anttable, 'WriteImagerColumns': 'T', 'WriteAutoCorr': 'T', 'Declination': '{}rad'.format( self.dec.to(u.rad).value ), 'RightAscension': '{}rad'.format( self.ra.to(u.rad).value ), 'StartFreq': [fi.to(u.Hz).value for fi in self.f0], 'StepFreq': self.df.to(u.Hz).value, 'NFrequencies': self.nf, 'NBands': self.nbands, 'StartTime': self.t0.isot.replace('T', '/'), 'StepTime': self.dt.to(u.s).value, 'NTimes': self.nt } parsetfile = join(self.savepath, 'makems.cfg') parset = open(parsetfile, 'w') for key in config.keys(): parset.write( '{} = {}\n'.format(key, config[key]) ) parset.close() log.info( 'Parset {} written'.format(parsetfile) ) return # --------------------------------------------------------- # # ----------------------- Internal ------------------------ # def _fill_attr(self, kwargs): """ """ for key, val in kwargs.items(): if hasattr(self, key): setattr(self, key, val) return
hpc_y = np.arange(-700, 800, 100) * u.arcsec hpc_x = np.zeros_like(hpc_y) ############################################################################## # Let's define how many days in the future we want to rotate to dt = TimeDelta(4*u.day) future_date = aia_map.date + dt ############################################################################## # Now let's plot the original and rotated positions on the AIA map. fig = plt.figure() ax = plt.subplot(projection=aia_map) aia_map.plot() ax.set_title('The effect of {} days of differential rotation'.format(dt.to(u.day).value)) aia_map.draw_grid() for this_hpc_x, this_hpc_y in zip(hpc_x, hpc_y): start_coord = SkyCoord(this_hpc_x, this_hpc_y, frame=aia_map.coordinate_frame) rotated_coord = solar_rotate_coordinate(start_coord, time=future_date) coord = SkyCoord([start_coord.Tx, rotated_coord.Tx], [start_coord.Ty, rotated_coord.Ty], frame=aia_map.coordinate_frame) ax.plot_coord(coord, 'o-') plt.ylim(0, aia_map.data.shape[1]) plt.xlim(0, aia_map.data.shape[0]) plt.show()
while curtime <= endtime: tpos, tvel = get_body_barycentric_posvel(body, curtime) # convert positions to light seconds pos.append(tpos.xyz.to('m') / const.c) # convert velocities to light seconds per second vel.append(tvel.xyz.to('m/s') / const.c) # calculate accelerations (using velocities +/- dt/2 around the current time) ctminus = curtime - dt / 2. _, mvel = get_body_barycentric_posvel(body, ctminus) ctplus = curtime + dt / 2. _, pvel = get_body_barycentric_posvel(body, ctplus) acc.append( ((pvel.xyz.to('m/s') - mvel.xyz.to('m/s')) / const.c) / dt.to('s')) curtime += dt # set output header headdic = {} headdic['exec'] = os.path.basename(sys.argv[0]) headdic['author'] = __author__ headdic['gitid'] = __id__ headdic['gitbranch'] = __branch__ headdic['gitdate'] = __date__ headdic['command'] = ' '.join([os.path.basename(sys.argv[0])] + sys.argv[1:]) headdic['ephem'] = args.ephemeris.upper() headdic['ephemurl'] = ephemfile
hpc_y = u.Quantity(np.arange(-700, 800, 100), u.arcsec) hpc_x = np.zeros_like(hpc_y) ############################################################################## # Let's define how many days in the future we want to rotate to dt = TimeDelta(4*u.day) future_date = aia_map.date + dt ############################################################################## # Now let's plot the original and rotated positions on the AIA map. fig = plt.figure() ax = plt.subplot(projection=aia_map) aia_map.plot() ax.set_title('The effect of {0} days of differential rotation'.format(dt.to(u.day).value)) aia_map.draw_grid() for this_hpc_x, this_hpc_y in zip(hpc_x, hpc_y): start_coord = SkyCoord(this_hpc_x, this_hpc_y, frame=aia_map.coordinate_frame) rotated_coord = solar_rotate_coordinate(start_coord, time=future_date) coord = SkyCoord([start_coord.Tx, rotated_coord.Tx], [start_coord.Ty, rotated_coord.Ty], frame=aia_map.coordinate_frame) ax.plot_coord(coord, 'o-') plt.ylim(0, aia_map.data.shape[1]) plt.xlim(0, aia_map.data.shape[0]) plt.show()