Ejemplo n.º 1
0
    def add_entity(self, domain, **kwargs):
        ''' Add a new Entity to tracking. '''

        # Set the entity's mapping func if one was specified
        map_func = kwargs.get('map_func', None)
        if map_func is not None and not callable(kwargs['map_func']):
            if self.entity_mapper is None:
                raise ValueError("Mapping function '%s' specified for Entity "
                                 "'%s', but no entity mapper was passed when "
                                 "initializing the current Layout. Please make"
                                 " sure the 'entity_mapper' argument is set." %
                                 (map_func, kwargs['name']))
            map_func = getattr(self.entity_mapper, kwargs['map_func'])
            kwargs['map_func'] = map_func

        ent = Entity(domain=domain, **kwargs)
        domain.add_entity(ent)

        if ent.mandatory:
            self.mandatory.add(ent.id)

        if ent.directory is not None:
            ent.directory = ent.directory.replace('{{root}}', self.root)

        self.entities[ent.id] = ent
        for alias in ent.aliases:
            self.entities[alias] = ent
        if self.dynamic_getters:
            func = partial(getattr(self, 'get'),
                           target=ent.name,
                           return_type='id')
            func_name = inflect.engine().plural(ent.name)
            setattr(self, 'get_%s' % func_name, func)
Ejemplo n.º 2
0
 def add_entity(self, **kwargs):
             # Set up the entities we need to track
         ent = Entity(**kwargs)
         if ent.mandatory:
             self.mandatory.add(ent.name)
         if ent.directory is not None:
             ent.directory = ent.directory.replace('{{root}}', self.root)
         self.entities[ent.name] = ent
         if self.dynamic_getters:
             func = partial(getattr(self, 'get'), target=ent.name,
                            return_type='id')
             func_name = inflect.engine().plural(ent.name)
             setattr(self, 'get_%s' % func_name, func)
Ejemplo n.º 3
0
    def add_derivatives(self, path, **kwargs):
        ''' Add BIDS-Derivatives datasets to tracking.

        Args:
            path (str, list): One or more paths to BIDS-Derivatives datasets.
                Each path can point to either a derivatives/ directory
                containing one more more pipeline directories, or to a single
                pipeline directory (e.g., derivatives/fmriprep).
            kwargs (dict): Optional keyword arguments to pass on to
                BIDSLayout() when initializing each of the derivative datasets.
        '''
        paths = listify(path)
        deriv_dirs = []

        # Collect all paths that contain a dataset_description.json
        def check_for_description(dir):
            dd = os.path.join(dir, 'dataset_description.json')
            return os.path.exists(dd)

        for p in paths:
            p = os.path.abspath(p)
            if os.path.exists(p):
                if check_for_description(p):
                    deriv_dirs.append(p)
                else:
                    subdirs = [
                        d for d in os.listdir(p)
                        if os.path.isdir(os.path.join(p, d))
                    ]
                    for sd in subdirs:
                        sd = os.path.join(p, sd)
                        if check_for_description(sd):
                            deriv_dirs.append(sd)

        local_entities = set(ent.name for ent in self.entities.values())
        for deriv in deriv_dirs:
            dd = os.path.join(deriv, 'dataset_description.json')
            with open(dd, 'r', encoding='utf-8') as ddfd:
                description = json.load(ddfd)
            pipeline_name = description.get('PipelineDescription',
                                            {}).get('Name', None)
            if pipeline_name is None:
                raise ValueError("Every valid BIDS-derivatives dataset must "
                                 "have a PipelineDescription.Name field set "
                                 "inside dataset_description.json.")
            if pipeline_name in self.derivatives:
                raise ValueError("Pipeline name '%s' has already been added "
                                 "to this BIDSLayout. Every added pipeline "
                                 "must have a unique name!")
            # Default config and sources values
            kwargs['config'] = kwargs.get('config') or ['bids', 'derivatives']
            kwargs['sources'] = kwargs.get('sources') or self
            self.derivatives[pipeline_name] = BIDSLayout(deriv, **kwargs)

            # Propagate derivative entities into top-level dynamic getters
            deriv_entities = set(
                ent.name
                for ent in self.derivatives[pipeline_name].entities.values())
            for deriv_ent in deriv_entities - local_entities:
                local_entities.add(deriv_ent)
                getter = 'get_' + inflect.engine().plural(deriv_ent)
                if not hasattr(self, getter):
                    func = partial(self.get,
                                   target=deriv_ent,
                                   return_type='id')
                    setattr(self, getter, func)