def create_parser(parser):
    """
    Adds argument groups to parser
    :param parser: The parser that is used to add argument groups
    :return: An updated parser
    """
    required_group = parser.add_argument_group('Required arguments',
        'These options are mandatory to run crYOLO train')
    required_group.add_argument('-c', '--conf', required=True, help=
        'Path to configuration file', widget='FileChooser', gooey_options={
        'validator': {'test': 'user_input.endswith("json")', 'message':
        'File has to end with .json!'}, 'wildcard': '*.json'})
    required_group.add_argument('-w', '--warmup', type=int, required=True,
        default=5, help=
        'Number of warmup epochs. Set it to zero if you fine tune a model.')
    optional_group = parser.add_argument_group('Optional arguments',
        'These options are optional to run crYOLO train')
    optional_group.add_argument('-g', '--gpu', default='', nargs='+', help=
        'Specifiy which gpu(s) should be used. Multiple GPUs are separated by a whitespace. If not defined otherwise by your system, it will use GPU 0 by default.'
        )
    optional_group.add_argument('-nc', '--num_cpu', type=int, default=-1,
        help=
        'Number of CPUs used during training. By default it will use half of the available CPUs.'
        )
    optional_group.add_argument('--gpu_fraction', type=float, default=1.0,
        help=
        'Specify the fraction of memory per GPU used by crYOLO during training. Only values between 0.0 and 1.0 are allowed.'
        , gooey_options={'validator': {'test':
        '0.0 <= float(user_input) <= 1.0', 'message':
        'Must be between 0 and 1.0'}})
    optional_group.add_argument('-e', '--early', default=10, type=int, help
        =
        'Early stop patience. If the validation loss did not improve longer than the early stop patience, the training is stopped.'
        )
    optional_group.add_argument('--fine_tune', action='store_true', default
        =False, help=
        'Set it to true if you only want to use the fine tune mode. When using the fine tune mode, only the last layers of your network are trained and youhave to specify pretrained_weights (see action "config"->"Training options") You typically use a general model as pretrained weights.'
        )
    optional_group.add_argument('-lft', '--layers_fine_tune', default=2,
        type=int, help='Layers to be trained when using fine tuning.')
    deexsp_group = parser.add_argument_group('Deprecated/Experimental/Special '
        , 'Contains either deprecated / experimental or very special options.')
    deexsp_group.add_argument('--seed', type=int, default=10, help=
        'Seed for random number generator. Mainly influences selection of validation images. Should be the same during different training runs!'
        )
    deexsp_group.add_argument('--warm_restarts', action='store_true', help=
        'Use warm restarts and cosine annealing during training')
    deexsp_group.add_argument('--skip_augmentation', action='store_true',
        default=False, help=
        'Use it if you want to deactivate data augmentation during training.')
    deexsp_group.add_argument('--use_multithreading', action='store_true',
        default=False, help=
        'If python multiprocessing leads to problems during training (e.g. freezing, dying workers) use multithreading instead of multiprocessing.'
        )
