Apply a custom EEG referencing scheme.
(inst, ref_from, ref_to=None, forward=None, ch_type="auto")
| 153 | |
| 154 | |
| 155 | def _apply_reference(inst, ref_from, ref_to=None, forward=None, ch_type="auto"): |
| 156 | """Apply a custom EEG referencing scheme.""" |
| 157 | ref_to = _check_before_reference(inst, ref_from, ref_to, ch_type) |
| 158 | |
| 159 | # Compute reference |
| 160 | if len(ref_from) > 0: |
| 161 | # this is guaranteed below, but we should avoid the crazy pick_channels |
| 162 | # behavior that [] gives all. Also use ordered=True just to make sure |
| 163 | # that all supplied channels actually exist. |
| 164 | assert len(ref_to) > 0 |
| 165 | ref_names = ref_from |
| 166 | ref_from = pick_channels(inst.ch_names, ref_from, ordered=True) |
| 167 | ref_to = pick_channels(inst.ch_names, ref_to, ordered=True) |
| 168 | |
| 169 | data = inst._data |
| 170 | ref_data = data[..., ref_from, :].mean(-2, keepdims=True) |
| 171 | data[..., ref_to, :] -= ref_data |
| 172 | ref_data = ref_data[..., 0, :] |
| 173 | |
| 174 | # REST |
| 175 | if forward is not None: |
| 176 | # use ch_sel and the given forward |
| 177 | forward = pick_channels_forward(forward, ref_names, ordered=True) |
| 178 | # 1-3. Compute a forward (G) and avg-ref'ed data (done above) |
| 179 | G = forward["sol"]["data"] |
| 180 | assert G.shape[0] == len(ref_names) |
| 181 | # 4. Compute the forward (G) and average-reference it (Ga): |
| 182 | Ga = G - np.mean(G, axis=0, keepdims=True) |
| 183 | # 5. Compute the Ga_inv by SVD |
| 184 | Ga_inv = pinv(Ga, rtol=1e-6) |
| 185 | # 6. Compute Ra = (G @ Ga_inv) in eq (8) from G and Ga_inv |
| 186 | Ra = G @ Ga_inv |
| 187 | # 7-8. Compute Vp = Ra @ Va; then Vpa=average(Vp) |
| 188 | Vpa = np.mean(Ra @ data[..., ref_from, :], axis=-2, keepdims=True) |
| 189 | data[..., ref_to, :] += Vpa |
| 190 | else: |
| 191 | ref_data = None |
| 192 | |
| 193 | return inst, ref_data |
| 194 | |
| 195 | |
| 196 | def _apply_dict_reference(inst, ref_dict): |