Exemple #1
0
def make_param(snapshot, filename=None):
    """
    Generates a default param dictionary.  Can be saved using 
    diskpy.utils.configsave

    EXAMPLE

    snapshot = pynbody.load('snapshot.std')  # Load snapshot
    param_dict = make_param(snapshot)  # Make default param dict
    diskpy.utils.configsave(param_dict, 'snapshot.param', ftype='param') # Save

    Optionally, the user can set the snapshot filename manually
    """
    param = configparser(_paramdefault, ftype='param')

    if filename is not None:

        param['achInFile'] = filename
        param['achOutName'] = os.path.splitext(filename)[0]

    elif snapshot.filename != '<created>':

        param['achInFile'] = snapshot.filename
        param['achOutName'] = os.path.splitext(snapshot.filename)[0]

    # Set up the length units
    param['dKpcUnit'] = snapshot['pos'].units.ratio('kpc')
    # Set up the mass units
    param['dMsolUnit'] = snapshot['mass'].units.ratio('Msol')
    # Set the mean molecular mass
    param['dMeanMolWeight'] = snapshot.gas['mu'][0]

    return param
Exemple #2
0
def getpar(key, param={}):
    """
    Attempts to retrieve the key from param or from the ChaNGa default param 
    options.  Raises ValueError if key not found in either.
    
    Parameters
    ----------
    key : object
    param : str or dict
        Paramname or param dict (see diskpy.utils.configparser).  If not 
        supplied, only the ChaNGa defaults are searched
    
    Returns
    -------
    value 
        The value, taken from param if present, otherwise taken from the ChaNGa
        default params
    """
    if isinstance(param, str):

        param = configparser(param, 'param')

    if key in param:

        value = param[key]

    elif key in _changadefault:

        value = _changadefault[key]

    else:

        raise ValueError, "Could not find {0} in param or defaults".format(key)

    return value
Exemple #3
0
def getpar(key, param={}):
    """
    Attempts to retrieve the key from param or from the ChaNGa default param 
    options.  Raises ValueError if key not found in either.
    
    Parameters
    ----------
    key : object
    param : str or dict
        Paramname or param dict (see diskpy.utils.configparser).  If not 
        supplied, only the ChaNGa defaults are searched
    
    Returns
    -------
    value 
        The value, taken from param if present, otherwise taken from the ChaNGa
        default params
    """
    if isinstance(param, str):
        
        param = configparser(param, 'param')
        
    if key in param:
        
        value = param[key]
        
    elif key in _changadefault:
        
        value = _changadefault[key]
        
    else:
        
        raise ValueError, "Could not find {0} in param or defaults".format(key)
        
    return value
Exemple #4
0
    def _load_units(param):

        # Load param if necessary
        if isinstance(param, str):

            param = configparser(param, 'param')

        # Universal G
        G = pynbody.units.G

        # Load units
        dKpcUnit = param['dKpcUnit']
        dMsolUnit = param['dMsolUnit']

        # Set up pynbody units
        m_unit = pynbody.units.Unit('{0} Msol'.format(dMsolUnit))
        l_unit = pynbody.units.Unit('{0} kpc'.format(dKpcUnit))
        t_unit = (l_unit**3/(G*m_unit))**(1,2)

        # Convert the time unit to something sensible
        years = t_unit.in_units('yr')
        t_unit = pynbody.units.Unit('{0} yr'.format(years))

        # Return
        outdict = {'l_unit':l_unit, 'm_unit':m_unit, 't_unit':t_unit}
        return outdict
Exemple #5
0
def find_param_names(simdir='.', paramfile=None, prefix=None):
    """
    Tries to find the .param and associated .log file for a simulation
    
    Returns paramfile, logfile
    
    If a filename is not found it will be returned as None
    """
    import path

    prefix = str(prefix)
    with path.Path(simdir) as directory:
        if paramfile is None:
            paramfile = prefix + '.param'
            if not os.path.isfile(paramfile):
                import glob
                names = glob.glob('*.param')
                if len(names) != 1:
                    print "could not find .param file"
                    paramfile = None
                else:
                    paramfile = names[0]

        logfile = None
        if paramfile is not None:

            try:
                # Load the param file
                param = configparser(paramfile, 'param')
                # Try to load the log file
                achOutName = getpar('achOutName', param)

                if os.path.isfile(achOutName + '.log'):
                    logfile = achOutName + '.log'
            except IOError:
                paramfile = None

        if logfile is None:
            if os.path.isfile(prefix + '.log'):
                logfile = prefix + '.log'

    if paramfile is not None:
        paramfile = os.path.join(simdir, paramfile)
    if logfile is not None:
        logfile = os.path.join(simdir, logfile)
    return paramfile, logfile
Exemple #6
0
def setup_param(param, snapshot=None, r_orb=1.0, n_orb=10.0, n_image=None, n_snap=100, \
n_check=None):
    """
    Sets up the following for a .param file:

        nSteps
        dDumpFrameStep
        iOutInterval
        iCheckInterval

    **ARGUMENTS**

    param : str or param_dict (see diskpy.utils.configparser, configsave)
        parameter file for the simulation, must already have dDelta and units
        set properly
        IF a str, assumed to be a filename
    snapshot : str or TipsySnap(see pynbody) or None
        Snapshot for the simulation.  Needed to estimate the outer orbital
        period.
        IF a str, assumed to be a filename
        IF None, the file pointed to by param is used
    r_orb : float
        radius to calculate the outer orbital period at as a fraction of the
        radius of the farthest out particle.  Must be between 0 and 1
    n_orb : float
        number of outer orbital periods to run simulation for
    n_image : int or None
        Total number of frames to dump (ie, dDumpFrameStep)
        If None, defaults to n_snap
    n_snap : int
        Total number of simulation outputs
    n_check : int or None
        Total number of simulation checkpoints.  If None, defaults to n_snap
    """

    if (r_orb > 1) | (r_orb < 0):

        raise ValueError, 'r_orb must be between 0 and 1'

    if isinstance(snapshot, str):

        # A filename has been passed, not a tipsy snapshot
        snapshot = pynbody.load(snapshot)

    if isinstance(param, str):

        # A filename has been passed.  Load the dictionary
        param = configparser(param, 'param')

    else:

        # Copy so as to not overwrite the input dict
        param = copy.deepcopy(param)

    R_max = r_orb * snapshot.g['rxy'].max()
    M_star = snapshot.s['mass']

    # Read in .param stuff
    l_unit = '{} kpc'.format(param['dKpcUnit'])
    m_unit = '{} Msol'.format(SimArray(param['dMsolUnit'], 'Msol'))

    # Outer radius and star mass in simulation units
    r = float(R_max.in_units(l_unit))
    M = float(M_star.in_units(m_unit))

    # Calculate the number of time steps to use
    dt = param['dDelta']
    period = 2 * np.pi * np.sqrt(r**3 / M)
    N = int(np.round(n_orb * period / dt))
    param['nSteps'] = N

    # Calculate how often to output snapshots, frames, checkpoints
    if n_check is None:

        n_check = n_snap

    if n_image is None:

        n_image = n_snap

    param['dDumpFrameStep'] = int(N / n_image)
    param['iOutInterval'] = int(N / n_snap)
    param['iCheckInterval'] = int(N / n_check)

    return param
Exemple #7
0
def units_from_param(param):
    """
    Figures out the simulation units from a .param file

    **ARGUMENTS**

    param : str or param dict (see configparser)
        Simulation .param file or param dict loaded by configparser
        Can also be a list or numpy array of these in which case a list
        of units dicts is returned

    **RETURNS**

    units : dict
        A dictionary of the units used in the simulation, returned as
        pynbody units
    """
    # Iterate over param if necessary
    if isinstance(param, (list, np.ndarray)):

        outlist = []

        for par in param:

            outlist.append(units_from_param(par))

        return outlist

    # Load param if necessary
    if isinstance(param, str):

        param = configparser(param, 'param')

    # Universal G
    G = pynbody.units.G

    # Load units
    dKpcUnit = getpar('dKpcUnit', param)
    dMsolUnit = getpar('dMsolUnit', param)

    # Set up pynbody units
    m_unit = pynbody.units.Unit('{0} Msol'.format(dMsolUnit))
    l_unit = pynbody.units.Unit('{0} kpc'.format(dKpcUnit))
    t_unit = (l_unit**3 / (G * m_unit))**(1, 2)

    # Convert the time unit to something sensible
    years = t_unit.in_units('yr')
    t_unit = pynbody.units.Unit('{0} yr'.format(years))

    # Calculate a couple derived units as well
    v_unit = l_unit / t_unit
    rho_unit = m_unit / l_unit**3
    acc_unit = l_unit / t_unit**2
    pres_unit = rho_unit * v_unit**2

    # Return
    outdict = {
        'l_unit': l_unit,
        'm_unit': m_unit,
        't_unit': t_unit,
        'v_unit': v_unit,
        'rho_unit': rho_unit,
        'acc_unit': acc_unit,
        'pres_unit': pres_unit
    }
    return outdict
Exemple #8
0
import pynbody
SimArray = pynbody.array.SimArray

from diskpy.utils import configparser, strip_units, get_units

# Constants
G = SimArray(1.0, 'G')

# Set up default filenames
_dir = os.path.dirname(os.path.realpath(__file__))
_paramdefault = os.path.join(_dir, 'default.param')
_directordefault = os.path.join(_dir, 'default.director')
_changadefault = os.path.join(_dir, 'changadefaults.param')

# Load the default parameters
_paramdefault = configparser(_paramdefault, 'param')
_directordefault = configparser(_directordefault, 'director')
_changadefault = configparser(_changadefault, 'param')


def getpar(key, param={}):
    """
    Attempts to retrieve the key from param or from the ChaNGa default param 
    options.  Raises ValueError if key not found in either.
    
    Parameters
    ----------
    key : object
    param : str or dict
        Paramname or param dict (see diskpy.utils.configparser).  If not 
        supplied, only the ChaNGa defaults are searched
Exemple #9
0
def find_clumps(f,
                n_smooth=32,
                param=None,
                arg_string=None,
                seed=None,
                verbose=True):
    """
    Uses skid (https://github.com/N-BodyShop/skid) to find clumps in a gaseous
    protoplanetary disk.  
    
    The linking length used is equal to the gravitational softening length of
    the gas particles.
    
    The density cut-off comes from the criterion that there are n_smooth particles
    within the Hill sphere of a particle.  This is formulated mathematically as:
    
        rho_min = 3*n_smooth*Mstar/R^3
        
    where R is the distance from the star.  The trick used here is to multiply
    all particle masses by R^3 before running skid so the density cut-off is:
    
        rho_min = 3*n_smooth*Mstar
        
    **ARGUMENTS**
    
    *f* : TipsySnap, or str
        A tipsy snapshot loaded/created by pynbody -OR- a filename pointing to a
        snapshot.
    
    *n_smooth* : int (optional)
        Number of particles used in SPH calculations.  Should be the same as used
        in the simulation.  Default = 32
    
    *param* : str (optional)
        filename for a .param file for the simulation
    
    *arg_string* : str (optional)
        Additional arguments to be passed to skid.  Cannot use -tau, -d, -m, -s, -o
    
    *seed* : int
        An integer used to seed the random filename generation for temporary
        files.  Necessary for multiprocessing and should be unique for each
        thread.
        
    *verbose* : bool
        Verbosity flag.  Default is True
    
    **RETURNS**
    
    *clumps* : array, int-like
        Array containing the group number each particle belongs to, with star
        particles coming after gas particles.  A zero means the particle belongs
        to no groups
    """
    # Parse areguments
    if isinstance(f, str):

        f = pynbody.load(f, paramfile=param)

    if seed is not None:

        np.random.seed(seed)

    # Estimate the linking length as the gravitational softening length
    tau = f.g['eps'][0]

    # Calculate minimum density
    rho_min = 3 * n_smooth * f.s['mass'][0]

    # Center on star.  This is done because R used in hill-sphere calculations
    # is relative to the star
    star_pos = f.s['pos'].copy()
    f['pos'] -= star_pos

    # Scale mass by R^3
    R = utils.strip_units(f['rxy'])
    m0 = f['mass'].copy()
    f['mass'] *= (R + tau)**3

    # Save temporary snapshot
    f_prefix = str(np.random.randint(np.iinfo(int).max))
    f_name = f_prefix + '.std'

    # Save temporary .param file
    if param is not None:

        param_name = f_prefix + '.param'
        param_dict = utils.configparser(param, 'param')
        utils.configsave(param_dict, param_name)

    f.write(filename=f_name, fmt=pynbody.tipsy.TipsySnap)

    f['pos'] += star_pos
    f['mass'] = m0

    command = 'totipnat < {} | skid -tau {:.2e} -d {:.2e} -m {:d} -s {:d} -o {}'\
    .format(f_name, tau, rho_min, n_smooth, n_smooth, f_prefix)
    p = subprocess.Popen(command,
                         shell=True,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)

    if verbose:

        for line in iter(p.stdout.readline, ''):
            print line,

    p.wait()

    # Load clumps
    clumps = loadhalos(f_prefix + '.grp')

    # Cleanup
    for name in glob.glob(f_prefix + '*'):

        os.remove(name)

    return clumps
Exemple #10
0
def find_clumps(f, n_smooth=32, param=None, arg_string=None, seed=None, verbose=True):
    """
    Uses skid (https://github.com/N-BodyShop/skid) to find clumps in a gaseous
    protoplanetary disk.  
    Also requires tipsy tools (https://github.com/N-BodyShop/tipsy_tools),
    specifically totipnat
    
    The linking length used is equal to the gravitational softening length of
    the gas particles.
    
    The density cut-off comes from the criterion that there are n_smooth particles
    within the Hill sphere of a particle.  This is formulated mathematically as:
    
        rho_min = 3*n_smooth*Mstar/R^3
        
    where R is the distance from the star.  The trick used here is to multiply
    all particle masses by R^3 before running skid so the density cut-off is:
    
        rho_min = 3*n_smooth*Mstar
        
    **ARGUMENTS**
    
    *f* : TipsySnap, or str
        A tipsy snapshot loaded/created by pynbody -OR- a filename pointing to a
        snapshot.
    
    *n_smooth* : int (optional)
        Number of particles used in SPH calculations.  Should be the same as used
        in the simulation.  Default = 32
    
    *param* : str (optional)
        filename for a .param file for the simulation
    
    *arg_string* : str (optional)
        Additional arguments to be passed to skid.  Cannot use -tau, -d, -m, -s, -o
    
    *seed* : int
        An integer used to seed the random filename generation for temporary
        files.  Necessary for multiprocessing and should be unique for each
        thread.
        
    *verbose* : bool
        Verbosity flag.  Default is True
    
    **RETURNS**
    
    *clumps* : array, int-like
        Array containing the group number each particle belongs to, with star
        particles coming after gas particles.  A zero means the particle belongs
        to no groups
    """
    # Check for skid and totipnat
    err = []
    skid_path = utils.which('skid')
    
    if skid_path is None:
        
        err.append('<skid not found : https://github.com/N-BodyShop/skid>')
        
    totipnat_path = utils.which('totipnat')
    
    if totipnat_path is None:
        
        err.append('<totipnat (part of tipsy tools) not found : '
        'https://github.com/N-BodyShop/tipsy_tools>')
        
    if len(err) > 0:
        
        err = '\n'.join(err)
        raise RuntimeError, err
        
    # Parse areguments
    if isinstance(f, str):
        
        f = pynbody.load(f, paramfile=param)
        
    if seed is not None:
        
        np.random.seed(seed)
        
    # Estimate the linking length as the gravitational softening length
    tau = f.g['eps'][0]
    
    # Calculate minimum density
    rho_min = 3*n_smooth*f.s['mass'][0]
    
    # Center on star.  This is done because R used in hill-sphere calculations
    # is relative to the star
    star_pos = f.s['pos'].copy()
    f['pos'] -= star_pos
    
    # Scale mass by R^3
    R = utils.strip_units(f['rxy'])
    m0 = f['mass'].copy()
    f['mass'] *= (R+tau)**3
    
    # Save temporary snapshot
    f_prefix = str(np.random.randint(np.iinfo(int).max))
    f_name = f_prefix + '.std'
    
    # Save temporary .param file
    if param is not None:
        
        param_name = f_prefix + '.param'
        param_dict = utils.configparser(param, 'param')
        utils.configsave(param_dict, param_name)
        
    f.write(filename=f_name, fmt=pynbody.tipsy.TipsySnap)
        
    f['pos'] += star_pos
    f['mass'] = m0
    
    command = 'totipnat < {} | skid -tau {:.2e} -d {:.2e} -m {:d} -s {:d} -o {}'\
    .format(f_name, tau, rho_min, n_smooth, n_smooth, f_prefix)
    p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    
    if verbose:
        
        for line in iter(p.stdout.readline, ''):
            print line,
            
    p.wait()
    
    # Load clumps
    clumps = loadhalos(f_prefix + '.grp')
    
    # Cleanup
    for name in glob.glob(f_prefix + '*'):
        
        os.remove(name)
        
    return clumps
Exemple #11
0
def setup_param(param, snapshot=None, r_orb=1.0, n_orb=10.0, n_image=None, n_snap=100, \
n_check=None):
    """
    Sets up the following for a .param file:

        nSteps
        dDumpFrameStep
        iOutInterval
        iCheckInterval

    **ARGUMENTS**

    param : str or param_dict (see diskpy.utils.configparser, configsave)
        parameter file for the simulation, must already have dDelta and units
        set properly
        IF a str, assumed to be a filename
    snapshot : str or TipsySnap(see pynbody) or None
        Snapshot for the simulation.  Needed to estimate the outer orbital
        period.
        IF a str, assumed to be a filename
        IF None, the file pointed to by param is used
    r_orb : float
        radius to calculate the outer orbital period at as a fraction of the
        radius of the farthest out particle.  Must be between 0 and 1
    n_orb : float
        number of outer orbital periods to run simulation for
    n_image : int or None
        Total number of frames to dump (ie, dDumpFrameStep)
        If None, defaults to n_snap
    n_snap : int
        Total number of simulation outputs
    n_check : int or None
        Total number of simulation checkpoints.  If None, defaults to n_snap
    """

    if (r_orb > 1) | (r_orb < 0):

        raise ValueError, 'r_orb must be between 0 and 1'

    if isinstance(snapshot, str):

        # A filename has been passed, not a tipsy snapshot
        snapshot = pynbody.load(snapshot)

    if isinstance(param, str):

        # A filename has been passed.  Load the dictionary
        param = configparser(param, 'param')

    else:

        # Copy so as to not overwrite the input dict
        param = copy.deepcopy(param)

    R_max = r_orb * snapshot.g['rxy'].max()
    M_star = snapshot.s['mass']

    # Read in .param stuff
    l_unit = '{} kpc'.format(param['dKpcUnit'])
    m_unit = '{} Msol'.format(SimArray(param['dMsolUnit'], 'Msol'))

    # Outer radius and star mass in simulation units
    r = float(R_max.in_units(l_unit))
    M = float(M_star.in_units(m_unit))

    # Calculate the number of time steps to use
    dt = param['dDelta']
    period = 2*np.pi*np.sqrt(r**3/M)
    N = int(np.round(n_orb * period/dt))
    param['nSteps'] = N

    # Calculate how often to output snapshots, frames, checkpoints
    if n_check is None:

        n_check = n_snap

    if n_image is None:

        n_image = n_snap

    param['dDumpFrameStep'] = int(N/n_image)
    param['iOutInterval'] = int(N/n_snap)
    param['iCheckInterval'] = int(N/n_check)

    return param
Exemple #12
0
def make_continue_sub(simdir='.', paramname='snapshot.param', \
newparam='continue.param', t=None, t_extra=None, oldsub='subber.sh', \
newsub='cont_subber.sh'):
    """
    Makes a submission script for continuing a simulation from a previous output.
    Also makes a .param file for the continued simulation.  The simulation
    will be continued in the same directory, with snapshot numbering scheme
    for outputs being the same.
    
    Parameters for the original simulation cannot be altered (except the number
    of steps you want to continue the simulation by).  PBS runtime parameters
    also cannot be changed (number of nodes, walltime, etc...)
    
    Any checkpoints will be deleted.
    
    Requires a submission script be present for the original simulation
    
    NOTE: if nSteps, nSteps_extra are not set, the total number of steps
    to simulate is not changed.
    
    
    **ARGUMENTS**
    
    simdir : str
        The simulation directory
    paramname : str
        Filename of the .param file for the simulation
    newparam : str
        filename for the .param file for the continued simulation
    t : float or SimArray
        Total simulation time to run.
        If no units are specified, it is in simulation units
    t_extra : float or SimArray
        Extra simulation time to run
        If no units are specified, it is in simulation units
        OVERIDES t!!!
    oldsub : str
        Filename for the original submission script
    newsub : str
        Filename for the new submission script
        
    **RETURNS**
    
    sub_path : str
        Full path to the PBS submission script
    
    """
    
    # Lazy man's way of dealing with files in another directory
    cwd = os.getcwd()
    
    os.chdir(simdir)
    
    # Load param file
    param = configparser(paramname, 'param')
    fprefix = param['achOutName']
    
    # Find all the outputs.  They should be of the format fprefix.000000
    search_exp = '^' + fprefix + '.(?:(?<!\d)\d{6}(?!\d))$'
    flist = []
    
    for fname in glob.glob(fprefix + '*'):
        
        if re.search(search_exp, fname) is not None:
            
            flist.append(fname)
    
    # Find the number of the last output (the last 6 chars should be an int)
    flist.sort()
    iStartStep = int(flist[-1][-6:])
    param['iStartStep'] = iStartStep
    param['achInFile'] = flist[-1]    
    dDelta = param['dDelta']
    
    # Set the number of steps to run        
    if t_extra is not None:
        
        # Convert to simulation units if needed
        if pynbody.units.has_units(t_extra):
            
            t_unit = units_from_param(param)['t_unit']
            t_extra.convert_units(t_unit)
        
        # Assign output
        param['nSteps'] = iStartStep + int(round(t_extra/dDelta))
        
    elif t is not None:
        
        # Convert to simulation units if needed
        if pynbody.units.has_units(t):
            
            t_unit = units_from_param(param)['t_unit']
            t.convert_units(t_unit)
            
        # Assign output
        param['nSteps'] = int(round(t/dDelta))
    
    # Save new param file
    configsave(param, newparam, ftype='param')
    
    # Delete old checkpoints

    for checkpoint in glob.glob(fprefix + '.chk*'):
        
        print 'removing ' + checkpoint
        os.system('rm -rf ' + checkpoint)
        
    if os.path.exists('lastcheckpoint'):
        
        print 'removing lastcheckpoint'
        os.remove('lastcheckpoint')
    
    # Create a submission script for the simulation continuation
    oldsubfile = open(oldsub, 'r')
    newsubfile = open(newsub, 'w')
    
    for line in oldsubfile:
        
        newsubfile.write(line.replace(paramname, newparam))
        
    oldsubfile.close()
    newsubfile.close()
    
    # Make the submission script executable
    os.chmod(newsub, 0777)
    
    sub_path = os.path.abspath(newsub)
    
    # Change back to original working directory
    os.chdir(cwd)
    
    return sub_path
Exemple #13
0
def load_acc(filename, param_name = None, low_mem = False):
    """
    Loads accelerations from a ChaNGa acceleration file (.acc2), ignoring the
    star particle.

    IF param_name is None, a .param file is searched for, otherwise param_name
    should be a string specifying a .param file name

    IF no param_file is found, the defaults are used:
        length unit: AU
        mass unit  : Msol

    Setting low_mem=True decreases memory usage by about 2x but also increases
    readtime by about 2x
    """

    if param_name is None:

        prefix = filename.split('.')[0]

        param_list = glob.glob('*' + prefix +'*param')

        if len(param_list) > 0:

            param_name = param_list[0]

        elif len(glob.glob('*.param')) > 0:

            param_name = glob.glob('*.param')[0]

        else:

            warnings.warn('Could not find .param file.  Assuming default units')

    if param_name is not None:

        # If a param name is set or a param file has been found:
        print 'Loading param file: {}'.format(param_name)
        param = configparser(param_name, ftype='param')

    else:

        # Set the default parameters
        param = {}
        # Assume AU as length unit
        param['dKpcUnit'] = pynbody.units.au.ratio('kpc')
        # Assume mass units as Msol
        param['dMsolUnit'] = 1.0

    # Figure out units
    G = pynbody.units.G
    l_unit = param['dKpcUnit']*pynbody.units.kpc
    m_unit = param['dMsolUnit']*pynbody.units.Msol
    t_unit = ((l_unit**3) * G**-1 * m_unit**-1)**(1,2)
    a_unit = l_unit * t_unit**-2

    if low_mem:

        acc_file = open(filename, 'r')
        n_particles = int(acc_file.readline().strip())
        acc = SimArray(np.zeros(3*n_particles, dtype=np.float32), a_unit)

        for i, line in enumerate(acc_file):

            acc[i] = np.float32(line.strip())

        acc_file.close()

        return acc.reshape([n_particles, 3], order='F')[0:-1]

    else:

        # Load acceleration file as numpy array
        acc = np.genfromtxt(filename, skip_header=1).astype(np.float32)
        n_particles = len(acc)/3

        # Reshape and make it a SimArray with proper units
        acc = SimArray(acc.reshape([n_particles, 3], order='F'), a_unit)

        return acc[0:-1]
Exemple #14
0
def load_acc(filename, param_name=None, low_mem=False):
    """
    Loads accelerations from a ChaNGa acceleration file (.acc2), ignoring the
    star particle.  ASSUMES A SINGLE STAR PARTICLE

    IF param_name is None, a .param file is searched for, otherwise param_name
    should be a string specifying a .param file name.  this is used to 
    specify units

    IF no param_file is found, the defaults are used:
        length unit: AU
        mass unit  : Msol

    Setting low_mem=True decreases memory usage by about 2x but also increases
    readtime by about 2x
    """
    # Try to infer units
    if param_name is None:

        prefix = filename.split('.')[0]

        param_list = glob.glob('*' + prefix + '*param')

        if len(param_list) > 0:

            param_name = param_list[0]

        elif len(glob.glob('*.param')) > 0:

            param_name = glob.glob('*.param')[0]

        else:

            warnings.warn(
                'Could not find .param file.  Assuming default units')

    if param_name is not None:

        # If a param name is set or a param file has been found:
        print 'Loading param file: {}'.format(param_name)
        param = configparser(param_name, ftype='param')

    else:

        # Set the default parameters
        param = {}
        # Assume AU as length unit
        param['dKpcUnit'] = pynbody.units.au.ratio('kpc')
        # Assume mass units as Msol
        param['dMsolUnit'] = 1.0

    # Figure out units
    G = pynbody.units.G
    l_unit = param['dKpcUnit'] * pynbody.units.kpc
    m_unit = param['dMsolUnit'] * pynbody.units.Msol
    t_unit = ((l_unit**3) * G**-1 * m_unit**-1)**(1, 2)
    a_unit = l_unit * t_unit**-2

    # LOAD
    acc = _load_tipsyarray3d_ascii(filename, low_mem=low_mem)
    acc.units = a_unit
    return acc
Exemple #15
0
def make_continue_sub(simdir='.', paramname='snapshot.param', \
newparam='continue.param', t=None, t_extra=None, oldsub='subber.sh', \
newsub='cont_subber.sh'):
    """
    Makes a submission script for continuing a simulation from a previous output.
    Also makes a .param file for the continued simulation.  The simulation
    will be continued in the same directory, with snapshot numbering scheme
    for outputs being the same.
    
    Parameters for the original simulation cannot be altered (except the number
    of steps you want to continue the simulation by).  PBS runtime parameters
    also cannot be changed (number of nodes, walltime, etc...)
    
    Any checkpoints will be deleted.
    
    Requires a submission script be present for the original simulation
    
    NOTE: if nSteps, nSteps_extra are not set, the total number of steps
    to simulate is not changed.
    
    
    **ARGUMENTS**
    
    simdir : str
        The simulation directory
    paramname : str
        Filename of the .param file for the simulation
    newparam : str
        filename for the .param file for the continued simulation
    t : float or SimArray
        Total simulation time to run.
        If no units are specified, it is in simulation units
    t_extra : float or SimArray
        Extra simulation time to run
        If no units are specified, it is in simulation units
        OVERIDES t!!!
    oldsub : str
        Filename for the original submission script
    newsub : str
        Filename for the new submission script
        
    **RETURNS**
    
    sub_path : str
        Full path to the PBS submission script
    
    """

    # Lazy man's way of dealing with files in another directory
    cwd = os.getcwd()

    os.chdir(simdir)

    # Load param file
    param = configparser(paramname, 'param')
    fprefix = param['achOutName']

    # Find all the outputs.  They should be of the format fprefix.000000
    search_exp = '^' + fprefix + '.(?:(?<!\d)\d{6}(?!\d))$'
    flist = []

    for fname in glob.glob(fprefix + '*'):

        if re.search(search_exp, fname) is not None:

            flist.append(fname)

    # Find the number of the last output (the last 6 chars should be an int)
    flist.sort()
    iStartStep = int(flist[-1][-6:])
    param['iStartStep'] = iStartStep
    param['achInFile'] = flist[-1]
    dDelta = param['dDelta']

    # Set the number of steps to run
    if t_extra is not None:

        # Convert to simulation units if needed
        if pynbody.units.has_units(t_extra):

            t_unit = units_from_param(param)['t_unit']
            t_extra.convert_units(t_unit)

        # Assign output
        param['nSteps'] = iStartStep + int(round(t_extra / dDelta))

    elif t is not None:

        # Convert to simulation units if needed
        if pynbody.units.has_units(t):

            t_unit = units_from_param(param)['t_unit']
            t.convert_units(t_unit)

        # Assign output
        param['nSteps'] = int(round(t / dDelta))

    # Save new param file
    configsave(param, newparam, ftype='param')

    # Delete old checkpoints

    for checkpoint in glob.glob(fprefix + '.chk*'):

        print 'removing ' + checkpoint
        os.system('rm -rf ' + checkpoint)

    if os.path.exists('lastcheckpoint'):

        print 'removing lastcheckpoint'
        os.remove('lastcheckpoint')

    # Create a submission script for the simulation continuation
    oldsubfile = open(oldsub, 'r')
    newsubfile = open(newsub, 'w')

    for line in oldsubfile:

        newsubfile.write(line.replace(paramname, newparam))

    oldsubfile.close()
    newsubfile.close()

    # Make the submission script executable
    os.chmod(newsub, 0777)

    sub_path = os.path.abspath(newsub)

    # Change back to original working directory
    os.chdir(cwd)

    return sub_path
Exemple #16
0
def make_director(sigma_min, sigma_max, r, resolution=1200, filename='snapshot'):
    """
    Makes a director dictionary for ChaNGa runs based on the min/max surface
    density, maximum image radius, and image resolution for a gaseous
    protoplanetary disk.  The created dictionary can be saved with
    diskpy.utils.configsave

    The method is to use an example director file (saved as default.director)
    which works for one simulation and scale the various parameters accordingly.
    default.director should have a commented line in it which reads:
        #sigma_max float
    where float is the maximum surface density of the simulation in simulation
    units.

    **ARGUMENTS**

    sigma_min : float
        The surface density that corresponds to 0 density on the image (ie the
        minimum threshold).  Required for setting the dynamic range
    sigma_max : float
        Maximum surface density in the simulation
    r : float
        Maximum radius to plot out to
    resolution : int or float
        Number of pixels in image.  The image is shape (resolution, resolution)
    filename : str
        prefix to use for saving the images.  Example: if filename='snapshot',
        then the outputs will be of form 'snapshot.000000000.ppm'

    **RETURNS**

    director : dict
        A .director dictionary.  Can be saved with diskpy.utils.configsave
    """
    # -----------------------------------------------------------
    # Parse defaults to get scale factor for c
    # -----------------------------------------------------------
    sigma_min, sigma_max, r = strip_units([sigma_min, sigma_max, r])
    defaults = configparser(_directordefault)
    if '#sigma_max' not in defaults:

        raise KeyError,'Default .director file should have a line e.g. << #sigma_max 0.01 >>'

    sigma_max0 = defaults['#sigma_max']
    c0 = defaults['colgas'][3]
    n0 = defaults['size'][0]
    r0 = defaults['eye'][2]
    A = (c0 * float(n0)**2)/(sigma_max0 * r0**2)

    # -----------------------------------------------------------
    # Create new director dictionary
    # -----------------------------------------------------------
    director = copy.deepcopy(defaults)
    director.pop('#sigma_max', None)

    logscale_min = sigma_min/sigma_max

    if pynbody.units.has_units(logscale_min):

        logscale_min = float(logscale_min.in_units('1'))

    c = A * float(sigma_max * r**2 /float(resolution)**2)

    director['colgas'][3] = c
    director['size'] = [resolution, resolution]
    director['eye'][2] = r
    director['file'] = filename

    return director
Exemple #17
0
import pynbody
SimArray = pynbody.array.SimArray

from diskpy.utils import configparser, strip_units, get_units

# Constants
G = SimArray(1.0,'G')

# Set up default filenames
_dir = os.path.dirname(os.path.realpath(__file__))
_paramdefault = os.path.join(_dir, 'default.param')
_directordefault = os.path.join(_dir, 'default.director')
_changadefault = os.path.join(_dir, 'changadefaults.param')

# Load the default parameters
_paramdefault = configparser(_paramdefault, 'param')
_directordefault = configparser(_directordefault, 'director')
_changadefault = configparser(_changadefault, 'param')

def getpar(key, param={}):
    """
    Attempts to retrieve the key from param or from the ChaNGa default param 
    options.  Raises ValueError if key not found in either.
    
    Parameters
    ----------
    key : object
    param : str or dict
        Paramname or param dict (see diskpy.utils.configparser).  If not 
        supplied, only the ChaNGa defaults are searched