def InterBeam(xpol, ypol, freq, jd, ra, dec): """ Interpolate beam at given frequency and sky position (RA and DEC) - xpol : Input beam model for xx polarization; type:string - ypol : Input beam model for yy polarization; type:string - freq : Frequency in Hz; type:float - ra : Right ascensions; type: numpy.ndarray - dec : Declinations; type:numpy.ndarray """ # Reading FEKO BEAMS ..." fekoX = fmt.FEKO(xpol) fekoY = fmt.FEKO(ypol) fields = fekoX.fields feko_xpol = fekoX.fields[0] feko_ypol = fekoY.fields[0] phi = feko_xpol.phi * np.pi / 180. # azimuth theta = feko_xpol.theta * np.pi / 180. # zenith theta = np.pi / 2 - theta # pyephem wants the elevation rather than the zenith angle beamFreqs = np.zeros(11) beamFreqs[0] = 100e6 for i in range(1, 11): beamFreqs[i] = beamFreqs[i - 1] + 10e6 # Computing BEAMS gxx = feko_xpol.etheta * np.conj( feko_xpol.etheta) + feko_xpol.ephi * np.conj(feko_xpol.ephi) beam = np.ndarray(shape=(gxx.shape[0], 4, len(beamFreqs)), dtype=complex) for j in range(len(beamFreqs)): feko_xpol = fekoX.fields[j] feko_ypol = fekoY.fields[j] for k in range(len(phi)): R_phi = np.array( [[np.cos(phi[k]), -1 * np.sin(phi[k])], [np.sin(phi[k]), np.cos(phi[k])]] ) # rotation matrix to convert for Ludwig-3 coordinates to normal alt-az coordinate system Ex = np.array([[feko_xpol.etheta[k]], [feko_xpol.ephi[k]]]).reshape(2) Ey = np.array([[feko_ypol.etheta[k]], [feko_ypol.ephi[k]]]).reshape(2) Ex_hv = np.dot(R_phi, Ex) Ey_hv = np.dot(R_phi, Ey) beam[k, 0, j] = Ex_hv[0] beam[k, 1, j] = Ex_hv[1] beam[k, 2, j] = Ey_hv[0] beam[k, 3, j] = Ey_hv[1] beam[:, 0, j] = beam[:, 0, j] / np.max(beam[:, 0, j]) beam[:, 3, j] = beam[:, 3, j] / np.max(beam[:, 3, j]) # Create OBSERVER paper = ephem.Observer() paper.lat, paper.long, paper.elevation = '-30:43:17', '21:25:40.08', 0.0 j0 = ephem.julian_date(0) paper.date = float(jd) - j0 + 5. / 60 / 24 beamRA = np.ndarray(shape=(phi.shape[0]), dtype=float) beamDEC = np.ndarray(shape=(phi.shape[0]), dtype=float) for k in range(beamRA.shape[0]): ra0, dec0 = paper.radec_of(phi[k], theta[k]) beamRA[k] = ra0 # RA in radians beamDEC[k] = dec0 # DEC in radians print "FREQUENCY INTERPOLATION" InterBeamF = np.ndarray(shape=(beam.shape[0], beam.shape[1]), dtype=complex) dist = np.abs(freq - np.array(beamFreqs)) # calculating the frequency distance ind = np.argsort(dist) ind.flatten() for p in range(4): if dist[ind[0]] == 0: InterBeamF[:, p] = beam[:, p, ind[0]] else: # 2-closest point interpolation weights = dist[ind[0]]**(-2) + dist[ind[1]]**(-2) InterBeamF[:, p] = (beam[:, p, ind[0]] * dist[ind[0]]**(-2) + beam[:, p, ind[1]] * dist[ind[1]]**(-2)) / weights InterHealBeam = np.ndarray(shape=(ra.shape[0], beam.shape[1]), dtype=complex) print "SPATIAL INTERPOLATION" for r in range(ra.shape[0]): ra[r] = ra[r] - 2 * np.pi if ra[r] > ( 2 * np.pi) else ra[r] # wrapping over ra dist = np.sqrt((ra[r] - beamRA)**2 + (dec[r] - beamDEC)**2) # calculating distance ind = np.argsort(dist) ind = ind.flatten() weights = dist[ind[0]]**(-1) + dist[ind[1]]**(-1) + dist[ind[2]]**(-1) for p in range(4): # 3-closest point interpolation InterHealBeam[r, p] = InterBeamF[ind[0], p] * dist[ind[0]]**( -1) + InterBeamF[ind[1], p] * dist[ind[1]]**( -1) + InterBeamF[ind[2], p] * dist[ind[2]]**(-1) InterHealBeam[r, p] = InterHealBeam[r, p] / weights np.savez(open('Beam-f%.4g_j%.5f.npz' % (freq * 1e-6, np.float(jd)), 'wb'), beam=InterHealBeam) return InterHealBeam
def genInterpBeam(freq,fits): beam_freqs = np.zeros((11),) beam_freqs[0] = 1e8 for k in range(1,len(beam_freqs)): beam_freqs[k] = beam_freqs[k-1] + 1e7 fekoX=fmt.FEKO('/home/nunhokee/diffuse_ems/beams/PAPER_FF_X.ffe') fekoY=fmt.FEKO('/home/nunhokee/diffuse_ems/beams/PAPER_FF_Y.ffe') feko_xpol=fekoX.fields[0] feko_ypol=fekoY.fields[0] gxx = feko_xpol.etheta*np.conj(feko_xpol.etheta)+feko_xpol.ephi*np.conj(feko_xpol.ephi) beam = np.ndarray(shape=(gxx.shape[0],4,beam_freqs.shape[0]),dtype=complex) for j in range(0,len(beam_freqs)): feko_xpol = fekoX.fields[j] feko_ypol = fekoY.fields[j] beam[:,0,j] = feko_xpol.etheta*np.conj(feko_xpol.etheta)+feko_xpol.ephi*np.conj(feko_xpol.ephi) beam[:,0,j] = beam[:,0,j] / np.max(beam[:,0,j]) beam[:,1,j] = feko_xpol.etheta*np.conj(feko_ypol.etheta)+feko_xpol.ephi*np.conj(feko_ypol.ephi) beam[:,2,j] = feko_ypol.etheta*np.conj(feko_xpol.etheta)+feko_ypol.ephi*np.conj(feko_xpol.ephi) beam[:,3,j] = feko_ypol.etheta*np.conj(feko_ypol.etheta)+feko_ypol.ephi*np.conj(feko_ypol.ephi) beam[:,3,j] = beam[:,3,j] / np.max(beam[:,3,j]) im,hdr,axisInfo=fitsUtil.readFITS(fits,hdr=True,axis=True) #load template FITS wcs=hdr['wcs'] axisDict={} for aid,aname in enumerate(axisInfo): if aname.startswith('RA'): axisDict['RA']=aid if aname.startswith('DEC'): axisDict['DEC']=aid if aname.startswith('FREQ'): axisDict['FREQ']=aid if aname.startswith('STOKES'): axisDict['STOKES']=aid #(l,m) grid for spatial interpolation phi=fekoX.fields[0].phi*np.pi/180. theta=fekoX.fields[0].theta*np.pi/180. #drop beam points near zenith as this can create artefacts deltaTheta=(np.pi/2.)/100. #delta of theta away from pi/2 to ignore thetaIdx=np.argwhere(theta<(np.pi/2.-deltaTheta)) theta0=theta.flatten() phi0=phi.flatten() #Generate a WCS structure with the same resolution as the template FITS file, but centered at the North Pole wcs = pywcs.WCS(naxis=2) wcs.wcs.crval = [0.,90.] wcs.wcs.crpix = [hdr['raPix'],hdr['decPix']] wcs.wcs.cdelt = [hdr['dra'],hdr['ddec']] wcs.wcs.ctype = ["RA---SIN", "DEC--SIN"] #compute the sky coordinates for each pixel mms=np.repeat(np.arange(im.shape[axisDict['RA']]),im.shape[axisDict['DEC']]).reshape((im.shape[axisDict['RA']],im.shape[axisDict['DEC']])) lls=mms.T imPhi,imTheta=wcs.wcs_pix2sky(np.array(mms.flatten(), np.float_),np.array(lls.flatten(), np.float_),1) #compute phi(RA)/theta(DEC) imPhi=imPhi.reshape(im.shape[axisDict['RA']],im.shape[axisDict['DEC']])*np.pi/180. imTheta-=90. imTheta*=-1. imTheta=imTheta.reshape(im.shape[axisDict['RA']],im.shape[axisDict['DEC']])*np.pi/180. InterpBeamIm=np.zeros((len(polID),im.shape[axisDict['RA']],im.shape[axisDict['DEC']]),dtype=complex) freqInterpBeams={} print "Frequency Interpolation" InterBeamF = np.zeros(shape=(gxx.shape[0],4),dtype=complex) df = np.abs(beam_freqs - freq) ind = np.argsort(df) for pid,plabel in enumerate(polID): if freq==beam_freqs[ind[0]]: InterBeamF[:,pid] = beam[:,pid,ind[0]] else: InterBeamF[:,pid] = (beam[:,pid,ind[0]]* df[ind[0]]**(-2.) + beam[:,pid,ind[1]]* df[ind[1]]**(-2.))/(df[ind[0]]**(-2.)+df[ind[1]]**(-2.)) InterBeamF0=InterBeamF[:,pid].flatten() freqInterpBeams[plabel]=InterBeamF0 print "Spatial Interpolation" for pid,plabel in enumerate(polID): InterpBeamIm0 = interpolate.griddata(np.column_stack((phi0, theta0)), freqInterpBeams[plabel],np.column_stack((imPhi.flatten(),imTheta.flatten())),method='linear') InterpBeamIm[pid]=InterpBeamIm0.reshape(imPhi.shape) return InterpBeamIm
action='store_true', help= 'Interpolate the inverted beam, use if output is being used to correct image' ) o.add_option( '-S', '--stokes', dest='stokes', action='store_true', help='Output the Stokes beams instead of the complex gain beams') opts, args = o.parse_args(sys.argv[1:]) fn = args[0] #Read in FEKO format beam models fekoX = fmt.FEKO(opts.xpol) fekoY = fmt.FEKO(opts.ypol) beam = genInterpBeam(fekoX, fekoY, fn, invert=opts.invert) #convert output to Stokes if option set stokesStr = '' if opts.stokes: print 'Generating Stokes beams' stokesBeam = np.zeros((4, beam.shape[1], beam.shape[2], beam.shape[3])) cplxBeam = np.zeros((4, beam.shape[1], beam.shape[2], beam.shape[3]), dtype='complex') cplxBeam[0] = beam[0] cplxBeam[1] = beam[1] + 1j * beam[2] cplxBeam[2] = beam[3] + 1j * beam[4] cplxBeam[3] = beam[5]
def old_PAPER_instrument_setup(z0_cza): # hack hack hack import sys sys.path.append( 'PAPER_beams/' ) # make this whatever it needs to be so that fmt can be imported import fmt nu0 = str(int(p.nu_axis[0] / 1e6)) nuf = str(int(p.nu_axis[-1] / 1e6)) band_str = nu0 + "-" + nuf local_jones0_file = 'local_jones0/PAPER/nside' + str( p.nside) + '_band' + band_str + '_Jdata.npy' if os.path.exists(local_jones0_file) == True: return np.load(local_jones0_file) fekoX = fmt.FEKO('PAPER_beams/PAPER_FF_X.ffe') fekoY = fmt.FEKO('PAPER_beams/PAPER_FF_Y.ffe') thetaF = np.radians(fekoX.fields[0].theta) phiF = np.radians(fekoX.fields[0].phi) nfreq = 11 npixF = thetaF.shape[0] nthetaF = 91 # don't think these are used nphiF = 73 jonesFnodes_ludwig = np.zeros((nfreq, npixF, 2, 2), dtype='complex128') for f in range(nfreq): jonesFnodes_ludwig[f, :, 0, 0] = fekoX.fields[f].etheta jonesFnodes_ludwig[f, :, 0, 1] = fekoX.fields[f].ephi jonesFnodes_ludwig[f, :, 1, 0] = fekoY.fields[f].etheta jonesFnodes_ludwig[f, :, 1, 1] = fekoY.fields[f].ephi # getting out of the Ludwig-3 basis. Seriously, wtf? # Copied Chuneeta/PolSims/genHealpyBeam. R_phi = np.array([[np.cos(phiF), np.sin(phiF)], [-np.sin(phiF), np.cos(phiF)]]).transpose(2, 0, 1) jonesFnodes = np.einsum('...ab,...bc->...ac', jonesFnodes_ludwig, R_phi) Rb = np.array([[0, 0, -1], [0, -1, 0], [-1, 0, 0]]) tb, pb = rotate_sphr_coords(Rb, thetaF, phiF) tF_v = t_hat_cart(thetaF, phiF) pF_v = p_hat_cart(thetaF, phiF) tb_v = t_hat_cart(tb, pb) fRtF_v = np.einsum('ab...,b...->a...', Rb, tF_v) fRpF_v = np.einsum('ab...,b...->a...', Rb, pF_v) cosX = np.einsum('a...,a...', fRtF_v, tb_v) sinX = np.einsum('a...,a...', fRpF_v, tb_v) basis_rot = np.array([[cosX, sinX], [-sinX, cosX]]) basis_rot = np.transpose(basis_rot, (2, 0, 1)) jonesFnodes_b = np.einsum('...ab,...bc->...ac', jonesFnodes, basis_rot) nside_F = 2**5 npix_F = hp.nside2npix(nside_F) h = lambda m: healpixellize(m, tb, pb, nside_F) jones_hpx_b = np.zeros((nfreq, npix_F, 2, 2), dtype='complex128') for f in range(nfreq): for i in range(2): for j in range(2): Re = h((jonesFnodes_b.real)[f, :, i, j]) Im = h((jonesFnodes_b.imag)[f, :, i, j]) jones_hpx_b[f, :, i, j] = Re + 1j * Im # note that Rb is an involution, Rb = Rb^-1 jones = np.zeros_like(jones_hpx_b) for i in range(11): jones[i] = rotate_jones( jones_hpx_b[i], Rb, multiway=True ) # rotate scalar components so instrument is pointed to northpole of healpix coordinate frame npix = hp.nside2npix(nside_F) hpxidx = np.arange(npix) cza, ra = hp.pix2ang(nside_F, hpxidx) z0 = r_hat_cart(z0_cza, 0.) RotAxis = np.cross(z0, np.array([0, 0, 1.])) RotAxis /= np.sqrt(np.dot(RotAxis, RotAxis)) RotAngle = np.arccos(np.dot(z0, [0, 0, 1.])) R_z0 = rotation_matrix(RotAxis, RotAngle) t0, p0 = rotate_sphr_coords(R_z0, cza, ra) hm = np.zeros(npix) hm[np.where(cza < (np.pi / 2. + np.pi / 20.) )] = 1 # Horizon mask; is 0 below the local horizon. # added some padding. Idea being to allow for some interpolation near the horizon. Questionable. npix_out = hp.nside2npix(p.nside) Jdata = np.zeros((11, npix_out, 2, 2), dtype='complex128') for i in range(11): J_f = flatten_jones(jones[i]) # J_f.shape = (npix_in, 8) J_f = J_f * np.tile(hm, 8).reshape(8, npix).transpose( 1, 0) # Apply horizon mask # Could future "rotation" of these zeroed-maps have small errors at the # edges of the horizon? due to the way healpy interpolates. # Unlikely to be important. # Comment update: Yep, it turns out this happens, BUT it is approximately # power-preserving. The pixels at the edges of the rotated mask are not # identically 1, but the sum over the mask is maintained to about a part # in 1e-5 # Perform a scalar rotation of each component so that the instrument's boresight # is pointed toward (z0_cza, 0), the location of the instrument on the # earth in the Current-Epoch-RA/Dec coordinate frame. J_f = rotate_jones(J_f, R_z0, multiway=False) if p.nside != nside_F: # Change the map resolution as needed. #d = lambda m: hp.ud_grade(m, nside=p.nside, power=-2.) # I think these two ended up being (roughly) the same? # The apparent normalization problem was really becuase of an freq. interpolation problem. # irf.harmonic_ud_grade is probably better for increasing resolution, but hp.ud_grade is # faster because it's just averaging/tiling instead of doing SHT's d = lambda m: harmonic_ud_grade(m, nside_F, p.nside) J_f = (np.asarray(map(d, J_f.T))).T # The inner transpose is so that correct dimension is map()'ed over, # and then the outer transpose returns the array to its original shape. J_f = inverse_flatten_jones( J_f) # Change shape to (nfreq,npix,2,2), complex-valued J_f = transform_basis( p.nside, J_f, z0_cza, R_z0 ) # right-multiply by the basis transformation matrix from RA/Dec to the Local CST basis. Jdata[i, :, :, :] = J_f if os.path.exists(local_jones0_file) == False: np.save(local_jones0_file, Jdata) return Jdata
def PAPER_instrument_setup(parameters_dict, z0_cza): param = Parameters(parameters_dict) import sys sys.path.append('PAPER_beams/') import fmt fekoX = fmt.FEKO('PAPER_beams/PAPER_FF_X.ffe') fekoY = fmt.FEKO('PAPER_beams/PAPER_FF_Y.ffe') thetaF = np.radians(fekoX.fields[0].theta) phiF = np.radians(fekoX.fields[0].phi) nfreq = 11 npixF = thetaF.shape[0] nthetaF = 91 nphiF = 73 ttF = thetaF.reshape(nthetaF, nphiF, order='F') ppF = phiF.reshape(nthetaF, nphiF, order='F') jonesFnodes = np.zeros((nfreq, npixF, 2, 2), dtype='complex128') tv = ttF[:, 0] pv = ppF[0, :] jonesFnodes = np.zeros((nfreq, npixF, 2, 2), dtype='complex128') tx, ty, px, py = [ np.zeros((nfreq, npixF), dtype='complex128') for x in range(4) ] for f in range(nfreq): tx[f] = fekoX.fields[f].etheta px[f] = fekoX.fields[f].ephi ty[f] = fekoY.fields[f].etheta py[f] = fekoY.fields[f].ephi Ibeam = (tx * tx.conj() + px * px.conj() + ty * ty.conj() + py * py.conj()).real / 2. norm_factor = np.outer(np.sqrt(np.amax(Ibeam, axis=1)), np.ones(npixF)) cosp = np.outer(np.ones(nfreq), np.cos(phiF)) sinp = np.outer(np.ones(nfreq), np.sin(phiF)) jonesFnodes[:, :, 0, 0] = cosp * tx - sinp * px jonesFnodes[:, :, 0, 1] = sinp * tx + cosp * px jonesFnodes[:, :, 1, 0] = cosp * ty - sinp * py jonesFnodes[:, :, 1, 1] = sinp * ty + cosp * py # jonesFnodes[:,:,0,0] = tx # jonesFnodes[:,:,0,1] = px # jonesFnodes[:,:,1,0] = ty # jonesFnodes[:,:,1,1] = py for i in range(2): for j in range(2): jonesFnodes[:, :, i, j] /= norm_factor jonesFimage = np.zeros((nfreq, nthetaF, nphiF, 2, 2), dtype='complex128') for f in range(nfreq): for i in range(2): for j in range(2): jonesFimage[f, :, :, i, j] = jonesFnodes[f, :, i, j].reshape(nthetaF, nphiF, order='F') jre = np.real(jonesFimage) jim = np.imag(jonesFimage) nside = 16 npix = hp.nside2npix(nside) hpxidx = np.arange(npix) cza, ra = hp.pix2ang(nside, hpxidx) jones_hpx = np.zeros((nfreq, npix, 2, 2), dtype='complex128') for f in range(11): for i in range(2): for j in range(2): jre_interpolant = interpolate.interp2d(pv, tv, jre[f, :, :, i, j], kind='cubic', fill_value=0.) jim_interpolant = interpolate.interp2d(pv, tv, jim[f, :, :, i, j], kind='cubic', fill_value=0.) jrehp = np.zeros(npix) jimhp = np.zeros(npix) for p in range(npix): jrehp[p] = jre_interpolant(ra[p], cza[p]) jimhp[p] = jim_interpolant(ra[p], cza[p]) jones_hpx[f, :, i, j] = jrehp - 1j * jimhp freqs = np.linspace(100., 200., 11, endpoint=True) nfreq_in = len(freqs) npix = jones_hpx.shape[1] jflat = np.zeros((nfreq_in, npix, 8), dtype='float64') for f in range(nfreq_in): jflat[f] = flatten_jones(jones_hpx[f]) lmax = 3 * nside - 1 nlm = hp.Alm.getsize(lmax) joneslm = np.zeros((nfreq_in, nlm, 8), dtype='complex128') sht = lambda x: hp.map2alm(x, lmax=lmax) for f in range(nfreq_in): joneslm[f] = (np.asarray(map(sht, jflat[f].T))).T joneslm_re = joneslm.real joneslm_im = joneslm.imag interpolant_re = interpolate.interp1d(freqs, joneslm_re, kind='cubic', axis=0) interpolant_im = interpolate.interp1d(freqs, joneslm_im, kind='cubic', axis=0) freqs_out = param.nu_axis / 1e6 nfreq_out = len(freqs_out) joneslm_re_flat = interpolant_re(freqs_out) joneslm_im_flat = interpolant_im(freqs_out) joneslm_flat = joneslm_re_flat + 1j * joneslm_im_flat nside2 = param.nside npix2 = hp.nside2npix(nside2) hpxidx = np.arange(npix2) cza, ra = hp.pix2ang(nside2, hpxidx) z0 = r_hat_cart(z0_cza, 0.) RotAxis = np.cross(z0, np.array([0, 0, 1.])) RotAxis /= np.sqrt(np.dot(RotAxis, RotAxis)) RotAngle = np.arccos(np.dot(z0, [0, 0, 1.])) R_z0 = rotation_matrix(RotAxis, RotAngle) hm = np.zeros(npix2) hm[np.where(cza < (np.pi / 2. + np.pi / 20.))] = 1 isht = lambda x: hp.alm2map( np.ascontiguousarray(x), nside2, verbose=False ) # I think the contiguaty of the array comes from when the FEKO data was read in Fortran ordering jones_up = np.zeros((nfreq_out, npix2, 2, 2), dtype='complex128') for f in range(nfreq_out): temp = (np.asarray(map(isht, joneslm_flat[f].T))).T temp *= np.tile(hm, 8).reshape(8, npix2).transpose(1, 0) temp = rotate_jones(temp, R_z0, multiway=False) jones_up[f] = inverse_flatten_jones(temp) theta, phi = rotate_sphr_coords(R_z0, cza, ra) cosp = np.outer(np.ones(nfreq_out), np.cos(phi)) sinp = np.outer(np.ones(nfreq_out), np.sin(phi)) # invRphi = np.array([ # [cosp,sinp], # [-sinp,cosp] # ]).transpose((2,3,0,1)) xa, xb, ya, yb = [jones_up[:, :, i, j] for i in range(2) for j in range(2)] jones_up2 = np.zeros_like(jones_up) jones_up2[:, :, 0, 0] = cosp * xa + sinp * xb jones_up2[:, :, 0, 1] = -sinp * xa + cosp * xb jones_up2[:, :, 1, 0] = cosp * ya + sinp * yb jones_up2[:, :, 1, 1] = -sinp * ya + cosp * yb Jdata = np.zeros((param.nfreq, param.npix, 2, 2), dtype='complex128') for f in range(param.nfreq): # J_f = flatten_jones(jones_up2[f]) # J_f *= np.tile(hm, 8).reshape(8, npix2).transpose(1,0) # J_f = rotate_jones(J_f, R_z0, multiway=False) # J_f = inverse_flatten_jones(J_f) J_f = PAPER_transform_basis(param.nside, jones_up2[f], z0_cza, R_z0) Jdata[f, :, :, :] = J_f print f return Jdata
def make_primary_beams(image_name,lst,stokes_choice,beam_filename): # # define the frequencies of the simulated beams # freq_beams = np.zeros(11) freq_beams[0] = 100e6 for j in range(1,11): freq_beams[j] = freq_beams[j - 1] + 10e6 # # read the input cube # tb.open(image_name) q_cube = tb.getcol('map') tb.close() # ra = np.ndarray(shape=(image.shape[0],image.shape[1]),dtype=float) # dec = np.ndarray(shape=(image.shape[0],image.shape[1]),dtype=float) ia.open(image_name) summary = ia.summary() # read the image summary cube_shape = summary['shape'] # read the image shape: RA, DEC, Stokes, Freq ra = np.ndarray(shape=(cube_shape[0],cube_shape[1]),dtype=float) dec = np.ndarray(shape=(cube_shape[0],cube_shape[1]),dtype=float) nchan = cube_shape[3] # number of channels in the cube start_freq = summary['refval'][3] # start frequencies in Hz df = summary['incr'][3] # frequency increment in Hz # # ra and dec will contain the RA and DEC corresponding to the pixel values in the image # # for j in range(0,cube_shape[0]): for k in range(0,cube_shape[1]): a=ia.toworld([j,k,0,0]) # a dictionary is returned with the world coordinates of that pixel b=a['numeric'] # the array is extracted from the dictionary a ra[j,k] = b[0] # save the RA for pixel j,k dec[j,k] = b[1] # save the DEC for pixel j,k # print ra[j,k] * 12/np.pi,dec[j,k] * 180/np.pi,j,k # print 'RA and DEC calculated' ia.close() # # # # read the beams # fekoX=fmt.FEKO('/home/gianni/PAPER/beams/fitBeam/data/PAPER_FF_X.ffe') fekoY=fmt.FEKO('/home/gianni/PAPER/beams/fitBeam/data/PAPER_FF_Y.ffe') feko_xpol=fekoX.fields[0] feko_ypol=fekoY.fields[0] phi=feko_xpol.phi*np.pi/180. # phi is the azimuth theta=feko_xpol.theta*np.pi/180. # theta is the zenith angle theta = np.pi/2 - theta # pyephem wants the elevation rather than the zenith angle ra_beams = np.ndarray(shape=(phi.shape[0]),dtype=float) # array of RA corresponding to (phi,theta) dec_beams = np.ndarray(shape=(phi.shape[0]),dtype=float) # array of DEC corresponding to (phi,theta) # # compute complex beams # gxx=feko_xpol.etheta*np.conj(feko_xpol.etheta)+feko_xpol.ephi*np.conj(feko_xpol.ephi) # # define an array that will contain all the simulated beams # beams = np.ndarray(shape=(gxx.shape[0],4,freq_beams.shape[0]),dtype=float) # # read all the beam models and save them in the beams array # for j in range(0,freq_beams.shape[0]): feko_xpol = fekoX.fields[j] # these two lines give an error, I need to check with Griffin how to fix it feko_ypol = fekoY.fields[j] # gxx = feko_xpol.etheta*np.conj(feko_xpol.etheta)+feko_xpol.ephi*np.conj(feko_xpol.ephi) gyy = feko_ypol.etheta*np.conj(feko_ypol.etheta)+feko_ypol.ephi*np.conj(feko_ypol.ephi) gxy = feko_xpol.etheta*np.conj(feko_ypol.etheta)+feko_xpol.ephi*np.conj(feko_ypol.ephi) gyx = feko_ypol.etheta*np.conj(feko_xpol.etheta)+feko_ypol.ephi*np.conj(feko_xpol.ephi) # # make the stokes beams # beams[:,0,j] = (gxx+gyy).real # beams[:,0,j] = beams[:,0,j] / np.max(beams[:,0,j]) # normalize the beams to be 1 at zenith beams[:,1,j] = (gxx-gyy).real beams[:,2,j] = (gxy+gyx).real beams[:,3,j] = (gxy-gyx).imag # norm_beam = np.max(beams[:,0,5]) # beam peak at 150 MHz beams[:,0,:] = beams[:,0,:] / norm_beam # normalize the beams to be 1 at zenith at 150 MHz # print norm_beam,np.max(beams[:,0,:]) print 'Beams read' # # bring the beam to RA,DEC coordinates # # Create an observer # paper = Observer() # # Set the observer at the Karoo # paper.lat, paper.long, paper.elevation = '-30:43:17', '21:25:40.08', 0.0 # j0 = ephem.julian_date(0) # invoked this way if import ephem j0 = julian_date(0) # invoked this way if from ephem import * # paper.date = float(lst) paper.date = float(lst) - j0 + 5./60/24 # I think I need this. At http://stackoverflow.com/questions/8962426/convert-topocentric-coordinates-azimuth-elevation-to-equatorial-coordinates # they seem to suggest that this is needed in order to get the right date and I seem to get the right # RA if I include this. The factor 5./60/24 needs to be added as the lst reported in the filename refers to # the beginning of the integration which is ~10 min long for j in range(0,ra_beams.shape[0]): a = paper.radec_of(phi[j],theta[j]) ra_beams[j] = a[0] # RA is in radians dec_beams[j] = a[1] # DEC is in radians # # # now interpolate the beams in frequency # interp_beam = np.ndarray(shape=(beams.shape[0],beams.shape[1],nchan),dtype=float) cube_freq = start_freq for chan in range(0,nchan): a = np.max(q_cube[:,:,0,chan,0]) b = np.min(q_cube[:,:,0,chan,0]) if (a != 0 and b != 0): # if the image is not empty, then proceed freq_dist = np.abs(cube_freq - freq_beams) freq_dist_s = np.sort(freq_dist) w = np.where(freq_dist == freq_dist_s[0]) if freq_dist_s[0] == 0: # # if the beam is simulated at the exact frequency channel, then do not interpolate # for j in range(0,4): interp_beam[:,j,chan] = beams[:,j,w[0][0]] # # if they are not, perform a weighted average of the two closest beams in frequency. The weights are the inverse of the frequency distance squared # else: w1 = np.where(freq_dist == freq_dist_s[1]) for j in range(0,4): interp_beam[:,j,chan] = (beams[:,j,w[0][0]] * freq_dist_s[0]**(-2) + beams[:,j,w1[0][0]] * freq_dist_s[1]**(-2)) / (freq_dist_s[0]**(-2) + freq_dist_s[1]**(-2)) # cube_freq = cube_freq + df # print 'Beams interpolated in frequency' # # now interpolate the beam at the observed RA,DEC # interp_beam_maps_q = np.ndarray(shape=(ra.shape[0],ra.shape[1],1,nchan,1),dtype=float) # for j in range(0,ra.shape[0]): for k in range(0,ra.shape[1]): # # interpolating amongst the three closest points # # x = np.cos(ra[j,k])*np.cos(ra_beams)*np.cos(dec[j,k])*np.cos(dec_beams) # y = np.sin(ra[j,k])*np.sin(ra_beams)*np.cos(dec[j,k])*np.cos(dec_beams) # z = np.sin(dec[j,k])*np.sin(dec_beams) # dist = np.sqrt(x**2 + y**2 + z**2) # dist = np.sqrt((ra[j,k] - ra_beams)**2 + (dec[j,k] - dec_beams)**2) dist_s = np.sort(dist) w0 = np.where(dist == dist_s[0]) w1 = np.where(dist == dist_s[1]) w2 = np.where(dist == dist_s[2]) # interp_beam_maps_q[j,k,0,:,0] = interp_beam[w0[0][0],stokes_choice,:] / dist_s[0] + interp_beam[w1[0][0],stokes_choice,:] / dist_s[1] + interp_beam[w2[0][0],stokes_choice,:] / dist_s[2] interp_beam_maps_q[j,k,0,:,0] = interp_beam_maps_q[j,k,0,:,0] / (dist_s[0]**(-1) + dist_s[1]**(-1) + dist_s[2]**(-1)) # # nearest neighbour interpolation # # dist = np.sqrt((ra[j,k] - ra_beams)**2 + (dec[j,k] - dec_beams)**2) # dist_s = np.sort(dist) # w0 = np.where(dist == dist_s[0]) # interp_beam_maps_q[j,k,0,:,0] = interp_beam[w0[0][0],stokes_choice,:] # print 'Beams interpolated in angle' # # store the beams into an image # # beam_filename = image_name.strip('.image') cmd = 'rm -rf ' + beam_filename + '.beams' os.system(cmd) cmd = 'cp -r ' + image_name + ' ' + beam_filename + '.beams' os.system(cmd) # tb.open(beam_filename + '.beams',nomodify=False) tb.putcol('map',interp_beam_maps_q) tb.close() tb.done() ia.open(beam_filename + '.beams') ia.tofits(beam_filename + '_beams.fits',overwrite=true) ia.close()