diff --git a/NiBAx/core/model/datamodel.py b/NiBAx/core/model/datamodel.py index e7c593bd6..46f764261 100644 --- a/NiBAx/core/model/datamodel.py +++ b/NiBAx/core/model/datamodel.py @@ -36,10 +36,15 @@ def __init__(self): self.ADModel = None - def SetMUSEDictionaries(self, MUSEDictNAMEtoID, MUSEDictIDtoNAME): + def SetMUSEDictionaries(self, MUSEDictNAMEtoID, MUSEDictIDtoNAME,MUSEDictDataFrame): """Setter for MUSE dictionary""" self.MUSEDictNAMEtoID = MUSEDictNAMEtoID self.MUSEDictIDtoNAME = MUSEDictIDtoNAME + self.MUSEDictDataFrame = MUSEDictDataFrame + + def SetDerivedMUSEMap(self,DerivedMUSEMap): + """Setter for Derived MUSE dictionary""" + self.DerivedMUSEMap = DerivedMUSEMap def SetDataFilePath(self,p): @@ -65,6 +70,14 @@ def GetHarmonizationModelFilePath(self): def GetMUSEDictionaries(self): """Get the MUSE dictionaries to map from ID to name and vice-versa""" return self.MUSEDictNAMEtoID, self.MUSEDictIDtoNAME + + def GetDerivedMUSEMap(self): + """Get the derived MUSE dictionary to map from SINGLE to DERIVED ROIs""" + return self.DerivedMUSEMap + + def GetMUSEDictDataFrame(self): + """Get the MUSE dictionaries to map from ID to name and vice-versa""" + return self.MUSEDictDataFrame def SetData(self,d): diff --git a/NiBAx/plugins/harmonization/harmonization.py b/NiBAx/plugins/harmonization/harmonization.py index 0121813bd..ef10edb9f 100644 --- a/NiBAx/plugins/harmonization/harmonization.py +++ b/NiBAx/plugins/harmonization/harmonization.py @@ -7,6 +7,7 @@ import matplotlib.patches as pat import numpy as np import pandas as pd +import re from NiBAx.core.plotcanvas import PlotCanvas from NiBAx.core.baseplugin import BasePlugin from NiBAx.core.gui.SearchableQComboBox import SearchableQComboBox @@ -39,6 +40,9 @@ def getUI(self): def SetupConnections(self): self.ui.load_harmonization_model_Btn.clicked.connect(lambda: self.OnLoadHarmonizationModelBtnClicked()) + if self.datamodel.data is None: + self.ui.load_harmonization_model_Btn.setEnabled(False) + self.ui.Harmonized_Data_Information_Lbl.setText('Data must be loaded before model selection.\nReturn to Load and Save Data tab to select data.') self.ui.load_other_model_Btn.clicked.connect(lambda: self.OnLoadHarmonizationModelBtnClicked()) self.ui.show_data_Btn.clicked.connect(lambda: self.OnShowDataBtnClicked()) self.ui.apply_model_to_dataset_Btn.clicked.connect(lambda: self.OnApplyModelToDatasetBtnClicked()) @@ -54,12 +58,14 @@ def SetupConnections(self): self.ui.show_data_Btn.setStyleSheet("background-color: rgb(230,230,255); color: black") else: self.ui.show_data_Btn.setEnabled(False) + def OnLoadHarmonizationModelBtnClicked(self): filename, _ = QtWidgets.QFileDialog.getOpenFileName(None, 'Open harmonization model file', QtCore.QDir().homePath(), "Pickle files (*.pkl.gz *.pkl)") + self.filename = os.path.basename(filename) if filename == "": text_1=('Harmonization model not selected') @@ -101,13 +107,9 @@ def OnLoadHarmonizationModelBtnClicked(self): self.ui.stackedWidget.setCurrentIndex(0) def PopulateROI(self): - #get data column header names - datakeys = self.datamodel.GetColumnHeaderNames() - #construct ROI list to populate comboBox - roiList = ( [x for x in datakeys if x.startswith('MUSE_Volume')]) - + MUSEDictDataFrame = self.datamodel.GetMUSEDictDataFrame() _, MUSEDictIDtoNAME = self.datamodel.GetMUSEDictionaries() - roiList = list(set(roiList).intersection(set(datakeys))) + roiList = list(set(self.datamodel.GetColumnHeaderNames()).intersection(set(MUSEDictDataFrame[MUSEDictDataFrame['ROI_LEVEL']=='SINGLE']['ROI_COL']))) roiList.sort() roiList = ['(MUSE) ' + list(map(MUSEDictIDtoNAME.get, [k]))[0] if k.startswith('MUSE_') else k for k in roiList] @@ -131,14 +133,18 @@ def UpdatePlot(self): currentROI = self.ui.comboBoxROI.currentText() # Translate ROI name back to ROI ID - try: - MUSEDictNAMEtoID, _ = self.datamodel.GetMUSEDictionaries() - if currentROI.startswith('(MUSE)'): - currentROI = list(map(MUSEDictNAMEtoID.get, [currentROI[7:]]))[0] - except: - currentROI = 'DLICV' - self.ui.comboBoxROI.setCurrentText('DLICV') - print("Could not translate combo box item. Setting to `DLICV`.") + AllItems = [self.ui.comboBoxROI.itemText(i) for i in range(self.ui.comboBoxROI.count())] + MUSEDictNAMEtoID, _ = self.datamodel.GetMUSEDictionaries() + if currentROI not in AllItems[:-1]: + self.ui.comboBoxROI.blockSignals(True) + self.ui.comboBoxROI.clear() + self.ui.comboBoxROI.blockSignals(False) + self.ui.comboBoxROI.addItems(AllItems[:-1]) + currentROI = self.ui.comboBoxROI.itemText(0) + self.ui.comboBoxROI.setCurrentText(currentROI) + print("Invalid input. Setting to %s." % (currentROI)) + + currentROI = list(map(MUSEDictNAMEtoID.get, [currentROI[7:]]))[0] #create empty dictionary of plot options plotOptions = dict() @@ -292,7 +298,12 @@ def plotMUSE(self,plotOptions): def OnAddToDataFrame(self): print('Saving modified data to pickle file...') - H_ROIs = ['H_'+x for x in self.datamodel.harmonization_model['ROIs']] + MUSEDictDataFrame= self.datamodel.GetMUSEDictDataFrame() + Derived_numbers = list(MUSEDictDataFrame[MUSEDictDataFrame['ROI_LEVEL']=='DERIVED']['ROI_INDEX']) + Derived_MUSE_Volumes = list('MUSE_Volume_' + str(x) for x in Derived_numbers) + ROI_list = list(self.datamodel.harmonization_model['ROIs']) + Derived_MUSE_Volumes + ROI_list.remove('MUSE_Volume_702') + H_ROIs = list('H_' + str(x) for x in ROI_list) ROIs_ICV_Sex_Residuals = ['RES_ICV_Sex_' + x for x in self.datamodel.harmonization_model['ROIs']] ROIs_Residuals = ['RES_' + x for x in self.datamodel.harmonization_model['ROIs']] RAW_Residuals = ['RAW_RES_' + x for x in self.datamodel.harmonization_model['ROIs']] @@ -316,6 +327,32 @@ def OnDataChanged(self): else: self.ui.show_data_Btn.setEnabled(False) + if self.datamodel.data is None: + self.ui.load_harmonization_model_Btn.setEnabled(False) + self.ui.Harmonized_Data_Information_Lbl.setText('Data must be loaded before model selection.\nReturn to Load and Save Data tab to select data.') + else: + self.ui.load_harmonization_model_Btn.setEnabled(True) + if self.datamodel.harmonization_model is None: + self.ui.Harmonized_Data_Information_Lbl.setText('No harmonization model has been selected') + else: + self.ui.Harmonized_Data_Information_Lbl.setObjectName('correct_label') + self.ui.Harmonized_Data_Information_Lbl.setStyleSheet('QLabel#correct_label {color: black}') + model_text1 = (self.filename +' loaded') + model_text2 = ('SITES in training set: '+ ' '.join([str(elem) for elem in list(self.datamodel.harmonization_model['SITE_labels'])])) + model_text2 = wrap_by_word(model_text2,4) + model_text1 += '\n\n'+model_text2 + if 'Covariates' in self.datamodel.harmonization_model: + covariates = self.datamodel.harmonization_model['Covariates'] + model_text3 = ('Harmonization Covariates: '+ str(covariates)) + model_text1 += '\n'+model_text3 + else: + model_text3 = ('Harmonization Covariates Unavailable') + model_text1 += '\n'+model_text3 + age_max = self.datamodel.harmonization_model['smooth_model']['bsplines_constructor'].knot_kwds[0]['upper_bound'] + age_min = self.datamodel.harmonization_model['smooth_model']['bsplines_constructor'].knot_kwds[0]['lower_bound'] + model_text4 = ('Valid Age Range: [' + str(age_min) + ', ' + str(age_max) + ']') + model_text1 += '\n'+model_text4 + self.ui.Harmonized_Data_Information_Lbl.setText(model_text1) def DoHarmonization(self): print('Running harmonization.') @@ -354,9 +391,9 @@ def DoHarmonization(self): continue print('Harmonizing '+ site) - gamma_hat_site = np.mean(((Raw_ROIs_Residuals[new_site_is_train,:])/np.dot(np.sqrt(var_pooled),np.ones((1,Raw_ROIs_Residuals[new_site_is_train,:].shape[0]))).T),0) + gamma_hat_site = np.nanmean(((Raw_ROIs_Residuals[new_site_is_train,:])/np.dot(np.sqrt(var_pooled),np.ones((1,Raw_ROIs_Residuals[new_site_is_train,:].shape[0]))).T),0) gamma_hat_site = gamma_hat_site[:,np.newaxis] - delta_hat_site = pow(np.std(((Raw_ROIs_Residuals[new_site_is_train,:])/np.dot(np.sqrt(var_pooled),np.ones((1,Raw_ROIs_Residuals[new_site_is_train,:].shape[0]))).T),0),2) + delta_hat_site = pow(np.nanstd(((Raw_ROIs_Residuals[new_site_is_train,:])/np.dot(np.sqrt(var_pooled),np.ones((1,Raw_ROIs_Residuals[new_site_is_train,:].shape[0]))).T),0),2) delta_hat_site = delta_hat_site[:,np.newaxis] site_gamma = pd.DataFrame(gamma_hat_site.T,columns=gamma_ROIs,index=[site]) @@ -378,8 +415,19 @@ def DoHarmonization(self): if 'isTrainMUSEHarmonization' in self.datamodel.data.columns: muse = pd.concat([self.datamodel.data['isTrainMUSEHarmonization'].copy(), covars, pd.DataFrame(bayes_data, columns=['H_' + s for s in self.datamodel.harmonization_model['ROIs']])],axis=1) + if 'UseForComBatGAMHarmonization' in self.datamodel.data.columns: + muse = pd.concat([self.datamodel.data['UseForComBatGAMHarmonization'].copy(), covars, pd.DataFrame(bayes_data, columns=['H_' + s for s in self.datamodel.harmonization_model['ROIs']])],axis=1) else: muse = pd.concat([covars,pd.DataFrame(bayes_data, columns=['H_' + s for s in self.datamodel.harmonization_model['ROIs']])],axis=1) + + # harmonize derived volumes + MUSEDictDataFrame= self.datamodel.GetMUSEDictDataFrame() + muse_mappings = self.datamodel.GetDerivedMUSEMap() + for ROI in MUSEDictDataFrame[MUSEDictDataFrame['ROI_LEVEL']=='DERIVED']['ROI_INDEX']: + single_ROIs = muse_mappings.loc[ROI].replace('NaN',np.nan).dropna().astype(np.float) + single_ROIs = ['H_MUSE_Volume_%0d' % x for x in single_ROIs] + muse['H_MUSE_Volume_%d' % ROI] = muse[single_ROIs].sum(axis=1,skipna=False) + muse.drop(columns=['H_MUSE_Volume_702'], inplace=True) start_index = len(self.datamodel.harmonization_model['SITE_labels']) sex_icv_effect = np.dot(muse[['Sex','DLICV_baseline']].copy(), self.datamodel.harmonization_model['B_hat'][start_index:(start_index+2),:]) diff --git a/NiBAx/plugins/loadsave/MUSE_DerivedROIs_Mappings.csv b/NiBAx/plugins/loadsave/MUSE_DerivedROIs_Mappings.csv new file mode 100755 index 000000000..42c2d6eb0 --- /dev/null +++ b/NiBAx/plugins/loadsave/MUSE_DerivedROIs_Mappings.csv @@ -0,0 +1,259 @@ +702,ICV +701,TOTALBRAIN,4,11,23,30,31,32,35,36,37,38,39,40,41,47,48,49,50,51,52,55,56,57,58,59,60,61,62,71,72,73,75,76,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,100,101,102,103,104,105,106,107,108,109,112,113,114,115,116,117,118,119,120,121,122,123,124,125,128,129,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207 +601,GM,23,30,31,32,36,37,38,39,47,48,55,56,57,58,59,60,71,72,73,75,76,100,101,102,103,104,105,106,107,108,109,112,113,114,115,116,117,118,119,120,121,122,123,124,125,128,129,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207 +604,WM,40,41,61,62,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95 +606,GM_L,30,32,37,39,48,56,58,60,75,101,103,105,107,109,113,115,117,119,121,123,125,129,133,135,137,139,141,143,145,147,149,151,153,155,157,161,163,165,167,169,171,173,175,177,179,181,183,185,187,191,193,195,197,199,201,203,205,207 +607,WM_L,41,62,82,84,86,88,90,92,94 +613,GM_R,23,31,36,38,47,55,57,59,76,100,102,104,106,108,112,114,116,118,120,122,124,128,132,134,136,138,140,142,144,146,148,150,152,154,156,160,162,164,166,168,170,172,174,176,178,180,182,184,186,190,192,194,196,198,200,202,204,206 +614,WM_R,40,61,81,83,85,87,89,91,93 +501,CORPUS_CALLOSUM,95 +502,CEREBELLUM,38,39,40,41,71,72,73 +503,DEEP_WM_GM,23,30,31,32,36,37,47,48,55,56,57,58,59,60,75,76,89,90,91,92,93,94 +504,FRONTAL,81,82,102,103,104,105,112,113,118,119,120,121,124,125,136,137,140,141,142,143,146,147,150,151,152,153,162,163,164,165,172,173,174,175,178,179,182,183,186,187,190,191,192,193,204,205 +505,LIMBIC,100,101,116,117,138,139,166,167,170,171 +506,OCCIPITAL,83,84,108,109,114,115,128,129,134,135,144,145,156,157,160,161,196,197 +507,PARIETAL,85,86,106,107,148,149,168,169,176,177,194,195,198,199 +508,TEMPORAL,87,88,122,123,132,133,154,155,180,181,184,185,200,201,202,203,206,207 +509,VENTRICLE,4,11,49,50,51,52 +510,CEREBELLUM_L,39,41 +511,DEEP_WM_GM_L,30,32,37,48,56,58,60,75,90,92,94 +512,FRONTAL_L,82,103,105,113,119,121,125,137,141,143,147,151,153,163,165,173,175,179,183,187,191,193,205 +513,LIMBIC_L,101,117,139,167,171 +514,OCCIPITAL_L,84,109,115,129,135,145,157,161,197 +515,PARIETAL_L,86,107,149,169,177,195,199 +516,TEMPORAL_L,88,123,133,155,181,185,201,203,207 +517,VENTRICLE_L,50,52 +518,CEREBELLUM_R,38,40 +519,DEEP_WM_GM_R,23,31,36,47,55,57,59,76,89,91,93 +520,FRONTAL_R,81,102,104,112,118,120,124,136,140,142,146,150,152,162,164,172,174,178,182,186,190,192,204 +521,LIMBIC_R,100,116,138,166,170 +522,OCCIPITAL_R,83,108,114,128,134,144,156,160,196 +523,PARIETAL_R,85,106,148,168,176,194,198 +524,TEMPORAL_R,87,122,132,154,180,184,200,202,206 +525,VENTRICLE_R,49,51 +401,BASAL_GANGLIA,23,30,36,37,55,56,57,58 +402,DEEP_GM,59,60 +403,DEEP_WM,89,90,91,92,93,94 +404,FRONTAL_GM,102,103,104,105,112,113,118,119,120,121,124,125,136,137,140,141,142,143,146,147,150,151,152,153,162,163,164,165,172,173,174,175,178,179,182,183,186,187,190,191,192,193,204,205 +405,FRONTAL_WM,81,82 +406,LIMBIC_GM,100,101,116,117,138,139,166,167,170,171 +407,OCCIPITAL_GM,108,109,114,115,128,129,134,135,144,145,156,157,160,161,196,197 +408,OCCIPITAL_WM,83,84 +409,PARIETAL_GM,106,107,148,149,168,169,176,177,194,195,198,199 +410,PARIETAL_WM,85,86 +411,TEMPORAL_GM,122,123,132,133,154,155,180,181,184,185,200,201,202,203,206,207 +412,TEMPORAL_WM,87,88 +413,BASAL_GANGLIA_L,30,37,56,58 +414,DEEP_GM_L,60 +415,DEEP_WM_L,90,92,94 +416,FRONTAL_GM_L,103,105,113,119,121,125,137,141,143,147,151,153,163,165,173,175,179,183,187,191,193,205 +417,FRONTAL_WM_L,82 +418,LIMBIC_GM_L,101,117,139,167,171 +419,OCCIPITAL_GM_L,109,115,129,135,145,157,161,197 +420,OCCIPITAL_WM_L,84 +421,PARIETAL_GM_L,107,149,169,177,195,199 +422,PARIETAL_WM_L,86 +423,TEMPORAL_GM_L,123,133,155,181,185,201,203,207 +424,TEMPORAL_WM_L,88 +425,BASAL_GANGLIA_R,23,36,55,57 +426,DEEP_GM_R,59 +427,DEEP_WM_R,89,91,93 +428,FRONTAL_GM_R,102,104,112,118,120,124,136,140,142,146,150,152,162,164,172,174,178,182,186,190,192,204 +429,FRONTAL_WM_R,81 +430,LIMBIC_GM_R,100,116,138,166,170 +431,OCCIPITAL_GM_R,108,114,128,134,144,156,160,196 +432,OCCIPITAL_WM_R,83 +433,PARIETAL_GM_R,106,148,168,176,194,198 +434,PARIETAL_WM_R,85 +435,TEMPORAL_GM_R,122,132,154,180,184,200,202,206 +436,TEMPORAL_WM_R,87 +301,FRONTAL_INFERIOR_GM,104,105,136,137,146,147,178,179 +302,FRONTAL_INSULAR_GM,102,103,172,173 +303,FRONTAL_LATERAL_GM,120,121,142,143,162,163,164,165,182,183,190,191,204,205 +304,FRONTAL_MEDIAL_GM,124,125,140,141,150,151,152,153,186,187,192,193 +305,FRONTAL_OPERCULAR_GM,112,113,118,119,174,175 +306,LIMBIC_CINGULATE_GM,100,101,138,139,166,167 +307,LIMBIC_MEDIALTEMPORAL_GM,116,117,170,171 +308,OCCIPITAL_INFERIOR_GM,160,161 +309,OCCIPITAL_LATERAL_GM,128,129,144,145,156,157,196,197 +310,OCCIPITAL_MEDIAL_GM,108,109,114,115,134,135 +311,PARIETAL_LATERAL_GM,106,107,176,177,194,195,198,199 +312,PARIETAL_MEDIAL_GM,148,149,168,169 +313,TEMPORAL_INFERIOR_GM,122,123 +314,TEMPORAL_LATERAL_GM,132,133,154,155,200,201,202,203 +315,TEMPORAL_SUPRATEMPORAL_GM,180,181,184,185,206,207 +316,FRONTAL_INFERIOR_GM_L,105,137,147,179 +317,FRONTAL_INSULAR_GM_L,103,173 +318,FRONTAL_LATERAL_GM_L,121,143,163,165,183,191,205 +319,FRONTAL_MEDIAL_GM_L,125,141,151,153,187,193 +320,FRONTAL_OPERCULAR_GM_L,113,119,175 +321,LIMBIC_CINGULATE_GM_L,101,139,167 +322,LIMBIC_MEDIALTEMPORAL_GM_L,117,171 +323,OCCIPITAL_INFERIOR_GM_L,161 +324,OCCIPITAL_LATERAL_GM_L,129,145,157,197 +325,OCCIPITAL_MEDIAL_GM_L,109,115,135 +326,PARIETAL_LATERAL_GM_L,107,177,195,199 +327,PARIETAL_MEDIAL_GM_L,149,169 +328,TEMPORAL_INFERIOR_GM_L,123 +329,TEMPORAL_LATERAL_GM_L,133,155,201,203 +330,TEMPORAL_SUPRATEMPORAL_GM_L,181,185,207 +331,FRONTAL_INFERIOR_GM_R,104,136,146,178 +332,FRONTAL_INSULAR_GM_R,102,172 +333,FRONTAL_LATERAL_GM_R,120,142,162,164,182,190,204 +334,FRONTAL_MEDIAL_GM_R,124,140,150,152,186,192 +335,FRONTAL_OPERCULAR_GM_R,112,118,174 +336,LIMBIC_CINGULATE_GM_R,100,138,166 +337,LIMBIC_MEDIALTEMPORAL_GM_R,116,170 +338,OCCIPITAL_INFERIOR_GM_R,160 +339,OCCIPITAL_LATERAL_GM_R,128,144,156,196 +340,OCCIPITAL_MEDIAL_GM_R,108,114,134 +341,PARIETAL_LATERAL_GM_R,106,176,194,198 +342,PARIETAL_MEDIAL_GM_R,148,168 +343,TEMPORAL_INFERIOR_GM_R,122 +344,TEMPORAL_LATERAL_GM_R,132,154,200,202 +345,TEMPORAL_SUPRATEMPORAL_GM_R,180,184,206 +4,3rd Ventricle,4 +11,4th Ventricle,11 +23,Right Accumbens Area,23 +30,Left Accumbens Area,30 +31,Right Amygdala,31 +32,Left Amygdala,32 +35,Brain Stem,35 +36,Right Caudate,36 +37,Left Caudate,37 +38,Right Cerebellum Exterior,38 +39,Left Cerebellum Exterior,39 +40,Right Cerebellum White Matter,40 +41,Left Cerebellum White Matter,41 +47,Right Hippocampus,47 +48,Left Hippocampus,48 +49,Right Inf Lat Vent,49 +50,Left Inf Lat Vent,50 +51,Right Lateral Ventricle,51 +52,Left Lateral Ventricle,52 +55,Right Pallidum,55 +56,Left Pallidum,56 +57,Right Putamen,57 +58,Left Putamen,58 +59,Right Thalamus Proper,59 +60,Left Thalamus Proper,60 +61,Right Ventral DC,61 +62,Left Ventral DC,62 +71,Cerebellar Vermal Lobules I-V,71 +72,Cerebellar Vermal Lobules VI-VII,72 +73,Cerebellar Vermal Lobules VIII-X,73 +75,Left Basal Forebrain,75 +76,Right Basal Forebrain,76 +81,frontal lobe WM right,81 +82,frontal lobe WM left,82 +83,occipital lobe WM right,83 +84,occipital lobe WM left,84 +85,parietal lobe WM right,85 +86,parietal lobe WM left,86 +87,temporal lobe WM right,87 +88,temporal lobe WM left,88 +89,fornix right,89 +90,fornix left,90 +91,anterior limb of internal capsule right,91 +92,anterior limb of internal capsule left,92 +93,posterior limb of internal capsule inc. cerebral peduncle right,93 +94,posterior limb of internal capsule inc. cerebral peduncle left,94 +95,corpus callosum,95 +100,Right ACgG anterior cingulate gyrus,100 +101,Left ACgG anterior cingulate gyrus,101 +102,Right AIns anterior insula,102 +103,Left AIns anterior insula,103 +104,Right AOrG anterior orbital gyrus,104 +105,Left AOrG anterior orbital gyrus,105 +106,Right AnG angular gyrus,106 +107,Left AnG angular gyrus,107 +108,Right Calc calcarine cortex,108 +109,Left Calc calcarine cortex,109 +112,Right CO central operculum,112 +113,Left CO central operculum,113 +114,Right Cun cuneus,114 +115,Left Cun cuneus,115 +116,Right Ent entorhinal area,116 +117,Left Ent entorhinal area,117 +118,Right FO frontal operculum,118 +119,Left FO frontal operculum,119 +120,Right FRP frontal pole,120 +121,Left FRP frontal pole,121 +122,Right FuG fusiform gyrus,122 +123,Left FuG fusiform gyrus,123 +124,Right GRe gyrus rectus,124 +125,Left GRe gyrus rectus,125 +128,Right IOG inferior occipital gyrus,128 +129,Left IOG inferior occipital gyrus,129 +132,Right ITG inferior temporal gyrus,132 +133,Left ITG inferior temporal gyrus,133 +134,Right LiG lingual gyrus,134 +135,Left LiG lingual gyrus,135 +136,Right LOrG lateral orbital gyrus,136 +137,Left LOrG lateral orbital gyrus,137 +138,Right MCgG middle cingulate gyrus,138 +139,Left MCgG middle cingulate gyrus,139 +140,Right MFC medial frontal cortex,140 +141,Left MFC medial frontal cortex,141 +142,Right MFG middle frontal gyrus,142 +143,Left MFG middle frontal gyrus,143 +144,Right MOG middle occipital gyrus,144 +145,Left MOG middle occipital gyrus,145 +146,Right MOrG medial orbital gyrus,146 +147,Left MOrG medial orbital gyrus,147 +148,Right MPoG postcentral gyrus medial segment,148 +149,Left MPoG postcentral gyrus medial segment,149 +150,Right MPrG precentral gyrus medial segment,150 +151,Left MPrG precentral gyrus medial segment,151 +152,Right MSFG superior frontal gyrus medial segment,152 +153,Left MSFG superior frontal gyrus medial segment,153 +154,Right MTG middle temporal gyrus,154 +155,Left MTG middle temporal gyrus,155 +156,Right OCP occipital pole,156 +157,Left OCP occipital pole,157 +160,Right OFuG occipital fusiform gyrus,160 +161,Left OFuG occipital fusiform gyrus,161 +162,Right OpIFG opercular part of the inferior frontal gyrus,162 +163,Left OpIFG opercular part of the inferior frontal gyrus,163 +164,Right OrIFG orbital part of the inferior frontal gyrus,164 +165,Left OrIFG orbital part of the inferior frontal gyrus,165 +166,Right PCgG posterior cingulate gyrus,166 +167,Left PCgG posterior cingulate gyrus,167 +168,Right PCu precuneus,168 +169,Left PCu precuneus,169 +170,Right PHG parahippocampal gyrus,170 +171,Left PHG parahippocampal gyrus,171 +172,Right PIns posterior insula,172 +173,Left PIns posterior insula,173 +174,Right PO parietal operculum,174 +175,Left PO parietal operculum,175 +176,Right PoG postcentral gyrus,176 +177,Left PoG postcentral gyrus,177 +178,Right POrG posterior orbital gyrus,178 +179,Left POrG posterior orbital gyrus,179 +180,Right PP planum polare,180 +181,Left PP planum polare,181 +182,Right PrG precentral gyrus,182 +183,Left PrG precentral gyrus,183 +184,Right PT planum temporale,184 +185,Left PT planum temporale,185 +186,Right SCA subcallosal area,186 +187,Left SCA subcallosal area,187 +190,Right SFG superior frontal gyrus,190 +191,Left SFG superior frontal gyrus,191 +192,Right SMC supplementary motor cortex,192 +193,Left SMC supplementary motor cortex,193 +194,Right SMG supramarginal gyrus,194 +195,Left SMG supramarginal gyrus,195 +196,Right SOG superior occipital gyrus,196 +197,Left SOG superior occipital gyrus,197 +198,Right SPL superior parietal lobule,198 +199,Left SPL superior parietal lobule,199 +200,Right STG superior temporal gyrus,200 +201,Left STG superior temporal gyrus,201 +202,Right TMP temporal pole,202 +203,Left TMP temporal pole,203 +204,Right TrIFG triangular part of the inferior frontal gyrus,204 +205,Left TrIFG triangular part of the inferior frontal gyrus,205 +206,Right TTG transverse temporal gyrus,206 +207,Left TTG transverse temporal gyrus,207 diff --git a/NiBAx/plugins/loadsave/dataio.py b/NiBAx/plugins/loadsave/dataio.py index 5075e334f..c5fa13624 100644 --- a/NiBAx/plugins/loadsave/dataio.py +++ b/NiBAx/plugins/loadsave/dataio.py @@ -36,9 +36,21 @@ def ReadMUSEDictionary(self): # e.g. ID to name; MUSE_Volume_48 -> Hippocampus right MUSEDictIDtoNAME = dict(zip(MUSEDict['ROI_COL'], MUSEDict['ROI_NAME'])) + MUSEDictDataFrame = MUSEDict + logger.info('MUSE dictionary read from file: %s', MUSEDictfile) - return MUSEDictNAMEtoID, MUSEDictIDtoNAME + return MUSEDictNAMEtoID, MUSEDictIDtoNAME, MUSEDictDataFrame + + def ReadDerivedMUSEMap(self): + # Load MUSE dictionary file + DerivedMapfile = os.path.join(os.path.dirname(__file__), 'MUSE_DerivedROIs_Mappings.csv') + DerivedMUSEMap = pd.read_csv(DerivedMapfile, + header=None, engine='python').reset_index().rename(columns={'level_0':'ROI_INDEX','level_1':'ROI_NAME'}).set_index('ROI_INDEX').drop(columns=['ROI_NAME']) + + logger.info('Derived MUSE dictionary read from file: %s', DerivedMapfile) + + return DerivedMUSEMap def ReadSPAREModel(self, filename): diff --git a/NiBAx/plugins/loadsave/loadsave.py b/NiBAx/plugins/loadsave/loadsave.py index 200a5f67e..535026a7d 100644 --- a/NiBAx/plugins/loadsave/loadsave.py +++ b/NiBAx/plugins/loadsave/loadsave.py @@ -107,8 +107,12 @@ def ReadData(self,filename): logger.info('New data read from file: %s', filename) #also read MUSE dictionary - MUSEDictNAMEtoID, MUSEDictIDtoNAME = dio.ReadMUSEDictionary() - self.datamodel.SetMUSEDictionaries(MUSEDictNAMEtoID, MUSEDictIDtoNAME) + MUSEDictNAMEtoID, MUSEDictIDtoNAME, MUSEDictDataFrame = dio.ReadMUSEDictionary() + self.datamodel.SetMUSEDictionaries(MUSEDictNAMEtoID, MUSEDictIDtoNAME,MUSEDictDataFrame) + + #also read Derived MUSE dictionary + DerivedMUSEMap = dio.ReadDerivedMUSEMap() + self.datamodel.SetDerivedMUSEMap(DerivedMUSEMap) #set data in model self.datamodel.SetDataFilePath(filename)