Ejemplo n.º 1
0
def instantiate(mac, operands, toplevel=True):
    """
    Return a copy of macro cobject ``mac`` where arguments are instantiated by the list
    `operands', used in the order of depth-first tree traversal of ``mac``.

    Check that the number of operands is OK vs mac
    """
    if isinstance(mac, cdummy):
        if len(operands) > 0:
            rep = operands.pop(0)
        else:
            raise Climaf_Macro_Error('no operand left')
    elif isinstance(mac, ctree):
        opers = []
        for o in mac.operands:
            opers.append(instantiate(o, operands, toplevel=False))
        rep = ctree(mac.operator, mac.script, *opers, **mac.parameters)
    elif isinstance(mac, scriptChild):
        father = instantiate(mac.father, operands, toplevel=False)
        rep = scriptChild(father, mac.variable)
    elif isinstance(mac, cdataset):
        rep = cdataset
    if toplevel and len(operands) != 0:
        raise Climaf_Macro_Error('too many operands; left operands are : ' +
                                 ` operands `)
    return (rep)
Ejemplo n.º 2
0
def instantiate(mac, operands, toplevel=True):
    """
    Return a copy of macro cobject ``mac`` where arguments are instantiated by the list
    `operands', used in the order of depth-first tree traversal of ``mac``.

    Check that the number of operands is OK vs mac
    """
    if isinstance(mac, cdummy):
        if len(operands) > 0:
            rep = operands.pop(0)
        else:
            raise Climaf_Macro_Error("no operand left")
    elif isinstance(mac, ctree):
        opers = []
        for o in mac.operands:
            opers.append(instantiate(o, operands, toplevel=False))
        rep = ctree(mac.operator, mac.script, *opers, **mac.parameters)
    elif isinstance(mac, scriptChild):
        father = instantiate(mac.father, operands, toplevel=False)
        rep = scriptChild(father, mac.variable)
    elif isinstance(mac, cdataset):
        rep = cdataset
    if toplevel and len(operands) != 0:
        raise Climaf_Macro_Error("too many operands; left operands are : " + ` operands `)
    return rep
Ejemplo n.º 3
0
def maketree(script_name, script, *operands, **parameters):
    rep=classes.ctree(script_name, script, *operands, **parameters)
    # TBD Analyze script inputs cardinality vs actual arguments
    # Create one child for each output
    defaultVariable=varOf(operands[0])
        #defaultPeriod=operands[0].period
    for outname in script.outputs :
        if outname is None :
            rep.variable=script.outputs[None]%defaultVariable
        else :
            son=classes.scriptChild(rep,outname)
            son.variable=script.outputs[outname]%defaultVariable
            rep.outputs[outname]=son
            setattr(rep,outname,son)
    return rep
Ejemplo n.º 4
0
def macro(name, cobj, lobjects=[]):
    """

    Define a CliMAF macro from a CliMAF compound object.

    Transform a Climaf object in a macro, replacing all datasets,
    and the objects of lobjects, by a dummy argument.  Register it in
    dict cmacros, if name is not None

    Args:
     name (string) : the name you want to give to the macro; a Python
      function with the same name will be defined
     cobj (CliMAF object, or string) : any CliMAF object, usually
      the result of a series of operators, that you would like to
      repeat using other input datasets; alternatively, you can provide
      the macro formula as a string (when accustomed to the syntax)
     lobjects (list, optional):  for expert use- a list of objects,
      which are sub-objects of cobject, and which should become arguments
      of the macro

    Returns:
      a macro; the returned value is usualy not used 'as is' : a
      python function is also defined in module cmacros and in main
      namespace, and you may use it in the same way as a CliMAF
      operator. All the datasets involved in ``cobj`` become arguments
      of the macro, which allows you to re-do the same computations
      and easily define objects similar to ``cobjs``

    Example::

     >>> # First use and combine CliMAF operators to get some interesting result using some dataset(s)
     >>> january_ta=ds(project='example',simulation='AMIPV6ALB2G',variable='ta',frequency='monthly',period='198001')
     >>> ta_europe=llbox(january_ta,latmin=40,latmax=60,lonmin=-15,lonmax=25)
     >>> ta_ezm=ccdo(ta_europe,operator='zonmean')
     >>> fig_ezm=plot(ta_ezm)
     >>> #
     >>> # Using this result as an example, define a macro named 'eu_cross_section',
     >>> # which arguments will be the datasets involved in this result
     >>> cmacro('eu_cross_section',fig_ezm)
     >>> #
     >>> # You can of course apply a macro to another dataset(s) (even here to a 2D variable)
     >>> pr=ds(project='example',simulation='AMIPV6ALB2G', variable='pr', frequency='monthly', period='198001')
     >>> pr_ezm=eu_cross_section(pr)
     >>> #
     >>> # All macros are registered in dictionary climaf.cmacro.cmacros,
     >>> # which is imported by climaf.api; you can list it by :
     >>> cmacros

    Note : macros are automatically saved in file ~/.climaf.macros, and can be edited

    See also much more explanations in the example at :download:`macro.py <../examples/macro.py>`
    """
    if isinstance(cobj, str):
        s = cobj
        # Next line used for interpreting macros's CRS
        exec("from climaf.cmacro import cdummy; ARG=cdummy()",
             sys.modules['__main__'].__dict__)
        try:
            cobj = eval(cobj, sys.modules['__main__'].__dict__)
        except:
            # usually case of a CRS which project is not currently defined
            clogger.error(
                "Cannot interpret %s with the projects currently define" % s)
            return None
        #print "string %s was interpreted as %s"%(s,cobj)
    domatch = False
    for o in lobjects:
        domatch = domatch or cobj==o or \
                  ( isinstance(cobj,cobject) and cobj.buildcrs() == o.buildcrs())
    if isinstance(cobj, cdataset) or isinstance(cobj, cdummy) or domatch:
        return cdummy()
    elif isinstance(cobj, ctree):
        rep = ctree(cobj.operator, cobj.script, *cobj.operands,
                    **cobj.parameters)
        rep.operands = map(macro, [None for o in rep.operands], rep.operands)
    elif isinstance(cobj, scriptChild):
        rep = scriptChild(macro(None, cobj.father), cobj.varname)
    elif isinstance(cobj, cpage):
        rep = cpage([
            map(macro, [None for fig in line], line) for line in cobj.fig_lines
        ], cobj.widths, cobj.heights)
    elif isinstance(cobj, cens):
        d = dict()
        for k, v in zip(
                cobj.keys(),
                map(macro, [None for o in cobj.values()], cobj.values())):
            d[k] = v
        rep = cens(d)
    elif cobj is None:
        return None
    else:
        clogger.error("Cannot yet handle object :%s", ` cobj `)
        rep = None
    if name and rep:
        cmacros[name] = rep
        doc = "A CliMAF macro, which text is " + ` rep `
        defs='def %s(*args) :\n  """%s"""\n  return instantiate(cmacros["%s"],[ x for x in args])\n'\
              % (name,doc,name)
        exec defs in globals()
        exec "from climaf.cmacro import %s" % name in sys.modules[
            '__main__'].__dict__
        clogger.debug("Macro %s has been declared" % name)

    return rep
Ejemplo n.º 5
0
def macro(name, cobj, lobjects=[]):
    """

    Define a CliMAF macro from a CliMAF compound object.

    Transform a Climaf object in a macro, replacing all datasets,
    and the objects of lobjects, by a dummy argument.  Register it in
    dict cmacros, if name is not None

    Args:
     name (string) : the name you want to give to the macro; a Python
      function with the same name will be defined
     cobj (CliMAF object, or string) : any CliMAF object, usually
      the result of a series of operators, that you would like to
      repeat using other input datasets; alternatively, you can provide
      the macro formula as a string (when accustomed to the syntax)
     lobjects (list, optional):  for expert use- a list of objects,
      which are sub-objects of cobject, and which should become arguments
      of the macro

    Returns:
      a macro; the returned value is usualy not used 'as is' : a
      python function is also defined in module cmacros and in main
      namespace, and you may use it in the same way as a CliMAF
      operator. All the datasets involved in ``cobj`` become arguments
      of the macro, which allows you to re-do the same computations
      and easily define objects similar to ``cobjs``

    Example::

     >>> # First use and combine CliMAF operators to get some interesting result using some dataset(s)
     >>> january_ta=ds(project='example',simulation='AMIPV6ALB2G',variable='ta',frequency='monthly',period='198001')
     >>> ta_europe=llbox(january_ta,latmin=40,latmax=60,lonmin=-15,lonmax=25)
     >>> ta_ezm=ccdo(ta_europe,operator='zonmean')
     >>> fig_ezm=plot(ta_ezm)
     >>> #
     >>> # Using this result as an example, define a macro named 'eu_cross_section',
     >>> # which arguments will be the datasets involved in this result
     >>> cmacro('eu_cross_section',fig_ezm)
     >>> #
     >>> # You can of course apply a macro to another dataset(s) (even here to a 2D variable)
     >>> pr=ds(project='example',simulation='AMIPV6ALB2G', variable='pr', frequency='monthly', period='198001')
     >>> pr_ezm=eu_cross_section(pr)
     >>> #
     >>> # All macros are registered in dictionary climaf.cmacro.cmacros,
     >>> # which is imported by climaf.api; you can list it by :
     >>> cmacros

    Note : macros are automatically saved in file ~/.climaf.macros, and can be edited

    See also much more explanations in the example at :download:`macro.py <../examples/macro.py>`
    """
    if isinstance(cobj, str):
        s = cobj
        # Next line used for interpreting macros's CRS
        exec ("from climaf.cmacro import cdummy; ARG=cdummy()", sys.modules["__main__"].__dict__)
        cobj = eval(cobj, sys.modules["__main__"].__dict__)
        # print "string %s was interpreted as %s"%(s,cobj)
    domatch = False
    for o in lobjects:
        domatch = domatch or cobj == o or (isinstance(cobj, cobject) and cobj.buildcrs() == o.buildcrs())
    if isinstance(cobj, cdataset) or isinstance(cobj, cdummy) or domatch:
        return cdummy()
    elif isinstance(cobj, ctree):
        rep = ctree(cobj.operator, cobj.script, *cobj.operands, **cobj.parameters)
        rep.operands = map(macro, [None for o in rep.operands], rep.operands)
    elif isinstance(cobj, scriptChild):
        rep = scriptChild(cmacro(None, cobj.father), cobj.varname)
    elif isinstance(cobj, cpage):
        rep = cpage(
            cobj.widths,
            cobj.heights,
            [map(cmacro, [None for fig in line], line) for line in cobj.fig_lines],
            cobj.orientation,
        )
    elif cobj is None:
        return None
    else:
        clogger.error("Cannot yet handle object :%s", ` cobj `)
        rep = None
    if name and rep:
        cmacros[name] = rep
        doc = "A CliMAF macro, which text is " + ` rep `
        defs = 'def %s(*args) :\n  """%s"""\n  return instantiate(cmacros["%s"],[ x for x in args])\n' % (
            name,
            doc,
            name,
        )
        exec defs in globals()
        exec "from climaf.cmacro import %s" % name in sys.modules["__main__"].__dict__
        clogger.debug("Macro %s has been declared" % name)

    return rep