def load_bids_events(layout, subject): '''Create a design_matrix instance from BIDS event file''' tr = layout.get_tr() n_tr = nib.load(layout.get(subject=subject, scope='raw', suffix='bold')[0].path).shape[-1] onsets = pd.read_csv(layout.get(subject=subject, suffix='events')[0].path, sep='\t') onsets.columns = ['Onset', 'Duration', 'Stim'] return onsets_to_dm(onsets, sampling_freq=1/tr, run_length=n_tr)
def get_trialtype_pain_regressors(self,nifti_data,onset_file): print("importing nifti") #import the nifti if (os.path.isfile(nifti_data + "nltoolstandard.nii.gz")): msmrl1 = Brain_Data( nifti_data + "nltoolstandard.nii.gz") else: msmrl1 = Brain_Data( nifti_data + ".nii.gz") msmrl1.write(nifti_data + "nltoolstandard.nii.gz") #preprocess the nifti? print("importing onsets") #import the onset onsets = onsets_to_dm( onset_file, TR=2, runLength=msmrl1.shape()[0] ) #process the onset files # onsets.sampling_rate=2 onsets_convolved=onsets.convolve() for c in onsets_convolved.columns: if sum(onsets_convolved.ix[:, c]) <= 0: print('deleting '+ str(c)) del onsets_convolved[c] onsets_convolved['linearterm']=range(1,361) onsets_convolved['quadraticterm']=[pow(x,2) for x in onsets_convolved['linearterm']] onsets_convolved['cubicterm']=[pow(x,3) for x in onsets_convolved['linearterm']] onsets_convolved['ones']=[1]*360 msmrl1.X=onsets_convolved print("convolved onsets; regressing...") #regress regression=msmrl1.regress() print("Regressing; calculating similarity...") msm_predicted_pain = regression['beta'].similarity(self.stats['weight_map'], 'dot_product') onset_colnames = onsets_convolved.columns.tolist() msm_predicted_pain_dict={} for i, b in enumerate(msm_predicted_pain): msm_predicted_pain_dict[onset_colnames[i]] = b return msm_predicted_pain_dict
def get_trialtype_pain_regressors(self, nifti_data, onset_file): print("importing nifti") #import the nifti #load the nltools prepped file if it's available. if (os.path.isfile(nifti_data + "nltoolstandard.nii.gz")): msmrl1 = Brain_Data(nifti_data + "nltoolstandard.nii.gz") else: #but if it's not; no worries; just load the original one. msmrl1 = Brain_Data(nifti_data + ".nii.gz") msmrl1.write(nifti_data + "nltoolstandard.nii.gz") #I want to standardize globally; this will preserve the relative strengths of each time point #and preserve the relative activity at each voxel. #and let's use the mean standard deviation across all the images. #msmrl1.data = msmrl1.data - np.tile(msmrl1.mean().mean(),msmrl1.data.shape) #msmrl1.data = msmrl1.data / np.tile(np.std(msmrl1.data,axis=1).mean(),msmrl1.data.shape) # OR we could apply the standardization to the OUTPUT. #grand_mean=msmrl1.mean().mean() #grand_sd=np.std(msmrl1.data,axis=1).mean() #preprocess the nifti? print("importing onsets") #import the onset onsets = onsets_to_dm(onset_file, TR=2, runLength=msmrl1.shape()[0]) #process the onset files # onsets.sampling_rate = 2 onsets_convolved = onsets.convolve() #delete columns with no information in them. for c in onsets_convolved.columns: if sum(onsets_convolved.ix[:, c]) <= 0: print('deleting ' + str(c)) del onsets_convolved[c] rowcount = onsets_convolved.__len__() if rowcount != 360: warnings.warn( "Just a friendly FYI: expected number of rows is 360 but this subject had " + str(rowcount) + ". Probably this subject got cut off the task half-way through." ) onsets_convolved['linearterm'] = range(1, rowcount + 1) onsets_convolved['quadraticterm'] = [ pow(x, 2) for x in onsets_convolved['linearterm'] ] onsets_convolved['cubicterm'] = [ pow(x, 3) for x in onsets_convolved['linearterm'] ] onsets_convolved['ones'] = [1] * rowcount msmrl1.X = onsets_convolved print("convolved onsets; regressing...") #regress the file on each of the onsets. So then, when we compare similarity to the regression, we'll be getting the #regression to the each event, not to each TR. regression = msmrl1.regress() print("Regressing; calculating similarity to the pain map from " + self.decoder_origin + "...") msm_predicted_pain = regression['beta'].similarity( self.decoder, 'dot_product') msm_predicted_pain_scaled = msm_predicted_pain - msmrl1.data.std() onset_colnames = onsets_convolved.columns.tolist() msm_predicted_pain_dict = {} for i, b in enumerate(msm_predicted_pain_scaled): msm_predicted_pain_dict[onset_colnames[i]] = b return msm_predicted_pain_dict
######################################################################### # Load and Manipulate an Onsets File # ------------------------------------ # # Nltools provides basic file-reading support for 2 or 3 column formatted onset files. # Users can look at the onsets_to_dm function() as a template to build more complex file readers if desired or to see additional features. # Here we simply point to an onsetfile where each event lasted exactly 1 TR, provide some basic experiment metadata, add an intercept, and get back a basic design matrix. from nltools.utils import get_resource_path from nltools.file_reader import onsets_to_dm from nltools.data import Design_Matrix import os onsetsFile = os.path.join(get_resource_path(),'onsets_example.txt') dm = onsets_to_dm(onsetsFile, TR=2.0, runLength=160, sort=True, addIntercept=True) ######################################################################### # The class stores basic meta data including convolution functions (default is glover HRF) and whether convolution has been performed, or whether the model contains a constant term. print(dm.info()) ######################################################################### # We can easily visualize the design matrix too dm.heatmap() ######################################################################### # We can also add nth order polynomial terms. In this case we'll add a linear term to capture linear trends. # By default the class will add all lower-order polynomials, but is smart enough to realize we already have a constant so it won't be duplicated.
# Creating a Design Matrix from an onsets file # ******************************************** # # Nltools provides basic file-reading support for 2 or 3 column formatted onset files. Users can look at the onsets_to_dm function as a template to build more complex file readers if desired or to see additional features. Nltools includes an example onsets file where each event lasted exactly 1 TR and TR = 2s. Lets use that to create a design matrix with an intercept and linear trend from nltools.utils import get_resource_path from nltools.file_reader import onsets_to_dm from nltools.data import Design_Matrix import os TR = 2.0 sampling_freq = 1. / TR onsetsFile = os.path.join(get_resource_path(), 'onsets_example.txt') dm = onsets_to_dm(onsetsFile, sampling_freq=sampling_freq, run_length=160, sort=True, add_poly=1) dm.heatmap() ######################################################################### # Creating a Design Matrix from a generic csv file # ************************************************ # # Alternatively you can read a generic csv file and transform it into a Design Matrix using pandas file reading capability. Here we'll read in an example covariates file that contains the output of motion realignment estimated during a fMRI preprocessing pipeline. import pandas as pd covariatesFile = os.path.join(get_resource_path(), 'covariates_example.csv') cov = pd.read_csv(covariatesFile) cov = Design_Matrix(cov, sampling_freq=sampling_freq)
def import_and_convolve(self, nifti_data, onset_file, data_mask=None, motion_regressors=None): print("importing nifti") # import the nifti # load the nltools prepped file if it's available. if (os.path.isfile(nifti_data + self.data_fmri_space + ".nii.gz")): msmrl1 = Brain_Data(nifti_data + self.data_fmri_space + ".nii.gz", mask=data_mask) else: # but if it's not; no worries; just load the original one. msmrl1 = Brain_Data(nifti_data + ".nii.gz", mask=data_mask) msmrl1.write(nifti_data + self.data_fmri_space + ".nii.gz") # I want to standardize globally; this will preserve the relative strengths of each time point # and preserve the relative activity at each voxel. # and let's use the mean standard deviation across all the images. # msmrl1.data = msmrl1.data - np.tile(msmrl1.mean().mean(),msmrl1.data.shape) # msmrl1.data = msmrl1.data / np.tile(np.std(msmrl1.data,axis=1).mean(),msmrl1.data.shape) # OR we could apply the standardization to the OUTPUT. # grand_mean=msmrl1.mean().mean() # grand_sd=np.std(msmrl1.data,axis=1).mean() # preprocess the nifti? print("importing onsets") # import the onset onsets = onsets_to_dm(onset_file, TR=2, runLength=msmrl1.shape()[0]) # process the onset files # onsets.sampling_rate = 2 onsets_convolved = onsets.convolve() # delete columns with no information in them. for c in onsets_convolved.columns: if sum(onsets_convolved.ix[:, c]) <= 0: print('deleting ' + str(c)) del onsets_convolved[c] rowcount = onsets_convolved.__len__() if rowcount != 360: warnings.warn( "Just a friendly FYI: expected number of rows is 360 but this subject had " + str(rowcount) + ". Probably this subject got cut off the task half-way through." ) onsets_convolved['linearterm'] = range(1, rowcount + 1) onsets_convolved['quadraticterm'] = [ pow(x, 2) for x in onsets_convolved['linearterm'] ] onsets_convolved['cubicterm'] = [ pow(x, 3) for x in onsets_convolved['linearterm'] ] onsets_convolved['ones'] = [1] * rowcount if (motion_regressors is not None): onsets_convolved = pandas.concat( [onsets_convolved, motion_regressors], axis=1) msmrl1.X = onsets_convolved return msmrl1
# delim_whitespace=True, header=None, comment='#', # names=["Index","SegId","NVoxels","Volume_mm3","StructName","Mean","StdDev","Min","Max","Range"]) # great and now add the labels to the summary file. # sub_r_m_roi_sum_dt=sub_r_m_roi_sum_dt.merge(freesurfer_LUT_df[["RegionId","Label"]],how='left',left_on='SegId',right_on='RegionId') colnames = sub_r_m_roi_dt.columns #onset_file='/Users/benjaminsmith/Dropbox/joint-modeling/data/runfiledetail20171020T012224_s214_reward_r1.txt' if (os.path.isfile(onset_file)): print('we have a match; ' + onset_file) print("importing onsets") # import the onset onsets = onsets_to_dm( onset_file, TR=2, runLength=sub_r_m_roi_dt.shape[ 0] #we don't know this for sure. But in this instance it doesn't matter. # import the run_length data from the data. ) onsets.sampling_rate = 2 onsets_convolved = onsets.convolve() #removing columns with nothing in them. for c in onsets_convolved.columns: if sum(onsets_convolved.loc[:, c]) <= 0: print('deleting ' + str(c)) del onsets_convolved[c] rowcount = onsets_convolved.__len__()
def test_onsets_to_dm(): fpath = os.path.join(get_resource_path(), "onsets_example.txt") data = pd.read_csv(os.path.join(get_resource_path(), "onsets_example.txt")) sampling_freq = 0.5 run_length = 1364 Duration = 10 TR = 1 / sampling_freq # Two-column # Test loading from a file dm = onsets_to_dm(fpath, sampling_freq, run_length) assert isinstance(dm, Design_Matrix) # Check it has run_length rows and nStim columns assert dm.shape == (run_length, data.Stim.nunique()) # Get the unique number of presentations of each Stim from the original file stim_counts = data.Stim.value_counts(sort=False)[dm.columns] # Check there are only as many onsets as occurences of each Stim np.allclose(stim_counts.values, dm.sum().values) # Three-column with loading from dataframe data["Duration"] = Duration dm = onsets_to_dm(data, sampling_freq, run_length) # Check it has run_length rows and nStim columns assert dm.shape == (run_length, data.Stim.nunique()) # Because timing varies in seconds and isn't TR-locked each stimulus should last at Duration/TR number of TRs and at most Duration/TR + 1 TRs # Check that the total number of TRs for each stimulus >= 1 + (Duration/TR) and <= 1 + (Duration/TR + 1) onsets = dm.sum().values durations = data.groupby("Stim").Duration.mean().values for o, c, d in zip(onsets, stim_counts, durations): assert c * (d / TR) <= o <= c * ((d / TR) + 1) # Multiple onsets dm = onsets_to_dm([data, data], sampling_freq, run_length) # Check it has run_length rows and nStim columns assert dm.shape == (run_length * 2, data.Stim.nunique()) # Multiple onsets with polynomials auto-added dm = onsets_to_dm([data, data], sampling_freq, run_length, add_poly=2) assert dm.shape == (run_length * 2, data.Stim.nunique() + (3 * 2)) dm = onsets_to_dm([data, data], sampling_freq, run_length, add_poly=2, keep_separate=False) assert dm.shape == (run_length * 2, data.Stim.nunique() + 3) # Three-column from file with variable durations data = pd.read_csv( os.path.join(get_resource_path(), "onsets_example_with_dur.txt")) run_length = 472 dm = onsets_to_dm(data, sampling_freq, run_length) assert dm.shape == (run_length, data.Stim.nunique()) onsets = dm.sum().values stim_counts = data.Stim.value_counts().values durations = data.groupby("Stim").Duration.mean().values for o, c, d in zip(onsets, stim_counts, durations): assert c * (d / TR) <= o <= c * ((d / TR) + 1)
msm_predicted_pain=msmrl1_detrended.similarity(stats['weight_map'],'correlation')# + stats['intercept'] msm_dat = pd.DataFrame(data= {'PredictedPain':msm_predicted_pain, 'Timepoint':msmrl1_detrended.X['TimePoint']}) with sns.plotting_context(context='paper',font_scale=2): sns.factorplot(data=msm_dat ,x='Timepoint',y='PredictedPain') #file should have headers: Stim,Onset,Duration #Onset and Duration should both be set in seconds. onsets=onsets_to_dm( sub113_onset_file, TR=2, runLength=msmrl1.shape()[0] ) onsets.sampling_rate=2 #I believe there is a bug in the code here which means we have to set Sampling Rate twice. onsets_convolved=onsets.convolve() list(onsets_convolved) #graph the pain activity against the pain regressor msm_dat = pd.DataFrame(data= {'PredictedPain':msm_predicted_pain, 'Timepoint':msmrl1_detrended.X['TimePoint']}) with sns.plotting_context(context='paper',font_scale=2): sns.factorplot(data=msm_dat ,x='Timepoint',y='PredictedPain')
dm_with_cosine = dm.add_dct_basis(duration=5) print(dm_with_cosine.details()) ######################################################################### # Load and Manipulate an Onsets File # ----------------------------------- # # Nltools provides basic file-reading support for 2 or 3 column formatted onset files. Users can look at the onsets_to_dm function as a template to build more complex file readers if desired or to see additional features. Nltools includes an example onsets file where each event lasted exactly 1 TR. Lets use that to create a design matrix with an intercept and linear trend from nltools.utils import get_resource_path from nltools.file_reader import onsets_to_dm from nltools.data import Design_Matrix import os onsetsFile = os.path.join(get_resource_path(),'onsets_example.txt') dm = onsets_to_dm(onsetsFile, TR=2.0, runLength=160, sort=True,add_poly=1) dm.heatmap() ######################################################################### # Design Matrix makes it easy to perform convolution and will auto-ignore all columns that are consider polynomials. By default it will use the one-parameter glover_hrf kernel (see nipy for details). However, any kernel can be passed as an argument, including a list of different kernels for highly flexible convolution across many types of data (e.g. SCR). dm = dm.convolve() print(dm.details()) dm.heatmap() ######################################################################### # Load and Z-score a Covariates File # ---------------------------------- # # Now we're going to handle a covariates file that's been generated by a preprocessing routine. First we'll read in the text file using pandas and convert it to a design matrix.