def METHOD_NAME(self, batch, return_logs=False, progress=0.0):
    """
    Processes a batch.
    Parameters
    ----------
    batch : dict
        Input batch
    return_logs : bool
        True if logs are stored
    progress :
        Training progress percentage
    Returns
    -------
    output : dict
        Dictionary containing a "loss" scalar and different metrics and predictions
        for logging and downstream usage.
    """
    # Calculate predicted depth and pose output
    output = super().METHOD_NAME(batch, return_logs=return_logs)
    if not self.training:
        # If not training, no need for self-supervised loss
        return output
    else:
        if output['poses'] is None:
            return None
        # Otherwise, calculate self-supervised loss
        self_sup_output = self.supervised_loss(
            batch['rgb_original'],
            batch['rgb_context_original'],
            output['inv_depths'],
            batch['depth'],
            batch['pose_context'],
            output['poses'],
            batch['intrinsics'],
            return_logs=return_logs,
            progress=progress)
        # Return loss and metrics
        return {
            'loss': self_sup_output['loss'],
            **merge_outputs(output, self_sup_output),
        }