def createModel(iniFileName): """ parse the ini file and construct the initial data for the entire model: all density, potentials, and Schwarzschild model components, with initial conditions for the orbit library and relevant density/kinematic targets. """ model = type('Model', (), {}) ini = RawConfigParser() ini.read(iniFileName) sec = ini.sections() sec_den = dict() # list of density components sec_pot = dict() # same for potential sec_comp = dict( ) # list of model components (each one may include several density objects) Omega = None for s in sec: if s.lower().startswith('density'): sec_den[s.lower()] = dict(ini.items(s)) if s.lower().startswith('potential'): sec_pot[s.lower()] = dict(ini.items(s)) if s.lower().startswith('component'): sec_comp[s.lower()] = dict(ini.items(s)) if s.lower() == 'global': # pattern speed for name, value in ini.items(s): if name.lower() == 'omega': Omega = float(value) # construct all density and potential objects den = dict() pot = dict() for name, value in sec_den.items(): den[name] = agama.Density(**value) for name, value in sec_pot.items(): if 'density' in value: listdens = list() for den_str in filter(None, re.split('[,\s]', value['density'].lower())): if den_str in sec_den: listdens.append(den[den_str]) if len(listdens) == 1: value['density'] = listdens[0] elif len(listdens) > 1: value['density'] = agama.Density(*listdens) # else there are no user-defined density sections print("Creating " + name) pot[name] = agama.Potential(**value) pot[name].export("model_" + name) model.density = den if len(pot) == 0: raise ValueError("No potential components defined") if len(pot) == 1: model.potential = pot.values()[0] else: model.potential = agama.Potential(*pot.values()) # determine corotation radius in case of nonzero pattern speed if Omega != 0: try: from scipy.optimize import brentq print("Omega=%.3g => corotation radius: %.3g" % ( Omega, brentq( lambda r: model.potential.force(r, 0, 0)[0] / r + Omega**2, 1e-10, 1e10, rtol=1e-4))) except Exception as e: print("Omega=%.3g, corotation radius unknown: %s" % (Omega, str(e))) # construct all model components if len(sec_comp) == 0: raise ValueError("No model components defined") model.components = dict() for name, value in sec_comp.items(): targets = list() if not 'density' in value: raise ValueError("Component " + name + " does not have an associated density") listdens = list() for den_str in filter(None, re.split('[,\s]', value['density'].lower())): if den_str in sec_den: listdens.append(den[den_str]) elif den_str in sec_pot: listdens.append(pot[den_str]) else: raise ValueError("Unknown density component: " + den_str + " in " + name) if len(listdens) == 1: density = listdens[0] elif len(listdens) > 1: density = agama.Density(*listdens) else: raise ValueError("No density components in " + name) print("Creating density target for " + name) targets.append(agama.Target(**value)) if 'kinemgrid' in value: options = { "type": 'KinemShell', \ "gridr": value['kinemgrid'], \ "degree": int(value['kinemdegree']) } print("Creating kinematic target for " + name) targets.append(agama.Target(**options)) if 'numorbits' in value: icoptions = { 'n': int(value['numorbits']), 'potential': model.potential } if 'icbeta' in value: icoptions['beta'] = float(value['icbeta']) if 'ickappa' in value: icoptions['kappa'] = float(value['ickappa']) print("Creating initial conditions for %i orbits in %s" % (icoptions['n'], name)) ic, weightprior = density.sample(**icoptions) else: raise ValueError("No orbits defined in " + name) if 'inttime' in value: inttime = float(value['inttime']) * model.potential.Tcirc(ic) else: raise ValueError("No integration time defined in " + name) comp = type('Component', (), \ {"density": density, "ic": ic, "weightprior": weightprior, \ "inttime": inttime, "targets": targets, "Omega": Omega} ) if 'trajsize' in value: comp.trajsize = int(value['trajsize']) if 'beta' in value: comp.beta = float(value['beta']) if 'nbody' in value: comp.nbody = int(value['nbody']) if not 'trajsize' in value: raise ValueError("No trajectory will be stored in " + name + ", cannot create Nbody model") model.components[name] = comp return model
posvel, gridx = numpy.linspace(-30.0, 30.0, 61), # [REQ] X-axis pixel boundaries for the 1st (LR) dataset gridy = numpy.linspace(-30.0, 30.0, 61), # [REQ] same for Y axis nbins = 150, # [REQ] desired number of Voronoi bins (the result may differ somewhat) alpha = alpha, # orientation angles - same as in kinemParams1 beta = beta, gamma = gamma1 ) # save the binning scheme to text file numpy.savetxt(filenameVorBin1, numpy.column_stack((xc, yc, bintags)), fmt='%7.3f %7.3f %7d') # 2st step: construct the LOSVD target and apply it to the N-body snapshot print('Computing LOSVDs of input snapshot') apertures = agama.schwarzlib.getBinnedApertures(xc, yc, bintags) # obtain boundary polygons from Voronoi bins gridx, gridy = agama.schwarzlib.makeGridForTargetLOSVD(apertures, psf1) # construct a suitable image-plane grid target = agama.Target(apertures=apertures, gridx=gridx, gridy=gridy, **kinemParams1) datacube = target((posvel, mass)).reshape(len(apertures), -1) # assign errors/noise on the computed values from the Poisson noise estimate of B-spline amplitudes particlemass = numpy.mean(mass) noisecube = (numpy.maximum(datacube, particlemass) * particlemass)**0.5 # 3rd step: convert the B-spline LOSVDs to GH moments print('Computing Gauss-Hermite moments and their error estimates') ghorder = 6 # [OPT] order of GH expansion ghm_val, ghm_err = agama.schwarzlib.ghMomentsErrors(degree=degree, gridv=gridv, values=datacube, errors=noisecube, ghorder=ghorder) ind = (1,2,6,7,8,9) # keep only these columns, corresponding to v,sigma,h3,h4,h5,h6 numpy.savetxt(filenameGH1, numpy.dstack((ghm_val, ghm_err))[:,ind,:].reshape(len(apertures), -1), fmt='%8.3f', header='v v_err sigma sigma_err h3 h3_err h4 h4_err h5 h5_err h6 h6_err') # 4th step: convert the B-splines to histograms, which are in fact 0th-degree B-splines; # we might have constructed model LOSVDs in terms of histograms directly, but this would have been less accurate
""" import agama, numpy # density profile den = agama.Density(type='Dehnen', axisRatioY=0.8, axisRatioZ=0.6, scaleRadius=1, mass=1, gamma=1) # potential corresponding to this density pot = agama.Potential(type='Multipole', lmax=8, mmax=6, density=den) # target1 is discretized density profile target1 = agama.Target(type='DensityClassicLinear', gridr=agama.nonuniformGrid(25, 0.1, 20.0), \ axisratioy=0.8, axisratioz=0.6, stripsPerPane=2) # target2 is discretized kinematic constraint (we will enforce velocity isotropy) target2 = agama.Target(type='KinemShell', gridR=agama.nonuniformGrid(15, 0.2, 10.0), degree=1) # construct initial conditions for the orbit library initcond, weightprior = den.sample(5000, potential=pot) # integration time is 50 orbital periods inttimes = 50 * pot.Tcirc(initcond) # integrate all orbits, storing the recorded data corresponding to each target # in the data1 and data2 arrays, and the trajectories - in trajs data1, data2, trajs = agama.orbit(potential=pot, ic=initcond, time=inttimes, \ trajsize=101, targets=[target1,target2])
def createModel(iniFileName): """ parse the ini file and construct the initial data for the entire model: all density, potentials, and Schwarzschild model components, with initial conditions for the orbit library and relevant density/kinematic targets. """ ini = ConfigParser.RawConfigParser() ini.read(iniFileName) sec = ini.sections() sec_den = dict() # list of density components sec_pot = dict() # same for potential sec_comp = dict( ) # list of model components (each one may include several density objects) for s in sec: if s.lower().startswith('density'): sec_den[s.lower()] = dict(ini.items(s)) if s.lower().startswith('potential'): sec_pot[s.lower()] = dict(ini.items(s)) if s.lower().startswith('component'): sec_comp[s.lower()] = dict(ini.items(s)) # construct all density and potential objects den = dict() pot = dict() for name, value in sec_den.items(): den[name] = agama.Density(**value) for name, value in sec_pot.items(): if value.has_key('density'): listdens = list() for den_str in filter(None, re.split('[,\s]', value['density'].lower())): if sec_den.has_key(den_str): listdens.append(den[den_str]) if len(listdens) == 1: value['density'] = listdens[0] elif len(listdens) > 1: value['density'] = agama.Density(*listdens) # else there are no user-defined density sections print "Creating", name pot[name] = agama.Potential(**value) pot[name].export("model_" + name) model = {'density': den} if len(pot) == 0: raise ValueError("No potential components defined") if len(pot) == 1: model['potential'] = pot.values()[0] else: model['potential'] = agama.Potential(*pot.values()) # construct all model components if len(sec_comp) == 0: raise ValueError("No model components defined") comp = dict() model['components'] = comp for name, value in sec_comp.items(): targets = list() if not value.has_key('density'): raise ValueError("Component " + name + " does not have an associated density") listdens = list() for den_str in filter(None, re.split('[,\s]', value['density'].lower())): if sec_den.has_key(den_str): listdens.append(den[den_str]) elif sec_pot.has_key(den_str): listdens.append(pot[den_str]) else: raise ValueError("Unknown density component: " + den_str + " in " + name) if len(listdens) == 1: value['density'] = listdens[0] elif len(listdens) > 1: value['density'] = agama.Density(*listdens) else: raise ValueError("No density components in " + name) print "Creating density target for", name targets.append(agama.Target(**value)) if value.has_key('kinemshells'): options = { "type": 'KinemJeans', "gridSizeR": int(value['kinemshells']), \ "density": value['density'], "potential": model['potential'] } if value.has_key('kinemdegree'): options['degree'] = int(value['kinemdegree']) print "Creating kinematic target for", name targets.append(agama.Target(**options)) if value.has_key('numorbits'): icoptions = { 'n': int(value['numorbits']), 'potential': model['potential'] } if value.has_key('icbeta'): icoptions['beta'] = float(value['icbeta']) if value.has_key('ickappa'): icoptions['kappa'] = float(value['ickappa']) print "Creating initial conditions for", icoptions[ 'n'], "orbits in", name ic, weightprior = value['density'].sample(**icoptions) else: raise ValueError("No orbits defined in " + name) if value.has_key('inttime'): inttime = float(value['inttime']) * model['potential'].Tcirc(ic) else: raise ValueError("No integration time defined in " + name) comp[name] = { "ic": ic, "weightprior": weightprior, "inttime": inttime, "targets": targets } if value.has_key('trajsize'): comp[name]['trajsize'] = int(value['trajsize']) if value.has_key('beta'): comp[name]['beta'] = float(value['beta']) if value.has_key('nbody'): comp[name]['nbody'] = int(value['nbody']) if not value.has_key('trajsize'): raise ValueError("No trajectory will be stored in " + name + ", cannot create Nbody model") return model
sersicIndex=4, axisRatioZ=0.6, scaleRadius=1, mass=1) # central black hole (slightly softened) potbh = agama.Potential(type='Plummer', scaleRadius=1e-4, mass=0.1) # total potential pot = agama.Potential(potstars, potbh) # discretized density profile is recorded on a grid of radial points and spherical harmonics up to lmax gridr = agama.nonuniformGrid( 50, 0.02, 20.0) # !! make sure that the grid covers the range of interest !! target = agama.Target(type='DensitySphHarm', gridr=gridr, lmax=8, mmax=0) # discretized density profile to be used as the density constraint rhs = target(potstars) print("Density constraint values") for i in range(len(gridr)): print("%s: mass= %g" % (target[i], rhs[i])) # construct initial conditions for the orbit library: # use the anisotropic Jeans eqs to set the (approximate) shape of the velocity ellipsoid and the mean v_phi; beta = 0.0 # velocity anisotropy in R/z plane: >0 - sigma_R>sigma_z, <0 - reverse. kappa = 0.8 # sets the amount of rotation v_phi vs. dispersion sigma_phi; 1 is rather fast rotation, 0 - no rot. initcond, _ = potstars.sample(10000, potential=pot, beta=beta, kappa=kappa) # integration time is 100 orbital periods inttimes = 100 * pot.Tcirc(initcond)
0, 2 * numpy.pi, 73) # approximate a circle with a polygon with this many vertices sa = numpy.sin(ang) sa[36] = sa[72] = 0 ca = numpy.cos(ang) ca[18] = ca[54] = 0 circ = [numpy.column_stack((rr * ca, rr * sa)) for rr in gridr[1:]] poly = [circ[0]] + [ numpy.vstack((p1, p2[::-1])) for p1, p2 in zip(circ[1:], circ[:-1]) ] numaper = len( poly ) # total number of apertures (all concentric rings except the central one, which is a circle) # define different types of target objects tar_dens = agama.Target(type='DensitySphHarm', gridr=gridr) tar_shell = agama.Target(type='KinemShell', gridr=gridr, degree=1) degree = 2 # B-spline degree for LOSVD representation (2 or 3 are strongly recommended) tar_losvd = agama.Target(type='LOSVD', degree=degree, apertures=poly, gridx=gridx, gridv=gridv, symmetry='s') # generate N-body samples from the model, # and integrate orbits with (some of) these initial conditions xv, mass = gm.sample(1000000) ic = xv[:10000] # use only a subset of ICs, to save time mat_dens, mat_shell, mat_losvd = agama.orbit( potential=pot,
# density profile den = agama.Density(type='Dehnen', axisRatioY=0.8, axisRatioZ=0.6, scaleRadius=1, mass=1, gamma=1) # potential corresponding to this density pot = agama.Potential(type='Multipole', lmax=8, mmax=6, density=den, gridsizer=30) # target1 is discretized density profile target1 = agama.Target(type='DensityClassicLinear', density=den, gridsizer=15, \ axisratioy=0.8, axisratioz=0.6, stripsPerPane=2, innerShellMass=0.04, outerShellMass=0.96) # target2 is discretized kinematic constraint (we will enforce velocity isotropy) target2 = agama.Target(type='KinemJeans', density=den, potential=pot, gridSizeR=10, degree=1) # construct initial conditions for the orbit library initcond, weightprior = den.sample(2000, potential=pot) # integration time is 50 orbital periods inttimes = 50 * pot.Tcirc(initcond) # integrate all orbits, storing the recorded data corresponding to each target # in the data1 and data2 arrays, and the trajectories - in trajs data1, data2, trajs = agama.orbit(potential=pot, ic=initcond, time=inttimes, \ trajsize=101, targets=[target1,target2])