Beispiel #1
0
def process_calculus(
    data,
    input_tmp,
    mod,
    output_tmp,
    xcolumn,
    fcolumn,
    foo,
    newcolumn,
    scale=DEFAULT_SCALE,
    shift=DEFAULT_SHIFT,
    overwrite=False,
    verbose=False,
):
    """manages I/O for performing calculations on a large number of files
    """
    N = len(data)
    for ind, eos in enumerate(data):
        tmp = {'moddraw': eos // mod, 'draw': eos}
        path = input_tmp % tmp
        if verbose:
            print('    %d/%d %s' % (ind + 1, N, path))
        d, c = io.load(path)

        ans, cols = calculus(d,
                             c,
                             xcolumn,
                             fcolumn,
                             foo,
                             newcolumn,
                             scale=scale,
                             shift=shift,
                             overwrite=overwrite)

        new = output_tmp % tmp
        if verbose:
            print('        writing: ' + new)

        newdir = os.path.dirname(new)
        if not os.path.exists(newdir):
            try:
                os.makedirs(newdir)
            except OSError:
                pass  ### directory already exists

        io.write(new, ans, cols)  ### save the result to the same file
Beispiel #2
0
def process2count(
    data,
    tmp,
    mod,
    reference_column,
    verbose=False,
):
    """handles I/O and extracts the number of lines in a particular file (like the number of branches, etc)
    """
    N = len(data)
    ans = np.empty(N, dtype=int)
    for i, eos in enumerate(data):
        path = tmp % {'moddraw': eos // mod, 'draw': eos}
        if verbose:
            print('    %d/%d %s' % (i + 1, N, path))
        d, _ = io.load(path, [reference_column])
        ans[i] = data2count(d)

    return ans, COUNT_TEMPLATE % reference_column
Beispiel #3
0
def process2sequences(eos,
                      eostmp,
                      mactmp,
                      min_central_pressurec2,
                      max_central_pressurec2,
                      central_baryon_density_range=None,
                      central_energy_densityc2_range=None,
                      mod=1000,
                      pressurec2_column=DEFAULT_PRESSUREC2_COLUMN,
                      energy_densityc2_column=DEFAULT_ENERGY_DENSITYC2_COLUMN,
                      baryon_density_column=DEFAULT_BARYON_DENSITY_COLUMN,
                      cs2c2_column=None,
                      central_eos_column=[],
                      central_column_template=DEFAULT_CENTRAL_COLUMN_TEMPLATE,
                      formalism=DEFAULT_FORMALISM,
                      verbose=False,
                      Verbose=False,
                      **kwargs):
    '''integrate stellar models for a whole set of EoS in a process
    '''
    verbose |= Verbose

    for draw in eos:
        tmp = {'draw': draw, 'moddraw': draw // mod}
        eospath = eostmp % tmp

        if verbose:
            print('loading EoS data from: ' + eospath)
        cols = [
            pressurec2_column, energy_densityc2_column, baryon_density_column
        ]
        if cs2c2_column is not None:
            cols.append(cs2c2_column)

        data, cols = io.load(
            eospath, cols + central_eos_column
        )  ### NOTE: this will not produce duplicated columns

        pressurec2 = data[:, cols.index(pressurec2_column)]
        energy_densityc2 = data[:, cols.index(energy_densityc2_column)]
        baryon_density = data[:, cols.index(baryon_density_column)]

        if cs2c2_column is not None:
            cs2c2 = data[:, cols.index(cs2c2_column)]
        else:
            cs2c2 = utils.num_dfdx(energy_densityc2, pressurec2)

        ### get local copy of bounds for just this EoS
        max_central_pc2 = max_central_pressurec2
        min_central_pc2 = min_central_pressurec2

        ### sanity check that our integration range is compatible with the EoS data available
        max_pressurec2 = np.max(pressurec2)
        if max_central_pc2 > max_pressurec2:
            if verbose:
                print(
                    'limitting central_pressurec2 <= %.6e based on EoS data\'s range'
                    % max_pressurec2)
            max_central_pc2 = max_pressurec2

        min_pressurec2 = np.min(pressurec2)
        if min_central_pc2 < min_pressurec2:
            if verbose:
                print(
                    'limitting central_pressurec2 >= %.6e based on EoS data\'s range'
                    % min_pressurec2)
            min_central_pc2 = min_pressurec2

        ### additionally check whether we're obeying the requested bounds on central baryon and energy densities
        if central_baryon_density_range is not None:
            min_baryon_density, max_baryon_density = central_baryon_density_range

            # check minimum
            min_pc2 = np.interp(min_baryon_density, baryon_density, pressurec2)
            if min_pc2 > min_central_pc2:
                if verbose:
                    print(
                        'limitting central_pressurec2 >= %.6e based on min_baryon_density = %.6e'
                        % (min_pc2, min_baryon_density))
                min_central_pc2 = min_pc2

            # check maximum
            max_pc2 = np.interp(max_baryon_density, baryon_density, pressurec2)
            if max_pc2 < max_central_pc2:
                if verbose:
                    print(
                        'limitting central_pressurec2 <= %.6e based on max_baryon_density = %.6e'
                        % (max_pc2, max_baryon_density))
                max_central_pc2 = max_pc2

        if central_energy_densityc2_range is not None:
            min_energy_densityc2, max_energy_densityc2 = central_energy_densityc2_range

            # check minimum
            min_pc2 = np.interp(min_energy_densityc2, energy_densityc2,
                                pressurec2)
            if min_pc2 > min_central_pc2:
                if verbose:
                    print(
                        'limitting central_pressurec2 >= %.6e based on min_energy_densityc2 = %.6e'
                        % (min_pc2, min_energy_densityc2))
                min_central_p2 = min_pc2

            # check maximum
            max_pc2 = np.interp(max_baryon_density, energy_densityc2,
                                pressurec2)
            if max_pc2 < max_central_pc2:
                if verbose:
                    print(
                        'limitting central_pressurec2 <= %.6e based on max_energy_densityc2 = %.6e'
                        % (max_pc2, max_energy_densityc2))
                max_central_pc2 = max_pc2

        ### check to make sure the pressure bounds are sane, futz them if they are not
        if max_central_pc2 < min_central_pc2:
            if verbose:
                print(
                    '''WARNING: central pressure bounds are out of order! Reverting to original bounds!
    min_central_pressurec2 = %.6e
    max_central_pressurec2 = %.6e''' %
                    (min_central_pressurec2, max_central_pressurec2))
            min_central_pc2, max_central_pc2 = min_central_pressurec2, max_central_pressurec2

        if verbose:
            print('''proceeding with central pressure bounds:
    min_central_pressurec2 = %.6e
    max_central_pressurec2 = %.6e''' % (min_central_pc2, max_central_pc2))

        ### now compute the stellar sequence
        if verbose:
            print('solving for sequence of stellar models with formalism=%s' %
                  formalism)
        central_pressurec2, macro, macro_cols = stellar_sequence(
            min_central_pc2,
            max_central_pc2,
            (pressurec2, energy_densityc2, baryon_density, cs2c2),
            verbose=Verbose,
            formalism=formalism,
            **kwargs)

        if verbose:
            print('    evaluated %d stellar models' % len(central_pressurec2))

        sequence, columns = append_central_values(
            central_pressurec2,
            pressurec2,
            data,
            cols,
            macro,
            macro_cols,
            central_eos_column=central_eos_column,
            central_column_template=central_column_template,
            verbose=verbose,
        )

        ### write the output
        macpath = mactmp % tmp
        if verbose:
            print('writing stellar sequence to: ' + macpath)
        io.write(macpath, sequence, columns)
Beispiel #4
0
def process2branch_properties(
    data,
    eos_template,
    eos_num_per_dir,
    mac_template,
    macro_num_per_dir,
    summary_template,
    eos_rho,
    macro_rhoc,
    macro_mass,
    output_eos_columns=DEFAULT_EOS_COLUMNS,
    output_macro_columns=DEFAULT_MACRO_COLUMNS,
    branch_template=None,
    verbose=False,
):
    """extract the branches for each EoS specified
    """
    tmp = dict()
    if branch_template is not None:  # do this backflip to make sure we can build string correctly
        branch_template = branch_template.replace('%(branch)06d',
                                                  '%(branch_string)s')
        tmp['branch_string'] = '%(branch)06d'

    N = len(data)
    for ind, eos in enumerate(data):

        ### construct paths
        # where we're going to read in data
        eos_path = eos_template % {
            'moddraw': eos // eos_num_per_dir,
            'draw': eos
        }

        tmp.update({'moddraw': eos // macro_num_per_dir, 'draw': eos})
        mac_path = mac_template % tmp

        # where we're going to write data
        sum_path = summary_template % tmp

        if verbose:
            print('    %d/%d' % (ind + 1, N))
            print('    loading macro: %s' % mac_path)
        mac_data, mac_cols = io.load(
            mac_path, [macro_rhoc, macro_mass] + output_macro_columns
        )  ### NOTE: we load all columns because we're going to re-write them all into subdir as separate branches

        if verbose:
            print('    loading eos: %s' % eos_path)
        eos_data, eos_cols = io.load(
            eos_path, [eos_rho] + output_eos_columns
        )  ### NOTE: this guarantees that eos_rho is the first column!
        baryon_density = eos_data[:, 0]  ### separate this for convenience

        # use macro data to identify separate stable branches
        # NOTE: we expect this to be ordered montonically in rhoc
        M = mac_data[:, mac_cols.index(macro_mass)]
        rhoc = mac_data[:, mac_cols.index(macro_rhoc)]

        if branch_template is not None:
            branch_tmp = branch_template % tmp
        else:
            branch_tmp = None

        params, names = data2branch_properties(
            rhoc,
            M,
            baryon_density,
            mac_data,
            mac_cols,
            eos_data,
            eos_cols,
            branch_template=branch_tmp,
            verbose=verbose,
        )
        if verbose:
            print('    writing summary into: %s' % sum_path)

        newdir = os.path.dirname(sum_path)
        if not os.path.exists(newdir):
            try:
                os.makedirs(newdir)
            except OSError:
                pass  ### directory already exists

        io.write(sum_path, params, names)
Beispiel #5
0
def process2extrema(
    data,
    tmp,
    mod,
    columns,
    static_ranges=None,
    dynamic_minima=None,
    dynamic_maxima=None,
    verbose=False,
):
    """manages I/O and extracts max, min for the specified columns
    """
    N = len(data)
    Ncol = len(columns)
    loadcolumns = columns[:]

    if static_ranges is not None:
        loadcolumns += [
            key for key in static_ranges.keys() if key not in loadcolumns
        ]  ### avoid duplicates
        static_ranges = [(loadcolumns.index(column), val)
                         for column, val in static_ranges.items()]
    else:
        static_ranges = []

    if dynamic_minima is not None:
        for val in dynamic_minima.values():
            assert len(
                val) == N, 'dynamic minima must have the same length as data'
        loadcolumns += [
            key for key in dynamic_minima.keys() if key not in loadcolumns
        ]
        dynamic_minima = [(loadcolumns.index(key), val)
                          for key, val in dynamic_minima.items()]
    else:
        dynamic_minima = []

    if dynamic_maxima is not None:
        for val in dynamic_maxima.values():
            assert len(
                val) == N, 'dynamic minima must have the same length as data'
        loadcolumns += [
            key for key in dynamic_maxima.keys() if key not in loadcolumns
        ]
        dynamic_maxima = [(loadcolumns.index(key), val)
                          for key, val in dynamic_maxima.items()]
    else:
        dynamic_maxima = []

    ans = np.empty((N, 2 * len(columns)), dtype=float)
    for i, eos in enumerate(data):
        path = tmp % {'moddraw': eos // mod, 'draw': eos}
        if verbose:
            sys.stdout.write('\r    %d/%d %s' % (i + 1, N, path))
            sys.stdout.flush()

        d, _ = io.load(path, loadcolumns)

        minima = [(j, val[i]) for j, val in dynamic_minima]
        maxima = [(j, val[i]) for j, val in dynamic_maxima]

        ans[i] = data2extrema(d,
                              Ncol,
                              static_ranges=static_ranges,
                              dynamic_minima=minima,
                              dynamic_maxima=maxima)

    if verbose:
        sys.stdout.write('\n')
        sys.stdout.flush()

    return ans
Beispiel #6
0
def process2moi_features(
    data,
    eos_template,
    eos_num_per_dir,
    mac_template,
    macro_num_per_dir,
    summary_template,
    eos_rho,
    eos_cs2c2,
    macro_rhoc,
    macro_mass,
    macro_moi,
    output_eos_columns=DEFAULT_EOS_COLUMNS,
    output_macro_columns=DEFAULT_MACRO_COLUMNS,
    flatten_thr=DEFAULT_FLATTEN_THR,
    smoothing_width=DEFAULT_SMOOTHING_WIDTH,
    diff_thr=DEFAULT_DIFF_THR,
    cs2c2_cofactor=DEFAULT_CS2C2_COFACTOR,
    verbose=False,
):
    """extract the branches for each EoS specified
    """
    N = len(data)
    for ind, eos in enumerate(data):

        ### construct paths
        # where we're going to read in data
        eos_path = eos_template % {
            'moddraw': eos // eos_num_per_dir,
            'draw': eos
        }

        tmp = {'moddraw': eos // macro_num_per_dir, 'draw': eos}
        mac_path = mac_template % tmp

        # where we're going to write data
        sum_path = summary_template % tmp

        if verbose:
            print('    %d/%d' % (ind + 1, N))
            print('    loading macro: %s' % mac_path)
        mac_data, mac_cols = io.load(
            mac_path,
            [macro_rhoc, macro_mass, macro_moi] + output_macro_columns
        )  ### NOTE: we load all columns because we're going to re-write them all into subdir as separate branches

        if verbose:
            print('    loading eos: %s' % eos_path)
        eos_data, eos_cols = io.load(
            eos_path, [eos_rho, eos_cs2c2] + output_eos_columns
        )  ### NOTE: this guarantees that eos_rho is the first column!
        baryon_density = eos_data[:, eos_cols.index(
            eos_rho)]  ### separate this for convenience
        cs2c2 = eos_data[:, eos_cols.index(eos_cs2c2)]

        # use macro data to identify separate stable branches
        # NOTE: we expect this to be ordered montonically in rhoc
        M = mac_data[:, mac_cols.index(macro_mass)]
        I = mac_data[:, mac_cols.index(macro_moi)]
        rhoc = mac_data[:, mac_cols.index(macro_rhoc)]

        params, names = data2moi_features(
            rhoc,
            M,
            I,
            baryon_density,
            cs2c2,
            mac_data,
            mac_cols,
            eos_data,
            eos_cols,
            flatten_thr=flatten_thr,
            smoothing_width=smoothing_width,
            diff_thr=diff_thr,
            cs2c2_cofactor=cs2c2_cofactor,
            verbose=verbose,
        )

        if verbose:
            print(
                '    writing summary of %d identified moi-features into: %s' %
                (len(params), sum_path))
        io.write(sum_path, params, names)
Beispiel #7
0
def process2samples(
    data,
    tmp,
    mod,
    xcolumn,
    ycolumns,
    static_x_test=None,
    dynamic_x_test=None,
    x_multiplier=1.,
    verbose=False,
    selection_rule=DEFAULT_SELECTION_RULE,
    branches_mapping=None,
    default_values=None,
):
    """manages I/O and extracts samples at the specified places
    returns an array that is ordered as follows
        for each ycolumn: for each static x_test
    """
    loadcolumns = [xcolumn] + ycolumns

    if static_x_test is None:
        static_x_test = []
    static_x_test = list(static_x_test)  ### make sure this is a list
    Nref = len(static_x_test)

    if dynamic_x_test is not None:
        assert len(dynamic_x_test) == len(data)
        Ndyn = np.shape(dynamic_x_test)[1]
    else:
        Ndyn = 0

    Ntot = Nref + Ndyn
    assert Ntot > 0, 'must provide at least one static_x_test or dynamic_x_test'

    if (Nref > 0) and (selection_rule == 'nearest_neighbor'):
        print(
            'WARNING! selection_rule="nearest_neighbor" may not be safe when specifying static_x_test. \
Instead, please use it only with dynamic_x_test that correspond to the exact values of individual samples \
that have already been extracted from the curves (e.g., the maximum)')

    if branches_mapping is not None:
        assert default_values is not None, 'must specify default_values when branches_mapping is not None'
        assert len(default_values) == len(
            ycolumns), 'must specify exactly 1 default value for each ycolumn!'

        branches_tmp, affine, affine_start, affine_stop = branches_mapping
        loadcolumns.append(affine)

    else:
        branches_tmp = None

    N = len(data)
    ans = np.empty((N, (Nref + Ndyn) * len(ycolumns)), dtype=float)
    for i, eos in enumerate(data):
        path = tmp % {'moddraw': eos // mod, 'draw': eos}
        if verbose:
            sys.stdout.write('\r    %d/%d %s' % (i + 1, N, path))
            sys.stdout.flush()

        d, c = io.load(path, loadcolumns)
        if branches_mapping is not None:
            a = d[:, c.index(affine)]

        x = d[:, c.index(xcolumn)] * x_multiplier
        d = d[:, [c.index(col) for col in ycolumns]]

        if branches_tmp is not None:
            branches_path = branches_tmp % {'moddraw': eos // mod, 'draw': eos}
            if verbose:
                sys.stdout.write('\r    %d/%d %s' % (i + 1, N, branches_path))
                sys.stdout.flush()

            b, _ = io.load(branches_path, [affine_start, affine_stop])
            branches = [(start <= a) * (a <= stop) for start, stop in b
                        ]  ### define booleans to represent branches

        else:
            branches = None

        x_test = static_x_test + (list(dynamic_x_test[i])
                                  if dynamic_x_test is not None else [])

        ans[i] = data2samples(
            x,
            d,
            x_test,
            selection_rule=selection_rule,
            branches=branches,
            default_values=default_values,
        )

    if verbose:
        sys.stdout.write('\n')
        sys.stdout.flush()

    return ans
Beispiel #8
0
def set_crust(crust_eos=DEFAULT_CRUST_EOS):
    global CRUST_PRESSUREC2, CRUST_ENERGY_DENSITYC2, CRUST_BARYON_DENSITY
    CRUST_PRESSUREC2, CRUST_ENERGY_DENSITYC2, CRUST_BARYON_DENSITY = \
        load(eospaths.get(crust_eos, crust_eos), columns=['pressurec2', 'energy_densityc2', 'baryon_density'])[0].transpose()