def RM(self, newtime, ra=None, dec=None): """ RM=i.RM(newtime, ra=None, dec=None)) compute Rotation Measure (rad/m**2) along the zenith if ra is None else along the specified direction """ TEC=self.__call__(newtime, ra=ra, dec=dec) if TEC is None: return None Bx,By,Bz=self.getB(newtime) if ra is None: # the important B is the Bz ZenPunc=0 AzPunc=0 else: if not isinstance(ra,astropy.units.quantity.Quantity): ra=angles.Angle(ra,unit=u.degree) if not isinstance(dec,astropy.units.quantity.Quantity): dec=angles.Angle(dec,unit=u.degree) az,el=ephem_utils.radec2azel(ra.degree,dec.degree,newtime) #logger.info('(RA,Dec)=(%.1f,%.1f) deg = (Az,El)=(%.1f,%.1f) deg' % ( # ra.degree,dec.degree,az,el)) az=angles.Angle(az,unit=u.degree) el=angles.Angle(el,unit=u.degree) za=angles.Angle(90,unit=u.degree)-el dLat,dLong,AzPunc,ZenPunc=self.ionosphere_geometry(az,za) # convert the components of B to the B along the LOS # taken from ionFR.py B=Bz*numpy.cos(ZenPunc) + numpy.sin(ZenPunc)*(By*numpy.sin(AzPunc)+Bx*numpy.cos(AzPunc)) # TEC is in 0.1 TECU # B is in G RM=RMconstant*B*TEC*1e15 return RM
def ionosphere_geometry(self,az,za): """ dLat,dLong,AzPunc,ZenPunc=ionosphere_geometry(self.az,za) return the change in Lat,Long and the Az,ZA of the ionosphere puncture quantities are decimal degrees if not explicitly given based on ionFR/ippcoor.PuncIonOffset """ # the zenith angle at the # Ionospheric piercing point if not isinstance(az,astropy.units.quantity.Quantity): az=angles.Angle(az,unit=u.degree) if not isinstance(za,astropy.units.quantity.Quantity): za=angles.Angle(za,unit=u.degree) ZenPunc = numpy.arcsin((c.R_earth*numpy.sin(za))/(c.R_earth + self.height)) theta = za - ZenPunc LatPunc=numpy.arcsin(numpy.sin(numpy.radians(_MWA.lat))*numpy.cos(theta) + numpy.cos(numpy.radians(_MWA.lat))*numpy.sin(theta)*numpy.cos(az)) # latitude difference dLat=LatPunc - _MWA.lat*u.degree # Longitude difference dLong = numpy.arcsin(numpy.sin(az)*numpy.sin(theta)/numpy.cos(LatPunc)) # Azimuth at the IPP AzPunc=numpy.arcsin(numpy.sin(az)*numpy.cos(numpy.radians(_MWA.lat))/numpy.cos(LatPunc)) return dLat,dLong,AzPunc,ZenPunc
def __call__(self, newtime, ra=None, dec=None): """ TEC=i(newtime, ra=None, dec=None) returns the zenith TEC (if ra is None) else the total TEC along the line-of-sight in 0.1*TECU """ if ra is None: return self.interpolate(newtime) else: if not isinstance(ra,astropy.units.quantity.Quantity): ra=angles.Angle(ra,unit=u.degree) if not isinstance(dec,astropy.units.quantity.Quantity): dec=angles.Angle(dec,unit=u.degree) az,el=ephem_utils.radec2azel(ra.degree,dec.degree,newtime) #print '(RA,Dec)=(%.1f,%.1f) deg = (Az,El)=(%.1f,%.1f) deg' % ( # ra.degree,dec.degree,az,el) az=angles.Angle(az,unit=u.degree) el=angles.Angle(el,unit=u.degree) za=angles.Angle(90,unit=u.degree)-el dLat,dLong,AzPunc,ZenPunc=self.ionosphere_geometry(az,za) #print dLat.to(u.degree),dLong.to(u.degree),AzPunc.to(u.degree),ZenPunc.to(u.degree) # return the full line of sight TEC, converting from vertical return self.interpolate(newtime, dlong=dLong, dlat=dLat)/numpy.cos(ZenPunc).value
def get_telescope_params(self): """ Puts the latitude, longitude and elevation of the telescope from the config file into Astropy Angle objects :return: latitude, longitude and elevation of the telescope as Astropy Angle objects """ logger.debug("Retrieving telescope parameters...") self.lat = angles.Angle(self.location.get("location", "latitude")) self.lon = angles.Angle(self.location.get("location", "longitude")) self.elev = float(self.location.get("location", "elevation")) return self.lat, self.lon, self.elev
def interpolate(self, newtime, dlong=0, dlat=0): """ return the zenith TEC interpolated at <newtime> <newtime> can be: astropy.time.Time int (assumed GPStime) datetime.datetime """ if not isinstance(dlong,astropy.units.quantity.Quantity): dlong=angles.Angle(dlong,unit=u.degree) if not isinstance(dlat,astropy.units.quantity.Quantity): dlat=angles.Angle(dlat,unit=u.degree) if self.filename is None: logger.error('Valid IONEX data not loaded') return None if not isinstance(newtime, astropy.time.Time): if isinstance(newtime, int): # assume gpstime newtime=astropy.time.Time(newtime, format='gps',scale='utc') if isinstance(newtime, datetime.datetime): newtime=astropy.time.Time(newtime, scale='utc') #logger.info('Interpolating for %s' % newtime) if not newtime >= self.dates[0]: logger.error('Requested time is not after the start of this data-set') return None if not newtime <= self.dates[-1]: logger.error('Requested time is not before the end of this data-set') return None dt=self.dates-newtime try: ibefore=numpy.where(dt.value<0)[0][-1] except IndexError: ibefore=0 try: iafter=numpy.where(dt.value>=0)[0][0] except IndexError: iafter=len(self.data)-1 if ibefore==0 and iafter==0: iafter=1 latvalue=angles.Angle(_MWA.lat,unit=u.degree)+dlat+angles.Angle(numpy.pi/2,unit=u.radian) lonvalue=angles.Angle(_MWA.long,unit=u.degree)+dlong+angles.Angle(numpy.pi,unit=u.radian) lonvalue_before=lonvalue+angles.Angle(dt[ibefore].jd*2*numpy.pi,unit=u.radian) lonvalue_after=lonvalue-angles.Angle(dt[iafter].jd*2*numpy.pi,unit=u.radian) interpbefore=scipy.interpolate.RectSphereBivariateSpline(numpy.radians(self.lats)+numpy.pi/2,numpy.radians(self.lons)+numpy.pi, self.data[ibefore]) interpafter=scipy.interpolate.RectSphereBivariateSpline(numpy.radians(self.lats)+numpy.pi/2,numpy.radians(self.lons)+numpy.pi, self.data[iafter]) valuebefore=interpbefore(latvalue.radian, lonvalue_before.radian)[0][0] valueafter=interpafter(latvalue.radian, lonvalue_after.radian)[0][0] return numpy.interp(0, [dt[ibefore].jd, dt[iafter].jd], [valuebefore, valueafter])
def getB(self, newtime, dlong=0, dlat=0): """ Bx,By,Bz=i.getB(newtime, dlong=0, dlat=0): return the geomagnetic field in G Bx=north component tangent to surface By=east component tangent to surface Bz=vertical component (-=down, +=up) value at MWA site for given time, shifted by dlong or dlat if specified quantities are decimal degrees if not explicitly given based on the International Geomagnetic Reference Field, 11th generation http://www.ngdc.noaa.gov/IAGA/vmod/igrf.html Geophys. J. Int., Vol 183, Issue 3, pp 1216-1230, December 2010. DOI: 10.1111/j.1365-246X.2010.04804.x. can check with http://www.ngdc.noaa.gov/geomag-web/#igrfwmm """ if not isinstance(dlong,astropy.units.quantity.Quantity): dlong=angles.Angle(dlong,unit=u.degree) if not isinstance(dlat,astropy.units.quantity.Quantity): dlat=angles.Angle(dlat,unit=u.degree) if not isinstance(newtime, astropy.time.Time): if isinstance(newtime, int): # assume gpstime newtime=astropy.time.Time(newtime, format='gps',scale='utc') if isinstance(newtime, datetime.datetime): newtime=astropy.time.Time(newtime, scale='utc') # these are in nT Bx,By,Bz,Bt=igrf11_python.igrf11syn(0, newtime.jyear, 1, self.height.to(u.km).value, 90-(_MWA.lat+angles.Angle(dlat).degree), _MWA.long+angles.Angle(dlong).degree) # convert to G Bx*=1e4*1e-9 By*=1e4*1e-9 Bz*=1e4*1e-9 return Bx,By,Bz
def get_sun(self, obs_time=Time.now()): """ Compute the altitude and azimuth of the moon at the given time :param obs_time: Astropy Time object. If None, use the current time as default. :return: altitude and azimuth angles as Astropy Angle objects """ logger.debug("Computing Sun coordinates...") observer = ephem.Observer() observer.date = obs_time.iso observer.lat, observer.lon, observer.elevation = self.lat.degree, self.lon.degree, self.elev self.sun = ephem.Sun() self.sun.compute(observer) # Warning, ass-coding here: output of sun.ra is different from sun.ra.__str__()... clap clap clap - again alpha = angles.Angle(self.sun.ra.__str__(), unit="hour") delta = angles.Angle(self.sun.dec.__str__(), unit="degree") # return Az, Alt as Angle object return self.get_AzAlt(alpha, delta, obs_time)
def get_AzAlt(self, alpha, delta, obs_time=None, ref_dir=0): """ #todo: can't we do it with astropy as well? idea from http://aa.usno.navy.mil/faq/docs/Alt_Az.php Compute the azimuth and altitude of a source at a given time (by default current time of execution), given its alpha and delta coordinates. :param alpha: Astrophy Angle object, right ascencion of the target you want to translate into altaz :param delta: Astrophy Angle object, declination of the target you want to translate into altaz :param obs_time: Astropy Time object. If None, use the current time as default. :param ref_dir: float, zero point of the azimuth. Default is 0, corresponding to North. :return: altitude and azimuth angles as Astropy Angle objects """ if not obs_time: obs_time = self.time lat, lon, elev = self.lat, self.lon, self.elev # Untouched code from Azimuth.py D = obs_time.jd - 2451545.0 GMST = 18.697374558 + 24.06570982441908 * D epsilon = np.deg2rad(23.4393 - 0.0000004 * D) eqeq = -0.000319 * np.sin( np.deg2rad(125.04 - 0.052954 * D)) - 0.000024 * np.sin( 2. * np.deg2rad(280.47 + 0.98565 * D)) * np.cos(epsilon) GAST = GMST + eqeq GAST -= np.floor(GAST / 24.) * 24. LHA = angles.Angle((GAST - alpha.hour) * 15 + lon.degree, unit="degree") if LHA > 0: LHA += angles.Angle(np.floor(LHA / 360.) * 360., unit="degree") else: LHA -= angles.Angle(np.floor(LHA / 360.) * 360., unit="degree") sina = np.cos(LHA.radian) * np.cos(delta.radian) * np.cos( lat.radian) + np.sin(delta.radian) * np.sin(lat.radian) Alt = angles.Angle(np.arcsin(sina), unit="radian") num = -np.sin(LHA.radian) den = np.tan(delta.radian) * np.cos(lat.radian) - np.sin( lat.radian) * np.cos(LHA.radian) Az = angles.Angle(np.arctan2(num, den), unit="radian") Az -= angles.Angle(ref_dir, unit="degree") # I changed this to get the same angle as the edp, using 0 (North) as reference if Az.degree < 0: Az += angles.Angle(360, unit="degree") return Az, Alt
def fit(self, iters=1): """tempopulsar.fit(iters=1) Runs `iters` iterations of the tempo2 fit, recomputing barycentric TOAs and residuals each time.""" f = fitter.wls_fitter(toas=self.t, model=self.model) for ii in range(iters + 1): f.call_minimize() fitp = f.model.get_params_dict("free", "quantity") # TODO: handle these units correctly for p, val in zip(fitp.keys(), fitp.values()): modval = getattr(f.model, p).value if (not has_astropy_unit(val)) and has_astropy_unit(modval): if type(modval) is ang.Angle: val = ang.Angle(val, unit=modval.unit) else: val = val * modval.unit self[p].val = val