def BuildDespoticInterpolator(): gmc = cloud(fileName="MilkyWayGMC.desp", verbose=True) # gmc.setTempEq(verbose=True) lines = gmc.lineLum("co") T = np.linspace(10,20,5) logn = np.linspace(1,5,10) co10=np.zeros((T.size, logn.size)) co21=np.zeros((T.size, logn.size)) co32=np.zeros((T.size, logn.size)) for j, density in enumerate(logn): for i,temp in enumerate(T): gmc.Tg=temp gmc.nH=1e1**density lines = gmc.lineLum("co") co10[i,j]=lines[0]["intTB"] co21[i,j]=lines[1]["intTB"] co32[i,j]=lines[2]["intTB"] fx = scipy.interpolate.interp1d(T,np.arange(len(T))) fy = scipy.interpolate.interp1d(logn,np.arange(len(logn))) def DespoticCO10(Tvals,n): intensity = mc(co10, [[fx(Tvals)],[fy(n)]]) return(intensity) def DespoticCO21(Tvals,n): intensity = mc(co21, [[fx(Tvals)],[fy(n)]]) return(intensity) def DespoticCO32(Tvals,n): intensity = mc(co32, [[fx(Tvals)],[fy(n)]]) return(intensity) return(DespoticCO10,DespoticCO21,DespoticCO32)
def tkin_all(density, sigma, lengthscale, gradient, tdust, crir=1e-17*u.s**-1, ISRF=1, tdust_rad=None, turbulence=True, gmc=gmc, reload_gmc=True, chemistry=False): assert density.unit.is_equivalent(u.cm**-3) assert sigma.unit.is_equivalent(u.km/u.s) assert lengthscale.unit.is_equivalent(u.pc) assert gradient.unit.is_equivalent(u.km/u.s/u.pc) assert crir.unit.is_equivalent(1/u.s) if reload_gmc: gmc=cloud('cloud.desp') gmc.sigmaNT = sigma.to(u.cm/u.s).value gmc.Td = tdust.to(u.K).value gmc.rad.TradDust = gmc.Td if tdust_rad is None else tdust_rad.to(u.K).value gmc.dVdr = gradient.to(u.s**-1).value gmc.rad.chi = ISRF # These are both per hydrogen, but we want to specify per particle, and # we're assuming the particles are H2 gmc.rad.ionRate = crir.to(u.s**-1).value * 2 gmc.nH = density.to(u.cm**-3).value * 2 turb_heating = turb_heating_generator(lengthscale, turbulence=turbulence) gmc.setTempEq(escapeProbGeom='LVG', PsiUser=turb_heating) #energy_balance = gmc.dEdt() if chemistry: gmc.setChemEq(network=NL99) gmc.setTempEq(escapeProbGeom='LVG', PsiUser=turb_heating) return gmc.Tg
def tkin_all(density, sigma, lengthscale, gradient, tdust, crir=1e-17 * u.s**-1, ISRF=1, tdust_rad=None, turbulence=True, gmc=gmc, reload_gmc=True, chemistry=False): assert density.unit.is_equivalent(u.cm**-3) assert sigma.unit.is_equivalent(u.km / u.s) assert lengthscale.unit.is_equivalent(u.pc) assert gradient.unit.is_equivalent(u.km / u.s / u.pc) assert crir.unit.is_equivalent(1 / u.s) if reload_gmc: gmc = cloud('cloud.desp') gmc.sigmaNT = sigma.to(u.cm / u.s).value gmc.Td = tdust.to(u.K).value gmc.rad.TradDust = gmc.Td if tdust_rad is None else tdust_rad.to(u.K).value gmc.dVdr = gradient.to(u.s**-1).value gmc.rad.chi = ISRF # These are both per hydrogen, but we want to specify per particle, and # we're assuming the particles are H2 gmc.rad.ionRate = crir.to(u.s**-1).value * 2 gmc.nH = density.to(u.cm**-3).value * 2 turb_heating = turb_heating_generator(lengthscale, turbulence=turbulence) try: gmc.setTempEq(escapeProbGeom='LVG', PsiUser=turb_heating) except despotic.despoticError as ex: print(ex) return np.nan if chemistry: gmc.setChemEq(network=NL99) gmc.setTempEq(escapeProbGeom='LVG', PsiUser=turb_heating) return gmc.Tg
try: fp = open('shockCool{:03d}.pkl'.format(i), 'rb') stateList.append(pickle.load(fp)) fp.close() restart=True except IOError: break # Did we find any existing data? if restart: # Yes: copy last state to slab object to initialize it slab = deepcopy(stateList[-1]) else: # No # Read the cloud initialization file slab=cloud(fileName='cloudfiles/postShockSlab.desp', \ verbose=verbose) # Compute initial level populations and dust temperature slab.dEdt(overrideSkip=True, dampFactor=dampFactor, \ verbose=verbose) slab.setDustTempEq(verbose=verbose) # Save initial state, both locally and to disk stateList.append(deepcopy(slab)) fp = open('shockCool000.pkl', 'wb') pickle.dump(slab, fp) fp.close() # Calculate time evolution, starting at proper position istart = len(stateList) - 1 extime = timedelta(0) for i, t in enumerate(times[istart:-1]):
def __init__(self, collider_densities={'ph2':990,'oh2':10}, temperature=30, species='co', datapath=None, hcolumn=1e21, abundance=1e-5, #column=1e13, tbackground=2.7315, deltav=1.0, escapeProbGeom='lvg', outfile='radex.out', logfile='radex.log', debug=False, ): """ Interface to DESPOTIC Parameters ---------- collider_densities: dict Dictionary giving the volume densities of the collider(s) in units of cm^-3. Valid entries are h2,oh2,ph2,e,He,H,H+. The keys are case-insensitive. temperature: float Local gas temperature in K species: str A string specifying a valid chemical species. This is used to look up the specified molecule hcolumn: float The total column density of hydrogen. abundance: float The molecule's abundance relative to H (NOT H2 as is normally done!). tbackground: float Background radiation temperature (e.g., CMB) deltav: float The FWHM line width (really, the single-zone velocity width to scale the column density by: this is most sensibly interpreted as a velocity gradient (dv/dR)) sigmaNT: float Nonthermal velocity dispersion (this is strictly ignored - deltav IS sigmant) datapath: str Path to the molecular data files """ import despotic self.cloud = despotic.cloud() self.cloud.nH = float(np.sum([collider_densities[k]*2 if 'h2' in k.lower() else collider_densities[k] for k in collider_densities])) for k in collider_densities.keys(): collider_densities[k.lower()] = collider_densities[k] if 'ph2' in collider_densities: self.cloud.comp.xpH2 = collider_densities['ph2'] / self.cloud.nH if 'oh2' in collider_densities: self.cloud.comp.xoH2 = collider_densities['oh2'] / self.cloud.nH self.cloud.Td = uvalue(temperature,u.K) self.cloud.Tg = uvalue(temperature,u.K) self.cloud.dust.sigma10 = 0.0 self.cloud.colDen = uvalue(hcolumn,u.cm**-2) if uvalue(tbackground,u.K) > 2.7315: self.cloud.rad.TradDust = uvalue(tbackground,u.K) self.species = species if datapath is None: emitterFile = species+'.dat' else: emitterFile = os.path.expanduser(os.path.join(datapath, species+'.dat')) self.cloud.addEmitter(species, abundance, emitterFile=emitterFile) self.cloud.comp.computeDerived(self.cloud.nH) self.escapeProbGeom = escapeProbGeom self.deltav = deltav
# Import the despotic library from despotic import cloud from despotic import emitter # Read the Milky Way GMC cloud file gmc = cloud(fileName='cloudfiles/MilkyWayGMC.desp') import numpy as np import pylab as pl gmc.sigmaNT = 1e5 # cm/s, instead of 2 as default gmc.Tg = 20 # start at 20 instead of 15 K gmc.Td = 20 # add ortho-h2co gmc.addEmitter('o-h2co_troscompt', 1e-9) # first plot: versus density densities = np.logspace(1,6) gmc.colDen = 5e21 # use a moderately high column, but not as high as the default tau11 = np.empty(densities.shape) tau22 = np.empty(densities.shape) for ii in xrange(tau11.size): gmc.nH = densities[ii] line = gmc.lineLum('o-h2co_troscompt') tau11[ii] = line[0]['tau'] tau22[ii] = line[2]['tau'] pl.rc('font',size=20)
######################################################################## # Program code ######################################################################## # Import the despotic library from despotic import cloud # Import standard python libraries from numpy import * from matplotlib.pyplot import * from datetime import datetime from datetime import timedelta # Read the Milky Way GMC cloud file gmc = cloud(fileName='cloudfiles/MilkyWayGMC.desp') # Read the ULIRG cloud file ulirg = cloud(fileName='cloudfiles/ULIRG.desp') # Compute the luminosity of the CO lines in both clouds t1=datetime.now() gmclines = gmc.lineLum('co') ulirglines = ulirg.lineLum('co') gmclines13 = gmc.lineLum('13co') ulirglines13 = ulirg.lineLum('13co') t2=datetime.now() print('Execution time = '+str(t2-t1)) # Print out the CO X factor for both clouds. This is column density # divided by velocity-integrated brightness temperature.
# Import the despotic library from despotic import cloud from despotic import emitter # Read the Milky Way GMC cloud file gmc = cloud(fileName='cloudfiles/MilkyWayGMC.desp') import numpy as np import pylab as pl gmc.sigmaNT = 1e5 # cm/s, instead of 2 as default gmc.Tg = 20 # start at 20 instead of 15 K gmc.Td = 20 # add ortho-h2co gmc.addEmitter('o-h2co_troscompt', 1e-9) # first plot: versus density densities = np.logspace(1, 6) gmc.colDen = 5e21 # use a moderately high column, but not as high as the default tau11 = np.empty(densities.shape) tau22 = np.empty(densities.shape) for ii in xrange(tau11.size): gmc.nH = densities[ii] line = gmc.lineLum('o-h2co_troscompt') tau11[ii] = line[0]['tau'] tau22[ii] = line[2]['tau'] pl.rc('font', size=20)
def build_despotic_grids(gridfile='ph2co_grid_despotic.fits', ph2coAbund=1e-8, nDens=21, logDensLower=2.0, logDensUpper=6.0, nCol=21, logColLower=11.0, logColUpper=15.0, nTemp=51, Tlower=10.0, Tupper=300.0, nDv=5, DvLower=1.0, DvUpper=5.0): """ Generates grids of p-H2CO line intensities using Despotic. Outputs a astropy Table. Parameters ---------- gridfile : string Name of grid file to output. ph2coAbund : float Fractional abundance of p-H2CO nDens : int Number of grid points in the volume density logDensLower : float log of volume density at lower bound of grid (log(n/cm**-3)) logDensUpper : float log of volume density at upper bound of grid (log(n/cm**-3)) nCol : int Number of grid points in the column density logColLower : float log of column density of p-H2CO at lower bound of grid (log(N/cm**-2)) logColUpper : float log of column density of p-H2CO at upper bound of grid (log(N/cm**-2)) nTemp : int Number of grid points in the temperature grid Tower : float temperature at lower bound of grid (K) Tupper : float temperature at upper bound of grid (K) nDv : int Number of grid points in the line width DvLower : float line width (non-thermal) at lower bound of grid (km/s) DvUpper : float line width (non-thermal) at upper bound of grid (km/s) """ if Democracy: raise Exception("No despotic install found. Cannot build grids") core = cloud(fileName="protostellarCore.desp", verbose=True) nlower = logDensLower nupper = logDensUpper Nlower = logColLower Nupper = logColUpper Temps = np.linspace(Tlower, Tupper, nTemp) Cols = 1e1**np.linspace(Nlower, Nupper, nCol) Densities = 1e1**(np.linspace(nlower, nupper, nDens)) LineWidth = np.linspace(DvLower, DvUpper, nDv) outtable = Table(names = ['Tex_303_202', 'Tex_322_221', 'Tex_321_220', 'tau_303_202', 'tau_322_221', 'tau_321_220', 'Temperature', 'Column', 'nH2', 'sigmaNT']) TempArr, ColArr, DensArr, DvArr = np.meshgrid(Temps, Cols, Densities, LineWidth) for T, N, n, dv in ProgressBar(zip(TempArr.flatten(), ColArr.flatten(), DensArr.flatten(), DvArr.flatten())): core.colDen = N/ph2coAbund core.Tg = T core.Td = T core.nH = n core.sigmaNT = dv lines = core.lineLum('p-h2co') outtable.add_row() outtable[-1]['Tex_303_202'] = lines[2]['Tex'] outtable[-1]['tau_303_202'] = lines[2]['tau'] outtable[-1]['Tex_322_221'] = lines[9]['Tex'] outtable[-1]['tau_322_221'] = lines[9]['tau'] outtable[-1]['Tex_321_220'] = lines[12]['Tex'] outtable[-1]['tau_321_220'] = lines[12]['tau'] outtable[-1]['Temperature'] = T outtable[-1]['Column'] = N outtable[-1]['nH2'] = n outtable[-1]['sigmaNT'] = dv outtable.write(gridfile, format='fits',overwrite=True)
from despotic import cloud import numpy import pylab specStr = 'CO' mycloud = cloud() mycloud.nH = 1.0e5 #gas density mycloud.colDen = 2.0e22 #cloud column density mycloud.sigmaNT = 4.0e5 #non-thermal velocity despersion mycloud.comp.xoH2 = 0.1 #ortho-H2 composition, xoH2 molecule per H nucleus mycloud.comp.xpH2 = 0.4 #para-H2 composition, xpH2 molecule per H nucleus mycloud.Tg = None #cloud gas kinetic temperature mycloud.Td = 0.0 #cloud dust temperature mycloud.addEmitter(specStr, 1.0e-7) #abudnace of the emitting species per H nucleus mycloud.Tg = 40.0 lines1 = mycloud.lineLum(specStr) mycloud.Tg = 400.0 lines2 = mycloud.lineLum(specStr) u1 = [l['upper'] for l in lines1] inten1 = numpy.array([l['intIntensity'] for l in lines1]) #intensity after subtracting the CMB contributuin u2 = [l['upper'] for l in lines2] inten2 = numpy.array([l['intIntensity'] for l in lines2])
def __init__(self, emitter_abundances, emitter_lines, dens_func, ps, Reff=1., sigmaNT=2.0e5, Tg=10., xoH2=0.1, xpH2=0.4, xHe=0.1, min_col=19, max_col=24, steps=11): """ __init__(emitter_abundances, emitter_lines, dens_func, ps, Reff=None, sigmaNT=2.0e5, Tg=10., xoH2=0.1, xpH2=0.4, xHe=0.1, min_col=19, max_col=24, steps=11) Initialise a CoGObj Attributes ---------- emitter_abundances : dict A dictionary whose keys are species name strings and whose values are relative abundances emitter_lines : dict A dictionary whose keys are species name strings and whose values are lists of lines needed (ordered by freq for each species. dens_func : DensityFunc or derived The mean density function of the cloud ps : IsmPowerspec or derived The power spectrum within the cloud. Reff : float The effective radius of the cloud used when estimating escape probabilities. Default is None, which implies size set by column density and nH. sigmaNT : float Non-thermal velocity dispersion Tg : float Gas temperature in Kelvin xoH2 : float relative abundance of ortho-H2 xpH2 : float relative abundance of para-H2 xHe : float relative abundance of He min_col : float The minimum log10 of the column density of H nuclei in cm^-2 to be used max_col : float The maximum log10 of the column density of H nuclei in cm^-2 to be used steps : int The number of steps used when finding the CoG """ # setup cloud self.cloud = dp.cloud() # check dens_func and ps types if not isinstance(dens_func, density.UniformDensityFunc): raise NotImplementedError("Currently only implemented with " "UniformDensityFunc density function " "instances") if not isinstance(ps, powerspec.SM14Powerspec): raise NotImplementedError("Currently only implemented with" "SM14Powerspec power-spectrum instances") self.dens_func = dens_func self.ps = ps self.cloud.sigmaNT = sigmaNT self.cloud.Tg = Tg self.cloud.comp.xoH2 = xoH2 self.cloud.comp.xpH2 = xpH2 self.cloud.comp.xHe = xHe # Set some derived cloud params self.cloud.nH = self.dens_func.dens_0 self.depth = self.dens_func.half_width * 2. self.cloud.colDen = self.dens_func.integral() * parsec if Reff is not None: self.cloud.Reff = Reff else: self.cloud.Reff = self.depth var_R = ps.outer_integral(1. / self.cloud.Reff) self.cloud.cfac = var_R / pow(self.cloud.nH, 2) + 1. # add emitters for emitter in emitter_abundances: self.cloud.addEmitter(emitter, emitter_abundances[emitter]) # set up dicts and arrays needed cols = np.linspace(min_col, max_col, steps) TB_dict = {} emitter_trans = {} for emitter in emitter_lines: TB_dict[emitter] = {} emitter_trans[emitter] = [ np.array(emitter_lines[emitter]) + 1, np.array(emitter_lines[emitter]) ] for line in emitter_lines[emitter]: TB_dict[emitter][line] = np.zeros(steps) # Find values for i, col in enumerate(cols): self.cloud.colDen = math.pow(10, col) self.cloud.nH = self.cloud.colDen / (self.depth * parsec) for emitter in emitter_lines: lines_dicts = self.cloud.lineLum( emitter, kt07=True, transition=emitter_trans[emitter]) for line in emitter_lines[emitter]: TB_dict[emitter][line][i] = (lines_dicts[ emitter_lines[emitter].index(line)]["intTB"]) # Fit splines self.splines = {} for emitter in emitter_lines: self.splines[emitter] = {} for line in emitter_lines[emitter]: self.splines[emitter][line] = (InterpolatedUnivariateSpline( cols, TB_dict[emitter][line]))
# plots graphical representations of the matrices at various points in # the procedues DESPOTIC uses to render them calculable. # ######################################################################## # Import libraries from despotic import cloud import numpy as np import matplotlib.pyplot as plt ######################################################################## # Program code ######################################################################## # Construct a test cloud cloud = cloud() # Assign density, gas temperature, abundances; they're all we need for # this test. Just use pure para-H2 for simplicity. cloud.nH = 1e3 cloud.comp.xpH2 = 0.5 cloud.Tg = 10.0 # Add three exmaple emitters; abundance values don't matter for this # example, so just set them to 1 cloud.addEmitter('co', 1.0) cloud.addEmitter('c+', 1.0, extrap=True, emitterURL='*****@*****.**') cloud.addEmitter('o-nh3', 1.0, extrap=True) # Compute level populations for optically thin cloud with no clumping; # get back the dict containing diagnostic information
# Import the despotic library from despotic import cloud # Import standard python libraries from numpy import * from matplotlib.pyplot import * from datetime import datetime from datetime import timedelta #from despotic.chemistry import NL99 from despotic.chemistry import NL99_GC ### # Read the Test Cloud file #testcloud = cloud(fileName='../cloudfiles/MilkyWayGMC.desp') testcloud = cloud(fileName='../cloudfiles/testcloud.desp') #if want interactive mode: #import code #code.interact(local=locals()) #from despotic.chemistry import abundanceDict # Lower the CR ionization rate so that a fully CO composition becomes # possible testcloud.rad.ionRate = 2e-17 # Raise the temperature to 20 K testcloud.Tg = 20.0
def __init__( self, collider_densities={ 'ph2': 990, 'oh2': 10 }, temperature=30, species='co', datapath=None, hcolumn=1e21, abundance=1e-5, #column=1e13, tbackground=2.7315, deltav=1.0, escapeProbGeom='lvg', outfile='radex.out', logfile='radex.log', debug=False, ): """ Interface to DESPOTIC Parameters ---------- collider_densities: dict Dictionary giving the volume densities of the collider(s) in units of cm^-3. Valid entries are h2,oh2,ph2,e,He,H,H+. The keys are case-insensitive. temperature: float Local gas temperature in K species: str A string specifying a valid chemical species. This is used to look up the specified molecule hcolumn: float The total column density of hydrogen. abundance: float The molecule's abundance relative to H (NOT H2 as is normally done!). tbackground: float Background radiation temperature (e.g., CMB) deltav: float The FWHM line width (really, the single-zone velocity width to scale the column density by: this is most sensibly interpreted as a velocity gradient (dv/dR)) sigmaNT: float Nonthermal velocity dispersion (this is strictly ignored - deltav IS sigmant) datapath: str Path to the molecular data files """ import despotic self.cloud = despotic.cloud() self.cloud.nH = float( np.sum([ collider_densities[k] * 2 if 'h2' in k.lower() else collider_densities[k] for k in collider_densities ])) for k in collider_densities.keys(): collider_densities[k.lower()] = collider_densities[k] if 'ph2' in collider_densities: self.cloud.comp.xpH2 = collider_densities['ph2'] / self.cloud.nH if 'oh2' in collider_densities: self.cloud.comp.xoH2 = collider_densities['oh2'] / self.cloud.nH self.cloud.Td = uvalue(temperature, u.K) self.cloud.Tg = uvalue(temperature, u.K) self.cloud.dust.sigma10 = 0.0 self.cloud.colDen = uvalue(hcolumn, u.cm**-2) if uvalue(tbackground, u.K) > 2.7315: self.cloud.rad.TradDust = uvalue(tbackground, u.K) self.species = species if datapath is None: emitterFile = species + '.dat' else: emitterFile = os.path.expanduser( os.path.join(datapath, species + '.dat')) self.cloud.addEmitter(species, abundance, emitterFile=emitterFile) self.cloud.comp.computeDerived(self.cloud.nH) self.escapeProbGeom = escapeProbGeom self.deltav = deltav
def despotify(pcube, vcube, vgrid, voxel_size=3.08e18, species='o-h2co', cloud=None, cloudfile='MilkyWayGMC.desp', cloudfile_path=None, output_linenumbers=[0,2], output_properties=['tau','Tex','intTB']): """ Turn a simulated ppp cube into a ppv cube using despotic for the radiative transfer Note that it is "despot-ify", not "de-spotify". Parameters ---------- pcube : np.ndarray 3-dimensional array containing values with units of density in n(H2) cm^-3 vcube : np.ndarray 3-dimensional array containing Z-velocity values, i.e. the velocity should be in the direction of the 0'th axis (because python arrays are inverted). Expected unit is km/s, but it doesn't matter as long as the velocity units match the vgrid units vgrid : np.ndarray 1-dimensional array containing the output velocity grid. Must have same units as vcube. voxel_size : float 1-dimensional size of a voxel in cm. Used to convert from density to column species : str A string identifying the LAMDA species name, e.g. 'o-h2co', 'co', etc. cloud : None or despotic.cloud Can pass in a despotic cloud instance that will be modified by the specified cube density. Otherwise, will be read from file. cloudfile : str The filename specifying the default cloud file to use cloudfile_path : str or None If none, defaults to despotic.__path__/cloudfiles/ output_linenumbers : iterable A list of integer indices for which line numbers should be output as cubes output_properties : iterable A list of strings identifying the line properties to output as cubes Returns ------- A data cube of dimensions [velocity,position,position] for each line in output_linenumbers for each property in output_properties """ if pcube.shape != vcube.shape: raise ValueError('Cube Size mismatch: {0},{1}'.format(str(pcube.shape), str(vcube.shape))) if vgrid.ndim > 1: raise ValueError('Velocity grid must be 1-dimensional') imshape = pcube.shape[1:] outcubeshape = (vgrid.size,) + imshape nelts = vgrid.size vinds = np.empty(vcube.shape, dtype='int64') # not needed # volume_spectra = np.empty(outcubeshape) # dens_spectra = np.empty(outcubeshape) for jj,kk in np.ndindex(imshape): vinds[:,jj,kk] = np.digitize(vcube[:,jj,kk], vgrid) # volume_spectra[:,jj,kk] = np.bincount(vinds[:,jj,kk], minlength=nelts) # dens_spectra[:,jj,kk] = np.bincount(vinds[:,jj,kk], # weights=pcube[:,jj,kk], # minlength=nelts) cloudfile_path = cloudfile_path or despotic.__path__[0]+"/cloudfiles/" if cloud is None: cloud = despotic.cloud(fileName="{0}/{1}".format(cloudfile_path, cloudfile)) try: from progressbar import ProgressBar,Percentage,Bar from progressbar import AdaptiveETA as ETA except ImportError: from progressbar import ProgressBar,Percentage,Bar from progressbar import ETA pb = ProgressBar(widgets=[Percentage(), ETA(), Bar()], maxval=pcube.size).start() # property cubes prior to gridding have same shape as input cubes # use dict() instead of {} for python2.6 compatibility prop_cubes = dict([ ("{0}{1}".format(pr,ln), np.empty(pcube.shape)) for ln,pr in itertools.product(output_linenumbers, output_properties)]) for (zi,yi,xi),nH in np.ndenumerate(pcube): cloud.nH = pcube[zi,yi,xi] cloud.colDen = cloud.nH * voxel_size line = cloud.lineLum(species) for ln,pr in itertools.product(output_linenumbers, output_properties): key = "{0}{1}".format(pr,ln) prop_cubes[key][zi,yi,xi] = line[ln][pr] pb.update(pb.currval+1) pb.finish() # spectral cubes have outcubeshape spectra_cubes = {} spectra_cubes = dict([ ("{0}{1}".format(pr,ln), np.empty(outcubeshape)) for ln,pr in itertools.product(output_linenumbers, output_properties)]) for key in prop_cubes: for jj,kk in itertools.product(*map(xrange,imshape)): spectra_cubes[key][:,jj,kk] = \ np.bincount(vinds[:,jj,kk], weights=prop_cubes[key][:,jj,kk], minlength=nelts) return spectra_cubes,prop_cubes
# Program code ######################################################################## # Constants import scipy.constants as physcons kB = physcons.k / physcons.erg mH = physcons.m_p / physcons.gram G = physcons.G * 1e3 # Only recompute if we haven't already done the computation try: gmc except NameError: # Use the Milky Way GMC file as a base, but add C+ and O as emitting species gmc = cloud('../cloudfiles/MilkyWayGMC.desp') gmc.addEmitter('c+', 1e-10) gmc.addEmitter('o', 1e-4) # Set CR ionization rate gmc.rad.ionRate = 3e-17 # Set IR temp to 10 K gmc.rad.TradDust = 10.0 gmc.Td = 10.0 # Set column density to 10^22 cm^-2 gmc.colDen = 1.0e22 # Set initial temperature guess to 20 K gmc.Tg = 20.0
def despotify(pcube, vcube, vgrid, voxel_size=3.08e18, species='o-h2co', cloud=None, cloudfile='MilkyWayGMC.desp', cloudfile_path=None, output_linenumbers=[0, 2], output_properties=['tau', 'Tex', 'intTB']): """ Turn a simulated ppp cube into a ppv cube using despotic for the radiative transfer Note that it is "despot-ify", not "de-spotify". Parameters ---------- pcube : np.ndarray 3-dimensional array containing values with units of density in n(H2) cm^-3 vcube : np.ndarray 3-dimensional array containing Z-velocity values, i.e. the velocity should be in the direction of the 0'th axis (because python arrays are inverted). Expected unit is km/s, but it doesn't matter as long as the velocity units match the vgrid units vgrid : np.ndarray 1-dimensional array containing the output velocity grid. Must have same units as vcube. voxel_size : float 1-dimensional size of a voxel in cm. Used to convert from density to column species : str A string identifying the LAMDA species name, e.g. 'o-h2co', 'co', etc. cloud : None or despotic.cloud Can pass in a despotic cloud instance that will be modified by the specified cube density. Otherwise, will be read from file. cloudfile : str The filename specifying the default cloud file to use cloudfile_path : str or None If none, defaults to despotic.__path__/cloudfiles/ output_linenumbers : iterable A list of integer indices for which line numbers should be output as cubes output_properties : iterable A list of strings identifying the line properties to output as cubes Returns ------- A data cube of dimensions [velocity,position,position] for each line in output_linenumbers for each property in output_properties """ if pcube.shape != vcube.shape: raise ValueError('Cube Size mismatch: {0},{1}'.format( str(pcube.shape), str(vcube.shape))) if vgrid.ndim > 1: raise ValueError('Velocity grid must be 1-dimensional') imshape = pcube.shape[1:] outcubeshape = (vgrid.size, ) + imshape nelts = vgrid.size vinds = np.empty(vcube.shape, dtype='int64') # not needed # volume_spectra = np.empty(outcubeshape) # dens_spectra = np.empty(outcubeshape) for jj, kk in np.ndindex(imshape): vinds[:, jj, kk] = np.digitize(vcube[:, jj, kk], vgrid) # volume_spectra[:,jj,kk] = np.bincount(vinds[:,jj,kk], minlength=nelts) # dens_spectra[:,jj,kk] = np.bincount(vinds[:,jj,kk], # weights=pcube[:,jj,kk], # minlength=nelts) cloudfile_path = cloudfile_path or despotic.__path__[0] + "/cloudfiles/" if cloud is None: cloud = despotic.cloud( fileName="{0}/{1}".format(cloudfile_path, cloudfile)) try: from progressbar import ProgressBar, Percentage, Bar from progressbar import AdaptiveETA as ETA except ImportError: from progressbar import ProgressBar, Percentage, Bar from progressbar import ETA pb = ProgressBar(widgets=[Percentage(), ETA(), Bar()], maxval=pcube.size).start() # property cubes prior to gridding have same shape as input cubes # use dict() instead of {} for python2.6 compatibility prop_cubes = dict([ ("{0}{1}".format(pr, ln), np.empty(pcube.shape)) for ln, pr in itertools.product(output_linenumbers, output_properties) ]) for (zi, yi, xi), nH in np.ndenumerate(pcube): cloud.nH = pcube[zi, yi, xi] cloud.colDen = cloud.nH * voxel_size line = cloud.lineLum(species) for ln, pr in itertools.product(output_linenumbers, output_properties): key = "{0}{1}".format(pr, ln) prop_cubes[key][zi, yi, xi] = line[ln][pr] pb.update(pb.currval + 1) pb.finish() # spectral cubes have outcubeshape spectra_cubes = {} spectra_cubes = dict([ ("{0}{1}".format(pr, ln), np.empty(outcubeshape)) for ln, pr in itertools.product(output_linenumbers, output_properties) ]) for key in prop_cubes: for jj, kk in itertools.product(*map(xrange, imshape)): spectra_cubes[key][:,jj,kk] = \ np.bincount(vinds[:,jj,kk], weights=prop_cubes[key][:,jj,kk], minlength=nelts) return spectra_cubes, prop_cubes
pl.switch_backend('Qt4Agg') from astropy import units as u from astropy import constants import paths from paths import fpath from astropy.utils.console import ProgressBar import pprint # Import the despotic library and the NL99 network; also import numpy from despotic import cloud import despotic import os import numpy as np # Use the Milky Way GMC file as a base gmc=cloud('cloud.desp') from despotic.chemistry import NL99 # gmc.setChemEq(network=NL99) def turb_heating_generator(lengthscale=1*u.pc, turbulence=True): def turb_heating(cloud, lengthscale=lengthscale): """ Turbulent heating rate depends on cloud linewidth (sigma_nonthermal) and driving scale of the turbulence DESPOTIC wants units of erg/s/H (per hydrogen), so the turbulent heating rate n sigma^3 / L is divided by n to get just sigma^3/L """ if turbulence: gamturb = (1.4 * constants.m_p * (0.5*3**1.5 * (cloud.sigmaNT*u.cm/u.s)**3 / (lengthscale))) return [(gamturb).to(u.erg/u.s).value, 0]
from astropy import units as u from astropy import constants from astropy.table import Table import paths from paths import fpath from astropy.utils.console import ProgressBar import pprint # Import the despotic library and the NL99 network; also import numpy from despotic import cloud import despotic import os import numpy as np # Use the Milky Way GMC file as a base gmc = cloud('cloud.desp') from despotic.chemistry import NL99 # gmc.setChemEq(network=NL99) def turb_heating_generator(lengthscale=1 * u.pc, turbulence=True): def turb_heating(cloud, lengthscale=lengthscale): """ Turbulent heating rate depends on cloud linewidth (sigma_nonthermal) and driving scale of the turbulence DESPOTIC wants units of erg/s/H (per hydrogen), so the turbulent heating rate n sigma^3 / L is divided by n to get just sigma^3/L MacLow 1999, 2002, 2004 gives exactly: 3e-27 erg cm^-3 s^-1 (n/1 cm^3) (v/10 km/s)**3 (L/100 pc)**-1 Ours is higher by the factor 3^1.5 = 5, which is the conversion from 1D
cloud_mass = 1e4 # msun box_area = 10. # pc vox_length = box_area * 3.08e18 / 256. total_density = pppcube.sum() # H2 cm^-3 cloud_mean_density = cloud_mass * 2e33/2.8/1.67e-24 / (total_density * vox_length**3) # start with simple case x,y = 128,128 nelts = 100 expand = 1 vgrid = np.linspace(ppvcube.min(),ppvcube.max(),nelts) vdata = ppvcube[:,y-expand:y+expand+1,x-expand:x+expand+1] pdata = pppcube[:,y-expand:y+expand+1,x-expand:x+expand+1] * cloud_mean_density gmc = cloud(fileName='/Users/adam/repos/despotic/cloudfiles/MilkyWayGMC.desp') gmc.sigmaNT = 1e5 # cm/s, instead of 2 as default gmc.Tg = 20. # start at 20 instead of 15 K gmc.Td = 20. # add ortho-h2co gmc.addEmitter('o-h2co', 1e-9) spectra,props = despotify(pdata, vdata, vgrid, vox_length, cloud=gmc) pl.figure() onedshape = vgrid.shape + (np.prod(spectra[spectra.keys()[0]].shape[1:]),) for ii,key in enumerate(spectra): pl.subplot(2,3,ii+1) pl.plot(vgrid, spectra[key].reshape(onedshape), label=key)
######################################################################## # User-settable options ######################################################################## # Set up a range of densities lognHgrid = np.arange(2, 6.01, 0.2) # Specify whether verbose printing while running is desired verbose = True ######################################################################## # Program code ######################################################################## # Read the protostellar core file core = cloud(fileName='cloudfiles/protostellarCore.desp', verbose=True) # Check if we have saved work try: # Load pickle files inFile = open('coreTemp_Tg.pkl', 'rb') Tg = pickle.load(inFile) inFile.close() inFile = open('coreTemp_Td.pkl', 'rb') Td = pickle.load(inFile) inFile.close() inFile = open('coreTemp_rates.pkl', 'rb') rates = pickle.load(inFile) inFile.close() startIdx = len(Tg) # Point at which to restart except IOError:
# Program code ######################################################################## # Constants import scipy.constants as physcons kB = physcons.k/physcons.erg mH = physcons.m_p/physcons.gram G = physcons.G*1e3 # Only recompute if we haven't already done the computation try: gmc except NameError: # Use the Milky Way GMC file as a base, but add C+ and O as emitting species gmc=cloud('../cloudfiles/MilkyWayGMC.desp') gmc.addEmitter('c+', 1e-10) gmc.addEmitter('o', 1e-4) # Set CR ionization rate gmc.rad.ionRate = 3e-17 # Set IR temp to 10 K gmc.rad.TradDust = 10.0 gmc.Td = 10.0 # Set column density to 10^22 cm^-2 gmc.colDen = 1.0e22 # Set initial temperature guess to 20 K gmc.Tg = 20.0
# User-settable options ######################################################################## # Set up a range of densities lognHgrid = np.arange(2, 6.01, 0.2) # Specify whether verbose printing while running is desired verbose = True ######################################################################## # Program code ######################################################################## # Read the protostellar core file core = cloud(fileName="cloudfiles/protostellarCore.desp", verbose=True) # Check if we have saved work try: # Load pickle files inFile = open("coreTemp_Tg.pkl", "rb") Tg = pickle.load(inFile) inFile.close() inFile = open("coreTemp_Td.pkl", "rb") Td = pickle.load(inFile) inFile.close() inFile = open("coreTemp_rates.pkl", "rb") rates = pickle.load(inFile) inFile.close() startIdx = len(Tg) # Point at which to restart except IOError:
""" Created on Wed Sep 20 07:14:25 2017 @author: kaytemori """ #Automate despotic GMC property finding to calculate the CO(1-0), CO(2-1) line #brightness ('intTb' in the despotic lines) and plot these brightnesses for #the despotic GMC model as a function of temperature for T= 5 K to 100 K #(T = 5, 10, 15, ... 100 K). from despotic import cloud import numpy as np import matplotlib.pyplot as plt gmc = cloud(fileName="MilkyWayGMC.desp", verbose=True) gmc.setTempEq(verbose=True) lines = gmc.lineLum("co") T = np.linspace(5, 100, 20) co10 = np.zeros(T.size) co21 = np.zeros(T.size) for i, temp in enumerate(T): gmc.Tg = temp lines = gmc.lineLum("co") co10[i] = lines[0]["intTB"] co21[i] = lines[1]["intTB"]
vox_length = box_area * 3.08e18 / 256. total_density = pppcube.sum() # H2 cm^-3 cloud_mean_density = cloud_mass * 2e33 / 2.8 / 1.67e-24 / (total_density * vox_length**3) # start with simple case x, y = 128, 128 nelts = 100 expand = 0 vgrid = np.linspace(ppvcube.min(), ppvcube.max(), nelts) vdata = ppvcube[:100, y - expand:y + expand + 1, x - expand:x + expand + 1] pdata = pppcube[:100, y - expand:y + expand + 1, x - expand:x + expand + 1] * cloud_mean_density gmc = cloud(fileName='/Users/adam/repos/despotic/cloudfiles/MilkyWayGMC.desp') gmc.sigmaNT = 1e5 # cm/s, instead of 2 as default gmc.Tg = 20. # start at 20 instead of 15 K gmc.Td = 20. # add ortho-h2co gmc.addEmitter('o-h2co', 1e-9) spectra, props = despotify(pdata, vdata, vgrid, vox_length, cloud=gmc) onedshape = vgrid.shape + (np.prod(spectra[spectra.keys()[0]].shape[1:]), ) for key in spectra: pl.figure() pl.plot(vgrid, spectra[key].reshape(onedshape), label=key) pl.legend(loc='best')