Source code for ramutils.pipelines.aggregated_report

""" Pipeline for creating aggregated stim reports """

from ramutils.tasks import *
from ramutils.events import find_subjects
from ramutils.log import get_logger
from .hooks import PipelineCallback

logger = get_logger()


[docs]def make_aggregated_report(subjects=None, experiments=None, sessions=None, fit_model=True, paths=None, pipeline_name="aggregate"): """ Build an aggregated stim session report This pipeline should be used for combining data across stim experiment sessions into a single report. The concept of a "joint report" already exists for record-only sessions and can be generated using the `ramutils.pipelines.report.make_report` pipeline. In the future, a more sensible approach would be to have joint reports for both stim sessions and record-only sessions be built using the same pipeline. Keyword Arguments ----------------- subjects: list or None The set of subjects to include when building the report. If None and one or more experiments are specified, then the subjects who completed each experiment will be identified automatically. experiments: list or None The set of experiments to include when building the report. This is primarily useful for combining FR with CatFR session data, effectively a joint report for stim sessions. However, it is also possible to combine across experiment series. For example, a joint report could be built that combines FR3, catFR3, FR5, and catFR5. This is possible because the report templates for these experiments are identical. It is not, however, possible to combine stim reports across dissimilar reports. For example, it would not make sense to build an aggregate report combining PS5 with catFR5 since those use completely different templates. sessions: list or None The set of sessions to include. This parameter can only be used if a single subject and a single experiment have been provided. The main use case is for generating a stim report that excludes 1 or more sessions. We do not currently support the ability to combine the sessions paramter with more than one subject or more than one experiment. This could be a future enhancement. For example, it may be useful to be able to generate an aggregated report of all the first sessions of a particular experiment type, or all first sessions for a particular subject. fit_model: bool If true, the a Bayesian hierachical multilvel model will be fit using the data combined across the requested subjects, experiments, and sessions. This process can be very slow as the number of sessions increases, so it is False by default. The main use case if for building a stim report that aggregates over the sessions that a particular subject completed of a particular experiment. paths: `ramutils.parameters.FilePaths` Helper class for setting up the set of paths that will be necessary for loading existing results pipeline_name : str Name to use for status updates. """ if experiments is not None: for i, experiment in enumerate(experiments): if 'Cat' in experiment: experiments[i] = experiments[i].replace('Cat', 'cat') all_classifier_evaluation_results, all_session_summaries, all_math_summaries, target_selection_table = [], [], [], None # All subjects completing a given experiment(s) if subjects is None and experiments is not None: for experiment in experiments: exp_subjects = find_subjects(experiment, paths.root) for subject in exp_subjects: pre_built_results = load_existing_results(subject, experiment, sessions, True, paths.data_db, joint_report=False, rootdir=paths.root).compute() if all([val is None for val in [pre_built_results['classifier_evaluation_results'], pre_built_results['session_summaries'], pre_built_results['math_summaries']]]): logger.warning('Unable to find underlying data for {}, experiment {}'.format( subject, experiment)) continue all_classifier_evaluation_results.extend( pre_built_results['classifier_evaluation_results']) all_session_summaries.extend( pre_built_results['session_summaries']) all_math_summaries.extend(pre_built_results['math_summaries']) subject = 'combined' experiment = "_".join(experiments) # Set of subject(s) completing a specific set of experiment(s) elif subjects is not None and experiments is not None and sessions is None: for subject in subjects: for experiment in experiments: pre_built_results = load_existing_results(subject, experiment, sessions, True, paths.data_db, joint_report=False, rootdir=paths.root).compute() # Check if only None values were returned. Processing will continue # undeterred if all([val is None for val in [pre_built_results['classifier_evaluation_results'], pre_built_results['session_summaries'], pre_built_results['math_summaries']]]): logger.warning('Unable to find underlying data for {}, experiment {}'.format( subject, experiment)) continue all_classifier_evaluation_results.extend( pre_built_results['classifier_evaluation_results']) all_session_summaries.extend( pre_built_results['session_summaries']) all_math_summaries.extend(pre_built_results['math_summaries']) subject = '_'.join(subjects) experiment = "_".join(experiments) # Single subject/experiment and a subset of sessions elif subjects is not None and experiments is not None and sessions is not None: if len(subjects) > 1 or len(experiments) > 1: raise RuntimeError( "When specifying sessions, only single subject and experiment are allowed") subject = subjects[0] experiment = experiments[0] pre_built_results = load_existing_results(subject, experiment, sessions, True, paths.data_db, joint_report=False, rootdir=paths.root).compute() if all([val is None for val in [pre_built_results['classifier_evaluation_results'], pre_built_results['session_summaries'], pre_built_results['math_summaries']]]): logger.warning('Unable to find underlying data for {}, experiment {}'.format( subject, experiment)) all_classifier_evaluation_results.extend( pre_built_results['classifier_evaluation_results']) all_session_summaries.extend(pre_built_results['session_summaries']) all_math_summaries.extend(pre_built_results['math_summaries']) else: raise RuntimeError( 'The requested type of aggregation is not currently supported') if fit_model: # Fit model and save resulting images. subject/experiment do not really matter since the model is the same # at least for now hmm_results = estimate_effects_of_stim( subject, 'FR3', all_session_summaries) output = save_all_output(subject, experiment, [], [], [], paths.data_db, behavioral_results=hmm_results, agg_report=True) else: output = None report = build_static_report(subject, experiment, all_session_summaries, all_math_summaries, target_selection_table, all_classifier_evaluation_results, paths.dest, hmm_results=output, save=True, aggregated_report=True) with PipelineCallback(pipeline_name): return report.compute()