# -*- coding: utf-8 -*-
#  Default values are set internally, if the corresponding parameter is not found in the configuration file.

#  [Optional but highly suggested] The name will be used for saving the models,logs and results.
#  Default: "trainSession"
sessionName = "trainSessionDm"

#  [Required] The main folder that the output will be placed.
folderForOutput = "../../../output/"

#  [Optional] Path to a saved model, to load parameters from at beginning of the session. If one is also specified from command line, the latter will be used.
#cnnModelFilePath = "../../../output/models/placeholder"

#  [Optional] Log performance metrics for Tensorboard at end of subepochs. {True or False}
tensorboard_log = True


#  =======================Training=====================================

#  +++++++++++Input+++++++++++

#  [Required] A list that should contain as many entries as the channels of the input image (eg multi-modal MRI). The entries should be paths to files. Those files should be listing the paths to the corresponding channels for each training-case. (see example files).
channelsTraining = ["./trainChannels_flair.cfg", "./trainChannels_t1c.cfg"]

#  [Required] The path to a file which should list paths to the Ground Truth labels of each training case.
gtLabelsTraining = "./trainGtLabels.cfg"

#  [Optional] The path to a file, which should list paths to the Region-Of-Interest masks for each training case.
#  If ROI masks are provided, the training samples will be extracted only within it. Otherwise from whole volume.
roiMasksTraining = "./trainRoiMasks.cfg"

#  +++++++++++Sampling+++++++++++

#  [Optional] Type-of-Sampling to use for training. 
#  [Possible Values] 0 = Foreground / Background, 1 = Uniform, 2 = Whole Image (Not impl yet), 3 = Separately-Per-Class.
#  Note: In case of (2) Full Image, ensure you provide segmentsDimTrain in modelConfig.cfg at least as big as image dimensions (+CNN's receptive field if padding is used).
#  Default: 3
typeOfSamplingForTraining = 3

#  [Optional] List the proportion (0.0 to 1.0) of samples to extract from each category of samples.
#  Note: Depending on the Type-of-Sampling chosen, list must be of the form:
#  	>> Fore/Background: [proportion-of-FOREground-samples, proportion-of-BACKground-samples], eg [0.3, 0.7]. IMPORTANT: FOREground first, background second!
#  	>> Uniform or Full-Image: Not Applicable and disregarded if given.
#  	>> Separate sampling of each class: [proportion-of-class-0(background), ..., proportion-of-class-N]
#  Note: Values will be internally normalized (to add up to 1.0).
#  Default: Foreground/Background or Separately-Each-Class : equal number of segments extracted for each of the categories. Uniform or Full-Image: N/A
# proportionOfSamplesToExtractPerCategoryTraining = [1., 1., 1., 1., 1.]

#  [Optional] This variable allows providing weighted-maps to indicate where to extract more segments for each category of samples. Higher weight means more samples from that area.
#  The value provided should be a List with paths to files. As many files as the categories of samples for the chosen Sampling-Type.
#  Similarly to the files listing the Ground Truth, Channels, etc per subject, these files should list the paths to the weight-maps of each subject for the corresponding category.
#  Note: Number of files required: Fore/Backgr:2, Uniform:1, Full-Image:N/A, Separate each class:NumOfOutputClasses (Incl Backgr).
#  IMPORTANT: Sequence of weight-maps is important!
#  >> If Fore/Background type of sampling, provide for the FOREground first!
#  >> If Separately sampling each class, provide weightmap-files in the same sequence as the class-labels in your Ground Truth! Eg background-0 first, class-1 second, etc.
#  Default : If this variable is not provided, samples are extracted based on the Ground-Truth labels and the ROI. 
# weightedMapsForSamplingEachCategoryTrain = ["./placeholder_weightmap_foreground.cfg", "./placeholder_weightmap_background.cfg"]


#  +++++++++++Training Cycle (see documentation)+++++++++++

#  [Optionals but highly suggested as they are model dependent.]
#  How many epochs to train for. Default: 35
numberOfEpochs = 35
#  How many subepochs comprise an epoch. Every subepoch I get Accuracy reported. Default: 20
numberOfSubepochs = 20
#  Every subepoch, load the images from that many cases and extract new training samples. Default: 50
numOfCasesLoadedPerSubepoch = 50
#  Every subepoch, extract in total this many segments and load them on the GPU. Memory Limitated. Default: 1000
#  Note: This number in combination with the batchsize define the number of optimization steps per subepoch (=NumOfSegmentsOnGpu / BatchSize).
numberTrainingSegmentsLoadedOnGpuPerSubep = 1000

#  [Required] Batch size for training.
batchsize_train = 10

# Number of CPUs for sampling. -1: No parallelism. 0: One parallel thread. 1,2,3...: Parallel processes spawned. Default: 0
num_processes_sampling = 0

#  +++++++++++Learning Rate Schedule+++++++++++

#  [Optional] The type of schedule to use for Learning Rate annealing.
#  Schedule types:   'stable' : stable LR.      'predef' : lowering at predefines epochs.
#                    'poly' : lr=lr_base * (1-iter/max_iter) ^ 0.9 (from PSPNet)        'auto' : Lower LR when validation accuracy plateaus.
#  Note: LR schedule is important. We suggest running stable, observing when training error plateaus, and defined your "predefined schedule.
#        Otherwise, use poly with long-enough number of epoch.
#  Default: 'poly'
typeOfLearningRateSchedule = 'predef'

#  [Auto & Predefined] By how much to divide LR when lowering. Default: 2
whenDecreasingDivideLrBy = 2.0

#  [Req. for Predefined] At which epochs to lower LR.
predefinedSchedule = [17, 22, 27, 30, 33]

#  How many epochs to initially wait before decreasing LR first time. For 'auto', this period specifies when val accuracy has plateaued. Irrelevant for 'predef'.
numEpochsToWaitBeforeLoweringLr = 10

#  +++++++++++Data Augmentation+++++++++++++++

# [Optional] Augmentation applied on image-level. Comment it out or set to None for no augmentation. (Default: None)
# Currently supported types: 'affine' deformations by rotation and scaling (Slows down training).
# Parameters:
# Affine: 'prob': Chance [0.-1.] to augment an image (suggested: 0.5, default 0.0).
#         'max_rot_xyz': Max degrees rotation per axis. 'max_scaling': Max scaling [0.-1.].
#         'interp_order_imgs': Interpolation order for images (0, 1 or 2), higher is better but slower (suggested: 1 or 2).
augm_img_prms_tr = {'affine': { 'prob': 0.0, 'max_rot_xyz': (45., 45., 45.), 'max_scaling': 0.1, 'interp_order_imgs': 1 } }

# [Optional] Augmentation applied on segment-level. Comment it out or set to None for no augmentation. (Default: None)
# hist_dist: Shift and scale the intensity histogram. I' = (I + shift) * scale
#            Shift and scale values are sampled from Gaussians N(mu,std).
#            Set 'shift': None and/or 'scale': None to disable them.
# reflect:   Augment by flipping samples. Specify probabilities to flip X,Y,Z axis. Set None for disabling.
# rotate90:  Augment by rotating samples on xy,yz,xz planes by 0,90,180,270 degrees. (suggested: image-level 'affine' seems better but slower)
#            Give probabilities of flipping a plane by 0,90,180,270 degrees. Sum is internally normalised to 1.
#            NOTE: Size of segment must be isotropic otherwise error will be raised.
augm_sample_prms_tr = { 'hist_dist': {'shift': {'mu': 0., 'std': 0.05}, 'scale': {'mu': 1., 'std': 0.01} },
                        'reflect':   (0.5, 0., 0.),
                        'rotate90':  {'xy': {'0': 0., '90': 0., '180': 0., '270': 0.},
                                      'yz': {'0': 0., '90': 0., '180': 0., '270': 0.},
                                      'xz': {'0': 0., '90': 0., '180': 0., '270': 0.} } }

#  +++++++++++Optimization+++++++++++

#  [Optionals]
#  Initial Learning Rate. Default: 0.001.
learningRate = 0.001
#  Optimizer to use. 0 for classic SGD, 1 for Adam, 2 for RmsProp. Default: 2
sgd0orAdam1orRms2 = 2
#  Type of momentum to use. 0 for standard momentum, 1 for Nesterov. Default: 1
classicMom0OrNesterov1 = 1
#  Momentum Value to use. Default: 0.6
momentumValue = 0.6
#  Non-Normalized (0) or Normalized momentum (1). Bear in mind that Normalized mom may result in smaller gradients and might need relatively higher Learning Rate. Default: 1
momNonNorm0orNormalized1 = 0
#  Parameters for RmsProp. Default: rho=0.9, e=10**(-4) (1e-6 blew up the gradients. Haven't tried 1e-5 yet).
rhoRms = 0.9
epsilonRms = 10**(-4)

#  [Optional] Losses and their weights for the total cost, given as a python dictionary.
#  Note: Give None as weight for a cost so that it is not computed at all (faster)
#  Defaults: {"xentr": 1.0, "iou": None, "dsc": None}
losses_and_weights = {"xentr": 1.0, "iou": None, "dsc": None}

#  [Optionals] Regularization L1 and L2.
#  Defaults: L1_reg = 0.000001, L2_reg = 0.0001
L1_reg = 0.000001
L2_reg = 0.0001

#  +++++++Freeze Layers++++++

#  [Optional] Specify layers the weights of which you wish to be kept fixed during training (eg to use weights from pre-training). First layer is 1.
#   One list for each of the normal, subsampled, and fully-connected (as 1x1 convs) pathways. For instance, provide [1,2,3] to keep first 3 layers fixed. [] or comment entry out to train all layers.
#   Defaults: [] for the Normal and FC pathway. For the Subsampled pathway, if entry is not specified, we mirror the option used for the Normal pathway. 
layersToFreezeNormal = []
layersToFreezeSubsampled = []
layersToFreezeFC = []



#  =============================Validation==================================

#  [Optionals] Specify whether to perform validation on samples and full-inference every few epochs. Default: False for both.
performValidationOnSamplesThroughoutTraining = True
performFullInferenceOnValidationImagesEveryFewEpochs = True

#  [Required] Similar to corresponding parameter for training, but points to cases for validation.
channelsValidation = ["./validation/validationChannels_flair.cfg", "./validation/validationChannels_t1c.cfg"]

#  [Required for validation on samples, optional for full-inference] Similar to corresponding parameter for training, but points to cases for validation.
gtLabelsValidation = "./validation/validationGtLabels.cfg"

#  [Optional] Similar to corresponding parameter for training
roiMasksValidation = "./validation/validationRoiMasks.cfg"

#  [Required if requested to save results for validation on whole images] The path to a file,
# ... which should list names for each validation case, to name the results after.
namesForPredictionsPerCaseVal = "./validation/validationNamesOfPredictions.cfg"

#  [Required] Similar to corresponding parameter for training. Only influences how accurately the validation samples will represent whole data. Memory bounded.
#  Default: 3000
numberValidationSegmentsLoadedOnGpuPerSubep = 5000

# [Optional] Batch size for validation on sampled image segments. Default: 50
batchsize_val_samples = 50

#  +++++ Sampling (validation) +++++:

#  [Optional] Type-of-Sampling to use for Validation. See description of corresponding variable for training.
#  Default: 1 (uniform sampling)
typeOfSamplingForVal = 1

#  [Optional] List the proportion (0.0 to 1.0) of samples to extract from each category of samples. See description of corresponding variable for training.
#  Default: Foreground/Background or Separately-Each-Class : equal number of segments extracted for each of the categories. Uniform or Full-Image: N/A
# proportionOfSamplesToExtractPerCategoryVal = [0.5, 0.5]

#  [Optional]
#  The following variable allows providing weighted-maps that indicate where to acquire more samples for each category/class. See description of corresponding variable for training.
#  Default : If this variable is not provided, samples are extracted based on the Ground-Truth labels and the ROI. 
# weightedMapsForSamplingEachCategoryVal = ["./validation/weightMapsForeground.cfg", "./validation/weightMapsBackground.cfg"]


#  +++++ Validation fully segmenting whole volumes +++++

#  [Optional] How often (epochs) to perform validation by fully inferring validation volumes. Time consuming. Default: 1
numberOfEpochsBetweenFullInferenceOnValImages = 5

#  [Optional] Batch size for validation on whole volumes. Default: 10
batchsize_val_whole = 10

#  [Optionals] Specify whether to save the segmentation and probability maps for each class. Default: True to all
saveSegmentationVal = True
saveProbMapsForEachClassVal = [True, True, True, True, True]

#  --Feature Maps--
#  Feature maps can also be saved, but section is omitted here. See testing configuration.


#  ================== Generics ===================

#  ++++ Data Compatibility Checks ++++

#  [Optional] Checks for format correctness of loaded input images. Can slow down the process.
#  Default: True
run_input_checks = True

#  +++++++ Data preprocessing ++++++

#  [Optional] Pad images to fully convolve. Default: True
padInputImagesBool = True

#  [Optional] Verbosity-level for logging info on intensity-normalization. 0: Nothing (default), 1: Per-subject, 2: Per-channel
norm_verbosity_lvl = 0

#  [Optional] Z-score intensity normalization parameters:
#     apply_to_all_channels: True/False. Whether to do z-score normalization to ALL channels. Default: False
#     apply_per_channel: None, or a List with one boolean per channel. Whether to normalize specific channel.
#                        NOTE: If apply_to_all_channels is True, apply_per_channel MUST be None.
#     cutoff_percents  : Cutoff at percentiles [float_low, float_high], values in [0.0 - 100.0].
#     cutoff_times_std : Cutoff intensities below/above [float_below, float_above] times std from the mean.
#     cutoff_below_mean: True/False. Cutoff intensities below image's mean. Useful to exclude air in brain MRI.
norm_zscore_prms = {'apply_to_all_channels': False,
                    'apply_per_channel': None,
                    'cutoff_percents': [5., 95.],
                    'cutoff_times_std': [3.,3.],
                    'cutoff_below_mean': False}


