def table(s, datas, names, vary_func): p0 = s.obj.pos.copy() r0 = s.obj.rad.copy() slicer = np.s_[s.image[s.inner].shape[0] / 2] model_image = s.image[s.inner][slicer].copy() results = [0] * (len(names) + 1) results[0] = ('Refernce', model_image, p0, r0) filename = tempfile.NamedTemporaryFile().name states.save(s, filename=filename) for i, (name, data) in enumerate(zip(names, datas)): print i, name, data state = states.load(filename) vary_func(state, data) state.reset() optimize(state) results[i + 1] = (name, state.get_difference_image()[slicer].copy(), state.obj.pos.copy(), state.obj.rad.copy()) os.remove(filename) return results
def _translate_particles(s, max_mem=1e9, desc='', min_rad='calc', max_rad='calc', invert=True, rz_order=0, do_polish=True): """ Workhorse for translating particles. See get_particles_featuring for docs. """ RLOG.info('Translate Particles:') opt.burn(s, mode='do-particles', n_loop=4, fractol=0.1, desc=desc + 'translate-particles', max_mem=max_mem, include_rad=False, dowarn=False) opt.burn(s, mode='do-particles', n_loop=4, fractol=0.05, desc=desc + 'translate-particles', max_mem=max_mem, include_rad=True, dowarn=False) RLOG.info('Start add-subtract') addsub.add_subtract(s, tries=30, min_rad=min_rad, max_rad=max_rad, invert=invert) states.save(s, desc=desc + 'translate-addsub') if do_polish: RLOG.info('Final Burn:') opt.burn(s, mode='burn', n_loop=3, fractol=3e-4, desc=desc + 'addsub-burn', max_mem=max_mem, rz_order=rz_order, dowarn=False) RLOG.info('Final Polish:') d = opt.burn(s, mode='polish', n_loop=4, fractol=3e-4, desc=desc + 'addsub-polish', max_mem=max_mem, rz_order=rz_order, dowarn=False) if not d['converged']: RLOG.warn('Optimization did not converge; consider re-running')
def do_samples(s, sweeps, burn, stepout=0.1, save_period=-1, prefix='peri', save_name=None, sigma=True, pos=True, quiet=False, postfix=None): h = [] ll = [] if not save_name: with tempfile.NamedTemporaryFile(suffix='.peri-state.pkl', prefix=prefix) as f: save_name = f.name for i in xrange(sweeps): if save_period > 0 and i % save_period == 0: with open(save_name, 'w') as tfile: pickle.dump([s, h, ll], tfile) if postfix is not None: states.save(s, desc=postfix, extra=[np.array(h), np.array(ll)]) if not quiet: print '{:=^79}'.format(' Sweep ' + str(i) + ' ') #sample_particles(s, stepout=stepout) if pos: sample_particle_pos(s, stepout=stepout, quiet=quiet) sample_particle_rad(s, stepout=stepout, quiet=quiet) sample_block(s, 'psf', stepout=stepout, quiet=quiet) sample_block(s, 'ilm', stepout=stepout, quiet=quiet) sample_block(s, 'off', stepout=stepout, quiet=quiet) sample_block(s, 'zscale', stepout=stepout, quiet=quiet) if s.bkg: sample_block(s, 'bkg', stepout=stepout, quiet=quiet) if s.slab: sample_block(s, 'slab', stepout=stepout, quiet=quiet) if sigma and s.nlogs: sample_block(s, 'sigma', stepout=stepout / 10, quiet=quiet) if i >= burn: h.append(s.state.copy()) ll.append(s.loglikelihood) if save_period > 0 and save_name: os.remove(save_name) h = np.array(h) ll = np.array(ll) return h, ll
def do_blocks(s, blocks, sweeps, burn, stepout=0.1, postfix=None, quiet=False): h, ll = [], [] for i in xrange(sweeps): if postfix is not None: states.save(s, desc=postfix, extra=[np.array(h), np.array(ll)]) if not quiet: print '{:=^79}'.format(' Sweep ' + str(i) + ' ') sample_state(s, blocks, stepout=stepout, N=1, doprint=~quiet) if i >= burn: h.append(s.state.copy()) ll.append(s.loglikelihood) h = np.array(h) ll = np.array(ll) return h, ll
# particle_positions n=100 # random_particles = np.c_[np.random.random(n), np.random.random(n),np.zeros(n)]*200.0 tile = util.Tile(200) small_im = util.RawImage(imFile, tile=tile) zpixel=1 xpixel=1 zscale=zpixel/xpixel particle_radii = 8.0 particles = objs.PlatonicSpheresCollection(particle_positions, particle_radii, zscale=zscale) objects = comp.comp.ComponentCollection([particles], category='obj') background = comp.ilms.LegendrePoly2P1D(order=(4,2,2), category='bkg') illumination = comp.ilms.BarnesStreakLegPoly2P1D(npts=(4, 2, 2)) offset = comp.GlobalScalar(name='offset', value=0.) point_spread_function = comp.exactpsf.ChebyshevLineScanConfocalPSF(pxsize=xpixel) model = models.ConfocalDyedParticlesModel() st = states.ImageState(small_im, [objects, illumination, background, point_spread_function], mdl=model) st.update('zscale', zscale) savefile = "/Volumes/PhD/expDesign/test/"+datetime.now().strftime("%Y%m%d-%H%M%S") + "_unoptimized" runner.link_zscale(st) runner.optimize_from_initial(st) savefile = "/Volumes/PhD/expDesign/test/"+datetime.now().strftime("%Y%m%d-%H%M%S") + "_inital_optimized" states.save(st,savefile) # new_st = runner.get_particles_featuring(8)
def optimize_from_initial(s, max_mem=1e9, invert='guess', desc='', rz_order=3, min_rad=None, max_rad=None): """ Optimizes a state from an initial set of positions and radii, without any known microscope parameters. Parameters ---------- s : :class:`peri.states.ImageState` The state to optimize. It is modified internally and returned. max_mem : Numeric, optional The maximum memory for the optimizer to use. Default is 1e9 (bytes) invert : Bool or `'guess'`, optional Set to True if the image is dark particles on a bright background, False otherwise. Used for add-subtract. The default is to guess from the state's current particles. desc : String, optional An additional description to infix for periodic saving along the way. Default is the null string ``''``. rz_order : int, optional ``rz_order`` as passed to opt.burn. Default is 3 min_rad : Float or None, optional The minimum radius to identify a particles as bad, as passed to add-subtract. Default is None, which picks half the median radii. If your sample is not monodisperse you should pick a different value. max_rad : Float or None, optional The maximum radius to identify a particles as bad, as passed to add-subtract. Default is None, which picks 1.5x the median radii. If your sample is not monodisperse you should pick a different value. Returns ------- s : :class:`peri.states.ImageState` The optimized state, which is the same as the input ``s`` but modified in-place. """ RLOG.info('Initial burn:') if desc is not None: desc_burn = desc + 'initial-burn' desc_polish = desc + 'addsub-polish' else: desc_burn, desc_polish = [None] * 2 opt.burn(s, mode='burn', n_loop=3, fractol=0.1, desc=desc_burn, max_mem=max_mem, include_rad=False, dowarn=False) opt.burn(s, mode='burn', n_loop=3, fractol=0.1, desc=desc_burn, max_mem=max_mem, include_rad=True, dowarn=False) RLOG.info('Start add-subtract') rad = s.obj_get_radii() if min_rad is None: min_rad = 0.5 * np.median(rad) if max_rad is None: max_rad = 1.5 * np.median(rad) addsub.add_subtract(s, tries=30, min_rad=min_rad, max_rad=max_rad, invert=invert) if desc is not None: states.save(s, desc=desc + 'initial-addsub') RLOG.info('Final polish:') d = opt.burn(s, mode='polish', n_loop=8, fractol=3e-4, desc=desc_polish, max_mem=max_mem, rz_order=rz_order, dowarn=False) if not d['converged']: RLOG.warn('Optimization did not converge; consider re-running') return s
def feature_from_pos_rad(statemaker, pos, rad, im_name=None, tile=None, desc='', use_full_path=False, statemaker_kwargs={}, **kwargs): """ Gets a completely-optimized state from an image and an initial guess of particle positions and radii. The state is periodically saved during optimization, with different filename for different stages of the optimization. The user can select the image. Parameters ---------- statemaker : Function A statemaker function. Given arguments `im` (a :class:`~peri.util.Image`), `pos` (numpy.ndarray), `rad` (ndarray), and any additional `statemaker_kwargs`, must return a :class:`~peri.states.ImageState`. There is an example function in scripts/statemaker_example.py pos : [N,3] element numpy.ndarray. The initial guess for the N particle positions. rad : N element numpy.ndarray. The initial guess for the N particle radii. im_name : string or None, optional The filename of the image to feature. Default is None, in which the user selects the image. tile : :class:`peri.util.Tile`, optional A tile of the sub-region of the image to feature. Default is None, i.e. entire image. desc : String, optional A description to be inserted in saved state. The save name will be, e.g., '0.tif-peri-' + desc + 'initial-burn.pkl'. Default is '' use_full_path : Bool, optional Set to True to use the full path name for the image. Default is False. statemaker_kwargs : Dict, optional kwargs-like dict of any additional keyword arguments to pass to the statemaker function. Default is ``{}``. Other Parameters ---------------- max_mem : Numeric The maximum additional memory to use for the optimizers, as passed to optimize.burn. Default is 1e9. min_rad : Float, optional The minimum particle radius, as passed to addsubtract.add_subtract. Particles with a fitted radius smaller than this are identified as fake and removed. Default is 0.5 * actual_rad. max_rad : Float, optional The maximum particle radius, as passed to addsubtract.add_subtract. Particles with a fitted radius larger than this are identified as fake and removed. Default is 1.5 * actual_rad, however you may find better results if you make this more stringent. invert : {'guess', True, False} Whether to invert the image for featuring, as passed to addsubtract.add_subtract. Default is to guess from the current state's particle positions. rz_order : int, optional If nonzero, the order of an additional augmented rscl(z) parameter for optimization. Default is 0; i.e. no rscl(z) optimization. zscale : Float, optional The zscale of the image. Default is 1.0 Returns ------- s : :class:`peri.states.ImageState` The optimized state. See Also -------- get_initial_featuring : Features an image from scratch, using centroid methods as initial particle locations. get_particle_featuring : Using a previous state's globals and positions as an initial guess, completely optimizes a state. translate_featuring : Use a previous state's globals and centroids methods for an initial particle guess, completely optimizes a state. Notes ----- The ``Other Parameters`` are passed to _optimize_from_centroid. Proceeds by centroid-featuring the image for an initial guess of particle positions, then optimizing the globals + positions until termination as called in _optimize_from_centroid. """ if np.size(pos) == 0: raise ValueError('`pos` is an empty array.') elif np.shape(pos)[1] != 3: raise ValueError('`pos` must be an [N,3] element numpy.ndarray.') _, im_name = _pick_state_im_name('', im_name, use_full_path=use_full_path) im = util.RawImage(im_name, tile=tile) s = statemaker(im, pos, rad, **statemaker_kwargs) RLOG.info('State Created.') if desc is not None: states.save(s, desc=desc + 'initial') optimize_from_initial(s, desc=desc, **kwargs) return s
def get_initial_featuring(statemaker, feature_rad, actual_rad=None, im_name=None, tile=None, invert=True, desc='', use_full_path=False, featuring_params={}, statemaker_kwargs={}, **kwargs): """ Completely optimizes a state from an image of roughly monodisperse particles. The user can interactively select the image. The state is periodically saved during optimization, with different filename for different stages of the optimization. Parameters ---------- statemaker : Function A statemaker function. Given arguments `im` (a :class:`~peri.util.Image`), `pos` (numpy.ndarray), `rad` (ndarray), and any additional `statemaker_kwargs`, must return a :class:`~peri.states.ImageState`. There is an example function in scripts/statemaker_example.py feature_rad : Int, odd The particle radius for featuring, as passed to locate_spheres. actual_rad : Float, optional The actual radius of the particles. Default is feature_rad im_name : string, optional The file name of the image to load. If not set, it is selected interactively through Tk. tile : :class:`peri.util.Tile`, optional The tile of the raw image to be analyzed. Default is None, the entire image. invert : Bool, optional Whether to invert the image for featuring, as passed to trackpy. Default is True. desc : String, optional A description to be inserted in saved state. The save name will be, e.g., '0.tif-peri-' + desc + 'initial-burn.pkl'. Default is '' use_full_path : Bool, optional Set to True to use the full path name for the image. Default is False. featuring_params : Dict, optional kwargs-like dict of any additional keyword arguments to pass to ``get_initial_featuring``, such as ``'use_tp'`` or ``'minmass'``. Default is ``{}``. statemaker_kwargs : Dict, optional kwargs-like dict of any additional keyword arguments to pass to the statemaker function. Default is ``{}``. Other Parameters ---------------- max_mem : Numeric The maximum additional memory to use for the optimizers, as passed to optimize.burn. Default is 1e9. min_rad : Float, optional The minimum particle radius, as passed to addsubtract.add_subtract. Particles with a fitted radius smaller than this are identified as fake and removed. Default is 0.5 * actual_rad. max_rad : Float, optional The maximum particle radius, as passed to addsubtract.add_subtract. Particles with a fitted radius larger than this are identified as fake and removed. Default is 1.5 * actual_rad, however you may find better results if you make this more stringent. rz_order : int, optional If nonzero, the order of an additional augmented rscl(z) parameter for optimization. Default is 0; i.e. no rscl(z) optimization. zscale : Float, optional The zscale of the image. Default is 1.0 Returns ------- s : :class:`peri.states.ImageState` The optimized state. See Also -------- feature_from_pos_rad : Using a previous state's globals and user-provided positions and radii as an initial guess, completely optimizes a state. get_particle_featuring : Using a previous state's globals and positions as an initial guess, completely optimizes a state. translate_featuring : Use a previous state's globals and centroids methods for an initial particle guess, completely optimizes a state. Notes ----- Proceeds by centroid-featuring the image for an initial guess of particle positions, then optimizing the globals + positions until termination as called in _optimize_from_centroid. The ``Other Parameters`` are passed to _optimize_from_centroid. """ if actual_rad is None: actual_rad = feature_rad _, im_name = _pick_state_im_name('', im_name, use_full_path=use_full_path) im = util.RawImage(im_name, tile=tile) pos = locate_spheres(im, feature_rad, invert=invert, **featuring_params) if np.size(pos) == 0: msg = 'No particles found. Try using a smaller `feature_rad`.' raise ValueError(msg) rad = np.ones(pos.shape[0], dtype='float') * actual_rad s = statemaker(im, pos, rad, **statemaker_kwargs) RLOG.info('State Created.') if desc is not None: states.save(s, desc=desc + 'initial') optimize_from_initial(s, invert=invert, desc=desc, **kwargs) return s