import copy


def create_gt_generator(model):
    """
    Create a "gt generator". This will be a copy of the model, minus the shape configuration. It will be fixed
    throughout one epoch, and will generate the ground truth to train the shape configuration model. This ground truth
    will be the pooling shape dimensions that yielded the lowest loss - simulating what could be the real shape
    dimension of the pedestrian.
    May also disable gradient computation for parts of the original model (that are not relevant from a point of view
    of training).
    :param model: the original model
    :return: the gt generator, and the interaction model
    """
    # gt_model a model that will be used to generate "predictions" that will be simulated as ground truth data
    shape_config = model.shape_config
    model.shape_config = None  # deepcopy might not work without this line, due to there being some extra tensors
    gt_generator = copy.deepcopy(model)
    gt_generator.eval()
    gt_generator.shape_config = None
    # disable all gradients - except for the ones associated to the shape configuration network
    model.shape_config = shape_config
    for param in gt_generator.parameters():
        param.requires_grad = False
    for param in model.parameters():
        param.requires_grad = True
    # because the actual pooling data will come from a dataset, and not computed by the module, the goal of this
    # interaction module is just to embed the data, and send it as direct input to the LSTM cell
    interaction_module = copy.deepcopy(gt_generator.interaction_module)
    return gt_generator, interaction_module