def Linecolor(self, num, cmap='jet'): ''' Return is from Blue to Red num: (1) color name: in ['red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'purple', 'pink', 'brown', 'black', 'white'] return () of this color (2) int, number of colors: return () of colors (3) == 'png' : open 'jizhipy_Plt_LineColor.png' cmap: Use which cmap to generate the linecolor (1) None=>'gist_rainbow_r' | Name of cmap (see plt_color.cmap(None)) (2) <matplotlib.colors.LinearSegmentedColormap> (cmap instance) (3) cmap='my': use my cmap ''' from jizhipy.Basic import Raise, IsType, ShellCmd, Path import numpy as np #---------------------------------------- if (IsType.isstr(num)): num = num.lower() if ('png' in num): uname = ShellCmd('uname')[0].lower() figpath = Path.jizhipyPath( 'jizhipy_tool/jizhipy_Plt_Color_Linecolor.png') operate = 'eog ' if (uname == 'linux') else 'open ' ShellCmd(operate + figpath) return #---------------------------------------- if (num in self.mycolor.keys()): return self.mycolor[num] else: Raise(Exception, num + ' NOT in ' + str(self.mycolor.keys())) #---------------------------------------- if (IsType.isstr(cmap) and cmap == 'my'): _jet_data_my = np.array([(255, 0, 0), (255, 128, 0), (200, 200, 0), (0, 200, 0), (0, 250, 250), (0, 0, 255), (160, 0, 255)]) / 255. r, g, b = _jet_data_my.T from scipy.interpolate import interp1d r, g, b = np.array([r, g, b]) * ratio x = np.linspace(0, 1, r.size) fr = interp1d(x, r) fg = interp1d(x, g) fb = interp1d(x, b) x = np.linspace(0, 1, num) r, g, b = fr(x), fg(x), fb(x) color = [] for i in range(num): color += [(r[i], g[i], b[i])] return tuple(color) #---------------------------------------- else: cmap = self.Cmap(cmap) color = [cmap(x)[:3] for x in np.linspace(0., 1, num)] for i in range(len(color)): color[i] = (color[i][0], color[i][1], color[i][2]) return tuple(color)
def __init__(self, freq_unit='MHz', unit='TCMB', resolution='hi', pygsmpath='gsm_components.hdf5'): """ Global sky model (GSM) class for generating sky models. Upon initialization, the map PCA data are loaded into memory and interpolation functions are pre-computed. Parameters ---------- freq_unit: 'Hz', 'MHz', or 'GHz' Unit of frequency. Defaults to 'MHz'. unit: 'MJysr', 'TCMB', 'TRJ' Unit of output data. MJy/Steradian, T_CMB in Kelvin, or T_RJ. resolution: 'hi' or 'low' Resolution of output map. Either 300 arcmin (low) or 24 arcmin (hi). For frequencies under 10 GHz, output is 48 arcmin. Notes ----- """ import numpy as np import h5py if (pygsmpath is None): pygsmpath = 'gsm2016_components.hdf5' if (not Path.ExistsPath(pygsmpath)): pygsmpath = Path.jizhipyPath( 'jizhipy_tool/pyGSM_component/gsm2016_components.hdf5') if (not Path.ExistsPath(pygsmpath)): Raise(Exception, 'pygsmpath="' + pygsmpath + '" NOT exists') self.GSM2016_FILEPATH = pygsmpath #---------------------------------------- if unit not in ['MJysr', 'TCMB', 'TRJ']: raise RuntimeError( "UNIT ERROR: %s not supported. Only MJysr, TCMB, TRJ are allowed." % unit) if resolution.lower() in ('hi', 'high', 'h'): resolution = 'hi' elif resolution.lower() in ('low', 'lo', 'l'): resolution = 'low' else: raise RuntimeError( "RESOLUTION ERROR: Must be either hi or low, not %s" % resolution) self.h5 = h5py.File(self.GSM2016_FILEPATH, "r") self.freq_unit = freq_unit self.unit = unit self.resolution = resolution # Map data to load labels = ['Synchrotron', 'CMB', 'HI', 'Dust1', 'Dust2', 'Free-Free'] self.n_comp = len(labels) self.map_ni_hr = np.array( [self.h5['highres_%s_map' % lb][:] for lb in labels]) self.map_ni_lr = self.h5['lowres_maps'] self.spec_nf = self.h5['spectra'][:] self.generated_map_data = None self.generated_map_freqs = None
def __init__(self, freq_unit='MHz', basemap='haslam', interpolation='pchip', pygsmpath='gsm_components.hdf5'): """ Global sky model (GSM) class for generating sky models. Upon initialization, the map PCA data are loaded into memory and interpolation functions are pre-computed. Parameters ---------- freq_unit: 'Hz', 'MHz', or 'GHz' Unit of frequency. Defaults to 'MHz'. gsm_version: 'haslam', 'wmap' or '5deg' GSM version to generate. The 5deg map has 5.1 degree resolution. This is a synthesized map made of all the maps considered in the de Oliveira-Costa et. al. paper At frequencies below 1GHz, haslam is preferred; you get higher resolution (1 degree) by locking to the Haslam 408 MHz map. At CMB frequencies, it is best to lock to the WMAP 23 GHz map, which is presented denoised with 2 degree resolution. interpolation: 'cubic' or 'pchip' Choose whether to use cubic spline interpolation or piecewise cubic hermitian interpolating polynomial (PCHIP). PCHIP is designed to never locally overshoot data, whereas splines are designed to have smooth first and second derivatives. Notes ----- The scipy `interp1d` function does not allow one to explicitly set second derivatives to zero at the endpoints, as is done in the original GSM. As such, results will differ. Further, we default to use PCHIP interpolation. """ import h5py from jizhipy.Basic import Path if (pygsmpath is None): pygsmpath = 'gsm_components.hdf5' if (not Path.ExistsPath(pygsmpath)): pygsmpath = Path.jizhipyPath( 'jizhipy_tool/pyGSM_component/gsm_components.hdf5') if (not Path.ExistsPath(pygsmpath)): Raise(Exception, 'pygsmpath="' + pygsmpath + '" NOT exists') self.GSM_FILEPATH = pygsmpath #---------------------------------------- try: assert basemap in {'5deg', 'wmap', 'haslam'} except AssertionError: raise RuntimeError( "GSM basemap unknown: %s. Choose '5deg', 'haslam' or 'wmap'" % basemap) try: assert interpolation in {'cubic', 'pchip'} except AssertionError: raise RuntimeError( "Interpolation must be set to either 'cubic' or 'pchip'") self.h5 = h5py.File(self.GSM_FILEPATH, "r") self.basemap = basemap self.interpolation_method = interpolation self.freq_unit = freq_unit self.pca_map_data = None self.interp_comps = None self.update_interpolants() self.generated_map_data = None self.generated_map_freqs = None
def LAB(fwhm, freqmin, freqmax, lon=None, lat=None, nside=None, coordsys='Galactic', labpath='labh.fits', verbose=True): ''' fwhm: [degree] fwhm==None: don't smooth the map freqmin, freqmax: [MHz] Average from freqmin (include) to freqmax (include) LAB freq resol: 0.00488281 MHz Must be isnum, NOT list If freqmax=None, then freqmax=freqmin lon, lat: [degree] lon: RA | l lat: Dec | b Must can be broadcast Use lon, lat first, otherwise, use nside nside: Healpix full sky map instead of lon, lat coordsys: 'Equatorial' | 'Galactic' labpath: str, where is the file "labh.fits" LAB: [1418.2329, 1422.5786] MHz ''' import pyfits import healpy as hp import numpy as np from jizhipy.Array import Asarray from jizhipy.Basic import Raise, IsType, Path from jizhipy.Astro import DopplerEffect from jizhipy.Transform import CoordTrans if (freqmin is not None): freqmin = Asarray(freqmin).flatten() if (freqmin.size != 1): Raise( Exception, 'freqmin must isnum, but now freqmin.size=' + str(freqmin.size)) freqmin = freqmin[0] if (freqmax is not None): freqmax = Asarray(freqmax) if (freqmax.size != 1): Raise( Exception, 'freqmax must isnum, but now freqmax.size=' + str(freqmax.size)) freqmax = freqmax[0] if (freqmin is not None and freqmax is None): freqmax = freqmin elif (freqmin is None and freqmax is not None): freqmin = freqmax elif (freqmin is None and freqmax is None): # if (verboase) : Raise(Warning, 'freqmin = freqmax = None') if (verboase): print('Warning: jp.LAB(), freqmin = freqmax = None') return np.array(0) if (freqmin < 1418.2329 or freqmax > 1422.5786): if (verbose): print( 'Warning: jp.LAB(), freqmin=%.3f, freqmax=%.3f out of [1418.2329, 1422.5786] MHz' % (freqmin, freqmax)) return np.array(0) #-------------------------------------------------- if (labpath is None): labpath = 'labh.fits' if (not Path.ExistsPath(labpath)): labpath = Path.jizhipyPath('jizhipy_tool/labh.fits') if (not Path.ExistsPath(labpath)): Raise(Exception, 'labath="' + labpath + '" NOT exists') fo = pyfits.open(labpath) #-------------------------------------------------- if (lon is not None and lat is not None): if (np.sum((lat < -90) + (lat > 90)) > 0): Raise(Exception, 'lat out of [-90, 90] degree') nside = None else: nside, islist = int(nside), True #-------------------------------------------------- hdr = fo[0].header bscale, bzero, blank = hdr['BSCALE_'], hdr['BZERO_'], hdr['BLANK_'] freq0 = hdr['FREQ0'] * 1e-6 # MHz Nlon, Nlat, Nfreq = hdr['NAXIS1'], hdr['NAXIS2'], hdr['NAXIS3'] vmin, dv = hdr['CRVAL3'] / 1000., hdr['CDELT3'] / 1000. # km/s #-------------------------------------------------- vlist = np.arange(vmin, vmin + Nfreq * dv, dv) freqlist = freq0 + DopplerEffect(freq0, None, vlist) df = freqlist[Nfreq / 2] - freqlist[Nfreq / 2 - 1] if (freqmin < freqlist.min() or freqmax > freqlist.max()): # if (verbose) : Raise(Warning, 'freqmin=%.3f, freqmax=%.3f out of [%.4f, %.4f] MHz' % (freqmin, freqmax, freqlist.min(), freqlist.max())) if (verbose): print( 'Warning: jp.LAB(), freqmin=%.3f, freqmax=%.3f out of [%.4f, %.4f] MHz' % (freqmin, freqmax, freqlist.min(), freqlist.max())) return np.array(0) nfreqmin = abs(freqlist - freqmin) nfreqmin = np.where(nfreqmin == nfreqmin.min())[0][0] nfreqmax = abs(freqlist - freqmax) nfreqmax = np.where(nfreqmax == nfreqmax.min())[0][0] nfreqmin, nfreqmax = np.sort([nfreqmin, nfreqmax]) nfreq = np.arange(nfreqmin, nfreqmax + 1) #-------------------------------------------------- # Take healpix map in Galactic lab = fo[0].data[nfreq] + 0 tf = (lab == blank) lab = np.float32(lab * bscale + bzero) lab[tf] = np.nan lab = np.ma.MaskedArray(lab, tf) lab = np.float32(lab.mean(0).data) # (361, 721) del tf #-------------------------------------------------- nsidelab = 256 # 512 latlab, lonlab = hp.pix2ang(nsidelab, np.arange(12 * nsidelab**2)) latlab, lonlab = 90 - latlab * 180 / np.pi, lonlab * 180 / np.pi lonlab %= 360 lonlab[lonlab > 180] = lonlab[lonlab > 180] - 360 nlon = ((lonlab - 180) / -0.5).round().astype(int) nlon[nlon >= Nlon] = Nlon - 1 del lonlab nlat = ((latlab + 90) / 0.5).round().astype(int) nlat[nlat >= Nlat] = Nlat - 1 del latlab npix = nlat * Nlon + nlon del nlat, nlon lab = lab.flatten()[npix] # healpix map del npix if (fwhm not in [0, None] and fwhm > 0.5): fwhm = (fwhm**2 - 0.5**2)**0.5 lab = np.float32( hp.smoothing(lab, fwhm * np.pi / 180, verbose=False)) # hp.smoothing() is slow ! #-------------------------------------------------- coordsys = str(coordsys).lower() if (nside is None): islist = False if (IsType.isnum(lon + lat)) else True lon, lat = lon + lat * 0, lon * 0 + lat # same shape lon %= 360 lon, lat = CoordTrans.Celestial(lon * np.pi / 180, lat * np.pi / 180, coordsys, 'Galactic') # rad npix = hp.ang2pix(nsidelab, np.pi / 2 - lat, lon) del lon, lat lab = lab[npix] else: if (nside != nsidelab): lab = hp.ud_grade(lab, nside) if (coordsys != 'galactic'): lab = CoordTrans.CelestialHealpix(lab, 'RING', 'Galactic', coordsys)[0] lab = np.float32(lab) if (not islist): lab = lab[0] return lab
def GSM2016(freq=None, outname=None, save=False, nside=None, coordsys='Galactic', unit='K', lowresol=False, dtype=None, verbose=False, rmnegative=False, rmsource=False, gsm2016path='GSM2016_data/', example=False): ''' An improved model of diffuse galactic radio emission from 10 MHz to 5 THz; arxiv:1605.04920; 2017MNRAS.464.3486Z Already remove CMB: -2.726 example: True | False ==True: read and return 'gsm2016_example.hdf5' jp.GSM2016(example=True) Only diffuse map, had remove CMB, 408MHz, K, nside=512 compname = ['Total', 'Synchrotron', 'CMB', 'HI', 'Dust1', 'Dust2', 'Free-Free'] # 'Dust1'=cold dust, 'Dust2'=warm dust freq: in MHz Must be one value, int | float, NOT list outname: Force to use .hdf5 format (1) ==str: complete output name (2) else: outname = 'gsm2016_'+strfreq+'.hdf5' save: ==False: exists, read, NOT save NOT exists, generate, NOT save ==True: exists, generate, save NOT exists, generate, save ==None: exists, read, NOT save NOT exists, generate, save lowresol: True | False (1) ==False: nside=1024 * freq< 10GHz, force resol=56arcmin ** freq<=10GHz, force resol=24arcmin (2) ==False nside=64, resol=5deg=300arcmin Use './data/lowres_maps.txt' unit: 'K'/'Trj' | 'Tcmb' | 'MJysr' dtype: 'float64' | 'float32' nside: Default nside=1024 rmnegative: reset negative True | False rmsource: remove sources from the output map 0/False | 1 | 2 | 3 | 4 0/False: NOT remove sources 1: remove CygA, CasA, Crab 2: remove sources outside center plane 3: remove sources inside center plane return: gsm.shape = (6, 12*nside**2) compname = ['Total', 'Synchrotron', 'CMB', 'HI', 'Dust1', 'Dust2', 'Free-Free'] # 'Dust1'=cold dust, 'Dust2'=warm dust ''' import numpy as np import healpy as hp import h5py from jizhipy.Astro import RemoveSource from jizhipy.Basic import Raise, SysFrame, Mkdir, Path, Time, IsType if (verbose): print('jizhipy.GSM2016:') if (nside is not None): n = int(round(np.log(nside) / np.log(2))) nside = 2**n else: nside = 512 coordsys = str(coordsys) if (verbose): print(' freq =', freq, 'MHz') print(' coordsys =', coordsys) print(' nside =', nside) #---------------------------------------- if (gsm2016path is None): gsm2016path = 'GSM2016_data/' if (not Path.ExistsPath(gsm2016path)): gsm2016path = Path.jizhipyPath('jizhipy_tool/GSM2016_data/') if (not Path.ExistsPath(gsm2016path)): Raise(Exception, 'gsmp2016path="' + gsm2016path + '" NOT exists') fdir = Path.AbsPath(gsm2016path) #---------------------------------------- if (example): if (verbose): print(' Use "gsm2016_example.hdf5"') fo = h5py.File(fdir + 'gsm2016_example.hdf5', 'r') gsm = fo['gsm2016'].value fo.close() # ud_grade to nside if (nside is not None and gsm[0].size != 12 * nside**2): gsm2 = [] for i in range(len(gsm)): gsm2.append(hp.ud_grade(gsm[i], nside)) gsm = np.array(gsm2) if (coordsys.lower() != 'galactic'): for i in range(len(gsm)): gsm[i] = CoordTrans.CelestialHealpix(gsm[i], 'ring', 'Galactic', coordsys)[0] return gsm #--------------------------------------------- #--------------------------------------------- freq, unit, lowresol, verbose, rmnegative, rmsource = float(freq), str( unit).lower(), bool(lowresol), bool(verbose), bool(rmnegative), int( rmsource) vb = '123' if (verbose) else False if (verbose): print( ' Total, Synchrotron, CMB, HI, Cold dust, Warm dust, Free-Free') if (freq <= 0): print('freq = ' + str(freq) + ' <=0') exit() dtype = np.dtype(dtype) #--------------------------------------------- #--------------------------------------------- if (IsType.isstr(outname)): outname = str(outname) else: strfreq = str(freq).split('.') while (strfreq[1] != '' and strfreq[1][-1] == '0'): strfreq[1] = strfreq[1][:-1] if (strfreq[1] == ''): strfreq = strfreq[0] else: strfreq = strfreq[0] + '.' + strfreq[1] outname = 'gsm2016_' + strfreq + '.hdf5' if (save is not False and '/' in outname): for i in range(len(outname) - 1, -1, -1): if (outname[i] == '/'): break Mkdir(outname[:i + 1]) #-------------------------------------------------- #-------------------------------------------------- freq /= 1000. # GHz kB, C, h, T = 1.38065e-23, 2.99792e8, 6.62607e-34, 2.725 hoverk = h / kB def K_CMB2MJysr(K_CMB, nu): # in Kelvin and Hz B_nu = 2 * (h * nu) * (nu / C)**2 / (np.exp(hoverk * nu / T) - 1) conversion_factor = (B_nu * C / nu / T)**2 / 2 * np.exp( hoverk * nu / T) / kB return K_CMB * conversion_factor * 1e20 # 1e-26 for Jy | 1e6 for MJy def K_RJ2MJysr(K_RJ, nu): # in Kelvin and Hz conversion_factor = 2 * (nu / C)**2 * kB return K_RJ * conversion_factor * 1e20 # 1e-26 for Jy | 1e6 for MJy mjysr2k = 1. / K_RJ2MJysr(1., 1e9 * freq) if (unit == 'tcmb'): unit = 'Tcmb' conversion = 1. / K_CMB2MJysr(1., 1e9 * freq) elif (unit == 'mjysr'): unit = 'MJysr' conversion = 1. if (verbose): print((' Unit Conversion at %.3f MHz: 1 MJysr == %f ' + unit) % (freq * 1000, mjysr2k)) else: # (unit in ['k', 'trj']) : unit = 'K' conversion = mjysr2k #-------------------------------------------------- #-------------------------------------------------- exist = True if (Path.ExistsPath(outname)) else False # if (exist and save is not True) : if (exist): try: fo = h5py.File(outname, 'r') gsm = fo['gsm2016'].value fo.close() if (verbose): print(' Exists: ', outname) return gsm except: pass #-------------------------------------------------- exist = False if (save is not False): save = True if (not exist): # generate spec_nf = np.loadtxt(fdir + 'spectra.txt') nfreq = spec_nf.shape[1] left_index = -1 for i in range(nfreq - 1): if (freq >= spec_nf[0, i] and freq <= spec_nf[0, i + 1]): left_index = i break if (left_index < 0): print( "FREQUENCY ERROR: %.3f MHz is outside supported frequency range of %.3f MHz to %.3f MHz." % (freq * 1000, spec_nf[0, 0] * 1000, spec_nf[0, -1] * 1000)) exit() #-------------------------------------------------- # compname must be this order, do NOT modify compname = ['Synchrotron', 'CMB', 'HI', 'Dust1', 'Dust2', 'Free-Free'] # 'Dust1'=cold dust, 'Dust2'=warm dust #-------------------------------------------------- if (lowresol): nside_data, op_resolution = 64, 300. else: nside_data = 1024 # forced because of *.bin files op_resolution = 56. if (freq < 10) else 24. if (not lowresol): gsm = np.array([ np.fromfile(fdir + 'highres_' + cname + '_map.bin', dtype='float32') for cname in compname ]) else: gsm = np.loadtxt(fdir + 'lowres_maps.txt') #-------------------------------------------------- interp_spec_nf = np.copy(spec_nf) interp_spec_nf[0:2] = np.log10(interp_spec_nf[0:2]) x1 = interp_spec_nf[0, left_index] x2 = interp_spec_nf[0, left_index + 1] y1 = interp_spec_nf[1:, left_index] y2 = interp_spec_nf[1:, left_index + 1] x = np.log10(freq) interpolated_vals = (x * (y2 - y1) + x2 * y1 - x1 * y2) / (x2 - x1) gsm = 10.**interpolated_vals[0] * interpolated_vals[1:, None] * gsm gsm = gsm * conversion #-------------------------------------------------- if (len(gsm.shape) == 1): gsm = gsm[None, :] else: gsm = np.concatenate([gsm.sum(0)[None, :], gsm], 0) #-------------------------------------------------- #-------------------------------------------------- # generate is nest, convert to ring # First ud_grade so that faster for i in range(len(gsm)): gsm[i] = hp.reorder(gsm[i], n2r=True) # ud_grade to nside if (gsm[0].size != 12 * nside**2): gsm2 = [] for i in range(len(gsm)): gsm2.append(hp.ud_grade(gsm[i], nside)) gsm = np.array(gsm2) #-------------------------------------------------- #-------------------------------------------------- # remove negative value in the hpmaps for i in range(len(gsm)): if (not rmnegative and i != 0): break tf = gsm[i] < 0 if (tf[tf].size == 0): continue g = gsm[i].copy() # g[tf] = g.mean() g[tf] = g[g > 0].min() g = hp.smoothing(g, np.pi / 180 * 10, verbose=False) gsm[i][tf] = g[tf] #-------------------------------------------------- #-------------------------------------------------- casa = np.array([[(111.44, -1.37), (93.89, 2.37)]]) # fwhm=7 casa1 = np.array([[(118.12, 4.78), (121.83, 1.09)]]) cyga = np.array([[(81, 2), (26.33, 8.38)]]) # fwhm=7 cyga1 = np.array([[(84.9, -0.55), (71.8, 0.4)]]) # fwhm=3 cyga2 = np.array([[(76.6, 0.4), (71.8, 0.4)]]) # fwhm=5 cyga3 = np.array([[(88.82, 4.69), (88.69, 2)]]) # fwhm=3 crab = np.array([[(-96, -2), (26.33, 8.38)]]) # fwhm=4.5 crab1 = np.array([[(-91.82, -1), (26.33, 8.38)]]) # fwhm=3 crab2 = np.array([[(-99.31, -3.43), (26.33, 8.38)]]) # fwhm=3 lb1 = np.concatenate( [casa, casa1, cyga, crab, cyga1, cyga2, cyga3, crab1, crab2], 0) fwhm1 = np.array([7, 3, 7, 4.5, 3, 5, 3, 2, 2]) lb10, lb11 = lb1[:, 0], lb1[:, 1] #-------------------------------------------------- other = np.array([[(-153.41, -1.91), (-163.58, -9.29)], [(-170.31, 2.08), (-163.58, -9.29)], [(-175.26, -5.88), (-163.58, -9.29)], [(-150.64, -19.38), (-157, -20)], [(-153.34, -16.39), (-157, -20)], [(133.73, 1.07), (126.89, 0.83)], [(160.4, 2.78), (157.61, -1.24)], [(73.2, -9.06), (68.38, -7.56)], [(63.39, -5.98), (68.38, -7.56)]]) fwhm2 = np.array([4, 4, 4, 1, 1, 2, 2, 3, 2]) lb20, lb21 = other[:, 0], other[:, 1] #-------------------------------------------------- center = np.array([[(-54.49, 0.08), (-58.03, -0.04)], [(-61.38, -0.18), (-58.03, -0.04)], [(-69.23, -0.59), (-58.03, -0.04)], [(-72.15, -0.73), (-58.03, -0.04)], [(-75.88, -0.42), (-58.03, -0.04)], [(-77.63, -1.2), (-58.03, -0.04)], [(-65.21, -1.2), (-58.03, -0.04)], [(-63.1, 9.8), (-60.6, 8.89)], [(-6.93, 16.9), (-9.35, 16.06)]]) fwhm3 = np.array([2, 2, 3, 3, 2, 2, 2, 2, 2]) lb30, lb31 = center[:, 0], center[:, 1] if (rmsource in [1, 2, 3, 4]): if (rmsource == 4): lb0 = np.concatenate([lb30, lb20, lb10], 0) lb1 = np.concatenate([lb31, lb21, lb11], 0) fwhm = np.concatenate([fwhm3, fwhm2, fwhm1]) elif (rmsource == 1): lb0, lb1, fwhm = lb10, lb11, fwhm1 elif (rmsource == 2): lb0, lb1, fwhm = lb20, lb21, fwhm2 elif (rmsource == 3): lb0, lb1, fwhm = lb30, lb31, fwhm3 gsm[0] = np.log10(gsm[0]) times, same, onebyone = 1, False, True pix, revalue = RemoveSource(gsm[0], lb0, lb1, fwhm, times, same, onebyone, vb) gsm[0][pix] = revalue gsm[0] = hp.smoothing(gsm[0], np.pi / 180, verbose=False) gsm[0] = 10.**gsm[0] gsm = gsm.astype(dtype) #-------------------------------------------------- #-------------------------------------------------- if (coordsys.lower() != 'galactic'): for i in range(len(gsm)): gsm[i] = CoordTrans.CelestialHealpix(gsm[i], 'ring', 'Galactic', coordsys)[0] if (save): if (verbose): print(' Saving to: ', outname) Path.ExistsPath(outname, old=True) fo = h5py.File(outname, 'w') fo['gsm2016'] = gsm fo['gsm2016'].attrs['freq'] = freq * 1000 fo['gsm2016'].attrs['unit'] = unit fo['gsm2016'].attrs['MJysr2K'] = mjysr2k fo['gsm2016'].attrs['lowresol'] = int(lowresol) fo['gsm2016'].attrs['nside'] = nside fo['gsm2016'].attrs['pixtype'] = 'healpix' fo['gsm2016'].attrs['ordering'] = 'ring' fo['gsm2016'].attrs['coordsys'] = 'Galactic' fo['gsm2016'].attrs['rmnegative'] = int(rmnegative) fo['gsm2016'].attrs['rmsource'] = int(rmsource) fo['gsm2016'].attrs['creadate'] = Time(0) fo.close() return gsm
def NVSSSUMSS(fwhm, lon=None, lat=None, nside=None, coordsys='Galactic', galcenter=True, nvsssumsspath='nvss-sumss_1.4GHz_15mJy_fullsky.hdf5'): ''' return radio source map * merged from NVSS and SUMSS * healpix, RING, full sky, 1.4GHz, 15mJ limit for completeness * fill the missing region fwhm: [degree] fwhm==None: don't smooth the map lon, lat: [degree] lon: RA | l lat: Dec | b Must can be broadcast Use lon, lat first, otherwise, use nside nside: Healpix full sky map instead of lon, lat nside0 = 1024 coordsys: 'Equatorial' | 'Galactic' | 'Ecliptic' galcenter: True | False ==True: Retain the galactic center ==False: discard the galactic center nvsssumsspath: str, where is the file 'nvss-sumss_1.4GHz_15mJy_fullsky.hdf5' ''' import numpy as np import healpy as hp import h5py from jizhipy.Array import Asarray from jizhipy.Basic import Raise, Path, IsType from jizhipy.Transform import CoordTrans if (nvsssumsspath is None): nvsssumsspath = 'nvss-sumss_1.4GHz_15mJy_fullsky.hdf5' nvsssumsspath = Path.AbsPath(str(nvsssumsspath)) if (not Path.ExistsPath(nvsssumsspath)): nvsssumsspath = Path.jizhipyPath( 'jizhipy_tool/nvss-sumss_1.4GHz_15mJy_fullsky.hdf5') if (not Path.ExistsPath(nvsssumsspath)): Raise(Exception, 'nvsssumsspath="' + nvsssumsspath + '" NOT exists') #-------------------------------------------------- nside0 = 1024 if (lon is not None and lat is not None): if (np.sum((lat < -90) + (lat > 90)) > 0): Raise(Exception, 'lat out of [-90, 90] degree') nside = None else: islist = True try: nside = int(nside) except: nside = nside0 #-------------------------------------------------- fo = h5py.File(nvsssumsspath, 'r') a = fo['nvsum'].value n, void = fo['void'].value a[n.astype(int)] = void resol = 0.06 # degree if (not galcenter): theta, phi = hp.pix2ang(nside0, np.arange(a.size)) theta, phi = 90 - theta * 180 / np.pi, phi * 180 / np.pi tf = (-5 < theta) * (theta < 5) * ((phi < 55) + (phi > 345)) n = np.arange(a.size)[tf] del theta, phi, tf m = (np.random.random(n.size) * void.size).astype(int) a[n] = void[m] #-------------------------------------------------- coordsys = str(coordsys).lower() if (nside is None): # use lon and lat to select region if (fwhm is not None and fwhm > resol): a = hp.smoothing(a, fwhm * np.pi / 180, verbose=False) a[a < 0] = 0 islist = False if (IsType.isnum(lon + lat)) else True lon, lat = lon + lat * 0, lon * 0 + lat # same shape lon %= 360 lon, lat = CoordTrans.Celestial(lon * np.pi / 180, lat * np.pi / 180, coordsys, 'galactic') # rad npix = hp.ang2pix(nside0, np.pi / 2 - lat, lon) del lon, lat a = a[npix] del npix else: # full sky healpix map if (coordsys != 'galactic'): a = CoordTrans.CelestialHealpix(a, 'RING', 'galactic', coordsys)[0] if (fwhm is not None and fwhm > resol): a = hp.smoothing(a, fwhm * np.pi / 180, verbose=False) a[a < 0] = 0 if (nside != nside0): a = hp.ud_grade(a, nside) a = np.float32(a) if (not islist): a = a[0] return a
def GSM(fwhm, freq, lon=None, lat=None, nside=None, coordsys='Galactic', gsmpath='gsm_parameter.out', save=False): ''' Already -2.726 fwhm: [degree] fwhm==None: don't smooth the map freq, dfreq: [MHz] Must be one/isnum, NOT list * freq: center frequency * dfreq: averaged from freq-dfreq/2 (include) to freq+dfreq/2 (include). For GSM(), dfreq effect is very small, so remove this argument lon, lat: [degree] lon: RA | l lat: Dec | b Must can be broadcast Use lon, lat first, otherwise, use nside nside: Healpix full sky map instead of lon, lat coordsys: 'Equatorial' | 'Galactic' | 'Ecliptic' gsmpath: str, where is the program "gsm_parameter.out" ./gsm_parameter.out freq outpath gsmdir save: True | False Save gsm_xxx.npy or not? Compile: gfortran -ffixed-line-length-none gsm_parameter.f -o gsm_parameter.out return: gsm, ndarray ''' import os import healpy as hp import numpy as np from jizhipy.Transform import CoordTrans from jizhipy.Array import Asarray from jizhipy.Basic import Raise, Path, ShellCmd, IsType if (gsmpath is None): gsmpath = 'gsm_parameter.out' freq = Asarray(freq).flatten() if (freq.size != 1): Raise(Exception, 'freq must isnum, but now freq.size=' + str(freq.size)) freq = freq[0] gsmpath = Path.AbsPath(str(gsmpath)) if (not Path.ExistsPath(gsmpath)): gsmpath = Path.jizhipyPath('jizhipy_tool/GSM/gsm_parameter.out') if (not Path.ExistsPath(gsmpath)): Raise(Exception, 'gsmpath="' + gsmpath + '" NOT exists') n = gsmpath.rfind('/') if (n < 0): gsmdir = '' else: gsmdir = gsmpath[:n + 1] if (lon is not None and lat is not None): if (np.sum((lat < -90) + (lat > 90)) > 0): Raise(Exception, 'lat out of [-90, 90] degree') nside = None else: islist = True try: nside = int(nside) except: nside = 512 #-------------------------------------------------- # list local "gsm_*.npy" gsmlist = ShellCmd('ls gsm_*.npy') ngsm = None for i in range(len(gsmlist)): try: f = np.sort([float(gsmlist[i][4:-4]), freq]) except: continue r = (f[1] / f[0])**3 if (r < 1.01): ngsm = i break if (ngsm is None): freqstr = ('%.2f' % freq) if (freqstr[-1] == '0'): freqstr = freqstr[:-1] if (freqstr[-1] == '0'): freqstr = freqstr[:-2] outname = 'gsm_' + freqstr os.system(gsmpath + ' ' + freqstr + ' ' + outname + '.dat ' + gsmdir) gsm = np.float32(np.loadtxt(outname + '.dat')) os.system('rm ' + outname + '.dat') if (save): np.save(outname + '.npy', gsm) else: gsm = np.float32(np.load(gsmlist[ngsm])) if (not save): os.system('rm ' + gsmlist[ngsm]) if (Path.ExistsPath('qaz_cols.dat')): os.system('rm qaz_cols.dat') nsidegsm = hp.get_nside(gsm) #-------------------------------------------------- coordsys = str(coordsys).lower() if (nside is None): if (fwhm is not None and fwhm > 1): fwhm = (fwhm**2 - 1)**0.5 gsm = hp.smoothing(gsm, fwhm * np.pi / 180, verbose=False) gsm[gsm < 0] = 0 islist = False if (IsType.isnum(lon + lat)) else True lon, lat = lon + lat * 0, lon * 0 + lat # same shape lon %= 360 lon, lat = CoordTrans.Celestial(lon * np.pi / 180, lat * np.pi / 180, coordsys, 'galactic') # rad npix = hp.ang2pix(nsidegsm, np.pi / 2 - lat, lon) del lon, lat gsm = gsm[npix] del npix else: if (nside != nsidegsm): gsm = hp.ud_grade(gsm, nside) if (coordsys != 'galactic'): gsm = CoordTrans.CelestialHealpix(gsm, 'RING', 'galactic', coordsys)[0] if (fwhm is not None and fwhm > 1): fwhm = (fwhm**2 - 1)**0.5 gsm = hp.smoothing(gsm, fwhm * np.pi / 180, verbose=False) gsm[gsm < 0] = 0 gsm = np.float32(gsm) if (not islist): gsm = gsm[0] return gsm