def particle_file_writer(fname, particle_new_domain, headers, data_old,
                             new_icpu):
        # Count number of particles
        npart = 0
        masks = {}
        for icpu_old, part_dom in particle_new_domain.items():
            mask = part_dom == new_icpu
            masks[icpu_old] = mask

            npart += mask.sum()

        # Extract fields
        fields = data_old[1].keys()

        with FF(fname, mode="w") as fout:
            h = headers.copy()
            h["npart"] = npart

            # Write headers
            for key, _len, dtype in h["_structure"]:
                tmp = np.atleast_1d(h[key]).astype(dtype)
                assert (len(tmp) == _len) or (_len == -1)
                fout.write_vector(tmp)

            # Write fields
            for field in fields:
                vals = np.empty(npart, dtype=data_old[1][field].dtype)

                i0 = 0
                for mask, dt in zip(masks.values(), data_old.values()):
                    count = mask.sum()
                    vals[i0:i0 + count] = dt[field][mask]
                    i0 += count

                fout.write_vector(vals)
    def fluid_file_reader(field_handler: FieldFileHandler, headers: dict = {}):
        with FF(field_handler.fname, "r") as fin:
            headers.update(fin.read_attrs(field_handler.attrs))
            nvar = headers["nvar"]
            nboundaries = headers["nboundary"]
            nlevelmax = headers["nlevelmax"]
            ncpu = headers["ncpu"]

            data_out = np.full(
                (nvar, 8, field_handler.domain.amr_header["ngrid_current"]),
                0,
                dtype="d",
            )

            ii = 0
            for ilvl in range(nlevelmax):
                for icpu in range(ncpu + nboundaries):
                    fin.read_int()  # ilvl2
                    ncache = fin.read_int()
                    if ncache > 0:
                        for icell in range(8):
                            for ivar in range(nvar):
                                data_out[ivar, icell,
                                         ii:ii + ncache] = fin.read_vector("d")
                    ii += ncache
        return headers, data_out
def read_mach(it, path='', grids_path='', parameters_path='', digits=5, verbose=False):
    nmax, nmay, nmaz, nlevels = parameters.read_parameters(load_nma=True, load_npalev=False, load_nlevels=True,
                                                           load_namr=False, load_size=False, path=parameters_path)
    npatch, patchnx, patchny, patchnz = read_grids(it, path=grids_path, parameters_path=parameters_path,
                                                   read_general=False,
                                                   read_patchnum=True, read_dmpartnum=False,
                                                   read_patchcellextension=True, read_patchcellposition=False,
                                                   read_patchposition=False, read_patchparent=False)

    with FF(os.path.join(path, filename(it, 'm', digits))) as f:
        if verbose:
            print('Reading mach number...')
        M = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
        for l in range(1, nlevels + 1):
            for ipatch in range(npatch[0:l].sum() + 1, npatch[0:l + 1].sum() + 1):
                M.append(np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))

    return tuple([M])
    def particle_file_reader(particle_handler: ParticleFileHandler,
                             headers: dict = {}) -> dict:

        data_out = {}
        with FF(particle_handler.fname, "r") as fin:
            headers.update(fin.read_attrs(particle_handler.attrs))
            try:
                npart = headers["npart"]
            except KeyError:
                npart = headers[""]
            npart = headers.get("npart", None)

            for k, dtype in particle_handler.field_types.items():
                data_out[k] = fin.read_vector(dtype)

                # This happens for sink files
                if npart is not None:
                    assert data_out[k].size == npart

        return headers, data_out
    def fluid_file_writer(fname, headers, data, numbl):
        with FF(fname, mode="w") as fout:
            for key, _len, dtype in headers["_structure"]:
                tmp = np.atleast_1d(headers[key]).astype(dtype)
                assert len(tmp) == _len
                fout.write_vector(tmp)
            nvar = headers["nvar"]
            nboundaries = headers["nboundary"]
            nlevelmax = headers["nlevelmax"]
            ncpu = headers["ncpu"]

            ii = 0

            for ilvl in range(1, 1 + nlevelmax):
                for icpu in range(1, ncpu + nboundaries + 1):
                    ncache = numbl[ilvl - 1, icpu - 1]
                    fout.write_vector(np.asarray([ilvl], dtype=np.int32))
                    fout.write_vector(np.asarray([ncache], dtype=np.int32))
                    if ncache > 0:
                        for icell in range(8):
                            for ivar in range(nvar):
                                tmp = data[ivar, icell, ii:ii + ncache]
                                fout.write_vector(np.ascontiguousarray(tmp))
                    ii += ncache
    def write_amr_file(headers, amr_struct, amr_file):
        """This write the new amr files

        Parameters
        ----------
        """

        # Make sure arrays have the right types
        def convert(key, dtype):
            amr_struct[key] = amr_struct[key].astype(dtype)

        for key in (
                "headl",
                "numbl",
                "ind_grid",
                "next",
                "prev",
                "parent",
                "nbor",
                "son",
                "cpu_map",
                "refmap",
        ):
            convert(key, np.int32)
        for key in ("xc", ):
            convert(key, np.float64)
        # Write headers
        f = FF(amr_file, mode="w")
        print("Writing headers. ", end="")
        for k, t in _HEADERS:
            tmp = np.atleast_1d(headers[k]).astype(t)
            print(k, end="...")
            f.write_vector(tmp)
        print()

        # Write global AMR structure
        print("Writing global AMR structure. ", end="")
        for k, t in _AMR_STRUCT:
            if not isinstance(t, int):
                tmp = np.ascontiguousarray(np.atleast_1d(amr_struct[k]),
                                           dtype=t)
            else:
                tmp = np.char.asarray(amr_struct[k].ljust(128).encode(),
                                      1).astype("c")
            print(f"{k}", end="...")
            f.write_vector(tmp)

        # Coarse level
        numbl = amr_struct["numbl"]
        print("Coarse level")
        # NOTE: since son has shape (ncoarse + ngridmax*8, we only need to write cell 0
        #       of coarse level (i.e. root oct)
        f.write_vector(amr_struct["coarse_son"].astype(np.int32))
        f.write_vector(amr_struct["coarse_refmap"].astype(np.int32))
        cpu_map_coarse = np.argwhere(numbl[0] == 1).astype(
            np.int32).flatten() + 1
        assert cpu_map_coarse.size == 1
        f.write_vector(cpu_map_coarse)

        print("Fine levels")
        nlevelmax = headers["nlevelmax"]
        ncpu = headers["ncpu"]
        nboundary = headers["nboundary"]
        if nboundary > 0:
            raise NotImplementedError

        ii = 0
        ncache = 0

        def write_chunk(key, extra_slice=...):
            f.write_vector(
                np.ascontiguousarray(amr_struct[key][ii:ii + ncache,
                                                     extra_slice]))

        for ilvl in range(nlevelmax):
            for ibound in range(ncpu + nboundary):
                if ibound < ncpu:
                    ncache = numbl[ilvl, ibound]
                # else:
                #     ncache = numbb[ilvl, ibound]
                if ncache == 0:
                    continue
                write_chunk("ind_grid")
                write_chunk("next")
                write_chunk("prev")
                for idim in range(3):
                    write_chunk("xc", idim)
                write_chunk("parent")
                for idim in range(2 * 3):
                    write_chunk("nbor", idim)
                for idim in range(2**3):
                    write_chunk("son", idim)
                for idim in range(2**3):
                    assert np.all(
                        amr_struct["cpu_map"][ii:ii + ncache, idim] > 0)
                    write_chunk("cpu_map", idim)
                for idim in range(2**3):
                    write_chunk("refmap", idim)

                ii += ncache
def read_amr(amr_file: str, longint: bool, quadhilbert: bool):
    i8b = "l" if longint else "i"
    qdp = "float128" if quadhilbert else "float64"
    dp = "float64"
    with FF(amr_file) as f:
        headers = {}
        for h in ramses_header(headers):
            headers.update(f.read_attrs(h))

        # Read level variables
        shape = headers["nlevelmax"], headers["ncpu"]
        headl = f.read_vector("i").reshape(shape)
        taill = f.read_vector("i").reshape(shape)
        numbl = f.read_vector("i").reshape(shape)
        try:
            numbtot = f.read_vector(i8b).reshape((10, headers["nlevelmax"]))
        except ValueError:
            raise Exception(
                "Caught an exception while reading numbtot. This is likely due "
                "to you forgetting to (un)set the longint flag!\n"
                "Try calling the script with/out `--longint`.")

        # Free memory
        headf, tailf, numbf, used_mem, used_mem_tot = f.read_vector("i")

        # Ordering
        ordering = "".join(f.read_vector("c").astype(str)).strip()
        ndomain = headers["ncpu"] * 1
        if ordering != "hilbert":
            raise NotImplementedError
        try:
            if quadhilbert:
                with open(amr_file, "br") as f2:
                    f2.seek(f.tell())
                    s1 = int.from_bytes(f2.read(4), byteorder="little")
                    bound_keys = np.array(
                        [
                            rawQuadToDouble(f2.read(16))
                            for i in range(ndomain + 1)
                        ],
                        dtype=np.float128,
                    )
                    s2 = int.from_bytes(f2.read(4), byteorder="little")
                    assert s1 == s2
                    f.seek(f2.tell())
            else:
                bound_keys = f.read_vector(qdp).reshape(ndomain + 1)
        except ValueError:
            raise Exception(
                "Caught an exception while reading hilbert keys. This is likely due "
                "to you forgetting to (un)set the quadhibert flag!\n"
                "Try calling the script with/out `--quadhilbert`.")

        nlevelmax, nboundary, ncpu, ndim, ngridmax = (headers[k]
                                                      for k in ("nlevelmax",
                                                                "nboundary",
                                                                "ncpu", "ndim",
                                                                "ngridmax"))

        # Allocate memory
        _level, _ndom, ind_grid, next, prev, parent = (np.zeros(ngridmax,
                                                                dtype="i")
                                                       for _ in range(6))
        _level_cell = np.zeros((ngridmax, 8), dtype="i")
        xc = np.zeros((ngridmax, ndim), dtype="d")
        nbor = np.zeros((ngridmax, 2 * ndim), dtype="i")
        son, cpu_map, refmap = (np.zeros((ngridmax, 2**ndim), dtype="i")
                                for _ in range(3))

        # Coarse levels
        # should be of length 1 unless there are non-periodic boundaries
        ncoarse = 1
        coarse_son = f.read_vector("i").reshape(ncoarse)
        coarse_refmap = f.read_vector("i").reshape(ncoarse)
        coarse_cpu_map = f.read_vector("i").reshape(ncoarse)

        ret = {"headers": headers}
        ret["headl"] = headl
        ret["taill"] = taill
        ret["numbl"] = numbl
        ret["numbtot"] = numbtot
        ret["bound_keys"] = bound_keys
        ret["son"] = son
        ret["refmap"] = refmap
        ret["cpu_map"] = cpu_map

        # Fine levels
        i = 0
        for ilevel in range(nlevelmax):
            for ibound in range(nboundary + ncpu):
                if ibound <= ncpu:
                    ncache = numbl[ilevel, ibound]  # NOTE: C-order vs. F-order
                else:
                    raise NotImplementedError(
                        "Cannot load datasets with non-periodic boundary conditions"
                    )
                    # ncache = numbb[ilevel, ibound - ncpu]

                def read(kind):
                    tmp = f.read_vector(kind)
                    return tmp.reshape(ncache)

                if ncache > 0:
                    ind_grid[i:i + ncache] = read("i")
                    next[i:i + ncache] = read("i")
                    prev[i:i + ncache] = read("i")
                    xc[i:i + ncache] = np.stack(
                        [read(dp) for i in range(ndim)], axis=-1)
                    parent[i:i + ncache] = read("i")
                    nbor[i:i + ncache] = np.stack(
                        [read("i") for idim in range(2 * ndim)], axis=-1)
                    son[i:i + ncache] = np.stack(
                        [read("i") for idim in range(2**ndim)], axis=-1)
                    cpu_map[i:i + ncache] = np.stack(
                        [read("i") for idim in range(2**ndim)], axis=-1)
                    refmap[i:i + ncache] = np.stack(
                        [read("i") for idim in range(2**ndim)], axis=-1)

                    _level[i:i + ncache] = ilevel + 1  # Fortran is 1-indexed
                    _level_cell[i:i + ncache, :] = ilevel + 2
                    _ndom[i:i + ncache] = ibound + 1  # Fortran is 1-indexed
                    i += ncache

        (
            ind_grid,
            next,
            prev,
            xc,
            parent,
            nbor,
            son,
            cpu_map,
            refmap,
            _level,
            _level_cell,
            _ndom,
        ) = (_[:i] for _ in (
            ind_grid,
            next,
            prev,
            xc,
            parent,
            nbor,
            son,
            cpu_map,
            refmap,
            _level,
            _level_cell,
            _ndom,
        ))

        ret.update(
            dict(
                ind_grid=ind_grid,
                next=next,
                prev=prev,
                xc=xc,
                parent=parent,
                nbor=nbor,
                son=son,
                cpu_map=cpu_map,
                refmap=refmap,
                coarse_refmap=coarse_refmap,
                coarse_cpu_map=coarse_cpu_map,
                coarse_son=coarse_son,
                _level=_level,
                _level_cell=_level_cell,
                _ndom=_ndom,
            ))

        return ret
def read_vortex(it, path='', grids_path='', parameters_path='', digits=5, are_divrot=True, are_potentials=True,
                are_velocities=True, is_header=True, verbose=False):
    """
    Reads the vortex (Helmholtz-Hodge decomposition) files

    Args:
        it: iteration number (int)
        path: path of the grids file in the system (str)
        parameters_path: path of the json parameters file of the simulation
        digits: number of digits the filename is written with (int)
        max_refined_level: maximum refinement level that wants to be read. Subsequent refinements will be skipped. (int)
        are_divrot: whehther velocity divergences and rotationals are written in the file
        are_potentials: whether (scalar and vector) potentials are written in the file
        are_velocities: whether (total, compressional and rotational) velocities are written in the file
        is_solapst: whether the overlap variable computed using the error estimate is written in the file

    Returns:
        Chosen quantities, as a list of arrays (one for each patch, starting with l=0 and subsequently);
        in the order specified by the order of the parameters in this definition.
    """

    nmax, nmay, nmaz, nlevels = parameters.read_parameters(load_nma=True, load_npalev=False, load_nlevels=True,
                                                           load_namr=False, load_size=False, path=parameters_path)
    npatch, patchnx, patchny, patchnz = read_grids(it, path=grids_path, parameters_path=parameters_path, read_general=False,
                                                   read_patchnum=True, read_dmpartnum=False,
                                                   read_patchcellextension=True, read_patchcellposition=False,
                                                   read_patchposition=False, read_patchparent=False)
    with FF(os.path.join(path, filename(it, 'v', digits))) as f:
        # read header
        if is_header:
            it_clus = f.read_vector('i')[0]
            # assert(it == it_clus)
            f.seek(0)  # this is a little bit ugly but whatever
            time, z = tuple(f.read_vector('f')[1:3])

        returnvariables = []

        if are_divrot:
            # divergence
            if verbose:
                print('Reading divergence...')
            div = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            for l in range(1, nlevels + 1):
                for ipatch in range(npatch[0:l].sum() + 1, npatch[0:l + 1].sum() + 1):
                    div.append(np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))

            # rotational
            if verbose:
                print('Reading rotational...')
            rotx = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            roty = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            rotz = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            for l in range(1, nlevels + 1):
                for ipatch in range(npatch[0:l].sum() + 1, npatch[0:l + 1].sum() + 1):
                    rotx.append(np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
                    roty.append(np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
                    rotz.append(np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))

            returnvariables.extend([div, rotx, roty, rotz])

        if are_potentials:
            # scalar
            if verbose:
                print('Reading scalar potential...')
            scalarpot = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            for l in range(1, nlevels + 1):
                for ipatch in range(npatch[0:l].sum() + 1, npatch[0:l + 1].sum() + 1):
                    scalarpot.append(np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch],
                                                                     patchnz[ipatch]), 'F'))

            # vector
            if verbose:
                print('Reading vector potential...')
            vecpotx = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            vecpoty = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            vecpotz = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            for l in range(1, nlevels + 1):
                for ipatch in range(npatch[0:l].sum() + 1, npatch[0:l + 1].sum() + 1):
                    vecpotx.append(
                        np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
                    vecpoty.append(
                        np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
                    vecpotz.append(
                        np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
            returnvariables.extend([scalarpot, vecpotx, vecpoty, vecpotz])

        if are_velocities:
            # total
            if verbose:
                print('Reading total velocity...')
            vx = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            vy = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            vz = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            for l in range(1, nlevels + 1):
                for ipatch in range(npatch[0:l].sum() + 1, npatch[0:l + 1].sum() + 1):
                    vx.append(
                        np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
                    vy.append(
                        np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
                    vz.append(
                        np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))

            # compressive
            if verbose:
                print('Reading compressive velocity...')
            velcompx = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            velcompy = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            velcompz = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            for l in range(1, nlevels + 1):
                for ipatch in range(npatch[0:l].sum() + 1, npatch[0:l + 1].sum() + 1):
                    velcompx.append(
                        np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
                    velcompy.append(
                        np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
                    velcompz.append(
                        np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
            # rotational
            if verbose:
                print('Reading rotational velocity...')
            velrotx = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            velroty = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            velrotz = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            for l in range(1, nlevels + 1):
                for ipatch in range(npatch[0:l].sum() + 1, npatch[0:l + 1].sum() + 1):
                    velrotx.append(np.reshape(f.read_vector('f'),
                                              (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
                    velroty.append(np.reshape(f.read_vector('f'),
                                              (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
                    velrotz.append(np.reshape(f.read_vector('f'),
                                              (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))

            returnvariables.extend([vx, vy, vz, velcompx, velcompy, velcompz, velrotx, velroty, velrotz])

    return tuple(returnvariables)
def read_clst(it, path='', parameters_path='', digits=5, max_refined_level=1000, output_deltastar=True, verbose=False,
              output_position=False, output_velocity=False, output_mass=False, output_temp=False,
              output_metalicity=False, output_id=False):
    """
    Reads the stellar (clst) file.
    For now, it only reads the delta.

    Args:
        it: iteration number (int)
        path: path of the output files in the system (str)
        parameters_path: path of the json parameters file of the simulation
        digits: number of digits the filename is written with (int)
        max_refined_level: maximum refinement level that wants to be read. Subsequent refinements will be skipped. (int)
        output_deltastar: whether deltadm (dark matter density contrast) is returned (bool)
        output_position: whether particles' positions are returned (bool)
        output_velocity: whether particles' velocities are returned (bool)
        output_mass: whether particles' masses are returned (bool)
        output_temp: whether particles' temperatures are returned (bool)
        output_metalicity: whether particles' metalicities are returned (bool)
        output_id: whether particles' ids are returned (bool)
        verbose: whether a message is printed when each refinement level is started (bool)

    Returns:
        Chosen quantities, in the order specified by the order of the parameters in this definition.
        delta_dm is returned as a list of numpy matrices. The 0-th element corresponds to l=0. The i-th element
        corresponds to the i-th patch.
        The rest of quantities are outputted as numpy vectors, the i-th element corresponding to the i-th stellar
        particle.


    """
    nmax, nmay, nmaz, nlevels = parameters.read_parameters(load_nma=True, load_npalev=False, load_nlevels=True,
                                                           load_namr=False, load_size=False, path=parameters_path)
    npatch, npart, patchnx, patchny, patchnz = read_grids(it, path=path, read_general=False, read_patchnum=True,
                                                          read_dmpartnum=True, read_patchcellextension=True,
                                                          read_patchcellposition=False, read_patchposition=False,
                                                          read_patchparent=False, parameters_path=parameters_path)

    with FF(os.path.join(path, filename(it, 's', digits))) as f:

        # read header
        it_clst = f.read_vector('i')[0]

        f.seek(0)  # this is a little bit ugly but whatever
        time, z = tuple(f.read_vector('f')[1:3])

        # l=0
        if verbose:
            print('Reading base grid...')

        if output_deltastar:
            delta_star = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
        else:
            f.skip()

        if output_position:
            stpart_x = f.read_vector('f')
            stpart_y = f.read_vector('f')
            stpart_z = f.read_vector('f')
        else:
            f.skip(3)

        if output_velocity:
            stpart_vx = f.read_vector('f')
            stpart_vy = f.read_vector('f')
            stpart_vz = f.read_vector('f')
        else:
            f.skip(3)

        if output_mass:
            stpart_mass = f.read_vector('f')
        else:
            f.skip()

        if output_temp:
            stpart_temp = f.read_vector('f')
        else:
            f.skip()

        if output_metalicity:
            stpart_metalicity = f.read_vector('f')
        else:
            f.skip()

        if output_id:
            stpart_id = np.zeros(stpart_x.size)

        # refinement levels
        for l in range(1, min(nlevels + 1, max_refined_level + 1)):
            if verbose:
                print('Reading level {}.'.format(l))
                print('{} patches'.format(npatch[l]))
            for ipatch in range(npatch[0:l].sum() + 1, npatch[0:l + 1].sum() + 1):
                if output_deltastar:
                    delta_star.append(
                        np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]),
                                   'F'))
                else:
                    f.skip()

            if output_position:
                stpart_x = np.append(stpart_x, f.read_vector('f'))
                stpart_y = np.append(stpart_y, f.read_vector('f'))
                stpart_z = np.append(stpart_z, f.read_vector('f'))
            else:
                f.skip(3)

            if output_velocity:
                stpart_vx = np.append(stpart_vx, f.read_vector('f'))
                stpart_vy = np.append(stpart_vy, f.read_vector('f'))
                stpart_vz = np.append(stpart_vz, f.read_vector('f'))
            else:
                f.skip(3)

            if output_mass:
                stpart_mass = np.append(stpart_mass, f.read_vector('f'))
            else:
                f.skip()

            if output_temp:
                stpart_temp = np.append(stpart_temp, f.read_vector('f'))
            else:
                f.skip()

            if output_metalicity:
                stpart_metalicity = np.append(stpart_metalicity, f.read_vector('f'))
            else:
                f.skip()

            if output_id:
                stpart_id = np.append(stpart_id, f.read_vector('i'))
            else:
                f.skip()

    returnvariables = []

    if output_deltastar:
        returnvariables.append(delta_star)
    if output_position:
        returnvariables.extend([stpart_x, stpart_y, stpart_z])
    if output_velocity:
        returnvariables.extend([stpart_vx, stpart_vy, stpart_vz])
    if output_mass:
        returnvariables.append(stpart_mass)
    if output_temp:
        returnvariables.append(stpart_temp)
    if output_metalicity:
        returnvariables.append(stpart_metalicity)
    if output_id:
        returnvariables.append(stpart_id)

    return tuple(returnvariables)
示例#10
0
def read_clus(it, path='', parameters_path='', digits=5, max_refined_level=1000, output_delta=True, output_v=True,
              output_pres=True, output_pot=True, output_opot=False, output_temp=True, output_metalicity=True,
              output_cr0amr=True, output_solapst=True, is_mascletB=False, output_B=False, is_cooling=True,
              verbose=False):
    """
    Reads the gas (baryonic, clus) file

    Args:
        it: iteration number (int)
        path: path of the grids file in the system (str)
        parameters_path: path of the json parameters file of the simulation
        digits: number of digits the filename is written with (int)
        max_refined_level: maximum refinement level that wants to be read. Subsequent refinements will be skipped. (int)
        output_delta: whether delta (density contrast) is returned (bool)
        output_v: whether velocities (vx, vy, vz) are returned (bool)
        output_pres: whether pressure is returned (bool)
        output_pot: whether gravitational potential is returned (bool)
        output_opot: whether gravitational potential in the previous iteration is returned (bool)
        output_temp: whether temperature is returned (bool)
        output_metalicity: whether metalicity is returned (bool)
        output_cr0amr: whether "refined variable" (1 if not refined, 0 if refined) is returned (bool)
        output_solapst: whether "solapst variable" (1 if the cell is kept, 0 otherwise) is returned (bool)
        is_mascletB: whether the outputs correspond to masclet-B (contains magnetic fields) (bool)
        output_B: whether magnetic field is returned; only if is_mascletB = True (bool)
        is_cooling: whether there is cooling (an thus T and metalicity are written) or not (bool)
        verbose: whether a message is printed when each refinement level is started (bool)
        fullverbose: whether a message is printed for each patch (recommended for debugging issues) (bool)

    Returns:
        Chosen quantities, as a list of arrays (one for each patch, starting with l=0 and subsequently);
        in the order specified by the order of the parameters in this definition.
    """

    if output_B and (not is_mascletB):
        print('Error: cannot output magnetic field if the simulation has not.')
        print('Terminating')
        return

    nmax, nmay, nmaz, nlevels = parameters.read_parameters(load_nma=True, load_npalev=False, load_nlevels=True,
                                                           load_namr=False, load_size=False, path=parameters_path)
    npatch, patchnx, patchny, patchnz = read_grids(it, path=path, parameters_path=parameters_path, read_general=False,
                                                   read_patchnum=True, read_dmpartnum=False,
                                                   read_patchcellextension=True, read_patchcellposition=False,
                                                   read_patchposition=False, read_patchparent=False)
    with FF(os.path.join(path, filename(it, 'b', digits))) as f:
        # read header
        it_clus = f.read_vector('i')[0]
        # assert(it == it_clus)
        f.seek(0)  # this is a little bit ugly but whatever
        time, z = tuple(f.read_vector('f')[1:3])

        # l=0
        if verbose:
            print('Reading base grid...')
        if output_delta:
            delta = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
        else:
            f.skip()

        if output_v:
            vx = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            vy = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            vz = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
        else:
            f.skip(3)

        if output_pres:
            pres = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
        else:
            f.skip()

        if output_pot:
            pot = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
        else:
            f.skip()

        if output_opot:
            opot = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
        else:
            f.skip()

        if is_cooling:
            if output_temp:
                temp = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            else:
                f.skip()

            if output_metalicity:
                metalicity = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            else:
                f.skip()

        if output_cr0amr:
            cr0amr = [np.reshape(f.read_vector('i'), (nmax, nmay, nmaz), 'F').astype('bool')]
        else:
            f.skip()

        if output_solapst:
            solapst = [0]

        if is_mascletB:
            if output_B:
                Bx = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
                By = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
                Bz = [np.reshape(f.read_vector('f'), (nmax, nmay, nmaz), 'F')]
            else:
                f.skip(3)


        # refinement levels
        for l in range(1, min(nlevels + 1, max_refined_level + 1)):
            if verbose:
                print('Reading level {}.'.format(l))
                print('{} patches.'.format(npatch[l]))
            for ipatch in range(npatch[0:l].sum() + 1, npatch[0:l + 1].sum() + 1):
                if verbose:
                    print('Reading patch {}'.format(ipatch))

                if output_delta:
                    delta.append(np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]),
                                            'F'))
                else:
                    f.skip()

                if output_v:
                    vx.append(np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
                    vy.append(np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
                    vz.append(np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
                else:
                    f.skip(3)

                if output_pres:
                    pres.append(np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]),
                                           'F'))
                else:
                    f.skip()

                if output_pot:
                    pot.append(np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
                else:
                    f.skip()

                if output_opot:
                    opot.append(
                        np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
                else:
                    f.skip()

                if is_cooling:
                    if output_temp:
                        temp.append(
                            np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
                    else:
                        f.skip()

                    if output_metalicity:
                        metalicity.append(
                            np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]), 'F'))
                    else:
                        f.skip()

                if output_cr0amr:
                    cr0amr.append(np.reshape(f.read_vector('i'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]),
                                             'F').astype('bool'))
                else:
                    f.skip()

                if output_solapst:
                    solapst.append(np.reshape(f.read_vector('i'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]),
                                              'F').astype('bool'))
                else:
                    f.skip()

                if is_mascletB:
                    if output_B:
                        Bx.append(np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]),
                                             'F'))
                        By.append(np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]),
                                             'F'))
                        Bz.append(np.reshape(f.read_vector('f'), (patchnx[ipatch], patchny[ipatch], patchnz[ipatch]),
                                             'F'))
                    else:
                        f.skip(3)

    returnvariables = []
    if output_delta:
        returnvariables.append(delta)
    if output_v:
        returnvariables.extend([vx, vy, vz])
    if output_pres:
        returnvariables.append(pres)
    if output_pot:
        returnvariables.append(pot)
    if output_opot:
        returnvariables.append(opot)
    if output_temp:
        returnvariables.append(temp)
    if output_metalicity:
        returnvariables.append(metalicity)
    if output_cr0amr:
        returnvariables.append(cr0amr)
    if output_solapst:
        returnvariables.append(solapst)
    if output_B:
        returnvariables.extend([Bx,By,Bz])

    return tuple(returnvariables)