def run_gtapp(gtapp, stream, dry_run, **kwargs):
    """Runs one on the ScienceTools apps

    Taken from fermipy.gtanalysis.run_gtapp by Matt Wood

    Parameters
    ----------

    gtapp : `GtApp.GtApp` object
        The application (e.g., gtbin)

    stream : stream object
        Must have 'write' function

    dry_run : bool
        Print command but do not run it

    kwargs : arguments used to invoke the application
    """
    if stream is None:
        stream = sys.stdout

    pfiles_orig = _set_pfiles(dry_run, **kwargs)    
    update_gtapp(gtapp, **kwargs)

    stream.write("%s\n" % gtapp.command())
    stream.flush()
    if dry_run:
        _reset_pfiles(pfiles_orig)       
        return 0

    try:
        stdin, stdout = gtapp.runWithOutput(print_command=False)
        for line in stdout:
            stream.write(line.strip())
        stream.flush()
        return_code = 0
    except:
        stream.write('Exited with exit code -1\n')
        return_code = -1

    _reset_pfiles(pfiles_orig)
    return return_code
Runs one on the ScienceTools apps

    Taken from fermipy.gtanalysis.run_gtapp by Matt Wood

    Parameters
    ----------

    gtapp : `GtApp.GtApp` object
        The application (e.g., gtbin)

    stream : stream object
        Must have 'write' function

    dry_run : bool
        Print command but do not run it

    kwargs : arguments used to invoke the application