def calc_particle_group_region_size(s, region_size=<NUM_LIT>, max_mem=<NUM_LIT>, **kwargs):
region_size = np.array(region_size).astype('<STR_LIT:int>')<EOL>def calc_mem_usage(region_size):<EOL><INDENT>rs = np.array(region_size)<EOL>particle_groups = separate_particles_into_groups(s, region_size=<EOL>rs.tolist(), **kwargs)<EOL>numpart = [np.size(g) for g in particle_groups]<EOL>biggroups = [particle_groups[i] for i in np.argsort(numpart)[-<NUM_LIT:5>:]]<EOL>def get_tile_jsize(group):<EOL><INDENT>nms = s.param_particle(group)<EOL>tile = s.get_update_io_tiles(nms, s.get_values(nms))[<NUM_LIT:2>]<EOL>return tile.shape.prod() * len(nms)<EOL><DEDENT>mems = [<NUM_LIT:8>*get_tile_jsize(g) for g in biggroups]  <EOL>return np.max(mems)<EOL><DEDENT>im_shape = s.oshape.shape<EOL>if calc_mem_usage(region_size) > max_mem:<EOL><INDENT>while ((calc_mem_usage(region_size) > max_mem) and<EOL>np.any(region_size > <NUM_LIT:2>)):<EOL><INDENT>region_size = np.clip(region_size-<NUM_LIT:1>, <NUM_LIT:2>, im_shape)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>while ((calc_mem_usage(region_size) < max_mem) and<EOL>np.any(region_size < im_shape)):<EOL><INDENT>region_size = np.clip(region_size+<NUM_LIT:1>, <NUM_LIT:2>, im_shape)<EOL><DEDENT>region_size -= <NUM_LIT:1> <EOL><DEDENT>return region_size<EOL>
Finds the biggest region size for LM particle optimization with a
given memory constraint.

Input Parameters
----------------
    s : :class:`peri.states.ImageState`
        The state with the particles
    region_size : Int or 3-element list-like of ints, optional.
        The initial guess for the region size. Default is 40
    max_mem : Numeric, optional
        The maximum memory for the optimizer to take. Default is 1e9

Other Parameters
----------------
    bounds: 2-element list-like of 3-element lists.
        The sub-region of the image over which to look for particles.
            bounds[0]: The lower-left  corner of the image region.
            bounds[1]: The upper-right corner of the image region.
        Default (None -> ([0,0,0], s.oshape.shape)) is a box of the entire
        image size, i.e. the default places every particle in the image
        somewhere in the groups.
Returns
-------
    region_size : numpy.ndarray of ints of the region size.