o
    i                     @  s   d dl mZ d dlZd dlZd dlZd dlmZ d dlZd dlm	Z
 d dlmZmZmZ d dlmZ d dlmZmZ d dlmZ ed	d
d\ZZed	dd\ZZeddd\ZZed\ZZejjeZdgZ G dd dZ!dS )    )annotationsN)Any)
NNUNETMode)analyze_datacreate_new_data_copycreate_new_dataset_json)ConfigParser)ensure_tupleoptional_import)run_cmdz4batchgenerators.utilities.file_and_folder_operationsload_pickle)namejointqdmnibabelnnUNetV2Runnerc                   @  s  e Zd ZdZ			ddddZdd ZddddZ					ddd!d"Z	#	$	%		&ddd-d.Ze	j
e	je	jfd/d&dfdd2d3Zdd$dddd#d$d%dd&e	j
e	je	jfd/dfdd5d6Zddd=d>Zd?d@ Ze	je	j
e	je	jfdfddEdFZe	je	j
e	je	jfdfddHdIZe	je	j
e	je	jfdfddJdKZddLdMZe	je	j
e	je	jffddNdOZd&e	j
e	je	je	jfdddddPdfddZd[Z		\							]		^	7			7dddqdrZ	P			dddvdwZ					ddd}d~ZdS )r   a  
    ``nnUNetV2Runner`` provides an interface in MONAI to use `nnU-Net` V2 library to analyze, train, and evaluate
    neural networks for medical image segmentation tasks.
    A version of nnunetv2 higher than 2.2 is needed for this class.

    ``nnUNetV2Runner`` can be used in two ways:

    #. with one line of code to execute the complete pipeline.
    #. with a series of commands to run each modules in the pipeline.

    The output of the interface is a directory that contains:

    #. converted dataset met the requirement of nnU-Net V2
    #. data analysis results
    #. checkpoints from the trained U-Net models
    #. validation accuracy in each fold of cross-validation
    #. the predictions on the testing datasets from the final algorithm ensemble and potential post-processing

    Args:
        input_config: the configuration dictionary or the file path to the configuration in the form of YAML.
            The keys required in the configuration are:
            - ``"datalist"``: File path to the datalist for the train/testing splits
            - ``"dataroot"``: File path to the dataset
            - ``"modality"``: Imaging modality, e.g. "CT", ["T2", "ADC"]
            Currently, the configuration supports these optional keys:
            - ``"nnunet_raw"``: File path that will be written to env variable for nnU-Net
            - ``"nnunet_preprocessed"``: File path that will be written to env variable for nnU-Net
            - ``"nnunet_results"``: File path that will be written to env variable for nnU-Net
            - ``"nnUNet_trained_models"``
            - ``"dataset_name_or_id"``: Name or Integer ID of the dataset
            If an optional key is not specified, then the pipeline will use the default values.
        trainer_class_name: the trainer class names offered by nnUNetV2 exhibit variations in training duration.
            Default: "nnUNetTrainer". Other options: "nnUNetTrainer_Xepoch". X could be one of 1,5,10,20,50,100,
            250,2000,4000,8000.
        export_validation_probabilities: True to save softmax predictions from final validation as npz
            files (in addition to predicted segmentations). Needed for finding the best ensemble.
            Default: True.
        work_dir: working directory to save the intermediate and final results.

    Examples:
        - Use the one-liner to start the nnU-Net workflow

        .. code-block:: bash

            python -m monai.apps.nnunet nnUNetV2Runner run --input_config ./input.yaml

        - Use `convert_dataset` to prepare the data to meet nnU-Net requirements, generate dataset JSON file,
            and copy the dataset to a location specified by ``nnunet_raw`` in the input config file

        .. code-block:: bash

            python -m monai.apps.nnunet nnUNetV2Runner convert_dataset --input_config="./input.yaml"

        - `convert_msd_dataset` is an alternative option to prepare the data if the dataset is MSD.

        .. code-block:: bash

            python -m monai.apps.nnunet nnUNetV2Runner convert_msd_dataset \
                --input_config "./input.yaml" --data_dir "/path/to/Task09_Spleen"

        - experiment planning and data pre-processing

        .. code-block:: bash

            python -m monai.apps.nnunet nnUNetV2Runner plan_and_process --input_config "./input.yaml"

        - training all 20 models using all GPUs available.
            "CUDA_VISIBLE_DEVICES" environment variable is not supported.

        .. code-block:: bash

            python -m monai.apps.nnunet nnUNetV2Runner train --input_config "./input.yaml"

        - training a single model on a single GPU for 5 epochs. Here ``config`` is used to specify the configuration.

        .. code-block:: bash

            python -m monai.apps.nnunet nnUNetV2Runner train_single_model --input_config "./input.yaml" \
                --config "3d_fullres" \
                --fold 0 \
                --gpu_id 0 \
                --trainer_class_name "nnUNetTrainer_5epochs" \
                --export_validation_probabilities True

        - training for all 20 models (4 configurations by 5 folds) on 2 GPUs

        .. code-block:: bash

            python -m monai.apps.nnunet nnUNetV2Runner train --input_config "./input.yaml" --gpu_id_for_all "0,1"

        - 5-fold training for a single model on 2 GPUs. Here ``configs`` is used to specify the configurations.

        .. code-block:: bash

            python -m monai.apps.nnunet nnUNetV2Runner train --input_config "./input.yaml" \
                --configs "3d_fullres" \
                --trainer_class_name "nnUNetTrainer_5epochs" \
                --export_validation_probabilities True \
                --gpu_id_for_all "0,1"

        - find the best configuration

        .. code-block:: bash

            python -m monai.apps.nnunet nnUNetV2Runner find_best_configuration --input_config "./input.yaml"

        - predict, ensemble, and post-process

        .. code-block:: bash

            python -m monai.apps.nnunet nnUNetV2Runner predict_ensemble_postprocessing --input_config "./input.yaml"

    nnUNetTrainerwork_dirTinput_configr   trainer_class_namestrexport_validation_probabilitiesboolreturnNonec                 C  s  i | _ || _|| _|| _|| _t| jtr| j| _ nt| jtr/tj	
| jr/t| j| _ nt| d| j dtj	d| jd| _| j dtj	d| jd| _| j dtj	d| jd| _tj	| jspt| j tj	| js}t| j tj	| jst| j | jtjd	< | jtjd< | jtjd
< tdtjd< t| j dd| _zddlm} |t| j| _W n ty   td| j d Y nw ddlm} || _d| _ i | _!d S )Nz is not a valid file or dict
nnunet_raw.ZnnUNet_raw_data_basennunet_preprocessednnUNet_preprocessednnunet_resultsZnnUNet_trained_modelsZ
nnUNet_rawnnUNet_results   ZOMP_NUM_THREADSdataset_name_or_idr   maybe_convert_to_dataset_namezDataset with name/ID: z cannot be found in the record. Please ignore the message above if you are running the pipeline from a fresh start. But if the dataset is expected to be found, please check your input_config.)default_num_processes   )"
input_infoZinput_config_or_dictr   r   r   
isinstancedictr   ospathisfiler   load_config_file
ValueErrorpopr   r   r   r   existsmakedirsenvironr"   -nnunetv2.utilities.dataset_name_id_conversionr$   intdataset_nameBaseExceptionloggerwarningZnnunetv2.configurationr%   	num_foldsbest_configuration)selfr   r   r   r   r$   r%    r<   c/home/dell461/cl/sdc2/last_ska_mid/HISourceFinder-master-l/src/monai/apps/nnunet/nnunetv2_runner.py__init__   sP   

znnUNetV2Runner.__init__c              
   C  sN  z	t t| jd }d|dd  }t| j d}dd |D }dd |D }||v r6td	 W dS | jd
}|d t	j
krI|dd }|d |t	j
d  }t	j| j|}t	j|sht	| ddlm} |t| j| _t| jd}d|v rt	t	j|d t	t	j|d ntd W dS d}d|v sd|v rt	t	j|d d|v rdnd}t|| d trd|| d v rt	t	j|d t||d\}	}
| jd}t|ts|g}t||
|	t|d t	j|dd t||||	|d W dS  ty& } ztd|  W Y d}~dS d}~ww )zQConvert and make a copy the dataset to meet the requirements of nnU-Net workflow.i  DatasetNz/*c                 S  s   g | ]
}| tjd  qS ))splitr*   sep.0_itemr<   r<   r=   
<listcomp>   s    z2nnUNetV2Runner.convert_dataset.<locals>.<listcomp>c                 S  s   g | ]	}| d d qS )_r   )rB   rD   r<   r<   r=   rG      s    z Dataset with the same ID exists!datarootrA   rH   r   r#   datalisttrainingZimagesTrZlabelsTrzHThe datalist file has incorrect format: the `training` key is not found.testtestingimagesTslabelZlabelsTs)datalist_jsondata_dirmodalityzdataset.json)rR   num_foreground_classesnum_input_channelsZnum_training_dataZoutput_filepath)test_keyrP   rQ   rT   Zoutput_datafolderzIInput config may be incorrect. Detail info: error/exception message is:
 )r   r4   r"   globr   r7   r8   r'   r/   r*   rC   rB   r+   r   r0   r1   r3   r$   r5   r   r-   errorr(   r)   r   listr   lenr   r6   )r;   Zraw_data_foldername_prefixsubdirsZdataset_idsrQ   Zraw_data_foldernamer$   rP   rU   rT   rS   rR   errr<   r<   r=   convert_dataset   sj   


"

znnUNetV2Runner.convert_datasetNrA   rQ   overwrite_id
str | Nonen_procr4   c                 C  s.   ddl m} |dk rdn| j}|||| dS )a  
        Convert and make a copy the MSD dataset to meet requirements of nnU-Net workflow.

        Args:
            data_dir: downloaded and extracted MSD dataset folder. CANNOT be nnUNetv1 dataset!
                Example: "/workspace/downloads/Task05_Prostate".
            overwrite_id: Overwrite the dataset id. If not set then use the id of the MSD task (inferred from
                the folder name). Only use this if you already have an equivalently numbered dataset!
            n_proc: Number of processes used.
        r   )convert_msd_datasetN)Z/nnunetv2.dataset_conversion.convert_MSD_datasetr`   r%   )r;   rQ   r]   r_   r`   num_processesr<   r<   r=   r`     s   z"nnUNetV2Runner.convert_msd_datasetDatasetFingerprintExtractorFfpenpfpverify_dataset_integritycleanverbosec                 C  sF   ddl m} |dk r| jn|}td |t| jg||||| dS )aW  
        Extracts the dataset fingerprint used for experiment planning.

        Args:
            fpe: [OPTIONAL] Name of the Dataset Fingerprint Extractor class that should be used. Default is
                "DatasetFingerprintExtractor".
            npfp: [OPTIONAL] Number of processes used for fingerprint extraction.
            verify_dataset_integrity: [RECOMMENDED] set this flag to check the dataset integrity. This is
                useful and should be done once for each dataset!
            clean: [OPTIONAL] Set this flag to overwrite existing fingerprints. If this flag is not set and a
                fingerprint already exists, the fingerprint extractor will not run.
            verbose: set this to print a lot of stuff. Useful for debugging. Will disable progress bar!
                Recommended for cluster environments.
        r   )extract_fingerprintszFingerprint extraction...N)4nnunetv2.experiment_planning.plan_and_preprocess_apirh   r%   r7   infor4   r"   )r;   rc   rd   re   rf   rg   rh   r<   r<   r=   rh   ,  s   
z#nnUNetV2Runner.extract_fingerprintsExperimentPlanner   DefaultPreprocessornnUNetPlansplgpu_memory_targetfloatpreprocessor_nameoverwrite_target_spacingoverwrite_plans_namec                 C  s4   ddl m} td |t| jg||||| dS )at  
        Generate a configuration file that specifies the details of the experiment.

        Args:
            pl: [OPTIONAL] Name of the Experiment Planner class that should be used. Default is "ExperimentPlanner".
                Note: There is no longer a distinction between 2d and 3d planner. It's an all-in-one solution now.
            gpu_memory_target: [OPTIONAL] DANGER ZONE! Sets a custom GPU memory target. Default: 8 [GB].
                Changing this will affect patch and batch size and will definitely affect your models' performance!
                Only use this if you really know what you are doing and NEVER use this without running the
                default nnU-Net first (as a baseline).
            preprocessor_name: [OPTIONAL] DANGER ZONE! Sets a custom preprocessor class. This class must be located in
                nnunetv2.preprocessing. Default: "DefaultPreprocessor". Changing this may affect your models'
                performance! Only use this if you really know what you are doing and NEVER use this without running the
                default nnU-Net first (as a baseline).
            overwrite_target_spacing: [OPTIONAL] DANGER ZONE! Sets a custom target spacing for the 3d_fullres
                and 3d_cascade_fullres configurations. Default: None [no changes]. Changing this will affect
                image size and potentially patch and batch size. This will definitely affect your models' performance!
                Only use this if you really know what you are doing and NEVER use this without running the
                default nnU-Net first (as a baseline). Changing the target spacing for the other configurations
                is currently not implemented. New target spacing must be a list of three numbers!
            overwrite_plans_name: [OPTIONAL] DANGER ZONE! If you used -gpu_memory_target, -preprocessor_name or
                -overwrite_target_spacing it is best practice to use -overwrite_plans_name to generate
                a differently named plans file such that the nnunet default plans are not overwritten.
                You will then need to specify your custom plan.
        r   )plan_experimentszExperiment planning...N)ri   ru   r7   rj   r4   r"   )r;   ro   rp   rr   rs   rt   ru   r<   r<   r=   ru   I  s   !

znnUNetV2Runner.plan_experiments)rl   rl   rl   ctuplec                 C  s4   ddl m} td |t| jg||||d dS )a  
        Apply a set of preprocessing operations to the input data before the training.

        Args:
            overwrite_plans_name: [OPTIONAL] You can use this to specify a custom plans file that you may have
                generated.
            c: [OPTIONAL] Configurations for which the preprocessing should be run. Default: 2d 3f_fullres
                3d_lowres. 3d_cascade_fullres does not need to be specified because it uses the data
                from 3f_fullres. Configurations that do not exist for some datasets will be skipped).
            n_proc: [OPTIONAL] Use this to define how many processes are to be used. If this is just one number then
                this number of processes is used for all configurations specified with -c. If it's a
                list of numbers this list must have as many elements as there are configurations. We
                then iterate over zip(configs, num_processes) to determine the number of processes
                used for each configuration. More processes are always faster (up to the number of
                threads your PC can support, so 8 for a 4-core CPU with hyperthreading. If you don't
                know what that is then don't touch it, or at least don't increase it!). DANGER: More
                often than not the number of processes that can be used is limited by the amount of
                RAM available. Image resampling takes up a lot of RAM. MONITOR RAM USAGE AND
                DECREASE -n_proc IF YOUR RAM FILLS UP TOO MUCH! Default: 8 4 8 (=8 processes for 2d, 4
                for 3d_fullres and 8 for 3d_lowres if -c is at its default).
            verbose: Set this to print a lot of stuff. Useful for debugging. Will disable the progress bar!
                Recommended for cluster environments.
        r   )
preprocesszPreprocessing...)configurationsra   rg   N)ri   rx   r7   rj   r4   r"   )r;   rv   r_   rt   rg   rx   r<   r<   r=   rx   v  s   


znnUNetV2Runner.preprocessno_ppc                 C  s@   |  ||||| | ||||	|
 |s| |||
| dS dS )a_  
        Performs experiment planning and preprocessing before the training.

        Args:
            fpe: [OPTIONAL] Name of the Dataset Fingerprint Extractor class that should be used. Default is
                "DatasetFingerprintExtractor".
            npfp: [OPTIONAL] Number of processes used for fingerprint extraction. Default: 8.
            verify_dataset_integrity: [RECOMMENDED] set this flag to check the dataset integrity.
                This is useful and should be done once for each dataset!
            no_pp: [OPTIONAL] Set this to only run fingerprint extraction and experiment planning (no
                preprocessing). Useful for debugging.
            clean:[OPTIONAL] Set this flag to overwrite existing fingerprints. If this flag is not set and a
                fingerprint already exists, the fingerprint extractor will not run. REQUIRED IF YOU
                CHANGE THE DATASET FINGERPRINT EXTRACTOR OR MAKE CHANGES TO THE DATASET!
            pl: [OPTIONAL] Name of the Experiment Planner class that should be used. Default is "ExperimentPlanner".
                Note: There is no longer a distinction between 2d and 3d planner. It's an all-in-one solution now.
            gpu_memory_target: [OPTIONAL] DANGER ZONE! Sets a custom GPU memory target. Default: 8 [GB].
                Changing this will affect patch and batch size and will
                definitely affect your models' performance! Only use this if you really know what you
                are doing and NEVER use this without running the default nnU-Net first (as a baseline).
            preprocessor_name: [OPTIONAL] DANGER ZONE! Sets a custom preprocessor class. This class must be located in
                nnunetv2.preprocessing. Default: "DefaultPreprocessor". Changing this may affect your
                models' performance! Only use this if you really know what you
                are doing and NEVER use this without running the default nnU-Net first (as a baseline).
            overwrite_target_spacing: [OPTIONAL] DANGER ZONE! Sets a custom target spacing for the 3d_fullres and
                3d_cascade_fullres configurations. Default: None [no changes]. Changing this will affect image size and
                potentially patch and batch size. This will definitely affect your models performance!
                Only use this if you really know what you are doing and NEVER use this without running the
                default nnU-Net first (as a baseline). Changing the target spacing for the other
                configurations is currently not implemented. New target spacing must be a list of three numbers!
            overwrite_plans_name: [OPTIONAL] USE A CUSTOM PLANS IDENTIFIER. If you used -gpu_memory_target,
                -preprocessor_name or -overwrite_target_spacing it is best practice to use -overwrite_plans_name to
                generate a differently named plans file such that the nnunet default plans are not
                overwritten. You will then need to specify your custom plans file with -p whenever
                running other nnunet commands (training, inference, etc)
            c: [OPTIONAL] Configurations for which the preprocessing should be run. Default: 2d 3f_fullres
                3d_lowres. 3d_cascade_fullres does not need to be specified because it uses the data
                from 3f_fullres. Configurations that do not exist for some datasets will be skipped.
            n_proc: [OPTIONAL] Use this to define how many processes are to be used. If this is just one number then
                this number of processes is used for all configurations specified with -c. If it's a
                list of numbers this list must have as many elements as there are configurations. We
                then iterate over zip(configs, num_processes) to determine the number of processes
                used for each configuration. More processes are always faster (up to the number of
                threads your PC can support, so 8 for a 4-core CPU with hyperthreading. If you don't
                know what that is then don't touch it, or at least don't increase it!). DANGER: More
                often than not the number of processes that can be used is limited by the amount of
                RAM available. Image resampling takes up a lot of RAM. MONITOR RAM USAGE AND
                DECREASE -n_proc IF YOUR RAM FILLS UP TOO MUCH! Default: 8 4 8 (=8 processes for 2d, 4
                for 3d_fullres and 8 for 3d_lowres if -c is at its default).
            verbose: Set this to print a lot of stuff. Useful for debugging. Will disable progress bar!
                (Recommended for cluster environments).
        N)rh   ru   rx   )r;   rc   rd   re   rz   rf   ro   rp   rr   rs   rt   rv   r_   rg   r<   r<   r=   plan_and_process  s
   DznnUNetV2Runner.plan_and_processr   configfoldgpu_idtuple | list | intkwargsc                 K  st   d|v r| d td d|v r| d td d|v r*| d td | ||||}t|dd d	S )
a  
        Run the training on a single GPU with one specified configuration provided.
        Note: this will override the environment variable `CUDA_VISIBLE_DEVICES`.

        Args:
            config: configuration that should be trained. Examples: "2d", "3d_fullres", "3d_lowres".
            fold: fold of the 5-fold cross-validation. Should be an int between 0 and 4.
            gpu_id: an integer to select the device to use, or a tuple/list of GPU device indices used for multi-GPU
                training (e.g., (0,1)). Default: 0.
            kwargs: this optional parameter allows you to specify additional arguments in
                ``nnunetv2.run.run_training.run_training_entry``.

                Currently supported args are:

                - p: custom plans identifier. Default: "nnUNetPlans".
                - pretrained_weights: path to nnU-Net checkpoint file to be used as pretrained model. Will only be
                    used when actually training. Beta. Use with caution. Default: False.
                - use_compressed: True to use compressed data for training. Reading compressed data is much
                    more CPU and (potentially) RAM intensive and should only be used if you know what you are
                    doing. Default: False.
                - c: continue training from latest checkpoint. Default: False.
                - val: True to run the validation only. Requires training to have finished.
                    Default: False.
                - disable_checkpointing: True to disable checkpointing. Ideal for testing things out and you
                    don't want to flood your hard drive with checkpoints. Default: False.
        num_gpusz(please use gpu_id to set the GPUs to usetrzLplease specify the `trainer_class_name` in the __init__ of `nnUNetV2Runner`.npzzYplease specify the `export_validation_probabilities` in the __init__ of `nnUNetV2Runner`.T)shellN)r/   r7   r8   train_single_model_commandr   )r;   r|   r}   r~   r   cmdr<   r<   r=   train_single_model  s   





z!nnUNetV2Runner.train_single_modelc                 C  s$  t |ttfr3t|dkr+d}tt|D ]}|||  d7 }qd|d d  }nd|d  }nd| }t |tsCt|dkrEdnt|}| d| j d| d| d d	| j d
|  }	| jrj|	d7 }	|	 D ]!\}
}|
dksz|
dkr|	d|
 d| 7 }	qn|	d|
 d| 7 }	qn|	S )Nr!    ,zCUDA_VISIBLE_DEVICES=rA   r   z nnUNetv2_train  z-tr z -num_gpus z --npzpZpretrained_weightsz -z --)
r(   rw   rX   rY   ranger4   r"   r   r   items)r;   r|   r}   r~   r   Zgpu_ids_str_idevice_settingr   r   _key_valuer<   r<   r=   r     s,   
"z)nnUNetV2Runner.train_single_model_commandconfigstuple | strgpu_id_for_alltuple | list | int | Nonec           	      K  s   |du r$t jddgt jd}|jd}t| d}tt	|}n	t
|tr-t|}tdt| d|  t|d	krO| jdt||d
| dS t|D ]}t	| jD ]}| jd|||d| qZqSdS )a  
        Run the training for all the models specified by the configurations.
        Note: to set the number of GPUs to use, use ``gpu_id_for_all`` instead of the `CUDA_VISIBLE_DEVICES`
        environment variable.

        Args:
            configs: configurations that should be trained.
                Default: ("2d", "3d_fullres", "3d_lowres", "3d_cascade_fullres").
            gpu_id_for_all: a tuple/list/integer of GPU device ID(s) to use for the training. Default:
                None (all available GPUs).
            kwargs: this optional parameter allows you to specify additional arguments defined in the
                ``train_single_model`` method.
        Nz
nvidia-smiz--list-gpus)stdoutzutf-8
znumber of GPUs is z, device ids are r!   r   r   )r|   r}   r~   r<   )
subprocessrunPIPEr   decoderY   striprB   rw   r   r(   r4   r	   r7   rj   train_parallelr9   r   )	r;   r   r   r   resultoutputr   cfg_foldr<   r<   r=   train.  s   
znnUNetV2Runner.trainrX   c              	   K  s@  g }t t j| j| jD ]\}}}tdd |D r!|| qddlm	} |D ]}	t
d|	 d ||	dd| jd	 q*|pBi }t|}
t|
}tjtjtjgtjgg}g }tt|D ]>}|d
d |
D  d}|| D ]+}|t|v rt| jD ]}|||  }| ||||}|d | | |d7 }q~qqq_|S )a  
        Create the line command for subprocess call for parallel training.

        Args:
            configs: configurations that should be trained.
                Default: ("2d", "3d_fullres", "3d_lowres", "3d_cascade_fullres").
            gpu_id_for_all: a tuple/list/integer of GPU device ID(s) to use for the training. Default:
                None (all available GPUs).
            kwargs: this optional parameter allows you to specify additional arguments defined in the
                ``train_single_model`` method.
        c                 s  s    | ]}| d V  qdS )z.npzN)endswith)rE   filer<   r<   r=   	<genexpr>d  s    z4nnUNetV2Runner.train_parallel_cmd.<locals>.<genexpr>r   )unpack_datasetzunpacking 'z'...TF)folderZunpack_segmentationZoverwrite_existingra   c                 S  s   i | ]}|g qS r<   r<   )rE   _jr<   r<   r=   
<dictcomp>y  s    z5nnUNetV2Runner.train_parallel_cmd.<locals>.<dictcomp>rA   r!   )r*   walkr+   r   r   r5   anyappendZ#nnunetv2.training.dataloading.utilsr   r7   rj   r%   r	   rY   MN_3D_FULLRESN_2DN_3D_LOWRESN_3D_CASCADE_FULLRESr   r9   r   )r;   r   r   r   Zfolder_namesrootrH   filesr   Zfolder_namedevices	n_devicesZ_configsall_cmdsZ_stage_index_configr   Z
the_devicer   r<   r<   r=   train_parallel_cmdP  s@   "

z!nnUNetV2Runner.train_parallel_cmdc                 K  s   | j d||d|}t|D ]+\}}| D ]"\}}|sqtd|d  d| d| dtj| j| j	 d	 qq|D ]6}	g }
|	D ]&}|	| sJqCd|	| }td	| d
| d |

tj|dtjd qC|
D ]}|  qlq=dS )a  
        Create the line command for subprocess call for parallel training.
        Note: to set the number of GPUs to use, use ``gpu_id_for_all`` instead of the `CUDA_VISIBLE_DEVICES`
        environment variable.

        Args:
            configs: configurations that should be trained.
                default: ("2d", "3d_fullres", "3d_lowres", "3d_cascade_fullres").
            gpu_id_for_all: a tuple/list/integer of GPU device ID(s) to use for the training. Default:
                None (all available GPUs).
            kwargs: this optional parameter allows you to specify additional arguments defined in the
                ``train_single_model`` method.
        r   ztraining - stage r!   z
:
for gpu z, commands: z
log '.txt' inside ''z; z&Current running command on GPU device z:
r   T)r   r   Nr<   )r   	enumerater   r7   rj   r*   r+   r   r   r5   r   r   PopenDEVNULLwait)r;   r   r   r   r   scmdsr~   Zgpu_cmdstage	processes	device_idZcmd_strr   r<   r<   r=   r     s6   
znnUNetV2Runner.train_parallelc                 K  s   | j d||dd| dS )al  
        Perform validation on single model.

        Args:
            config: configuration that should be trained.
            fold: fold of the 5-fold cross-validation. Should be an int between 0 and 4.
            kwargs: this optional parameter allows you to specify additional arguments defined in the
                ``train_single_model`` method.
        T)r|   r}   only_run_validationNr<   )r   )r;   r|   r}   r   r<   r<   r=   validate_single_model  s   
z$nnUNetV2Runner.validate_single_modelc                 K  s8   t |D ]}t| jD ]}| jd||d| qqdS )a  
        Perform validation in all models defined by the configurations over 5 folds.

        Args:
            configs: configurations that should be trained.
                default: ("2d", "3d_fullres", "3d_lowres", "3d_cascade_fullres").
            kwargs: this optional parameter allows you to specify additional arguments defined in the
                ``train_single_model`` method.
        )r|   r}   Nr<   )r	   r   r9   r   )r;   r   r   r   r   r<   r<   r=   validate  s
   znnUNetV2Runner.validater   r!            planstrainerstuple | str | Noneallow_ensemblingra   	overwritefoldslist[int] | tuple[int, ...]strictc	              	   C  st   ddl m}	m}
 t|}t|}|du r| j}t|}|	|||}|dk r(| jn|}|
t| j||||||d dS )aH  
        Find the best model configurations.

        Args:
            plans: list of plan identifiers. Default: nnUNetPlans.
            configs: list of configurations. Default: ["2d", "3d_fullres", "3d_lowres", "3d_cascade_fullres"].
            trainers: list of trainers. Default: nnUNetTrainer.
            allow_ensembling: set this flag to enable ensembling.
            num_processes: number of processes to use for ensembling, postprocessing, etc.
            overwrite: if set we will overwrite already ensembled files etc. May speed up consecutive
                runs of this command (not recommended) at the risk of not updating outdated results.
            folds: folds to use. Default: (0, 1, 2, 3, 4).
            strict: a switch that triggers RunTimeError if the logging folder cannot be found. Default: False.
        r   )0dumb_trainer_config_plans_to_trained_models_dictfind_best_configurationN)r   ra   r   r   r   )Z+nnunetv2.evaluation.find_best_configurationr   r   r	   r   r%   r4   r"   )r;   r   r   r   r   ra   r   r   r   r   r   modelsr<   r<   r=   r     s"   
z&nnUNetV2Runner.find_best_configuration      ?checkpoint_final.pthr!   list_of_lists_or_source_folderstr | list[list[str]]output_folderstr | None | list[str]model_training_output_dir	use_foldstuple[int, ...] | str | Nonetile_step_sizeuse_gaussianuse_mirroringperform_everything_on_gpusave_probabilitiescheckpoint_name folder_with_segs_from_prev_stage	num_partspart_idnum_processes_preprocessing!num_processes_segmentation_exportc                 C  s~   | t jd< ddlm} |dk r| jn|}|dk r| jn|}||||||	d}|j|||d |j|||
||||||d	 dS )a6
  
        Use this to run inference with nnU-Net. This function is used when you want to manually specify a folder containing
            a trained nnU-Net model. This is useful when the nnunet environment variables (nnUNet_results) are not set.

        Args:
            list_of_lists_or_source_folder: input folder. Remember to use the correct channel numberings for
                your files (_0000 etc). File endings must be the same as the training dataset!
            output_folder: Output folder. If it does not exist it will be created. Predicted segmentations will
                have the same name as their source images.
            model_training_output_dir: folder in which the trained model is. Must have subfolders fold_X for the
                different folds you trained.
            use_folds: specify the folds of the trained model that should be used for prediction
                Default: (0, 1, 2, 3, 4).
            tile_step_size: step size for sliding window prediction. The larger it is the faster but less accurate
                the prediction. Default: 0.5. Cannot be larger than 1. We recommend the default.
            use_gaussian: use Gaussian smoothing as test-time augmentation.
            use_mirroring: use mirroring/flipping as test-time augmentation.
            verbose: set this if you like being talked to. You will have to be a good listener/reader.
            save_probabilities: set this to export predicted class "probabilities". Required if you want to ensemble
                multiple configurations.
            overwrite: overwrite an existing previous prediction (will not overwrite existing files)
            checkpoint_name: name of the checkpoint you want to use. Default: checkpoint_final.pth.
            folder_with_segs_from_prev_stage: folder containing the predictions of the previous stage.
                Required for cascaded models.
            num_parts: number of separate nnUNetv2_predict call that you will be making. Default: 1 (= this one
                call predicts everything).
            part_id: if multiple nnUNetv2_predict exist, which one is this? IDs start with 0 can end with
                num_parts - 1. So when you submit 5 nnUNetv2_predict calls you need to set -num_parts
                5 and use -part_id 0, 1, 2, 3 and 4.
            num_processes_preprocessing: out-of-RAM issues.
            num_processes_segmentation_export: Number of processes used for segmentation export.
                More is not always better. Beware of out-of-RAM issues.
            gpu_id: which GPU to use for prediction.
        CUDA_VISIBLE_DEVICESr   )nnUNetPredictor)r   r   r   Zperform_everything_on_devicerg   )r   r   r   )	r   Z/output_folder_or_list_of_truncated_output_filesr   r   r   r   r   r   r   N)r*   r2   (nnunetv2.inference.predict_from_raw_datar   r%   Z$initialize_from_trained_model_folderZpredict_from_files)r;   r   r   r   r   r   r   r   r   rg   r   r   r   r   r   r   r   r   r~   r   Zn_processes_preprocessingZn_processes_segmentation_export	predictorr<   r<   r=   predict  s6   7
znnUNetV2Runner.predictrun_ensemblerun_predictrun_postprocessingc                 K  sn  ddl m} ddlm} ddlm} t| j| jd}	t| j	| j}
t
tj| j	| jd| _|o;t| jd d d	k}|}g }| jd d D ]3}t|
d
|d  }|| |rz|t| j|d |d |d }| jd|	||||ddd| qG|r||t|
ddd |rt|
d}n|r|d }|rt| jd d \}}||t|
d||| jd d d dS dS )a  
        Run prediction, ensemble, and/or postprocessing optionally.

        Args:
            folds: which folds to use
            run_ensemble: whether to run ensembling.
            run_predict: whether to predict using trained checkpoints
            run_postprocessing: whether to conduct post-processing
            kwargs: this optional parameter allows you to specify additional arguments defined in the
                ``predict`` method.
        r   )ensemble_folders)apply_postprocessing_to_folder)get_output_folderrN   zinference_information.jsonZbest_model_or_ensembleZselected_model_or_modelsr!   pred_configurationtrainerplans_identifierFT)r   r   r   r   r   rg   r   Zensemble_predictions)Zsave_merged_probabilitiesZpostprocessing_fileZ"ensemble_predictions_postprocessedZsome_plans_file)Zplans_file_or_dictNr<   )Znnunetv2.ensembling.ensembler   Z3nnunetv2.postprocessing.remove_connected_componentsr   Z&nnunetv2.utilities.file_path_utilitiesr   r   r   r5   r   r   r-   r*   r+   r:   rY   r   r4   r"   r   r   )r;   r   r   r   r   r   r   r   r   
source_dirZtarget_dir_baseZ
used_foldsZoutput_foldersim
output_dirmodel_folderZfolder_for_ppZpp_fnsZpp_fn_kwargsr<   r<   r=   predict_ensemble_postprocessingR  sd   


z.nnUNetV2Runner.predict_ensemble_postprocessingrun_convert_datasetrun_plan_and_process	run_trainrun_find_best_configuration#run_predict_ensemble_postprocessingc                 C  s@   |r|    |r|   |r|   |r|   |r|   dS )a  
        Run the nnU-Net pipeline.

        Args:
            run_convert_dataset: whether to convert datasets, defaults to True.
            run_plan_and_process: whether to preprocess and analyze the dataset, defaults to True.
            run_train: whether to train models, defaults to True.
            run_find_best_configuration: whether to find the best model (ensemble) configurations, defaults to True.
            run_predict_ensemble_postprocessing: whether to make predictions on test datasets, defaults to True.
        N)r\   r{   r   r   r   )r;   r   r   r  r  r  r<   r<   r=   r     s   znnUNetV2Runner.run)r   r   T)
r   r   r   r   r   r   r   r   r   r   )NrA   )rQ   r   r]   r^   r_   r4   r   r   )rb   rA   FFF)rc   r   rd   r4   re   r   rf   r   rg   r   r   r   )rk   rl   rm   Nrn   )ro   r   rp   rq   rr   r   rs   r   rt   r   r   r   )
rv   rw   r_   rw   rt   r   rg   r   r   r   )rc   r   rd   r4   re   r   rz   r   rf   r   ro   r   rp   r4   rr   r   rs   r   rt   r   rv   rw   r_   rw   rg   r   r   r   )r   )
r|   r   r}   r4   r~   r   r   r   r   r   )r   r   r   r   r   r   r   r   )r   r   r   r   r   r   r   rX   )r|   r   r}   r4   r   r   r   r   )r   rw   r   r   r   r   )r   r   r   r   r   r   r   r   ra   r4   r   r   r   r   r   r   r   r   )Nr   TTTTFTr   Nr!   r   rA   rA   r   )&r   r   r   r   r   r   r   r   r   rq   r   r   r   r   r   r   rg   r   r   r   r   r   r   r   r   r^   r   r4   r   r4   r   r4   r   r4   r~   r4   r   r   )r   TTT)r   rw   r   r   r   r   r   r   r   r   r   r   )TTTTT)r   r   r   r   r  r   r  r   r  r   r   r   )__name__
__module____qualname____doc__r>   r\   r`   rh   ru   r   r   r   r   rx   r{   r   r   r   r   r   r   r   r   r   r   r   r   r<   r<   r<   r=   r   %   s    u@D/+J*$7
)6YN)"
__future__r   rV   r*   r   typingr   monaiZmonai.apps.nnunet.utilsr   r   r   r   r   monai.bundler   monai.utilsr	   r
   monai.utils.miscr   r   rH   r   r   has_tqdmnibappsutils
get_loggerr  r7   __all__r   r<   r<   r<   r=   <module>   s$   