def doymax(da: xr.DataArray) -> xr.DataArray: """Return the day of year of the maximum value.""" i = da.argmax(dim="time") out = da.time.dt.dayofyear.isel(time=i, drop=True) out.attrs.update(units="", is_dayofyear=np.int32(1), calendar=get_calendar(da)) return out
def _call_bases(self, image: xr.DataArray, intensity_threshold: float, quality_threshold: float) -> xr.DataArray: """ Determines the nucleotide present in each pixel of each (round, channel). The pixel values in the resulting image are the base quality score. The base quality score is calculated as the intensity of the pixel divided by the L2 norm of the all channels for that pixel. The base call score as a range of (0, 1) with a value of 0 and 1 being no call and a perfect call, respectively. Parameters ---------- image : xr.DataArray Image for base calling. Should have the following dims: Axes.CH, Axes.X, Axes.Y intensity_threshold : float Minimum intensity a pixel must have to be called a base. Set to zero for no thresholding. quality_threshold : float Minimum intensity a pixel must have to be called a base. Set to zero for no thresholding. """ # Get the maximum value for each round/z max_chan = image.argmax(dim=Axes.CH.value) max_values = image.max(dim=Axes.CH.value) # Get the norms for each pixel norms = self._vector_norm(x=image, dim=Axes.CH) # Calculate the base qualities base_qualities = max_values / norms # Filter the base call qualities base_qualities_filtered = xr.where(base_qualities < quality_threshold, 0, base_qualities) # Threshold the intensity values base_qualities_filtered = xr.where(max_values < intensity_threshold, 0, base_qualities_filtered) # Put the base calls in place base_calls = xr.full_like(other=image, fill_value=0) base_calls[max_chan] = base_qualities_filtered return base_calls
def doymax(da: xr.DataArray): """Return the day of year of the maximum value.""" i = da.argmax(dim="time") out = da.time.dt.dayofyear[i] out.attrs["units"] = "" return out
def doymax(da: xr.DataArray) -> xr.DataArray: """Return the day of year of the maximum value.""" i = da.argmax(dim="time") out = da.time.dt.dayofyear[i] out.attrs.update(units="", is_dayofyear=1, calendar=get_calendar(da)) return out
def first_run( da: xr.DataArray, window: int, dim: str = "time", coord: Optional[Union[str, bool]] = False, ufunc_1dim: Union[str, bool] = "from_context", ) -> xr.DataArray: """Return the index of the first item of the first run of at least a given length. Parameters ---------- da : xr.DataArray Input N-dimensional DataArray (boolean). window : int Minimum duration of consecutive run to accumulate values. When equal to 1, an optimized version of the algorithm is used. dim : str Dimension along which to calculate consecutive run (default: 'time'). coord : Optional[str] If not False, the function returns values along `dim` instead of indexes. If `dim` has a datetime dtype, `coord` can also be a str of the name of the DateTimeAccessor object to use (ex: 'dayofyear'). ufunc_1dim : Union[str, bool] Use the 1d 'ufunc' version of this function : default (auto) will attempt to select optimal usage based on number of data points. Using 1D_ufunc=True is typically more efficient for DataArray with a small number of grid points. Ignored when `window=1`. Returns ------- xr.DataArray Index (or coordinate if `coord` is not False) of first item in first valid run. Returns np.nan if there are no valid runs. """ ufunc_1dim = use_ufunc(ufunc_1dim, da, dim=dim) da = da.fillna( 0) # We expect a boolean array, but there could be NaNs nonetheless if window == 1: out = xr.where(da.any(dim=dim), da.argmax(dim=dim), np.NaN) elif ufunc_1dim: out = first_run_ufunc(x=da, window=window, dim=dim) else: da = da.astype("int") i = xr.DataArray(np.arange(da[dim].size), dims=dim) ind = xr.broadcast(i, da)[0].transpose(*da.dims) if isinstance(da.data, dsk.Array): ind = ind.chunk(da.chunks) wind_sum = da.rolling({dim: window}).sum(skipna=False) out = ind.where(wind_sum >= window).min(dim=dim) - (window - 1) # remove window - 1 as rolling result index is last element of the moving window if coord: crd = da[dim] if isinstance(coord, str): crd = getattr(crd.dt, coord) out = lazy_indexing(crd, out) if dim in out.coords: out = out.drop_vars(dim) return out