def run(self, bead): "creates the display" if self.__pins is None: self.__pins = self._hpins() if isinstance(self._fit, dict): cnf = dict(sequence=self._sequence, oligos=self._oligos, **dict(self._fit)) elif self._fit is not True: cnf = dict(sequence=self._sequence, oligos=self._oligos, fit=self._fit) else: cnf = dict(sequence=self._sequence, oligos=self._oligos) self.__fits = self._items.new(FitToHairpinDict, config=cnf) if 'rescaling' in getattr(getattr(self._items, 'track', None), 'instrument', ()): self.__fits.config = self.__fits.config.rescale( float(self._items.track.instrument['rescaling'])) cache = self.__cache if bead not in cache: try: cache[bead] = min(self.__fits[bead].distances.items(), key=lambda i: i[1][0]) except Exception as exc: # pylint: disable=broad-except cache[bead] = None, exc key, dist = cache[bead] if isinstance(dist, Exception): return hv.Overlay([hv.Curve(([0], [0])), hv.Text(0, 1, str(dist))]) tmp = self(stretch=dist.stretch, bias=dist.bias) crv = tmp.elements(self._items[[bead]], group=key) # pylint: disable=no-member hpc = self.__pins[key] data = np.copy(hpc.data) tmp = next(iter(crv)).data if isinstance(tmp, np.ndarray): data[:, 1] *= np.nanmax(tmp[:, 1]) else: data[:, 1] *= np.nanmax(tmp['events']) def _pos(val): return .8 * np.nanmax(val) + .2 * np.nanmin(val) pars = np.round(dist.stretch, 1), np.round(dist.bias, 4) if pars[1] < 0: txt = f'{hpc.vdims[0]} = {pars[0]}·({hpc.kdims[0]}+{-pars[1]})' else: txt = f'{hpc.vdims[0]} = {pars[0]}·({hpc.kdims[0]}-{pars[1]})' text = hv.Text(_pos(data[:, 0]), _pos(data[:, 1]), txt, kdims=hpc.kdims + hpc.vdims) return hv.Overlay(crv + [hpc.clone(data=data), text], group=key)
def _create(self, opts, good): opts = deepcopy(opts) for i, j in self.graphdims().items(): opts.setdefault(i, j) if isinstance(self._labels, str): crvs = [self._tpe(j, label=self._labels, **opts) for i, j in good] elif (len(good) < 3 and self._labels) or self._labels is True: crvs = [self._tpe(j, label=f'{i}', **opts) for i, j in good] else: crvs = [self._tpe(j, **opts) for _, j in good] if 0. < self._alpha < 1.: crvs = [i.options(alpha=self._alpha) for i in crvs] if not any(isinstance(i, hv.Text) for i in crvs): # dummy text for warnings for i in crvs: if isinstance(i.data, pd.DataFrame): continue val = next(((j[0], j[1]) for j in i.data if np.isnan(j).sum() == 0), None) if val is not None: break else: val = .5, 5. crvs.insert( 0, hv.Text(*val, '', kdims=[opts['kdims'][0], opts['vdims'][0]])) return hv.Overlay(crvs)
def _convert(self, kdims, ovrs): ovrs = super()._convert(kdims, ovrs) ind = self._refindex(kdims) if ind is None or ind >= len(tuple(ovrs)) or len(tuple( ovrs[ind])) == 0: return ovrs firsts = [ next((j for j in i if hasattr(j, 'dpx_label')), next((j for j in i if not isinstance(j, hv.Text)), next(iter(i)))) for i in ovrs ] txt = [getattr(i, 'dpx_label', None) for i in firsts] txt = [i for i in txt if i] if len(txt) == 0 or len(txt) > 4: txt = [''] elif len(txt) > 1: txt = [i.label + ': ' + j for i, j in zip(firsts, txt)] ovrs = list(ovrs) first = next(iter(tuple(ovrs[ind]))) kdims = first.kdims + first.vdims if isinstance(first.data, np.ndarray): minv = [np.nanmin(first.data[:, k]) for k in range(2)] maxv = [np.nanmax(first.data[:, k]) for k in range(2)] else: minv = [np.nanmin(first.data[k]) for k in first.data.columns[:2]] maxv = [np.nanmax(first.data[k]) for k in first.data.columns[:2]] ovrs.append( hv.Text(minv[0] * .7 + maxv[0] * .3, minv[1] * .3 + maxv[1] * .7, '\n'.join(txt), kdims=kdims)) return hv.Overlay(ovrs)
def _convert(self, kdims, ovrs): # pylint: disable=arguments-differ ind = self._refindex(kdims) if ind is None or ind < 0 or ind >= len(tuple(ovrs)): return ovrs area = next(iter(ovrs[ind])).to(hv.Area) ovrs[ind] = hv.Overlay([area.options(alpha=0.5)] + list(ovrs[ind]), label=ovrs[ind].label, group=ovrs[ind].group) return ovrs
def run(self, key, bead, stretch, bias): "Creates the display" cache = self.__cache if (key, bead) != cache[0]: cache[0] = key, bead cache[1] = list(self.__fcn(key, bead)) mid = len(cache[1]) // 2 clones = [self.__clone(i, stretch, bias) for i in cache[1][mid:]] return hv.Overlay(cache[1][:mid] + clones)
def errormessage(self, exc): "displays error message" args = getattr(exc, 'args', tuple()) if not (isinstance(args, (list, tuple)) and len(args) == 2): return None opts = self.graphdims() opts.update(self._opts) cdims = {i: opts[i] for i in ('kdims', 'vdims') if i in opts} tdims = (cdims['kdims'] + opts.get('vdims', []))[:2] txt = (hv.Text( 0.5, .9, str(args[0]), kdims=tdims).options(finalize_hooks=[self._error_finalize_hook])) return hv.Overlay( [txt, self._tpe(([0., np.NaN, 1.], [0., np.NaN, 1.]), **cdims)])
def run(self, bead, sequence, stretch, bias): "creates the display" cache = self.__cache if bead != cache[0]: cache[0] = bead cache[1] = self.elements(self._items[[bead]]) fcn = self.__clone clones = [fcn(i, stretch, bias) for i in cache[1]] if sequence != cache[2]: hpc = self.__pins[sequence] data = np.copy(hpc.data) if isinstance(clones[0].data, np.ndarray): data[:, 1] *= np.nanmax(clones[0].data[:, 1]) else: data[:, 1] *= np.nanmax(clones[0].data['events']) cache[2] = sequence cache[3] = [hpc.clone(data=data)] return hv.Overlay(clones + cache[3])
def display( self, # pylint: disable=too-many-arguments beads=None, calib=None, cmap='YlGn', colorbar=True): """ displays the FoV with bead positions as well as calibration images. """ if calib is None: calib = any(x.image is not None and x.image.size != 0 for x in self.beads.values()) bnd = self.bounds() beads = list(self.beads.keys() ) if beads is None or beads is Ellipsis else list(beads) if len(beads) and np.isscalar(beads[0]): beads = (beads, ) itms = [ hv.Image(self.image[::-1], bounds=bnd).options(colorbar=colorbar, cmap=cmap) ] for grp in beads: if grp is None or grp is Ellipsis: grp = list(self.beads.keys()) good = {i: j.position[:2] for i, j in self.beads.items() if i in grp} xvals = [i for i, _ in good.values()] yvals = [i for _, i in good.values()] txt = [f'{i}' for i in good.keys()] itms.append(hv.Points((xvals, yvals))) itms.extend(hv.Text(*i) for i in zip(xvals, yvals, txt)) top = hv.Overlay(itms).redim(x='x (μm)', y='y (μm)') top = top.options({"Points": {"size": 10, "alpha": .6}}) if not calib: return top bottom = hv.DynamicMap( lambda bead: self.beads[bead].display(colorbar=colorbar), kdims=['bead']).redim.values(bead=beads) return (top + bottom).cols(1)
def _reference_method(self, key, bead): fcn, kdims = self._base() val = fcn(self._reference, bead, neverempty=True, labels=self._reference) if self._refdims: val = val.redim( **{ i.name: i.clone(label=f'{self._reference}{i.label}') for i in val.dimensions() }) label = (key if self._labels is None else False if self._labels is False else 'key') other = fcn(key, bead, neverempty=True, labels=label) if self._reflayout == 'same': return hv.Overlay(self._convert(kdims, [val, other])) if self._reflayout in ('left', 'top'): return (val + other).cols(1 if self._reflayout == 'top' else 2) return (other + val).cols(1 if self._reflayout == 'bottom' else 2)
def _overlayed_method(self, key): kdims = self._default_kdims() kword = 'key' if self._overlay == 'bead' else 'bead' opts = kdims[self._overlay] fcn = partial( self._default_display, **{ kword: key, 'dataonly': len(kdims[self._overlay]) > 2, 'neverempty': True }) if len(kdims[self._overlay]) <= 2: crvs = [fcn(i) for i in opts] else: self._items = self._items.freeze() with ThreadPoolExecutor() as tpool: data = list(tpool.map(fcn, opts)) with ProcessPoolExecutor() as ppool: crvs = list(ppool.map(self._process_pooled_display, data)) return hv.Overlay(self._convert(kdims, crvs))
def consensus(self, opts=None, hmap=True, normalize=True, **kwa): "return average bead" data = self.dataframe(False, normalize=normalize, **kwa) RampConsensusBeadProcessor.consensus(data, normalize, self.beads("ok")) data.columns = [self._name(i) for i in data.columns] cols = [ i for i in data.columns if not any(j in i for j in ("zmag", "@low", "@high", "consensus")) ] _crv = partial( self._crv, data, (dict(color="gray", alpha=.25) if opts is None else opts), "Z (% bead length)" if normalize else "Z (µm)") if hmap: crvs = {int(i.split()[1]): _crv(i) for i in cols} mean = _crv("consensus") return (hv.DynamicMap(lambda x: crvs[x] * mean, kdims=['bead' ]).redim.values(bead=list(crvs))) return hv.Overlay([_crv(i) for i in cols + ["consensus"]])
def _perall(self): if self._area: keys = self._keys if self._keys else self._items.beads.keys() return hv.Overlay([self._perbead(i) for i in keys]) return self._run(self._items)
def _perall(self, **opts): "Returns the method used by the dynamic map" return hv.Overlay(self.detailed(self._items, **opts))
def _run(self, evts, **opts): "shows overlayed Curve items" return hv.Overlay(self.elements(evts, **opts))
def __quadmeshtext(self, crvs): color = self._textcolor return hv.Overlay([ hv.Text(0.01, i + .5, j).options(text_color=color) for i, (j, _) in enumerate(crvs) ])