def make_image(self, image_name="output.fits", npix=600, phi=0.0, convolve=False): inclination = self.parameters["inclination"] posang = self.parameters["posang"] wavelength = self.parameters["wavelength"] print(self.domain_size()) image.makeImage(npix=npix, incl=inclination, posang=posang, phi=phi, wav=wavelength, binary=True, sizeau=self.domain_size()) # This calls radmc3d im = image.readImage(binary=True) self.parameters["sizepix_x"] = im.sizepix_x self.parameters["sizepix_y"] = im.sizepix_y if len(im.x) == 0: raise RuntimeError("Image creation failed, image is empty") if convolve: im = im.imConv(fwhm=1e-3 * np.array(self.parameters["beam_fwhm"]), pa=1e-3 * self.parameters["beam_posang"], dpc=self.parameters["distance"]) im.raw_input = lambda s: "y" image.plotImage(im, log=True, maxlog=2, dpc=101.0, cmap='inferno')
def observe_cont(self, lam, incl=None, phi=None, posang=None): incl = incl or self.incl phi = phi or self.phi posang = phi or self.posang logger.info(f"Observing continum with wavelength of {lam} micron") zoomau = np.concatenate([self.zoomau_x, self.zoomau_y]) cmd = gen_radmc_cmd( mode="image", dpc=self.dpc, incl=incl, phi=phi, posang=posang, npixx=self.npixx, npixy=self.npixx, lam=lam, zoomau=zoomau, option="noscat nostar", ) tools.shell(cmd, cwd=self.radmc_dir, error_keyword="ERROR", log_prefix=" ") self.data_cont = rmci.readImage(fname=f"{self.radmc_dir}/image.out") self.data_cont.freq0 = nc.c / (lam * 1e4) odat = Image(radmcdata=self.data_cont, datatype="continum") if self.conv: odat.Ipp = self.convolver(odat.Ipp) odat.add_convolution_info(**self.convolve_config) return odat
def _subcalc(self, p, cmd): dn = f"proc{p:d}" dpath_sub = f"{self.radmc_dir}/{dn}" os.makedirs(dpath_sub, exist_ok=True) for f in glob.glob(f"{self.radmc_dir}/*"): if re.search(r".*\.(inp|dat)$", f): shutil.copy2(f, f"{dpath_sub}/") log = logger.isEnabledFor(INFO) and p == 0 tools.shell( cmd, cwd=dpath_sub, log=log, error_keyword="ERROR", log_prefix=" ", ) with contextlib.redirect_stdout(open(os.devnull, "w")): fname = f"{dpath_sub}/image.out" return rmci.readImage(fname=fname)
import radmc3dPy.image as image import matplotlib.pyplot as plt import numpy as np i = 7 dist = 5410. #lambdas = np.array([ 37500., 20000., 13043.47826087, 9375., 7142.85714286, # 5454.54545455, 4285.71428571, 3529.41176471]) #en GHz: np.array([8,15,23,32,42,55,70,85])*1. GHz. im = image.readImage() #image.plotImage(im, au=True, log=True, maxlog=10, saturate=1e-5, cmap=plt.cm.gist_heat) """ image.plotImage(im, dpc=140, arcsec=True, log=True, maxlog=10, saturate=1e-5, cmap=plt.cm.gist_heat) image.plotImage(im, dpc=dist, arcsec=True, log=True, maxlog=10, saturate=1e-5, cmap=plt.cm.gist_heat) cim = im.imConv(fwhm=[1.0, 0.6], pa=120., dpc=dist) image.plotImage(cim, arcsec=True, dpc=dist, log=True, maxlog=10, bunit='snu', cmap=plt.cm.gist_heat) """ im.writeFits('img_shell.fits', dpc=5410.) #, coord='03h10m05s -10d05m30s') #Mirar lo de inputs desde terminal
def logprob(parameters, observed_intensity, observed_intensity_error, observed_radius): # returning an extremely low logprob in case of unrealistic physical conditions if parameters[0] <= 0 or parameters[5] <= 0 or parameters[5] > 0.5: return -np.inf try: # The different indices in the parameters list correspond to different physical paramters sigma_coeff = parameters[0] sigma_exp = parameters[1] size_exp = parameters[2] amax_coeff = parameters[3] amax_exp = parameters[4] d2g_coeff = parameters[5] d2g_exp = parameters[6] # All files are outputed to a temporary python directory temp_directory = tempfile.TemporaryDirectory(dir='.') temp_path = temp_directory.name # os.chdir(temp_directory.name) # opac_name = 'DSHARP' # choices: DSHARP, Draine # CUTOUT OPACITY PART 1 # Mass, t and luminosity from Avenhaus 2018 mstar = 0.7 * MS lstar = 1.56 * LS tstar = 4266.00 mdust = 121 * Mea * 5 mdisk = mdust / 0.1 # flang = 0.05 # ?? zrmax = 1.0 # ?? nr = 100 rin = 0.1 * au r_c = 100 * au # ?? rout = 400 * au # 400au from avenhaus paper #DSHARP Huang 2018 says 290 au alpha = 1e-3 opac_params = ['dustcomponents', {'method': 'simplemixing'}] d = disklab.DiskRadialModel(mstar=mstar, lstar=lstar, tstar=tstar, mdisk=mdisk, nr=nr, alpha=alpha, rin=rin, rout=rout) d.make_disk_from_simplified_lbp(sigma_coeff, 3 * r_c, sigma_exp) if d.mass / mstar > 0.2: return -np.inf d2g = d2g_coeff * ((d.r / au)**d2g_exp) # add N dust species ngrains = 10 # agrains = np.array([5.e-5, 1.e-1]) agrains = np.logspace(-5, -1, ngrains) a_max = np.array([]) for rad_step in range(len(d.r)): a_max = np.append(a_max, np.max(agrains[agrains < (d.r[rad_step] / AU)**(-amax_exp) * amax_coeff])) a, a_i, sig_da = get_powerlaw_dust_distribution(d.sigma / 100, a_max, q=4 - size_exp, na=ngrains, a0=1e-5, a1=1e-1) # size_distri = agrains**size_exp # size_distri /= size_distri.sum() for eps, agrain in zip(np.transpose(sig_da), a): d.add_dust(agrain=agrain, xigrain=rho_s, dtg=d2g * eps) # load the opacity from the previously calculated opacity table for dust in d.dust: # dust.grain.load_standard_opacity('draine2003', 'astrosilicates', verbose=True) dust.grain.read_opacity(os.path.join(temp_path, opac_fname + '.npz')) # compute the mean opacities d.meanopacitymodel = opac_params d.compute_mean_opacity() def movingaverage(interval, window_size): window = np.ones(int(window_size)) / float(window_size) return np.convolve(interval, window, 'same') d.mean_opacity_planck[7:] = movingaverage(d.mean_opacity_planck, 10)[7:] d.mean_opacity_rosseland[7:] = movingaverage(d.mean_opacity_rosseland, 10)[7:] for iter in range(100): d.compute_hsurf() d.compute_flareindex() d.compute_flareangle_from_flareindex(inclrstar=True) d.compute_disktmid(keeptvisc=False) d.compute_cs_and_hp() disk2d = disklab.Disk2D(disk=d, zrmax=zrmax, meanopacitymodel=d.meanopacitymodel, nz=100) # snippet vertstruc 2d_1 for vert in disk2d.verts: vert.iterate_vertical_structure() disk2d.radial_raytrace() for vert in disk2d.verts: vert.solve_vert_rad_diffusion() vert.tgas = (vert.tgas**4 + 15**4)**(1 / 4) for dust in vert.dust: dust.compute_settling_mixing_equilibrium() rmcd = disklab.radmc3d.get_radmc3d_arrays(disk2d, showplots=False) # Assign the radmc3d data # nphi = rmcd['nphi'] ri = rmcd['ri'] thetai = rmcd['thetai'] phii = rmcd['phii'] nr = rmcd['nr'] # nth = rmcd['nth'] # nphi = rmcd['nphi'] rho = rmcd['rho'] rmcd_temp = rmcd['temp'] # Define the wavelength grid for the radiative transfer nlam = 200 lam = np.logspace(-5, 1, nlam) lam_mic = lam * 1e4 # Write the `RADMC3D` input radmc3d.write_stars_input(d, lam_mic, path=temp_path) radmc3d.write_grid(ri, thetai, phii, mirror=False, path=temp_path) radmc3d.write_dust_density(rmcd_temp, fname='dust_temperature.dat', path=temp_path, mirror=False) # writes out the temperature radmc3d.write_dust_density(rho, mirror=False, path=temp_path) radmc3d.write_wavelength_micron(lam_mic, path=temp_path) radmc3d.write_opacity(disk2d, path=temp_path) radmc3d.write_radmc3d_input( {'scattering_mode': 5, 'scattering_mode_max': 5, 'nphot': 10000000}, path=temp_path) # mm continuum image calculation lam_obs = 0.125 rd = 300 * au radmc3d.radmc3d( f'image incl 47.5 posang -144.4 npix 500 lambda {lam_obs * 1e4} sizeau {4 * rd / au} secondorder setthreads 1', path=temp_path) # obtaining the resultant radial intensity profile and subsequent calculation of the logprob from this image divided by number of observation im = radmc3d.read_image(filename=os.path.join(temp_path, 'image.out')) radial_profile = [] radial = [] for x, y in zip(range(0, 251, 1), range(249, 500, 1)): radial_profile.append( im.image[y][int(round(249 + x * np.tan(0.6213372)))]) radial.append(np.sqrt( (im.x[int(round(249 + x * np.tan(0.6213372)))] / au)**2 + (im.y[y] / au)**2)) radial = np.asarray(radial) radial_profile = np.asarray(radial_profile) radial_profile = radial_profile[radial > 158] radial = radial[radial > 158] observed_intensity = observed_intensity[observed_radius > 1] observed_intensity_error = observed_intensity_error[observed_radius > 1] observed_radius = observed_radius[observed_radius > 1] log_prob_mm = -0.5 * np.sum((np.interp(observed_radius, radial / 158, radial_profile) - observed_intensity)**2 / (observed_intensity_error**2)) / len(observed_radius) # scattered light calculation # CUT OUT OPACITIES PART 2 for filename in glob.glob(os.path.join(temp_path, "dustkappa_*.inp")): os.remove(filename) for x in agrains: i_grain = agrains.searchsorted(x) opacity.write_radmc3d_scatmat_file(i_grain, opacity_dict, f'{i_grain}', path=temp_path) def write(fid, *args, **kwargs): fmt = kwargs.pop('fmt', '') sep = kwargs.pop('sep', ' ') fid.write(sep.join([('{' + fmt + '}').format(a) for a in args]) + '\n') with open(os.path.join(temp_path, 'dustopac.inp'), 'w') as f: write(f, '2 Format number of this file') write(f, '{} Nr of dust species'.format(len(agrains))) for x in agrains: i_grain = agrains.searchsorted(x) write(f, '============================================================================') write(f, '10 Way in which this dust species is read') write(f, '0 0=Thermal grain') write(f, '{} Extension of name of dustscatmat_***.inp file'.format(i_grain)) write(f, '----------------------------------------------------------------------------') # image calculation rd = 250 * au # radmc3d.radmc3d(f'image incl 47.5 posang -54.4 npix 500 lambda 1.65 sizeau 500 setthreads 4') radmc3d.radmc3d('image incl 47.5 posang 54.4 npix 500 lambda 1.65 sizeau 1000 setthreads 4', path=temp_path) # data = analyze.readData(dtemp=True, binary = False) im = image.readImage(os.path.join(temp_path, 'image.out')) im.writeFits(os.path.join(temp_path, 'image.fits'), dpc=158., coord='15h56m09.17658s -37d56m06.1193s') disk = 'IMLup' # fname = dh.get_datafile(disk) fname = 'Qphi_IMLup.fits' PA = dh.sources.loc[disk]['PA'] inc = dh.sources.loc[disk]['inc'] d = dh.sources.loc[disk]['distance [pc]'] # T_star = 10.**dh.sources.loc[disk]['log T_eff/ K'] # L_star = 10.**dh.sources.loc[disk]['log L_star/L_sun'] * c.L_sun.cgs.value # M_star = 10.**dh.sources.loc[disk]['log M_star/M_sun'] * c.M_sun.cgs.value # R_star = np.sqrt(L_star / (4 * np.pi * c.sigma_sb.cgs.value * T_star**4)) clip = 3.0 # fix the header of the sphere image hdulist = fits.open(fname) hdu0 = hdulist[0] hdu0.header['cdelt1'] = -3.405e-06 hdu0.header['cdelt2'] = 3.405e-06 hdu0.header['crpix1'] = hdu0.header['naxis1'] // 2 + 1 hdu0.header['crpix2'] = hdu0.header['naxis2'] // 2 + 1 hdu0.header['crval1'] = 0.0 hdu0.header['crval2'] = 0.0 hdu0.header['crval3'] = 1.65e-4 data = imagecube(hdulist, clip=clip) x, y, dy = data.radial_profile(inc=inc, PA=PA, z0=0.2, psi=1.27) profile = (y * u.Jy / data.beam_area_str).cgs.value profile_err = (dy * u.Jy / data.beam_area_str).cgs.value image_name = os.path.join(temp_path, 'image.fits') # calculating the profile from scattered light image using imagecube and then calculation of the logprob sim_data = imagecube(image_name, clip=clip) sim_x, sim_y, sim_dy = sim_data.radial_profile(inc=inc, PA=PA, z0=0.2, psi=1.27) sim_profile = (sim_y * u.Jy / sim_data.beam_area_str).cgs.value sim_profile_err = (sim_dy * u.Jy / sim_data.beam_area_str).cgs.value profile = profile[x > 1] profile_err = profile_err[x > 1] x = x[x > 1] sim_profile = sim_profile[sim_x > 1] sim_profile_err = sim_profile_err[sim_x > 1] sim_x = sim_x[sim_x > 1] log_prob_scat = -0.5 * np.nansum((np.interp(x, sim_x, sim_profile) - profile)**2 / (profile_err**2)) / len(x) # adding the two log probs and then multiplying by a large factor in order to make the MCMC more sensitive to changes log_prob = (log_prob_mm + log_prob_scat) except Exception: log_prob = -np.inf return log_prob
def commence(rundir, polunitlen=-2, dis=400, polmax=None, dooutput_op=1, pltopwav=None, dooutput_im=1, imlim=None, imUnits=None, imxlim=None, imylim=None,opltr=None,imaxisUnits='au', dooutput_wavim=1, anglim=None, angcmap=None, dooutput_xy=0, xyinx=None, tdxlim=None, tdylim=None, dooutput_minor=0, dooutput_stokes=0, dooutput_conv=0, fwhm=None, pa=[[0]], dooutput_alpha=0, dooutput_fits=0, bwidthmhz=2000., coord='03h10m05s -10d05m30s', dooutput_los=0, dokern=False, dooutput_sed=0, pltsed=None, dooutput_compreal=0 ): """ dooutput_conv : bool to output the convolved images imlim : list list of two elements for vmin, vmax of output_im image imxlim : tuple x coordinate limit for image in AU imylim : tuple y coordinate limit for image in AU xyinx : tuple 2 element tuple to specify which image to plot xy. In (a,b) where a is the index for inclination and b is for wavelength tdxlim : tuple tdylim : tuple 2 element tuple fwhm : list number of different resolutions by number of wavelengths in image.out pa : list number of different resolutions by number of wavelengths in image.out pltsed : 2d array [0,:] for wavelength [1,:] for observed flux opltr : list of floats the radii that is desired for overplot in au """ if os.path.isdir(rundir) is False: raise ValueError('rundir does not exist: %s'%rundir) # stokes inputs for fits files stokespref = ['I', 'Q', 'U', 'V'] # inclinations for image fname = os.path.join(rundir, 'inp.imageinc') imageinc = fntools.zylreadvec(fname) ninc = len(imageinc) # read parameter file parobj = params.radmc3dPar() parobj.readPar(fdir=rundir) # opacity op = dustopac.radmc3dDustOpac() res = op.readMasterOpac(fdir=rundir) op.readOpac(fdir=rundir, ext=res['ext'], scatmat=res['scatmat'], alignfact=res['align'][0]) fkabs = interpolate.interp1d(op.wav[0], op.kabs[0], kind='linear') fksca = interpolate.interp1d(op.wav[0], op.ksca[0], kind='linear') dinfo = op.readDustInfo() if res['align'][0]: kpara90 = op.kpara[0][0,-1] korth90 = op.korth[0][0,-1] else: kpara90 = 1. korth90 = 1. # read dust density and temperature dat = analyze.readData(fdir=rundir, binary=False, ddens=True, dtemp=True) # see if heatsource.inp exists to read accretion luminosity if os.path.isfile(os.path.join(rundir, 'heatsource.inp')): qvisdat = analyze.readData(fdir=rundir, binary=False, qvis=True) acclum = qvisdat.getHeatingLum() else: acclum = 0. temp2d = np.squeeze(dat.dusttemp[:,:,0,0]) if dokern: kern = np.array([[1,1,1,1,1], [1,2,2,2,1], [1,2,3,2,1], [1,2,2,2,1], [1,1,1,1,1]], dtype=np.float64) kern = kern / sum(kern) temp2d = convolve(temp2d, kern, boundary='fill', fill_value=0.) rho2d = np.squeeze(dat.rhodust[:,:,0,0]) reg = rho2d < 1e-32 rho2d[reg] = 1e-32 rholog = np.log10(rho2d) raxis = dat.grid.xi rstg = dat.grid.x ttaaxis = dat.grid.yi ttastg = dat.grid.y # output opacity if dooutput_op: pngname = rundir+'/out_opacity.png' getOutput_op(op, res, dinfo, pngname, pltopwav=pltopwav) # spectrum if dooutput_sed and os.path.isfile('inp.spectruminc'): star = star = radsources.radmc3dRadSources() star.readStarsinp(fdir=rundir) sedinc = fntools.zylreadvec('inp.spectruminc') nsedinc = len(sedinc) for ii in range(nsedinc): fname = rundir + '/myspectrum.i%d.out'%(sedinc[ii]) spec = image.radmc3dImage() spec.readSpectrum(fname=fname, dpc=dis) pngname = rundir + '/out_sed.i%d.png'%(sedinc[ii]) getOutput_sed(spec, pngname, star=star, pltsed=pltsed) # start iterating image related for ii in range(ninc): fname = os.path.join(rundir, 'myimage.i%d.out'%(imageinc[ii])) im = image.readImage(fname=fname) fname = os.path.join(rundir, 'mytausurf1.i%d.out'%(imageinc[ii])) if os.path.isfile(fname): tauim = image.readImage(fname=fname) else: tauim = None fname = rundir + '/mytau3d.i%d.out'%(imageinc[ii]) if os.path.isfile(fname): tau3d = image.readTauSurf3D(fname=fname) else: tau3d = None fname = os.path.join(rundir,'myoptdepth.i%d.out'%(imageinc[ii])) if os.path.isfile(fname): optim = image.readImage(fname=fname) else: optim = None camwavfile = os.path.join(rundir, 'camera_wavelength_micron.inp.image') if os.path.isfile(camwavfile): camwav = image.readCameraWavelength(fname=rundir+'/camera_wavelength_micron.inp.image') else: camwav = im.wav ncamwav = len(camwav) # line of sight properties along minor axis if dooutput_minor or dooutput_los: ylostemp = range(im.ny) ylosdens = range(im.ny) for iy in range(im.ny): ym = im.y[iy] lostemp = los.extract(imageinc[ii]*natconst.rad, ym, temp2d, raxis, rstg,ttaaxis,ttastg,0.) losdens = los.extract(imageinc[ii]*natconst.rad, ym, rholog, raxis, rstg,ttaaxis,ttastg,-32.) losdens['valcell'] = 10.**(losdens['valcell']) losdens['valwall'] = 10.**(losdens['valwall']) ylostemp[iy] = lostemp ylosdens[iy] = losdens # plot images through all wavelengths if dooutput_wavim: pngname = rundir + '/out_wavim.i%d.png'%imageinc[ii] getOutput_wavim(im, dis, pngname, imTblim=imlim, imxlim=imxlim, imylim=imylim, opltr=opltr, inc=imageinc[ii], anglim=anglim, angcmap=angcmap) # plot spectral index through all wavelengths if dooutput_alpha and (ncamwav > 0): pngname = rundir + '/out_alpha.i%d.png'%(imageinc[ii]) getOutput_alpha(im, op, pngname, opltr=opltr, inc=imageinc[ii]) ifreq = 0 for ifreq in range(ncamwav): kext = fkabs(camwav[ifreq]) + fksca(camwav[ifreq]) if dooutput_im: pngname = rundir+'/out_im.i%d.f%d.png'%(imageinc[ii],camwav[ifreq]) getOutput_im(ifreq, dis, im, optim, tauim, polunitlen, fkabs, fksca, pngname, polmax=polmax, imlim=None, imUnits='Tb', xlim=imxlim, ylim=imylim, opltr=opltr, inc=imageinc[ii], axisUnits=imaxisUnits) if dooutput_xy: if xyinx is not None: if (xyinx[0] == ii) and (xyinx[1] == ifreq): pngname = rundir+'/out_xy.i%d.f%d.png'%(imageinc[ii],camwav[ifreq]) getOutput_xy(ifreq, tau3d, dat, acclum, tdxlim, tdylim, pngname=pngname, parobj=parobj) else: pngname = rundir+'/out_xy.i%d.f%d.png'%(imageinc[ii],camwav[ifreq]) getOutput_xy(ifreq, tau3d, dat, acclum, tdxlim, tdylim, pngname=pngname, parobj=parobj) if dooutput_minor: pngname=rundir+'/out_minor.i%d.f%d.png'%(imageinc[ii],camwav[ifreq]) getOutput_minor(ifreq, im, optim, kpara90, korth90, kext, ylostemp, ylosdens, pngname) if dooutput_stokes: pngname=rundir+'/out_stokes.i%d.f%d.png'%(imageinc[ii],camwav[ifreq]) getOutput_stokes(ifreq, dis, im, pngname, polmax=polmax) if dooutput_los: pngname = rundir + '/out_los.i%d.f%d.png'%(imageinc[ii],camwav[ifreq]) getOutput_los(camwav[ifreq], fkabs, fksca, losdens, lostemp, pngname) if dooutput_fits: # output to fits file if im.stokes: #if stokes image for isk in range(4): fitsname = os.path.join(rundir, 'myimage.i%d.f%d.%s.fits'%(imageinc[ii], camwav[ifreq],stokespref[isk]) ) im.writeFits(fname=fitsname, dpc=dis, casa=True, bandwidthmhz=bwidthmhz, coord=coord, stokes=stokespref[isk], ifreq=ifreq, overwrite=True) else: fitsname = os.path.join(rundir, 'myimage.i%d.f%d.fits'%(imageinc[ii], camwav[ifreq]) ) im.writeFits(fname=fitsname, dpc=dis, casa=True, bandwidthmhz=bwidthmhz, coord=coord, stokes='I', ifreq=ifreq, overwrite=True) if (dooutput_conv) & (fwhm is not None): npa = len(pa) for ipa in range(npa): conv = im.imConv(dpc=dis, psfType='gauss', fwhm=fwhm[ipa], pa=pa[ipa]) # plot convolved image through all wavelengths if dooutput_wavim: pngname = rundir + '/out_wavim.i%d.b%d.png'%(imageinc[ii], ipa) getOutput_wavim(conv, dis, pngname, imTblim=imlim, imxlim=imxlim, imylim=imylim, opltr=opltr, inc=imageinc[ii], anglim=anglim, angcmap=angcmap) for ifreq in range(ncamwav): if dooutput_im: pngname = rundir+'/out_im.i%d.f%d.b%d.png'%(imageinc[ii],camwav[ifreq], ipa) getOutput_im(ifreq, dis, conv, optim, tauim, polunitlen, fkabs, fksca, pngname, polmax=polmax, imlim=imlim, imUnits=imUnits, xlim=imxlim, ylim=imylim, opltr=opltr, inc=imageinc[ii], axisUnits=imaxisUnits) # if dooutput_xy: # pngname = rundir+'/out_xy.i%d.f%d.b%d.png'%(imageinc[ii],camwav[ifreq], ipa) # getOutput_xy(ifreq, tauim, tau3d, dat, pngname) if dooutput_minor: pngname=rundir+'/out_minor.i%d.f%d.b%d.png'%(imageinc[ii],camwav[ifreq], ipa) getOutput_minor(ifreq, conv, optim, kpara90, korth90, kext, ylostemp, ylosdens, pngname) if dooutput_stokes: pngname=rundir+'/out_stokes.i%d.f%d.b%d.png'%(imageinc[ii],camwav[ifreq], ipa) getOutput_stokes(ifreq, dis, conv, pngname, polmax=polmax) if dooutput_fits: if conv.stokes: for isk in range(4): fitsname = os.path.join(rundir, 'myimage.i%d.f%d.%s.b%d.fits'%(imageinc[ii], camwav[ifreq],stokespref[isk], ipa)) conv.writeFits(fname=fitsname, dpc=dis, casa=True, bandwidthmhz=bwidthmhz, coord=coord, stokes=stokespref[isk], ifreq=ifreq, overwrite=True) else: fitsname = os.path.join(rundir, 'myimage.i%d.f%d.b%d.fits'%(imageinc[ii], camwav[ifreq], ipa)) conv.writeFits(fname=fitsname, dpc=dis, casa=True, bandwidthmhz=bwidthmhz, coord=coord, stokes='I', ifreq=ifreq, overwrite=True) # free up this memory del conv # free up the memory before going to next iteration del im del tauim del tau3d del optim
def observe_line(self, iline=None, molname=None, incl=None, phi=None, posang=None): iline = iline or self.iline molname = molname or self.molname incl = incl or self.incl phi = phi or self.phi posang = posang or self.posang logger.info(f"Observing line with {molname}") self.nlam = int(round(self.vfw_kms / self.dv_kms)) # + 1 mol_path = f"{self.radmc_dir}/molecule_{molname}.inp" self.mol = rmca.readMol(fname=mol_path) logger.info( f"Total cell number is {self.npixx}x{self.npixy}x{self.nlam}" + f" = {self.npixx*self.npixy*self.nlam}" ) common_cmd = { "mode": "image", "dpc": self.dpc, "incl": incl, "phi": phi, "posang": posang, "npixx": self.npixx, "npixy": self.npixy, "zoomau": [*self.zoomau_x, *self.zoomau_y], "iline": self.iline, "option": "noscat nostar nodust " + self.lineobs_option + " ", # + (" doppcatch " if , } v_calc_points = np.linspace(-self.vfw_kms / 2, self.vfw_kms / 2, self.nlam) if self.n_thread >= 2: logger.info(f"Use OpenMP dividing processes into velocity directions.") logger.info(f"Number of threads is {self.n_thread}.") # Load-balance for multiple processing n_points = self._divide_nlam_by_threads(self.nlam, self.n_thread) vrange_list = self._calc_vrange_list(v_calc_points, n_points) v_center = [0.5 * (vmax + vmin) for vmin, vmax in vrange_list] v_hwidth = [0.5 * (vmax - vmin) for vmin, vmax in vrange_list] logger.info(f"All calc points: {format_array(v_calc_points)}") logger.info("Calc points in each thread:") _zipped = zip(v_center, v_hwidth, n_points) for i, (vc, vhw, ncp) in enumerate(_zipped): vax_nthread = np.linspace(vc - vhw, vc + vhw, ncp) logger.info(f" -- {i}th thread: {format_array(vax_nthread)}") def cmdfunc(i): return gen_radmc_cmd( vc_kms=v_center[i], vhw_kms=v_hwidth[i], nlam=n_points[i], **common_cmd, ) args = [(i, cmdfunc(i)) for i in range(self.n_thread)] with multiprocessing.Pool(self.n_thread) as pool: results = pool.starmap(self._subcalc, args) # exit() self._check_multiple_returns(results) self.data = self._combine_multiple_returns(results) else: logger.info(f"Not use OpenMP.") cmd = gen_radmc_cmd(vhw_kms=self.vfw_kms / 2, nlam=self.nlam, **common_cmd) tools.shell(cmd, cwd=self.radmc_dir) self.data = rmci.readImage(fname=f"{self.radmc_dir}/image.out") if np.max(self.data.image) == 0: print(vars(self.data)) logger.warning("Zero image !") raise Exception # self.data.dpc = self.dpc self.data.dpc = self.dpc self.data.freq0 = self.mol.freq[iline - 1] odat = ObsData3D(datatype="line") odat.read(radmcdata=self.data) odat.add_obs_info( iline=iline, molname=molname, incl=incl, phi=phi, posang=posang ) if self.conv: odat.Ippv = self.convolver(odat.Ippv) odat.add_convolution_info(**self.convolve_config) return odat
def logP(parameters, options, debug=False): # set the path to the radmc3d executable if getpass.getuser() == 'birnstiel': radmc3d_exec = Path('~/.bin/radmc3d').expanduser() else: radmc3d_exec = Path('~/bin/radmc3d').expanduser() # get the options set in the notebook PA = options['PA'] inc = options['inc'] dpc = options['distance'] clip = options['clip'] lam_mm = options['lam_mm'] mstar = options['mstar'] lstar = options['lstar'] tstar = options['tstar'] # get the mm observables x_mm_obs = options['x_mm_obs'] y_mm_obs = options['y_mm_obs'] dy_mm_obs = options['dy_mm_obs'] fname_mm_obs = options['fname_mm_obs'] # get options used in the scattered light image z0 = options['z0'] psi = options['psi'] lam_sca = options['lam_sca'] beam_sca = options['beam_sca'] fname_sca_obs = options['fname_sca_obs'] # get the scattered light data profiles_sca_obs = options['profiles_sca_obs'] # name of the opacities file fname_opac = options['fname_opac'] # get the disklab model parameters nr = options['nr'] rin = options['rin'] r_c = options['r_c'] rout = options['rout'] alpha = options['alpha'] # create a temporary folder in the current folder temp_directory = tempfile.TemporaryDirectory(dir='.') temp_path = temp_directory.name # ### make the disklab 2D model disk2d = make_disklab2d_model(parameters, mstar, lstar, tstar, nr, alpha, rin, rout, r_c, fname_opac, show_plots=debug) print( f'disk to star mass ratio = {disk2d.disk.mass / disk2d.disk.mstar:.2g}' ) # read the wavelength grid from the opacity file and write out radmc setup opac_dict = read_opacs(fname_opac) lam_opac = opac_dict['lam'] n_a = len(opac_dict['a']) write_radmc3d(disk2d, lam_opac, temp_path, show_plots=debug) # ## Calculate the mm continuum image fname_mm_sim = Path(temp_path) / 'image_mm.fits' disklab.radmc3d.radmc3d( f'image incl {inc} posang {PA-90} npix 500 lambda {lam_mm * 1e4} sizeau {2 * rout / au} secondorder setthreads 1', path=temp_path, executable=str(radmc3d_exec)) radmc_image = Path(temp_path) / 'image.out' if radmc_image.is_file(): im_mm_sim = image.readImage(str(radmc_image)) radmc_image.replace(Path(temp_path) / 'image_mm.out') im_mm_sim.writeFits(str(fname_mm_sim), dpc=dpc, coord='15h56m09.17658s -37d56m06.1193s') # Read in the fits files into imagecubes, and copy the beam information from the observation to the simulation. iq_mm_obs = imagecube(str(fname_mm_obs), clip=clip) iq_mm_sim = imagecube(str(fname_mm_sim), clip=clip) iq_mm_sim.bmaj, iq_mm_sim.bmin, iq_mm_sim.bpa = iq_mm_obs.beam iq_mm_sim.beamarea_arcsec = iq_mm_sim._calculate_beam_area_arcsec() iq_mm_sim.beamarea_str = iq_mm_sim._calculate_beam_area_str() x_mm_sim, y_mm_sim, dy_mm_sim = get_profile_from_fits(str(fname_mm_sim), clip=clip, inc=inc, PA=PA, z0=0.0, psi=0.0, beam=iq_mm_obs.beam, show_plots=debug) i_max = max(len(x_mm_obs), len(x_mm_sim)) x_mm_sim = x_mm_sim[:i_max] y_mm_sim = y_mm_sim[:i_max] dy_mm_sim = dy_mm_sim[:i_max] x_mm_obs = x_mm_obs[:i_max] y_mm_obs = y_mm_obs[:i_max] dy_mm_obs = dy_mm_obs[:i_max] if not np.allclose(x_mm_sim, x_mm_obs): try: from IPython import embed embed() except Exception: raise AssertionError( 'observed and simulated radial profile grids are not equal') # TODO: Calculate the log probability for the mm here # %% Scattered light image for i_grain in range(n_a): opacity.write_radmc3d_scatmat_file(i_grain, opac_dict, f'{i_grain}', path=temp_path) with open(Path(temp_path) / 'dustopac.inp', 'w') as f: write(f, '2 Format number of this file') write(f, '{} Nr of dust species'.format(n_a)) for i_grain in range(n_a): write( f, '============================================================================' ) write(f, '10 Way in which this dust species is read') write(f, '0 0=Thermal grain') write( f, '{} Extension of name of dustscatmat_***.inp file' .format(i_grain)) write( f, '----------------------------------------------------------------------------' ) # image calculation iq_sca_obs = imagecube(str(fname_sca_obs), clip=clip) disklab.radmc3d.radmc3d( f'image incl {inc} posang {PA-90} npix {iq_sca_obs.data.shape[0]} lambda {lam_sca / 1e-4} sizeau {2 * rout / au} setthreads 4', path=temp_path, executable=str(radmc3d_exec)) fname_sca_sim = Path(temp_path) / 'image_sca.fits' if (Path(temp_path) / 'image.out').is_file(): (Path(temp_path) / 'image.out').replace( fname_sca_sim.with_suffix('.out')) im = image.readImage(str(fname_sca_sim.with_suffix('.out'))) im.writeFits(str(fname_sca_sim), dpc=dpc, coord='15h56m09.17658s -37d56m06.1193s') iq_sca_sim = imagecube(str(fname_sca_sim), clip=clip) # set the "beam" for the two images such that the samplint happens identically for iq in [iq_sca_obs, iq_sca_sim]: iq.bmaj, iq.bmin, iq.bpa = beam_sca iq.beamarea_arcsec = iq._calculate_beam_area_arcsec() iq.beamarea_str = iq._calculate_beam_area_str() # %% get the scattered light profile profiles_sca_sim = get_normalized_profiles(str(fname_sca_sim), clip=clip, inc=inc, PA=PA, z0=z0, psi=psi, beam=beam_sca) try: assert np.allclose(profiles_sca_obs['B']['x'], profiles_sca_sim['B']['x']) except Exception: # raise AssertionError('observed and simulated radial profile grids are not equal') warnings.warn( 'observed and simulated radial profile grids are not equal') try: from IPython import embed embed() except Exception: pass # TODO: calculate logP from the four profiles logP = -np.inf if debug: debug_info = { 'profiles_sca_sim': profiles_sca_sim, 'profiles_sca_obs': profiles_sca_obs, 'x_mm_sim': x_mm_sim, 'y_mm_sim': y_mm_sim, 'dy_mm_sim': dy_mm_sim, 'x_mm_obs': x_mm_obs, 'y_mm_obs': y_mm_obs, 'dy_mm_obs': dy_mm_obs, 'iq_mm_obs': iq_mm_obs, 'iq_mm_sim': iq_mm_sim, 'iq_sca_obs': iq_sca_obs, 'iq_sca_sim': iq_sca_sim, 'disk2d': disk2d, 'fname_sca_sim': fname_sca_sim, 'temp_path': temp_path, } return logP, debug_info else: return logP