Adding support for new file types ================================= *XNAT Ingest* doesn't have built-in knowledge of DICOM, NIfTI, or any other specific format baked into its core logic. Instead, every file on disk is represented as a typed ``FileSet`` from the `FileFormats `_ package (e.g. ``DicomSeries``, ``NiftiGz``), and format-specific behaviour is provided by that type rather than by ``xnat_ingest`` itself. This is what lets the same pipeline code handle a wildly different data — clinical DICOMs, derived NIfTIs, proprietary raw PET data — without a format-specific branch for each one. Grouping files into resources ---------------------------------- ``group``'s ``--datatype`` option (see :doc:`/cli`) is a FileFormats MIME-like identifier (or a ``|``-separated union of several) that says which types of file to look for in the input paths at all. Within a matched session, ``--scan``/ ``--resource`` (:class:`~xnat_ingest.helpers.arg_types.IDSpec`) then decide which scan and resource each file belongs to, based on values read out of the file's own metadata (e.g. DICOM ``SeriesNumber``, ``ImageType``) — see :class:`~xnat_ingest.model.resource.ImagingResource` and :class:`~xnat_ingest.model.scan.ImagingScan`. Reading metadata --------------------- Metadata is read via FileFormats' ``read_metadata`` "extra" — a method declared with ``@extra`` on ``FileSet`` itself (so it applies to every format), with the actual implementation registered separately, per format, via ``@extra_implementation``. This indirection is what lets ``xnat_ingest`` call ``fileset.metadata`` (or ``fileset.read_metadata()``) generically, regardless of what the underlying format actually is, and is why adding support for a new file type is a matter of writing an ``extra_implementation`` for it in a `FileFormats extras package `_ (e.g. ``fileformats-medimage-extras``), rather than modifying ``xnat_ingest`` itself. Deidentifying via extra implementations -------------------------------------------- The ``deidentify`` command works the same way: ``MedicalImagingData.deidentify`` is declared as an ``@extra`` (in ``fileformats-medimage``), and the concrete implementation for DICOM lives in that package's own ``extra_implementation``-decorated function, keyed by type via ``functools.singledispatch``. ``ImagingSession.deidentify`` (see :class:`~xnat_ingest.model.session.ImagingSession`) only decides *which* spec applies to a given resource — the actual deidentification logic is entirely delegated to whatever's registered for that resource's type. Note that as of writing, the registered DICOM implementation ignores the ``spec`` argument's contents and always strips a fixed, built-in set of tags — see :doc:`/how_to/deidentify` for the current state of per-project spec customisation. Only formats flagged ``contains_phi = True`` (the ``MedicalImagingData`` default) are run through ``deidentify`` at all — formats known not to carry patient information (e.g. derived NIfTIs) set ``contains_phi = False`` and are just copied through unchanged.