def call_necessary(file_in, file_out, min_file_size=0):
    """
    Check if all input files exist and at least one output file does not exist or is invalid.
    :param file_in: list of str or str
    :param file_out: list of str or str
    :param min_file_size: int
    :return:
    """

    if isinstance(file_in, str):
        file_in = [file_in]
    elif isinstance(file_in, list):
        pass
    else:
        raise ValueError('Wrong input type')

    if isinstance(file_out, str):
        file_out = [file_out]
    elif isinstance(file_out, list):
        pass
    else:
        raise ValueError('Wrong output type')

    inputs_missing = [f for f in file_in if not os.path.isfile(f)]
    if len(inputs_missing) > 0:
        print('WARNING: Input file are missing: {}'.format(inputs_missing))
        return False

    outputs_missing = [f for f in file_out if not os.path.isfile(f)]
    if len(outputs_missing) > 0:
        if len(outputs_missing) < len(file_out):
            print("WARNING: Only some output files are missing: {}".format(outputs_missing))
        return True

    min_output_file_size = min([os.path.getsize(f) for f in file_out])
    if min_output_file_size < min_file_size:
        return True

    oldest_input_file_mtime = max([os.path.getmtime(f) for f in file_in])
    youngest_output_file_mtime = min([os.path.getmtime(f) for f in file_out])

    if oldest_input_file_mtime >= youngest_output_file_mtime:
        # debug
        import time
        input_file_mtime_arg_max = np.argmax(np.array([os.path.getmtime(f) for f in file_in]))
        output_file_mtime_arg_min = np.argmin(np.array([os.path.getmtime(f) for f in file_out]))
        input_file_mtime_max = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(oldest_input_file_mtime))
        output_file_mtime_min = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(youngest_output_file_mtime))
        print('Input file {} \nis newer than output file {}: \n{} >= {}'.format(
            file_in[input_file_mtime_arg_max], file_out[output_file_mtime_arg_min],
            input_file_mtime_max, output_file_mtime_min))
        return True

    return False

    Check if all input files exist and at least one output file does not exist or is invalid.
    :param file_in: list of str or str
    :param file_out: list of str or str
    :param min_file_size: int
    :return:
    
source/base/file_utils.py