2020import subprocess
2121import pandas as pd
2222from os .path import join
23+ from os import chmod
2324from os import listdir , walk , environ
2425from pathlib import Path
2526import json
2930import shutil
3031import argparse
3132import importlib
33+ import zipfile
34+ import stat
3235
3336try :
3437 import helper_functions
@@ -172,6 +175,50 @@ def collect_date_time_from_file_name(file_name):
172175 return date , time
173176
174177
178+ def use_included_binary ():
179+ # get system platform
180+ systems_system = system ().lower ()
181+ module_folder = Path (__file__ ).parent .resolve ()
182+ binary_folder = module_folder / "dcm2niix_binaries"
183+ dcm2niix_zip = "dcm2niix_{}.zip"
184+ if "darwin" in systems_system :
185+ zipped = binary_folder / dcm2niix_zip .format ("mac" )
186+ elif "linux" in systems_system :
187+ zipped = binary_folder / dcm2niix_zip .format ("lnx" )
188+ elif "windows" in systems_system :
189+ zipped = binary_folder / dcm2niix_zip .format ("win" )
190+ else :
191+ raise ValueError (
192+ f"System must be Darwin, Linux, or Windows to use included binaries, got { system ()} "
193+ )
194+
195+ # Check if binary already exists
196+ if systems_system == "windows" :
197+ dcm2niix_binary = binary_folder / "dcm2niix.exe"
198+ else :
199+ dcm2niix_binary = binary_folder / "dcm2niix"
200+
201+ # Only extract if binary doesn't exist
202+ if not dcm2niix_binary .exists () and zipped .exists ():
203+ try :
204+ with zipfile .ZipFile (zipped , "r" ) as ref :
205+ ref .extractall (zipped .parent )
206+ except zipfile .BadZipFile as e :
207+ logger .error (
208+ f"Unable to extract { zipped } , try manually setting DCM2NIIX_PATH in env or .pypet2bids_config"
209+ )
210+ raise e
211+
212+ # Check to make sure binary is there and set permissions
213+ if dcm2niix_binary .exists ():
214+ if systems_system != "windows" :
215+ chmod (dcm2niix_binary , stat .S_IXUSR | stat .S_IXGRP | stat .S_IXOTH )
216+ helper_functions .modify_config_file ("DCM2NIIX_PATH" , dcm2niix_binary )
217+ return dcm2niix_binary
218+ else :
219+ return None
220+
221+
175222class Dcm2niix4PET :
176223 def __init__ (
177224 self ,
@@ -445,17 +492,21 @@ def check_posix():
445492 dcm2niix_path = helper_functions .check_pet2bids_config ()
446493
447494 if not dcm2niix_path :
448- pkged = "https://github.com/rordenlab/dcm2niix/releases"
449- instructions = "https://github.com/rordenlab/dcm2niix#install"
450- no_dcm2niix = f"""Unable to locate Dcm2niix on your system $PATH or using the path specified in
451- $HOME/.pypet2bidsconfig. Installation instructions for dcm2niix can be found here
452- { instructions }
453- and packaged versions can be found at
454- { pkged }
455- Alternatively, you can set the path to dcm2niix in the config file at $HOME/.pet2bidsconfig
456- using the command dcm2niix4pet --set-dcm2niix-path."""
457- logger .error (no_dcm2niix )
458- dcm2niix_path = None
495+ # determine if osx or linux
496+ dcm2niix_path = use_included_binary ()
497+
498+ if not dcm2niix_path :
499+ pkged = "https://github.com/rordenlab/dcm2niix/releases"
500+ instructions = "https://github.com/rordenlab/dcm2niix#install"
501+ no_dcm2niix = f"""Unable to locate Dcm2niix on your system $PATH or using the path specified in
502+ $HOME/.pypet2bidsconfig. Installation instructions for dcm2niix can be found here
503+ { instructions }
504+ and packaged versions can be found at
505+ { pkged }
506+ Alternatively, you can set the path to dcm2niix in the config file at $HOME/.pet2bidsconfig
507+ using the command dcm2niix4pet --set-dcm2niix-path."""
508+ logger .error (no_dcm2niix )
509+ dcm2niix_path = None
459510
460511 return dcm2niix_path
461512
@@ -465,8 +516,8 @@ def check_for_dcm2niix(self):
465516
466517 :return: status code of the command dcm2niix -h
467518 """
468-
469- if system (). lower () != "windows" :
519+ operating_system = system (). lower ()
520+ if operating_system != "windows" :
470521 dcm2niix_path = self .check_posix ()
471522 # fall back and check the config file if it's not on the path
472523 if not dcm2niix_path :
0 commit comments