Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
        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
Ejemplo n.º 3
0
"""
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])
Ejemplo n.º 4
0
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)
Ejemplo n.º 6
0
    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,
Ejemplo n.º 7
0
# 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])