Using pydeface within the dcm2bids config file

Hi all,

I saw in the dcm2bids “advanced use” topics that the pydeface process can be called to deface scans during the dcm2bids process. apparently, you can put a line in just above the “description” line in the config file to call it (the “defaceTpl:” line). However, I also saw a couple of things that confused me:

I ran across a line in the document that says " !!! danger The anonymizer option no longer exists from v2.0.0 . It is still possible to deface the anatomical nifti images." Is this saying the defaceTpl does not work with the newer dcm2bids versions, or am I misunderstanding?

Also there is one example line that says the usage is “defaceTpl”: [“pydeface”, “–outfile”, “dstFile”, “srcFile”" , but then later on it says it’s “defaceTpl”: “pydeface --outfile {dstFile} {srcFile}”. Does someone know if it’s still working and which line to use in the Config.json file?

Thanks!
Wade

Hi @wade and welcome to NeuroStars!

For what it’s worth, I run pydeface outside of dcm2bids (since I like to add the rec-defaced label to my output images). The syntax is something like pydeface $t1_in --outfile $t1_out.

To define my output name, I do t1_outpath=${t1/${acq}/"${acq}_rec-defaced"},
where ${acq} is acq-MPRAGE (for example) and is something that is in my dcm2bids config file to put on all my T1 outputs. t1_outpath then becomes the input name with _rec-defaced appended after the acq label.

Best,
Steven

Hi @wade,

The new version version of dcm2bids will fix the issue with pydeface.
I think everything will be working within the next 2 weeks or so.
In the meantime, @Steven suggestion is the way to go.

Best,
Arnaud

Awesome. Thank you!
Wade

Hi all,
So I updated to dcm2bids v3 and updated my config files so everything works. However, when I add the pydeface lines at the top of the config file, pydeface STILL doesn’t work. Here’s what I have at the top of my config file:
{
“post-op”: [
{
“cmd”: “pydeface --outfile dst_file src_file”,
“datatype”: “anat”,
“suffix”: [
“T1w”,
“T2w”
]
}
],
“descriptions”: …etc.

Am I supposed to define what the dst_file and src_file are or something? The config file gives no errors when running and runs perfectly, it just skips the pydeface.

Thanks!
Wad

I’m working on it. I should have a new release next week.
Thank you for your patience.
Arnaud

Hi @wade,

Can you give it a try with the PR I’m suggesting to fix your issue (PR 260) ?
If it’s still doesn’t do anything please provide the whole config file.
Best,
Arnaud

Hi Arnaud,

Thanks for the help! I’m not sure how to use PR 260 - I’m using the dcm2bids container. I tried to get into the container to inspect the code and make the change, but for some reason when I “apptainer shell dcm2bids_3.0.2.sif”, it won’t let me inside the container. (Maybe I’m doing something wrong, I’m fairly new to containers.) But here’s the whole config file:

{
  "_comment": "dcm2bids config file for UT NECTARY study data - June 23, 2023",
  "descriptions": [
    {
      "datatype": "anat",
      "suffix": "T2w",
      "custom_entities": "rec-orig",
      "criteria": {
        "SeriesDescription": "*T2*",
        "ImageTypeText": [
            "ORIGINAL",
            "PRIMARY",
            "M",
            "DIS2D"
            ]
         },
      "sidecar_changes": {
        "ProtocolName": "T2 - original scan"
      }
    },
    {
      "datatype": "anat",
      "suffix": "T2w",
      "custom_entities": "rec-norm",
      "criteria": {
        "SeriesDescription": "*T2*",
        "ImageTypeText": [
            "ORIGINAL",
            "PRIMARY",
            "M",
            "NORM",
            "DIS2D"
            ]
         },
      "sidecar_changes": {
        "ProtocolName": "T2 - normalized scan"
      }
    },
    {
      "datatype": "anat",
      "suffix": "T1w",
      "custom_entities": "rec-orig",
      "criteria": {
        "SeriesDescription": "*T1*",
        "ImageTypeText": [
            "ORIGINAL",
            "PRIMARY",
            "M",
            "DIS2D"
            ]
         },
      "sidecar_changes": {
        "ProtocolName": "T1 - original scan"
      }
    },
    {
      "datatype": "anat",
      "suffix": "T1w",
      "custom_entities": "rec-norm",
      "criteria": {
        "SeriesDescription": "*T1*",
        "ImageTypeText": [
            "ORIGINAL",
            "PRIMARY",
            "M",
            "NORM",
            "DIS2D"
            ]
         },
      "sidecar_changes": {
        "ProtocolName": "T1 - normalized scan"
      }
    },
    {
      "_comment": "NECTARY resting state config files",
      "id": "id_rest_AP",
      "datatype": "func",
      "suffix": "bold",
      "custom_entities": [
        "task-rest",
        "dir-AP"
      ],
      "criteria": {
        "SeriesDescription": "*REST*",
        "ProtocolName": "*dir-AP*",
        "PhaseEncodingDirection": "j-"
      },
      "sidecar_changes": {
        "TaskName": "rest AP"
      }
    },
    {
      "_comment": "NECTARY resting state config files",
      "id": "id_rest_PAWD",
      "datatype": "func",
      "suffix": "bold",
      "custom_entities": [
        "task-rest",
        "dir-PAWD"
      ],
      "criteria": {
        "SeriesDescription": "*REST*",
        "ProtocolName": "*dir-AP*",
        "PhaseEncodingDirection": "j"
      },
      "sidecar_changes": {
        "TaskName": "rest AP, but taken PA"
      }
    },
    {
      "_comment": "NECTARY resting state phase map config files",
      "datatype": "fmap",
      "suffix": "epi",
      "custom_entities": [
        "acq-restDmap",
        "dir-PA"
      ],
      "criteria": {
        "SeriesDescription": "*REST*",
        "ProtocolName": "*distmap*",
        "PhaseEncodingDirection": "j"
      },
          "sidecar_changes": {
        "IntendedFor": [
          "id_rest_AP",
          "id_rest_PAWD"
        ],
      "TaskName": "rest dmap PA"
      }
    },
    {
      "_comment": "NECTARY resting state phase map config files",
      "datatype": "fmap",
      "suffix": "epi",
      "custom_entities": [
        "acq-restDmap",
        "dir-APWD"
      ],
      "criteria": {
        "SeriesDescription": "*REST*",
        "ProtocolName": "*distmap*",
        "PhaseEncodingDirection": "j-"
      },
          "sidecar_changes": {
        "IntendedFor": [
          "id_rest_AP",
          "id_rest_PAWD"
        ],
      "TaskName": "rest dmap PA, but taken AP"
      }
    },
    {
      "_comment": "NECTARY MID task (card guessing) config files",
      "id": "id_mid_AP",
      "datatype": "func",
      "suffix": "bold",
      "custom_entities": [
        "task-mid",
        "dir-AP"
      ],
      "criteria": {
        "SeriesDescription": "*MID*",
        "ProtocolName": "*dir-AP*",
        "PhaseEncodingDirection": "j-"
      },
      "sidecar_changes": {
        "TaskName": "mid"
      }
    },
    {
      "_comment": "NECTARY MID task (card guessing) config files",
      "id": "id_mid_PAWD",
      "datatype": "func",
      "suffix": "bold",
      "custom_entities": [
        "task-mid",
        "dir-PAWD"
      ],
      "criteria": {
        "SeriesDescription": "*MID*",
        "ProtocolName": "*dir-AP*",
        "PhaseEncodingDirection": "j"
      },
      "sidecar_changes": {
        "TaskName": "mid"
      }
    },
    {
      "_comment": "NECTARY Social Reward task config files",
      "id": "id_soc_AP",
      "datatype": "func",
      "suffix": "bold",
      "custom_entities": [
        "task-soc",
        "dir-AP"
      ],
      "criteria": {
        "SeriesDescription": "*SOCIAL_dir-AP*",
        "PhaseEncodingDirection": "j-"
      },
      "sidecar_changes": {
        "TaskName": "social likeability task Healey, 2014"
      }
    },
    {
      "_comment": "NECTARY Social Reward task WRONG DIRECTION config files",
      "id": "id_soc_PAWD",
      "datatype": "func",
      "suffix": "bold",
      "custom_entities": [
        "task-soc",
        "dir-PAWD"
      ],
      "criteria": {
        "SeriesDescription": "*SOCIAL_dir-AP*",
        "PhaseEncodingDirection": "j"
      },
      "sidecar_changes": {
        "TaskName": "social likeability task Healey, 2014 wrong direction"
      }
    },
    {
      "_comment": "NECTARY distortion map for MID task (card guessing) and SWT",
      "datatype": "fmap",
      "suffix": "epi",
      "custom_entities": [
        "acq-fMRIdist",
        "dir-PA"
      ],
      "criteria": {
        "SeriesDescription": "*fMRIdist_dir-PA*",
        "PhaseEncodingDirection":"j",
        "ProtocolName": "*distmap*"
      },
          "sidecar_changes": {
        "IntendedFor": [
          "id_mid_AP",
          "id_mid_PAWD",
          "id_soc_AP",
          "id_soc_PAWD"
        ]
      }
    },
    {
      "_comment": "NECTARY distortion map WRONG DIR for MID (card guessing) and SWT",
      "datatype": "fmap",
      "suffix": "epi",
      "custom_entities": [
        "acq-fMRIdist",
        "dir-APWD"
      ],
      "criteria": {
        "SeriesDescription": "*fMRIdist_dir-PA*",
        "PhaseEncodingDirection": "j-",
        "ProtocolName": "*distmap*"
      },
          "sidecar_changes": {
        "IntendedFor": [
          "id_mid_AP",
          "id_mid_PAWD",
          "id_soc_AP",
          "id_soc_PAWD"
        ]
      }
    },
    {
      "_comment": "NECTARY Cyberball task config files",
      "id": "id_cyb_AP",
      "datatype": "func",
      "suffix": "bold",
      "custom_entities": [
        "task-cyb",
        "dir-AP"
      ],
      "criteria": {
        "SeriesDescription": "*Cyberball_dir-AP*",
        "PhaseEncodingDirection": "j-"
      },
      "sidecar_changes": {
        "TaskName": "cyberball"
      }
    },
    {
      "_comment": "NECTARY Cyberball task config files",
      "id": "id_cyb_PAWD",
      "datatype": "func",
      "suffix": "bold",
      "custom_entities": [
        "task-cyb",
        "dir-PAWD"
      ],
      "criteria": {
        "SeriesDescription": "*Cyberball_dir-AP*",
        "PhaseEncodingDirection": "j"
      },
      "sidecar_changes": {
        "TaskName": "cyberball task wrong direction"
      }
    },
    {
      "_comment": "NECTARY Cyberball distortion map config files",
      "datatype": "fmap",
      "suffix": "epi",
      "custom_entities": [
        "acq-cybDmap",
        "dir-PA"
      ],
      "criteria": {
        "SeriesDescription": "*Cyberball_dir-PA*",
        "ProtocolName": "*distmap*",
        "PhaseEncodingDirection": "j"
      },
          "sidecar_changes": {
        "IntendedFor": [
          "id_cyb_AP",
          "id_cyb_PAWD"
        ]
      }
    },
    {
      "_comment": "NECTARY Cyberball distortion map config files",
      "datatype": "fmap",
      "suffix": "epi",
      "custom_entities": [
        "acq-cybDmap",
        "dir-APWD"
      ],
      "criteria": {
        "SeriesDescription": "*Cyberball_dir-PA*",
        "ProtocolName": "*distmap*",
        "PhaseEncodingDirection": "j-"
      },
          "sidecar_changes": {
        "IntendedFor": [
          "id_cyb_AP",
          "id_cyb_PAWD"
        ]
      }
    },
    {
      "_comment": "NECTARY DWI 80-direction acquisition config files",
      "id": "id_dwi_AP",
      "datatype": "dwi",
      "suffix": "dwi",
      "custom_entities": "dir-AP",
      "criteria": {
        "SeriesDescription": "*dwi*",
        "ProtocolName": "*dir-AP*",
        "PhaseEncodingDirection": "j-",
        "ImageType": [
          "ORIGINAL",
          "PRIMARY",
          "DIFFUSION",
          "NONE"
        ]
      }
    },
    {
      "_comment": "NECTARY DWI 80-dir WRONG DIRECTION acquisition config files",
      "id": "id_dwi_PAWD",
      "datatype": "dwi",
      "suffix": "dwi",
      "custom_entities": "dir-PAWD",
      "criteria": {
        "SeriesDescription": "*dwi*",
        "ProtocolName": "*dir-AP*",
        "PhaseEncodingDirection": "j",
        "ImageType": [
          "ORIGINAL",
          "PRIMARY",
          "DIFFUSION",
          "NONE"
        ]
      }
    },
    {
      "_comment": "NECTARY DWI distortion map config files",
      "datatype": "fmap",
      "suffix": "epi",
      "custom_entities": [
        "acq-dwi",
        "dir-PA"
      ],
      "criteria": {
        "SeriesDescription": "*dwi*",
        "ProtocolName": "*distmap*",
        "PhaseEncodingDirection": "j"
      },
          "sidecar_changes": {
        "IntendedFor": [
          "id_dwi_AP",
          "id_dwi_PAWD"
        ]
      }
    },
    {
      "_comment": "NECTARY DWI distortion map config files",
      "datatype": "fmap",
      "suffix": "epi",
      "custom_entities": [
        "acq-dwi",
        "dir-APWD"
      ],
      "criteria": {
        "SeriesDescription": "*dwi*",
        "ProtocolName": "*distmap*",
        "PhaseEncodingDirection": "j-"
      },
          "sidecar_changes": {
        "IntendedFor": [
          "id_dwi_AP",
          "id_dwi_PAWD"
        ]
      }
    }
  ]
}

Hi @wade,

Make and activate a virtual environment (e.g., with anaconda), then

git clone -b fix_post_op --single-branch git@github.com:UNFmontreal/Dcm2Bids.git and then pip install -e . inside the cloned repo.

Best,
Steven

Hi Araud,
I just downloaded the dcm2bids 3.1 container and tried using pydeface with the “post-op” process like in the example. I haven’t changed anything in my config.json that I posted above. Everything works fine, but no pydeface happens. I’ve looked for other explanations and examples of using “post-op… pydeface” but I can’t find anything beyond the one example given. Is that really all I need to type in the “cmd” value? Just "pydeface --outfile dst_file src_file”? Or did I need paths or something like that? I’m not even getting errors like it’s trying to run it but can’t. It just skips over it like it’s not there.

Thanks,
Wade

Can you share just the relevant parts of your config file? So the post_op and descriptions with just your anatomical files? As well as the output log of dcm2bids?

Thanks,
Steven

Hi @wade, @Steven,
So far, pydeface is not included in the dcm2bids container.

I highly suggest to download dcm2bids 3.1.0 binaries and install pydeface in a python environment.

We’ll work on the container so it can include pydeface but there are a lot of big/heavy dependencies and we need to find a way to reduce the size of the container as much as possible.

Hope it helps.

Best,
Arnaud

Ahhhhhhhh… I see. Yeah, that would be why it’s not starting. OK, thanks! I just thought I was going crazy there for a minute. We’ll work-around until it’s included in the future.

Thanks for the help!
Wade