populse / populse_mia

Multiparametric Image Analysis
Other
10 stars 9 forks source link

[Initialization step] Issue during initialization because Nipype process need an existing image #298

Closed manuegrx closed 1 year ago

manuegrx commented 1 year ago

This is an issue with mia_processess but I think it concerns how populse_mia works.

Problem when initializing the pipeline with the process mia_processes.bricks.preprocess.spm.Realign when the in_files parameters are not existing images.

When initializing the pipeline, in list_outputs function (in Realign class of mia_processes.bricks.preprocess.spm.Realign), Nipype Realign process is called in order to get outputs's path name (which is not the same depending on the input parameters). However, the func_is_3d (nipype.interfaces.base) function is called in Realign class in Nipype (nipype.interfaces.spm.preprocess):

    def _list_outputs(self):
        outputs = self._outputs().get()
        resliced_all = self.inputs.write_which[0] > 0
        resliced_mean = self.inputs.write_which[1] > 0

        if self.inputs.jobtype != "write":
            if isdefined(self.inputs.in_files):
                outputs["realignment_parameters"] = []
            for imgf in self.inputs.in_files:
                if isinstance(imgf, list):
                    tmp_imgf = imgf[0]
                else:
                    tmp_imgf = imgf
                outputs["realignment_parameters"].append(
                    fname_presuffix(
                        tmp_imgf, prefix="rp_", suffix=".txt", use_ext=False
                    )
                )
                   break

This function check the image dimension using nibabel.load, so the image must exist:

  def func_is_3d(in_file):
    """Checks if input functional files are 3d."""

    if isinstance(in_file, list):
        return func_is_3d(in_file[0])
    else:
        img = load(in_file)
        shape = img.shape
        if len(shape) == 3 or (len(shape) == 4 and shape[3] == 1):
            return True
        else:
            return False

--> if the in_files parameters are not existing images initialization is not correctly done, but it is the principle of populse_mia to do initialization without existing image

Potential solution : For the Nipype process that need existing images in input, do not call Nipype process during the initialization step and code in mia_processes output path name --> we will need to check in our side if the future image dimension so the issue is quite the same

servoz commented 1 year ago

The capsule machinery tries to update all trait values of the output process instance when an input trait of the process instance is changed.

However, the initialisation step in Mia is based on the use of "false inputs" (only the name is defined, but the corresponding data does not exist yet). We have already discussed a lot about this in the past (@denisri had rightly proposed the concept of "data coming from the future"!; moreover, there are still things to do on this subject in relation to the indexing in the database of these data "coming from the future", especially in the case of a deported calculation. I believe that at least one ticket is open on this subject).

The main problems of this way of doing things is precisely when nipype needs the data to exist at the time of initialisation, as you show exactly here.

This means that the current mia_processes.bricks.preprocess.spm.Realign.list_outputs() method needs to be improved. I will look at this.

denisri commented 1 year ago

I don't remember how nipype inputs are marked or forced to exist when they are files, and where it raises errors. I remember that in capsul pipelines, nodes inputs which are connected from outputs of upstream nodes are modified (Pipeline.add_link() calls a function soma.controller.trait_utils.relax_exists_constraint() on connected input trait for this). But I don't remember what is done on nipype traits, and what exactly causes problem in your situation.

servoz commented 1 year ago

I opened a ticket (related to this one) in the mia_processes part.

It is rather in mia_processes that the necessary change should be made. I think that everything works correctly on the side of capsul and populse_mia (the exception raised in nipype is well catched by capsul).

We just have to do the job that can't be done in nipype, in mia_processes. I will look at this.