예제 #1
0
    def bound_data_spec(self, name):
        """
        Returns either the dataset/field that has been passed to the study
        __init__ matching the dataset/field name provided or the derived
        dataset that is to be generated using the pipeline associated
        with the generated data_spec

        Parameters
        ----------
        name : Str
            Name of the data spec to the find the corresponding primary
            dataset or derived dataset to be generated
        """
        if isinstance(name, BaseDatum):
            name = name.name
        try:
            data = self._inputs[name]
        except KeyError:
            try:
                data = self._bound_specs[name]
            except KeyError:
                if name in self._data_specs:
                    raise NiAnalysisMissingDataException(
                        "Acquired (i.e. non-generated) dataset '{}' "
                        "was not supplied when the study '{}' was "
                        "initiated".format(name, self.name))
                else:
                    raise NiAnalysisNameError(
                        name, "'{}' is not a recognised dataset_spec name "
                        "for {} studies.".format(name,
                                                 self.__class__.__name__))
        return data
예제 #2
0
 def option_spec(cls, name):
     try:
         return cls._option_specs[name]
     except KeyError:
         raise NiAnalysisNameError(
             name, "No option spec named '{}' in {} (available: "
             "'{}')".format(name, cls.__name__,
                            "', '".join(cls._option_specs.keys())))
예제 #3
0
파일: multi.py 프로젝트: sforazz/arcana
 def strip_prefix(self, name):
     if not name.startswith(self.name + '_'):
         raise NiAnalysisNameError(
             name,
             "'{}' is not explicitly provided in SubStudySpec "
             "name map and doesn't start with the SubStudySpec "
             "prefix '{}_'".format(name, self.name))
     return name[len(self.name) + 1:]
예제 #4
0
파일: multi.py 프로젝트: sforazz/arcana
 def sub_study_spec(cls, name):
     try:
         return cls._sub_study_specs[name]
     except KeyError:
         raise NiAnalysisNameError(
             name,
             "'{}' not found in sub-studes ('{}')"
             .format(name, "', '".join(cls._sub_study_specs)))
예제 #5
0
파일: multi.py 프로젝트: sforazz/arcana
 def sub_study(self, name):
     try:
         return self._sub_studies[name]
     except KeyError:
         raise NiAnalysisNameError(
             name,
             "'{}' not found in sub-studes ('{}')"
             .format(name, "', '".join(self._sub_studies)))
예제 #6
0
 def _get_option(self, name):
     try:
         option = self._options[name]
     except KeyError:
         try:
             option = self._option_specs[name]
         except KeyError:
             raise NiAnalysisNameError(
                 name,
                 "{} does not have an option named '{}'".format(self, name))
     return option
예제 #7
0
파일: multi.py 프로젝트: sforazz/arcana
 def inverse_map(self, name):
     try:
         return self._inv_map[name]
     except KeyError:
         if name not in chain(self.study_class.data_spec_names(),
                              self.study_class.option_spec_names()):
             raise NiAnalysisNameError(
                 name,
                 "'{}' doesn't match any datasets, fields or options"
                 " in the study class {} ('{}')"
                 .format(name, self.study_class.__name__,
                         "', '".join(
                             self.study_class.data_spec_names())))
         return self.apply_prefix(name)
예제 #8
0
    def add_input(self, input_name):
        """
        Adds a new input to the pipeline. Useful if extending a pipeline in a
        derived Study class

        Parameters
        ----------
        input_name : str
            Name of the input to add to the pipeline
        """
        if input_name not in self.study.data_spec_names():
            raise NiAnalysisNameError(
                input_name,
                "'{}' is not a name of a specified dataset or field in {} "
                "Study".format(input_name, self.study.name))
        self._inputs.append(input_name)
예제 #9
0
파일: multi.py 프로젝트: sforazz/arcana
    def __init__(self, name, archive, runner, inputs, options=None,
                 **kwargs):
        options = [] if options is None else options
        try:
            if not issubclass(type(self).__dict__['__metaclass__'],
                              MultiStudyMetaClass):
                raise KeyError
        except KeyError:
            raise NiAnalysisUsageError(
                "Need to set MultiStudyMetaClass (or sub-class) as "
                "the metaclass of all classes derived from "
                "MultiStudy")
        super(MultiStudy, self).__init__(name, archive, runner, inputs,
                                         options=options, **kwargs)
        self._sub_studies = {}
        for sub_study_spec in self.sub_study_specs():
            # Create copies of the input datasets to pass to the
            # __init__ method of the generated sub-studies
            sub_study_cls = sub_study_spec.study_class
            mapped_inputs = []
            for inpt in inputs:
                try:
                    mapped_inputs.append(
                        inpt.renamed(sub_study_spec.map(inpt.name)))
                except NiAnalysisNameError:
                    pass  # Ignore datasets not required for sub-study
            mapped_options = []
            for opt_name in sub_study_cls.option_spec_names():
                mapped_name = sub_study_spec.inverse_map(opt_name)
                option = self._get_option(mapped_name)
                mapped_options.append(option.renamed(opt_name))
            # Create sub-study
            sub_study = sub_study_spec.study_class(
                name + '_' + sub_study_spec.name,
                archive, runner, mapped_inputs,
                options=mapped_options,
                enforce_inputs=False)
#             # Set sub-study as attribute
#             setattr(self, sub_study_spec.name, sub_study)
            # Append to dictionary of sub_studies
            if sub_study_spec.name in self._sub_studies:
                raise NiAnalysisNameError(
                    sub_study_spec.name,
                    "Duplicate sub-study names '{}'"
                    .format(sub_study_spec.name))
            self._sub_studies[sub_study_spec.name] = sub_study
예제 #10
0
파일: multi.py 프로젝트: sforazz/arcana
 def map(self, name):
     try:
         return self._name_map[name]
     except KeyError:
         mapped = self.strip_prefix(name)
         if mapped not in chain(self.study_class.data_spec_names(),
                                self.study_class.option_spec_names()):
             raise NiAnalysisNameError(
                 name,
                 "'{}' has a matching prefix '{}_' but '{}' doesn't"
                 " match any datasets, fields or options in the "
                 "study class {} ('{}')"
                 .format(name, self.name, mapped,
                         self.study_class.__name__,
                         "', '".join(
                             self.study_class.data_spec_names())))
         return mapped
예제 #11
0
    def data_spec(cls, name):
        """
        Return the dataset_spec, i.e. the template of the dataset expected to
        be supplied or generated corresponding to the dataset_spec name.

        Parameters
        ----------
        name : Str
            Name of the dataset_spec to return
        """
        if isinstance(name, BaseDatum):
            name = name.name
        try:
            return cls._data_specs[name]
        except KeyError:
            raise NiAnalysisNameError(
                name, "No dataset spec named '{}' in {} (available: "
                "'{}')".format(name, cls.__name__,
                               "', '".join(cls._data_specs.keys())))
예제 #12
0
 def __init__(self,
              name,
              archive,
              runner,
              inputs,
              options=None,
              subject_ids=None,
              visit_ids=None,
              enforce_inputs=True,
              reprocess=False):
     try:
         if not issubclass(
                 type(self).__dict__['__metaclass__'], StudyMetaClass):
             raise KeyError
     except KeyError:
         raise NiAnalysisUsageError(
             "Need to have StudyMetaClass (or a sub-class) as "
             "the metaclass of all classes derived from Study")
     if isinstance(options, dict):
         # Convert dictionary of key-value pairs into list of Option
         # objects
         options = [Option(k, v) for k, v in options.items()]
     elif options is None:
         options = []
     self._name = name
     self._archive = archive
     self._runner = runner
     self._inputs = {}
     # "Bind" data specs in the class to the current study object
     # this will allow them to prepend the study name to the name
     # of the dataset
     self._bound_specs = {}
     for opt in options:
         try:
             opt_spec = self._option_specs[opt.name]
         except KeyError:
             raise NiAnalysisNameError(
                 "Provided option '{}' is not present in the "
                 "allowable options for {} classes ('{}')".format(
                     opt.name,
                     type(self).__name__,
                     "', '".join(self.default_options)))
         if not isinstance(opt.value, opt_spec.dtype):
             raise NiAnalysisUsageError(
                 "Incorrect datatype for '{}' option provided "
                 "to '{}' {}, {} ({}). Should be {}".format(
                     opt.name, name,
                     type(self).__name__, type(opt.value), opt_spec.dtype))
         if (opt_spec.choices is not None
                 and opt.value not in opt_spec.choices):
             raise NiAnalysisUsageError(
                 "Provided value for '{}' option in '{}' {}, {}, is "
                 "not a valid choice. Can be one of {}".format(
                     opt.name, name,
                     type(self).__name__, opt.value,
                     ','.join(opt_spec.choices)))
     self._options = dict((o.name, o) for o in options)
     self._subject_ids = subject_ids
     self._visit_ids = visit_ids
     self._tree_cache = None
     # Add each "input dataset" checking to see whether the given
     # dataset_spec name is valid for the study type
     for inpt in inputs:
         if inpt.name not in self._data_specs:
             raise NiAnalysisNameError(
                 inpt.name,
                 "Match name '{}' isn't in data specs of {} ('{}')".format(
                     inpt.name, self.__class__.__name__,
                     "', '".join(self._data_specs)))
         self._inputs[inpt.name] = inpt.bind(self)
     for spec in self.data_specs():
         if not spec.derived:
             # Emit a warning if an acquired dataset has not been
             # provided for an "acquired dataset"
             if spec.name not in self._inputs:
                 msg = (" acquired dataset '{}' was not given as an "
                        "input of {}.".format(spec.name, self))
                 if spec.optional:
                     logger.info('Optional' + msg)
                 else:
                     if enforce_inputs:
                         raise NiAnalysisMissingInputError(
                             'Non-optional' + msg + " Pipelines "
                             "depending on this dataset will not run")
         else:
             self._bound_specs[spec.name] = spec.bind(self)
     self._reprocess = reprocess
     # Record options accessed before a pipeline is created
     # so they can be attributed to the pipeline after creation
     self._pre_options = defaultdict(list)
예제 #13
0
 def input(self, name):
     try:
         return self._inputs[name]
     except KeyError:
         raise NiAnalysisNameError(
             name, "{} doesn't have an input named '{}'".format(self, name))