def altaz(self): ''' outputs RM data from altaz calculation Returns ------- tuple: array[float]: parallel B field array array[float]: RM data array[float]: RM error data ''' self.RMs = {} self.dRMs = {} self.B_paras = {} self.TEC = {} self.dTEC = {} alt_src, az_src = self._hp_arr() zen_src , _ = hp.pix2ang(self.nside, np.arange(self.npix)) az_src = np.degrees(az_src) zen_src = np.degrees(zen_src) for uday in self.day_groups: group = self.day_groups[uday] time_strs = [item.split(' ')[1] for item in group] UTs_dec = [] for time_str in time_strs: Hr, Min, Sec = [float(x) for x in time_str.split(':')] dec_hour = Hr + Min / 60. + Sec / 3600. UTs_dec.append(dec_hour) year, month, day = [int(x) for x in uday.split('-')] tec_a, rms_a, ion_height, TEC = self.ionex_data(year, month, day) tec_hp = itp.ionex2healpix(tec_a, UTs_dec, TEC['lat'], TEC['lon']) rms_hp = itp.ionex2healpix(rms_a, UTs_dec, TEC['lat'], TEC['lon']) coord_lat, coord_lon, az_punct, zen_punct = phys.ipp(self.lat_str, self.lon_str, az_src, zen_src, ion_height) #XXX B_para calculated per DAY B_para = phys.B_IGRF(year, month, day, coord_lat, coord_lon, ion_height, az_punct, zen_punct) RMs = [] dRMs = [] for ui,UT in enumerate(UTs_dec): TEC_path, RMS_TEC_path = itp.get_los_tec(tec_hp[ui], rms_hp[ui], coord_lat, coord_lon, zen_punct) RM_ut = phys.RotationMeasure(TEC_path, B_para) dRM_ut = phys.RotationMeasure(RMS_TEC_path, B_para) RMs.append(RM_ut) dRMs.append(dRM_ut) self.RMs.update({key:RMs[ti] for ti, key in enumerate(group)}) self.dRMs.update({key:dRMs[ti] for ti, key in enumerate(group)}) self.B_paras[uday] = B_para self.TEC.update({key:tec_hp[ti] for ti,key in enumerate(group)}) self.dTEC.update({key:rms_hp[ti] for ti,key in enumerate(group)})
def altaz(self): ''' outputs RM data from altaz calculation Returns ------- tuple: array[float]: parallel B field array array[float]: RM data array[float]: RM error data ''' rm_s = [] drm_s = [] b_para_s = [] alt_src, az_src = self._hp_arr() zen_src = 90. - alt_src for date in self.times: date_str, _, _ = str(date).partition('T') RM_dir = self.make_rm_dir(date_str) year, month, day = map(int, date_str.split('-')) tec_hp, rms_hp, ion_height = self.ionex_data(year, month, day) coord_lat, coord_lon, az_punct, zen_punct = phys.ipp( self.lat_str, self.lon_str, az_src, zen_src, ion_height) #XXX B_para calculated per DAY B_para = phys.B_IGRF(year, month, day, coord_lat, coord_lon, ion_height, az_punct, zen_punct) RMs = [] dRMs = [] for ui, UT in enumerate(self.UTs): hour = utils.std_hour(UT) radec_file = os.path.join(RM_dir, 'radec{hour}.txt'.format(hour=hour)) utils.write_radec(UT, radec_file, alt_src, az_src, date_str, self.location) #UTs are integer distances apart. Would an enumeration be better? TEC_path, RMS_TEC_path = itp.get_los_tec( tec_hp[ui], rms_hp[ui], coord_lat, coord_lon, zen_punct) new_file = os.path.join(RM_dir, 'IonRM{hour}.txt'.format(hour=hour)) utils.write_RM(hour, new_file, B_para, TEC_path, RMS_TEC_path) _, _, _, RM_ut, dRM_ut = np.loadtxt(new_file, unpack=True) RMs.append(RM_ut) dRMs.append(dRM_ut) rm_s.append(RMs) drm_s.append(dRMs) b_para_s.append(B_para) self.RMs = np.array(rm_s) self.dRMs = np.array(drm_s) self.B_paras = np.array(b_para_s)
def calc_ionRIME_rm(self, verbose=False): # angle logic hpxidx = np.arange(self.npix) theta, phi = hp.pix2ang(self.nside, hpxidx) R = hp.rotator.Rotator(rot=[0,-120.712]) zen, az = R(theta, phi) az[az < 0] += 2. * np.pi # az = -az zen_src = np.degrees(zen) az_src = np.degrees(az) # setup storage self.RMs = {} self.dRMs = {} self.B_paras = {} self.TEC = {} self.dTEC = {} for uday in self.day_groups: # time logic group = self.day_groups[uday] time_strs = [item.split(' ')[1] for item in group] UTs_dec = [] for time_str in time_strs: Hr, Min, Sec = [float(x) for x in time_str.split(':')] dec_hour = Hr + Min / 60. + Sec / 3600. UTs_dec.append(dec_hour) year, month, day = [int(x) for x in uday.split('-')] tec_a, rms_a, ion_height, TEC = self.ionex_data(year, month, day) tec_hp = itp.ionex2healpix(tec_a, UTs_dec, TEC['lat'], TEC['lon']) rms_hp = itp.ionex2healpix(rms_a, UTs_dec, TEC['lat'], TEC['lon']) coord_lat, coord_lon, az_punct, zen_punct = phys.ipp(self.lat_str, self.lon_str, az_src, zen_src, ion_height) #XXX B_para calculated per DAY B_para = phys.B_IGRF(year, month, day, coord_lat, coord_lon, ion_height, az_punct, zen_punct) RMs = [] dRMs = [] for ui,UT in enumerate(UTs_dec): TEC_path, RMS_TEC_path = itp.get_los_tec(tec_hp[ui], rms_hp[ui], coord_lat, coord_lon, zen_punct) RM_ut = phys.RotationMeasure(TEC_path, B_para) dRM_ut = phys.RotationMeasure(RMS_TEC_path, B_para) RMs.append(RM_ut) dRMs.append(dRM_ut) self.RMs.update({key:RMs[ti] for ti, key in enumerate(group)}) self.dRMs.update({key:dRMs[ti] for ti, key in enumerate(group)}) self.B_paras[uday] = B_para self.TEC.update({key:tec_hp[ti] for ti,key in enumerate(group)}) self.dTEC.update({key:rms_hp[ti] for ti,key in enumerate(group)})
def _test_ionosphere_map(date_str='2004-05-19T00:00:00'): # date_str = '2004-05-19T00:00:00' lat_str = '30d43m17.5ss' lon_str = '21d25m41.9se' year, month, day = date_str.split('T')[0].split('-') tec_hp, rms_hp, ion_height = inx.IONEX_data(year, month, day, verbose=False) nside_in = 2**4 npix_in = hp.nside2npix(nside_in) hpxidx = np.arange(npix_in) za, az = hp.pix2ang(nside_in, hpxidx) lat, lon, az_p, za_p = phys.ipp(lat_str, lon_str, np.degrees(az), np.degrees(za), ion_height) B_para = phys.B_IGRF(year, month, day, lat, lon, ion_height, az_p, za_p) TEC_path = np.zeros((24,npix)) for t in range(0,24): hour = rad.std_hour(t, verbose=False) TEC_path[t], _ = itp.interp_space(tec_hp[t], rms_hp[t], lat, lon, za_p) RM_maps = ion_RM(B_para, TEC_path) for t in range(24): RM_maps[t] = rotate_healpix_map(RM_maps[t], R_z0.T)
def calc_radec_rm(self, ras, decs, verbose=False): #TODO: allow ra,dec to be floats, rather than arrays of floats # (to maintain single-pointing functionality) if not all((i <= 2. * np.pi and i >= 0.) for i in ras): raise ValueError('All RAs must be between 0 and 2*pi radians') if not all((i <= np.pi / 2. and i >= -np.pi / 2.) for i in decs): raise ValueError('All Decs must be between -pi/2 and pi/2 radians') self.coordinates_flag = 'J2000_RaDec' #final storage arrays b_para_s = [] rm_s = [] drm_s = [] lsts_s = [] alt_src_s = [] for time in self.times: #for every day #parsing, creating directory structure time_str, _, _ = str(time).partition('T') RM_dir = self.make_rm_dir(time_str) year, month, day = map(int, time_str.split('-')) if verbose: print(year, month, day) #data aquisition tec_hp, rms_hp, ion_height = self.ionex_data(year, month, day) #temp storage arrays alt_src_all = np.zeros([24, 3072]) lsts = np.zeros(24) RM_add = [] dRM_add = [] # predict the ionospheric RM for every hour within a day for ui, UT in enumerate(self.UTs): hour = utils.std_hour(UT) c_icrs = SkyCoord(ra=ras * u.radian, dec=decs * u.radian, location=self.location, obstime=time + UT * u.hr, frame='icrs') # Added to calculate LST for the given time c_local = AltAz(az=0. * u.deg, alt=90. * u.deg, obstime=time + UT * u.hr, location=self.location) c_local_Zeq = c_local.transform_to(ICRS) lsts[ui] = c_local_Zeq.ra.degree # Transform given RA/Dec into alt/az c_altaz = c_icrs.transform_to('altaz') alt_src = np.array(c_altaz.alt.degree) az_src = np.array(c_altaz.az.degree) alt_src_all[ui, :] = alt_src # AltAz.zen doesn't have method to return angle data zen_src = np.array(Angle(c_altaz.zen).degree) # Calculating the ion piercing point (IPP) depends on alt/az coords coord_lat, coord_lon, az_punct, zen_punct = phys.ipp( self.lat_str, self.lon_str, az_src, zen_src, ion_height) #XXX B_para calculated per UT #these are the data we care about B_para = phys.B_IGRF(year, month, day, coord_lat, coord_lon, ion_height, az_punct, zen_punct) TEC_path, RMS_TEC_path = itp.get_los_tec( tec_hp[ui], rms_hp[ui], coord_lat, coord_lon, zen_punct) IRM = 2.6e-17 * B_para * TEC_path rms_IRM = 2.6e-17 * B_para * RMS_TEC_path #TODO: replace append commands with numpy array indicies b_para_s.append(B_para) RM_add.append(IRM) dRM_add.append(rms_IRM) alt_src_s.append(alt_src_all) lsts_s.append(lsts) rm_s.append(RM_add) drm_s.append(dRM_add) self.B_para = np.array(b_para_s) self.RMs = np.array(rm_s) self.dRMs = np.array(drm_s) self.alt_src = np.array(alt_src_s) self.lst = np.array(lsts_s)
def calc_radec_rm(self, ras, decs, verbose=False): #TODO: allow ra,dec to be floats, rather than arrays of floats # (to maintain single-pointing functionality) if not all((i<=2. * np.pi and i>=0.) for i in ras): raise ValueError('All RAs must be between 0 and 2*pi radians') if not all((i<=np.pi/2. and i>=-np.pi/2.) for i in decs): raise ValueError('All Decs must be between -pi/2 and pi/2 radians') self.coordinates_flag = 'J2000_RaDec' # setup storage self.B_paras = {} self.RMs = {} self.dRMs = {} self.TEC = {} self.dTEC = {} self.lsts_s = {} alt_src_s = {} for uday in self.day_groups: # time logic group = self.day_groups[uday] time_strs = [item.split(' ')[1] for item in group] UTs_dec = [] for time_str in time_strs: Hr, Min, Sec = [float(x) for x in time_str.split(':')] dec_hour = Hr + Min / 60. + Sec / 3600. UTs_dec.append(dec_hour) year, month, day = [int(x) for x in uday.split('-')] #data aquisition tec_a, rms_a, ion_height, TEC = self.ionex_data(year, month, day) tec_hp = itp.ionex2healpix(tec_a, UTs_dec, TEC['lat'], TEC['lon']) rms_hp = itp.ionex2healpix(rms_a, UTs_dec, TEC['lat'], TEC['lon']) lsts,RMs,dRMs = [],[],[] # predict the ionospheric RM for every hour within a day for ui,UT in enumerate(UTs_dec): time = Time(uday + ' ' + time_strs[ui], format='iso', scale='utc') # XXX is this string reconstructed properly? not tested c_icrs = SkyCoord(ra=ras * u.radian, dec=decs * u.radian, location=self.location, obstime=time, frame='icrs') # Added to calculate LST for the given time c_local = AltAz(az=0.*u.deg, alt=90.*u.deg, obstime=time, location=self.location) c_local_Zeq = c_local.transform_to(ICRS) lsts.append(c_local_Zeq.ra.degree) # Transform given RA/Dec into alt/az c_altaz = c_icrs.transform_to('altaz') alt_src = np.array(c_altaz.alt.degree) az_src = np.array(c_altaz.az.degree) # AltAz.zen doesn't have method to return angle data zen_src = np.array(Angle(c_altaz.zen).degree) # Calculating the ion piercing point (IPP) depends on alt/az coords coord_lat, coord_lon, az_punct, zen_punct = phys.ipp(self.lat_str, self.lon_str, az_src, zen_src, ion_height) #XXX B_para calculated per UT #these are the data we care about B_para = phys.B_IGRF(year, month, day, coord_lat, coord_lon, ion_height, az_punct, zen_punct) TEC_path, RMS_TEC_path = itp.get_los_tec(tec_hp[ui], rms_hp[ui], coord_lat, coord_lon, zen_punct) RMs_ut = phys.RotationMeasure(TEC_path, B_para) dRMs_ut = phys.RotationMeasure(RMS_TEC_path, B_para) #TODO: replace append commands with numpy array indicies RMs.append(RMs_ut) dRMs.append(dRMs_ut) self.RMs.update({key:RMs[ti] for ti, key in enumerate(group)}) self.dRMs.update({key:dRMs[ti] for ti, key in enumerate(group)}) self.B_paras[uday] = B_para self.TEC.update({key:tec_hp[ti] for ti,key in enumerate(group)}) self.dTEC.update({key:rms_hp[ti] for ti,key in enumerate(group)})