def test_statsmodel_to_df(func): func = getattr(smf, func) np.random.seed(0) amplitude = 1.432 df_cha = pd.DataFrame() for n in range(5): raw = simulate_nirs_raw(sfreq=3., amplitude=amplitude, sig_dur=300., stim_dur=5., isi_min=15., isi_max=45.) raw._data += np.random.normal(0, np.sqrt(1e-12), raw._data.shape) design_matrix = make_first_level_design_matrix(raw, stim_dur=5.0) glm_est = run_glm(raw, design_matrix) with pytest.warns(RuntimeWarning, match='Non standard source detect'): cha = glm_est.to_dataframe() cha["ID"] = '%02d' % n df_cha = pd.concat([df_cha, cha], ignore_index=True) df_cha["theta"] = df_cha["theta"] * 1.0e6 roi_model = func("theta ~ -1 + Condition", df_cha, groups=df_cha["ID"]).fit() df = statsmodels_to_results(roi_model) assert type(df) == pd.DataFrame assert_allclose(df["Coef."]["Condition[A]"], amplitude, rtol=0.1) assert df["Significant"]["Condition[A]"] assert df.shape == (8, 8) roi_model = smf.rlm("theta ~ -1 + Condition", df_cha, groups=df_cha["ID"]).fit() df = statsmodels_to_results(roi_model) assert type(df) == pd.DataFrame assert_allclose(df["Coef."]["Condition[A]"], amplitude, rtol=0.1) assert df["Significant"]["Condition[A]"] assert df.shape == (8, 8)
# Create path to file based on experiment info bids_path = dataset.update(subject=sub) # Analyse data and return both ROI and channel results raw_haemo, channel = individual_analysis(bids_path, sub) # Append individual results to all participants df_cha = pd.concat([df_cha, channel], ignore_index=True) ch_summary = df_cha.query("Condition in ['Tapping_Right']") assert len(ch_summary) ch_summary = ch_summary.query("Chroma in ['hbo']") ch_model = smf.mixedlm("theta ~ -1 + ch_name", ch_summary, groups=ch_summary["ID"]).fit(method='nm') model_df = statsmodels_to_results(ch_model, order=raw_haemo.copy().pick("hbo").ch_names) # %% # Plot surface projection of GLM results # -------------------------------------- # # Finally, we can project the GLM results from each channel to the nearest cortical surface # and overlay the sensor positions and two different regions of interest. # In this example we also highlight the premotor cortex and auditory association cortex # in green and blue respectively. # Plot the projection and sensor locations brain = plot_glm_surface_projection(raw_haemo.copy().pick("hbo"), model_df, colorbar=True) brain.add_sensors(raw_haemo.info,
# # Now we can summarise the output of the second level model. # This figure shows that the control condition has small responses that # are not significantly different to zero for both HbO # and HbR in both hemispheres. # Whereas clear significant responses are show for the two tapping conditions. # We also observe the the tapping response is # larger in the contralateral hemisphere. # Filled symbols represent HbO, unfilled symbols represent HbR. # Regenerate the results from the original group model above grp_results = df_roi.query("Condition in ['Control','Tapping_Left', 'Tapping_Right']") roi_model = smf.mixedlm("theta ~ -1 + ROI:Condition:Chroma", grp_results, groups=grp_results["ID"]).fit(method='nm') df = statsmodels_to_results(roi_model) sns.catplot(x="Condition", y="Coef.", hue="ROI", data=df.query("Chroma == 'hbo'"), ci=None, palette="muted", height=4, s=10) # %% # Group topographic visualisation # ------------------------------- # # We can also view the topographic representation of the data # (rather than the ROI summary above). # Here we just plot the oxyhaemoglobin for the two tapping conditions. # First we compute the mixed effects model for each channel (rather # than region of interest as above). # Then we pass these results to the topomap function.
# The model is summarised below, and is not displayed here. # You can display the model output using: lme.summary() # %% # Summarise group-level findings # --------------------------------------------------------------------- # # Next the values from the model above are extracted into a dataframe for # more convenient analysis below. # A subset of the results is displayed, illustrating the estimated coefficients # for oxyhaemoglobin (HbO) for the right hand tapping condition. # Create a dataframe from LME model for plotting below df_sum = statsmodels_to_results(lme) df_sum["delay"] = [int(n) for n in df_sum["delay"]] df_sum = df_sum.sort_values('delay') # Print the result for the oxyhaemoglobin data in the tapping condition df_sum.query("TidyCond in ['Tapping']").query("Chroma in ['hbo']") # %% # Note in the output above that there are 10 FIR delays. # A coefficient estimate has been calculated for each delay. # These coefficients must be multiplied by the FIR function to obtain the # morphology of the fNIRS response. # %% # Plot the response from a single condition # ---------------------------------------------------------------------
############################################################################### # Visualise group results # ----------------------- # # Now we can summarise the output of the second level model. # This figure shows that the control condition has small responses that # are not significantly different to zero for both HbO # and HbR in both hemispheres. # Whereas clear significant responses are show for the two tapping conditions. # We also observe the the tapping response is # larger in the contralateral hemisphere. # Filled symbols represent HbO, unfilled symbols represent HbR. df = statsmodels_to_results(roi_model) ggplot(df.query("Chroma == 'hbo'"), aes(x='Condition', y='Coef.', color='Significant', shape='ROI')) \ + geom_hline(y_intercept=0, linetype="dashed", size=1) \ + geom_point(size=5) \ + scale_shape_manual(values=[16, 17]) \ + ggsize(800, 300) \ + geom_point(data=df.query("Chroma == 'hbr'") .query("ROI == 'Left_Hemisphere'"), size=5, shape=1) \ + geom_point(data=df.query("Chroma == 'hbr'") .query("ROI == 'Right_Hemisphere'"), size=5, shape=2) ############################################################################### # Group topographic visualisation