Esempio n. 1
0
def main(argv=None, **kwargs):
    '''main function for test.py.

    Long-form of command line arguments can also be supplied as kwargs.

    If argv is not None, command line parsing will be performed.
    '''
    logger = Component.get_logger()

    parser = optparse.OptionParser(version="%prog version: $Id$",
                                   usage=globals()["__doc__"])

    parser.add_option("-t", "--tracker", dest="tracker", type="string",
                      help="tracker to use [default=%default]")

    parser.add_option("-p", "--page", dest="page", type="string",
                      help="render an rst page [default=%default]")

    parser.add_option("-a", "--tracks", dest="tracks", type="string",
                      help="tracks to use [default=%default]")

    parser.add_option("-m", "--transformer", dest="transformers",
                      type="string", action="append",
                      help="add transformation [default=%default]")

    parser.add_option("-s", "--slices", dest="slices", type="string",
                      help="slices to use [default=%default]")

    parser.add_option("-r", "--renderer", dest="renderer", type="string",
                      help="renderer to use [default=%default]")

    parser.add_option("-w", "--path", "--trackerdir",
                      dest="trackerdir", type="string",
                      help="path to trackers [default=%default]")

    parser.add_option("-f", "--force", dest="force", action="store_true",
                      help="force recomputation of data by deleting cached "
                      "results [default=%default]")

    parser.add_option("-o", "--option", dest="options", type="string",
                      action="append",
                      help="renderer options - supply as key=value pairs "
                      "(without spaces). [default=%default]")

    parser.add_option("-l", "--language", dest="language", type="choice",
                      choices=("rst", "notebook"),
                      help="output language for snippet. Use ``rst`` "
                      "to create a snippet to paste "
                      "into a cgatreport document. Use ``notebook`` to "
                      "create a snippet to paste "
                      "into an ipython notebook [default=%default]")

    parser.add_option("--no-print", dest="do_print", action="store_false",
                      help="do not print an rst text element to create "
                      "the displayed plots [default=%default].")

    parser.add_option("--no-show", dest="do_show", action="store_false",
                      help="do not show a plot [default=%default].")

    parser.add_option("--layout", dest="layout", type="string",
                      help="output rst with layout [default=%default].")

    parser.add_option("-i", "--start-interpreter", dest="start_interpreter",
                      action="store_true",
                      help="do not render, but start python interpreter "
                      "[default=%default].")

    parser.add_option("-I", "--ii", "--start-ipython", dest="start_ipython",
                      action="store_true",
                      help="do not render, start ipython interpreter "
                      "[default=%default].")

    parser.add_option(
        "--workdir", dest="workdir", type="string",
        help="working directory - change to this directory "
        "before executing "
        "[default=%default]")

    parser.add_option(
        "--hardcopy", dest="hardcopy", type="string",
        help="output images of plots. The parameter should "
        "contain one or more %s "
        "The suffix determines the type of plot. "
        "[default=%default].")

    parser.set_defaults(
        loglevel=1,
        tracker=None,
        transformers=[],
        tracks=None,
        slices=None,
        options=[],
        renderer="table",
        do_show=True,
        do_print=True,
        force=False,
        trackerdir=TRACKERDIR,
        caption="add caption here",
        start_interpreter=False,
        start_ipython=False,
        language="rst",
        workdir=None,
        layout=None,
        dpi=100)

    if argv is None and len(kwargs) == 0:
        argv = sys.argv

    if argv:
        (options, args) = parser.parse_args(argv)
    else:
        (options, args) = parser.parse_args([])

        ######################################################
        # set keyword arguments as options
        for keyword, value in list(kwargs.items()):
            if hasattr(options, keyword):
                setattr(options, keyword, value)
                del kwargs[keyword]

        # change some kwarguments
        if options.transformers:
            for keyword, value in list(kwargs.items()):
                if keyword.startswith("tf"):
                    kwargs["tf-{}".format(keyword[2:])] = value

    if options.workdir is not None:
        savedir = os.getcwd()
        os.chdir(options.workdir)
    else:
        savedir = None

    if args:
        update_options_from_blob(kwargs, options, args)

    Utils.update_parameters(sorted(glob.glob("*.ini")))

    ######################################################
    # configure options
    options.trackerdir = os.path.abspath(
        os.path.expanduser(options.trackerdir))
    if os.path.exists(options.trackerdir):
        sys.path.insert(0, options.trackerdir)
    else:
        logger.warn("directory %s does not exist" % options.trackerdir)

    ######################################################
    # test plugins
    for x in options.options:
        if "=" in x:
            data = x.split("=")
            key, val = [y.strip() for y in (data[0], "=".join(data[1:]))]
        else:
            key, val = x.strip(), None
        kwargs[key] = val

    if options.tracks:
        kwargs["tracks"] = options.tracks
    if options.slices:
        kwargs["slices"] = options.slices

    kwargs = update_options(kwargs)

    option_map = get_option_map()
    renderer_options = select_and_delete_options(
        kwargs, option_map["render"])
    transformer_options = select_and_delete_options(
        kwargs, option_map["transform"])
    display_options = select_and_delete_options(
        kwargs, option_map["display"])
    tracker_options = select_and_delete_options(
        kwargs, option_map["tracker"], expand=["tracker"])

    ######################################################
    # decide whether to render or not
    if options.renderer == "none" or options.start_interpreter or \
       options.start_ipython or options.language == "notebook":
        renderer = None
    else:
        renderer = get_renderer(options.renderer, {**renderer_options,
                                                   **kwargs})

    try:
        rstdir = os.getcwd()
        srcdir = os.getcwd()
        builddir = os.getcwd()
        renderer.set_paths(rstdir, srcdir, builddir)
        renderer.set_display_options(display_options)
    except AttributeError:
        # User renderers will not have these methods
        pass

    transformers = get_transformers(
        options.transformers, transformer_options)

    exclude = set(("Tracker",
                   "TrackerSQL",
                   "returnLabeledData",
                   "returnMultipleColumnData",
                   "returnMultipleColumns",
                   "returnSingleColumn",
                   "returnSingleColumnData",
                   "SQLError",
                   "MultipleColumns",
                   "MultipleColumnData",
                   "LabeledData",
                   "DataSimple",
                   "Data"))

    ######################################################
    # build from tracker
    if options.tracker:

        if "." in options.tracker:
            parts = options.tracker.split(".")
            tracker_modulename = ".".join(parts[:-1])
            tracker_name = parts[-1]
        else:
            tracker_modulename = None
            tracker_name = options.tracker

        try:
            _code, tracker, tracker_path = make_tracker(
                options.tracker, (), tracker_options)
        except ImportError:
            # try to find class in module
            trackers = []

            for filename in glob.glob(
                    os.path.join(options.trackerdir, "*.py")):
                modulename = os.path.basename(filename)
                trackers.extend(
                    [x for x in get_available_trackers(modulename)
                     if x[0] not in exclude])

            for name, tracker_class, modulename, is_derived in trackers:
                if name == tracker_name:
                    if tracker_modulename is not None:
                        if modulename == tracker_modulename:
                            break
                    else:
                        tracker_modulename = modulename
                        break
            else:
                available_trackers = set([x[0] for x in trackers if x[3]])
                print((
                    "unknown tracker '%s': possible trackers are\n  %s" %
                    (options.tracker, "\n  ".join(sorted(available_trackers)))))
                print(
                    "(the list above does not contain functions).")
                sys.exit(1)

            # instantiate functors
            if is_derived:
                tracker = tracker_class(**kwargs)
            #  but not functions
            else:
                tracker = tracker_class

        # remove everything related to that tracker for a clean slate
        if options.force:
            removed = CGATReport.clean.removeTracker(tracker_name)
            print(("removed all data for tracker %s: %i files" %
                   (tracker_name, len(removed))))

        dispatcher = Dispatcher(tracker, renderer, transformers)

        if renderer is None:
            # dispatcher.parseArguments(**kwargs)
            # result = dispatcher.collect()
            # result = dispatcher.transform()
            result = dispatcher(**kwargs)
            options.do_print = options.language == "notebook"
            options.do_show = False
            options.hardcopy = False
        else:
            # needs to be resolved between renderer and dispatcher options
            result = dispatcher(**kwargs)

        if options.do_print:

            sys.stdout.write(".. ---- TEMPLATE START --------\n\n")

            if options.language == "rst":
                writeRST(sys.stdout,
                         options,
                         kwargs,
                         renderer_options,
                         transformer_options,
                         display_options,
                         tracker_modulename,
                         tracker_name)
            elif options.language == "notebook":
                writeNotebook(sys.stdout,
                              options,
                              kwargs,
                              renderer_options,
                              transformer_options,
                              display_options,
                              tracker_modulename,
                              tracker_name)

            sys.stdout.write("\n.. ---- TEMPLATE END ----------\n")

        sys.stdout.write("\n.. ---- OUTPUT-----------------\n")

        if result and renderer is not None:
            if options.layout is not None:
                lines = Utils.layoutBlocks(result, layout=options.layout)
                print(("\n".join(lines)))
            else:
                for r in result:
                    if r.title:
                        print("")
                        print(("title: %s" % r.title))
                        print("")
                    for ss in str(r).split("\n"):
                        print(force_encode(ss))

        if options.hardcopy:

            fig_managers = _pylab_helpers.Gcf.get_all_fig_managers()
            # create all the images
            for figman in fig_managers:
                # create all images
                figid = figman.num
                outfile = re.sub("%s", str(figid), options.hardcopy)
                figman.canvas.figure.savefig(outfile, dpi=options.dpi)

        if result and options.do_show:
            if options.renderer.startswith("r-"):
                for r in result:
                    if hasattr(r, 'rggplot'):
                        from rpy2.robjects import r as R
                        import rpy2.rinterface
                        try:
                            R.plot(r.rggplot)
                        except rpy2.rinterface.RRuntimeError as msg:
                            if re.search("object.*not found", str(msg)):
                                print(('%s: available columns in dataframe=%s' %
                                       (msg,
                                        R('''colnames(rframe)'''))))

                print("press Ctrl-c to stop")
                while 1:
                    pass

            elif len(_pylab_helpers.Gcf.get_all_fig_managers()) > 0:
                plt.show()

            else:
                for rr in result:
                    if hasattr(r, 'xls'):
                        tmpfile, outpath = tempfile.mkstemp(
                            dir='.', suffix='.xlsx')
                        os.close(tmpfile)
                        print(('saving xlsx to %s' % outpath))
                        r.xls.save(outpath)
                    elif hasattr(r, 'bokeh'):
                        import bokeh.plotting as bk
                        bk.show(r.bokeh)

    ######################################################
    # build page
    elif options.page:

        from CGATReport import build
        CGATReport.report_directive.DEBUG = True
        CGATReport.report_directive.FORCE = True

        if not os.path.exists(options.page):
            raise IOError("page %s does not exist" % options.page)

        options.num_jobs = 1

        build.buildPlots(
            [options.page, ], options, [], os.path.dirname(options.page))

        if options.do_show:
            if options.renderer.startswith("r-"):
                print("press Ctrl-c to stop")
                while 1:
                    pass

            elif _pylab_helpers.Gcf.get_all_fig_managers() > 0:
                plt.show()

    else:
        raise ValueError(
            "please specify either a tracker "
            "(-t/--tracker) or a page (-p/--page) to test")

    if savedir is not None:
        os.chdir(savedir)

    if options.tracker and renderer is None:
        datatree = dispatcher.getDataTree()
        dataframe = dispatcher.getDataFrame()

        # trying to push R objects
        # from rpy2.robjects import r as R
        # for k, v in flat_iterator(datatree):
        #     try:
        #         R.assign(k, v)
        #     except ValueError, msg:
        #         print ("could not push %s: %s" % (k,msg))
        #         pass
        # print ("----------------------------------------")
        if options.start_interpreter:
            print ("--> cgatreport - available data structures <--")
            print(("    datatree=%s" % type(datatree)))
            print(("    dataframe=%s" % type(dataframe)))
            interpreter = code.InteractiveConsole(
                dict(list(globals().items()) + list(locals().items())))
            interpreter.interact()
            return dataframe
        elif options.start_ipython:
            import IPython
            IPython.embed()
            return dataframe

        return dataframe