def create_process_chain_entry(cube1_object: DataObject,
                               cube2_object: DataObject,
                               output_object: DataObject):
    """Create a Actinia command of the process chain

    :param cube1_object:
    :param cube2_object:
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    # t.merge does not have a method to resolve overlaps

    pc = {
        "id":
        "t_merge_%i" % rn,
        "module":
        "t.merge",
        "inputs": [{
            "param": "inputs",
            "value": "%(cube1)s,%(cube2)s" % {
                "cube1": cube1_object.grass_name(),
                "cube2": cube2_object.grass_name()
            }
        }, {
            "param": "output",
            "value": output_object.grass_name()
        }]
    }

    return pc
def create_process_chain_entry(
        output_object: DataObject,
        red_object: DataObject,
        green_object: DataObject,
        blue_object: DataObject) -> list:
    """Actinia process to export an RGB composite GeoTiff

    :param output_object:
    :param red_name:
    :param green_name:
    :param blue_name:
    :return: The process chain
    """

    rn = randint(0, 1000000)
    pc = []

    composite = {
        "id": "composite_%i" % rn,
        "module": "r.composite",
        "inputs": [{"param": "red", "value": red_object.grass_name()},
                   {"param": "green", "value": green_object.grass_name()},
                   {"param": "blue", "value": blue_object.grass_name()}],
        "outputs": [{"export": {"type": "raster", "format": "GTiff"},
                     "param": "output",
                     "value": output_object.grass_name()}]}
    pc.append(composite)

    return pc
def create_process_chain_entry(input_object: DataObject,
                               output_object: DataObject):
    """Create a Actinia command of the process chain

    :param input_object:
    :param vector_object:
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    pc = {
        "id":
        "t_rast_algebra_%i" % rn,
        "module":
        "t.rast.algebra",
        "inputs": [
            {
                "param": "expression",
                "value": "%(result)s = 1 * %(input)s" % {
                    "result": output_object.grass_name(),
                    "input": input_object.grass_name()
                }
            },
            {
                "param": "basename",
                "value": "trim"
            },
        ]
    }

    return pc
def create_process_chain_entry(input_time_series: DataObject,
                               nir_band, red_band,
                               output_time_series: DataObject):
    """Create a Actinia process description that uses t.rast.ndvi to create the NDVI time series

    :param input_time_series: The input time series object with red and nir bands
    :param output_time_series: The object of the output time series
    :return: A list of Actinia process chain descriptions
    """
    rn = randint(0, 1000000)

    # TODO: adjust t.rast.ndvi to accept nir band and red band names
    #       pass nir_band and red_band to t.rast.ndvi

    pc = [
        {"id": "t_rast_ndvi_%i" % rn,
         "module": "t.rast.ndvi",
         "inputs": [{"param": "input",
                     "value": "%(input)s" % {"input": input_time_series.grass_name()}},
                    {"param": "basename",
                     "value": "ndvi"},
                    {"param": "output",
                     "value": output_time_series.grass_name()}]},
        {"id": "t_rast_color_%i" % rn,
         "module": "t.rast.colors",
         "inputs": [{"param": "input",
                     "value": output_time_series.grass_name()},
                    {"param": "color",
                     "value": "ndvi"}]}]

    return pc
Example #5
0
def create_process_chain_entry(input: DataObject, mask: DataObject,
                               output: DataObject):
    """Create a Actinia process description that uses r.mapcalc
       to apply a mask.

       NOTE: according to multilayer_mask, 0 means not masked, 1 means masked
             this is the other way around compared to GRASS

    :param input: The input map name
    :param mask: The mask map name
    :param output: The name of the output map
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    pc = {
        "id":
        "r_mapcalc_%i" % rn,
        "module":
        "r.mapcalc",
        "inputs": [{
            "param": "expression",
            "value": "%(result)s = if(isnull(%(mask)s) || %(mask)s == 0, "
            "null(), %(raw)s)" % {
                "result": output.grass_name(),
                "raw": input.grass_name(),
                "mask": mask.grass_name()
            }
        }]
    }

    return pc
Example #6
0
def create__process_chain_entry(input_object: DataObject, start_time: str,
                                end_time: str, output_object: DataObject):
    """Create a Actinia command of the process chain that uses t.rast.extract to create a subset of a strds
       The filter checks whether the temporal dimension value is
       greater than or equal to the lower boundary (start date/time)
       and the temporal dimension value is less than the value of the
       upper boundary (end date/time). This corresponds to a
       left-closed interval, which contains the lower boundary but not
       the upper boundary.

    :param input_object: The input strds object
    :param start_time:
    :param end_time:
    :param output_object: The output strds object
    :return: A Actinia process chain description
    """

    start_time = start_time.replace('T', ' ')
    end_time = end_time.replace('T', ' ')

    # Get info about the time series to extract its resolution settings and
    # bbox
    rn = randint(0, 1000000)

    # end_time can be null, and we can not find out if end_time is set because
    # the input does not exist yet
    pc = {
        "id":
        "t_rast_extract_%i" % rn,
        "module":
        "t.rast.extract",
        "inputs": [{
            "param": "input",
            "value": input_object.grass_name()
        }, {
            "param": "where",
            "value": "start_time >= '%(start)s' "
            "AND start_time <= '%(end)s'" % {
                "start": start_time,
                "end": end_time
            }
        }, {
            "param": "output",
            "value": output_object.grass_name()
        }, {
            "param": "expression",
            "value": "1.0 * %s" % input_object.grass_name()
        }, {
            "param": "basename",
            "value": f"{input_object.name}_extract"
        }, {
            "param": "suffix",
            "value": "num"
        }]
    }

    return pc
def create__process_chain_entry(input_object: DataObject, target, source,
                                output_object: DataObject):
    """Create a Actinia command of the process chain that uses
       t.rast.renamebands to rename band names.

    :param input_object: The input strds object
    :param dimension:
    :param target:
    :param source:
    :param output_object: The output strds object
    :return: A Actinia process chain description
    """

    # Get info about the time series to extract its resolution settings and
    # bbox
    rn = randint(0, 1000000)

    # source can be null
    if source:
        pc = {
            "id":
            "t_rast_renamebands_%i" % rn,
            "module":
            "t.rast.renamebands",
            "inputs": [{
                "param": "input",
                "value": input_object.grass_name()
            }, {
                "param": "target",
                "value": (',').join(target)
            }, {
                "param": "source",
                "value": (',').join(source)
            }, {
                "param": "output",
                "value": output_object.grass_name()
            }]
        }
    else:
        pc = {
            "id":
            "t_rast_renamebands_%i" % rn,
            "module":
            "t.rast.renamebands",
            "inputs": [{
                "param": "input",
                "value": input_object.grass_name()
            }, {
                "param": "target",
                "value": (',').join(target)
            }, {
                "param": "output",
                "value": output_object.grass_name()
            }]
        }

    return pc
Example #8
0
def get_process_list(node: Node):
    """Analyse the process description and return the Actinia process chain and the name of the processing result

    :param node: The process node
    :return: (output_objects, actinia_process_list)
    """

    input_objects, process_list = check_node_parents(node=node)
    output_objects = []

    if "result" not in node.arguments:
        raise Exception("The result name must be specified as parameter")
    if "expression" not in node.arguments:
        raise Exception("The expression must be specified as parameter")
    if "basename" not in node.arguments:
        raise Exception("The basename must be specified as parameter")

    result = DataObject(
        name=node.arguments["result"],
        datatype=GrassDataType.STRDS)

    expression = node.arguments["expression"]
    basename = node.arguments["basename"]

    if "a" in node.arguments:
        a = list(node.get_parent_by_name(parent_name="a").output_objects)[-1]
        expression = expression.replace("$a", a.grass_name())
    if "b" in node.arguments:
        b = list(node.get_parent_by_name(parent_name="b").output_objects)[-1]
        expression = expression.replace("$b", b.grass_name())
    if "c" in node.arguments:
        c = list(node.get_parent_by_name(parent_name="c").output_objects)[-1]
        expression = expression.replace("$c", c.grass_name())
    if "d" in node.arguments:
        d = list(node.get_parent_by_name(parent_name="d").output_objects)[-1]
        expression = expression.replace("$d", d.grass_name())
    if "e" in node.arguments:
        e = list(node.get_parent_by_name(parent_name="e").output_objects)[-1]
        expression = expression.replace("$e", e.grass_name())
    if "f" in node.arguments:
        f = list(node.get_parent_by_name(parent_name="f").output_objects)[-1]
        expression = expression.replace("$f", f.grass_name())

    expression = expression.replace("$result", result.grass_name())

    output_objects.append(result)
    node.add_output(output_object=result)

    pc = create_process_chain_entry(expression=expression, basename=basename)
    process_list.extend(pc)

    return output_objects, process_list
Example #9
0
def create_process_chain_entry(input_object: DataObject, method,
                               output_object: DataObject):
    """Create a Actinia process description.

    :param input_object: The input time series name
    :param method: The method for time reduction
    :param output_map: The name of the output raster map
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    # TODO: a new GRASS addon that
    # 1. fetches a list of raster maps in a strds
    # 2. resamples each raster map with the selected method

    # translate openeo method to GRASS method
    if method == "near":
        method = "nearest"
    if method == "cubic":
        method = "bicubic"
    if method == "max":
        method = "maximum"
    if method == "min":
        method = "minimum"
    if method == "med":
        method = "median"
    if method == "q1":
        method = "quart1"
    if method == "q3":
        method = "quart3"

    pc = [{
        "id":
        "t_rast_resample_%i" % rn,
        "module":
        "t.rast.resample",
        "inputs": [{
            "param": "input",
            "value": input_object.grass_name()
        }, {
            "param": "method",
            "value": method
        }, {
            "param": "output",
            "value": output_object.grass_name()
        }],
    }]

    return pc
Example #10
0
def get_process_list(node: Node):
    """Analyse the process description and return the Actinia process
       chain and the name of the processing result

    :param node: The process node
    :return: (output_objects, actinia_process_list)
    """

    input_objects, process_list = check_node_parents(node=node)
    output_objects = []

    # First analyse the data entry
    if "id" not in node.arguments:
        raise Exception("Process %s requires parameter <id>" % PROCESS_NAME)

    input_object = DataObject.from_string(node.arguments["id"])

    spatial_extent = None
    if "spatial_extent" in node.arguments:
        spatial_extent = node.arguments["spatial_extent"]
    temporal_extent = None
    if "temporal_extent" in node.arguments:
        temporal_extent = node.arguments["temporal_extent"]
    bands = None
    if "bands" in node.arguments:
        bands = node.arguments["bands"]

    if input_object.is_strds() and \
       (temporal_extent is not None or bands is not None):
        output_object = DataObject(
            name=create_output_name(input_object.name, node),
            datatype=input_object.datatype)
    elif input_object.is_stac():
        output_object = DataObject(
            name=create_output_name(input_object.name, node),
            datatype=input_object.datatype)
    else:
        output_object = input_object

    output_objects.append(output_object)
    node.add_output(output_object)

    pc = create_process_chain_entry(input_object,
                                    spatial_extent,
                                    temporal_extent,
                                    bands,
                                    output_object)
    process_list.extend(pc)

    return output_objects, process_list
Example #11
0
def create_process_chain_entry(input_object: DataObject, formula, operators,
                               output_object: DataObject):
    """Create a Actinia process description.

    :param input_object: The input time series object
    :param output_object: The output time series or raster object
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    # t.rast.mapcalc

    formula = formula.replace('data', input_object.grass_name())

    pc = {
        "id":
        "t_rast_mapcalc_%i" % rn,
        "module":
        "t.rast.mapcalc",
        "inputs": [
            {
                "param": "expression",
                "value": "%(formula)s" % {
                    "formula": formula
                }
            },
            {
                "param": "input",
                "value": "%(input)s" % {
                    "input": input_object.grass_name()
                }
            },
            {
                "param": "output",
                "value": output_object.grass_name()
            },
            # the basename will always replace any individual
            # raster map names from the input STRDS,
            # but some basename is required.
            {
                "param": "basename",
                "value": output_object.grass_name()
            }
        ]
    }

    return pc
Example #12
0
def get_process_list(node: Node):
    """Analyse the process description and return the Actinia process chain
    and the name of the processing result layer
    which is a single raster layer

    :param node: The process node
    :return: (output_objects, actinia_process_list)
    """

    input_objects, process_list = check_node_parents(node=node)
    output_objects = []

    if "method" not in node.arguments:
        raise Exception("Parameter method is required.")

    for input_object in node.get_parent_by_name("data").output_objects:

        output_object = DataObject(
            name=create_output_name(input_object.name, PROCESS_NAME),
            datatype=GrassDataType.RASTER)
        output_objects.append(output_object)
        node.add_output(output_object=output_object)

        pc = create_process_chain_entry(
            input_object, node.arguments["method"], output_object)
        process_list.append(pc)

    return output_objects, process_list
Example #13
0
def get_process_list(node: Node):
    """Analyse the process node and return the Actinia process chain and the name of the processing result

    :param node: The process node
    :return: (output_objects, actinia_process_list)
    """

    input_objects, process_list = check_node_parents(node=node)
    output_objects = []

    if "data" not in node.arguments:
        raise Exception("Process %s requires parameter data" % PROCESS_NAME)

    input_objects = node.get_parent_by_name(parent_name="data").output_objects

    if not input_objects:
        raise Exception("Process %s requires an input strds" % PROCESS_NAME)

    input_object = list(input_objects)[-1]

    output_object = DataObject(name=create_output_name(input_object.name,
                                                       PROCESS_NAME),
                               datatype=GrassDataType.STRDS)
    output_objects.append(output_object)

    # pc = create_process_chain_entry(input_object, vector_object, output_object)
    # process_list.append(pc)

    return output_objects, process_list
def get_process_list(node: Node) -> Tuple[list, list]:
    """Analyse the process node and return the Actinia process chain and the name of the processing result

    :param node: The process node
    :return: (output_objects, actinia_process_list)
    """

    input_objects, process_list = check_node_parents(node=node)
    output_objects = []

    if "data" not in node.arguments or \
            "min" not in node.arguments or \
            "max" not in node.arguments:
        raise Exception("Process %s requires parameter data, min, max" %
                        PROCESS_NAME)

    newmin = node.arguments["min"]
    newmax = node.arguments["max"]

    # for each raster separately
    for input_object in node.get_parent_by_name("data").output_objects:

        output_object = DataObject(name=create_output_name(
            input_object.name, PROCESS_NAME),
                                   datatype=GrassDataType.RASTER)
        output_objects.append(output_object)
        node.add_output(output_object=output_object)

        pc = create_process_chain_entry(input_object, newmin, newmax,
                                        output_object)
        process_list.append(pc)

    # TODO: create strds from output raster maps

    return output_objects, process_list
Example #15
0
def get_process_list(node: Node):
    """Analyse the process description and return the Actinia process chain
    and the name of the processing result layer
    which is a single raster layer

    :param node: The process node
    :return: (output_objects, actinia_process_list)
    """

    input_objects, process_list = check_node_parents(node=node)
    output_objects = []

    if "percentile" not in node.arguments:
        raise Exception("Parameter percentile is required.")

    for data_object in node.get_parent_by_name("data").output_objects:
        # multiple strds as input ?
        # multiple raster layers as output !
        output_object = DataObject(name=create_output_name(
            data_object.name, node),
                                   datatype=GrassDataType.STRDS)
        output_objects.append(output_object)
        node.add_output(output_object=output_object)

        pc = create_process_chain_entry(data_object,
                                        node.arguments["percentile"],
                                        output_object)
        process_list.append(pc)

    return output_objects, process_list
Example #16
0
def get_process_list(node: Node):
    """Analyse the process description and return the Actinia process chain
    and the name of the processing result layer
    which is a single raster layer

    :param node: The process node
    :return: (output_objects, actinia_process_list)
    """

    tree, operators = construct_tree(
        node.as_dict()['arguments']['process']['process_graph'])
    # print (operators)
    formula = None
    output_datatype = GrassDataType.RASTER
    formula = serialize_tree(tree)
    # print(formula)
    output_datatype = GrassDataType.STRDS

    input_objects, process_list = check_node_parents(node=node)
    output_objects = []

    for input_object in node.get_parent_by_name("data").output_objects:

        output_object = DataObject(name=create_output_name(
            input_object.name, PROCESS_NAME),
                                   datatype=output_datatype)
        output_objects.append(output_object)
        node.add_output(output_object=output_object)

        pc = create_process_chain_entry(input_object, formula, operators,
                                        output_object)
        process_list.append(pc)

    return output_objects, process_list
def get_process_list(node: Node) -> Tuple[list, list]:
    """Analyse the process node and return the Actinia process chain and the name of the processing result

    :param node: The process node
    :return: (output_objects, actinia_process_list)
    """

    input_objects, process_list = check_node_parents(node=node)
    output_objects = []

    if "data" not in node.arguments or \
            "min" not in node.arguments or \
            "max" not in node.arguments:
        raise Exception("Process %s requires parameter data, min, max" %
                        PROCESS_NAME)

    vmin = node.arguments["min"]
    vmax = node.arguments["max"]

    for data_object in input_objects:

        output_object = DataObject(name=create_output_name(
            data_object.name, node),
                                   datatype=GrassDataType.STRDS)
        output_objects.append(output_object)
        node.add_output(output_object=output_object)

        pc = create_process_chain_entry(data_object, vmin, vmax, output_object)
        process_list.append(pc)

    return output_objects, process_list
def get_process_list(node: Node):
    """Analyse the process description and return the Actinia process chain
    and the name of the processing result layer which is a single raster layer

    :param args: The process description
    :return: (output_names, actinia_process_list)
    """

    # Get the input description and the process chain to attach this process
    input_objects, process_list = check_node_parents(node=node)
    output_objects = []

    input_objects = node.get_parent_by_name(parent_name="data").output_objects

    python_file_url = node.arguments["udf"]
    udf_runtime = None
    if "runtime" in node.arguments:
        udf_runtime = node.arguments["runtime"]
    udf_version = None
    if "version" in node.arguments:
        udf_version = node.arguments["version"]

    for input_object in input_objects:

        output_object = DataObject(name=create_output_name(
            input_object.name, PROCESS_NAME),
                                   datatype=GrassDataType.STRDS)
        output_objects.append(output_object)

        pc = create_process_chain_entry(input_object, python_file_url,
                                        udf_runtime, udf_version,
                                        output_object)
        process_list.append(pc)

    return output_objects, process_list
def get_process_list(node: Node):
    """Analyse the process description and return the Actinia process chain and the name of the processing result
    strds that was filtered by start and end date

    :param node: The process node
    :return: (output_names, actinia_process_list)
    """

    input_objects, process_list = check_node_parents(node=node)
    output_objects = []

    for data_object in node.get_parent_by_name(
            parent_name="data").output_objects:

        # Skip if the datatype is not a strds and put the input into the output
        if data_object.is_strds() is False:
            output_objects.append(data_object)
            continue

        if "dimension" not in node.arguments or \
                node.arguments["dimension"] != "bands":
            raise Exception(
                "Process %s requires dimension to be set to bands" %
                PROCESS_NAME)

        output_object = DataObject(name=create_output_name(
            data_object.name, node),
                                   datatype=GrassDataType.STRDS)
        output_objects.append(output_object)
        node.add_output(output_object=output_object)

        if not isinstance(node.arguments["target"], list):
            raise Exception("Process %s requires target to be a list" %
                            PROCESS_NAME)
        target = node.arguments["target"]
        source = None
        if "source" in node.arguments:
            if not isinstance(node.arguments["source"], list):
                raise Exception("Process %s requires source to be a list" %
                                PROCESS_NAME)
            source = node.arguments["source"]
            if len(source) != len(target):
                raise Exception(
                    "Process %s requires source and target to have the same number of items"
                    % PROCESS_NAME)
        else:
            if len(target) != 1:
                raise Exception(
                    "Process %s requires one item in target if source is not given"
                    % PROCESS_NAME)

        pc = create__process_chain_entry(input_object=data_object,
                                         target=target,
                                         source=source,
                                         output_object=output_object)
        process_list.extend(pc)

    return output_objects, process_list
def create_process_chain_entry(input_object: DataObject, vmin: float,
                               vmax: float, output_object: DataObject):
    """Create a Actinia command of the process chain that uses t.rast.mapcalc
    to filter raster values by the specified interval

    :param input_object: The input time series object
    :param min: smallest allowed value
    :param max: largest allowed value
    :param output_object: The output time series object
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    pc = {
        "id":
        "t_rast_mapcalc_%i" % rn,
        "module":
        "t.rast.mapcalc",
        "inputs": [
            {
                "param": "expression",
                "value": "%(result)s = if(%(raw)s < %(min)s || "
                "%(raw)s > %(max)s), null(), %(raw)s)" % {
                    "result": output_object.grass_name(),
                    "raw": input_object.grass_name(),
                    "min": str(vmin),
                    "max": str(vmax)
                }
            },
            {
                "param": "basename",
                "value": output_object.name
            },
            {
                "param": "output",
                "value": output_object.grass_name()
            },
        ]
    }

    return pc
def get_process_list(node: Node):
    """Analyse the process description and return the Actinia process chain
    and the name of the processing result layer
    which is a single raster layer

    :param node: The process node
    :return: (output_objects, actinia_process_list)
    """

    input_objects, process_list = check_node_parents(node=node)
    output_objects = []

    if "nf" not in node.arguments:
        raise Exception("Parameter nf is required.")
    nf = int(node.arguments["nf"])
    dod = 0
    if "dod" in node.arguments:
        dod = int(node.arguments["dod"])
    fet = 1.7977e308
    if "fet" in node.arguments:
        fet = float(node.arguments["fet"])
    range_low = -1.7977e308
    if "range_low" in node.arguments:
        range_low = float(node.arguments["range_low"])
    range_high = 1.7977e308
    if "range_high" in node.arguments:
        range_high = float(node.arguments["range_high"])
    reject_low = False
    if "reject_low" in node.arguments:
        reject_low = bool(node.arguments["reject_low"])
    reject_high = False
    if "reject_high" in node.arguments:
        reject_high = bool(node.arguments["reject_high"])

    for data_object in node.get_parent_by_name("data").output_objects:

        # Skip if the datatype is not a strds and put the input into the output
        if data_object.is_strds() is False:
            output_objects.append(data_object)
            continue

        # multiple strds as input ?
        output_object = DataObject(name=create_output_name(
            data_object.name, PROCESS_NAME),
                                   datatype=GrassDataType.STRDS)
        output_objects.append(output_object)
        node.add_output(output_object=output_object)

        pc = create_process_chain_entry(data_object, nf, dod, fet, range_low,
                                        range_high, reject_low, reject_high,
                                        output_object)
        process_list.append(pc)

    return output_objects, process_list
Example #22
0
def create_process_chain_entry(
        input_object: DataObject,
        method,
        output_object: DataObject):
    """Create a Actinia process description that uses t.rast.series to reduce a time series.

    :param input_object: The input time series object
    :param method: The method for time reduction
    :param output_map: The name of the output raster object
    :return: A Actinia process chain description
    """
    rn = randint(0, 1000000)

    pc = {"id": "t_rast_series_%i" % rn,
          "module": "t.rast.series",
          "inputs": [{"param": "input", "value": input_object.grass_name()},
                     {"param": "method", "value": method},
                     {"param": "output", "value": output_object.grass_name()}],
          "flags": "t"}

    return pc
def create_process_chain_entry(input_object: DataObject, options: dict):
    """Create a Actinia command of the process chain that computes the regional statistics based on a
    strds and a polygon.

    :param input_object: The name of the raster layer
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)
    pc = []

    output_format = "GTiff"
    if input_object.is_vector():
        output_format = "GML"

    # the actinia exporter currently does not support GDAL creation options
    # parameter options is ignored
    options_list = list()
    for key in options:
        optstr = ("%s=%s" % (key, options[key]))
        options_list.append(optstr)

    exporter = {
        "id":
        "save_result_%i" % rn,
        "module":
        "exporter",
        "outputs": [{
            "export": {
                "type": input_object.datatype.value,
                "format": output_format
            },
            "param": "map",
            "value": input_object.grass_name()
        }]
    }

    pc.append(exporter)

    return pc
Example #24
0
def create_process_chain_entry(
        nir_time_series: DataObject,
        red_time_series: DataObject,
        blue_time_series: DataObject,
        scale: float,
        output_time_series: DataObject):
    """Create a Actinia process description that uses t.rast.mapcalc to create the EVI time series

    :param nir_time_series: The NIR band time series name
    :param red_time_series: The RED band time series name
    :param blue_time_series: The BLUE band time series name
    :param scale: scale factor
    :param output_time_series: The name of the output time series
    :return: A list of Actinia process chain descriptions
    """

    rn = randint(0, 1000000)

    pc = [
        {"id": "t_rast_mapcalc_%i" % rn,
         "module": "t.rast.mapcalc",
         "inputs": [{"param": "expression",
                     "value": "%(result)s = float(2.5 * %(scale)s * (%(nir)s - %(red)s)/"
                              "(%(nir)s * %(scale)s + 6.0 * %(red)s * %(scale)s -7.5 * %(blue)s * %(scale)s + 1.0))" % {
                                  "result": output_time_series.grass_name(),
                                  "nir": nir_time_series.grass_name(),
                                  "red": red_time_series.grass_name(),
                                  "blue": blue_time_series.grass_name(),
                                  "scale": scale}},
                    {"param": "inputs",
                     "value": "%(nir)s,%(red)s,%(blue)s" % {"nir": nir_time_series.grass_name(),
                                                            "red": red_time_series.grass_name(),
                                                            "blue": blue_time_series.grass_name()}},
                    {"param": "basename",
                     "value": output_time_series.name},
                    {"param": "output",
                     "value": output_time_series.grass_name()}]},
        {"id": "t_rast_color_%i" % rn,
         "module": "t.rast.colors",
         "inputs": [{"param": "input",
                     "value": output_time_series.grass_name()},
                    {"param": "color",
                     "value": "ndvi"}]}]

    return pc
def create_process_chain_entry(band1_time_series: DataObject,
                               band2_time_series: DataObject,
                               output_time_series: DataObject):
    """Create a Actinia process description that uses t.rast.mapcalc to create the normalized difference time series

    :param band1_time_series: The first band time series object
    :param band2_time_series: The second band time series object
    :param output_time_series: The object of the output time series
    :return: A list of Actinia process chain descriptions
    """

    rn = randint(0, 1000000)

    pc = [{
        "id":
        "t_rast_mapcalc_%i" % rn,
        "module":
        "t.rast.mapcalc",
        "inputs": [{
            "param": "expression",
            "value": "%(result)s = float((%(band1)s - %(band2)s)/"
            "(%(band1)s + %(band2)s))" % {
                "result": output_time_series.grass_name(),
                "band1": band1_time_series.grass_name(),
                "band2": band2_time_series.grass_name()
            }
        }, {
            "param": "inputs",
            "value": "%(band1)s,%(band2)s" % {
                "band1": band1_time_series.grass_name(),
                "band2": band2_time_series.grass_name()
            }
        }, {
            "param": "basename",
            "value": "nd"
        }, {
            "param": "output",
            "value": output_time_series.grass_name()
        }]
    }, {
        "id":
        "t_rast_color_%i" % rn,
        "module":
        "t.rast.colors",
        "inputs": [{
            "param": "input",
            "value": output_time_series.grass_name()
        }, {
            "param": "color",
            "value": "ndvi"
        }]
    }]

    return pc
def get_process_list(node: Node):
    """Analyse the process description and return the Actinia process chain and the name of the processing result

    :param node: The process node
    :return: (output_objects, actinia_process_list)
    """

    input_objects, process_list = check_node_parents(node=node)
    output_objects = []

    # Get the input data
    input_objects = node.get_parent_by_name(parent_name="data").output_objects

    input_strds = list(input_objects)[-1]

    nir_band = "nir"
    red_band = "red"
    if "nir" in node.arguments and \
       node.arguments["nir"] is not None and \
       node.arguments["nir"] != "null":
        nir_band = node.arguments["nir"]
    if "red" in node.arguments and \
       node.arguments["red"] is not None and \
       node.arguments["red"] != "null":
        red_band = node.arguments["red"]

    target_band = None
    if "target_band" in node.arguments and \
       node.arguments["target_band"] is not None and \
       node.arguments["target_band"] != "null":
        target_band = node.arguments["target_band"]

    output_objects.extend(list(input_objects))

    output_object = DataObject(
        name=create_output_name(input_strds.name, node),
        datatype=GrassDataType.STRDS)
    if target_band is None:
        output_objects.append(output_object)
        node.add_output(output_object=output_object)
    else:
        # if target band is given, extend the input strds
        output_objects.append(input_strds)
        node.add_output(output_object=input_strds)

    pc = create_process_chain_entry(
        input_strds, nir_band, red_band, target_band, output_object)
    process_list.extend(pc)

    return output_objects, process_list
def get_process_list(node: Node):
    """Analyse the process description and return the Actinia process chain and the name of the processing result

    :param node: The process node
    :return: (output_objects, actinia_process_list)
    """

    input_objects, process_list = check_node_parents(node=node)
    output_objects = []

    # First analyse the data entries
    if "band1" not in node.arguments:
        raise Exception("Process %s requires parameter <band1>" % PROCESS_NAME)

    if "band2" not in node.arguments:
        raise Exception("Process %s requires parameter <band2>" % PROCESS_NAME)

    # Get the red and nir data separately
    band1_input_objects = node.get_parent_by_name(
        parent_name="band1").output_objects
    band2_input_objects = node.get_parent_by_name(
        parent_name="band2").output_objects

    if not band1_input_objects:
        raise Exception(
            "Process %s requires an input strds for band 1" %
            PROCESS_NAME)

    if not band2_input_objects:
        raise Exception(
            "Process %s requires an input strds for band 2" %
            PROCESS_NAME)

    band1_strds = list(band1_input_objects)[-1]
    band2_strds = list(band2_input_objects)[-1]

    output_objects.extend(list(band1_input_objects))
    output_objects.extend(list(band2_input_objects))

    output_object = DataObject(
        name=create_output_name(band1_strds.name, node),
        datatype=GrassDataType.STRDS)
    output_objects.append(output_object)
    node.add_output(output_object=output_object)

    pc = create_process_chain_entry(band1_strds, band2_strds, output_object)
    process_list.extend(pc)

    return output_objects, process_list
Example #28
0
def create_process_chain_entry(input_object: DataObject, percentile,
                               output_object: DataObject):
    """Create a Actinia process description that uses t.rast.series to reduce a time series.

    :param input_time_series: The input time series object
    :param percentile: The percentile to use for time reduction
    :param output_map: The object of the output raster map
    :return: A Actinia process chain description
    """
    rn = randint(0, 1000000)

    quantile = float(percentile) / 100.0

    pc = {
        "id":
        "t_rast_series_%i" % rn,
        "module":
        "t.rast.series",
        "inputs": [{
            "param": "input",
            "value": input_object.grass_name()
        }, {
            "param": "method",
            "value": "quantile"
        }, {
            "param": "quantile",
            "value": quantile
        }, {
            "param": "output",
            "value": output_object.grass_name()
        }],
        "flags":
        "t"
    }

    return pc
Example #29
0
def get_process_list(node: Node):
    """Analyse the process description and return the Actinia process chain
    and the name of the processing result layer
    which is a single raster layer

    :param node: The process node
    :return: (output_objects, actinia_process_list)
    """
    # get dimension type
    dimtype = get_dimension_type(node.arguments["dimension"])
    if dimtype is None:
        raise Exception(
            'Unable to determine dimension type for dimension <%s>.' %
            (node.arguments["dimension"]))

    tree, operators = construct_tree(
        node.as_dict()['arguments']['reducer']['process_graph'])
    # print (operators)
    formula = None
    output_datatype = GrassDataType.STRDS
    if dimtype == 'bands':
        formula = serialize_tree(tree)
        # print (formula)
        output_datatype = GrassDataType.STRDS
    elif dimtype == 'temporal':
        if len(operators) != 1:
            raise Exception(
                'Only one method is supported by reduce process on the temporal dimension.'
            )

    input_objects, process_list = check_node_parents(node=node)
    output_objects = []

    for input_object in node.get_parent_by_name("data").output_objects:

        output_object = DataObject(name=create_output_name(
            input_object.name, node),
                                   datatype=output_datatype)
        output_objects.append(output_object)
        node.add_output(output_object=output_object)

        pc = create_process_chain_entry(input_object, dimtype, formula,
                                        operators, output_object)
        process_list.extend(pc)

    return output_objects, process_list
Example #30
0
def create_process_chain_entry(input_time_series: DataObject,
                               bands, wavelengths,
                               output_time_series: DataObject):
    """Create a Actinia command of the process chain that uses g.region to create a valid computational region
    for the provide input strds

    :param north:
    :param south:
    :param east:
    :param west:
    :param crs:
    :return: A Actinia process chain description
    """

    rn = randint(0, 1000000)

    # convert wavelengths to a string
    wvstring = None
    pc = None
    if wavelengths and bands:
        wvstring = (',').join(wavelengths)

        pc = {"id": "t_rast_filterbands_%i" % rn,
              "module": "t.rast.filterbands",
              "inputs": [{"param": "input",
                          "value": "%(input)s" % {"input": input_time_series.grass_name()}},
                         {"param": "bands",
                          "value": "%(bands)s" % {"bands": (',').join(bands)}},
                         {"param": "wavelengths",
                          "value": "%(wavelengths)s" % {"wavelengths": wvstring}},
                         {"param": "output",
                          "value": output_time_series.grass_name()}]}
    elif bands:
        pc = {"id": "t_rast_filterbands_%i" % rn,
              "module": "t.rast.filterbands",
              "inputs": [{"param": "input",
                          "value": "%(input)s" % {"input": input_time_series.grass_name()}},
                         {"param": "bands",
                          "value": "%(bands)s" % {"bands": (',').join(bands)}},
                         {"param": "output",
                          "value": output_time_series.grass_name()}]}
    elif wavelengths:
        wvstring = (',').join(wavelengths)
        pc = {"id": "t_rast_filterbands_%i" % rn,
              "module": "t.rast.filterbands",
              "inputs": [{"param": "input",
                          "value": "%(input)s" % {"input": input_time_series.grass_name()}},
                         {"param": "bands",
                          "value": "%(bands)s" % {"bands": (',').join(bands)}},
                         {"param": "output",
                          "value": output_time_series.grass_name()}]}

    return pc