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: in val_mode: passes batch through to spatial_tiling method without data_aug.
  in test_mode: if cf.test_aug is set in configs, createst 4 mirrored versions of the input image,
  passes all of them to the next processing step (spatial_tiling method) and re-transforms returned predictions
  to original image version.
  :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,
                      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: ["in","val_mode",":","passes","batch","through","to","spatial_tiling","method","without","data_aug",".","in","test_mode",":","if","cf.test_aug","is","set","in","configs",",","createst","4","mirrored","versions","of","the","input","image",",","passes","all","of","them","to","the","next","processing","step","(","spatial_tiling","method",")","and","re-transforms","returned","predictions","to","original","image","version",".",":","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",",","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 data_aug_forward(self, batch):
      """
      in val_mode: passes batch through to spatial_tiling method without data_aug.
      in test_mode: if cf.test_aug is set in configs, createst 4 mirrored versions of the input image,
      passes all of them to the next processing step (spatial_tiling method) and re-transforms returned predictions
      to original image version.
      :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,
                          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)
      """
      patch_crops = (
          batch["patch_crop_coords"] if self.patched_patient else None
      )
      results_list = [self.spatial_tiling_forward(batch, patch_crops)]
      org_img_shape = batch["original_img_shape"]
  
      if self.mode == "test" and self.cf.test_aug:
          if self.patched_patient:
              # apply mirror transformations to patch-crop coordinates, for correct tiling in spatial_tiling method.
              mirrored_patch_crops = get_mirrored_patch_crops(
                  patch_crops, batch["original_img_shape"]
              )
          else:
              mirrored_patch_crops = [None] * 3
  
          img = np.copy(batch["data"])
  
          # first mirroring: y-axis.
          batch["data"] = np.flip(img, axis=2).copy()
          chunk_dict = self.spatial_tiling_forward(
              batch, mirrored_patch_crops[0], n_aug="1"
          )
          # re-transform coordinates.
          for ix in range(len(chunk_dict["boxes"])):
              for boxix in range(len(chunk_dict["boxes"][ix])):
                  coords = chunk_dict["boxes"][ix][boxix][
                      "box_coords"
                  ].copy()
                  coords[0] = (
                      org_img_shape[2]
                      - chunk_dict["boxes"][ix][boxix]["box_coords"][2]
                  )
                  coords[2] = (
                      org_img_shape[2]
                      - chunk_dict["boxes"][ix][boxix]["box_coords"][0]
                  )
                  assert coords[2] >= coords[0], [
                      coords,
                      chunk_dict["boxes"][ix][boxix][
                          "box_coords"
                      ].copy(),
                  ]
                  assert coords[3] >= coords[1], [
                      coords,
                      chunk_dict["boxes"][ix][boxix][
                          "box_coords"
                      ].copy(),
                  ]
                  chunk_dict["boxes"][ix][boxix]["box_coords"] = coords
          # re-transform segmentation predictions.
          chunk_dict["seg_preds"] = np.flip(
              chunk_dict["seg_preds"], axis=2
          )
          results_list.append(chunk_dict)
  
          # second mirroring: x-axis.
          batch["data"] = np.flip(img, axis=3).copy()
          chunk_dict = self.spatial_tiling_forward(
              batch, mirrored_patch_crops[1], n_aug="2"
          )
          # re-transform coordinates.
          for ix in range(len(chunk_dict["boxes"])):
              for boxix in range(len(chunk_dict["boxes"][ix])):
                  coords = chunk_dict["boxes"][ix][boxix][
                      "box_coords"
                  ].copy()
                  coords[1] = (
                      org_img_shape[3]
                      - chunk_dict["boxes"][ix][boxix]["box_coords"][3]
                  )
                  coords[3] = (
                      org_img_shape[3]
                      - chunk_dict["boxes"][ix][boxix]["box_coords"][1]
                  )
                  assert coords[2] >= coords[0], [
                      coords,
                      chunk_dict["boxes"][ix][boxix][
                          "box_coords"
                      ].copy(),
                  ]
                  assert coords[3] >= coords[1], [
                      coords,
                      chunk_dict["boxes"][ix][boxix][
                          "box_coords"
                      ].copy(),
                  ]
                  chunk_dict["boxes"][ix][boxix]["box_coords"] = coords
          # re-transform segmentation predictions.
          chunk_dict["seg_preds"] = np.flip(
              chunk_dict["seg_preds"], axis=3
          )
          results_list.append(chunk_dict)
  
          # third mirroring: y-axis and x-axis.
          batch["data"] = np.flip(np.flip(img, axis=2), axis=3).copy()
          chunk_dict = self.spatial_tiling_forward(
              batch, mirrored_patch_crops[2], n_aug="3"
          )
          # re-transform coordinates.
          for ix in range(len(chunk_dict["boxes"])):
              for boxix in range(len(chunk_dict["boxes"][ix])):
                  coords = chunk_dict["boxes"][ix][boxix][
                      "box_coords"
                  ].copy()
                  coords[0] = (
                      org_img_shape[2]
                      - chunk_dict["boxes"][ix][boxix]["box_coords"][2]
                  )
                  coords[2] = (
                      org_img_shape[2]
                      - chunk_dict["boxes"][ix][boxix]["box_coords"][0]
                  )
                  coords[1] = (
                      org_img_shape[3]
                      - chunk_dict["boxes"][ix][boxix]["box_coords"][3]
                  )
                  coords[3] = (
                      org_img_shape[3]
                      - chunk_dict["boxes"][ix][boxix]["box_coords"][1]
                  )
                  assert coords[2] >= coords[0], [
                      coords,
                      chunk_dict["boxes"][ix][boxix][
                          "box_coords"
                      ].copy(),
                  ]
                  assert coords[3] >= coords[1], [
                      coords,
                      chunk_dict["boxes"][ix][boxix][
                          "box_coords"
                      ].copy(),
                  ]
                  chunk_dict["boxes"][ix][boxix]["box_coords"] = coords
          # re-transform segmentation predictions.
          chunk_dict["seg_preds"] = np.flip(
              np.flip(chunk_dict["seg_preds"], axis=2), axis=3
          ).copy()
          results_list.append(chunk_dict)
  
          batch["data"] = img
  
      # aggregate all boxes/seg_preds per batch element from data_aug predictions.
      results_dict = {}
      results_dict["boxes"] = [
          [
              item
              for d in results_list
              for item in d["boxes"][batch_instance]
          ]
          for batch_instance in range(org_img_shape[0])
      ]
      results_dict["seg_preds"] = np.array(
          [
              [
                  item
                  for d in results_list
                  for item in d["seg_preds"][batch_instance]
              ]
              for batch_instance in range(org_img_shape[0])
          ]
      )
      if self.mode == "val":
          results_dict["monitor_values"] = results_list[0][
              "monitor_values"
          ]
  
      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 5 for calling the Predictor obj's underlying member method code with example usage: obj.data_aug_forward(batch) and returns: results_dict