Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions .blackignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Virtual environments
.venv/
venv/
env/
ENV/
env.bak/
venv.bak/

# Python cache
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
.pytest_cache/

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
*.manifest
*.spec

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# OS
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Project specific
__MACOSX/
*.zip
*.mat
*.v
*.v.gz
*.avi
*.jpg
*.bytes
4 changes: 1 addition & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,4 @@ pythongithubworkflow: installdependencies collectphantoms decompressphantoms tes
@echo finished running python tests

black:
@for file in `find pypet2bids/ -name "*.py"`; do \
black $$file; \
done
@black pypet2bids/
87 changes: 81 additions & 6 deletions pypet2bids/pypet2bids/dcm2niix4pet.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ def __init__(
metadata_path=None,
metadata_translation_script=None,
additional_arguments={},
dcm2niix_options="",
file_format="%p_%i_%t_%s",
silent=False,
tempdir_location=None,
Expand Down Expand Up @@ -364,6 +365,42 @@ def __init__(
load_spreadsheet_data["blood_json"]
)

# we default to these options, a user may supply their own combination, this will allow full customization of all
# but the file arguments for dcm2niix
if dcm2niix_options:
# Filter out -f flag and its value from custom options since file format is handled separately
options_list = dcm2niix_options.split()
filtered_options = []
i = 0
while i < len(options_list):
if options_list[i] == "-f" and i + 1 < len(options_list):
# Skip -f and its value
i += 2
else:
filtered_options.append(options_list[i])
i += 1
self.dcm2niix_options = " ".join(filtered_options)
else:
# Check for dcm2niix options in config file and environment variable
config_options = helper_functions.check_pet2bids_config(
"PET2BIDS_DCM2NIIX_OPTIONS"
)
env_options = environ.get("PET2BIDS_DCM2NIIX_OPTIONS")

# Priority: command line > environment variable > config file > default
if env_options:
self.dcm2niix_options = env_options
logger.info(
f"Using dcm2niix options from environment variable: {env_options}"
)
elif config_options:
self.dcm2niix_options = config_options
logger.info(
f"Using dcm2niix options from config file: {config_options}"
)
else:
self.dcm2niix_options = "-b y -w 1 -z y"
logger.debug("Using default dcm2niix options: -b y -w 1 -z y")
self.file_format = file_format
# we may want to include additional information to the sidecar, tsv, or json files generated after conversion
# this variable stores the mapping between output files and a single dicom header used to generate those files
Expand Down Expand Up @@ -480,7 +517,7 @@ def run_dcm2niix(self):
self.tempdir_location = tempdir_pathlike
# people use screwy paths, we do this before running dcm2niix to account for that
image_folder = helper_functions.sanitize_bad_path(self.image_folder)
cmd = f"{self.dcm2niix_path} -b y -w 1 -z y {file_format_args} -o {tempdir_pathlike} {image_folder}"
cmd = f"{self.dcm2niix_path} {self.dcm2niix_options} {file_format_args} -o {tempdir_pathlike} {image_folder}"
convert = subprocess.run(cmd, shell=True, capture_output=True)
self.telemetry_data["dcm2niix"] = {
"returncode": convert.returncode,
Expand Down Expand Up @@ -674,10 +711,19 @@ def run_dcm2niix(self):
if re.search(
r"\d+.\d+", sidecar_json.get("ConvolutionKernel")
):
recon_filter_size = re.search(
r"\d+.\d*", sidecar_json.get("ConvolutionKernel")
)[0]
recon_filter_size = float(recon_filter_size)
try:
recon_filter_size = re.search(
r"\d+.\d*",
sidecar_json.get("ConvolutionKernel"),
)[0]
recon_filter_size = float(recon_filter_size)
except ValueError:
# If float conversion fails, try splitting and take first part
match_str = re.search(
r"\d+.\d*",
sidecar_json.get("ConvolutionKernel"),
)[0]
recon_filter_size = float(match_str.split()[0])
sidecar_json.update(
{"ReconFilterSize": float(recon_filter_size)}
)
Expand Down Expand Up @@ -1037,9 +1083,13 @@ def load_spread_sheet_data(self):

example usage:

dcm2niix4pet folder_with_pet_dicoms/ --destinationp-path sub-ValidBidSSubject/pet # the simplest conversion
dcm2niix4pet folder_with_pet_dicoms/ --destination-path sub-ValidBidSSubject/pet # the simplest conversion
dcm2niix4pet folder_with_pet_dicoms/ --destination-path sub-ValidBidsSubject/pet --metadata-path metadata.xlsx \
# use with an input spreadsheet
dcm2niix4pet folder_with_pet_dicoms/ --destination-path sub-ValidBidsSubject/pet --dcm2niix-options -v y -w 1 -z y \
# use with custom dcm2niix options
dcm2niix4pet --set-dcm2niix-options '-v y -w 1 -z y' \
# set default dcm2niix options in config file

"""
)
Expand Down Expand Up @@ -1135,6 +1185,13 @@ def cli():
f"DCM2NIIX_PATH",
type=pathlib.Path,
)
parser.add_argument(
"--set-dcm2niix-options",
help="Provide dcm2niix options to be used as defaults, writes to config "
f"file {Path.home()}/.pet2bidsconfig under the variable "
f"PET2BIDS_DCM2NIIX_OPTIONS. Example: --set-dcm2niix-options '-v y -w 1 -z y'",
type=str,
)
parser.add_argument(
"--set-default-metadata-json",
help="Provide a path to a default metadata file json file."
Expand Down Expand Up @@ -1190,6 +1247,15 @@ def cli():
help="Accept any NifTi produced by dcm2niix even if it contains errors. This flag should only be used for "
"batch processing and only if you're performing robust QC after the fact.",
)
parser.add_argument(
"--dcm2niix-options",
nargs="*",
default=[],
help="Additional dcm2niix options to pass through. Use the same format as dcm2niix command line. "
"Note: -f flag and its value will be filtered out as file format is handled separately. "
"You can also set default options using --set-dcm2niix-options or the PET2BIDS_DCM2NIIX_OPTIONS environment variable. "
"Example: --dcm2niix-options -v y -w 1 -z y",
)
return parser


Expand Down Expand Up @@ -1336,6 +1402,12 @@ def main():
helper_functions.modify_config_file("DCM2NIIX_PATH", cli_args.set_dcm2niix_path)
sys.exit(0)

if cli_args.set_dcm2niix_options:
helper_functions.modify_config_file(
"PET2BIDS_DCM2NIIX_OPTIONS", cli_args.set_dcm2niix_options
)
sys.exit(0)

if cli_args.set_default_metadata_json:
helper_functions.modify_config_file(
"DEFAULT_METADATA_JSON", cli_args.set_default_metadata_json
Expand All @@ -1354,6 +1426,9 @@ def main():
cli_args.translation_script_path
),
additional_arguments=cli_args.kwargs,
dcm2niix_options=(
" ".join(cli_args.dcm2niix_options) if cli_args.dcm2niix_options else ""
),
tempdir_location=cli_args.tempdir,
silent=cli_args.silent,
ezbids=cli_args.ezbids,
Expand Down
21 changes: 20 additions & 1 deletion pypet2bids/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "pypet2bids"
version = "1.4.3"
version = "1.4.4"
description = "A python library for converting PET imaging and blood data to BIDS."
authors = [
{name = "anthony galassi", email = "[email protected]"}
Expand Down Expand Up @@ -52,6 +52,7 @@ dev = [
"pyinstaller>=5.4.1",
"build>=0.10.0",
"briefcase>=0.3.23; python_version>='3.9'",
"black>=23.0.0",
]

[project.scripts]
Expand All @@ -78,3 +79,21 @@ include = [
"/pypet2bids",
"/README.md",
]

[tool.black]
line-length = 88
target-version = ['py38']
include = '\.pyi?$'
extend-exclude = '''
/(
# directories
\.eggs
| \.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| build
| dist
)/
'''
Loading