コード例 #1
0
    def sanity_check(self):

        # Check file has the expected size (e.g. in case ID type is wrong)
        if not (self.all_bytes_used()):
            raise SanityCheckFailedException("File size is incorrect!")

        # Check sum over particle types equals total number of particles in each group
        grouplen = self["GroupLen"][...]
        grouplentype = self["GroupLenType"][...]
        if np.any(np.sum(grouplentype, axis=1, dtype=np.int64) != grouplen):
            raise SanityCheckFailedException(
                "GroupLen not consistent with GroupLenType!")

        # Each offset should be previous offset plus length
        if self["Nids"][...] > 1:
            groupoffset = self["GroupOffset"][...]
            if np.any(groupoffset[1:] != groupoffset[:-1] + grouplen[:-1]):
                raise SanityCheckFailedException(
                    "Offsets and lengths not consistent!")

        # Check sum of mass over particle types equals total mass of particles in each group
        groupmass = self["GroupMass"][...]
        groupmasstype = self["GroupMassType"][...]
        mass_sum = np.sum(groupmasstype, axis=1, dtype=np.float64)
        if np.any(np.abs(mass_sum - groupmass) / groupmass > 1.0e-5):
            raise SanityCheckFailedException(
                "GroupMass not consistent with GroupMassType!")
コード例 #2
0
    def sanity_check(self):

        # Check file has the expected size (e.g. in case ID type is wrong)
        if not (self.all_bytes_used()):
            raise SanityCheckFailedException("File size is incorrect!")

        # Check that IDs don't contain duplicates
        ids = self["GroupIDs"][...]
        idx, counts = np.unique(ids, return_counts=True)
        if np.any(counts != 1):
            raise SanityCheckFailedException("Found duplicate IDs!")
コード例 #3
0
    def sanity_check(self):

        ngroups = self["Ngroups"][...]
        nids = self["Nids"][...]
        nfiles = self["NFiles"][...]
        nsubgroups = self["Nsubhalos"][...]

        nsubperhalo = self["NsubPerHalo"][...]
        firstsubofhalo = self["FirstSubOfHalo"][...]
        sublen = self["SubLen"][...]
        suboffset = self["SubOffset"][...]
        subparenthalo = self["SubParentHalo"][...]

        # Check assignment of subhalos to halos
        if np.sum(nsubperhalo) != nsubgroups:
            raise SanityCheckFailedException("Sum of NSubPerHalo is wrong")
        ind = nsubperhalo > 0
        if np.any(firstsubofhalo[ind] < 0) or np.any(
                firstsubofhalo[ind] >= nsubgroups):
            raise SanityCheckFailedException("FirstSubOfHalo out of range")
        if np.any(suboffset < 0) or np.any(suboffset + sublen > nids):
            raise SanityCheckFailedException(
                "Subhalo particle index(es) out of range")

        # Check subhalo parent group index
        parent = np.repeat(np.arange(ngroups, dtype=np.int32), nsubperhalo)
        if np.any(subparenthalo != parent):
            raise SanityCheckFailedException(
                "Subhalo parent halo index is wrong")

        # Check quantities which should be finite
        for name in ("Halo_M_Mean200", "Halo_R_Mean200", "Halo_M_Crit200",
                     "Halo_R_Crit200", "Halo_M_TopHat200", "Halo_R_TopHat200",
                     "SubPos", "SubVel", "SubVelDisp", "SubVmax", "SubSpin",
                     "SubHalfMass"):
            data = self[name][...]
            if np.any(np.logical_not(np.isfinite(data))):
                raise SanityCheckFailedException(
                    "Quantity %s has non-finite value" % name)

        # Return None if everything looks ok
        return None
コード例 #4
0
    def sanity_check(self):

        ids = self["GroupIDs"][...]
        if np.any(ids < 0):
            raise SanityCheckFailedException("Found negative ID")

        # Split ID into particle ID and hash key
        key = np.right_shift(ids, 34)
        ids = ids - np.left_shift(key, 34)

        # Note: hash table size and max ID hard coded here
        if np.any(key < 0) or np.any(key >= 256**3):
            raise SanityCheckFailedException("Hash key out of range")
        if np.any(ids < 0) or np.any(ids > 2160**3):
            raise SanityCheckFailedException("Particle ID out of range")
        if sum(ids == 0) > 1:
            raise SanityCheckFailedException("Found multiple zero IDs")

        # Return None if everything looks ok
        return None
コード例 #5
0
    def sanity_check(self):

        ngroups = self["Ngroups"][...]
        nids = self["Nids"][...]
        grouplen = self["GroupLen"][...]
        groupoffset = self["GroupOffset"][...]

        if sum(grouplen) != nids:
            raise SanityCheckFailedException(
                "Sum of group sizes does not equal number of particle IDs")

        if any(groupoffset < 0) or any(groupoffset >= nids):
            raise SanityCheckFailedException("Group offset out of range")

        if ngroups > 1:
            if any(groupoffset[1:] != groupoffset[:-1] + grouplen[:-1]):
                raise SanityCheckFailedException(
                    "Group offset not equal to (offset+length) of previous group"
                )

        return None
コード例 #6
0
    def sanity_check(self):

        # Check file has the expected size (e.g. in case ID type is wrong)
        if not (self.all_bytes_used()):
            raise SanityCheckFailedException("File size is incorrect!")

        totnids = self["TotNids"][...]
        totngroups = self["TotNgroups"][...]
        totnsubgroups = self["TotNsubgroups"][...]

        # Checks on header
        if totnids < 0 or totngroups < 0 or totnsubgroups < 0:
            raise SanityCheckFailedException(
                "Negative number of groups/subgroups/IDs")

        # Checks on group properties
        if np.any(self["GroupLen"][...] < 0):
            raise SanityCheckFailedException(
                "Found group with non-positive length!")
        if totnids < 2**31:
            # Offsets overflow if we have too many particles (e.g. Millennium-2),
            # so this test is expected to fail in that case
            if np.any(self["GroupOffset"][...] < 0) or np.any(
                    self["GroupOffset"][...] +
                    self["GroupLen"][...] > totnids):
                raise SanityCheckFailedException(
                    "Found group with offset out of range!")

        # Check pointers from groups to subgroups are sane
        firstsub = self["FirstSub"][...]
        nsubs = self["Nsubs"][...]
        if np.any(nsubs < 0):
            raise SanityCheckFailedException(
                "Negative number of subgroups in group!")
        ind = nsubs > 0
        if np.any(firstsub[ind] < 0) or np.any(
                firstsub[ind] + nsubs[ind] > totnsubgroups):
            raise SanityCheckFailedException(
                "Found group with subgroup index out of range!")

        # Check some group properties that we expect to be finite and non-negative
        for prop in ("GroupMass", "Halo_M_Mean200", "Halo_R_Mean200",
                     "Halo_M_Crit200", "Halo_R_Crit200", "Halo_M_TopHat200",
                     "Halo_R_TopHat200"):
            data = self[prop][...]
            if not (np.all(np.isfinite(data))):
                raise Exception("Found non-finite value in dataset %s" % prop)
            if not (np.all(data >= 0.0)):
                raise Exception("Found negative value in dataset %s" % prop)

        # Checks on subgroup properties
        if np.any(self["SubLen"][...] < 0):
            raise SanityCheckFailedException(
                "Found subgroup with non-positive length!")
        if totnids < 2**31:
            # Offsets overflow if we have too many particles (e.g. Millennium-2),
            # so this test is expected to fail in that case
            if np.any(self["SubOffset"][...] < 0) or np.any(
                    self["SubOffset"][...] + self["SubLen"][...] > totnids):
                raise SanityCheckFailedException(
                    "Found group with offset out of range!")

        # Check some subgroup properties that we expect to be finite and (in some cases) non-negative
        for prop in ("SubMass", "SubPos", "SubVel", "SubCofM", "SubSpin",
                     "SubVelDisp", "SubVmax", "SubRVmax", "SubHalfMass"):
            data = self[prop][...]
            if not (np.all(np.isfinite(data))):
                raise Exception("Found non-finite value in dataset %s" % prop)
            if not (np.all(data >= 0.0)) and prop in ("SubMass", "SubVelDisp",
                                                      "SubVmax", "SubRVmax",
                                                      "SubHalfMass"):
                raise Exception("Found negative value in dataset %s" % prop)

        # Check SubGrNr is in range and in the expected order
        subgrnr = self["SubGrNr"][...]
        if np.any(subgrnr < 0) or np.any(subgrnr >= totngroups):
            raise SanityCheckFailedException(
                "Subgroup's SubGrNr out of range!")
        if subgrnr.shape[0] > 1:
            if np.any(subgrnr[1:] < subgrnr[:-1]):
                raise SanityCheckFailedException(
                    "Subgroup SubGrNr's are not in ascending order!")
コード例 #7
0
    def sanity_check(self):

        n = self["Header"]
        boxsize = self["Header"].attrs["BoxSize"]
        nptot = self["Header"].attrs["NumPart_Total"]
        hashtabsize = self["Header"].attrs["HashTabSize"]
        nptot = nptot[1] + (nptot[2] << 32)

        # Determine hashbits
        hashbits = 1
        while hashtabsize > 2:
            hashtabsize /= 2
            hashbits += 1
        hashbits /= 3  # bits per dimension
        del hashtabsize

        # Check positions
        pos = self["PartType1/Coordinates"][...]
        if not (np.all(np.isfinite(pos))):
            raise SanityCheckFailedException(
                "Particle coordinate is not finite")
        if np.any(pos < 0.0) or np.any(pos > boxsize):
            raise SanityCheckFailedException(
                "Particle coordinate out of range")
        # (don't dealloc positions yet - needed for hash table check)

        # Check velocities
        vel = self["PartType1/Velocities"][...]
        if not (np.all(np.isfinite(vel))):
            raise SanityCheckFailedException("Particle velocity is not finite")
        if np.any(abs(vel) > 1.0e6):
            raise SanityCheckFailedException("Suspiciously high velocity")
        del vel

        # Check IDs
        ids = self["PartType1/ParticleIDs"][...]
        if np.any(ids < 0) or np.any(ids > nptot):
            raise SanityCheckFailedException("Particle ID out of range")
        del ids

        # Read hash table
        first_hash_cell = self["first_hash_cell"][...]
        last_hash_cell = self["last_hash_cell"][...]
        blockid = self["blockid"][...]

        # Calculate hash key for each particle
        key = np.zeros(pos.shape[0], dtype=np.int32) - 1
        for i in range(last_hash_cell - first_hash_cell):
            key[blockid[i]:blockid[i + 1]] = i + first_hash_cell
        key[blockid[-1]:] = last_hash_cell

        # Convert hash keys to grid coordinates
        ix, iy, iz = peano_hilbert_key_inverses(key, hashbits)

        # Convert grid coordinates to physical coords of cell centre
        cellsize = boxsize / (2**hashbits)
        cell_pos = np.empty_like(pos)
        cell_pos[:, 0] = ix * cellsize + 0.5 * cellsize
        cell_pos[:, 1] = iy * cellsize + 0.5 * cellsize
        cell_pos[:, 2] = iz * cellsize + 0.5 * cellsize

        # Ensure all particles are within cells
        for i in range(3):
            dx = np.abs(pos[:, i] - cell_pos[:, i])
            ind = dx > 0.5 * boxsize
            dx[ind] = boxsize - dx[ind]
            if any(dx > 1.001 * 0.5 * cellsize):
                raise SanityCheckFailedException(
                    "Particle not in correct hash cell")

        # Return None if everything looks ok
        return None