eegprep 0.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,187 @@
1
+ # Example to export MNE epochs to EEGLAB dataset
2
+ # Events are not handled correctly in this example but it works
3
+
4
+ import mne
5
+ from mne.datasets import sample
6
+ from mne.preprocessing import ICA
7
+ import math
8
+
9
+ import numpy as np
10
+ from scipy.io import savemat
11
+
12
+ # Load example data
13
+ def eeg_mne2eeglab_epochs(epochs, ica):
14
+
15
+ # export to EEGLAB dataset
16
+ data = epochs.get_data() # Get the data from the epochs
17
+ n_epochs, n_channels, n_times = data.shape
18
+ ica_weights = ica.get_components() # ICA weights (n_components x n_channels)
19
+
20
+ # create identity matrix of size n_channels x n_channels
21
+ ica_sphere = np.eye(n_channels) # ICA sphere (n_channels x n_channels)
22
+
23
+ # Compute the mixing matrix (inverse weights)
24
+ ica_inverse_weights = np.linalg.pinv(ica_weights) # Shape: (n_channels, n_components)
25
+
26
+ ica_channels = ica.info['ch_names']
27
+ raw_channels = epochs.info['ch_names'] # Assuming you have the raw object
28
+ ica_channel_indices = [raw_channels.index(ch) for ch in ica_channels]
29
+ ica_channel_indices = np.array(ica_channel_indices)
30
+
31
+ ica_act = ica.get_sources(epochs).get_data(copy=True).transpose(1, 2, 0) # Get the ICA activations
32
+
33
+ print('Reference conversion may not be accurate...')
34
+ if 'custom_ref_applied' in epochs.info and epochs.info['custom_ref_applied']:
35
+ ref = 'common' # Custom reference was applied
36
+ else:
37
+ ref = 'average' # Default to average reference
38
+
39
+ eeglab_dict = {
40
+ 'setname' : '',
41
+ 'filename' : '',
42
+ 'filepath' : '',
43
+ 'subject' : '',
44
+ 'group' : '',
45
+ 'condition' : '',
46
+ 'session' : np.array([]),
47
+ 'comments' : '',
48
+ 'nbchan' : n_channels,
49
+ 'trials' : n_epochs,
50
+ 'pnts' : n_times,
51
+ 'srate' : epochs.info['sfreq'],
52
+ 'xmin' : epochs.times[0],
53
+ 'xmax' : epochs.times[-1],
54
+ 'times' : epochs.times,
55
+ 'data' : data,
56
+ 'icaact' : ica_act,
57
+ 'icawinv' : ica_inverse_weights,
58
+ 'icasphere' : ica_weights,
59
+ 'icaweights' : ica_sphere,
60
+ 'icachansind' : ica_channel_indices,
61
+ 'chanlocs' : np.array([]),
62
+ 'urchanlocs' : np.array([]),
63
+ 'chaninfo' : np.array([]),
64
+ 'ref' : ref,
65
+ 'event' : np.array([]),
66
+ 'urevent' : np.array([]),
67
+ 'eventdescription': np.array([]),
68
+ 'epoch' : np.array([]),
69
+ 'epochdescription': np.array([]),
70
+ 'reject' : np.array([]),
71
+ 'stats' : np.array([]),
72
+ 'specdata' : np.array([]),
73
+ 'specicaact' : np.array([]),
74
+ 'splinefile' : np.array([]),
75
+ 'icasplinefile' : np.array([]),
76
+ 'dipfit' : np.array([]),
77
+ 'history' : np.array([]),
78
+ 'saved' : np.array([]),
79
+ 'etc' : np.array([]),
80
+ 'datfile' : np.array([]),
81
+ 'run' : np.array([]),
82
+ 'roi' : np.array([]),
83
+ }
84
+
85
+ # create channel locations
86
+ ch_names = epochs.ch_names
87
+
88
+ ch_locs = epochs.info['chs']
89
+
90
+ theta_all = []
91
+ radius_all = []
92
+ sph_theta_all = []
93
+ sph_phi_all = []
94
+ sph_radius_all = []
95
+ X_all = []
96
+ Y_all = []
97
+ Z_all = []
98
+ for ch in ch_locs:
99
+ if 'loc' in ch and ch['loc'] is not None:
100
+ X_all.append(ch['loc'][1]*1000)
101
+ Y_all.append(-ch['loc'][0]*1000)
102
+ Z_all.append(ch['loc'][2]*1000)
103
+ hypotxy = math.hypot(X_all[-1],Y_all[-1])
104
+ sph_radius_all.append(math.hypot(hypotxy,Z_all[-1]))
105
+
106
+ az = math.atan2(Y_all[-1],X_all[-1])/math.pi*180
107
+ horiz = math.atan2(Z_all[-1],hypotxy)/math.pi*180
108
+
109
+ sph_theta_all.append(az)
110
+ sph_phi_all.append(horiz)
111
+
112
+ theta_all.append(-az) # warning inverse notation compared to MATLAB to match
113
+ radius_all.append(0.5 - horiz/180) # warning inverse notation compared to MATLAB to match
114
+
115
+ d_list = [{
116
+ 'labels': ch_name,
117
+ 'theta': theta,
118
+ 'radius': radius,
119
+ 'X': X,
120
+ 'Y': Y,
121
+ 'Z': Z,
122
+ 'sph_theta': sph_theta,
123
+ 'sph_phi': sph_phi,
124
+ 'sph_radius': sph_radius,
125
+ 'type': 'EEG',
126
+ 'urchan': 0,
127
+ 'ref': ''
128
+ } for ch_name, theta, radius, X, Y, Z, sph_theta, sph_phi, sph_radius in zip(ch_names, theta_all, radius_all, X_all, Y_all, Z_all, sph_theta_all, sph_phi_all, sph_radius_all)]
129
+ # Create the list of dictionaries with a string field
130
+ # d_list = [{
131
+ # 'labels': ch_name,
132
+ # 'theta': math.atan2(ch_loc[0], ch_loc[1]),
133
+ # 'radius': math.hypot(ch_loc[1], ch_loc[0]),
134
+ # 'X': ch_loc[1]*1000,
135
+ # 'Y': ch_loc[0]*1000,
136
+ # 'Z': ch_loc[2]*1000,
137
+ # 'sph_theta': 0,
138
+ # 'sph_phi': 0,
139
+ # 'sph_radius': 0,
140
+ # 'type': 'EEG',
141
+ # 'urchan': 0,
142
+ # 'ref': ''
143
+ # } for ch_name, ch_loc in zip(ch_names, ch_locs_xyz)]
144
+
145
+ # convert d_list to a numpy array
146
+ d_list = np.array(d_list)
147
+ eeglab_dict['chanlocs'] = d_list
148
+
149
+ # # Step 4: Save the EEGLAB dataset as a .mat file
150
+ return eeglab_dict
151
+
152
+ #print("EEGLAB dataset saved successfully!")
153
+
154
+ def test_eeg_mne2eeeglab_epochs():
155
+ sample_data_folder = mne.datasets.sample.data_path()
156
+ sample_data_raw_file = (
157
+ sample_data_folder / "MEG" / "sample" / "sample_audvis_filt-0-40_raw.fif"
158
+ )
159
+
160
+ raw = mne.io.read_raw_fif(sample_data_raw_file)
161
+
162
+ # extract data epochs
163
+ events = mne.find_events(raw, stim_channel="STI 014")
164
+ event_dict = {
165
+ "auditory/left": 1,
166
+ "auditory/right": 2,
167
+ "visual/left": 3,
168
+ "visual/right": 4,
169
+ "smiley": 5,
170
+ "buttonpress": 32,
171
+ }
172
+ epochs = mne.Epochs(
173
+ raw,
174
+ events,
175
+ event_id=event_dict,
176
+ tmin=-0.2,
177
+ tmax=0.5,
178
+ preload=True,
179
+ )
180
+
181
+ ica = ICA(n_components=15, random_state=97, max_iter=800)
182
+ ica.fit(raw)
183
+
184
+ EEG = eeg_mne2eeglab_epochs(epochs, ica)
185
+ savemat('output_file.mat', EEG) # use pop_saveset
186
+
187
+ # test_eeg_mne2eeeglab_epochs()
eegprep/eeg_rpsd.py ADDED
@@ -0,0 +1,65 @@
1
+ import numpy as np
2
+ from numpy.fft import fft
3
+ from scipy.signal.windows import hamming
4
+
5
+ def eeg_rpsd(EEG, nfreqs=None, pct_data=100):
6
+ # clean input cutoff freq
7
+ nyquist = EEG['srate'] // 2
8
+ if nfreqs is None or nfreqs > nyquist:
9
+ nfreqs = nyquist
10
+ nfreqs = int(nfreqs)
11
+
12
+ # setup constants
13
+ ncomp = EEG['icaweights'].shape[0]
14
+
15
+ # Hamming window
16
+ n_points = min(EEG['pnts'], EEG['srate'])
17
+ m = n_points
18
+ isOddLength = m % 2
19
+ if isOddLength:
20
+ x = np.arange(0, (m - 1) / 2 + 1) / (m - 1)
21
+ else:
22
+ x = np.arange(0, m / 2) / (m - 1)
23
+
24
+ a = 0.54
25
+ window = a - (1 - a) * np.cos(2 * np.pi * x)
26
+ if isOddLength:
27
+ window = np.concatenate([window, window[-2::-1]])
28
+ else:
29
+ window = np.concatenate([window, window[::-1]])
30
+
31
+ cutoff = (EEG['pnts'] // n_points) * n_points
32
+ index = np.add.outer(np.ceil(np.arange(0, cutoff - n_points + 1, n_points/2)).astype(int), np.arange(0, n_points)).astype(int).transpose()
33
+
34
+ np.random.seed(0) # rng('default') in MATLAB
35
+ n_seg = index.shape[1] * EEG['trials']
36
+ subset = np.random.permutation(n_seg)[:int(n_seg * pct_data / 100)]
37
+
38
+ # calculate windowed spectrums
39
+ psdmed = np.zeros((ncomp, nfreqs))
40
+ for it in range(ncomp):
41
+ temp = np.reshape(EEG['icaact'][it, index, :], (1, index.shape[0], index.shape[1] * EEG['trials']))
42
+ temp = temp[:, :, subset] * window[:, np.newaxis]
43
+ temp = fft(temp, n_points, axis=1)
44
+ temp = np.abs(temp) ** 2
45
+ temp = temp[:, 1:nfreqs + 1, :] * 2 / (EEG['srate'] * np.sum(window ** 2))
46
+ if nfreqs == nyquist:
47
+ temp[:, -1, :] /= 2
48
+ psdmed[it, :] = 20 * np.log10(np.median(temp, axis=2))
49
+
50
+ return psdmed
51
+
52
+ def test_eeg_rpsd():
53
+ EEG = {
54
+ 'srate': 256,
55
+ 'icaweights': np.random.randn(10, 256),
56
+ 'pnts': 1000,
57
+ 'trials': 5,
58
+ 'icaact': np.random.randn(10, 1000, 5)
59
+ }
60
+
61
+ psdmed = eeg_rpsd(EEG, 100)
62
+ assert psdmed.shape == (10, 100)
63
+ assert np.all(np.isfinite(psdmed))
64
+
65
+ # test_eeg_rpsd()
@@ -0,0 +1,17 @@
1
+ from eeg_rpsd import eeg_rpsd
2
+ from pop_loadset import pop_loadset
3
+ import sys
4
+
5
+ if len(sys.argv) > 1:
6
+ eeglab_file_path = sys.argv[1]
7
+ else:
8
+ eeglab_file_path = '/System/Volumes/Data/data/matlab/eeglab/sample_data/eeglab_data_epochs_ica.set'
9
+ EEG = pop_loadset(eeglab_file_path)
10
+
11
+ # Print the loaded data
12
+ res = eeg_rpsd(EEG, 100)
13
+
14
+ # save in a matlab file
15
+ import scipy.io
16
+ scipy.io.savemat('eeg_rpsd_data.mat', {'grid': res})
17
+ print('Saved eeg_rpsd_data.mat')
@@ -0,0 +1,117 @@
1
+ from oct2py import Oct2Py, get_log
2
+ from pop_saveset import pop_saveset
3
+ from pop_loadset import pop_loadset
4
+ import logging
5
+ import os
6
+ import sys
7
+
8
+ eeglab = Oct2Py(logger=get_log())
9
+ oc = Oct2Py(logger=get_log())
10
+ eeglab.logger = get_log("new_log")
11
+
12
+ def pop_resample( EEG, freq): # 2 additional parameters in MATLAB (never used)
13
+
14
+ pop_saveset(EEG, 'tmp.set') # 0.8 seconds
15
+ EEG2 = eeglab.pop_loadset('tmp.set') # 2 seconds
16
+ EEG2 = eeglab.pop_resample(EEG2, freq) # 2.4 seconds
17
+ eeglab.pop_saveset(EEG2, 'tmp2.set') # 2.4 seconds
18
+ EEG3 = pop_loadset('tmp2.set') # 0.2 seconds
19
+
20
+ # delete temporary files
21
+ os.remove('tmp.set')
22
+ os.remove('tmp2.set')
23
+ return EEG3
24
+
25
+
26
+ def pop_eegfiltnew(locutoff=None,hicutoff=None,revfilt=False,plotfreqz=False):
27
+ # error if locutoff and hicutoff are none
28
+ if locutoff==None and hicutoff==None:
29
+ raise('Cannot have low cutoff and high cutoff not defined')
30
+
31
+ pop_saveset(EEG, 'tmp.set') # 0.8 seconds
32
+ EEG2 = eeglab.pop_loadset('tmp.set') # 2 seconds
33
+ EEG3 = pop_eegfiltnew(EEG2, 'locutoff',locutoff,'hicutoff',hicutoff,'revfilt',revfilt,'plotfreqz',plotfreqz)
34
+ eeglab.pop_saveset(EEG2, 'tmp2.set') # 2.4 seconds
35
+ EEG4 = pop_loadset('tmp2.set') # 0.2 seconds
36
+
37
+ # delete temporary files
38
+ os.remove('tmp.set')
39
+ os.remove('tmp2.set')
40
+ return EEG4
41
+
42
+ def clean_artifacts( EEG, ChannelCriterion=False, LineNoiseCriterion=False, FlatlineCriterion=False, BurstCriterion=False, WindowCriterion=0, Highpass=[0.25, 0.75], WindowCriterionTolerances=[float('-inf'), 8]):
43
+
44
+ if ChannelCriterion == False or ChannelCriterion == 'off':
45
+ ChannelCriterion='off'
46
+ else:
47
+ ChannelCriterion='on'
48
+
49
+ if LineNoiseCriterion == False or LineNoiseCriterion == 'off':
50
+ LineNoiseCriterion='off'
51
+ else:
52
+ LineNoiseCriterion='on'
53
+
54
+ if FlatlineCriterion == False or FlatlineCriterion == 'off':
55
+ FlatlineCriterion='off'
56
+ else:
57
+ FlatlineCriterion='on'
58
+
59
+ if BurstCriterion == False or BurstCriterion == 'off':
60
+ BurstCriterion='off'
61
+ else:
62
+ BurstCriterion='on'
63
+
64
+ pop_saveset(EEG, 'tmp.set') # 0.8 seconds
65
+ EEG2 = eeglab.pop_loadset('tmp.set') # 2 seconds
66
+ EEG3 = eeglab.clean_artifacts(EEG2, 'ChannelCriterion', ChannelCriterion, \
67
+ 'LineNoiseCriterion', LineNoiseCriterion, \
68
+ 'FlatlineCriterion', FlatlineCriterion, \
69
+ 'BurstCriterion', BurstCriterion, \
70
+ 'WindowCriterion', WindowCriterion, \
71
+ 'Highpass',Highpass, \
72
+ 'WindowCriterionTolerances', WindowCriterionTolerances)
73
+ eeglab.pop_saveset(EEG3, 'tmp2.set') # 2.4 seconds
74
+ EEG4 = pop_loadset('tmp2.set') # 0.2 seconds
75
+
76
+ # delete temporary files
77
+ os.remove('tmp.set')
78
+ os.remove('tmp2.set')
79
+ return EEG3
80
+
81
+ # sys.exit()
82
+
83
+ eeglab.logger.setLevel(logging.WARNING)
84
+ eeglab.warning('off', 'backtrace')
85
+
86
+ # On the command line, type "octave-8.4.0" OCTAVE_EXECUTABLE or OCTAVE var
87
+ path2eeglab = '/System/Volumes/Data/data/matlab/eeglab/' # init >10 seconds
88
+ eeglab.addpath(path2eeglab + '/functions/guifunc')
89
+ eeglab.addpath(path2eeglab + '/functions/popfunc')
90
+ eeglab.addpath(path2eeglab + '/functions/adminfunc')
91
+ eeglab.addpath(path2eeglab + '/plugins/firfilt')
92
+ eeglab.addpath(path2eeglab + '/functions/sigprocfunc')
93
+ eeglab.addpath(path2eeglab + '/functions/miscfunc')
94
+ eeglab.addpath(path2eeglab + '/plugins/dipfit')
95
+ eeglab.addpath(path2eeglab + '/plugins/clean_rawdata')
96
+ res = eeglab.version()
97
+ print('Running EEGLAB commands in compatibility mode with Octave ' + res)
98
+ eeglab.logger.setLevel(logging.INFO)
99
+
100
+ eeglab_file_path = '/System/Volumes/Data/data/matlab/eeglab/sample_data/eeglab_data_epochs_ica.set'
101
+
102
+ EEG = pop_loadset(eeglab_file_path)
103
+ EEG = pop_eegfiltnew(EEG, locutoff=5,hicutoff=25,revfilt=True,plotfreqz=False)
104
+
105
+ # EEG = eeglab.pop_loadset(eeglab_file_path)
106
+ # TMPEEG = eeglab.pop_eegfiltnew(EEG, 'locutoff',5,'hicutoff',25,'revfilt',1,'plotfreqz',0)
107
+ # CLEANEDEEG = eeglab.clean_artifacts(TMPEEG, 'ChannelCriterion', 'off',
108
+ # 'LineNoiseCriterion', 'off',
109
+ # 'FlatlineCriterion', 'off',
110
+ # 'BurstCriterion', 'off',
111
+ # 'WindowCriterion', 0,
112
+ # 'Highpass',[0.25, 0.75],
113
+ # 'WindowCriterionTolerances', [-10000000, 8])
114
+
115
+ # clean_artifacts( EEG, ChannelCriterion='on' )
116
+
117
+
eegprep/iclabel.py ADDED
@@ -0,0 +1,51 @@
1
+ from .ICL_feature_extractor import ICL_feature_extractor
2
+ from .iclabel_net import ICLabelNet
3
+ import torch
4
+ import numpy as np
5
+
6
+ def iclabel(EEG, algorithm='default'):
7
+ # issue error if algorithm is not 'default'
8
+ if algorithm != 'default':
9
+ raise ValueError('Only the default algorithm is supported')
10
+
11
+ #ICLABEL Extract ICLabel features from an EEG dataset.
12
+ features = ICL_feature_extractor(EEG, True)
13
+
14
+ # Equivalent of MATLAB code reshaping
15
+ features[0] = np.single(np.concatenate([features[0],-features[0],features[0][:, ::-1, :, :],-features[0][:, ::-1, :, :]], axis=3))
16
+ features[1] = np.single(np.tile(features[1], (1, 1, 1, 4)))
17
+ features[2] = np.single(np.tile(features[2], (1, 1, 1, 4)))
18
+ print('Feature 0 shape:', features[0].shape)
19
+ print('Feature 1 shape:', features[1].shape)
20
+ print('Feature 2 shape:', features[2].shape)
21
+
22
+ # Load the ICLabelNet model
23
+ model = ICLabelNet('netICL.mat')
24
+
25
+ # Convert the features to torch tensors
26
+ image = torch.tensor(features[0]).permute(-1, 2, 0, 1)
27
+ psdmed = torch.tensor(features[1]).permute(-1, 2, 0, 1)
28
+ autocorr = torch.tensor(features[2]).permute(-1, 2, 0, 1)
29
+
30
+ # Get the output from the model
31
+ output = model(image, psdmed, autocorr)
32
+ output_np = output.detach().numpy()
33
+ output_np = output_np.T # Transpose the array
34
+ output_np = np.reshape(output_np, (-1, 4), order='F') # Reshape to have 4 columns
35
+ output_np = np.mean(output_np, axis=1) # Compute the mean along the second axis (columns)
36
+ output_np = np.reshape(output_np, (7, -1), order='F') # Reshape to have 7 rows
37
+ output_np = output_np.T # Transpose back
38
+
39
+ if 'ic_classification' not in EEG['etc']:
40
+ EEG['etc']['ic_classification'] = {}
41
+ if 'ICLabel' not in EEG['etc']['ic_classification']:
42
+ EEG['etc']['ic_classification']['ICLabel'] = {}
43
+
44
+ EEG['etc']['ic_classification']['ICLabel']['classes'] = np.array(
45
+ ['Brain', 'Muscle', 'Eye', 'Heart', 'Line Noise', 'Channel Noise', 'Other'],
46
+ dtype=np.object
47
+ )
48
+ EEG['etc']['ic_classification']['ICLabel']['classifications'] = output_np
49
+ EEG['etc']['ic_classification']['ICLabel']['version'] = 'default'
50
+
51
+ return EEG
@@ -0,0 +1,26 @@
1
+ from iclabel import iclabel
2
+ from pop_loadset import pop_loadset
3
+ from pop_saveset import pop_saveset
4
+ import sys
5
+
6
+ # check if there are 2 arguments otherwise issue an error
7
+ if len(sys.argv) != 3:
8
+ raise ValueError('Please provide the input and output file paths as command line arguments')
9
+
10
+ # get first command line argument
11
+ eeglab_file_path_in = sys.argv[1]
12
+ eeglab_file_path_out = sys.argv[2]
13
+
14
+ EEG = pop_loadset(eeglab_file_path_in)
15
+ # EEG['data'] = EEG['data'].reshape(EEG['data'].shape[0], -1)
16
+ # EEG['icaact'] = EEG['icaact'].reshape(EEG['icaact'].shape[0], -1)
17
+ # EEG['nbchan'] = EEG['data'].shape[0]
18
+ # EEG['pnts'] = EEG['data'].shape[1]
19
+ # EEG['trials'] = 1
20
+
21
+ # Print the loaded data
22
+ print('Data shape:', EEG['data'].shape)
23
+ EEG = iclabel(EEG, 'default')
24
+
25
+ # save dataset
26
+ pop_saveset(EEG, eeglab_file_path_out)
eegprep/iclabel_net.py ADDED
@@ -0,0 +1,136 @@
1
+ import scipy.io
2
+ import torch
3
+ import scipy
4
+ import numpy as np
5
+
6
+ class Reshape(torch.nn.Module):
7
+ def __init__(self, shape):
8
+ super().__init__()
9
+ self.shape = shape
10
+
11
+ def forward(self, x):
12
+ return x.view(x.shape[0], *self.shape)
13
+
14
+ class Concatenate(torch.nn.Module):
15
+ def __init__(self, dim):
16
+ super().__init__()
17
+ self.dim = dim
18
+
19
+ def forward(self, x: list):
20
+ return torch.cat(x, dim=self.dim)
21
+
22
+
23
+ class ICLabelNet(torch.nn.Module):
24
+ def __init__(self, mat_path):
25
+ super().__init__()
26
+ iclabel_matlab = scipy.io.loadmat(mat_path)
27
+ params = iclabel_matlab['params'][0]
28
+ i = 11
29
+ print('shape of param', i, torch.tensor(params[i][1]).shape)
30
+ self.discriminator_image_layer1_conv = torch.nn.Conv2d(in_channels=1, out_channels=128, kernel_size=4, stride=2, padding=1, dilation=1)
31
+ print(self.discriminator_image_layer1_conv.weight.shape)
32
+ self.discriminator_image_layer1_conv.weight = torch.nn.Parameter(torch.tensor(params[0][1]).permute(3, 2, 0, 1))
33
+ self.discriminator_image_layer1_conv.bias = torch.nn.Parameter(torch.tensor(params[1][1]).squeeze())
34
+ self.discriminator_image_layer1_relu = torch.nn.LeakyReLU(0.2)
35
+ self.discriminator_image_layer2_conv = torch.nn.Conv2d(in_channels=128, out_channels=256, kernel_size=4, stride=2, padding=1, dilation=1)
36
+ self.discriminator_image_layer2_conv.weight = torch.nn.Parameter(torch.tensor(params[2][1]).permute(3, 2, 0, 1))
37
+ self.discriminator_image_layer2_conv.bias = torch.nn.Parameter(torch.tensor(params[3][1]).squeeze())
38
+ self.discriminator_image_layer2_relu = torch.nn.LeakyReLU(0.2)
39
+ self.discriminator_image_layer3_conv = torch.nn.Conv2d(in_channels=256, out_channels=512, kernel_size=4, stride=2, padding=1, dilation=1)
40
+ self.discriminator_image_layer3_conv.weight = torch.nn.Parameter(torch.tensor(params[4][1]).permute(3, 2, 0, 1))
41
+ self.discriminator_image_layer3_conv.bias = torch.nn.Parameter(torch.tensor(params[5][1]).squeeze())
42
+ self.discriminator_image_layer3_relu = torch.nn.LeakyReLU(0.2)
43
+ self.discriminator_psdmed_layer1_conv_conv = torch.nn.Conv2d(in_channels=1, out_channels=128, kernel_size=(1,3), stride=1, padding=(0,1), dilation=1)
44
+ self.discriminator_psdmed_layer1_conv_conv.weight = torch.nn.Parameter(torch.tensor(params[6][1]).permute(3, 2, 0, 1))
45
+ self.discriminator_psdmed_layer1_conv_conv.bias = torch.nn.Parameter(torch.tensor(params[7][1]).squeeze())
46
+ self.discriminator_psdmed_layer1_conv_relu = torch.nn.LeakyReLU(0.2)
47
+ self.discriminator_psdmed_layer2_conv_conv = torch.nn.Conv2d(in_channels=128, out_channels=256, kernel_size=(1,3), stride=1, padding=(0,1), dilation=1)
48
+ self.discriminator_psdmed_layer2_conv_conv.weight = torch.nn.Parameter(torch.tensor(params[8][1]).permute(3, 2, 0, 1))
49
+ self.discriminator_psdmed_layer2_conv_conv.bias = torch.nn.Parameter(torch.tensor(params[9][1]).squeeze())
50
+ self.discriminator_psdmed_layer2_conv_relu = torch.nn.LeakyReLU(0.2)
51
+ self.discriminator_psdmed_layer3_conv_conv = torch.nn.Conv2d(in_channels=256, out_channels=1, kernel_size=(1,3), stride=1, padding=(0,1), dilation=1)
52
+ self.discriminator_psdmed_layer3_conv_conv.weight = torch.nn.Parameter(torch.tensor(params[10][1]).unsqueeze(3).permute(3, 2, 0, 1))
53
+ self.discriminator_psdmed_layer3_conv_conv.bias = torch.nn.Parameter(torch.tensor(params[11][1]).squeeze(1))
54
+ self.discriminator_psdmed_layer3_conv_relu = torch.nn.LeakyReLU(0.2)
55
+ self.discriminator_autocorr_layer1_conv_conv = torch.nn.Conv2d(in_channels=1, out_channels=128, kernel_size=(1,3), stride=1, padding=(0,1), dilation=1)
56
+ self.discriminator_autocorr_layer1_conv_conv.weight = torch.nn.Parameter(torch.tensor(params[12][1]).permute(3, 2, 0, 1))
57
+ self.discriminator_autocorr_layer1_conv_conv.bias = torch.nn.Parameter(torch.tensor(params[13][1]).squeeze())
58
+ self.discriminator_autocorr_layer1_conv_relu = torch.nn.LeakyReLU(0.2)
59
+ self.discriminator_autocorr_layer2_conv_conv = torch.nn.Conv2d(in_channels=128, out_channels=256, kernel_size=(1,3), stride=1, padding=(0,1), dilation=1)
60
+ self.discriminator_autocorr_layer2_conv_conv.weight = torch.nn.Parameter(torch.tensor(params[14][1]).permute(3, 2, 0, 1))
61
+ self.discriminator_autocorr_layer2_conv_conv.bias = torch.nn.Parameter(torch.tensor(params[15][1]).squeeze())
62
+ self.discriminator_autocorr_layer2_conv_relu = torch.nn.LeakyReLU(0.2)
63
+ self.discriminator_autocorr_layer3_conv_conv = torch.nn.Conv2d(in_channels=256, out_channels=1, kernel_size=(1,3), stride=1, padding=(0,1), dilation=1)
64
+ self.discriminator_autocorr_layer3_conv_conv.weight = torch.nn.Parameter(torch.tensor(params[16][1]).unsqueeze(3).permute(3, 2, 0, 1))
65
+ self.discriminator_autocorr_layer3_conv_conv.bias = torch.nn.Parameter(torch.tensor(params[17][1]).squeeze(1))
66
+ self.discriminator_autocorr_layer3_conv_relu = torch.nn.LeakyReLU(0.2)
67
+ self.discriminator_psdmed_reshape = Reshape((100, 1, 1))
68
+ self.discriminator_psdmed_concat1 = Concatenate(dim=2)
69
+ self.discriminator_psdmed_concat2 = Concatenate(dim=3)
70
+ self.discriminator_autocorr_reshape = Reshape((100, 1, 1))
71
+ self.discriminator_autocorr_concat1 = Concatenate(dim=2)
72
+ self.discriminator_autocorr_concat2 = Concatenate(dim=3)
73
+ self.discriminator_concat = Concatenate(dim=1)
74
+ self.discriminator_conv = torch.nn.Conv2d(in_channels=712, out_channels=7, kernel_size=4, stride=1, padding=0, dilation=1)
75
+ self.discriminator_conv.weight = torch.nn.Parameter(torch.tensor(params[18][1]).permute(3, 2, 0, 1))
76
+ self.discriminator_conv.bias = torch.nn.Parameter(torch.tensor(params[19][1]).squeeze())
77
+ self.discriminator_softmax = torch.nn.Softmax(dim=1)
78
+
79
+ def forward(self, image, psdmed, autocorr):
80
+ x_image = self.discriminator_image_layer1_conv(image)
81
+ x_image = self.discriminator_image_layer1_relu(x_image)
82
+ x_image = self.discriminator_image_layer2_conv(x_image)
83
+ x_image = self.discriminator_image_layer2_relu(x_image)
84
+ x_image = self.discriminator_image_layer3_conv(x_image)
85
+ x_image = self.discriminator_image_layer3_relu(x_image)
86
+ print('x_image', x_image.shape)
87
+
88
+ x_psdmed = self.discriminator_psdmed_layer1_conv_conv(psdmed)
89
+ x_psdmed = self.discriminator_psdmed_layer1_conv_relu(x_psdmed)
90
+ x_psdmed = self.discriminator_psdmed_layer2_conv_conv(x_psdmed)
91
+ x_psdmed = self.discriminator_psdmed_layer2_conv_relu(x_psdmed)
92
+ x_psdmed = self.discriminator_psdmed_layer3_conv_conv(x_psdmed)
93
+ x_psdmed = self.discriminator_psdmed_layer3_conv_relu(x_psdmed)
94
+ x_psdmed = self.discriminator_psdmed_reshape(x_psdmed)
95
+ x_psdmed = self.discriminator_psdmed_concat1([x_psdmed]*4)
96
+ x_psdmed = self.discriminator_psdmed_concat2([x_psdmed]*4)
97
+ print('x_psdmed', x_psdmed.shape)
98
+
99
+ x_autocorr = self.discriminator_autocorr_layer1_conv_conv(autocorr)
100
+ x_autocorr = self.discriminator_autocorr_layer1_conv_relu(x_autocorr)
101
+ x_autocorr = self.discriminator_autocorr_layer2_conv_conv(x_autocorr)
102
+ x_autocorr = self.discriminator_autocorr_layer2_conv_relu(x_autocorr)
103
+ x_autocorr = self.discriminator_autocorr_layer3_conv_conv(x_autocorr)
104
+ x_autocorr = self.discriminator_autocorr_layer3_conv_relu(x_autocorr)
105
+ x_autocorr = self.discriminator_autocorr_reshape(x_autocorr)
106
+ x_autocorr = self.discriminator_autocorr_concat1([x_autocorr]*4)
107
+ x_autocorr = self.discriminator_autocorr_concat2([x_autocorr]*4)
108
+ print('x_autocorr', x_autocorr.shape)
109
+
110
+ x = self.discriminator_concat([x_image, x_psdmed, x_autocorr])
111
+ x = self.discriminator_conv(x)
112
+ print('x', x.shape)
113
+ # subtract max value to avoid overflow
114
+ x = x - torch.max(x, dim=1, keepdim=True).values
115
+ x = self.discriminator_softmax(x)
116
+
117
+ return x
118
+
119
+ # if __name__ == "__main__":
120
+ # model = ICLabelNet('netICL.mat')
121
+ # image_mat = scipy.io.loadmat('net_vars.mat')['in_image']
122
+ # psdmed_mat = scipy.io.loadmat('net_vars.mat')['in_psdmed']
123
+ # autocorr_mat = scipy.io.loadmat('net_vars.mat')['in_autocorr']
124
+ # # assuming third dimension is trivial and last dimension is channel. First two dimensions (32 x 32) are size of topoplot
125
+ # image = torch.tensor(image_mat).permute(-1, 2, 0, 1)
126
+ # print('image shape', image.shape)
127
+ # psdmed = torch.tensor(psdmed_mat).permute(-1, 2, 0, 1)
128
+ # print('psd shape', psdmed.shape)
129
+ # autocorr = torch.tensor(autocorr_mat).permute(-1, 2, 0, 1)
130
+ # print('autocorr shape', autocorr.shape)
131
+ # output = model(image, psdmed, autocorr)
132
+ # print(output.shape)
133
+
134
+ # # save the output to a mat file
135
+ # scipy.io.savemat('output4.mat', {'output': output.detach().numpy()})
136
+