sensors.m 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. function res = sensors(this, type, newsens)
  2. % Sets and gets sensor fields for EEG and MEG
  3. % returns empty matrix if no sensors are defined.
  4. % FORMAT res = sensors(this, type, newsens)
  5. % type - 'EEG' or 'MEG'
  6. % _______________________________________________________________________
  7. % Copyright (C) 2008-2012 Wellcome Trust Centre for Neuroimaging
  8. % Vladimir Litvak
  9. % $Id: sensors.m 6829 2016-07-07 10:16:46Z vladimir $
  10. if nargin<2
  11. error('Sensor type (EEG or MEG) must be specified');
  12. end
  13. switch lower(type)
  14. case 'eeg'
  15. if nargin < 3
  16. if isfield(this.sensors, 'eeg')
  17. res = this.sensors.eeg;
  18. else
  19. res = [];
  20. end
  21. else
  22. this.sensors(1).eeg = newsens;
  23. res = check(this);
  24. end
  25. case 'meg'
  26. if nargin < 3
  27. if isfield(this.sensors, 'meg')
  28. res = this.sensors.meg;
  29. else
  30. res = [];
  31. end
  32. else
  33. this.sensors(1).meg = newsens;
  34. res = check(this);
  35. end
  36. case 'src'
  37. if nargin < 3
  38. if isfield(this.sensors, 'src')
  39. res = this.sensors.src;
  40. else
  41. res = [];
  42. end
  43. else
  44. this.sensors(1).src = newsens;
  45. res = check(this);
  46. end
  47. otherwise
  48. error('Unsupported sensor type');
  49. end
  50. if nargin < 3 && ~isempty(res) && ismember(lower(type), {'eeg', 'meg'}) && this.montage.Mind > 0
  51. sens = res;
  52. montage = this.montage.M(this.montage.Mind);
  53. if ~isempty(intersect(sens.label, montage.labelorg))
  54. sensmontage = montage;
  55. [sel1, sel2] = spm_match_str(sens.label, sensmontage.labelorg);
  56. sensmontage.labelorg = sensmontage.labelorg(sel2);
  57. sensmontage.tra = sensmontage.tra(:, sel2);
  58. selempty = find(all(sensmontage.tra == 0, 2));
  59. sensmontage.tra(selempty, :) = [];
  60. sensmontage.labelnew(selempty) = [];
  61. if isfield(sensmontage, 'chantypeorg')
  62. sensmontage.chantypeorg = sensmontage.chantypeorg(sel2);
  63. end
  64. if isfield(sensmontage, 'chanunitorg')
  65. sensmontage.chanunitorg = sensmontage.chanunitorg(sel2);
  66. end
  67. if isfield(sensmontage, 'chantypenew')
  68. sensmontage.chantypenew(selempty) = [];
  69. end
  70. if isfield(sensmontage, 'chanunitnew')
  71. sensmontage.chanunitnew(selempty) = [];
  72. end
  73. chanunitorig = sens.chanunit(sel1);
  74. chantypeorig = sens.chantype(sel1);
  75. labelorg = sens.label;
  76. keepunused = 'no'; % not sure if this is good for all cases
  77. sens = ft_apply_montage(sens, sensmontage, 'keepunused', keepunused);
  78. if strcmpi(type, 'MEG')
  79. if isfield(sens, 'balance') && ~isequal(sens.balance.current, 'none')
  80. balance = ft_apply_montage(getfield(sens.balance, sens.balance.current), sensmontage, 'keepunused', keepunused);
  81. else
  82. balance = sensmontage;
  83. end
  84. sens.balance.custom = balance;
  85. sens.balance.current = 'custom';
  86. end
  87. % If all the original channels contributing to a new channel have
  88. % the same units, transfer them to the new channel. This might be
  89. % wrong if the montage itself changes the units by scaling the data.
  90. if isfield(sens, 'chanunit')
  91. chanunit = sens.chanunit;
  92. else
  93. chanunit = repmat({'unknown'}, numel(sens.label), 1);
  94. end
  95. if isfield(sens, 'chantype')
  96. chantype = sens.chantype;
  97. else
  98. chantype = repmat({'unknown'}, numel(sens.label), 1);
  99. end
  100. for j = 1:numel(sens.label)
  101. k = strmatch(sens.label{j}, sensmontage.labelnew, 'exact');
  102. if ~isempty(k)
  103. if isequal(chanunit{j}, 'unknown')
  104. unit = unique(chanunitorig(~~abs(sensmontage.tra(k, :))));
  105. if numel(unit)==1
  106. chanunit(j) = unit;
  107. elseif strcmpi(type, 'MEG')
  108. chanunit{j} = 'T';
  109. else
  110. chanunit{j} = 'V';
  111. end
  112. end
  113. if isequal(chantype{j}, 'unknown')
  114. ctype = unique(chantypeorig(~~abs(sensmontage.tra(k, :))));
  115. if numel(ctype)==1
  116. chantype(j) = ctype;
  117. elseif strcmpi(type, 'MEG')
  118. chantype{j} = 'megmag';
  119. else
  120. chantype{j} = 'eeg';
  121. end
  122. end
  123. else %channel was not in the montage, but just copied
  124. k = strmatch(sens.label{j}, labelorg, 'exact');
  125. if isequal(chanunit{j}, 'unknown')
  126. chanunit(j) = chanunitorig(k);
  127. end
  128. if isequal(chantype{j}, 'unknown')
  129. chantype(j) = chantypeorig(k);
  130. end
  131. end
  132. end
  133. sens.chanunit = chanunit;
  134. sens.chantype = chantype;
  135. end
  136. if strcmpi(type, 'MEG')
  137. res = ft_datatype_sens(sens, 'amplitude', 'T', 'distance', 'mm');
  138. else
  139. res = ft_datatype_sens(sens, 'amplitude', 'V', 'distance', 'mm');
  140. end
  141. end