def _generate_continuous( self, uts: UTS, # time axis for the output ds: Dataset, # events stim_var: str, code: Code, directory: Path, ): # place multiple input files into a continuous predictor cache = { stim: self._load(uts.tstep, code.with_stim(stim).nuts_file_name(self.columns), directory) for stim in ds[stim_var].cells } # determine type stim_type = {type(s) for s in cache.values()} assert len(stim_type) == 1 stim_type = stim_type.pop() # generate x if stim_type is Dataset: dss = [] for t, stim in ds.zip('T_relative', stim_var): x = cache[stim].copy() x['time'] += t dss.append(x) if code.nuts_method: x_stop_ds = t_stop_ds(x, t) dss.append(x_stop_ds) x = self._ds_to_ndvar(combine(dss), uts, code) elif stim_type is NDVar: v = cache[ds[0, stim_var]] dimnames = v.get_dimnames(first='time') dims = (uts, *v.get_dims(dimnames[1:])) x = NDVar.zeros(dims, code.key) for t, stim in ds.zip('T_relative', stim_var): x_stim = cache[stim] i_start = uts._array_index(t + x_stim.time.tmin) i_stop = i_start + len(x_stim.time) if i_stop > len(uts): raise ValueError( f"{code.string_without_rand} for {stim} is longer than the data" ) x.x[i_start:i_stop] = x_stim.get_data(dimnames) else: raise RuntimeError(f"stim_type={stim_type!r}") return x
def _ds_to_ndvar(self, ds: Dataset, uts: UTS, code: Code): if self.columns: column_key, mask_key = code.nuts_columns if column_key is None: column_key = 'value' ds[:, column_key] = 1 else: column_key = 'value' mask_key = 'mask' if 'mask' in ds else None if mask_key: mask = ds[mask_key].x assert mask.dtype.kind == 'b', "'mask' must be boolean" else: mask = None if code.shuffle_index: shuffle_mask = ds[code.shuffle_index].x if shuffle_mask.dtype.kind != 'b': raise code.error("shuffle index must be boolean", -1) elif code.shuffle == 'permute' and mask is not None: assert not numpy.any(shuffle_mask[~mask]) elif code.shuffle == 'permute': shuffle_mask = mask else: shuffle_mask = None if code.shuffle == 'remask': if mask is None: raise code.error("$remask for predictor without mask", -1) rng = code._get_rng() if shuffle_mask is None: rng.shuffle(mask) else: remask = mask[shuffle_mask] rng.shuffle(remask) mask[shuffle_mask] = remask code.register_shuffle(index=True) if mask is not None: ds[column_key] *= mask if code.shuffle == 'permute': rng = code._get_rng() if shuffle_mask is None: rng.shuffle(ds[column_key].x) else: values = ds[column_key].x[shuffle_mask] rng.shuffle(values) ds[column_key].x[shuffle_mask] = values code.register_shuffle(index=True) # prepare output NDVar if code.nuts_method == 'is': dim = Categorial('representation', ('step', 'impulse')) x = NDVar(numpy.zeros((2, len(uts))), (dim, uts), name=code.key) x_step, x_impulse = x else: x = NDVar(numpy.zeros(len(uts)), uts, name=code.key) if code.nuts_method == 'step': x_step, x_impulse = x, None elif not code.nuts_method: x_step, x_impulse = None, x else: raise code.error(f"NUTS-method={code.nuts_method!r}") # fill in values ds = ds[ds['time'] < uts.tstop] if x_impulse is not None: for t, v in ds.zip('time', column_key): x_impulse[t] = v if x_step is not None: t_stops = ds[1:, 'time'] if ds[-1, column_key] != 0: if 'tstop' not in ds.info: raise code.error( "For step representation, the predictor datasets needs to contain ds.info['tstop'] to determine the end of the last step", -1) t_stops = chain(t_stops, [ds.info['tstop']]) for t0, t1, v in zip(ds['time'], t_stops, ds[column_key]): x_step[t0:t1] = v return x