Replace sensor geometry information and reorder cal_chs.
(info, fine_cal, ignore_ref)
| 2206 | |
| 2207 | |
| 2208 | def _update_sensor_geometry(info, fine_cal, ignore_ref): |
| 2209 | """Replace sensor geometry information and reorder cal_chs.""" |
| 2210 | info_to_cal, fine_cal, _ = _prep_fine_cal(info, fine_cal, ignore_ref=ignore_ref) |
| 2211 | grad_picks = pick_types(info, meg="grad", exclude=(), ref_meg=not ignore_ref) |
| 2212 | mag_picks = pick_types(info, meg="mag", exclude=(), ref_meg=not ignore_ref) |
| 2213 | |
| 2214 | # Determine gradiometer imbalances and magnetometer calibrations |
| 2215 | grad_imbalances = np.array( |
| 2216 | [fine_cal["imb_cals"][info_to_cal[gi]] for gi in grad_picks] |
| 2217 | ).T |
| 2218 | if grad_imbalances.shape[0] not in [0, 1, 3]: |
| 2219 | raise ValueError( |
| 2220 | "Must have 1 (x) or 3 (x, y, z) point-like " |
| 2221 | f"magnetometers. Currently have {grad_imbalances.shape[0]}." |
| 2222 | ) |
| 2223 | mag_cals = np.array([fine_cal["imb_cals"][info_to_cal[mi]] for mi in mag_picks]) |
| 2224 | # Now let's actually construct our point-like adjustment coils for grads |
| 2225 | grad_coilsets = _get_grad_point_coilsets( |
| 2226 | info, n_types=len(grad_imbalances), ignore_ref=ignore_ref |
| 2227 | ) |
| 2228 | calibration = dict( |
| 2229 | grad_imbalances=grad_imbalances, grad_coilsets=grad_coilsets, mag_cals=mag_cals |
| 2230 | ) |
| 2231 | |
| 2232 | # Replace sensor locations (and track differences) for fine calibration |
| 2233 | ang_shift = list() |
| 2234 | used = np.zeros(len(info["chs"]), bool) |
| 2235 | cal_corrs = list() |
| 2236 | cal_chans = list() |
| 2237 | adjust_logged = False |
| 2238 | for oi, ci in info_to_cal.items(): |
| 2239 | assert not used[oi] |
| 2240 | used[oi] = True |
| 2241 | info_ch = info["chs"][oi] |
| 2242 | # This only works for VV-like names |
| 2243 | try: |
| 2244 | ch_num = int(fine_cal["ch_names"][ci].lstrip("MEG").lstrip("0")) |
| 2245 | except ValueError: # invalid literal for int() with base 10 |
| 2246 | ch_num = oi |
| 2247 | cal_chans.append([ch_num, info_ch["coil_type"]]) |
| 2248 | |
| 2249 | # Some .dat files might only rotate EZ, so we must check first that |
| 2250 | # EX and EY are orthogonal to EZ. If not, we find the rotation between |
| 2251 | # the original and fine-cal ez, and rotate EX and EY accordingly: |
| 2252 | ch_coil_rot = _loc_to_coil_trans(info_ch["loc"])[:3, :3] |
| 2253 | cal_loc = fine_cal["locs"][ci].copy() |
| 2254 | cal_coil_rot = _loc_to_coil_trans(cal_loc)[:3, :3] |
| 2255 | if ( |
| 2256 | np.max( |
| 2257 | [ |
| 2258 | np.abs(np.dot(cal_coil_rot[:, ii], cal_coil_rot[:, 2])) |
| 2259 | for ii in range(2) |
| 2260 | ] |
| 2261 | ) |
| 2262 | > 1e-6 |
| 2263 | ): # X or Y not orthogonal |
| 2264 | if not adjust_logged: |
| 2265 | logger.info(" Adjusting non-orthogonal EX and EY") |
no test coverage detected