class_docstr: Prediction pipeline:
  - receives a patched patient image (n_patches, c, y, x, (z)) from patient data loader.
  - forwards patches through model in chunks of batch_size. (method: batch_tiling_forward)
  - unmolds predictions (boxes and segmentations) to original patient coordinates. (method: spatial_tiling_forward)
  
  Ensembling (mode == 'test'):
  - for inference, forwards 4 mirrored versions of image to through model and unmolds predictions afterwards
    accordingly (method: data_aug_forward)
  - for inference, loads multiple parameter-sets of the trained model corresponding to different epochs. for each
    parameter-set loops over entire test set, runs prediction pipeline for each patient. (method: predict_test_set)
  
  Consolidation of predictions:
  - consolidates a patient's predictions (boxes, segmentations) collected over patches, data_aug- and temporal ensembling,
    performs clustering and weighted averaging (external function: apply_wbc_to_patient) to obtain consistent outptus.
  - for 2D networks, consolidates box predictions to 3D cubes via clustering (adaption of non-maximum surpression).
    (external function: merge_2D_to_3D_preds_per_patient)
  
  Ground truth handling:
  - dissmisses any ground truth boxes returned by the model (happens in validation mode, patch-based groundtruth)
  - if provided by data loader, adds 3D ground truth to the final predictions to be passed to the evaluator.
class_docstr_tok: ["Prediction","pipeline",":","-","receives","a","patched","patient","image","(","n_patches",",","c",",","y",",","x",",","(","z",")",")","from","patient","data","loader",".","-","forwards","patches","through","model","in","chunks","of","batch_size",".","(","method",":","batch_tiling_forward",")","-","unmolds","predictions","(","boxes","and","segmentations",")","to","original","patient","coordinates",".","(","method",":","spatial_tiling_forward",")","Ensembling","(","mode","==","'test","'",")",":","-","for","inference",",","forwards","4","mirrored","versions","of","image","to","through","model","and","unmolds","predictions","afterwards","accordingly","(","method",":","data_aug_forward",")","-","for","inference",",","loads","multiple","parameter-sets","of","the","trained","model","corresponding","to","different","epochs",".","for","each","parameter-set","loops","over","entire","test","set",",","runs","prediction","pipeline","for","each","patient",".","(","method",":","predict_test_set",")","Consolidation","of","predictions",":","-","consolidates","a","patient","'s","predictions","(","boxes",",","segmentations",")","collected","over","patches",",","data_aug-","and","temporal","ensembling",",","performs","clustering","and","weighted","averaging","(","external","function",":","apply_wbc_to_patient",")","to","obtain","consistent","outptus",".","-","for","2D","networks",",","consolidates","box","predictions","to","3D","cubes","via","clustering","(","adaption","of","non-maximum","surpression",")",".","(","external","function",":","merge_2D_to_3D_preds_per_patient",")","Ground","truth","handling",":","-","dissmisses","any","ground","truth","boxes","returned","by","the","model","(","happens","in","validation","mode",",","patch-based","groundtruth",")","-","if","provided","by","data","loader",",","adds","3D","ground","truth","to","the","final","predictions","to","be","passed","to","the","evaluator","."]
docstr: predicts one patient.
  called either directly via loop over validation set in exec.py (mode=='val')
  or from self.predict_test_set (mode=='test).
  in val mode:  adds 3D ground truth info to predictions and runs consolidation and 2Dto3D merging of predictions.
  in test mode: returns raw predictions (ground truth addition, consolidation, 2D to 3D merging are
                done in self.predict_test_set, because patient predictions across several epochs might be needed
                to be collected first, in case of temporal ensembling).
  :return. results_dict: stores the results for one patient. dictionary with keys:
           - 'boxes': list over batch elements. each element is a list over boxes, where each box is
                      one dictionary: [[box_0, ...], [box_n,...]]. batch elements are slices for 2D predictions
                      (if not merged to 3D), and a dummy batch dimension of 1 for 3D predictions.
           - 'seg_preds': pixel-wise predictions. (b, 1, y, x, (z))
           - monitor_values (only in validation mode)
docstr_tok: ["predicts","one","patient",".","called","either","directly","via","loop","over","validation","set","in","exec.py","(","mode=='val","'",")","or","from","self.predict_test_set","(","mode=='test",")",".","in","val","mode",":","adds","3D","ground","truth","info","to","predictions","and","runs","consolidation","and","2Dto3D","merging","of","predictions",".","in","test","mode",":","returns","raw","predictions","(","ground","truth","addition",",","consolidation",",","2D","to","3D","merging","are","done","in","self.predict_test_set",",","because","patient","predictions","across","several","epochs","might","be","needed","to","be","collected","first",",","in","case","of","temporal","ensembling",")",".",":","return",".","results_dict",":","stores","the","results","for","one","patient",".","dictionary","with","keys",":","-","'boxes","'",":","list","over","batch","elements",".","each","element","is","a","list","over","boxes",",","where","each","box","is","one","dictionary",":","[","[","box_0",",","...","]",",","[","box_n",",","...","]","]",".","batch","elements","are","slices","for","2D","predictions","(","if","not","merged","to","3D",")",",","and","a","dummy","batch","dimension","of","1","for","3D","predictions",".","-","'seg_preds","'",":","pixel-wise","predictions",".","(","b",",","1",",","y",",","x",",","(","z",")",")","-","monitor_values","(","only","in","validation","mode",")"]
code: def predict_patient(self, batch):
      """
      predicts one patient.
      called either directly via loop over validation set in exec.py (mode=='val')
      or from self.predict_test_set (mode=='test).
      in val mode:  adds 3D ground truth info to predictions and runs consolidation and 2Dto3D merging of predictions.
      in test mode: returns raw predictions (ground truth addition, consolidation, 2D to 3D merging are
                    done in self.predict_test_set, because patient predictions across several epochs might be needed
                    to be collected first, in case of temporal ensembling).
      :return. results_dict: stores the results for one patient. dictionary with keys:
               - 'boxes': list over batch elements. each element is a list over boxes, where each box is
                          one dictionary: [[box_0, ...], [box_n,...]]. batch elements are slices for 2D predictions
                          (if not merged to 3D), and a dummy batch dimension of 1 for 3D predictions.
               - 'seg_preds': pixel-wise predictions. (b, 1, y, x, (z))
               - monitor_values (only in validation mode)
      """
      self.logger.info(
          "evaluating patient {} for fold {} ".format(
              batch["pid"], self.cf.fold
          )
      )
  
      # True if patient is provided in patches and predictions need to be tiled.
      self.patched_patient = (
          True if "patch_crop_coords" in list(batch.keys()) else False
      )
  
      # forward batch through prediction pipeline.
      results_dict = self.data_aug_forward(batch)
  
      if self.mode == "val":
          for b in range(batch["patient_bb_target"].shape[0]):
              for t in range(len(batch["patient_bb_target"][b])):
                  results_dict["boxes"][b].append(
                      {
                          "box_coords": batch["patient_bb_target"][b][
                              t
                          ],
                          "box_label": batch["patient_roi_labels"][b][
                              t
                          ],
                          "box_type": "gt",
                      }
                  )
  
          if self.patched_patient:
              wcs_input = [
                  results_dict["boxes"],
                  "dummy_pid",
                  self.cf.class_dict,
                  self.cf.wcs_iou,
                  self.n_ens,
              ]
              results_dict["boxes"] = apply_wbc_to_patient(wcs_input)[0]
  
          if self.cf.merge_2D_to_3D_preds:
              merge_dims_inputs = [
                  results_dict["boxes"],
                  "dummy_pid",
                  self.cf.class_dict,
                  self.cf.merge_3D_iou,
              ]
              results_dict["boxes"] = merge_2D_to_3D_preds_per_patient(
                  merge_dims_inputs
              )[0]
  
      return results_dict
  
imports: import os
  import numpy
  import torch
  from scipy.stats import norm
  from collections import OrderedDict
  from multiprocessing import Pool
  import pickle
  import pandas
label_desc: Use image node_id 2 for calling the Predictor obj's underlying member method code with example usage: obj.predict_patient(batch) and returns: results_dict