Exemple #1
0
def test_index_metadata(index_metadata, query, result):
    data_dir = join(get_test_data_path(), '7t_trt')
    layout = BIDSLayout(data_dir, index_metadata=index_metadata)
    if not index_metadata and query is not None:
        indexer = BIDSLayoutIndexer(layout)
        indexer.index_metadata(**query)
    sample_file = layout.get(task='rest', extension='nii.gz',
                             acq='fullbrain')[0]
    metadata = sample_file.get_metadata()
    assert metadata.get('RepetitionTime') == result
Exemple #2
0
def test_force_index(layout_ds005):
    data_dir = join(get_test_data_path(), 'ds005')
    target = join(data_dir, 'models', 'ds-005_type-test_model.json')
    indexer = BIDSLayoutIndexer(force_index=['models'])
    model_layout = BIDSLayout(data_dir, validate=True, indexer=indexer)
    assert target not in layout_ds005.files
    assert target in model_layout.files
    assert 'all' not in model_layout.get_subjects()
    for f in model_layout.files.values():
        assert 'derivatives' not in f.path
Exemple #3
0
    def init(cls):
        """Create a new BIDS Layout accessible with :attr:`~execution.layout`."""
        if cls._layout is None:
            import re
            from bids.layout.index import BIDSLayoutIndexer
            from bids.layout import BIDSLayout

            _db_path = cls.bids_database_dir or (
                cls.work_dir / cls.run_uuid / "bids_db"
            )
            _db_path.mkdir(exist_ok=True, parents=True)

            # Recommended after PyBIDS 12.1
            _indexer = BIDSLayoutIndexer(
                validate=False,
                ignore=(
                    "code",
                    "stimuli",
                    "sourcedata",
                    "models",
                    "derivatives",
                    "scripts",
                    re.compile(r"^\."),
                    # Exclude modalities and contrasts ignored by MRIQC (doesn't know how to QC)
                    re.compile(
                        r"sub-[a-zA-Z0-9]+(/ses-[a-zA-Z0-9]+)?/(dwi|fmap|perf)/"
                    ),
                    re.compile(
                        r"sub-[a-zA-Z0-9]+(/ses-[a-zA-Z0-9]+)?/anat/.*_"
                        r"(PDw|T2starw|FLAIR|inplaneT1|inplaneT2|PDT2|angio|T2star"
                        r"|FLASH|PD|T1map|T2map|T2starmap|R1map|R2map|R2starmap|PDmap"
                        r"|MTRmap|MTsat|UNIT1|T1rho|MWFmap|MTVmap|PDT2map|Chimap"
                        r"|S0map|M0map|defacemask|MESE|MEGRE|VFA|IRT1|MP2RAGE|MPM|MTS|MTR)\."
                    ),
                    re.compile(
                        r"sub-[a-zA-Z0-9]+(/ses-[a-zA-Z0-9]+)?/func/.*"
                        r"_(cbv|sbref|phase|events|physio|stim)\."
                    ),
                ),
            )
            cls._layout = BIDSLayout(
                str(cls.bids_dir),
                database_path=_db_path,
                reset_database=cls.bids_database_dir is None,
                indexer=_indexer,
            )
            cls.bids_database_dir = _db_path

        cls.layout = cls._layout
Exemple #4
0
def test_ignore_files(layout_ds005):
    data_dir = join(get_test_data_path(), 'ds005')
    target1 = join(data_dir, 'models', 'ds-005_type-test_model.json')
    target2 = join(data_dir, 'models', 'extras', 'ds-005_type-test_model.json')
    layout1 = BIDSLayout(data_dir, validate=False)
    assert target1 not in layout_ds005.files
    assert target1 not in layout1.files
    assert target2 not in layout1.files
    # now the models/ dir should show up, because passing ignore explicitly
    # overrides the default - but 'model/extras/' should still be ignored
    # because of the regex.
    ignore = [re.compile('xtra'), 'dummy']
    indexer = BIDSLayoutIndexer(validate=False, ignore=ignore)
    layout2 = BIDSLayout(data_dir, indexer=indexer)
    assert target1 in layout2.files
    assert target2 not in layout2.files
Exemple #5
0
def init_layout():
    from .bids import Layout
    from bids.layout.index import BIDSLayoutIndexer

    global TF_LAYOUT
    TF_LAYOUT = Layout(
        TF_HOME,
        validate=False,
        config="templateflow",
        indexer=BIDSLayoutIndexer(
            validate=False,
            ignore=(
                ".git",
                ".datalad",
                ".gitannex",
                ".gitattributes",
                ".github",
                "scripts",
            ),
        ),
    )
Exemple #6
0
    def _resolve_bids(self, fileobj: File) -> list[File]:

        # load using pybids
        validate = False  # save time
        layout = BIDSLayout(
            root=fileobj.path,
            reset_database=True,  # force reindex in case files have changed
            absolute_paths=True,
            validate=validate,
            indexer=BIDSLayoutIndexer(
                validate=validate,
                index_metadata=False,  # save time
            ),
        )

        # load override metadata
        basemetadata = dict()
        if hasattr(fileobj, "metadata"):
            metadata = getattr(fileobj, "metadata", None)
            if isinstance(metadata, dict):
                basemetadata.update(metadata)

        resolved_files: list[File] = []
        for obj in layout.get_files().values():
            file: File | None = to_fileobj(obj, basemetadata)

            if file is None:
                continue

            self.fileobj_by_filepaths[file.path] = file
            self.specfileobj_by_filepaths[file.path] = file
            resolved_files.append(file)

        intended_for: dict[str, frozenset[tuple[str, str]]] = dict()
        for file in resolved_files:
            if file.datatype != "fmap":
                continue

            metadata = SidecarMetadataLoader.load(file.path)
            if metadata is None:
                continue

            intended_for_paths = metadata.get("intended_for")
            if intended_for_paths is None:
                continue

            linked_fmap_tags = frozenset(file.tags.items())
            for intended_for_path in intended_for_paths:
                intended_for[intended_for_path] = linked_fmap_tags

        informed_by: dict[frozenset[tuple[str, str]],
                          list[frozenset[tuple[str, str]]]] = defaultdict(list)
        for file in resolved_files:
            file_tags = frozenset(file.tags.items())

            for file_path, linked_fmap_tags in intended_for.items():
                if file.path.endswith(file_path):  # slow performance
                    informed_by[file_tags].append(linked_fmap_tags)

        mappings: set[tuple[tuple[str, str], tuple[str, str]]] = set()
        for func_tags, linked_fmap_tags_list in informed_by.items():
            for linked_fmap_tags in linked_fmap_tags_list:
                for func_tag, linked_fmap_tag in product(
                        func_tags, linked_fmap_tags):
                    if func_tag[0] == "sub" or linked_fmap_tag[0] == "sub":
                        continue
                    if (func_tag[0] == linked_fmap_tag[0]
                        ):  # only map between different entities
                        continue
                    mappings.add((func_tag, linked_fmap_tag))

        intended_for_rules = defaultdict(list)
        for functag, fmaptag in mappings:
            entity, val = functag
            funcstr = f"{entity}.{val}"

            entity, val = fmaptag
            fmapstr = f"{entity}.{val}"

            intended_for_rules[fmapstr].append(funcstr)

        if len(intended_for) > 0:
            logger.info(
                "Inferred mapping between func and fmap files to be %s",
                pformat(intended_for_rules),
            )
            for file in resolved_files:
                if file.datatype != "fmap":
                    continue
                file.intended_for = intended_for_rules

        return resolved_files