def recruit_new(self, rec_rate_ph, rec_r, p_rec_r, tissue, grid, cyto):
        num_reps = rec_rate_ph  # maximum number of macrophages recruited per time step

        cyto_index = np.argwhere(
            np.logical_and(tissue == TissueType.BLOOD.value, cyto >= rec_r))
        if len(cyto_index) == 0:
            # nowhere to place cells
            return

        for _ in range(num_reps):
            if p_rec_r > rg.random():
                ii = rg.integers(cyto_index.shape[0])
                point = Point(
                    x=grid.x[cyto_index[ii, 2]],
                    y=grid.y[cyto_index[ii, 1]],
                    z=grid.z[cyto_index[ii, 0]],
                )
                # Do we really want these things to always be in the exact center of the voxel?
                # No we do not. Should not have any effect on model, but maybe some on
                # visualization.
                perturbation = rg.multivariate_normal(mean=[0.0, 0.0, 0.0],
                                                      cov=[[0.25, 0.0, 0.0],
                                                           [0.0, 0.25, 0.0],
                                                           [0.0, 0.0, 0.25]])
                perturbation_magnitude = np.linalg.norm(perturbation)
                perturbation /= max(1.0, perturbation_magnitude)
                point += perturbation
                self.append(MacrophageCellData.create_cell(point=point))
    def recruit_new(self, rec_rate_ph, rec_r, granule_count, neutropenic, time, grid, tissue, cyto):
        num_reps = 0
        if not neutropenic:
            num_reps = rec_rate_ph  # number of neutrophils recruited per time step
        elif neutropenic and 48 <= time <= 96:
            # TODO: relate 3 to Algorithm S3.14 and rec_rate_ph or introduce neutropenic parameter
            #  In S3.14: num_reps = 6 and int( (time-48)/ 8), both are 1/3 values here
            num_reps = int((time - 48) / 8) * 3

        if num_reps <= 0:
            return

        cyto_index = np.argwhere(np.logical_and(tissue == TissueType.BLOOD.value, cyto >= rec_r))
        if len(cyto_index) <= 0:
            # nowhere to place cells
            return

        for _ in range(num_reps):
            ii = rg.integers(cyto_index.shape[0])
            point = Point(
                x=grid.x[cyto_index[ii, 2]],
                y=grid.y[cyto_index[ii, 1]],
                z=grid.z[cyto_index[ii, 0]],
            )

            self.append(
                NeutrophilCellData.create_cell(
                    point=point,
                    status=NeutrophilCellData.Status.NONGRANULATING,
                    granule_count=granule_count,
                )
            )
 def remove_if_sporeless(self, val):
     living = self.alive()
     living_len = len(living)
     num = int(val * living_len)
     if num == 0 and living_len > 0:
         num = 1
     for _ in range(num):
         r = rg.integers(living_len)
         self.cell_data[living[r]]['dead'] = True