2020from ..cov import _ensure_cov , compute_whitener , make_ad_hoc_cov
2121from ..dipole import Dipole , fit_dipole
2222from ..evoked import Evoked
23- from ..forward import convert_forward_solution , make_field_map
23+ from ..forward import make_field_map
2424from ..forward ._make_forward import _ForwardModeler
2525from ..minimum_norm import apply_inverse , make_inverse_operator
2626from ..source_estimate import (
2727 SourceEstimate ,
2828 _BaseSurfaceSourceEstimate ,
2929 read_source_estimate ,
3030)
31- from ..source_space import setup_volume_source_space
31+ from ..source_space . _source_space import _complete_vol_src , _make_discrete_source_space
3232from ..surface import _normal_orth
3333from ..transforms import _get_trans , _get_transforms_to_coord_frame , apply_trans
3434from ..utils import (
@@ -842,10 +842,6 @@ def _on_dipole_toggle(active, dip_num):
842842 def _on_dipole_set_name (name , dip_num ):
843843 return self ._on_dipole_set_name (name , dip_num )
844844
845- @_auto_weakref
846- def _on_dipole_toggle_fix_orientation (fix , dip_num ):
847- return self ._on_dipole_toggle_fix_orientation (fix , dip_num )
848-
849845 @_auto_weakref
850846 def _on_dipole_delete (dip_num ):
851847 return self ._on_dipole_delete (dip_num )
@@ -881,12 +877,9 @@ def _on_dipole_hover(dip_num, hover):
881877 arrow_mesh = arrow_mesh ,
882878 color = dip_color ,
883879 dip = dip ,
884- fix_ori = True ,
885- fix_position = True ,
886880 helmet_coords = helmet_coords ,
887881 helmet_pos = helmet_pos ,
888882 num = dip_num ,
889- # fit_time=self._current_time,
890883 )
891884 self ._dipoles [dip_num ] = dipole_dict
892885
@@ -924,16 +917,6 @@ def _on_dipole_hover(dip_num, hover):
924917 enter = partial (_on_dipole_hover , dip_num = dip_num , hover = True ),
925918 leave = partial (_on_dipole_hover , dip_num = dip_num , hover = False ),
926919 )
927- widgets .append (
928- r ._dock_add_check_box (
929- name = "Fix ori" ,
930- value = True ,
931- callback = partial (
932- _on_dipole_toggle_fix_orientation , dip_num = dip_num
933- ),
934- layout = hlayout ,
935- )
936- )
937920 widgets .append (
938921 r ._dock_add_button (
939922 name = "" ,
@@ -1011,58 +994,32 @@ def _fit_timecourses(self):
1011994 # TODO: When two active dipoles have (nearly) identical positions, they
1012995 # collapse to a single point in the discrete source space below, which
1013996 # errors out. Ideal behavior unclear: merge them, or error informatively?
1014- this_src = setup_volume_source_space (
1015- "sample" ,
1016- pos = dict (
1017- rr = apply_trans (
1018- self ._head_mri_t ,
1019- np .vstack ([d ["dip" ].pos [0 ] for d in active_dips ]),
1020- ),
1021- nn = apply_trans (
1022- self ._head_mri_t ,
1023- np .vstack ([d ["dip" ].ori [0 ] for d in active_dips ]),
1024- ),
1025- ),
997+ this_src = _complete_vol_src (
998+ [
999+ _make_discrete_source_space (
1000+ pos = dict (
1001+ rr = np .vstack ([d ["dip" ].pos [0 ] for d in active_dips ]),
1002+ nn = np .vstack ([d ["dip" ].ori [0 ] for d in active_dips ]),
1003+ ),
1004+ coord_frame = "head" ,
1005+ )
1006+ ]
10261007 )
10271008 this_fwd = self .fwd .compute (this_src )
1028- this_fwd = convert_forward_solution (this_fwd , surf_ori = False )
10291009
10301010 if self ._multi_dipole_method == "Multi dipole (MNE)" :
10311011 inv = make_inverse_operator (
1032- self ._evoked .info ,
1033- # fwd,
1034- this_fwd ,
1035- self ._cov ,
1036- fixed = False ,
1037- loose = 1.0 ,
1012+ info = self ._evoked .info ,
1013+ forward = this_fwd ,
1014+ noise_cov = self ._cov ,
1015+ loose = 0 ,
10381016 depth = 0 ,
10391017 rank = self ._rank ,
10401018 )
1041- stc = apply_inverse (
1042- self ._evoked ,
1043- inv ,
1044- method = "MNE" ,
1045- lambda2 = 1e-6 ,
1046- pick_ori = "vector" ,
1047- )
1048-
1049- timecourses = stc .magnitude ().data
1050- orientations = (stc .data / timecourses [:, np .newaxis , :]).transpose (
1051- 0 , 2 , 1
1052- )
1053- fixed_timecourses = stc .project (
1054- np .array ([dip ["dip" ].ori [0 ] for dip in active_dips ])
1055- )[0 ].data
1056-
1019+ stc = apply_inverse (self ._evoked , inv , method = "MNE" , lambda2 = 1e-6 )
10571020 for i , dip in enumerate (active_dips ):
1058- if dip ["fix_ori" ]:
1059- dip ["timecourse" ] = fixed_timecourses [i ]
1060- dip ["orientation" ] = dip ["dip" ].ori .repeat (
1061- len (stc .times ), axis = 0
1062- )
1063- else :
1064- dip ["timecourse" ] = timecourses [i ]
1065- dip ["orientation" ] = orientations [i ]
1021+ dip ["timecourse" ] = stc .data [i ]
1022+ dip ["orientation" ] = dip ["dip" ].ori .repeat (len (stc .times ), axis = 0 )
10661023 else :
10671024 assert self ._multi_dipole_method == "Single dipole" # only other option
10681025 for dip in active_dips :
@@ -1071,20 +1028,16 @@ def _fit_timecourses(self):
10711028 self ._cov ,
10721029 self ._bem ,
10731030 pos = dip ["dip" ].pos [0 ], # position is always fixed
1074- ori = dip ["dip" ].ori [0 ] if dip [ "fix_ori" ] else None ,
1031+ ori = dip ["dip" ].ori [0 ],
10751032 trans = self ._head_mri_t ,
10761033 rank = self ._rank ,
10771034 n_jobs = self ._n_jobs ,
10781035 verbose = True ,
10791036 )
1080- if dip ["fix_ori" ]:
1081- dip ["timecourse" ] = dip_with_timecourse .data [0 ]
1082- dip ["orientation" ] = dip ["dip" ].ori .repeat (
1083- len (dip_with_timecourse .times ), axis = 0
1084- )
1085- else :
1086- dip ["timecourse" ] = dip_with_timecourse .amplitude
1087- dip ["orientation" ] = dip_with_timecourse .ori
1037+ dip ["timecourse" ] = dip_with_timecourse .data [0 ]
1038+ dip ["orientation" ] = dip ["dip" ].ori .repeat (
1039+ len (dip_with_timecourse .times ), axis = 0
1040+ )
10881041
10891042 # Update matplotlib canvas at the bottom of the window. Timecourses are
10901043 # stored in SI units (Am), but shown in nAm, hence the 1e9 scaling at the
@@ -1261,7 +1214,11 @@ def _update_arrows(self):
12611214 # TODO: Need to expose a public method for setting the multi-dipole method
12621215 def _on_select_method (self , method ):
12631216 """Select the method to use for multi-dipole timecourse fitting."""
1264- _check_option ("method" , method , ("Multi dipole (MNE)" , "Single dipole" ))
1217+ _check_option (
1218+ "method" ,
1219+ method ,
1220+ ("Multi dipole (MNE)" , "Single dipole" ),
1221+ )
12651222 if method == self ._multi_dipole_method :
12661223 return
12671224 self ._multi_dipole_method = method
@@ -1297,11 +1254,6 @@ def _on_dipole_set_name(self, name, dip_num):
12971254 self ._dipoles [dip_num ]["dip" ].name = name
12981255 self ._renderer ._mplcanvas .update_plot ()
12991256
1300- def _on_dipole_toggle_fix_orientation (self , fix , dip_num ):
1301- """Fix dipole orientation when fitting timecourse."""
1302- self ._dipoles [dip_num ]["fix_ori" ] = bool (fix )
1303- self ._fit_timecourses ()
1304-
13051257 def _on_dipole_delete (self , dip_num ):
13061258 """Delete previously fitted dipole."""
13071259 dipole = self ._dipoles [dip_num ]
0 commit comments